Shazad Maved Shazad Maved - 3 months ago 24
C++ Question

How to convert local object coordinates to world coordinates?

I need a simple way to convert my objects coordinate into world coordinates, so that a can locate them in that coordinate system and do collision detection?


First, some background. In 3D graphics, you need to worry about several vector spaces:

  • Model space - these are usually the coordinates you specify to OpenGL
  • World space - coordinates are specified with respect to some central point in the world.
  • View space - coordinates are specified with respect to the camera
  • Projection space - everything on the screen fits in the interval [-1, +1] in each dimension.

Coordinates are specified homogeneously, so each vector has components (x, y, z, w), where w is a scaling factor. You can obtain coordinates in 3-space as (x/w, y/w, z/w). The scaling factor is needed for certain transformations like perspective projection that wouldn't be possible with non-homogenous coordinates.

4x4 matrices are needed to transform coordinates from one vector space to another. You could have three different matrices:

  • Model matrix (model to world)
  • View matrix (world to view)
  • Projection matrix (view to projection space)

You would project a coordinate C onto the screen using the formula:

C' = P * V * M * C

OpenGL internally maintains two matrices: modelview (model and view multiplied together), and projection. There is also a texture matrix we won't worry about. When you call glMatrixMode, you are switching between these matrices. You replace the current matrix with the identity matrix using glLoadIdentity. You apply transformations to the current matrix with functions like glTranslatef, glRotatef, or gluProjection. Each of these functions just creates a 4x4 matrix the implements that specific transformation, then multiplies the current matrix by it. You can see what the transformation matrices are in the OpenGL 2.1 reference pages.

Now for the actual answer. You need to maintain a 4x4 model matrix for each object in your scene. The model matrix will contain all the transformations needed to change model coordinates into world coordinates. For instance, every time you call glTranslate, you would update your model matrix:

T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T

You can then use your model matrix to get coordinates into world space (make sure they are homogenous coordinates first; just set w = 1, if they aren't):

V' = V * M

Since you are maintaining these transformations in parallel, you don't actually need to maintain the OpenGL modelview matrix anymore. You can pass in your model matrix as a uniform to your shaders. You can maintain your own view and projection matrices in similar ways. This is required in recent versions of OpenGL; all of the matrix handling functions are deprecated.