Reputation: 21
Okay so this is a pretty specific question having to do with my camera transform in OpenGL. When the view opens the rotation point is around the origin - and when you translate the camera it does the translation first and then the rotation to keep the rotation point around the origin.
Well I want the rotation point to change from the origin to the hexagon tile you click without the camera position appearing to change. This seems very vague so I have included some pictures to illustrate.
I cant include pictures because my rep isnt high enough on here but here is a link to the photo on flickr
Right now when I click on a new tile to change the rotation point the camera moves to keep that tile at the center of the screen. I would post a link to show but again only enough rep for two links - so instead I will post a link to the picture of how I want the change of rotation point to happen (the camera doesn't move when the rotation point changes).
Okay now some code - here is the code for getting the camera transform matrix
NSMatrix4Df rotateTransform = NSMatrix4Df::getRotationMatrix(-orientation.x,-orientation.y,-orientation.z);
NSMatrix4Df rotationTranslationTransform = NSMatrix4Df::getTranslationMatrix(rotationPoint.x,rotationPoint.y,rotationPoint.z);
NSMatrix4Df cameraTranslateTransform = NSMatrix4Df::getTranslationMatrix(position.x,position.y,position.z);
return cameraTranslateTransform * rotateTransform * rotateTransform;
where orientation, position, and rotationPoint are all in world space. Here is the code for the actual matrix transformations.
NSMatrix4Df NSMatrix4Df::getRotationMatrix(float xAxisAng, float yAxisAng, float zAxisAng)
{
float xRad = DegreesToRadians(xAxisAng);
float yRad = DegreesToRadians(yAxisAng);
float zRad = DegreesToRadians(zAxisAng);
NSMatrix4Df xRotMat;
NSMatrix4Df yRotMat;
NSMatrix4Df zRotMat;
xRotMat.value(1,1) = cosf(xRad); xRotMat.value(1,2) = -sinf(xRad);
xRotMat.value(2,1) = sinf(xRad); xRotMat.value(2,2) = cosf(xRad);
yRotMat.value(0,0) = cosf(yRad); yRotMat.value(0,2) = -sinf(yRad);
yRotMat.value(2,0) = sinf(yRad); yRotMat.value(2,2) = cosf(yRad);
zRotMat.value(0,0) = cosf(zRad); zRotMat.value(0,1) = -sinf(zRad);
zRotMat.value(1,0) = sinf(zRad); zRotMat.value(1,1) = cosf(zRad);
return zRotMat * yRotMat * xRotMat;
}
NSMatrix4Df NSMatrix4Df::getTranslationMatrix(float xMove, float yMove, float zMove)
{
NSMatrix4Df identity;
// set the fourth column of the matrix to the translation amount
// the rest of the matrix is the identity matrix
identity.setColumn(NSVec4Df(xMove,yMove,zMove,1),3);
return identity;
}
The NSMatrix4Df creates a 2 dimensional array representing a 4x4 matrix ([4][4]) filled with the identity matrix. The code for that is here.
NSMatrix4Df::NSMatrix4Df():rows(MATDIM4D),
columns(MATDIM4D)
{
data[0][0] = 1; data[0][1] = 0; data[0][2] = 0; data[0][3] = 0;
data[1][0] = 0; data[1][1] = 1; data[1][2] = 0; data[1][3] = 0;
data[2][0] = 0; data[2][1] = 0; data[2][2] = 1; data[2][3] = 0;
data[3][0] = 0; data[3][1] = 0; data[3][2] = 0; data[3][3] = 1;
}
So basically my question is this - does anybody know how to translate the position of the camera after moving the rotation point so that it appears the camera stays in the same spot when the rotation point moves. I tried just adding a translation after the rotation point translation like so...
NSMatrix4Df rotateTransform = NSMatrix4Df::getRotationMatrix(-orientation.x,-orientation.y,-orientation.z);
NSMatrix4Df rotationTranslationTransform = NSMatrix4Df::getTranslationMatrix(rotationPoint.x,rotationPoint.y,rotationPoint.z);
NSMatrix4Df cameraTranslateTransform = NSMatrix4Df::getTranslationMatrix(**position.x - rotationPoint.x,position.y - rotationPoint.y,position.z - rotationPoint.z**);
return cameraTranslateTransform * rotateTransform * rotateTransform;
This works except for when the camera is rotated at all before changing the rotation point and I can't figure out why. In this case (when the camera is rotated prior to changing the rotation point) the camera will translate in a way that is effected by the amount of rotation. So for example if there is 45 degrees of rotation around the x axis it will cause the camera to transform an extra amount in the x direction. I can't figure out why.
I know to rotate the camera around a point other than origin you do translate * rotate * -translate which is what I have in the last case but the final translation isn't correct if the camera is rotated. I think there must be something wrong with my translation or rotation code but I don't know what.
I know this is a complicated question by if anyone has any insight I would appreciate the help. Thanks for your time.
Upvotes: 2
Views: 930
Reputation: 5068
You are running into a basic property of matrix multiplication. If you have real numbers 4*5 == 5*4. That's not true for matrices though.
I am a bit drunk writing this answer so I am probably going to get it wrong, because it's just the opposite of what feels natural: The right most transform happens first, the left one last.
An easy way for you to test this is to try your camera matrix left and right. One of them will do what you want :) It is usually very helpful to think of matrix multiplications on the right side as a transform to a different space. In 3D that is usually MODEL * CAMERA * PROJECTION. Now you want to change CAMERA. Either you want a transform before it or after it. Say you make you changes up by a matrix from mouse input INPUT. Then you can do INPUT * CAMERA or CAMERA * INPUT. In the first case your frame of reference is the world without the camera, in the second case it is the world as seen by the camera.
You are trying to do something similar with applying and undoing translation but that is not enough.
I hope this helps a bit. Feel free to follow up. But also read up on matrix math. It's a steep learning curve but well worth it and judging from your question you are very close :)
Upvotes: 1