PDA

View Full Version : damn the matrices!!

lee
01-30-2001, 03:04 PM
hi everyone, i'm trying to implement a camera, and i understand how to use the glMultMatrixf function to translate and rotate, and squish objects..but i'm not clear on how to use it with a vector?? i've read a lot about using it with vector multiplication, but i don't understand exactly WHAT it does...(if anything). is it commonly used?? any info would be very helpful, thanks.

also, can someone explain please what the advantage is of using the matrix operations to move the camera rather than just translating the entire scene with glTranslatef and glRotatef?

lee

zed
01-30-2001, 04:49 PM
a/ no gimbal lock problems
b/ only one operation 'multmatrice' instead of a few 'translate and rotating'

your best bet would be to use gluLookAT

Rizo
01-30-2001, 10:39 PM
Hi Zed,

nobody told me about the damn gimbal lock. http://www.opengl.org/discussion_boards/ubb/smile.gif been spending 3-4 days on a simple rotation, but couldn't get it to work.

do I have to use glLookAt to avoid the gimbal problem? I have found a work around to premultiply the rotation matrices

push matrix
glRotatef (x...
glRotatef (y...
glRotatef (z...
save matrix to m
pop matrix
multiply matrix by m

this essentially multiplies my matrix as following

m * Rx * Ry * Rz * m

which cause my object to appear half the size...(no biggy)

but I understand this is very inefficient (specially reading matrix values off the vid card is VERY VERY slow)

do u think I can just use the rotation matrices and multiply them by hand and not use glLookAt? if I need to use glLookAt, can u give me some tips?

Much appreciated,
Rizo

Elixer
01-31-2001, 07:59 AM
Why are you even multiplying the matrix in the first place?? I don't see the point of doing it the way you are.

What does m contain when you first load it?

You don't need to use glLookAt, since that does all the loads/multiples for you. (up,eye,front-- or whatever the order is)

Oh, and if you want to know how to use vectors, look at the 80+ topic on glmultmatrix on this board... I don't know how you missed it. http://www.opengl.org/discussion_boards/ubb/wink.gif

[This message has been edited by Elixer (edited 01-31-2001).]

Punchey
01-31-2001, 08:20 AM
I'm sorry, Elixer, but gluLookAt does not do all the stuff for you. You must rotate the "camera" matrix first so that you send the valid "look at" values to gluLookAt. There's no possible way to use gluLookAt to rotate the matrix for you. So, if you want to take advantage of T&L, you have to do the following (psudocode):

MATRIX mat;
glPushMatrix();
glRotate(x...)
glRotate(y...)
glRotate(z...)
glTranslate(...,z)
glGetFloatv(...&mat...);
glPopMatrix();
// and only NOW do we have the values to pass to gluLookAt
gluLookAt(mat[12],mat[13],mat[14]...);

Ofcourse, you could do this *slightly* differently and not use gluLookAt and instead just multiply the modelview matrix with our matrix. But in either case, you have to load the matrix in and rotate it and translate it and then get it back. Otherwise, what the heck do you send to gluLookAt unless you're doing some kind of pre-hardcoded camera thing???

DFrey
01-31-2001, 09:08 AM
Woah. You do not want to do that Punchey. gluLookAt quite easily constructs a view matrix, and post multiplies the current matrix (which should be the modelview matrix) by it.
From MSDN:
The gluLookAt function creates a viewing matrix derived from an eye point, a reference point indicating the center of the scene, and an up vector. The matrix maps the reference point to the negative z-axis and the eye point to the origin, so that when you use a typical projection matrix, the center of the scene maps to the center of the viewport. Similarly, the direction described by the up vector projected onto the viewing plane is mapped to the positive y-axis so that it points upward in the viewport. The up vector must not be parallel to the line of sight from the eye to the reference point.
Once you have the modelview matrix set either by using discrete transformations or gluLookAt, you can then do the discrete transformations for the objects within the scene. The values you pass to gluLookAt should be quite easy to come by, one is the direction you want the camera to look, another is the position of the camera, and the final value is the up vector and is normally a constant.

Thaellin
01-31-2001, 09:09 AM
Assuming you track camera location in world coordinates, and track your viewing vector/orientation vector as unit vectors, you should be able to:

gluLookAt(cameraX, cameraY, cameraZ,
cameraX + viewX, cameraY + viewY, cameraZ + viewZ,
upX, upY, upZ);

... and be done with it. No?

-- Jeff

[This message has been edited by Thaellin (edited 01-31-2001).]

DFrey
01-31-2001, 09:15 AM
Rizo: If you need to do matrix math, it would be wise to create a matrix math library. That will be much faster than trying to use OpenGL as a math library, which it is not.

Rizo
02-01-2001, 09:57 AM
Thanks,

using the matrix lib already...here is what our prof told us

Screen <- [World Centred transformation][model_view_matrix][Body Centred transformations] <- P

where P is the point in the 3D coordinates and Screen is what we see (ignorning other matrices). To do Body Centred Rotation, we should multiply the matrices on the right of [model_view_matrix]. to do world centred rotations (eg, trackball) we should multiply the rotation matrix on the left of [model_view_matrix]. Eg, after a trackball rotation the above looks like this

screen <- [T][model_view_matrix] <- P

and if I do a body centred x-rotation, then it looks like this

screen <- [T][model_view_matrix][Rx] <- P

and if I do a World centred y-rotation then

screen <- [Ry][T][model_view_matrix][Rx] <- P

I've been trying this out...but doesn't work, perhaps I haven't implemented it correctly.

I should say that, it seems that even you experienced guys are confused about all this rotations http://www.opengl.org/discussion_boards/ubb/smile.gif so many conflicts I don't know whom to trust. http://www.opengl.org/discussion_boards/ubb/smile.gif

Thanks,
Rizo

Punchey
02-06-2001, 04:27 AM
DFrey, Yes, I DO want to do that. I am right and your quote proves it. gluLookAt does not give you your up vector, front vector, or position information. You have to *SEND* those things *TO* gluLookAt. Therefore, gluLookAt _*DOES NOT*_ do EVERYTHING for you. Sure, it sets up the modelview matrix for you but only AFTER you have supplied it with elements from your camera matrix. Therefore, you must still manipulate your camera matrix using rotation and translation operations BEFORE using gluLookAt. This is all I was saying. I never said that gluLookAt didn't give you a fully translated and rotated modelview matrix. But it sure as hell does not give you a camera matrix that describes the orientation thereof.

Bob
02-06-2001, 05:00 AM
gluLookAt creates a fully translated and rotated modelview matrix. Just grab the source for Mesa3D and see for yourself. In there, you will find two gl-commands: glMultMatrix, which does the rotation, and glTranslate, which does the translation.

You are correct, gluLookAt does not give you the upvector, front vector and any other information. But that is completely unecessary, since you already know them.

If you want the viewpoint at A, looking at B, you just put the proper arguments into gluLookAt, and it creats the necessary information for you, so that the modelview matrix is currently located at A, looking at B. Of course, the upvector is, as DFrey said, mostly constat, so that was not mentioned. But since it's constant you know it.

glMatrixMode(GL_MODELVIEW);
gluLookAt(10,0,10, 0, 0, 0, 0, 1, 1);

The above code will generate a modelview matrix, that is located at (10, 0, 0), will be rotated so that it is looking at the origin, and view of the origin will be slightly roleld aswell because of the upvector. No magic involved with manual rotations/translations, and other mathematical tricks. Can it be easier?

Are you really sure you know what gluLookAt actually does and how it works? Try read the Red Book...

DFrey
02-06-2001, 05:06 AM
Thanks Bob. http://www.opengl.org/discussion_boards/ubb/biggrin.gif

Punchey: What I'm saying is that regarding the up vector, front vector, or position information, you generally should already have that information to give to gluLookAt. You should not need to get that info by reading the matrix back from OpenGL (generally a slow thing to do).

And in case your viewpoint is attached to some hierarchy, in which case some translations and rotations may be necessary, do that with your own matrix code. Do not use OpenGL as a math library. That is, if you are interested in maximum performance.

[This message has been edited by DFrey (edited 02-06-2001).]

Punchey
02-06-2001, 12:30 PM
Yes, Bob, I know exactly what gluLookAt does and your questioning me as much is not appreciated. Sure, you can simply use straight values or values not pulled from a matrix. But, as has been stated, using those values, you must generally assume that the up vector is constant. And, in many cases you can safely do this. However, there are also a GREAT many cases in which you DO NOT want to do that. And, more and more nowadays, you don't want to do that at all. In most modern game development cases (particularly FPS-type games such as shooters and flight sims), you want the camera to be attached to a object in the world. Sure, you don't HAVE to use a matrix, but it's a very nice thing to do in MANY instances. And that's why using a camera/object matrix is a very easy way to go about doing things. And so I maintain that gluLookAt DOES NOT magically do everything for you. Yes, it creates a modelview matrix for you given the front, up, and position. But you have to supply those values to it and therefore, in the vast majority of circumstances, there is still more work to be done. e.g. rotating and translating the camera. Sometimes not.

As for it being slow to read a matrix back into OpenGL, I think you might be the one who doesn't understand how gluLookAt works. All you have to do is a:
gluLookAt(matrix[12].matrix[13],...)

Now how slow is that? How is that any slower than anything else?

[This message has been edited by Punchey (edited 02-06-2001).]

Michael Steinberg
02-06-2001, 12:39 PM
Always when these cases happen, Punchey, I simply do it all myself. I only use glu functions if they perfectly fit into my problems.

Punchey
02-06-2001, 01:01 PM
That's another way of going about it.

DFrey
02-06-2001, 01:05 PM
No Punchey, it it not the indexed addressing of the matrix that is slow. It is getting the matrix from OpenGL using glGetFloatv, that's the performance issue I'm speaking of.
You are using OpenGL as though it were a math library, which in general, is a bad thing to do. And again, the only time I can see you needing to use any matrix math to get any of the vectors for gluLookAt is if the camera is attached to some member of a hierarchy (except the root). Otherwise, as in almost all shooters and sims, you already know precisely where the camera should be and how it should be oriented.

[This message has been edited by DFrey (edited 02-06-2001).]

The Wolf
02-06-2001, 01:20 PM
I agree with Punchey, you still have to supply the info to gluLookAt, and if the camera is bound to a model then what's the best way of doing the model translation/rotation? I've heared that the glGet* function is slow but it's either that or doing your own matrix math, which is better? OR is there another way to do this whole thing?

remember the model is walking/flying around not a specific point looking at another specific point.

DFrey
02-06-2001, 02:13 PM
remember the model is walking/flying around not a specific point looking at another specific point.

I think quite the contrary. A model has a origin (i.e. a specific point), and is looking in the forward direction at any point along the forward direction. Just take the forward view vector and add it to the model's origin (plus another vector for camera offset if needed) and that is a good point to send to gluLooAt, and the up vector is still just a constant. No extended matrix math is necessary to do that.

[This message has been edited by DFrey (edited 02-06-2001).]

The Wolf
02-06-2001, 04:05 PM
so then DFrey how would you do the rotation for the models view vector? would you use openGL, or homemade vector math?

DFrey
02-06-2001, 05:14 PM
To rotate the view vector, I would definately use a math library, not OpenGL. To rotate the model, I would use OpenGL. I'd even track the OpenGL modelview matrix with my own, if for some reason, I needed to access the matrix, I can get the info from the copy without resorting to glGetFloatv. Of course, I'd only go to that length if I needed such access many times per frame.

[This message has been edited by DFrey (edited 02-06-2001).]

Punchey
02-06-2001, 05:35 PM
I've read alot about how it is better to rotate etc. your matrices using OpenGL because it is optimized in your drivers if you have hardware T&L. So you'll actually be off-loading the math to your GPU instead of bogging down your CPU with it. If you have information to the contrary, please post it as it will probably be pivotal to the decision of many of us OpenGL programmers.

DFrey
02-06-2001, 06:13 PM
See this thread to see info to the contrary: http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/001519.html

And just in case you haven't learned about who mcraighead is, he is part of NVIDIA's OpenGL driver development team. For in the linked thread, he provides the answer you seek.

The Wolf
02-06-2001, 07:37 PM
But we still seem to be at a dead-lock. you said "To rotate the view vector, I would definately use a math library" and you also said "To rotate the model, I would use OpenGL.", My question is why don't you use the same routines to manipulate both the camera (or view) and the model, heck they both move the same way (yaw/pitch/roll/move).
This is all getting very confusing, would you mind posting some source code on what you're talking about.
PS: I'm not disputing the fact that glGet is slow, which is what mcraighead is saying, what I am inquiring about is: what is the best way to the matrix/view (or what ever you want to call it) manipulation

DFrey
02-06-2001, 08:01 PM
Rotating a single vector and rotating a model are in fact different things. When you rotate a model, you don't really care where any particular vertex gets transformed to as long as the transformation is consistent and as desired. When you transform a vector, you are doing so for the express purpose of finding the result. The best way to set the modelview matrix is dependent upon your needs.

The Wolf
02-07-2001, 04:58 AM
But who's talking about rotating the whole model, we're talking about the stage before that? we're only interested in the entity that holds information like model origin, heading, local axis, basically the matrix that holds this information. The matrix that you use to project the model.
SO, just like for each model you hold a matrix (which has the origin, and the model's local x,y,z axis), why not hold a matrix for the view? the only way you would hold the view as a vector is when you're thinking 2D graphics, or Doom style games (not Quake, no looking up and down), if you want to have 6 DOF, the view should be held as a matrix, so you can do Yaw/Pitch/Roll/move operations. Allow me to demonstrate:
Let's say you wanna change the pitch on your camera (look up/down) then you rotate about the local X-axis which is the 1st column in the camera matrix (we're talking about OpenGL matrices, column dominant), however if you hold the camera as a vector (as you say) you would have to hold 3 vectors (for the local axises) + the camera origin, which is the same as the matrix (remember we're talking about 6 DOF).
SO, if the camera is a matrix, and the models have matrices (for their heading) then why would you use 2 different methods to calculate matrices that are layed out identically?
REMEMBER, we're only interested in manipulating the heading of the object (camera or model), i.e, we're only talking about the camera or model matrix and what is the best way to do yaw/pitch/roll/move operations on that matrix.

[This message has been edited by The Wolf (edited 02-07-2001).]

DFrey
02-07-2001, 06:15 AM
I'm not using two different methods. All matrices and vectors that I calculate, I do so with a math library. I do not use OpenGL as a math library. I give OpenGL the matrix I calculate rather than get the matrix from OpenGL only to give it back again. Period.

the only way you would hold the view as a vector is when you're thinking 2D graphics, or Doom style games (not Quake, no looking up and down)

Sorry, but you couldn't be more wrong. You can very easily use a vector to specify any point you want to look at, and another to specify where you want the position of the camera to be. See the view vector is relative to some other vector (the position). So when I say view vector, that automatically implies AT LEAST 2 vectors. Not one vector as you seem to think I thought, which if you reread my post you'll clearly see I spoke of two vectors for the view. In 6 DOF you would need at least 3 vectors (view heirarchies can require many more). I'm also perfectly aware that vectors are not the only constructs for camera systems. Some people like to use quaternions as well afterall. Of course in the end, since OpenGL only uses matrices, all constructs must eventually be converted to matrices before they are of any use. gluLookAt is one such function for converting a set of vectors into an appropriate view matrix. You don't have to hold my hand when it comes to matrix math, I am a classicly trained physicist. http://www.opengl.org/discussion_boards/ubb/tongue.gif I'm far too intimate with such things. Take a look at my web page and you'll see the model viewer I wrote. For that program, I calculated all the matrices (that model in the screenshot has 4 independent parts each with its own rotation matrix and relative position).

[This message has been edited by DFrey (edited 02-07-2001).]

The Wolf
02-07-2001, 07:23 AM
with all due respect, we seem to be going in circles most of the time saying the same thing, and for some reason you keep going back and contradicting yourself, which might be because you misunderstood what we were talking about or vice versa. Anyways no biggy http://www.opengl.org/discussion_boards/ubb/smile.gif , but in the interest of world peace and this forum PLEASE NO MORE REPLIES ON THIS THREAD. no offence to anyone but this conversation could go on forever, maybe the question can be posted differently in a new light and in a new thread. Thanks

[This message has been edited by The Wolf (edited 02-07-2001).]

DFrey
02-07-2001, 09:03 AM
I'm sorry, but could you please concisely point out one point on which I contradicted myself? If I did, I'd like to correct the mistake.

[This message has been edited by DFrey (edited 02-07-2001).]

Elixer
02-07-2001, 12:30 PM
Dfrey wrote : "classicly trained physicist".

That explains it!

It all boils down to E=mc^2 http://www.opengl.org/discussion_boards/ubb/biggrin.gif

All kidding aside, Dfrey seems to be correct, I don't see what you mean wolf, and I suppose we will never find out, since you want this thread to die. http://www.opengl.org/discussion_boards/ubb/smile.gif

Punchey
02-07-2001, 03:06 PM
Okay, I can't resist... DFrey, you are correct when you say that you'd need at least 3 vectors for 6DOF. But why in the world would you preffer to maintain 3 seperate vectors to describe ONE orientation? I'd MUCH rather use a matrix for this. Especially considering you needn't do much more than to simply use the same matrix as you're using for whatever object you're viewing from. If you're viewing freely from no particular object, GREAT! But if you're wanting to see something from the perspective of, say, an object in the world such as another player or ship or whatever, then there's not much more to it than simply grabbing that object's matrix and using it for your camera (sending those values to gluLookAt or whatever you like). At any rate, I think we all know enough to get done what we want done by now... let's just leave it at that until we find that we don't. At which point, we'll come crawling back to eachother begging for advice. ;-)

DFrey
02-07-2001, 04:02 PM
Whoa there. At no point did I say I preferred using view vectors over a view matrix. Each different construct has its uses in which it makes more sense. For a heirarchical system I much more prefer matrices over view vectors. For sequencing, I'd prefer quaternions or axis-angle systems.
And yes, even Euler angles are quite ok for most circumstances (when full 6 DOF is not needed). One should use the tool that best makes sense for the job, and different jobs require different tools. But no tool should be misused. Using OpenGL as a math library, is tantamount to using a hammer to drive a screw - it'll work, but it's not very efficient or readable. That's the main message I was trying to get across in virtually all of my posts in this thread.

Punchey
02-08-2001, 04:43 AM
Whatever....