Appropriate Multiplication of Matrices for Rotation/Translation

Appropriate multiplication of matrices for rotation/translation

[SOLVED]
java floating point errors were the only cause

M = T * I * T[inv]

did not result into an identity matrix,
so instead of using Matrix.MultiplyMM

I type all the multiplications between the matrices

Matrix / vector multiplication order

Your C++ matrices are probably stored as row major under the hood. Which means that multiplying them from left to right is an "origin" transformation, while right to left would be a "local" incremental transformation.

OpenGL however uses a column major ordering memory layout (The 13th, 14th and 15th elements in the 16 element array are treated as the translation component).

To use your row major matrices in OpenGL, there are 2 things you can do:

  1. glUniformMatrix* functions, have a parameter to pass in a GL_TRUE to the transpose:

void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

This will re-arrange them to be column major.


  1. The other is to revert the ordering of operations in the shader:

gl_Position = vec4(a_Position, 0.0, 1.0) * u_Matrix;

But most GLSL literature you will find will use local left to right column major ordering, so it may be better to stick with that.

Another alternative is to change the layout on the C++ side to make them column major (but I personally think row major is easier to deal with there).

Apply transformations on matrix instead of rotation and translation

You could if your transformations were a series of rotations, because you could multiply them together and then apply that matrix.

You could uf your transformations were a series of translations, because then you could add them together and add the result.

The best you can do is:

A = R*B + T

Algebra makes this clear:

A = R(1)*R(2)*...*R(n)*B + (T(1)+T(2)+....+T(m))

Transformation Matrix Multiplication by matrix type, C++

I think a better idea is to store only position and orientation of an object instead of the whole matrix. You only compute the matrix for rendering purpose, once after all transformations. The transformations are done by adding translations (for the position) and multiplying quaternions (for the orientation).

Rotation, Translation and Default Camera Location

I think the order in which the matrices are written in the code somewhat obfuscates the intent, so I've boiled down what's actually happening into the following pseudocode to make it easier to explain.

I've replaced that last matrix with the one from the template, since your modification just has the effect of doubling the rotation about the Y axis.

modelViewMatrix = identity *
translate(0, 0, 5) *
rotate(angle, axis(0, 1, 0)) *
rotate(angle, axis(1, 1, 1))

Since the matrix is multiplied on the left of the vector in the shader, we're going to read the matrices from right to left to determine their cumulative effect.

First, we rotate the cube around the axis (1, 1, 1), which passes diagonally through the origin. Then, we rotate about the cube about the Y axis. These rotations combine to form a sort of "tumble" animation. Then, we translate the cube by 5 units along the +Z axis (which, as you observe, goes into the screen since we're regarding our world as left-handed). Finally, we apply our camera transformation, which is hard-coded to be the identity matrix. We could have used an additional positive translation along +Z as the camera matrix to move the cube even further from the camera, or a negative value to move the cube closer.

To answer your questions:

  1. There is no default location for the camera, other than the origin (0, 0, 0) if you want to think of it like that. You "position" the camera in the world by multiplying the vertex positions by the inverse of the transformation that represents how the camera is placed in the world.

  2. Model I/O builds meshes that are "centered" around the origin, to the extent this makes sense for the shape being generated. Cylinders, ellipsoids, and boxes are actually centered around the origin, while cones are constructed with their apex at the origin and their axis extending along -Y.

  3. The rotation doesn't really involve the translation as much as it's combined with it. The reason for the translation is that we need to position the cube away from the camera; otherwise we'd be inside it when drawing.

One final note on order of operations: If we applied the translation before the rotation, it would cause the box to "orbit" around the camera, since as you note, rotations are always relative to the origin of the current frame of reference.

How to translate based on origin / world space with homogenous matrix

In this case, try applying left-multiplication. As you're probably aware, matrix multiplication is not commutative in general. AB is not the same as BA. If you multiply with the translation matrix on the left and the object transform on the right, you'll likely get it.



Related Topics



Leave a reply



Submit