/*=========================================================================== transformmatrix.cpp Created: October 16, 2000 Auuthor: Bryan Brandt Copyright (c) 2000 Radical Entertainment, Inc. All rights reserved. ===========================================================================*/ //#include //#include //#include //#include //#include //#include //#include //#include #include "transformmatrix.h" TransformMatrix::TransformMatrix(): rotateOrder(ORDER_XYZ) { SetIdentity(); } TransformMatrix::TransformMatrix(const MDagPath& dagPath): rotateOrder(ORDER_XYZ) { SetIdentity(); Assign(dagPath); } TransformMatrix::TransformMatrix(const MTransformationMatrix& xform): rotateOrder(ORDER_XYZ) { SetIdentity(); Assign(xform); } bool TransformMatrix::Assign(const MDagPath& dagPath) { MStatus status; MObject node = dagPath.node(&status); if (!status) return false; if (node.hasFn(MFn::kJoint)) { MDagPath tmpDagPath = dagPath; return AssignJoint(tmpDagPath, node); } else if (node.hasFn(MFn::kTransform)) { MFnTransform xformNode(dagPath, &status); if (!status) return false; MTransformationMatrix xform = xformNode.transformation(&status); if (!status) return false; return Assign(xform); } return false; } bool TransformMatrix::AssignJoint(MDagPath& dagPath, MObject& node) { MStatus status; MFnIkJoint jointNode(node, &status); if (!status) return false; double tmp[3]; MQuaternion tmpQuat; MEulerRotation tmpEuler; MVector tmpVector; scalePivot.x = 0.0f; scalePivot.y = 0.0f; scalePivot.z = 0.0f; status = jointNode.getScale(tmp); if (!status) return false; scaleX = (float)tmp[0]; scaleY = (float)tmp[1]; scaleZ = (float)tmp[2]; // we've officially updated a scale dependency, // so set the scale matrix dirty flag scaleDirty = true; shearXY = 0.0f; shearXZ = 0.0f; shearYZ = 0.0f; scalePivotTranslate.x = 0.0f; scalePivotTranslate.y = 0.0f; scalePivotTranslate.z = 0.0f; rotatePivot.x = 0.0f; rotatePivot.y = 0.0f; rotatePivot.z = 0.0f; // we've officially updated a hierarchy dependency, // so set the hierarchy matrix dirty flag hierarchyDirty = true; status = jointNode.getScaleOrientation(tmpQuat); if (!status) return false; tmpEuler = tmpQuat.asEulerRotation(); tmpEuler.reorderIt(MEulerRotation::kXYZ); rotateAxisX = (float)tmpEuler.x; rotateAxisY = (float)tmpEuler.y; rotateAxisZ = (float)tmpEuler.z; MTransformationMatrix::RotationOrder ro; jointNode.getRotation(tmp, ro); switch (ro) { case MTransformationMatrix::kXYZ: rotateOrder = ORDER_XYZ; break; case MTransformationMatrix::kYZX: rotateOrder = ORDER_YZX; break; case MTransformationMatrix::kZXY: rotateOrder = ORDER_ZXY; break; case MTransformationMatrix::kXZY: rotateOrder = ORDER_XZY; break; case MTransformationMatrix::kYXZ: rotateOrder = ORDER_YXZ; break; case MTransformationMatrix::kZYX: rotateOrder = ORDER_ZYX; break; default: return false; } rotateX = (float)tmp[0]; rotateY = (float)tmp[1]; rotateZ = (float)tmp[2]; rotatePivotTranslate.x = 0.0f; rotatePivotTranslate.y = 0.0f; rotatePivotTranslate.z = 0.0f; status = jointNode.getOrientation(tmpEuler); tmpEuler.reorderIt(MEulerRotation::kXYZ); jointOrientX = (float)tmpEuler.x; jointOrientY = (float)tmpEuler.y; jointOrientZ = (float)tmpEuler.z; // default inverseScale to identity inverseScaleX = 1.0f; inverseScaleY = 1.0f; inverseScaleZ = 1.0f; // retrieve the segment scale compensate attribute MFnDependencyNode depNode(node, &status); if (!status) return false; MPlug plug = depNode.findPlug("segmentScaleCompensate", &status); if (!status) return false; bool segmentScaleCompensate; status = plug.getValue(segmentScaleCompensate); if (!status) return false; // if we are compensating for parent scale, do so if (segmentScaleCompensate) { plug = depNode.findPlug("inverseScaleX", &status); if (!status) return false; status = plug.getValue(inverseScaleX); if (!status) return false; if (inverseScaleX != 0.0f) inverseScaleX = (1.0f / inverseScaleX); plug = depNode.findPlug("inverseScaleY", &status); if (!status) return false; status = plug.getValue(inverseScaleY); if (!status) return false; if (inverseScaleY != 0.0f) inverseScaleY = (1.0f / inverseScaleY); plug = depNode.findPlug("inverseScaleZ", &status); if (!status) return false; status = plug.getValue(inverseScaleZ); if (!status) return false; if (inverseScaleZ != 0.0f) inverseScaleZ = (1.0f / inverseScaleZ); } tmpVector = jointNode.translation(MSpace::kWorld, &status); if (!status) return false; translate.x = (float)tmpVector.x; translate.y = (float)tmpVector.y; translate.z = (float)tmpVector.z; return true; } bool TransformMatrix::Assign(const MTransformationMatrix& xform) { MStatus status; MPoint tmpPoint; double tmpArray[3]; MQuaternion tmpQuat; MEulerRotation tmpEuler; MVector tmpVector; tmpPoint = xform.scalePivot(MSpace::kWorld, &status); if (!status) return false; scalePivot.x = (float)tmpPoint.x; scalePivot.y = (float)tmpPoint.y; scalePivot.z = (float)tmpPoint.z; // we've officially updated a scale dependency, // so set the scale matrix dirty flag scaleDirty = true; status = xform.getScale(tmpArray, MSpace::kWorld); if (!status) return false; scaleX = (float)tmpArray[0]; scaleY = (float)tmpArray[1]; scaleZ = (float)tmpArray[2]; status = xform.getShear(tmpArray, MSpace::kWorld); if (!status) return false; shearXY = (float)tmpArray[0]; shearXZ = (float)tmpArray[1]; shearYZ = (float)tmpArray[2]; tmpPoint = xform.scalePivotTranslation(MSpace::kWorld, &status); if (!status) return false; scalePivotTranslate.x = (float)tmpPoint.x; scalePivotTranslate.y = (float)tmpPoint.y; scalePivotTranslate.z = (float)tmpPoint.z; tmpPoint = xform.rotatePivot(MSpace::kWorld, &status); if (!status) return false; rotatePivot.x = (float)tmpPoint.x; rotatePivot.y = (float)tmpPoint.y; rotatePivot.z = (float)tmpPoint.z; // we've officially updated a hierarchy dependency, // so set the hierarchy matrix dirty flag hierarchyDirty = true; tmpQuat = xform.rotationOrientation(); tmpEuler = tmpQuat.asEulerRotation(); tmpEuler.reorderIt(MEulerRotation::kXYZ); rotateAxisX = (float)tmpEuler.x; rotateAxisY = (float)tmpEuler.y; rotateAxisZ = (float)tmpEuler.z; MTransformationMatrix::RotationOrder ro = xform.rotationOrder(); switch (ro) { case MTransformationMatrix::kXYZ: rotateOrder = ORDER_XYZ; break; case MTransformationMatrix::kYZX: rotateOrder = ORDER_YZX; break; case MTransformationMatrix::kZXY: rotateOrder = ORDER_ZXY; break; case MTransformationMatrix::kXZY: rotateOrder = ORDER_XZY; break; case MTransformationMatrix::kYXZ: rotateOrder = ORDER_YXZ; break; case MTransformationMatrix::kZYX: rotateOrder = ORDER_ZYX; break; default: return false; } tmpQuat = xform.rotation(); tmpEuler = tmpQuat.asEulerRotation(); switch (rotateOrder) { case ORDER_XYZ: tmpEuler.reorderIt(MEulerRotation::kXYZ); break; case ORDER_YZX: tmpEuler.reorderIt(MEulerRotation::kYZX); break; case ORDER_ZXY: tmpEuler.reorderIt(MEulerRotation::kZXY); break; case ORDER_XZY: tmpEuler.reorderIt(MEulerRotation::kXZY); break; case ORDER_YXZ: tmpEuler.reorderIt(MEulerRotation::kYXZ); break; case ORDER_ZYX: tmpEuler.reorderIt(MEulerRotation::kZYX); break; default: return false; } rotateX = (float)tmpEuler.x; rotateY = (float)tmpEuler.y; rotateZ = (float)tmpEuler.z; tmpVector = xform.rotatePivotTranslation(MSpace::kWorld, &status); if (!status) return false; rotatePivotTranslate.x = (float)tmpVector.x; rotatePivotTranslate.y = (float)tmpVector.y; rotatePivotTranslate.z = (float)tmpVector.z; // only used in joints jointOrientX = 0.0f; jointOrientY = 0.0f; jointOrientZ = 0.0f; // only used in joints inverseScaleX = 1.0f; inverseScaleY = 1.0f; inverseScaleZ = 1.0f; tmpVector = xform.translation(MSpace::kWorld, &status); if (!status) return false; translate.x = (float)tmpVector.x; translate.y = (float)tmpVector.y; translate.z = (float)tmpVector.z; return true; } void TransformMatrix::SetScalePivot(const tlPoint& sp) { scalePivot = sp; scaleDirty = true; } void TransformMatrix::SetScale(float x, float y, float z) { scaleX = x; scaleY = y; scaleZ = z; scaleDirty = true; } void TransformMatrix::SetScaleX(float x) { scaleX = x; scaleDirty = true; } void TransformMatrix::SetScaleY(float y) { scaleY = y; scaleDirty = true; } void TransformMatrix::SetScaleZ(float z) { scaleZ = z; scaleDirty = true; } void TransformMatrix::SetShear(float xy, float xz, float yz) { shearXY = xy; shearXZ = xz; shearYZ = yz; scaleDirty = true; } void TransformMatrix::SetShearXY(float xy) { shearXY = xy; scaleDirty = true; } void TransformMatrix::SetShearXZ(float xz) { shearXZ = xz; scaleDirty = true; } void TransformMatrix::SetShearYZ(float yz) { shearYZ = yz; scaleDirty = true; } void TransformMatrix::SetScalePivotTranslate(float x, float y, float z) { scalePivotTranslate.x = x; scalePivotTranslate.y = y; scalePivotTranslate.z = z; scaleDirty = true; } void TransformMatrix::SetScalePivotTranslate(const tlPoint& spt) { scalePivotTranslate = spt; scaleDirty = true; } void TransformMatrix::SetScalePivotX(float x) { scalePivotTranslate.x = x; scaleDirty = true; } void TransformMatrix::SetScalePivotY(float y) { scalePivotTranslate.y = y; scaleDirty = true; } void TransformMatrix::SetScalePivotZ(float z) { scalePivotTranslate.z = z; scaleDirty = true; } void TransformMatrix::SetRotatePivot(float x, float y, float z) { rotatePivot.x = x; rotatePivot.y = y; rotatePivot.z = z; hierarchyDirty = true; } void TransformMatrix::SetRotatePivot(const tlPoint& rp) { rotatePivot = rp; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotX(float x) { rotatePivot.x = x; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotY(float y) { rotatePivot.y = y; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotZ(float z) { rotatePivot.z = z; hierarchyDirty = true; } void TransformMatrix::SetRotateAxis(float x, float y, float z) { rotateAxisX = x; rotateAxisY = y; rotateAxisZ = z; hierarchyDirty = true; } void TransformMatrix::SetRotateAxisX(float rax) { rotateAxisX = rax; hierarchyDirty = true; } void TransformMatrix::SetRotateAxisY(float ray) { rotateAxisY = ray; hierarchyDirty = true; } void TransformMatrix::SetRotateAxisZ(float raz) { rotateAxisZ = raz; hierarchyDirty = true; } void TransformMatrix::SetRotate(float x, float y, float z) { rotateX = x; rotateY = y; rotateZ = z; hierarchyDirty = true; } void TransformMatrix::SetRotateX(float x) { rotateX = x; hierarchyDirty = true; } void TransformMatrix::SetRotateY(float y) { rotateY = y; hierarchyDirty = true; } void TransformMatrix::SetRotateZ(float z) { rotateZ = z; hierarchyDirty = true; } void TransformMatrix::SetRotateOrder(RotateOrder ro) { rotateOrder = ro; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotTranslate(float x, float y, float z) { rotatePivotTranslate.x = x; rotatePivotTranslate.y = y; rotatePivotTranslate.z = z; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotTranslate(const tlPoint& rpt) { rotatePivotTranslate = rpt; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotTranslateX(float x) { rotatePivotTranslate.x = x; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotTranslateY(float y) { rotatePivotTranslate.y = y; hierarchyDirty = true; } void TransformMatrix::SetRotatePivotTranslateZ(float z) { rotatePivotTranslate.z = z; hierarchyDirty = true; } void TransformMatrix::SetJointOrient(float x, float y, float z) { jointOrientX = x; jointOrientY = y; jointOrientZ = z; hierarchyDirty = true; } void TransformMatrix::SetJointOrientX(float x) { jointOrientX = x; hierarchyDirty = true; } void TransformMatrix::SetJointOrientY(float y) { jointOrientY = y; hierarchyDirty = true; } void TransformMatrix::SetJointOrientZ(float z) { jointOrientZ = z; hierarchyDirty = true; } void TransformMatrix::SetInverseScale(float x, float y, float z) { inverseScaleX = x; inverseScaleY = y; inverseScaleZ = z; hierarchyDirty = true; } void TransformMatrix::SetInverseScaleX(float x) { inverseScaleX = x; hierarchyDirty = true; } void TransformMatrix::SetInverseScaleY(float y) { inverseScaleY = y; hierarchyDirty = true; } void TransformMatrix::SetInverseScaleZ(float z) { inverseScaleZ = z; hierarchyDirty = true; } void TransformMatrix::SetTranslate(float x, float y, float z) { translate.x = x; translate.y = y; translate.z = z; hierarchyDirty = true; } void TransformMatrix::SetTranslate(const tlPoint& t) { translate = t; hierarchyDirty = true; } void TransformMatrix::SetTranslateX(float x) { translate.x = x; hierarchyDirty = true; } void TransformMatrix::SetTranslateY(float y) { translate.y = y; hierarchyDirty = true; } void TransformMatrix::SetTranslateZ(float z) { translate.z = z; hierarchyDirty = true; } void TransformMatrix::SetScaleMatrixIdentity() { scalePivot.x = 0.0f; scalePivot.y = 0.0f; scalePivot.z = 0.0f; scaleX = 1.0f; scaleY = 1.0f; scaleZ = 1.0f; shearXY = 0.0f; shearXZ = 0.0f; shearYZ = 0.0f; scalePivotTranslate.x = 0.0f; scalePivotTranslate.y = 0.0f; scalePivotTranslate.z = 0.0f; scaleMatrix.IdentityMatrix(); scaleDirty = false; } void TransformMatrix::SetHierarchyMatrixIdentity() { rotatePivot.x = 0.0f; rotatePivot.y = 0.0f; rotatePivot.z = 0.0f; rotateAxisX = 0.0f; rotateAxisY = 0.0f; rotateAxisZ = 0.0f; rotateX = 0.0f; rotateY = 0.0f; rotateZ = 0.0f; rotatePivotTranslate.x = 0.0f; rotatePivotTranslate.y = 0.0f; rotatePivotTranslate.z = 0.0f; jointOrientX = 0.0f; jointOrientY = 0.0f; jointOrientZ = 0.0f; inverseScaleX = 1.0f; inverseScaleY = 1.0f; inverseScaleZ = 1.0f; translate.x = 0.0f; translate.y = 0.0f; translate.z = 0.0f; hierarchyMatrix.IdentityMatrix(); hierarchyDirty = false; } void TransformMatrix::SetIdentity() { SetScaleMatrixIdentity(); SetHierarchyMatrixIdentity(); } void TransformMatrix::ComputeScaleMatrix() { if (!scaleDirty) return; scaleMatrix.IdentityMatrix(); scaleMatrix.Translate(-scalePivot); scaleMatrix.Scale(scaleX, scaleY, scaleZ, true); scaleMatrix.Shear(shearXY, shearXZ, shearYZ); scaleMatrix.Translate(scalePivot); scaleMatrix.Translate(scalePivotTranslate); scaleMatrix.Scale(inverseScaleX, inverseScaleY, inverseScaleZ, true); scaleDirty = false; } void TransformMatrix::ComputeHierarchyMatrix() { if (!hierarchyDirty) return; hierarchyMatrix.IdentityMatrix(); hierarchyMatrix.Translate(-rotatePivot); hierarchyMatrix.RotateX(rotateAxisX); hierarchyMatrix.RotateY(rotateAxisY); hierarchyMatrix.RotateZ(rotateAxisZ); switch (rotateOrder) { case ORDER_XYZ: hierarchyMatrix.RotateX(rotateX); hierarchyMatrix.RotateY(rotateY); hierarchyMatrix.RotateZ(rotateZ); break; case ORDER_YZX: hierarchyMatrix.RotateY(rotateY); hierarchyMatrix.RotateZ(rotateZ); hierarchyMatrix.RotateX(rotateX); break; case ORDER_ZXY: hierarchyMatrix.RotateZ(rotateZ); hierarchyMatrix.RotateX(rotateX); hierarchyMatrix.RotateY(rotateY); break; case ORDER_XZY: hierarchyMatrix.RotateX(rotateX); hierarchyMatrix.RotateZ(rotateZ); hierarchyMatrix.RotateY(rotateY); break; case ORDER_YXZ: hierarchyMatrix.RotateY(rotateY); hierarchyMatrix.RotateX(rotateX); hierarchyMatrix.RotateZ(rotateZ); break; case ORDER_ZYX: hierarchyMatrix.RotateZ(rotateZ); hierarchyMatrix.RotateY(rotateY); hierarchyMatrix.RotateX(rotateX); break; } hierarchyMatrix.Translate(rotatePivot); hierarchyMatrix.Translate(rotatePivotTranslate); hierarchyMatrix.RotateX(jointOrientX); hierarchyMatrix.RotateY(jointOrientY); hierarchyMatrix.RotateZ(jointOrientZ); //hierarchyMatrix.Scale(inverseScaleX, inverseScaleY, inverseScaleZ, true); hierarchyMatrix.Translate(translate); hierarchyDirty = false; } const tlMatrix& TransformMatrix::GetScaleMatrix() const { const_cast(this)->ComputeScaleMatrix(); return scaleMatrix; } const tlMatrix& TransformMatrix::GetHierarchyMatrix() const { const_cast(this)->ComputeHierarchyMatrix(); return hierarchyMatrix; } void TransformMatrix::GetScaleMatrixLHS(tlMatrix& matrix) const { GetScaleMatrixRHS(matrix); matrix.RHSToLHS(); } void TransformMatrix::GetHierarchyMatrixLHS(tlMatrix& matrix) const { GetHierarchyMatrixRHS(matrix); matrix.RHSToLHS(); } void TransformMatrix::GetScaleMatrixRHS(tlMatrix& matrix) const { const_cast(this)->ComputeScaleMatrix(); matrix = scaleMatrix; } void TransformMatrix::GetHierarchyMatrixRHS(tlMatrix& matrix) const { const_cast(this)->ComputeHierarchyMatrix(); matrix = hierarchyMatrix; } // End of file.