Ray Casting
by Justin Mosiman · in Torque Game Engine · 07/14/2006 (12:10 pm) · 9 replies
Hi,
Based on the direction that I am looking, I want to cast a ray and find the point that the ray intersects with the terrain or another object. The variables that I have to work with are yaw angle, pitch angle, and position (x,y,z). Is this possible?
Thanks,
Justin
Based on the direction that I am looking, I want to cast a ray and find the point that the ray intersects with the terrain or another object. The variables that I have to work with are yaw angle, pitch angle, and position (x,y,z). Is this possible?
Thanks,
Justin
#2
07/14/2006 (1:12 pm)
Here's some sample code. The function below will return the ID of whatever object the current control object (usually the player or the editor camera) is looking at.function testRay()
{
%client = localClientConnection;
%player = %client.getControlObject();
%start = %player.getEyePoint();
%rayLength = 1000;
%rayDirection = VectorScale(%player.getEyeVector(), %rayLength);
%end = VectorAdd(%start, %rayDirection);
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType | $TypeMasks::ShapeBaseObjectType;
%rayInfo = ContainerRayCast(%start, %end, %mask, %player);
if (getWordCount(%rayInfo))
{
%object = getWord(%rayInfo, 0);
%point = getWords(%rayInfo, 1, 3);
%normal = getWords(%rayInfo, 4, 6);
return %object;
} else {
return 0;
}
}
#3
If theta is your angle off of the x-axis heading towards your y-axis and rho is your angle off the z-axis heading towards the x-y-plane, then your unit vector will be:
x = sin( rho ) * cos( theta ),
y = sin( rho ) * sin( theta ),
z = cos( rho ).
Usually a pitch angle is defined as the angle up from the x-y-plane towards the z-axis. In that case, change the rho to (90 - pitch). (Of course, then the sin and cos can be re-simplified, but I leave that as an exercise for the reader.)
07/14/2006 (1:19 pm)
It's not too hard. Since ray casts require an end point, I would convert your yaw and pitch angle into a unit vector. Then multiply that unit vector by some large number (say 500) and add it to your position. Set the start position to your (x,y,z) and your end position to the (x',y',z') position.If theta is your angle off of the x-axis heading towards your y-axis and rho is your angle off the z-axis heading towards the x-y-plane, then your unit vector will be:
x = sin( rho ) * cos( theta ),
y = sin( rho ) * sin( theta ),
z = cos( rho ).
Usually a pitch angle is defined as the angle up from the x-y-plane towards the z-axis. In that case, change the rho to (90 - pitch). (Of course, then the sin and cos can be re-simplified, but I leave that as an exercise for the reader.)
#4
Here's what I'm working on:
I'm pretty close to finsihing a new camera, one that is similar to the RTS camera except it changes position when you pitch/yaw/zoom so it rotates around a center position. I have that part working, but right now the camera has a problem with terrain height changes (it just goes through the terrain). I can calculate if the camera position is greater/equal to the terrain, so I will be able to make sure it doesn't go through the terrain while moving.
I have a center variable (x,y) that updates when you pan, so the center always changes when you move. I cannot use the same method for updating the center z variable because the center is not always at the same height as the camera. For example, if you are moving up a hill, the center is not moving up at the same rate because it's not necessarly on the same hill (or even on a hill). So the problem that I'm having is finding the center, and I thought that it could be solved with a ray cast. Am I on the right track with this whole ray cast thing?
Thanks
07/14/2006 (2:11 pm)
Thanks for the help, what if I don't know the distance to the endpoint? I'm trying to find that endpoint. Maybe ray cast is the wrong word.Here's what I'm working on:
I'm pretty close to finsihing a new camera, one that is similar to the RTS camera except it changes position when you pitch/yaw/zoom so it rotates around a center position. I have that part working, but right now the camera has a problem with terrain height changes (it just goes through the terrain). I can calculate if the camera position is greater/equal to the terrain, so I will be able to make sure it doesn't go through the terrain while moving.
I have a center variable (x,y) that updates when you pan, so the center always changes when you move. I cannot use the same method for updating the center z variable because the center is not always at the same height as the camera. For example, if you are moving up a hill, the center is not moving up at the same rate because it's not necessarly on the same hill (or even on a hill). So the problem that I'm having is finding the center, and I thought that it could be solved with a ray cast. Am I on the right track with this whole ray cast thing?
Thanks
#5
I know the stock third person camera has "collision" on it for if you back up against a wall or something it won't go through the wall, so you could maybe look at how that works too.
07/14/2006 (2:38 pm)
Well if it's terrain... then just doing a downward raycast would be fine (just subtract a bunch from the z value of your initial position for the second point of the raycast). The distance of the raycast isn't that important, just needs to be far enough so it can always find the ground. The raycast will return the point (and thus the height) you are looking to avoid going below.I know the stock third person camera has "collision" on it for if you back up against a wall or something it won't go through the wall, so you could maybe look at how that works too.
#6
I already can figure out the current height, and if it goes under the terrain or not, that's not the problem. Let me come up with a different example.
Lets say that you are looking almost parallel with the terrain (but not totally parallel, we want the center to exist). And then lets say that you move left up a small hill (along the x axis just to make it easy). The way that I am doing it right now, the center position's x axis would change at the same rate that the camera's x axis is changing. So if I move left 5 units, the center would move left 5 units also. That is all well and good, but then you have to factor in the hill. Because you increase in height with the hill, I can't just increase the centers height because then the centers height would be floating (or if I'm going down a hill for example, it could be below the terrain).
So that way won't work. What I want to do is find out if there is some way that I can cast a ray (or a vector, I don't know what I would have to use) that would create a line and get the coordinates with the terrain that it intersects with, because eventually this line will intersect with the terrain somewhere.
So that's the idea, I can come up with another example if needed.
Thanks
07/14/2006 (9:35 pm)
Quote:The raycast will return the point (and thus the height) you are looking to avoid going below.
I already can figure out the current height, and if it goes under the terrain or not, that's not the problem. Let me come up with a different example.
Lets say that you are looking almost parallel with the terrain (but not totally parallel, we want the center to exist). And then lets say that you move left up a small hill (along the x axis just to make it easy). The way that I am doing it right now, the center position's x axis would change at the same rate that the camera's x axis is changing. So if I move left 5 units, the center would move left 5 units also. That is all well and good, but then you have to factor in the hill. Because you increase in height with the hill, I can't just increase the centers height because then the centers height would be floating (or if I'm going down a hill for example, it could be below the terrain).
So that way won't work. What I want to do is find out if there is some way that I can cast a ray (or a vector, I don't know what I would have to use) that would create a line and get the coordinates with the terrain that it intersects with, because eventually this line will intersect with the terrain somewhere.
So that's the idea, I can come up with another example if needed.
Thanks
#7
I have modified the testRay function above to all me to use it on AIPlayers as well...
When I use it as it was originally designed, everything works, fine, I point my cursor at an Object (based on the masks) and I get the ID of the object returned, however when i use it for an AI client ie.
unless Im standing right in front of the AI player, it returns the id of the terrain. Is there a simple xyz intercept formula for me to verify that the AI is able to see me at the specified distance? I am using TGEA 1.8.1. Also, if I am not asking the right questions I apologize. The documentation for TGEA is hard to find sine it is community driven. If there is somewhere else I should be looking please let me know.
11/30/2009 (3:27 am)
The question above is way above my head, but the testRay function above has helped me understand how to use the rayCast function. I am very new, so please bear with me. I have modified the testRay function above to all me to use it on AIPlayers as well...
function testRay(%forAi,%id)
{
if(%forAi == false){
%client = localClientConnection;
%player = %client.getControlObject();
}else{
%player = %id;
}
%start = %player.getEyePoint();
%rayLength = 1000;
%rayDirection = VectorScale(%player.getEyeVector(), %rayLength);
%end = VectorAdd(%start, %rayDirection);
%mask = $TypeMasks::PlayerObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType | $TypeMasks::ShapeBaseObjectType;
%rayInfo = ContainerRayCast(%start, %end, %mask, %player);
if (getWordCount(%rayInfo))
{
%object = getWord(%rayInfo, 0);
%point = getWords(%rayInfo, 1, 3);
%normal = getWords(%rayInfo, 4, 6);
return %object;
} else {
return 0;
}
}When I use it as it was originally designed, everything works, fine, I point my cursor at an Object (based on the masks) and I get the ID of the object returned, however when i use it for an AI client ie.
echo(testRay(true,2259));//where 2259 is the ID of one of the AIPlayers.
unless Im standing right in front of the AI player, it returns the id of the terrain. Is there a simple xyz intercept formula for me to verify that the AI is able to see me at the specified distance? I am using TGEA 1.8.1. Also, if I am not asking the right questions I apologize. The documentation for TGEA is hard to find sine it is community driven. If there is somewhere else I should be looking please let me know.
#8
Hope this helps someone else out!
11/30/2009 (3:41 am)
I used the setAimLocation() function to verify that my function was working properly. 2423.setAimLocation(2296.getTransform());//2423 is the ID of the AIPlayer // and 2296 is the ID of the localclient player echo(testRay(true,2423)); //returned 2296 at the correct distances
Hope this helps someone else out!
#9
%start = %player.getEyePoint();
now if you set the id to the id of the ai player then that would mean its using the eye point of the ai player
is it possible that the eye point and the vector of the ai player is not facing in the right direction?
maybe its on an angle that shoots into the air or the ground being that it works when you are standing directly in front of it?
11/30/2009 (11:58 pm)
i havent ran or tested the script but it looks like it calls to use the ray at%start = %player.getEyePoint();
now if you set the id to the id of the ai player then that would mean its using the eye point of the ai player
is it possible that the eye point and the vector of the ai player is not facing in the right direction?
maybe its on an angle that shoots into the air or the ground being that it works when you are standing directly in front of it?
Torque Owner Paul /*Wedge*/ DElia