BsFBXImporter.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  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 <BsMeshImportOptions.h>
  15. namespace BansheeEngine
  16. {
  17. Matrix4 FBXToNativeType(const FbxAMatrix& value)
  18. {
  19. Matrix4 native;
  20. for (UINT32 row = 0; row < 4; row++)
  21. for (UINT32 col = 0; col < 4; col++)
  22. native[row][col] = (float)value[col][row];
  23. return native;
  24. }
  25. Vector4 FBXToNativeType(const FbxVector4& value)
  26. {
  27. Vector4 native;
  28. native.x = (float)value[0];
  29. native.y = (float)value[1];
  30. native.z = (float)value[2];
  31. native.w = (float)value[3];
  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. splitMeshVertices(importedScene);
  110. Vector<SubMesh> subMeshes;
  111. MeshDataPtr meshData = generateMeshData(importedScene, fbxImportOptions, subMeshes);
  112. // TODO - Later: Optimize mesh: Remove bad and degenerate polygons, optimize for vertex cache
  113. shutDownSdk();
  114. INT32 usage = MU_STATIC;
  115. if (meshImportOptions->getCPUReadable())
  116. usage |= MU_CPUCACHED;
  117. MeshPtr mesh = Mesh::_createPtr(meshData, subMeshes, usage);
  118. WString fileName = filePath.getWFilename(false);
  119. mesh->setName(fileName);
  120. return mesh;
  121. }
  122. bool FBXImporter::startUpSdk(FbxScene*& scene)
  123. {
  124. mFBXManager = FbxManager::Create();
  125. if (mFBXManager == nullptr)
  126. {
  127. LOGERR("FBX import failed: FBX SDK failed to initialize. FbxManager::Create() failed.");
  128. return false;
  129. }
  130. FbxIOSettings* ios = FbxIOSettings::Create(mFBXManager, IOSROOT);
  131. mFBXManager->SetIOSettings(ios);
  132. scene = FbxScene::Create(mFBXManager, "Import Scene");
  133. if (scene == nullptr)
  134. {
  135. LOGWRN("FBX import failed: Failed to create FBX scene.");
  136. return false;
  137. }
  138. return true;
  139. }
  140. void FBXImporter::shutDownSdk()
  141. {
  142. mFBXManager->Destroy();
  143. mFBXManager = nullptr;
  144. }
  145. bool FBXImporter::loadFBXFile(FbxScene* scene, const Path& filePath)
  146. {
  147. int lFileMajor, lFileMinor, lFileRevision;
  148. int lSDKMajor, lSDKMinor, lSDKRevision;
  149. FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);
  150. FbxImporter* importer = FbxImporter::Create(mFBXManager, "");
  151. bool importStatus = importer->Initialize(filePath.toString().c_str(), -1, mFBXManager->GetIOSettings());
  152. importer->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);
  153. if(!importStatus)
  154. {
  155. LOGERR("FBX import failed: Call to FbxImporter::Initialize() failed.\n" +
  156. String("Error returned: %s\n\n") + String(importer->GetStatus().GetErrorString()));
  157. return false;
  158. }
  159. mFBXManager->GetIOSettings()->SetBoolProp(IMP_FBX_TEXTURE, false);
  160. mFBXManager->GetIOSettings()->SetBoolProp(IMP_FBX_GOBO, false);
  161. importStatus = importer->Import(scene);
  162. if(!importStatus)
  163. {
  164. importer->Destroy();
  165. LOGERR("FBX import failed: Call to FbxImporter::Initialize() failed.\n" +
  166. String("Error returned: %s\n\n") + String(importer->GetStatus().GetErrorString()));
  167. return false;
  168. }
  169. FbxAxisSystem fileCoordSystem = scene->GetGlobalSettings().GetAxisSystem();
  170. FbxAxisSystem bsCoordSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eRightHanded);
  171. if (fileCoordSystem != bsCoordSystem)
  172. bsCoordSystem.ConvertScene(scene);
  173. importer->Destroy();
  174. return true;
  175. }
  176. void FBXImporter::parseScene(FbxScene* scene, const FBXImportOptions& options, FBXImportScene& outputScene)
  177. {
  178. outputScene.rootNode = createImportNode(outputScene, scene->GetRootNode(), nullptr);
  179. Stack<FbxNode*> todo;
  180. todo.push(scene->GetRootNode());
  181. while(!todo.empty())
  182. {
  183. FbxNode* curNode = todo.top();
  184. FBXImportNode* curImportNode = outputScene.nodeMap[curNode];
  185. todo.pop();
  186. const char* name = curNode->GetName();
  187. FbxNodeAttribute* attrib = curNode->GetNodeAttribute();
  188. if(attrib != nullptr)
  189. {
  190. FbxNodeAttribute::EType attribType = attrib->GetAttributeType();
  191. switch(attribType)
  192. {
  193. case FbxNodeAttribute::eNurbs:
  194. case FbxNodeAttribute::eNurbsSurface:
  195. case FbxNodeAttribute::ePatch:
  196. {
  197. FbxGeometryConverter geomConverter(mFBXManager);
  198. attrib = geomConverter.Triangulate(attrib, true);
  199. if (attrib->GetAttributeType() == FbxNodeAttribute::eMesh)
  200. {
  201. FbxMesh* mesh = static_cast<FbxMesh*>(attrib);
  202. mesh->RemoveBadPolygons();
  203. parseMesh(mesh, curImportNode, options, outputScene);
  204. }
  205. }
  206. break;
  207. case FbxNodeAttribute::eMesh:
  208. {
  209. FbxMesh* mesh = static_cast<FbxMesh*>(attrib);
  210. mesh->RemoveBadPolygons();
  211. if(!mesh->IsTriangleMesh())
  212. {
  213. FbxGeometryConverter geomConverter(mFBXManager);
  214. geomConverter.Triangulate(mesh, true);
  215. attrib = curNode->GetNodeAttribute();
  216. mesh = static_cast<FbxMesh*>(attrib);
  217. }
  218. parseMesh(mesh, curImportNode, options, outputScene);
  219. }
  220. break;
  221. }
  222. }
  223. for (int i = 0; i < curNode->GetChildCount(); i++)
  224. {
  225. FbxNode* childNode = curNode->GetChild(i);
  226. createImportNode(outputScene, childNode, curImportNode);
  227. todo.push(childNode);
  228. }
  229. }
  230. // TODO - Parse animation
  231. }
  232. FBXImportNode* FBXImporter::createImportNode(FBXImportScene& scene, FbxNode* fbxNode, FBXImportNode* parent)
  233. {
  234. FBXImportNode* node = bs_new<FBXImportNode>();
  235. Vector3 translation = FBXToNativeType(fbxNode->LclTranslation.Get());
  236. Vector3 rotationEuler = FBXToNativeType(fbxNode->LclRotation.Get());
  237. Vector3 scale = FBXToNativeType(fbxNode->LclScaling.Get());
  238. Quaternion rotation((Radian)rotationEuler.x, (Radian)rotationEuler.y, (Radian)rotationEuler.z);
  239. node->localTransform.setTRS(translation, rotation, scale);
  240. node->fbxNode = fbxNode;
  241. if (parent != nullptr)
  242. {
  243. node->worldTransform = node->localTransform * parent->worldTransform;
  244. parent->children.push_back(node);
  245. }
  246. else
  247. node->worldTransform = node->localTransform;
  248. scene.nodeMap.insert(std::make_pair(fbxNode, node));
  249. return node;
  250. }
  251. void FBXImporter::splitMeshVertices(FBXImportScene& scene)
  252. {
  253. Vector<FBXImportMesh*> splitMeshes;
  254. for (auto& mesh : scene.meshes)
  255. {
  256. FBXImportMesh* splitMesh = bs_new<FBXImportMesh>();
  257. splitMesh->fbxMesh = mesh->fbxMesh;
  258. splitMesh->referencedBy = mesh->referencedBy;
  259. splitMesh->bones = mesh->bones;
  260. FBXUtility::splitVertices(*mesh, *splitMesh);
  261. FBXUtility::flipWindingOrder(*splitMesh);
  262. splitMeshes.push_back(splitMesh);
  263. bs_delete(mesh);
  264. }
  265. scene.meshes = splitMeshes;
  266. }
  267. MeshDataPtr FBXImporter::generateMeshData(const FBXImportScene& scene, const FBXImportOptions& options, Vector<SubMesh>& outputSubMeshes)
  268. {
  269. Matrix4 importScale = Matrix4::scaling(options.importScale);
  270. Vector<MeshDataPtr> allMeshData;
  271. Vector<Vector<SubMesh>> allSubMeshes;
  272. for (auto& mesh : scene.meshes)
  273. {
  274. Vector<Vector<UINT32>> indicesPerMaterial;
  275. for (UINT32 i = 0; i < (UINT32)mesh->indices.size(); i++)
  276. {
  277. while (mesh->materials[i] >= indicesPerMaterial.size())
  278. indicesPerMaterial.push_back(Vector<UINT32>());
  279. indicesPerMaterial[mesh->materials[i]].push_back(mesh->indices[i]);
  280. }
  281. UINT32* orderedIndices = (UINT32*)bs_alloc((UINT32)mesh->indices.size() * sizeof(UINT32));
  282. Vector<SubMesh> subMeshes;
  283. UINT32 currentIndex = 0;
  284. for (auto& subMeshIndices : indicesPerMaterial)
  285. {
  286. UINT32 indexCount = (UINT32)subMeshIndices.size();
  287. UINT32* dest = orderedIndices + currentIndex;
  288. memcpy(dest, subMeshIndices.data(), indexCount * sizeof(UINT32));
  289. subMeshes.push_back(SubMesh(currentIndex, indexCount, DOT_TRIANGLE_LIST));
  290. currentIndex += indexCount;
  291. }
  292. VertexDataDescPtr vertexDesc = bs_shared_ptr<VertexDataDesc>();
  293. vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
  294. size_t numVertices = mesh->positions.size();
  295. bool hasColors = mesh->colors.size() == numVertices;
  296. bool hasNormals = mesh->normals.size() == numVertices;
  297. if (hasColors)
  298. vertexDesc->addVertElem(VET_COLOR, VES_COLOR);
  299. bool hasTangents = false;
  300. if (hasNormals)
  301. {
  302. vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
  303. if (mesh->tangents.size() == numVertices &&
  304. mesh->bitangents.size() == numVertices)
  305. {
  306. vertexDesc->addVertElem(VET_FLOAT4, VES_TANGENT);
  307. hasTangents = true;
  308. }
  309. }
  310. int UVIdx = 0;
  311. for (UINT32 i = 0; i < FBX_IMPORT_MAX_UV_LAYERS; i++)
  312. {
  313. if (mesh->UV[i].size() == numVertices)
  314. {
  315. vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD, UVIdx++);
  316. }
  317. }
  318. UINT32 numIndices = (UINT32)mesh->indices.size();
  319. for (auto& node : mesh->referencedBy)
  320. {
  321. Matrix4 worldTransform = node->worldTransform * importScale;
  322. Matrix4 worldTransformIT = worldTransform.transpose();
  323. worldTransformIT = worldTransformIT.inverse();
  324. MeshDataPtr meshData = bs_shared_ptr<MeshData>((UINT32)numVertices, numIndices, vertexDesc);
  325. // Copy indices
  326. UINT32* indices = meshData->getIndices32();
  327. memcpy(indices, mesh->indices.data(), numIndices * sizeof(UINT32));
  328. // Copy & transform positions
  329. auto posIter = meshData->getVec3DataIter(VES_POSITION, 0);
  330. for (auto& position : mesh->positions)
  331. {
  332. Vector3 tfrmdValue = worldTransform.multiplyAffine((Vector3)position);
  333. posIter.addValue(tfrmdValue);
  334. }
  335. // Copy & transform normals
  336. if (hasNormals)
  337. {
  338. auto normalIter = meshData->getVec3DataIter(VES_NORMAL, 0);
  339. // Copy, convert & transform tangents & bitangents
  340. if (hasTangents)
  341. {
  342. auto tangentIter = meshData->getVec4DataIter(VES_TANGENT, 0);
  343. for (UINT32 i = 0; i < (UINT32)numVertices; i++)
  344. {
  345. Vector3 normal = (Vector3)mesh->normals[i];
  346. normal = worldTransformIT.multiplyAffine(normal);
  347. normalIter.addValue(normal);
  348. Vector3 tangent = (Vector3)mesh->tangents[i];
  349. tangent = worldTransformIT.multiplyAffine(tangent);
  350. Vector3 bitangent = (Vector3)mesh->bitangents[i];
  351. bitangent = worldTransformIT.multiplyAffine(bitangent);
  352. Vector3 engineBitangent = Vector3::cross(normal, tangent);
  353. float sign = Vector3::dot(engineBitangent, bitangent);
  354. Vector4 combinedTangent(tangent.x, tangent.y, tangent.z, sign > 0 ? 1.0f : -1.0f);
  355. tangentIter.addValue(combinedTangent);
  356. }
  357. }
  358. else // Just normals
  359. {
  360. for (auto& normal : mesh->normals)
  361. {
  362. Vector3 tfrmdValue = worldTransformIT.multiplyAffine((Vector3)normal);
  363. normalIter.addValue(tfrmdValue);
  364. }
  365. }
  366. }
  367. // Copy colors
  368. if (hasColors)
  369. {
  370. auto colorIter = meshData->getDWORDDataIter(VES_COLOR, 0);
  371. for (auto& color : mesh->colors)
  372. colorIter.addValue(color);
  373. }
  374. // Copy UV
  375. int writeUVIDx = 0;
  376. for (auto& uvLayer : mesh->UV)
  377. {
  378. if (uvLayer.size() == numVertices)
  379. {
  380. auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD, writeUVIDx);
  381. for (auto& uv : uvLayer)
  382. {
  383. uv.y = 1.0f - uv.y;
  384. uvIter.addValue(uv);
  385. }
  386. writeUVIDx++;
  387. }
  388. }
  389. allMeshData.push_back(meshData);
  390. allSubMeshes.push_back(subMeshes);
  391. }
  392. }
  393. if (allMeshData.size() > 1)
  394. {
  395. return MeshData::combine(allMeshData, allSubMeshes, outputSubMeshes);
  396. }
  397. else if (allMeshData.size() == 1)
  398. {
  399. outputSubMeshes = allSubMeshes[0];
  400. return allMeshData[0];
  401. }
  402. return nullptr;
  403. }
  404. template<class TFBX, class TNative>
  405. class FBXDirectIndexer
  406. {
  407. public:
  408. FBXDirectIndexer(const FbxLayerElementTemplate<TFBX>& layer)
  409. :mElementArray(layer.GetDirectArray()),
  410. mElementCount(mElementArray.GetCount())
  411. {}
  412. bool get(int index, TNative& output) const
  413. {
  414. if (index < 0 || index >= mElementCount)
  415. return false;
  416. output = FBXToNativeType(mElementArray.GetAt(index));
  417. return true;
  418. }
  419. bool isEmpty() const
  420. {
  421. return mElementCount == 0;
  422. }
  423. private:
  424. const FbxLayerElementArrayTemplate<TFBX>& mElementArray;
  425. int mElementCount;
  426. };
  427. template<class TFBX, class TNative>
  428. class FBXIndexIndexer
  429. {
  430. public:
  431. FBXIndexIndexer(const FbxLayerElementTemplate<TFBX>& layer)
  432. :mElementArray(layer.GetDirectArray()),
  433. mIndexArray(layer.GetIndexArray()),
  434. mElementCount(mElementArray.GetCount()),
  435. mIndexCount(mIndexArray.GetCount())
  436. {}
  437. bool get(int index, TNative& output) const
  438. {
  439. if (index < 0 || index >= mIndexCount)
  440. return false;
  441. int actualIndex = mIndexArray.GetAt(index);
  442. if (actualIndex < 0 || actualIndex >= mElementCount)
  443. return false;
  444. output = FBXToNativeType(mElementArray.GetAt(actualIndex));
  445. return true;
  446. }
  447. bool isEmpty() const
  448. {
  449. return mElementCount == 0 || mIndexCount == 0;
  450. }
  451. private:
  452. const FbxLayerElementArrayTemplate<TFBX>& mElementArray;
  453. const FbxLayerElementArrayTemplate<int>& mIndexArray;
  454. int mElementCount;
  455. int mIndexCount;
  456. };
  457. template<class TFBX, class TNative, class TIndexer>
  458. void readLayerData(FbxLayerElementTemplate<TFBX>& layer, Vector<TNative>& output, const Vector<int>& indices)
  459. {
  460. TIndexer indexer(layer);
  461. if (indexer.isEmpty())
  462. return;
  463. output.resize(indices.size());
  464. FbxLayerElement::EMappingMode mappingMode = layer.GetMappingMode();
  465. UINT32 indexCount = (UINT32)indices.size();
  466. switch (mappingMode)
  467. {
  468. case FbxLayerElement::eByControlPoint:
  469. for (UINT32 i = 0; i < indexCount; i++)
  470. {
  471. int index = indices[i];
  472. indexer.get(index, output[i]);
  473. }
  474. break;
  475. case FbxLayerElement::eByPolygonVertex:
  476. for (UINT32 i = 0; i < indexCount; i++)
  477. indexer.get(i, output[i]);
  478. break;
  479. case FbxLayerElement::eByPolygon:
  480. // We expect mesh to be triangulated here
  481. {
  482. UINT32 polygonCount = indexCount / 3;
  483. UINT32 index = 0;
  484. for (UINT32 i = 0; i < polygonCount; i++)
  485. {
  486. TNative value;
  487. indexer.get(i, value);
  488. output[index++] = value;
  489. output[index++] = value;
  490. output[index++] = value;
  491. }
  492. }
  493. break;
  494. case FbxLayerElement::eAllSame:
  495. {
  496. TNative value;
  497. indexer.get(0, value);
  498. for (UINT32 i = 0; i < indexCount; i++)
  499. output[i] = value;
  500. }
  501. break;
  502. default:
  503. LOGWRN("FBX Import: Unsupported layer mapping mode.");
  504. break;
  505. }
  506. }
  507. template<class TFBX, class TNative>
  508. void readLayerData(FbxLayerElementTemplate<TFBX>& layer, Vector<TNative>& output, const Vector<int>& indices)
  509. {
  510. FbxLayerElement::EReferenceMode refMode = layer.GetReferenceMode();
  511. if (refMode == FbxLayerElement::eDirect)
  512. readLayerData<TFBX, TNative, FBXDirectIndexer<TFBX, TNative> >(layer, output, indices);
  513. else if (refMode == FbxLayerElement::eIndexToDirect)
  514. readLayerData<TFBX, TNative, FBXIndexIndexer<TFBX, TNative> >(layer, output, indices);
  515. else
  516. LOGWRN("FBX Import: Unsupported layer reference mode.");
  517. }
  518. void FBXImporter::parseMesh(FbxMesh* mesh, FBXImportNode* parentNode, const FBXImportOptions& options, FBXImportScene& outputScene)
  519. {
  520. // Check if valid
  521. if (!mesh->IsTriangleMesh())
  522. return;
  523. UINT32 vertexCount = mesh->GetControlPointsCount();
  524. UINT32 triangleCount = mesh->GetPolygonCount();
  525. if (vertexCount == 0 || triangleCount == 0)
  526. return;
  527. // Register in global mesh array
  528. FBXImportMesh* importMesh = nullptr;
  529. auto iterFindMesh = outputScene.meshMap.find(mesh);
  530. if (iterFindMesh != outputScene.meshMap.end())
  531. {
  532. UINT32 meshIdx = iterFindMesh->second;
  533. outputScene.meshes[meshIdx]->referencedBy.push_back(parentNode);
  534. return;
  535. }
  536. else
  537. {
  538. importMesh = bs_new<FBXImportMesh>();
  539. outputScene.meshes.push_back(importMesh);
  540. importMesh->referencedBy.push_back(parentNode);
  541. importMesh->fbxMesh = mesh;
  542. outputScene.meshMap[mesh] = (UINT32)outputScene.meshes.size() - 1;
  543. }
  544. // Import vertices
  545. importMesh->positions.resize(vertexCount);
  546. FbxVector4* controlPoints = mesh->GetControlPoints();
  547. for (UINT32 i = 0; i < vertexCount; i++)
  548. importMesh->positions[i] = FBXToNativeType(controlPoints[i]);
  549. // Import triangles
  550. UINT32 indexCount = triangleCount * 3;
  551. importMesh->indices.resize(indexCount);
  552. int* fbxIndices = mesh->GetPolygonVertices();
  553. importMesh->indices.assign(fbxIndices, fbxIndices + indexCount);
  554. // Import UVs
  555. Vector<FbxLayerElementUV*> fbxUVLayers;
  556. //// Search the diffuse layers first
  557. for (UINT32 i = 0; i < FBX_IMPORT_MAX_UV_LAYERS; i++)
  558. {
  559. FbxLayer* layer = mesh->GetLayer(i, FbxLayerElement::eUV);
  560. if (layer == nullptr)
  561. continue;
  562. for (int j = FbxLayerElement::eTextureDiffuse; j < FbxLayerElement::eTypeCount; j++)
  563. {
  564. FbxLayerElementUV* uvLayer = layer->GetUVs((FbxLayerElement::EType)j);
  565. if (uvLayer == nullptr)
  566. continue;
  567. fbxUVLayers.push_back(uvLayer);
  568. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  569. break;
  570. }
  571. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  572. break;
  573. }
  574. //// If there's room, search all others too
  575. if (fbxUVLayers.size() < FBX_IMPORT_MAX_UV_LAYERS)
  576. {
  577. UINT32 numLayers = mesh->GetLayerCount();
  578. for (UINT32 i = 0; i < numLayers; i++)
  579. {
  580. FbxLayer* layer = mesh->GetLayer(i);
  581. if (layer == nullptr)
  582. continue;
  583. for (int j = FbxLayerElement::eTextureDiffuse; j < FbxLayerElement::eTypeCount; j++)
  584. {
  585. FbxLayerElementUV* uvLayer = layer->GetUVs((FbxLayerElement::EType)j);
  586. if (uvLayer == nullptr)
  587. continue;
  588. auto iterFind = std::find(fbxUVLayers.begin(), fbxUVLayers.end(), uvLayer);
  589. if (iterFind != fbxUVLayers.end())
  590. continue;
  591. fbxUVLayers.push_back(uvLayer);
  592. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  593. break;
  594. }
  595. if (fbxUVLayers.size() == FBX_IMPORT_MAX_UV_LAYERS)
  596. break;
  597. }
  598. }
  599. for (size_t i = 0; i < fbxUVLayers.size(); i++)
  600. readLayerData(*fbxUVLayers[i], importMesh->UV[i], importMesh->indices);
  601. FbxLayer* mainLayer = mesh->GetLayer(0);
  602. if (mainLayer != nullptr)
  603. {
  604. // Import colors
  605. if (mainLayer->GetVertexColors() != nullptr)
  606. readLayerData(*mainLayer->GetVertexColors(), importMesh->colors, importMesh->indices);
  607. // Import normals
  608. if (options.importNormals)
  609. {
  610. bool hasNormals = mainLayer->GetNormals() != nullptr;
  611. if (!hasNormals)
  612. {
  613. if (mainLayer->GetSmoothing() != nullptr)
  614. {
  615. FbxLayerElementSmoothing* smoothing = mainLayer->GetSmoothing();
  616. if (smoothing->GetMappingMode() == FbxLayerElement::eByEdge)
  617. {
  618. FbxGeometryConverter converter(mFBXManager);
  619. converter.ComputePolygonSmoothingFromEdgeSmoothing(mesh, 0);
  620. }
  621. readLayerData(*smoothing, importMesh->smoothingGroups, importMesh->indices);
  622. if (!importMesh->smoothingGroups.empty())
  623. {
  624. FBXUtility::normalsFromSmoothing(importMesh->positions, importMesh->indices,
  625. importMesh->smoothingGroups, importMesh->normals);
  626. hasNormals = true;
  627. }
  628. }
  629. if (!hasNormals)
  630. {
  631. // TODO - Calculate normals
  632. }
  633. }
  634. else
  635. readLayerData(*mainLayer->GetNormals(), importMesh->normals, importMesh->indices);
  636. }
  637. // Import tangents
  638. if (options.importTangents)
  639. {
  640. bool hasTangents = mainLayer->GetTangents() != nullptr && mainLayer->GetBinormals() != nullptr;
  641. if (!hasTangents)
  642. {
  643. if (fbxUVLayers.size() > 0)
  644. hasTangents = mesh->GenerateTangentsData(0, false);
  645. }
  646. if (hasTangents)
  647. {
  648. readLayerData(*mainLayer->GetTangents(), importMesh->tangents, importMesh->indices);
  649. readLayerData(*mainLayer->GetBinormals(), importMesh->bitangents, importMesh->indices);
  650. }
  651. else
  652. {
  653. // TODO - Calculate tangent frame
  654. }
  655. }
  656. // Import material indexes
  657. if (mainLayer->GetMaterials() != nullptr)
  658. {
  659. Vector<FbxSurfaceMaterial*> fbxMaterials;
  660. readLayerData(*mainLayer->GetMaterials(), fbxMaterials, importMesh->indices);
  661. UnorderedMap<FbxSurfaceMaterial*, int> materialLookup;
  662. int nextMaterialIdx = 0;
  663. for (UINT32 i = 0; i < (UINT32)fbxMaterials.size(); i++)
  664. {
  665. auto iterFind = materialLookup.find(fbxMaterials[i]);
  666. int materialIdx = 0;
  667. if (iterFind != materialLookup.end())
  668. materialIdx = iterFind->second;
  669. else
  670. {
  671. materialIdx = nextMaterialIdx++;
  672. materialLookup[fbxMaterials[i]] = materialIdx;
  673. }
  674. importMesh->materials.push_back(materialIdx);
  675. }
  676. }
  677. }
  678. }
  679. void FBXImporter::importBlendShapes(FBXImportScene& scene, const FBXImportOptions& options)
  680. {
  681. for (auto& mesh : scene.meshes)
  682. {
  683. FbxMesh* fbxMesh = mesh->fbxMesh;
  684. UINT32 deformerCount = (UINT32)fbxMesh->GetDeformerCount(FbxDeformer::eBlendShape);
  685. for (UINT32 i = 0; i < deformerCount; i++)
  686. {
  687. FbxBlendShape* deformer = static_cast<FbxBlendShape*>(fbxMesh->GetDeformer(i, FbxDeformer::eBlendShape));
  688. UINT32 blendShapeChannelCount = (UINT32)deformer->GetBlendShapeChannelCount();
  689. for (UINT32 j = 0; j < blendShapeChannelCount; ++j)
  690. {
  691. FbxBlendShapeChannel* channel = deformer->GetBlendShapeChannel(j);
  692. double* weights = channel->GetTargetShapeFullWeights();
  693. UINT32 frameCount = channel->GetTargetShapeCount();
  694. if (frameCount == 0)
  695. continue;
  696. mesh->blendShapes.push_back(FBXBlendShape());
  697. FBXBlendShape& blendShape = mesh->blendShapes.back();
  698. blendShape.name = channel->GetName();
  699. blendShape.frames.resize(frameCount);
  700. for (UINT32 k = 0; k < frameCount; k++)
  701. {
  702. FbxShape* fbxShape = channel->GetTargetShape(k);
  703. FBXBlendShapeFrame& frame = blendShape.frames[k];
  704. frame.weight = (float)weights[k];
  705. importBlendShapeFrame(fbxShape, *mesh, options, frame);
  706. }
  707. }
  708. }
  709. }
  710. }
  711. void FBXImporter::importBlendShapeFrame(FbxShape* shape, const FBXImportMesh& mesh, const FBXImportOptions& options, FBXBlendShapeFrame& outFrame)
  712. {
  713. UINT32 vertexCount = (UINT32)shape->GetControlPointsCount();
  714. outFrame.positions.resize(vertexCount);
  715. FbxVector4* controlPoints = shape->GetControlPoints();
  716. for (UINT32 i = 0; i < vertexCount; i++)
  717. outFrame.positions[i] = FBXToNativeType(controlPoints[i]);
  718. FbxLayer* mainLayer = shape->GetLayer(0);
  719. if (options.importNormals)
  720. {
  721. bool hasNormals = mainLayer->GetNormals() != nullptr;
  722. if (!hasNormals)
  723. {
  724. if (!mesh.smoothingGroups.empty())
  725. {
  726. FBXUtility::normalsFromSmoothing(outFrame.positions, mesh.indices,
  727. mesh.smoothingGroups, outFrame.normals);
  728. }
  729. else
  730. {
  731. // TODO - Calculate normals
  732. }
  733. }
  734. else
  735. readLayerData(*mainLayer->GetNormals(), outFrame.normals, mesh.indices);
  736. }
  737. if (options.importTangents)
  738. {
  739. bool hasTangents = mainLayer->GetTangents() != nullptr && mainLayer->GetBinormals() != nullptr;
  740. if (hasTangents)
  741. {
  742. readLayerData(*mainLayer->GetTangents(), outFrame.tangents, mesh.indices);
  743. readLayerData(*mainLayer->GetBinormals(), outFrame.bitangents, mesh.indices);
  744. }
  745. else
  746. {
  747. // TODO - Calculate tangent frame
  748. }
  749. }
  750. }
  751. void FBXImporter::importSkin(FBXImportScene& scene)
  752. {
  753. for (auto& mesh : scene.meshes)
  754. {
  755. FbxMesh* fbxMesh = mesh->fbxMesh;
  756. UINT32 deformerCount = (UINT32)fbxMesh->GetDeformerCount(FbxDeformer::eSkin);
  757. if (deformerCount > 0)
  758. {
  759. // We ignore other deformers if there's more than one
  760. FbxSkin* deformer = static_cast<FbxSkin*>(fbxMesh->GetDeformer(0, FbxDeformer::eSkin));
  761. UINT32 boneCount = (UINT32)deformer->GetClusterCount();
  762. if (boneCount == 0)
  763. continue;
  764. // If only one bone and it links to itself, ignore the bone
  765. if (boneCount == 1)
  766. {
  767. FbxCluster* cluster = deformer->GetCluster(0);
  768. if (mesh->referencedBy.size() == 1 && mesh->referencedBy[0]->fbxNode == cluster->GetLink())
  769. continue;
  770. }
  771. importSkin(scene, deformer, *mesh);
  772. }
  773. }
  774. }
  775. void FBXImporter::importSkin(FBXImportScene& scene, FbxSkin* skin, FBXImportMesh& mesh)
  776. {
  777. Vector<FBXBoneInfluence>& influences = mesh.boneInfluences;
  778. influences.resize(mesh.positions.size());
  779. UnorderedSet<FbxNode*> existingBones;
  780. UINT32 boneCount = (UINT32)skin->GetClusterCount();
  781. for (UINT32 i = 0; i < boneCount; i++)
  782. {
  783. FbxCluster* cluster = skin->GetCluster(i);
  784. FbxNode* link = cluster->GetLink();
  785. // The bone node doesn't exist, skip it
  786. auto iterFind = scene.nodeMap.find(link);
  787. if (iterFind == scene.nodeMap.end())
  788. continue;
  789. mesh.bones.push_back(FBXBone());
  790. FBXBone& bone = mesh.bones.back();
  791. bone.node = iterFind->second;
  792. FbxAMatrix clusterTransform;
  793. cluster->GetTransformMatrix(clusterTransform);
  794. FbxAMatrix linkTransform;
  795. cluster->GetTransformLinkMatrix(linkTransform);
  796. FbxAMatrix bindPose = linkTransform.Inverse() * clusterTransform;
  797. bone.bindPose = FBXToNativeType(bindPose);
  798. bool isDuplicate = existingBones.insert(link).second;
  799. bool isAdditive = cluster->GetLinkMode() == FbxCluster::eAdditive;
  800. // We avoid importing weights twice for duplicate bones and we don't
  801. // support additive link mode.
  802. bool importWeights = !isDuplicate && !isAdditive;
  803. if (!importWeights)
  804. continue;
  805. double* weights = cluster->GetControlPointWeights();
  806. INT32* indices = cluster->GetControlPointIndices();
  807. UINT32 numIndices = (UINT32)cluster->GetControlPointIndicesCount();
  808. INT32 numVertices = (INT32)influences.size();
  809. // Add new weights while keeping them in order and removing the smallest ones
  810. // if number of influences exceeds the set maximum value
  811. for (UINT32 j = 0; j < numIndices; j++)
  812. {
  813. INT32 vertexIndex = indices[j];
  814. float weight = (float)weights[j];
  815. for (UINT32 k = 0; k < FBX_IMPORT_MAX_BONE_INFLUENCES; k++)
  816. {
  817. if (vertexIndex < 0 || vertexIndex >= numVertices)
  818. continue;
  819. if (weight >= influences[vertexIndex].weights[k])
  820. {
  821. for (UINT32 l = FBX_IMPORT_MAX_BONE_INFLUENCES - 2; l >= k; l--)
  822. {
  823. influences[vertexIndex].weights[l + 1] = influences[vertexIndex].weights[l];
  824. influences[vertexIndex].indices[l + 1] = influences[vertexIndex].indices[l];
  825. }
  826. influences[vertexIndex].weights[k] = weight;
  827. influences[vertexIndex].indices[k] = i;
  828. break;
  829. }
  830. }
  831. }
  832. }
  833. if (mesh.bones.empty())
  834. mesh.boneInfluences.clear();
  835. // Normalize weights
  836. UINT32 numInfluences = (UINT32)mesh.boneInfluences.size();
  837. for (UINT32 i = 0; i < numInfluences; i++)
  838. {
  839. float sum = 0.0f;
  840. for (UINT32 j = 0; j < FBX_IMPORT_MAX_BONE_INFLUENCES; j++)
  841. sum += influences[i].weights[j];
  842. float invSum = 1.0f / sum;
  843. for (UINT32 j = 0; j < FBX_IMPORT_MAX_BONE_INFLUENCES; j++)
  844. influences[i].weights[j] *= invSum;
  845. }
  846. }
  847. }