# gMultMatrixf causing issues over time

I am using a physics engine that gives a matrix for the placing of different objects, so I made the following draw code, but the world slowly deteriorates.

float matrix;
body->getTransform().getOpenGLMatrix(matrix);
gMultMatrixf(matrix);

//draw object

body->getTransform().getInverse().getOpenGLMatrix(matrix);
gMultMatrixf(matrix);

I think it might be that the inverse is not the exact inverse of the matrix due to floating-point precision. I really appreciate the help because I have been ignoring the issue for a long time now because I have not to figure out a fix.

The issue is with accumulated rounding error. A matrix generated by `glRotate` (or similar) should be orthonormal (all axes mutually perpendicular and of unit length) but due to the finite precision of floating-point numbers it won’t be exactly orthonormal. Composing two not-quite-orthonormal matrices produces something that’s even farther from orthonormal. If you do this every frame, eventually the deviation will become visible, particularly if you’re using single precision floating-point (the “decay” occurs much more slowly with double precision).

The solution is to periodically regenerate the matrix, forcing the axes to have unit length and to be mutually perpendicular. Restoring the length is simple enough, maintaining orthogonality can be achieved via the Gram-Schmidt process or by using cross products. For a view matrix, you typically want to retain the Z axis direction, then calculate X=cross(Y,Z), Y=cross(Z,X). For a 4x4 matrix, regenerate the upper-left 3x3 submatrix as above, force the bottom row to be [0,0,0,1] if necessary (it probably isn’t), and leave the right-hand column (translation) alone.

A made it so they every time it multiplies the matrix it undoes it by storing the matrix before and setting it after. Now it works perfectly. Thank you for the quick response and the help of fixing the problem.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.