diff options
Diffstat (limited to 'linden/indra/llmath/v3math.h')
-rw-r--r-- | linden/indra/llmath/v3math.h | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/linden/indra/llmath/v3math.h b/linden/indra/llmath/v3math.h new file mode 100644 index 0000000..68e60de --- /dev/null +++ b/linden/indra/llmath/v3math.h | |||
@@ -0,0 +1,465 @@ | |||
1 | /** | ||
2 | * @file v3math.h | ||
3 | * @brief LLVector3 class header file. | ||
4 | * | ||
5 | * Copyright (c) 2000-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_V3MATH_H | ||
29 | #define LL_V3MATH_H | ||
30 | |||
31 | #include "llerror.h" | ||
32 | #include "llmath.h" | ||
33 | |||
34 | #include "llsd.h" | ||
35 | class LLVector4; | ||
36 | class LLMatrix3; | ||
37 | class LLVector3d; | ||
38 | class LLQuaternion; | ||
39 | |||
40 | // Llvector3 = |x y z w| | ||
41 | |||
42 | static const U32 LENGTHOFVECTOR3 = 3; | ||
43 | |||
44 | class LLVector3 | ||
45 | { | ||
46 | public: | ||
47 | F32 mV[LENGTHOFVECTOR3]; | ||
48 | |||
49 | static const LLVector3 zero; | ||
50 | static const LLVector3 x_axis; | ||
51 | static const LLVector3 y_axis; | ||
52 | static const LLVector3 z_axis; | ||
53 | static const LLVector3 x_axis_neg; | ||
54 | static const LLVector3 y_axis_neg; | ||
55 | static const LLVector3 z_axis_neg; | ||
56 | static const LLVector3 all_one; | ||
57 | |||
58 | inline LLVector3(); // Initializes LLVector3 to (0, 0, 0) | ||
59 | inline LLVector3(const F32 x, const F32 y, const F32 z); // Initializes LLVector3 to (x. y, z) | ||
60 | inline explicit LLVector3(const F32 *vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) | ||
61 | explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) | ||
62 | explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) | ||
63 | LLVector3(const LLSD& sd) | ||
64 | { | ||
65 | setValue(sd); | ||
66 | } | ||
67 | |||
68 | LLSD getValue() const | ||
69 | { | ||
70 | LLSD ret; | ||
71 | ret[0] = mV[0]; | ||
72 | ret[1] = mV[1]; | ||
73 | ret[2] = mV[2]; | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | void setValue(const LLSD& sd) | ||
78 | { | ||
79 | mV[0] = (F32) sd[0].asReal(); | ||
80 | mV[1] = (F32) sd[1].asReal(); | ||
81 | mV[2] = (F32) sd[2].asReal(); | ||
82 | } | ||
83 | |||
84 | const LLVector3& operator=(const LLSD& sd) | ||
85 | { | ||
86 | setValue(sd); | ||
87 | return *this; | ||
88 | } | ||
89 | |||
90 | inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite | ||
91 | BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed | ||
92 | |||
93 | void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization | ||
94 | void quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization | ||
95 | void snap(S32 sig_digits); // snaps x,y,z to sig_digits decimal places | ||
96 | |||
97 | BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed | ||
98 | |||
99 | inline void clearVec(); // Clears LLVector3 to (0, 0, 0, 1) | ||
100 | inline void zeroVec(); // Zero LLVector3 to (0, 0, 0, 0) | ||
101 | inline void setVec(F32 x, F32 y, F32 z); // Sets LLVector3 to (x, y, z, 1) | ||
102 | inline void setVec(const LLVector3 &vec); // Sets LLVector3 to vec | ||
103 | inline void setVec(const F32 *vec); // Sets LLVector3 to vec | ||
104 | |||
105 | const LLVector3& setVec(const LLVector4 &vec); | ||
106 | const LLVector3& setVec(const LLVector3d &vec); // Sets LLVector3 to vec | ||
107 | |||
108 | F32 magVec() const; // Returns magnitude of LLVector3 | ||
109 | F32 magVecSquared() const; // Returns magnitude squared of LLVector3 | ||
110 | inline F32 normVec(); // Normalizes and returns the magnitude of LLVector3 | ||
111 | |||
112 | const LLVector3& rotVec(F32 angle, const LLVector3 &vec); // Rotates about vec by angle radians | ||
113 | const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians | ||
114 | const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat | ||
115 | const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q | ||
116 | |||
117 | const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec | ||
118 | LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec | ||
119 | |||
120 | BOOL isNull() const; // Returns TRUE if vector has a _very_small_ length | ||
121 | BOOL isExactlyZero() const { return !mV[VX] && !mV[VY] && !mV[VZ]; } | ||
122 | |||
123 | F32 operator[](int idx) const { return mV[idx]; } | ||
124 | F32 &operator[](int idx) { return mV[idx]; } | ||
125 | |||
126 | friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b); // Return vector a + b | ||
127 | friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b); // Return vector a minus b | ||
128 | friend F32 operator*(const LLVector3 &a, const LLVector3 &b); // Return a dot b | ||
129 | friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b); // Return a cross b | ||
130 | friend LLVector3 operator*(const LLVector3 &a, F32 k); // Return a times scaler k | ||
131 | friend LLVector3 operator/(const LLVector3 &a, F32 k); // Return a divided by scaler k | ||
132 | friend LLVector3 operator*(F32 k, const LLVector3 &a); // Return a times scaler k | ||
133 | friend bool operator==(const LLVector3 &a, const LLVector3 &b); // Return a == b | ||
134 | friend bool operator!=(const LLVector3 &a, const LLVector3 &b); // Return a != b | ||
135 | // less than operator useful for using vectors as std::map keys | ||
136 | friend bool operator<(const LLVector3 &a, const LLVector3 &b); // Return a < b | ||
137 | |||
138 | friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b); // Return vector a + b | ||
139 | friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b); // Return vector a minus b | ||
140 | friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b); // Return a cross b | ||
141 | friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b); // Returns a * b; | ||
142 | friend const LLVector3& operator*=(LLVector3 &a, F32 k); // Return a times scaler k | ||
143 | friend const LLVector3& operator/=(LLVector3 &a, F32 k); // Return a divided by scaler k | ||
144 | friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b); // Returns a * b; | ||
145 | |||
146 | friend LLVector3 operator-(const LLVector3 &a); // Return vector -a | ||
147 | |||
148 | friend std::ostream& operator<<(std::ostream& s, const LLVector3 &a); // Stream a | ||
149 | |||
150 | static BOOL parseVector3(const char* buf, LLVector3* value); | ||
151 | }; | ||
152 | |||
153 | typedef LLVector3 LLSimLocalVec; | ||
154 | |||
155 | // Non-member functions | ||
156 | |||
157 | F32 angle_between(const LLVector3 &a, const LLVector3 &b); // Returns angle (radians) between a and b | ||
158 | BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon=F_APPROXIMATELY_ZERO); // Returns TRUE if a and b are very close to parallel | ||
159 | F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance between a and b | ||
160 | F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance sqaured between a and b | ||
161 | F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance sqaured between a and b ignoring Z component | ||
162 | LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b | ||
163 | LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b | ||
164 | |||
165 | inline LLVector3::LLVector3(void) | ||
166 | { | ||
167 | mV[0] = 0.f; | ||
168 | mV[1] = 0.f; | ||
169 | mV[2] = 0.f; | ||
170 | } | ||
171 | |||
172 | inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z) | ||
173 | { | ||
174 | mV[VX] = x; | ||
175 | mV[VY] = y; | ||
176 | mV[VZ] = z; | ||
177 | } | ||
178 | |||
179 | inline LLVector3::LLVector3(const F32 *vec) | ||
180 | { | ||
181 | mV[VX] = vec[VX]; | ||
182 | mV[VY] = vec[VY]; | ||
183 | mV[VZ] = vec[VZ]; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | inline LLVector3::LLVector3(const LLVector3 ©) | ||
188 | { | ||
189 | mV[VX] = copy.mV[VX]; | ||
190 | mV[VY] = copy.mV[VY]; | ||
191 | mV[VZ] = copy.mV[VZ]; | ||
192 | } | ||
193 | */ | ||
194 | |||
195 | // Destructors | ||
196 | |||
197 | // checker | ||
198 | inline BOOL LLVector3::isFinite() const | ||
199 | { | ||
200 | return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ])); | ||
201 | } | ||
202 | |||
203 | |||
204 | // Clear and Assignment Functions | ||
205 | |||
206 | inline void LLVector3::clearVec(void) | ||
207 | { | ||
208 | mV[0] = 0.f; | ||
209 | mV[1] = 0.f; | ||
210 | mV[2] = 0.f; | ||
211 | } | ||
212 | |||
213 | inline void LLVector3::zeroVec(void) | ||
214 | { | ||
215 | mV[0] = 0.f; | ||
216 | mV[1] = 0.f; | ||
217 | mV[2] = 0.f; | ||
218 | } | ||
219 | |||
220 | inline void LLVector3::setVec(F32 x, F32 y, F32 z) | ||
221 | { | ||
222 | mV[VX] = x; | ||
223 | mV[VY] = y; | ||
224 | mV[VZ] = z; | ||
225 | } | ||
226 | |||
227 | inline void LLVector3::setVec(const LLVector3 &vec) | ||
228 | { | ||
229 | mV[0] = vec.mV[0]; | ||
230 | mV[1] = vec.mV[1]; | ||
231 | mV[2] = vec.mV[2]; | ||
232 | } | ||
233 | |||
234 | inline void LLVector3::setVec(const F32 *vec) | ||
235 | { | ||
236 | mV[0] = vec[0]; | ||
237 | mV[1] = vec[1]; | ||
238 | mV[2] = vec[2]; | ||
239 | } | ||
240 | |||
241 | inline F32 LLVector3::normVec(void) | ||
242 | { | ||
243 | F32 mag = fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); | ||
244 | F32 oomag; | ||
245 | |||
246 | if (mag > FP_MAG_THRESHOLD) | ||
247 | { | ||
248 | oomag = 1.f/mag; | ||
249 | mV[0] *= oomag; | ||
250 | mV[1] *= oomag; | ||
251 | mV[2] *= oomag; | ||
252 | } | ||
253 | else | ||
254 | { | ||
255 | mV[0] = 0.f; | ||
256 | mV[1] = 0.f; | ||
257 | mV[2] = 0.f; | ||
258 | mag = 0; | ||
259 | } | ||
260 | return (mag); | ||
261 | } | ||
262 | |||
263 | // LLVector3 Magnitude and Normalization Functions | ||
264 | |||
265 | inline F32 LLVector3::magVec(void) const | ||
266 | { | ||
267 | return fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); | ||
268 | } | ||
269 | |||
270 | inline F32 LLVector3::magVecSquared(void) const | ||
271 | { | ||
272 | return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; | ||
273 | } | ||
274 | |||
275 | inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b) | ||
276 | { | ||
277 | LLVector3 c(a); | ||
278 | return c += b; | ||
279 | } | ||
280 | |||
281 | inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b) | ||
282 | { | ||
283 | LLVector3 c(a); | ||
284 | return c -= b; | ||
285 | } | ||
286 | |||
287 | inline F32 operator*(const LLVector3 &a, const LLVector3 &b) | ||
288 | { | ||
289 | return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]); | ||
290 | } | ||
291 | |||
292 | inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b) | ||
293 | { | ||
294 | return LLVector3( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1] ); | ||
295 | } | ||
296 | |||
297 | inline LLVector3 operator/(const LLVector3 &a, F32 k) | ||
298 | { | ||
299 | F32 t = 1.f / k; | ||
300 | return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t ); | ||
301 | } | ||
302 | |||
303 | inline LLVector3 operator*(const LLVector3 &a, F32 k) | ||
304 | { | ||
305 | return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); | ||
306 | } | ||
307 | |||
308 | inline LLVector3 operator*(F32 k, const LLVector3 &a) | ||
309 | { | ||
310 | return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); | ||
311 | } | ||
312 | |||
313 | inline bool operator==(const LLVector3 &a, const LLVector3 &b) | ||
314 | { | ||
315 | return ( (a.mV[0] == b.mV[0]) | ||
316 | &&(a.mV[1] == b.mV[1]) | ||
317 | &&(a.mV[2] == b.mV[2])); | ||
318 | } | ||
319 | |||
320 | inline bool operator!=(const LLVector3 &a, const LLVector3 &b) | ||
321 | { | ||
322 | return ( (a.mV[0] != b.mV[0]) | ||
323 | ||(a.mV[1] != b.mV[1]) | ||
324 | ||(a.mV[2] != b.mV[2])); | ||
325 | } | ||
326 | |||
327 | inline bool operator<(const LLVector3 &a, const LLVector3 &b) | ||
328 | { | ||
329 | return (a.mV[0] < b.mV[0] | ||
330 | || (a.mV[0] == b.mV[0] | ||
331 | && (a.mV[1] < b.mV[1] | ||
332 | || (a.mV[1] == b.mV[1]) | ||
333 | && a.mV[2] < b.mV[2]))); | ||
334 | } | ||
335 | |||
336 | inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b) | ||
337 | { | ||
338 | a.mV[0] += b.mV[0]; | ||
339 | a.mV[1] += b.mV[1]; | ||
340 | a.mV[2] += b.mV[2]; | ||
341 | return a; | ||
342 | } | ||
343 | |||
344 | inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b) | ||
345 | { | ||
346 | a.mV[0] -= b.mV[0]; | ||
347 | a.mV[1] -= b.mV[1]; | ||
348 | a.mV[2] -= b.mV[2]; | ||
349 | return a; | ||
350 | } | ||
351 | |||
352 | inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b) | ||
353 | { | ||
354 | LLVector3 ret( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1]); | ||
355 | a = ret; | ||
356 | return a; | ||
357 | } | ||
358 | |||
359 | inline const LLVector3& operator*=(LLVector3 &a, F32 k) | ||
360 | { | ||
361 | a.mV[0] *= k; | ||
362 | a.mV[1] *= k; | ||
363 | a.mV[2] *= k; | ||
364 | return a; | ||
365 | } | ||
366 | |||
367 | inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b) | ||
368 | { | ||
369 | a.mV[0] *= b.mV[0]; | ||
370 | a.mV[1] *= b.mV[1]; | ||
371 | a.mV[2] *= b.mV[2]; | ||
372 | return a; | ||
373 | } | ||
374 | |||
375 | inline const LLVector3& operator/=(LLVector3 &a, F32 k) | ||
376 | { | ||
377 | F32 t = 1.f / k; | ||
378 | a.mV[0] *= t; | ||
379 | a.mV[1] *= t; | ||
380 | a.mV[2] *= t; | ||
381 | return a; | ||
382 | } | ||
383 | |||
384 | inline LLVector3 operator-(const LLVector3 &a) | ||
385 | { | ||
386 | return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] ); | ||
387 | } | ||
388 | |||
389 | inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b) | ||
390 | { | ||
391 | F32 x = a.mV[0] - b.mV[0]; | ||
392 | F32 y = a.mV[1] - b.mV[1]; | ||
393 | F32 z = a.mV[2] - b.mV[2]; | ||
394 | return fsqrtf( x*x + y*y + z*z ); | ||
395 | } | ||
396 | |||
397 | inline F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b) | ||
398 | { | ||
399 | F32 x = a.mV[0] - b.mV[0]; | ||
400 | F32 y = a.mV[1] - b.mV[1]; | ||
401 | F32 z = a.mV[2] - b.mV[2]; | ||
402 | return x*x + y*y + z*z; | ||
403 | } | ||
404 | |||
405 | inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b) | ||
406 | { | ||
407 | F32 x = a.mV[0] - b.mV[0]; | ||
408 | F32 y = a.mV[1] - b.mV[1]; | ||
409 | return x*x + y*y; | ||
410 | } | ||
411 | |||
412 | inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b) | ||
413 | { | ||
414 | LLVector3 project_axis = b; | ||
415 | project_axis.normVec(); | ||
416 | return project_axis * (a * project_axis); | ||
417 | } | ||
418 | |||
419 | inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u) | ||
420 | { | ||
421 | return LLVector3( | ||
422 | a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, | ||
423 | a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, | ||
424 | a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u); | ||
425 | } | ||
426 | |||
427 | |||
428 | inline BOOL LLVector3::isNull() const | ||
429 | { | ||
430 | if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] ) | ||
431 | { | ||
432 | return TRUE; | ||
433 | } | ||
434 | return FALSE; | ||
435 | } | ||
436 | |||
437 | |||
438 | inline F32 angle_between(const LLVector3& a, const LLVector3& b) | ||
439 | { | ||
440 | LLVector3 an = a; | ||
441 | LLVector3 bn = b; | ||
442 | an.normVec(); | ||
443 | bn.normVec(); | ||
444 | F32 cosine = an * bn; | ||
445 | F32 angle = (cosine >= 1.0f) ? 0.0f : | ||
446 | (cosine <= -1.0f) ? F_PI : | ||
447 | (F32)acos(cosine); | ||
448 | return angle; | ||
449 | } | ||
450 | |||
451 | inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon) | ||
452 | { | ||
453 | LLVector3 an = a; | ||
454 | LLVector3 bn = b; | ||
455 | an.normVec(); | ||
456 | bn.normVec(); | ||
457 | F32 dot = an * bn; | ||
458 | if ( (1.0f - fabs(dot)) < epsilon) | ||
459 | { | ||
460 | return TRUE; | ||
461 | } | ||
462 | return FALSE; | ||
463 | } | ||
464 | |||
465 | #endif | ||