   Camera class problem
  I'm trying to create a simple camera class but I'm having some problems with the SetViewByMouse() function: I'm only calling functions for yaw and pitch but the camera rolls in a strange way and I can't figure it why. Here's the code:camera.h#include "CVector3D.h"#include "CMatrix.h"#include <math.h>namespace CAMERA{const unsigned int FPS_CAM = 0;const unsigned int TPS_CAM = 1;}  class CCamera{private:unsigned int CameraType;bool FlyMode; // Used only with FPS_CAMfloat CameraSensitivity;void RegenerateVectors();public:CVector3D eyePos;CVector3D xAxis;CVector3D yAxis;CVector3D zAxis;float AngleXZ;   float AngleYZ;int *mx, *my, *w, *h;CCamera():CameraSensitivity(0.1f){CameraType = CAMERA::FPS_CAM;FlyMode = false;eyePos = CVector3D(0.0f, 0.0f, 6.0f);xAxis = CVector3D(1.0f, 0.0f, 0.0f);yAxis = CVector3D(0.0f, 1.0f, 0.0f);zAxis = CVector3D(0.0f, 0.0f, 1.0f);};void Pitch(float angle);void Yaw(float angle);void Roll(float angle);void Look();void Set(int *_mx, int *_my, int *_w, int *_h);void SetFly(bool FlyMode);void SetCameraType(unsigned int CameraType);void Move(float Amount);  void Strafe(float Amount);void SetViewByMouse();void SetPosition(CVector3D Position);void SetViewPoint(CVector3D PointView);};camera.cpp#include "CCamera.h"#include <GL/glut.h>void CCamera::Set(int *_mx, int *_my, int *_w, int *_h){mx = _mx;my = _my;w  = _w;h  = _h;}void CCamera::Look(){CMatrix mat(xAxis.x, yAxis.x, zAxis.x, 0.0f,xAxis.y, yAxis.y, zAxis.y, 0.0f,xAxis.z, yAxis.z, zAxis.z, 0.0f,-Dot(eyePos,xAxis), -Dot(eyePos,yAxis),-Dot(eyePos,zAxis), 1.0f);glMultMatrixf(*mat);}  void CCamera::Move(float Amount){ if (CameraType == CAMERA::FPS_CAM){if ( FlyMode ){eyePos = eyePos + -zAxis * Amount;}else{eyePos.x = eyePos.x - zAxis.x * Amount;eyePos.z = eyePos.z - zAxis.z * Amount;}}else{// Camera type CAMERA::TPS_CAM --- Not implemented yet}}void CCamera::Strafe(float Amount){ eyePos += xAxis * Amount;}void CCamera::SetFly(bool FlyMode){this->FlyMode = FlyMode;}void CCamera::SetCameraType(unsigned int CameraType){this->CameraType = CameraType;}void CCamera::SetPosition(CVector3D Position){}void CCamera::SetViewPoint(CVector3D PointView){}void CCamera::Pitch(float angle){CMatrix mat;mat.Rotate(angle, xAxis, true);yAxis = yAxis.MatrixMultiply(mat);zAxis = zAxis.MatrixMultiply(mat);RegenerateVectors();}void CCamera::Yaw(float angle){CMatrix mat;mat.Rotate(angle, yAxis, true);xAxis = xAxis.MatrixMultiply(mat);zAxis = zAxis.MatrixMultiply(mat);RegenerateVectors();}void CCamera::Roll(float angle){CMatrix mat;mat.Rotate(angle, zAxis, true);xAxis = xAxis.MatrixMultiply(mat);yAxis = yAxis.MatrixMultiply(mat);RegenerateVectors();}void CCamera::RegenerateVectors(){zAxis.Normalize();yAxis = Cross(zAxis, xAxis);yAxis.Normalize();xAxis = Cross(yAxis, zAxis);xAxis.Normalize();}void CCamera::SetViewByMouse(){// Get current cursor positionint MiddleX = (*w) >> 1;int MiddleY = (*h) >> 1;// Now move it back to the middle of the screenif (MiddleX==(*mx) && MiddleY==(*my))return;glutWarpPointer(MiddleX, MiddleY);int X = (*mx) - MiddleX;int Y = (*my) - MiddleY;AngleXZ += X * CameraSensitivity;AngleYZ += Y * CameraSensitivity;Pitch(-Y * CameraSensitivity);Yaw(-X * CameraSensitivity);if (AngleYZ < -90.0f){Pitch(Y * CameraSensitivity);AngleYZ = -90.0f;} if (AngleYZ > 90.0f){Pitch(Y * CameraSensitivity);AngleYZ = 90.0f;}}
  It looks like you've implemented 6DOF rather than FPS-style motion (with 6DOF motion, accumulated yaw and pitch can lead to perceived roll). In other words, the camera is behaving as it should - you've just implemented something other than what you intended :)If you want typical FPS motion you'll most likely need to take a different approach (representing your object's orientation using spherical coordinates, for example, works very well for FPS motion).I can post some links if you need more info.   ;  How funny!Yes, do post some links please.   ;Quote:Yes, do post some links please.Link 1Link 2;  Thanks! The code helped but I can't seem to understand the mathematics behind it, more precisely why are the vectors m_forwardView and m_forwardMove are calculated as they are. Where should i go/What should I read to clarify this?m_forwardView = sp;m_forwardView[j] = cp * cy;m_forwardView[k] = cp * sy;m_forwardMove = 0.0f;m_forwardMove[j] = cy;m_forwardMove[k] = sy;;Quote:Original post by DeliveranceThanks! The code helped but I can't seem to understand the mathematics behind it, more precisely why are the vectors m_forwardView and m_forwardMove are calculated as they are. Where should i go/What should I read to clarify this?*** Source Snippet Removed ***Google 'spherical coordinates' (the code in question performs a spherical-to-Cartesian coordinate conversion).(Oh, and the 'forward move' vector is calculated separately from the 'forward view' vector because, at least in the context of FPS character motion, the forward movement vector is usually restricted to the ground plane while the forward view vector is free to pitch up and down.)   