This commit is contained in:
parent
315e0521c9
commit
fd6f3edf15
@ -8,7 +8,6 @@
|
|||||||
#include <osg/PositionAttitudeTransform>
|
#include <osg/PositionAttitudeTransform>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osgDB/ConvertUTF>
|
#include <osgDB/ConvertUTF>
|
||||||
|
|
||||||
#include <osgDB/FileNameUtils>
|
#include <osgDB/FileNameUtils>
|
||||||
#include <osgDB/FileUtils>
|
#include <osgDB/FileUtils>
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
@ -27,43 +26,6 @@
|
|||||||
#include "fbxMaterialToOsgStateSet.h"
|
#include "fbxMaterialToOsgStateSet.h"
|
||||||
#include "WriterNodeVisitor.h"
|
#include "WriterNodeVisitor.h"
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
//For MultiByteToWideChar
|
|
||||||
#include <Windows.h>
|
|
||||||
#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.
|
/// Returns true if the given node is a basic root group with no special information.
|
||||||
/// Used in conjunction with UseFbxRoot option.
|
/// Used in conjunction with UseFbxRoot option.
|
||||||
/// Identity transforms are considered as basic root nodes.
|
/// Identity transforms are considered as basic root nodes.
|
||||||
@ -161,7 +123,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
|||||||
#ifdef OSG_USE_UTF8_FILENAME
|
#ifdef OSG_USE_UTF8_FILENAME
|
||||||
const std::string& utf8filename(filename);
|
const std::string& utf8filename(filename);
|
||||||
#else
|
#else
|
||||||
std::string utf8filename(convertStringFromCurrentCodePageToUTF8(filename));
|
std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int fileFormat;
|
int fileFormat;
|
||||||
@ -197,9 +159,9 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
|||||||
|
|
||||||
if (KFbxNode* pNode = pScene->GetRootNode())
|
if (KFbxNode* pNode = pScene->GetRootNode())
|
||||||
{
|
{
|
||||||
pScene->SetCurrentTake(pScene->GetCurrentTakeName());
|
pScene->SetCurrentTake(pScene->GetCurrentTakeName());
|
||||||
|
|
||||||
bool useFbxRoot = false;
|
bool useFbxRoot = false;
|
||||||
if (options)
|
if (options)
|
||||||
{
|
{
|
||||||
std::istringstream iss(options->getOptionString());
|
std::istringstream iss(options->getOptionString());
|
||||||
@ -226,33 +188,33 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
|||||||
std::string filePath = osgDB::getFilePath(filename);
|
std::string filePath = osgDB::getFilePath(filename);
|
||||||
FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get());
|
FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get());
|
||||||
|
|
||||||
std::map<KFbxNode*, osg::Node*> nodeMap;
|
std::map<KFbxNode*, osg::Node*> nodeMap;
|
||||||
std::map<KFbxNode*, osg::Matrix> boneBindMatrices;
|
std::map<KFbxNode*, osg::Matrix> boneBindMatrices;
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*> skeletonMap;
|
std::map<KFbxNode*, osgAnimation::Skeleton*> skeletonMap;
|
||||||
ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager,
|
ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager,
|
||||||
bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
|
bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
|
||||||
boneBindMatrices, skeletonMap, localOptions.get());
|
boneBindMatrices, skeletonMap, localOptions.get());
|
||||||
|
|
||||||
if (res.success())
|
if (res.success())
|
||||||
{
|
{
|
||||||
for (std::map<KFbxNode*, osg::Matrix>::const_iterator it = boneBindMatrices.begin();
|
for (std::map<KFbxNode*, osg::Matrix>::const_iterator it = boneBindMatrices.begin();
|
||||||
it != boneBindMatrices.end(); ++it)
|
it != boneBindMatrices.end(); ++it)
|
||||||
{
|
{
|
||||||
std::map<KFbxNode*, osg::Node*>::iterator nodeIt = nodeMap.find(it->first);
|
std::map<KFbxNode*, osg::Node*>::iterator nodeIt = nodeMap.find(it->first);
|
||||||
if (nodeIt != nodeMap.end())
|
if (nodeIt != nodeMap.end())
|
||||||
{
|
{
|
||||||
osgAnimation::Bone& osgBone = dynamic_cast<osgAnimation::Bone&>(*nodeIt->second);
|
osgAnimation::Bone& osgBone = dynamic_cast<osgAnimation::Bone&>(*nodeIt->second);
|
||||||
osgBone.setInvBindMatrixInSkeletonSpace(it->second);
|
osgBone.setInvBindMatrixInSkeletonSpace(it->second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* osgNode = res.getNode();
|
osg::Node* osgNode = res.getNode();
|
||||||
osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);
|
osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);
|
||||||
osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON);
|
osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON);
|
||||||
|
|
||||||
if (pAnimationManager.valid())
|
if (pAnimationManager.valid())
|
||||||
{
|
{
|
||||||
@ -327,7 +289,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit,
|
|||||||
}
|
}
|
||||||
catch (...)
|
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;
|
return ReadResult::ERROR_IN_READING_FILE;
|
||||||
@ -404,7 +366,7 @@ osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode(
|
|||||||
#ifdef OSG_USE_UTF8_FILENAME
|
#ifdef OSG_USE_UTF8_FILENAME
|
||||||
const std::string& utf8filename(filename);
|
const std::string& utf8filename(filename);
|
||||||
#else
|
#else
|
||||||
std::string utf8filename(convertStringFromCurrentCodePageToUTF8(filename));
|
std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!lExporter->Initialize(utf8filename.c_str()))
|
if (!lExporter->Initialize(utf8filename.c_str()))
|
||||||
|
@ -261,12 +261,12 @@ void readAnimation(KFbxNode* pNode, const std::string& targetName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
|
osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
|
||||||
KFbxNode* pNode, KFbxMesh* fbxMesh,
|
KFbxNode* pNode, KFbxMesh* fbxMesh,
|
||||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||||
std::vector<StateSetContent>& stateSetList,
|
std::vector<StateSetContent>& stateSetList,
|
||||||
const char* szName,
|
const char* szName,
|
||||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
||||||
{
|
{
|
||||||
GeometryMap geometryMap;
|
GeometryMap geometryMap;
|
||||||
|
|
||||||
@ -413,7 +413,7 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
|
|||||||
{
|
{
|
||||||
osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();
|
osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();
|
||||||
|
|
||||||
osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry;
|
osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry;
|
||||||
pRig->setSourceGeometry(pGeometry);
|
pRig->setSourceGeometry(pGeometry);
|
||||||
pRig->copyFrom(*pGeometry);
|
pRig->copyFrom(*pGeometry);
|
||||||
old2newGeometryMap.insert(GeometryRigGeometryMap::value_type(
|
old2newGeometryMap.insert(GeometryRigGeometryMap::value_type(
|
||||||
@ -433,17 +433,17 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
|
|||||||
for (int j = 0; j < nClusters; ++j)
|
for (int j = 0; j < nClusters; ++j)
|
||||||
{
|
{
|
||||||
KFbxCluster* pCluster = (KFbxCluster*)pSkin->GetCluster(j);
|
KFbxCluster* pCluster = (KFbxCluster*)pSkin->GetCluster(j);
|
||||||
//assert(KFbxCluster::eNORMALIZE == pCluster->GetLinkMode());
|
//assert(KFbxCluster::eNORMALIZE == pCluster->GetLinkMode());
|
||||||
KFbxNode* pBone = pCluster->GetLink();
|
KFbxNode* pBone = pCluster->GetLink();
|
||||||
|
|
||||||
KFbxXMatrix transformLink;
|
KFbxXMatrix transformLink;
|
||||||
pCluster->GetTransformLinkMatrix(transformLink);
|
pCluster->GetTransformLinkMatrix(transformLink);
|
||||||
KFbxXMatrix transformLinkInverse = transformLink.Inverse();
|
KFbxXMatrix transformLinkInverse = transformLink.Inverse();
|
||||||
const double* pTransformLinkInverse = transformLinkInverse;
|
const double* pTransformLinkInverse = transformLinkInverse;
|
||||||
if (!boneBindMatrices.insert(std::pair<KFbxNode*, osg::Matrix>(pBone, osg::Matrix(pTransformLinkInverse))).second)
|
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;
|
osg::notify(osg::WARN) << "Multiple meshes attached to a bone - bind matrices may be incorrect." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nIndices = pCluster->GetControlPointIndicesCount();
|
int nIndices = pCluster->GetControlPointIndicesCount();
|
||||||
int* pIndices = pCluster->GetControlPointIndices();
|
int* pIndices = pCluster->GetControlPointIndices();
|
||||||
@ -555,57 +555,56 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KFbxXMatrix fbxVertexTransform;
|
KFbxXMatrix fbxGeometricTransform;
|
||||||
fbxVertexTransform.SetTRS(
|
fbxGeometricTransform.SetTRS(
|
||||||
pNode->GeometricTranslation.Get(),
|
pNode->GeometricTranslation.Get(),
|
||||||
pNode->GeometricRotation.Get(),
|
pNode->GeometricRotation.Get(),
|
||||||
pNode->GeometricScaling.Get());
|
pNode->GeometricScaling.Get());
|
||||||
const double* pVertexMat = fbxVertexTransform;
|
const double* pGeometricMat = fbxGeometricTransform;
|
||||||
osg::Matrix vertexMat(pVertexMat);
|
osg::Matrix osgGeometricTransform(pGeometricMat);
|
||||||
|
|
||||||
// Bind shape matrix
|
if (geomType == GEOMETRY_RIG)
|
||||||
// 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);
|
KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN);
|
||||||
pMatTrans->addChild(pGeode);
|
if (pSkin->GetClusterCount())
|
||||||
pResult = pMatTrans;
|
{
|
||||||
|
KFbxXMatrix fbxTransformMatrix;
|
||||||
|
pSkin->GetCluster(0)->GetTransformMatrix(fbxTransformMatrix);
|
||||||
|
const double* pTransformMatrix = fbxTransformMatrix;
|
||||||
|
osgGeometricTransform.postMult(osg::Matrix(pTransformMatrix));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geomType == GEOMETRY_RIG)
|
osg::Node* pResult = pGeode;
|
||||||
{
|
|
||||||
//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);
|
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,
|
osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager,
|
||||||
KFbxNode* pNode,
|
KFbxNode* pNode,
|
||||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||||
std::vector<StateSetContent>& stateSetList,
|
std::vector<StateSetContent>& stateSetList,
|
||||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
||||||
{
|
{
|
||||||
KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(pNode->GetNodeAttribute());
|
KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(pNode->GetNodeAttribute());
|
||||||
|
|
||||||
@ -615,5 +614,5 @@ osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList,
|
return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList,
|
||||||
pNode->GetName(), boneBindMatrices, skeletonMap);
|
pNode->GetName(), boneBindMatrices, skeletonMap);
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
#include "fbxMaterialToOsgStateSet.h"
|
#include "fbxMaterialToOsgStateSet.h"
|
||||||
osgDB::ReaderWriter::ReadResult readFbxMesh(
|
osgDB::ReaderWriter::ReadResult readFbxMesh(
|
||||||
FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager,
|
FBXFILESDK_NAMESPACE::KFbxSdkManager& pSdkManager,
|
||||||
FBXFILESDK_NAMESPACE::KFbxNode* pNode,
|
FBXFILESDK_NAMESPACE::KFbxNode* pNode,
|
||||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||||
std::vector<StateSetContent>&,
|
std::vector<StateSetContent>&,
|
||||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap);
|
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,29 +47,29 @@ osg::Quat makeQuat(const fbxDouble3& degrees, ERotationOrder fbxRotOrder)
|
|||||||
radiansZ, osg::Vec3d(0,0,1));
|
radiansZ, osg::Vec3d(0,0,1));
|
||||||
case eEULER_XZY:
|
case eEULER_XZY:
|
||||||
return osg::Quat(
|
return osg::Quat(
|
||||||
radiansX, osg::Vec3d(1,0,0),
|
radiansX, osg::Vec3d(1,0,0),
|
||||||
radiansZ, osg::Vec3d(0,0,1),
|
radiansZ, osg::Vec3d(0,0,1),
|
||||||
radiansY, osg::Vec3d(0,1,0));
|
radiansY, osg::Vec3d(0,1,0));
|
||||||
case eEULER_YZX:
|
case eEULER_YZX:
|
||||||
return osg::Quat(
|
return osg::Quat(
|
||||||
radiansY, osg::Vec3d(0,1,0),
|
radiansY, osg::Vec3d(0,1,0),
|
||||||
radiansZ, osg::Vec3d(0,0,1),
|
radiansZ, osg::Vec3d(0,0,1),
|
||||||
radiansX, osg::Vec3d(1,0,0));
|
radiansX, osg::Vec3d(1,0,0));
|
||||||
case eEULER_YXZ:
|
case eEULER_YXZ:
|
||||||
return osg::Quat(
|
return osg::Quat(
|
||||||
radiansY, osg::Vec3d(0,1,0),
|
radiansY, osg::Vec3d(0,1,0),
|
||||||
radiansX, osg::Vec3d(1,0,0),
|
radiansX, osg::Vec3d(1,0,0),
|
||||||
radiansZ, osg::Vec3d(0,0,1));
|
radiansZ, osg::Vec3d(0,0,1));
|
||||||
case eEULER_ZXY:
|
case eEULER_ZXY:
|
||||||
return osg::Quat(
|
return osg::Quat(
|
||||||
radiansZ, osg::Vec3d(0,0,1),
|
radiansZ, osg::Vec3d(0,0,1),
|
||||||
radiansX, osg::Vec3d(1,0,0),
|
radiansX, osg::Vec3d(1,0,0),
|
||||||
radiansY, osg::Vec3d(0,1,0));
|
radiansY, osg::Vec3d(0,1,0));
|
||||||
case eEULER_ZYX:
|
case eEULER_ZYX:
|
||||||
return osg::Quat(
|
return osg::Quat(
|
||||||
radiansZ, osg::Vec3d(0,0,1),
|
radiansZ, osg::Vec3d(0,0,1),
|
||||||
radiansY, osg::Vec3d(0,1,0),
|
radiansY, osg::Vec3d(0,1,0),
|
||||||
radiansX, osg::Vec3d(1,0,0));
|
radiansX, osg::Vec3d(1,0,0));
|
||||||
case eSPHERIC_XYZ:
|
case eSPHERIC_XYZ:
|
||||||
{
|
{
|
||||||
//I don't know what eSPHERIC_XYZ means, so this is a complete guess.
|
//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
|
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 fbxLclPos = pNode->LclTranslation.Get();
|
||||||
fbxDouble3 fbxRotOff = pNode->RotationOffset.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[0] + fbxRotOff[0] + fbxRotPiv[0],
|
||||||
fbxLclPos[1] + fbxRotOff[1] + fbxRotPiv[1],
|
fbxLclPos[1] + fbxRotOff[1] + fbxRotPiv[1],
|
||||||
fbxLclPos[2] + fbxRotOff[2] + fbxRotPiv[2]));
|
fbxLclPos[2] + fbxRotOff[2] + fbxRotPiv[2]));
|
||||||
m.preMultRotate(
|
if (rotationActive)
|
||||||
makeQuat(fbxPostRot, fbxRotOrder) *
|
{
|
||||||
makeQuat(fbxLclRot, fbxRotOrder) *
|
m.preMultRotate(
|
||||||
makeQuat(fbxPreRot, fbxRotOrder));
|
makeQuat(fbxPostRot, fbxRotOrder) *
|
||||||
|
makeQuat(fbxLclRot, fbxRotOrder) *
|
||||||
|
makeQuat(fbxPreRot, fbxRotOrder));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m.preMultRotate(makeQuat(fbxLclRot, fbxRotOrder));
|
||||||
|
}
|
||||||
m.preMultTranslate(osg::Vec3d(
|
m.preMultTranslate(osg::Vec3d(
|
||||||
fbxSclOff[0] + fbxSclPiv[0] - fbxRotPiv[0],
|
fbxSclOff[0] + fbxSclPiv[0] - fbxRotPiv[0],
|
||||||
fbxSclOff[1] + fbxSclPiv[1] - fbxRotPiv[1],
|
fbxSclOff[1] + fbxSclPiv[1] - fbxRotPiv[1],
|
||||||
@ -226,13 +237,24 @@ void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, KFb
|
|||||||
fbxRotPiv[1] + fbxRotOffset[1],
|
fbxRotPiv[1] + fbxRotOffset[1],
|
||||||
fbxRotPiv[2] + fbxRotOffset[2]));
|
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);
|
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 fbxSclOffset = pNode->ScalingOffset.Get();
|
||||||
fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get();
|
fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get();
|
||||||
@ -256,7 +278,7 @@ void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, KFb
|
|||||||
|
|
||||||
osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode,
|
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)
|
std::map<KFbxNode*, osg::Node*>& nodeMap)
|
||||||
{
|
{
|
||||||
if (bNeedSkeleton)
|
if (bNeedSkeleton)
|
||||||
{
|
{
|
||||||
@ -267,7 +289,7 @@ osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode,
|
|||||||
readUpdateMatrixTransform(pUpdate, pNode);
|
readUpdateMatrixTransform(pUpdate, pNode);
|
||||||
osgBone->setUpdateCallback(pUpdate);
|
osgBone->setUpdateCallback(pUpdate);
|
||||||
|
|
||||||
nodeMap.insert(std::pair<KFbxNode*, osg::Node*>(pNode, osgBone));
|
nodeMap.insert(std::pair<KFbxNode*, osg::Node*>(pNode, osgBone));
|
||||||
|
|
||||||
return osgBone;
|
return osgBone;
|
||||||
}
|
}
|
||||||
@ -300,9 +322,9 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||||
bool& bIsBone, int& nLightCount,
|
bool& bIsBone, int& nLightCount,
|
||||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
||||||
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
||||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||||
const osgDB::Options* options)
|
const osgDB::Options* options)
|
||||||
{
|
{
|
||||||
if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute())
|
if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute())
|
||||||
@ -315,8 +337,8 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bIsBone = false;
|
bIsBone = false;
|
||||||
bool bCreateSkeleton = false;
|
bool bCreateSkeleton = false;
|
||||||
|
|
||||||
KFbxNodeAttribute::EAttributeType lAttributeType = KFbxNodeAttribute::eUNIDENTIFIED;
|
KFbxNodeAttribute::EAttributeType lAttributeType = KFbxNodeAttribute::eUNIDENTIFIED;
|
||||||
if (pNode->GetNodeAttribute())
|
if (pNode->GetNodeAttribute())
|
||||||
@ -355,7 +377,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
osgDB::ReaderWriter::ReadResult childResult = readFbxNode(
|
osgDB::ReaderWriter::ReadResult childResult = readFbxNode(
|
||||||
pSdkManager, pChildNode, pAnimationManager,
|
pSdkManager, pChildNode, pAnimationManager,
|
||||||
bChildIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
|
bChildIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
|
||||||
boneBindMatrices, skeletonMap, options);
|
boneBindMatrices, skeletonMap, options);
|
||||||
if (childResult.error())
|
if (childResult.error())
|
||||||
{
|
{
|
||||||
return childResult;
|
return childResult;
|
||||||
@ -364,7 +386,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
{
|
{
|
||||||
if (bChildIsBone)
|
if (bChildIsBone)
|
||||||
{
|
{
|
||||||
if (!bIsBone) bCreateSkeleton = true;
|
if (!bIsBone) bCreateSkeleton = true;
|
||||||
skeletal.push_back(osgChild);
|
skeletal.push_back(osgChild);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -401,23 +423,23 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
break;
|
break;
|
||||||
case KFbxNodeAttribute::eMESH:
|
case KFbxNodeAttribute::eMESH:
|
||||||
{
|
{
|
||||||
size_t bindMatrixCount = boneBindMatrices.size();
|
size_t bindMatrixCount = boneBindMatrices.size();
|
||||||
osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager,
|
osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager,
|
||||||
pNode, pAnimationManager, stateSetList, boneBindMatrices, skeletonMap);
|
pNode, pAnimationManager, stateSetList, boneBindMatrices, skeletonMap);
|
||||||
if (meshRes.error())
|
if (meshRes.error())
|
||||||
{
|
{
|
||||||
return meshRes;
|
return meshRes;
|
||||||
}
|
}
|
||||||
else if (osg::Node* node = meshRes.getNode())
|
else if (osg::Node* node = meshRes.getNode())
|
||||||
{
|
{
|
||||||
bEmpty = false;
|
bEmpty = false;
|
||||||
|
|
||||||
if (bindMatrixCount != boneBindMatrices.size())
|
if (bindMatrixCount != boneBindMatrices.size())
|
||||||
{
|
{
|
||||||
//The mesh is skinned therefore the bind matrix will handle all transformations.
|
//The mesh is skinned therefore the bind matrix will handle all transformations.
|
||||||
localMatrix.makeIdentity();
|
localMatrix.makeIdentity();
|
||||||
bLocalMatrixIdentity = true;
|
bLocalMatrixIdentity = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animName.empty() &&
|
if (animName.empty() &&
|
||||||
children.empty() &&
|
children.empty() &&
|
||||||
@ -427,7 +449,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
return osgDB::ReaderWriter::ReadResult(node);
|
return osgDB::ReaderWriter::ReadResult(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
children.insert(children.begin(), node);
|
children.insert(children.begin(), node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -451,7 +473,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
}
|
}
|
||||||
else
|
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);
|
if (!osgGroup) osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bIsBone, nodeMap);
|
||||||
|
|
||||||
osg::Group* pAddChildrenTo = osgGroup.get();
|
osg::Group* pAddChildrenTo = osgGroup.get();
|
||||||
if (bCreateSkeleton)
|
if (bCreateSkeleton)
|
||||||
{
|
{
|
||||||
osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, skeletonMap);
|
osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, skeletonMap);
|
||||||
osgSkeleton->setDefaultUpdateCallback();
|
osgSkeleton->setDefaultUpdateCallback();
|
||||||
pAddChildrenTo->addChild(osgSkeleton);
|
pAddChildrenTo->addChild(osgSkeleton);
|
||||||
pAddChildrenTo = osgSkeleton;
|
pAddChildrenTo = osgSkeleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (osg::NodeList::iterator it = skeletal.begin(); it != skeletal.end(); ++it)
|
for (osg::NodeList::iterator it = skeletal.begin(); it != skeletal.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -488,26 +510,26 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
osgAnimation::Skeleton* getSkeleton(KFbxNode* fbxNode,
|
osgAnimation::Skeleton* getSkeleton(KFbxNode* fbxNode,
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
|
||||||
{
|
{
|
||||||
//Find the first non-skeleton ancestor of the node.
|
//Find the first non-skeleton ancestor of the node.
|
||||||
while (fbxNode &&
|
while (fbxNode &&
|
||||||
fbxNode->GetNodeAttribute() &&
|
fbxNode->GetNodeAttribute() &&
|
||||||
fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON)
|
fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON)
|
||||||
{
|
{
|
||||||
fbxNode = fbxNode->GetParent();
|
fbxNode = fbxNode->GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>::const_iterator it = skeletonMap.find(fbxNode);
|
std::map<KFbxNode*, osgAnimation::Skeleton*>::const_iterator it = skeletonMap.find(fbxNode);
|
||||||
if (it == skeletonMap.end())
|
if (it == skeletonMap.end())
|
||||||
{
|
{
|
||||||
osgAnimation::Skeleton* skel = new osgAnimation::Skeleton;
|
osgAnimation::Skeleton* skel = new osgAnimation::Skeleton;
|
||||||
skel->setDefaultUpdateCallback();
|
skel->setDefaultUpdateCallback();
|
||||||
skeletonMap.insert(std::pair<KFbxNode*, osgAnimation::Skeleton*>(fbxNode, skel));
|
skeletonMap.insert(std::pair<KFbxNode*, osgAnimation::Skeleton*>(fbxNode, skel));
|
||||||
return skel;
|
return skel;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ osgDB::ReaderWriter::ReadResult readFbxNode(
|
|||||||
bool& bIsBone,
|
bool& bIsBone,
|
||||||
int& nLightCount,
|
int& nLightCount,
|
||||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
||||||
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
||||||
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
std::map<KFbxNode*, osg::Matrix>& boneBindMatrices,
|
||||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||||
const osgDB::Options* options = NULL);
|
const osgDB::Options* options = NULL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user