Free Mouse movement, space-sim like.

Hey, I’m working on a small engine that will require free mouse movement for the camera, like that found in a space sim. Right now, I’ve got my camera moving somewhat like in shooting games like quake, etc… I’ve found lots of tutorials on mouse controlled cameras, but most of them describe FPS cameras, which I’ve already got. I can’t seem to find anything about space-sim like movement. Anyone here have any good links to check out, or tips or suggestions? thanks.

What is a “space sim camera” ? Perhaps you want to
have a quaternion for the orientation representation
of the camera, and integrate the quaternion from pitch,
roll, and yaw rates, where the rates are given as
functions of the mouse potion. Will this work for you?

From the four quaternion components you can go to
direction cosines, which are the components of an
orthogonal transformation (a 3x3 rotation matrix).
If you make the transpose of this matrix the upper
left minor of the homogeneous coordinates column-major
that OpenGL uses, you can simply glMultMatrix();
that 4x4 at each frame before rendering the scene.
It is easy, if that is what you want. With the exception
of introducing the quaternion, its intergrator, and
the routines to go through the steps I mentioned,
it should, otherwise, be a small modification to
your existing FPS camera.

the “Space Sim” camera, I’ll try to explain. Moving the mouse forwards should cause the view to tilt forwards (pitch). always. even if you flip upside down. backwards tilts the mouse the other way. Moving the mouse sideways always causes the camera view to rotate sideways, yaw. The current problem I have is that yaw is done around the y-axis, even if the pitch is 90 degrees. the result is that if the player were to look straight down at the ground, then move the mouse sideways, the ground would spin below them, rather than panning sideways.
The trick, I think to fixing it is to not rotate around the y-axis, but to rotate around a vector that has had the pitch transformation applied to it. I thought it was a good idea but it doesn’t seem to be working too smoothly, and I was wondering if anyone else had heard of something like this, or knew of a solution.

iznogoud: I sort of get your solution, and I think I saw a tutorial that did something similar to what I want with quaternions. Then I heard it was possible to do it without quaternions and thought it would be a challenge to actually try to implement it. I’ll look into what you suggest in more detail, as it sounds a bit different.

hmm alright I just re-re-read what I wrote and realize that what I’m saying is not as clear as it could be. let me try again:
first, the mouse causes backwards tilts, not the other way around.
second, for tilting the camera up and down, it is a simple rotation around the x-axis. the camera is initially created looking along the z-axis, and then whenever the camera is panned left or right, that transformation gets applied before the tilt transformation. so the tilt gets applied first, to an identity matrix, then the pan gets applied to the titled system. I think that is why the tilt always works nicely, but the pan doesn’t. I’m stuck at what transformation has to be applied before the tilt.
If this is not making sense, let me know I’ll try again. :wink:

I realized what was going wrong from the first posting.

You are running into Gimbal Lock problems (spinning
ground, etc.). You will avoid all of these problems
if you use a quaternion. This is equivalent to a flight
simulator, where the quaternion stores the orientation
of your plane. You are sitting inside the plane, and
consequently, the plane is your camera… Google
quaternion and its integration. For your information,
the integrator is a 4x4 matrix, which depends on the
quaternion components and the three rates (pitch,
roll, yaw). You integrate the quaternion in the
same way that you integrate ODEs, and then you must
normalize it (read about them and you will know what
I mean).

The rates (angular velocities) can be functions of
the motion of the mouse. Oh, and you will need one
more axis of some sort to perform yaw rotations.

Once you have the four quaternion components at each
frame, you revert to direction cosines for purposes
of OpenGL rendering – re-read what I wrote above.

This is easy, and if you are having trouble, drop
me a private message and I will come up with some
info for you, but it is nothing you cannot find with
Google.

Alright I’ve done more looking at gimbal lock and quaternions, and so far, I’m not too lost (why don’t they teach this stuff in school? :wink: ).
From what I can understand, the most popular for using quaternions for camera rotation is to create 3 quaternions based on the rotation around the x,y,z axes; multiply these quaternions together to get the final quaternion, then use this for the camera rotation. …I think. The only part that throws me off is that this technique seems to assume that I already know roll, pitch and yaw. But because I’m using the mouse, I can only get pitch and yaw, so I’m not sure how I can get roll. :confused:
I couldn’t find much that was good at explaining quaternion integration or how it’s helpful; all the game dev related sites don’t even mention it.
I’m not sure what you mean by ODE.
I’ll be working at this again a bit tomorrow probably, maybe I’ll think of something…

Three quaternions is wrong – that causes Gimball lock again.

You should keep ONE quaternion, or one matrix, representing the camera rotation. When the user pushes the yoke forward, you extract the “right” vector from that quaternion or matrix, and apply a rotation around that vector by some negative degree. When the yoke is pulled back, you rotate some positive degree, again around the “right” vector of the quat/matrix. Same thing for turning: extract the “up” vector and rotate around that.

You rotate by just composing the transformations, back into the main transformation. That way, the matrix or quaternion always represents your current orientation in space.

Note that successive transformations of normalized matrices or quaternions will de-normalize them, so you should make sure you re-orthonormalize the matrix every so often (say, once a frame), and/or re-normalize the quaternion (again, once a frame).

First of all, here is a “brutal” site with most things
you will (or will not) need to know about quaternions:
http://www2.gsu.edu/~oprdeb/qtrn/

Jwatte re-itterated, in some sense, what I was saying.

Here is what you do in a cookbook-type way:

 
GLdouble q[4],qm[4][4],pitch_r,roll_r,yaw_r;
...
init_orientation(q);

/* main loop */
while(I_am_not_done) {
   trap_mouse_and_keyboard_events(&pitch_r,&roll_r,&yaw_r);
   integrate_quaternion(q,pitch_r,roll_r,yaw_r);
   get_direction_cosines_from_quaternion(q, qm);

   set_action_gl_state();
   glMatrixMode(GL_MODELVIEW);
   glMultMatrixd(qm);
   render_objects();
   swap_buffers();
}

 

The matrix qm[][] is a column_major 4x4 matrix,
which means that the first three columns hold the
three vectors that form your orientation basis.

The function that integrates the quaternion also
normalizes it… it also alters the quaternion,
so make sure it is passed in as a pointer (what I
wrote above should work for both q an qm).

The trickiest thing is how you setup the function
that traps mouse movements and makes them into changes
in the pitch, roll, and yaw rates… use your
imagination…

I hope this helps.

I’ve spent a couple days looking stuff up.
iznogoud: yeah that site was “brutal”! I think you assumed too much about my math background. I could probably get all this if I had the time to study it in detail, but I don’t. I need a working demo in a couple months and this camera is just the begining. I also have all my regular courses to go through. I’ll have to check back at that site later when I have more time, or maybe find a good book…
I found another site that explained things a little more gentler, although maybe not as rigorously: http://www.gamedev.net/reference/articles/article1095.asp
The sample code and technique was pretty clear. I understand most of it.
“The trickiest thing is how you setup the function
that traps mouse movements and makes them into changes
in the pitch, roll, and yaw rates”
actually, I found this to be one of the easiest parts. I guess everyone has different ideas of “tricky” :wink: