PageRenderTime 32ms CodeModel.GetById 1ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmath/v3dmath.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 475 lines | 363 code | 75 blank | 37 comment | 14 complexity | a6aca3aa65a7fbecc52ee38666322dc4 MD5 | raw file
  1/** 
  2 * @file v3dmath.h
  3 * @brief High precision 3 dimensional vector.
  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_V3DMATH_H
 28#define LL_V3DMATH_H
 29
 30#include "llerror.h"
 31#include "v3math.h"
 32
 33class LLVector3d
 34{
 35	public:
 36		F64 mdV[3];
 37
 38		const static LLVector3d zero;
 39		const static LLVector3d x_axis;
 40		const static LLVector3d y_axis;
 41		const static LLVector3d z_axis;
 42		const static LLVector3d x_axis_neg;
 43		const static LLVector3d y_axis_neg;
 44		const static LLVector3d z_axis_neg;
 45
 46		inline LLVector3d();							// Initializes LLVector3d to (0, 0, 0)
 47		inline LLVector3d(const F64 x, const F64 y, const F64 z);			// Initializes LLVector3d to (x. y, z)
 48		inline explicit LLVector3d(const F64 *vec);				// Initializes LLVector3d to (vec[0]. vec[1], vec[2])
 49		inline explicit LLVector3d(const LLVector3 &vec);
 50		explicit LLVector3d(const LLSD& sd)
 51		{
 52			setValue(sd);
 53		}
 54
 55		void setValue(const LLSD& sd)
 56		{
 57			mdV[0] = sd[0].asReal();
 58			mdV[1] = sd[1].asReal();
 59			mdV[2] = sd[2].asReal();
 60		}
 61
 62		LLSD getValue() const
 63		{
 64			LLSD ret;
 65			ret[0] = mdV[0];
 66			ret[1] = mdV[1];
 67			ret[2] = mdV[2];
 68			return ret;
 69		}
 70
 71		inline BOOL isFinite() const;									// checks to see if all values of LLVector3d are finite
 72		BOOL		clamp(const F64 min, const F64 max);		// Clamps all values to (min,max), returns TRUE if data changed
 73		BOOL		abs();						// sets all values to absolute value of original value (first octant), returns TRUE if changed
 74
 75		inline const LLVector3d&	clearVec();		// Clears LLVector3d to (0, 0, 0, 1)
 76		inline const LLVector3d&	setZero();		// Zero LLVector3d to (0, 0, 0, 0)
 77		inline const LLVector3d&	zeroVec();		// deprecated
 78		inline const LLVector3d&	setVec(const F64 x, const F64 y, const F64 z);	// Sets LLVector3d to (x, y, z, 1)
 79		inline const LLVector3d&	setVec(const LLVector3d &vec);	// Sets LLVector3d to vec
 80		inline const LLVector3d&	setVec(const F64 *vec);			// Sets LLVector3d to vec
 81		inline const LLVector3d&	setVec(const LLVector3 &vec);
 82
 83		F64		magVec() const;				// Returns magnitude of LLVector3d
 84		F64		magVecSquared() const;		// Returns magnitude squared of LLVector3d
 85		inline F64		normVec();					// Normalizes and returns the magnitude of LLVector3d
 86
 87		F64 length() const;			// Returns magnitude of LLVector3d
 88		F64 lengthSquared() const;	// Returns magnitude squared of LLVector3d
 89		inline F64 normalize();		// Normalizes and returns the magnitude of LLVector3d
 90
 91		const LLVector3d&	rotVec(const F64 angle, const LLVector3d &vec);	// Rotates about vec by angle radians
 92		const LLVector3d&	rotVec(const F64 angle, const F64 x, const F64 y, const F64 z);		// Rotates about x,y,z by angle radians
 93		const LLVector3d&	rotVec(const LLMatrix3 &mat);				// Rotates by LLMatrix4 mat
 94		const LLVector3d&	rotVec(const LLQuaternion &q);				// Rotates by LLQuaternion q
 95
 96		BOOL isNull() const;			// Returns TRUE if vector has a _very_small_ length
 97		BOOL isExactlyZero() const		{ return !mdV[VX] && !mdV[VY] && !mdV[VZ]; }
 98
 99		const LLVector3d&	operator=(const LLVector4 &a);
100
101		F64 operator[](int idx) const { return mdV[idx]; }
102		F64 &operator[](int idx) { return mdV[idx]; }
103
104		friend LLVector3d operator+(const LLVector3d &a, const LLVector3d &b);	// Return vector a + b
105		friend LLVector3d operator-(const LLVector3d &a, const LLVector3d &b);	// Return vector a minus b
106		friend F64 operator*(const LLVector3d &a, const LLVector3d &b);		// Return a dot b
107		friend LLVector3d operator%(const LLVector3d &a, const LLVector3d &b);	// Return a cross b
108		friend LLVector3d operator*(const LLVector3d &a, const F64 k);				// Return a times scaler k
109		friend LLVector3d operator/(const LLVector3d &a, const F64 k);				// Return a divided by scaler k
110		friend LLVector3d operator*(const F64 k, const LLVector3d &a);				// Return a times scaler k
111		friend bool operator==(const LLVector3d &a, const LLVector3d &b);		// Return a == b
112		friend bool operator!=(const LLVector3d &a, const LLVector3d &b);		// Return a != b
113
114		friend const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b);	// Return vector a + b
115		friend const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b);	// Return vector a minus b
116		friend const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b);	// Return a cross b
117		friend const LLVector3d& operator*=(LLVector3d &a, const F64 k);				// Return a times scaler k
118		friend const LLVector3d& operator/=(LLVector3d &a, const F64 k);				// Return a divided by scaler k
119
120		friend LLVector3d operator-(const LLVector3d &a);					// Return vector -a
121
122		friend std::ostream&	 operator<<(std::ostream& s, const LLVector3d &a);		// Stream a
123
124		static BOOL parseVector3d(const std::string& buf, LLVector3d* value);
125
126};
127
128typedef LLVector3d LLGlobalVec;
129
130const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
131{
132	mdV[0] = vec.mV[0];
133	mdV[1] = vec.mV[1];
134	mdV[2] = vec.mV[2];
135	return *this;
136}
137
138
139inline LLVector3d::LLVector3d(void)
140{
141	mdV[0] = 0.f;
142	mdV[1] = 0.f;
143	mdV[2] = 0.f;
144}
145
146inline LLVector3d::LLVector3d(const F64 x, const F64 y, const F64 z)
147{
148	mdV[VX] = x;
149	mdV[VY] = y;
150	mdV[VZ] = z;
151}
152
153inline LLVector3d::LLVector3d(const F64 *vec)
154{
155	mdV[VX] = vec[VX];
156	mdV[VY] = vec[VY];
157	mdV[VZ] = vec[VZ];
158}
159
160inline LLVector3d::LLVector3d(const LLVector3 &vec)
161{
162	mdV[VX] = vec.mV[VX];
163	mdV[VY] = vec.mV[VY];
164	mdV[VZ] = vec.mV[VZ];
165}
166
167/*
168inline LLVector3d::LLVector3d(const LLVector3d &copy)
169{
170	mdV[VX] = copy.mdV[VX];
171	mdV[VY] = copy.mdV[VY];
172	mdV[VZ] = copy.mdV[VZ];
173}
174*/
175
176// Destructors
177
178// checker
179inline BOOL LLVector3d::isFinite() const
180{
181	return (llfinite(mdV[VX]) && llfinite(mdV[VY]) && llfinite(mdV[VZ]));
182}
183
184
185// Clear and Assignment Functions
186
187inline const LLVector3d&	LLVector3d::clearVec(void)
188{
189	mdV[0] = 0.f;
190	mdV[1] = 0.f;
191	mdV[2]= 0.f;
192	return (*this);
193}
194
195inline const LLVector3d&	LLVector3d::setZero(void)
196{
197	mdV[0] = 0.f;
198	mdV[1] = 0.f;
199	mdV[2] = 0.f;
200	return (*this);
201}
202
203inline const LLVector3d&	LLVector3d::zeroVec(void)
204{
205	mdV[0] = 0.f;
206	mdV[1] = 0.f;
207	mdV[2] = 0.f;
208	return (*this);
209}
210
211inline const LLVector3d&	LLVector3d::setVec(const F64 x, const F64 y, const F64 z)
212{
213	mdV[VX] = x;
214	mdV[VY] = y;
215	mdV[VZ] = z;
216	return (*this);
217}
218
219inline const LLVector3d&	LLVector3d::setVec(const LLVector3d &vec)
220{
221	mdV[0] = vec.mdV[0];
222	mdV[1] = vec.mdV[1];
223	mdV[2] = vec.mdV[2];
224	return (*this);
225}
226
227inline const LLVector3d&	LLVector3d::setVec(const F64 *vec)
228{
229	mdV[0] = vec[0];
230	mdV[1] = vec[1];
231	mdV[2] = vec[2];
232	return (*this);
233}
234
235inline F64 LLVector3d::normVec(void)
236{
237	F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
238	F64 oomag;
239
240	if (mag > FP_MAG_THRESHOLD)
241	{
242		oomag = 1.f/mag;
243		mdV[0] *= oomag;
244		mdV[1] *= oomag;
245		mdV[2] *= oomag;
246	}
247	else
248	{
249		mdV[0] = 0.f;
250		mdV[1] = 0.f;
251		mdV[2] = 0.f;
252		mag = 0;
253	}
254	return (mag);
255}
256
257inline F64 LLVector3d::normalize(void)
258{
259	F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
260	F64 oomag;
261
262	if (mag > FP_MAG_THRESHOLD)
263	{
264		oomag = 1.f/mag;
265		mdV[0] *= oomag;
266		mdV[1] *= oomag;
267		mdV[2] *= oomag;
268	}
269	else
270	{
271		mdV[0] = 0.f;
272		mdV[1] = 0.f;
273		mdV[2] = 0.f;
274		mag = 0;
275	}
276	return (mag);
277}
278
279// LLVector3d Magnitude and Normalization Functions
280
281inline F64	LLVector3d::magVec(void) const
282{
283	return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
284}
285
286inline F64	LLVector3d::magVecSquared(void) const
287{
288	return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
289}
290
291inline F64	LLVector3d::length(void) const
292{
293	return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
294}
295
296inline F64	LLVector3d::lengthSquared(void) const
297{
298	return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
299}
300
301inline LLVector3d operator+(const LLVector3d &a, const LLVector3d &b)
302{
303	LLVector3d c(a);
304	return c += b;
305}
306
307inline LLVector3d operator-(const LLVector3d &a, const LLVector3d &b)
308{
309	LLVector3d c(a);
310	return c -= b;
311}
312
313inline F64  operator*(const LLVector3d &a, const LLVector3d &b)
314{
315	return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]);
316}
317
318inline LLVector3d operator%(const LLVector3d &a, const LLVector3d &b)
319{
320	return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] );
321}
322
323inline LLVector3d operator/(const LLVector3d &a, const F64 k)
324{
325	F64 t = 1.f / k;
326	return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t );
327}
328
329inline LLVector3d operator*(const LLVector3d &a, const F64 k)
330{
331	return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
332}
333
334inline LLVector3d operator*(F64 k, const LLVector3d &a)
335{
336	return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
337}
338
339inline bool operator==(const LLVector3d &a, const LLVector3d &b)
340{
341	return (  (a.mdV[0] == b.mdV[0])
342			&&(a.mdV[1] == b.mdV[1])
343			&&(a.mdV[2] == b.mdV[2]));
344}
345
346inline bool operator!=(const LLVector3d &a, const LLVector3d &b)
347{
348	return (  (a.mdV[0] != b.mdV[0])
349			||(a.mdV[1] != b.mdV[1])
350			||(a.mdV[2] != b.mdV[2]));
351}
352
353inline const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b)
354{
355	a.mdV[0] += b.mdV[0];
356	a.mdV[1] += b.mdV[1];
357	a.mdV[2] += b.mdV[2];
358	return a;
359}
360
361inline const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b)
362{
363	a.mdV[0] -= b.mdV[0];
364	a.mdV[1] -= b.mdV[1];
365	a.mdV[2] -= b.mdV[2];
366	return a;
367}
368
369inline const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b)
370{
371	LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]);
372	a = ret;
373	return a;
374}
375
376inline const LLVector3d& operator*=(LLVector3d &a, const F64 k)
377{
378	a.mdV[0] *= k;
379	a.mdV[1] *= k;
380	a.mdV[2] *= k;
381	return a;
382}
383
384inline const LLVector3d& operator/=(LLVector3d &a, const F64 k)
385{
386	F64 t = 1.f / k;
387	a.mdV[0] *= t;
388	a.mdV[1] *= t;
389	a.mdV[2] *= t;
390	return a;
391}
392
393inline LLVector3d operator-(const LLVector3d &a)
394{
395	return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] );
396}
397
398inline F64	dist_vec(const LLVector3d &a, const LLVector3d &b)
399{
400	F64 x = a.mdV[0] - b.mdV[0];
401	F64 y = a.mdV[1] - b.mdV[1];
402	F64 z = a.mdV[2] - b.mdV[2];
403	return (F32) sqrt( x*x + y*y + z*z );
404}
405
406inline F64	dist_vec_squared(const LLVector3d &a, const LLVector3d &b)
407{
408	F64 x = a.mdV[0] - b.mdV[0];
409	F64 y = a.mdV[1] - b.mdV[1];
410	F64 z = a.mdV[2] - b.mdV[2];
411	return x*x + y*y + z*z;
412}
413
414inline F64	dist_vec_squared2D(const LLVector3d &a, const LLVector3d &b)
415{
416	F64 x = a.mdV[0] - b.mdV[0];
417	F64 y = a.mdV[1] - b.mdV[1];
418	return x*x + y*y;
419}
420
421inline LLVector3d lerp(const LLVector3d &a, const LLVector3d &b, const F64 u)
422{
423	return LLVector3d(
424		a.mdV[VX] + (b.mdV[VX] - a.mdV[VX]) * u,
425		a.mdV[VY] + (b.mdV[VY] - a.mdV[VY]) * u,
426		a.mdV[VZ] + (b.mdV[VZ] - a.mdV[VZ]) * u);
427}
428
429
430inline BOOL	LLVector3d::isNull() const
431{
432	if ( F_APPROXIMATELY_ZERO > mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ] )
433	{
434		return TRUE;
435	}
436	return FALSE;
437}
438
439
440inline F64 angle_between(const LLVector3d& a, const LLVector3d& b)
441{
442	LLVector3d an = a;
443	LLVector3d bn = b;
444	an.normalize();
445	bn.normalize();
446	F64 cosine = an * bn;
447	F64 angle = (cosine >= 1.0f) ? 0.0f :
448				(cosine <= -1.0f) ? F_PI :
449				acos(cosine);
450	return angle;
451}
452
453inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 epsilon)
454{
455	LLVector3d an = a;
456	LLVector3d bn = b;
457	an.normalize();
458	bn.normalize();
459	F64 dot = an * bn;
460	if ( (1.0f - fabs(dot)) < epsilon)
461	{
462		return TRUE;
463	}
464	return FALSE;
465
466}
467
468inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b)
469{
470	LLVector3d project_axis = b;
471	project_axis.normalize();
472	return project_axis * (a * project_axis);
473}
474
475#endif // LL_V3DMATH_H