Nuclide
Software Development Kit for id Technology
math.h
1/*
2 * Copyright (c) 2016-2024 Vera Visions LLC.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
14 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*/
16
33#define MATH_PI 3.1415926
34noref const vector g_vec_null = [0.0f, 0.0f, 0.0f];
35
36#ifdef MENU
37
38vector vectoangles2(vector fwd, optional vector up) = #11;
39void rotatevectorsbyangle(vector angle) = #0;
40
41#define vectoangles vectoangles2
42
43vector v_forward;
44vector v_up;
45vector v_right;
46void makevectors( vector angles )
47{
48 float angle;
49 float sr, sp, sy, cr, cp, cy;
50
51 angle = angles[1] * (M_PI*2 / 360);
52 sy = sin(angle);
53 cy = cos(angle);
54 angle = angles[0] * (M_PI*2 / 360);
55 sp = sin(angle);
56 cp = cos(angle);
57 angle = angles[2] * (M_PI*2 / 360);
58 sr = sin(angle);
59 cr = cos(angle);
60
61 v_forward[0] = cp*cy;
62 v_forward[1] = cp*sy;
63 v_forward[2] = -sp;
64
65 v_right[0] = (-1*sr*sp*cy+-1*cr*-sy);
66 v_right[1] = (-1*sr*sp*sy+-1*cr*cy);
67 v_right[2] = -1*sr*cp;
68
69 v_up[0] = (cr*sp*cy+-sr*-sy);
70 v_up[1] = (cr*sp*sy+-sr*cy);
71 v_up[2] = cr*cp;
72}
73#endif
74
75
82float
83lerpAngle(float startAngle, float endAngle, float lerpAmount)
84{
85 float shortest_angle = ((((endAngle - startAngle) % 360.0f) + 540.0f) % 360.0f) - 180.0f;
86 return shortest_angle * lerpAmount;
87}
88
95float
96lerp(float startValue, float endValue, float lerpAmount)
97{
98 return (startValue * (1 - lerpAmount)) + (endValue * lerpAmount);
99}
100
105float
106fixAngleDelta(float angleValue)
107{
108 if (angleValue > 180) {
109 angleValue -= 360;
110 } else if (angleValue < -180) {
111 angleValue += 360;
112 } else {
113 return angleValue;
114 }
115
116 return fixAngleDelta(angleValue);
117}
118
119
124vector
125fixAngle(vector inputAngle)
126{
127 inputAngle[0] = fixAngleDelta(inputAngle[0]);
128 inputAngle[1] = fixAngleDelta(inputAngle[1]);
129 inputAngle[2] = fixAngleDelta(inputAngle[2]);
130 return inputAngle;
131}
132
138vector
139reflect(vector hitDirection, vector planeNormal)
140{
141 return hitDirection - 2 * dotproduct(hitDirection, planeNormal) * planeNormal;
142}
143
148vector
149randomVector(bool flyUp)
150{
151 vector tmp;
152 tmp[0] = random() - 0.5f;
153 tmp[1] = random() - 0.5f;
154
155 if ( flyUp == true ) {
156 tmp[2] = random();
157 } else {
158 tmp[2] = random() - 0.5f;
159 }
160
161 return tmp * 2.0f;
162}
163
170vector
171rotateAroundPoint(vector pos, vector pivot, float degr)
172{
173 vector new = pos;
174 new[0] = pivot[0] + (pos[0] - pivot[0]) * cos(degr) - (pos[1] - pivot[1]) * sin(degr);
175 new[1] = pivot[1] + (pos[0] - pivot[0]) * sin(degr) + (pos[1] - pivot[1]) * cos(degr);
176 return new;
177}
178
184vector
185angleDifference(vector angle1, vector angle2)
186{
187 static float Math_AngleDiff_S(float from, float to) {
188 float angleDelta = from - to;
189
190 if (angleDelta > 180) {
191 angleDelta -= 360;
192 } else if (angleDelta < -180) {
193 angleDelta += 360;
194 }
195
196 return angleDelta;
197 }
198
199 vector newAngle;
200
201 /* clean up input angles */
202 angle1 = fixAngle(angle1);
203 angle2 = fixAngle(angle2);
204
205 newAngle[0] = Math_AngleDiff_S(angle1[0], angle2[0]);
206 newAngle[1] = Math_AngleDiff_S(angle1[1], angle2[1]);
207 newAngle[2] = Math_AngleDiff_S(angle1[2], angle2[2]);
208 return newAngle;
209}
210
217vector
218hsvToRGB(float h, float s, float v)
219{
220 float i,f,p,q,t;
221 vector col = [0,0,0];
222
223 h = max(0.0, min(360.0, h));
224 s = max(0.0, min(100.0, s));
225 v = max(0.0, min(100.0, v));
226
227 s /= 100;
228 v /= 100;
229
230 if (s == 0) {
231 col[0] = col[1] = col[2] = rint(v*255);
232 return col;
233 }
234
235 h /= 60;
236 i = floor(h);
237 f = h - i;
238 p = v * (1 - s);
239 q = v * (1 - s * f);
240 t = v * (1 - s * (1 - f));
241
242 switch (i) {
243 case 0:
244 col[0] = rint(255*v);
245 col[1] = rint(255*t);
246 col[2] = rint(255*p);
247 break;
248 case 1:
249 col[0] = rint(255*q);
250 col[1] = rint(255*v);
251 col[2] = rint(255*p);
252 break;
253 case 2:
254 col[0] = rint(255*p);
255 col[1] = rint(255*v);
256 col[2] = rint(255*t);
257 break;
258 case 3:
259 col[0] = rint(255*p);
260 col[1] = rint(255*q);
261 col[2] = rint(255*v);
262 break;
263 case 4:
264 col[0] = rint(255*t);
265 col[1] = rint(255*p);
266 col[2] = rint(255*v);
267 break;
268 default:
269 col[0] = rint(255*v);
270 col[1] = rint(255*p);
271 col[2] = rint(255*q);
272 }
273 return col;
274} // end of math
276
277#include "math_vector.h"