Hello all,
Well, I’m new and this is my first post to these forums… I hope I’m not wearing out my welcome with the length and number of questions presented. I’ve tried to find answers to these questions elsewhere (books, tutorial/doc links from OpenGL.org, etc.) with no luck.
I’m having difficulty wrapping my brain around OpenGL’s rotations. What I want to do is to have a number of objects (any number) in my scene, each of which I can rotate with 3DOF relative to it’s own local coordinate system. Next, I’d like to be able to place the viewpoint within any one of these objects at any given time.
I did this in the past (years ago) with a 3D DOS engine which I derived from the engine developed in the book “The Black Art of 3D Programming”. If I remember correctly, the engine was based on matrices (with all of the matrix math coded into the engine), but most of the work I did to enhance it worked with vectors. I was able to get true 6DOF local coordinate control of my objects (that is, pressing my “yaw”, “roll” and “pitch” control keys would change the orientation of the object based on it’s current orientation, not world axes). I accomplished this using some functions that I got from a guy on CompuServe’s Game Developers Forum (back in the good ole days…). If I remember correctly, the program he gave me was called “yawpitch.exe”, and it used two functions… one was called, I think, alt_az_to_eq() and I seem to remember getting the impression that this function’s purpose was to convert from azimuth to equatorial coordinates… but I really never fully understood how the functions worked. What I did understand about the functions was that they used a lot of complex math, including many divides and a few square roots. Sorry for all the detail - I’m hoping it helps illustrate what I’m trying to do.
So, not initially worrying about camera angle, the first thing I did in my new OpenGL program (just to get things moving around on the screen) was basically this:
get_user_input(); // pitch, yaw, roll changes
total_pitch += pitch_change;
total_yaw += yaw_change;
total_roll += roll_change;
glLoadIdentity();
glRotatef(total_pitch, 1.0f, 0.0f, 0.0f);
glRotatef(total_yaw, 0.0f, 1.0f, 0.0f);
glRotatef(total_roll, 0.0f, 0.0f, 1.0f);
drawObject();
As you can imagine, this did not give me the local 3DOF rotations I was looking for (and I didn't expect it to). Putting off the task of digging up the "yawpitch" program and figuring out (again) how to implement it's functions, I just started fiddling around with what I had. So, I changed my program a bit, and to my complete astonishment, the local 3DOF control I was looking for materialized. I still don't exactly understand why it works and if someone could enlighten me, I'd appreciate it. Here's basically what I did in my loop:
get_user_input();
glLoadMatixf(object_matrix);
glRotatef(pitch_change, 1.0f, 0.0f, 0.0f);
glRotatef(yaw_change, 0.0f, 1.0f, 0.0f);
glRotatef(roll_change, 0.0f, 0.0f, 1.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, object_matrix);
drawObject();
I'm loading/saving the matrix because I have several objects, and I'd like to keep each object's matrix around so that I can (eventually) extract information from the "current state" matrix for any given object (more on that in a moment) -- is this a good idea for a real-time engine?
So, groovy, my object now works the way I'd like it to (like an airplane in a flight sim)... but how do I get my "camera" to work the same way? I tried implementing the same incremental transformations with a separate matrix called (creatively enough) "camera", and then loading up this matrix and multiplying it with object_matrix, but it didn't work... implementing the camera this way still gives me camera rotations relative to world axes.
It looks like I could use the gluLookAt() function that I hear so much about... but I'm somewhat reluctant to stray from the core OpenGL API (I'm not really sure why... I think it's got something to do with the "purity" of this little learning project of mine). Is there an easy way to apply my rotations (like the easy way I stumbled onto 3DOF for my object) that would allow the camera to move in the same way, without using gluLookAt() or implementing my own (with that alt_az_to_eq() function that I don't understand)?
If I could get the ijk vectors out of object_matrix, I could use them, along with it's position, to get my "look at" point and "up" vector -- this would place my camera into the object, which is really what I want to do. Does this sound like the correct approach? If so, how exactly do I get these vectors out of my matrix?
Thanks a bunch,
-BradlyP