Archived

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

Cuchulainn

Camera Question

Recommended Posts

Ok - this is gonna be hard to explain so bare with me. I am creating a 3d space flight sim. I have a pretty good outside camera but it has a problem - it seems to work the same way as ordinary flight simulators' outside cameras work. When you play an ordinary flight sim and you take off and you fly directly upwards - some flight simulators flip their camera as soon as you start to face toward the airport again - this is caused by the upvector of the camera being 0,1,0 - ie - directly up. Of course - this didnt look too bad - but in space - where there is no up or down - i dont want it to flip when its travelling upwards at 90degrees+. I tried setting the upvector to the vector perpendicular to the direction of my spaceship - ie its up vector (which can also point down if the space ship is facing toward you.) This didnt work as its different in space - theres no air - so if you thrust toward a planet, turned off engines, your velocity vector is still going toward the planet and then if you turn around your spaceship on the x axis - rotate backwards and forwards - when you are looking straight down the ships up vector, it flips - but when you fly directly up - it doesnt. Ok - yes this is very confusing - so i will show you the code that i have now - this is the ordinary flight sim code technique. cameraposition.x = objects[0].Position.x - (objects[0].velvecn.x * 15); cameraposition.y = objects[0].Position.y - (objects[0].velvecn.y * 15); cameraposition.z = objects[0].Position.z - (objects[0].velvecn.z * 15); cameralookat.x = cameraposition.x + objects cameraup = D3DXVECTOR(0,1,0); [0].velvec.x;//objects[0].Position.x + objects[0].velvec.x; cameralookat.y = cameraposition.y + objects[0].velvec.y;//objects[0].Position.y + objects[0].velvec.y; cameralookat.z = cameraposition.z + objects[0].velvec.z;//objects[0].Position.z + objects[0].velvec.z ; what i'm looking for is the value to set my upvector - i'll completely understand if you say u havent a clue in hell what i'm talking about - i'm not sure i know myself. If you prone to headaches - dont try to understand this. * Edit: Subject - Jim [edited by - Jim Adams on November 4, 2002 4:09:24 PM]

Share this post


Link to post
Share on other sites
Just a side note : You should've chosen a better post title

It seems that you're not using the appropriate rotation/coordinate system for a flight sim. Such a 3D roaming freedom suggests the usage of a Right-Up-Forward coordinate system for your camera ( referred to as RUF, from now on ).

Assume your craft/spaceship starts looking along the +ve direction of the Z axis == its forward is the Z axis ( 0, 0, 1 ), right is the x axis ( 1, 0, 0 ), and its up is the Y axis ( 0, 1, 0 ).

That's how to keep track of your directions :


  // Assuming you have yaw, pitch and roll in radians

// Yaw : Rotation right and left ( around the Up axis )

// Pitch : Rotation up and down ( around the Right axis )

// Roll : Rotation around the forward axis

// Here, I'll perform the rotations in the order : Yaw Pitch Roll

D3DXMatrixRotationAxis( &yawMatrix,&upVec,yaw );
D3DXVec3TransformCoord( &forwardVec,&forwardVec,&yawMatrix );
D3DXVec3TransformCoord( &rightVec,&rightVec,&yawMatrix );

D3DXMatrixRotationAxis( &pitchMatrix,&rightVec,pitch );
D3DXVec3TransformCoord( &forwardVec,&forwardVec,&pitchMatrix );
D3DXVec3TransformCoord( &upVec,&upVec,&pitchMatrix );

D3DXMatrixRotationAxis( &rollMatrix,&forwardVec,roll );
D3DXVec3TransformCoord( &upVec,&upVec,&rollMatrix );
D3DXVec3TransformCoord( &rightVec,&rightVec,&rollMatrix );

What this code does is create the rotation matrix responsible for yaw, and then rotates the forward and right vectors by this matrix. Why? The axis you rotate about - here : THe up axis - remains fixed, always ( as long as you're rotating around 1 axis at a time ), and the other 2 axes are changed.

The result of the code above is that you have your RUF vectors now pointing in the correct directions ( of the spaceship ).

If I don't make sense, then you need someone to explain this to you in more detail ( I don't have much time, unfortunately ).

