Sign in to follow this  
xXShadowAsasNXx

Quaternion Problems.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
Could you edit your post and enclose the code in [source] tags? I'd be happy to look over the code, but it's a bit hard to read at the moment :)

Also, what type of motion are you after here? Are you looking for typical FPS-style camera/object control?

Share this post


Link to post
Share on other sites
Not sure if either of these will help, but I have had your problem and this is how I fixed it.

1. Try inverting your viewing matrix. I got this wrong and I had the same problem.

2. If you want more fundamental guides, try drawing a large axis-aligned wire-frame cube around yourself. As you move, it should NOT rotate. Also, perhaps draw a smaller axis-aligned cube centered directly ahead of you. Use absolute coordinates with an identity ((1,0,0),(0,1,0),(0,0,1)) model-view matrix.

I've never used a 3rd party lib for quaternions so I don't know the details of D3DX's version. I also haven't used D3D for 5+ years.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this