This commit is contained in:
Michael PLATINGS 2010-03-03 16:14:04 +00:00
parent 315e0521c9
commit fd6f3edf15
5 changed files with 179 additions and 196 deletions

View File

@ -8,7 +8,6 @@
#include <osg/PositionAttitudeTransform>
#include <osg/Texture2D>
#include <osgDB/ConvertUTF>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
@ -27,43 +26,6 @@
#include "fbxMaterialToOsgStateSet.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.
/// 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;
@ -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()))

View File

@ -555,32 +555,31 @@ 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<KFbxPose*> pPoseList;
KArrayTemplate<int> pIndex;
if (KFbxPose::GetBindPoseContaining(
pSdkManager, pNode, pPoseList, pIndex))
if (geomType == GEOMETRY_RIG)
{
const double* pBindShapeMat = pPoseList[0]->GetMatrix(pIndex[0]);
vertexMat.postMult(osg::Matrix(pBindShapeMat));
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));
}
}
osg::Node* pResult = pGeode;
if (!vertexMat.isIdentity())
if (!osgGeometricTransform.isIdentity())
{
osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(vertexMat);
osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(osgGeometricTransform);
pMatTrans->addChild(pGeode);
pResult = pMatTrans;
}

View File

@ -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]));
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();
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);
if (rotationActive)
{
staticTransform.preMultRotate(makeQuat(pNode->PostRotation.Get(), fbxRotOrder));
}
fbxDouble3 fbxSclOffset = pNode->ScalingOffset.Get();
fbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get();