Jump to content
  • Advertisement
Sign in to follow this  
Zouflain

OpenGL glLookAt() & quaternions in flight simulator situation

This topic is 3883 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

Alright, a few things I should say because I'm not sure if I use the "standard" coordinate system. Rather than use Y for depth (which always felt counter intuitive to me), I use Z much as if I were making a 2D program and added a Z axis. Prior to any translation, Objects approaching the screen have a lower Z value than those retreating, objects increase in X value as they move right and objects increase in Y value as they approach the top of the screen. The object in question has an attitude defined in a quaternion such that it's neutral position (ie [1,0,0,0]) would be represented by an aircraft with it's nose facing right and it's top facing the screen (ie, the left wing is above the right and the line between them runs parallel to the XY plane). The specific situation I have is as follows: I have such an object, it's location in 3D space, and it's attitude. I can convert the attitude from a quaternion to an axis angle easy enough, if that is indeed what I need. I know how to project a point that lies directly ahead of an object, and I know the objects location, so I have the xfrom,yfrom,&&zfrom in addition to the xto,yto,&&zto, but not how to calculate the up vector for a glLookAt. In far less (poorly used and/or inaccurate) terminology, rather than an object to appear to rotate in space, I'd like all of space to appear to rotate - just as if I were in the cockpit of an aircraft. Thank you for any assistance or suggestions. I can usually google search this sort of information, but my results have not been fruitful. Quaternions are popular enough, but their explanations come in only two forms: too simple to explain what I need, or far too technical (regarding OpenGL, in which I'm a novice) to understand.

Share this post


Link to post
Share on other sites
Advertisement
If you have the orientation of the ship stored as a quaternion you can use this quaternion to transform the 3 basis vectors that make up the coordinate space of your ship. A combination of these should produce the vector you're refering to.

quat shipOrientation;
vec3 x(1,0,0);
vec3 y(0,1,0);
vec3 z(0,0,1);

vec3 shipX = shipOrientation.Transform(x);
vec3 shipY = shipOrientation.Transform(y);
vec3 shipZ = shipOrientation.Transform(z);

Share this post


Link to post
Share on other sites
Thank you for the input, but I don't quite understand. I now have 3 translated vectors, but (though I have a feeling it's painfully obvious) I can't see how this can be used in a call to glLookAt.

Is there no way to use a single glLookAt call to represent the desired up vector, or do I need to call it three times (which for some reason doesn't feel right to me) using these three translated vectors? I finally learned quaternions (I've written my own class for them about 4 times) to a decent degree, but I'm still well behind in handling OpenGL's matrices (or matrices in general). Using the same #to and #from values, do I need to glLookAt three times? And, because it's a rotation of a matrix, isn't it non-commutative (for future reference)?

Share this post


Link to post
Share on other sites
The problem behind the problem is "all of space to appear to rotate". In OpenGL, there is the MODELVIEW matrix. It is used to transform from local (model) co-ordinates to global (world) co-ordinates to view co-ordinates. Also all of this is in fact done by a single matrix multiplication, looking at its composition helps its understanding:
V * M
where V denotes the VIEW portion and M the MODEL portion of the MODELVIEW matrix (I'm using column vector here since OpenGL does so). In case of the OP, V comes from the cockpit of the ship the viewer is sitting in, while M comes from any "outside" models. Since there are several outside models, one has in fact a couple of matrices, one for each model
V * M1
V * M2
...
but for each resulting matrix V is fixed (for the current rendering step).

Next, let's drop the special meaning of V by saying there _is_ actually a ship the viewer is sitting in. Hence there is a transformation description, defining how the ship is placed and oriented in the world. So it has an own M, let's name that one M0. Since any M describes how to transform local stuff to global co-ordinates, its inverse M-1 describes how to transform global stuff to local co-ordinates. That is eactly what the viewer does: It relates the world to its own (local) head. In other words, transforming the world to the local co-ordinate system of the viewer means that the VIEW portion is given by the inverse of the "viewing" ship:
V := M0-1

Besides the OP's special definition of co-ordinate frames, that would be the way to go: Handle the camera like an object in the world, having a location and orientation so that its M0 can be computed. Affect the location and orientation by the ship's controls. Compute V as given above when beginning a new rendering step.

gluLooAt is for doing the step of computing V. However, you have to compute its parameters, which actually are more or less already the parts of V. Moreover, not using gluLookAt allows you to drop the usage of the point in front of the nose (okay, camera), what leads more natural into the direction of ship control.

The solution bzroom has posted shows exactly that. It uses the M0 (he has reduced it to the orientation, since the translation has no impact on direction vectors at all, and named it "shipOrientation") and the local principal axes "x", "y", and "z", to just extract the 3 column vectors of M0 (in fact mathematically correct but performance-wise unnecessary). So gluLookAt does only a little more than inverting the transformation.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zouflain
Thank you for the input, but I don't quite understand. I now have 3 translated vectors, but (though I have a feeling it's painfully obvious) I can't see how this can be used in a call to glLookAt.

The 3 vectors are the forward, side, and up vectors if you want to name them so. Mathematically they are the 3 vectors that (together with the position) build up the local co-ordinate frame of the camera/viewer ship. I.e. the shipX can be named the "forward" vector since your ship points into the x direction; it is given in global co-ordinates. As far as I understand your OP correctly, shipZ (notice the negative sign, but perhaps I'm wrong with that sign) will be the "up" vector you're looking for. Notice furthur that the "ship" bzroom is talking about is the viewer ship.


BTW: Just to be correct (although it doesn't change anything on the problem, but may push your understanding): The 3 vectors are _not_ translated. They cannot be translated at all because they are _direction_ vectors. Only _position_ vectors can be translated.

[Edited by - haegarr on February 7, 2008 4:21:53 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!