I have been searching for an answer for my question long time ago and still I am not getting the answer.
I know that the answer is posted somewhere on the web in many places and I do know that it could be simple however
I am like many other newbies confused simply because all the guys trying to answer the question present it ambiguously
In OpenGL I know that there is no camera and it is nothing but a concept, I know that moving the camera left is
the same as moving the world right using a simple translate command but when it comes to rotations nobody gives clear answers.
Sorry for the long introduction but here is my question:
I am writing a camera class that uses quaternions, I want the camera to spin around its local axis (Y)
however the camera instead is rotating around the Y of the world coordinate system, it is orbiting instead of spinning
there should be something simple I am missing but the model view duality is still not clear for me in case of rotation
help is appreciated.
What it comes down to is rather simple. You define a matrix which gives the “world coordinates with respect to the camera” and you need to rotate the camera. Lets take another look at the object matrix representation… An object matrix (lets call this O) is defined as the “object’s coordinate system with respect to the world”. When you want to rotate the object, you multiply in a rotation matrix (lets call it R).
The new object matrix = O x R
But to rotate the camera, you need to do things backwards in comparison. What you end up doing is actually backwards, because remember O x R != R x O in matrix math. So, to put it simply, the rotated camera problem you are trying to work out is…
new camera matrix = R x C
where the old camera matrix = C
I hope this helps
Quaternions are the right approach. I posted a code snippet in this forum for a guy with a similar question:
This is a good time to break your dependence on glRotate…
The orientation of your camera (or any object in your scene, for that matter) can be represented by 3 vectors. These 3 vectors are orthogonal, and represent your camera’s local axes.
Create 3 vectors for the camera in your program. Start them out set to (1,0,0) (0,1,0) (0,0,1). When you want to rotate your camera, you preform rotations on these vectors directly. You will need a function that can rotate a vector around another vector by a given angle (I will not go into the math for this, because you can easily find it on the web). This is the key to rotating around the camera’s local axes.
Once you have the vectors, it is simple to modify the modelview matrix according to your camera’s position and orientation. You simply take the 3 vectors I described above and put them into the 3x3 part of the matrix (optionally you can put the inverse of the camera’s position in the 4th row to translate at the same time). Use glLoadMatrix or glMultMatrix with the matrix you just created and you are good to go.
Hope this helps.
Although your reply is abstract and to be honest with u, it is really the most helpful one, I still did not implement that but I have read somehting similar. I think like u said the procedure is like:
- rotate the camera direction vector using the rotation quaternion
- convert the world coordinates to camera space
- then apply the view matrix
I am going to that, I hope that is gonna work
once things are good I’ll share it with
thanks so much
Here is a set of functions you need. This will give you a skeleton of how to do it. I leave it up to you to fill in the code for each function.
If you want to have an FPS style camera, it is possible to do it with a much simpler camera setup than this. Descent style cameras (remember that game?) require something more along the lines of what I am giving you here. In either case, this same system is useful for other objects in your scene besides your camera.
//Rotate the vector around the axis by the given angle
void RotateVector(Vector& vector, float angle, const Vector& axis);
//struct representing the camera
/*function to rotate the camera about its local axes. Rotate the camera’s vector’s around themselves. i.e. The x and z vectors get rotated around the y vector. The y and z vectors get rotated around the x vector… After doing this, use the cross product to make them orthogonal again. */
void RotateCamera(Camera & camera, float x, float y, float z);
/*put the 3 camera vectors into the 3x3 part of a matrix which is initialized to the indentity matrix.
identity matrix is
1 0 0| 0
0 1 0| 0
0 0 1| 0
0 0 1 1
the |'s show you where the 3x3 part is. load the three orientation vectors into there. After creating this matrix, load it with glLoadMatrix, or multiply the current modelview matrix by this matrix with glMultMatrix*/
void DoCameraTransform(const Camera& camera);
[This message has been edited by ioquan (edited 10-13-2003).]
Yep. Your gonna be doing some vector math.
There is your original Viewpoint Vector; you must choose a different vector to look at - this comes from reading the keyboard or mouse and deciding which way you are turning.
You can take three vectors: Your current camera location vector, the vector you want to look at (determines your viewing direction) and an up vector (tells us where up is and is actually your Y axis - if you draw a line from your position vector to the up vector you will get your Y axis) - plug these into:
gluLookAt(Position.x, Position.y, Position.z,
View.x, View.y, View.z,
Up.x, Up.y, Up.z);
This should allow you to modify your view properly.
After I typed all that, you tell him to use gluLookAt? …
I have still some minor work but I can say now I am able to Yaw, Pitch and Roll my camera successfully.
Note: (Yaw : Z or Camera Line of Site) (Pitch : Y or Camera Up vector) (Roll : X or Camera right vector)
now follow the steps below (assuming you have the needed quaternion math):
- Convert from Axis Angle to Quaternion where Axis = camera up vector since we are pitching , angle = pitch angle
- multiply this quaternion by the current camera’s orientation quaternion to add the effect
- use this quaternion to rotate camera’s look vector or line of sight
- since the look vector is changed, the right vector is changed as a result and keep in mind that the up is not changed so we need to find the new right vector which is simply (look X up) , normalize the result
- now u can use gluLookat or u can use glLoadMatrix using a WorldToCamera view matrix available at the end of this link
I am now going to do more tests, play with SLERP and try to fly the camera along spiral paths of that is possible
You can look at my camera tutorial.
This tutorial describe the descent, first person and spectate camera moving.