Skip to main content
gamedev.net
🔒 Locked

camera problems

Started by Infinite_Daremo Feb 24, 2009 at 8:21 AM 3 replies 850+ views
Original Post
Infinite_Daremo
Infinite_Daremo
Ok ive been raging over this code for a couple of days now.. and im starting to get sick of it. So here i go asking for help. ive got a camera class which takes in a position matrix and then does the following to it before senting it to my graphics component.


void FpsCamera::drawCamera(Graphics *g)
{

    VTfloat const offset = 12.f;//given it a default offset...the user cannot chnage this

    m_CameraTarget = m_CameraPosition.matrix[3] + m_CameraPosition.matrix[2] * offset;

    VTVector4 m_Look =  VTVector4::normal( m_CameraTarget - m_CameraPosition.matrix[3] );

    VTVector4 m_Right =  VTVector4::normal( VTVector4::crossProduct(m_CameraPosition.matrix[1],m_Look));

    VTVector4 m_Up = VTVector4::crossProduct(m_Look,m_Right);

    m_CameraMatrix.matrix[0].x = m_Right.x; m_CameraMatrix.matrix[0].y = m_Up.x; m_CameraMatrix.matrix[0].z = m_Look.x;
    m_CameraMatrix.matrix[1].x = m_Right.y; m_CameraMatrix.matrix[1].y = m_Up.y; m_CameraMatrix.matrix[1].z = m_Look.y;
    m_CameraMatrix.matrix[2].x = m_Right.z; m_CameraMatrix.matrix[2].y = m_Up.z; m_CameraMatrix.matrix[2].z = m_Look.z;

    m_CameraMatrix.matrix[3].x = -VTVector4::dotProduct3( m_Right, m_CameraPosition.matrix[3]);
    m_CameraMatrix.matrix[3].y = -VTVector4::dotProduct3( m_Up, m_CameraPosition.matrix[3]);
    m_CameraMatrix.matrix[3].z = -VTVector4::dotProduct3( m_Look, m_CameraPosition.matrix[3]);

    g->updateViewMatrix(m_CameraMatrix);
    g->updateFOV(m_CurrentFOV);
}

that takes the matrix and creates a lookat matrix from it. to move the camera i use the follow peices of code.


//moving forwards

    if(input->checkForIdIsHeld(0))
    {
        ////move forwards
        m_Player.matrix[3] += m_Player.matrix[2] * (1.f / m_UpdateRate);
    }

//rotating the camera

    m_Player *= VTMatrix4x4::rotateAroundAxis(m_Player.matrix[0] ,input->getChangeInMouseY() * ( 1.0f / m_UpdateRate ) );

    m_Player *= VTMatrix4x4::rotateAroundAxis(m_Player.matrix[1] , input->getChangeInMouseX() * ( 1.0f / m_UpdateRate ) );

here is also the code for my rotate around a axis


VTMatrix4x4 VTMatrix4x4::rotateAroundAxis(VTVector4 axis, VTfloat angle)
{
    //#ifdef _SWFLOAT

//  #else
    //   VTfloat sine = (VTfloat)sin(angle);
    //   VTfloat cosine = (VTfloat)cos(angle);
//  #endif

       VTMatrix4x4 temp;

        VTfloat cosine( (VTfloat) cos(angle) );
        VTfloat sine( (VTfloat) sin(angle) );

   VTfloat t = 1.0f - cosine;

   temp.matrix[0].x = (t * axis.x * axis.x) + (cosine);
   temp.matrix[0].y = (t * axis.x * axis.y) - (axis.z * sine);
   temp.matrix[0].z = (t * axis.x * axis.z) + (axis.y * sine);

   temp.matrix[1].x = (t * axis.x * axis.y) + (axis.z * sine);
   temp.matrix[1].y = (t * axis.y * axis.y) + (cosine);
   temp.matrix[1].z = (t * axis.y * axis.z) - (axis.x * sine);

   temp.matrix[2].x = (t * axis.x * axis.z) - (axis.y * sine);
   temp.matrix[2].y = (t * axis.y * axis.z) + (axis.x * sine);
   temp.matrix[2].z = (t * axis.z * axis.z) + (cosine);

   return temp;

}

the code works fine...when only one rotation is used, in either x or y but when other are put together the camera goes mad.. see
If anyone could point me in the right direct i would be very happy
Zakwayda
Zakwayda
As far as I can tell, the camera is doing exactly what you've told it to do :) What you have there is 'free' incremental rotation (e.g. 6DOF), and that's exactly what happens when you have sequential incremental changes to pitch and yaw (that is, it can result in perceived roll).

If you want more of an FPS-style 'fixed-up' camera, then you'll want to take a simpler approach. Typically, you would use Euler angles; store your camera's orientation in yaw-pitch form, update these variables in response to user input, and then build the orientation matrix from scratch each frame using these variables.
sirGustav
sirGustav
While I use c# and quaternions instead of C++ and matrices, my fps camera is based around rotateAroundAxis and multiplications. Hope this helps...
quat rx = new quat(AxisAngle.RightHandAround(vec3.Up, angle.FromDegrees(-dx)));quat ry = new quat(AxisAngle.RightHandAround(rotation.Right, angle.FromDegrees(-dy)));rotation *= rx * ry;

As far as I can tell you seem to rotate around the matrix's up instead of the "global" up.

[Edited by - sirGustav on February 26, 2009 11:04:36 AM]
Zakwayda
Zakwayda
Quote:
Original post by sirGustav
While I use c# and quaternions instead of C++ and matrices, my fps camera is based around rotateAroundAxis and multiplications. Hope this helps...
quat rx = new quat(AxisAngle.RightHandAround(vec3.Up, angle.FromDegrees(-dx)));quat ry = new quat(AxisAngle.RightHandAround(rotation.Right, angle.FromDegrees(-dy)));rotation = rx * ry;

As far as I can tell you seem to rotate around the matrix's up instead of the "global" up.
Yup, this is the same as what I suggested - represent the camera orientation using two angles (e.g. pitch and yaw), and then build a transform from scratch each update using these angles.
sirGustav
sirGustav
actually I don't save the rotation between frames(apart from the quaternion). The code posted was a mash up between my fpsCameraRotation util function and forum/notepad coding-without compiling, hence it looked like I was recalculating the rotation every frame :)
Thanks for noticing that bug, I corrected the code now :)

That said, saving the angles and recalculating the matrix everyframe might be a good idea since it would be easier to limit the view.

Topic Locked

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

Sign in to reply to this topic.