Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

OleKaiwalker

FPS Camera and quaternions

This topic is 5539 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

Advertisement
by learning on how to do it on your own

do you really expect someone to write your code?

look on gametutorials.com for quaternion tutorials

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You don''t need quaternions for a quake-like camera, just some simple rotation matrices. In fact I think the rotation part can be handled by just two calls to glRotate*().

Share this post


Link to post
Share on other sites
To get a camera to move in an fps-based way, this is how i do it:

1. update the camera every frame (but not the input.)

2. set a timer on the hWnd for input (eg 50 times per second (1000/50), make it so user can change how many times to poll the input.

OOOOOOOOOOOOOOOOOOORRRRRRRRRRRRRRRRRRRRR


1. In camera::move() function, make the amount moved by divided by the camera fps

Share this post


Link to post
Share on other sites
he''s asking for an explanation, not for code. and im rather sure he''s talking about a first person shooter cam not a frames per second cam.

im confused why you would want to mix matrix operations and quaternions. but for basic fps style without leaning to the side you simply rotate around the global up (always 0,1,0) and your local right (values 0,1,2 in your transformation matrix or 0,4,8 in your "view" matrix -if its already inverted-)

but the details depend on what you got so far

Share this post


Link to post
Share on other sites
I want to use quaternions to avoid gimbal lock...

I have a self-written code with camera rotation - but it rotation around a wrong point and it''s still very buggy.

My code ->

// The Camera Class

class CCamera {

public:

CCamera();

GLvoid RotateCamera(GLfloat X, GLfloat Y, GLfloat Z, GLfloat angle);
GLvoid CreateMatrix();

private:

CVector3 cPosition;
CQuaternion4 cRotation;

GLfloat cMatrix[16];

};

CCamera::CCamera(){

// Reset The Camera
memset(cMatrix,0,sizeof(cMatrix));

CVector3 vZero = CVector3(0.0f, 0.0f, -6.0f);
cPosition = vZero;

CQuaternion4 cQuaternion4 = CQuaternion4(0.0f, 0.0f, 0.0f, 1.0f);
cRotation = cQuaternion4;
}

GLvoid CCamera::RotateCamera(GLfloat x, GLfloat y, GLfloat z, GLfloat degree){

// Normalize The Vector Class
CVector3 cVector = CVector3(x, y, z);
cVector = NormalizeVector(cVector);

// Convert From Degress To Radians
GLfloat angle = GLfloat((degree / 180.0f) * 3.14);

// Calculate Sin Once For Optimization
GLfloat cSin = (GLfloat)sin(angle / 2.0f);

CQuaternion4 newRotation;

// Calculate The W Value By Cos
newRotation.w = (GLfloat)cos(angle / 2.0f);

// Calculate The Last Quaternions
newRotation.x = GLfloat(cVector.x * cSin);
newRotation.y = GLfloat(cVector.y * cSin);
newRotation.z = GLfloat(cVector.z * cSin);

// Multiply The New Quaternion With The Current
cRotation = cRotation * newRotation;

// Normalize The Result
cRotation = NormalizeQuaternion(cRotation);

}

GLvoid CCamera::CreateMatrix(){

CQuaternion4 cQuat = cRotation;

// First row
cMatrix[0] = 1.0f - 2.0f * (cQuat.y * cQuat.y + cQuat.z * cQuat.z);
cMatrix[1] = 2.0f * (cQuat.x * cQuat.y + cQuat.z * cQuat.w);
cMatrix[2] = 2.0f * (cQuat.x * cQuat.z - cQuat.y * cQuat.w);
cMatrix[3] = 0.0f;

// Second row
cMatrix[4] = 2.0f * (cQuat.x * cQuat.y - cQuat.z * cQuat.w);
cMatrix[5] = 1.0f - 2.0f * (cQuat.x * cQuat.x + cQuat.z * cQuat.z);
cMatrix[6] = 2.0f * (cQuat.z * cQuat.y + cQuat.x * cQuat.w);
cMatrix[7] = 0.0f;

// Third row
cMatrix[8] = 2.0f * (cQuat.x * cQuat.z + cQuat.y * cQuat.w);
cMatrix[9] = 2.0f * (cQuat.y * cQuat.z - cQuat.x * cQuat.w);
cMatrix[10] = 1.0f - 2.0f * (cQuat.x * cQuat.x + cQuat.y * cQuat.y);
cMatrix[11] = 0.0f;

// Fourth row
cMatrix[12] = cPosition.x;
cMatrix[13] = cPosition.y;
cMatrix[14] = cPosition.z;
cMatrix[15] = 1.0f;

glMultMatrixf(cMatrix);

}

As you can see I turn axis rotations into quaterions, but the Camera it turning around the wrong point.

Share this post


Link to post
Share on other sites
void CCamera::CameraMove()
{

if(g_DInput.KeyPressed(DIK_UP))
VectorMA(vieworigin,m_flFrametime*1000,forward,vieworigin);


if(g_DInput.KeyPressed(DIK_DOWN))
VectorMA(vieworigin,-m_flFrametime*1000,forward,vieworigin);

if(g_DInput.KeyPressed(DIK_RIGHT))
VectorMA(vieworigin,m_flFrametime*300,right,vieworigin);

if(g_DInput.KeyPressed(DIK_LEFT))
VectorMA(vieworigin,-m_flFrametime*300,right,vieworigin);
}

void CCamera::CameraRotate()
{
viewangles[PITCH]+=g_DInput.m_currstate.lY*0.12;
viewangles[YAW]-=g_DInput.m_currstate.lX*0.12;
viewangles[ROLL]=0;
AngleVectors(viewangles,forward,right,up);
VectorNormalize(forward);
VectorNormalize(right);
VectorNormalize(up);
}

void CRenderer::LeftHandedMatrix(vec3_t forward,vec3_t up,vec3_t eye)
{
static vec3_t f,s,u;
static float m[16];

VectorSubtract(forward,eye,f);
VectorNormalize(f);
VectorNormalize(up);
CrossProduct(f,up,s);
CrossProduct(s,f,u);

m[0]=s[0];
m[1]=u[0];
m[2]=-f[0];
m[3]=m[11]=m[12]=m[13]=m[14]=m[7]=0;

m[15]=1;
m[4]=s[1];
m[5]=u[1];
m[6]=-f[1];

m[8]=s[2];
m[9]=u[2];
m[10]=-f[2];

glMultMatrixf(m);
}

LeftHandedMatrix(g_Camera.forward,g_Camera.up,origin);
glTranslatef(-g_Camera.vieworigin[0],-g_Camera.vieworigin[1],-g_Camera.vieworigin[2]);



thats my quake like camera it works perfect for a quake like ego shooter

Share this post


Link to post
Share on other sites
Thx Basiror...

I think the problem with my own code is, that dispite of my z distance being set to -6.0f away from the origin 0 in my camera constructor - the camera still rotates around the origin (0,0,0).

At the vector point (0,0,0) is my cube placed, making it look like I''m rotating around it.

Anybody, who knows, how to make my camera rotate around the cPositions (0,0,-6.0f), instead of it original origin (0,0,0)???

Share this post


Link to post
Share on other sites
if your rotations arent in local space they will always be around the origin. the easiest way to avoid this is to set the position to the origin, rotate and then set the old position again.

Share this post


Link to post
Share on other sites
LeftHandedMatrix(g_Camera.forward,g_Camera.up,origin);


if you use my code then
origin is the world origin==0,0,0

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!