Multiple cameras

Hello,

I have written a simple importer for LightWave 6.5 .lwo and .lws files. The code can display models (using triangles and quads) just fine, but I’m having problems replicating the cameras assigned in the scene (.lws) file by LightWave.

I have four cameras in the scene: the front one is positioned roughly at the front of the object (a spaceship), shows the ship’s forefront and points out in the distance; the back one is positioned behind and above the object, and it points at the object (but not at the origin); the left and right ones are positioned on the wings of the ship and point out in the distance. Basically, for each camera I have its position and its target (“eye” and “at” in gluLookAt() terms).

I understand that in order to replicate these views I cannot just pass the camera position and target to gluLookAt() [tried that and it didn’t work], and I was wondering whether anyone could point me to some sample code to compute the inverse transforms required to replicate the cameras described above.

Thank you,
Dario

I don’t see why you can’t just pass the position and eye (along with an up vector) to gluLookAt. However, what you will have to do is use glViewport to draw to a particular section of the screen. So, for each camera, you set up a new glViewport and a new camera matrix and redraw the entire scene.

Originally posted by Korval:
I don’t see why you can’t just pass the position and eye (along with an up vector) to gluLookAt. However, what you will have to do is use glViewport to draw to a particular section of the screen. So, for each camera, you set up a new glViewport and a new camera matrix and redraw the entire scene.

I cannot just pass the eye, target and up vector because, as I said in my initial post, it doesn’t work.
It’s not a glViewport() issue either – I am not interested in displaying multiple cameras at the same time… I’d just like to be able to switch between the available cameras in a single viewport.
gluLookAt() is not sufficient to display the different cameras: I have already tried it and it doesn’t work the way LightWave works.
What I’d need is some sample code for the inverse transforms required to replicate the cameras as seen in LW. This probably entails translating, rotating and such – I just don’t know what the correct inverse transforms are.

Thank you,
Dario

Are you using a glLoadIdentity() before you use the new gluLookAt values? gluLookAt will multiply to the current matrix, not replace it so you need to set it to the identity matrix first or you will not get what you expect.

Also, make sure you use it on the modelview matrix and not the projection matrix.

There’s no reason I can think of why gluLookAt shouldn’t work for you. If the above suggestions don’t help fix the problem then explain a bit more about what is wrong. Just saying “it doesn’t work” doesn’t really tell us much to help you figure it out. You have to tell us what you are seeing that tells you it doesn’t work. It’s like going into a doctors office and just saying “I’m sick” and expecting him to know exactly what’s wrong with you with no other description of your symptoms.

Originally posted by Deiussum:
[b]Are you using a glLoadIdentity() before you use the new gluLookAt values? gluLookAt will multiply to the current matrix, not replace it so you need to set it to the identity matrix first or you will not get what you expect.

Also, make sure you use it on the modelview matrix and not the projection matrix.

[/b]

Yes, I am using glLoadIdentity() on the modelview matrix before calling gluLookAt().

As I said in my previous posts, I have four cameras: front, back, left, right. What I am trying to do is to render the model from the cameras’ point of view.

The code looks like this:

glMatrixmode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye.x, eye.y, eye.z, at.x, at.y, at.z, 0.0, 1.0, 0.0);
glTranslatef(-eye.x, -eye.y, -eye.z);

DrawModel();

All model coordinates are within a unit cube. The eye and at vectors are read directly from the LightWave scene file. Their coordinates are correct, that is, identical to what they are in LightWave but the z coordinate is inverted – in LW, positive z’s go out in the distance instead of going towards the screen as in OpenGL. No additional transforms are performed on the model prior to drawing it. The call to glTranslatef() above does not do what I expect, changing the signs of the coordinates in the call does not do what I expect either, nor does using the at vector (with either plain/inverted coordinates) instead of the eye vector. Therefore, I think I need some more complex inverse transforms.

You can take a look at what the cameras look like in LightWave and in my code by downloading the following screenshots:
http://dappsoft.dreamhost.com/MultipleCameras.zip

All screenshots are in .jpg format.

Thank you,
Dario

Take out the glTranslatef part and you should be fine. Part of gluLookAt does the equivalent of that, so doing it twice is not going to get the effect you want.

It would seem, from what you’re telling me, that lightwave is using a left-handed coordinate system. To make sure, take a +x vector and cross it with the +y vector. If the result is the +z vector, then it’s right-handed (like OpenGL’s). If not, then you will have to flip the coordinate system.

After you set up the camera matrix, multiply a matrix that negates the z-column of the matrix. That should get you in right handed coordinates.

Originally posted by Korval:
Take out the glTranslatef part and you should be fine. Part of gluLookAt does the equivalent of that, so doing it twice is not going to get the effect you want.

Unfortunately it doesn’t seem to do the trick. I have posted the new results at:
http://dappsoft.dreamhost.com/MultipleCameras.zip

As you can see, although now the back camera shows correctly the ship from behind, orientation and distance are still wrong. Also, the front camera shows the ship from the back, at the wrong distance and orientation. Moreover, the left and right cameras do the wrong thing: instead of showing the left and right wings, looking at the horizon, they show the ship from the left/right.

Originally posted by Korval:
It would seem, from what you’re telling me, that lightwave is using a left-handed coordinate system. To make sure, take a +x vector and cross it with the +y vector. If the result is the +z vector, then it’s right-handed (like OpenGL’s). If not, then you will have to flip the coordinate system.

Yes, LightWave uses left-handed as opposed to right-handed as in OpenGL.

Originally posted by Korval:
After you set up the camera matrix, multiply a matrix that negates the z-column of the matrix. That should get you in right handed coordinates.

I am flipping the z’s of both the eye and the target when I load them from the LightWave scene file. Isn’t that enough? Could you please an example of such a matrix?

Thank you,
Dario

Originally posted by Dario:
I am flipping the z’s of both the eye and the target when I load them from the LightWave scene file. Isn’t that enough? Could you please an example of such a matrix?

I should’ve known that – just use glScalef(1.0, 1.0, -1.0);
Of course at the root there was a stupid mistake – it turns out I was calling gluLookAt() twice… it’s working now.
Sorry about that…

Thank you very much,
Dario