intersectRay Help!

]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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
KaSa's picture

Sorry for not being able to

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's picture

This code works but only on

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's picture

Try adding an input for the

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's picture

This looks like it should

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's picture

Well I got most of it sorted

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.htm

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 ) )

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.