Transforming local coordinates to world coordinates.

Hi there ppl…

I’m building an OpenGL application for a Computer Graphics assignment that is supposed to render complex 3D trees. So far so good, nothing special.

I’ve defined a recursive procedure in Delphi that can draw binary trees given a couple of parameters and it works perfectly, but this procedure is currently called every time the tree is drawn. This is, of course, unnecessary and I would like to save my tree as an interleaved vertex/color-array or as a display list. But now I’m stuck with a problem. This is my recursive procedure (I’ve left out a couple of details):

Procedure DrawTree(Depth, MaxDepth: Byte; Scale, Length, Angle, Twist: Double)

// Some Const en Var declarations…

Begin

// Setting up some variables and constants and drawing a cylinder at the desired position as the current branch…

If Depth<>0 Then Begin //Call DrawTree again?

glTranslatef(0, Length, 0);

glPushMatrix(); //New branch number one…
glRotatef(Angle, 0, 0, 1);
glRotatef(Twist, 0, 1, 0);
DrawTree(Depth - 1, MaxDepth, Scale, Length * Scale, Angle, Twist);
glPopMatrix();

glPushMatrix(); //New branch number two…
glRotatef(-Angle, 0, 0, 1);
glRotatef(Twist, 0, 1, 0);
DrawTree(Depth - 1, MaxDepth, Scale, Length * Scale, Angle, Twist);
glPopMatrix();

End;

End;

Every new branch has its own local coordinate system, but if I want to save my tree, I actually want to save every knot at which a fork occurs as a vertex in an array in WORLD coordinates. So I have to figure out how to convert the current local coordinates to world coordinates based on the current modelviewmatrix on the stack and that’s the part were I’m stuck. How do I convert local to world coordinates? I thought about multiplying a coordinate in local space by the inverse of the current modelview matrix, but calculationally this seems to intensive to me, so I thought there might be some other, faster way of doing it.

A thing worth mentioning might be that the camera also resides on the modelviewmatrix (although I don’t know whether or not this makes any difference for my problem), the procedure that redraws the scene is as follows (again with a couple of details left out):

Procedure Redraw(Sender: TObject);
Begin

glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
With Camera Do Begin
gluLookAt(EyeX, EyeY, EyeZ, TarX, TarY, TarZ, UpX, UpY, UpZ);
glRotatef(OrbX, 1, 0, 0); //Camera rotations
glRotatef(OrbY, 0, 1, 0);

// Some lighting routines…

End;

DrawTree(DepthBar.Position, DepthBar.Position, ScaleBar.Position / 100, LengthBar.Position / 100, AngleBar.Position, TwistBar.Position);
PageFlip;

End;

I hope this makes some sense and someone out there knows what I’m trying to do, I’d really appreciate some help at transforming the local coords to world coords in a fast way ;-).

GRTZ and thanks in advance,

VuurSnikkel.

Don’t use opengls matrix manipulation functions for this kind of thing. You basically need to maintain your own copy a matrix at each node (a local one, and an absolute one - absolute being the local matrix multiplied by all its parents absolute matrix).

Well…

I was afraid it would boil down to something like this (let go of the OpenGL modelviewmatrix modification routines and implement your own) ;-). But if this is the only feasible solution, I will give it a go, thanks for your tip.

GRTZ,

VuurSnikkel.