Advertisement

Rotation based on Forward and Up vectors

Started by June 24, 2003 04:39 PM
1 comment, last by HappyDude 21 years, 7 months ago
If I''ve stored normalized vectors of the up and forward directions of an object, how would I translate this into a rotation? At first I tried looking up the function used to create matrices for lookat functions and just removing the translation, but that didn''t seem to work at all. After that I tried taking the inverse cosine of the dot product of the object''s forward vector and a forward vector for an object with no rotation (assumed to be 0,0,1 (left-hand system)), and then using that as the angle for a rotation around the axis found by taking the cross product of the object''s forward vector and a forward vector of an object with no rotation. The problem with this was that the rotation around the object''s z-axis was completely skewed in almost all cases. So, anyone know a better method (aside from rewriting all my code using quats instead of forward/up vectors) or a way to fix whatever I was trying to do?
that's not difficult. It might seems more like a lecture or something, but it's a point everybody whould know and understand fully(-ish, I'm no math specialist).

here we go...

A rotational matrix is an agglomeration of 3 orthogonal axis.

1  0  0 -> left0  1  0 -> up0  0  1 -> forward|  |  |v  v  vl  u  fe  p  of     rt     w      a      r      d


now, there are lots of assumptions, and things that depend on the way you work out the rotations and the 'forward' direction of your object.

for me, forward is positive Z (OpenGL style). You may use the X axis as your forward axis, and it can get very confusing.

Also, the matrices are either row-major, or column-major (which is why I have two sets of left/up/forward in the diagram). Only one of them will work for you. You ought to do a search in the math/graphics libraries you use to see which one is teh right one for you. Either way, you can try both of them and see what works, and what doesn't. One wil be quite wrong (bad orientation).

the third axis you require to build up the matrix is the 'left' axis. I use a right-handed coordinate system, like most sane people do. Basically, x would be your right thumb pointing left, Y would be your index pointing up, and Z would be your middle finger pointing forward in front of you (a bit a stretch, I know ). Hence, the Z component being the forward vector.

to clarify, I will forget about left/up/forward, and use 'X', 'Y', 'Z' as the name for the rows or columns of the matrix. This will agree with everybody.

1  0  0 -> X0  1  0 -> Y0  0  1 -> Z|  |  |v  v  vX  Y  Z



because this is a right-handed orthonormal coordinate sytem, you can work out each axis in respect to the two others.

Z = X x Y
X = Y x Z
Y = Z x X

and the 'x' operator does a cross product
Vector Cross(Vector A, Vector B){    return Vector(A.y*B.z-A.z*B.y,                   A.z*B.x-A.x*B.z,                  A.x*B.y-A.y*B.x);}

so there, create a left vector by doing the cross between the up and the forward vector, load your vectors into the rows OR columns of a matrix (check on the maths library to decide which one to use), and presto, you have an orientation matrix.

as an example...

Left = Up x Forward

... and ONLY one of those would do what you want, depending on your definition of what is forward, and what type of matrix it is.

Matrix.SetRow(0, Left)
Matrix.SetRow(1, Up)
Matrix.SetRow(2, Forward)

or try
Matrix.SetColumn(0, Left)
Matrix.SetColumn(1, Up)
Matrix.SetColumn(2, Forward)

or try
Matrix.SetRow(0, Forward)
Matrix.SetRow(1, Up)
Matrix.SetRow(2, Left)

ect...


for LookAt() function, it's best if you try to make sure that all the vectors are orthogonal to each other.

say, you have a forward vector Forward = (Target - CamPos), and a set-in-stone Up vector. Forward might not be orthogonal to Up (say if you are looking slightly down, and up is (0, 1, 0)).

you can correct the problem as is

Diff = (Target - CamPos);Up   = CamUp;Left = Up x Diff;Left.Normalise();Forward = Left x Up;// Forward.Normalise(); // should not be required


there, you are assured the 3 vectors are orthonormal (unless Diff is aligned with Up or Diff = 0), and you can build a good orthonormal orientation matrix (can't remember how it's called now).

You can also make sure the forward vector IS the definitive vector from where everything should be aligned to. It's exactly the same as above, but different

   Forward = (Target - CamPos);Forward.Normalise();Up      = CamUp;Left    = Up x Forward;Left.Normalise();Up = Forward x Left;// Up.Normalise();




[edited by - oliii on June 24, 2003 8:50:13 PM]

Everything is better with Metal.

Advertisement
Thanks for the reply. My entire problem had been that I had my vectors set up across the rows, when they were supposed to be placed in the matrix as columns. Would never have noticed it if you didn''t mention it in your post .

This topic is closed to new replies.

Advertisement