# calculating new vertex after pops, pushes

This topic is 4347 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

after several pushes and pops how can i calculate the new transformed position of a vertex. Should i multlply it with the current modelview matrix tia Paul

##### Share on other sites
Yes, that's all you need to do.

Just in case, glGetFloatv with the GL_MODELVIEW_MATRIX parameter will return the current matrix on the stack.

##### Share on other sites
Great:)

and calculating the transformed normal is multiplying with the upper 3*3 part of it then i guess?

##### Share on other sites
Yes, since normals are vectors and do not have any translation, only the 3x3 rotation component is necessary.

##### Share on other sites
Quote:
 Original post by gorgorathafter several pushes and pops how can i calculate the new transformed position of a vertex. Should i multlply it with the current modelview matrix

Oh, be careful with that. As the name implies, MODELVIEW contains
(a) the global -> VIEW transformation,
(b) the MODEL -> global transformation.

Are you sure that you mean a location in VIEW space if you ask for transformed vertices? Most often the global space is desired. Use the GL's matrix stacks for rendering, and not for IK, collision detection, ...

Many people here on GDnet (including me) suggest to not "misuse" GL's state for tracking own geometrical state, not at least due to the VIEW thing. Do it yourself instead.

Quote:
 Original post by gorgorathand calculating the transformed normal is multiplying with the upper 3*3 part of it then i guess?

That depends. A direction vector (as opposed to a position vector) is actually invariant for translation. Homogeneous vectors (that are the vectors with 4 components although still used for 3D space) handle that automatically. Affine vectors (3 components for 3D space) must be distincted by the programmer: Consider the translational part of a transformation matrix if and only if a positional vector is dealt with.

A normal vector is a kind of direction vector, so far so good. But if you mean a vector that is perpendicular to the surface then you could not transform it like an ordinary direction vector, or else the perpendicularity may be lost. The problem occurs as soon as scaling/shearing plays a role. Then you have to use the transpose of the inverse of the matrix.

As long as only rotation is done, the transpose of the inverse is identical with the original matrix, and hence all goes the right way. (But you should still have in mind what's going on!)

Quote:
 Original post by bpointsince normals are vectors and do not have any translation, only the 3x3 rotation component is necessary.

As said, please remember that the linear sub-matrix (that is the mentioned 3x3 matrix) also holds scaling/shearing; in general, it holds a combination of all applied linear affine transformations (what is, AFAIK, all but the translation).

##### Share on other sites
Quote:
 Original post by haegarrAs said, please remember that the linear sub-matrix (that is the mentioned 3x3 matrix) also holds scaling/shearing; in general, it holds a combination of all applied linear affine transformations (what is, AFAIK, all but the translation).

If the matrix had scaling/shearing, wouldn't renormalizing the normal vector also return the same result?

##### Share on other sites
what i've got is a hierarchical model of a human, when rendering it i start with the parent node. push/pop/translate depending on the current bone rotation position, and render child nodes. So basically when drawing the vertices i would like to know their NEW position in WorldSpace. how can i achieve this.

cheers,

Paul

##### Share on other sites
Quote:
 Original post by bpointIf the matrix had scaling/shearing, wouldn't renormalizing the normal vector also return the same result?

The question is: What is meant with the term "normal vector"?

If one means a direction vector of unit length (due to the normalization operation) then yes, re-normalization of the transformed vector will yield in the vector as if the matrix would consist of rotation only (say, the scaling/shearing is undone). This is true since a normalization changes the length but not the orientation of a vector.

On the other hand, if one means the vector perpendicular to a surface (e.g. in a plane definition, or a vertex normal used for lighting calculations), then re-normalization alone would _not_ work in all cases. It would work for uniform scaling.

But think of a height-field used as a terrain. In such a case it appears one or the other time that a scaling is applied that is done in vertical direction with another factor than in the horizontal directions. Re-normalization would not work properly any longer!

So, as already stated, one should ever have in mind what's going on when programming something. E.g. if one implements a general purpose vector library, s/he has to deal with all the edges and corners, of course. If one implements a special purpose algorithm, s/he could take advantage of assumptions, but should comment that.

##### Share on other sites
Quote:
 Original post by gorgorathwhat i've got is a hierarchical model of a human, when rendering it i start with the parent node. push/pop/translate depending on the current bone rotation position, and render child nodes. So basically when drawing the vertices i would like to know their NEW position in WorldSpace. how can i achieve this.

If all you want to do is drawing them, then there is no need to do anything other, since drawing actually means to consider also the VIEW matrix.

BUT: If you have to do other things like computing new rotation angles by inverse kinematics of the bones (e.g. from use input) or the like, you _could_ use GL's MODELVIEW matrix, but you _should not_.

(1) You have to multiply it with the inverse of the VIEW matrix to isolate the MODEL matrix from it, or else you end up in the VIEW space but not in the global space. Let T denote the current overall MODELVIEW transformation you could fetch by a glGet, then T is a matrix combined like
T := V * M
where V is the VIEW matrix part (usually set-up from a camera or the like), and M the current MODEL matrix (set-up from the current model, of course).

Since you're interested in M only, you have to calculate
V-1 * T = V-1 * V * M = M

Moreover, for IK you have to deal with local co-ordinate frames, not only with the global frame, so there would be more to be "undone".

(2) You have to perform IK operations (or whatever) most often _before_ rendering.

EDIT
(3) You may suffer from finite numerical resolution after a while (e.g. after applying a couple of consecutive rotations in an animation). So you have to perform correction algorithms or else switch to another rotation representation than matrices, and that is something not supported by GL. So you have to mixin your own stuff anyway.

If you have to implement a small, "quick'n'dirty" solution, then okay, but if you want to do something long-living, then you will run into problems one day if you don't drive your own matrix/vector stuff.

[Edited by - haegarr on March 31, 2006 4:01:57 AM]

##### Share on other sites
Forward kinematics only, no fancy stuff like IK..for now;)
So then i think I need to multiply matrices myself. Let's say i have assigned the right foot as parent. When i rotate the ankle, the whole body should move over this axis. Can i just multiply these matrices, starting with the parent and traversing down the children. And then calculate the new position of the vertices

so in pseudo code

while( children )
{
children.parent.getMat4().multiplyBy(this.mat4);
for( children.numVertices )
newVertices = this.mat4.multByVector3();
children = this.children.
}

hope it is clear, it's almost weekend;)

Cheers,

Paul

##### Share on other sites
Quote:
 Original post by gorgorathwhile( children ){ children.parent.getMat4().multiplyBy(this.mat4); for( children.numVertices ) newVertices = this.mat4.multByVector3(); children = this.children.}

That seems me correct so far.

Btw: Whether you actually need to transform all the vertices yourself is out of my scope. Normally you need to do so if you're blending several bones for particular vertices, if you have a single mesh ("skin") partially influenced by bones, or ... don't know. If you have separated meshes (usually one per bone), and the meshes are transformed by the bones without changing their shape (say they are static), then you need not do so.

##### Share on other sites
Please note that doing any kind of Get in performance sensitive code is generally discouraged. Also note that current hardware tends to maintain the matrix stack in software, and matrix multiples are pretty darned cheap nowadays, in contrast to the early days of IRIS GL when this model was first introduced.

You may wish to implement your own push/pop and send your matrix directly via glLoadMatrix rather than having the GL maintain the matrix with incremental changes.

If you don't need to Get in your inner loops, of course its just easier to let the implementation manage this for you.