Skip to main content
GameDev.net gamedev.net
🔒 Locked

Rotation

Started by Lythic Sep 27, 2002 at 4:55 PM 3 replies 400+ views
Original Post
Lythic
Lythic
Can anyone here who has not done their good deed for the day, please explain to me how to rotate a camera view? In my mind, if player x presses the right arrow key down, the camera should swivel to the right. As I understand it, this means moving the lookAt point around... but on a circle-rim around the camera... I just have no idea how that''s done... please? Someone? Anyone?
Magriep
Magriep
Ok while searching this is what I found in my book for 3d rotation (which I'm not at yet ), don't know if this will help:
x-axis: y(new) = y(old) cos(theta)-z(old) sin(theta)
z(new) = y(old) sin(theta)+z(old) cos(theta)

y-axis: x(new) = x(old) cos(theta)-z(old) sin(theta)
z(new) = x(old) sin(theta)+z(old) cos(theta)

z-axis: x(new) = x(old) cos(theta)-y(old) sin(theta)
y(new) = x(old) sin(theta)+y(old) cos(theta)

Note: the "(new") is just to distinguish the old and new numbers, not to multiply them like theta. Theta is the angle by which you want to rotate.

So obviuosly you need to know trig in order to rotate things in 3d.

[edited by - Magriep on September 27, 2002 6:13:48 PM]
helix
helix
It's late and I'm too tired to go into much detail, so I'll just post some code for you to look at. This does (for me) all the standard FPS movement.

