PDA

View Full Version : Get Direction from Transformation Matrix or Quat



deshan
08-30-2011, 07:58 PM
Hi All,

Probably this may be a repat of question. Forgive me.

I have transformation matrix like following.

m00 m10 m20 m30
m01 m11 m21 m31
m02 m12 m22 m32
m03 m13 m23 m33

Could you please tell me how do I get the direction for FPS camera using above transformation?

I also have pitch, yaw and roll degrees. I have used "create from angle axis" implementation to make the quaternion. So I also has the quat value.

Some how I need to get the direction where the camera is heading.

Pls help me.

remdul
08-31-2011, 10:05 AM
Very easy.

As you probably know, one 1x3 portion of the 4x4 transform contains the XYZ translation vector (aka position).

Likewise, one 3x3 portion of the matrix contains the rotation (and scale or shear at the same time, but I'll ignore that here).

And the great thing about transformation matrices, is that this 3x3 rotation sub-matrix itself consists of three normalized vectors.
Turns out, the first column is the vector pointing to the right (positive X axis). The column to the right of that is the 'up vector' (positive Y). The column next to that, is the vector pointing rearward or forward depending on your camera orientation convention (positive Z axis).



// OpenGL matrix convention for typical GL software
// with positive Y=up and positive Z=rearward direction
RT = right
UP = up
BK = back
POS = position/translation
US = uniform scale

float transform[16];

[0] [4] [8 ] [12]
[1] [5] [9 ] [13]
[2] [6] [10] [14]
[3] [7] [11] [15]

[RT.x] [UP.x] [BK.x] [POS.x]
[RT.y] [UP.y] [BK.y] [POS.y]
[RT.z] [UP.z] [BK.z] [POS.Z]
[ ] [ ] [ ] [US ]

So in other words, you can fish your camera direction vector (and up vector, you may need it too) out of the transformation matrix, and plug it straight into gluLookAt (or whatever you use to setup the projection).

If I understood you right, you are constructing the transformation matrix from quaternions? You can then also simply rotate the 'up' and 'back' vector of the untransformed camera by the quaternion rotation. It should be computationally cheaper, although, as I noted above, once constructed, a 4x4 transformation matrix can hold lots of readily available useful information for many purposes. So depending on your needs, a matrix may be more handy.

deshan
09-01-2011, 01:31 AM
remdul, tank you so much for awesome explanation. :)

I tried as you have explained. Here I have small question.
In my case it seems to be has problems in the matrix.

Here I have tried to move my camera to the direction which it face as following


RT = right
UP = up
BK = back
POS = position/translation

Vector3 newPosition(
POS.x + BK.x,
POS.y + BK.y,
POS.z + BK.z);
camera->setPosition(newPosition);

But it didn't worked as expected. So I change it as following.
And it did work.

Vector3 newPosition(
POS.x + RT.z,
POS.y + UP.z,
POS.z + BK.z);
camera->setPosition(newPosition);


Honestly I do not know why. Perhaps it may be a problem in my code of quaternian to matrix44 calculation



class Quaternion
{
public:

float m_w;
float m_z;
float m_y;
float m_x;

Matrix44 Quaternion::make44Matrix()
{
Matrix44 out; // Matrix44 class has a float array with 16 elements

// First column
out.matrix[ 0] = 1.0f - 2.0f * ( m_y * m_y + m_z * m_z );
out.matrix[ 1] = 2.0f * (m_x * m_y + m_z * m_w);
out.matrix[ 2] = 2.0f * (m_x * m_z - m_y * m_w);
out.matrix[ 3] = 0.0f;

// Second column
out.matrix[ 4] = 2.0f * ( m_x * m_y - m_z * m_w );
out.matrix[ 5] = 1.0f - 2.0f * ( m_x * m_x + m_z * m_z );
out.matrix[ 6] = 2.0f * (m_z * m_y + m_x * m_w );
out.matrix[ 7] = 0.0f;

// Third column
out.matrix[ 8] = 2.0f * ( m_x * m_z + m_y * m_w );
out.matrix[ 9] = 2.0f * ( m_y * m_z - m_x * m_w );
out.matrix[10] = 1.0f - 2.0f * ( m_x * m_x + m_y * m_y );
out.matrix[11] = 0.0f;

// Fourth column
out.matrix[12] = 0;
out.matrix[13] = 0;
out.matrix[14] = 0;
out.matrix[15] = 1.0f;

return out;
}
}

again thank you very much!