Archived

This topic is now archived and is closed to further replies.

ogracian

Rotating camera around a target (3rd person camera)

Recommended Posts

Hello I am trying to code a 3D person camera but unfortunalty I am having some troubles I have used some methods to achieve this but no one works fine. Here is how I am doing but seems to suffer Gibal-Lock. static void RotateAroundPoint(const D3DXVECTOR3 & center, float fAngle, float x, float y, float z) { D3DXVECTOR3 newPos; D3DXVECTOR3 viewPos = CamPos - center; float cosTheta = cosf(fAngle * 0.1f); float sinTheta = sinf(fAngle * 0.1f); newPos.x = (cosTheta + (1 - cosTheta) * x * x)* viewPos.x; newPos.x += ((1 - cosTheta) * x * y - z * sinTheta) * viewPos.y; newPos.x += ((1 - cosTheta) * x * z + y * sinTheta)* viewPos.z; // // Find the new y position for the new rotated point newPos.y = ((1 - cosTheta) * x * y + z * sinTheta)* viewPos.x; newPos.y += (cosTheta + (1 - cosTheta) * y * y) * viewPos.y; newPos.y += ((1 - cosTheta) * y * z - x * sinTheta)* viewPos.z; // // Find the new z position for the new rotated point newPos.z = ((1 - cosTheta) * x * z - y * sinTheta)* viewPos.x; newPos.z += ((1 - cosTheta) * y * z + x * sinTheta)* viewPos.y; newPos.z += (cosTheta + (1 - cosTheta) * z * z)* viewPos.z; CamPos = center + newPos; } So to rotate around axis with mouse I use : RotateAroundPoint(target, mouse_pos.x*fFrameTime*5, 0, 1, 0); or RotateAroundPoint(BallPos, mouse_pos.x*fFrameTime*5, 1, 0, 0); then to update my viewmatrix I use: D3DXMATRIX m; D3DXMatrixLookAtLH(&m, &CamPos, &BallPos, &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); m_pDevice->SetTransform(D3DTS_VIEW, &m); But this method suffer Gimbal-Lock and the movements is kind of jerky, So I really appreciate so much if someone could help me with a better method using quaternions for a smooth movement. Thanks in advance, Oscar

Share this post


Link to post
Share on other sites
if youre using d3d, do you have the objects matrix? if so, simply create the rotation matrix multiply it with the objects matrix store the result in the camera matrix and translate it back. or store your camera matrix relative to the object. just translate back, apply all your rotations and before setting the view matrix multiply it with the objects matrix.

Share this post


Link to post
Share on other sites
Hi

Thanks for your replay, about your method, unofrtunatly I am not
storing the objects matrix, well not to rotate it, I am coding a pool game, so which I am implemeting is the camara rotating around the white ball (shoot aiming), so the camara should be looking at the ball all time (lookAt) while rotating around it (left-right, up-down), but the method that I am using seems to suffer Gimbal Lock and also the movement is kind of jerky.

Regards,
Oscar

Share this post


Link to post
Share on other sites
an orientation matrix is nothing more that 3 orthonormal axes.

example,

1 0 0 ->x
0 1 0 ->y
0 0 1 ->z

or
1 0 0
0 1 0
0 0 1
| | |
v v v
x y z

depending if the matrix is row or column major.

Anyway, you want to point from point P to point O, while keeping the camera pointing roughly up.

So, say you have 3 vectors X, Y, Z to define the orientation of the camera, and P the position of the camera. You want to point towards O, and the camera should stay roughly up.

therefore, Z = (O - P).UnitVector();
Y = (0, 1, 0)
X = (Y x Z).UnitVector();

However, you might find that the matrix is a bit skewed (X''s length will be < 1)

so What you can do then is

Y = (Z x X)

so, do

Z = (O - P).UnitVector();
Y = (0, 1, 0)
X = (Y x Z).UnitVector();
Y = (Z x X)

in that order.

Then all you have to do is load the vectors into the matrix (either on each rows or each columns).

this is the algorithm for gluLookAt(Eye, Target, Up), where Up can be anything you want, really (not just (0, 1, 0)).

You can use the angle of yours to rotate the Eye position around the ball, much simpler.

Share this post


Link to post
Share on other sites