Run the following each frame (this is in my game's main update function.

    
// Rotate camera on arrows

float fRotSpeed = DEG_PS * DEG * FRAMERATE_S;
D3DXVECTOR3 v = m_pCamera->GetPos();
D3DXVECTOR3 u = m_pCamera->GetUp();
D3DXVECTOR3 d = m_pCamera->GetDir();

//

// Camera look

//

if( m_pSettings->bMouseInput ) // Mouse look

{
D3DXVECTOR3 vAxis;

// Left and right

D3DXMatrixRotationY( &mat, m_pMouse->XAxis() * fRotSpeed );
D3DXVec3TransformCoord( &d, &d, &mat );
D3DXVec3TransformCoord( &u, &u, &mat );

// Up / down

D3DXVec3Cross( &vAxis, &d, &u );
D3DXVec3Normalize( &vAxis, &vAxis );
D3DXMatrixRotationAxis( &mat, &vAxis, m_pMouse->YAxis() * -fRotSpeed );
D3DXVec3TransformCoord( &d, &d, &mat );
D3DXVec3TransformCoord( &u, &u, &mat );
}
else // Keyboard look

{
// Left and right

if( m_pKeyboard->KeyDown( DIK_LEFT, 0 ) )
{
D3DXMatrixRotationY( &mat, -fRotSpeed );
D3DXVec3TransformCoord( &d, &d, &mat );
D3DXVec3TransformCoord( &u, &u, &mat );
}
if( m_pKeyboard->KeyDown( DIK_RIGHT, 0 ) )
{
D3DXMatrixRotationY( &mat, fRotSpeed );
D3DXVec3TransformCoord( &d, &d, &mat );
D3DXVec3TransformCoord( &u, &u, &mat );
}

// Up and down

if( m_pKeyboard->KeyDown( DIK_UP, 0 ) )
{
// Rotate about the axis perpendicular to the line of sight and the up vector

D3DXVECTOR3 vAxis;
D3DXVec3Cross( &vAxis, &(m_pCamera->GetDir()), &(m_pCamera->GetUp()) );
D3DXVec3Normalize( &vAxis, &vAxis );

D3DXMatrixRotationAxis( &mat, &vAxis, -fRotSpeed );
D3DXVec3TransformCoord( &d, &d, &mat );
D3DXVec3TransformCoord( &u, &u, &mat );
}
if( m_pKeyboard->KeyDown( DIK_DOWN, 0 ) )
{
// Rotate about the axis perpendicular to the line of sight and the up vector

D3DXVECTOR3 vAxis;
D3DXVec3Cross( &vAxis, &(m_pCamera->GetDir()), &(m_pCamera->GetUp()) );
D3DXVec3Normalize( &vAxis, &vAxis );

D3DXMatrixRotationAxis( &mat, &vAxis, fRotSpeed );
D3DXVec3TransformCoord( &d, &d, &mat );
D3DXVec3TransformCoord( &u, &u, &mat );
}
}

//

// Move camera

//


// Move forward and back

if( m_pKeyboard->KeyDown( DIK_W, 0 ) )
{
D3DXVECTOR3 vec;

// Restrain camera to x/z movement only if flag is not set

if( !m_pSettings->bFreeMove )
{
vec = m_pCamera->GetDir() * MOVE_SPEED_FIXED;
vec.y = 0.0f; //NOTE: Not doing this will introduce gimbal lock where you lose a degree of freedom

}
else
vec = m_pCamera->GetDir() * MOVE_SPEED;

v += vec;
}
if( m_pKeyboard->KeyDown( DIK_S, 0 ) )
{
D3DXVECTOR3 vec;

// Restrain camera to x/z movement only if flag is not set

if( !m_pSettings->bFreeMove )
{
vec = m_pCamera->GetDir() * MOVE_SPEED_FIXED;
vec.y = 0.0f; //NOTE: Not doing this will introduce gimbal lock where you lose a degree of freedom

}
else
vec = m_pCamera->GetDir() * MOVE_SPEED;

v -= vec;
}

// Strafe left and right

if( m_pKeyboard->KeyDown( DIK_A, 0 ) )
{
// Rotate about the axis perpendicular to the line of sight and the up vector

D3DXVECTOR3 vec;
D3DXVECTOR3 vAxis;
D3DXVec3Cross( &vAxis, &(m_pCamera->GetDir()), &(m_pCamera->GetUp()) );

// Restrain camera to x/z movement only if flag is not set

if( m_pSettings->bFreeMove )
{
D3DXVec3Normalize( &vAxis, &vAxis );

vec = vAxis * MOVE_SPEED;
}
else
{
vAxis.y = 0.0f;
D3DXVec3Normalize( &vAxis, &vAxis );

vec = vAxis * MOVE_SPEED_FIXED;
}

v += vec;
}
if( m_pKeyboard->KeyDown( DIK_D, 0 ) )
{
// Rotate about the axis perpendicular to the line of sight and the up vector

D3DXVECTOR3 vec;
D3DXVECTOR3 vAxis;
D3DXVec3Cross( &vAxis, &(m_pCamera->GetDir()), &(m_pCamera->GetUp()) );

// Restrain camera to x/z movement only if flag is not set

if( m_pSettings->bFreeMove )
{
D3DXVec3Normalize( &vAxis, &vAxis );

vec = vAxis * MOVE_SPEED;
}
else
{
vAxis.y = 0.0f;
D3DXVec3Normalize( &vAxis, &vAxis );

vec = vAxis * MOVE_SPEED_FIXED;
}

v -= vec;
}

// Move up and down

if( m_pKeyboard->KeyDown( DIK_NUMPAD8, 0 ) )
{
D3DXVECTOR3 vec;
D3DXVec3Scale( &vec, &(m_pCamera->GetUp()), MOVE_SPEED );
D3DXVec3Add( &v, &v, &vec );
}
if( m_pKeyboard->KeyDown( DIK_NUMPAD2, 0 ) )
{
D3DXVECTOR3 vec;
D3DXVec3Scale( &vec, &(m_pCamera->GetUp()), MOVE_SPEED );
D3DXVec3Subtract( &v, &v, &vec );
}

m_pCamera->SetPos( &v );

D3DXVec3Normalize( &d, &d );
m_pCamera->SetDir( &d );

D3DXVec3Normalize( &u, &u );
m_pCamera->SetUp( &u );


The camera has a look-at vector, an up vector, a position, and a direction vector (amoung other things). The following code is from my camera's update function (run after the code given above each frame). Just set the resulting view matrix in your render call.

  
m_vAt = m_vPos + m_vDir;

//

// Set up our view matrix. A view matrix can be defined given an eye point,

// a point to look at, and a direction for which way is up.

//

D3DXMatrixLookAtLH( &m_matView, &m_vPos, &m_vAt, &m_vUp );


I hope that was some help.

[edited by - beoch on September 29, 2002 6:18:28 AM]
Prototype
Prototype
To make it easy you can control your camera with rotation and tilt properties, where rotation is the number of degrees the camera is rotated around the y-axis, and tilt is the number of degrees the camera is looking up or down.
Your LookVec would then be:

LookVec.x = sin(rad(rotation));
LookVec.y = sin(rad(tilt));
LookVec.z = cos(rad(rotation));

where rad(x) = PI * (x/180).
This kind of camera is easier to program than working with straight vectors.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.