void addBindMatrix( BindMatrixMap& boneBindMatrices, KFbxNode* pBone, const osg::Matrix& bindMatrix, osgAnimation::RigGeometry* pRigGeometry) { boneBindMatrices.insert(BindMatrixMap::value_type( BindMatrixMap::key_type(pBone, pRigGeometry), bindMatrix)); }
void resolveBindMatrices( osg::Node& root, const BindMatrixMap& boneBindMatrices, const std::map<KFbxNode*, osg::Node*>& nodeMap) { std::set<std::string> nodeNames; for (std::map<KFbxNode*, osg::Node*>::const_iterator it = nodeMap.begin(); it != nodeMap.end(); ++it) { nodeNames.insert(it->second->getName()); } for (BindMatrixMap::const_iterator it = boneBindMatrices.begin(); it != boneBindMatrices.end();) { KFbxNode* const fbxBone = it->first.first; std::map<KFbxNode*, osg::Node*>::const_iterator nodeIt = nodeMap.find(fbxBone); if (nodeIt != nodeMap.end()) { const osg::Matrix bindMatrix = it->second; osgAnimation::Bone& osgBone = dynamic_cast<osgAnimation::Bone&>(*nodeIt->second); osgBone.setInvBindMatrixInSkeletonSpace(bindMatrix); ++it; for (; it != boneBindMatrices.end() && it->first.first == fbxBone; ++it) { if (it->second != bindMatrix) { std::string name; for (int i = 0;; ++i) { std::stringstream ss; ss << osgBone.getName() << '_' << i; name = ss.str(); if (nodeNames.insert(name).second) { break; } } osgAnimation::Bone* newBone = new osgAnimation::Bone(name); newBone->setDefaultUpdateCallback(); newBone->setInvBindMatrixInSkeletonSpace(it->second); osgBone.addChild(newBone); osgAnimation::RigGeometry* pRigGeometry = it->first.second; osgAnimation::VertexInfluenceMap* vertexInfluences = pRigGeometry->getInfluenceMap(); osgAnimation::VertexInfluenceMap::iterator vimIt = vertexInfluences->find(osgBone.getName()); if (vimIt != vertexInfluences->end()) { osgAnimation::VertexInfluence vi; vi.swap(vimIt->second); vertexInfluences->erase(vimIt); osgAnimation::VertexInfluence& vi2 = (*vertexInfluences)[name]; vi.swap(vi2); vi2.setName(name); } else { OSG_WARN << "No vertex influences found for \"" << osgBone.getName() << "\"" << std::endl; } } } } else { OSG_WARN << "No bone found for \"" << fbxBone->GetName() << "\"" << std::endl; ++it; } } }
void resolveBindMatrices( osg::Node& root, const BindMatrixMap& boneBindMatrices, const std::map<FbxNode*, osg::Node*>& nodeMap) { std::set<std::string> nodeNames; for (std::map<FbxNode*, osg::Node*>::const_iterator it = nodeMap.begin(); it != nodeMap.end(); ++it) { nodeNames.insert(it->second->getName()); } for (BindMatrixMap::const_iterator it = boneBindMatrices.begin(); it != boneBindMatrices.end(); ++it) { FbxNode* const fbxBone = it->first; std::map<FbxNode*, osg::Node*>::const_iterator nodeIt = nodeMap.find(fbxBone); if (nodeIt != nodeMap.end()) { osgAnimation::Bone* originalBone = dynamic_cast<osgAnimation::Bone*>(nodeIt->second); // Iterate bind matrices and create new bones if needed const BindMatrixGeometryMap& bindMatrixGeom = it->second; for ( BindMatrixGeometryMap::const_iterator bindIt = bindMatrixGeom.begin(); bindIt != bindMatrixGeom.end(); ++bindIt) { // First matrix will use original bone if (bindIt == bindMatrixGeom.begin()) { originalBone->setInvBindMatrixInSkeletonSpace(bindIt->first); } else { // Additional matrices need new bone std::string name; for (int i = 0;; ++i) { std::stringstream ss; ss << originalBone->getName() << '_' << i; name = ss.str(); if (nodeNames.insert(name).second) { break; } } osgAnimation::Bone* newBone = new osgAnimation::Bone(name); newBone->setDefaultUpdateCallback(); newBone->setInvBindMatrixInSkeletonSpace(bindIt->first); originalBone->addChild(newBone); // Update rig geometry with new bone names for (std::set<osgAnimation::RigGeometry*>::const_iterator rigIt = bindIt->second.begin(); rigIt != bindIt->second.end(); ++rigIt) { osgAnimation::RigGeometry* pRigGeometry = (*rigIt); osgAnimation::VertexInfluenceMap* vertexInfluences = pRigGeometry->getInfluenceMap(); osgAnimation::VertexInfluenceMap::iterator vimIt = vertexInfluences->find(originalBone->getName()); if (vimIt != vertexInfluences->end()) { osgAnimation::VertexInfluence vi; vi.swap(vimIt->second); vertexInfluences->erase(vimIt); osgAnimation::VertexInfluence& vi2 = (*vertexInfluences)[name]; vi.swap(vi2); vi2.setName(name); } else { OSG_WARN << "No vertex influences found for \"" << originalBone->getName() << "\"" << std::endl; } } } } } else { OSG_WARN << "No bone found for \"" << fbxBone->GetName() << "\"" << std::endl; ++it; } } }