• Advertisement
Sign in to follow this  

ModelView Problems

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

Hi Guys, Im having trouble understatnding the difference between Viewing and Modelling transformations using the ModelView Transformation. Viewing transformations should be made before modeling ones. Would appropriate code be glMatrixMode(GL_MODELVIEW); //then gluLookAt(...); //set camera, then glTranslate(..); //translate to position to draw model DrawModel(); //Draw model function How do I differentiate between translating the camera and translating models? I want to be able to: 1. Move the camera around my model. & 2. Move my model with a stationary camera. Thanks for any help given!

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Cacks
Hi Guys,

Im having trouble understatnding the difference between Viewing and Modelling transformations using the ModelView Transformation.

Viewing transformations should be made before modeling ones. Would appropriate code be

glMatrixMode(GL_MODELVIEW); //then
gluLookAt(...); //set camera, then
glTranslate(..); //translate to position to draw model
DrawModel(); //Draw model function

How do I differentiate between translating the camera and translating models?

I want to be able to:
1. Move the camera around my model. &
2. Move my model with a stationary camera.

Thanks for any help given!


To move your camera around your model you will need to change the gluLookAt() parameters and you will most likely need to trig out the path you want to move around your model...
to move the model just call gltranslatef() before you call your rendering code to display the model...

Look into glPopMattrix() and glPushMatrix() and you will need to increment your xyz or whichever you need to move your model in the glTranslatef()

Share this post


Link to post
Share on other sites
Can u also use glTranslate etc to modify the camera postiion? If this is the case how do you distiguish between wanting to move either the camera or model?

Before using gluLookAt() do I have to specify glMatrixMode(GL_MODELVIEW)?

Thanks

Share this post


Link to post
Share on other sites
Think of the camera defining an origin and an orientation of viewing in the world. A model's co-ordinate frame is (for now) also given in the world (don't confuse this with the vertices of the mesh, since those are almost given in the local co-ordinate frame of the model).

Since the screen should display not the origin of the world but what the camera "sees", you actually want the overall transformation
mesh (or local) -> world (or global) -> camera (or view)

Now, since the model is assumed to be given in global co-ordinates, you have to set-up the models co-ordinate frame as the transformation local->global. Now also the camera is (normally) given in the global co-odinate frame, so there is a transformation view->global. But due to the overall transformation mentioned above, you want the inverse, namely global->view.

Next you have to consider that the first transformation you supply OGL with will be the last applied to vertices. Looking again at the overall transformation above, that means you first have to supply the global->view trafo, then the local->global trafo of the model. With V denoting the global->view (or in OGL terms the VIEW) trafo, and M denoting the local->global trafo (or in OGL terms the MODEL) trafo, and furthur considering that OGL uses column vectors, you get
V * M

Next, assume that a single trafo in use is build from rotation R and translation T (no scale for simplicity). You should apply rotation first, followed by translation, since otherwise rotation will simultanously also do a translation on an arc, what makes things weired. So
V * M = TV * RV * TM * RM
where e.g. TV means the translation part of V, and RM similarly the rotation part of M.

Now, considering that the camera C is defined by the inverse of V, you get
V * M = C^-1 * M = (TC * RC)^-1 * TM * RM
what is, under the given circumstances, identical to
RC^t * TC^-1 * TM * RM
where RC^t means the transpose of RC, and TC^-1 is the same as TC but with negated translation values. The both left terms together describe the VIEW matrix here, the both right parts together the (simplest form of a) MODEL matrix.

So, writing in OGL, you have to do
(1) glLoadIdentity
(2) glRotate with inverse camera orientation
(3) glTranslate with inverse camera position
for the set-up of the VIEW matrix, followed by
(4) glTranslate with the model position
(5) glRotate with the model orientation


Notice that this is the basic form. More sophisticated transformations are usual.


