Archived

This topic is now archived and is closed to further replies.

LlelanD

Transforming coordinates between two reference frames in a scene.

Recommended Posts

In what manner can you use OpenGL to transform the coordinates from another frame to the current frame? An example: Object1 is an object within the scene that has a target coordinate relative to the local frame (say - a dot on a sphere). Object2 is another object within the scene (say - a long thin cylinder along the local z-axis) that needs to be oriented so that the Z+ axis points towards the target coordinate of Object1. What you get is a cylinder that always points to the dot on the sphere no matter their relative positions. In what manner is OpenGL designed to be used to transform the target coordinate from the local reference frame of Object1 to the local reference frame of Object2 so that Object2 can then be correctly oriented? Is this something that OpenGL is even capable of doing, or must you rely on the matrix operation capabilities of your host CPU?

Share this post


Link to post
Share on other sites
I''m amazed at how well this question seems to have stumped people. I also posted it on the OpenGL Forum where I did get some replies. Unfortunately, no one seemed to really understand what I was talking about. I eventually figured out one way to do this and, since there were no replies on this forum, have reposted my findings here in the hope that either you will find it useful or that someone might know a better way.


Fortunately, I''ve figured out a way to do it. It''s a little cheesy, but it works and it uses the graphic hardware via OpenGL to do the matrix operations instead of the host CPU.

  • Transform to, render, and pop back from the target frame (F2).
  • Transform to the tracker frame (F1).
  • Push the model matrix and load the identity matrix.
  • Apply the inverse transform for F1.
  • Apply the transform for F2.
  • Cheesy part - Use a loaded matrix to hold up to 4 coordinates which will be transformed by the set of matrices we just applied.
  • Do a glMultMatrix() to transform the points.
  • Read back the current matrix using "glGetFloatv(GL_MODELVIEW_MATRIX, matrix);" (or glGetDouble()) to get the transformed coordinates.
  • Pop the F1 frame back in.
  • Orient the frame with the coordinates you just transformed from F2 to F1.
  • Render your frame.

Works like a charm. Here''s the display code. If you''d like to see this run, you can download my zipped GLUT example and try it out for yourself. It''s just a simplified example with a few keyboard controls.
  • F1 will toggle full-screen/windowed.
  • ''a'' toggles the frame axes.
  • ''g'' toggle the XZ grid.
  • ''+'' and ''-'' speed up/slow down the animation speed.

If anyone has a better way of using OpenGL to transform points between frames, Please let me know.

    
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Transform from view (FV) to world (FW).

glLoadIdentity();
gluLookAt(2.0, 4.0, 12.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

// Draw FW objects.

drawGrid();


// Draw the target frame (F2).

glPushMatrix();
applyF2();
renderF2();
glPopMatrix();


// Draw the tracker frame (F1).

glPushMatrix();
applyF1();

// This F1 tracker must always orient its z-axis to the F2 point [0, 0, 0]

// (The center of the wandering purple piece of fuzz).

// We must transform the F2 point coordinates (PF2) to F1 coordinates (PF1).

// PF1 = inv(F1) x F2 x PF2

glPushMatrix();
glLoadIdentity();
applyInvF1();
applyF2();

// Use a transformation matrix as a set of 4 points to transform.

// (We''re only going to use the first point)

GLfloat m[16];
zero(m);
m[ 0] = 0.0; m[ 1] = 0.0; m[ 2] = 0.0; m[ 3] = 1.0;
glMultMatrixf(m);
glGetFloatv(GL_MODELVIEW_MATRIX, m);
glPopMatrix();

// Orient F1 to point the z-axis to the point now in F1 coordinates.

track(m[0], m[1], m[2], 0.0);
renderF1();
glPopMatrix();


// Update the display.

glutSwapBuffers();

Some screen shots:


Share this post


Link to post
Share on other sites