View Full Version : Using IntersectRay for car wheels on a Rugged surface
wamo 04 April 2008, 04:57 PM hi guys,
i'm trying to evaluate intersectRay for a wheel that is linked to a point helper,on a surface.
i added a position script on wheel.pos.z then wrote the script below:
p = $Point01.pos
r0 = Ray [p.x,p.y,p.z] [p.x,p.y,p.z]
the = intersectRay $Plane01 r0
the.position.z
but it returns me:
unknown property : "position" in undefined
so what's the problem?
also i'm not that much familier with intersectRay,dose it work when i move time slider? or it works realtime?
i was wondering if you scripters can help me,
thanks in advanced..


Kramsurfer
04 April 2008, 05:19 PM
If your point falls below the mesh you'll get "undefined" as the return on the ray intersect, so you need to have the point of your ray well above the mesh. Maybe
( ray [p.x,p.y, (p.z + 100)] [p.x,p.y,p.z] )
You'll still want to trap for the instance when it returns "undefined" just to keep things rolling..
The position script will update on the sliderTime or CurrentTime change. The way you appear to be writing it, it will be a progressive time based solution. You will need to set keys if you are intending on rendering it on more than one machine.
The other option is to look at the time before your current position using the "At Time" command and see how much your wheel has changed since then and make adjustments to it based on that and the ray intersect..
good luck...
wamo
04 April 2008, 06:56 PM
thanks Kramsurfer for your replay,but still can't do it
i show you a screen capture of the scene to be more clear:
http://aycu07.webshots.com/image/49366/2001214475714527832_th.jpg (http://allyoucanupload.webshots.com/v/2001214475714527832)
as you see the wheel is on the surface not below that,also
i didn't catch what you mean of this:
You'll still want to trap for the instance when it returns "undefined" just to keep things rolling..
plz explain more...dude.
thanks,
Ehsan.
wamo
04 April 2008, 07:02 PM
delete plz...
derp123
04 April 2008, 06:14 AM
At any point, if your ray does not hit plane01, it will return undefined. This means you are trying to access the position value of the intersection, but it doesn't exist. Avoiding it to crash is straight forward. Only continue the code if an intersection happens, which would be in MAXscript:
p = $Point01.pos
r0 = Ray [p.x,p.y,p.z] [p.x,p.y,p.z]
the = intersectRay $Plane01 r0
if the != undefined do the.position.z  If there's a hit, return the position of the interesction
else 0  If there's a miss, just set the position value to 0
Also, you could fix up the values you are giving to your ray. Something like this:
r0 = Ray [p.x,p.y,(p.z+100)] [0,0,1]
The first 3 point value is the position of the ray. You would want it exactly where the wheel is, but higher up in Z, just to make sure it doesn't go through the ground. The second 3 point value is the direction of the ray. You would want it to shoot straight down where your ground is.
wamo
04 April 2008, 08:07 AM
Hi Jason,really thank you,it was a perfect help to me,
but still it doesn't return the intersection.pos.z value,so the wheel.pos.z do not access
that value,i attached the main file for you,plz download it and see what happens to this.
bnvm
04 April 2008, 07:56 PM
The expression works the reason why it doesn't appear to work is because the cylinder is linked to the point object. I never use expressions for this type of thing so I am not sure why it doesn't work, but I it appears that the z offset is being applied in parent space not world space. If you add this,
aHitLoc.pos.z += 10
after this line,
aHitLoc = intersectRay $plane01 aRay
You will see that it works.
So the expression evaluates and gets a value of 0.0 from aHitLoc.pos.z, no matter how high or low you move the point01 object aHitLoc.pos.z will always return 0.0 since a flat plane at z = 0 is being used as the colision object. Therefore this expression is always returning the same value which is being applied to the cylinder in the local coordinate system of its parrent object, the point, therefire the sphere always follows exactly the motion of the point.
This expression works it gets arround the local space problem by using the distance between the point and the position stored in aHitLoc to offset the z height of the cylinder. This one will only work until the pivot of the point moves below the plane, at that point the cylinder will simply follow the point until the point moves back above the ground plane. Notice how all of the calculations that require aHitLoc are in the != undefined do loop, this prevents the expression from crashing when aHitLoc = undefined.
dependson $point01 $plane01
aRay = ray $Point01.position $Point01.dir
aHitLoc = intersectRay $plane01 aRay
HitZ = 29.4  radius of cylinder
if aHitLoc != undefined do
(
dist = distance aRay.pos aHitLoc.pos
HitZ = dist
)
HitZ
I hope this helps you some, also you may want to consider setting keys rather than using controllers for this as you could add in tire motion and tire rotation in a single script rather than multiple controllers.
bnvm
wamo
04 April 2008, 05:08 AM
The expression works the reason why it doesn't appear to work is because the cylinder is linked to the point object. I never use expressions for this type of thing so I am not sure why it doesn't work, but I it appears that the z offset is being applied in parent space not world space. If you add this,
aHitLoc.pos.z += 10
after this line,
aHitLoc = intersectRay $plane01 aRay
You will see that it works.
So the expression evaluates and gets a value of 0.0 from aHitLoc.pos.z, no matter how high or low you move the point01 object aHitLoc.pos.z will always return 0.0 since a flat plane at z = 0 is being used as the colision object. Therefore this expression is always returning the same value which is being applied to the cylinder in the local coordinate system of its parrent object, the point, therefire the sphere always follows exactly the motion of the point.
This expression works it gets arround the local space problem by using the distance between the point and the position stored in aHitLoc to offset the z height of the cylinder. This one will only work until the pivot of the point moves below the plane, at that point the cylinder will simply follow the point until the point moves back above the ground plane. Notice how all of the calculations that require aHitLoc are in the != undefined do loop, this prevents the expression from crashing when aHitLoc = undefined.
dependson $point01 $plane01
aRay = ray $Point01.position $Point01.dir
aHitLoc = intersectRay $plane01 aRay
HitZ = 29.4  radius of cylinder
if aHitLoc != undefined do
(
dist = distance aRay.pos aHitLoc.pos
HitZ = dist
)
HitZ
I hope this helps you some, also you may want to consider setting keys rather than using controllers for this as you could add in tire motion and tire rotation in a single script rather than multiple controllers.
bnvm
hey,thank you
it's a great help also i got some answer in rigging forum,but now i have another question about using this issue:
for example:we have twe building and a car that wants to fly from one to another one,but when useing the script above,when the car reaches to the space between the two buildings it suddenly backs to [0,0,0] position so it's not a good stuff.
but how game artist solved this problem,can you help me out to solve it?
thanks in advanced.
bnvm
04 April 2008, 03:16 PM
In order for this expression not to snap back up after leaving the roof you need to keep track of the previous offset "dist" so you can assign it on frames where aHitLoc = undefined. Take a look at this new expression I added a new variable oldDist to store the "dist" so it can be used whenever aHitLoc = undefined. I needed to create a global variable for this to work which is declared at the top of the expression, which is not ideal. Since I couldn't get this to work without using a global variable the "oldDist" will need a unique name for every tire that has a controller on it otherwise the controllers will be constantly overwriting this single variable and a incorrect values may be passed to the controller. Compare this one to the previous if you want to see what changes where made.
global oldDist
dependson $point01 $plane01
aRay = ray $Point01.position $Point01.dir
aHitLoc = intersectRay $plane01 aRay
HitZ = 29.4  radius of cylinder
if aHitLoc != undefined then
(
dist = distance aRay.pos aHitLoc.pos
HitZ = dist
OldDist = dist
)
else
(
if OldDist != undefined do
(
HitZ = OldDist
)
)
HitZ
bnvm
CGTalk Moderation
04 April 2008, 03:16 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.