There's a good article dealing with this subject, titled "Rotating the Camera without it screwing up" by Gary simons. Search for it in google.

If you fail to find it, tell me and I'll mail you the article.

[edited by - Coder on November 2, 2002 2:38:21 PM]

Share this post


Link to post
Share on other sites
Not sure if this will solve your exact problem, but this is my simple Camera class that uses Quaternions for orientation (rotation) to prevent that 90 pitch up gimbal lock that occurs when using relative matrix rotation.


  
CCamera::CCamera()
{
LookAt(D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f,0.0f,1.0f), D3DXVECTOR3(0.0f,1.0f,0.0f));
Update();
}

// Build new translation matrix

void CCamera::Move(D3DXVECTOR3 vNewPosition)
{
m_vPosition = vNewPosition;
m_bNeedsUpdate = TRUE;
}

void CCamera::MoveRel(D3DXVECTOR3 vDeltaPosition)
{
m_vPosition += vDeltaPosition;
m_bNeedsUpdate = TRUE;
}

void CCamera::Rotate(D3DXQUATERNION qNewOrientation)
{
m_qOrientation = qNewOrientation;
m_bNeedsUpdate = TRUE;
}

// Build new rotation quaternion

void CCamera::Rotate(D3DXVECTOR3 vNewRotation)
{
D3DXQuaternionRotationYawPitchRoll(&m_qOrientation,vNewRotation.y, vNewRotation.x, vNewRotation.z);
m_bNeedsUpdate = TRUE;
}

void CCamera::RotateRel(D3DXVECTOR3 vDeltaRotation)
{
// This will rotate about the camera''s current rotational position.

D3DXQUATERNION qTemp;
D3DXQuaternionRotationYawPitchRoll(&qTemp, vDeltaRotation.y, vDeltaRotation.x, vDeltaRotation.z);

// Now rotate current orientation by new rotation.

m_qOrientation *= qTemp;
m_bNeedsUpdate = TRUE;
}

// Move forward along current vector

void CCamera::MoveForward(float Dist)
{
D3DXMATRIX matTemp;
D3DXVECTOR3 vForward(0.0f,0.0f,-1.0f);

D3DXMatrixRotationQuaternion(&matTemp, &m_qOrientation);
D3DXMatrixTranspose(&matTemp, &matTemp);
D3DXVec3TransformCoord(&vForward, &vForward, &matTemp);

// update location

m_vPosition -= vForward * Dist;
m_bNeedsUpdate = TRUE;

}

void CCamera::LookAt(D3DXVECTOR3 vEye, D3DXVECTOR3 vAt, D3DXVECTOR3 vUp)
{
D3DXMATRIX matTemp;

// Set up rotation matrix

D3DXMatrixLookAtLH(&matTemp, &vEye, &vAt, &vUp);

m_vPosition = vEye;

// Get the orientation

D3DXQuaternionRotationMatrix(&m_qOrientation, &matTemp);

m_bNeedsUpdate = TRUE;
}

void CCamera::Update()
{
D3DXMATRIX matRotation;
D3DXMATRIX matTranslation;

// Set translation from position vectors (use opposite since this is camera)

D3DXMatrixTranslation(&matTranslation, -m_vPosition.x, -m_vPosition.y, -m_vPosition.z);

// Create a rotation matrix from orientation quaternion

D3DXMatrixRotationQuaternion(&matRotation, &m_qOrientation);

// Create the view matrix by rotating then translating

D3DXMatrixMultiply(&m_matView, &matTranslation, &matRotation);

m_bNeedsUpdate = FALSE;
}

D3DXMATRIX *CCamera::GetViewMatrix()
{
if(m_bNeedsUpdate == TRUE) Update();
return &m_matView;
}

Share this post


Link to post
Share on other sites