BsFBXImporter.cpp 45 KB

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