PageRenderTime 66ms CodeModel.GetById 17ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmath/v4math.h

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