Trouble understanding coordinates

Right now I am working with some open source head tracking project that renders a model in OpenGL and it follows my head motion–I’m basically using it blindly.

My trouble deals with coordinates in a frame of reference. For instance, the head model is rotating in the window as I move my head, but the point (0,0,0) that I draw using glvertex3f is not changing, and, in fact, sometimes is inconsistent. How would I to determine absolute orientation based on this rotating frame of reference? By absolute orientation, I mean with respect to the webcamera that is display my image and having a head model rendered simultaneously in its own frame of reference?

I was told to look at the GL_PROJECTION and rotation matrices to rotate that frame of reference into some other frame of reference and then project it into the 2-d place of my screen, but I just have no idea how that is done.

It’s not quite clear what you’re asking here, or what kind of head-tracked setup you’re working with. Are you dealing with displays mounted on your head (e.g. goggles), or are you dealing with one or more monitors sitting stationary desktop, or …? Are you tracking head translation, head rotation, or both for the purposes of “moving the eye frustum(s)” though space? Are you simulating mono or stereo? Also I don’t understand what you are talking about with “absolute coordinates”? Are you talking world coordinates? That is the parent space in which everything is positioned?

As far as OpenGL MODELVIEW and PROJECTION transforms goes, does this make sense:

Hmm, let me see if I can phrase what I’m working with properly. The code I am using is EHCI located here:

http://code.google.com/p/ehci/

and uses a webcamera to track head orientation, and it draws vectors that correspond to facial direction as shown in the video in that link. What I don’t know how to do is use the information from the vectors being drawn (the ones shown in the video) to determine whether someone is looking in a direction. What I originally thought I could do was compare the points used to draw the vector, let’s say one is

(x,y,z) and the other is (x’,y’,z’) and the vector is made with glvertex3f.

I wanted to compare (x’,y’,z’) to (0,0,0) to calculate the angle of the face in a specific dimension. The problem is that, even though the model is moving around, (x’,y’,z’) is always the same value because the frame of reference is moving as opposed to the point.

Is this clearer?

I believe it is object coordinates, and these coordinates are being rotated by some rotation matrix, but I am not certain. How would I be able to check for certain?

You can grab the current MODELVIEW and PROJECTION matrices like this:

Unless you’re writing your own shaders and using your own matrix uniforms, then this’ll give you the transforms active at a given point in your program.

You should read a good introduction to vector math and transforms in some book. Some books are pretty sad in this area, but a few are really good. I personally like the one in Peter Shirley’s Realistic Ray Tracing the best (first edition was best).

Once you figure out how all this works, you just create an ONB (orthonormal basis) class, and then build a FrameOfRef class that uses it, pop the math in member functions, and then just use it when you want to build space transforms.


class ONB:
  vec3 u,v,w;
  ...

class FrameOfRef:
  ONB  basis;
  vec3 origin;

  void getUVWtoXYZ( mat4 &mat )
  void getXYZtoUVW( mat4 &mat );
  ...

Thanks for the response! I know how rotation and projection matrices work, but I didn’t know how to do it with OpenGL is what I meant because I didn’t know how the matrices were setup or acquired or even what they did specifically.

After reading a little here:

http://www.opengl.org/resources/faq/technical/transformations.htm

What I understand is that I should pass a vector of length 4 through the MODELVIEW matrix and then through PROJECTION so that I can get the equivalent transformation that is going on with the model. So, for instance, here is some pseudocode

float x[4];
x[0] = x[1] = x[2] = 1; x[3] = 0; //declare 1 1 1 0 vector to ignore the translation part of the matrix and only see rotation

xModel = MODELVIEW * x; //rotated matrix based on model rotation?

xChange = xModel - x; //find vector indicating direction change

//draw vector showing direction change of the vector with respect to (0,0,0).

glBegin();
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(xChange[0], xChange[1], xChange[2]);
glEnd();

Is this the right idea? Also, how would getting clip coordinates by going through PROJECTION with xModel be more useful? Is it that anything outside of the rendered window would be clipped?

Lastly, in my pseudocode, would it be right to say that the MODELVIEW matrix is constantly updated and that my constant vector [1 1 1 0] would be changed to a different value each time it passes through MODELVIEW? The reason I ask is because when I was looking at the object coordinates (I believe they were) of the vectors being drawn on the head model, and their values were unchanged at all points in time but the vectors were moving on the screen, implying a rotation and translation.

Thanks!

Dunno. Not really sure what you are doing, or trying to do.

Also, how would getting clip coordinates by going through PROJECTION … be more useful? Is it that anything outside of the rendered window would be clipped?

Close, but not quite. The idea of PROJECTION is to take you to a 4D space where you can clip to the view frustum “BEFORE” you have to do a divide, which can blow up on you and generate space flips. Once you’ve clipped, then it’s safe to do the divide and know that nothing nasty will happen.

