• 15
• 15
• 11
• 9
• 10

# 3D Quaternion Camera

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

## Recommended Posts

Can anyone here give me a link or book, much better, that teaches on how to create a fps camera on 3d space with no gimbal lock?? I hope that it also explain how did he get the formula on it. I got this camera RotateView Function from a md2 model but didn't understand how he derived that.

void RotateView(float angle, float x, float y, float z)
{
core::vector3df vNewView;

// Get the view vector (The direction we are facing)
core::vector3df vView = cView - cPosition;

// Calculate the sine and cosine of the angle once
float cosTheta = (float)cos(angle);
float sinTheta = (float)sin(angle);

// Find the new x position for the new rotated point
vNewView.x  = (cosTheta + (1 - cosTheta) * x * x)		* vView.x;
vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta)	* vView.y;
vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta)	* vView.z;

// Find the new y position for the new rotated point
vNewView.y  = ((1 - cosTheta) * x * y + z * sinTheta)	* vView.x;
vNewView.y += (cosTheta + (1 - cosTheta) * y * y)		* vView.y;
vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta)	* vView.z;

// Find the new z position for the new rotated point
vNewView.z  = ((1 - cosTheta) * x * z - y * sinTheta)	* vView.x;
vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta)	* vView.y;
vNewView.z += (cosTheta + (1 - cosTheta) * z * z)		* vView.z;

// Now we just add the newly rotated vector to our position to set
// our new rotated view of our camera.
cView = cPosition + vNewView;
}


Thanks John Stuart [Edited by - John Stuart on October 18, 2009 6:42:18 PM]

##### Share on other sites
There are so many articles about 3D cameras, I wouldn't know where to begin. Remember that most of them will be tailored to a specific graphics API, such as OpenGL.

The two methods that I've used for a 3D camera without using Euler angles (which suffer from Gimbal Lock) are Quaternions. In general I have a vector position of my camera and a Quaternion for it's orientation.

http://www.gamedev.net/reference/programming/features/quatcam/

##### Share on other sites
I have a question. Why did he use sin in x,y,z and cos in w? Is there any geometric explanation how he did that? He just states that here's the formula. http://www.gamedev.net/reference/programming/features/quatcam/page3.asp

##### Share on other sites
Glad I could help. I also thought that some of the stuff at GPWiki helped me understand some things, since the general Wiki article is rather math dense:

http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation

http://en.wikipedia.org/wiki/Quaternion

I didn't study the code you posted too closely, but from the looks it's basically building a rotation matrix.

http://en.wikipedia.org/wiki/Rotation_matrix

##### Share on other sites
Thanks nullmind for the help. Sorry for the late reply. I'm quite busy this past few days because of college stuffs.

I tried playing around with the first link you posted. I don't know what is happening but my screen is rotating so so so so fast.

The code is exactly the same with what was posted on the article page 3. Page 3

I checked:
1) formula for Cross Product
2) see if the frame is too high. so i enabled the vsnyc but no luck
3) put MouseSensitivity to 1,10,100,1000...
3) check the code line by line...
4) rewrite everything again... still no luck...

Can anyone here help me?

##### Share on other sites
The problem above is I forgot to put glLoadIdentity() before calling camera update... O.o

Now.. Here's my problem... The camera rotating weirdly.. Can anyone here check my codes? I don't know any person who can help me.

camera()	{		Position.set(0.0, 0.0, 0.0);		View.set(0.0, 1.0, 0.5);		Up.set(0.0, 0.0, 1.0);	}	void SetViewByMouse()	{	  POINT mousePosition;	  int MiddleX = 800/2;	  int MiddleY = 600/2;	  vector3d MouseDirection(0, 0, 0);	  static float CurrentRotationX = 0.0;	  GetCursorPos(&mousePosition);	  if((mousePosition.x == MiddleX) && (mousePosition.y == MiddleY))		return;	  SetCursorPos(MiddleX, MiddleY);	  MouseDirection.x = (float)(MiddleX - mousePosition.x)/100.0f; 	  MouseDirection.y = (float)(MiddleY - mousePosition.y)/100.0f;	  CurrentRotationX += MouseDirection.y;	  	  // We don't want to rotate up more than one radian, so we cap it.	  if(CurrentRotationX > 1)	  {		CurrentRotationX = 1;		return;	  }	  // We don't want to rotate down more than one radian, so we cap it.	  if(CurrentRotationX < -1)	  {		CurrentRotationX = -1;		return;	  }	  else	  {		// get the axis to rotate around the x-axis. 		vector3d Axis;		// To be able to use the quaternion conjugate, the axis to		// rotate around must be normalized.		Axis = Axis.Normalize( (View - Position).Cross(Up) );		// Rotate around the y axis		RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);		// Rotate around the x axis		RotateCamera(MouseDirection.x, 0, 1, 0);	  }	}	void RotateCamera(float angle, float x, float y, float z)	{		quaternion temp, quat_view, result;		temp.x = x * sin(angle/2);		temp.y = y * sin(angle/2);		temp.z = z * sin(angle/2);		temp.w = cos(angle/2);		quat_view.x = View.x;		quat_view.y = View.y;		quat_view.z = View.z;		quat_view.w = 0;		result = (temp*quat_view)*temp.Conjugate();		View.x = result.x;		View.y = result.y;		View.z = result.z;	}	void CameraLook()	{		gluLookAt(Position.x, Position.y, Position.z, View.x, View.y, View.z, Up.x, Up.y, Up.z);	}