void readAnimation(KFbxNode* pNode, KFbxScene& fbxScene, const std::string& targetName, osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, KFbxMesh* pMesh, int nBlendShape, int nBlendShapeChannel, int nShape) { for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i) { KFbxAnimStack* pAnimStack = KFbxCast<KFbxAnimStack>(fbxScene.GetSrcObject(FBX_TYPE(KFbxAnimStack), i)); int nbAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(KFbxAnimLayer)); const char* pTakeName = pAnimStack->GetName(); if (!pTakeName || !*pTakeName) continue; for (int j = 0; j < nbAnimLayers; j++) { KFbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(KFbxAnimLayer), j); KFbxAnimCurve* pCurve = pMesh->GetShapeChannel(nBlendShape, nBlendShapeChannel, pAnimLayer, false); if (!pCurve) { continue; } int nKeys = pCurve->KeyGetCount(); if (!nKeys) { continue; } osgAnimation::FloatLinearChannel* pChannel = new osgAnimation::FloatLinearChannel; std::vector<osgAnimation::TemplateKeyframe<float> >& keyFrameCntr = *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer(); for (int k = 0; k < nKeys; ++k) { KFbxAnimCurveKey key = pCurve->KeyGet(k); double fTime = key.GetTime().GetSecondDouble(); float fValue = static_cast<float>(key.GetValue() * 0.01); keyFrameCntr.push_back(osgAnimation::FloatKeyframe(fTime,fValue)); } pChannel->setTargetName(targetName); std::stringstream ss; ss << nShape; pChannel->setName(ss.str()); addChannel(pChannel, pAnimationManager, pTakeName); } } }
void readKeys(KFbxAnimCurve* curveX, KFbxAnimCurve* curveY, KFbxAnimCurve* curveZ, const fbxDouble3& defaultValue, std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> >& keyFrameCntr, float scalar = 1.0f) { KFbxAnimCurve* curves[3] = {curveX, curveY, curveZ}; typedef std::set<double> TimeSet; typedef std::map<double, float> TimeFloatMap; TimeSet times; TimeFloatMap curveTimeMap[3]; for (int nCurve = 0; nCurve < 3; ++nCurve) { KFbxAnimCurve* pCurve = curves[nCurve]; int nKeys = pCurve ? pCurve->KeyGetCount() : 0; if (!nKeys) { times.insert(0.0); curveTimeMap[nCurve][0.0] = defaultValue[nCurve] * scalar; } for (int i = 0; i < nKeys; ++i) { KFbxAnimCurveKey key = pCurve->KeyGet(i); double fTime = key.GetTime().GetSecondDouble(); times.insert(fTime); curveTimeMap[nCurve][fTime] = static_cast<float>(key.GetValue()) * scalar; } } for (TimeSet::iterator it = times.begin(); it != times.end(); ++it) { double fTime = *it; osg::Vec3 val; for (int i = 0; i < 3; ++i) { if (curveTimeMap[i].empty()) continue; TimeFloatMap::iterator lb = curveTimeMap[i].lower_bound(fTime); if (lb == curveTimeMap[i].end()) --lb; val[i] = lb->second; } keyFrameCntr.push_back(osgAnimation::Vec3Keyframe(fTime, val)); } }