FBXSceneEncoder.cpp 46 KB

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