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