3
votes

So until recently I have been transforming my OpenGL objects like this (Rotation_Matrix is GLfloat[16], I get it from a quaternion that stores the object's orientation, works well):

glTranslatef(Position.x, Position.y, Position.z);
glMultMatrixf(Rotation_Matrix);

BUT I recently discovered that I can just do glMultMatrixf() if I do this first:

Rotation_Matrix[12] = Position.x;
Rotation_Matrix[13] = Position.y;
Rotation_Matrix[14] = Position.z;

This translates everything well, and I believe this is important for transitioning to OpenGL 3.0+ later? Because we have to have our own matrices, I think.

So I switched over to new system without glTranslatef(), and all works well except my camera. For camera I get Camera_Matrix from inverse of orientation quaternion, it used to work fine like this:

glMultMatrixf(Camera_Matrix);
glTranslatef(-CameraPos.x, -CameraPos.y, -CameraPos.z);

But if I set values 12, 13 and 14 to -CameraPos, the camera doesn't move right, sometimes going forward makes it go sideways and vice versa, and the more I move the more the movement is wrong.

How can I add translation to the camera's transformation matrix properly?

SOLUTION:

Instead of using normal position, you must calculate dot products as such (remember these are OpenGL matrices!):

GLfloat xDot = Position.x * m_RotationMatrix[0] +
               Position.y * m_RotationMatrix[4] +
               Position.z * m_RotationMatrix[8];

GLfloat yDot = Position.x * m_RotationMatrix[1] +
               Position.y * m_RotationMatrix[5] +
               Position.z * m_RotationMatrix[9];

GLfloat zDot = Position.x * m_RotationMatrix[2] +
               Position.y * m_RotationMatrix[6] +
               Position.z * m_RotationMatrix[10];

m_RotationMatrix[12] = -xDot;
m_RotationMatrix[13] = -yDot;
m_RotationMatrix[14] = -zDot;
2
Why don't you just use glm? :)Bartek Banachewicz

2 Answers

3
votes

The model transformation for the camera would be

M = T * R

Since the View transformation is the inverse, this is

V = R^-1 * T^-1

This implies that the overall rotation contains a rotated translation vector. You have to calculate it from the dot products:

translation.x = -dot(position, right vector)
translation.y = -dot(position, up vector)
translation.z = -dot(position, direction vector)

You can retrieve those vectors from the matrix. They are in the first three columns / rows.

0
votes

You're translating in world space, probably. You want to be translating in view/camera space. Make sure to read up in your favorite reference, or http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter04.html. Looking forward, it could be a good idea to not rely on opengl for matrix math (deprecated). Consider using glm.