Show
Ignore:
Timestamp:
03/04/10 17:27:19 (5 years ago)
Author:
mplatings
Message:

Fix for some FBX files with multiple meshes bound to a bone.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/ReaderWriterFBX.cpp

    r11141 r11153  
    1515#include <osgAnimation/AnimationManagerBase> 
    1616#include <osgAnimation/Bone> 
     17#include <osgAnimation/RigGeometry> 
    1718#include <osgAnimation/Skeleton> 
     19#include <osgAnimation/VertexInfluence> 
    1820 
    1921#if defined(_MSC_VER) 
     
    9698    } 
    9799}; 
     100 
     101void resolveBindMatrices( 
     102    osg::Node& root, 
     103    const BindMatrixMap& boneBindMatrices, 
     104    const std::map<KFbxNode*, osg::Node*>& nodeMap) 
     105{ 
     106    std::set<std::string> nodeNames; 
     107    for (std::map<KFbxNode*, osg::Node*>::const_iterator it = nodeMap.begin(); it != nodeMap.end(); ++it) 
     108    { 
     109        nodeNames.insert(it->second->getName()); 
     110    } 
     111 
     112    for (BindMatrixMap::const_iterator it = boneBindMatrices.begin(); 
     113        it != boneBindMatrices.end();) 
     114    { 
     115        KFbxNode* const fbxBone = it->first.first; 
     116        std::map<KFbxNode*, osg::Node*>::const_iterator nodeIt = nodeMap.find(fbxBone); 
     117        if (nodeIt != nodeMap.end()) 
     118        { 
     119            const osg::Matrix bindMatrix = it->second; 
     120            osgAnimation::Bone& osgBone = dynamic_cast<osgAnimation::Bone&>(*nodeIt->second); 
     121            osgBone.setInvBindMatrixInSkeletonSpace(bindMatrix); 
     122 
     123            ++it; 
     124            for (; it != boneBindMatrices.end() && it->first.first == fbxBone; ++it) 
     125            { 
     126                if (it->second != bindMatrix) 
     127                { 
     128                    std::string name; 
     129                    for (int i = 0;; ++i) 
     130                    { 
     131                        std::stringstream ss; 
     132                        ss << osgBone.getName() << '_' << i; 
     133                        name = ss.str(); 
     134                        if (nodeNames.insert(name).second) 
     135                        { 
     136                            break; 
     137                        } 
     138                    } 
     139                    osgAnimation::Bone* newBone = new osgAnimation::Bone(name); 
     140                    newBone->setDefaultUpdateCallback(); 
     141                    newBone->setInvBindMatrixInSkeletonSpace(it->second); 
     142                    osgBone.addChild(newBone); 
     143 
     144                    osgAnimation::RigGeometry* pRigGeometry = it->first.second; 
     145                     
     146                    osgAnimation::VertexInfluenceMap* vertexInfluences = pRigGeometry->getInfluenceMap(); 
     147 
     148                    osgAnimation::VertexInfluenceMap::iterator vimIt = vertexInfluences->find(osgBone.getName()); 
     149                    if (vimIt != vertexInfluences->end()) 
     150                    { 
     151                        osgAnimation::VertexInfluence vi; 
     152                        vi.swap(vimIt->second); 
     153                        vertexInfluences->erase(vimIt); 
     154                        osgAnimation::VertexInfluence& vi2 = (*vertexInfluences)[name]; 
     155                        vi.swap(vi2); 
     156                        vi2.setName(name); 
     157                    } 
     158                    else 
     159                    { 
     160                        assert(0); 
     161                    } 
     162                } 
     163            } 
     164        } 
     165        else 
     166        { 
     167            assert(0); 
     168        } 
     169    } 
     170} 
    98171 
    99172osgDB::ReaderWriter::ReadResult 
     
    190263 
    191264            std::map<KFbxNode*, osg::Node*> nodeMap; 
    192             std::map<KFbxNode*, osg::Matrix> boneBindMatrices; 
     265            BindMatrixMap boneBindMatrices; 
    193266            std::map<KFbxNode*, osgAnimation::Skeleton*> skeletonMap; 
    194267            ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager, 
     
    198271            if (res.success()) 
    199272            { 
    200                 for (std::map<KFbxNode*, osg::Matrix>::const_iterator it = boneBindMatrices.begin(); 
    201                     it != boneBindMatrices.end(); ++it) 
    202                 { 
    203                     std::map<KFbxNode*, osg::Node*>::iterator nodeIt = nodeMap.find(it->first); 
    204                     if (nodeIt != nodeMap.end()) 
    205                     { 
    206                         osgAnimation::Bone& osgBone = dynamic_cast<osgAnimation::Bone&>(*nodeIt->second); 
    207                         osgBone.setInvBindMatrixInSkeletonSpace(it->second); 
    208                     } 
    209                     else 
    210                     { 
    211                         assert(0); 
    212                     } 
    213                 } 
     273                resolveBindMatrices(*res.getNode(), boneBindMatrices, nodeMap); 
    214274 
    215275                osg::Node* osgNode = res.getNode();