Changeset 11153

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

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

Location:
OpenSceneGraph/trunk/src/osgPlugins/fbx
Files:
5 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(); 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRMesh.cpp

    r11144 r11153  
    261261} 
    262262 
     263void addBindMatrix( 
     264    BindMatrixMap& boneBindMatrices, 
     265    KFbxNode* pBone, 
     266    const osg::Matrix& bindMatrix, 
     267    osgAnimation::RigGeometry* pRigGeometry) 
     268{ 
     269    boneBindMatrices.insert(BindMatrixMap::value_type( 
     270        BindMatrixMap::key_type(pBone, pRigGeometry), bindMatrix)); 
     271} 
     272 
    263273osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, 
    264274    KFbxNode* pNode, KFbxMesh* fbxMesh, 
     
    266276    std::vector<StateSetContent>& stateSetList, 
    267277    const char* szName, 
    268     std::map<KFbxNode*, osg::Matrix>& boneBindMatrices, 
     278    BindMatrixMap& boneBindMatrices, 
    269279    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap) 
    270280{ 
     
    441451                KFbxXMatrix transformLinkInverse = transformLink.Inverse(); 
    442452                const double* pTransformLinkInverse = transformLinkInverse; 
    443                 if (!boneBindMatrices.insert(std::pair<KFbxNode*, osg::Matrix>(pBone, osg::Matrix(pTransformLinkInverse))).second) 
    444                 { 
    445                     osg::notify(osg::WARN) << "Multiple meshes attached to a bone - bind matrices may be incorrect." << std::endl; 
    446                 } 
     453                osg::Matrix bindMatrix(pTransformLinkInverse); 
    447454 
    448455                int nIndices = pCluster->GetControlPointIndicesCount(); 
     
    464471                            dynamic_cast<osgAnimation::RigGeometry&>( 
    465472                            *old2newGeometryMap[gi.first]); 
     473                        addBindMatrix(boneBindMatrices, pBone, bindMatrix, &rig); 
    466474                        osgAnimation::VertexInfluenceMap& vim = 
    467475                            *rig.getInfluenceMap(); 
     
    604612    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    605613    std::vector<StateSetContent>& stateSetList, 
    606     std::map<KFbxNode*, osg::Matrix>& boneBindMatrices, 
     614    BindMatrixMap& boneBindMatrices, 
    607615    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap) 
    608616{ 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRMesh.h

    r11141 r11153  
    55#include <osgDB/ReaderWriter> 
    66#include <osg/Material> 
    7 #include "fbxMaterialToOsgStateSet.h" 
     7#include "fbxRNode.h" 
    88osgDB::ReaderWriter::ReadResult readFbxMesh( 
    99    FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager, 
     
    1111    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    1212    std::vector<StateSetContent>&, 
    13     std::map<KFbxNode*, osg::Matrix>& boneBindMatrices, 
     13    BindMatrixMap& boneBindMatrices, 
    1414    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap); 
    1515 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRNode.cpp

    r11144 r11153  
    324324    FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, 
    325325    std::map<KFbxNode*, osg::Node*>& nodeMap, 
    326     std::map<KFbxNode*, osg::Matrix>& boneBindMatrices, 
     326    BindMatrixMap& boneBindMatrices, 
    327327    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap, 
    328328    const osgDB::Options* options) 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRNode.h

    r11141 r11153  
    66{ 
    77    class AnimationManagerBase; 
     8    class RigGeometry; 
    89} 
     10 
     11typedef std::map<std::pair<KFbxNode*, osgAnimation::RigGeometry*>, osg::Matrix> BindMatrixMap; 
    912 
    1013osgAnimation::Skeleton* getSkeleton(KFbxNode*, std::map<KFbxNode*, osgAnimation::Skeleton*>&); 
     
    1821    FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, 
    1922    std::map<KFbxNode*, osg::Node*>& nodeMap, 
    20     std::map<KFbxNode*, osg::Matrix>& boneBindMatrices, 
     23    BindMatrixMap& boneBindMatrices, 
    2124    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap, 
    2225    const osgDB::Options* options = NULL);