I have a camera class that contains a 4x4 view matrix as a member variable. Most of my camera controls work fine when doing them directly on the view matrix. In an attempt to unify all of my scene objects I want to do all of these transformations on the local matrix.
I plan on ultimately switching to a model with scale, position and rotation stored separately but that isn't the question at the moment.
Here my question again in a (hopefully more clear way):
I want to perform a turn table animation on a camera (rotation around an arbitrary point) I have working code for doing it directly on the view matrix. Also very important, the rotation must be around a set up axis (in my case +Y).
How can I achieve the same affect by transforming the local matrix directly?
Working turn table control directly on view matrix
// dX and dY are mouse deltas for the current frame
Vector3 position = viewMatrix.getPosition();
Vector3 forward = viewMatrix.getForward();
Vector3 right = viewMatrix.getRight();
// rotate around the focal point in front of us
Vector3 rotationPoint = position + forward * focalPoint;
Matrix4 rot;
rot.translate(rotationPoint);
rot.rotate(-dY, right);
rot.rotate(-dX, Vector3::Y_AXIS);
rot.translate(-rotationPoint);
viewMatrix = viewMatrix * rot;
Attempt to make it work on the local matrix:
// dX and dY are mouse deltas for the current frame
Vector3 position = localMatrix.getPosition();
Vector3 forward = localMatrix.getForward();
Vector3 right = localMatrix.getRight();
// rotate around the focal point in front of us
Vector3 rotationPoint = position + forward * focalPoint;
Matrix4 rot;
rot.translate(-rotationPoint);
rot.rotate(dX, Vector3::Y_AXIS);
rot.rotate(dY, right);
rot.translate(rotationPoint);
localMatrix = localMatrix * rot;
What happens: The animation is wonky, the pivot point seem to move while I rotate and the camera slowly drifts away.
Additional information:
Why do I need that? I want to be able to transform any scene object the same way. I might want to rotate a mesh around a point like I do the camera.
Is it easier to achieve what I want with a scale/position/rotation model? Even if it is I'm still interested on where I'm making a mistake here.
I will edit this post in the morning if there are any uncertain parts.
------------------------------------------------------
Edit:
I tried to rephrase my problem a bit I will leave the initial post for now, I hope I am more clear in this second attempt.
My Problem: I have working code for controlling a cameras view matrix and orbiting around a point in space.
Here is said code:
// get position and look at, look up and look right directions for the view matrix
Vector3 pos, la, lu, lr;
viewMatrix.lookAt(&pos, &la, &lu, &lr);
// rotate around point 5 units in front of us
Vector3 rotationPoint = pos+ la * 5;
Matrix4 rot;
rot.translate(rotationPoint);
rot.rotate(-dY, lr);
rot.rotate(-dX, Vector3(0,1,0));
rot.translate(-rotationPoint);
viewMatrix *= rot;
here is the code for the lookAt function used above: It will retrieve you the position and forward, right, up directions from a VIEW matrix.
void Matrix4::lookAt(Vector3* eye, Vector3* at, Vector3* up, Vector3* ri)
{
Matrix3 invRot(_m); // get the current view matrix
invRot.translation(0,0,0); // remove the translation
invRot.transpose(); // transpose it to get inverse rot.
eye->set(invRot.multVec(-translation())); // setMatrix eye
ri->set( _m[0], _m[4], _m[8]); // normalized look right vector
up->set( _m[1], _m[5], _m[9]); // normalized look up vector
at->set(-_m[2],-_m[6],-_m[10]); // normalized look at vector
}
Note: the matrices are column major.
The code above works, the camera orbits an object around the world Y axis perfeclty. What I want to do: I want this same behaviour, but on a cube or other mesh! So I obviously don't need to do it on the view matrix then, since the transformation of that cube uses a world matrix. Now I could of course use the above and just invert it, but that is kind of cheating.
Here is my attempt to make the above work on a world space matrix:
// get the position and the three axis directions for the world matrix
Vector3 pos, la, lu, lr;
pos = worldMatrix.translation();
la.set(-worldMatrix.m(8), -worldMatrix.m(9), -worldMatrix.m(10));
lr.set(worldMatrix.m(0), worldMatrix.m(1), worldMatrix.m(2));
lu.set(worldMatrix.m(4), worldMatrix.m(5), worldMatrix.m(6));
Vector3 rotationPoint = pos + la * 5;
Matrix4 rot;
rot.translate(-rotationPoint);
rot.rotate(dX, Vector3(0,1,0));
rot.rotate(dY, lr);
rot.translate(rotationPoint);
worldMatrix *= rot;
The matrix is still column major. The retrieved position, look at, look right and look up vectors are correct. But when I print out the rotationPoint it moves. So the question is as simple as: Why does the above world matrix code not rotate my cube around the Y and look right axis around 'rotationPoint'?