Sign in to follow this  

Camera rotation problems

This topic is 2955 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 having problems trying to rotate my camera. I am storing the cameras position, look at, and up in three vectors (vectors are just structs that hold x,y,z). I am trying to do my rotation as such:
void Camera::Rotate(float angle)
{        
        Vector3f Tin = Vector3f(-m_pos.GetX(), -m_pos.GetY(), -m_pos.GetZ());

	float x = (Tin.GetX() * cos(-angle)) - (Tin.GetZ() * sin(-angle));
	float z = (Tin.GetX() * sin(-angle)) - (Tin.GetZ() * cos(-angle));

	Tin.SetX(x);
	Tin.SetZ(z);

	m_lookAt = Vector3f(-Tin.GetX(), -Tin.GetY(), -Tin.GetZ());
}

I am attempting to do this rotation by - PI/360.0f when the user presses the left arrow key or PI/360.f when they press the right arrow, however this works and starts to rotate and then it goes so far and everything dissapears. In my input handling i do
if(cApp->m_bKeys[VK_LEFT] == true)
{
	angle+= -3.14159265359f / 360.0f;

					
	cGLEngine->RotateCamera(angle);
	
}
if(cApp->m_bKeys[VK_RIGHT] == true)
{
	angle+= 3.14159265359f / 360.0f;
					
	cGLEngine->RotateCamera(angle);
}

Share this post


Link to post
Share on other sites
So instead of doing this all with vectors I switched to using a 4x4 matrix for doing my rotation. Now everything rotates but it goes maybe 90 degrees then starts going the opposite direction. Here is how the rotations are being done now

void Camera::Rotate(float angle)
{
//Vector3f fwd = m_lookAt - m_pos;

//Vector3f axis = fwd.CrossProduct(m_up);
//axis.Normalize();

Matrix4 Tin, Tout, Raxis, Mlook;

Tin.MakeTranslationmatrix(-m_pos.GetX(), -m_pos.GetY(), -m_pos.GetZ());
Tout.MakeTranslationmatrix(m_pos.GetX(), m_pos.GetY(), m_pos.GetZ());


Raxis.makeRotationMatrixY(angle);

Mlook = Tin * Raxis * Tout;

m_lookAt = Multiply(Mlook, m_lookAt);
}


The rotation matrix looks like this:

m_matrix[0][0] = cos(angle); m_matrix[0][1] = 0.0; m_matrix[0][2] = sin(angle); m_matrix[0][3] = 0.0;
m_matrix[1][0] = 0.0; m_matrix[1][1] = 1.0; m_matrix[1][2] = 0.0; m_matrix[1][3] = 0.0;
m_matrix[2][0] = -sin(angle); m_matrix[2][1] = 0.0; m_matrix[2][2] = cosA; m_matrix[2][3] = 0.0;
m_matrix[3][0] = 0.0; m_matrix[3][1] = 0.0; m_matrix[3][2] = 0.0; m_matrix[3][3] = 1.0;





forgot, the camera is set up through a call to gluLookAt


void Camera::Set() const
{
gluLookAt(m_pos.GetX(), m_pos.GetY(), m_pos.GetZ(), // eye position
m_lookAt.GetX(), m_lookAt.GetY(), m_lookAt.GetZ(), // center (look at)
m_up.GetX(), m_up.GetY(), m_up.GetZ()); // up
}



[Edited by - xDS4Lx on November 8, 2009 10:55:51 AM]

Share this post


Link to post
Share on other sites
So a little more..... i think that the rotation matrix is wrong, its about the Y axis, but i want to rotate around the cameras position. I want to rotate the cameras lookAt around its pos. In my dx code i have:

D3DXVECTOR3 fwd = look - pos;
D3DXVECTOR3 axis;

D3DXVec3Cross(&axis, &fwd, &up);
D3DXVec3Normalize(&axis, &axis);

D3DXMATRIX Tin, Tout, Raxis, Mlook;

