1

(This is a similar question to extracting scale matrix from modelview matrix ) but I think it's a bit more general, so I'm reposting it.

I have a modelview matrix in WebGL, composed of a series of transformations from local object space to world space, followed by a transformation from world space to homogeneous WebGL coordinates (-1 to 1 in all directions).

This matrix is built up throughout our code over a series of convoluted steps. One of these steps is to render to a texture, and then blit the texture onto the screen. This process is extracted to be generalized so we can use it for any 2D texture painting operation. Unfortunately, it provides its own view/projection transformation. At the point at which I'm calling this, I have only the combined modelview matrix.

What I want to do is preserve the transformations made on the modelview matrix as it's built up along the way, but I don't want to include the view transformation. In other words, given a modelview matrix, and a known view transformation, is there a way to extract just the model transformation as a matrix?

We're not using perspective projection, and all of our transformations are 2-dimensional in nature, so a general solution isn't necessary (although I have had this question before when working in 3D, so something that could be extended to 3D would be really useful).

jwir3
  • 6,019
  • 5
  • 47
  • 92
  • 2
    So you're saying you know `V * M` and `V`, and you want to get `M`? Then it should be as simple as `inverse(V) * (V * M)`. – HolyBlackCat Jul 18 '18 at 21:54
  • To add to what @HolyBlackCat said, if you don't know `V` then you're out of luck. It's no different than saying A = 11, B = 12. Given the number 23 and no knowledge of A or B what was A. Without knowing V you can't know derive M. If you know V though you can remove it as @HolyBlackCat mentioned. – gman Jul 19 '18 at 03:44
  • @HolyBlackCat the modelview holds `Inverse(V)*M` the `V` is inversed there !!! – Spektre Jul 19 '18 at 08:24
  • I do in fact know the view matrix, so this is a possible option. – jwir3 Jul 19 '18 at 21:04

1 Answers1

1

If i get it right you have Inverse(V)*M inside modelview and you are building it incrementally. That means in your code you are doing something like this:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
... here M transforms ...
... here render or whatever ...

With multiple objects the stuff usually looks like this:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
for (all objects)
 {
 glPushMatrix();
 ... here M transforms ...
 ... here render or whatever ...
 glPopMatrix();
 }

So to obtain V you can do this:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
double iV[16],iVM[16];
glGetDoublev(GL_MODELVIEW_MATRIX,iV);
for (all objects)
 {
 glPushMatrix();
 ... here M transforms ...
 glGetDoublev(GL_MODELVIEW_MATRIX,iVM);
 ... here render or whatever ...
 glPopMatrix();
 }

now:

    iVM =   iV*M
V * iVM = V*iV*M
V * iVM =      M

where V = Inverse(iV) holds the direct view matrix and M holds the direct model matrix. As OpenGL does not have inverse matrix you can do it by transpose + position computation see:

see the matrix_inv function in there so the result would be:

double M[16],V[16];
matrix_inv(V,iV);
matrix_mul(M,V,iVM);

Where matrix_mul code you can find in here:

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • This is not an OpenGL question. There is no such thing as `glMatrixMode`, `glPushMatrix` etc in WebGL. In fact in OpenGL those functions have been deprecated for over 10 years. – gman Jul 19 '18 at 14:51
  • @gman You're right, but this question is more generally about how to get the inverse matrix. Even though the functions don't exist, the process might work. – jwir3 Jul 19 '18 at 21:01
  • @jwir3 I do not code for WEBGL but it does not matter which api you use the mechanism is the same. You just need to keep in check which matrix is direct and which is inverse and what the multiplication order is ... btw. I know the old GL api is depreceated and I use the new one too but the old one is easier to make examples and more reliable as the new stuff is often buggy due to bad drivers. – Spektre Jul 19 '18 at 21:47
  • 1
    Even though the question wasn't about OpenGL, I'm accepting this answer because the theory is sound and I successfully applied it to WebGL. – jwir3 Jul 24 '18 at 16:24