Camera 3rd Person (similar to Tomb Raider) with using quaternions
I am working on a 3d game, similar to game Tomb Raider. But i got problems with my camera math. In the game Tomb Raider for camera use a quaternions for smooth camera movement, and really using quaternions very effectively. I have studied quaternion mathematic, but has not found him uses for the camera. In this my main problem. I use Direct3D 8.0 Api. All mathematic functions quaternions are included in this api. Ad notam camera 1st person with quaternios - no problem for me. I read a article "Rotating Objects Using Quaternions" on the Gamasutra.com, but answer has not found. Also i read more articles about cameras and quaternios on the FlipCode.com and GameDev.net, and nothing has found. Was on a forum. I think this problem have a more gamemakers with using 3rd person camera view. Is grateful for any information and ideas about 3rd camera person view with using quaternions! Beforehand thanks!
slerp
------------------General Equation, this is Private Function reporting for duty, sir!a2k
October 26, 2002 02:38 AM
quote:
Original post by a2k
slerp
Slerp - It not the answer to my question! Be attentive, a2k!
Slerp - It not the answer to my question! Be attentive, a2k!
[edited by - John Golubev on October 26, 2002 3:39:53 AM]
[edited by - John Golubev on October 26, 2002 3:39:53 AM]
Why not?
Slerp = interpolating one quat rotation to another
Does not matter if this is for cameras or whatever.
Slerp = interpolating one quat rotation to another
Does not matter if this is for cameras or whatever.
What for to me Slerp? The Slerp is used for smooth interpolation between two quaternios or more. For me main, to rotate camera around of the point (player) with use quaternios. Interpolating quaternions - this second matter. For me, no problem making camera 1st person view. I do it so:
-----------------------------------------------------------------
g_vecVelocity = g_vecVelocity * 0.9f + vecT * 0.1f;
g_vecAngularVelocity = g_vecAngularVelocity * 0.9f + vecR * 0.1f;
D3DXMATRIX matT, matR;
D3DXQUATERNION qR;
vecT = g_vecVelocity * FrameTimer->GetSecsPerFrame() * g_fSpeed;
vecR = g_vecAngularVelocity * FrameTimer->GetSecsPerFrame() * g_fAngularSpeed;
D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
D3DXMatrixMultiply(&g_matPosition, &matT,&g_matPosition);
D3DXQuaternionRotationAxis(&qR,&D3DXVECTOR3(0,1,0),vecR.y);
D3DXMatrixRotationQuaternion(&matR, &qR);
D3DXMatrixMultiply(&g_matPosition, &matR,&g_matPosition);
D3DXMatrixInverse(&g_matView, NULL, &g_matPosition);
D3DDevice->SetTransform(D3DTS_VIEW,&g_matView);
-----------------------------------------------------------------
One idea to rotate this camera around given point(the player) to add function:
-------------------------------------------------------
D3DXVECTOR3 vec;
vec.x=100*cosf(vecR.y)-100*sinf(vecR.y);
vec.z=100*cosf(vecR.y)+100*sinf(vecR.y);
vec.y=0;
-------------------------------------------------------
To combine of a two vectors "vec" with vector vecT (in the up code), i.e. vecT = vecT + vec. But, why that is impossible. The camera instantly departs.
[edited by - John Golubev on October 28, 2002 5:55:22 AM]
-----------------------------------------------------------------
g_vecVelocity = g_vecVelocity * 0.9f + vecT * 0.1f;
g_vecAngularVelocity = g_vecAngularVelocity * 0.9f + vecR * 0.1f;
D3DXMATRIX matT, matR;
D3DXQUATERNION qR;
vecT = g_vecVelocity * FrameTimer->GetSecsPerFrame() * g_fSpeed;
vecR = g_vecAngularVelocity * FrameTimer->GetSecsPerFrame() * g_fAngularSpeed;
D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
D3DXMatrixMultiply(&g_matPosition, &matT,&g_matPosition);
D3DXQuaternionRotationAxis(&qR,&D3DXVECTOR3(0,1,0),vecR.y);
D3DXMatrixRotationQuaternion(&matR, &qR);
D3DXMatrixMultiply(&g_matPosition, &matR,&g_matPosition);
D3DXMatrixInverse(&g_matView, NULL, &g_matPosition);
D3DDevice->SetTransform(D3DTS_VIEW,&g_matView);
-----------------------------------------------------------------
One idea to rotate this camera around given point(the player) to add function:
-------------------------------------------------------
D3DXVECTOR3 vec;
vec.x=100*cosf(vecR.y)-100*sinf(vecR.y);
vec.z=100*cosf(vecR.y)+100*sinf(vecR.y);
vec.y=0;
-------------------------------------------------------
To combine of a two vectors "vec" with vector vecT (in the up code), i.e. vecT = vecT + vec. But, why that is impossible. The camera instantly departs.
[edited by - John Golubev on October 28, 2002 5:55:22 AM]
quote:
What for to me Slerp?
Between two camera rotations.
Unlike a 4x4 matrix, a quaternion cannot store translation or
scale information, only rotation information.
Imagine that your camera exists in its own local coordinate system,
centered at (0,0,0). If you store a previous and a current rotation
for your camera, you can slerp between these two rotations.
I repeat, what for to me Slerp? I don''t need yet in smooth camera movements, while. For me main to rotate the camera around of the main hero.
Looking at your code, I don't think you're using quaternions to any real effect. The power of quaternions is the ability to interpolate between any two arbitrary rotations, not rotations around a fixed axis. To do that, it's easier to just interpolate the angle you're rotating.
I think what you need to do to free your camera is to change your variables to:
- height above player (given as an angle theta)
- angle around player (given as an angle alpha)
- distance from player
You start the camera off at a fixed point, say (0,0,1) -- this is all relative to the player.
The quaternions you are interpolating are both constructed the same way:
1) Rotate camera up from z-axis to the specified height
Result: (0,sin[theta],cos[theta])
2) Rotate camera around the y-axis
Result: (cos[theta]sin[alpha],sin[theta],cos[theta]cos[alpha])
This rotation will not interpolate well with alpha and theta, so you interpolate (SLERP) the associated quaternions instead.
After you apply the interpolated quaternion, you scale the camera position by its distance from the player. This gives you a matrix that you can use to position the camera relative to the player.
Note: Calculating a quaternion and then using it as a rotation every frame is much slower than just calculating the rotation matrix. You only calculate the initial and final quaternions, and interpolate/multiply each frame.
I hope at least some of this helps -- I'm still getting the hang of quaternions myself so this might not be totally accurate.
Tom
[edited by - ParadigmShift on October 29, 2002 2:37:25 AM]
I think what you need to do to free your camera is to change your variables to:
- height above player (given as an angle theta)
- angle around player (given as an angle alpha)
- distance from player
You start the camera off at a fixed point, say (0,0,1) -- this is all relative to the player.
The quaternions you are interpolating are both constructed the same way:
1) Rotate camera up from z-axis to the specified height
Result: (0,sin[theta],cos[theta])
2) Rotate camera around the y-axis
Result: (cos[theta]sin[alpha],sin[theta],cos[theta]cos[alpha])
This rotation will not interpolate well with alpha and theta, so you interpolate (SLERP) the associated quaternions instead.
After you apply the interpolated quaternion, you scale the camera position by its distance from the player. This gives you a matrix that you can use to position the camera relative to the player.
Note: Calculating a quaternion and then using it as a rotation every frame is much slower than just calculating the rotation matrix. You only calculate the initial and final quaternions, and interpolate/multiply each frame.
I hope at least some of this helps -- I'm still getting the hang of quaternions myself so this might not be totally accurate.
Tom
[edited by - ParadigmShift on October 29, 2002 2:37:25 AM]
"E-mail is for geeks and pedophiles." -Cruel Intentions
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement