1

Ok so i know when i call glRotatef() it does this,

C = C * M

where "C" is the current matrix on the stack, and "M" is the matrix computed by glRotatef(). However this causes the object to rotate around its local-axis. If i want to rotate the object around its global axis I'd have to do

 C = M * C

so for example if i wanted to rotate around global x, then global y, then global z. it'd be

C = Mz * My* Mx * C

I have tested it and it works. I wanna know the reason why do we have to premultiply for global rotation and vice versa.

The "C" in my case is the modelview matrix. Do Note i am not talking about pre multiplying matrices with vectors. I know all the column major - row major stuff. I wanna know the consequences of pre/post multiplying a transformation to another matrix4x4.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
gallickgunner
  • 472
  • 5
  • 20
  • These just state that you have to premultiply for global rotation and i wanna know why you are doing that and not the other way around. I think it has something to do with basis transforms and the internal representation of the space. How does OGL knows "I have to rotate around global axes since its premultiplication" – gallickgunner Aug 15 '17 at 09:18
  • 1
    @Rabbid76: It is a mathematics question, but it's one specific to graphics programming. – Nicol Bolas Aug 15 '17 at 15:44

2 Answers2

2

At its core, a transformation matrix is a function that converts positions/directions from space I to space O: input to output. And therefore, transformations behave a lot like function composition. There is a difference between f(g(X)) and g(f(X)).

So you start with is a matrix C that, given a vertex Vi which is in space I, this will be true: Vo = C * Vi, where Vo is the vertex in the space O.

So, let's go back to your original example: C = C * M. To cut down on confusion (I need to talk about the original C and the output), I'm going to give the new matrix a particular name: D = C * M.

The space I, the input space for C was a particular model space. You're now adding a new transformation to this, which had its own input and output spaces. And by multiplying them together to form a single transformation, you are declaring something:

That Mo, the output space of M, is the same space as Ci, C's input space. Therefore, we are now dealing with three spaces: Mi, Mo/Ci, and Co.

However, D is a composition of those transforms. It goes from the space Mi to the space Co; we never see Mo/Ci. The difference between C and D is their input spaces.

Here's the thing: the space Co, C's output space? It has a particular name: world space.

Therefore, D goes to the exact same world space as C did. So it should be no surprise that right-multiplying won't cause a rotation around world space.

So let's look at this: E = M * C. Here, we have a different situation. E has the same input space (model space) as C, but it now has a different output space. That is, the world space that E transforms into is different from the world space that C transformed into.

And that's exactly what you want if you want to rotate something relative to world space. You are changing world space for that object.

If you change the model space for a transform, you are transforming relative to model space. If you change the world space for a transform, you are transforming relative to world space.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thanks for answering and i feel like this is much closer to what i was expecting. Some things i don't understand. What is the Input space for `M` in the case `D = C * M` Isn't it the model space? – gallickgunner Aug 15 '17 at 16:04
  • @wandering-warrior: Think of the names for spaces like the names for variables. They're useful to people, but they don't change the *math*. `Co` is world space because we *say* that it's world space and treat it as world space. But `C` has no real knowledge of "world space"; it's just a transform from one space to another. Same goes for `M`. If we declare that `D` is a transform from model to world space, then we are simultaneously declaring that `Mi` is the new model space for `D`. But that's a conceptual choice, not an intrinsic property of `D` or `M`. – Nicol Bolas Aug 15 '17 at 16:07
  • Then this means it is intuitive for us to think that rotation matrices have the same input and output space? Like in case `D = C * M` M takes vertices in model space and returns vertices in model space and in `D = M * C` it takes vertices in world space and returns the modified vertices in world space hence the rotation around global axes? – gallickgunner Aug 15 '17 at 16:14
  • @wandering-warrior: No, only the *identity* matrix has the same input and output space. Every matrix transforms from its input space to its output space. What we call those spaces *does not matter*. Just like it doesn't matter what you name your variables. If you want to call `Mo` "mid-model-space" or "left-hip space" or "some name I just made up space", that's fine. But `M` has an output space. – Nicol Bolas Aug 15 '17 at 16:20
  • ok i get what you are trying to say xD Thanks for giving a unique and broader answer. Can you recommend some books to polish these mathematical concepts? I've read some graphics but they don't approach maths from the maths pov. I mean the focus only from the graphics point of view. – gallickgunner Aug 15 '17 at 16:23
  • And i know it doesn't sound right but i have one more question i am really stuck on :) if you can help i'd appreciate it. https://stackoverflow.com/questions/45652366/gimbal-lock-how-does-it-happen – gallickgunner Aug 15 '17 at 16:24
1

Let's start with global coordinates system. You have a point V(x,y,z,w) in that first system.

Next you do a rotation over an axis. The rotation is defined in a matrix M1. Think of rotating the axis, not the point. The same point V can now be expressed in this new coordinates system as V'(x', y', z', w'). We know that we can get these new coordinates by
V' = M1·V using col-mayor order and being V a 4x1 matrix.

Next we want a second rotation around likely other axis. M2 is the rotating matrix. But wait, are we going to rotate relative to the second system or to first one?

V" = M2·V

or

V" = M2·V'

"No", you say, "relative to the second, already rotated coordinates system."
OK. So you have:

V" = M2·V'  = M2·(M1·V) = (M2·M1)·V  but **NOT=** (M1·M2)·V

The key is that you apply a transform matrix to a previous system. The order you apply several transformations is NOT commutative. As an example, try 'first translate and then rotate' versus 'first rotate and then translate'.

Rotating a point by an angle alpha or rotating the axis by the opposite -alpha produces the same final coordinates. In other words, you do same matrix operations.

Then with your C,M nomenclature, let's get the difference between C·M and M·C
V1 = C·V0 transforms from local object axis to global axis
V2 = M·V0 rotates (transform) in local object axis
V3 = M·V1 = M·C·V0 rotates after transform to global, this is, in global axis
V4 = C·V2 = C·M·V0 transform after rotating in local

Noticed I wrote matrix operations for column-mayor order.

Ripi2
  • 7,031
  • 1
  • 17
  • 33