Need help with exact order of several transformations

Hi,

I know that this is a tired old question, but I have a situation where I couldn’t find an exact example, and my answer seems to be slightly off. Thought that I would check with the experts.

I have a model whose origin is at the center. It also goes lengthwise along the x axis.

For reference, lets put x to the right, y forward, z up.

So, it looks like:

xxxx^y
xxxx|
xxxx| body axis.
xxxx| (excuse the x’s, had trouble lining up)
xxxx|
xxlodeM______>x

I have a transformation and rotation matrix that moves the model to the correct spot in the world.

However, the data that I get, assumes that the model origin is at the tip of the model, and that the model is already rolled 45 degrees along the x axis.

So, without additional transformation, I get the model flying rolled, with the draw position point at the center.

Another piece to the puzzle : I am using a scenegraph (osg), so for my own sanity, I’m trying to keep the matrices separate until I understand everything, and I’ll combine them later.

The model is also scaled incorrectly, and I need to make it 3 times bigger, along all axis.

So, I have done the following…
This is in scene graph order, which I am pretty sure is the standard OpenGL reverse order.

Apply Position Transformation / rotation to get to right spot in world.

Translate ModelLength/2.0 on -x axis
(cone insertion, see below)
Rotate +/- 45 degrees along x axis.
Scale by three
Draw Model

This seems to work correctly.

Now, I need to attach a cone headlight.
I am given the azimuth and elevation in body axis form. This is good. However, my special headlight model is also origined incorrectly.
it is shaped like a cone, with the point on top.
Its origin is also in the center.

So, if I draw it with no extra transformation, then it is attached to the nose of the model (correct), but pointing straight down. It is also attached at the center of the cone, not the tip.

So, at the drawcone point, I add in code to translate along the Z axis (to get origin at cone tip) then pitch up along y axis. (notice the order reversal).
This gets me:

Rotate 90 degrees along y
Translate Cone height/2 along z (maybe -z).

This now results in the cone pointing straight out of the object.

Final code looks like :

Apply Model World Coordinate Translation / Rotation.
Translate along model axis
branch cone:
apply elevation rotation from data
apply azimuth rotation from data.
rotate 90 degrees along y
translate along z
draw cone:
branch model:
Translate ModelLength/2.0 on -x axis
Rotate +/- 45 degrees along x axis.
Scale by three
Draw Model

The branches mean that the only matrices that are used at that point are projection, world, and the initial translate.

The elevation and azimuth data, when 0, keep the cone pointing along the body axis of the object. However, when I give it the correct values, it is almost right, but not quite.

End question:

  1. Is the ordering sane? I don’t understand why calling
    glTranslate
    glRotate
    glScale
    looks right in the model case, but
    glRotate
    glTranslate
    looks right in the attached cone case.

  2. Could I be getting nailed by some kind of gimbal lock with my constant 90.0 rotation around an axis?

  3. In general, when trying to re-origin a model (both in translation and rotation) which ordering makes the most sense?
    glTranslate
    glRotate
    drawModel
    or
    glRotate
    glTranslate
    drawModel.

Thanks for the endurance in reading this. I know that the example is a little hokey, because it’s a simplification of a much more complex setup, but the identified problems should be the correct ones.

Thanks,

TriangleMan.

To correct your origin of the model to it’s nose, perform a translate immediately before you draw it.

In a scene graph this would be a transformation node immediately above the model with a translate in that node.

You can put your roll of 45 degrees before or after this matrix it won’t matter if the translation is along the axis of the roll.

Your scale of 3X shoule be above the translate, if it is below the translate you will need to increase the amount you translate by the magnitude of the scale.

So in OpenGL it would be:

glScale*();
glRotate*();
glTranslate*();
Draw_model();

That assumes that the vector specified in the glRotatef call matches the triplet in the translate call (from your description it should).

In a scene graph it would linked something like this:

xform_scale->xform_rotate->xform_translate->drawable

Thanks Angus.

That makes a lot of sense. It is also the most intuitive way to do it, which is good.

But…

In cases where I have models that have completely whacked out origins, which are skewed AND translated outside the model, it seems to be more convenient to do

scale->translate->rotate->drawable.

Since it can be hard to translate first when the axes of translation are so skewed.

I “seem” to have that working on a few models.

Will I suffer ill effects down the road from this? Because I could do the translation first, but on some of the models, the numbers would be really bizarre. If that’s the correct way to do it though, then that’s what I’ll do.

Thanks,
TM