fbxmath.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /****************************************************************************************
  2. Copyright (C) 2015 Autodesk, Inc.
  3. All rights reserved.
  4. Use of this software is subject to the terms of the Autodesk license agreement
  5. provided at the time of installation or download, or which otherwise accompanies
  6. this software in either electronic or hard copy form.
  7. ****************************************************************************************/
  8. //! \file fbxmath.h
  9. #ifndef _FBXSDK_CORE_MATH_H_
  10. #define _FBXSDK_CORE_MATH_H_
  11. #include <fbxsdk/fbxsdk_def.h>
  12. #include <fbxsdk/core/math/fbxvector2.h>
  13. #include <fbxsdk/core/math/fbxvector4.h>
  14. #include <fbxsdk/core/math/fbxmatrix.h>
  15. #include <fbxsdk/core/math/fbxaffinematrix.h>
  16. //On Mac OS, cmath will include math.h and undef "isnan"
  17. #if defined(FBXSDK_ENV_MAC)
  18. #include <cmath>
  19. extern "C" int isnan (double);
  20. #endif
  21. #include <fbxsdk/fbxsdk_nsbegin.h>
  22. #if defined(FBXSDK_ENV_WIN)
  23. #ifndef isnan
  24. #define isnan _isnan
  25. #endif
  26. #ifndef finite
  27. #define finite _finite
  28. #endif
  29. #endif
  30. //---------------------------------------------------------------------------------------
  31. //Common Constants
  32. #define FBXSDK_PI 3.1415926535897932384626433832795028841971693993751 //!< PI mathematic constant
  33. #define FBXSDK_PI_DIV_2 1.5707963267948966192313216916397514420985846996875 //!< PI divided by 2
  34. #define FBXSDK_PI_DIV_180 0.017453292519943295769236907684886127134428718885417 //!< PI divived by 180
  35. #define FBXSDK_180_DIV_PI 57.295779513082320876798154814105170332405472466565 //!< 180 divided by PI
  36. #define FBXSDK_1_DIV_LN2 1.4426950408889634073599246810018921374266459541530 //!< 1 divided by LogN2
  37. //---------------------------------------------------------------------------------------
  38. //Unit Convertion Ratio
  39. #define FBXSDK_DEG_TO_RAD FBXSDK_PI_DIV_180 //!< Degree to Radian
  40. #define FBXSDK_RAD_TO_DEG FBXSDK_180_DIV_PI //!< Radian to Degree
  41. #define FBXSDK_IN_TO_CM 2.54 //!< Inch to Centimeter
  42. #define FBXSDK_MM_TO_CM 0.1 //!< Millimeter to Centimeter
  43. #define FBXSDK_CM_TO_IN 0.393700787 //!< Centimeter to Inch
  44. #define FBXSDK_IN_TO_MM 25.4 //!< Inch to Millimeter
  45. #define FBXSDK_MM_TO_IN 0.0393700787 //!< Millimeter to Inch
  46. #define FBXSDK_FT_TO_M 0.3048 //!< Feet to Meter
  47. #define FBXSDK_M_TO_FT 3.2808399 //!< Meter to Feet
  48. #define FBXSDK_YD_TO_FT 3 //!< Yard to Feet
  49. #define FBXSDK_FT_TO_YD 0.333333333 //!< Feet to Yard
  50. #define FBXSDK_KM_TO_MILE 0.621371192 //!< Kilometer to Mile
  51. #define FBXSDK_MILE_TO_KM 1.609344 //!< Mile to Kilometer
  52. #define FBXSDK_YD_TO_M 0.9144 //!< Yard to Meter
  53. #define FBXSDK_M_TO_YD 1.0936133 //!< Meter to Yard
  54. //---------------------------------------------------------------------------------------
  55. //Euler Definition
  56. #define FBXSDK_EULER_DEGENERATE FbxEuler::DegenerateThreshold() //!< Euler degenerate threshold can be changed with a call to FbxEuler::SetDegenerateThreshold.
  57. class FBXSDK_DLL FbxEuler
  58. {
  59. public:
  60. enum EAxis {eAxisX=0, eAxisY=1, eAxisZ=2};
  61. enum EOrder
  62. {
  63. eOrderXYZ,
  64. eOrderXZY,
  65. eOrderYZX,
  66. eOrderYXZ,
  67. eOrderZXY,
  68. eOrderZYX,
  69. eOrderSphericXYZ
  70. };
  71. static bool IsParityOdd(EOrder pOrder);
  72. static bool IsRepeat(EOrder pOrder);
  73. static const int AxisTableSize;
  74. static const int AxisTable[][3];
  75. // Used to detect Euler gimbal locks when extracting the rotation vector from
  76. // the FbxAMatrix. This value should only be changed when the user system stores
  77. // single floating point values into the FbxAMatrix with a very low precision.
  78. // In this case, the default threshold value would be too small for a proper detection
  79. // and the extracted values can quickly become off target by a huge amount.
  80. static void SetDegenerateThreshold(double pThreshold=16.0*FBXSDK_FLOAT_EPSILON);
  81. static inline double DegenerateThreshold() { return FbxEuler::mDegenerateThreshold; }
  82. private:
  83. static double mDegenerateThreshold;
  84. };
  85. /** Rotation order flags.
  86. * Each rotate order produces a different end orientation. For example, if the rotation order for an object is set to XYZ,
  87. * the object first rotates about its X-axis, then its Y-axis, and finally its Z-axis.
  88. */
  89. #define EFbxRotationOrder FbxEuler::EOrder
  90. #define eEulerXYZ FbxEuler::eOrderXYZ
  91. #define eEulerXZY FbxEuler::eOrderXZY
  92. #define eEulerYZX FbxEuler::eOrderYZX
  93. #define eEulerYXZ FbxEuler::eOrderYXZ
  94. #define eEulerZXY FbxEuler::eOrderZXY
  95. #define eEulerZYX FbxEuler::eOrderZYX
  96. #define eSphericXYZ FbxEuler::eOrderSphericXYZ
  97. /** Quaternion interpolation modes. */
  98. enum EFbxQuatInterpMode
  99. {
  100. eQuatInterpOff, //!< Do not evaluate using quaternion interpolation.
  101. eQuatInterpClassic, //!< Legacy quaternion interpolation mode.
  102. eQuatInterpSlerp, //!< Spherical linear interpolation.
  103. eQuatInterpCubic, //!< Cubic interpolation.
  104. eQuatInterpTangentDependent, //!< Mix between Slerp and cubic interpolation, depending on the specified tangents for each key.
  105. eQuatInterpCount //!< Number of quaternion interpolation modes. Mark the end of this enum.
  106. };
  107. extern FBXSDK_DLL const FbxDouble FbxIdentityMatrix[4][4];
  108. extern FBXSDK_DLL const FbxVector4 FbxZeroVector4;
  109. inline float FbxFloor(const float x)
  110. {
  111. return float(floor(x));
  112. }
  113. inline double FbxFloor(const double x)
  114. {
  115. return floor(x);
  116. }
  117. inline float FbxCeil(const float x)
  118. {
  119. return float(ceil(x));
  120. }
  121. inline double FbxCeil(const double x)
  122. {
  123. return ceil(x);
  124. }
  125. template<class T> inline T FbxSign(const T x)
  126. {
  127. return (x < 0) ? T(-1) : T(1);
  128. }
  129. template<class T> inline T FbxRound(const T x)
  130. {
  131. T y = FbxFloor(x);
  132. return (x - y < T(0.5)) ? y : y + T(1);
  133. }
  134. inline FbxUChar FbxAbs(const FbxUChar x)
  135. {
  136. return x;
  137. }
  138. inline FbxUShort FbxAbs(const FbxUShort x)
  139. {
  140. return x;
  141. }
  142. inline FbxUInt FbxAbs(const FbxUInt x)
  143. {
  144. return x;
  145. }
  146. #ifndef FBXSDK_SYSTEM_IS_LP64
  147. inline FbxULong FbxAbs(const FbxULong x)
  148. {
  149. return x;
  150. }
  151. #endif
  152. inline FbxULongLong FbxAbs(const FbxULongLong x)
  153. {
  154. return x;
  155. }
  156. inline FbxFloat FbxAbs(const FbxFloat x)
  157. {
  158. return (FbxFloat)fabs(x);
  159. }
  160. inline FbxDouble FbxAbs(const FbxDouble x)
  161. {
  162. return fabs(x);
  163. }
  164. template<class T> inline T FbxAbs(const T x)
  165. {
  166. return (x >= 0) ? x : ((x > FbxMin(x)) ? -x : FbxMax(x));
  167. }
  168. template<class T> inline T FbxClamp(const T value, const T min, const T max)
  169. {
  170. return (value < min) ? min : ((value > max) ? max : value);
  171. }
  172. template<class T> inline bool FbxEqual(const T x, const T y, const T e=(T)FBXSDK_TOLERANCE)
  173. {
  174. return FbxAbs(x - y) <= e;
  175. }
  176. inline bool FbxEqual(const FbxDouble2& x, const FbxDouble2& y, const double e=FBXSDK_TOLERANCE)
  177. {
  178. return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) );
  179. }
  180. inline bool FbxEqual(const FbxDouble3& x, const FbxDouble3& y, const double e=FBXSDK_TOLERANCE)
  181. {
  182. return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) && FbxEqual(x.mData[2], y.mData[2], e) );
  183. }
  184. inline bool FbxEqual(const FbxDouble4& x, const FbxDouble4& y, const double e=FBXSDK_TOLERANCE)
  185. {
  186. return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) && FbxEqual(x.mData[2], y.mData[2], e) && FbxEqual(x.mData[3], y.mData[3], e) );
  187. }
  188. inline bool FbxEqual(const FbxDouble4x4& x, const FbxDouble4x4& y, const double e=FBXSDK_TOLERANCE)
  189. {
  190. return ( FbxEqual(x[0], y[0], e) && FbxEqual(x[1], y[1], e) && FbxEqual(x[2], y[2], e) && FbxEqual(x[3], y[3], e) );
  191. }
  192. inline bool FbxEqual(const FbxVector2& x, const FbxVector2& y, const double e=FBXSDK_TOLERANCE)
  193. {
  194. return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) );
  195. }
  196. inline bool FbxEqual(const FbxVector4& x, const FbxVector4& y, const double e=FBXSDK_TOLERANCE)
  197. {
  198. return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) && FbxEqual(x.mData[2], y.mData[2], e) && FbxEqual(x.mData[3], y.mData[3], e) );
  199. }
  200. inline bool FbxEqual(const FbxMatrix& x, const FbxMatrix& y, const double e=FBXSDK_TOLERANCE)
  201. {
  202. return ( FbxEqual(x[0], y[0], e) && FbxEqual(x[1], y[1], e) && FbxEqual(x[2], y[2], e) && FbxEqual(x[3], y[3], e) );
  203. }
  204. inline bool FbxEqual(const FbxAMatrix& x, const FbxAMatrix& y, const double e=FBXSDK_TOLERANCE)
  205. {
  206. return ( FbxEqual(x[0], y[0], e) && FbxEqual(x[1], y[1], e) && FbxEqual(x[2], y[2], e) && FbxEqual(x[3], y[3], e) );
  207. }
  208. inline FbxDouble FbxMod(const FbxFloat x, FbxFloat& i)
  209. {
  210. return modff(x, &i);
  211. }
  212. inline FbxDouble FbxMod(const FbxDouble x, FbxDouble& i)
  213. {
  214. return modf(x, &i);
  215. }
  216. inline FbxDouble FbxMod(const FbxFloat x)
  217. {
  218. FbxFloat i;
  219. return modff(x, &i);
  220. }
  221. inline FbxDouble FbxMod(const FbxDouble x)
  222. {
  223. FbxDouble i;
  224. return modf(x, &i);
  225. }
  226. template<class T> inline T FbxReciprocal(const T x)
  227. {
  228. return T(1) / x;
  229. }
  230. inline double FbxSqrt(const double x)
  231. {
  232. return sqrt(x);
  233. }
  234. inline float FbxSqrt(const float x)
  235. {
  236. return sqrtf(x);
  237. }
  238. template<class T> inline T FbxSqrt(const T x)
  239. {
  240. if( x > 1 )
  241. {
  242. T z, y = x >> 1;
  243. do
  244. {
  245. z = y;
  246. y = (y + (x / y)) >> 1;
  247. }
  248. while(y < z);
  249. return z;
  250. }
  251. else
  252. {
  253. return x;
  254. }
  255. }
  256. inline float FbxExp(const float x)
  257. {
  258. return expf(x);
  259. }
  260. inline double FbxExp(const double x)
  261. {
  262. return exp(x);
  263. }
  264. inline float FbxLog(const float x)
  265. {
  266. return float(log(x));
  267. }
  268. inline double FbxLog(const double x)
  269. {
  270. return log(x);
  271. }
  272. template<class T> inline T FbxPow(const T x, const T y)
  273. {
  274. return (T)FbxExp(y * FbxLog((double)x));
  275. }
  276. template<class T> inline T FbxLog2(const T x)
  277. {
  278. return (T)(FbxLog(x) * FBXSDK_1_DIV_LN2);
  279. }
  280. inline float FbxSin(const float x)
  281. {
  282. return sinf(x);
  283. }
  284. inline double FbxSin(const double x)
  285. {
  286. return sin(x);
  287. }
  288. inline float FbxCos(const float x)
  289. {
  290. return cosf(x);
  291. }
  292. inline double FbxCos(const double x)
  293. {
  294. return cos(x);
  295. }
  296. inline float FbxTan(const float x)
  297. {
  298. return tanf(x);
  299. }
  300. inline double FbxTan(const double x)
  301. {
  302. return tan(x);
  303. }
  304. // *y = cos(x), sin(x)
  305. template<class T> inline T FbxSinCos(const T x, T* y)
  306. {
  307. return *y = FbxCos(x), FbxSin(x);
  308. }
  309. // *y = cos(x * pi/180), sin(x * pi/180)
  310. template<class T> inline T FbxSinCosd(const T x, T* y)
  311. {
  312. return FbxSinCos(T(x * FBXSDK_PI_DIV_180), y);
  313. }
  314. inline float FbxASin(const float x)
  315. {
  316. return asinf(x);
  317. }
  318. inline double FbxASin(const double x)
  319. {
  320. return asin(x);
  321. }
  322. template<class T> inline T FbxASind(const T x)
  323. {
  324. return (T)(FbxASin((double)x) * FBXSDK_180_DIV_PI);
  325. }
  326. inline float FbxACos(const float x)
  327. {
  328. return acosf(x);
  329. }
  330. inline double FbxACos(const double x)
  331. {
  332. return acos(x);
  333. }
  334. template<class T> inline T FbxACosd(const T x)
  335. {
  336. return (T)(FbxACos(x) * FBXSDK_180_DIV_PI);
  337. }
  338. inline float FbxATan(const float x)
  339. {
  340. return atanf(x);
  341. }
  342. inline double FbxATan(const double x)
  343. {
  344. return atan(x);
  345. }
  346. template<class T> inline T FbxATand(const T x)
  347. {
  348. return (T)(FbxATan(x) * FBXSDK_180_DIV_PI);
  349. }
  350. inline float FbxATan(const float y, const float x)
  351. {
  352. return atan2f(y, x);
  353. }
  354. inline double FbxATan(const double y, const double x)
  355. {
  356. return atan2(y, x);
  357. }
  358. template<class T> inline T FbxATand(const T y, const T x)
  359. {
  360. return (T)(FbxATan(y, x) * FBXSDK_180_DIV_PI);
  361. }
  362. template<class T> inline T FbxNorm(const T x, const T y)
  363. {
  364. return FbxSqrt(x * x + y * y);
  365. }
  366. template<class T> inline T FbxNorm(const T x, const T y, const T z)
  367. {
  368. return FbxSqrt(x * x + y * y + z * z);
  369. }
  370. template<class T> inline T FbxNorm(const T w, const T x, const T y, const T z)
  371. {
  372. return FbxSqrt(w * w + x * x + y * y + z * z);
  373. }
  374. template<class T> inline T FbxHypot(const T x, const T y)
  375. {
  376. return FbxSqrt(x * x + y * y);
  377. }
  378. template<class T> inline T FbxHypot(const T x, const T y, const T z)
  379. {
  380. return FbxSqrt(x * x + y * y + z * z);
  381. }
  382. template<class T> inline T FbxHypot(const T w, const T x, const T y, const T z)
  383. {
  384. return FbxSqrt(w * w + x * x + y * y + z * z);
  385. }
  386. inline FbxVector4 FbxRejection(const FbxVector4& a, const FbxVector4& b)
  387. {
  388. return a - b * (a.DotProduct(b) / b.DotProduct(b));
  389. }
  390. template<class T> inline int FbxBitCount(const T x)
  391. {
  392. int n = 0;
  393. T c = x;
  394. while( c )
  395. {
  396. n += int(c & 1);
  397. c = (c >> 1);
  398. }
  399. return n;
  400. }
  401. template<class T> inline void FbxFixInfinite(T& x)
  402. {
  403. if( x != x || x > FbxMax(x) || x < -FbxMax(x) )
  404. {
  405. x = T(0);
  406. }
  407. }
  408. template<class T> inline T FbxExp(const T x);
  409. template<class T> inline T FbxLog(const T x);
  410. template<class T> inline T FbxSin(const T x);
  411. template<class T> inline T FbxCos(const T x);
  412. template<class T> inline T FbxASin(const T x);
  413. template<class T> inline T FbxACos(const T x);
  414. template<class T> inline T FbxATan(const T x);
  415. template<class T> inline T FbxATan(const T y, const T x);
  416. #include <fbxsdk/fbxsdk_nsend.h>
  417. #endif /* _FBXSDK_CORE_MATH_H_ */