MATHLIB.CPP 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. // mathlib.c -- math primitives
  19. #include "stdafx.h"
  20. #include "cmdlib.h"
  21. #include "mathlib.h"
  22. vec3_t vec3_origin = {0.0f,0.0f,0.0f};
  23. float VectorLength(vec3_t v)
  24. {
  25. int i;
  26. float length;
  27. length = 0.0f;
  28. for (i=0 ; i< 3 ; i++)
  29. length += v[i]*v[i];
  30. length = (float)sqrt (length);
  31. return length;
  32. }
  33. qboolean VectorCompare (vec3_t v1, vec3_t v2)
  34. {
  35. int i;
  36. for (i=0 ; i<3 ; i++)
  37. if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON)
  38. return false;
  39. return true;
  40. }
  41. vec_t Q_rint (vec_t in)
  42. {
  43. if (g_PrefsDlg.m_bNoClamp)
  44. return in;
  45. else
  46. return (float)floor (in + 0.5);
  47. }
  48. void VectorMA (vec3_t va, float scale, vec3_t vb, vec3_t vc)
  49. {
  50. vc[0] = va[0] + scale*vb[0];
  51. vc[1] = va[1] + scale*vb[1];
  52. vc[2] = va[2] + scale*vb[2];
  53. }
  54. void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
  55. {
  56. cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
  57. cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
  58. cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
  59. }
  60. vec_t _DotProduct (vec3_t v1, vec3_t v2)
  61. {
  62. return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
  63. }
  64. void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out)
  65. {
  66. out[0] = va[0]-vb[0];
  67. out[1] = va[1]-vb[1];
  68. out[2] = va[2]-vb[2];
  69. }
  70. void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out)
  71. {
  72. out[0] = va[0]+vb[0];
  73. out[1] = va[1]+vb[1];
  74. out[2] = va[2]+vb[2];
  75. }
  76. void _VectorCopy (vec3_t in, vec3_t out)
  77. {
  78. out[0] = in[0];
  79. out[1] = in[1];
  80. out[2] = in[2];
  81. }
  82. vec_t VectorNormalize (vec3_t v)
  83. {
  84. int i;
  85. float length;
  86. length = 0.0f;
  87. for (i=0 ; i< 3 ; i++)
  88. length += v[i]*v[i];
  89. length = (float)sqrt (length);
  90. if (length == 0)
  91. return (vec_t)0;
  92. for (i=0 ; i< 3 ; i++)
  93. v[i] /= length;
  94. return length;
  95. }
  96. void VectorInverse (vec3_t v)
  97. {
  98. v[0] = -v[0];
  99. v[1] = -v[1];
  100. v[2] = -v[2];
  101. }
  102. void VectorScale (vec3_t v, vec_t scale, vec3_t out)
  103. {
  104. out[0] = v[0] * scale;
  105. out[1] = v[1] * scale;
  106. out[2] = v[2] * scale;
  107. }
  108. void VectorRotate (vec3_t vIn, vec3_t vRotation, vec3_t out)
  109. {
  110. vec3_t vWork, va;
  111. VectorCopy(vIn, va);
  112. VectorCopy(va, vWork);
  113. int nIndex[3][2];
  114. nIndex[0][0] = 1; nIndex[0][1] = 2;
  115. nIndex[1][0] = 2; nIndex[1][1] = 0;
  116. nIndex[2][0] = 0; nIndex[2][1] = 1;
  117. for (int i = 0; i < 3; i++)
  118. {
  119. if (vRotation[i] != 0)
  120. {
  121. double dAngle = vRotation[i] * Q_PI / 180.0;
  122. double c = cos(dAngle);
  123. double s = sin(dAngle);
  124. vWork[nIndex[i][0]] = va[nIndex[i][0]] * c - va[nIndex[i][1]] * s;
  125. vWork[nIndex[i][1]] = va[nIndex[i][0]] * s + va[nIndex[i][1]] * c;
  126. }
  127. VectorCopy(vWork, va);
  128. }
  129. VectorCopy(vWork, out);
  130. }
  131. void VectorRotate (vec3_t vIn, vec3_t vRotation, vec3_t vOrigin, vec3_t out)
  132. {
  133. vec3_t vTemp, vTemp2;
  134. VectorSubtract(vIn, vOrigin, vTemp);
  135. VectorRotate(vTemp, vRotation, vTemp2);
  136. VectorAdd(vTemp2, vOrigin, out);
  137. }
  138. void VectorPolar(vec3_t v, float radius, float theta, float phi)
  139. {
  140. v[0]=float(radius * cos(theta) * cos(phi));
  141. v[1]=float(radius * sin(theta) * cos(phi));
  142. v[2]=float(radius * sin(phi));
  143. }
  144. void VectorSnap(vec3_t v)
  145. {
  146. for (int i = 0; i < 3; i++)
  147. {
  148. v[i] = floor (v[i] + 0.5);
  149. }
  150. }
  151. void _Vector5Add (vec5_t va, vec5_t vb, vec5_t out)
  152. {
  153. out[0] = va[0]+vb[0];
  154. out[1] = va[1]+vb[1];
  155. out[2] = va[2]+vb[2];
  156. out[3] = va[3]+vb[3];
  157. out[4] = va[4]+vb[4];
  158. }
  159. void _Vector5Scale (vec5_t v, vec_t scale, vec5_t out)
  160. {
  161. out[0] = v[0] * scale;
  162. out[1] = v[1] * scale;
  163. out[2] = v[2] * scale;
  164. out[3] = v[3] * scale;
  165. out[4] = v[4] * scale;
  166. }
  167. void _Vector53Copy (vec5_t in, vec3_t out)
  168. {
  169. out[0] = in[0];
  170. out[1] = in[1];
  171. out[2] = in[2];
  172. }
  173. // NOTE: added these from Ritual's Q3Radiant
  174. void ClearBounds (vec3_t mins, vec3_t maxs)
  175. {
  176. mins[0] = mins[1] = mins[2] = 99999;
  177. maxs[0] = maxs[1] = maxs[2] = -99999;
  178. }
  179. void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs)
  180. {
  181. int i;
  182. vec_t val;
  183. for (i=0 ; i<3 ; i++)
  184. {
  185. val = v[i];
  186. if (val < mins[i])
  187. mins[i] = val;
  188. if (val > maxs[i])
  189. maxs[i] = val;
  190. }
  191. }
  192. #define PITCH 0 // up / down
  193. #define YAW 1 // left / right
  194. #define ROLL 2 // fall over
  195. #ifndef M_PI
  196. #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
  197. #endif
  198. void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
  199. {
  200. float angle;
  201. static float sr, sp, sy, cr, cp, cy;
  202. // static to help MS compiler fp bugs
  203. angle = angles[YAW] * (M_PI*2 / 360);
  204. sy = sin(angle);
  205. cy = cos(angle);
  206. angle = angles[PITCH] * (M_PI*2 / 360);
  207. sp = sin(angle);
  208. cp = cos(angle);
  209. angle = angles[ROLL] * (M_PI*2 / 360);
  210. sr = sin(angle);
  211. cr = cos(angle);
  212. if (forward)
  213. {
  214. forward[0] = cp*cy;
  215. forward[1] = cp*sy;
  216. forward[2] = -sp;
  217. }
  218. if (right)
  219. {
  220. right[0] = -sr*sp*cy+cr*sy;
  221. right[1] = -sr*sp*sy-cr*cy;
  222. right[2] = -sr*cp;
  223. }
  224. if (up)
  225. {
  226. up[0] = cr*sp*cy+sr*sy;
  227. up[1] = cr*sp*sy-sr*cy;
  228. up[2] = cr*cp;
  229. }
  230. }
  231. void VectorToAngles( vec3_t vec, vec3_t angles )
  232. {
  233. float forward;
  234. float yaw, pitch;
  235. if ( ( vec[ 0 ] == 0 ) && ( vec[ 1 ] == 0 ) )
  236. {
  237. yaw = 0;
  238. if ( vec[ 2 ] > 0 )
  239. {
  240. pitch = 90;
  241. }
  242. else
  243. {
  244. pitch = 270;
  245. }
  246. }
  247. else
  248. {
  249. yaw = atan2( vec[ 1 ], vec[ 0 ] ) * 180 / M_PI;
  250. if ( yaw < 0 )
  251. {
  252. yaw += 360;
  253. }
  254. forward = ( float )sqrt( vec[ 0 ] * vec[ 0 ] + vec[ 1 ] * vec[ 1 ] );
  255. pitch = atan2( vec[ 2 ], forward ) * 180 / M_PI;
  256. if ( pitch < 0 )
  257. {
  258. pitch += 360;
  259. }
  260. }
  261. angles[ 0 ] = pitch;
  262. angles[ 1 ] = yaw;
  263. angles[ 2 ] = 0;
  264. }