osgAnimation::Animation* readFbxAnimation(KFbxNode* pNode, KFbxAnimLayer* pAnimLayer, const char* pTakeName, const char* targetName, osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager) { ERotationOrder rotOrder = pNode->RotationOrder.IsValid() ? pNode->RotationOrder.Get() : eEULER_XYZ; osgAnimation::Channel* pTranslationChannel = 0; osgAnimation::Channel* pRotationChannel = 0; if (pNode->LclRotation.IsValid()) { fbxDouble3 fbxBaseValue = pNode->LclRotation.Get(); pRotationChannel = readFbxChannelsQuat( pNode->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_X), pNode->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_Y), pNode->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_Z), pNode->LclRotation.Get(), targetName, rotOrder); } if (pNode->LclTranslation.IsValid()) { pTranslationChannel = readFbxChannels( pNode->LclTranslation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_T_X), pNode->LclTranslation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_T_Y), pNode->LclTranslation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_T_Z), pNode->LclTranslation.Get(), targetName, "translate"); } osgAnimation::Channel* pScaleChannel = readFbxChannels( pNode->LclScaling, pAnimLayer, targetName, "scale"); return addChannels(pTranslationChannel, pRotationChannel, pScaleChannel, pAnimManager, pTakeName); }
void readFbxRotationAnimation(osgAnimation::Channel* channels[3], FbxNode* pNode, FbxAnimLayer* pAnimLayer, const char* targetName) { if (!pNode->LclRotation.IsValid()) { return; } EFbxRotationOrder rotOrder = pNode->RotationOrder.IsValid() ? pNode->RotationOrder.Get() : eEulerXYZ; if (pNode->QuaternionInterpolate.IsValid() && pNode->QuaternionInterpolate.Get()) { channels[0] = readFbxChannelsQuat( pNode->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X), pNode->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y), pNode->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z), pNode->LclRotation.Get(), targetName, rotOrder); } else { const char* curveNames[3] = {FBXSDK_CURVENODE_COMPONENT_X, FBXSDK_CURVENODE_COMPONENT_Y, FBXSDK_CURVENODE_COMPONENT_Z}; FbxDouble3 fbxPropValue = pNode->LclRotation.Get(); fbxPropValue[0] = osg::DegreesToRadians(fbxPropValue[0]); fbxPropValue[1] = osg::DegreesToRadians(fbxPropValue[1]); fbxPropValue[2] = osg::DegreesToRadians(fbxPropValue[2]); for (int i = 0; i < 3; ++i) { FbxAnimCurve* curve = pNode->LclRotation.GetCurve(pAnimLayer, curveNames[i]); if (!curve) { continue; } FbxAnimCurveDef::EInterpolationType interpolationType = FbxAnimCurveDef::eInterpolationConstant; if (curve && curve->KeyGetCount()) interpolationType = curve->KeyGetInterpolation(0); if (interpolationType == FbxAnimCurveDef::eInterpolationCubic) { osgAnimation::FloatCubicBezierKeyframeContainer* pKeyFrameCntr = new osgAnimation::FloatCubicBezierKeyframeContainer; for (int j = 0; j < curve->KeyGetCount(); ++j) { double fTime = curve->KeyGetTime(j).GetSecondDouble(); float angle = curve->KeyGetValue(j); //FbxAnimCurveDef::EWeightedMode tangentWeightMode = curve->KeyGet(j).GetTangentWeightMode(); FbxAnimCurveTangentInfo leftTangent = curve->KeyGetLeftDerivativeInfo(j); FbxAnimCurveTangentInfo rightTangent = curve->KeyGetRightDerivativeInfo(j); if (j > 0) { leftTangent.mDerivative *= fTime - curve->KeyGetTime(j - 1).GetSecondDouble(); } if (j + 1 < curve->KeyGetCount()) { rightTangent.mDerivative *= curve->KeyGetTime(j + 1).GetSecondDouble() - fTime; } osgAnimation::FloatCubicBezier key( osg::DegreesToRadians(angle), osg::DegreesToRadians(angle - leftTangent.mDerivative / 3.0), osg::DegreesToRadians(angle + rightTangent.mDerivative / 3.0)); pKeyFrameCntr->push_back(osgAnimation::FloatCubicBezierKeyframe( fTime, key)); } reorderControlPoints(*pKeyFrameCntr); osgAnimation::FloatCubicBezierChannel* pCubicChannel = new osgAnimation::FloatCubicBezierChannel; pCubicChannel->getOrCreateSampler()->setKeyframeContainer(pKeyFrameCntr); channels[i] = pCubicChannel; } else { osgAnimation::FloatKeyframeContainer* keys = new osgAnimation::FloatKeyframeContainer; for (int j = 0; j < curve->KeyGetCount(); ++j) { FbxAnimCurveKey key = curve->KeyGet(j); keys->push_back(osgAnimation::FloatKeyframe( key.GetTime().GetSecondDouble(), static_cast<float>(osg::DegreesToRadians(key.GetValue())))); } if (interpolationType == FbxAnimCurveDef::eInterpolationConstant) { osgAnimation::FloatStepChannel* pStepChannel = new osgAnimation::FloatStepChannel(); pStepChannel->getOrCreateSampler()->setKeyframeContainer(keys); channels[i] = pStepChannel; } else { osgAnimation::FloatLinearChannel* pLinearChannel = new osgAnimation::FloatLinearChannel(); pLinearChannel->getOrCreateSampler()->setKeyframeContainer(keys); channels[i] = pLinearChannel; } } channels[i]->setTargetName(targetName); channels[i]->setName(std::string("rotate") + curveNames[i]); } } }