PageRenderTime 34ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/source/gameshared/q_math.c

https://github.com/Racenet/racesow
C | 1209 lines | 914 code | 174 blank | 121 comment | 114 complexity | a4378093382d0f79fcb2210ea2493993 MD5 | raw file
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "q_arch.h"
  16. #include "q_math.h"
  17. #include "q_shared.h"
  18. #include "q_collision.h"
  19. vec3_t vec3_origin = { 0, 0, 0 };
  20. vec3_t axis_identity[3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
  21. quat_t quat_identity = { 0, 0, 0, 1 };
  22. //============================================================================
  23. vec3_t bytedirs[NUMVERTEXNORMALS] =
  24. {
  25. #include "anorms.h"
  26. };
  27. int DirToByte( vec3_t dir )
  28. {
  29. int i, best;
  30. float d, bestd;
  31. qboolean normalized;
  32. if( !dir || VectorCompare( dir, vec3_origin ) )
  33. return NUMVERTEXNORMALS;
  34. if( DotProduct( dir, dir ) == 1 )
  35. normalized = qtrue;
  36. else
  37. normalized = qfalse;
  38. bestd = 0;
  39. best = 0;
  40. for( i = 0; i < NUMVERTEXNORMALS; i++ )
  41. {
  42. d = DotProduct( dir, bytedirs[i] );
  43. if( ( d == 1 ) && normalized )
  44. return i;
  45. if( d > bestd )
  46. {
  47. bestd = d;
  48. best = i;
  49. }
  50. }
  51. return best;
  52. }
  53. void ByteToDir( int b, vec3_t dir )
  54. {
  55. if( b < 0 || b >= NUMVERTEXNORMALS )
  56. VectorSet( dir, 0, 0, 0 );
  57. else
  58. VectorCopy( bytedirs[b], dir );
  59. }
  60. //============================================================================
  61. vec4_t colorBlack = { 0, 0, 0, 1 };
  62. vec4_t colorRed = { 1, 0, 0, 1 };
  63. vec4_t colorGreen = { 0, 1, 0, 1 };
  64. vec4_t colorBlue = { 0, 0, 1, 1 };
  65. vec4_t colorYellow = { 1, 1, 0, 1 };
  66. vec4_t colorOrange = { 1, 0.5, 0, 1 };
  67. vec4_t colorMagenta = { 1, 0, 1, 1 };
  68. vec4_t colorCyan = { 0, 1, 1, 1 };
  69. vec4_t colorWhite = { 1, 1, 1, 1 };
  70. vec4_t colorLtGrey = { 0.75, 0.75, 0.75, 1 };
  71. vec4_t colorMdGrey = { 0.5, 0.5, 0.5, 1 };
  72. vec4_t colorDkGrey = { 0.25, 0.25, 0.25, 1 };
  73. vec4_t color_table[MAX_S_COLORS] =
  74. {
  75. { 0.0, 0.0, 0.0, 1.0 },
  76. { 1.0, 0.0, 0.0, 1.0 },
  77. { 0.0, 1.0, 0.0, 1.0 },
  78. { 1.0, 1.0, 0.0, 1.0 },
  79. { 0.0, 0.0, 1.0, 1.0 },
  80. { 0.0, 1.0, 1.0, 1.0 },
  81. { 1.0, 0.0, 1.0, 1.0 }, // magenta
  82. { 1.0, 1.0, 1.0, 1.0 },
  83. { 1.0, 0.5, 0.0, 1.0 }, // orange
  84. { 0.5, 0.5, 0.5, 1.0 }, // grey
  85. };
  86. //===============
  87. //ColorNormalize
  88. //===============
  89. vec_t ColorNormalize( const vec_t *in, vec_t *out )
  90. {
  91. vec_t f = max( max( in[0], in[1] ), in[2] );
  92. if( f > 1.0f )
  93. {
  94. f = 1.0f / f;
  95. out[0] = in[0] * f;
  96. out[1] = in[1] * f;
  97. out[2] = in[2] * f;
  98. }
  99. else
  100. {
  101. out[0] = in[0];
  102. out[1] = in[1];
  103. out[2] = in[2];
  104. }
  105. return f;
  106. }
  107. //============================================================================
  108. void NormToLatLong( const vec3_t normal, qbyte latlong[2] )
  109. {
  110. // can't do atan2 (normal[1], normal[0])
  111. if( normal[0] == 0 && normal[1] == 0 )
  112. {
  113. if( normal[2] > 0 )
  114. {
  115. latlong[0] = 0; // acos ( 1 )
  116. latlong[1] = 0;
  117. }
  118. else
  119. {
  120. latlong[0] = 128; // acos ( -1 )
  121. latlong[1] = 0;
  122. }
  123. }
  124. else
  125. {
  126. int angle;
  127. angle = (int)( acos( normal[2] ) * 255.0 / M_TWOPI ) & 255;
  128. latlong[0] = angle;
  129. angle = (int)( atan2( normal[1], normal[0] ) * 255.0 / M_TWOPI ) & 255;
  130. latlong[1] = angle;
  131. }
  132. }
  133. void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up )
  134. {
  135. float d;
  136. // this rotate and negate guarantees a vector not colinear with the original
  137. VectorSet( right, forward[2], -forward[0], forward[1] );
  138. d = DotProduct( right, forward );
  139. VectorMA( right, -d, forward, right );
  140. VectorNormalize( right );
  141. CrossProduct( right, forward, up );
  142. }
  143. void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
  144. {
  145. float t0, t1;
  146. float c, s;
  147. vec3_t vr, vu, vf;
  148. s = DEG2RAD( degrees );
  149. c = cos( s );
  150. s = sin( s );
  151. VectorCopy( dir, vf );
  152. MakeNormalVectors( vf, vr, vu );
  153. t0 = vr[0] * c + vu[0] * -s;
  154. t1 = vr[0] * s + vu[0] * c;
  155. dst[0] = ( t0 * vr[0] + t1 * vu[0] + vf[0] * vf[0] ) * point[0]
  156. + ( t0 * vr[1] + t1 * vu[1] + vf[0] * vf[1] ) * point[1]
  157. + ( t0 * vr[2] + t1 * vu[2] + vf[0] * vf[2] ) * point[2];
  158. t0 = vr[1] * c + vu[1] * -s;
  159. t1 = vr[1] * s + vu[1] * c;
  160. dst[1] = ( t0 * vr[0] + t1 * vu[0] + vf[1] * vf[0] ) * point[0]
  161. + ( t0 * vr[1] + t1 * vu[1] + vf[1] * vf[1] ) * point[1]
  162. + ( t0 * vr[2] + t1 * vu[2] + vf[1] * vf[2] ) * point[2];
  163. t0 = vr[2] * c + vu[2] * -s;
  164. t1 = vr[2] * s + vu[2] * c;
  165. dst[2] = ( t0 * vr[0] + t1 * vu[0] + vf[2] * vf[0] ) * point[0]
  166. + ( t0 * vr[1] + t1 * vu[1] + vf[2] * vf[1] ) * point[1]
  167. + ( t0 * vr[2] + t1 * vu[2] + vf[2] * vf[2] ) * point[2];
  168. }
  169. void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up )
  170. {
  171. float angle;
  172. static float sr, sp, sy, cr, cp, cy, t;
  173. // static to help MS compiler fp bugs
  174. angle = DEG2RAD( angles[YAW] );
  175. sy = sin( angle );
  176. cy = cos( angle );
  177. angle = DEG2RAD( angles[PITCH] );
  178. sp = sin( angle );
  179. cp = cos( angle );
  180. angle = DEG2RAD( angles[ROLL] );
  181. sr = sin( angle );
  182. cr = cos( angle );
  183. if( forward )
  184. {
  185. forward[0] = cp*cy;
  186. forward[1] = cp*sy;
  187. forward[2] = -sp;
  188. }
  189. if( right )
  190. {
  191. t = sr*sp;
  192. right[0] = ( -1*t*cy+ -1*cr* -sy );
  193. right[1] = ( -1*t*sy+ -1*cr*cy );
  194. right[2] = -1*sr*cp;
  195. }
  196. if( up )
  197. {
  198. t = cr*sp;
  199. up[0] = ( t*cy+ -sr* -sy );
  200. up[1] = ( t*sy+ -sr*cy );
  201. up[2] = cr*cp;
  202. }
  203. }
  204. void VecToAngles( const vec3_t vec, vec3_t angles )
  205. {
  206. float forward;
  207. float yaw, pitch;
  208. if( vec[1] == 0 && vec[0] == 0 )
  209. {
  210. yaw = 0;
  211. if( vec[2] > 0 )
  212. pitch = 90;
  213. else
  214. pitch = 270;
  215. }
  216. else
  217. {
  218. if( vec[0] )
  219. yaw = RAD2DEG( atan2( vec[1], vec[0] ) );
  220. else if( vec[1] > 0 )
  221. yaw = 90;
  222. else
  223. yaw = -90;
  224. if( yaw < 0 )
  225. yaw += 360;
  226. forward = sqrt( vec[0]*vec[0] + vec[1]*vec[1] );
  227. pitch = RAD2DEG( atan2( vec[2], forward ) );
  228. if( pitch < 0 )
  229. pitch += 360;
  230. }
  231. angles[PITCH] = -pitch;
  232. angles[YAW] = yaw;
  233. angles[ROLL] = 0;
  234. }
  235. void AnglesToAxis( const vec3_t angles, vec3_t axis[3] )
  236. {
  237. AngleVectors( angles, axis[0], axis[1], axis[2] );
  238. VectorInverse( axis[1] );
  239. }
  240. // similar to MakeNormalVectors but for rotational matrices
  241. // (FIXME: weird, what's the diff between this and MakeNormalVectors?)
  242. void NormalVectorToAxis( const vec3_t forward, vec3_t axis[3] )
  243. {
  244. VectorCopy( forward, axis[0] );
  245. if( forward[0] || forward[1] )
  246. {
  247. VectorSet( axis[1], forward[1], -forward[0], 0 );
  248. VectorNormalize( axis[1] );
  249. CrossProduct( axis[0], axis[1], axis[2] );
  250. }
  251. else
  252. {
  253. VectorSet( axis[1], 1, 0, 0 );
  254. VectorSet( axis[2], 0, 1, 0 );
  255. }
  256. }
  257. void BuildBoxPoints( vec3_t p[8], const vec3_t org, const vec3_t mins, const vec3_t maxs )
  258. {
  259. VectorAdd( org, mins, p[0] );
  260. VectorAdd( org, maxs, p[1] );
  261. VectorSet( p[2], p[0][0], p[0][1], p[1][2] );
  262. VectorSet( p[3], p[0][0], p[1][1], p[0][2] );
  263. VectorSet( p[4], p[0][0], p[1][1], p[1][2] );
  264. VectorSet( p[5], p[1][0], p[1][1], p[0][2] );
  265. VectorSet( p[6], p[1][0], p[0][1], p[1][2] );
  266. VectorSet( p[7], p[1][0], p[0][1], p[0][2] );
  267. }
  268. void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
  269. {
  270. float d;
  271. vec3_t n;
  272. float inv_denom;
  273. inv_denom = 1.0F / DotProduct( normal, normal );
  274. d = DotProduct( normal, p ) * inv_denom;
  275. n[0] = normal[0] * inv_denom;
  276. n[1] = normal[1] * inv_denom;
  277. n[2] = normal[2] * inv_denom;
  278. dst[0] = p[0] - d * n[0];
  279. dst[1] = p[1] - d * n[1];
  280. dst[2] = p[2] - d * n[2];
  281. }
  282. //
  283. // assumes "src" is normalized
  284. //
  285. void PerpendicularVector( vec3_t dst, const vec3_t src )
  286. {
  287. int pos;
  288. int i;
  289. float minelem = 1.0F;
  290. vec3_t tempvec;
  291. //
  292. // find the smallest magnitude axially aligned vector
  293. //
  294. for( pos = 0, i = 0; i < 3; i++ )
  295. {
  296. if( fabs( src[i] ) < minelem )
  297. {
  298. pos = i;
  299. minelem = fabs( src[i] );
  300. }
  301. }
  302. tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
  303. tempvec[pos] = 1.0F;
  304. //
  305. // project the point onto the plane defined by src
  306. //
  307. ProjectPointOnPlane( dst, tempvec, src );
  308. //
  309. // normalize the result
  310. //
  311. VectorNormalize( dst );
  312. }
  313. //============================================================================
  314. float Q_RSqrt( float number )
  315. {
  316. int i;
  317. float x2, y;
  318. if( number == 0.0 )
  319. return 0.0;
  320. x2 = number * 0.5f;
  321. y = number;
  322. i = *(int *) &y; // evil floating point bit level hacking
  323. i = 0x5f3759df - ( i >> 1 ); // what the fuck?
  324. y = *(float *) &i;
  325. y = y * ( 1.5f - ( x2 * y * y ) ); // this can be done a second time
  326. return y;
  327. }
  328. int Q_rand( int *seed )
  329. {
  330. *seed = *seed * 1103515245 + 12345;
  331. return ( (unsigned int)( *seed / 65536 ) % 32768 );
  332. }
  333. //===============
  334. //LerpAngle
  335. //
  336. //===============
  337. float LerpAngle( float a2, float a1, const float frac )
  338. {
  339. if( a1 - a2 > 180 )
  340. a1 -= 360;
  341. if( a1 - a2 < -180 )
  342. a1 += 360;
  343. return a2 + frac * ( a1 - a2 );
  344. }
  345. //=================
  346. //AngleSubtract
  347. //
  348. //Always returns a value from -180 to 180
  349. //=================
  350. float AngleSubtract( float a1, float a2 )
  351. {
  352. float a;
  353. a = a1 - a2;
  354. while( a > 180 )
  355. {
  356. a -= 360;
  357. }
  358. while( a < -180 )
  359. {
  360. a += 360;
  361. }
  362. return a;
  363. }
  364. //=================
  365. //AnglesSubtract
  366. //
  367. //Always returns a value from -180 to 180
  368. //=================
  369. void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 )
  370. {
  371. v3[0] = AngleSubtract( v1[0], v2[0] );
  372. v3[1] = AngleSubtract( v1[1], v2[1] );
  373. v3[2] = AngleSubtract( v1[2], v2[2] );
  374. }
  375. //=================
  376. //AngleNormalize360
  377. //
  378. //returns angle normalized to the range [0 <= angle < 360]
  379. //=================
  380. float AngleNormalize360( float angle )
  381. {
  382. return ( 360.0 / 65536 ) * ( (int)( angle * ( 65536 / 360.0 ) ) & 65535 );
  383. }
  384. //=================
  385. //AngleNormalize180
  386. //
  387. //returns angle normalized to the range [-180 < angle <= 180]
  388. //=================
  389. float AngleNormalize180( float angle )
  390. {
  391. angle = AngleNormalize360( angle );
  392. if( angle > 180.0 )
  393. {
  394. angle -= 360.0;
  395. }
  396. return angle;
  397. }
  398. //=================
  399. //AngleDelta
  400. //
  401. //returns the normalized delta from angle1 to angle2
  402. //=================
  403. float AngleDelta( float angle1, float angle2 )
  404. {
  405. return AngleNormalize180( angle1 - angle2 );
  406. }
  407. //=================
  408. //anglemod
  409. //=================
  410. float anglemod( float a )
  411. {
  412. a = ( 360.0/65536 ) * ( (int)( a*( 65536/360.0 ) ) & 65535 );
  413. return a;
  414. }
  415. //====================
  416. //CalcFov
  417. //====================
  418. float CalcFov( float fov_x, float width, float height )
  419. {
  420. float x;
  421. if( fov_x < 1 || fov_x > 179 )
  422. Sys_Error( "Bad fov: %f", fov_x );
  423. x = width/tan( fov_x/360*M_PI );
  424. return atan( height/x )*360/M_PI;
  425. }
  426. //====================
  427. //AdjustFov
  428. //====================
  429. void AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x )
  430. {
  431. float x, y;
  432. if( width*3 == 4*height || width*4 == height*5 )
  433. { // 4:3 or 5:4 ratio
  434. return;
  435. }
  436. if( lock_x )
  437. {
  438. *fov_y = 2 *atan( ( width *3 ) / ( height *4 ) *tan ( *fov_y *M_PI / 360.0 *0.5 ) )*360/M_PI;
  439. return;
  440. }
  441. y = CalcFov( *fov_x, 640, 480 );
  442. x = *fov_x;
  443. *fov_x = CalcFov( y, height, width );
  444. if( *fov_x < x )
  445. *fov_x = x;
  446. else
  447. *fov_y = y;
  448. }
  449. //==================
  450. //BoxOnPlaneSide
  451. //
  452. //Returns 1, 2, or 1 + 2
  453. //==================
  454. int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const struct cplane_s *p )
  455. {
  456. float dist1, dist2;
  457. int sides;
  458. // general case
  459. switch( p->signbits )
  460. {
  461. case 0:
  462. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  463. dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  464. break;
  465. case 1:
  466. dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  467. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  468. break;
  469. case 2:
  470. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  471. dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  472. break;
  473. case 3:
  474. dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  475. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  476. break;
  477. case 4:
  478. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  479. dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  480. break;
  481. case 5:
  482. dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  483. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  484. break;
  485. case 6:
  486. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  487. dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  488. break;
  489. case 7:
  490. dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  491. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  492. break;
  493. default:
  494. dist1 = dist2 = 0; // shut up compiler
  495. assert( 0 );
  496. break;
  497. }
  498. sides = 0;
  499. if( dist1 >= p->dist )
  500. sides = 1;
  501. if( dist2 < p->dist )
  502. sides |= 2;
  503. #if 0
  504. assert( sides != 0 );
  505. #endif
  506. return sides;
  507. }
  508. //=================
  509. //SignbitsForPlane
  510. //=================
  511. int SignbitsForPlane( const cplane_t *out )
  512. {
  513. int bits, j;
  514. // for fast box on planeside test
  515. bits = 0;
  516. for( j = 0; j < 3; j++ )
  517. {
  518. if( out->normal[j] < 0 )
  519. bits |= 1<<j;
  520. }
  521. return bits;
  522. }
  523. //=================
  524. //PlaneTypeForNormal
  525. //=================
  526. int PlaneTypeForNormal( const vec3_t normal )
  527. {
  528. // NOTE: should these have an epsilon around 1.0?
  529. if( normal[0] >= 1.0 )
  530. return PLANE_X;
  531. if( normal[1] >= 1.0 )
  532. return PLANE_Y;
  533. if( normal[2] >= 1.0 )
  534. return PLANE_Z;
  535. return PLANE_NONAXIAL;
  536. }
  537. //=================
  538. //CategorizePlane
  539. //
  540. //A slightly more complex version of SignbitsForPlane and PlaneTypeForNormal,
  541. //which also tries to fix possible floating point glitches (like -0.00000 cases)
  542. //=================
  543. void CategorizePlane( cplane_t *plane )
  544. {
  545. int i;
  546. plane->signbits = 0;
  547. plane->type = PLANE_NONAXIAL;
  548. for( i = 0; i < 3; i++ )
  549. {
  550. if( plane->normal[i] < 0 )
  551. {
  552. plane->signbits |= 1<<i;
  553. if( plane->normal[i] == -1.0f )
  554. {
  555. plane->signbits = ( 1<<i );
  556. VectorClear( plane->normal );
  557. plane->normal[i] = -1.0f;
  558. break;
  559. }
  560. }
  561. else if( plane->normal[i] == 1.0f )
  562. {
  563. plane->type = i;
  564. plane->signbits = 0;
  565. VectorClear( plane->normal );
  566. plane->normal[i] = 1.0f;
  567. break;
  568. }
  569. }
  570. }
  571. //=================
  572. //PlaneFromPoints
  573. //=================
  574. void PlaneFromPoints( vec3_t verts[3], cplane_t *plane )
  575. {
  576. vec3_t v1, v2;
  577. VectorSubtract( verts[1], verts[0], v1 );
  578. VectorSubtract( verts[2], verts[0], v2 );
  579. CrossProduct( v2, v1, plane->normal );
  580. VectorNormalize( plane->normal );
  581. plane->dist = DotProduct( verts[0], plane->normal );
  582. }
  583. #define PLANE_NORMAL_EPSILON 0.00001
  584. #define PLANE_DIST_EPSILON 0.01
  585. //=================
  586. //ComparePlanes
  587. //=================
  588. qboolean ComparePlanes( const vec3_t p1normal, vec_t p1dist, const vec3_t p2normal, vec_t p2dist )
  589. {
  590. if( fabs( p1normal[0] - p2normal[0] ) < PLANE_NORMAL_EPSILON
  591. && fabs( p1normal[1] - p2normal[1] ) < PLANE_NORMAL_EPSILON
  592. && fabs( p1normal[2] - p2normal[2] ) < PLANE_NORMAL_EPSILON
  593. && fabs( p1dist - p2dist ) < PLANE_DIST_EPSILON )
  594. return qtrue;
  595. return qfalse;
  596. }
  597. //==============
  598. //SnapVector
  599. //==============
  600. void SnapVector( vec3_t normal )
  601. {
  602. int i;
  603. for( i = 0; i < 3; i++ )
  604. {
  605. if( fabs( normal[i] - 1 ) < PLANE_NORMAL_EPSILON )
  606. {
  607. VectorClear( normal );
  608. normal[i] = 1;
  609. break;
  610. }
  611. if( fabs( normal[i] - -1 ) < PLANE_NORMAL_EPSILON )
  612. {
  613. VectorClear( normal );
  614. normal[i] = -1;
  615. break;
  616. }
  617. }
  618. }
  619. //==============
  620. //SnapPlane
  621. //==============
  622. void SnapPlane( vec3_t normal, vec_t *dist )
  623. {
  624. SnapVector( normal );
  625. if( fabs( *dist - Q_rint( *dist ) ) < PLANE_DIST_EPSILON )
  626. {
  627. *dist = Q_rint( *dist );
  628. }
  629. }
  630. void ClearBounds( vec3_t mins, vec3_t maxs )
  631. {
  632. mins[0] = mins[1] = mins[2] = 99999;
  633. maxs[0] = maxs[1] = maxs[2] = -99999;
  634. }
  635. qboolean BoundsIntersect( const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2 )
  636. {
  637. return (qboolean)( mins1[0] <= maxs2[0] && mins1[1] <= maxs2[1] && mins1[2] <= maxs2[2] &&
  638. maxs1[0] >= mins2[0] && maxs1[1] >= mins2[1] && maxs1[2] >= mins2[2] );
  639. }
  640. qboolean BoundsAndSphereIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t centre, float radius )
  641. {
  642. int i;
  643. float dmin = 0;
  644. float radius2 = radius * radius;
  645. for( i = 0; i < 3; i++ )
  646. {
  647. if( centre[i] < mins[i] )
  648. dmin += ( centre[i] - mins[i] ) * ( centre[i] - mins[i] );
  649. else if( centre[i] > maxs[i] )
  650. dmin += ( centre[i] - maxs[i] ) * ( centre[i] - maxs[i] );
  651. }
  652. if( dmin <= radius2 )
  653. return qtrue;
  654. return qfalse;
  655. }
  656. void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs )
  657. {
  658. int i;
  659. vec_t val;
  660. for( i = 0; i < 3; i++ )
  661. {
  662. val = v[i];
  663. if( val < mins[i] )
  664. mins[i] = val;
  665. if( val > maxs[i] )
  666. maxs[i] = val;
  667. }
  668. }
  669. //=================
  670. //RadiusFromBounds
  671. //=================
  672. float RadiusFromBounds( const vec3_t mins, const vec3_t maxs )
  673. {
  674. int i;
  675. vec3_t corner;
  676. for( i = 0; i < 3; i++ )
  677. {
  678. corner[i] = fabs( mins[i] ) > fabs( maxs[i] ) ? fabs( mins[i] ) : fabs( maxs[i] );
  679. }
  680. return VectorLength( corner );
  681. }
  682. vec_t VectorNormalize( vec3_t v )
  683. {
  684. float length, ilength;
  685. length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  686. if( length )
  687. {
  688. length = sqrt( length ); // FIXME
  689. ilength = 1.0/length;
  690. v[0] *= ilength;
  691. v[1] *= ilength;
  692. v[2] *= ilength;
  693. }
  694. return length;
  695. }
  696. vec_t VectorNormalize2( const vec3_t v, vec3_t out )
  697. {
  698. float length, ilength;
  699. length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  700. if( length )
  701. {
  702. length = sqrt( length ); // FIXME
  703. ilength = 1.0/length;
  704. out[0] = v[0]*ilength;
  705. out[1] = v[1]*ilength;
  706. out[2] = v[2]*ilength;
  707. }
  708. else
  709. {
  710. VectorClear( out );
  711. }
  712. return length;
  713. }
  714. // fast vector normalize routine that does not check to make sure
  715. // that length != 0, nor does it return length, uses rsqrt approximation
  716. void VectorNormalizeFast( vec3_t v )
  717. {
  718. float ilength = Q_RSqrt( DotProduct( v, v ) );
  719. v[0] *= ilength;
  720. v[1] *= ilength;
  721. v[2] *= ilength;
  722. }
  723. void _VectorMA( const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc )
  724. {
  725. vecc[0] = veca[0] + scale*vecb[0];
  726. vecc[1] = veca[1] + scale*vecb[1];
  727. vecc[2] = veca[2] + scale*vecb[2];
  728. }
  729. vec_t _DotProduct( const vec3_t v1, const vec3_t v2 )
  730. {
  731. return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
  732. }
  733. void _VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out )
  734. {
  735. out[0] = veca[0]-vecb[0];
  736. out[1] = veca[1]-vecb[1];
  737. out[2] = veca[2]-vecb[2];
  738. }
  739. void _VectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out )
  740. {
  741. out[0] = veca[0]+vecb[0];
  742. out[1] = veca[1]+vecb[1];
  743. out[2] = veca[2]+vecb[2];
  744. }
  745. void _VectorCopy( const vec3_t in, vec3_t out )
  746. {
  747. out[0] = in[0];
  748. out[1] = in[1];
  749. out[2] = in[2];
  750. }
  751. int Q_log2( int val )
  752. {
  753. int answer = 0;
  754. while( val >>= 1 )
  755. answer++;
  756. return answer;
  757. }
  758. //============================================================================
  759. void Matrix_Identity( vec3_t m[3] )
  760. {
  761. int i, j;
  762. for( i = 0; i < 3; i++ )
  763. for( j = 0; j < 3; j++ )
  764. if( i == j )
  765. m[i][j] = 1.0;
  766. else
  767. m[i][j] = 0.0;
  768. }
  769. void Matrix_Copy( vec3_t m1[3], vec3_t m2[3] )
  770. {
  771. int i, j;
  772. for( i = 0; i < 3; i++ )
  773. for( j = 0; j < 3; j++ )
  774. m2[i][j] = m1[i][j];
  775. }
  776. qboolean Matrix_Compare( vec3_t m1[3], vec3_t m2[3] )
  777. {
  778. int i, j;
  779. for( i = 0; i < 3; i++ )
  780. for( j = 0; j < 3; j++ )
  781. if( m1[i][j] != m2[i][j] )
  782. return qfalse;
  783. return qtrue;
  784. }
  785. void Matrix_Multiply( vec3_t m1[3], vec3_t m2[3], vec3_t out[3] )
  786. {
  787. out[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0];
  788. out[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1];
  789. out[0][2] = m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2];
  790. out[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0];
  791. out[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1];
  792. out[1][2] = m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2];
  793. out[2][0] = m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0];
  794. out[2][1] = m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1];
  795. out[2][2] = m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2];
  796. }
  797. void Matrix_TransformVector( vec3_t m[3], vec3_t v, vec3_t out )
  798. {
  799. out[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];
  800. out[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];
  801. out[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];
  802. }
  803. void Matrix_Transpose( vec3_t in[3], vec3_t out[3] )
  804. {
  805. out[0][0] = in[0][0];
  806. out[1][1] = in[1][1];
  807. out[2][2] = in[2][2];
  808. out[0][1] = in[1][0];
  809. out[0][2] = in[2][0];
  810. out[1][0] = in[0][1];
  811. out[1][2] = in[2][1];
  812. out[2][0] = in[0][2];
  813. out[2][1] = in[1][2];
  814. }
  815. void Matrix_EulerAngles( vec3_t m[3], vec3_t angles )
  816. {
  817. vec_t c;
  818. vec_t pitch, yaw, roll;
  819. pitch = -asin( m[0][2] );
  820. c = cos( pitch );
  821. if( fabs( c ) > 5*10e-6 ) // Gimball lock?
  822. { // no
  823. c = 1.0f / c;
  824. pitch = RAD2DEG( pitch );
  825. yaw = RAD2DEG( atan2( m[0][1] * c, m[0][0] * c ) );
  826. roll = RAD2DEG( atan2( -m[1][2] * c, m[2][2] * c ) );
  827. }
  828. else
  829. { // yes
  830. pitch = m[0][2] > 0 ? -90 : 90;
  831. yaw = RAD2DEG( atan2( m[1][0], -m[1][1] ) );
  832. roll = 180;
  833. }
  834. angles[PITCH] = pitch;
  835. angles[YAW] = yaw;
  836. angles[ROLL] = roll;
  837. }
  838. void Matrix_Rotate( vec3_t m[3], vec_t angle, vec_t x, vec_t y, vec_t z )
  839. {
  840. vec3_t t[3], b[3];
  841. vec_t c = cos( DEG2RAD( angle ) );
  842. vec_t s = sin( DEG2RAD( angle ) );
  843. vec_t mc = 1 - c, t1, t2;
  844. t[0][0] = ( x * x * mc ) + c;
  845. t[1][1] = ( y * y * mc ) + c;
  846. t[2][2] = ( z * z * mc ) + c;
  847. t1 = y * x * mc;
  848. t2 = z * s;
  849. t[0][1] = t1 + t2;
  850. t[1][0] = t1 - t2;
  851. t1 = x * z * mc;
  852. t2 = y * s;
  853. t[0][2] = t1 - t2;
  854. t[2][0] = t1 + t2;
  855. t1 = y * z * mc;
  856. t2 = x * s;
  857. t[1][2] = t1 + t2;
  858. t[2][1] = t1 - t2;
  859. Matrix_Copy( m, b );
  860. Matrix_Multiply( b, t, m );
  861. }
  862. void Matrix_FromPoints( vec3_t v1, vec3_t v2, vec3_t v3, vec3_t m[3] )
  863. {
  864. float d;
  865. m[2][0] = ( v1[1] - v2[1] ) * ( v3[2] - v2[2] ) - ( v1[2] - v2[2] ) * ( v3[1] - v2[1] );
  866. m[2][1] = ( v1[2] - v2[2] ) * ( v3[0] - v2[0] ) - ( v1[0] - v2[0] ) * ( v3[2] - v2[2] );
  867. m[2][2] = ( v1[0] - v2[0] ) * ( v3[1] - v2[1] ) - ( v1[1] - v2[1] ) * ( v3[0] - v2[0] );
  868. VectorNormalizeFast( m[2] );
  869. // this rotate and negate guarantees a vector not colinear with the original
  870. VectorSet( m[1], m[2][2], -m[2][0], m[2][1] );
  871. d = -DotProduct( m[1], m[2] );
  872. VectorMA( m[1], d, m[2], m[1] );
  873. VectorNormalizeFast( m[1] );
  874. CrossProduct( m[1], m[2], m[0] );
  875. }
  876. //============================================================================
  877. void Quat_Identity( quat_t q )
  878. {
  879. q[0] = 0;
  880. q[1] = 0;
  881. q[2] = 0;
  882. q[3] = 1;
  883. }
  884. void Quat_Copy( const quat_t q1, quat_t q2 )
  885. {
  886. q2[0] = q1[0];
  887. q2[1] = q1[1];
  888. q2[2] = q1[2];
  889. q2[3] = q1[3];
  890. }
  891. qboolean Quat_Compare( const quat_t q1, const quat_t q2 )
  892. {
  893. if( q1[0] != q2[0] || q1[1] != q2[1] || q1[2] != q2[2] || q1[3] != q2[3] )
  894. return qfalse;
  895. return qtrue;
  896. }
  897. void Quat_Conjugate( const quat_t q1, quat_t q2 )
  898. {
  899. q2[0] = -q1[0];
  900. q2[1] = -q1[1];
  901. q2[2] = -q1[2];
  902. q2[3] = q1[3];
  903. }
  904. vec_t Quat_Normalize( quat_t q )
  905. {
  906. vec_t length;
  907. length = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
  908. if( length != 0 )
  909. {
  910. vec_t ilength = 1.0 / sqrt( length );
  911. q[0] *= ilength;
  912. q[1] *= ilength;
  913. q[2] *= ilength;
  914. q[3] *= ilength;
  915. }
  916. return length;
  917. }
  918. vec_t Quat_Inverse( const quat_t q1, quat_t q2 )
  919. {
  920. Quat_Conjugate( q1, q2 );
  921. return Quat_Normalize( q2 );
  922. }
  923. void Matrix_Quat( vec3_t m[3], quat_t q )
  924. {
  925. vec_t tr, s;
  926. tr = m[0][0] + m[1][1] + m[2][2];
  927. if( tr > 0.00001 )
  928. {
  929. s = sqrt( tr + 1.0 );
  930. q[3] = s * 0.5; s = 0.5 / s;
  931. q[0] = ( m[2][1] - m[1][2] ) * s;
  932. q[1] = ( m[0][2] - m[2][0] ) * s;
  933. q[2] = ( m[1][0] - m[0][1] ) * s;
  934. }
  935. else
  936. {
  937. int i, j, k;
  938. i = 0;
  939. if( m[1][1] > m[0][0] ) i = 1;
  940. if( m[2][2] > m[i][i] ) i = 2;
  941. j = ( i + 1 ) % 3;
  942. k = ( i + 2 ) % 3;
  943. s = sqrt( m[i][i] - ( m[j][j] + m[k][k] ) + 1.0 );
  944. q[i] = s * 0.5; if( s != 0.0 ) s = 0.5 / s;
  945. q[j] = ( m[j][i] + m[i][j] ) * s;
  946. q[k] = ( m[k][i] + m[i][k] ) * s;
  947. q[3] = ( m[k][j] - m[j][k] ) * s;
  948. }
  949. Quat_Normalize( q );
  950. }
  951. void Quat_Multiply( const quat_t q1, const quat_t q2, quat_t out )
  952. {
  953. out[0] = q1[3] * q2[0] + q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1];
  954. out[1] = q1[3] * q2[1] + q1[1] * q2[3] + q1[2] * q2[0] - q1[0] * q2[2];
  955. out[2] = q1[3] * q2[2] + q1[2] * q2[3] + q1[0] * q2[1] - q1[1] * q2[0];
  956. out[3] = q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2];
  957. }
  958. void Quat_Lerp( const quat_t q1, const quat_t q2, vec_t t, quat_t out )
  959. {
  960. quat_t p1;
  961. vec_t omega, cosom, sinom, scale0, scale1, sinsqr;
  962. if( Quat_Compare( q1, q2 ) )
  963. {
  964. Quat_Copy( q1, out );
  965. return;
  966. }
  967. cosom = q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3];
  968. if( cosom < 0.0 )
  969. {
  970. cosom = -cosom;
  971. p1[0] = -q1[0]; p1[1] = -q1[1];
  972. p1[2] = -q1[2]; p1[3] = -q1[3];
  973. }
  974. else
  975. {
  976. p1[0] = q1[0]; p1[1] = q1[1];
  977. p1[2] = q1[2]; p1[3] = q1[3];
  978. }
  979. if( cosom < 1.0 - 0.0001 )
  980. {
  981. sinsqr = 1.0 - cosom * cosom;
  982. sinom = Q_RSqrt( sinsqr );
  983. omega = atan2( sinsqr * sinom, cosom );
  984. scale0 = sin( ( 1.0 - t ) * omega ) * sinom;
  985. scale1 = sin( t * omega ) * sinom;
  986. }
  987. else
  988. {
  989. scale0 = 1.0 - t;
  990. scale1 = t;
  991. }
  992. out[0] = scale0 * p1[0] + scale1 * q2[0];
  993. out[1] = scale0 * p1[1] + scale1 * q2[1];
  994. out[2] = scale0 * p1[2] + scale1 * q2[2];
  995. out[3] = scale0 * p1[3] + scale1 * q2[3];
  996. }
  997. void Quat_Vectors( const quat_t q, vec3_t f, vec3_t r, vec3_t u )
  998. {
  999. vec_t wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
  1000. x2 = q[0] + q[0]; y2 = q[1] + q[1]; z2 = q[2] + q[2];
  1001. xx = q[0] * x2; yy = q[1] * y2; zz = q[2] * z2;
  1002. f[0] = 1.0f - yy - zz; r[1] = 1.0f - xx - zz; u[2] = 1.0f - xx - yy;
  1003. yz = q[1] * z2; wx = q[3] * x2;
  1004. r[2] = yz - wx; u[1] = yz + wx;
  1005. xy = q[0] * y2; wz = q[3] * z2;
  1006. f[1] = xy - wz; r[0] = xy + wz;
  1007. xz = q[0] * z2; wy = q[3] * y2;
  1008. f[2] = xz + wy; u[0] = xz - wy;
  1009. }
  1010. void Quat_Matrix( const quat_t q, vec3_t m[3] )
  1011. {
  1012. Quat_Vectors( q, m[0], m[1], m[2] );
  1013. }
  1014. void Quat_TransformVector( const quat_t q, const vec3_t v, vec3_t out )
  1015. {
  1016. vec_t wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
  1017. x2 = q[0] + q[0]; y2 = q[1] + q[1]; z2 = q[2] + q[2];
  1018. xx = q[0] * x2; xy = q[0] * y2; xz = q[0] * z2;
  1019. yy = q[1] * y2; yz = q[1] * z2; zz = q[2] * z2;
  1020. wx = q[3] * x2; wy = q[3] * y2; wz = q[3] * z2;
  1021. out[0] = ( 1.0f - yy - zz ) * v[0] + ( xy - wz ) * v[1] + ( xz + wy ) * v[2];
  1022. out[1] = ( xy + wz ) * v[0] + ( 1.0f - xx - zz ) * v[1] + ( yz - wx ) * v[2];
  1023. out[2] = ( xz - wy ) * v[0] + ( yz + wx ) * v[1] + ( 1.0f - xx - yy ) * v[2];
  1024. }
  1025. void Quat_ConcatTransforms( const quat_t q1, const vec3_t v1, const quat_t q2, const vec3_t v2, quat_t q, vec3_t v )
  1026. {
  1027. Quat_Multiply( q1, q2, q );
  1028. Quat_TransformVector( q1, v2, v );
  1029. v[0] += v1[0]; v[1] += v1[1]; v[2] += v1[2];
  1030. }