Transforming coordinates between two reference frames in a scene.

Started by
10 comments, last by LlelanD 22 years, 8 months ago
quote:Original post by TerranFury
One quick note: Unless the video card supports hardware T&L and you''re using the T&L extensions, the transforms will be performed by the CPU anyway , no matter how you do them.


True, but it needs to be implemented by the driver anyway, and so if the writers are nice, they will use whatever machine code optimisation they can to do it. So in most cases, it should still be faster then "manually doing the calculations".

Advertisement
Well, Gorg ol' buddy, I've got no idea where you're going with that. As far as I can see, after transforming to, rendering, and popping back from F2, you are:
  • re-transforming to F2,
  • using a loaded matrix to re-transform back out to frame world (FW),
  • using a loaded matrix to transform to F1,
  • and then drawing F1.
This does not orient F1 to point to a coordinate in F2. Either I'm being neutronically dense, or we're talking apples and Studebakers here.

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:




Edited by - LlelanD on August 12, 2001 2:53:33 PM

This topic is closed to new replies.

Advertisement