PageRenderTime 79ms CodeModel.GetById 1ms app.highlight 72ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmath/v3math.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 590 lines | 453 code | 93 blank | 44 comment | 29 complexity | 0da4c56b6ef5bb60c1eeb070a849949b MD5 | raw file
  1/** 
  2 * @file v3math.h
  3 * @brief LLVector3 class header file.
  4 *
  5 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library 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 GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_V3MATH_H
 28#define LL_V3MATH_H
 29
 30#include "llerror.h"
 31#include "llmath.h"
 32
 33#include "llsd.h"
 34class LLVector2;
 35class LLVector4;
 36class LLMatrix3;
 37class LLMatrix4;
 38class LLVector3d;
 39class LLQuaternion;
 40
 41//  LLvector3 = |x y z w|
 42
 43static const U32 LENGTHOFVECTOR3 = 3;
 44
 45class LLVector3
 46{
 47	public:
 48		F32 mV[LENGTHOFVECTOR3];
 49
 50		static const LLVector3 zero;
 51		static const LLVector3 x_axis;
 52		static const LLVector3 y_axis;
 53		static const LLVector3 z_axis;
 54		static const LLVector3 x_axis_neg;
 55		static const LLVector3 y_axis_neg;
 56		static const LLVector3 z_axis_neg;
 57		static const LLVector3 all_one;
 58
 59		inline LLVector3();							// Initializes LLVector3 to (0, 0, 0)
 60		inline LLVector3(const F32 x, const F32 y, const F32 z);			// Initializes LLVector3 to (x. y, z)
 61		inline explicit LLVector3(const F32 *vec);				// Initializes LLVector3 to (vec[0]. vec[1], vec[2])
 62		explicit LLVector3(const LLVector2 &vec);				// Initializes LLVector3 to (vec[0]. vec[1], 0)
 63		explicit LLVector3(const LLVector3d &vec);				// Initializes LLVector3 to (vec[0]. vec[1], vec[2])
 64		explicit LLVector3(const LLVector4 &vec);				// Initializes LLVector4 to (vec[0]. vec[1], vec[2])
 65		explicit LLVector3(const LLSD& sd);
 66
 67		LLSD getValue() const;
 68
 69		void setValue(const LLSD& sd);
 70
 71		inline BOOL isFinite() const;									// checks to see if all values of LLVector3 are finite
 72		BOOL		clamp(F32 min, F32 max);		// Clamps all values to (min,max), returns TRUE if data changed
 73		BOOL		clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector
 74		BOOL		clampLength( F32 length_limit );					// Scales vector to limit length to a value
 75
 76		void		quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization
 77		void		quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization
 78		void 		snap(S32 sig_digits);											// snaps x,y,z to sig_digits decimal places
 79
 80		BOOL		abs();						// sets all values to absolute value of original value (first octant), returns TRUE if changed
 81		
 82		inline void	clear();						// Clears LLVector3 to (0, 0, 0)
 83		inline void	setZero();						// Clears LLVector3 to (0, 0, 0)
 84		inline void	clearVec();						// deprecated
 85		inline void	zeroVec();						// deprecated
 86
 87		inline void	set(F32 x, F32 y, F32 z);		// Sets LLVector3 to (x, y, z, 1)
 88		inline void	set(const LLVector3 &vec);		// Sets LLVector3 to vec
 89		inline void	set(const F32 *vec);			// Sets LLVector3 to vec
 90		const LLVector3& set(const LLVector4 &vec);
 91		const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec
 92
 93		inline void	setVec(F32 x, F32 y, F32 z);	// deprecated
 94		inline void	setVec(const LLVector3 &vec);	// deprecated
 95		inline void	setVec(const F32 *vec);			// deprecated
 96
 97		const LLVector3& setVec(const LLVector4 &vec);  // deprecated
 98		const LLVector3& setVec(const LLVector3d &vec);	// deprecated
 99
100		F32		length() const;			// Returns magnitude of LLVector3
101		F32		lengthSquared() const;	// Returns magnitude squared of LLVector3
102		F32		magVec() const;			// deprecated
103		F32		magVecSquared() const;	// deprecated
104
105		inline F32		normalize();	// Normalizes and returns the magnitude of LLVector3
106		inline F32		normVec();		// deprecated
107
108		inline BOOL inRange( F32 min, F32 max ) const; // Returns true if all values of the vector are between min and max
109
110		const LLVector3&	rotVec(F32 angle, const LLVector3 &vec);	// Rotates about vec by angle radians
111		const LLVector3&	rotVec(F32 angle, F32 x, F32 y, F32 z);		// Rotates about x,y,z by angle radians
112		const LLVector3&	rotVec(const LLMatrix3 &mat);				// Rotates by LLMatrix4 mat
113		const LLVector3&	rotVec(const LLQuaternion &q);				// Rotates by LLQuaternion q
114		const LLVector3&	transVec(const LLMatrix4& mat);				// Transforms by LLMatrix4 mat (mat * v)
115
116		const LLVector3&	scaleVec(const LLVector3& vec);				// scales per component by vec
117		LLVector3			scaledVec(const LLVector3& vec) const;			// get a copy of this vector scaled by vec
118
119		BOOL isNull() const;			// Returns TRUE if vector has a _very_small_ length
120		BOOL isExactlyZero() const		{ return !mV[VX] && !mV[VY] && !mV[VZ]; }
121
122		F32 operator[](int idx) const { return mV[idx]; }
123		F32 &operator[](int idx) { return mV[idx]; }
124	
125		friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b);	// Return vector a + b
126		friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b);	// Return vector a minus b
127		friend F32 operator*(const LLVector3 &a, const LLVector3 &b);		// Return a dot b
128		friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b);	// Return a cross b
129		friend LLVector3 operator*(const LLVector3 &a, F32 k);				// Return a times scaler k
130		friend LLVector3 operator/(const LLVector3 &a, F32 k);				// Return a divided by scaler k
131		friend LLVector3 operator*(F32 k, const LLVector3 &a);				// Return a times scaler k
132		friend bool operator==(const LLVector3 &a, const LLVector3 &b);		// Return a == b
133		friend bool operator!=(const LLVector3 &a, const LLVector3 &b);		// Return a != b
134		// less than operator useful for using vectors as std::map keys
135		friend bool operator<(const LLVector3 &a, const LLVector3 &b);		// Return a < b
136
137		friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b);	// Return vector a + b
138		friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b);	// Return vector a minus b
139		friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b);	// Return a cross b
140		friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b);	// Returns a * b;
141		friend const LLVector3& operator*=(LLVector3 &a, F32 k);				// Return a times scaler k
142		friend const LLVector3& operator/=(LLVector3 &a, F32 k);				// Return a divided by scaler k
143		friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b);	// Returns a * b;
144
145		friend LLVector3 operator-(const LLVector3 &a);					// Return vector -a
146
147		friend std::ostream&	 operator<<(std::ostream& s, const LLVector3 &a);		// Stream a
148
149		static BOOL parseVector3(const std::string& buf, LLVector3* value);
150};
151
152typedef LLVector3 LLSimLocalVec;
153
154// Non-member functions 
155
156F32	angle_between(const LLVector3 &a, const LLVector3 &b);	// Returns angle (radians) between a and b
157BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon=F_APPROXIMATELY_ZERO);	// Returns TRUE if a and b are very close to parallel
158F32	dist_vec(const LLVector3 &a, const LLVector3 &b);		// Returns distance between a and b
159F32	dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b
160F32	dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component
161LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
162LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
163LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
164LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
165
166inline LLVector3::LLVector3(void)
167{
168	mV[0] = 0.f;
169	mV[1] = 0.f;
170	mV[2] = 0.f;
171}
172
173inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)
174{
175	mV[VX] = x;
176	mV[VY] = y;
177	mV[VZ] = z;
178}
179
180inline LLVector3::LLVector3(const F32 *vec)
181{
182	mV[VX] = vec[VX];
183	mV[VY] = vec[VY];
184	mV[VZ] = vec[VZ];
185}
186
187/*
188inline LLVector3::LLVector3(const LLVector3 &copy)
189{
190	mV[VX] = copy.mV[VX];
191	mV[VY] = copy.mV[VY];
192	mV[VZ] = copy.mV[VZ];
193}
194*/
195
196// Destructors
197
198// checker
199inline BOOL LLVector3::isFinite() const
200{
201	return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));
202}
203
204
205// Clear and Assignment Functions
206
207inline void	LLVector3::clear(void)
208{
209	mV[0] = 0.f;
210	mV[1] = 0.f;
211	mV[2] = 0.f;
212}
213
214inline void	LLVector3::setZero(void)
215{
216	mV[0] = 0.f;
217	mV[1] = 0.f;
218	mV[2] = 0.f;
219}
220
221inline void	LLVector3::clearVec(void)
222{
223	mV[0] = 0.f;
224	mV[1] = 0.f;
225	mV[2] = 0.f;
226}
227
228inline void	LLVector3::zeroVec(void)
229{
230	mV[0] = 0.f;
231	mV[1] = 0.f;
232	mV[2] = 0.f;
233}
234
235inline void	LLVector3::set(F32 x, F32 y, F32 z)
236{
237	mV[VX] = x;
238	mV[VY] = y;
239	mV[VZ] = z;
240}
241
242inline void	LLVector3::set(const LLVector3 &vec)
243{
244	mV[0] = vec.mV[0];
245	mV[1] = vec.mV[1];
246	mV[2] = vec.mV[2];
247}
248
249inline void	LLVector3::set(const F32 *vec)
250{
251	mV[0] = vec[0];
252	mV[1] = vec[1];
253	mV[2] = vec[2];
254}
255
256// deprecated
257inline void	LLVector3::setVec(F32 x, F32 y, F32 z)
258{
259	mV[VX] = x;
260	mV[VY] = y;
261	mV[VZ] = z;
262}
263
264// deprecated
265inline void	LLVector3::setVec(const LLVector3 &vec)
266{
267	mV[0] = vec.mV[0];
268	mV[1] = vec.mV[1];
269	mV[2] = vec.mV[2];
270}
271
272// deprecated
273inline void	LLVector3::setVec(const F32 *vec)
274{
275	mV[0] = vec[0];
276	mV[1] = vec[1];
277	mV[2] = vec[2];
278}
279
280inline F32 LLVector3::normalize(void)
281{
282	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
283	F32 oomag;
284
285	if (mag > FP_MAG_THRESHOLD)
286	{
287		oomag = 1.f/mag;
288		mV[0] *= oomag;
289		mV[1] *= oomag;
290		mV[2] *= oomag;
291	}
292	else
293	{
294		mV[0] = 0.f;
295		mV[1] = 0.f;
296		mV[2] = 0.f;
297		mag = 0;
298	}
299	return (mag);
300}
301
302// deprecated
303inline F32 LLVector3::normVec(void)
304{
305	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
306	F32 oomag;
307
308	if (mag > FP_MAG_THRESHOLD)
309	{
310		oomag = 1.f/mag;
311		mV[0] *= oomag;
312		mV[1] *= oomag;
313		mV[2] *= oomag;
314	}
315	else
316	{
317		mV[0] = 0.f;
318		mV[1] = 0.f;
319		mV[2] = 0.f;
320		mag = 0;
321	}
322	return (mag);
323}
324
325// LLVector3 Magnitude and Normalization Functions
326
327inline F32	LLVector3::length(void) const
328{
329	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
330}
331
332inline F32	LLVector3::lengthSquared(void) const
333{
334	return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
335}
336
337inline F32	LLVector3::magVec(void) const
338{
339	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
340}
341
342inline F32	LLVector3::magVecSquared(void) const
343{
344	return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
345}
346
347inline BOOL LLVector3::inRange( F32 min, F32 max ) const
348{
349	return mV[0] >= min && mV[0] <= max &&
350		   mV[1] >= min && mV[1] <= max &&
351		   mV[2] >= min && mV[2] <= max;		
352}
353
354inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b)
355{
356	LLVector3 c(a);
357	return c += b;
358}
359
360inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b)
361{
362	LLVector3 c(a);
363	return c -= b;
364}
365
366inline F32  operator*(const LLVector3 &a, const LLVector3 &b)
367{
368	return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]);
369}
370
371inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b)
372{
373	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] );
374}
375
376inline LLVector3 operator/(const LLVector3 &a, F32 k)
377{
378	F32 t = 1.f / k;
379	return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t );
380}
381
382inline LLVector3 operator*(const LLVector3 &a, F32 k)
383{
384	return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
385}
386
387inline LLVector3 operator*(F32 k, const LLVector3 &a)
388{
389	return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
390}
391
392inline bool operator==(const LLVector3 &a, const LLVector3 &b)
393{
394	return (  (a.mV[0] == b.mV[0])
395			&&(a.mV[1] == b.mV[1])
396			&&(a.mV[2] == b.mV[2]));
397}
398
399inline bool operator!=(const LLVector3 &a, const LLVector3 &b)
400{
401	return (  (a.mV[0] != b.mV[0])
402			||(a.mV[1] != b.mV[1])
403			||(a.mV[2] != b.mV[2]));
404}
405
406inline bool operator<(const LLVector3 &a, const LLVector3 &b)
407{
408	return (a.mV[0] < b.mV[0]
409			|| (a.mV[0] == b.mV[0]
410				&& (a.mV[1] < b.mV[1]
411					|| ((a.mV[1] == b.mV[1])
412						&& a.mV[2] < b.mV[2]))));
413}
414
415inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b)
416{
417	a.mV[0] += b.mV[0];
418	a.mV[1] += b.mV[1];
419	a.mV[2] += b.mV[2];
420	return a;
421}
422
423inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b)
424{
425	a.mV[0] -= b.mV[0];
426	a.mV[1] -= b.mV[1];
427	a.mV[2] -= b.mV[2];
428	return a;
429}
430
431inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b)
432{
433	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]);
434	a = ret;
435	return a;
436}
437
438inline const LLVector3& operator*=(LLVector3 &a, F32 k)
439{
440	a.mV[0] *= k;
441	a.mV[1] *= k;
442	a.mV[2] *= k;
443	return a;
444}
445
446inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b)
447{
448	a.mV[0] *= b.mV[0];
449	a.mV[1] *= b.mV[1];
450	a.mV[2] *= b.mV[2];
451	return a;
452}
453
454inline const LLVector3& operator/=(LLVector3 &a, F32 k)
455{
456	F32 t = 1.f / k;
457	a.mV[0] *= t;
458	a.mV[1] *= t;
459	a.mV[2] *= t;
460	return a;
461}
462
463inline LLVector3 operator-(const LLVector3 &a)
464{
465	return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );
466}
467
468inline F32	dist_vec(const LLVector3 &a, const LLVector3 &b)
469{
470	F32 x = a.mV[0] - b.mV[0];
471	F32 y = a.mV[1] - b.mV[1];
472	F32 z = a.mV[2] - b.mV[2];
473	return (F32) sqrt( x*x + y*y + z*z );
474}
475
476inline F32	dist_vec_squared(const LLVector3 &a, const LLVector3 &b)
477{
478	F32 x = a.mV[0] - b.mV[0];
479	F32 y = a.mV[1] - b.mV[1];
480	F32 z = a.mV[2] - b.mV[2];
481	return x*x + y*y + z*z;
482}
483
484inline F32	dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)
485{
486	F32 x = a.mV[0] - b.mV[0];
487	F32 y = a.mV[1] - b.mV[1];
488	return x*x + y*y;
489}
490
491inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
492{
493	LLVector3 project_axis = b;
494	project_axis.normalize();
495	return project_axis * (a * project_axis);
496}
497
498inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
499{
500	return projected_vec(a, b);
501}
502
503inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)
504{
505	return a - projected_vec(a, b);
506}
507
508
509inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
510{
511	return LLVector3(
512		a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
513		a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
514		a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
515}
516
517
518inline BOOL	LLVector3::isNull() const
519{
520	if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] )
521	{
522		return TRUE;
523	}
524	return FALSE;
525}
526
527inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
528{
529	for (U32 i = 0; i < 3; i++)
530	{
531		if (min.mV[i] > pos.mV[i])
532		{
533			min.mV[i] = pos.mV[i];
534		}
535		if (max.mV[i] < pos.mV[i])
536		{
537			max.mV[i] = pos.mV[i];
538		}
539	}
540}
541
542inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos)
543{
544	for (U32 i = 0; i < 3; i++)
545	{
546		if (min.mV[i] > pos[i])
547		{
548			min.mV[i] = pos[i];
549		}
550		if (max.mV[i] < pos[i])
551		{
552			max.mV[i] = pos[i];
553		}
554	}
555}
556
557inline F32 angle_between(const LLVector3& a, const LLVector3& b)
558{
559	LLVector3 an = a;
560	LLVector3 bn = b;
561	an.normalize();
562	bn.normalize();
563	F32 cosine = an * bn;
564	F32 angle = (cosine >= 1.0f) ? 0.0f :
565				(cosine <= -1.0f) ? F_PI :
566				(F32)acos(cosine);
567	return angle;
568}
569
570inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)
571{
572	LLVector3 an = a;
573	LLVector3 bn = b;
574	an.normalize();
575	bn.normalize();
576	F32 dot = an * bn;
577	if ( (1.0f - fabs(dot)) < epsilon)
578	{
579		return TRUE;
580	}
581	return FALSE;
582}
583
584inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a) 
585{
586	s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }";
587	return s;
588}
589
590#endif