void readRotationElement(KFbxTypedProperty<fbxDouble3>& prop, ERotationOrder fbxRotOrder, bool quatInterpolate, osgAnimation::UpdateMatrixTransform* pUpdate, osg::Matrix& staticTransform) { if (prop.GetKFCurve(KFCURVENODE_R_X) || prop.GetKFCurve(KFCURVENODE_R_Y) || prop.GetKFCurve(KFCURVENODE_R_Z)) { if (quatInterpolate) { if (!staticTransform.isIdentity()) { pUpdate->getStackedTransforms().push_back( new osgAnimation::StackedMatrixElement(staticTransform)); staticTransform.makeIdentity(); } pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedQuaternionElement( "quaternion", makeQuat(prop.Get(), fbxRotOrder))); } else { char* curveNames[3] = {KFCURVENODE_R_X, KFCURVENODE_R_Y, KFCURVENODE_R_Z}; osg::Vec3 axes[3] = {osg::Vec3(1,0,0), osg::Vec3(0,1,0), osg::Vec3(0,0,1)}; fbxDouble3 fbxPropValue = prop.Get(); fbxPropValue[0] = osg::DegreesToRadians(fbxPropValue[0]); fbxPropValue[1] = osg::DegreesToRadians(fbxPropValue[1]); fbxPropValue[2] = osg::DegreesToRadians(fbxPropValue[2]); int order[3] = {0, 1, 2}; getRotationOrder(fbxRotOrder, order); for (int i = 0; i < 3; ++i) { int j = order[2-i]; if (prop.GetKFCurve(curveNames[j])) { if (!staticTransform.isIdentity()) { pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform)); staticTransform.makeIdentity(); } pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement( std::string("rotate") + curveNames[j], axes[j], fbxPropValue[j])); } else { staticTransform.preMultRotate(osg::Quat(fbxPropValue[j], axes[j])); } } } } else { staticTransform.preMultRotate(makeQuat(prop.Get(), fbxRotOrder)); } }
bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const { osg::Quat billboardRotation; osgUtil::CullVisitor* cullvisitor = dynamic_cast<osgUtil::CullVisitor*>(nv); if (cullvisitor) { osg::Vec3 eyevector = cullvisitor->getEyeLocal()-_position; eyevector.normalize(); osg::Vec3 side = _axis^_normal; side.normalize(); float angle = atan2(eyevector*_normal,eyevector*side); billboardRotation.makeRotate(osg::PI_2-angle,_axis); } matrix.preMultTranslate(_position); matrix.preMultRotate(billboardRotation); matrix.preMultRotate(_attitude); matrix.preMultTranslate(-_pivotPoint); return true; }
void makeLocalMatrix(const FbxNode* pNode, osg::Matrix& m) { /*From http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/the-makeup-of-the-local-matrix-of-an-kfbxnode/ Local Matrix = LclTranslation * RotationOffset * RotationPivot * PreRotation * LclRotation * PostRotation * RotationPivotInverse * ScalingOffset * ScalingPivot * LclScaling * ScalingPivotInverse LocalTranslation : translate (xform -query -translation) RotationOffset: translation compensates for the change in the rotate pivot point (xform -q -rotateTranslation) RotationPivot: current rotate pivot position (xform -q -rotatePivot) PreRotation : joint orientation(pre rotation) LocalRotation: rotate transform (xform -q -rotation & xform -q -rotateOrder) PostRotation : rotate axis (xform -q -rotateAxis) RotationPivotInverse: inverse of RotationPivot ScalingOffset: translation compensates for the change in the scale pivot point (xform -q -scaleTranslation) ScalingPivot: current scale pivot position (xform -q -scalePivot) LocalScaling: scale transform (xform -q -scale) ScalingPivotInverse: inverse of ScalingPivot */ // When this flag is set to false, the RotationOrder, the Pre/Post rotation // values and the rotation limits should be ignored. bool rotationActive = pNode->RotationActive.Get(); EFbxRotationOrder fbxRotOrder = rotationActive ? pNode->RotationOrder.Get() : eEulerXYZ; FbxDouble3 fbxLclPos = pNode->LclTranslation.Get(); FbxDouble3 fbxRotOff = pNode->RotationOffset.Get(); FbxDouble3 fbxRotPiv = pNode->RotationPivot.Get(); FbxDouble3 fbxPreRot = pNode->PreRotation.Get(); FbxDouble3 fbxLclRot = pNode->LclRotation.Get(); FbxDouble3 fbxPostRot = pNode->PostRotation.Get(); FbxDouble3 fbxSclOff = pNode->ScalingOffset.Get(); FbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get(); FbxDouble3 fbxLclScl = pNode->LclScaling.Get(); m.makeTranslate(osg::Vec3d( fbxLclPos[0] + fbxRotOff[0] + fbxRotPiv[0], fbxLclPos[1] + fbxRotOff[1] + fbxRotPiv[1], fbxLclPos[2] + fbxRotOff[2] + fbxRotPiv[2])); if (rotationActive) { m.preMultRotate( makeQuat(fbxPostRot, fbxRotOrder) * makeQuat(fbxLclRot, fbxRotOrder) * makeQuat(fbxPreRot, fbxRotOrder)); } else { m.preMultRotate(makeQuat(fbxLclRot, fbxRotOrder)); } m.preMultTranslate(osg::Vec3d( fbxSclOff[0] + fbxSclPiv[0] - fbxRotPiv[0], fbxSclOff[1] + fbxSclPiv[1] - fbxRotPiv[1], fbxSclOff[2] + fbxSclPiv[2] - fbxRotPiv[2])); m.preMultScale(osg::Vec3d(fbxLclScl[0], fbxLclScl[1], fbxLclScl[2])); m.preMultTranslate(osg::Vec3d( -fbxSclPiv[0], -fbxSclPiv[1], -fbxSclPiv[2])); }
void StackedQuaternionElement::applyToMatrix(osg::Matrix &matrix) const { matrix.preMultRotate(_quaternion); }
void StackedRotateAxisElement::applyToMatrix(osg::Matrix& matrix) const { matrix.preMultRotate(osg::Quat(_angle, _axis)); }