EMath.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /***************************************************************************
  2. EMath.h - description
  3. -------------------
  4. begin : Sat Jan 29 2000
  5. copyright : (C) 2000 by Henrik Enqvist
  6. email : henqvist@excite.com
  7. ***************************************************************************/
  8. #ifndef EMATH_H
  9. #define EMATH_H
  10. #define EM_ZERO(a) ( (a) > -0.000001 && (a) < 0.000001 )
  11. #define EMathApplyMatrix(mtx, vtxIn, vtxOut) \
  12. vtxOut.x = vtxIn.x * mtx.v[0][0] + vtxIn.y * mtx.v[0][1] + vtxIn.z * mtx.v[0][2] + mtx.t[0]; \
  13. vtxOut.y = vtxIn.x * mtx.v[1][0] + vtxIn.y * mtx.v[1][1] + vtxIn.z * mtx.v[1][2] + mtx.t[1]; \
  14. vtxOut.z = vtxIn.x * mtx.v[2][0] + vtxIn.y * mtx.v[2][1] + vtxIn.z * mtx.v[2][2] + mtx.t[2];
  15. #define EMathApplyMatrixRot(mtx, vtxIn, vtxOut) \
  16. vtxOut.x = vtxIn.x * mtx.v[0][0] + vtxIn.y * mtx.v[0][1] + vtxIn.z * mtx.v[0][2]; \
  17. vtxOut.y = vtxIn.x * mtx.v[1][0] + vtxIn.y * mtx.v[1][1] + vtxIn.z * mtx.v[1][2]; \
  18. vtxOut.z = vtxIn.x * mtx.v[2][0] + vtxIn.y * mtx.v[2][1] + vtxIn.z * mtx.v[2][2];
  19. #define EM_PI 3.1415926f
  20. #define EM_PI_DIV_2 1.5707963f
  21. #define EM_PI_2 6.2831853f
  22. #define EM_SQRT_2 1.4142135f
  23. #define EM_SIN_45 0.7071069f
  24. #define EM_SIN_60 0.8660254f
  25. #define EM_SQRT_3 1.73205f
  26. #define EM_MAX(a, b) ( (a) > (b) ? (a) : (b) )
  27. #define EM_MIN(a, b) ( (a) < (b) ? (a) : (b) )
  28. #define EM_ABS(a) ( (a) > 0 ? (a) : -(a) )
  29. #if EM_USE_FAST_FLOAT2INT
  30. typedef struct {
  31. union {
  32. int i;
  33. float f;
  34. };
  35. } IntOrFloat;
  36. extern IntOrFloat gBias;
  37. #define ConvFloat2Int(a) \
  38. a.f += gBias.f; \
  39. a.i -= gBias.i;
  40. #endif // EM_USE_FAST_FLOAT2INT
  41. typedef struct {
  42. float v[3][3];
  43. float t[3];
  44. } Matrix;
  45. typedef struct {
  46. float x, y, z;
  47. } Vertex3D;
  48. typedef struct {
  49. float u, v;
  50. } TexCoord;
  51. typedef struct {
  52. float r, g, b, a;
  53. } Color;
  54. typedef struct {
  55. float x, y, z, w;
  56. } Quaternion;
  57. /** A class that collects the math functions. */
  58. class EMath {
  59. public:
  60. EMath();
  61. ~EMath();
  62. inline static void applyMatrix(const Matrix & mtx, const Vertex3D & vtxIn,
  63. Vertex3D & vtxOut) {
  64. vtxOut.x = vtxIn.x * mtx.v[0][0] + vtxIn.y * mtx.v[0][1]
  65. + vtxIn.z * mtx.v[0][2] + mtx.t[0];
  66. vtxOut.y = vtxIn.x * mtx.v[1][0] + vtxIn.y * mtx.v[1][1]
  67. + vtxIn.z * mtx.v[1][2] + mtx.t[1];
  68. vtxOut.z = vtxIn.x * mtx.v[2][0] + vtxIn.y * mtx.v[2][1]
  69. + vtxIn.z * mtx.v[2][2] + mtx.t[2];
  70. };
  71. inline static void applyMatrixRot(const Matrix & mtx, const Vertex3D & vtxIn,
  72. Vertex3D & vtxOut) {
  73. vtxOut.x = vtxIn.x * mtx.v[0][0] + vtxIn.y * mtx.v[0][1] + vtxIn.z * mtx.v[0][2];
  74. vtxOut.y = vtxIn.x * mtx.v[1][0] + vtxIn.y * mtx.v[1][1] + vtxIn.z * mtx.v[1][2];
  75. vtxOut.z = vtxIn.x * mtx.v[2][0] + vtxIn.y * mtx.v[2][1] + vtxIn.z * mtx.v[2][2];
  76. };
  77. static void applyMatrixTrans(const Matrix & mtx, const Vertex3D & vtxIn, Vertex3D & vtxOut);
  78. static void crossProduct(const Vertex3D & vtxA, const Vertex3D & vtxB, Vertex3D & vtxOut);
  79. // static void getCameraMatrix(Matrix & mtx, const Vertex3D & trans, Vertex3D & front,
  80. // Vertex3D & up, float fov, float aspect);
  81. static void getTransformationMatrix(Matrix & mtx, const Vertex3D & vtxT,
  82. const Vertex3D & vtxR, const Vertex3D & vtxS);
  83. static void getTransformationMatrix(Matrix & mtx, const Vertex3D & vtxT,
  84. const Quaternion & qRot, const Vertex3D & vtxS);
  85. static void inverse(const Matrix & mtx, Matrix & inv);
  86. static void matrixMulti(const Matrix & mtxA, const Matrix & mtxB, Matrix & mtxOut);
  87. static float dotProduct(const Vertex3D & vtxA, const Vertex3D & vtxB);
  88. static float emAcos(float f);
  89. static float emAtan(float f);
  90. static float emCos(float f);
  91. static float emRand();
  92. static float emSin(float f);
  93. static float emSqrt(float f);
  94. static float emTan(float f);
  95. static float emPow(float x, float y);
  96. inline static void add(const Vertex3D & vtxA, Vertex3D & vtxOut) {
  97. vtxOut.x += vtxA.x;
  98. vtxOut.y += vtxA.y;
  99. vtxOut.z += vtxA.z;
  100. };
  101. inline static void add(const Vertex3D & vtxA, const Vertex3D & vtxB, Vertex3D & vtxOut) {
  102. vtxOut.x = vtxA.x + vtxB.x;
  103. vtxOut.y = vtxA.y + vtxB.y;
  104. vtxOut.z = vtxA.z + vtxB.z;
  105. };
  106. inline static void subst(const Vertex3D & vtxA, Vertex3D & vtxOut) {
  107. vtxOut.x -= vtxA.x;
  108. vtxOut.y -= vtxA.y;
  109. vtxOut.z -= vtxA.z;
  110. };
  111. inline static void subst(const Vertex3D & vtxA, const Vertex3D & vtxB, Vertex3D & vtxOut) {
  112. vtxOut.x = vtxA.x - vtxB.x;
  113. vtxOut.y = vtxA.y - vtxB.y;
  114. vtxOut.z = vtxA.z - vtxB.z;
  115. };
  116. inline static void scaleVertex(Vertex3D & vtx, float s) {
  117. vtx.x *= s;
  118. vtx.y *= s;
  119. vtx.z *= s;
  120. };
  121. static void normalizeVector(Vertex3D & vtx);
  122. static float polygonZNormal(const Vertex3D & edgeA, const Vertex3D & edgeB,
  123. const Vertex3D & edgeC);
  124. void planeLineIntersection(const Vertex3D & nrml, float dist,
  125. const Vertex3D & vtxA, const Vertex3D & vtxB, Vertex3D & vtxDiff);
  126. /** The projection of vxtA onto vxtB. vtxA and vxtOut is ( in this case )
  127. * allowed to be the same vector. */
  128. static float projection(const Vertex3D & vtxA, const Vertex3D & vtxB, Vertex3D & vtxOut);
  129. /** Get the perpendicular component of the projection */
  130. static float perpendicular(const Vertex3D & vtxA, const Vertex3D & vtxB, Vertex3D & vtxOut);
  131. /** Counts the "reflection" vector of vtxIn onto a plane with the normal vtxWall.
  132. * vtxIn and vtxOut is ( in this case ) allowed to be the same vector. */
  133. static void reflection(const Vertex3D & vtxIn, const Vertex3D & vtxWall,
  134. Vertex3D & vtxOut, bool bBehind = false);
  135. /** Counts the "reflection" vector of vtxIn onto a plane with the normal vtxWall.
  136. * vtxIn and vtxOut is ( in this case ) allowed to be the same vector. The damping
  137. * factor is 1 for normal, 0 for max damping and over 1 for extra bounce. The wall
  138. * factor is as if the wall would give a little push, 0 for normal. Scale is the
  139. * length of the vector, 1 for normal. */
  140. static void reflectionDamp(const Vertex3D & vtxIn, const Vertex3D & vtxWall,
  141. Vertex3D & vtxOut, float damp, float extra,
  142. float scale, bool bBehind = false);
  143. static void scaleVector(Vertex3D & vtx, float sc);
  144. inline static float vectorLength(const Vertex3D & vtx) {
  145. return EMath::emSqrt(vtx.x * vtx.x + vtx.y * vtx.y + vtx.z * vtx.z);
  146. };
  147. /** The vector length but without the square root */
  148. inline static float vectorLengthSqr(const Vertex3D & vtx) {
  149. return (vtx.x * vtx.x + vtx.y * vtx.y + vtx.z * vtx.z);
  150. };
  151. static float volume(const Vertex3D & vtxA, const Vertex3D & vtxB, const Vertex3D & vtxC);
  152. static void rotationArc(const Vertex3D & vtxA, const Vertex3D & vtxB, Quaternion & vtxOut);
  153. static void quaternionMulti(const Quaternion & qA, const Quaternion & qB, Quaternion & qOut);
  154. /** Quadratic interpolation. f0 is at t=0, f1 is at t=1 and f2 at t=2. You
  155. * may give any t for recieving values. */
  156. static float quadratic(float f0, float f1, float f2, float t);
  157. static float cubic(float f0, float f1, float f2, float f3, float t);
  158. static const Matrix identityMatrix;
  159. };
  160. #endif // EMATH_H