Saturday, October 24, 2015

opengl - Combining rotation,scaling around a pivot with translation into a matrix



In short: I need to combine rotation (in the form of a quaternion), scaling around a pivot point along with translation into a transformation matrix.


The long: I am trying to implement a proprietary model format. This format includes animations. Part of that animation involves generating a matrix which combines rotation (in the form of a quaternion) and scaling around a pivot point, with translation into a transformation matrix. I am using OpenGL and the OpenGL math library (GLM)


Someone else has already implemented parts of the proprietary model format using DirectX. The part in question was implemented in directX like this:


D3DXMatrixTransformation(&BaseMatrix, &ModelBaseData->PivotPoint, NULL, &ScalingVector, &ModelBaseData->PivotPoint, reinterpret_cast(&RotationVector), &TranslationVector);

I found the WINE implementation of this function and attempted to duplicate it like this:


mat4 m1, m2, m3, m4, m5, m6, m7, p1, p2, p3, p4, p5;

m5 = glm::translate(0,0,0);
m7 = glm::translate(pivot+translationVector);

m1 = glm::translate(-pivot);
m3 = glm::scale(scalingVector);
m6 = glm::mat4_cast(rotationQuaternion); //Convert quaternion to a matrix

//m2 & m4 are identity
p1 = m1;// * m2
p2 = p1 * m3; //Apply scaling first
p3 = p2;// * m4;
p4 = p3 * m5;
p5 = p4;

p5 = p4 * m6;
mat4 result = p5 * m7;

(I realize glm::translate(0,0,0) is the identity matrix) Unfortunately neither the scaling nor the rotation seems to work correctly like this. So I took another approach based off of this ordering of translation, rotation and scaling.


mat4 result = glm::scale(scalingVector) * glm::translate(pivot) * glm::mat4_cast(rotationQuaternion) * glm::translate(translationVector);

However the scaling does not appear to be around the pivot point and I'm not entirely sure about the rotation. Does anyone have any tips on how to accomplish this?



Answer



Rotation/scaling is around the origin. To both scale/rotate around a pivot, you apply a negative translation to move the pivot point to the origin, apply your scale and rotate, and then move your pivot point back.


mat4 result = glm::translate(-pivot) *

glm::scale(..) *
glm::rotate(..) *
glm::translate(pivot) *
glm::translate(..);

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...