Changeset 11109

Show
Ignore:
Timestamp:
02/24/10 11:25:50 (4 years ago)
Author:
mplatings
Message:
 
Location:
OpenSceneGraph/trunk/src/osgPlugins/fbx
Files:
2 added
9 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/CMakeLists.txt

    r10780 r11109  
    88    fbxRNode.cpp 
    99    ReaderWriterFBX.cpp 
     10    WriterNodeVisitor.cpp 
     11    fbxMaterialToOsgStateSet.cpp 
    1012) 
    1113 
     
    1719    fbxRNode.h 
    1820    ReaderWriterFBX.h 
     21    WriterNodeVisitor.h 
     22    fbxMaterialToOsgStateSet.h 
    1923) 
    2024 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/ReaderWriterFBX.cpp

    r10780 r11109  
    55#include <osg/MatrixTransform> 
    66#include <osg/Material> 
     7#include <osg/PositionAttitudeTransform> 
    78#include <osg/Texture2D> 
     9#include <osgDB/ConvertUTF> 
    810 
    911#include <osgDB/FileNameUtils> 
     
    1113#include <osgDB/ReadFile> 
    1214#include <osgDB/Registry> 
    13  
    1415#include <osgAnimation/AnimationManagerBase> 
     16#include <osgAnimation/Bone> 
    1517#include <osgAnimation/Skeleton> 
    16  
    17 #include <OpenThreads/ScopedLock> 
    1818 
    1919#if defined(_MSC_VER) 
     
    2424#include "ReaderWriterFBX.h" 
    2525#include "fbxRNode.h" 
     26#include "fbxMaterialToOsgStateSet.h" 
     27#include "WriterNodeVisitor.h" 
     28 
     29 
     30/// Returns true if the given node is a basic root group with no special information. 
     31/// Used in conjunction with UseFbxRoot option. 
     32/// Identity transforms are considered as basic root nodes. 
     33bool isBasicRootNode(const osg::Node& node) 
     34{ 
     35    const osg::Group* osgGroup = node.asGroup(); 
     36    if (!osgGroup) 
     37    { 
     38        // Geodes & such are not basic root nodes 
     39        return false; 
     40    } 
     41 
     42    // Test if we've got an empty transform (= a group!) 
     43    const osg::Transform* transform = osgGroup->asTransform(); 
     44    if (transform) 
     45    { 
     46        if (const osg::MatrixTransform* matrixTransform = transform->asMatrixTransform()) 
     47        { 
     48            if (!matrixTransform->getMatrix().isIdentity()) 
     49            { 
     50                // Non-identity matrix transform 
     51                return false; 
     52            } 
     53        } 
     54        else if (const osg::PositionAttitudeTransform* pat = transform->asPositionAttitudeTransform()) 
     55        { 
     56            if (pat->getPosition() != osg::Vec3d() || 
     57                pat->getAttitude() != osg::Quat() || 
     58                pat->getScale() != osg::Vec3d(1.0f, 1.0f, 1.0f) || 
     59                pat->getPivotPoint() != osg::Vec3d()) 
     60            { 
     61                // Non-identity position attribute transform 
     62                return false; 
     63            } 
     64        } 
     65        else 
     66        { 
     67            // Other transform (not identity or not predefined type) 
     68            return false; 
     69        } 
     70    } 
     71 
     72    // Test the presence of a non-empty stateset 
     73    if (node.getStateSet()) 
     74    { 
     75        osg::ref_ptr<osg::StateSet> emptyStateSet = new osg::StateSet; 
     76        if (node.getStateSet()->compare(*emptyStateSet, true) != 0) 
     77        { 
     78            return false; 
     79        } 
     80    } 
     81 
     82    return true; 
     83} 
     84 
     85 
     86class CleanUpFbx 
     87{ 
     88    KFbxSdkManager* m_pSdkManager; 
     89public: 
     90    explicit CleanUpFbx(KFbxSdkManager* pSdkManager) : m_pSdkManager(pSdkManager) 
     91    {} 
     92 
     93    ~CleanUpFbx() 
     94    { 
     95        KFbxIOSettings::IOSettingsRef().FreeIOSettings(); 
     96        m_pSdkManager->Destroy(); 
     97    } 
     98}; 
     99 
     100class ConvertBindMatrixVisitor : public osg::NodeVisitor 
     101{ 
     102public: 
     103    ConvertBindMatrixVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} 
     104 
     105    virtual void apply(osg::MatrixTransform& node) 
     106    { 
     107        if (osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node)) 
     108        { 
     109            bone->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(bone->getMatrixInBoneSpace())); 
     110            if (const osgAnimation::Bone* parent = bone->getBoneParent()) 
     111            { 
     112                bone->setInvBindMatrixInSkeletonSpace(parent->getInvBindMatrixInSkeletonSpace() * bone->getInvBindMatrixInSkeletonSpace()); 
     113            } 
     114        } 
     115 
     116        traverse(node); 
     117    } 
     118}; 
    26119 
    27120osgDB::ReaderWriter::ReadResult 
    28 ReaderWriterFBX::readNode(const std::string& utf8filename, 
    29                           const osgDB::ReaderWriter::Options* options) const 
     121ReaderWriterFBX::readNode(const std::string& filenameInit, 
     122                          const Options* options) const 
    30123{ 
    31     OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex); 
    32  
    33124    try 
    34125    { 
    35         std::string ext(osgDB::getLowerCaseFileExtension(utf8filename)); 
    36         if(!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; 
    37  
    38         std::string fileName(osgDB::findDataFile(utf8filename, options)); 
    39         if( fileName.empty()) return ReadResult::FILE_NOT_FOUND; 
     126        std::string ext(osgDB::getLowerCaseFileExtension(filenameInit)); 
     127        if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; 
     128 
     129        std::string filename(osgDB::findDataFile(filenameInit, options)); 
     130        if (filename.empty()) return ReadResult::FILE_NOT_FOUND; 
    40131 
    41132        KFbxSdkManager* pSdkManager = KFbxSdkManager::Create(); 
     
    46137        } 
    47138 
    48         class CleanUpFbx 
    49         { 
    50             KFbxSdkManager* m_pSdkManager; 
    51         public: 
    52             CleanUpFbx(KFbxSdkManager* pSdkManager) : m_pSdkManager(pSdkManager) 
    53             {} 
    54  
    55             ~CleanUpFbx() 
    56             { 
    57                 KFbxIOSettings::IOSettingsRef().FreeIOSettings(); 
    58                 m_pSdkManager->Destroy(); 
    59             } 
    60         } cleanUpFbx(pSdkManager); 
    61  
    62         KFbxScene* pScene = KFbxScene::Create(pSdkManager,""); 
     139        CleanUpFbx cleanUpFbx(pSdkManager); 
     140 
     141        KFbxScene* pScene = KFbxScene::Create(pSdkManager, ""); 
     142 
     143        // The FBX SDK interprets the filename as UTF-8 
     144#ifdef OSG_USE_UTF8_FILENAME 
     145        const std::string& utf8filename(filename); 
     146#else 
     147        std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); 
     148#endif 
    63149 
    64150        int fileFormat; 
     
    67153            return ReadResult::FILE_NOT_HANDLED; 
    68154        } 
    69  
    70         KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager,""); 
     155        KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager, ""); 
    71156        lImporter->SetFileFormat(fileFormat); 
    72157 
     
    81166        } 
    82167 
    83         for(int i = 0; i < lImporter->GetTakeCount(); i++) 
     168        for (int i = 0; i < lImporter->GetTakeCount(); i++) 
    84169        { 
    85170            KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); 
     
    93178        } 
    94179 
     180        //KFbxAxisSystem::OpenGL.ConvertScene(pScene);        // Doesn't work as expected. Still need to transform vertices. 
     181 
    95182        if (KFbxNode* pNode = pScene->GetRootNode()) 
    96183        { 
     184            bool useFbxRoot = false; 
     185            if (options) 
     186            { 
     187                std::istringstream iss(options->getOptionString()); 
     188                std::string opt; 
     189                while (iss >> opt) 
     190                { 
     191                    if (opt == "UseFbxRoot") 
     192                    { 
     193                        useFbxRoot = true; 
     194                    } 
     195                } 
     196            } 
     197 
    97198            osg::ref_ptr<osgAnimation::AnimationManagerBase> pAnimationManager; 
    98199            bool bNeedSkeleton = false; 
    99200            int nLightCount = 0; 
     201            osg::ref_ptr<Options> localOptions = NULL; 
     202            if (options) 
     203                localOptions = options->cloneOptions(); 
     204            else 
     205                localOptions = new osgDB::Options(); 
     206            localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_IMAGES); 
     207 
     208            std::string filePath = osgDB::getFilePath(filename); 
     209            FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get()); 
     210            
    100211            ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager, 
    101                 osgDB::getFilePath(fileName), bNeedSkeleton, nLightCount); 
     212                bNeedSkeleton, nLightCount, fbxMaterialToOsgStateSet, localOptions.get()); 
     213 
    102214            if (res.success()) 
    103215            { 
     
    105217                if (bNeedSkeleton) 
    106218                { 
     219                    ConvertBindMatrixVisitor convertBindMatrixVisitor; 
     220                    osgNode->accept(convertBindMatrixVisitor); 
    107221                    osgAnimation::Skeleton* osgSkeleton = new osgAnimation::Skeleton; 
    108222                    osgSkeleton->setDefaultUpdateCallback(); 
     
    121235                    //because the animations may be altered after registering 
    122236                    pAnimationManager->buildTargetReference(); 
    123  
    124237                    osgNode->setUpdateCallback(pAnimationManager.get()); 
    125238                } 
    126239 
    127240                KFbxAxisSystem fbxAxis = pScene->GetGlobalSettings().GetAxisSystem(); 
    128                 int upSign; 
    129                 KFbxAxisSystem::eUpVector eUp = fbxAxis.GetUpVector(upSign); 
    130                 bool bLeftHanded = fbxAxis.GetCoorSystem() == KFbxAxisSystem::LeftHanded; 
    131                 if (eUp != KFbxAxisSystem::YAxis || upSign < 0 || bLeftHanded) 
    132                 { 
     241 
     242                if (fbxAxis != KFbxAxisSystem::OpenGL) 
     243                { 
     244                    int upSign; 
     245                    KFbxAxisSystem::eUpVector eUp = fbxAxis.GetUpVector(upSign); 
     246                    bool bLeftHanded = fbxAxis.GetCoorSystem() == KFbxAxisSystem::LeftHanded; 
    133247                    float fSign = upSign < 0 ? -1.0f : 1.0f; 
    134248                    float zScale = bLeftHanded ? -1.0f : 1.0f; 
     
    147261                        break; 
    148262                    } 
    149                     osg::MatrixTransform* pTransform = new osg::MatrixTransform(mat); 
    150                     pTransform->addChild(osgNode); 
    151                     osgNode = pTransform; 
    152                 } 
    153  
     263 
     264                    osg::Transform* pTransformTemp = osgNode->asTransform(); 
     265                    osg::MatrixTransform* pMatrixTransform = pTransformTemp ? 
     266                        pTransformTemp->asMatrixTransform() : NULL; 
     267                    if (pMatrixTransform) 
     268                    { 
     269                        pMatrixTransform->setMatrix(pMatrixTransform->getMatrix() * mat); 
     270                    } 
     271                    else 
     272                    { 
     273                        pMatrixTransform = new osg::MatrixTransform(mat); 
     274                        if (useFbxRoot && isBasicRootNode(*osgNode)) 
     275                        { 
     276                            // If root node is a simple group, put all FBX elements under the OSG root 
     277                            osg::Group* osgGroup = osgNode->asGroup(); 
     278                            for(unsigned int i = 0; i < osgGroup->getNumChildren(); ++i) 
     279                            { 
     280                                pMatrixTransform->addChild(osgGroup->getChild(i)); 
     281                            } 
     282                            pMatrixTransform->setName(osgGroup->getName()); 
     283                        } 
     284                        else 
     285                        { 
     286                            pMatrixTransform->addChild(osgNode); 
     287                        } 
     288                    } 
     289                    osgNode = pMatrixTransform; 
     290                } 
     291 
     292                osgNode->setName(filenameInit); 
    154293                return osgNode; 
    155294            } 
     
    163302} 
    164303 
     304osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode( 
     305    const osg::Node& node, 
     306    const std::string& filename, 
     307    const Options* options) const 
     308{ 
     309    try 
     310    { 
     311        std::string ext = osgDB::getLowerCaseFileExtension(filename); 
     312        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; 
     313 
     314        osg::ref_ptr<Options> localOptions = options ? 
     315            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 
     316        localOptions->getDatabasePathList().push_front(osgDB::getFilePath(filename)); 
     317 
     318        KFbxSdkManager* pSdkManager = KFbxSdkManager::Create(); 
     319 
     320        if (!pSdkManager) 
     321        { 
     322            return WriteResult::ERROR_IN_WRITING_FILE; 
     323        } 
     324 
     325        CleanUpFbx cleanUpFbx(pSdkManager); 
     326 
     327        bool useFbxRoot = false; 
     328        if (options) 
     329        { 
     330            std::istringstream iss(options->getOptionString()); 
     331            std::string opt; 
     332            while (iss >> opt) 
     333            { 
     334                if (opt == "Embedded") 
     335                { 
     336                    IOSREF.SetBoolProp(EXP_FBX_EMBEDDED, true); 
     337                    if (KFbxIOSettings::IOSettingsRef().IsIOSettingsAllocated()) 
     338                        KFbxIOSettings::IOSettingsRef().AllocateIOSettings(*pSdkManager); 
     339                } 
     340                else if (opt == "UseFbxRoot") 
     341                { 
     342                    useFbxRoot = true; 
     343                } 
     344            } 
     345        } 
     346 
     347        KFbxScene* pScene = KFbxScene::Create(pSdkManager, ""); 
     348        WriterNodeVisitor writerNodeVisitor(pScene, pSdkManager, filename, 
     349            options, osgDB::getFilePath(node.getName().empty() ? filename : node.getName())); 
     350        if (useFbxRoot && isBasicRootNode(node)) 
     351        { 
     352            // If root node is a simple group, put all elements under the FBX root 
     353            const osg::Group * osgGroup = node.asGroup(); 
     354            for(unsigned int child=0; child<osgGroup->getNumChildren(); ++child) { 
     355                const_cast<osg::Node *>(osgGroup->getChild(child))->accept(writerNodeVisitor); 
     356            } 
     357        } 
     358        else { 
     359            // Normal scene 
     360            const_cast<osg::Node&>(node).accept(writerNodeVisitor); 
     361        } 
     362 
     363        KFbxExporter* lExporter = KFbxExporter::Create(pSdkManager, ""); 
     364        pScene->GetGlobalSettings().SetAxisSystem(KFbxAxisSystem::eOpenGL); 
     365 
     366        // Ensure the directory exists or else the FBX SDK will fail 
     367        if (!osgDB::makeDirectoryForFile(filename)) { 
     368            osg::notify(osg::NOTICE) << "Can't create directory for file '" << filename << "'. FBX SDK may fail creating the file." << std::endl; 
     369        } 
     370 
     371        // The FBX SDK interprets the filename as UTF-8 
     372#ifdef OSG_USE_UTF8_FILENAME 
     373        std::string utf8filename(filename); 
     374#else 
     375        std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); 
     376#endif 
     377 
     378        if (!lExporter->Initialize(utf8filename.c_str())) 
     379        { 
     380            return std::string(lExporter->GetLastErrorString()); 
     381        } 
     382        if (!lExporter->Export(pScene)) 
     383        { 
     384            return std::string(lExporter->GetLastErrorString()); 
     385        } 
     386 
     387        return WriteResult::FILE_SAVED; 
     388    } 
     389    catch (const std::string& s) 
     390    { 
     391        return s; 
     392    } 
     393    catch (const char* s) 
     394    { 
     395        return std::string(s); 
     396    } 
     397    catch (...) 
     398    { 
     399    } 
     400 
     401    return WriteResult::ERROR_IN_WRITING_FILE; 
     402} 
     403 
    165404/////////////////////////////////////////////////////////////////////////// 
    166405// Add ourself to the Registry to instantiate the reader/writer. 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/ReaderWriterFBX.h

    r10780 r11109  
    22#define READERWRITERFBX_H 
    33 
    4 #include <OpenThreads/ReentrantMutex> 
    54#include <osgDB/ReaderWriter> 
    65 
     
    1514    { 
    1615        supportsExtension("fbx", "FBX format"); 
     16        supportsOption("Embedded", "Embed textures in FBX file when writing"); 
     17        supportsOption("UseFbxRoot", "(Read/write option) If the source OSG root node is a simple group with no stateset, the writer will put its children directly under the FBX root, and vice-versa for reading"); 
    1718    } 
    1819 
    1920    const char* className() const { return "FBX reader/writer"; } 
    2021 
    21     /// The FBX SDK interprets the filename as UTF-8 
    22     ReadResult readNode(const std::string& utf8filename, const Options*) const; 
    23    
    24 private: 
    25     mutable OpenThreads::ReentrantMutex _serializerMutex; 
     22    virtual ReadResult readNode(const std::string& filename, const Options*) const; 
     23    virtual WriteResult writeNode(const osg::Node&, const std::string& filename, const Options*) const; 
    2624}; 
    2725 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRAnimation.cpp

    r10780 r11109  
    55#include <osgAnimation/Channel> 
    66#include <osgAnimation/Sampler> 
    7 #include <osgAnimation/UpdateCallback> 
    87 
    98#if defined(_MSC_VER) 
     
    2524 
    2625void readKeys(KFCurve* curveX, KFCurve* curveY, KFCurve* curveZ, 
    27               float scalar, const osg::Vec3& baseValue, bool multiply, 
    28               std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> >& keyFrameCntr) 
     26              std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> >& keyFrameCntr, float scalar = 1.0f) 
    2927{ 
    3028    KFCurve* curves[3] = {curveX, curveY, curveZ}; 
     
    5957    { 
    6058        float fTime = *it; 
    61         osg::Vec3 val(baseValue); 
     59        osg::Vec3 val; 
    6260        for (int i = 0; i < 3; ++i) 
    6361        { 
     
    6664            TimeFloatMap::iterator lb = curveTimeMap[i].lower_bound(fTime); 
    6765            if (lb == curveTimeMap[i].end()) --lb; 
    68             if (multiply) 
    69             { 
    70                 val[i] *= lb->second; 
    71             } 
    72             else 
    73             { 
    74                 val[i] += lb->second; 
    75             } 
     66            val[i] = lb->second; 
    7667        } 
    7768        keyFrameCntr.push_back(osgAnimation::Vec3Keyframe(fTime, val)); 
     
    8071 
    8172osgAnimation::Channel* readFbxChannels(KFCurve* curveX, KFCurve* curveY, 
    82     KFCurve* curveZ, const char* targetName, const char* channelName, 
    83     float scalar, const osg::Vec3& baseValue, bool multiply) 
    84 { 
    85     if (!curveX && !curveY && !curveZ) 
    86     { 
    87         return 0; 
    88     } 
    89  
    90     if (!curveX->KeyGetCount() && !curveY->KeyGetCount() && !curveZ->KeyGetCount()) 
     73    KFCurve* curveZ, const char* targetName, const char* channelName) 
     74{ 
     75    if (!(curveX && curveX->KeyGetCount()) && 
     76        !(curveY && curveY->KeyGetCount()) && 
     77        !(curveZ && curveZ->KeyGetCount())) 
    9178    { 
    9279        return 0; 
     
    9986    pChannel->setTargetName(targetName); 
    10087    pChannel->setName(channelName); 
    101     readKeys(curveX, curveY, curveZ, scalar, baseValue, multiply, *pKeyFrameCntr); 
     88    readKeys(curveX, curveY, curveZ, *pKeyFrameCntr); 
    10289 
    10390    return pChannel; 
     
    10693osgAnimation::Channel* readFbxChannels( 
    10794    KFbxTypedProperty<fbxDouble3>& fbxProp, const char* pTakeName, 
    108     const char* targetName, const char* channelName, const osg::Vec3& baseValue, float scalar, bool multiply) 
     95    const char* targetName, const char* channelName) 
    10996{ 
    11097    if (!fbxProp.IsValid()) return 0; 
     
    114101        fbxProp.GetKFCurve("Y", pTakeName), 
    115102        fbxProp.GetKFCurve("Z", pTakeName), 
    116         targetName, channelName, scalar, 
    117         baseValue * scalar, multiply); 
     103        targetName, channelName); 
    118104} 
    119105 
    120106osgAnimation::Channel* readFbxChannelsQuat( 
    121107    KFCurve* curveX, KFCurve* curveY, KFCurve* curveZ, const char* targetName, 
    122     const osg::Quat& baseQuat, ERotationOrder rotOrder) 
    123 { 
    124     if (!curveX && !curveY && !curveZ) 
     108    ERotationOrder rotOrder) 
     109{ 
     110    if (!(curveX && curveX->KeyGetCount()) && 
     111        !(curveY && curveY->KeyGetCount()) && 
     112        !(curveZ && curveZ->KeyGetCount())) 
    125113    { 
    126114        return 0; 
     
    132120    typedef std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> > KeyFrameCntr; 
    133121    KeyFrameCntr eulerFrameCntr; 
    134     readKeys(curveX, curveY, curveZ, static_cast<float>(osg::PI / 180.0), osg::Vec3(0,0,0), false, eulerFrameCntr); 
     122    readKeys(curveX, curveY, curveZ, eulerFrameCntr, static_cast<float>(osg::PI / 180.0)); 
    135123 
    136124    osgAnimation::QuatSphericalLinearSampler::KeyframeContainerType& quatFrameCntr = 
     
    143131        const osg::Vec3& euler = it->getValue(); 
    144132        quatFrameCntr.push_back(osgAnimation::QuatKeyframe( 
    145             it->getTime(), makeQuat(euler, rotOrder) * baseQuat)); 
     133            it->getTime(), makeQuat(euler, rotOrder))); 
    146134    } 
    147135 
     
    153141    osgAnimation::Channel* pRotationChannel, 
    154142    osgAnimation::Channel* pScaleChannel, 
    155     osg::ref_ptr<osgAnimation::AnimationManagerBase> &pAnimManager, 
     143    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager, 
    156144    const char* pTakeName) 
    157145{ 
     
    190178} 
    191179 
    192 osgAnimation::Animation* readFbxBoneAnimation(KFbxNode* pNode, 
     180osgAnimation::Animation* readFbxAnimation(KFbxNode* pNode, 
    193181    const char* pTakeName, const char* targetName, 
    194182    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager) 
     
    200188 
    201189    ERotationOrder rotOrder = pNode->RotationOrder.IsValid() ? pNode->RotationOrder.Get() : eEULER_XYZ; 
    202     osg::Quat inverseRot; 
    203190 
    204191    osgAnimation::Channel* pTranslationChannel = 0; 
     
    207194    if (pNode->LclRotation.IsValid()) 
    208195    { 
    209         inverseRot = makeQuat(pNode->LclRotation.Get(), rotOrder).inverse(); 
     196        fbxDouble3 fbxBaseValue = pNode->LclRotation.Get(); 
    210197 
    211198        pRotationChannel = readFbxChannelsQuat( 
     
    213200            pNode->LclRotation.GetKFCurve(KFCURVENODE_R_Y, pTakeName), 
    214201            pNode->LclRotation.GetKFCurve(KFCURVENODE_R_Z, pTakeName), 
    215             targetName, inverseRot, rotOrder); 
     202            targetName, rotOrder); 
    216203    } 
    217204 
    218205    if (pNode->LclTranslation.IsValid()) 
    219206    { 
    220         fbxDouble3 fbxBaseValue = pNode->LclTranslation.Get(); 
    221         osg::Vec3 offsetTranslation( 
    222             -static_cast<float>(fbxBaseValue[0]), 
    223             -static_cast<float>(fbxBaseValue[1]), 
    224             -static_cast<float>(fbxBaseValue[2])); 
    225  
    226207        pTranslationChannel = readFbxChannels( 
    227208            pNode->LclTranslation.GetKFCurve(KFCURVENODE_T_X, pTakeName), 
    228209            pNode->LclTranslation.GetKFCurve(KFCURVENODE_T_Y, pTakeName), 
    229210            pNode->LclTranslation.GetKFCurve(KFCURVENODE_T_Z, pTakeName), 
    230             targetName, "position", 1.0f, offsetTranslation, false); 
    231  
    232         if (pTranslationChannel) 
    233         { 
    234             osgAnimation::Vec3KeyframeContainer& keyFrameCntr = 
    235                 dynamic_cast<osgAnimation::Vec3KeyframeContainer&>( 
    236                 *pTranslationChannel->getSampler()->getKeyframeContainer()); 
    237  
    238             for (int i = 0; i < keyFrameCntr.size(); ++i) 
    239             { 
    240                 keyFrameCntr[i].setValue(inverseRot * keyFrameCntr[i].getValue()); 
    241             } 
    242         } 
     211            targetName, "translate"); 
    243212    } 
    244213 
    245214    osgAnimation::Channel* pScaleChannel = readFbxChannels( 
    246         pNode->LclScaling, pTakeName, targetName, "scale", osg::Vec3(0,0,0), 1.0f, true); 
     215        pNode->LclScaling, pTakeName, targetName, "scale"); 
    247216 
    248217    return addChannels(pTranslationChannel, pRotationChannel, pScaleChannel, pAnimManager, pTakeName); 
    249 } 
    250  
    251 osgAnimation::Animation* readFbxAnimation(KFbxNode* pNode, 
    252     const char* pTakeName, const char* targetName, 
    253     osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager) 
    254 { 
    255     if (!pTakeName) return 0; 
    256  
    257     osgAnimation::Channel* pTranslationChannel = readFbxChannels( 
    258         pNode->LclTranslation, pTakeName, targetName, "position", osg::Vec3(0,0,0), 1.0f, false); 
    259  
    260     //TODO: This will break if there are rotations in more than one of 
    261     // Pre/Lcl/Post so really they should each get their own MatrixTransform. 
    262     fbxDouble3 fbxPreRot = pNode->PreRotation.Get(); 
    263     fbxDouble3 fbxPostRot = pNode->PostRotation.Get(); 
    264     osg::Vec3 eulerOffset( 
    265         static_cast<float>(fbxPreRot[0] + fbxPostRot[0]), 
    266         static_cast<float>(fbxPreRot[1] + fbxPostRot[1]), 
    267         static_cast<float>(fbxPreRot[2] + fbxPostRot[2])); 
    268  
    269     osgAnimation::Channel* pRotationChannel = readFbxChannels( 
    270         pNode->LclRotation, pTakeName, targetName, "euler", eulerOffset, static_cast<float>(osg::PI / 180.0), false); 
    271  
    272     osgAnimation::Channel* pScaleChannel = readFbxChannels( 
    273         pNode->LclScaling, pTakeName, targetName, "scale", osg::Vec3(1,1,1), 1.0f, true); 
    274  
    275     return addChannels(pTranslationChannel, pRotationChannel, pScaleChannel, pAnimManager, pTakeName); 
    276 } 
    277  
    278 std::string readFbxBoneAnimation(KFbxNode* pNode, 
    279     osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager, 
    280     const char* targetName) 
    281 { 
    282     std::string result; 
    283     for (int i = 1; i < pNode->GetTakeNodeCount(); ++i) 
    284     { 
    285         const char* pTakeName = pNode->GetTakeNodeName(i); 
    286         if (osgAnimation::Animation* pAnimation = readFbxBoneAnimation( 
    287             pNode, pTakeName, targetName, pAnimManager)) 
    288         { 
    289             result = targetName; 
    290         } 
    291     } 
    292     return result; 
    293218} 
    294219 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRAnimation.h

    r10780 r11109  
    33 
    44#include <fbxfilesdk/fbxfilesdk_def.h> 
    5  
    6 std::string readFbxBoneAnimation( 
    7     FBXFILESDK_NAMESPACE::KFbxNode*, 
    8     osg::ref_ptr<osgAnimation::AnimationManagerBase>&, 
    9     const char* targetName); 
    105 
    116std::string readFbxAnimation( 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRMesh.cpp

    r10796 r11109  
     1#include <cassert> 
     2#include <sstream> 
     3 
    14#include <osg/Geode> 
    25#include <osg/Image> 
     
    133136 
    134137osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, 
    135     const std::vector<osg::ref_ptr<osg::Material>>& materialList, 
    136     const std::vector<osg::ref_ptr<osg::Texture>>& textureList, 
    137     GeometryType gt, unsigned mti, bool bNormal, bool bTexCoord, bool bColor) 
     138    std::vector<StateSetContent>& stateSetList, 
     139    GeometryType gt, unsigned int mti, bool bNormal, bool bTexCoord, bool bColor) 
    138140{ 
    139141    GeometryMap::iterator it = geometryMap.find(mti); 
     
    145147 
    146148    osg::ref_ptr<osg::Geometry> pGeometry; 
    147     if (gt == GEOMETRY_RIG) 
    148     { 
    149         osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry; 
    150         pRig->setInfluenceMap(new osgAnimation::VertexInfluenceMap); 
    151         pGeometry = pRig; 
    152     } 
    153     else if (gt == GEOMETRY_MORPH) 
     149    if (gt == GEOMETRY_MORPH) 
    154150    { 
    155151        pGeometry = new osgAnimation::MorphGeometry; 
     
    165161    if (bColor) pGeometry->setColorData(osg::Geometry::ArrayData(new osg::Vec4Array, osg::Geometry::BIND_PER_VERTEX)); 
    166162 
    167     if (mti < materialList.size()) 
    168     { 
    169         pGeometry->getOrCreateStateSet()->setAttributeAndModes(materialList[mti].get()); 
    170     } 
    171  
    172     if (mti < textureList.size()) 
    173     { 
    174         pGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, textureList[mti].get()); 
    175     } 
    176  
    177     geometryMap.insert(std::pair<unsigned, osg::ref_ptr<osg::Geometry>>(mti, pGeometry)); 
     163    if (mti < stateSetList.size()) 
     164    { 
     165        const StateSetContent& ss = stateSetList[mti]; 
     166        if(ss.first) 
     167            pGeometry->getOrCreateStateSet()->setAttributeAndModes(ss.first); 
     168        if(ss.second) 
     169            pGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, ss.second); 
     170    } 
     171 
     172    geometryMap.insert(std::pair<unsigned, osg::ref_ptr<osg::Geometry> >(mti, pGeometry)); 
    178173    pGeode->addDrawable(pGeometry.get()); 
    179174 
     
    196191void addChannel( 
    197192    osgAnimation::Channel* pChannel, 
    198     osg::ref_ptr<osgAnimation::AnimationManagerBase> &pAnimManager, 
     193    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager, 
    199194    const char* pTakeName) 
    200195{ 
     
    226221} 
    227222 
    228 void readAnimation(KFbxNode* pNode, osg::Geode* pGeode, 
     223void readAnimation(KFbxNode* pNode, const std::string& targetName, 
    229224    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    230225    KFbxMesh* pMesh, int nShape) 
     
    234229        const char* pTakeName = pNode->GetTakeNodeName(i); 
    235230 
    236         KFCurve* pCurve = pMesh->GetShapeChannel(nShape, true, pTakeName); 
     231        KFCurve* pCurve = pMesh->GetShapeChannel(nShape, false, pTakeName); 
     232        if (!pCurve) 
     233        { 
     234            continue; 
     235        } 
     236 
     237        int nKeys = pCurve->KeyGetCount(); 
     238        if (!nKeys) 
     239        { 
     240            continue; 
     241        } 
    237242 
    238243        osgAnimation::FloatLinearChannel* pChannel = new osgAnimation::FloatLinearChannel; 
    239244        std::vector<osgAnimation::TemplateKeyframe<float> >& keyFrameCntr = *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer(); 
    240  
    241         int nKeys = pCurve->KeyGetCount(); 
    242         if (!nKeys) 
    243         { 
    244             float fValue = static_cast<float>(pCurve->GetValue() * 0.01); 
    245             keyFrameCntr.push_back(osgAnimation::FloatKeyframe(0.0f,fValue)); 
    246         } 
    247245 
    248246        for (int k = 0; k < nKeys; ++k) 
     
    254252        } 
    255253 
    256         pChannel->setTargetName(pGeode->getName()); 
    257         pChannel->setName(pMesh->GetShapeName(nShape)); 
     254        pChannel->setTargetName(targetName); 
     255        std::stringstream ss; 
     256        ss << nShape; 
     257        pChannel->setName(ss.str()); 
    258258        addChannel(pChannel, pAnimationManager, pTakeName); 
    259259    } 
     
    262262osgDB::ReaderWriter::ReadResult readMesh(KFbxNode* pNode, KFbxMesh* fbxMesh, 
    263263    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    264     const std::vector<osg::ref_ptr<osg::Material>>& materialList, 
    265     const std::vector<osg::ref_ptr<osg::Texture>>& textureList, 
     264    std::vector<StateSetContent>& stateSetList, 
    266265    const char* szName) 
    267266{ 
     
    321320 
    322321        osg::Geometry* pGeometry = getGeometry(pGeode, geometryMap, 
    323             materialList, textureList, geomType, materialIndex, 
     322            stateSetList, geomType, materialIndex, 
    324323            pFbxNormals != 0, pFbxUVs != 0, pFbxColors != 0); 
    325324 
     
    347346            fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v2, GIPair(pGeometry, pVertices->size() + 2))); 
    348347 
    349  
    350348            pVertices->push_back(convertVec3(pFbxVertices[v0])); 
    351349            pVertices->push_back(convertVec3(pFbxVertices[v1])); 
     
    386384    { 
    387385        osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); 
    388         pGeometry->setName(pGeode->getName()); 
     386        if (pGeode->getNumDrawables() > 1) 
     387        { 
     388            std::stringstream ss; 
     389            ss << pGeode->getName() << " " << i + 1; 
     390            pGeometry->setName(ss.str()); 
     391        } 
     392        else 
     393        { 
     394            pGeometry->setName(pGeode->getName()); 
     395        } 
    389396 
    390397        osg::DrawArrays* pDrawArrays = new osg::DrawArrays( 
     
    395402    if (geomType == GEOMETRY_RIG) 
    396403    { 
     404        typedef std::map<osg::ref_ptr<osg::Geometry>, 
     405            osg::ref_ptr<osgAnimation::RigGeometry> > GeometryRigGeometryMap; 
     406        GeometryRigGeometryMap old2newGeometryMap; 
     407 
     408        for (int i = 0; i < pGeode->getNumDrawables(); ++i) 
     409        { 
     410            osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); 
     411            osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry; 
     412            pRig->setSourceGeometry(pGeometry); 
     413            pRig->copyFrom(*pGeometry); 
     414            old2newGeometryMap.insert(GeometryRigGeometryMap::value_type( 
     415                pGeometry, pRig)); 
     416            pRig->setDataVariance(osg::Object::DYNAMIC); 
     417            pRig->setUseDisplayList( false ); 
     418            pGeode->setDrawable(i, pRig); 
     419 
     420            pRig->setInfluenceMap(new osgAnimation::VertexInfluenceMap); 
     421            pGeometry = pRig; 
     422        } 
     423 
    397424        for (int i = 0; i < nDeformerCount; ++i) 
    398425        { 
     
    419446                    { 
    420447                        GIPair gi = it->second; 
    421                         osgAnimation::RigGeometry& rig = dynamic_cast<osgAnimation::RigGeometry&>(*gi.first); 
    422                         osgAnimation::VertexInfluenceMap& vim = *rig.getInfluenceMap(); 
    423                         osgAnimation::VertexInfluence& vi = getVertexInfluence(vim, pBone->GetName()); 
     448                        osgAnimation::RigGeometry& rig = 
     449                            dynamic_cast<osgAnimation::RigGeometry&>( 
     450                            *old2newGeometryMap[gi.first]); 
     451                        osgAnimation::VertexInfluenceMap& vim = 
     452                            *rig.getInfluenceMap(); 
     453                        osgAnimation::VertexInfluence& vi = 
     454                            getVertexInfluence(vim, pBone->GetName()); 
    424455                        vi.push_back(osgAnimation::VertexIndexWeight( 
    425456                            gi.second, weight)); 
     
    431462    else if (geomType == GEOMETRY_MORPH) 
    432463    { 
    433         pGeode->addUpdateCallback(new osgAnimation::UpdateMorph(pGeode->getName())); 
    434  
    435  
    436464        for (int i = 0; i < pGeode->getNumDrawables(); ++i) 
    437465        { 
     
    439467 
    440468            osgAnimation::MorphGeometry& morph = dynamic_cast<osgAnimation::MorphGeometry&>(*pGeometry); 
     469 
     470            pGeode->addUpdateCallback(new osgAnimation::UpdateMorph(morph.getName())); 
    441471 
    442472            //read morph geometry 
     
    464494                } 
    465495                pMorphTarget->setName(fbxMesh->GetShapeName(j)); 
    466                 KFCurve* pCurve = fbxMesh->GetShapeChannel(j); 
    467                 double defaultWeight = pCurve->GetValue() * 0.01; 
    468                 morph.addMorphTarget(pMorphTarget, static_cast<float>(defaultWeight)); 
    469  
    470                 readAnimation(pNode, pGeode, pAnimationManager, fbxMesh, j); 
     496                morph.addMorphTarget(pMorphTarget, 0.0f); 
     497 
     498                readAnimation(pNode, morph.getName(), pAnimationManager, fbxMesh, j); 
    471499            } 
    472500        } 
     
    535563osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxNode* pNode, 
    536564    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    537     const std::vector<osg::ref_ptr<osg::Material>>& materialList, 
    538     const std::vector<osg::ref_ptr<osg::Texture>>& textureList) 
     565    std::vector<StateSetContent>& stateSetList) 
    539566{ 
    540567    KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(pNode->GetNodeAttribute()); 
     
    545572    } 
    546573 
    547     return readMesh(pNode, lMesh, pAnimationManager, materialList, textureList, pNode->GetName()); 
    548 } 
     574    return readMesh(pNode, lMesh, pAnimationManager, stateSetList, pNode->GetName()); 
     575} 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRMesh.h

    r10780 r11109  
    55#include <osgDB/ReaderWriter> 
    66#include <osg/Material> 
    7  
     7#include "fbxMaterialToOsgStateSet.h" 
    88osgDB::ReaderWriter::ReadResult readFbxMesh( 
    99    FBXFILESDK_NAMESPACE::KFbxNode* pNode, 
    1010    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    11     const std::vector<osg::ref_ptr<osg::Material>>&, 
    12     const std::vector<osg::ref_ptr<osg::Texture>>&); 
     11    std::vector<StateSetContent> &); 
    1312 
    1413#endif 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRNode.cpp

    r10780 r11109  
     1#include <cassert> 
    12#include <memory> 
    2  
     3#include <sstream> 
     4 
     5#include <osg/io_utils> 
    36#include <osg/Notify> 
    47#include <osg/MatrixTransform> 
     
    1013 
    1114#include <osgAnimation/AnimationManagerBase> 
     15#include <osgAnimation/Bone> 
    1216#include <osgAnimation/Skeleton> 
    13 #include <osgAnimation/UpdateCallback> 
     17#include <osgAnimation/StackedMatrixElement> 
     18#include <osgAnimation/StackedQuaternionElement> 
     19#include <osgAnimation/StackedScaleElement> 
     20#include <osgAnimation/StackedTranslateElement> 
     21#include <osgAnimation/UpdateBone> 
    1422 
    1523#if defined(_MSC_VER) 
     
    2230#include "fbxRLight.h" 
    2331#include "fbxRMesh.h" 
    24  
    25 template <typename FbxT, typename OsgT, typename ConvertFunc> 
    26 class FbxToOsgMap 
    27 { 
    28     std::map<const FbxT*, osg::ref_ptr<OsgT>> m_map; 
    29 public: 
    30     ConvertFunc m_convertFunc; 
    31  
    32     FbxToOsgMap(ConvertFunc convertFunc) : m_convertFunc(convertFunc) {} 
    33  
    34     osg::ref_ptr<OsgT> Get(const FbxT* fbx) 
    35     { 
    36         if (!fbx) 
    37             return 0; 
    38         std::map<const FbxT*, osg::ref_ptr<OsgT>>::iterator it = m_map.find(fbx); 
    39         if (it != m_map.end()) 
    40         { 
    41             return it->second; 
    42         } 
    43         osg::ref_ptr<OsgT> osgObj = m_convertFunc(fbx); 
    44         m_map.insert(std::pair<const FbxT*, osg::ref_ptr<OsgT>>(fbx, osgObj)); 
    45         return osgObj; 
    46     } 
    47 }; 
    48  
    49 struct GetOsgTexture 
    50 { 
    51     const std::string& m_dir; 
    52  
    53     GetOsgTexture(const std::string& dir) : m_dir(dir) {} 
    54  
    55     static osg::Texture::WrapMode convertWrap(KFbxTexture::EWrapMode wrap) 
    56     { 
    57         return wrap == KFbxTexture::eREPEAT ? 
    58             osg::Texture2D::REPEAT : osg::Texture2D::CLAMP_TO_EDGE; 
    59     } 
    60  
    61     osg::ref_ptr<osg::Texture2D> operator () (const KFbxTexture* fbx) 
    62     { 
    63         osg::Image* pImage; 
    64         if ((pImage = osgDB::readImageFile(osgDB::concatPaths(m_dir, fbx->GetRelativeFileName()))) || 
    65             (pImage = osgDB::readImageFile(osgDB::concatPaths(m_dir, fbx->GetFileName())))) 
    66         { 
    67             osg::ref_ptr<osg::Texture2D> pOsgTex = new osg::Texture2D; 
    68  
    69             pOsgTex->setImage(pImage); 
    70             pOsgTex->setWrap(osg::Texture2D::WRAP_S, convertWrap(fbx->GetWrapModeU())); 
    71             pOsgTex->setWrap(osg::Texture2D::WRAP_T, convertWrap(fbx->GetWrapModeV())); 
    72  
    73             return pOsgTex; 
    74         } 
    75         else 
    76         { 
    77             return 0; 
    78         } 
    79     } 
    80 }; 
    81  
    82 struct GetOsgMaterial 
    83 { 
    84     typedef FbxToOsgMap<KFbxTexture, osg::Texture2D, GetOsgTexture> TextureMap; 
    85     TextureMap m_textureMap; 
    86  
    87 public: 
    88     osg::ref_ptr<osg::Texture2D> m_pTexture; 
    89  
    90     GetOsgMaterial(const std::string& dir) : m_textureMap(GetOsgTexture(dir)){} 
    91  
    92     osg::ref_ptr<osg::Material> operator () (const KFbxSurfaceMaterial* pFbxMat) 
    93     { 
    94         osg::ref_ptr<osg::Material> pOsgMat = new osg::Material; 
    95  
    96         const KFbxSurfaceLambert* pFbxLambert = dynamic_cast<const KFbxSurfaceLambert*>(pFbxMat); 
    97  
    98         const KFbxProperty lProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sDiffuse); 
    99         if(lProperty.IsValid()){ 
    100             int lNbTex = lProperty.GetSrcObjectCount(KFbxTexture::ClassId); 
    101             for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) 
    102             { 
    103                 const KFbxTexture* lTexture = KFbxCast<KFbxTexture>(lProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex));  
    104                 if(lTexture) 
    105                 { 
    106                     m_pTexture = m_textureMap.Get(lTexture); 
    107                 } 
    108  
    109                 //For now only allow 1 texture 
    110                 break; 
    111             } 
    112         } 
    113  
    114         if (pFbxLambert) 
    115         { 
    116             fbxDouble3 color = pFbxLambert->GetDiffuseColor().Get(); 
    117             double factor = pFbxLambert->GetDiffuseFactor().Get(); 
    118             pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4( 
    119                 static_cast<float>(color[0] * factor), 
    120                 static_cast<float>(color[1] * factor), 
    121                 static_cast<float>(color[2] * factor), 
    122                 static_cast<float>(1.0 - pFbxLambert->GetTransparencyFactor().Get()))); 
    123  
    124             color = pFbxLambert->GetAmbientColor().Get(); 
    125             factor = pFbxLambert->GetAmbientFactor().Get(); 
    126             pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4( 
    127                 static_cast<float>(color[0] * factor), 
    128                 static_cast<float>(color[1] * factor), 
    129                 static_cast<float>(color[2] * factor), 
    130                 1.0f)); 
    131  
    132             color = pFbxLambert->GetEmissiveColor().Get(); 
    133             factor = pFbxLambert->GetEmissiveFactor().Get(); 
    134             pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4( 
    135                 static_cast<float>(color[0] * factor), 
    136                 static_cast<float>(color[1] * factor), 
    137                 static_cast<float>(color[2] * factor), 
    138                 1.0f)); 
    139  
    140             if (const KFbxSurfacePhong* pFbxPhong = dynamic_cast<const KFbxSurfacePhong*>(pFbxLambert)) 
    141             { 
    142                 color = pFbxPhong->GetSpecularColor().Get(); 
    143                 factor = pFbxPhong->GetSpecularFactor().Get(); 
    144                 pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4( 
    145                     static_cast<float>(color[0] * factor), 
    146                     static_cast<float>(color[1] * factor), 
    147                     static_cast<float>(color[2] * factor), 
    148                     1.0f)); 
    149  
    150                 pOsgMat->setShininess(osg::Material::FRONT_AND_BACK, 
    151                     static_cast<float>(pFbxPhong->GetShininess().Get())); 
    152             } 
    153         } 
    154  
    155         return pOsgMat; 
    156     } 
    157 }; 
     32#include "fbxRNode.h" 
     33#include "fbxMaterialToOsgStateSet.h" 
    15834 
    15935osg::Quat makeQuat(const fbxDouble3& degrees, ERotationOrder fbxRotOrder) 
     
    260136} 
    261137 
    262 void getApproximateTransform(const KFbxNode* pNode, osg::Vec3& trans, osg::Quat& quat, osg::Vec3& scale) 
    263 { 
    264     ERotationOrder fbxRotOrder = pNode->RotationOrder.Get(); 
    265  
    266     fbxDouble3 fbxLclPos = pNode->LclTranslation.Get(); 
    267     //fbxDouble3 fbxRotOff = pNode->RotationOffset.Get(); 
    268     //fbxDouble3 fbxRotPiv = pNode->RotationPivot.Get(); 
    269     fbxDouble3 fbxPreRot = pNode->PreRotation.Get(); 
    270     fbxDouble3 fbxLclRot = pNode->LclRotation.Get(); 
    271     fbxDouble3 fbxPostRot = pNode->PostRotation.Get(); 
    272     //fbxDouble3 fbxSclOff = pNode->ScalingOffset.Get(); 
    273     //fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get(); 
    274     fbxDouble3 fbxLclScl = pNode->LclScaling.Get(); 
    275  
    276     trans.set( 
    277         static_cast<float>(fbxLclPos[0]), 
    278         static_cast<float>(fbxLclPos[1]), 
    279         static_cast<float>(fbxLclPos[2])); 
    280  
    281     quat = 
    282         makeQuat(fbxPostRot, fbxRotOrder) * 
    283         makeQuat(fbxLclRot, fbxRotOrder) * 
    284         makeQuat(fbxPreRot, fbxRotOrder); 
    285  
    286     scale.set( 
    287         static_cast<float>(fbxLclScl[0]), 
    288         static_cast<float>(fbxLclScl[1]), 
    289         static_cast<float>(fbxLclScl[2])); 
    290 } 
    291  
    292 void getApproximateTransform(const KFbxNode* pNode, osg::Vec3& trans, osg::Vec3& euler, osg::Vec3& scale) 
    293 { 
    294     //ERotationOrder fbxRotOrder = pNode->RotationOrder.Get(); 
    295  
    296     fbxDouble3 fbxLclPos = pNode->LclTranslation.Get(); 
    297     //fbxDouble3 fbxRotOff = pNode->RotationOffset.Get(); 
    298     //fbxDouble3 fbxRotPiv = pNode->RotationPivot.Get(); 
    299     fbxDouble3 fbxPreRot = pNode->PreRotation.Get(); 
    300     fbxDouble3 fbxLclRot = pNode->LclRotation.Get(); 
    301     fbxDouble3 fbxPostRot = pNode->PostRotation.Get(); 
    302     //fbxDouble3 fbxSclOff = pNode->ScalingOffset.Get(); 
    303     //fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get(); 
    304     fbxDouble3 fbxLclScl = pNode->LclScaling.Get(); 
    305  
    306     trans.set( 
    307         static_cast<float>(fbxLclPos[0]), 
    308         static_cast<float>(fbxLclPos[1]), 
    309         static_cast<float>(fbxLclPos[2])); 
    310  
    311     //TODO: Convert each rotation to a quaternion, concatenate them and extract euler from that. 
    312     euler.set( 
    313         osg::DegreesToRadians(static_cast<float>(fbxPreRot[0] + fbxLclRot[0] + fbxPostRot[0])), 
    314         osg::DegreesToRadians(static_cast<float>(fbxPreRot[1] + fbxLclRot[1] + fbxPostRot[1])), 
    315         osg::DegreesToRadians(static_cast<float>(fbxPreRot[2] + fbxLclRot[2] + fbxPostRot[2]))); 
    316  
    317     scale.set( 
    318         static_cast<float>(fbxLclScl[0]), 
    319         static_cast<float>(fbxLclScl[1]), 
    320         static_cast<float>(fbxLclScl[2])); 
    321 } 
    322  
    323138bool readBindPose(KFbxSdkManager& pManager, KFbxNode* pNode, 
    324     osgAnimation::Bone* osgBone) 
     139                  osgAnimation::Bone* osgBone) 
    325140{ 
    326141    KArrayTemplate<KFbxPose*> pPoseList; 
     
    333148 
    334149    const double* pMat = pPoseList[0]->GetMatrix(pIndex[0]); 
    335     osgBone->setBindMatrixInBoneSpace(osg::Matrix(pMat)); 
     150    osgBone->setMatrix(osg::Matrix(pMat)); 
    336151    return true; 
     152} 
     153 
     154void readTranslationElement(KFbxTypedProperty<fbxDouble3>& prop, 
     155                            osgAnimation::UpdateMatrixTransform* pUpdate, 
     156                            osg::Matrix& staticTransform) 
     157{ 
     158    fbxDouble3 fbxPropValue = prop.Get(); 
     159    osg::Vec3d val( 
     160        fbxPropValue[0], 
     161        fbxPropValue[1], 
     162        fbxPropValue[2]); 
     163 
     164    if (prop.GetKFCurve(KFCURVENODE_T_X) || 
     165        prop.GetKFCurve(KFCURVENODE_T_Y) || 
     166        prop.GetKFCurve(KFCURVENODE_T_Z)) 
     167    { 
     168        if (!staticTransform.isIdentity()) 
     169        { 
     170            pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform)); 
     171            staticTransform.makeIdentity(); 
     172        } 
     173        pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", val)); 
     174    } 
     175    else 
     176    { 
     177        staticTransform.preMultTranslate(val); 
     178    } 
     179} 
     180 
     181void readRotationElement(KFbxTypedProperty<fbxDouble3>& prop, 
     182                         ERotationOrder fbxRotOrder, 
     183                         osgAnimation::UpdateMatrixTransform* pUpdate, 
     184                         osg::Matrix& staticTransform) 
     185{ 
     186    osg::Quat quat = makeQuat(prop.Get(), fbxRotOrder); 
     187 
     188    if (prop.GetKFCurve(KFCURVENODE_R_X) || 
     189        prop.GetKFCurve(KFCURVENODE_R_Y) || 
     190        prop.GetKFCurve(KFCURVENODE_R_Z)) 
     191    { 
     192        if (!staticTransform.isIdentity()) 
     193        { 
     194            pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform)); 
     195            staticTransform.makeIdentity(); 
     196        } 
     197        pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedQuaternionElement("quaternion", quat)); 
     198    } 
     199    else 
     200    { 
     201        staticTransform.preMultRotate(quat); 
     202    } 
     203} 
     204 
     205void readScaleElement(KFbxTypedProperty<fbxDouble3>& prop, 
     206                      osgAnimation::UpdateMatrixTransform* pUpdate, 
     207                      osg::Matrix& staticTransform) 
     208{ 
     209    fbxDouble3 fbxPropValue = prop.Get(); 
     210    osg::Vec3d val( 
     211        fbxPropValue[0], 
     212        fbxPropValue[1], 
     213        fbxPropValue[2]); 
     214 
     215    if (prop.GetKFCurve(KFCURVENODE_S_X) || 
     216        prop.GetKFCurve(KFCURVENODE_S_Y) || 
     217        prop.GetKFCurve(KFCURVENODE_S_Z)) 
     218    { 
     219        if (!staticTransform.isIdentity()) 
     220        { 
     221            pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform)); 
     222            staticTransform.makeIdentity(); 
     223        } 
     224        pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedScaleElement("scale", val)); 
     225    } 
     226    else 
     227    { 
     228        staticTransform.preMultScale(val); 
     229    } 
     230} 
     231 
     232void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, KFbxNode* pNode) 
     233{ 
     234    osg::Matrix staticTransform; 
     235 
     236    readTranslationElement(pNode->LclTranslation, pUpdate, staticTransform); 
     237 
     238    fbxDouble3 fbxRotOffset = pNode->RotationOffset.Get(); 
     239    fbxDouble3 fbxRotPiv = pNode->RotationPivot.Get(); 
     240    staticTransform.preMultTranslate(osg::Vec3d( 
     241        fbxRotPiv[0] + fbxRotOffset[0], 
     242        fbxRotPiv[1] + fbxRotOffset[1], 
     243        fbxRotPiv[2] + fbxRotOffset[2])); 
     244 
     245    ERotationOrder fbxRotOrder = pNode->RotationOrder.IsValid() ? pNode->RotationOrder.Get() : eEULER_XYZ; 
     246 
     247    staticTransform.preMultRotate(makeQuat(pNode->PreRotation.Get(), fbxRotOrder)); 
     248 
     249    readRotationElement(pNode->LclRotation, fbxRotOrder, pUpdate, staticTransform); 
     250 
     251    staticTransform.preMultRotate(makeQuat(pNode->PostRotation.Get(), fbxRotOrder)); 
     252 
     253    fbxDouble3 fbxSclOffset = pNode->ScalingOffset.Get(); 
     254    fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get(); 
     255    staticTransform.preMultTranslate(osg::Vec3d( 
     256        fbxSclOffset[0] + fbxSclPiv[0] - fbxRotPiv[0], 
     257        fbxSclOffset[1] + fbxSclPiv[1] - fbxRotPiv[1], 
     258        fbxSclOffset[2] + fbxSclPiv[2] - fbxRotPiv[2])); 
     259 
     260    readScaleElement(pNode->LclScaling, pUpdate, staticTransform); 
     261 
     262    staticTransform.preMultTranslate(osg::Vec3d( 
     263        -fbxSclPiv[0], 
     264        -fbxSclPiv[1], 
     265        -fbxSclPiv[2])); 
     266 
     267    if (!staticTransform.isIdentity()) 
     268    { 
     269        pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform)); 
     270    } 
    337271} 
    338272 
     
    345279        osgBone->setDataVariance(osg::Object::DYNAMIC); 
    346280        osgBone->setName(pNode->GetName()); 
    347         osgBone->setDefaultUpdateCallback(animName); 
     281        osgAnimation::UpdateBone* pUpdate = new osgAnimation::UpdateBone(animName); 
     282        readUpdateMatrixTransform(pUpdate, pNode); 
     283        osgBone->setUpdateCallback(pUpdate); 
    348284 
    349285        readBindPose(pSdkManager, pNode, osgBone); 
     
    363299        osg::MatrixTransform* pTransform = new osg::MatrixTransform(localMatrix); 
    364300        pTransform->setName(pNode->GetName()); 
     301 
    365302        if (bAnimated) 
    366303        { 
    367             osgAnimation::UpdateTransform* pUpdate = new osgAnimation::UpdateTransform(animName); 
    368  
    369             osg::Vec3 trans, rot, scale; 
    370             getApproximateTransform(pNode, trans, rot, scale); 
    371  
    372             pUpdate->getPosition()->setValue(trans); 
    373             pUpdate->getEuler()->setValue(rot); 
    374             pUpdate->getScale()->setValue(scale); 
     304            osgAnimation::UpdateMatrixTransform* pUpdate = new osgAnimation::UpdateMatrixTransform(animName); 
     305            readUpdateMatrixTransform(pUpdate, pNode); 
    375306            pTransform->setUpdateCallback(pUpdate); 
    376307        } 
     308 
    377309        return pTransform; 
    378310    } 
     
    382314    KFbxSdkManager& pSdkManager, KFbxNode* pNode, 
    383315    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    384     const std::string& dir, bool& bNeedSkeleton, int& nLightCount) 
     316    bool& bNeedSkeleton, int& nLightCount, 
     317    FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, 
     318    const osgDB::Options* options) 
    385319{ 
    386320    if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute()) 
     
    405339 
    406340    unsigned nMaterials = pNode->GetMaterialCount(); 
    407     std::vector<osg::ref_ptr<osg::Material>> materialList; 
    408     std::vector<osg::ref_ptr<osg::Texture>> textureList; 
    409     materialList.reserve(nMaterials); 
    410  
    411     typedef FbxToOsgMap<KFbxSurfaceMaterial, osg::Material, GetOsgMaterial> MaterialMap; 
    412     MaterialMap materialMap(dir); 
     341    std::vector<StateSetContent > stateSetList; 
    413342 
    414343    for (unsigned i = 0; i < nMaterials; ++i) 
    415344    { 
    416         materialList.push_back(materialMap.Get(pNode->GetMaterial(i))); 
    417         textureList.push_back(materialMap.m_convertFunc.m_pTexture); 
     345        KFbxSurfaceMaterial* fbxMaterial = pNode->GetMaterial(i); 
     346        assert(fbxMaterial); 
     347        stateSetList.push_back(fbxMaterialToOsgStateSet.convert(fbxMaterial)); 
    418348    } 
    419349 
     
    433363        bool bChildNeedSkeleton = false; 
    434364        osgDB::ReaderWriter::ReadResult childResult = readFbxNode( 
    435             pSdkManager, pChildNode, pAnimationManager, dir, 
    436             bChildNeedSkeleton, nLightCount); 
     365            pSdkManager, pChildNode, pAnimationManager, 
     366            bChildNeedSkeleton, nLightCount, fbxMaterialToOsgStateSet, options); 
    437367        if (childResult.error()) 
    438368        { 
     
    453383    } 
    454384 
    455     std::string animName; 
    456      
    457     if (bNeedSkeleton) 
    458     { 
    459         animName = readFbxBoneAnimation(pNode, pAnimationManager, 
    460             pNode->GetName()); 
    461     } 
    462     else 
    463     { 
    464         animName = readFbxAnimation(pNode, pAnimationManager, pNode->GetName()); 
    465     } 
     385    std::string animName = readFbxAnimation(pNode, pAnimationManager, pNode->GetName()); 
    466386 
    467387    osg::Matrix localMatrix; 
     
    476396    { 
    477397    case KFbxNodeAttribute::eUNIDENTIFIED: 
    478         if (children.size() + skeletal.size() == 1) 
     398        if (bLocalMatrixIdentity && children.size() + skeletal.size() == 1) 
    479399        { 
    480400            if (children.size() == 1) 
     
    491411        { 
    492412            osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pNode, 
    493                 pAnimationManager, materialList, textureList); 
     413                pAnimationManager, stateSetList); 
    494414            if (meshRes.error()) 
    495415            { 
     
    507427                } 
    508428                osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bNeedSkeleton); 
     429                assert(osgGroup->getStateSet() == NULL); 
    509430                osgGroup->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); 
    510431 
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRNode.h

    r10780 r11109  
    22#define FBXRNODE_H 
    33 
     4#include "fbxMaterialToOsgStateSet.h" 
    45namespace osgAnimation 
    56{ 
     
    1112    FBXFILESDK_NAMESPACE::KFbxNode* pNode, 
    1213    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 
    13     const std::string& dir, 
    1414    bool& bNeedSkeleton, 
    15     int& nLightCount); 
     15    int& nLightCount, 
     16    FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, 
     17    const osgDB::Options* options = NULL); 
    1618 
    1719#endif