import_utils.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*************************************************************************/
  2. /* import_utils.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "import_utils.h"
  31. Vector3 ImportUtils::deg2rad(const Vector3 &p_rotation) {
  32. return p_rotation / 180.0 * Math_PI;
  33. }
  34. Vector3 ImportUtils::rad2deg(const Vector3 &p_rotation) {
  35. return p_rotation / Math_PI * 180.0;
  36. }
  37. Basis ImportUtils::EulerToBasis(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation) {
  38. Basis ret;
  39. // FBX is using intrinsic euler, we can convert intrinsic to extrinsic (the one used in godot
  40. // by simply invert its order: https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf
  41. switch (mode) {
  42. case FBXDocParser::Model::RotOrder_EulerXYZ:
  43. ret.set_euler_zyx(p_rotation);
  44. break;
  45. case FBXDocParser::Model::RotOrder_EulerXZY:
  46. ret.set_euler_yzx(p_rotation);
  47. break;
  48. case FBXDocParser::Model::RotOrder_EulerYZX:
  49. ret.set_euler_xzy(p_rotation);
  50. break;
  51. case FBXDocParser::Model::RotOrder_EulerYXZ:
  52. ret.set_euler_zxy(p_rotation);
  53. break;
  54. case FBXDocParser::Model::RotOrder_EulerZXY:
  55. ret.set_euler_yxz(p_rotation);
  56. break;
  57. case FBXDocParser::Model::RotOrder_EulerZYX:
  58. ret.set_euler_xyz(p_rotation);
  59. break;
  60. case FBXDocParser::Model::RotOrder_SphericXYZ:
  61. // TODO do this.
  62. break;
  63. default:
  64. // If you land here, Please integrate all enums.
  65. CRASH_NOW_MSG("This is not unreachable.");
  66. }
  67. return ret;
  68. }
  69. Quat ImportUtils::EulerToQuaternion(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation) {
  70. return ImportUtils::EulerToBasis(mode, p_rotation);
  71. }
  72. Vector3 ImportUtils::BasisToEuler(FBXDocParser::Model::RotOrder mode, const Basis &p_rotation) {
  73. // FBX is using intrinsic euler, we can convert intrinsic to extrinsic (the one used in godot
  74. // by simply invert its order: https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf
  75. switch (mode) {
  76. case FBXDocParser::Model::RotOrder_EulerXYZ:
  77. return p_rotation.get_euler_zyx();
  78. case FBXDocParser::Model::RotOrder_EulerXZY:
  79. return p_rotation.get_euler_yzx();
  80. case FBXDocParser::Model::RotOrder_EulerYZX:
  81. return p_rotation.get_euler_xzy();
  82. case FBXDocParser::Model::RotOrder_EulerYXZ:
  83. return p_rotation.get_euler_zxy();
  84. case FBXDocParser::Model::RotOrder_EulerZXY:
  85. return p_rotation.get_euler_yxz();
  86. case FBXDocParser::Model::RotOrder_EulerZYX:
  87. return p_rotation.get_euler_xyz();
  88. case FBXDocParser::Model::RotOrder_SphericXYZ:
  89. // TODO
  90. return Vector3();
  91. default:
  92. // If you land here, Please integrate all enums.
  93. CRASH_NOW_MSG("This is not unreachable.");
  94. return Vector3();
  95. }
  96. }
  97. Vector3 ImportUtils::QuaternionToEuler(FBXDocParser::Model::RotOrder mode, const Quat &p_rotation) {
  98. return BasisToEuler(mode, p_rotation);
  99. }
  100. Transform get_unscaled_transform(const Transform &p_initial, real_t p_scale) {
  101. Transform unscaled = Transform(p_initial.basis, p_initial.origin * p_scale);
  102. ERR_FAIL_COND_V_MSG(unscaled.basis.determinant() == 0, Transform(), "det is zero unscaled?");
  103. return unscaled;
  104. }
  105. Vector3 get_poly_normal(const std::vector<Vector3> &p_vertices) {
  106. ERR_FAIL_COND_V_MSG(p_vertices.size() < 3, Vector3(0, 0, 0), "At least 3 vertices are necessary");
  107. // Using long double to make sure that normal is computed for even really tiny objects.
  108. typedef long double ldouble;
  109. ldouble x = 0.0;
  110. ldouble y = 0.0;
  111. ldouble z = 0.0;
  112. for (size_t i = 0; i < p_vertices.size(); i += 1) {
  113. const Vector3 current = p_vertices[i];
  114. const Vector3 next = p_vertices[(i + 1) % p_vertices.size()];
  115. x += (ldouble(current.y) - ldouble(next.y)) * (ldouble(current.z) + ldouble(next.z));
  116. y += (ldouble(current.z) - ldouble(next.z)) * (ldouble(current.x) + ldouble(next.x));
  117. z += (ldouble(current.x) - ldouble(next.x)) * (ldouble(current.y) + ldouble(next.y));
  118. }
  119. const ldouble l2 = x * x + y * y + z * z;
  120. if (l2 == 0.0) {
  121. return (p_vertices[0] - p_vertices[1]).normalized().cross((p_vertices[0] - p_vertices[2]).normalized()).normalized();
  122. } else {
  123. const double l = Math::sqrt(double(l2));
  124. return Vector3(x / l, y / l, z / l);
  125. }
  126. }