From fd6f3edf15e07192a2e6868580f9a9a726caeadd Mon Sep 17 00:00:00 2001 From: Michael PLATINGS Date: Wed, 3 Mar 2010 16:14:04 +0000 Subject: [PATCH] --- src/osgPlugins/fbx/ReaderWriterFBX.cpp | 90 ++++---------- src/osgPlugins/fbx/fbxRMesh.cpp | 107 ++++++++-------- src/osgPlugins/fbx/fbxRMesh.h | 8 +- src/osgPlugins/fbx/fbxRNode.cpp | 164 ++++++++++++++----------- src/osgPlugins/fbx/fbxRNode.h | 6 +- 5 files changed, 179 insertions(+), 196 deletions(-) diff --git a/src/osgPlugins/fbx/ReaderWriterFBX.cpp b/src/osgPlugins/fbx/ReaderWriterFBX.cpp index 51ea6bfbe..0bd6ead45 100644 --- a/src/osgPlugins/fbx/ReaderWriterFBX.cpp +++ b/src/osgPlugins/fbx/ReaderWriterFBX.cpp @@ -8,7 +8,6 @@ #include #include #include - #include #include #include @@ -27,43 +26,6 @@ #include "fbxMaterialToOsgStateSet.h" #include "WriterNodeVisitor.h" -#if defined(WIN32) && !defined(__CYGWIN__) -#define WIN32_LEAN_AND_MEAN -//For MultiByteToWideChar -#include -#endif - -// This function belongs in osgDB. Delete this function and use the osgDB -// version once Robert accepts the submission. -std::string convertStringFromCurrentCodePageToUTF8(const std::string& str) -{ -#if defined(WIN32) && !defined(__CYGWIN__) - if (str.length() == 0) - { - return std::string(); - } - - int utf16Length = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), 0, 0); - if (utf16Length <= 0) - { - osg::notify(osg::WARN) << "Cannot convert multi-byte string to UTF-8." << std::endl; - return std::string(); - } - - std::wstring sUTF16(utf16Length, L'\0'); - utf16Length = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &sUTF16[0], utf16Length); - if (utf16Length <= 0) - { - osg::notify(osg::WARN) << "Cannot convert multi-byte string to UTF-8." << std::endl; - return std::string(); - } - - return osgDB::convertUTF16toUTF8(sUTF16); -#else - return str; -#endif -} - /// Returns true if the given node is a basic root group with no special information. /// Used in conjunction with UseFbxRoot option. /// Identity transforms are considered as basic root nodes. @@ -161,7 +123,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, #ifdef OSG_USE_UTF8_FILENAME const std::string& utf8filename(filename); #else - std::string utf8filename(convertStringFromCurrentCodePageToUTF8(filename)); + std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); #endif int fileFormat; @@ -197,9 +159,9 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, if (KFbxNode* pNode = pScene->GetRootNode()) { - pScene->SetCurrentTake(pScene->GetCurrentTakeName()); + pScene->SetCurrentTake(pScene->GetCurrentTakeName()); - bool useFbxRoot = false; + bool useFbxRoot = false; if (options) { std::istringstream iss(options->getOptionString()); @@ -226,33 +188,33 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, std::string filePath = osgDB::getFilePath(filename); FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get()); - std::map nodeMap; - std::map boneBindMatrices; - std::map skeletonMap; + std::map nodeMap; + std::map boneBindMatrices; + std::map skeletonMap; ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager, bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap, - boneBindMatrices, skeletonMap, localOptions.get()); + boneBindMatrices, skeletonMap, localOptions.get()); if (res.success()) { - for (std::map::const_iterator it = boneBindMatrices.begin(); - it != boneBindMatrices.end(); ++it) - { - std::map::iterator nodeIt = nodeMap.find(it->first); - if (nodeIt != nodeMap.end()) - { - osgAnimation::Bone& osgBone = dynamic_cast(*nodeIt->second); - osgBone.setInvBindMatrixInSkeletonSpace(it->second); - } - else - { - assert(0); - } - } + for (std::map::const_iterator it = boneBindMatrices.begin(); + it != boneBindMatrices.end(); ++it) + { + std::map::iterator nodeIt = nodeMap.find(it->first); + if (nodeIt != nodeMap.end()) + { + osgAnimation::Bone& osgBone = dynamic_cast(*nodeIt->second); + osgBone.setInvBindMatrixInSkeletonSpace(it->second); + } + else + { + assert(0); + } + } - osg::Node* osgNode = res.getNode(); - osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); - osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON); + osg::Node* osgNode = res.getNode(); + osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); + osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON); if (pAnimationManager.valid()) { @@ -327,7 +289,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, } catch (...) { - osg::notify(osg::WARN) << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl; + osg::notify(osg::WARN) << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl; } return ReadResult::ERROR_IN_READING_FILE; @@ -404,7 +366,7 @@ osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode( #ifdef OSG_USE_UTF8_FILENAME const std::string& utf8filename(filename); #else - std::string utf8filename(convertStringFromCurrentCodePageToUTF8(filename)); + std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); #endif if (!lExporter->Initialize(utf8filename.c_str())) diff --git a/src/osgPlugins/fbx/fbxRMesh.cpp b/src/osgPlugins/fbx/fbxRMesh.cpp index 501a7e470..bafee57c4 100644 --- a/src/osgPlugins/fbx/fbxRMesh.cpp +++ b/src/osgPlugins/fbx/fbxRMesh.cpp @@ -261,12 +261,12 @@ void readAnimation(KFbxNode* pNode, const std::string& targetName, } osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, - KFbxNode* pNode, KFbxMesh* fbxMesh, + KFbxNode* pNode, KFbxMesh* fbxMesh, osg::ref_ptr& pAnimationManager, std::vector& stateSetList, - const char* szName, - std::map& boneBindMatrices, - std::map& skeletonMap) + const char* szName, + std::map& boneBindMatrices, + std::map& skeletonMap) { GeometryMap geometryMap; @@ -413,7 +413,7 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, { osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); - osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry; + osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry; pRig->setSourceGeometry(pGeometry); pRig->copyFrom(*pGeometry); old2newGeometryMap.insert(GeometryRigGeometryMap::value_type( @@ -433,17 +433,17 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, for (int j = 0; j < nClusters; ++j) { KFbxCluster* pCluster = (KFbxCluster*)pSkin->GetCluster(j); - //assert(KFbxCluster::eNORMALIZE == pCluster->GetLinkMode()); + //assert(KFbxCluster::eNORMALIZE == pCluster->GetLinkMode()); KFbxNode* pBone = pCluster->GetLink(); - KFbxXMatrix transformLink; - pCluster->GetTransformLinkMatrix(transformLink); - KFbxXMatrix transformLinkInverse = transformLink.Inverse(); - const double* pTransformLinkInverse = transformLinkInverse; - if (!boneBindMatrices.insert(std::pair(pBone, osg::Matrix(pTransformLinkInverse))).second) - { - osg::notify(osg::WARN) << "Multiple meshes attached to a bone - bind matrices may be incorrect." << std::endl; - } + KFbxXMatrix transformLink; + pCluster->GetTransformLinkMatrix(transformLink); + KFbxXMatrix transformLinkInverse = transformLink.Inverse(); + const double* pTransformLinkInverse = transformLinkInverse; + if (!boneBindMatrices.insert(std::pair(pBone, osg::Matrix(pTransformLinkInverse))).second) + { + osg::notify(osg::WARN) << "Multiple meshes attached to a bone - bind matrices may be incorrect." << std::endl; + } int nIndices = pCluster->GetControlPointIndicesCount(); int* pIndices = pCluster->GetControlPointIndices(); @@ -555,57 +555,56 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, } } - KFbxXMatrix fbxVertexTransform; - fbxVertexTransform.SetTRS( + KFbxXMatrix fbxGeometricTransform; + fbxGeometricTransform.SetTRS( pNode->GeometricTranslation.Get(), pNode->GeometricRotation.Get(), pNode->GeometricScaling.Get()); - const double* pVertexMat = fbxVertexTransform; - osg::Matrix vertexMat(pVertexMat); + const double* pGeometricMat = fbxGeometricTransform; + osg::Matrix osgGeometricTransform(pGeometricMat); - // Bind shape matrix - // For some models this is necessary, however for other models (such as - // those exported from Blender) it shouldn't be applied. - // TODO: Figure out how to make this work in all cases. - KArrayTemplate pPoseList; - KArrayTemplate pIndex; - if (KFbxPose::GetBindPoseContaining( - pSdkManager, pNode, pPoseList, pIndex)) - { - const double* pBindShapeMat = pPoseList[0]->GetMatrix(pIndex[0]); - vertexMat.postMult(osg::Matrix(pBindShapeMat)); - } - - osg::Node* pResult = pGeode; - - if (!vertexMat.isIdentity()) + if (geomType == GEOMETRY_RIG) { - osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(vertexMat); - pMatTrans->addChild(pGeode); - pResult = pMatTrans; + KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN); + if (pSkin->GetClusterCount()) + { + KFbxXMatrix fbxTransformMatrix; + pSkin->GetCluster(0)->GetTransformMatrix(fbxTransformMatrix); + const double* pTransformMatrix = fbxTransformMatrix; + osgGeometricTransform.postMult(osg::Matrix(pTransformMatrix)); + } } - if (geomType == GEOMETRY_RIG) - { - //Add the geometry to the skeleton ancestor of one of the bones. - KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN); - if (pSkin->GetClusterCount()) - { - osgAnimation::Skeleton* pSkeleton = getSkeleton(pSkin->GetCluster(0)->GetLink(), skeletonMap); - pSkeleton->addChild(pResult); - return osgDB::ReaderWriter::ReadResult::FILE_LOADED; - } - } + osg::Node* pResult = pGeode; - return osgDB::ReaderWriter::ReadResult(pResult); + if (!osgGeometricTransform.isIdentity()) + { + osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(osgGeometricTransform); + pMatTrans->addChild(pGeode); + pResult = pMatTrans; + } + + if (geomType == GEOMETRY_RIG) + { + //Add the geometry to the skeleton ancestor of one of the bones. + KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN); + if (pSkin->GetClusterCount()) + { + osgAnimation::Skeleton* pSkeleton = getSkeleton(pSkin->GetCluster(0)->GetLink(), skeletonMap); + pSkeleton->addChild(pResult); + return osgDB::ReaderWriter::ReadResult::FILE_LOADED; + } + } + + return osgDB::ReaderWriter::ReadResult(pResult); } osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager, - KFbxNode* pNode, + KFbxNode* pNode, osg::ref_ptr& pAnimationManager, - std::vector& stateSetList, - std::map& boneBindMatrices, - std::map& skeletonMap) + std::vector& stateSetList, + std::map& boneBindMatrices, + std::map& skeletonMap) { KFbxMesh* lMesh = dynamic_cast(pNode->GetNodeAttribute()); @@ -615,5 +614,5 @@ osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager, } return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList, - pNode->GetName(), boneBindMatrices, skeletonMap); + pNode->GetName(), boneBindMatrices, skeletonMap); } diff --git a/src/osgPlugins/fbx/fbxRMesh.h b/src/osgPlugins/fbx/fbxRMesh.h index bcb4fdea2..97c3d3c48 100644 --- a/src/osgPlugins/fbx/fbxRMesh.h +++ b/src/osgPlugins/fbx/fbxRMesh.h @@ -6,11 +6,11 @@ #include #include "fbxMaterialToOsgStateSet.h" osgDB::ReaderWriter::ReadResult readFbxMesh( - FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager, - FBXFILESDK_NAMESPACE::KFbxNode* pNode, + FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager, + FBXFILESDK_NAMESPACE::KFbxNode* pNode, osg::ref_ptr& pAnimationManager, std::vector&, - std::map& boneBindMatrices, - std::map& skeletonMap); + std::map& boneBindMatrices, + std::map& skeletonMap); #endif diff --git a/src/osgPlugins/fbx/fbxRNode.cpp b/src/osgPlugins/fbx/fbxRNode.cpp index f4d896638..cc7024f4a 100644 --- a/src/osgPlugins/fbx/fbxRNode.cpp +++ b/src/osgPlugins/fbx/fbxRNode.cpp @@ -47,29 +47,29 @@ osg::Quat makeQuat(const fbxDouble3& degrees, ERotationOrder fbxRotOrder) radiansZ, osg::Vec3d(0,0,1)); case eEULER_XZY: return osg::Quat( - radiansX, osg::Vec3d(1,0,0), - radiansZ, osg::Vec3d(0,0,1), - radiansY, osg::Vec3d(0,1,0)); + radiansX, osg::Vec3d(1,0,0), + radiansZ, osg::Vec3d(0,0,1), + radiansY, osg::Vec3d(0,1,0)); case eEULER_YZX: - return osg::Quat( - radiansY, osg::Vec3d(0,1,0), - radiansZ, osg::Vec3d(0,0,1), - radiansX, osg::Vec3d(1,0,0)); + return osg::Quat( + radiansY, osg::Vec3d(0,1,0), + radiansZ, osg::Vec3d(0,0,1), + radiansX, osg::Vec3d(1,0,0)); case eEULER_YXZ: - return osg::Quat( - radiansY, osg::Vec3d(0,1,0), - radiansX, osg::Vec3d(1,0,0), - radiansZ, osg::Vec3d(0,0,1)); + return osg::Quat( + radiansY, osg::Vec3d(0,1,0), + radiansX, osg::Vec3d(1,0,0), + radiansZ, osg::Vec3d(0,0,1)); case eEULER_ZXY: return osg::Quat( radiansZ, osg::Vec3d(0,0,1), radiansX, osg::Vec3d(1,0,0), radiansY, osg::Vec3d(0,1,0)); case eEULER_ZYX: - return osg::Quat( - radiansZ, osg::Vec3d(0,0,1), - radiansY, osg::Vec3d(0,1,0), - radiansX, osg::Vec3d(1,0,0)); + return osg::Quat( + radiansZ, osg::Vec3d(0,0,1), + radiansY, osg::Vec3d(0,1,0), + radiansX, osg::Vec3d(1,0,0)); case eSPHERIC_XYZ: { //I don't know what eSPHERIC_XYZ means, so this is a complete guess. @@ -104,7 +104,11 @@ void makeLocalMatrix(const KFbxNode* pNode, osg::Matrix& m) ScalingPivotInverse: inverse of ScalingPivot */ - ERotationOrder fbxRotOrder = pNode->RotationOrder.Get(); + // When this flag is set to false, the RotationOrder, the Pre/Post rotation + // values and the rotation limits should be ignored. + bool rotationActive = pNode->RotationActive.Get(); + + ERotationOrder fbxRotOrder = rotationActive ? pNode->RotationOrder.Get() : eEULER_XYZ; fbxDouble3 fbxLclPos = pNode->LclTranslation.Get(); fbxDouble3 fbxRotOff = pNode->RotationOffset.Get(); @@ -120,10 +124,17 @@ void makeLocalMatrix(const KFbxNode* pNode, osg::Matrix& m) fbxLclPos[0] + fbxRotOff[0] + fbxRotPiv[0], fbxLclPos[1] + fbxRotOff[1] + fbxRotPiv[1], fbxLclPos[2] + fbxRotOff[2] + fbxRotPiv[2])); - m.preMultRotate( - makeQuat(fbxPostRot, fbxRotOrder) * - makeQuat(fbxLclRot, fbxRotOrder) * - makeQuat(fbxPreRot, fbxRotOrder)); + if (rotationActive) + { + m.preMultRotate( + makeQuat(fbxPostRot, fbxRotOrder) * + makeQuat(fbxLclRot, fbxRotOrder) * + makeQuat(fbxPreRot, fbxRotOrder)); + } + else + { + m.preMultRotate(makeQuat(fbxLclRot, fbxRotOrder)); + } m.preMultTranslate(osg::Vec3d( fbxSclOff[0] + fbxSclPiv[0] - fbxRotPiv[0], fbxSclOff[1] + fbxSclPiv[1] - fbxRotPiv[1], @@ -226,13 +237,24 @@ void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, KFb fbxRotPiv[1] + fbxRotOffset[1], fbxRotPiv[2] + fbxRotOffset[2])); - ERotationOrder fbxRotOrder = pNode->RotationOrder.IsValid() ? pNode->RotationOrder.Get() : eEULER_XYZ; + // When this flag is set to false, the RotationOrder, the Pre/Post rotation + // values and the rotation limits should be ignored. + bool rotationActive = pNode->RotationActive.Get(); - staticTransform.preMultRotate(makeQuat(pNode->PreRotation.Get(), fbxRotOrder)); + ERotationOrder fbxRotOrder = (rotationActive && pNode->RotationOrder.IsValid()) ? + pNode->RotationOrder.Get() : eEULER_XYZ; + + if (rotationActive) + { + staticTransform.preMultRotate(makeQuat(pNode->PreRotation.Get(), fbxRotOrder)); + } readRotationElement(pNode->LclRotation, fbxRotOrder, pUpdate, staticTransform); - staticTransform.preMultRotate(makeQuat(pNode->PostRotation.Get(), fbxRotOrder)); + if (rotationActive) + { + staticTransform.preMultRotate(makeQuat(pNode->PostRotation.Get(), fbxRotOrder)); + } fbxDouble3 fbxSclOffset = pNode->ScalingOffset.Get(); fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get(); @@ -256,7 +278,7 @@ void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, KFb osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode, const std::string& animName, const osg::Matrix& localMatrix, bool bNeedSkeleton, - std::map& nodeMap) + std::map& nodeMap) { if (bNeedSkeleton) { @@ -267,7 +289,7 @@ osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode, readUpdateMatrixTransform(pUpdate, pNode); osgBone->setUpdateCallback(pUpdate); - nodeMap.insert(std::pair(pNode, osgBone)); + nodeMap.insert(std::pair(pNode, osgBone)); return osgBone; } @@ -300,9 +322,9 @@ osgDB::ReaderWriter::ReadResult readFbxNode( osg::ref_ptr& pAnimationManager, bool& bIsBone, int& nLightCount, FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, - std::map& nodeMap, - std::map& boneBindMatrices, - std::map& skeletonMap, + std::map& nodeMap, + std::map& boneBindMatrices, + std::map& skeletonMap, const osgDB::Options* options) { if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute()) @@ -315,8 +337,8 @@ osgDB::ReaderWriter::ReadResult readFbxNode( } } - bIsBone = false; - bool bCreateSkeleton = false; + bIsBone = false; + bool bCreateSkeleton = false; KFbxNodeAttribute::EAttributeType lAttributeType = KFbxNodeAttribute::eUNIDENTIFIED; if (pNode->GetNodeAttribute()) @@ -355,7 +377,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( osgDB::ReaderWriter::ReadResult childResult = readFbxNode( pSdkManager, pChildNode, pAnimationManager, bChildIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap, - boneBindMatrices, skeletonMap, options); + boneBindMatrices, skeletonMap, options); if (childResult.error()) { return childResult; @@ -364,7 +386,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( { if (bChildIsBone) { - if (!bIsBone) bCreateSkeleton = true; + if (!bIsBone) bCreateSkeleton = true; skeletal.push_back(osgChild); } else @@ -401,23 +423,23 @@ osgDB::ReaderWriter::ReadResult readFbxNode( break; case KFbxNodeAttribute::eMESH: { - size_t bindMatrixCount = boneBindMatrices.size(); + size_t bindMatrixCount = boneBindMatrices.size(); osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager, - pNode, pAnimationManager, stateSetList, boneBindMatrices, skeletonMap); + pNode, pAnimationManager, stateSetList, boneBindMatrices, skeletonMap); if (meshRes.error()) { return meshRes; } else if (osg::Node* node = meshRes.getNode()) { - bEmpty = false; + bEmpty = false; - if (bindMatrixCount != boneBindMatrices.size()) - { - //The mesh is skinned therefore the bind matrix will handle all transformations. - localMatrix.makeIdentity(); - bLocalMatrixIdentity = true; - } + if (bindMatrixCount != boneBindMatrices.size()) + { + //The mesh is skinned therefore the bind matrix will handle all transformations. + localMatrix.makeIdentity(); + bLocalMatrixIdentity = true; + } if (animName.empty() && children.empty() && @@ -427,7 +449,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( return osgDB::ReaderWriter::ReadResult(node); } - children.insert(children.begin(), node); + children.insert(children.begin(), node); } } break; @@ -451,7 +473,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( } else { - children.insert(children.begin(), resGroup); + children.insert(children.begin(), resGroup); } } } @@ -465,14 +487,14 @@ osgDB::ReaderWriter::ReadResult readFbxNode( if (!osgGroup) osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bIsBone, nodeMap); - osg::Group* pAddChildrenTo = osgGroup.get(); - if (bCreateSkeleton) - { - osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, skeletonMap); - osgSkeleton->setDefaultUpdateCallback(); - pAddChildrenTo->addChild(osgSkeleton); - pAddChildrenTo = osgSkeleton; - } + osg::Group* pAddChildrenTo = osgGroup.get(); + if (bCreateSkeleton) + { + osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, skeletonMap); + osgSkeleton->setDefaultUpdateCallback(); + pAddChildrenTo->addChild(osgSkeleton); + pAddChildrenTo = osgSkeleton; + } for (osg::NodeList::iterator it = skeletal.begin(); it != skeletal.end(); ++it) { @@ -488,26 +510,26 @@ osgDB::ReaderWriter::ReadResult readFbxNode( } osgAnimation::Skeleton* getSkeleton(KFbxNode* fbxNode, - std::map& skeletonMap) + std::map& skeletonMap) { - //Find the first non-skeleton ancestor of the node. - while (fbxNode && - fbxNode->GetNodeAttribute() && - fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON) - { - fbxNode = fbxNode->GetParent(); - } + //Find the first non-skeleton ancestor of the node. + while (fbxNode && + fbxNode->GetNodeAttribute() && + fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON) + { + fbxNode = fbxNode->GetParent(); + } - std::map::const_iterator it = skeletonMap.find(fbxNode); - if (it == skeletonMap.end()) - { - osgAnimation::Skeleton* skel = new osgAnimation::Skeleton; - skel->setDefaultUpdateCallback(); - skeletonMap.insert(std::pair(fbxNode, skel)); - return skel; - } - else - { - return it->second; - } + std::map::const_iterator it = skeletonMap.find(fbxNode); + if (it == skeletonMap.end()) + { + osgAnimation::Skeleton* skel = new osgAnimation::Skeleton; + skel->setDefaultUpdateCallback(); + skeletonMap.insert(std::pair(fbxNode, skel)); + return skel; + } + else + { + return it->second; + } } diff --git a/src/osgPlugins/fbx/fbxRNode.h b/src/osgPlugins/fbx/fbxRNode.h index 50cda219f..20a5f26c0 100644 --- a/src/osgPlugins/fbx/fbxRNode.h +++ b/src/osgPlugins/fbx/fbxRNode.h @@ -16,9 +16,9 @@ osgDB::ReaderWriter::ReadResult readFbxNode( bool& bIsBone, int& nLightCount, FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, - std::map& nodeMap, - std::map& boneBindMatrices, - std::map& skeletonMap, + std::map& nodeMap, + std::map& boneBindMatrices, + std::map& skeletonMap, const osgDB::Options* options = NULL); #endif