EDIT: manual page says that gluLookAt is equivalent to
glMultMatrixf(M); glTranslated(-eyex,-eyey,-eyez);
where M is computed as rotation matrix from the given parameters. So yes, I assume that the matrix stack has to be already chosen, and also the identity martix should be loaded (but I don't know it surely). Notice furthurmore that the order of the both transformations gluLookAt does, and also that the eye point if negated. All this could be found in the explanation above, too.

Share this post


Link to post
Share on other sites

Would I first write:

glMatrixMode(GL_ModelVIEW):

then

How do I specify I want to move the camera here?
(1) glLoadIdentity
(2) glRotate with inverse camera orientation
(3) glTranslate with inverse camera position
for the set-up of the VIEW matrix


How do I specify that I want to move the model here?
(4) glTranslate with the model position
(5) glRotate with the model orientation

Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by Cacks
glMatrixMode(GL_ModelVIEW):

You should switch the MODELVIEW matrix on if it isn't the current matrix. Normally it _is_ current (if the rest of code is written correct), but you could switch it on there to be sure.

Quote:
Original post by Cacks
How do I specify I want to move the camera here?
(1) glLoadIdentity
(2) glRotate with inverse camera orientation
(3) glTranslate with inverse camera position
for the set-up of the VIEW matrix

You don't need to specify this. Imagine this: After the total set-up of the matrix (say both the VIEW and the MODEL part) you push geometry in form of vertices to OGL. As soon as a vertex is supplied, OGL transform that vertex by the set-up transformation matrix. That could be written like this:
p' := C^-1 * M * p = MODELVIEW_MATRIX * p
where p is the original (i.e. model local) vertex position, and p' the transformed one, say in view co-ordinates. As you can see here, there is no special need for OGL to distinguish between the VIEW and the MODEL part, and hence there is no need for you to specifiy that the first matrix is the VIEW matrix. In other words, only the fact of how the math is applied and that you supply the C^-1 matrix first (making them to be applied last) makes it implicitely the VIEW matrix.

This behaviour of OGL is often confusing first, but you'll see that stuff is ok.

Share this post


Link to post
Share on other sites
Appendix:

Quote:
Original post by Cacks
How do I specify I want to move the camera here?
(1) glLoadIdentity
(2) glRotate with inverse camera orientation
(3) glTranslate with inverse camera position
for the set-up of the VIEW matrix

Please notice that this _does not_ move the camera! Instead it instructs OGL to reflect the effect of a (rotated and) translated camera! I suggest you to make a strict distinction of these things. Track the state of the camera like any model in your data set. When its time to render, supply the local transformation to OGL. You should avoid to use OGL to track a transformation state for you if possible.

Share this post


Link to post
Share on other sites
So is the camera position determined by the first transformations as transformations are performed in reverse order?

Also is this the correct format for rendering:
1. ModelView transformations
2. Projection transformation
3. ViewPort transformation

or are these meant to occur in the reverse order?

Thanks!!

Share this post


Link to post
Share on other sites
Quote:
Original post by Cacks
So is the camera position determined by the first transformations as transformations are performed in reverse order?

Also is this the correct format for rendering:
1. ModelView transformations
2. Projection transformation
3. ViewPort transformation

or are these meant to occur in the reverse order?

Thanks!!


You are correct. In the rendering pipeline for OpenGL a vertex transformed in that order. Normally though, you only need to set the Projection matrix and the viewport once (upon initialization). Your main concern in rendering is the modelview matrix.

Share this post


Link to post
Share on other sites
Some different ways to look at it:

No, their is no absurd "first transformation applies to camera" system that would only make it a pain to work with and confuse people. The easy explanation is that there ISN'T a camera. Your view point will always be the origin and you will always be looking down negative z. All you can do is to PRETEND that there is a camera by moving everything else in the opposite way. To make life easier you can treat the camera as an object and setup the modelview with the cameras inverse transformation, which means nothing but "transform everything coming after that in the opposite way".

I would also advice to NOT use the "OpenGL is doing everything backwards" point of view, as it will just confuse the hell out of you when you start pushing and popping the matrix a lot. All transformations are done in local space and applied to the current modelview (ie. they create a transformation matrix and multiply it to the current modelview). Now the fun part is that if you have transformation T and modelview M, multiplying it one way applies it in local coordinates and the other way uses global coordinates. Order matters, and if you apply T "after" M it will be based on M (which is the sum of all previous transformations), but if you apply it "before" M it uses the unchanged coordinates (ie. global). If of course it is really making it a lot easier for you to think in world space, then the consequence is that you can pretent it is all happening in reverse order.

Might be less confusing in D3D, where you have to manually create and multiply the matrices and can decide on the order yourself. But OpenGL is doing a new transformation AFTER previous ones, which especially means that if you first rotate and then translate the translation will use different axes than it would have before the rotation. Think of every "object" to have its own coordinate system and that everything you do is using the objects coord system and NOT the world coord system. Some nifty images might help to explain, but lacking nifty images all I can say is that this is good and neat. An objects "forward" (depending on how you modelled it, let's just say the z axis by default), will always be the objects "forward", no matter how much you move and rotate it around. You don't need to figure out which way an object is facing, if all you want to do is move it forward. You can stubbornly glTranslate(0,0,speed) (or could, as usually you want to know where it ended up and "asking" OpenGL all the time isn't exactly efficient).

Share this post


Link to post
Share on other sites
OGL doesn't apply transformations in reverse/backward order. The point is that OGL by itself does allow only to multiply from one side (as oppsite to D3D, as Trienco already stated). All this is in fact only a question of matrix algebra. So this could be expressed fine the following way:

Lets assume using column vectors. Looking at vector algebra, this means that the current MODELVIEW matrix M is replaced by
M' := M * T
where T denotes any new transformation suppied to OGL (by either glMultMatrix, glRotate, glTranslate, or glScale). It comes out that transforming a vertex position under this circumstances looks like
v' := M' * v = ( M * T ) * v = M * ( T * v )

Although actually OGL stores and applies M' (say the concatenated matrix) only, you can see that the _effect_ is mathematically the same as like T applied to v, and then the former matrix M applied to the result of T*v. One could say that T is a more local transformation as M is.

The same argumentation yields in the answer of how to order scale, rotation, and translation usually. To have lowest effect of the transformations to each other, the mesh should be scaled in its local system (since scaling in local system doesn't change the local origin nor the local orientation), then rotated around its local origin (since rotation doesn't change the local origin), and then translate it. As you see here, each next step has lesser local parts that it left uneffected. So, in the above writing
T := P * R * S
where P denotes the translation ("positioning", since T already denotes the total transformation), R the rotation, and S the scaling.

So, if you use OGL to build the new matrix M'
M' := M * T = M * P * R * S
from the current MODELVIEW matrix M with such a transformation above, simply invoke OGL by going from left to right along the formula. With M being already stored in OGL, of course, you have to choose the order of invocations
glTranslate(...);
glRotate(...);
glScale(...);

Share this post


Link to post
Share on other sites
Lets say I'm going to have a scene, that contains bricks. I use gluLookAt that effectively sets my camera view. Each brick has local coordinates, which are their vertices. I draw each brick in world coordinates using glTranslate & glRotate. The viewing transformations must be specified before anyother modelling transformations. This is because transformations in OpenGL are applied in reverse order.

Does this sound ok as an overview of whats happeing or is this wrong?

Thanks for all the help, im finding this modelview difficult to understand precisely LOL!

Share this post


Link to post
Share on other sites
(In the following I'll try to be nit-picking once more, since the problem may need some precise terminology to be understood?!)

Quote:
Original post by Cacks
Lets say I'm going to have a scene, that contains bricks. I use gluLookAt that effectively sets my camera view. Each brick has local coordinates, which are their vertices.

Just to clarify: The scene (say the world at a specific moment of time) consists of a wall. The wall consists of some bricks. Each brick is given by an own model, having its own mesh and material. Hierarchically the bricks are part of the wall, and the wall is part of the world. In this sense the wall at a whole, even if not having an own mesh (no own vertices), could have a specific origin placed in the world, and an orientation w.r.t. the world. This origin and orientation together is the wall's local co-ordinate frame. It is often visualized by a 3D Cartesian axes cross in modelling applications. Now, each particular brick in the wall could have its own co-ordinate frame, too. However, instead of relating the origin and orientation to the world, you could relate it to the frame of the wall! Due to this, translating the wall will translate all bricks immediately also, since the bricks depend on the wall. Now, one step deeper, the vertices of the mesh of a brick are related to the local co-ordinate frame of the brick. So, translating the brick means to translate its mesh also. Please notice the hierarchy in this stuff; it is called the "forward kinematics chain", since changing a more globalframe implicitely affects also the related, more local frames.

So precisely, the vertices of a brick _are_ not local co-ordinates, but their co-ordinates are given relative to a local co-ordinate frame. That is why is is also named MODEL co-ordinates.

Quote:
Original post by Cacks
I draw each brick in world coordinates using glTranslate & glRotate.

Also this is a question of exact terminology. You push vertices in their local co-ordinates into OGL, so I would say you draw it in local co-ordinates. But due to the fact that you have set-up the MODELVIEW matrix, OGL transforms the vertices from the local/model co-ordinates on-the-fly into view co-ordinates. That is why that matrix is named MODELVIEW matrix: from model (local) co-ordinates to view co-ordinates.

Quote:
Original post by Cacks
The viewing transformations must be specified before anyother modelling transformations. This is because transformations in OpenGL are applied in reverse order.

Transformations in OGL are applied in the correct order (see my post above!). Due to OGL's API you have to supply the more local transformations nearer to the time you supply vertices. That is all.

Quote:
Original post by Cacks
Thanks for all the help, im finding this modelview difficult to understand precisely LOL!

Don't give up, you're on the right way ;-)


Perhaps a hint: If you transform a model's mesh from the local frame to the global frame, you rotate and translate the mesh. If you think of the VIEW being what a camera sees, and you think of the camera as an object in world, please notice that the VIEW matrix is nothing than the inverse of the camera's local co-ordinate frame. Why? Because you could imagine the _world_ being translated so that the camera becomes the absolute origin, and the _world_ being rotated around that absoloute origin so that the camera becomes aligned to the principal orientation. This is just the opposite of how models are transformed.

Share this post


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

  • Advertisement