Changeset 11109
- Timestamp:
- 02/24/10 11:25:50 (3 years ago)
- Location:
- OpenSceneGraph/trunk/src/osgPlugins/fbx
- Files:
-
- 2 added
- 9 modified
-
CMakeLists.txt (modified) (2 diffs)
-
ReaderWriterFBX.cpp (modified) (11 diffs)
-
ReaderWriterFBX.h (modified) (2 diffs)
-
WriterNodeVisitor.cpp (added)
-
WriterNodeVisitor.h (added)
-
fbxRAnimation.cpp (modified) (15 diffs)
-
fbxRAnimation.h (modified) (1 diff)
-
fbxRMesh.cpp (modified) (19 diffs)
-
fbxRMesh.h (modified) (1 diff)
-
fbxRNode.cpp (modified) (14 diffs)
-
fbxRNode.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgPlugins/fbx/CMakeLists.txt
r10780 r11109 8 8 fbxRNode.cpp 9 9 ReaderWriterFBX.cpp 10 WriterNodeVisitor.cpp 11 fbxMaterialToOsgStateSet.cpp 10 12 ) 11 13 … … 17 19 fbxRNode.h 18 20 ReaderWriterFBX.h 21 WriterNodeVisitor.h 22 fbxMaterialToOsgStateSet.h 19 23 ) 20 24 -
OpenSceneGraph/trunk/src/osgPlugins/fbx/ReaderWriterFBX.cpp
r10780 r11109 5 5 #include <osg/MatrixTransform> 6 6 #include <osg/Material> 7 #include <osg/PositionAttitudeTransform> 7 8 #include <osg/Texture2D> 9 #include <osgDB/ConvertUTF> 8 10 9 11 #include <osgDB/FileNameUtils> … … 11 13 #include <osgDB/ReadFile> 12 14 #include <osgDB/Registry> 13 14 15 #include <osgAnimation/AnimationManagerBase> 16 #include <osgAnimation/Bone> 15 17 #include <osgAnimation/Skeleton> 16 17 #include <OpenThreads/ScopedLock>18 18 19 19 #if defined(_MSC_VER) … … 24 24 #include "ReaderWriterFBX.h" 25 25 #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. 33 bool 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 86 class CleanUpFbx 87 { 88 KFbxSdkManager* m_pSdkManager; 89 public: 90 explicit CleanUpFbx(KFbxSdkManager* pSdkManager) : m_pSdkManager(pSdkManager) 91 {} 92 93 ~CleanUpFbx() 94 { 95 KFbxIOSettings::IOSettingsRef().FreeIOSettings(); 96 m_pSdkManager->Destroy(); 97 } 98 }; 99 100 class ConvertBindMatrixVisitor : public osg::NodeVisitor 101 { 102 public: 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 }; 26 119 27 120 osgDB::ReaderWriter::ReadResult 28 ReaderWriterFBX::readNode(const std::string& utf8filename,29 const osgDB::ReaderWriter::Options* options) const121 ReaderWriterFBX::readNode(const std::string& filenameInit, 122 const Options* options) const 30 123 { 31 OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex);32 33 124 try 34 125 { 35 std::string ext(osgDB::getLowerCaseFileExtension( utf8filename));36 if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;37 38 std::string file Name(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; 40 131 41 132 KFbxSdkManager* pSdkManager = KFbxSdkManager::Create(); … … 46 137 } 47 138 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 63 149 64 150 int fileFormat; … … 67 153 return ReadResult::FILE_NOT_HANDLED; 68 154 } 69 70 KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager,""); 155 KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager, ""); 71 156 lImporter->SetFileFormat(fileFormat); 72 157 … … 81 166 } 82 167 83 for (int i = 0; i < lImporter->GetTakeCount(); i++)168 for (int i = 0; i < lImporter->GetTakeCount(); i++) 84 169 { 85 170 KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); … … 93 178 } 94 179 180 //KFbxAxisSystem::OpenGL.ConvertScene(pScene); // Doesn't work as expected. Still need to transform vertices. 181 95 182 if (KFbxNode* pNode = pScene->GetRootNode()) 96 183 { 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 97 198 osg::ref_ptr<osgAnimation::AnimationManagerBase> pAnimationManager; 98 199 bool bNeedSkeleton = false; 99 200 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 100 211 ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager, 101 osgDB::getFilePath(fileName), bNeedSkeleton, nLightCount); 212 bNeedSkeleton, nLightCount, fbxMaterialToOsgStateSet, localOptions.get()); 213 102 214 if (res.success()) 103 215 { … … 105 217 if (bNeedSkeleton) 106 218 { 219 ConvertBindMatrixVisitor convertBindMatrixVisitor; 220 osgNode->accept(convertBindMatrixVisitor); 107 221 osgAnimation::Skeleton* osgSkeleton = new osgAnimation::Skeleton; 108 222 osgSkeleton->setDefaultUpdateCallback(); … … 121 235 //because the animations may be altered after registering 122 236 pAnimationManager->buildTargetReference(); 123 124 237 osgNode->setUpdateCallback(pAnimationManager.get()); 125 238 } 126 239 127 240 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; 133 247 float fSign = upSign < 0 ? -1.0f : 1.0f; 134 248 float zScale = bLeftHanded ? -1.0f : 1.0f; … … 147 261 break; 148 262 } 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); 154 293 return osgNode; 155 294 } … … 163 302 } 164 303 304 osgDB::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 165 404 /////////////////////////////////////////////////////////////////////////// 166 405 // Add ourself to the Registry to instantiate the reader/writer. -
OpenSceneGraph/trunk/src/osgPlugins/fbx/ReaderWriterFBX.h
r10780 r11109 2 2 #define READERWRITERFBX_H 3 3 4 #include <OpenThreads/ReentrantMutex>5 4 #include <osgDB/ReaderWriter> 6 5 … … 15 14 { 16 15 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"); 17 18 } 18 19 19 20 const char* className() const { return "FBX reader/writer"; } 20 21 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; 26 24 }; 27 25 -
OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRAnimation.cpp
r10780 r11109 5 5 #include <osgAnimation/Channel> 6 6 #include <osgAnimation/Sampler> 7 #include <osgAnimation/UpdateCallback>8 7 9 8 #if defined(_MSC_VER) … … 25 24 26 25 void 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) 29 27 { 30 28 KFCurve* curves[3] = {curveX, curveY, curveZ}; … … 59 57 { 60 58 float fTime = *it; 61 osg::Vec3 val (baseValue);59 osg::Vec3 val; 62 60 for (int i = 0; i < 3; ++i) 63 61 { … … 66 64 TimeFloatMap::iterator lb = curveTimeMap[i].lower_bound(fTime); 67 65 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; 76 67 } 77 68 keyFrameCntr.push_back(osgAnimation::Vec3Keyframe(fTime, val)); … … 80 71 81 72 osgAnimation::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())) 91 78 { 92 79 return 0; … … 99 86 pChannel->setTargetName(targetName); 100 87 pChannel->setName(channelName); 101 readKeys(curveX, curveY, curveZ, scalar, baseValue, multiply,*pKeyFrameCntr);88 readKeys(curveX, curveY, curveZ, *pKeyFrameCntr); 102 89 103 90 return pChannel; … … 106 93 osgAnimation::Channel* readFbxChannels( 107 94 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) 109 96 { 110 97 if (!fbxProp.IsValid()) return 0; … … 114 101 fbxProp.GetKFCurve("Y", pTakeName), 115 102 fbxProp.GetKFCurve("Z", pTakeName), 116 targetName, channelName, scalar, 117 baseValue * scalar, multiply); 103 targetName, channelName); 118 104 } 119 105 120 106 osgAnimation::Channel* readFbxChannelsQuat( 121 107 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())) 125 113 { 126 114 return 0; … … 132 120 typedef std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> > KeyFrameCntr; 133 121 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)); 135 123 136 124 osgAnimation::QuatSphericalLinearSampler::KeyframeContainerType& quatFrameCntr = … … 143 131 const osg::Vec3& euler = it->getValue(); 144 132 quatFrameCntr.push_back(osgAnimation::QuatKeyframe( 145 it->getTime(), makeQuat(euler, rotOrder) * baseQuat));133 it->getTime(), makeQuat(euler, rotOrder))); 146 134 } 147 135 … … 153 141 osgAnimation::Channel* pRotationChannel, 154 142 osgAnimation::Channel* pScaleChannel, 155 osg::ref_ptr<osgAnimation::AnimationManagerBase> &pAnimManager,143 osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager, 156 144 const char* pTakeName) 157 145 { … … 190 178 } 191 179 192 osgAnimation::Animation* readFbx BoneAnimation(KFbxNode* pNode,180 osgAnimation::Animation* readFbxAnimation(KFbxNode* pNode, 193 181 const char* pTakeName, const char* targetName, 194 182 osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager) … … 200 188 201 189 ERotationOrder rotOrder = pNode->RotationOrder.IsValid() ? pNode->RotationOrder.Get() : eEULER_XYZ; 202 osg::Quat inverseRot;203 190 204 191 osgAnimation::Channel* pTranslationChannel = 0; … … 207 194 if (pNode->LclRotation.IsValid()) 208 195 { 209 inverseRot = makeQuat(pNode->LclRotation.Get(), rotOrder).inverse();196 fbxDouble3 fbxBaseValue = pNode->LclRotation.Get(); 210 197 211 198 pRotationChannel = readFbxChannelsQuat( … … 213 200 pNode->LclRotation.GetKFCurve(KFCURVENODE_R_Y, pTakeName), 214 201 pNode->LclRotation.GetKFCurve(KFCURVENODE_R_Z, pTakeName), 215 targetName, inverseRot,rotOrder);202 targetName, rotOrder); 216 203 } 217 204 218 205 if (pNode->LclTranslation.IsValid()) 219 206 { 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 226 207 pTranslationChannel = readFbxChannels( 227 208 pNode->LclTranslation.GetKFCurve(KFCURVENODE_T_X, pTakeName), 228 209 pNode->LclTranslation.GetKFCurve(KFCURVENODE_T_Y, pTakeName), 229 210 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"); 243 212 } 244 213 245 214 osgAnimation::Channel* pScaleChannel = readFbxChannels( 246 pNode->LclScaling, pTakeName, targetName, "scale" , osg::Vec3(0,0,0), 1.0f, true);215 pNode->LclScaling, pTakeName, targetName, "scale"); 247 216 248 217 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 of261 // 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;293 218 } 294 219 -
OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRAnimation.h
r10780 r11109 3 3 4 4 #include <fbxfilesdk/fbxfilesdk_def.h> 5 6 std::string readFbxBoneAnimation(7 FBXFILESDK_NAMESPACE::KFbxNode*,8 osg::ref_ptr<osgAnimation::AnimationManagerBase>&,9 const char* targetName);10 5 11 6 std::string readFbxAnimation( -
OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRMesh.cpp
r10796 r11109 1 #include <cassert> 2 #include <sstream> 3 1 4 #include <osg/Geode> 2 5 #include <osg/Image> … … 133 136 134 137 osg::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) 138 140 { 139 141 GeometryMap::iterator it = geometryMap.find(mti); … … 145 147 146 148 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) 154 150 { 155 151 pGeometry = new osgAnimation::MorphGeometry; … … 165 161 if (bColor) pGeometry->setColorData(osg::Geometry::ArrayData(new osg::Vec4Array, osg::Geometry::BIND_PER_VERTEX)); 166 162 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)); 178 173 pGeode->addDrawable(pGeometry.get()); 179 174 … … 196 191 void addChannel( 197 192 osgAnimation::Channel* pChannel, 198 osg::ref_ptr<osgAnimation::AnimationManagerBase> &pAnimManager,193 osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager, 199 194 const char* pTakeName) 200 195 { … … 226 221 } 227 222 228 void readAnimation(KFbxNode* pNode, osg::Geode* pGeode,223 void readAnimation(KFbxNode* pNode, const std::string& targetName, 229 224 osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 230 225 KFbxMesh* pMesh, int nShape) … … 234 229 const char* pTakeName = pNode->GetTakeNodeName(i); 235 230 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 } 237 242 238 243 osgAnimation::FloatLinearChannel* pChannel = new osgAnimation::FloatLinearChannel; 239 244 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 }247 245 248 246 for (int k = 0; k < nKeys; ++k) … … 254 252 } 255 253 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()); 258 258 addChannel(pChannel, pAnimationManager, pTakeName); 259 259 } … … 262 262 osgDB::ReaderWriter::ReadResult readMesh(KFbxNode* pNode, KFbxMesh* fbxMesh, 263 263 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, 266 265 const char* szName) 267 266 { … … 321 320 322 321 osg::Geometry* pGeometry = getGeometry(pGeode, geometryMap, 323 materialList, textureList, geomType, materialIndex,322 stateSetList, geomType, materialIndex, 324 323 pFbxNormals != 0, pFbxUVs != 0, pFbxColors != 0); 325 324 … … 347 346 fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v2, GIPair(pGeometry, pVertices->size() + 2))); 348 347 349 350 348 pVertices->push_back(convertVec3(pFbxVertices[v0])); 351 349 pVertices->push_back(convertVec3(pFbxVertices[v1])); … … 386 384 { 387 385 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 } 389 396 390 397 osg::DrawArrays* pDrawArrays = new osg::DrawArrays( … … 395 402 if (geomType == GEOMETRY_RIG) 396 403 { 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 397 424 for (int i = 0; i < nDeformerCount; ++i) 398 425 { … … 419 446 { 420 447 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()); 424 455 vi.push_back(osgAnimation::VertexIndexWeight( 425 456 gi.second, weight)); … … 431 462 else if (geomType == GEOMETRY_MORPH) 432 463 { 433 pGeode->addUpdateCallback(new osgAnimation::UpdateMorph(pGeode->getName()));434 435 436 464 for (int i = 0; i < pGeode->getNumDrawables(); ++i) 437 465 { … … 439 467 440 468 osgAnimation::MorphGeometry& morph = dynamic_cast<osgAnimation::MorphGeometry&>(*pGeometry); 469 470 pGeode->addUpdateCallback(new osgAnimation::UpdateMorph(morph.getName())); 441 471 442 472 //read morph geometry … … 464 494 } 465 495 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); 471 499 } 472 500 } … … 535 563 osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxNode* pNode, 536 564 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) 539 566 { 540 567 KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(pNode->GetNodeAttribute()); … … 545 572 } 546 573 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 5 5 #include <osgDB/ReaderWriter> 6 6 #include <osg/Material> 7 7 #include "fbxMaterialToOsgStateSet.h" 8 8 osgDB::ReaderWriter::ReadResult readFbxMesh( 9 9 FBXFILESDK_NAMESPACE::KFbxNode* pNode, 10 10 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> &); 13 12 14 13 #endif -
OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRNode.cpp
r10780 r11109 1 #include <cassert> 1 2 #include <memory> 2 3 #include <sstream> 4 5 #include <osg/io_utils> 3 6 #include <osg/Notify> 4 7 #include <osg/MatrixTransform> … … 10 13 11 14 #include <osgAnimation/AnimationManagerBase> 15 #include <osgAnimation/Bone> 12 16 #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> 14 22 15 23 #if defined(_MSC_VER) … … 22 30 #include "fbxRLight.h" 23 31 #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" 158 34 159 35 osg::Quat makeQuat(const fbxDouble3& degrees, ERotationOrder fbxRotOrder) … … 260 136 } 261 137 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 323 138 bool readBindPose(KFbxSdkManager& pManager, KFbxNode* pNode, 324 osgAnimation::Bone* osgBone)139 osgAnimation::Bone* osgBone) 325 140 { 326 141 KArrayTemplate<KFbxPose*> pPoseList; … … 333 148 334 149 const double* pMat = pPoseList[0]->GetMatrix(pIndex[0]); 335 osgBone->set BindMatrixInBoneSpace(osg::Matrix(pMat));150 osgBone->setMatrix(osg::Matrix(pMat)); 336 151 return true; 152 } 153 154 void 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 181 void 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 205 void 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 232 void 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 } 337 271 } 338 272 … … 345 279 osgBone->setDataVariance(osg::Object::DYNAMIC); 346 280 osgBone->setName(pNode->GetName()); 347 osgBone->setDefaultUpdateCallback(animName); 281 osgAnimation::UpdateBone* pUpdate = new osgAnimation::UpdateBone(animName); 282 readUpdateMatrixTransform(pUpdate, pNode); 283 osgBone->setUpdateCallback(pUpdate); 348 284 349 285 readBindPose(pSdkManager, pNode, osgBone); … … 363 299 osg::MatrixTransform* pTransform = new osg::MatrixTransform(localMatrix); 364 300 pTransform->setName(pNode->GetName()); 301 365 302 if (bAnimated) 366 303 { 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); 375 306 pTransform->setUpdateCallback(pUpdate); 376 307 } 308 377 309 return pTransform; 378 310 } … … 382 314 KFbxSdkManager& pSdkManager, KFbxNode* pNode, 383 315 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) 385 319 { 386 320 if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute()) … … 405 339 406 340 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; 413 342 414 343 for (unsigned i = 0; i < nMaterials; ++i) 415 344 { 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)); 418 348 } 419 349 … … 433 363 bool bChildNeedSkeleton = false; 434 364 osgDB::ReaderWriter::ReadResult childResult = readFbxNode( 435 pSdkManager, pChildNode, pAnimationManager, dir,436 bChildNeedSkeleton, nLightCount );365 pSdkManager, pChildNode, pAnimationManager, 366 bChildNeedSkeleton, nLightCount, fbxMaterialToOsgStateSet, options); 437 367 if (childResult.error()) 438 368 { … … 453 383 } 454 384 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()); 466 386 467 387 osg::Matrix localMatrix; … … 476 396 { 477 397 case KFbxNodeAttribute::eUNIDENTIFIED: 478 if ( children.size() + skeletal.size() == 1)398 if (bLocalMatrixIdentity && children.size() + skeletal.size() == 1) 479 399 { 480 400 if (children.size() == 1) … … 491 411 { 492 412 osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pNode, 493 pAnimationManager, materialList, textureList);413 pAnimationManager, stateSetList); 494 414 if (meshRes.error()) 495 415 { … … 507 427 } 508 428 osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bNeedSkeleton); 429 assert(osgGroup->getStateSet() == NULL); 509 430 osgGroup->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); 510 431 -
OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxRNode.h
r10780 r11109 2 2 #define FBXRNODE_H 3 3 4 #include "fbxMaterialToOsgStateSet.h" 4 5 namespace osgAnimation 5 6 { … … 11 12 FBXFILESDK_NAMESPACE::KFbxNode* pNode, 12 13 osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager, 13 const std::string& dir,14 14 bool& bNeedSkeleton, 15 int& nLightCount); 15 int& nLightCount, 16 FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, 17 const osgDB::Options* options = NULL); 16 18 17 19 #endif
