Once a week, we see the question "
How do I make one object point to face another position/object?"
Often, the solutions offered are "subtract the position of one from the other," which only tells you the direction you want to go in, not how to actually rotate to face that direction.
Another solution offered usually involves trigonometry, typically based on Math.Atan2(), and makes some assumptions about which direction you want to be "up".
The problem is not as simple as "just subtract one from the other." Also, the problem does not require trig to be solved.
Here is a different statement of the same problem:
"
I
have an arrow/ship/character that is built to point down the Z axis
when in Identity rotation at position P. How do I rotate it so that it
points at object O, with up axis U ?"
The actual math involved, as long as O is not linearly dependent with U, is simple.
1) Create the vector D = (O-P).
2) Create the vector U cross D, and normalize. Call this "Right"
3) Create the vector Right cross U and normalize. Call this "Backwards"
4) Create the vector Backwards cross Right. Call this "Up"
4) Your matrix is now these three vectors written in rows (assuming row vectors on the right):
// O is your object's position
// P is the position of the object to face
// U is the nominal "up" vector (typically Vector3.Y)
// Note: this does not work when O is straight below or straight above P
Matrix RotateToFace(Vector3 O, Vector3 P, Vector3 U)
{
Vector3 D = (O - P);
Vector3 Right = Vector3.Cross(U, D);
Vector3.Normalize(ref Right, out Right);
Vector3 Backwards = Vector3.Cross(Right, U);
Vector3.Normalize(ref Backwards, out Backwards);
Vector3 Up = Vector3.Cross(Backwards, Right);
Matrix rot = new Matrix(Right.X, Right.Y, Right.Z, 0, Up.X, Up.Y, Up.Z, 0, Backwards.X, Backwards.Y, Backwards.Z, 0, 0, 0, 0, 1);
return rot;
}
If
your object is modeled pointing down some axis other than positive Z,
you can pre-multiply the matrix that turns the model around to face Z,
and then multiply this matrix, to get the final orientation matrix. However, if you build your object in 3ds Max such that it is looking at you (you see the front), then the object is already facing positive X when you export it.
What this does, geometrically, is:
* Assuming the Z axis will be pointing at the object
*
Using the nominal "up" to find where the "right" (X) axis will point.
This means that the above/below positions won't work, because "right"
could be anything.
* Using the calculated Z and X axes, calculate
the actual "up" (Y) axis that's aligned with the initial up, but
creates an orthogonal coordinate space.
That in turn gets turned into a matrix, which ends up being the matrix you use to rotate the object.
Math is Cool!
--
Jon Watte, Direct3D MVP
kW X-port 3ds Max .X exporter
14 days after getting my RROD box back, it's going back for service again. Grr.