FBXSceneEncoder.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  1. #ifdef USE_FBX
  2. #include <algorithm>
  3. #include <string>
  4. #include "FBXSceneEncoder.h"
  5. #include "EncoderArguments.h"
  6. using namespace gameplay;
  7. /**
  8. * Returns the aspect ratio from the given camera.
  9. *
  10. * @param fbxCamera The FBX camera to get the aspect ratio from.
  11. *
  12. * @return The aspect ratio from the camera.
  13. */
  14. static float getAspectRatio(KFbxCamera* fbxCamera);
  15. /**
  16. * Returns the field of view Y from the given camera.
  17. *
  18. * @param fbxCamera The camera to get the fiew of view from.
  19. *
  20. * @return The field of view Y.
  21. */
  22. static float getFieldOfView(KFbxCamera* fbxCamera);
  23. /**
  24. * Loads the texture coordinates from given mesh's polygon part into the vertex.
  25. *
  26. * @param fbxMesh The mesh to get the polygon from.
  27. * @param polyIndex The index of the polygon.
  28. * @param posInPoly The position in the polygon.
  29. * @param vertex The vertex to copy the texture coordinates to.
  30. */
  31. static void loadTextureCoords(KFbxMesh* fbxMesh, int polyIndex, int posInPoly, Vertex* vertex);
  32. /**
  33. * Loads the normal from the mesh and adds it to the given vertex.
  34. *
  35. * @param fbxMesh The mesh to get the polygon from.
  36. * @param vertexIndex The vertex index in the mesh.
  37. * @param vertex The vertex to copy to.
  38. */
  39. static void loadNormal(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
  40. /**
  41. * Loads the tangent from the mesh and adds it to the given vertex.
  42. *
  43. * @param fbxMesh The mesh to load from.
  44. * @param vertexIndex The index of the vertex within fbxMesh.
  45. * @param vertex The vertex to copy to.
  46. */
  47. static void loadTangent(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
  48. /**
  49. * Loads the binormal from the mesh and adds it to the given vertex.
  50. *
  51. * @param fbxMesh The mesh to load from.
  52. * @param vertexIndex The index of the vertex within fbxMesh.
  53. * @param vertex The vertex to copy to.
  54. */
  55. static void loadBinormal(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
  56. /**
  57. * Loads the vertex diffuse color from the mesh and adds it to the given vertex.
  58. *
  59. * @param fbxMesh The mesh to load from.
  60. * @param vertexIndex The index of the vertex within fbxMesh.
  61. * @param vertex The vertex to copy to.
  62. */
  63. static void loadVertexColor(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
  64. /**
  65. * Loads the blend weight and blend indices data into the vertex.
  66. *
  67. * @param vertexWeights List of vertex weights. The x member contains the blendIndices. The y member contains the blendWeights.
  68. * @param vertex The vertex to copy the blend data to.
  69. */
  70. static void loadBlendData(const std::vector<Vector2>& vertexWeights, Vertex* vertex);
  71. /**
  72. * Loads the blend weights and blend indices from the given mesh.
  73. *
  74. * Each element of weights is a list of Vector2s where "x" is the blend index and "y" is the blend weight.
  75. *
  76. * @param fbxMesh The mesh to load from.
  77. * @param weights List of blend weights and blend indices for each vertex.
  78. *
  79. * @return True if this mesh has a mesh skin, false otherwise.
  80. */
  81. static bool loadBlendWeights(KFbxMesh* fbxMesh, std::vector<std::vector<Vector2> >& weights);
  82. /**
  83. * Copies from an FBX matrix to a float[16] array.
  84. */
  85. static void copyMatrix(const KFbxMatrix& fbxMatrix, float* matrix);
  86. /**
  87. * Copies from an FBX matrix to a gameplay matrix.
  88. */
  89. static void copyMatrix(const KFbxMatrix& fbxMatrix, Matrix& matrix);
  90. /**
  91. * Finds the min and max start time and stop time of the given animation curve.
  92. *
  93. * startTime is updated if the animation curve contains a start time that is less than startTime.
  94. * stopTime is updated if the animation curve contains a stop time that is greater than stopTime.
  95. * frameRate is updated if the animation curve contains a frame rate that is greater than frameRate.
  96. *
  97. * @param animCurve The animation curve to read from.
  98. * @param startTime The min start time. (in/out)
  99. * @param stopTime The max stop time. (in/out)
  100. * @param frameRate The frame rate. (in/out)
  101. */
  102. static void findMinMaxTime(KFbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate);
  103. /**
  104. * Appends a key frame of the given node's transform at the given time.
  105. *
  106. * @param fbxNode The node to get the matrix transform from.
  107. * @param time The key time to add and the time to get the transform from.
  108. * @param keyTimes The list of key times to append to.
  109. * @param keyValues The list of key values to append to.
  110. */
  111. static void appendKeyFrame(KFbxNode* fbxNode, float time, std::vector<float>* keyTimes, std::vector<float>* keyValues);
  112. /**
  113. * Decomposes the given node's matrix transform at the given time and copies to scale, rotation and translation.
  114. *
  115. * @param fbxNode The node to get the matrix transform from.
  116. * @param time The time to get the matrix transform from.
  117. * @param scale The scale to copy to.
  118. * @param rotation The rotation to copy to.
  119. * @param translation The translation to copy to.
  120. */
  121. static void decompose(KFbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation);
  122. /**
  123. * Creates an animation channel that targets the given node and target attribute using the given key times and key values.
  124. *
  125. * @param fbxNode The node to target.
  126. * @param targetAttrib The attribute type to target.
  127. * @param keyTimes The key times for the animation channel.
  128. * @param keyValues The key values for the animation channel.
  129. *
  130. * @return The newly created animation channel.
  131. */
  132. static AnimationChannel* createAnimationChannel(KFbxNode* fbxNode, unsigned int targetAttrib, const std::vector<float>& keyTimes, const std::vector<float>& keyValues);
  133. void addScaleChannel(Animation* animation, KFbxNode* fbxNode, float startTime, float stopTime);
  134. void addTranslateChannel(Animation* animation, KFbxNode* fbxNode, float startTime, float stopTime);
  135. ////////////////////////////////////
  136. // Member Functions
  137. ////////////////////////////////////
  138. FBXSceneEncoder::FBXSceneEncoder()
  139. : _groupAnimation(NULL)
  140. {
  141. }
  142. FBXSceneEncoder::~FBXSceneEncoder()
  143. {
  144. }
  145. void FBXSceneEncoder::write(const std::string& filepath, const EncoderArguments& arguments)
  146. {
  147. KFbxSdkManager* sdkManager = KFbxSdkManager::Create();
  148. KFbxIOSettings *ios = KFbxIOSettings::Create(sdkManager, IOSROOT);
  149. sdkManager->SetIOSettings(ios);
  150. KFbxImporter* importer = KFbxImporter::Create(sdkManager,"");
  151. if (!importer->Initialize(filepath.c_str(), -1, sdkManager->GetIOSettings()))
  152. {
  153. printf("Call to KFbxImporter::Initialize() failed.\n");
  154. printf("Error returned: %s\n\n", importer->GetLastErrorString());
  155. exit(-1);
  156. }
  157. KFbxScene* fbxScene = KFbxScene::Create(sdkManager,"__FBX_SCENE__");
  158. print("Loading FBX file.");
  159. importer->Import(fbxScene);
  160. importer->Destroy();
  161. print("Loading Scene.");
  162. loadScene(fbxScene);
  163. print("Loading animations.");
  164. loadAnimations(fbxScene, arguments);
  165. sdkManager->Destroy();
  166. print("Optimizing GamePlay Binary.");
  167. _gamePlayFile.adjust();
  168. std::string filenameOnly = getFilenameFromFilePath(filepath);
  169. std::string dstFilename = filepath.substr(0, filepath.find_last_of('/'));
  170. dstFilename.append(1, '/');
  171. dstFilename.append(getFilenameNoExt(filenameOnly));
  172. if (arguments.textOutputEnabled())
  173. {
  174. std::string outFile = dstFilename + ".xml";
  175. fprintf(stderr, "Saving debug file: %s\n", outFile.c_str());
  176. _gamePlayFile.saveText(outFile);
  177. }
  178. else
  179. {
  180. std::string outFile = dstFilename + ".gpb";
  181. fprintf(stderr, "Saving binary file: %s\n", outFile.c_str());
  182. _gamePlayFile.saveBinary(outFile);
  183. }
  184. }
  185. void FBXSceneEncoder::loadScene(KFbxScene* fbxScene)
  186. {
  187. Scene* scene = new Scene();
  188. scene->setId(fbxScene->GetName());
  189. if (scene->getId().length() == 0)
  190. {
  191. scene->setId("__SCENE__");
  192. }
  193. // Load all of the nodes and their contents.
  194. KFbxNode* rootNode = fbxScene->GetRootNode();
  195. if (rootNode)
  196. {
  197. print("Triangulate.");
  198. triangulateRecursive(rootNode);
  199. print("Load nodes.");
  200. // Don't include the FBX root node in the GPB.
  201. const int childCount = rootNode->GetChildCount();
  202. for (int i = 0; i < childCount; ++i)
  203. {
  204. Node* node = loadNode(rootNode->GetChild(i));
  205. if (node)
  206. {
  207. scene->add(node);
  208. }
  209. }
  210. }
  211. // Load the MeshSkin information from the scene's poses.
  212. loadBindShapes(fbxScene);
  213. // Find the ambient light of the scene
  214. KFbxColor ambientColor = fbxScene->GetGlobalSettings().GetAmbientColor();
  215. scene->setAmbientColor((float)ambientColor.mRed, (float)ambientColor.mGreen, (float)ambientColor.mBlue);
  216. // Assign the first camera node (if there is one) in the scene as the active camera
  217. // This ensures that if there's a camera in the scene that it is assigned as the
  218. // active camera.
  219. // TODO: add logic to find the "active" camera node in the fbxScene
  220. scene->setActiveCameraNode(scene->getFirstCameraNode());
  221. _gamePlayFile.addScene(scene);
  222. }
  223. void FBXSceneEncoder::loadAnimationChannels(KFbxAnimLayer* animLayer, KFbxNode* fbxNode, Animation* animation)
  224. {
  225. const std::string* targetId = NULL;
  226. const char* name = fbxNode->GetName();
  227. Node* node = _gamePlayFile.getNode(name);
  228. if (node)
  229. {
  230. targetId = &node->getId();
  231. }
  232. // Determine which properties are animated on this node
  233. // Find the transform at each key frame
  234. // TODO: Ignore properties that are not animated (scale, rotation, translation)
  235. // This should result in only one animation channel per animated node.
  236. float startTime = FLT_MAX, stopTime = -1.0f, frameRate = -FLT_MAX;
  237. bool tx = false, ty = false, tz = false, rx = false, ry = false, rz = false, sx = false, sy = false, sz = false;
  238. KFbxAnimCurve* animCurve = NULL;
  239. animCurve = fbxNode->LclTranslation.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_T_X);
  240. if (animCurve)
  241. {
  242. tx = true;
  243. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  244. }
  245. animCurve = fbxNode->LclTranslation.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_T_Y);
  246. if (animCurve)
  247. {
  248. ty = true;
  249. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  250. }
  251. animCurve = fbxNode->LclTranslation.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_T_Z);
  252. if (animCurve)
  253. {
  254. tz = true;
  255. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  256. }
  257. animCurve = fbxNode->LclRotation.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_R_X);
  258. if (animCurve)
  259. {
  260. rx = true;
  261. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  262. }
  263. animCurve = fbxNode->LclRotation.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_R_Y);
  264. if (animCurve)
  265. {
  266. ry = true;
  267. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  268. }
  269. animCurve = fbxNode->LclRotation.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_R_Z);
  270. if (animCurve)
  271. {
  272. rz = true;
  273. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  274. }
  275. animCurve = fbxNode->LclScaling.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_S_X);
  276. if (animCurve)
  277. {
  278. sx = true;
  279. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  280. }
  281. animCurve = fbxNode->LclScaling.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_S_Y);
  282. if (animCurve)
  283. {
  284. sy = true;
  285. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  286. }
  287. animCurve = fbxNode->LclScaling.GetCurve<KFbxAnimCurve>(animLayer, KFCURVENODE_S_Z);
  288. if (animCurve)
  289. {
  290. sz = true;
  291. findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
  292. }
  293. bool translate = tx | ty | tz;
  294. bool scale = sx | sy | sz;
  295. bool rotate = rx | ry | rz;
  296. if (translate || rotate || scale)
  297. {
  298. assert(startTime != FLT_MAX);
  299. assert(stopTime >= 0.0f);
  300. AnimationChannel* channel = new AnimationChannel();
  301. channel->setTargetId(name);
  302. channel->setTargetAttribute(Transform::ANIMATE_SCALE_ROTATE_TRANSLATE);
  303. float increment = 1000.0f / frameRate;
  304. std::vector<float> keyTimes;
  305. std::vector<float> keyValues;
  306. for (float time = startTime; time < stopTime; time += increment)
  307. {
  308. appendKeyFrame(fbxNode, time, &keyTimes, &keyValues);
  309. }
  310. // Add the last key frame at exactly stopTime
  311. appendKeyFrame(fbxNode, stopTime, &keyTimes, &keyValues);
  312. channel->setKeyTimes(keyTimes);
  313. /*
  314. std::vector<float> newKeyValues;
  315. for (size_t i = 0, size = keyValues.size(); i < size; i += 10)
  316. {
  317. if (translate)
  318. {
  319. newKeyValues.push_back(keyValues[i+0]);
  320. newKeyValues.push_back(keyValues[i+1]);
  321. newKeyValues.push_back(keyValues[i+2]);
  322. }
  323. if (rotate)
  324. {
  325. newKeyValues.push_back(keyValues[i+3]);
  326. newKeyValues.push_back(keyValues[i+4]);
  327. newKeyValues.push_back(keyValues[i+5]);
  328. newKeyValues.push_back(keyValues[i+6]);
  329. }
  330. if (scale)
  331. {
  332. newKeyValues.push_back(keyValues[i+7]);
  333. newKeyValues.push_back(keyValues[i+8]);
  334. newKeyValues.push_back(keyValues[i+9]);
  335. }
  336. }
  337. channel->setKeyValues(newKeyValues);
  338. */
  339. channel->setKeyValues(keyValues);
  340. channel->setInterpolation(AnimationChannel::LINEAR);
  341. animation->add(channel);
  342. /*
  343. if (!translate)
  344. {
  345. addTranslateChannel(animation, fbxNode, startTime, stopTime);
  346. }
  347. if (!rotate)
  348. {
  349. printf("rotate?\n"); // TODO
  350. }
  351. if (!scale)
  352. {
  353. addScaleChannel(animation, fbxNode, startTime, stopTime);
  354. }
  355. */
  356. if (_groupAnimation != animation)
  357. {
  358. // TODO explains
  359. _gamePlayFile.addAnimation(animation);
  360. }
  361. }
  362. }
  363. void FBXSceneEncoder::loadAnimationLayer(KFbxAnimLayer* fbxAnimLayer, KFbxNode* fbxNode, const EncoderArguments& arguments)
  364. {
  365. bool animationGroupId = false;
  366. const char* name = fbxNode->GetName();
  367. // Check if this node's animations are supposed to be grouped
  368. if (name)
  369. {
  370. std::string str = name;
  371. if (arguments.containsGroupNodeId(str))
  372. {
  373. animationGroupId = true;
  374. _groupAnimation = new Animation();
  375. _groupAnimation->setId(arguments.getAnimationId(str));
  376. }
  377. }
  378. Animation* animation = _groupAnimation;
  379. if (!_groupAnimation)
  380. {
  381. animation = new Animation();
  382. animation->setId(name);
  383. }
  384. loadAnimationChannels(fbxAnimLayer, fbxNode, animation);
  385. const int childCount = fbxNode->GetChildCount();
  386. for (int modelCount = 0; modelCount < childCount; ++modelCount)
  387. {
  388. loadAnimationLayer(fbxAnimLayer, fbxNode->GetChild(modelCount), arguments);
  389. }
  390. if (animationGroupId)
  391. {
  392. _gamePlayFile.addAnimation(_groupAnimation);
  393. _groupAnimation = NULL;
  394. }
  395. }
  396. void FBXSceneEncoder::loadAnimations(KFbxScene* fbxScene, const EncoderArguments& arguments)
  397. {
  398. KFbxAnimEvaluator* evaluator = fbxScene->GetEvaluator();
  399. if (!evaluator)
  400. return;
  401. KFbxAnimStack* animStack = evaluator->GetContext();
  402. if (!animStack)
  403. return;
  404. for (int i = 0; i < fbxScene->GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i)
  405. {
  406. KFbxAnimStack* animStack = KFbxCast<KFbxAnimStack>(fbxScene->GetSrcObject(FBX_TYPE(KFbxAnimStack), i));
  407. int nbAnimLayers = animStack->GetMemberCount(FBX_TYPE(KFbxAnimLayer));
  408. for (int l = 0; l < nbAnimLayers; ++l)
  409. {
  410. KFbxAnimLayer* animLayer = animStack->GetMember(FBX_TYPE(KFbxAnimLayer), l);
  411. loadAnimationLayer(animLayer, fbxScene->GetRootNode(), arguments);
  412. }
  413. }
  414. }
  415. Node* FBXSceneEncoder::loadNode(KFbxNode* fbxNode)
  416. {
  417. Node* node = NULL;
  418. // Check if this node has already been loaded
  419. const char* id = fbxNode->GetName();
  420. if (id && strlen(id) > 0)
  421. {
  422. node = _gamePlayFile.getNode(fbxNode->GetName());
  423. if (node)
  424. {
  425. return node;
  426. }
  427. }
  428. node = new Node();
  429. if (id)
  430. {
  431. node->setId(id);
  432. }
  433. _gamePlayFile.addNode(node);
  434. transformNode(fbxNode, node);
  435. loadCamera(fbxNode, node);
  436. loadLight(fbxNode, node);
  437. loadModel(fbxNode, node);
  438. if (fbxNode->GetSkeleton())
  439. {
  440. // Indicate that this is a joint node for the purpose of debugging.
  441. // The XML debug output will print that this node is a joint.
  442. node->setIsJoint(true);
  443. }
  444. // Load child nodes
  445. const int childCount = fbxNode->GetChildCount();
  446. for (int i = 0; i < childCount; ++i)
  447. {
  448. Node* child = loadNode(fbxNode->GetChild(i));
  449. if (child)
  450. {
  451. node->addChild(child);
  452. }
  453. }
  454. return node;
  455. }
  456. Mesh* FBXSceneEncoder::getMesh(size_t meshId)
  457. {
  458. // Check if this mesh was already loaded.
  459. std::map<size_t, Mesh*>::iterator it = _meshes.find(meshId);
  460. if (it != _meshes.end())
  461. {
  462. return it->second;
  463. }
  464. return NULL;
  465. }
  466. void FBXSceneEncoder::saveMesh(size_t meshId, Mesh* mesh)
  467. {
  468. assert(mesh);
  469. if (!getMesh(meshId))
  470. {
  471. _meshes[meshId] = mesh;
  472. }
  473. }
  474. void FBXSceneEncoder::print(const char* str)
  475. {
  476. fprintf(stderr,"%s\n", str);
  477. }
  478. void FBXSceneEncoder::transformNode(KFbxNode* fbxNode, Node* node)
  479. {
  480. KFbxXMatrix matrix;
  481. if (fbxNode->GetCamera() || fbxNode->GetLight())
  482. {
  483. // TODO: Why is this necessary for Camera and Light?
  484. matrix.SetTRS(fbxNode->LclTranslation.Get(), fbxNode->LclRotation.Get(), fbxNode->LclScaling.Get());
  485. }
  486. else
  487. {
  488. matrix = fbxNode->EvaluateLocalTransform();
  489. }
  490. float m[16];
  491. copyMatrix(matrix, m);
  492. int i = 0;
  493. for (int row = 0; row < 4; ++row)
  494. {
  495. for (int col = 0; col < 4; ++col)
  496. {
  497. m[i++] = (float)matrix.Get(row, col);
  498. }
  499. }
  500. node->setTransformMatrix(m);
  501. }
  502. void FBXSceneEncoder::loadBindShapes(KFbxScene* fbxScene)
  503. {
  504. float m[16];
  505. const int poseCount = fbxScene->GetPoseCount();
  506. for (int i = 0; i < poseCount; ++i)
  507. {
  508. KFbxPose* pose = fbxScene->GetPose(i);
  509. assert(pose);
  510. if (pose->IsBindPose() && pose->GetCount() > 0)
  511. {
  512. KFbxNode* fbxNode = pose->GetNode(0);
  513. if (fbxNode->GetMesh() != NULL)
  514. {
  515. Node* node = _gamePlayFile.getNode(fbxNode->GetName());
  516. assert(node && node->getModel());
  517. Model* model = node->getModel();
  518. if (model && model->getSkin())
  519. {
  520. MeshSkin* skin = model->getSkin();
  521. copyMatrix(pose->GetMatrix(0), m);
  522. skin->setBindShape(m);
  523. }
  524. }
  525. }
  526. }
  527. }
  528. void FBXSceneEncoder::loadCamera(KFbxNode* fbxNode, Node* node)
  529. {
  530. KFbxCamera* fbxCamera = fbxNode->GetCamera();
  531. if (!fbxCamera)
  532. {
  533. return;
  534. }
  535. Camera* camera = new Camera();
  536. const char* name = fbxNode->GetName();
  537. if (name)
  538. {
  539. std::string id(name);
  540. id.append("_Camera");
  541. camera->setId(id);
  542. }
  543. camera->setAspectRatio(getAspectRatio(fbxCamera));
  544. camera->setNearPlane((float)fbxCamera->NearPlane.Get());
  545. camera->setFarPlane((float)fbxCamera->FarPlane.Get());
  546. if (fbxCamera->ProjectionType.Get() == KFbxCamera::eORTHOGONAL)
  547. {
  548. camera->setOrthographic();
  549. camera->setViewportWidth((float)fbxCamera->GetApertureWidth());
  550. camera->setViewportWidth((float)fbxCamera->GetApertureHeight());
  551. // xmag in FBX can be calculated from: OrthoZoom * 30.0 / 2.0
  552. camera->setViewportWidth((float)fbxCamera->OrthoZoom.Get() * 15.0f);
  553. }
  554. else if (fbxCamera->ProjectionType.Get() == KFbxCamera::ePERSPECTIVE)
  555. {
  556. camera->setPerspective();
  557. camera->setFieldOfView(getFieldOfView(fbxCamera));
  558. }
  559. else
  560. {
  561. warning("Unknown camera type in node");
  562. return;
  563. }
  564. _gamePlayFile.addCamera(camera);
  565. node->setCamera(camera);
  566. }
  567. void FBXSceneEncoder::loadLight(KFbxNode* fbxNode, Node* node)
  568. {
  569. KFbxLight* fbxLight = fbxNode->GetLight();
  570. if (!fbxLight)
  571. {
  572. return;
  573. }
  574. Light* light = new Light();
  575. const char* name = fbxNode->GetName();
  576. if (name)
  577. {
  578. std::string id(name);
  579. id.append("_Light");
  580. light->setId(id);
  581. }
  582. fbxDouble3 color = fbxLight->Color.Get();
  583. light->setColor((float)color[0], (float)color[1], (float)color[2]);
  584. switch (fbxLight->LightType.Get())
  585. {
  586. case KFbxLight::ePOINT:
  587. {
  588. KFbxLight::EDecayType decayType = fbxLight->DecayType.Get();
  589. switch (decayType)
  590. {
  591. case KFbxLight::eNONE:
  592. // No decay. Can assume we have an ambient light, because ambient lights in the scene are
  593. // converted to point lights with no decay when exporting to FBX.
  594. light->setAmbientLight();
  595. break;
  596. case KFbxLight::eLINEAR:
  597. light->setPointLight();
  598. light->setLinearAttenuation((float)fbxLight->DecayStart.Get());
  599. break;
  600. case KFbxLight::eQUADRATIC:
  601. light->setPointLight();
  602. light->setQuadraticAttenuation((float)fbxLight->DecayStart.Get());
  603. break;
  604. case KFbxLight::eCUBIC:
  605. default:
  606. // Not supported..
  607. break;
  608. }
  609. break;
  610. }
  611. case KFbxLight::eDIRECTIONAL:
  612. {
  613. light->setDirectionalLight();
  614. break;
  615. }
  616. case KFbxLight::eSPOT:
  617. {
  618. light->setSpotLight();
  619. KFbxLight::EDecayType decayType = fbxLight->DecayType.Get();
  620. switch (decayType)
  621. {
  622. case KFbxLight::eNONE:
  623. // No decay.
  624. break;
  625. case KFbxLight::eLINEAR:
  626. light->setLinearAttenuation((float)fbxLight->DecayStart.Get());
  627. break;
  628. case KFbxLight::eQUADRATIC:
  629. light->setQuadraticAttenuation((float)fbxLight->DecayStart.Get());
  630. break;
  631. case KFbxLight::eCUBIC:
  632. // Not supported..
  633. break;
  634. }
  635. light->setFalloffAngle(MATH_DEG_TO_RAD((float)fbxLight->ConeAngle.Get())); // fall off angle
  636. break;
  637. }
  638. default:
  639. {
  640. warning("Unknown light type in node.");
  641. return;
  642. }
  643. }
  644. _gamePlayFile.addLight(light);
  645. node->setLight(light);
  646. }
  647. void FBXSceneEncoder::loadModel(KFbxNode* fbxNode, Node* node)
  648. {
  649. KFbxMesh* fbxMesh = fbxNode->GetMesh();
  650. if (!fbxMesh)
  651. {
  652. return;
  653. }
  654. if (fbxMesh->IsTriangleMesh())
  655. {
  656. Mesh* mesh = loadMesh(fbxMesh);
  657. Model* model = new Model();
  658. model->setMesh(mesh);
  659. node->setModel(model);
  660. loadSkin(fbxMesh, model);
  661. if (model->getSkin())
  662. {
  663. // TODO: explain
  664. node->resetTransformMatrix();
  665. }
  666. }
  667. }
  668. void FBXSceneEncoder::loadSkin(KFbxMesh* fbxMesh, Model* model)
  669. {
  670. const int deformerCount = fbxMesh->GetDeformerCount();
  671. for (int i = 0; i < deformerCount; ++i)
  672. {
  673. KFbxDeformer* deformer = fbxMesh->GetDeformer(i);
  674. if (deformer->GetDeformerType() == KFbxDeformer::eSKIN)
  675. {
  676. KFbxSkin* fbxSkin = static_cast<KFbxSkin*>(deformer);
  677. MeshSkin* skin = new MeshSkin();
  678. std::vector<std::string> jointNames;
  679. std::vector<Node*> joints;
  680. std::vector<Matrix> bindPoses;
  681. const int clusterCount = fbxSkin->GetClusterCount();
  682. for (int j = 0; j < clusterCount; ++j)
  683. {
  684. KFbxCluster* cluster = fbxSkin->GetCluster(j);
  685. assert(cluster);
  686. KFbxNode* linkedNode = cluster->GetLink();
  687. assert(linkedNode);
  688. if (linkedNode->GetSkeleton())
  689. {
  690. const char* jointName = linkedNode->GetName();
  691. assert(jointName);
  692. jointNames.push_back(jointName);
  693. Node* joint = loadNode(linkedNode);
  694. assert(joint);
  695. joints.push_back(joint);
  696. KFbxXMatrix matrix;
  697. cluster->GetTransformLinkMatrix(matrix);
  698. Matrix m;
  699. copyMatrix(matrix.Inverse(), m);
  700. bindPoses.push_back(m);
  701. }
  702. }
  703. skin->setJointNames(jointNames);
  704. skin->setJoints(joints);
  705. skin->setBindPoses(bindPoses);
  706. model->setSkin(skin);
  707. break;
  708. }
  709. }
  710. }
  711. Mesh* FBXSceneEncoder::loadMesh(KFbxMesh* fbxMesh)
  712. {
  713. // Check if this mesh has already been loaded.
  714. Mesh* mesh = getMesh(fbxMesh->GetUniqueID());
  715. if (mesh)
  716. {
  717. return mesh;
  718. }
  719. mesh = new Mesh();
  720. // GamePlay requires that a mesh have a unique ID but KFbxMesh doesn't have a string ID.
  721. const char* name = fbxMesh->GetNode()->GetName();
  722. if (name)
  723. {
  724. std::string id(name);
  725. id.append("_Mesh");
  726. mesh->setId(id);
  727. }
  728. // The number of mesh parts is equal to the number of materials that affect this mesh.
  729. // There is always at least one mesh part.
  730. std::vector<MeshPart*> meshParts;
  731. const int materialCount = fbxMesh->GetNode()->GetMaterialCount();
  732. int meshPartSize = (materialCount > 0) ? materialCount : 1;
  733. for (int i = 0; i < meshPartSize; ++i)
  734. {
  735. meshParts.push_back(new MeshPart());
  736. }
  737. // Find the blend weights and blend indices if this mesh is skinned.
  738. std::vector<std::vector<Vector2> > weights;
  739. bool hasSkin = loadBlendWeights(fbxMesh, weights);
  740. int vertexIndex = 0;
  741. KFbxVector4* controlPoints = fbxMesh->GetControlPoints();
  742. const int polygonCount = fbxMesh->GetPolygonCount();
  743. for (int polyIndex = 0; polyIndex < polygonCount; ++polyIndex)
  744. {
  745. const int polygonSize = fbxMesh->GetPolygonSize(polyIndex);
  746. for (int posInPoly = 0; posInPoly < polygonSize; ++posInPoly)
  747. {
  748. int controlPointIndex = fbxMesh->GetPolygonVertex(polyIndex, posInPoly);
  749. Vertex vertex;
  750. KFbxVector4& position = controlPoints[controlPointIndex];
  751. vertex.position.x = (float)position[0];
  752. vertex.position.y = (float)position[1];
  753. vertex.position.z = (float)position[2];
  754. loadTextureCoords(fbxMesh, polyIndex, posInPoly, &vertex);
  755. loadNormal(fbxMesh, vertexIndex, &vertex);
  756. loadTangent(fbxMesh, vertexIndex, &vertex);
  757. loadBinormal(fbxMesh, vertexIndex, &vertex);
  758. loadVertexColor(fbxMesh, vertexIndex, &vertex);
  759. if (hasSkin)
  760. {
  761. loadBlendData(weights[controlPointIndex], &vertex);
  762. }
  763. // Determine which mesh part this vertex index should be added to based on the material that affects it.
  764. int meshPartIndex = 0;
  765. const int elementMatrialCount = fbxMesh->GetElementMaterialCount();
  766. for (int k = 0; k < elementMatrialCount; ++k)
  767. {
  768. KFbxGeometryElementMaterial* elementMaterial = fbxMesh->GetElementMaterial(k);
  769. meshPartIndex = elementMaterial->GetIndexArray().GetAt(polyIndex);
  770. }
  771. // Add the vertex to the mesh if it hasn't already been added and find the vertex index.
  772. unsigned int index;
  773. if (mesh->contains(vertex))
  774. {
  775. index = mesh->getVertexIndex(vertex);
  776. }
  777. else
  778. {
  779. index = mesh->addVertex(vertex);
  780. }
  781. meshParts[meshPartIndex]->addIndex(index);
  782. vertexIndex++;
  783. }
  784. }
  785. const size_t meshpartsSize = meshParts.size();
  786. for (size_t i = 0; i < meshpartsSize; ++i)
  787. {
  788. mesh->addMeshPart(meshParts[i]);
  789. }
  790. // The order that the vertex elements are add to the list matters.
  791. // It should be the same order as how the Vertex data is written.
  792. // Position
  793. mesh->addVetexAttribute(POSITION, Vertex::POSITION_COUNT);
  794. const Vertex& vertex = mesh->vertices[0];
  795. // Normals
  796. if (vertex.hasNormal)
  797. {
  798. mesh->addVetexAttribute(NORMAL, Vertex::NORMAL_COUNT);
  799. }
  800. // Tangents
  801. if (vertex.hasTangent)
  802. {
  803. mesh->addVetexAttribute(TANGENT, Vertex::TANGENT_COUNT);
  804. }
  805. // Binormals
  806. if (vertex.hasBinormal)
  807. {
  808. mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
  809. }
  810. // Texture Coordinates
  811. if (vertex.hasTexCoord)
  812. {
  813. mesh->addVetexAttribute(TEXCOORD0, Vertex::TEXCOORD_COUNT);
  814. }
  815. // Diffuse Color
  816. if (vertex.hasDiffuse)
  817. {
  818. mesh->addVetexAttribute(COLOR, Vertex::DIFFUSE_COUNT);
  819. }
  820. // Skinning BlendWeights BlendIndices
  821. if (vertex.hasWeights)
  822. {
  823. mesh->addVetexAttribute(BLENDWEIGHTS, Vertex::BLEND_WEIGHTS_COUNT);
  824. mesh->addVetexAttribute(BLENDINDICES, Vertex::BLEND_INDICES_COUNT);
  825. }
  826. _gamePlayFile.addMesh(mesh);
  827. saveMesh(fbxMesh->GetUniqueID(), mesh);
  828. return mesh;
  829. }
  830. void FBXSceneEncoder::triangulateRecursive(KFbxNode* fbxNode)
  831. {
  832. // Triangulate all NURBS, patch and mesh under this node recursively.
  833. KFbxNodeAttribute* nodeAttribute = fbxNode->GetNodeAttribute();
  834. if (nodeAttribute)
  835. {
  836. if (nodeAttribute->GetAttributeType() == KFbxNodeAttribute::eMESH ||
  837. nodeAttribute->GetAttributeType() == KFbxNodeAttribute::eNURB ||
  838. nodeAttribute->GetAttributeType() == KFbxNodeAttribute::eNURBS_SURFACE ||
  839. nodeAttribute->GetAttributeType() == KFbxNodeAttribute::ePATCH)
  840. {
  841. KFbxGeometryConverter converter(fbxNode->GetFbxSdkManager());
  842. converter.TriangulateInPlace(fbxNode);
  843. }
  844. }
  845. const int childCount = fbxNode->GetChildCount();
  846. for (int childIndex = 0; childIndex < childCount; ++childIndex)
  847. {
  848. triangulateRecursive(fbxNode->GetChild(childIndex));
  849. }
  850. }
  851. void FBXSceneEncoder::warning(const std::string& message)
  852. {
  853. printf("Warning: %s\n", message.c_str());
  854. }
  855. void FBXSceneEncoder::warning(const char* message)
  856. {
  857. printf("Warning: %s\n", message);
  858. }
  859. ////////////////////////////////////
  860. // Functions
  861. ////////////////////////////////////
  862. float getAspectRatio(KFbxCamera* fbxCamera)
  863. {
  864. return (float)fbxCamera->FilmAspectRatio.Get();
  865. /*
  866. KFbxCamera::ECameraAspectRatioMode camAspectRatioMode = fbxCamera->GetAspectRatioMode();
  867. double aspectX = fbxCamera->AspectWidth.Get();
  868. double aspectY = fbxCamera->AspectHeight.Get();
  869. double aspectRatio = 1.333333;
  870. switch ( camAspectRatioMode)
  871. {
  872. case KFbxCamera::eWINDOW_SIZE:
  873. aspectRatio = aspectX / aspectY;
  874. break;
  875. case KFbxCamera::eFIXED_RATIO:
  876. aspectRatio = aspectX;
  877. break;
  878. case KFbxCamera::eFIXED_RESOLUTION:
  879. aspectRatio = aspectX / aspectY * fbxCamera->GetPixelRatio();
  880. break;
  881. case KFbxCamera::eFIXED_WIDTH:
  882. aspectRatio = fbxCamera->GetPixelRatio() / aspectY;
  883. break;
  884. case KFbxCamera::eFIXED_HEIGHT:
  885. aspectRatio = fbxCamera->GetPixelRatio() * aspectX;
  886. break;
  887. default:
  888. break;
  889. }
  890. return (float)aspectRatio;
  891. */
  892. }
  893. inline double vfov(double hfov, double aspect)
  894. {
  895. static const double MATH_PI_180 = 0.01745329251994329576923690768489;
  896. static const double MATH_180_PI = 57.295779513082320876798154814105;
  897. return (2.0 * atan((aspect) * tan( (hfov * MATH_PI_180) * 0.5)) * MATH_180_PI);
  898. }
  899. float getFieldOfView(KFbxCamera* fbxCamera)
  900. {
  901. double fieldOfViewX = 0.0;
  902. double fieldOfViewY = 0.0;
  903. double filmHeight = fbxCamera->GetApertureHeight();
  904. double filmWidth = fbxCamera->GetApertureWidth() * fbxCamera->GetSqueezeRatio();
  905. double apertureRatio = filmHeight / filmWidth;
  906. if ( fbxCamera->GetApertureMode() == KFbxCamera::eVERTICAL)
  907. {
  908. fieldOfViewY = fbxCamera->FieldOfView.Get();
  909. }
  910. else if (fbxCamera->GetApertureMode() == KFbxCamera::eHORIZONTAL)
  911. {
  912. fieldOfViewX = fbxCamera->FieldOfView.Get();
  913. fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
  914. }
  915. else if (fbxCamera->GetApertureMode() == KFbxCamera::eFOCAL_LENGTH)
  916. {
  917. fieldOfViewX = fbxCamera->ComputeFieldOfView(fbxCamera->FocalLength.Get());
  918. fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
  919. }
  920. else if (fbxCamera->GetApertureMode() == KFbxCamera::eHORIZONTAL_AND_VERTICAL)
  921. {
  922. fieldOfViewY = fbxCamera->FieldOfViewY.Get();
  923. }
  924. else
  925. {
  926. fieldOfViewY = 45.0;
  927. }
  928. return (float)fieldOfViewY;
  929. }
  930. void loadTextureCoords(KFbxMesh* fbxMesh, int polyIndex, int posInPoly, Vertex* vertex)
  931. {
  932. assert(fbxMesh && polyIndex >=0 && posInPoly >= 0);
  933. if (fbxMesh->GetElementUVCount() > 0)
  934. {
  935. // Get only the first UV coordinates.
  936. KFbxGeometryElementUV* uv = fbxMesh->GetElementUV(0);
  937. switch (uv->GetMappingMode())
  938. {
  939. case KFbxGeometryElement::eBY_CONTROL_POINT:
  940. switch (uv->GetReferenceMode())
  941. {
  942. case KFbxGeometryElement::eDIRECT:
  943. vertex->hasTexCoord = true;
  944. vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(polyIndex)[0];
  945. vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(polyIndex)[1];
  946. break;
  947. case KFbxGeometryElement::eINDEX_TO_DIRECT:
  948. {
  949. int id = uv->GetIndexArray().GetAt(polyIndex);
  950. vertex->hasTexCoord = true;
  951. vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(id)[0];
  952. vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(id)[1];
  953. }
  954. break;
  955. default:
  956. break;
  957. }
  958. break;
  959. case KFbxGeometryElement::eBY_POLYGON_VERTEX:
  960. {
  961. int lTextureUVIndex = fbxMesh->GetTextureUVIndex(polyIndex, posInPoly);
  962. switch (uv->GetReferenceMode())
  963. {
  964. case KFbxGeometryElement::eDIRECT:
  965. case KFbxGeometryElement::eINDEX_TO_DIRECT:
  966. vertex->hasTexCoord = true;
  967. vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(lTextureUVIndex)[0];
  968. vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(lTextureUVIndex)[1];
  969. break;
  970. default:
  971. break;
  972. }
  973. }
  974. break;
  975. default:
  976. break;
  977. }
  978. }
  979. }
  980. void loadNormal(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
  981. {
  982. if (fbxMesh->GetElementNormalCount() > 0)
  983. {
  984. // Get only the first
  985. KFbxGeometryElementNormal* normal = fbxMesh->GetElementNormal(0);
  986. if (normal->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX)
  987. {
  988. switch (normal->GetReferenceMode())
  989. {
  990. case KFbxGeometryElement::eDIRECT:
  991. {
  992. KFbxVector4 vec4 = normal->GetDirectArray().GetAt(vertexIndex);
  993. vertex->hasNormal = true;
  994. vertex->normal.x = (float)vec4[0];
  995. vertex->normal.y = (float)vec4[1];
  996. vertex->normal.z = (float)vec4[2];
  997. }
  998. break;
  999. case KFbxGeometryElement::eINDEX_TO_DIRECT:
  1000. {
  1001. int id = normal->GetIndexArray().GetAt(vertexIndex);
  1002. KFbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
  1003. vertex->hasNormal = true;
  1004. vertex->normal.x = (float)vec4[0];
  1005. vertex->normal.y = (float)vec4[1];
  1006. vertex->normal.z = (float)vec4[2];
  1007. }
  1008. break;
  1009. default:
  1010. break;
  1011. }
  1012. }
  1013. }
  1014. }
  1015. void loadTangent(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
  1016. {
  1017. if (fbxMesh->GetElementTangentCount() > 0)
  1018. {
  1019. // Get only the first tangent
  1020. KFbxGeometryElementTangent* tangent = fbxMesh->GetElementTangent(0);
  1021. if (tangent->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX)
  1022. {
  1023. switch (tangent->GetReferenceMode())
  1024. {
  1025. case KFbxGeometryElement::eDIRECT:
  1026. {
  1027. KFbxVector4 vec4 = tangent->GetDirectArray().GetAt(vertexIndex);
  1028. vertex->hasTangent = true;
  1029. vertex->tangent.x = (float)vec4[0];
  1030. vertex->tangent.y = (float)vec4[1];
  1031. vertex->tangent.z = (float)vec4[2];
  1032. }
  1033. break;
  1034. case KFbxGeometryElement::eINDEX_TO_DIRECT:
  1035. {
  1036. int id = tangent->GetIndexArray().GetAt(vertexIndex);
  1037. KFbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
  1038. vertex->hasTangent = true;
  1039. vertex->tangent.x = (float)vec4[0];
  1040. vertex->tangent.y = (float)vec4[1];
  1041. vertex->tangent.z = (float)vec4[2];
  1042. }
  1043. break;
  1044. default:
  1045. break;
  1046. }
  1047. }
  1048. }
  1049. }
  1050. void loadBinormal(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
  1051. {
  1052. if (fbxMesh->GetElementBinormalCount() > 0)
  1053. {
  1054. // Get only the first binormal.
  1055. KFbxGeometryElementBinormal* binormal = fbxMesh->GetElementBinormal(0);
  1056. if (binormal->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX)
  1057. {
  1058. switch (binormal->GetReferenceMode())
  1059. {
  1060. case KFbxGeometryElement::eDIRECT:
  1061. {
  1062. KFbxVector4 vec4 = binormal->GetDirectArray().GetAt(vertexIndex);
  1063. vertex->hasBinormal = true;
  1064. vertex->binormal.x = (float)vec4[0];
  1065. vertex->binormal.y = (float)vec4[1];
  1066. vertex->binormal.z = (float)vec4[2];
  1067. }
  1068. break;
  1069. case KFbxGeometryElement::eINDEX_TO_DIRECT:
  1070. {
  1071. int id = binormal->GetIndexArray().GetAt(vertexIndex);
  1072. KFbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
  1073. vertex->hasBinormal = true;
  1074. vertex->binormal.x = (float)vec4[0];
  1075. vertex->binormal.y = (float)vec4[1];
  1076. vertex->binormal.z = (float)vec4[2];
  1077. }
  1078. break;
  1079. default:
  1080. break;
  1081. }
  1082. }
  1083. }
  1084. }
  1085. void loadVertexColor(KFbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
  1086. {
  1087. if (fbxMesh->GetElementVertexColorCount() > 0)
  1088. {
  1089. // Get only the first vertex color.
  1090. KFbxGeometryElementVertexColor* vertexColor = fbxMesh->GetElementVertexColor(0);
  1091. if (vertexColor->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX)
  1092. {
  1093. switch (vertexColor->GetReferenceMode())
  1094. {
  1095. case KFbxGeometryElement::eDIRECT:
  1096. {
  1097. KFbxColor color = vertexColor->GetDirectArray().GetAt(vertexIndex);
  1098. vertex->hasDiffuse = true;
  1099. vertex->diffuse.x = (float)color.mRed;
  1100. vertex->diffuse.y = (float)color.mGreen;
  1101. vertex->diffuse.z = (float)color.mBlue;
  1102. vertex->diffuse.w = (float)color.mAlpha;
  1103. }
  1104. break;
  1105. case KFbxGeometryElement::eINDEX_TO_DIRECT:
  1106. {
  1107. int id = vertexColor->GetIndexArray().GetAt(vertexIndex);
  1108. KFbxColor color = vertexColor->GetDirectArray().GetAt(id);
  1109. vertex->hasDiffuse = true;
  1110. vertex->diffuse.x = (float)color.mRed;
  1111. vertex->diffuse.y = (float)color.mGreen;
  1112. vertex->diffuse.z = (float)color.mBlue;
  1113. vertex->diffuse.w = (float)color.mAlpha;
  1114. }
  1115. break;
  1116. default:
  1117. break;
  1118. }
  1119. }
  1120. }
  1121. }
  1122. void loadBlendData(const std::vector<Vector2>& vertexWeights, Vertex* vertex)
  1123. {
  1124. size_t size = vertexWeights.size();
  1125. if (size >= 1)
  1126. {
  1127. vertex->hasWeights= true;
  1128. vertex->blendIndices.x = vertexWeights[0].x;
  1129. vertex->blendWeights.x = vertexWeights[0].y;
  1130. }
  1131. if (size >= 2)
  1132. {
  1133. vertex->blendIndices.y = vertexWeights[1].x;
  1134. vertex->blendWeights.y = vertexWeights[1].y;
  1135. }
  1136. if (size >= 3)
  1137. {
  1138. vertex->blendIndices.z = vertexWeights[2].x;
  1139. vertex->blendWeights.z = vertexWeights[2].y;
  1140. }
  1141. if (size >= 4)
  1142. {
  1143. vertex->blendIndices.w = vertexWeights[3].x;
  1144. vertex->blendWeights.w = vertexWeights[3].y;
  1145. }
  1146. //vertex->normalizeBlendWeight();
  1147. }
  1148. bool loadBlendWeights(KFbxMesh* fbxMesh, std::vector<std::vector<Vector2> >& weights)
  1149. {
  1150. assert(fbxMesh);
  1151. const int vertexCount = fbxMesh->GetControlPointsCount();
  1152. KFbxSkin* fbxSkin = NULL;
  1153. const int deformerCount = fbxMesh->GetDeformerCount();
  1154. for (int i = 0; i < deformerCount; ++i)
  1155. {
  1156. KFbxDeformer* deformer = fbxMesh->GetDeformer(i);
  1157. if (deformer->GetDeformerType() == KFbxDeformer::eSKIN)
  1158. {
  1159. fbxSkin = static_cast<KFbxSkin*>(deformer);
  1160. weights.resize(vertexCount);
  1161. const int clusterCount = fbxSkin->GetClusterCount();
  1162. for (int j = 0; j < clusterCount; ++j)
  1163. {
  1164. KFbxCluster* cluster = fbxSkin->GetCluster(j);
  1165. assert(cluster);
  1166. KFbxNode* linkedNode = cluster->GetLink();
  1167. assert(linkedNode);
  1168. const int vertexIndexCount = cluster->GetControlPointIndicesCount();
  1169. for (int k = 0; k < vertexIndexCount; ++k)
  1170. {
  1171. int index = cluster->GetControlPointIndices()[k];
  1172. if (index >= vertexCount)
  1173. {
  1174. continue;
  1175. }
  1176. double weight = cluster->GetControlPointWeights()[k];
  1177. if (weight == 0.0)
  1178. {
  1179. continue;
  1180. }
  1181. weights[index].push_back(Vector2((float)j, (float)weight));
  1182. }
  1183. }
  1184. // Only the first skin deformer will be loaded.
  1185. // There probably won't be more than one.
  1186. break;
  1187. }
  1188. }
  1189. return fbxSkin != NULL;
  1190. }
  1191. void findMinMaxTime(KFbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate)
  1192. {
  1193. KTime start, stop;
  1194. animCurve->GetTimeInterval(start, stop);
  1195. *startTime = std::min(*startTime, (float)start.GetMilliSeconds());
  1196. *stopTime = std::max(*stopTime, (float)stop.GetMilliSeconds());
  1197. *frameRate = std::max(*frameRate, (float)stop.GetFrameRate(KTime::eDEFAULT_MODE));
  1198. }
  1199. void appendKeyFrame(KFbxNode* fbxNode, float time, std::vector<float>* keyTimes, std::vector<float>* keyValues)
  1200. {
  1201. KFbxXMatrix fbxMatrix;
  1202. Matrix matrix;
  1203. KTime kTime;
  1204. kTime.SetMilliSeconds((kLongLong)time);
  1205. fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
  1206. copyMatrix(fbxMatrix, matrix);
  1207. Vector3 scale;
  1208. Quaternion rotation;
  1209. Vector3 translation;
  1210. matrix.decompose(&scale, &rotation, &translation);
  1211. rotation.normalize();
  1212. keyTimes->push_back(time);
  1213. keyValues->push_back(scale.x);
  1214. keyValues->push_back(scale.y);
  1215. keyValues->push_back(scale.z);
  1216. keyValues->push_back(rotation.x);
  1217. keyValues->push_back(rotation.y);
  1218. keyValues->push_back(rotation.z);
  1219. keyValues->push_back(rotation.w);
  1220. keyValues->push_back(translation.x);
  1221. keyValues->push_back(translation.y);
  1222. keyValues->push_back(translation.z);
  1223. }
  1224. void decompose(KFbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation)
  1225. {
  1226. KFbxXMatrix fbxMatrix;
  1227. Matrix matrix;
  1228. KTime kTime;
  1229. kTime.SetMilliSeconds((kLongLong)time);
  1230. fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
  1231. copyMatrix(fbxMatrix, matrix);
  1232. matrix.decompose(scale, rotation, translation);
  1233. }
  1234. AnimationChannel* createAnimationChannel(KFbxNode* fbxNode, unsigned int targetAttrib, const std::vector<float>& keyTimes, const std::vector<float>& keyValues)
  1235. {
  1236. AnimationChannel* channel = new AnimationChannel();
  1237. channel->setTargetId(fbxNode->GetName());
  1238. channel->setKeyTimes(keyTimes);
  1239. channel->setKeyValues(keyValues);
  1240. channel->setInterpolation(AnimationChannel::LINEAR);
  1241. channel->setTargetAttribute(targetAttrib);
  1242. return channel;
  1243. }
  1244. void addScaleChannel(Animation* animation, KFbxNode* fbxNode, float startTime, float stopTime)
  1245. {
  1246. std::vector<float> keyTimes;
  1247. std::vector<float> keyValues;
  1248. Vector3 scale;
  1249. Quaternion rotation;
  1250. Vector3 translation;
  1251. decompose(fbxNode, startTime, &scale, &rotation, &translation);
  1252. keyTimes.push_back(startTime);
  1253. keyValues.push_back(scale.x);
  1254. keyValues.push_back(scale.y);
  1255. keyValues.push_back(scale.z);
  1256. decompose(fbxNode, stopTime, &scale, &rotation, &translation);
  1257. keyTimes.push_back(stopTime);
  1258. keyValues.push_back(scale.x);
  1259. keyValues.push_back(scale.y);
  1260. keyValues.push_back(scale.z);
  1261. AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_SCALE, keyTimes, keyValues);
  1262. animation->add(channel);
  1263. }
  1264. void addTranslateChannel(Animation* animation, KFbxNode* fbxNode, float startTime, float stopTime)
  1265. {
  1266. std::vector<float> keyTimes;
  1267. std::vector<float> keyValues;
  1268. Vector3 scale;
  1269. Quaternion rotation;
  1270. Vector3 translation;
  1271. decompose(fbxNode, startTime, &scale, &rotation, &translation);
  1272. keyTimes.push_back(startTime);
  1273. keyValues.push_back(translation.x);
  1274. keyValues.push_back(translation.y);
  1275. keyValues.push_back(translation.z);
  1276. decompose(fbxNode, stopTime, &scale, &rotation, &translation);
  1277. keyTimes.push_back(stopTime);
  1278. keyValues.push_back(translation.x);
  1279. keyValues.push_back(translation.y);
  1280. keyValues.push_back(translation.z);
  1281. AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_TRANSLATE, keyTimes, keyValues);
  1282. animation->add(channel);
  1283. }
  1284. void copyMatrix(const KFbxMatrix& fbxMatrix, float* matrix)
  1285. {
  1286. int i = 0;
  1287. for (int row = 0; row < 4; ++row)
  1288. {
  1289. for (int col = 0; col < 4; ++col)
  1290. {
  1291. matrix[i++] = (float)fbxMatrix.Get(row, col);
  1292. }
  1293. }
  1294. }
  1295. void copyMatrix(const KFbxMatrix& fbxMatrix, Matrix& matrix)
  1296. {
  1297. int i = 0;
  1298. for (int row = 0; row < 4; ++row)
  1299. {
  1300. for (int col = 0; col < 4; ++col)
  1301. {
  1302. matrix.m[i++] = (float)fbxMatrix.Get(row, col);
  1303. }
  1304. }
  1305. }
  1306. #endif