Advertisement
Snorflake

mathlib.h

Jun 11th, 2015
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.94 KB | None | 0 0
  1. /*
  2. TODO: Finish this
  3. */
  4. #ifndef M_PI
  5. #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
  6. #endif
  7.  
  8. #define M_PI_F ((float)(M_PI)) // Shouldn't collide with anything.
  9. #ifndef RAD2DEG
  10. #define RAD2DEG( x ) ( (float)(x) * (float)(180.f / M_PI_F) )
  11. #endif
  12.  
  13. #ifndef DEG2RAD
  14. #define DEG2RAD( x ) ( (float)(x) * (float)(M_PI_F / 180.f) )
  15. #endif
  16. enum
  17. {
  18. PITCH = 0, // up / down
  19. YAW, // left / right
  20. ROLL // fall over
  21. };
  22. // Math routines done in optimized assembly math package routines
  23. void inline SinCos(float radians, float *sine, float *cosine)
  24. {
  25. *sine = sin(radians);
  26. *cosine = cos(radians);
  27.  
  28. }
  29. void AngleVectors(const QAngle &angles, Vector *forward)
  30. {
  31. Assert(s_bMathlibInitialized);
  32. Assert(forward);
  33.  
  34. float sp, sy, cp, cy;
  35.  
  36. SinCos(DEG2RAD(angles[YAW]), &sy, &cy);
  37. SinCos(DEG2RAD(angles[PITCH]), &sp, &cp);
  38.  
  39. forward->x = cp*cy;
  40. forward->y = cp*sy;
  41. forward->z = -sp;
  42. }
  43. void AngleVectors(const QAngle &angles, Vector *forward, Vector *right, Vector *up)
  44. {
  45. Assert(s_bMathlibInitialized);
  46.  
  47. float sr, sp, sy, cr, cp, cy;
  48.  
  49. #ifdef _X360
  50. fltx4 radians, scale, sine, cosine;
  51. radians = LoadUnaligned3SIMD(angles.Base());
  52. scale = ReplicateX4(M_PI_F / 180.f);
  53. radians = MulSIMD(radians, scale);
  54. SinCos3SIMD(sine, cosine, radians);
  55. sp = SubFloat(sine, 0); sy = SubFloat(sine, 1); sr = SubFloat(sine, 2);
  56. cp = SubFloat(cosine, 0); cy = SubFloat(cosine, 1); cr = SubFloat(cosine, 2);
  57. #else
  58. SinCos(DEG2RAD(angles[YAW]), &sy, &cy);
  59. SinCos(DEG2RAD(angles[PITCH]), &sp, &cp);
  60. SinCos(DEG2RAD(angles[ROLL]), &sr, &cr);
  61. #endif
  62.  
  63. if (forward)
  64. {
  65. forward->x = cp*cy;
  66. forward->y = cp*sy;
  67. forward->z = -sp;
  68. }
  69.  
  70. if (right)
  71. {
  72. right->x = (-1 * sr*sp*cy + -1 * cr*-sy);
  73. right->y = (-1 * sr*sp*sy + -1 * cr*cy);
  74. right->z = -1 * sr*cp;
  75. }
  76.  
  77. if (up)
  78. {
  79. up->x = (cr*sp*cy + -sr*-sy);
  80. up->y = (cr*sp*sy + -sr*cy);
  81. up->z = cr*cp;
  82. }
  83. }
  84. void AngleVectorsTranspose(const QAngle &angles, Vector *forward, Vector *right, Vector *up)
  85. {
  86. Assert(s_bMathlibInitialized);
  87. float sr, sp, sy, cr, cp, cy;
  88.  
  89. SinCos(DEG2RAD(angles[YAW]), &sy, &cy);
  90. SinCos(DEG2RAD(angles[PITCH]), &sp, &cp);
  91. SinCos(DEG2RAD(angles[ROLL]), &sr, &cr);
  92.  
  93. if (forward)
  94. {
  95. forward->x = cp*cy;
  96. forward->y = (sr*sp*cy + cr*-sy);
  97. forward->z = (cr*sp*cy + -sr*-sy);
  98. }
  99.  
  100. if (right)
  101. {
  102. right->x = cp*sy;
  103. right->y = (sr*sp*sy + cr*cy);
  104. right->z = (cr*sp*sy + -sr*cy);
  105. }
  106.  
  107. if (up)
  108. {
  109. up->x = -sp;
  110. up->y = sr*cp;
  111. up->z = cr*cp;
  112. }
  113. }
  114.  
  115. void VectorAngles(const Vector& forward, QAngle &angles)
  116. {
  117. Assert(s_bMathlibInitialized);
  118. float tmp, yaw, pitch;
  119.  
  120. if (forward[1] == 0 && forward[0] == 0)
  121. {
  122. yaw = 0;
  123. if (forward[2] > 0)
  124. pitch = 270;
  125. else
  126. pitch = 90;
  127. }
  128. else
  129. {
  130. yaw = (atan2(forward[1], forward[0]) * 180 / M_PI);
  131. if (yaw < 0)
  132. yaw += 360;
  133.  
  134. tmp = sqrt(forward[0] * forward[0] + forward[1] * forward[1]);
  135. pitch = (atan2(-forward[2], tmp) * 180 / M_PI);
  136. if (pitch < 0)
  137. pitch += 360;
  138. }
  139.  
  140. angles[0] = pitch;
  141. angles[1] = yaw;
  142. angles[2] = 0;
  143. }
  144. void CrossProduct(const float* v1, const float* v2, float* cross)
  145. {
  146. Assert(s_bMathlibInitialized);
  147. Assert(v1 != cross);
  148. Assert(v2 != cross);
  149. cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
  150. cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
  151. cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
  152. }
  153. inline void _SSE_RSqrtInline(float a, float* out)
  154. {
  155. __m128 xx = _mm_load_ss(&a);
  156. __m128 xr = _mm_rsqrt_ss(xx);
  157. __m128 xt;
  158. xt = _mm_mul_ss(xr, xr);
  159. xt = _mm_mul_ss(xt, xx);
  160. xt = _mm_sub_ss(_mm_set_ss(3.f), xt);
  161. xt = _mm_mul_ss(xt, _mm_set_ss(0.5f));
  162. xr = _mm_mul_ss(xr, xt);
  163. _mm_store_ss(out, xr);
  164. }
  165. FORCEINLINE float VectorNormalize(Vector& vec)
  166. {
  167. #ifndef DEBUG // stop crashing my edit-and-continue!
  168. #if defined(__i386__) || defined(_M_IX86)
  169. #define DO_SSE_OPTIMIZATION
  170. #endif
  171. #endif
  172.  
  173. #if defined( DO_SSE_OPTIMIZATION )
  174. float sqrlen = vec.LengthSqr() + 1.0e-10f, invlen;
  175. _SSE_RSqrtInline(sqrlen, &invlen);
  176. vec.x *= invlen;
  177. vec.y *= invlen;
  178. vec.z *= invlen;
  179. return sqrlen * invlen;
  180. #else
  181. extern float (FASTCALL *pfVectorNormalize)(Vector& v);
  182. return (*pfVectorNormalize)(vec);
  183. #endif
  184. }
  185. void MatrixGetColumn(const matrix3x4_t& in, int column, Vector &out)
  186. {
  187. out.x = in[0][column];
  188. out.y = in[1][column];
  189. out.z = in[2][column];
  190. }
  191.  
  192. void MatrixSetColumn(const Vector &in, int column, matrix3x4_t& out)
  193. {
  194. out[0][column] = in.x;
  195. out[1][column] = in.y;
  196. out[2][column] = in.z;
  197. }
  198. void SetIdentityMatrix(matrix3x4_t& matrix)
  199. {
  200. memset(matrix.Base(), 0, sizeof(float)* 3 * 4);
  201. matrix[0][0] = 1.0;
  202. matrix[1][1] = 1.0;
  203. matrix[2][2] = 1.0;
  204. }
  205. void SetScaleMatrix(float x, float y, float z, matrix3x4_t &dst);
  206. void MatrixBuildRotationAboutAxis(const Vector &vAxisOfRot, float angleDegrees, matrix3x4_t &dst);
  207. void VectorTransform(class Vector const &, struct matrix3x4_t const &, class Vector &);
  208.  
  209. float QuaternionNormalize(Quaternion &q)
  210. {
  211. Assert( s_bMathlibInitialized );
  212. float radius, iradius;
  213.  
  214. Assert(q.IsValid());
  215.  
  216. radius = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
  217.  
  218. if (radius) // > FLT_EPSILON && ((radius < 1.0f - 4*FLT_EPSILON) || (radius > 1.0f + 4*FLT_EPSILON))
  219. {
  220. radius = sqrt(radius);
  221. iradius = 1.0f / radius;
  222. q[3] *= iradius;
  223. q[2] *= iradius;
  224. q[1] *= iradius;
  225. q[0] *= iradius;
  226. }
  227. return radius;
  228. }
  229. void MatrixAngles(const matrix3x4_t &matrix, Quaternion &q, Vector &pos)
  230. {
  231. #ifdef _VPROF_MATHLIB
  232. VPROF_BUDGET("MatrixQuaternion", "Mathlib");
  233. #endif
  234. float trace;
  235. trace = matrix[0][0] + matrix[1][1] + matrix[2][2] + 1.0f;
  236. if (trace > 1.0f + FLT_EPSILON)
  237. {
  238. // VPROF_INCREMENT_COUNTER("MatrixQuaternion A",1);
  239. q.x = (matrix[2][1] - matrix[1][2]);
  240. q.y = (matrix[0][2] - matrix[2][0]);
  241. q.z = (matrix[1][0] - matrix[0][1]);
  242. q.w = trace;
  243. }
  244. else if (matrix[0][0] > matrix[1][1] && matrix[0][0] > matrix[2][2])
  245. {
  246. // VPROF_INCREMENT_COUNTER("MatrixQuaternion B",1);
  247. trace = 1.0f + matrix[0][0] - matrix[1][1] - matrix[2][2];
  248. q.x = trace;
  249. q.y = (matrix[1][0] + matrix[0][1]);
  250. q.z = (matrix[0][2] + matrix[2][0]);
  251. q.w = (matrix[2][1] - matrix[1][2]);
  252. }
  253. else if (matrix[1][1] > matrix[2][2])
  254. {
  255. // VPROF_INCREMENT_COUNTER("MatrixQuaternion C",1);
  256. trace = 1.0f + matrix[1][1] - matrix[0][0] - matrix[2][2];
  257. q.x = (matrix[0][1] + matrix[1][0]);
  258. q.y = trace;
  259. q.z = (matrix[2][1] + matrix[1][2]);
  260. q.w = (matrix[0][2] - matrix[2][0]);
  261. }
  262. else
  263. {
  264. // VPROF_INCREMENT_COUNTER("MatrixQuaternion D",1);
  265. trace = 1.0f + matrix[2][2] - matrix[0][0] - matrix[1][1];
  266. q.x = (matrix[0][2] + matrix[2][0]);
  267. q.y = (matrix[2][1] + matrix[1][2]);
  268. q.z = trace;
  269. q.w = (matrix[1][0] - matrix[0][1]);
  270. }
  271.  
  272. QuaternionNormalize(q);
  273.  
  274. #if 0
  275. // check against the angle version
  276. RadianEuler ang;
  277. MatrixAngles(matrix, ang);
  278. Quaternion test;
  279. AngleQuaternion(ang, test);
  280. float d = QuaternionDotProduct(q, test);
  281. Assert(fabs(d) > 0.99 && fabs(d) < 1.01);
  282. #endif
  283.  
  284. MatrixGetColumn(matrix, 3, pos);
  285. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement