Jump to content
  • Advertisement
Sign in to follow this  
xXShadowAsasNXx

Quaternion Problems.

This topic is 3379 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!