2
0

BsFBXImporter.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  1. #include "BsFBXImporter.h"
  2. #include "BsResource.h"
  3. #include "BsCoreApplication.h"
  4. #include "BsDebug.h"
  5. #include "BsDataStream.h"
  6. #include "BsMeshData.h"
  7. #include "BsMesh.h"
  8. #include "BsVector2.h"
  9. #include "BsVector3.h"
  10. #include "BsVector4.h"
  11. #include "BsQuaternion.h"
  12. #include "BsVertexDataDesc.h"
  13. #include "BsFBXUtility.h"
  14. #include "BsMeshUtility.h"
  15. #include <BsMeshImportOptions.h>
  16. namespace BansheeEngine
  17. {
  18. Matrix4 FBXToNativeType(const FbxAMatrix& value)
  19. {
  20. Matrix4 native;
  21. for (UINT32 row = 0; row < 4; row++)
  22. for (UINT32 col = 0; col < 4; col++)
  23. native[row][col] = (float)value[col][row];
  24. return native;
  25. }
  26. Vector3 FBXToNativeType(const FbxVector4& value)
  27. {
  28. Vector3 native;
  29. native.x = (float)value[0];
  30. native.y = (float)value[1];
  31. native.z = (float)value[2];
  32. return native;
  33. }
  34. Vector3 FBXToNativeType(const FbxDouble3& value)
  35. {
  36. Vector3 native;
  37. native.x = (float)value[0];
  38. native.y = (float)value[1];
  39. native.z = (float)value[2];
  40. return native;
  41. }
  42. Vector2 FBXToNativeType(const FbxVector2& value)
  43. {
  44. Vector2 native;
  45. native.x = (float)value[0];
  46. native.y = (float)value[1];
  47. return native;
  48. }
  49. RGBA FBXToNativeType(const FbxColor& value)
  50. {
  51. Color native;
  52. native.r = (float)value[0];
  53. native.g = (float)value[1];
  54. native.b = (float)value[2];
  55. native.a = (float)value[3];
  56. return native.getAsRGBA();
  57. }
  58. FbxSurfaceMaterial* FBXToNativeType(FbxSurfaceMaterial* const& value)
  59. {
  60. return value;
  61. }
  62. int FBXToNativeType(const int & value)
  63. {
  64. return value;
  65. }
  66. FBXImporter::FBXImporter()
  67. :SpecificImporter(), mFBXManager(nullptr)
  68. {
  69. mExtensions.push_back(L"fbx");
  70. }
  71. FBXImporter::~FBXImporter()
  72. {
  73. }
  74. bool FBXImporter::isExtensionSupported(const WString& ext) const
  75. {
  76. WString lowerCaseExt = ext;
  77. StringUtil::toLowerCase(lowerCaseExt);
  78. return find(mExtensions.begin(), mExtensions.end(), lowerCaseExt) != mExtensions.end();
  79. }
  80. bool FBXImporter::isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const
  81. {
  82. return true; // FBX files can be plain-text so I don't even check for magic number
  83. }
  84. ImportOptionsPtr FBXImporter::createImportOptions() const
  85. {
  86. return bs_shared_ptr<MeshImportOptions, PoolAlloc>();
  87. }
  88. ResourcePtr FBXImporter::import(const Path& filePath, ConstImportOptionsPtr importOptions)
  89. {
  90. FbxScene* fbxScene = nullptr;
  91. if (!startUpSdk(fbxScene))
  92. return nullptr;
  93. if (!loadFBXFile(fbxScene, filePath))
  94. return nullptr;
  95. const MeshImportOptions* meshImportOptions = static_cast<const MeshImportOptions*>(importOptions.get());
  96. FBXImportOptions fbxImportOptions;
  97. fbxImportOptions.importNormals = meshImportOptions->getImportNormals();
  98. fbxImportOptions.importTangents = meshImportOptions->getImportTangents();
  99. fbxImportOptions.importAnimation = meshImportOptions->getImportAnimation();
  100. fbxImportOptions.importBlendShapes = meshImportOptions->getImportBlendShapes();
  101. fbxImportOptions.importSkin = meshImportOptions->getImportSkin();
  102. fbxImportOptions.importScale = meshImportOptions->getImportScale();
  103. FBXImportScene importedScene;
  104. parseScene(fbxScene, fbxImportOptions, importedScene);
  105. if (fbxImportOptions.importBlendShapes)
  106. importBlendShapes(importedScene, fbxImportOptions);
  107. if (fbxImportOptions.importSkin)
  108. importSkin(importedScene);
  109. if (fbxImportOptions.importAnimation)
  110. importAnimations(fbxScene, fbxImportOptions, importedScene);
  111. splitMeshVertices(importedScene);
  112. generateMissingTangentSpace(importedScene, fbxImportOptions);
  113. Vector<SubMesh> subMeshes;
  114. MeshDataPtr meshData = generateMeshData(importedScene, fbxImportOptions, subMeshes);
  115. // TODO - Later: Optimize mesh: Remove bad and degenerate polygons, weld nearby vertices, optimize for vertex cache
  116. shutDownSdk();
  117. INT32 usage = MU_STATIC;
  118. if (meshImportOptions->getCPUReadable())
  119. usage |= MU_CPUCACHED;
  120. MeshPtr mesh = Mesh::_createPtr(meshData, subMeshes, usage);
  121. WString fileName = filePath.getWFilename(false);
  122. mesh->setName(fileName);
  123. return mesh;
  124. }
  125. bool FBXImporter::startUpSdk(FbxScene*& scene)
  126. {
  127. mFBXManager = FbxManager::Create();
  128. if (mFBXManager == nullptr)
  129. {
  130. LOGERR("FBX import failed: FBX SDK failed to initialize. FbxManager::Create() failed.");
  131. return false;
  132. }
  133. FbxIOSettings* ios = FbxIOSettings::Create(mFBXManager, IOSROOT);
  134. mFBXManager->SetIOSettings(ios);
  135. scene = FbxScene::Create(mFBXManager, "Import Scene");
  136. if (scene == nullptr)
  137. {
  138. LOGWRN("FBX import failed: Failed to create FBX scene.");
  139. return false;
  140. }
  141. return true;
  142. }
  143. void FBXImporter::shutDownSdk()
  144. {
  145. mFBXManager->Destroy();
  146. mFBXManager = nullptr;
  147. }
  148. bool FBXImporter::loadFBXFile(FbxScene* scene, const Path& filePath)
  149. {
  150. int lFileMajor, lFileMinor, lFileRevision;
  151. int lSDKMajor, lSDKMinor, lSDKRevision;
  152. FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);
  153. FbxImporter* importer = FbxImporter::Create(mFBXManager, "");
  154. bool importStatus = importer->Initialize(filePath.toString().c_str(), -1, mFBXManager->GetIOSettings());
  155. importer->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);
  156. if(!importStatus)
  157. {
  158. LOGERR("FBX import failed: Call to FbxImporter::Initialize() failed.\n" +
  159. String("Error returned: %s\n\n") + String(importer->GetStatus().GetErrorString()));
  160. return false;
  161. }
  162. mFBXManager->GetIOSettings()->SetBoolProp(IMP_FBX_TEXTURE, false);
  163. mFBXManager->GetIOSettings()->SetBoolProp(IMP_FBX_GOBO, false);
  164. importStatus = importer->Import(scene);
  165. if(!importStatus)
  166. {
  167. importer->Destroy();
  168. LOGERR("FBX import failed: Call to FbxImporter::Initialize() failed.\n" +
  169. String("Error returned: %s\n\n") + String(importer->GetStatus().GetErrorString()));
  170. return false;
  171. }
  172. FbxAxisSystem fileCoordSystem = scene->GetGlobalSettings().GetAxisSystem();
  173. FbxAxisSystem bsCoordSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eRightHanded);
  174. if (fileCoordSystem != bsCoordSystem)
  175. bsCoordSystem.ConvertScene(scene);
  176. importer->Destroy();
  177. return true;
  178. }
  179. void FBXImporter::parseScene(FbxScene* scene, const FBXImportOptions& options, FBXImportScene& outputScene)
  180. {
  181. outputScene.rootNode = createImportNode(outputScene, scene->GetRootNode(), nullptr);
  182. Stack<FbxNode*> todo;
  183. todo.push(scene->GetRootNode());
  184. while(!todo.empty())
  185. {
  186. FbxNode* curNode = todo.top();
  187. FBXImportNode* curImportNode = outputScene.nodeMap[curNode];
  188. todo.pop();
  189. const char* name = curNode->GetName();
  190. FbxNodeAttribute* attrib = curNode->GetNodeAttribute();
  191. if(attrib != nullptr)
  192. {
  193. FbxNodeAttribute::EType attribType = attrib->GetAttributeType();
  194. switch(attribType)
  195. {
  196. case FbxNodeAttribute::eNurbs:
  197. case FbxNodeAttribute::eNurbsSurface:
  198. case FbxNodeAttribute::ePatch:
  199. {
  200. FbxGeometryConverter geomConverter(mFBXManager);
  201. attrib = geomConverter.Triangulate(attrib, true);
  202. if (attrib->GetAttributeType() == FbxNodeAttribute::eMesh)
  203. {
  204. FbxMesh* mesh = static_cast<FbxMesh*>(attrib);
  205. mesh->RemoveBadPolygons();
  206. parseMesh(mesh, curImportNode, options, outputScene);
  207. }
  208. }
  209. break;
  210. case FbxNodeAttribute::eMesh:
  211. {
  212. FbxMesh* mesh = static_cast<FbxMesh*>(attrib);
  213. mesh->RemoveBadPolygons();
  214. if(!mesh->IsTriangleMesh())
  215. {
  216. FbxGeometryConverter geomConverter(mFBXManager);
  217. geomConverter.Triangulate(mesh, true);
  218. attrib = curNode->GetNodeAttribute();
  219. mesh = static_cast<FbxMesh*>(attrib);
  220. }
  221. parseMesh(mesh, curImportNode, options, outputScene);
  222. }
  223. break;
  224. }
  225. }
  226. for (int i = 0; i < curNode->GetChildCount(); i++)
  227. {
  228. FbxNode* childNode = curNode->GetChild(i);
  229. createImportNode(outputScene, childNode, curImportNode);
  230. todo.push(childNode);
  231. }
  232. }
  233. }
  234. FBXImportNode* FBXImporter::createImportNode(FBXImportScene& scene, FbxNode* fbxNode, FBXImportNode* parent)
  235. {
  236. FBXImportNode* node = bs_new<FBXImportNode>();
  237. Vector3 translation = FBXToNativeType(fbxNode->LclTranslation.Get());
  238. Vector3 rotationEuler = FBXToNativeType(fbxNode->LclRotation.Get());
  239. Vector3 scale = FBXToNativeType(fbxNode->LclScaling.Get());
  240. Quaternion rotation((Radian)rotationEuler.x, (Radian)rotationEuler.y, (Radian)rotationEuler.z);
  241. node->localTransform.setTRS(translation, rotation, scale);
  242. node->fbxNode = fbxNode;
  243. if (parent != nullptr)
  244. {
  245. node->worldTransform = node->localTransform * parent->worldTransform;
  246. parent->children.push_back(node);
  247. }
  248. else
  249. node->worldTransform = node->localTransform;
  250. scene.nodeMap.insert(std::make_pair(fbxNode, node));
  251. return node;
  252. }
  253. void FBXImporter::splitMeshVertices(FBXImportScene& scene)
  254. {
  255. Vector<FBXImportMesh*> splitMeshes;
  256. for (auto& mesh : scene.meshes)
  257. {
  258. FBXImportMesh* splitMesh = bs_new<FBXImportMesh>();
  259. splitMesh->fbxMesh = mesh->fbxMesh;
  260. splitMesh->referencedBy = mesh->referencedBy;
  261. splitMesh->bones = mesh->bones;
  262. FBXUtility::splitVertices(*mesh, *splitMesh);
  263. FBXUtility::flipWindingOrder(*splitMesh);
  264. splitMeshes.push_back(splitMesh);
  265. bs_delete(mesh);
  266. }
  267. scene.meshes = splitMeshes;
  268. }
  269. MeshDataPtr FBXImporter::generateMeshData(const FBXImportScene& scene, const FBXImportOptions& options, Vector<SubMesh>& outputSubMeshes)
  270. {
  271. Matrix4 importScale = Matrix4::scaling(options.importScale);
  272. Vector<MeshDataPtr> allMeshData;
  273. Vector<Vector<SubMesh>> allSubMeshes;
  274. for (auto& mesh : scene.meshes)
  275. {
  276. Vector<Vector<UINT32>> indicesPerMaterial;
  277. for (UINT32 i = 0; i < (UINT32)mesh->indices.size(); i++)
  278. {
  279. while (mesh->materials[i] >= indicesPerMaterial.size())
  280. indicesPerMaterial.push_back(Vector<UINT32>());
  281. indicesPerMaterial[mesh->materials[i]].push_back(mesh->indices[i]);
  282. }
  283. UINT32* orderedIndices = (UINT32*)bs_alloc((UINT32)mesh->indices.size() * sizeof(UINT32));
  284. Vector<SubMesh> subMeshes;
  285. UINT32 currentIndex = 0;
  286. for (auto& subMeshIndices : indicesPerMaterial)
  287. {
  288. UINT32 indexCount = (UINT32)subMeshIndices.size();
  289. UINT32* dest = orderedIndices + currentIndex;
  290. memcpy(dest, subMeshIndices.data(), indexCount * sizeof(UINT32));
  291. subMeshes.push_back(SubMesh(currentIndex, indexCount, DOT_TRIANGLE_LIST));
  292. currentIndex += indexCount;
  293. }
  294. VertexDataDescPtr vertexDesc = bs_shared_ptr<VertexDataDesc>();
  295. vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
  296. size_t numVertices = mesh->positions.size();
  297. bool hasColors = mesh->colors.size() == numVertices;
  298. bool hasNormals = mesh->normals.size() == numVertices;
  299. if (hasColors)
  300. vertexDesc->addVertElem(VET_COLOR, VES_COLOR);
  301. bool hasTangents = false;
  302. if (hasNormals)
  303. {
  304. vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
  305. if (mesh->tangents.size() == numVertices &&
  306. mesh->bitangents.size() == numVertices)
  307. {
  308. vertexDesc->addVertElem(VET_FLOAT4, VES_TANGENT);
  309. hasTangents = true;
  310. }
  311. }
  312. int UVIdx = 0;
  313. for (UINT32 i = 0; i < FBX_IMPORT_MAX_UV_LAYERS; i++)
  314. {
  315. if (mesh->UV[i].size() == numVertices)
  316. {
  317. vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD, UVIdx++);
  318. }
  319. }
  320. UINT32 numIndices = (UINT32)mesh->indices.size();
  321. for (auto& node : mesh->referencedBy)
  322. {
  323. Matrix4 worldTransform = node->worldTransform * importScale;
  324. Matrix4 worldTransformIT = worldTransform.transpose();
  325. worldTransformIT = worldTransformIT.inverse();
  326. MeshDataPtr meshData = bs_shared_ptr<MeshData>((UINT32)numVertices, numIndices, vertexDesc);
  327. // Copy indices
  328. UINT32* indices = meshData->getIndices32();
  329. memcpy(indices, mesh->indices.data(), numIndices * sizeof(UINT32));
  330. // Copy & transform positions
  331. auto posIter = meshData->getVec3DataIter(VES_POSITION, 0);
  332. for (auto& position : mesh->positions)
  333. {
  334. Vector3 tfrmdValue = worldTransform.multiplyAffine((Vector3)position);
  335. posIter.addValue(tfrmdValue);
  336. }
  337. // Copy & transform normals
  338. if (hasNormals)
  339. {
  340. auto normalIter = meshData->getVec3DataIter(VES_NORMAL, 0);
  341. // Copy, convert & transform tangents & bitangents
  342. if (hasTangents)
  343. {
  344. auto tangentIter = meshData->getVec4DataIter(VES_TANGENT, 0);
  345. for (UINT32 i = 0; i < (UINT32)numVertices; i++)
  346. {
  347. Vector3 normal = (Vector3)mesh->normals[i];
  348. normal = worldTransformIT.multiplyAffine(normal);
  349. normalIter.addValue(normal);
  350. Vector3 tangent = (Vector3)mesh->tangents[i];
  351. tangent = worldTransformIT.multiplyAffine(tangent);
  352. Vector3 bitangent = (Vector3)mesh->bitangents[i];
  353. bitangent = worldTransformIT.multiplyAffine(bitangent);
  354. Vector3 engineBitangent = Vector3::cross(normal, tangent);
  355. float sign = Vector3::dot(engineBitangent, bitangent);
  356. Vector4 combinedTangent(tangent.x, tangent.y, tangent.z, sign > 0 ? 1.0f : -1.0f);
  357. tangentIter.addValue(combinedTangent);
  358. }
  359. }
  360. else // Just normals
  361. {
  362. for (auto& normal : mesh->normals)
  363. {
  364. Vector3 tfrmdValue = worldTransformIT.multiplyAffine((Vector3)normal);
  365. normalIter.addValue(tfrmdValue);
  366. }
  367. }
  368. }
  369. // Copy colors
  370. if (hasColors)
  371. {
  372. auto colorIter = meshData->getDWORDDataIter(VES_COLOR, 0);
  373. for (auto& color : mesh->colors)
  374. colorIter.addValue(color);
  375. }
  376. // Copy UV
  377. int writeUVIDx = 0;
  378. for (auto& uvLayer : mesh->UV)
  379. {
  380. if (uvLayer.size() == numVertices)
  381. {
  382. auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD, writeUVIDx);
  383. for (auto& uv : uvLayer)
  384. {
  385. uv.y = 1.0f - uv.y;
  386. uvIter.addValue(uv);
  387. }
  388. writeUVIDx++;
  389. }
  390. }
  391. allMeshData.push_back(meshData);
  392. allSubMeshes.push_back(subMeshes);
  393. }
  394. }
  395. if (allMeshData.size() > 1)
  396. {
  397. return MeshData::combine(allMeshData, allSubMeshes, outputSubMeshes);
  398. }
  399. else if (allMeshData.size() == 1)
  400. {
  401. outputSubMeshes = allSubMeshes[0];
  402. return allMeshData[0];
  403. }
  404. return nullptr;
  405. }
  406. template<class TFBX, class TNative>
  407. class FBXDirectIndexer
  408. {
  409. public:
  410. FBXDirectIndexer(const FbxLayerElementTemplate<TFBX>& layer)
  411. :mElementArray(layer.GetDirectArray()),
  412. mElementCount(mElementArray.GetCount())
  413. {}
  414. bool get(int index, TNative& output) const
  415. {
  416. if (index < 0 || index >= mElementCount)
  417. return false;
  418. output = FBXToNativeType(mElementArray.GetAt(index));
  419. return true;
  420. }
  421. bool isEmpty() const
  422. {
  423. return mElementCount == 0;
  424. }
  425. private:
  426. const FbxLayerElementArrayTemplate<TFBX>& mElementArray;
  427. int mElementCount;
  428. };
  429. template<class TFBX, class TNative>
  430. class FBXIndexIndexer
  431. {
  432. public:
  433. FBXIndexIndexer(const FbxLayerElementTemplate<TFBX>& layer)
  434. :mElementArray(layer.GetDirectArray()),
  435. mIndexArray(layer.GetIndexArray()),
  436. mElementCount(mElementArray.GetCount()),
  437. mIndexCount(mIndexArray.GetCount())
  438. {}
  439. bool get(int index, TNative& output) const
  440. {
  441. if (index < 0 || index >= mIndexCount)
  442. return false;
  443. int actualIndex = mIndexArray.GetAt(index);
  444. if (actualIndex < 0 || actualIndex >= mElementCount)
  445. return false;
  446. output = FBXToNativeType(mElementArray.GetAt(actualIndex));
  447. return true;
  448. }
  449. bool isEmpty() const
  450. {
  451. return mElementCount == 0 || mIndexCount == 0;
  452. }
  453. private:
  454. const FbxLayerElementArrayTemplate<TFBX>& mElementArray;
  455. const FbxLayerElementArrayTemplate<int>& mIndexArray;
  456. int mElementCount;
  457. int mIndexCount;
  458. };
  459. template<class TFBX, class TNative, class TIndexer>
  460. void readLayerData(FbxLayerElementTemplate<TFBX>& layer, Vector<TNative>& output, const Vector<int>& indices)
  461. {
  462. TIndexer indexer(layer);
  463. if (indexer.isEmpty())
  464. return;
  465. output.resize(indices.size());
  466. FbxLayerElement::EMappingMode mappingMode = layer.GetMappingMode();
  467. UINT32 indexCount = (UINT32)indices.size();
  468. switch (mappingMode)
  469. {
  470. case FbxLayerElement::eByControlPoint:
  471. for (UINT32 i = 0; i < indexCount; i++)
  472. {
  473. int index = indices[i];
  474. indexer.get(index, output[i]);
  475. }
  476. break;
  477. case FbxLayerElement::eByPolygonVertex:
  478. for (UINT32 i = 0; i < indexCount; i++)
  479. indexer.get(i, output[i]);
  480. break;
  481. case FbxLayerElement::eByPolygon:
  482. // We expect mesh to be triangulated here
  483. {
  484. UINT32 polygonCount = indexCount / 3;
  485. UINT32 index = 0;
  486. for (UINT32 i = 0; i < polygonCount; i++)
  487. {
  488. TNative value;
  489. indexer.get(i, value);
  490. output[index++] = value;
  491. output[index++] = value;
  492. output[index++] = value;
  493. }
  494. }
  495. break;
  496. case FbxLayerElement::eAllSame:
  497. {
  498. TNative value;
  499. indexer.get(0, value);
  500. for (UINT32 i = 0; i < indexCount; i++)
  501. output[i] = value;
  502. }
  503. break;
  504. default:
  505. LOGWRN("FBX Import: Unsupported layer mapping mode.");
  506. break;
  507. }
  508. }
  509. template<class TFBX, class TNative>
  510. void readLayerData(FbxLayerElementTemplate<TFBX>& layer, Vector<TNative>& output, const Vector<int>& indices)
  511. {
  512. FbxLayerElement::EReferenceMode refMode = layer.GetReferenceMode();
  513. if (refMode == FbxLayerElement::eDirect)
  514. readLayerData<TFBX, TNative, FBXDirectIndexer<TFBX, TNative> >(layer, output, indices);
  515. else if (refMode == FbxLayerElement::eIndexToDirect)
  516. readLayerData<TFBX, TNative, FBXIndexIndexer<TFBX, TNative> >(layer, output, indices);
  517. else
  518. LOGWRN("FBX Import: Unsupported layer reference mode.");
  519. }
  520. void FBXImporter::parseMesh(FbxMesh* mesh, FBXImportNode* parentNode, const FBXImportOptions& options, FBXImportScene& outputScene)
  521. {
  522. // Check if valid
  523. if (!mesh->IsTriangleMesh())
  524. return;
  525. UINT32 vertexCount = mesh->GetControlPointsCount();
  526. UINT32 triangleCount = mesh->GetPolygonCount();
  527. if (vertexCount == 0 || triangleCount == 0)
  528. return;
  529. // Register in global mesh array
  530. FBXImportMesh* importMesh = nullptr;
  531. auto iterFindMesh = outputScene.meshMap.find(mesh);
  532. if (iterFindMesh != outputScene.meshMap.end())
  533. {
  534. UINT32 meshIdx = iterFindMesh->second;
  535. outputScene.meshes[meshIdx]->referencedBy.push_back(parentNode);
  536. return;
  537. }
  538. else
  539. {
  540. importMesh = bs_new<FBXImportMesh>();
  541. outputScene.meshes.push_back(importMesh);
  542. importMesh->referencedBy.push_back(parentNode);
  543. importMesh->fbxMesh = mesh;
  544. outputScene.meshMap[mesh] = (UINT32)outputScene.meshes.size() - 1;
  545. }
  546. // Import vertices
  547. importMesh->positions.resize(vertexCount);
  548. FbxVector4* controlPoints = mesh->GetControlPoints();
  549. for (UINT32 i = 0; i < vertexCount; i++)
  550. importMesh->positions[i] = FBXToNativeType(controlPoints[i]);
  551. // Import triangles
  552. UINT32 indexCount = triangleCount * 3;
  553. importMesh->indices.resize(indexCount);
  554. int* fbxIndices = mesh->GetPolygonVertices();
  555. importMesh->indices.assign(fbxIndices, fbxIndices + indexCount);
  556. // Import UVs
  557. Vector<FbxLayerElementUV*> fbxUVLayers;
  558. //// Search the diffuse layers first
  559. for (UINT32 i = 0; i < FBX_IMPORT_MAX_UV_LAYERS; i++)
  560. {
  561. FbxLayer* layer = mesh->GetLayer(i, FbxLayerElement::eUV);
  562. if (layer == nullptr)
  563. continue;
  564. for (int j = FbxLayerElement::eTextureDiffuse; j < FbxLayerElement::eTypeCount; j++)
  565. {
  566. FbxLayerElementUV* uvLayer = layer->GetUVs((FbxLayerElement::EType)j);
  567. if (uvLayer == nullptr)
  568. continue;
  569. fbxUVLayers.push_back(uvLayer);
  570. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  571. break;
  572. }
  573. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  574. break;
  575. }
  576. //// If there's room, search all others too
  577. if (fbxUVLayers.size() < FBX_IMPORT_MAX_UV_LAYERS)
  578. {
  579. UINT32 numLayers = mesh->GetLayerCount();
  580. for (UINT32 i = 0; i < numLayers; i++)
  581. {
  582. FbxLayer* layer = mesh->GetLayer(i);
  583. if (layer == nullptr)
  584. continue;
  585. for (int j = FbxLayerElement::eTextureDiffuse; j < FbxLayerElement::eTypeCount; j++)
  586. {
  587. FbxLayerElementUV* uvLayer = layer->GetUVs((FbxLayerElement::EType)j);
  588. if (uvLayer == nullptr)
  589. continue;
  590. auto iterFind = std::find(fbxUVLayers.begin(), fbxUVLayers.end(), uvLayer);
  591. if (iterFind != fbxUVLayers.end())
  592. continue;
  593. fbxUVLayers.push_back(uvLayer);
  594. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  595. break;
  596. }
  597. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  598. break;
  599. }
  600. }
  601. for (size_t i = 0; i < fbxUVLayers.size(); i++)
  602. readLayerData(*fbxUVLayers[i], importMesh->UV[i], importMesh->indices);
  603. FbxLayer* mainLayer = mesh->GetLayer(0);
  604. if (mainLayer != nullptr)
  605. {
  606. // Import colors
  607. if (mainLayer->GetVertexColors() != nullptr)
  608. readLayerData(*mainLayer->GetVertexColors(), importMesh->colors, importMesh->indices);
  609. // Import normals
  610. if (options.importNormals)
  611. {
  612. bool hasNormals = mainLayer->GetNormals() != nullptr;
  613. if (!hasNormals)
  614. {
  615. if (mainLayer->GetSmoothing() != nullptr)
  616. {
  617. FbxLayerElementSmoothing* smoothing = mainLayer->GetSmoothing();
  618. if (smoothing->GetMappingMode() == FbxLayerElement::eByEdge)
  619. {
  620. FbxGeometryConverter converter(mFBXManager);
  621. converter.ComputePolygonSmoothingFromEdgeSmoothing(mesh, 0);
  622. }
  623. readLayerData(*smoothing, importMesh->smoothingGroups, importMesh->indices);
  624. if (!importMesh->smoothingGroups.empty())
  625. {
  626. FBXUtility::normalsFromSmoothing(importMesh->positions, importMesh->indices,
  627. importMesh->smoothingGroups, importMesh->normals);
  628. }
  629. }
  630. }
  631. else
  632. readLayerData(*mainLayer->GetNormals(), importMesh->normals, importMesh->indices);
  633. }
  634. // Import tangents
  635. if (options.importTangents)
  636. {
  637. bool hasTangents = mainLayer->GetTangents() != nullptr && mainLayer->GetBinormals() != nullptr;
  638. if (!hasTangents)
  639. {
  640. if (fbxUVLayers.size() > 0)
  641. hasTangents = mesh->GenerateTangentsData(0, false);
  642. }
  643. if (hasTangents)
  644. {
  645. readLayerData(*mainLayer->GetTangents(), importMesh->tangents, importMesh->indices);
  646. readLayerData(*mainLayer->GetBinormals(), importMesh->bitangents, importMesh->indices);
  647. }
  648. }
  649. // Import material indexes
  650. if (mainLayer->GetMaterials() != nullptr)
  651. {
  652. Vector<FbxSurfaceMaterial*> fbxMaterials;
  653. readLayerData(*mainLayer->GetMaterials(), fbxMaterials, importMesh->indices);
  654. UnorderedMap<FbxSurfaceMaterial*, int> materialLookup;
  655. int nextMaterialIdx = 0;
  656. for (UINT32 i = 0; i < (UINT32)fbxMaterials.size(); i++)
  657. {
  658. auto iterFind = materialLookup.find(fbxMaterials[i]);
  659. int materialIdx = 0;
  660. if (iterFind != materialLookup.end())
  661. materialIdx = iterFind->second;
  662. else
  663. {
  664. materialIdx = nextMaterialIdx++;
  665. materialLookup[fbxMaterials[i]] = materialIdx;
  666. }
  667. importMesh->materials.push_back(materialIdx);
  668. }
  669. }
  670. }
  671. }
  672. void FBXImporter::importBlendShapes(FBXImportScene& scene, const FBXImportOptions& options)
  673. {
  674. for (auto& mesh : scene.meshes)
  675. {
  676. FbxMesh* fbxMesh = mesh->fbxMesh;
  677. UINT32 deformerCount = (UINT32)fbxMesh->GetDeformerCount(FbxDeformer::eBlendShape);
  678. for (UINT32 i = 0; i < deformerCount; i++)
  679. {
  680. FbxBlendShape* deformer = static_cast<FbxBlendShape*>(fbxMesh->GetDeformer(i, FbxDeformer::eBlendShape));
  681. UINT32 blendShapeChannelCount = (UINT32)deformer->GetBlendShapeChannelCount();
  682. for (UINT32 j = 0; j < blendShapeChannelCount; ++j)
  683. {
  684. FbxBlendShapeChannel* channel = deformer->GetBlendShapeChannel(j);
  685. double* weights = channel->GetTargetShapeFullWeights();
  686. UINT32 frameCount = channel->GetTargetShapeCount();
  687. if (frameCount == 0)
  688. continue;
  689. mesh->blendShapes.push_back(FBXBlendShape());
  690. FBXBlendShape& blendShape = mesh->blendShapes.back();
  691. blendShape.name = channel->GetName();
  692. blendShape.frames.resize(frameCount);
  693. for (UINT32 k = 0; k < frameCount; k++)
  694. {
  695. FbxShape* fbxShape = channel->GetTargetShape(k);
  696. FBXBlendShapeFrame& frame = blendShape.frames[k];
  697. frame.weight = (float)weights[k];
  698. importBlendShapeFrame(fbxShape, *mesh, options, frame);
  699. }
  700. }
  701. }
  702. }
  703. }
  704. void FBXImporter::importBlendShapeFrame(FbxShape* shape, const FBXImportMesh& mesh, const FBXImportOptions& options, FBXBlendShapeFrame& outFrame)
  705. {
  706. UINT32 vertexCount = (UINT32)shape->GetControlPointsCount();
  707. outFrame.positions.resize(vertexCount);
  708. FbxVector4* controlPoints = shape->GetControlPoints();
  709. for (UINT32 i = 0; i < vertexCount; i++)
  710. outFrame.positions[i] = FBXToNativeType(controlPoints[i]);
  711. FbxLayer* mainLayer = shape->GetLayer(0);
  712. if (options.importNormals)
  713. {
  714. bool hasNormals = mainLayer->GetNormals() != nullptr;
  715. if (!hasNormals)
  716. {
  717. if (!mesh.smoothingGroups.empty())
  718. {
  719. FBXUtility::normalsFromSmoothing(outFrame.positions, mesh.indices,
  720. mesh.smoothingGroups, outFrame.normals);
  721. }
  722. }
  723. else
  724. readLayerData(*mainLayer->GetNormals(), outFrame.normals, mesh.indices);
  725. }
  726. if (options.importTangents)
  727. {
  728. bool hasTangents = mainLayer->GetTangents() != nullptr && mainLayer->GetBinormals() != nullptr;
  729. if (hasTangents)
  730. {
  731. readLayerData(*mainLayer->GetTangents(), outFrame.tangents, mesh.indices);
  732. readLayerData(*mainLayer->GetBinormals(), outFrame.bitangents, mesh.indices);
  733. }
  734. }
  735. }
  736. void FBXImporter::importSkin(FBXImportScene& scene)
  737. {
  738. for (auto& mesh : scene.meshes)
  739. {
  740. FbxMesh* fbxMesh = mesh->fbxMesh;
  741. UINT32 deformerCount = (UINT32)fbxMesh->GetDeformerCount(FbxDeformer::eSkin);
  742. if (deformerCount > 0)
  743. {
  744. // We ignore other deformers if there's more than one
  745. FbxSkin* deformer = static_cast<FbxSkin*>(fbxMesh->GetDeformer(0, FbxDeformer::eSkin));
  746. UINT32 boneCount = (UINT32)deformer->GetClusterCount();
  747. if (boneCount == 0)
  748. continue;
  749. // If only one bone and it links to itself, ignore the bone
  750. if (boneCount == 1)
  751. {
  752. FbxCluster* cluster = deformer->GetCluster(0);
  753. if (mesh->referencedBy.size() == 1 && mesh->referencedBy[0]->fbxNode == cluster->GetLink())
  754. continue;
  755. }
  756. importSkin(scene, deformer, *mesh);
  757. }
  758. }
  759. }
  760. void FBXImporter::importSkin(FBXImportScene& scene, FbxSkin* skin, FBXImportMesh& mesh)
  761. {
  762. Vector<FBXBoneInfluence>& influences = mesh.boneInfluences;
  763. influences.resize(mesh.positions.size());
  764. UnorderedSet<FbxNode*> existingBones;
  765. UINT32 boneCount = (UINT32)skin->GetClusterCount();
  766. for (UINT32 i = 0; i < boneCount; i++)
  767. {
  768. FbxCluster* cluster = skin->GetCluster(i);
  769. FbxNode* link = cluster->GetLink();
  770. // The bone node doesn't exist, skip it
  771. auto iterFind = scene.nodeMap.find(link);
  772. if (iterFind == scene.nodeMap.end())
  773. continue;
  774. mesh.bones.push_back(FBXBone());
  775. FBXBone& bone = mesh.bones.back();
  776. bone.node = iterFind->second;
  777. FbxAMatrix clusterTransform;
  778. cluster->GetTransformMatrix(clusterTransform);
  779. FbxAMatrix linkTransform;
  780. cluster->GetTransformLinkMatrix(linkTransform);
  781. FbxAMatrix bindPose = linkTransform.Inverse() * clusterTransform;
  782. bone.bindPose = FBXToNativeType(bindPose);
  783. bool isDuplicate = existingBones.insert(link).second;
  784. bool isAdditive = cluster->GetLinkMode() == FbxCluster::eAdditive;
  785. // We avoid importing weights twice for duplicate bones and we don't
  786. // support additive link mode.
  787. bool importWeights = !isDuplicate && !isAdditive;
  788. if (!importWeights)
  789. continue;
  790. double* weights = cluster->GetControlPointWeights();
  791. INT32* indices = cluster->GetControlPointIndices();
  792. UINT32 numIndices = (UINT32)cluster->GetControlPointIndicesCount();
  793. INT32 numVertices = (INT32)influences.size();
  794. // Add new weights while keeping them in order and removing the smallest ones
  795. // if number of influences exceeds the set maximum value
  796. for (UINT32 j = 0; j < numIndices; j++)
  797. {
  798. INT32 vertexIndex = indices[j];
  799. float weight = (float)weights[j];
  800. for (UINT32 k = 0; k < FBX_IMPORT_MAX_BONE_INFLUENCES; k++)
  801. {
  802. if (vertexIndex < 0 || vertexIndex >= numVertices)
  803. continue;
  804. if (weight >= influences[vertexIndex].weights[k])
  805. {
  806. for (UINT32 l = FBX_IMPORT_MAX_BONE_INFLUENCES - 2; l >= k; l--)
  807. {
  808. influences[vertexIndex].weights[l + 1] = influences[vertexIndex].weights[l];
  809. influences[vertexIndex].indices[l + 1] = influences[vertexIndex].indices[l];
  810. }
  811. influences[vertexIndex].weights[k] = weight;
  812. influences[vertexIndex].indices[k] = i;
  813. break;
  814. }
  815. }
  816. }
  817. }
  818. if (mesh.bones.empty())
  819. mesh.boneInfluences.clear();
  820. // Normalize weights
  821. UINT32 numInfluences = (UINT32)mesh.boneInfluences.size();
  822. for (UINT32 i = 0; i < numInfluences; i++)
  823. {
  824. float sum = 0.0f;
  825. for (UINT32 j = 0; j < FBX_IMPORT_MAX_BONE_INFLUENCES; j++)
  826. sum += influences[i].weights[j];
  827. float invSum = 1.0f / sum;
  828. for (UINT32 j = 0; j < FBX_IMPORT_MAX_BONE_INFLUENCES; j++)
  829. influences[i].weights[j] *= invSum;
  830. }
  831. }
  832. void FBXImporter::generateMissingTangentSpace(FBXImportScene& scene, const FBXImportOptions& options)
  833. {
  834. for (auto& mesh : scene.meshes)
  835. {
  836. UINT32 numVertices = (UINT32)mesh->positions.size();
  837. UINT32 numIndices = (UINT32)mesh->indices.size();
  838. if ((options.importNormals || options.importTangents) && mesh->normals.empty())
  839. {
  840. mesh->normals.resize(numVertices);
  841. MeshUtility::calculateNormals(mesh->positions.data(), (UINT8*)mesh->indices.data(), numVertices, numIndices, mesh->normals.data());
  842. }
  843. if (options.importTangents && !mesh->UV[0].empty() && (mesh->tangents.empty() || mesh->bitangents.empty()))
  844. {
  845. mesh->tangents.resize(numVertices);
  846. mesh->bitangents.resize(numVertices);
  847. MeshUtility::calculateTangents(mesh->positions.data(), mesh->normals.data(), mesh->UV[0].data(), (UINT8*)mesh->indices.data(),
  848. numVertices, numIndices, mesh->tangents.data(), mesh->bitangents.data());
  849. }
  850. for (auto& shape : mesh->blendShapes)
  851. {
  852. for (auto& frame : shape.frames)
  853. {
  854. if ((options.importNormals || options.importTangents) && frame.normals.empty())
  855. {
  856. frame.normals.resize(numVertices);
  857. MeshUtility::calculateNormals(mesh->positions.data(), (UINT8*)mesh->indices.data(), numVertices, numIndices, frame.normals.data());
  858. }
  859. if (options.importTangents && !mesh->UV[0].empty() && (frame.tangents.empty() || frame.bitangents.empty()))
  860. {
  861. mesh->tangents.resize(numVertices);
  862. mesh->bitangents.resize(numVertices);
  863. MeshUtility::calculateTangents(mesh->positions.data(), frame.normals.data(), mesh->UV[0].data(), (UINT8*)mesh->indices.data(),
  864. numVertices, numIndices, frame.tangents.data(), frame.bitangents.data());
  865. }
  866. }
  867. }
  868. }
  869. }
  870. void FBXImporter::importAnimations(FbxScene* scene, FBXImportOptions& importOptions, FBXImportScene& importScene)
  871. {
  872. FbxNode* root = scene->GetRootNode();
  873. UINT32 numAnimStacks = (UINT32)scene->GetSrcObjectCount<FbxAnimStack>();
  874. for (UINT32 i = 0; i < numAnimStacks; i++)
  875. {
  876. FbxAnimStack* animStack = scene->GetSrcObject<FbxAnimStack>(i);
  877. importScene.clips.push_back(FBXAnimationClip());
  878. FBXAnimationClip& clip = importScene.clips.back();
  879. clip.name = animStack->GetName();
  880. FbxTimeSpan timeSpan = animStack->GetLocalTimeSpan();
  881. clip.start = (float)timeSpan.GetStart().GetSecondDouble();
  882. clip.end = (float)timeSpan.GetStop().GetSecondDouble();
  883. UINT32 layerCount = animStack->GetMemberCount<FbxAnimLayer>();
  884. if (layerCount > 1)
  885. {
  886. FbxAnimEvaluator* evaluator = scene->GetAnimationEvaluator();
  887. FbxTime startTime;
  888. startTime.SetSecondDouble(clip.start);
  889. FbxTime endTime;
  890. endTime.SetSecondDouble(clip.end);
  891. FbxTime sampleRate;
  892. if (importOptions.animResample)
  893. sampleRate.SetSecondDouble(importOptions.animSampleRate);
  894. else
  895. {
  896. FbxTime::EMode timeMode = scene->GetGlobalSettings().GetTimeMode();
  897. sampleRate.SetSecondDouble(1.0f / FbxTime::GetFrameRate(timeMode));
  898. }
  899. if (!animStack->BakeLayers(evaluator, startTime, endTime, sampleRate))
  900. continue;
  901. layerCount = animStack->GetMemberCount<FbxAnimLayer>();
  902. }
  903. if (layerCount == 1)
  904. {
  905. FbxAnimLayer* animLayer = animStack->GetMember<FbxAnimLayer>(0);
  906. importAnimations(animLayer, root, importOptions, clip, importScene);
  907. }
  908. }
  909. }
  910. void FBXImporter::importAnimations(FbxAnimLayer* layer, FbxNode* node, FBXImportOptions& importOptions,
  911. FBXAnimationClip& clip, FBXImportScene& importScene)
  912. {
  913. FbxAnimCurve* translation[3];
  914. translation[0] = node->LclTranslation.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_X);
  915. translation[1] = node->LclTranslation.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_Y);
  916. translation[2] = node->LclTranslation.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_Z);
  917. FbxAnimCurve* rotation[3];
  918. rotation[0] = node->LclRotation.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_X);
  919. rotation[1] = node->LclRotation.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_Y);
  920. rotation[2] = node->LclRotation.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_Z);
  921. FbxAnimCurve* scale[3];
  922. scale[0] = node->LclScaling.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_X);
  923. scale[1] = node->LclScaling.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_Y);
  924. scale[2] = node->LclScaling.GetCurve(layer, FBXSDK_CURVENODE_COMPONENT_Z);
  925. auto hasCurveValues = [](FbxAnimCurve* curves[3])
  926. {
  927. for (UINT32 i = 0; i < 3; i++)
  928. {
  929. if (curves[i] != nullptr && curves[i]->KeyGetCount() > 0)
  930. return true;
  931. }
  932. return false;
  933. };
  934. bool hasBoneAnimation = hasCurveValues(translation) || hasCurveValues(rotation) || hasCurveValues(scale);
  935. if (hasBoneAnimation)
  936. {
  937. clip.boneAnimations.push_back(FBXBoneAnimation());
  938. FBXBoneAnimation& boneAnim = clip.boneAnimations.back();
  939. boneAnim.node = importScene.nodeMap[node];
  940. importCurve(translation[0], importOptions, boneAnim.translation[0], clip.start, clip.end);
  941. importCurve(translation[1], importOptions, boneAnim.translation[1], clip.start, clip.end);
  942. importCurve(translation[2], importOptions, boneAnim.translation[2], clip.start, clip.end);
  943. importCurve(scale[0], importOptions, boneAnim.scale[0], clip.start, clip.end);
  944. importCurve(scale[1], importOptions, boneAnim.scale[1], clip.start, clip.end);
  945. importCurve(scale[2], importOptions, boneAnim.scale[2], clip.start, clip.end);
  946. FBXAnimationCurve tempCurveRotation[3];
  947. importCurve(rotation[0], importOptions, tempCurveRotation[0], clip.start, clip.end);
  948. importCurve(rotation[1], importOptions, tempCurveRotation[1], clip.start, clip.end);
  949. importCurve(rotation[2], importOptions, tempCurveRotation[2], clip.start, clip.end);
  950. eulerToQuaternionCurves(tempCurveRotation, boneAnim.rotation);
  951. }
  952. if (importOptions.importBlendShapes)
  953. {
  954. FbxMesh* fbxMesh = node->GetMesh();
  955. if (fbxMesh != nullptr)
  956. {
  957. INT32 deformerCount = fbxMesh->GetDeformerCount(FbxDeformer::eBlendShape);
  958. for (INT32 i = 0; i < deformerCount; i++)
  959. {
  960. FbxBlendShape* deformer = static_cast<FbxBlendShape*>(fbxMesh->GetDeformer(i, FbxDeformer::eBlendShape));
  961. INT32 channelCount = deformer->GetBlendShapeChannelCount();
  962. for (INT32 j = 0; j < channelCount; j++)
  963. {
  964. FbxBlendShapeChannel* channel = deformer->GetBlendShapeChannel(j);
  965. FbxAnimCurve* curve = fbxMesh->GetShapeChannel(i, j, layer);
  966. if (curve != nullptr && curve->KeyGetCount() > 0)
  967. {
  968. clip.blendShapeAnimations.push_back(FBXBlendShapeAnimation());
  969. FBXBlendShapeAnimation& blendShapeAnim = clip.blendShapeAnimations.back();
  970. blendShapeAnim.blendShape = channel->GetName();
  971. importCurve(curve, importOptions, blendShapeAnim.curve, clip.start, clip.end);
  972. }
  973. }
  974. }
  975. }
  976. }
  977. UINT32 childCount = (UINT32)node->GetChildCount();
  978. for (UINT32 i = 0; i < childCount; i++)
  979. {
  980. FbxNode* child = node->GetChild(i);
  981. importAnimations(layer, child, importOptions, clip, importScene);
  982. }
  983. }
  984. void FBXImporter::eulerToQuaternionCurves(FBXAnimationCurve(&eulerCurves)[3], FBXAnimationCurve(&quatCurves)[4])
  985. {
  986. INT32 numKeys = (INT32)eulerCurves[0].keyframes.size();
  987. if (numKeys != (INT32)eulerCurves[1].keyframes.size() || numKeys != (INT32)eulerCurves[2].keyframes.size())
  988. return;
  989. Quaternion lastQuat;
  990. for (INT32 i = 0; i < numKeys; i++)
  991. {
  992. float time = eulerCurves[0].keyframes[i].time;
  993. Degree x = (Degree)eulerCurves[0].keyframes[i].value;
  994. Degree y = (Degree)eulerCurves[1].keyframes[i].value;
  995. Degree z = (Degree)eulerCurves[2].keyframes[i].value;
  996. Quaternion quat(x, y, z);
  997. // Flip quaternion in case rotation is over 180 degrees
  998. if (i > 0)
  999. {
  1000. float dot = quat.dot(lastQuat);
  1001. if (dot < 0.0f)
  1002. quat = Quaternion(-quat.x, -quat.y, -quat.z, -quat.w);
  1003. }
  1004. // TODO - If animation is looping I should also compare last and first for continuity
  1005. for (INT32 j = 0; j < 4; j++)
  1006. {
  1007. quatCurves[j].keyframes.push_back(FBXKeyFrame());
  1008. FBXKeyFrame& keyFrame = quatCurves[j].keyframes.back();
  1009. keyFrame.time = time;
  1010. keyFrame.value = quat[j];
  1011. // TODO - Recalculate tangents(make sure not to ignore original ones)
  1012. // - Pay attention to deal with non-equally spaced keyframes
  1013. // TODO - Tangent recalculation assumes all curves are cubic, which might not be the case
  1014. keyFrame.inTangent = 0;
  1015. keyFrame.outTangent = 0;
  1016. }
  1017. lastQuat = quat;
  1018. }
  1019. }
  1020. void FBXImporter::importCurve(FbxAnimCurve* fbxCurve, FBXImportOptions& importOptions, FBXAnimationCurve& curve, float start, float end)
  1021. {
  1022. if (fbxCurve == nullptr)
  1023. return;
  1024. INT32 keyCount = fbxCurve->KeyGetCount();
  1025. if (importOptions.animResample)
  1026. {
  1027. float curveStart = std::numeric_limits<float>::infinity();
  1028. float curveEnd = -std::numeric_limits<float>::infinity();
  1029. for (INT32 i = 0; i < keyCount; i++)
  1030. {
  1031. FbxTime fbxTime = fbxCurve->KeyGetTime(i);
  1032. float time = (float)fbxTime.GetSecondDouble();
  1033. curveStart = std::min(time, curveStart);
  1034. curveEnd = std::max(time, curveEnd);
  1035. }
  1036. curveStart = Math::clamp(curveStart, start, end);
  1037. curveEnd = Math::clamp(curveEnd, start, end);
  1038. float curveLength = curveEnd - curveStart;
  1039. INT32 numSamples = Math::ceilToInt(curveLength / importOptions.animSampleRate);
  1040. // We don't use the exact provided sample rate but instead modify it slightly so it
  1041. // completely covers the curve range including start/end points while maintaining
  1042. // constant time step between keyframes.
  1043. float dt = curveLength / (float)numSamples;
  1044. INT32 lastKeyframe = 0;
  1045. INT32 lastLeftTangent = 0;
  1046. INT32 lastRightTangent = 0;
  1047. for (INT32 i = 0; i < numSamples; i++)
  1048. {
  1049. float sampleTime = std::min(curveStart + i * dt, curveEnd);
  1050. FbxTime fbxSampleTime;
  1051. fbxSampleTime.SetSecondDouble(sampleTime);
  1052. curve.keyframes.push_back(FBXKeyFrame());
  1053. FBXKeyFrame& keyFrame = curve.keyframes.back();
  1054. keyFrame.time = sampleTime;
  1055. keyFrame.value = fbxCurve->Evaluate(fbxSampleTime, &lastKeyframe);
  1056. keyFrame.inTangent = fbxCurve->EvaluateLeftDerivative(fbxSampleTime, &lastLeftTangent);
  1057. keyFrame.outTangent = fbxCurve->EvaluateRightDerivative(fbxSampleTime, &lastRightTangent);
  1058. }
  1059. }
  1060. else
  1061. {
  1062. for (int i = 0; i < keyCount; i++)
  1063. {
  1064. FbxTime fbxTime = fbxCurve->KeyGetTime(i);
  1065. float time = (float)fbxTime.GetSecondDouble();
  1066. if (time < start || time > end)
  1067. continue;
  1068. curve.keyframes.push_back(FBXKeyFrame());
  1069. FBXKeyFrame& keyFrame = curve.keyframes.back();
  1070. keyFrame.time = time;
  1071. keyFrame.value = fbxCurve->KeyGetValue(i);
  1072. keyFrame.inTangent = fbxCurve->KeyGetLeftDerivative(i);
  1073. keyFrame.outTangent = fbxCurve->KeyGetRightDerivative(i);
  1074. }
  1075. }
  1076. }
  1077. }