I am working on a Quaternion based camera class, and all has been well until now... Basically, I am using the mouse to control the camera's Yaw & Pitch. When i start the program, I am looking at a cube and I can Yaw & Pitch the camera correctly, but when i go 1 side to the left, look at the cube, and try to pitch the camera(mouse up & down) it seems like it is rolling. Then if i go to the back of the cube and pitch it, it is correct. As i go from front to side and pith the camera, it rolls more and pitches less until it is aligned with the side of the cube, and it does nothing but roll. Here is some code.
Camera.cpp
#include "Camera.hpp"
#include <math.h>
Camera::Camera()
{
FovY = 3.141592f * 0.5f;
AspectRatio = 0.0f;
ZNear = 0.1f;
ZFar = 100.0f;
Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
XAxis = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
YAxis = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
ZAxis = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
D3DXQuaternionIdentity(&Orientation);
D3DXMatrixIdentity(&View);
D3DXMatrixIdentity(&Projection);
SetView(Position, XAxis, YAxis, ZAxis);
SetProjection(FovY, AspectRatio, ZNear, ZFar);
};
void Camera::SetView(const D3DXVECTOR3& Position, const D3DXVECTOR3& XAxis, const D3DXVECTOR3& YAxis, const D3DXVECTOR3& ZAxis)
{
View(0, 0) = XAxis.x;
View(0, 1) = YAxis.x;
View(0, 2) = ZAxis.x;
View(0, 3) = 0;
View(1, 0) = XAxis.y;
View(1, 1) = YAxis.y;
View(1, 2) = ZAxis.y;
View(1, 3) = 0;
View(2, 0) = XAxis.z;
View(2, 1) = YAxis.z;
View(2, 2) = ZAxis.z;
View(2, 3) = 0;
View(3, 0) = -(D3DXVec3Dot(&XAxis, &Position));
View(3, 1) = -(D3DXVec3Dot(&YAxis, &Position));
View(3, 2) = -(D3DXVec3Dot(&ZAxis, &Position));
View(3, 3) = 1;
D3DXQuaternionRotationMatrix(&Orientation, &View);
this->Position = Position;
this->XAxis = XAxis;
this->YAxis = YAxis;
this->ZAxis = ZAxis;
};
void Camera::SetProjection(float FovY, float AspectRatio, float ZNear, float ZFar)
{
float YScale = 1.0f / tanf(FovY * 0.5f);
Projection(0, 0) = YScale / AspectRatio; // XScale
Projection(0, 1) = 0;
Projection(0, 2) = 0;
Projection(0, 3) = 0;
Projection(1, 0) = 0;
Projection(1, 1) = YScale;
Projection(1, 2) = 0;
Projection(1, 3) = 0;
Projection(2, 0) = 0;
Projection(2, 1) = 0;
Projection(2, 2) = ZFar / (ZFar - ZNear);
Projection(2, 3) = 1;
Projection(3, 0) = 0;
Projection(3, 1) = 0;
Projection(3, 2) = -ZNear * ZFar / (ZFar - ZNear);
Projection(3, 3) = 0;
};
void Camera::SetPosition(float x, float y, float z)
{
Position.x = x;
Position.y = y;
Position.z = z;
View(3,0) = -D3DXVec3Dot(&XAxis, &Position);
View(3,1) = -D3DXVec3Dot(&YAxis, &Position);
View(3,2) = -D3DXVec3Dot(&ZAxis, &Position);
};
void Camera::Move(float dx, float dy, float dz)
{
Position += XAxis * dx;
Position += YAxis * dy;
Position += ZAxis * dz;
View(3,0) = -D3DXVec3Dot(&XAxis, &Position);
View(3,1) = -D3DXVec3Dot(&YAxis, &Position);
View(3,2) = -D3DXVec3Dot(&ZAxis, &Position);
};
void Camera::SetOrientation(float Yaw, float Pitch, float Roll)
{
D3DXQuaternionRotationYawPitchRoll(&Orientation, Yaw, Pitch, Roll);
D3DXQuaternionNormalize(&Orientation, &Orientation);
D3DXMatrixRotationQuaternion(&View, &Orientation);
XAxis = D3DXVECTOR3(View(0,0), View(1,0), View(2,0));
YAxis = D3DXVECTOR3(View(0,1), View(1,1), View(2,1));
ZAxis = D3DXVECTOR3(View(0,2), View(1,2), View(2,2));
View(3,0) = -D3DXVec3Dot(&XAxis, &Position);
View(3,1) = -D3DXVec3Dot(&YAxis, &Position);
View(3,2) = -D3DXVec3Dot(&ZAxis, &Position);
};
void Camera::SetOrientation(const D3DXQUATERNION& Orientation)
{
this->Orientation = Orientation;
D3DXQuaternionNormalize(&this->Orientation, &this->Orientation);
D3DXMatrixRotationQuaternion(&View, &this->Orientation);
XAxis = D3DXVECTOR3(View(0,0), View(1,0), View(2,0));
YAxis = D3DXVECTOR3(View(0,1), View(1,1), View(2,1));
ZAxis = D3DXVECTOR3(View(0,2), View(1,2), View(2,2));
View(3,0) = -D3DXVec3Dot(&XAxis, &Position);
View(3,1) = -D3DXVec3Dot(&YAxis, &Position);
View(3,2) = -D3DXVec3Dot(&ZAxis, &Position);
};
Some stuff from Game.cpp
D3DXVECTOR3 Position(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 YAxis( 0.0f, 1.0f, 0.0f );
D3DXVECTOR3 XAxis(1.0f, 0.0f, 0.0f);
D3DXVECTOR3 ZAxis(0.0f, 0.0f, 1.0f);
int DeltaMouseX;
int DeltaMouseY;
Camera Cam;
float Yaw;
float Pitch;
...
D3DXMatrixIdentity( &g_World );
Cam.SetView(Position, XAxis, YAxis, ZAxis);
Cam.SetProjection(3.141592f * 0.5f, (float)width / (float)height, 0.1f, 100.0f);
...
Yaw -= (float)DeltaMouseX / 5.0f;
Pitch -= (float)DeltaMouseY / 5.0f;
if(Yaw > 360.0f)
Yaw -= 360.0f;
if(Yaw < 0.0f)
Yaw += 360.0f;
if(Pitch > 360.0f)
Pitch -= 360.0f;
if(Pitch < 0.0f)
Pitch += 360.0f;
Cam.SetOrientation(D3DXToRadian(Yaw), D3DXToRadian(Pitch), 0.0f);
DeltaMouseX = 0;
DeltaMouseY = 0;
SetCursorPos(0, 0);
if(Keystate[Key_A] == true)
{
Cam.Move(-0.005f, 0.0f, 0.0f);
}
if(Keystate[Key_W] == true)
{
Cam.Move(0.0f, 0.0f, 0.005f);
}
if(Keystate[Key_D] == true)
{
Cam.Move(0.005f, 0.0f, 0.0f);
}
if(Keystate[Key_S] == true)
{
Cam.Move(0.0f, 0.0f, -0.005f);
}
Someone plz help!!! This is pissing me off!!!
[Edited by - xXShadowAsasNXx on September 8, 2009 9:51:21 PM]