Nuclide
Software Development Kit for id Technology
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
32static void
33anglesMake(vector angle)
34{
35 makevectors(angle);
36 g_vectorCacheLast = angle;
37 g_vectorCacheForward = v_forward;
38 g_vectorCacheRight = v_right;
39 g_vectorCacheUp = v_up;
40}
41
47vector
48anglesToForward(vector angle)
49{
50 if (angle == g_vectorCacheLast) {
51 return g_vectorCacheForward;
52 }
53
54 anglesMake(angle);
55 return g_vectorCacheForward;
56}
57
63vector
64anglesToRight(vector angle)
65{
66 if (angle == g_vectorCacheLast) {
67 return g_vectorCacheRight;
68 }
69
70 anglesMake(angle);
71 return g_vectorCacheRight;
72}
73
79vector
80anglesToUp(vector angle)
81{
82 if (angle == g_vectorCacheLast) {
83 return g_vectorCacheUp;
84 }
85
86 anglesMake(angle);
87 return g_vectorCacheUp;
88}
89
95float
96distanceSquared(vector pointA, vector pointB)
97{
98 float diffX = pointA[0] - pointB[0];
99 float diffY = pointA[1] - pointB[1];
100 float diffZ = pointA[2] - pointB[2];
101 return (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
102}
103
109float
110distance(vector pointA, vector pointB)
111{
112 return sqrt(distanceSquared(pointA, pointB));
113}
114
120float
121distance2D(vector pointA, vector pointB)
122{
123 float diffX = pointA[0] - pointB[0];
124 float diffY = pointA[1] - pointB[1];
125 return sqrt((diffX * diffX) + (diffY * diffY));
126}
127
134bool
135closer(vector referencePoint, vector pointA, vector pointB)
136{
137 float distanceA = distanceSquared(referencePoint, pointA);
138 float distanceB = distanceSquared(referencePoint, pointA);
139 return (distanceA < distanceB) ? true : false;
140}
141
146vector
147combineAngles(vector angleA, vector angleB)
148{
149 makevectors(angleA);
150 rotatevectorsbyangle(angleB);
151 return vectoangles(v_forward, v_up);
152}
153
158float
159length(vector toCalculate)
160{
161 static vector lastInput = g_vec_null;
162 static float lastOutput = 0.0f;
163
164 if (toCalculate == lastInput) {
165 return lastOutput;
166 }
167
168 lastInput = toCalculate;
169 lastOutput = vlen(toCalculate);
170 return lastOutput;
171}
172
177float
178lengthSquared(vector target)
179{
180 return (target[0] * target[0]) + (target[1] * target[1]) + (target[2] * target[2]);
181}
182
188float
189vectorDot(vector vectorA, vector vectorB)
190{
191 return dotproduct(vectorA, vectorB);
192}
193
200vector
201vectorLerp(vector fromVector, vector toVector, float lerpFraction)
202{
203 static float vectorLerp_Lerp( float fA, float fB, float fPercent) {
204 return (fA * (1 - fPercent)) + (fB * fPercent);
205 }
206
207 vector outputVector = g_vec_null;
208 outputVector[0] = vectorLerp_Lerp(fromVector[0], toVector[0], lerpFraction);
209 outputVector[1] = vectorLerp_Lerp(fromVector[1], toVector[1], lerpFraction);
210 outputVector[2] = vectorLerp_Lerp(fromVector[2], toVector[2], lerpFraction);
211 return outputVector;
212}
213
218vector
219vectorNormalize(vector toNormalize)
220{
221 static vector lastInput = g_vec_null;
222 static vector lastOutput = g_vec_null;
223
224 if (toNormalize == lastInput) {
225 return lastOutput;
226 }
227
228 lastInput = toNormalize;
229 lastOutput = normalize(toNormalize);
230 return lastOutput;
231}
232
237vector
238vectorToAngles(vector toAngles)
239{
240 static vector lastInput = g_vec_null;
241 static vector lastOutput = g_vec_null;
242
243 if (toAngles == lastInput) {
244 return lastOutput;
245 }
246
247 lastInput = toAngles;
248 lastOutput = fixAngle(vectoangles(toAngles));
249 return lastOutput;
250}
251
257vector
258vectorToAnglesRoll(vector forwardDir, vector rollDir)
259{
260 static vector lastInput = g_vec_null;
261 static vector lastInput2 = g_vec_null;
262 static vector lastOutput = g_vec_null;
263
264 if (forwardDir == lastInput && rollDir == lastInput2) {
265 return lastOutput;
266 }
267
268 lastInput = forwardDir;
269 lastInput2 = rollDir;
270 lastOutput = fixAngle(vectoangles(forwardDir, rollDir));
271 return lastOutput;
272}
273
280vector
281lerpAngleVector(vector inputAngle, vector endAngle, float lerpAmount)
282{
283 vector currentDir = anglesToForward(inputAngle);
284 vector desiredDir = anglesToForward(endAngle);
285 return vectorToAngles(vectorLerp(currentDir, desiredDir, lerpAmount));
286}
287
293vector
294dirFromTarget(vector lookingEnt, vector targetEnt)
295{
296 return anglesToForward(vectorToAngles(targetEnt - lookingEnt));
297}
298 // end of common