This commit is contained in:
parent
1f4060ead6
commit
2609c4aa02
@ -1,5 +1,6 @@
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/MatrixTransform>
|
||||
@ -133,26 +134,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ConvertBindMatrixVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
ConvertBindMatrixVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
virtual void apply(osg::MatrixTransform& node)
|
||||
{
|
||||
if (osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node))
|
||||
{
|
||||
bone->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(bone->getMatrixInBoneSpace()));
|
||||
if (const osgAnimation::Bone* parent = bone->getBoneParent())
|
||||
{
|
||||
bone->setInvBindMatrixInSkeletonSpace(parent->getInvBindMatrixInSkeletonSpace() * bone->getInvBindMatrixInSkeletonSpace());
|
||||
}
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
};
|
||||
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterFBX::readNode(const std::string& filenameInit,
|
||||
const Options* options) const
|
||||
@ -189,9 +170,8 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager, "");
|
||||
lImporter->SetFileFormat(fileFormat);
|
||||
|
||||
if (!lImporter->Initialize(utf8filename.c_str()))
|
||||
if (!lImporter->Initialize(utf8filename.c_str(), fileFormat))
|
||||
{
|
||||
return std::string(lImporter->GetLastErrorString());
|
||||
}
|
||||
@ -217,7 +197,9 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
||||
|
||||
if (KFbxNode* pNode = pScene->GetRootNode())
|
||||
{
|
||||
bool useFbxRoot = false;
|
||||
pScene->SetCurrentTake(pScene->GetCurrentTakeName());
|
||||
|
||||
bool useFbxRoot = false;
|
||||
if (options)
|
||||
{
|
||||
std::istringstream iss(options->getOptionString());
|
||||
@ -232,7 +214,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase> pAnimationManager;
|
||||
bool bNeedSkeleton = false;
|
||||
bool bIsBone = false;
|
||||
int nLightCount = 0;
|
||||
osg::ref_ptr<Options> localOptions = NULL;
|
||||
if (options)
|
||||
@ -243,22 +225,35 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
||||
|
||||
std::string filePath = osgDB::getFilePath(filename);
|
||||
FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get());
|
||||
|
||||
|
||||
std::map<KFbxNode*, osg::Node*> nodeMap;
|
||||
std::map<KFbxNode*, osg::Matrix> boneBindMatrices;
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*> skeletonMap;
|
||||
ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager,
|
||||
bNeedSkeleton, nLightCount, fbxMaterialToOsgStateSet, localOptions.get());
|
||||
bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
|
||||
boneBindMatrices, skeletonMap, localOptions.get());
|
||||
|
||||
if (res.success())
|
||||
{
|
||||
osg::Node* osgNode = res.getNode();
|
||||
if (bNeedSkeleton)
|
||||
{
|
||||
ConvertBindMatrixVisitor convertBindMatrixVisitor;
|
||||
osgNode->accept(convertBindMatrixVisitor);
|
||||
osgAnimation::Skeleton* osgSkeleton = new osgAnimation::Skeleton;
|
||||
osgSkeleton->setDefaultUpdateCallback();
|
||||
osgSkeleton->addChild(osgNode);
|
||||
osgNode = osgSkeleton;
|
||||
}
|
||||
for (std::map<KFbxNode*, osg::Matrix>::const_iterator it = boneBindMatrices.begin();
|
||||
it != boneBindMatrices.end(); ++it)
|
||||
{
|
||||
std::map<KFbxNode*, osg::Node*>::iterator nodeIt = nodeMap.find(it->first);
|
||||
if (nodeIt != nodeMap.end())
|
||||
{
|
||||
osgAnimation::Bone& osgBone = dynamic_cast<osgAnimation::Bone&>(*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);
|
||||
|
||||
if (pAnimationManager.valid())
|
||||
{
|
||||
if (osgNode->getUpdateCallback())
|
||||
@ -332,6 +327,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
osg::notify(osg::WARN) << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl;
|
||||
}
|
||||
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <fbxsdk.h>
|
||||
|
||||
#include "fbxRMesh.h"
|
||||
#include "fbxRNode.h"
|
||||
|
||||
enum GeometryType
|
||||
{
|
||||
@ -259,10 +260,13 @@ void readAnimation(KFbxNode* pNode, const std::string& targetName,
|
||||
}
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readMesh(KFbxNode* pNode, KFbxMesh* fbxMesh,
|
||||
osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
|
||||
KFbxNode* pNode, KFbxMesh* fbxMesh,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
std::vector<StateSetContent>& stateSetList,
|
||||
const char* szName)
|
||||
const char* szName,
|
||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
||||
{
|
||||
GeometryMap geometryMap;
|
||||
|
||||
@ -408,7 +412,8 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxNode* pNode, KFbxMesh* fbxMesh,
|
||||
for (int i = 0; i < pGeode->getNumDrawables(); ++i)
|
||||
{
|
||||
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(
|
||||
@ -428,8 +433,18 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxNode* pNode, KFbxMesh* fbxMesh,
|
||||
for (int j = 0; j < nClusters; ++j)
|
||||
{
|
||||
KFbxCluster* pCluster = (KFbxCluster*)pSkin->GetCluster(j);
|
||||
//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<KFbxNode*, osg::Matrix>(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();
|
||||
double* pWeights = pCluster->GetControlPointWeights();
|
||||
@ -542,27 +557,55 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxNode* pNode, KFbxMesh* fbxMesh,
|
||||
|
||||
KFbxXMatrix fbxVertexTransform;
|
||||
fbxVertexTransform.SetTRS(
|
||||
pNode->GetGeometricTranslation(KFbxNode::eSOURCE_SET),
|
||||
pNode->GetGeometricRotation(KFbxNode::eSOURCE_SET),
|
||||
pNode->GetGeometricScaling(KFbxNode::eSOURCE_SET));
|
||||
pNode->GeometricTranslation.Get(),
|
||||
pNode->GeometricRotation.Get(),
|
||||
pNode->GeometricScaling.Get());
|
||||
const double* pVertexMat = fbxVertexTransform;
|
||||
osg::Matrix vertexMat(pVertexMat);
|
||||
|
||||
if (vertexMat.isIdentity())
|
||||
{
|
||||
return osgDB::ReaderWriter::ReadResult(pGeode);
|
||||
}
|
||||
else
|
||||
// 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<KFbxPose*> pPoseList;
|
||||
KArrayTemplate<int> 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())
|
||||
{
|
||||
osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(vertexMat);
|
||||
pMatTrans->addChild(pGeode);
|
||||
return osgDB::ReaderWriter::ReadResult(pMatTrans);
|
||||
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(KFbxNode* pNode,
|
||||
osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager,
|
||||
KFbxNode* pNode,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
std::vector<StateSetContent>& stateSetList)
|
||||
std::vector<StateSetContent>& stateSetList,
|
||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
||||
{
|
||||
KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(pNode->GetNodeAttribute());
|
||||
|
||||
@ -571,5 +614,6 @@ osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxNode* pNode,
|
||||
return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
return readMesh(pNode, lMesh, pAnimationManager, stateSetList, pNode->GetName());
|
||||
return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList,
|
||||
pNode->GetName(), boneBindMatrices, skeletonMap);
|
||||
}
|
||||
|
@ -6,8 +6,11 @@
|
||||
#include <osg/Material>
|
||||
#include "fbxMaterialToOsgStateSet.h"
|
||||
osgDB::ReaderWriter::ReadResult readFbxMesh(
|
||||
FBXFILESDK_NAMESPACE::KFbxNode* pNode,
|
||||
FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager,
|
||||
FBXFILESDK_NAMESPACE::KFbxNode* pNode,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
std::vector<StateSetContent> &);
|
||||
std::vector<StateSetContent>&,
|
||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap);
|
||||
|
||||
#endif
|
||||
|
@ -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),
|
||||
radiansY, osg::Vec3d(0,0,1),
|
||||
radiansZ, 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(
|
||||
radiansX, osg::Vec3d(0,1,0),
|
||||
radiansY, osg::Vec3d(0,0,1),
|
||||
radiansZ, 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(
|
||||
radiansX, osg::Vec3d(0,1,0),
|
||||
radiansY, 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(
|
||||
radiansX, osg::Vec3d(0,0,1),
|
||||
radiansY, osg::Vec3d(1,0,0),
|
||||
radiansZ, osg::Vec3d(0,1,0));
|
||||
radiansZ, osg::Vec3d(0,0,1),
|
||||
radiansX, osg::Vec3d(1,0,0),
|
||||
radiansY, osg::Vec3d(0,1,0));
|
||||
case eEULER_ZYX:
|
||||
return osg::Quat(
|
||||
radiansX, osg::Vec3d(0,0,1),
|
||||
radiansY, osg::Vec3d(0,1,0),
|
||||
radiansZ, 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.
|
||||
@ -135,22 +135,6 @@ void makeLocalMatrix(const KFbxNode* pNode, osg::Matrix& m)
|
||||
-fbxSclPiv[2]));
|
||||
}
|
||||
|
||||
bool readBindPose(KFbxSdkManager& pManager, KFbxNode* pNode,
|
||||
osgAnimation::Bone* osgBone)
|
||||
{
|
||||
KArrayTemplate<KFbxPose*> pPoseList;
|
||||
KArrayTemplate<int> pIndex;
|
||||
if (!pNode || !KFbxPose::GetBindPoseContaining(
|
||||
pManager, pNode, pPoseList, pIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const double* pMat = pPoseList[0]->GetMatrix(pIndex[0]);
|
||||
osgBone->setMatrix(osg::Matrix(pMat));
|
||||
return true;
|
||||
}
|
||||
|
||||
void readTranslationElement(KFbxTypedProperty<fbxDouble3>& prop,
|
||||
osgAnimation::UpdateMatrixTransform* pUpdate,
|
||||
osg::Matrix& staticTransform)
|
||||
@ -271,7 +255,8 @@ void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, KFb
|
||||
}
|
||||
|
||||
osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode,
|
||||
const std::string& animName, const osg::Matrix& localMatrix, bool bNeedSkeleton)
|
||||
const std::string& animName, const osg::Matrix& localMatrix, bool bNeedSkeleton,
|
||||
std::map<KFbxNode*, osg::Node*>& nodeMap)
|
||||
{
|
||||
if (bNeedSkeleton)
|
||||
{
|
||||
@ -282,7 +267,7 @@ osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode,
|
||||
readUpdateMatrixTransform(pUpdate, pNode);
|
||||
osgBone->setUpdateCallback(pUpdate);
|
||||
|
||||
readBindPose(pSdkManager, pNode, osgBone);
|
||||
nodeMap.insert(std::pair<KFbxNode*, osg::Node*>(pNode, osgBone));
|
||||
|
||||
return osgBone;
|
||||
}
|
||||
@ -313,8 +298,11 @@ osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode,
|
||||
osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
KFbxSdkManager& pSdkManager, KFbxNode* pNode,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
bool& bNeedSkeleton, int& nLightCount,
|
||||
bool& bIsBone, int& nLightCount,
|
||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
||||
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||
const osgDB::Options* options)
|
||||
{
|
||||
if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute())
|
||||
@ -327,13 +315,16 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
}
|
||||
}
|
||||
|
||||
bIsBone = false;
|
||||
bool bCreateSkeleton = false;
|
||||
|
||||
KFbxNodeAttribute::EAttributeType lAttributeType = KFbxNodeAttribute::eUNIDENTIFIED;
|
||||
if (pNode->GetNodeAttribute())
|
||||
{
|
||||
lAttributeType = pNode->GetNodeAttribute()->GetAttributeType();
|
||||
if (lAttributeType == KFbxNodeAttribute::eSKELETON)
|
||||
{
|
||||
bNeedSkeleton = true;
|
||||
bIsBone = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,19 +351,20 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
continue;
|
||||
}
|
||||
|
||||
bool bChildNeedSkeleton = false;
|
||||
bool bChildIsBone = false;
|
||||
osgDB::ReaderWriter::ReadResult childResult = readFbxNode(
|
||||
pSdkManager, pChildNode, pAnimationManager,
|
||||
bChildNeedSkeleton, nLightCount, fbxMaterialToOsgStateSet, options);
|
||||
bChildIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
|
||||
boneBindMatrices, skeletonMap, options);
|
||||
if (childResult.error())
|
||||
{
|
||||
return childResult;
|
||||
}
|
||||
else if (osg::Node* osgChild = childResult.getNode())
|
||||
{
|
||||
if (bChildNeedSkeleton)
|
||||
if (bChildIsBone)
|
||||
{
|
||||
bNeedSkeleton = true;
|
||||
if (!bIsBone) bCreateSkeleton = true;
|
||||
skeletal.push_back(osgChild);
|
||||
}
|
||||
else
|
||||
@ -390,7 +382,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
|
||||
osg::ref_ptr<osg::Group> osgGroup;
|
||||
|
||||
bool bEmpty = children.empty() && !bNeedSkeleton;
|
||||
bool bEmpty = children.empty() && !bIsBone;
|
||||
|
||||
switch (lAttributeType)
|
||||
{
|
||||
@ -409,15 +401,24 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
break;
|
||||
case KFbxNodeAttribute::eMESH:
|
||||
{
|
||||
osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pNode,
|
||||
pAnimationManager, stateSetList);
|
||||
size_t bindMatrixCount = boneBindMatrices.size();
|
||||
osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager,
|
||||
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 (animName.empty() &&
|
||||
children.empty() &&
|
||||
skeletal.empty() &&
|
||||
@ -425,11 +426,8 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
{
|
||||
return osgDB::ReaderWriter::ReadResult(node);
|
||||
}
|
||||
osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bNeedSkeleton);
|
||||
assert(osgGroup->getStateSet() == NULL);
|
||||
osgGroup->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);
|
||||
|
||||
osgGroup->addChild(node);
|
||||
children.insert(children.begin(), node);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -453,9 +451,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
}
|
||||
else
|
||||
{
|
||||
osgGroup = createGroupNode(pSdkManager, pNode, animName,
|
||||
localMatrix, bNeedSkeleton);
|
||||
osgGroup->addChild(resGroup);
|
||||
children.insert(children.begin(), resGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,15 +463,51 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
osgDB::ReaderWriter::ReadResult(0);
|
||||
}
|
||||
|
||||
if (!osgGroup) osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bNeedSkeleton);
|
||||
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;
|
||||
}
|
||||
|
||||
for (osg::NodeList::iterator it = skeletal.begin(); it != skeletal.end(); ++it)
|
||||
{
|
||||
osgGroup->addChild(it->get());
|
||||
pAddChildrenTo->addChild(it->get());
|
||||
}
|
||||
for (osg::NodeList::iterator it = children.begin(); it != children.end(); ++it)
|
||||
{
|
||||
osgGroup->addChild(it->get());
|
||||
pAddChildrenTo->addChild(it->get());
|
||||
}
|
||||
|
||||
|
||||
return osgDB::ReaderWriter::ReadResult(osgGroup.get());
|
||||
}
|
||||
|
||||
osgAnimation::Skeleton* getSkeleton(KFbxNode* fbxNode,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
||||
{
|
||||
//Find the first non-skeleton ancestor of the node.
|
||||
while (fbxNode &&
|
||||
fbxNode->GetNodeAttribute() &&
|
||||
fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON)
|
||||
{
|
||||
fbxNode = fbxNode->GetParent();
|
||||
}
|
||||
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>::const_iterator it = skeletonMap.find(fbxNode);
|
||||
if (it == skeletonMap.end())
|
||||
{
|
||||
osgAnimation::Skeleton* skel = new osgAnimation::Skeleton;
|
||||
skel->setDefaultUpdateCallback();
|
||||
skeletonMap.insert(std::pair<KFbxNode*, osgAnimation::Skeleton*>(fbxNode, skel));
|
||||
return skel;
|
||||
}
|
||||
else
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,18 @@ namespace osgAnimation
|
||||
class AnimationManagerBase;
|
||||
}
|
||||
|
||||
osgAnimation::Skeleton* getSkeleton(KFbxNode*, std::map<KFbxNode*, osgAnimation::Skeleton*>&);
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager,
|
||||
FBXFILESDK_NAMESPACE::KFbxNode* pNode,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
bool& bNeedSkeleton,
|
||||
bool& bIsBone,
|
||||
int& nLightCount,
|
||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
||||
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||
const osgDB::Options* options = NULL);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user