FBXUtil.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. #include <algorithm>
  2. #include <string>
  3. #include <sstream>
  4. #include "FBXUtil.h"
  5. #include "Transform.h"
  6. #include "Vector3.h"
  7. #include "Vector2.h"
  8. using namespace gameplay;
  9. using std::string;
  10. using std::vector;
  11. using std::map;
  12. using std::ostringstream;
  13. float getAspectRatio(FbxCamera* fbxCamera)
  14. {
  15. return (float)fbxCamera->FilmAspectRatio.Get();
  16. /*
  17. FbxCamera::ECameraAspectRatioMode camAspectRatioMode = fbxCamera->GetAspectRatioMode();
  18. double aspectX = fbxCamera->AspectWidth.Get();
  19. double aspectY = fbxCamera->AspectHeight.Get();
  20. double aspectRatio = 1.333333;
  21. switch ( camAspectRatioMode)
  22. {
  23. case FbxCamera::eWINDOW_SIZE:
  24. aspectRatio = aspectX / aspectY;
  25. break;
  26. case FbxCamera::eFIXED_RATIO:
  27. aspectRatio = aspectX;
  28. break;
  29. case FbxCamera::eFIXED_RESOLUTION:
  30. aspectRatio = aspectX / aspectY * fbxCamera->GetPixelRatio();
  31. break;
  32. case FbxCamera::eFIXED_WIDTH:
  33. aspectRatio = fbxCamera->GetPixelRatio() / aspectY;
  34. break;
  35. case FbxCamera::eFIXED_HEIGHT:
  36. aspectRatio = fbxCamera->GetPixelRatio() * aspectX;
  37. break;
  38. default:
  39. break;
  40. }
  41. return (float)aspectRatio;
  42. */
  43. }
  44. inline double vfov(double hfov, double aspect)
  45. {
  46. static const double MATH_PI_180 = 0.01745329251994329576923690768489;
  47. static const double MATH_180_PI = 57.295779513082320876798154814105;
  48. return (2.0 * atan((aspect) * tan( (hfov * MATH_PI_180) * 0.5)) * MATH_180_PI);
  49. }
  50. float getFieldOfView(FbxCamera* fbxCamera)
  51. {
  52. double fieldOfViewX = 0.0;
  53. double fieldOfViewY = 0.0;
  54. double filmHeight = fbxCamera->GetApertureHeight();
  55. double filmWidth = fbxCamera->GetApertureWidth() * fbxCamera->GetSqueezeRatio();
  56. double apertureRatio = filmHeight / filmWidth;
  57. if ( fbxCamera->GetApertureMode() == FbxCamera::eVertical)
  58. {
  59. fieldOfViewY = fbxCamera->FieldOfView.Get();
  60. }
  61. else if (fbxCamera->GetApertureMode() == FbxCamera::eHorizontal)
  62. {
  63. fieldOfViewX = fbxCamera->FieldOfView.Get();
  64. fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
  65. }
  66. else if (fbxCamera->GetApertureMode() == FbxCamera::eFocalLength)
  67. {
  68. fieldOfViewX = fbxCamera->ComputeFieldOfView(fbxCamera->FocalLength.Get());
  69. fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
  70. }
  71. else if (fbxCamera->GetApertureMode() == FbxCamera::eHorizAndVert)
  72. {
  73. fieldOfViewY = fbxCamera->FieldOfViewY.Get();
  74. }
  75. else
  76. {
  77. fieldOfViewY = 45.0;
  78. }
  79. return (float)fieldOfViewY;
  80. }
  81. void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex)
  82. {
  83. assert(fbxMesh && polyIndex >= 0 && posInPoly >= 0);
  84. const bool useIndex = uvs->GetReferenceMode() != FbxGeometryElement::eDirect;
  85. const int indexCount = useIndex ? uvs->GetIndexArray().GetCount() : 0;
  86. int uvIndex = -1;
  87. switch (uvs->GetMappingMode())
  88. {
  89. case FbxGeometryElement::eByControlPoint:
  90. {
  91. // Get the index of the current vertex in control points array
  92. int polyVertIndex = fbxMesh->GetPolygonVertex(polyIndex, posInPoly);
  93. // The UV index depends on the reference mode
  94. uvIndex = useIndex ? uvs->GetIndexArray().GetAt(polyVertIndex) : polyVertIndex;
  95. }
  96. break;
  97. case FbxGeometryElement::eByPolygonVertex:
  98. if (meshVertexIndex < indexCount)
  99. {
  100. uvIndex = useIndex ? uvs->GetIndexArray().GetAt(meshVertexIndex) : meshVertexIndex;
  101. }
  102. break;
  103. default:
  104. // Only support eByPolygonVertex and eByControlPoint mappings
  105. break;
  106. }
  107. vertex->hasTexCoord[uvSetIndex] = true;
  108. // Store UV information in vertex
  109. if (uvIndex != -1)
  110. {
  111. FbxVector2 uvValue = uvs->GetDirectArray().GetAt(uvIndex);
  112. vertex->texCoord[uvSetIndex].x = (float)uvValue[0];
  113. vertex->texCoord[uvSetIndex].y = (float)uvValue[1];
  114. }
  115. }
  116. void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
  117. {
  118. if (fbxMesh->GetElementNormalCount() > 0)
  119. {
  120. // Get only the first
  121. FbxGeometryElementNormal* normal = fbxMesh->GetElementNormal(0);
  122. FbxGeometryElement::EMappingMode mappingMode = normal->GetMappingMode();
  123. if (mappingMode == FbxGeometryElement::eByControlPoint)
  124. {
  125. switch (normal->GetReferenceMode())
  126. {
  127. case FbxGeometryElement::eDirect:
  128. {
  129. FbxVector4 vec4 = normal->GetDirectArray().GetAt(controlPointIndex);
  130. vertex->hasNormal = true;
  131. vertex->normal.x = (float)vec4[0];
  132. vertex->normal.y = (float)vec4[1];
  133. vertex->normal.z = (float)vec4[2];
  134. }
  135. break;
  136. case FbxGeometryElement::eIndexToDirect:
  137. {
  138. int id = normal->GetIndexArray().GetAt(controlPointIndex);
  139. FbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
  140. vertex->hasNormal = true;
  141. vertex->normal.x = (float)vec4[0];
  142. vertex->normal.y = (float)vec4[1];
  143. vertex->normal.z = (float)vec4[2];
  144. }
  145. break;
  146. default:
  147. break;
  148. }
  149. }
  150. else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
  151. {
  152. switch (normal->GetReferenceMode())
  153. {
  154. case FbxGeometryElement::eDirect:
  155. {
  156. FbxVector4 vec4 = normal->GetDirectArray().GetAt(vertexIndex);
  157. vertex->hasNormal = true;
  158. vertex->normal.x = (float)vec4[0];
  159. vertex->normal.y = (float)vec4[1];
  160. vertex->normal.z = (float)vec4[2];
  161. }
  162. break;
  163. case FbxGeometryElement::eIndexToDirect:
  164. {
  165. int id = normal->GetIndexArray().GetAt(vertexIndex);
  166. FbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
  167. vertex->hasNormal = true;
  168. vertex->normal.x = (float)vec4[0];
  169. vertex->normal.y = (float)vec4[1];
  170. vertex->normal.z = (float)vec4[2];
  171. }
  172. break;
  173. default:
  174. break;
  175. }
  176. }
  177. }
  178. }
  179. void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
  180. {
  181. if (fbxMesh->GetElementTangentCount() > 0)
  182. {
  183. // Get only the first tangent
  184. FbxGeometryElementTangent* tangent = fbxMesh->GetElementTangent(0);
  185. FbxGeometryElement::EMappingMode mappingMode = tangent->GetMappingMode();
  186. if (mappingMode == FbxGeometryElement::eByControlPoint)
  187. {
  188. switch (tangent->GetReferenceMode())
  189. {
  190. case FbxGeometryElement::eDirect:
  191. {
  192. FbxVector4 vec4 = tangent->GetDirectArray().GetAt(controlPointIndex);
  193. vertex->hasTangent = true;
  194. vertex->tangent.x = (float)vec4[0];
  195. vertex->tangent.y = (float)vec4[1];
  196. vertex->tangent.z = (float)vec4[2];
  197. }
  198. break;
  199. case FbxGeometryElement::eIndexToDirect:
  200. {
  201. int id = tangent->GetIndexArray().GetAt(controlPointIndex);
  202. FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
  203. vertex->hasTangent = true;
  204. vertex->tangent.x = (float)vec4[0];
  205. vertex->tangent.y = (float)vec4[1];
  206. vertex->tangent.z = (float)vec4[2];
  207. }
  208. break;
  209. default:
  210. break;
  211. }
  212. }
  213. else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
  214. {
  215. switch (tangent->GetReferenceMode())
  216. {
  217. case FbxGeometryElement::eDirect:
  218. {
  219. FbxVector4 vec4 = tangent->GetDirectArray().GetAt(vertexIndex);
  220. vertex->hasTangent = true;
  221. vertex->tangent.x = (float)vec4[0];
  222. vertex->tangent.y = (float)vec4[1];
  223. vertex->tangent.z = (float)vec4[2];
  224. }
  225. break;
  226. case FbxGeometryElement::eIndexToDirect:
  227. {
  228. int id = tangent->GetIndexArray().GetAt(vertexIndex);
  229. FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
  230. vertex->hasTangent = true;
  231. vertex->tangent.x = (float)vec4[0];
  232. vertex->tangent.y = (float)vec4[1];
  233. vertex->tangent.z = (float)vec4[2];
  234. }
  235. break;
  236. default:
  237. break;
  238. }
  239. }
  240. }
  241. }
  242. void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
  243. {
  244. if (fbxMesh->GetElementBinormalCount() > 0)
  245. {
  246. // Get only the first binormal.
  247. FbxGeometryElementBinormal* binormal = fbxMesh->GetElementBinormal(0);
  248. FbxGeometryElement::EMappingMode mappingMode = binormal->GetMappingMode();
  249. if (mappingMode == FbxGeometryElement::eByControlPoint)
  250. {
  251. switch (binormal->GetReferenceMode())
  252. {
  253. case FbxGeometryElement::eDirect:
  254. {
  255. FbxVector4 vec4 = binormal->GetDirectArray().GetAt(controlPointIndex);
  256. vertex->hasBinormal = true;
  257. vertex->binormal.x = (float)vec4[0];
  258. vertex->binormal.y = (float)vec4[1];
  259. vertex->binormal.z = (float)vec4[2];
  260. }
  261. break;
  262. case FbxGeometryElement::eIndexToDirect:
  263. {
  264. int id = binormal->GetIndexArray().GetAt(controlPointIndex);
  265. FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
  266. vertex->hasBinormal = true;
  267. vertex->binormal.x = (float)vec4[0];
  268. vertex->binormal.y = (float)vec4[1];
  269. vertex->binormal.z = (float)vec4[2];
  270. }
  271. break;
  272. default:
  273. break;
  274. }
  275. }
  276. else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
  277. {
  278. switch (binormal->GetReferenceMode())
  279. {
  280. case FbxGeometryElement::eDirect:
  281. {
  282. FbxVector4 vec4 = binormal->GetDirectArray().GetAt(vertexIndex);
  283. vertex->hasBinormal = true;
  284. vertex->binormal.x = (float)vec4[0];
  285. vertex->binormal.y = (float)vec4[1];
  286. vertex->binormal.z = (float)vec4[2];
  287. }
  288. break;
  289. case FbxGeometryElement::eIndexToDirect:
  290. {
  291. int id = binormal->GetIndexArray().GetAt(vertexIndex);
  292. FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
  293. vertex->hasBinormal = true;
  294. vertex->binormal.x = (float)vec4[0];
  295. vertex->binormal.y = (float)vec4[1];
  296. vertex->binormal.z = (float)vec4[2];
  297. }
  298. break;
  299. default:
  300. break;
  301. }
  302. }
  303. }
  304. }
  305. void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
  306. {
  307. if (fbxMesh->GetElementVertexColorCount() > 0)
  308. {
  309. // Get only the first vertex color.
  310. FbxGeometryElementVertexColor* vertexColor = fbxMesh->GetElementVertexColor(0);
  311. FbxGeometryElement::EMappingMode mappingMode = vertexColor->GetMappingMode();
  312. if (mappingMode == FbxGeometryElement::eByControlPoint)
  313. {
  314. switch (vertexColor->GetReferenceMode())
  315. {
  316. case FbxGeometryElement::eDirect:
  317. {
  318. FbxColor color = vertexColor->GetDirectArray().GetAt(controlPointIndex);
  319. vertex->hasDiffuse = true;
  320. vertex->diffuse.x = (float)color.mRed;
  321. vertex->diffuse.y = (float)color.mGreen;
  322. vertex->diffuse.z = (float)color.mBlue;
  323. vertex->diffuse.w = (float)color.mAlpha;
  324. }
  325. break;
  326. case FbxGeometryElement::eIndexToDirect:
  327. {
  328. int id = vertexColor->GetIndexArray().GetAt(controlPointIndex);
  329. FbxColor color = vertexColor->GetDirectArray().GetAt(id);
  330. vertex->hasDiffuse = true;
  331. vertex->diffuse.x = (float)color.mRed;
  332. vertex->diffuse.y = (float)color.mGreen;
  333. vertex->diffuse.z = (float)color.mBlue;
  334. vertex->diffuse.w = (float)color.mAlpha;
  335. }
  336. break;
  337. default:
  338. break;
  339. }
  340. }
  341. else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
  342. {
  343. switch (vertexColor->GetReferenceMode())
  344. {
  345. case FbxGeometryElement::eDirect:
  346. {
  347. FbxColor color = vertexColor->GetDirectArray().GetAt(vertexIndex);
  348. vertex->hasDiffuse = true;
  349. vertex->diffuse.x = (float)color.mRed;
  350. vertex->diffuse.y = (float)color.mGreen;
  351. vertex->diffuse.z = (float)color.mBlue;
  352. vertex->diffuse.w = (float)color.mAlpha;
  353. }
  354. break;
  355. case FbxGeometryElement::eIndexToDirect:
  356. {
  357. int id = vertexColor->GetIndexArray().GetAt(vertexIndex);
  358. FbxColor color = vertexColor->GetDirectArray().GetAt(id);
  359. vertex->hasDiffuse = true;
  360. vertex->diffuse.x = (float)color.mRed;
  361. vertex->diffuse.y = (float)color.mGreen;
  362. vertex->diffuse.z = (float)color.mBlue;
  363. vertex->diffuse.w = (float)color.mAlpha;
  364. }
  365. break;
  366. default:
  367. break;
  368. }
  369. }
  370. }
  371. }
  372. void loadBlendData(const vector<Vector2>& vertexWeights, Vertex* vertex)
  373. {
  374. size_t size = vertexWeights.size();
  375. if (size >= 1)
  376. {
  377. vertex->hasWeights= true;
  378. vertex->blendIndices.x = vertexWeights[0].x;
  379. vertex->blendWeights.x = vertexWeights[0].y;
  380. }
  381. if (size >= 2)
  382. {
  383. vertex->blendIndices.y = vertexWeights[1].x;
  384. vertex->blendWeights.y = vertexWeights[1].y;
  385. }
  386. if (size >= 3)
  387. {
  388. vertex->blendIndices.z = vertexWeights[2].x;
  389. vertex->blendWeights.z = vertexWeights[2].y;
  390. }
  391. if (size >= 4)
  392. {
  393. vertex->blendIndices.w = vertexWeights[3].x;
  394. vertex->blendWeights.w = vertexWeights[3].y;
  395. }
  396. //vertex->normalizeBlendWeight();
  397. }
  398. bool loadBlendWeights(FbxMesh* fbxMesh, vector<vector<Vector2> >& weights)
  399. {
  400. assert(fbxMesh);
  401. const int vertexCount = fbxMesh->GetControlPointsCount();
  402. FbxSkin* fbxSkin = NULL;
  403. const int deformerCount = fbxMesh->GetDeformerCount();
  404. for (int i = 0; i < deformerCount; ++i)
  405. {
  406. FbxDeformer* deformer = fbxMesh->GetDeformer(i);
  407. if (deformer->GetDeformerType() == FbxDeformer::eSkin)
  408. {
  409. fbxSkin = FbxCast<FbxSkin>(deformer);
  410. weights.resize(vertexCount);
  411. const int clusterCount = fbxSkin->GetClusterCount();
  412. for (int j = 0; j < clusterCount; ++j)
  413. {
  414. FbxCluster* cluster = fbxSkin->GetCluster(j);
  415. assert(cluster);
  416. const int vertexIndexCount = cluster->GetControlPointIndicesCount();
  417. for (int k = 0; k < vertexIndexCount; ++k)
  418. {
  419. int index = cluster->GetControlPointIndices()[k];
  420. if (index >= vertexCount)
  421. {
  422. continue;
  423. }
  424. double weight = cluster->GetControlPointWeights()[k];
  425. if (weight == 0.0)
  426. {
  427. continue;
  428. }
  429. weights[index].push_back(Vector2((float)j, (float)weight));
  430. }
  431. }
  432. // Only the first skin deformer will be loaded.
  433. // There probably won't be more than one.
  434. break;
  435. }
  436. }
  437. return fbxSkin != NULL;
  438. }
  439. void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate)
  440. {
  441. FbxTime start, stop;
  442. FbxTimeSpan timeSpan;
  443. animCurve->GetTimeInterval(timeSpan);
  444. start = timeSpan.GetStart();
  445. stop = timeSpan.GetStop();
  446. *startTime = std::min(*startTime, (float)start.GetMilliSeconds());
  447. *stopTime = std::max(*stopTime, (float)stop.GetMilliSeconds());
  448. *frameRate = std::max(*frameRate, (float)stop.GetFrameRate(FbxTime::eDefaultMode));
  449. }
  450. void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
  451. {
  452. // Write key time
  453. channel->getKeyTimes().push_back(time);
  454. // Write key values
  455. vector<float>& keyValues = channel->getKeyValues();
  456. switch (channel->getTargetAttribute())
  457. {
  458. case Transform::ANIMATE_SCALE:
  459. {
  460. keyValues.push_back(scale.x);
  461. keyValues.push_back(scale.y);
  462. keyValues.push_back(scale.z);
  463. }
  464. break;
  465. case Transform::ANIMATE_SCALE_X:
  466. {
  467. keyValues.push_back(scale.x);
  468. }
  469. break;
  470. case Transform::ANIMATE_SCALE_Y:
  471. {
  472. keyValues.push_back(scale.y);
  473. }
  474. break;
  475. case Transform::ANIMATE_SCALE_Z:
  476. {
  477. keyValues.push_back(scale.z);
  478. }
  479. break;
  480. case Transform::ANIMATE_ROTATE:
  481. {
  482. keyValues.push_back(rotation.x);
  483. keyValues.push_back(rotation.y);
  484. keyValues.push_back(rotation.z);
  485. keyValues.push_back(rotation.w);
  486. }
  487. break;
  488. case Transform::ANIMATE_TRANSLATE:
  489. {
  490. keyValues.push_back(translation.x);
  491. keyValues.push_back(translation.y);
  492. keyValues.push_back(translation.z);
  493. }
  494. break;
  495. case Transform::ANIMATE_TRANSLATE_X:
  496. {
  497. keyValues.push_back(translation.x);
  498. }
  499. break;
  500. case Transform::ANIMATE_TRANSLATE_Y:
  501. {
  502. keyValues.push_back(translation.y);
  503. }
  504. break;
  505. case Transform::ANIMATE_TRANSLATE_Z:
  506. {
  507. keyValues.push_back(translation.z);
  508. }
  509. break;
  510. case Transform::ANIMATE_ROTATE_TRANSLATE:
  511. {
  512. keyValues.push_back(rotation.x);
  513. keyValues.push_back(rotation.y);
  514. keyValues.push_back(rotation.z);
  515. keyValues.push_back(rotation.w);
  516. keyValues.push_back(translation.x);
  517. keyValues.push_back(translation.y);
  518. keyValues.push_back(translation.z);
  519. }
  520. break;
  521. case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
  522. {
  523. keyValues.push_back(scale.x);
  524. keyValues.push_back(scale.y);
  525. keyValues.push_back(scale.z);
  526. keyValues.push_back(rotation.x);
  527. keyValues.push_back(rotation.y);
  528. keyValues.push_back(rotation.z);
  529. keyValues.push_back(rotation.w);
  530. keyValues.push_back(translation.x);
  531. keyValues.push_back(translation.y);
  532. keyValues.push_back(translation.z);
  533. }
  534. break;
  535. case Transform::ANIMATE_SCALE_TRANSLATE:
  536. {
  537. keyValues.push_back(scale.x);
  538. keyValues.push_back(scale.y);
  539. keyValues.push_back(scale.z);
  540. keyValues.push_back(translation.x);
  541. keyValues.push_back(translation.y);
  542. keyValues.push_back(translation.z);
  543. }
  544. break;
  545. case Transform::ANIMATE_SCALE_ROTATE:
  546. {
  547. keyValues.push_back(scale.x);
  548. keyValues.push_back(scale.y);
  549. keyValues.push_back(scale.z);
  550. keyValues.push_back(rotation.x);
  551. keyValues.push_back(rotation.y);
  552. keyValues.push_back(rotation.z);
  553. keyValues.push_back(rotation.w);
  554. }
  555. break;
  556. default:
  557. {
  558. LOG(1, "Warning: Invalid animatoin target (%d) attribute for node: %s.\n", channel->getTargetAttribute(), fbxNode->GetName());
  559. }
  560. return;
  561. }
  562. }
  563. void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation)
  564. {
  565. FbxAMatrix fbxMatrix;
  566. Matrix matrix;
  567. FbxTime kTime;
  568. kTime.SetMilliSeconds((FbxLongLong)time);
  569. fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
  570. copyMatrix(fbxMatrix, matrix);
  571. matrix.decompose(scale, rotation, translation);
  572. }
  573. AnimationChannel* createAnimationChannel(FbxNode* fbxNode, unsigned int targetAttrib, const vector<float>& keyTimes, const vector<float>& keyValues)
  574. {
  575. AnimationChannel* channel = new AnimationChannel();
  576. channel->setTargetId(fbxNode->GetName());
  577. channel->setKeyTimes(keyTimes);
  578. channel->setKeyValues(keyValues);
  579. channel->setInterpolation(AnimationChannel::LINEAR);
  580. channel->setTargetAttribute(targetAttrib);
  581. return channel;
  582. }
  583. void addScaleChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime)
  584. {
  585. vector<float> keyTimes;
  586. vector<float> keyValues;
  587. Vector3 scale;
  588. Quaternion rotation;
  589. Vector3 translation;
  590. decompose(fbxNode, startTime, &scale, &rotation, &translation);
  591. keyTimes.push_back(startTime);
  592. keyValues.push_back(scale.x);
  593. keyValues.push_back(scale.y);
  594. keyValues.push_back(scale.z);
  595. decompose(fbxNode, stopTime, &scale, &rotation, &translation);
  596. keyTimes.push_back(stopTime);
  597. keyValues.push_back(scale.x);
  598. keyValues.push_back(scale.y);
  599. keyValues.push_back(scale.z);
  600. AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_SCALE, keyTimes, keyValues);
  601. animation->add(channel);
  602. }
  603. void addTranslateChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime)
  604. {
  605. vector<float> keyTimes;
  606. vector<float> keyValues;
  607. Vector3 scale;
  608. Quaternion rotation;
  609. Vector3 translation;
  610. decompose(fbxNode, startTime, &scale, &rotation, &translation);
  611. keyTimes.push_back(startTime);
  612. keyValues.push_back(translation.x);
  613. keyValues.push_back(translation.y);
  614. keyValues.push_back(translation.z);
  615. decompose(fbxNode, stopTime, &scale, &rotation, &translation);
  616. keyTimes.push_back(stopTime);
  617. keyValues.push_back(translation.x);
  618. keyValues.push_back(translation.y);
  619. keyValues.push_back(translation.z);
  620. AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_TRANSLATE, keyTimes, keyValues);
  621. animation->add(channel);
  622. }
  623. void copyMatrix(const FbxMatrix& fbxMatrix, float* matrix)
  624. {
  625. int i = 0;
  626. for (int row = 0; row < 4; ++row)
  627. {
  628. for (int col = 0; col < 4; ++col)
  629. {
  630. matrix[i++] = (float)fbxMatrix.Get(row, col);
  631. }
  632. }
  633. }
  634. void copyMatrix(const FbxMatrix& fbxMatrix, Matrix& matrix)
  635. {
  636. int i = 0;
  637. for (int row = 0; row < 4; ++row)
  638. {
  639. for (int col = 0; col < 4; ++col)
  640. {
  641. matrix.m[i++] = (float)fbxMatrix.Get(row, col);
  642. }
  643. }
  644. }
  645. bool isGroupAnimationPossible(FbxScene* fbxScene)
  646. {
  647. FbxNode* rootNode = fbxScene->GetRootNode();
  648. if (rootNode)
  649. {
  650. if (isGroupAnimationPossible(rootNode))
  651. return true;
  652. }
  653. return false;
  654. }
  655. bool isGroupAnimationPossible(FbxNode* fbxNode)
  656. {
  657. if (fbxNode)
  658. {
  659. FbxMesh* fbxMesh = fbxNode->GetMesh();
  660. if (isGroupAnimationPossible(fbxMesh))
  661. return true;
  662. const int childCount = fbxNode->GetChildCount();
  663. for (int i = 0; i < childCount; ++i)
  664. {
  665. if (isGroupAnimationPossible(fbxNode->GetChild(i)))
  666. return true;
  667. }
  668. }
  669. return false;
  670. }
  671. bool isGroupAnimationPossible(FbxMesh* fbxMesh)
  672. {
  673. if (fbxMesh)
  674. {
  675. const int deformerCount = fbxMesh->GetDeformerCount();
  676. for (int i = 0; i < deformerCount; ++i)
  677. {
  678. FbxDeformer* deformer = fbxMesh->GetDeformer(i);
  679. if (deformer->GetDeformerType() == FbxDeformer::eSkin)
  680. {
  681. FbxSkin* fbxSkin = FbxCast<FbxSkin>(deformer);
  682. if (fbxSkin)
  683. {
  684. return true;
  685. }
  686. }
  687. }
  688. }
  689. return false;
  690. }
  691. bool isBlack(FbxDouble3& fbxDouble)
  692. {
  693. return fbxDouble[0] == 0.0 && fbxDouble[1] == 0.0 && fbxDouble[2] == 0.0;
  694. }
  695. void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments)
  696. {
  697. if (!fbxNode)
  698. return;
  699. const char* name = fbxNode->GetName();
  700. if (name && strlen(name) > 0)
  701. {
  702. FbxMesh* fbxMesh = fbxNode->GetMesh();
  703. if (fbxMesh && arguments.isGenerateTangentBinormalId(string(name)))
  704. {
  705. fbxMesh->GenerateTangentsDataForAllUVSets();
  706. }
  707. }
  708. // visit child nodes
  709. const int childCount = fbxNode->GetChildCount();
  710. for (int i = 0; i < childCount; ++i)
  711. {
  712. generateTangentsAndBinormals(fbxNode->GetChild(i), arguments);
  713. }
  714. }
  715. FbxAnimCurve* getCurve(FbxPropertyT<FbxDouble3>& prop, FbxAnimLayer* animLayer, const char* pChannel)
  716. {
  717. #if FBXSDK_VERSION_MAJOR == 2013 && FBXSDK_VERSION_MINOR == 1
  718. return prop.GetCurve<FbxAnimCurve>(animLayer, pChannel);
  719. #else
  720. return prop.GetCurve(animLayer, pChannel);
  721. #endif
  722. }
  723. std::string toString(const FbxDouble3& fbxDouble)
  724. {
  725. ostringstream stream;
  726. stream << fbxDouble[0] << ", " << fbxDouble[1] << ", " << fbxDouble[2];
  727. return stream.str();
  728. }
  729. std::string toString(const FbxDouble3& fbxDouble, double d)
  730. {
  731. ostringstream stream;
  732. stream << fbxDouble[0] << ", " << fbxDouble[1] << ", " << fbxDouble[2] << ", " << d;
  733. return stream.str();
  734. }
  735. std::string toString(double value)
  736. {
  737. ostringstream stream;
  738. stream << value;
  739. return stream.str();
  740. }