简体   繁体   中英

Can't rotate object from other place that isn't origin point

I know that the supposed way to make this as simple as possible is to use:

glTranslate(a,b,c);
glRotate(...);
glTranslate(-a,-b,-c);

But in this case I'm using buffers to make things more clear and fast, the thing is that I'm doing the equivalent which is:

iMat4x4 tempModel;
iMat4x4 tempModel2;


tempModel = math::translate(tempModel, iVec3(0.5f * size.x, 0.5f * size.y, 0.0f));
model[3].z = model[3].w = 0;
model[3] = model[3] + tempModel[3];

model = math::rotate(model, rotation, iVec3(0.0f, 0.0f, 1.0f));

tempModel2 = math::translate(tempModel2, iVec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
model[3].z = model[3].w = 0;
model[3] = model[3] + tempModel2[3];

But still, when I do something like object->rotation = sin(Time::WorldTime) I get the object rotating from the upper left corner.

Also, what is supposed to be the objective of moving the object to the origin before rotating, the rotation matrix has no effect wether I change it, and the 4th Column of the matrix is not multiplied in any way with the rotation matrix, just placed where it was before...

Adding the translational matrix's elements is not equivalent to multiplying by the corresponding translation matrix, the latter being the correct way to apply the translation.


Explanation

[Rotation matrix R , translation offset t - matrix T , model point p .]

Directly adding the translation matrix T is equivalent to pre-multiplying by it, which means the offset is added to the output point:

p --> R*p + t
  ( = T*R*p )

So the final point is:

p' = R*p - t + t = R*p
 ( = T*inv(T)*R )

The translation matrix and its inverse (offset by -t ) cancel each other out, and you are left with an effective rotation about the origin.

On the other hand, post-multiplying by the translation matrix is equivalent to pre-applying the translation:

p --> R*(p - t)
  ( = R*inv(T)*p )

So the correct final point is:

p' = R*(p - t) + t
 ( = T*R*inv(T)*p )

Note that the effective offset does not cancel out because T and inv(T) are not next to each other in the expression.


Correct code

model_final = tempModel1 * model * tempModel2;
            //    T      *   R   *   inv(T)

(Or using whichever one of your library's functions that multiplies the matrices in the "conventional" way as above)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM