Nuclide
Software Development Kit for id Technology (BETA)
c_math_vector.h
1/*
2 * Copyright (c) 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
27var vector g_vectorCacheLast;
28var vector g_vectorCacheForward;
29var vector g_vectorCacheRight;
30var vector g_vectorCacheUp;
31
32void AngleVectors ( vector angles )
33{
34 float angle;
35 float sr, sp, sy, cr, cp, cy;
36
37 angle = angles[1] * (M_PI*2 / 360);
38 sy = sin(angle);
39 cy = cos(angle);
40 angle = angles[0] * (M_PI*2 / 360);
41 sp = sin(angle);
42 cp = cos(angle);
43 angle = angles[2] * (M_PI*2 / 360);
44 sr = sin(angle);
45 cr = cos(angle);
46
47 v_forward[0] = cp*cy;
48 v_forward[1] = cp*sy;
49 v_forward[2] = -sp;
50
51 v_right[0] = (-1*sr*sp*cy+-1*cr*-sy);
52 v_right[1] = (-1*sr*sp*sy+-1*cr*cy);
53 v_right[2] = -1*sr*cp;
54
55 v_up[0] = (cr*sp*cy+-sr*-sy);
56 v_up[1] = (cr*sp*sy+-sr*cy);
57 v_up[2] = cr*cp;
58}
59
60static void
61anglesMake(vector targetAngle)
62{
63 AngleVectors(targetAngle);
64 g_vectorCacheLast = targetAngle;
65 g_vectorCacheForward = v_forward;
66 g_vectorCacheRight = v_right;
67 g_vectorCacheUp = v_up;
68}
69
75vector
76anglesToForward(vector targetAngle)
77{
78 if (targetAngle != g_vectorCacheLast) {
79 anglesMake(targetAngle);
80 }
81
82 return (g_vectorCacheForward);
83}
84
90vector
91anglesToRight(vector targetAngle)
92{
93 if (targetAngle != g_vectorCacheLast) {
94 anglesMake(targetAngle);
95 }
96
97 return (g_vectorCacheRight);
98}
99
105vector
106anglesToUp(vector targetAngle)
107{
108 if (targetAngle != g_vectorCacheLast) {
109 anglesMake(targetAngle);
110 }
111
112 return (g_vectorCacheUp);
113}
114
120float
121distanceSquared(vector pointA, vector pointB)
122{
123 float diffX = pointA[0] - pointB[0];
124 float diffY = pointA[1] - pointB[1];
125 float diffZ = pointA[2] - pointB[2];
126 return (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
127}
128
134float
135distance(vector pointA, vector pointB)
136{
137 return sqrt(distanceSquared(pointA, pointB));
138}
139
145float
146distance2D(vector pointA, vector pointB)
147{
148 float diffX = pointA[0] - pointB[0];
149 float diffY = pointA[1] - pointB[1];
150 return sqrt((diffX * diffX) + (diffY * diffY));
151}
152
159bool
160closer(vector referencePoint, vector pointA, vector pointB)
161{
162 float distanceA = distanceSquared(referencePoint, pointA);
163 float distanceB = distanceSquared(referencePoint, pointA);
164 return (distanceA < distanceB) ? true : false;
165}
166
171vector
172combineAngles(vector angleA, vector angleB)
173{
174 makevectors(angleA);
175 rotatevectorsbyangle(angleB);
176 return vectoangles(v_forward, v_up);
177}
178
183float
184length(vector toCalculate)
185{
186 static vector lastInput = g_vec_null;
187 static float lastOutput = 0.0f;
188
189 if (toCalculate == lastInput) {
190 return lastOutput;
191 }
192
193 lastInput = toCalculate;
194 lastOutput = vlen(toCalculate);
195 return lastOutput;
196}
197
202float
203lengthSquared(vector target)
204{
205 return (target[0] * target[0]) + (target[1] * target[1]) + (target[2] * target[2]);
206}
207
213float
214vectorDot(vector vectorA, vector vectorB)
215{
216 return dotproduct(vectorA, vectorB);
217}
218
225vector
226vectorLerp(vector fromVector, vector toVector, float lerpFraction)
227{
228 static float vectorLerp_Lerp( float fA, float fB, float fPercent) {
229 return (fA * (1 - fPercent)) + (fB * fPercent);
230 }
231
232 vector outputVector = g_vec_null;
233 outputVector[0] = vectorLerp_Lerp(fromVector[0], toVector[0], lerpFraction);
234 outputVector[1] = vectorLerp_Lerp(fromVector[1], toVector[1], lerpFraction);
235 outputVector[2] = vectorLerp_Lerp(fromVector[2], toVector[2], lerpFraction);
236 return outputVector;
237}
238
243vector
244vectorNormalize(vector toNormalize)
245{
246 static vector lastInput = g_vec_null;
247 static vector lastOutput = g_vec_null;
248
249 if (toNormalize == lastInput) {
250 return lastOutput;
251 }
252
253 lastInput = toNormalize;
254 lastOutput = normalize(toNormalize);
255 return lastOutput;
256}
257
262vector
263vectorToAngles(vector toAngles)
264{
265 static vector lastInput = g_vec_null;
266 static vector lastOutput = g_vec_null;
267
268 if (toAngles == lastInput) {
269 return lastOutput;
270 }
271
272 lastInput = toAngles;
273 lastOutput = fixAngle(vectoangles(toAngles));
274 return lastOutput;
275}
276
282vector
283vectorToAnglesRoll(vector forwardDir, vector rollDir)
284{
285 static vector lastInput = g_vec_null;
286 static vector lastInput2 = g_vec_null;
287 static vector lastOutput = g_vec_null;
288
289 if (forwardDir == lastInput && rollDir == lastInput2) {
290 return lastOutput;
291 }
292
293 lastInput = forwardDir;
294 lastInput2 = rollDir;
295 lastOutput = fixAngle(vectoangles(forwardDir, rollDir));
296 return lastOutput;
297}
298
305vector
306lerpAngleVector(vector inputAngle, vector endAngle, float lerpAmount)
307{
308 vector currentDir = anglesToForward(inputAngle);
309 vector desiredDir = anglesToForward(endAngle);
310 return vectorToAngles(vectorLerp(currentDir, desiredDir, lerpAmount));
311}
312
318vector
319dirFromTarget(vector lookingEnt, vector targetEnt)
320{
321 return anglesToForward(vectorToAngles(targetEnt - lookingEnt));
322}
323 // end of common