UFO: Alien Invasion
Loading...
Searching...
No Matches
mathlib.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 1997-2001 Id Software, Inc.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, 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
34const vec2_t vec2_origin = { 0, 0 };
35const vec3_t vec3_origin = { 0, 0, 0 };
36const vec4_t vec4_origin = { 0, 0, 0, 0 };
37const 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 */
102const 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 */
105const 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
130int 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
157{
158 /* round x down to the nearest integer */
159 return floor(in + 0.5);
160}
161
171double 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
219bool 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);
243
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
261void 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
268void 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
304void 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
325void 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
350void 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
366void 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
380void 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
395void 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
413int 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
447void 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
473void 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
484float 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
492int Q_log2 (int val)
493{
494 int answer = 0;
495
496 while (val >>= 1)
497 answer++;
498 return answer;
499}
500
506float frand (void)
507{
508 return (rand() & 32767) * (1.0 / 32767);
509}
510
511
517float crand (void)
518{
519 return (rand() & 32767) * (2.0 / 32767) - 1;
520}
521
529void 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}
544
546void 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. */
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
592void 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
603void 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
631void 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
666bool 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
692static inline void ProjectPointOnPlane (vec3_t dst, const vec3_t point, const vec3_t normal)
693{
694 float distance;
695
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
716static 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
780void 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 */
803}
804
820void 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
827static 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
849void 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
910void 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
922void 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
934void 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
973{
974 return (i > 0 && !(i & (i - 1)));
975}
976
981float 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
995float AngleNormalize360 (float angle)
996{
997 return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535);
998}
999
1004float AngleNormalize180 (float angle)
1005{
1006 angle = AngleNormalize360(angle);
1007 if (angle > 180.0)
1008 angle -= 360.0;
1009 return angle;
1010}
1011
1019void 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
1032void 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
1042void 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
1057void 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
1088void 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);
1094}
1095
1101void 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
1110bool 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}
Definition aabb.h:42
vec3_t maxs
Definition aabb.h:258
vec3_t mins
Definition aabb.h:257
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
Definition aabb.h:155
void set(const AABB &other)
Copies the values from the given aabb.
Definition aabb.h:60
void shift(const vec3_t shiftVec)
shove the whole box by the given vector
Definition aabb.h:246
static const GridBox EMPTY
Definition mathlib.h:122
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
definitions common between client and server, but not game lib
voidpf void uLong size
Definition ioapi.h:42
voidpf uLong int origin
Definition ioapi.h:45
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
const vec4_t dvecs[PATHFINDING_DIRECTIONS]
Definition mathlib.cpp:58
void VectorMidpoint(const vec3_t point1, const vec3_t point2, vec3_t midpoint)
Calculates the midpoint between two vectors.
Definition mathlib.cpp:473
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 ClearBounds(vec3_t mins, vec3_t maxs)
Sets mins and maxs to their starting points before using AddPointToBounds.
Definition mathlib.cpp:1032
float VectorAngleBetween(const vec3_t vec1, const vec3_t vec2)
Calculates the angle (in radians) between the two given vectors.
Definition mathlib.cpp:484
void gaussrand(float *gauss1, float *gauss2)
generate two gaussian distributed random numbers with median at 0 and stdev of 1
Definition mathlib.cpp:529
float AngleNormalize360(float angle)
returns angle normalized to the range [0 <= angle < 360]
Definition mathlib.cpp:995
#define DIRECTION_SOUTH
Definition mathlib.cpp:110
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
vec_t VectorNormalize(vec3_t v)
Calculate unit vector for a given vec3_t.
Definition mathlib.cpp:745
void GLMatrixAssemble(const vec3_t origin, const vec3_t angles, float *matrix)
Builds an opengl translation and rotation matrix.
Definition mathlib.cpp:325
#define DIRECTION_NORTH
Definition mathlib.cpp:109
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
Definition mathlib.cpp:434
#define logf(x)
Definition mathlib.cpp:31
const vec4_t vec4_origin
Definition mathlib.cpp:36
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
#define DIRECTION_NORTHEAST
Definition mathlib.cpp:111
const byte dvleft[CORE_DIRECTIONS]
Definition mathlib.cpp:119
#define RT2
cos 45 degree
Definition mathlib.cpp:40
vec_t Q_rint(const vec_t in)
Round to nearest integer.
Definition mathlib.cpp:156
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
#define DIRECTION_NORTHWEST
Definition mathlib.cpp:113
void Orthogonalize(vec3_t out, const vec3_t in)
Grahm-Schmidt orthogonalization.
Definition mathlib.cpp:1088
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 MatrixTranspose(const vec3_t m[3], vec3_t t[3])
Transposes m and stores the result in t.
Definition mathlib.cpp:1101
const vec3_t vec3_origin
Definition mathlib.cpp:35
int Q_log2(int val)
Definition mathlib.cpp:492
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
const float directionAngles[CORE_DIRECTIONS]
Definition mathlib.cpp:105
vec_t VectorNormalize2(const vec3_t v, vec3_t out)
Calculated the normal vector for a given vec3_t.
Definition mathlib.cpp:237
void GLPositionTransform(const float m[16], const vec3_t in, vec3_t out)
Transform position (xyz) vector by OpenGL rules.
Definition mathlib.cpp:380
void VectorCreateRotationMatrix(const vec3_t angles, vec3_t matrix[3])
Definition mathlib.cpp:592
void VectorInverse(vec3_t v)
Inverse a vector.
Definition mathlib.cpp:460
float crand(void)
Return random values between -1 and 1.
Definition mathlib.cpp:517
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
const vec2_t vec2_origin
Definition mathlib.cpp:34
#define DIRECTION_EAST
Definition mathlib.cpp:107
void PolarToVec(const vec2_t a, vec3_t v)
Converts longitude and latitude to a 3D vector in Euclidean coordinates.
Definition mathlib.cpp:910
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
const byte dvright[CORE_DIRECTIONS]
Definition mathlib.cpp:116
bool RayIntersectAABB(const vec3_t start, const vec3_t end, const AABB &aabb)
Definition mathlib.cpp:1110
vec_t ColorNormalize(const vec3_t in, vec3_t out)
Definition mathlib.cpp:190
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
void VectorRotate(vec3_t m[3], const vec3_t va, vec3_t vb)
Rotate a vector with a rotation matrix.
Definition mathlib.cpp:395
#define DIRECTION_SOUTHEAST
Definition mathlib.cpp:114
static void R_ConcatRotations(float in1[3][3], float in2[3][3], float out[3][3])
Definition mathlib.cpp:827
const pos3_t pos3_origin
Definition mathlib.cpp:37
bool Q_IsPowerOfTwo(int i)
Checks whether i is power of two value.
Definition mathlib.cpp:972
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
float AngleNormalize180(float angle)
returns angle normalized to the range [-180 < angle <= 180]
Definition mathlib.cpp:1004
void PerpendicularVector(vec3_t dst, const vec3_t src)
Finds a vector perpendicular to the source vector.
Definition mathlib.cpp:780
int AngleToDir(int angle)
Returns the index of array directionAngles[DIRECTIONS] whose value is the closest to angle.
Definition mathlib.cpp:130
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
static float Q_rsqrtApprox(const float number)
Definition mathlib.cpp:716
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
#define DIRECTION_SOUTHWEST
Definition mathlib.cpp:112
double GetDistanceOnGlobe(const vec2_t pos1, const vec2_t pos2)
Calculate distance on the geoscape.
Definition mathlib.cpp:171
void VectorClampMA(vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc)
Definition mathlib.cpp:268
void VecToPolar(const vec3_t v, vec2_t a)
Converts vector coordinates into polar coordinates.
Definition mathlib.cpp:922
float LerpAngle(float a2, float a1, float frac)
Returns the angle resulting from turning fraction * angle from angle1 to angle2.
Definition mathlib.cpp:981
void VecToAngles(const vec3_t value1, vec3_t angles)
Converts a vector to an angle vector.
Definition mathlib.cpp:934
#define DIRECTION_WEST
Definition mathlib.cpp:108
const float dvecsn[CORE_DIRECTIONS][2]
Definition mathlib.cpp:102
void VectorRotatePoint(vec3_t point, vec3_t matrix[3])
Definition mathlib.cpp:603
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
float frand(void)
Return random values between 0 and 1.
Definition mathlib.cpp:506
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 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's plane. The fourth component of the res...
Definition mathlib.cpp:1057
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 GLVectorTransform(const float m[16], const vec4_t in, vec4_t out)
Multiply 4*4 matrix by 4d vector.
Definition mathlib.cpp:366
#define DIRECTIONS
Number of angles from a position (2-dimensional).
Definition mathlib.h:78
#define CORE_DIRECTIONS
Definition mathlib.h:88
#define PATHFINDING_DIRECTIONS
Definition mathlib.h:87
#define torad
Definition mathlib.h:50
#define YAW
Definition mathlib.h:55
#define PITCH
Definition mathlib.h:54
#define todeg
Definition mathlib.h:51
#define ROLL
Definition mathlib.h:56
static struct mdfour * m
Definition md4.cpp:35
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition r_gl.h:110
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
#define OBJZERO(obj)
Definition shared.h:178
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition shared.cpp:410
pos_t pos3_t[3]
Definition ufotypes.h:58
float vec_t
Definition ufotypes.h:37
vec_t vec3_t[3]
Definition ufotypes.h:39
vec_t vec4_t[4]
Definition ufotypes.h:40
vec_t vec2_t[2]
Definition ufotypes.h:38
static const vec3_t scale
#define VectorMul(scalar, b, dest)
Definition vector.h:48
#define VectorClear(a)
Definition vector.h:55
#define VectorNotEmpty(a)
Definition vector.h:72
#define EQUAL(a, b)
Definition vector.h:37
#define VectorSubtract(a, b, dest)
Definition vector.h:45
#define VectorCopy(src, dest)
Definition vector.h:51
#define Vector2Empty(a)
Definition vector.h:74
#define VectorAdd(a, b, dest)
Definition vector.h:47
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
Definition vector.h:44
#define VectorSet(v, x, y, z)
Definition vector.h:59
#define VectorScale(in, scale, out)
Definition vector.h:79