Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera flip problem

Tags:

c#

xna

I'm programming a game in C# using the XNA3.1 engine. However I'm having a small issue with my camera, basically my camera tends to "flip" when it rotates more than 180 degrees on its roll (when the camera reaches 180 degrees, it seems to flip back to 0 degrees). The code for obtaining the view matrix is as follows:

Globals.g_GameProcessingInfo.camera.viewMat = Matrix.CreateLookAt(Globals.g_GameProcessingInfo.camera.target.pos, Globals.g_GameProcessingInfo.camera.LookAt, up);                //Calculate the view matrix

The Globals.g_GameProcessingInfo.camera.LookAt variable the position 1 unit directly in front of the camera, relative to the rotation of the camera, and the "up" variable is obtained with the following function:

static Vector3 GetUp()      //Get the up Vector of the camera
{
    Vector3 up = Vector3.Zero;
    Quaternion quat = Quaternion.Identity;
    Quaternion.CreateFromYawPitchRoll(Globals.g_GameProcessingInfo.camera.target.rot.Y, Globals.g_GameProcessingInfo.camera.target.rot.X, Globals.g_GameProcessingInfo.camera.target.rot.Z, out quat);

    up.X = 2 * quat.X * quat.Y - 2 * quat.W * quat.Z;       //Set the up x-value based on the orientation of the camera
    up.Y = 1 - 2 * quat.X * quat.Z - 2 * quat.Z * quat.Z;   //Set the up y-value based on the orientation of the camera
    up.Z = 2 * quat.Z * quat.Y + 2 * quat.W * quat.X;       //Set the up z-value based on the orientation of the camera
    return up;      //Return the up Vector3
}
like image 274
Ice Phoenix Avatar asked Nov 06 '22 17:11

Ice Phoenix


1 Answers

I got same problems in OpenGL with gluLookAt. I fixed that problem with my own camera class:

void Camera::ComputeVectors()
{
    Matrix4x4 rotX, rotZ;
    Quaternion q_x, q_y, q_z;
    Quaternion q_yx, q_yz;
    q_x.FromAngleAxis(radians.x, startAxisX);
    q_y.FromAngleAxis(radians.y, startAxisY);
    q_z.FromAngleAxis(radians.z, startAxisZ);
    q_yx = q_y * q_x;
    q_yx.ToMatrix(rotZ);
    q_yz = q_y * q_z;
    q_yz.ToMatrix(rotX);
    axisX = startAxisX;
    axisZ = startAxisZ; 
    axisX.Transform(rotX);
    axisZ.Transform(rotZ);
    axisY = axisX.Cross(axisZ);

    position = startPosition;
    position -= center;
    position.Transform(q_yx);
    position += center;
}

It is maybe overcomplicated, but working. axisY is your up vector. Full code listing is at: http://github.com/filipkunc/opengl-editor-cocoa/blob/master/PureCpp/MathCore/Camera.cpp

Hope it helps.

like image 180
Filip Kunc Avatar answered Nov 13 '22 00:11

Filip Kunc