UFO: Alien Invasion
Doxygen documentation generating
mathlib.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 1997-2001 Id Software, Inc.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "mathlib.h"
27 #include "../common/common.h"
28 #include <algorithm>
29 
30 #ifndef logf
31 #define logf(x) ((float)log((double)(x)))
32 #endif
33 
34 const vec2_t vec2_origin = { 0, 0 };
35 const vec3_t vec3_origin = { 0, 0, 0 };
36 const vec4_t vec4_origin = { 0, 0, 0, 0 };
37 const pos3_t pos3_origin = { 0, 0, 0 };
38 
40 #define RT2 0.70710678118654752440084436210485
41 
43 
59  { 1, 0, 0, 0}, /* E */
60  {-1, 0, 0, 0}, /* W */
61  { 0, 1, 0, 0}, /* N */
62  { 0, -1, 0, 0}, /* S */
63  { 1, 1, 0, 0}, /* NE */
64  {-1, -1, 0, 0}, /* SW */
65  {-1, 1, 0, 0}, /* NW */
66  { 1, -1, 0, 0}, /* SE */
67  { 0, 0, 1, 0}, /* CLIMB UP */
68  { 0, 0, -1, 0}, /* CLIMB DOWN */
69  { 0, 0, 0, -1}, /* STAND UP */
70  { 0, 0, 0, 1}, /* STAND DOWN */
71  { 0, 0, 0, 0}, /* UNDEFINED OPPOSITE OF FALL DOWN */
72  { 0, 0, -1, 0}, /* FALL DOWN */
73  { 0, 0, 0, 0}, /* UNDEFINED */
74  { 0, 0, 0, 0}, /* UNDEFINED */
75  { 1, 0, 1, 0}, /* UP E (Fliers only)*/
76  {-1, 0, 1, 0}, /* UP W (Fliers only) */
77  { 0, 1, 1, 0}, /* UP N (Fliers only) */
78  { 0, -1, 1, 0}, /* UP S (Fliers only) */
79  { 1, 1, 1, 0}, /* UP NE (Fliers only) */
80  {-1, -1, 1, 0}, /* UP SW (Fliers only) */
81  {-1, 1, 1, 0}, /* UP NW (Fliers only) */
82  { 1, -1, 1, 0}, /* UP SE (Fliers only) */
83  { 1, 0, 0, 0}, /* E (Fliers only)*/
84  {-1, 0, 0, 0}, /* W (Fliers only) */
85  { 0, 1, 0, 0}, /* N (Fliers only) */
86  { 0, -1, 0, 0}, /* S (Fliers only) */
87  { 1, 1, 0, 0}, /* NE (Fliers only) */
88  {-1, -1, 0, 0}, /* SW (Fliers only) */
89  {-1, 1, 0, 0}, /* NW (Fliers only) */
90  { 1, -1, 0, 0}, /* SE (Fliers only) */
91  { 1, 0, -1, 0}, /* DOWN E (Fliers only) */
92  {-1, 0, -1, 0}, /* DOWN W (Fliers only) */
93  { 0, 1, -1, 0}, /* DOWN N (Fliers only) */
94  { 0, -1, -1, 0}, /* DOWN S (Fliers only) */
95  { 1, 1, -1, 0}, /* DOWN NE (Fliers only) */
96  {-1, -1, -1, 0}, /* DOWN SW (Fliers only) */
97  {-1, 1, -1, 0}, /* DOWN NW (Fliers only) */
98  { 1, -1, -1, 0}, /* DOWN SE (Fliers only) */
99  };
100 
101 /* 0:E 1:W 2:N 3:S 4:NE 5:SW 6:NW 7:SE */
102 const float dvecsn[CORE_DIRECTIONS][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, {RT2, RT2}, {-RT2, -RT2}, {-RT2, RT2}, {RT2, -RT2} };
104 /* 0:E 1: W 2:N 3:S 4:NE 5:SW 6:NW 7:SE */
105 const float directionAngles[CORE_DIRECTIONS] = { 0, 180.0f, 90.0f, 270.0f, 45.0f, 225.0f, 135.0f, 315.0f };
106 
107 #define DIRECTION_EAST 0
108 #define DIRECTION_WEST 1
109 #define DIRECTION_NORTH 2
110 #define DIRECTION_SOUTH 3
111 #define DIRECTION_NORTHEAST 4
112 #define DIRECTION_SOUTHWEST 5
113 #define DIRECTION_NORTHWEST 6
114 #define DIRECTION_SOUTHEAST 7
115 
122 
123 
130 int AngleToDir (int angle)
131 {
132  angle += 22;
133  /* set angle between 0 <= angle < 360 */
134  angle %= 360;
135  /* next step is because the result of angle %= 360 when angle is negative depends of the compiler
136  * (it can be between -360 < angle <= 0 or 0 <= angle < 360) */
137  if (angle < 0)
138  angle += 360;
139 
140  /* get an integer quotient */
141  angle /= 45;
142 
143  if (angle >= 0 && angle < CORE_DIRECTIONS) {
144  static const int anglesToDV[8] = {0, 4, 2, 6, 1, 5, 3, 7};
145  return anglesToDV[angle];
146  }
147 
148  /* This is the default for unknown values. */
149  Com_Printf("Error in AngleToDV: shouldn't have reached this line\n");
150  return 0;
151 }
152 
156 vec_t Q_rint (const vec_t in)
157 {
158  /* round x down to the nearest integer */
159  return floor(in + 0.5);
160 }
161 
171 double GetDistanceOnGlobe (const vec2_t pos1, const vec2_t pos2)
172 {
173  /* convert into rad */
174  const double latitude1 = pos1[1] * torad;
175  const double latitude2 = pos2[1] * torad;
176  const double deltaLongitude = (pos1[0] - pos2[0]) * torad;
177  double distance;
178 
179  distance = cos(latitude1) * cos(latitude2) * cos(deltaLongitude) + sin(latitude1) * sin(latitude2);
180  distance = std::min(std::max(-1.0, distance), 1.0);
181  distance = acos(distance) * todeg;
182 
183  assert(distance >= 0.0);
184  return distance;
185 }
186 
191 {
192  float max;
193 
194  /* find the brightest component */
195  max = in[0];
196  if (in[1] > max)
197  max = in[1];
198  if (in[2] > max)
199  max = in[2];
200 
201  /* avoid FPE */
202  if (EQUAL(max, 0.0f)) {
203  VectorClear(out);
204  return 0;
205  }
206 
207  VectorScale(in, 1.0f / max, out);
208 
209  return max;
210 }
211 
219 bool VectorNearer (const vec3_t v1, const vec3_t v2, const vec3_t comp)
220 {
221  vec3_t d1, d2;
222 
223  VectorSubtract(comp, v1, d1);
224  VectorSubtract(comp, v2, d2);
225 
226  return VectorLength(d1) < VectorLength(d2);
227 }
228 
238 {
239  float length;
240 
241  length = DotProduct(v, v);
242  length = sqrt(length);
244  if (!EQUAL(length, 0.0f)) {
245  const float ilength = 1.0f / length;
246  out[0] = v[0] * ilength;
247  out[1] = v[1] * ilength;
248  out[2] = v[2] * ilength;
249  }
250 
251  return length;
252 }
253 
261 void VectorMA (const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
262 {
263  outVector[0] = veca[0] + scale * vecb[0];
264  outVector[1] = veca[1] + scale * vecb[1];
265  outVector[2] = veca[2] + scale * vecb[2];
266 }
267 
268 void VectorClampMA (vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc)
269 {
270  int i;
271 
272  /* clamp veca to bounds */
273  for (i = 0; i < 3; i++)
274  if (veca[i] > 4094.0)
275  veca[i] = 4094.0;
276  else if (veca[i] < -4094.0)
277  veca[i] = -4094.0;
278 
279  /* rescale to fit */
280  for (i = 0; i < 3; i++) {
281  const float test = veca[i] + scale * vecb[i];
282  if (test < -4095.0f) {
283  const float newScale = (-4094.0 - veca[i]) / vecb[i];
284  if (fabs(newScale) < fabs(scale))
285  scale = newScale;
286  } else if (test > 4095.0f) {
287  const float newScale = (4094.0 - veca[i]) / vecb[i];
288  if (fabs(newScale) < fabs(scale))
289  scale = newScale;
290  }
291  }
292 
293  /* use rescaled scale */
294  VectorMA(veca, scale, vecb, vecc);
295 }
296 
304 void MatrixMultiply (const vec3_t a[3], const vec3_t b[3], vec3_t c[3])
305 {
306  c[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2];
307  c[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2];
308  c[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2];
309 
310  c[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2];
311  c[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2];
312  c[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2];
313 
314  c[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2];
315  c[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2];
316  c[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2];
317 }
318 
325 void GLMatrixAssemble (const vec3_t origin, const vec3_t angles, float* matrix)
326 {
327  /* fill in edge values */
328  matrix[3] = matrix[7] = matrix[11] = 0.0;
329  matrix[15] = 1.0;
330 
331  /* add rotation */
332  AngleVectors(angles, &matrix[0], &matrix[4], &matrix[8]);
333  /* flip an axis */
334  VectorInverse(&matrix[4]);
335 
336  /* add translation */
337  matrix[12] = origin[0];
338  matrix[13] = origin[1];
339  matrix[14] = origin[2];
340 }
341 
350 void GLMatrixMultiply (const float a[16], const float b[16], float c[16])
351 {
352  for (int j = 0; j < 4; j++) {
353  int k = j * 4;
354  for (int i = 0; i < 4; i++)
355  c[i + k] = a[i] * b[k] + a[i + 4] * b[k + 1] + a[i + 8] * b[k + 2] + a[i + 12] * b[k + 3];
356  }
357 }
358 
366 void GLVectorTransform (const float m[16], const vec4_t in, vec4_t out)
367 {
368  for (int i = 0; i < 4; i++)
369  out[i] = m[i] * in[0] + m[i + 4] * in[1] + m[i + 8] * in[2] + m[i + 12] * in[3];
370 }
371 
380 void GLPositionTransform (const float m[16], const vec3_t in, vec3_t out)
381 {
382  for (int i = 0; i < 3; i++)
383  out[i] = m[i] * in[0] + m[i + 4] * in[1] + m[i + 8] * in[2] + m[i + 12];
384 }
385 
395 void VectorRotate (vec3_t m[3], const vec3_t va, vec3_t vb)
396 {
397  vb[0] = m[0][0] * va[0] + m[1][0] * va[1] + m[2][0] * va[2];
398  vb[1] = m[0][1] * va[0] + m[1][1] * va[1] + m[2][1] * va[2];
399  vb[2] = m[0][2] * va[0] + m[1][2] * va[1] + m[2][2] * va[2];
400 }
401 
413 int VectorCompareEps (const vec3_t v1, const vec3_t v2, float epsilon)
414 {
415  vec3_t d;
416 
417  VectorSubtract(v1, v2, d);
418  d[0] = fabs(d[0]);
419  d[1] = fabs(d[1]);
420  d[2] = fabs(d[2]);
421 
422  if (d[0] > epsilon || d[1] > epsilon || d[2] > epsilon)
423  return 0;
424 
425  return 1;
426 }
427 
435 {
436  return sqrtf(DotProduct(v, v));
437 }
438 
447 void VectorMix (const vec3_t v1, const vec3_t v2, float mix, vec3_t out)
448 {
449  const float number = 1.0 - mix;
450 
451  out[0] = v1[0] * number + v2[0] * mix;
452  out[1] = v1[1] * number + v2[1] * mix;
453  out[2] = v1[2] * number + v2[2] * mix;
454 }
455 
461 {
462  v[0] = -v[0];
463  v[1] = -v[1];
464  v[2] = -v[2];
465 }
466 
473 void VectorMidpoint (const vec3_t point1, const vec3_t point2, vec3_t midpoint)
474 {
475  VectorAdd(point1, point2, midpoint);
476  VectorScale(midpoint, 0.5f, midpoint);
477 }
478 
484 float VectorAngleBetween (const vec3_t vec1, const vec3_t vec2)
485 {
486  const float dot = DotProduct(vec1, vec2);
487  const float angle = acos(dot);
488  return angle;
489 }
490 
491 
492 int Q_log2 (int val)
493 {
494  int answer = 0;
495 
496  while (val >>= 1)
497  answer++;
498  return answer;
499 }
500 
506 float frand (void)
507 {
508  return (rand() & 32767) * (1.0 / 32767);
509 }
510 
511 
517 float crand (void)
518 {
519  return (rand() & 32767) * (2.0 / 32767) - 1;
520 }
521 
529 void gaussrand (float* gauss1, float* gauss2)
530 {
531  float x1, x2, w, tmp;
532 
533  do {
534  x1 = crand();
535  x2 = crand();
536  w = x1 * x1 + x2 * x2;
537  } while (w >= 1.0);
538 
539  tmp = -2 * logf(w);
540  w = sqrt(tmp / w);
541  *gauss1 = x1 * w;
542  *gauss2 = x2 * w;
543 }
546 void CalculateMinsMaxs (const vec3_t angles, const AABB& relBox, const vec3_t origin, AABB& absBox)
547 {
548  /* expand for rotation */
549  if (VectorNotEmpty(angles)) {
550  vec3_t minVec, maxVec, tmpMinVec, tmpMaxVec;
551  vec3_t centerVec, halfVec, newCenterVec, newHalfVec;
552  vec3_t m[3];
553 
554  /* Find the center of the extents. */
555  relBox.getCenter(centerVec);
556 
557  /* Find the half height and half width of the extents. */
558  VectorSubtract(relBox.maxs, centerVec, halfVec);
559 
560  /* Rotate the center about the origin. */
561  VectorCreateRotationMatrix(angles, m);
562  VectorRotate(m, centerVec, newCenterVec);
563  VectorRotate(m, halfVec, newHalfVec);
564 
565  /* Set minVec and maxVec to bound around newCenterVec at halfVec size. */
566  VectorSubtract(newCenterVec, newHalfVec, tmpMinVec);
567  VectorAdd(newCenterVec, newHalfVec, tmpMaxVec);
568 
569  /* rotation may have changed min and max of the box, so adjust it */
570  minVec[0] = std::min(tmpMinVec[0], tmpMaxVec[0]);
571  minVec[1] = std::min(tmpMinVec[1], tmpMaxVec[1]);
572  minVec[2] = std::min(tmpMinVec[2], tmpMaxVec[2]);
573  maxVec[0] = std::max(tmpMinVec[0], tmpMaxVec[0]);
574  maxVec[1] = std::max(tmpMinVec[1], tmpMaxVec[1]);
575  maxVec[2] = std::max(tmpMinVec[2], tmpMaxVec[2]);
576 
577  /* Adjust the absolute mins/maxs */
578  absBox.set(minVec, maxVec);
579  } else { /* normal */
580  absBox.set(relBox);
581  }
582  absBox.shift(origin);
583 }
584 
592 void VectorCreateRotationMatrix (const vec3_t angles, vec3_t matrix[3])
593 {
594  AngleVectors(angles, matrix[0], matrix[1], matrix[2]);
595  VectorInverse(matrix[1]);
596 }
597 
603 void VectorRotatePoint (vec3_t point, vec3_t matrix[3])
604 {
605  vec3_t tvec;
606 
607  VectorCopy(point, tvec);
608 
609  point[0] = DotProduct(matrix[0], tvec);
610  point[1] = DotProduct(matrix[1], tvec);
611  point[2] = DotProduct(matrix[2], tvec);
612 }
613 
631 void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
632 {
633  const float anglePitch = angles[PITCH] * torad;
634  const float sp = sin(anglePitch);
635  const float cp = cos(anglePitch);
636  const float angleYaw = angles[YAW] * torad;
637  const float sy = sin(angleYaw);
638  const float cy = cos(angleYaw);
639  const float angleRoll = angles[ROLL] * torad;
640  const float sr = sin(angleRoll);
641  const float cr = cos(angleRoll);
642 
643  if (forward) {
644  forward[0] = cp * cy;
645  forward[1] = cp * sy;
646  forward[2] = -sp;
647  }
648  if (right) {
649  right[0] = (-1 * sr * sp * cy + -1 * cr * -sy);
650  right[1] = (-1 * sr * sp * sy + -1 * cr * cy);
651  right[2] = -1 * sr * cp;
652  }
653  if (up) {
654  up[0] = (cr * sp * cy + -sr * -sy);
655  up[1] = (cr * sp * sy + -sr * cy);
656  up[2] = cr * cp;
657  }
658 }
659 
666 bool FrustumVis (const vec3_t origin, int dir, const vec3_t point)
667 {
668  /* view frustum check */
669  vec3_t delta;
670  byte dv;
671 
672  delta[0] = point[0] - origin[0];
673  delta[1] = point[1] - origin[1];
674  delta[2] = 0;
675  VectorNormalizeFast(delta);
676  dv = dir & (DIRECTIONS - 1);
677 
678  /* test 120 frustum (cos 60 = 0.5) */
679  if ((delta[0] * dvecsn[dv][0] + delta[1] * dvecsn[dv][1]) < 0.5)
680  return false;
681 
682  return true;
683 }
684 
692 static inline void ProjectPointOnPlane (vec3_t dst, const vec3_t point, const vec3_t normal)
693 {
694  float distance;
696 #if 0
697  vec3_t n;
698  float inv_denom;
699  /* I added a sqrt there, otherwise this function does not work for unnormalized vector (13052007 Kracken) */
700  /* old line was inv_denom = 1.0F / DotProduct(normal, normal); */
701  inv_denom = 1.0F / sqrt(DotProduct(normal, normal));
702 #endif
703 
704  distance = DotProduct(normal, point);
705 #if 0
706  n[0] = normal[0] * inv_denom;
707  n[1] = normal[1] * inv_denom;
708  n[2] = normal[2] * inv_denom;
709 #endif
710 
711  dst[0] = point[0] - distance * normal[0];
712  dst[1] = point[1] - distance * normal[1];
713  dst[2] = point[2] - distance * normal[2];
714 }
715 
716 static inline float Q_rsqrtApprox (const float number)
717 {
718  union
719  {
720  float f;
721  int i;
722  } t;
723  float y;
724  float x2;
725  const float threehalfs = 1.5F;
726 
727  x2 = number * 0.5F;
728  t.f = number;
729  /* what the fuck? */
730  t.i = 0x5f3759df - (t.i >> 1);
731  y = t.f;
732  /* 1st iteration */
733  y = y * (threehalfs - (x2 * y * y));
734  /* 2nd iteration */
735  y = y * (threehalfs - (x2 * y * y));
736  return y;
737 }
738 
746 {
747  const float length = sqrt(DotProduct(v, v));
748  if (length) {
749  const float ilength = 1.0 / length;
750  v[0] *= ilength;
751  v[1] *= ilength;
752  v[2] *= ilength;
753  }
754 
755  return length;
756 }
757 
763 {
764  const float ilength = Q_rsqrtApprox(DotProduct(v, v));
765  v[0] *= ilength;
766  v[1] *= ilength;
767  v[2] *= ilength;
768 }
769 
780 void PerpendicularVector (vec3_t dst, const vec3_t src)
781 {
782  int pos;
783  int i;
784  float minelem = 1.0F;
785  vec3_t tempvec;
786 
787  /* find the smallest magnitude axially aligned vector */
788  for (pos = 0, i = 0; i < 3; i++) {
789  const float a = fabs(src[i]);
790  if (a < minelem) {
791  pos = i;
792  minelem = a;
793  }
794  }
795  tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
796  tempvec[pos] = 1.0F;
797 
798  /* project the point onto the plane defined by src */
799  ProjectPointOnPlane(dst, tempvec, src);
800 
801  /* normalize the result */
802  VectorNormalizeFast(dst);
803 }
804 
820 void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross)
821 {
822  cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
823  cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
824  cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
825 }
826 
827 static inline void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3])
828 {
829  out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
830  out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
831  out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
832  out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
833  out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
834  out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
835  out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
836  out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
837  out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
838 }
839 
849 void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
850 {
851  float m[3][3];
852  float im[3][3];
853  float zrot[3][3];
854  float tmpmat[3][3];
855  float rot[3][3];
856  vec3_t vr, vup, vf;
857 
858  vf[0] = dir[0];
859  vf[1] = dir[1];
860  vf[2] = dir[2];
861 
862  PerpendicularVector(vr, dir);
863  CrossProduct(vr, vf, vup);
864 
865  m[0][0] = vr[0];
866  m[1][0] = vr[1];
867  m[2][0] = vr[2];
868 
869  m[0][1] = vup[0];
870  m[1][1] = vup[1];
871  m[2][1] = vup[2];
872 
873  m[0][2] = vf[0];
874  m[1][2] = vf[1];
875  m[2][2] = vf[2];
876 
877  memcpy(im, m, sizeof(im));
878 
879  im[0][1] = m[1][0];
880  im[0][2] = m[2][0];
881  im[1][0] = m[0][1];
882  im[1][2] = m[2][1];
883  im[2][0] = m[0][2];
884  im[2][1] = m[1][2];
885 
886  OBJZERO(zrot);
887 
888  /* now prepare the rotation matrix */
889  zrot[0][0] = cos(degrees * torad);
890  zrot[0][1] = sin(degrees * torad);
891  zrot[1][0] = -sin(degrees * torad);
892  zrot[1][1] = cos(degrees * torad);
893  zrot[2][2] = 1.0F;
894 
895  R_ConcatRotations(m, zrot, tmpmat);
896  R_ConcatRotations(tmpmat, im, rot);
897 
898  for (int i = 0; i < 3; i++) {
899  dst[i] = DotProduct(rot[i], point);
900  }
901 }
902 
910 void PolarToVec (const vec2_t a, vec3_t v)
911 {
912  const float p = a[0] * torad; /* long */
913  const float t = a[1] * torad; /* lat */
914  /* v[0] = z, v[1] = x, v[2] = y - wtf? */
915  VectorSet(v, cos(p) * cos(t), sin(p) * cos(t), sin(t));
916 }
917 
922 void VecToPolar (const vec3_t v, vec2_t a)
923 {
924  a[0] = todeg * atan2(v[1], v[0]); /* long */
925  a[1] = 90 - todeg * acos(v[2]); /* lat */
926 }
927 
934 void VecToAngles (const vec3_t value1, vec3_t angles)
935 {
936  float yaw, pitch;
937 
938  /* only check the first two values for being zero */
939  if (Vector2Empty(value1)) {
940  yaw = 0.0f;
941  if (value1[2] > 0.0f)
942  pitch = 90.0f;
943  else
944  pitch = 270.0f;
945  } else {
946  const float forward = sqrt(value1[0] * value1[0] + value1[1] * value1[1]);
947  if (!EQUAL(value1[0], 0.0f))
948  yaw = atan2(value1[1], value1[0]) * todeg;
949  else if (value1[1] > 0.0f)
950  yaw = 90.0f;
951  else
952  yaw = -90.0f;
953  if (yaw < 0.0f)
954  yaw += 360.0f;
955 
956  pitch = atan2(value1[2], forward) * todeg;
957  if (pitch < 0.0f)
958  pitch += 360.0f;
959  }
960 
961  /* up and down */
962  angles[PITCH] = -pitch;
963  /* left and right */
964  angles[YAW] = yaw;
965  /* tilt left and right */
966  angles[ROLL] = 0.0f;
967 }
968 
972 bool Q_IsPowerOfTwo (int i)
973 {
974  return (i > 0 && !(i & (i - 1)));
975 }
976 
981 float LerpAngle (float a2, float a1, float frac)
982 {
983  if (a1 - a2 > 180)
984  a1 -= 360;
985  if (a1 - a2 < -180)
986  a1 += 360;
987  return a2 + frac * (a1 - a2);
988 }
989 
995 float AngleNormalize360 (float angle)
996 {
997  return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535);
998 }
999 
1004 float AngleNormalize180 (float angle)
1005 {
1006  angle = AngleNormalize360(angle);
1007  if (angle > 180.0)
1008  angle -= 360.0;
1009  return angle;
1010 }
1011 
1019 void VectorCalcMinsMaxs (const vec3_t center, const vec3_t size, vec3_t mins, vec3_t maxs)
1020 {
1021  for (int i = 0; i < 3; i++) {
1022  const vec_t length = fabsf(size[i]) / 2;
1023  mins[i] = center[i] - length;
1024  maxs[i] = center[i] + length;
1025  }
1026 }
1027 
1032 void ClearBounds (vec3_t mins, vec3_t maxs)
1033 {
1034  mins[0] = mins[1] = mins[2] = 99999;
1035  maxs[0] = maxs[1] = maxs[2] = -99999;
1036 }
1037 
1042 void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs)
1043 {
1044  for (int i = 0; i < 3; i++) {
1045  vec_t val = v[i];
1046  if (val < mins[i])
1047  mins[i] = val;
1048  if (val > maxs[i])
1049  maxs[i] = val;
1050  }
1051 }
1052 
1057 void TangentVectors (const vec3_t normal, const vec3_t sdir, const vec3_t tdir, vec4_t tangent, vec3_t binormal)
1058 {
1059  vec3_t s, t;
1060 
1061  /* normalize the directional vectors */
1062  VectorCopy(sdir, s);
1064 
1065  VectorCopy(tdir, t);
1067 
1068  /* project the directional vector onto the plane */
1069  VectorMA(s, -DotProduct(s, normal), normal, tangent);
1070  VectorNormalizeFast(tangent);
1071 
1072  /* resolve sidedness, encode as fourth tangent component */
1073  CrossProduct(normal, tangent, binormal);
1074 
1075  if (DotProduct(t, binormal) < 0.0)
1076  tangent[3] = -1.0;
1077  else
1078  tangent[3] = 1.0;
1079 
1080  VectorScale(binormal, tangent[3], binormal);
1081 }
1082 
1088 void Orthogonalize (vec3_t out, const vec3_t in)
1089 {
1090  vec3_t tmp;
1091  VectorMul(DotProduct(out, in), in, tmp);
1092  VectorSubtract(out, tmp, out);
1093  VectorNormalizeFast(out);
1094 }
1095 
1101 void MatrixTranspose (const vec3_t m[3], vec3_t t[3])
1102 {
1103  for (int i = 0; i < 3; i++) {
1104  for(int j = 0; j < 3; j++) {
1105  t[i][j] = m[j][i];
1106  }
1107  }
1108 }
1109 
1110 bool RayIntersectAABB (const vec3_t start, const vec3_t end, const AABB& aabb)
1111 {
1112  float t0 = 0.0f;
1113  float t1 = 1.0f;
1114  vec3_t delta;
1115 
1116  VectorSubtract(end, start, delta);
1117 
1118  for (int i = 0; i < 3; i++) {
1119  const float threshold = 1.0e-6f;
1120  float u0, u1;
1121 
1122  if (fabs(delta[i]) < threshold) {
1123  if (delta[i] > 0.0f) {
1124  return !(end[i] < aabb.mins[i] || start[i] > aabb.maxs[i]);
1125  } else {
1126  return !(start[i] < aabb.mins[i] || end[i] > aabb.maxs[i]);
1127  }
1128  }
1129 
1130  u0 = (aabb.mins[i] - start[i]) / delta[i];
1131  u1 = (aabb.maxs[i] - start[i]) / delta[i];
1132 
1133  if (u0 > u1) {
1134  const float temp = u0;
1135  u0 = u1;
1136  u1 = temp;
1137  }
1138 
1139  if (u1 < t0 || u0 > t1) {
1140  return false;
1141  }
1142 
1143  t0 = std::max(u0, t0);
1144  t1 = std::min(u1, t1);
1145 
1146  if (t1 < t0) {
1147  return false;
1148  }
1149  }
1150 
1151  return true;
1152 }
void VectorMix(const vec3_t v1, const vec3_t v2, float mix, vec3_t out)
Calculate a position on v1 v2 line.
Definition: mathlib.cpp:447
bool FrustumVis(const vec3_t origin, int dir, const vec3_t point)
Checks whether a point is visible from a given position.
Definition: mathlib.cpp:666
void CalculateMinsMaxs(const vec3_t angles, const AABB &relBox, const vec3_t origin, AABB &absBox)
Calculates the bounding box in absolute coordinates, also for rotating objects. WARNING: do not use t...
Definition: mathlib.cpp:546
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
Definition: mathlib.cpp:434
vec3_t maxs
Definition: aabb.h:258
#define VectorCopy(src, dest)
Definition: vector.h:51
#define DIRECTION_EAST
Definition: mathlib.cpp:107
#define VectorSet(v, x, y, z)
Definition: vector.h:59
void GLMatrixAssemble(const vec3_t origin, const vec3_t angles, float *matrix)
Builds an opengl translation and rotation matrix.
Definition: mathlib.cpp:325
void VectorMA(const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
Sets vector_out (vc) to vevtor1 (va) + scale * vector2 (vb)
Definition: mathlib.cpp:261
void VectorRotatePoint(vec3_t point, vec3_t matrix[3])
Definition: mathlib.cpp:603
static float Q_rsqrtApprox(const float number)
Definition: mathlib.cpp:716
vec_t ColorNormalize(const vec3_t in, vec3_t out)
Definition: mathlib.cpp:190
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don&#39;t need to have varargs versions of all text functi...
Definition: shared.cpp:410
#define ROLL
Definition: mathlib.h:56
void VecToPolar(const vec3_t v, vec2_t a)
Converts vector coordinates into polar coordinates.
Definition: mathlib.cpp:922
static const vec3_t scale
bool VectorNearer(const vec3_t v1, const vec3_t v2, const vec3_t comp)
Checks whether the given vector v1 is closer to comp as the vector v2.
Definition: mathlib.cpp:219
float AngleNormalize180(float angle)
returns angle normalized to the range [-180 < angle <= 180]
Definition: mathlib.cpp:1004
#define RT2
cos 45 degree
Definition: mathlib.cpp:40
#define EQUAL(a, b)
Definition: vector.h:37
voidpf uLong int origin
Definition: ioapi.h:45
#define DIRECTION_SOUTH
Definition: mathlib.cpp:110
const vec3_t vec3_origin
Definition: mathlib.cpp:35
void VectorInverse(vec3_t v)
Inverse a vector.
Definition: mathlib.cpp:460
float vec_t
Definition: ufotypes.h:37
const vec2_t vec2_origin
Definition: mathlib.cpp:34
voidpf void uLong size
Definition: ioapi.h:42
void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross)
binary operation on vectors in a three-dimensional space
Definition: mathlib.cpp:820
const vec4_t dvecs[PATHFINDING_DIRECTIONS]
Definition: mathlib.cpp:58
vec_t VectorNormalize2(const vec3_t v, vec3_t out)
Calculated the normal vector for a given vec3_t.
Definition: mathlib.cpp:237
static void ProjectPointOnPlane(vec3_t dst, const vec3_t point, const vec3_t normal)
Projects a point on a plane passing through the origin.
Definition: mathlib.cpp:692
void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
Rotate a point around a given vector.
Definition: mathlib.cpp:849
void GLPositionTransform(const float m[16], const vec3_t in, vec3_t out)
Transform position (xyz) vector by OpenGL rules.
Definition: mathlib.cpp:380
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
#define DIRECTION_SOUTHWEST
Definition: mathlib.cpp:112
void VectorCreateRotationMatrix(const vec3_t angles, vec3_t matrix[3])
Definition: mathlib.cpp:592
void VectorNormalizeFast(vec3_t v)
fast vector normalize routine that does not check to make sure that length != 0, nor does it return l...
Definition: mathlib.cpp:762
void MatrixTranspose(const vec3_t m[3], vec3_t t[3])
Transposes m and stores the result in t.
Definition: mathlib.cpp:1101
const byte dvleft[CORE_DIRECTIONS]
Definition: mathlib.cpp:119
#define VectorScale(in, scale, out)
Definition: vector.h:79
void VectorClampMA(vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc)
Definition: mathlib.cpp:268
#define YAW
Definition: mathlib.h:55
int AngleToDir(int angle)
Returns the index of array directionAngles[DIRECTIONS] whose value is the closest to angle...
Definition: mathlib.cpp:130
#define Vector2Empty(a)
Definition: vector.h:74
#define todeg
Definition: mathlib.h:51
void AngleVectors(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Create the rotation matrix in order to rotate something.
Definition: mathlib.cpp:631
void VectorCalcMinsMaxs(const vec3_t center, const vec3_t size, vec3_t mins, vec3_t maxs)
Calculates a bounding box from a center and a size.
Definition: mathlib.cpp:1019
#define VectorMul(scalar, b, dest)
Definition: vector.h:48
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
Definition: vector.h:44
#define logf(x)
Definition: mathlib.cpp:31
void AddPointToBounds(const vec3_t v, vec3_t mins, vec3_t maxs)
If the point is outside the box defined by mins and maxs, expand the box to accommodate it...
Definition: mathlib.cpp:1042
#define OBJZERO(obj)
Definition: shared.h:178
#define PATHFINDING_DIRECTIONS
Definition: mathlib.h:87
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition: r_gl.h:110
void set(const AABB &other)
Copies the values from the given aabb.
Definition: aabb.h:60
#define DIRECTION_SOUTHEAST
Definition: mathlib.cpp:114
void PolarToVec(const vec2_t a, vec3_t v)
Converts longitude and latitude to a 3D vector in Euclidean coordinates.
Definition: mathlib.cpp:910
#define DIRECTION_WEST
Definition: mathlib.cpp:108
void TangentVectors(const vec3_t normal, const vec3_t sdir, const vec3_t tdir, vec4_t tangent, vec3_t binormal)
Projects the normalized directional vectors on to the normal&#39;s plane. The fourth component of the res...
Definition: mathlib.cpp:1057
void VecToAngles(const vec3_t value1, vec3_t angles)
Converts a vector to an angle vector.
Definition: mathlib.cpp:934
Definition: aabb.h:42
#define PITCH
Definition: mathlib.h:54
void Orthogonalize(vec3_t out, const vec3_t in)
Grahm-Schmidt orthogonalization.
Definition: mathlib.cpp:1088
vec3_t mins
Definition: aabb.h:257
#define VectorNotEmpty(a)
Definition: vector.h:72
pos_t pos3_t[3]
Definition: ufotypes.h:58
void shift(const vec3_t shiftVec)
shove the whole box by the given vector
Definition: aabb.h:246
const vec4_t vec4_origin
Definition: mathlib.cpp:36
void PerpendicularVector(vec3_t dst, const vec3_t src)
Finds a vector perpendicular to the source vector.
Definition: mathlib.cpp:780
float AngleNormalize360(float angle)
returns angle normalized to the range [0 <= angle < 360]
Definition: mathlib.cpp:995
static const GridBox EMPTY
Definition: mathlib.h:122
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
Definition: aabb.h:155
int Q_log2(int val)
Definition: mathlib.cpp:492
#define DIRECTION_NORTH
Definition: mathlib.cpp:109
const float dvecsn[CORE_DIRECTIONS][2]
Definition: mathlib.cpp:102
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
#define VectorClear(a)
Definition: vector.h:55
void MatrixMultiply(const vec3_t a[3], const vec3_t b[3], vec3_t c[3])
Multiply 3*3 matrix by 3*3 matrix.
Definition: mathlib.cpp:304
void GLMatrixMultiply(const float a[16], const float b[16], float c[16])
Multiply 4*4 matrix by 4*4 matrix.
Definition: mathlib.cpp:350
void gaussrand(float *gauss1, float *gauss2)
generate two gaussian distributed random numbers with median at 0 and stdev of 1
Definition: mathlib.cpp:529
#define VectorAdd(a, b, dest)
Definition: vector.h:47
#define DIRECTION_NORTHWEST
Definition: mathlib.cpp:113
float frand(void)
Return random values between 0 and 1.
Definition: mathlib.cpp:506
QGL_EXTERN GLint i
Definition: r_gl.h:113
void VectorMidpoint(const vec3_t point1, const vec3_t point2, vec3_t midpoint)
Calculates the midpoint between two vectors.
Definition: mathlib.cpp:473
const byte dvright[CORE_DIRECTIONS]
Definition: mathlib.cpp:116
vec_t VectorNormalize(vec3_t v)
Calculate unit vector for a given vec3_t.
Definition: mathlib.cpp:745
#define CORE_DIRECTIONS
Definition: mathlib.h:88
float crand(void)
Return random values between -1 and 1.
Definition: mathlib.cpp:517
vec_t vec3_t[3]
Definition: ufotypes.h:39
bool RayIntersectAABB(const vec3_t start, const vec3_t end, const AABB &aabb)
Definition: mathlib.cpp:1110
#define torad
Definition: mathlib.h:50
vec_t vec2_t[2]
Definition: ufotypes.h:38
#define DIRECTIONS
Number of angles from a position (2-dimensional)
Definition: mathlib.h:78
vec_t Q_rint(const vec_t in)
Round to nearest integer.
Definition: mathlib.cpp:156
void VectorRotate(vec3_t m[3], const vec3_t va, vec3_t vb)
Rotate a vector with a rotation matrix.
Definition: mathlib.cpp:395
int VectorCompareEps(const vec3_t v1, const vec3_t v2, float epsilon)
Compare two vectors that may have an epsilon difference but still be the same vectors.
Definition: mathlib.cpp:413
const float directionAngles[CORE_DIRECTIONS]
Definition: mathlib.cpp:105
void GLVectorTransform(const float m[16], const vec4_t in, vec4_t out)
Multiply 4*4 matrix by 4d vector.
Definition: mathlib.cpp:366
bool Q_IsPowerOfTwo(int i)
Checks whether i is power of two value.
Definition: mathlib.cpp:972
float VectorAngleBetween(const vec3_t vec1, const vec3_t vec2)
Calculates the angle (in radians) between the two given vectors.
Definition: mathlib.cpp:484
#define DIRECTION_NORTHEAST
Definition: mathlib.cpp:111
uint8_t byte
Definition: ufotypes.h:34
QGL_EXTERN int GLboolean GLfloat * v
Definition: r_gl.h:120
static struct mdfour * m
Definition: md4.cpp:35
void ClearBounds(vec3_t mins, vec3_t maxs)
Sets mins and maxs to their starting points before using AddPointToBounds.
Definition: mathlib.cpp:1032
#define VectorSubtract(a, b, dest)
Definition: vector.h:45
static void R_ConcatRotations(float in1[3][3], float in2[3][3], float out[3][3])
Definition: mathlib.cpp:827
double GetDistanceOnGlobe(const vec2_t pos1, const vec2_t pos2)
Calculate distance on the geoscape.
Definition: mathlib.cpp:171
float LerpAngle(float a2, float a1, float frac)
Returns the angle resulting from turning fraction * angle from angle1 to angle2.
Definition: mathlib.cpp:981
vec_t vec4_t[4]
Definition: ufotypes.h:40
const pos3_t pos3_origin
Definition: mathlib.cpp:37