I need some vector math help, please.
I need some vector math help, please.
I have two nodes. How can I find our if one node is facing within 30 degrees of the other one (like its field of vision )
You can use the scalar product between the two "forward" vectors. So, assuming that x=(x_1, x_2, x_3) is pointing forward for node 1 and y=(y_1, y_2, y_3) does the same for node 2, and assuming further that both x and y have length 1, the following equation is true:
where a is the (unorientated) angle between x and y.
Code: Select all
x_1*y_1+x_2*y_2+x_3*y_3 = cos a,
It has long been an axiom of mine that the little things are
infinitely the most important.
-- Sir Arthur Conan Doyle, "A Case of Identity"
infinitely the most important.
-- Sir Arthur Conan Doyle, "A Case of Identity"
rincewind is correct that you can use the scalar product (also called dot product) to find the angle, but you shouldn't use the look vectors of both nodes.
That would just tell whether they are facing the same direction, not if one can actually "see" the other.
To find out if node A is looking at node B, you need two vectors:
1) The looking direction of node A.
2) The vector from A and B.
To find the looking vector of node A: (I think it's like this)
Then, to determine if node A can "see" a point:
The 0.75 is there because cos30*cos30 = 0.75 - if you want another field of view, change 0.75 to the square of the cosine of that angle.
Note: I haven't tested all this; it may not work but I think it does.
(Got timeout when trying to post this - sorry if this is a double-post)
That would just tell whether they are facing the same direction, not if one can actually "see" the other.
To find out if node A is looking at node B, you need two vectors:
1) The looking direction of node A.
2) The vector from A and B.
To find the looking vector of node A: (I think it's like this)
Code: Select all
// call updateAbsoluteTransformation if you have moved it since last frame
core::vector3df getLookDirection( const scene::ISceneNode* sceneNode )
{
const core::matrix4& mat = sceneNode->getAbsoluteTransformation();
return core::vector3df(mat.M[0], mat.M[1], mat.M[2]);
}
Code: Select all
bool isPointInFieldOfView( const scene::ISceneNode* A, const core::vector3df& point )
{
core::vector3df look = getLookDirection( A );
core::vector3df ab = point - A->getPosition();
f32 dot = look.dotProduct( ab );
return (dot > 0) && (dot*dot >= look.getLengthSQ()*ab.getLengthSQ()*0.75);
}
Note: I haven't tested all this; it may not work but I think it does.
(Got timeout when trying to post this - sorry if this is a double-post)
I'm not familiar with C#, but I can take a good guess as to what it might look like.
The line that says return core::vector3df(mat.M[0], mat.M[1], mat.M[2]) makes a vector from the first column and rows 1, 2 and 3.
In short, let the column index be 0 and row index 0, 1 and 2.
So in C# it might look like this:
ab is a the vector from A to B - it is in world coordinates and not angles.
The code I wrote doesn't really allow you to tell what direction to turn because it uses all 3 rotation axes.
For a simple FPS game you could make it a bit easier by using the orientation (north/south look direction) and pitch (up/down look direction).
The line that says return core::vector3df(mat.M[0], mat.M[1], mat.M[2]) makes a vector from the first column and rows 1, 2 and 3.
In short, let the column index be 0 and row index 0, 1 and 2.
So in C# it might look like this:
Code: Select all
return core::vector3df(mat.get_M(0,0), mat.get_M(0,1), mat.M(0,2));
The code I wrote doesn't really allow you to tell what direction to turn because it uses all 3 rotation axes.
For a simple FPS game you could make it a bit easier by using the orientation (north/south look direction) and pitch (up/down look direction).