D3DXMatrixTranslation(&Tin,-pos.x, -pos.y, -pos.z);

D3DXMatrixTranslation(&Tout, pos.x, pos.y, pos.z);

D3DXMatrixRotationAxis(&Raxis, &up, angle);

Mlook = Tin * Raxis * Tout;

D3DXVec3TransformCoord(&look, &look, &Mlook);
D3DXVec3TransformCoord(&up, &up, &Raxis);



So, how do i build the matrix Raxis?

Share this post


Link to post
Share on other sites
I haven't gone into the specifics of everything that you're doing, but make sure that you remember that opengl matrices are transposed versus what you would expect to see in DirectX. I see you've got what looks like the same code for OpenGL and DX, but you have to remember to do all of your matrix multiplication in reverse of what you do in directx.

I don't know if your problems go deeper than that, but if you have it working in directx than it shouldn't be any more difficult in opengl.

If you still can't figure it out I can maybe help, but please define what all your variables are, I don't know what you're trying to do with Tin, Tout, etc.

Share this post


Link to post
Share on other sites
This looks like you've started to experiment and overcomplicated things (especially Tin and Tout).

You already seem to store a matrix for the camera. The vectors in this matrix (and any objects matrix) are right/up/forward/position (of course depending on handedness and how you model your world).

Just multiply the rotation matrix to this matrix and for lookat you obviously need to use position+forward as lookat (or -forward).


void CameraGL::setView() {
glMatrixMode(GL_MODELVIEW);
gluLookAt(Transform[12], Transform[13], Transform[14],
Transform[12]+Transform[8], Transform[13]+Transform[9], Transform[14]+Transform[10],
Transform[4], Transform[5], Transform[6]);
}

//You should do this yourself in some matrix lib if you want to avoid stalling in case of previous commands still being in the pipeline

void CameraGL::rotate(float deg, float x, float y, float z) {
glPushMatrix();
glLoadMatrixf(Transform);
glRotatef(deg, x,y,z);
glGetFloatv(GL_MODELVIEW_MATRIX, Transform);
glPopMatrix();
}




Quote:

I see you've got what looks like the same code for OpenGL and DX, but you have to remember to do all of your matrix multiplication in reverse of what you do in directx.


Only if you don't want to explain the difference of local and global coordinates and how the order of matrix multiplication affects that. At the very least you should say "in reverse order if you prefer thinking in world space".

OpenGL applies transformations to the current matrix (and in object space) and the result is the same as
matrix = transform * matrix; in D3D

Matrix multiplication isn't a time to be clever and write
matrix *= transformation,
because now you apply the transformation in "world space", moving/rotating around the world axes (or rather, the object axes before the _other_ transformations in matrix are applied).

Share this post


Link to post
Share on other sites
Thanks, I was able to get the camera to rotate around all the way, now however it will jump around every once in a while. Here is what I changed the code to:


Matrix4 Tin, Tout, Raxis, Mlook;

Tin.MakeTranslationmatrix(-m_pos.GetX(), -m_pos.GetY(), -m_pos.GetZ());
Tout.MakeTranslationmatrix(m_pos.GetX(), m_pos.GetY(), m_pos.GetZ());

Raxis.makeRotationMatrixY(angle);


Mlook = Tin * Raxis * Tout;


Vector3f result = Multiply(m_lookAt - m_pos, Mlook);

m_lookAt.SetX(result.GetX());
m_lookAt.SetZ(result.GetZ());



To explain some, Tin and Tout are the translation in and translation out, Raxis is the rotation axis and Mlook is the look matrix after the calculations. The cameras initial positions are:

x = 0.0
y = 0.23
z = 1.0

upX = 0.0
upY = 1.0
upZ = 0.0

lookX = x (0.0)
lookY = y (0.23)
lookZ = x - 1 (0.0)

Share this post


Link to post
Share on other sites

This topic is 2955 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.

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