Jump to content
  • Advertisement
Sign in to follow this  
bah

OpenGL How does OpenGL calculate the inverse of a matrix?

This topic is 4979 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

As you specify simple transformations (i.e. rotation, translation and scaling) OpenGL can quickly and easily calculate the inverse for transforming the normals. But how does it calculates the inverse of a matrix that you loaded with glLoadMatrixf()?

Share this post


Link to post
Share on other sites
Advertisement
There are two 'common' methods to inversing matrices. For small matrices (like transformations) you can compute the 'adjoint' matrix and multiply it with the inverse determinant. For larger matrices, usually Gauss-Jordan elimination is used to solve AX = I.

Greetz,

Illco

PS: but I don't know about what GL does on the inside!

Share this post


Link to post
Share on other sites
Unfortunately, the matrices I need to inverse are 4x4 composite and represent all three basic transformations. I just want my implementation to produce identical results to those of OpenGL.

Share this post


Link to post
Share on other sites
4x4 is still relatively small. I use this:

inline float &Matrix::operator()(int i, int j)
{
return m[i - 1][j - 1];
}

Matrix Matrix::inverse()
{
const Matrix &M = *this;
Matrix I;

float M3344 = M(3, 3) * M(4, 4) - M(4, 3) * M(3, 4);
float M2344 = M(2, 3) * M(4, 4) - M(4, 3) * M(2, 4);
float M2334 = M(2, 3) * M(3, 4) - M(3, 3) * M(2, 4);
float M3244 = M(3, 2) * M(4, 4) - M(4, 2) * M(3, 4);
float M2244 = M(2, 2) * M(4, 4) - M(4, 2) * M(2, 4);
float M2234 = M(2, 2) * M(3, 4) - M(3, 2) * M(2, 4);
float M3243 = M(3, 2) * M(4, 3) - M(4, 2) * M(3, 3);
float M2243 = M(2, 2) * M(4, 3) - M(4, 2) * M(2, 3);
float M2233 = M(2, 2) * M(3, 3) - M(3, 2) * M(2, 3);
float M1344 = M(1, 3) * M(4, 4) - M(4, 3) * M(1, 4);
float M1334 = M(1, 3) * M(3, 4) - M(3, 3) * M(1, 4);
float M1244 = M(1, 2) * M(4, 4) - M(4, 2) * M(1, 4);
float M1234 = M(1, 2) * M(3, 4) - M(3, 2) * M(1, 4);
float M1243 = M(1, 2) * M(4, 3) - M(4, 2) * M(1, 3);
float M1233 = M(1, 2) * M(3, 3) - M(3, 2) * M(1, 3);
float M1324 = M(1, 3) * M(2, 4) - M(2, 3) * M(1, 4);
float M1224 = M(1, 2) * M(2, 4) - M(2, 2) * M(1, 4);
float M1223 = M(1, 2) * M(2, 3) - M(2, 2) * M(1, 3);

// Adjoint Matrix
I(1, 1) = M(2, 2) * M3344 - M(3, 2) * M2344 + M(4, 2) * M2334;
I(2, 1) = -M(2, 1) * M3344 + M(3, 1) * M2344 - M(4, 1) * M2334;
I(3, 1) = M(2, 1) * M3244 - M(3, 1) * M2244 + M(4, 1) * M2234;
I(4, 1) = -M(2, 1) * M3243 + M(3, 1) * M2243 - M(4, 1) * M2233;

I(1, 2) = -M(1, 2) * M3344 + M(3, 2) * M1344 - M(4, 2) * M1334;
I(2, 2) = M(1, 1) * M3344 - M(3, 1) * M1344 + M(4, 1) * M1334;
I(3, 2) = -M(1, 1) * M3244 + M(3, 1) * M1244 - M(4, 1) * M1234;
I(4, 2) = M(1, 1) * M3243 - M(3, 1) * M1243 + M(4, 1) * M1233;

I(1, 3) = M(1, 2) * M2344 - M(2, 2) * M1344 + M(4, 2) * M1324;
I(2, 3) = -M(1, 1) * M2344 + M(2, 1) * M1344 - M(4, 1) * M1324;
I(3, 3) = M(1, 1) * M2244 - M(2, 1) * M1244 + M(4, 1) * M1224;
I(4, 3) = -M(1, 1) * M2243 + M(2, 1) * M1243 - M(4, 1) * M1223;

I(1, 4) = -M(1, 2) * M2334 + M(2, 2) * M1334 - M(3, 2) * M1324;
I(2, 4) = M(1, 1) * M2334 - M(2, 1) * M1334 + M(3, 1) * M1324;
I(3, 4) = -M(1, 1) * M2234 + M(2, 1) * M1234 - M(3, 1) * M1224;
I(4, 4) = M(1, 1) * M2233 - M(2, 1) * M1233 + M(3, 1) * M1223;

// Division by determinant
I /= M(1, 1) * I(1, 1) +
M(2, 1) * I(1, 2) +
M(3, 1) * I(1, 3) +
M(4, 1) * I(1, 4);

return I;
}


Sorry for the weird indexing, I kindof like using the mathematical conventions...

Share this post


Link to post
Share on other sites
Shouldn't you check to see if the determinate is 0 before doing the division? Last I checked dividing by 0 is not a good thing and sometimes determinates are 0. ;)


-SirKnight

Share this post


Link to post
Share on other sites
I've always been curious about that myself SirKnight.

Assuming the only matrices you'll be dealing with are "translate" and "rotate" operation matrices, and combinations thereof, is it possible to ever get to a matrix that can't be inverted?

I think once you start getting into projectino matrices, etc, then it's more than likely to happen, but if you can restrict yourself to modelview operations, will you ever get a non-invertable matrix?

just curious.
/not-a-math-guy

Share this post


Link to post
Share on other sites
I'm fairly certain that a matrix restricted to rotation, translation, non-zero scaling, and shear will always be invertable. Also, such matrices can be inverted more cheaply than in the general case.

If your matrix contains only translation, rotation, and perhaps uniform non-zero scaling (not positive about the last one), the inverse can be found even more cheaply, using trivial operations only.

Share this post


Link to post
Share on other sites
To expand on the inversion of a matrix, check out this. This is a coded version of what jyk said. This is much faster too (assuming you aren't non-uniformly scaling).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!