Lastly, in my pseudocode, would it be right to say that the MODELVIEW matrix is constantly updated and that my constant vector [1 1 1 0] would be changed to a different value each time it passes through MODELVIEW? The reason I ask is because when I was looking at the object coordinates (I believe they were) of the vectors being drawn on the head model, and their values were unchanged at all points in time but the vectors were moving on the screen, implying a rotation and translation.

Depends on your application.

Aren’t you in control of the value of the MODELVIEW matrix?

What I am trying to do is use the already made software and modify it to draw where a person is looking at on a monitor. Since I know 3-D using one of their algorithms as well as rotation, as the model is rotating as I rotate my head and drawing vectors indicating orientation.

My issue is that I need to find the angle of the vectors on the screen so I can estimate a vector from the user’s head to intersect with the monitor’s plane using angle and distance. I originally thought I could simply grab the vector and compare the vector to some reference vectors (1,0,0,0) for instance. The problem is that the basis is rotating as opposed to the vectors moving. So, I need to find a way to determine rotation using the code they already have.

Would it be possible to determine angle in a specific axis by using an arbitrary vector, such as (1,1,1,0) and passing it through MODELVIEW and PROJECTION, and then comparing the output with (1,1,1,0). That’s really what I’m trying to find out how to do–how to use the already present code to extract some angle of rotation in each axis.

I’m not sure I get where you’re tapping into this thing, but here’s some thoughts.

You probably want to forget PROJECTION. Clip space doesn’t really matter much to you unless you’re getting clip space values from the software or something. Stick to the orthonormal spaces in the problem.

Of those, there are 3 basic spaces here:

EYE SPACE (origin at center of monitor, -Z out toward the scene, X right, Y up),

WORLD SPACE (the space the guy’s defined in), and

OBJECT SPACE (the space of the guy’s head; let’s say -Z is the direction he’s looking, X is to his right, and Y is up.).

Now if the MODELVIEW you’re tapping out from the software literally takes you from this OBJECT SPACE to this EYE SPACE, then you just render a constant vector of (0,0,-1) with that MODELVIEW active, and it’ll always point out from the guy’s head.

If you want to find the intersection of where the guy’s looking, simply transform the OBJECT SPACE point (0,0,0,1) (presumably the point between the guy’s eyes) and the OBJECT SPACE vector (0,0,-1,0) by that MODELVIEW, and you’ll get a point and vector in EYE SPACE. Then do the math to intersect that ray (i.e. pt + vector) against the EYE SPACE plane Z=-near. That’s the point on the near clip plane (the monitor) where the guy is looking (assuming his pupils are looking straight forward too :slight_smile:

Awesome, the numbers coming out from the MODELVIEW multiplication make sense because when I’m looking at the center of the screen X = 0 and Y = 0 and moving left to right makes sensible changes and same for up down. I can’t seem to get “near” by simply calling it so can I infer “near” by looking at

gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);

where the near plane is defined as .1f?

If that is the case, then I can find the intersection point on the screen by:

My vector is X,Y,Z

Divide Z by .1 to find a scalar indicating intersection with near plane.

divide x and y by that scalar, and I have my X and Y coordinate on the near plane?

Is that correct?

Also, I’m using glvertex3f and is drawing

glBegin(GL_LINES);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 0.0f,0.0f,0.0f);
glVertex3f( 0.0f,0.0f,1.0f);
glEnd();

as a vector in space that rotates with my head. That is because it is drawn on the model’s reference axis correct, which is worldspace?

How would I draw a point in Eye Space?

Thanks a lot for all of your help!

Yes. That’s not quite “infer” though – it’s a given :slight_smile: So in that case, Z=-0.1f is the plane of the screen in EYE SPACE.

Or more verbosely, where the general form of a 3D plane equation is Ax+By+Cz+D=0, the plane equation of the screen in eye space is 0x + 0y + 1z + nearz = 0, where nearz = 0.1.

If that is the case, then I can find the intersection point on the screen by:

My vector is X,Y,Z

Divide Z by .1 to find a scalar indicating intersection with near plane. divide x and y by that scalar, and I have my X and Y coordinate on the near plane? Is that correct?

You’re just talking about a vector here. So “intersecting” it alone doesn’t make sense.

You can’t intersect a vector with anything without a point of origin. That is you have to have a ray (point & vector). Then you can can intersect with the screen. Origin is the presumably the point between the guy’s eyes and vector is his look-direction (presumably).

Transform that ray (point and vector) from OBJECT SPACE to EYE SPACE, then plug them into the plane equation for the screen (use parametric form of a ray), and you’ll have your answer.

This ends up being simple to solve. A couple dot products and a subtract to find t, then a dot product and an add to find the intersection point. Just google intersection of line and plane.

How would I draw a point in Eye Space?

Load the identity matrix onto the MODELVIEW stack.

E.g. glMatrixMode( GL_MODELVIEW ); glLoadIdentity();, or glMatrixLoadIdentityEXT( GL_MODELVIEW );