1 /*
2 ===========================================================================
3 Copyright (C) 1999 - 2005, Id Software, Inc.
4 Copyright (C) 2000 - 2013, Raven Software, Inc.
5 Copyright (C) 2001 - 2013, Activision, Inc.
6 Copyright (C) 2013 - 2015, OpenJK contributors
7 
8 This file is part of the OpenJK source code.
9 
10 OpenJK is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
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.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 ===========================================================================
22 */
23 #pragma once
24 
25 #include "q_platform.h"
26 
27 
28 #if defined(__cplusplus)
29 extern "C" {
30 #endif
31 
32 typedef float vec_t;
33 typedef float vec2_t[2], vec3_t[3], vec4_t[4], vec5_t[5];
34 typedef int	  ivec2_t[2], ivec3_t[3], ivec4_t[4], ivec5_t[5];
35 typedef vec3_t vec3pair_t[2], matrix3_t[3];
36 
37 typedef	int	fixed4_t, fixed8_t, fixed16_t;
38 
39 #ifndef M_PI
40 #define M_PI		3.14159265358979323846f	// matches value in gcc v2 math.h
41 #endif
42 
43 #define	MAX_QINT			0x7fffffff
44 #define	MIN_QINT			(-MAX_QINT-1)
45 
46 
47 ///////////////////////////////////////////////////////////////////////////
48 //
49 //      DIRECTION ENCODING
50 //
51 ///////////////////////////////////////////////////////////////////////////
52 int DirToByte( vec3_t dir );
53 void ByteToDir( int b, vec3_t dir );
54 void NormalToLatLong( const vec3_t normal, byte bytes[2] );
55 
56 
57 ///////////////////////////////////////////////////////////////////////////
58 //
59 //      RANDOM NUMBER GENERATION
60 //
61 ///////////////////////////////////////////////////////////////////////////
62 #define QRAND_MAX 32768
63 
64 int   Q_rand( int *seed );
65 float Q_random( int *seed );
66 float Q_crandom( int *seed );
67 
68 void  Rand_Init( int seed );
69 float Q_flrand( float min, float max );
70 int   Q_irand( int value1, int value2 );
71 float flrand( float min, float max );
72 int   irand( int min, int max );
73 
74 float erandom( float mean );
75 
76 
77 ///////////////////////////////////////////////////////////////////////////
78 //
79 //      MATH UTILITIES
80 //
81 ///////////////////////////////////////////////////////////////////////////
82 #define minimum( x, y ) ((x) < (y) ? (x) : (y))
83 #define maximum( x, y ) ((x) > (y) ? (x) : (y))
84 
85 #define PI_DIV_180		0.017453292519943295769236907684886f
86 #define INV_PI_DIV_180	57.295779513082320876798154814105f
87 
88 #define DEG2RAD( a ) ( ( (a) * PI_DIV_180 ) )
89 #define RAD2DEG( a ) ( ( (a) * INV_PI_DIV_180 ) )
90 
91 #define SQRTFAST( x ) ( (x) * Q_rsqrt( x ) )
92 
93 #define Q_min(x,y) ((x)<(y)?(x):(y))
94 #define Q_max(x,y) ((x)>(y)?(x):(y))
95 
96 #if defined(_MSC_VER)
Q_ftol(float f)97 static __inline long Q_ftol( float f )
98 {
99 	return (long)f;
100 }
101 #else
Q_ftol(float f)102 static inline long Q_ftol( float f )
103 {
104 	return (long)f;
105 }
106 #endif
107 
108 signed char ClampChar( int i );
109 signed short ClampShort( int i );
110 int Com_Clampi( int min, int max, int value );
111 float Com_Clamp( float min, float max, float value );
112 int Com_AbsClampi( int min, int max, int value );
113 float Com_AbsClamp( float min, float max, float value );
114 
115 float Q_rsqrt( float number );
116 float Q_fabs( float f );
117 
118 float Q_acos(float c);
119 float Q_asin(float c);
120 float Q_powf ( float x, int y );
121 qboolean Q_isnan (float f);
122 int Q_log2( int val );
123 
124 float LerpAngle(float from, float to, float frac);
125 float AngleSubtract( float a1, float a2 );
126 void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 );
127 float AngleMod(float a);
128 float AngleNormalize360 ( float angle );
129 float AngleNormalize180 ( float angle );
130 float AngleDelta( float angle1, float angle2 );
131 
132 
133 ///////////////////////////////////////////////////////////////////////////
134 //
135 //      GEOMETRIC UTILITIES
136 //
137 ///////////////////////////////////////////////////////////////////////////
138 // angle indexes
139 #define	PITCH	0		// up / down
140 #define	YAW		1		// left / right
141 #define	ROLL	2		// fall over
142 
143 qboolean PlaneFromPoints( vec4_t plane, const vec3_t a, const vec3_t b, const vec3_t c );
144 void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
145 void RotateAroundDirection( matrix3_t axis, float yaw );
146 void vectoangles( const vec3_t value1, vec3_t angles );
147 vec_t GetYawForDirection( const vec3_t p1, const vec3_t p2 );
148 void GetAnglesForDirection( const vec3_t p1, const vec3_t p2, vec3_t out );
149 void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal );
150 qboolean G_FindClosestPointOnLineSegment( const vec3_t start, const vec3_t end, const vec3_t from, vec3_t result );
151 float G_PointDistFromLineSegment( const vec3_t start, const vec3_t end, const vec3_t from );
152 void MatrixMultiply(float in1[3][3], float in2[3][3], float out[3][3]);
153 
154 
155 ///////////////////////////////////////////////////////////////////////////
156 //
157 //      BOUNDING BOX
158 //
159 ///////////////////////////////////////////////////////////////////////////
160 float RadiusFromBounds( const vec3_t mins, const vec3_t maxs );
161 void ClearBounds( vec3_t mins, vec3_t maxs );
162 void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs );
163 
164 
165 ///////////////////////////////////////////////////////////////////////////
166 //
167 //      PLANE
168 //
169 ///////////////////////////////////////////////////////////////////////////
170 // plane types are used to speed some tests
171 // 0-2 are axial planes
172 #define	PLANE_X			0
173 #define	PLANE_Y			1
174 #define	PLANE_Z			2
175 #define	PLANE_NON_AXIAL	3
176 
177 // plane_t structure
178 typedef struct cplane_s {
179 	vec3_t	normal;
180 	float	dist;
181 	byte	type;			// for fast side tests: 0,1,2 = axial, 3 = nonaxial
182 	byte	signbits;		// signx + (signy<<1) + (signz<<2), used as lookup during collision
183 	byte	pad[2];
184 } cplane_t;
185 
186 void SetPlaneSignbits( cplane_t *out );
187 int	PlaneTypeForNormal( vec3_t normal );
188 int BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, cplane_t *p);
189 
190 
191 ///////////////////////////////////////////////////////////////////////////
192 //
193 //      AXIS
194 //
195 ///////////////////////////////////////////////////////////////////////////
196 extern matrix3_t axisDefault;
197 
198 void AxisClear( matrix3_t axis );
199 void AxisCopy( matrix3_t in, matrix3_t out );
200 void AnglesToAxis( const vec3_t angles, matrix3_t axis );
201 
202 
203 ///////////////////////////////////////////////////////////////////////////
204 //
205 //      VEC2
206 //
207 ///////////////////////////////////////////////////////////////////////////
208 extern vec2_t vec3_zero;
209 
210 #define VectorScale2M(v, factor, dst) \
211 	(dst)[0] = (v[0]) * (factor), \
212 	(dst)[1] = (v[1]) * (factor)
213 #define VectorCopy2M(src, dst) \
214 	(dst)[0] = (src[0]), \
215 	(dst)[1] = (src[1])
216 #define VectorClear2M(dst) \
217 	memset((dst), 0, sizeof((dst)[0]) * 2)
218 
219 void VectorAdd2( const vec2_t vec1, const vec2_t vec2, vec2_t vecOut );
220 void VectorSubtract2( const vec2_t vec1, const vec2_t vec2, vec2_t vec2_t );
221 void VectorScale2( const vec2_t vecIn, float scale, vec2_t vecOut );
222 void VectorMA2( const vec2_t vec1, float scale, const vec2_t vec2, vec2_t vecOut );
223 void VectorSet2( vec2_t vec, float x, float y );
224 void VectorClear2( vec2_t vec );
225 void VectorCopy2( const vec2_t vecIn, vec2_t vecOut );
226 
227 
228 ///////////////////////////////////////////////////////////////////////////
229 //
230 //      VEC3
231 //
232 ///////////////////////////////////////////////////////////////////////////
233 extern vec3_t vec3_origin;
234 
235 #define VectorScaleM(v, factor, dst) \
236 	(dst)[0] = (v[0]) * (factor), \
237 	(dst)[1] = (v[1]) * (factor), \
238 	(dst)[2] = (v[2]) * (factor)
239 #define VectorCopyM(src, dst) \
240 	(dst)[0] = (src[0]), \
241 	(dst)[1] = (src[1]), \
242 	(dst)[2] = (src[2])
243 #define VectorClearM(dst) \
244 	memset((dst), 0, sizeof((dst)[0]) * 3)
245 
246 void VectorAdd( const vec3_t vec1, const vec3_t vec2, vec3_t vecOut );
247 void VectorSubtract( const vec3_t vec1, const vec3_t vec2, vec3_t vecOut );
248 void VectorScale( const vec3_t vecIn, float scale, vec3_t vecOut );
249 void VectorMA( const vec3_t vec1, float scale, const vec3_t vec2, vec3_t vecOut );
250 void VectorSet( vec3_t vec, float x, float y, float z );
251 void VectorClear( vec3_t vec );
252 void VectorCopy( const vec3_t vecIn, vec3_t vecOut );
253 float VectorLength( const vec3_t vec );
254 float VectorLengthSquared( const vec3_t vec );
255 void VectorNormalizeFast( vec3_t vec );
256 float VectorNormalize( vec3_t vec );
257 float VectorNormalize2( const vec3_t vec, vec3_t vecOut );
258 void VectorAdvance( const vec3_t veca, const float scale, const vec3_t vecb, vec3_t vecc);
259 void VectorInc( vec3_t vec );
260 void VectorDec( vec3_t vec );
261 void VectorInverse( vec3_t vec );
262 void CrossProduct( const vec3_t vec1, const vec3_t vec2, vec3_t vecOut );
263 float DotProduct( const vec3_t vec1, const vec3_t vec2 );
264 qboolean VectorCompare( const vec3_t vec1, const vec3_t vec2 );
265 qboolean VectorCompare2( const vec3_t v1, const vec3_t v2 );
266 
267 void SnapVector( float *v );
268 float Distance( const vec3_t p1, const vec3_t p2 );
269 float DistanceSquared( const vec3_t p1, const vec3_t p2 );
270 float DistanceHorizontal( const vec3_t p1, const vec3_t p2 );
271 float DistanceHorizontalSquared( const vec3_t p1, const vec3_t p2 );
272 void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up);
273 void VectorRotate( const vec3_t in, matrix3_t matrix, vec3_t out );
274 void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
275 void PerpendicularVector( vec3_t dst, const vec3_t src );
276 float DotProductNormalize( const vec3_t inVec1, const vec3_t inVec2 );
277 
278 #define VectorScaleVector(a,b,c)		(((c)[0]=(a)[0]*(b)[0]),((c)[1]=(a)[1]*(b)[1]),((c)[2]=(a)[2]*(b)[2]))
279 #define VectorInverseScaleVector(a,b,c)	((c)[0]=(a)[0]/(b)[0],(c)[1]=(a)[1]/(b)[1],(c)[2]=(a)[2]/(b)[2])
280 #define VectorScaleVectorAdd(c,a,b,o)	((o)[0]=(c)[0]+((a)[0]*(b)[0]),(o)[1]=(c)[1]+((a)[1]*(b)[1]),(o)[2]=(c)[2]+((a)[2]*(b)[2]))
281 #define VectorAverage(a,b,c)			(((c)[0]=((a)[0]+(b)[0])*0.5f),((c)[1]=((a)[1]+(b)[1])*0.5f),((c)[2]=((a)[2]+(b)[2])*0.5f))
282 #define VectorNegate(a,b)				((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
283 
284 
285 ///////////////////////////////////////////////////////////////////////////
286 //
287 //      VEC4
288 //
289 ///////////////////////////////////////////////////////////////////////////
290 void VectorScale4( const vec4_t vecIn, float scale, vec4_t vecOut );
291 void VectorCopy4( const vec4_t vecIn, vec4_t vecOut );
292 void VectorSet4( vec4_t vec, float x, float y, float z, float w );
293 void VectorClear4( vec4_t vec );
294 
295 ///////////////////////////////////////////////////////////////////////////
296 //
297 //      VEC5
298 //
299 ///////////////////////////////////////////////////////////////////////////
300 void VectorSet5( vec5_t vec, float x, float y, float z, float w, float u );
301 
302 
303 #if defined(__cplusplus)
304 } // extern "C"
305 #endif
306