ScriptSpot

Forum topic · General Scripting

intersectRay Help!

By viro · 2009-03-25

Description

]I am taking our current intersectRay functionality that works by using a pick button and adapting it to work with a list box and an array as apposed to the one object version used by the pick button. I am not sure if I am going about this the right way and I wanted to get some feedback on what I am missing. Essentially what I am trying to do is to take our current machine rigs and give them the ability to drive along multiple ground objects picked by the list box. I have been trying to get it to work for a couple days now. I hope someone can give me some help on what I am doing wrong.

ca = custAttributes.getDef $.modifiers[1].controls
attributes controls
redefine:ca
(
	parameters main rollout:controlsR
	(

		collisionObj type:#maxObject

	)
          local list=#()
	--#########################################
	--Functions
	--#########################################

	fn intersect rayCas =
	(
		if collisionObj!=undefined and (isValidNode collisionObj.node) then
		(
			intersectRay collisionObj.node rayCas
		)else
		(
			undefined
		)
	)
	--#########################################
	--Rollouts
	--#########################################
	rollout controlsR	"controls" width:160 height:1000
	(

		group "ground"
		(
			listbox listObj "Ground Objects:" height:5
			button remove "remove" across:2
			pickbutton add "add" across:2
		)

			--when the add button is pressed do this
			on add picked obj do
		(
			--Make sure the object is an editabale mesh and if so go to the next line
			if classOf obj == Editable_mesh then
			(	
			--add the picked object to the list array
						for i in 1 to (listObj.items.count) do
							(
								collisionObj= (listObj.items[i])
								collisionObj=nodeTransformMonitor node:obj forwardTransformChangeMsgs:false
							)

				print collisionObj
				(listObj.items) = append(listObj.items) (obj.name)
				list = (listObj.items)

			)
			
		)

			on remove pressed do
		(
			collisionObj=undefined
			print collisionObj
			--if array is not empty and selected is not empty then
			if (listObj.selection) != 0 then
		(
			--delete the selected object from the lsit
		(listObj.items) = deleteItem (listObj.items) listObj.selection
		)
		)
			on controls open do
		(

			(listObj.items)=list

		)
	)

)
--Positon Script Controller
--variables
rayObj=--Ray casting object
master=--controll object attribute holder.control
masterObj=--control Object
--Script in controler
rayCas=(ray rayObj.pos (-rayObj.transform.row3))
hit=master.intersect rayCas

if hit==undefined then
(masterObj.pos)
else
(hit.pos)
Comments (5)

KaSa · 2009-04-01

Sorry for not being able to follow up before now. There seems to be an extra i, after do, in the loop. And it is checking the validity of ground[1] only, but assuming that ground[1] is valid, it should operate on everything in ground. Is it possible that there is a naming conflict for ground?

viro · 2009-03-30

This code works but only on ground[1] so the first item in the listbox. So I know it works bit I believe the for loop is not working or is always giving a value of 1 but i cant figure out why.

fn getIntersection theRay= ( if ground[1]!=undefined and (isValidNode ground[1].node) then ( for i in ground do i ( intersectRay ground[i].node rayV ) ) else ( undefined ) )

KaSa · 2009-03-26

Try adding an input for the ground objects to the function after rayV, and then call the function in a loop. For this example I called it ground_obj.

fn gethit rayV ground_obj =
(
if ground_obj!=undefined and (isValidNode ground_obj.node) then
(
intersectRay ground_obj.node rayV
)
else ( undefined )
)

Then do this:

for i in listObj.items do gethit rayV i

If that doesn't work, try putting the ground objects into an array and loop through that instead of trying to access them directly from listObj.

viro · 2009-03-26

This looks like it should work. I think I am having problems because I access the function from a script controller and the function is contained in a custom attribute holder. ground is already an array and it is all working. So I need to take the 1 in ground[1] and change it to i ground[i] and make a loop that will run the function for each item in the
list box. Problem is that every one I have tried has failed.

In your example the for loop would be in the script controller correct? which fails because listObj.items cant be accessed.(i think)So i would think I just need to make the for loop a function that can be accessed by the controller?

so here is what I have in the script controller


--variables
master= refers to the attribute holder
masterObj= refers to the master object node that has the Ca
rayObj=refers to the ray casting object
rayV=(ray rayObj.pos (-rayObj.transform.row3))
hit=master.getHit rayV 

if hit==undefined then
(masterObj.pos)
else
(hit.pos)

then this is the Attribute holder code


ca = custAttributes.getDef $.modifiers[1].motorgradermaster
attributes motorgradermaster
redefine:ca
(
	parameters main rollout:motorgrader
	(
		
		ground type:#maxObjectTab tabSize:0 tabSizeVariable:true
		
	)
	--#########################################
	--Functions
	--#########################################
fn gethit rayV =
	(
		if ground[1]!=undefined and (isValidNode ground[1].node) then
			(
				intersectRay ground[1].node rayV
			)
					else
			( 
				undefined 
			)
	)
		

	--#########################################
	--Rollouts
	--#########################################
	rollout motorgrader "Motor Grader Rig" width:160 height:1000
	(

		local btW1=140
		local  btW2=65

		group "ground"
		(
		listBox listObj "Ground Objects:" height:5
		pickButton addObject "Add Object" width:btW2 across:2
		button deleteObject "Delete" width:btW2
		)

		--function that updates the list
		fn updateList=
		(
			nNames=for n in ground collect n.node.name
			listObj.items=nNames
		)
		
		on addObject picked obj do
		(
			weak = (nodeTransformMonitor node:obj forwardTransformChangeMsgs:false)
			append ground weak
			updateList()
		)
		on deleteObject pressed do
		(
			num=listObj.selection
			if num!=0 then
			(
				deleteItem ground num
				updateList()
			)
		)

		on motorgrader open do
		(
			updateList()
		)
	)
)

viro · 2009-03-25

Well I got most of it sorted out by taking a look at Pen's tutorial on weak referencing. http://paulneale.com/tutorials/Scripting/weakReferences/weakReferences.h…

Now I need to figure out how to get the intersectRay function to work with an array of objects. Heres what I have working now. Obviously this is just taking the first item in the array and using it. I tried a for loop already to with no luck. Any ideas?

fn gethit rayV = ( if ground[1]!=undefined and (isValidNode ground[1].node) then ( intersectRay ground[1].node rayV ) else ( undefined ) )