# Confused: local to world space?

## Recommended Posts

awdorrin    100
I may not be using the right terms, which may be why I'm not finding an answer, but I'm not sure how to convert a coordinate from a local space to the world space. For instance, lets say I do the following:
gluLookAt( pos.x, pos.y, pos.z, view.x, view.y, view.z, up.x, up.y, up.z);
glPushMatrix();
glTranslated( relative.x, relative.y, relative.z);
glBegin(GL_POINT);
glVertex3d(0,0,0);
glEnd()
glPopMatrix();

So my question is, after I draw the point at the relative location, how can I determine the location of that point back to the 'world coordinate space' ? I'm fairly certain there would be some matrix operation(s) to do this, however I have been trying to figure out a solution, and assume I'm not using the right search terms to narrow things down. I have myself rather confused so I'm hoping maybe this is something incredibly obvious that I'm just missing. :-( Thanks in advance to anyone that can point me in the right direction.

##### Share on other sites
The graphics pipeline uses the various matrices to calculate screen position from your model-space vertices. The screen coordinates (before the homogenous normalization operation and clipping that the pipeline does) from a vertex is usually calculated by the product of the model-view-projection matrix with the vertex vector.

Vec_screen = Proj * View * Model * Vec_model
where Proj is the projection matrix, View is the view matrix, and Model is the model matrix. The thing to understand is that each of these matrices transforms coordinates from a certain space to another. It helps to look at it from right to left. Model matrix transforms model vertices to world-space coordinates (this accounts for the position, scale and rotation of the object in the world), view matrix transforms world coordinates into coordinates relative to the camera and its orientation. Projection matrix scales coordinates closer to the camera to achieve a perspective effect to transform into screen-space coordinates.

Now, you are trying to find world-space coordinates from screen-space coordinates (assuming you have the depth value as well) You just need to undo the projection and view transformations! This means multiplying by the inverse projection and view matrices.

Vec_world = View_inv * Proj_inv * Vec_screen

Unfortunately for you, OpenGL doesn't have separate model and view matrices. Instead, you are supposed to work with a single matrix that represents the product of the two, namely the modelview matrix. (View * Model) You would have to calculate the inverse view and projection matrices themselves.

##### Share on other sites
awdorrin    100
I came across the 'gluUnProject()' function and it appears that it provides the answer I was looking for.

Using the example I showed in my first post, I did the following (simplified C# code):

gluLookAt( pos.x, pos.y, pos.z, view.x, view.y, view.z, up.x, up.y, up.z);glPushMatrix();glTranslated( relative.x, relative.y, relative.z);glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);glGetInteverv(GL_VIEWPORT, viewPort);gluUnProject(0,0,0, modelMatrix, projMatrix, viewPort, out x, out y, out z);glBegin(GL_POINT);glVertex3d(0,0,0);glEnd()glPopMatrix();Vector3 locAsWorldCoord = new Vector3(-x, -y, -z);

So far this seems like its giving me the answer I need, and matches up with your (really good) description, Thanks!

##### Share on other sites
haegarr    7372
Uhh, I'm not happy with that solution since gluUnProject computes a transformation INV(PM) where P denotes the projection matrix and M the modelview matrix. Assuming that really the local-to-global transformation is the thing you're looking for, then:

1. The projection matrix has absolutely nothing to do with the local-to-global transformation. If at all, use a P to be the identity matrix instead of what glGetDoublev(GL_PROJECTION_MATRIX, ...) gives you.

2. The modelview transformation contains not only the model transformation (what is the same as the local-to-global transformation looking for) but the view transformation as well (what means that the inverse camera transformation is incorporated).

3. Even if considering both points above, gluUnProject would apply INV(M), in other words the inverse model transformation (i.e. the global-to-local transformation). Reverting this by negating the resulting point vector works if and only if nothing else than translation was used in the model matrix.

That said, if you want to compute the local-to-global transformation, your best choice is to ignore OpenGL's matrix stack totally for this purpose, and handle the matrices yourself. If you don't want to do so, then at least glGetDoublev the modelview matrix just after setting up the view matrix portion, and glGetDoublev it also after you've applied the model transformation. Then you've V and V*M, so you need to compute the inverse of V and multiply it so that
V-1 * V * M = M
is the transformation matrix you're looking for.

[Edited by - haegarr on February 17, 2010 9:27:05 AM]

##### Share on other sites
awdorrin    100
I think I understand what you are saying.

Thing is, I am using C# and the Tao Framework currently, so I have no Matrix classes. Guess its time to port to use the OpenTk libraries. I think they have Matrix classes included...

##### Share on other sites
awdorrin    100
Eh, after taking some time, it looks like migrating from Tao Framework to OpenTk will not be straight forward... so I guess its time to find a Matrix class to see if I can work through this with what I have...