sse/vectormath_aos.h

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
00003    All rights reserved.
00004 
00005    Redistribution and use in source and binary forms,
00006    with or without modification, are permitted provided that the
00007    following conditions are met:
00008     * Redistributions of source code must retain the above copyright
00009       notice, this list of conditions and the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright
00011       notice, this list of conditions and the following disclaimer in the
00012       documentation and/or other materials provided with the distribution.
00013     * Neither the name of the Sony Computer Entertainment Inc nor the names
00014       of its contributors may be used to endorse or promote products derived
00015       from this software without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027    POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 
00031 #ifndef _VECTORMATH_AOS_CPP_SSE_H
00032 #define _VECTORMATH_AOS_CPP_SSE_H
00033 
00034 #include <math.h>
00035 #include <xmmintrin.h>
00036 #include <emmintrin.h>
00037 #include <assert.h>
00038 
00039 #define Vector3Ref Vector3&
00040 #define QuatRef Quat&
00041 #define Matrix3Ref Matrix3&
00042 
00043 #if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400)
00044         #define USE_SSE3_LDDQU
00045 
00046         #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) __declspec(align(16)) a
00047         #define VM_ATTRIBUTE_ALIGN16 __declspec(align(16))
00048         #define VECTORMATH_FORCE_INLINE __forceinline 
00049 #else
00050         #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) a __attribute__ ((aligned (16)))        
00051         #define VM_ATTRIBUTE_ALIGN16 __attribute__ ((aligned (16)))     
00052         #define VECTORMATH_FORCE_INLINE inline __attribute__ ((always_inline))
00053         #ifdef __SSE3__
00054                 #define USE_SSE3_LDDQU
00055         #endif //__SSE3__
00056 #endif//_WIN32
00057 
00058 
00059 #ifdef USE_SSE3_LDDQU
00060 #include <pmmintrin.h>//_mm_lddqu_si128
00061 #endif //USE_SSE3_LDDQU
00062 
00063 
00064 // TODO: Tidy
00065 typedef __m128 vec_float4;
00066 typedef __m128 vec_uint4;
00067 typedef __m128 vec_int4;
00068 typedef __m128i vec_uchar16;
00069 typedef __m128i vec_ushort8;
00070 
00071 #define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
00072 
00073 #define _mm_ror_ps(vec,i)       \
00074         (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec))
00075 #define _mm_rol_ps(vec,i)       \
00076         (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(7-i)%4,(unsigned char)(6-i)%4,(unsigned char)(5-i)%4,(unsigned char)(4-i)%4))) : (vec))
00077 
00078 #define vec_sld(vec,vec2,x) _mm_ror_ps(vec, ((x)/4))
00079 
00080 #define _mm_abs_ps(vec)         _mm_andnot_ps(_MASKSIGN_,vec)
00081 #define _mm_neg_ps(vec)         _mm_xor_ps(_MASKSIGN_,vec)
00082 
00083 #define vec_madd(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b) )
00084 
00085 union SSEFloat
00086 {
00087         __m128i vi;
00088         __m128 m128;
00089         __m128 vf;
00090         unsigned int    ui[4];
00091         unsigned short s[8];
00092         float f[4];
00093         SSEFloat(__m128 v) : m128(v) {}
00094     SSEFloat(__m128i v) : vi(v) {}
00095         SSEFloat() {}//uninitialized
00096 };
00097 
00098 static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, __m128 mask)
00099 {
00100         return _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a));
00101 }
00102 static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, const unsigned int *_mask)
00103 {
00104         return vec_sel(a, b, _mm_load_ps((float *)_mask));
00105 }
00106 static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, unsigned int _mask)
00107 {
00108         return vec_sel(a, b, _mm_set1_ps(*(float *)&_mask));
00109 }
00110 
00111 static VECTORMATH_FORCE_INLINE __m128 toM128(unsigned int x)
00112 {
00113     return _mm_set1_ps( *(float *)&x );
00114 }
00115 
00116 static VECTORMATH_FORCE_INLINE __m128 fabsf4(__m128 x)
00117 {
00118     return _mm_and_ps( x, toM128( 0x7fffffff ) );
00119 }
00120 /*
00121 union SSE64
00122 {
00123         __m128 m128;
00124         struct
00125         {
00126                 __m64 m01;
00127                 __m64 m23;
00128         } m64;
00129 };
00130 
00131 static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a)
00132 {
00133         assert(a == 0); // Only 2^0 supported
00134         (void)a;
00135         SSE64 sse64;
00136         sse64.m64.m01 = _mm_cvttps_pi32(x);
00137         sse64.m64.m23 = _mm_cvttps_pi32(_mm_ror_ps(x,2));
00138         _mm_empty();
00139     return sse64.m128;
00140 }
00141 
00142 static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a)
00143 {
00144         assert(a == 0); // Only 2^0 supported
00145         (void)a;
00146         SSE64 sse64;
00147         sse64.m128 = x;
00148         __m128 result =_mm_movelh_ps(
00149                 _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m01),
00150                 _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m23));
00151         _mm_empty();
00152         return result;
00153 }
00154 */
00155 static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a)
00156 {
00157         assert(a == 0); // Only 2^0 supported
00158         (void)a;
00159         __m128i result = _mm_cvtps_epi32(x);
00160     return (__m128 &)result;
00161 }
00162 
00163 static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a)
00164 {
00165         assert(a == 0); // Only 2^0 supported
00166         (void)a;
00167         return _mm_cvtepi32_ps((__m128i &)x);
00168 }
00169 
00170 #define vec_nmsub(a,b,c) _mm_sub_ps( c, _mm_mul_ps( a, b ) )
00171 #define vec_sub(a,b) _mm_sub_ps( a, b )
00172 #define vec_add(a,b) _mm_add_ps( a, b )
00173 #define vec_mul(a,b) _mm_mul_ps( a, b )
00174 #define vec_xor(a,b) _mm_xor_ps( a, b )
00175 #define vec_and(a,b) _mm_and_ps( a, b )
00176 #define vec_cmpeq(a,b) _mm_cmpeq_ps( a, b )
00177 #define vec_cmpgt(a,b) _mm_cmpgt_ps( a, b )
00178 
00179 #define vec_mergeh(a,b) _mm_unpacklo_ps( a, b )
00180 #define vec_mergel(a,b) _mm_unpackhi_ps( a, b )
00181 
00182 #define vec_andc(a,b) _mm_andnot_ps( b, a )
00183 
00184 #define sqrtf4(x) _mm_sqrt_ps( x )
00185 #define rsqrtf4(x) _mm_rsqrt_ps( x )
00186 #define recipf4(x) _mm_rcp_ps( x )
00187 #define negatef4(x) _mm_sub_ps( _mm_setzero_ps(), x )
00188 
00189 static VECTORMATH_FORCE_INLINE __m128 newtonrapson_rsqrt4( const __m128 v )
00190 {   
00191 #define _half4 _mm_setr_ps(.5f,.5f,.5f,.5f) 
00192 #define _three _mm_setr_ps(3.f,3.f,3.f,3.f)
00193 const __m128 approx = _mm_rsqrt_ps( v );   
00194 const __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx);   
00195 return _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls) );
00196 }
00197 
00198 static VECTORMATH_FORCE_INLINE __m128 acosf4(__m128 x)
00199 {
00200     __m128 xabs = fabsf4(x);
00201         __m128 select = _mm_cmplt_ps( x, _mm_setzero_ps() );
00202     __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs));
00203     
00204     /* Instruction counts can be reduced if the polynomial was
00205      * computed entirely from nested (dependent) fma's. However, 
00206      * to reduce the number of pipeline stalls, the polygon is evaluated 
00207      * in two halves (hi amd lo). 
00208      */
00209     __m128 xabs2 = _mm_mul_ps(xabs,  xabs);
00210     __m128 xabs4 = _mm_mul_ps(xabs2, xabs2);
00211     __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f),
00212                 xabs, _mm_set1_ps(0.0066700901f)),
00213                         xabs, _mm_set1_ps(-0.0170881256f)),
00214                                 xabs, _mm_set1_ps( 0.0308918810f));
00215     __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f),
00216                 xabs, _mm_set1_ps(0.0889789874f)),
00217                         xabs, _mm_set1_ps(-0.2145988016f)),
00218                                 xabs, _mm_set1_ps( 1.5707963050f));
00219     
00220     __m128 result = vec_madd(hi, xabs4, lo);
00221     
00222     // Adjust the result if x is negactive.
00223     return vec_sel(
00224                 vec_mul(t1, result),                                                                    // Positive
00225                 vec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)),   // Negative
00226                 select);
00227 }
00228 
00229 static VECTORMATH_FORCE_INLINE __m128 sinf4(vec_float4 x)
00230 {
00231 
00232 //
00233 // Common constants used to evaluate sinf4/cosf4/tanf4
00234 //
00235 #define _SINCOS_CC0  -0.0013602249f
00236 #define _SINCOS_CC1   0.0416566950f
00237 #define _SINCOS_CC2  -0.4999990225f
00238 #define _SINCOS_SC0  -0.0001950727f
00239 #define _SINCOS_SC1   0.0083320758f
00240 #define _SINCOS_SC2  -0.1666665247f
00241 
00242 #define _SINCOS_KC1  1.57079625129f
00243 #define _SINCOS_KC2  7.54978995489e-8f
00244 
00245     vec_float4 xl,xl2,xl3,res;
00246 
00247     // Range reduction using : xl = angle * TwoOverPi;
00248     //  
00249     xl = vec_mul(x, _mm_set1_ps(0.63661977236f));
00250 
00251     // Find the quadrant the angle falls in
00252     // using:  q = (int) (ceil(abs(xl))*sign(xl))
00253     //
00254     vec_int4 q = vec_cts(xl,0);
00255 
00256     // Compute an offset based on the quadrant that the angle falls in
00257     // 
00258     vec_int4 offset = _mm_and_ps(q,toM128(0x3));
00259 
00260     // Remainder in range [-pi/4..pi/4]
00261     //
00262     vec_float4 qf = vec_ctf(q,0);
00263     xl  = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x));
00264     
00265     // Compute x^2 and x^3
00266     //
00267     xl2 = vec_mul(xl,xl);
00268     xl3 = vec_mul(xl2,xl);
00269     
00270     // Compute both the sin and cos of the angles
00271     // using a polynomial expression:
00272     //   cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and
00273     //   sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2)
00274     //
00275     
00276     vec_float4 cx =
00277                 vec_madd(
00278                         vec_madd(
00279                                 vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f));
00280     vec_float4 sx =
00281                 vec_madd(
00282                         vec_madd(
00283                                 vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl);
00284 
00285     // Use the cosine when the offset is odd and the sin
00286     // when the offset is even
00287     //
00288     res = vec_sel(cx,sx,vec_cmpeq(vec_and(offset,
00289                                           toM128(0x1)),
00290                                                                                   _mm_setzero_ps()));
00291 
00292     // Flip the sign of the result when (offset mod 4) = 1 or 2
00293     //
00294     return vec_sel(
00295                 vec_xor(toM128(0x80000000U), res),      // Negative
00296                 res,                                                            // Positive
00297                 vec_cmpeq(vec_and(offset,toM128(0x2)),_mm_setzero_ps()));
00298 }
00299 
00300 static VECTORMATH_FORCE_INLINE void sincosf4(vec_float4 x, vec_float4* s, vec_float4* c)
00301 {
00302     vec_float4 xl,xl2,xl3;
00303     vec_int4   offsetSin, offsetCos;
00304 
00305     // Range reduction using : xl = angle * TwoOverPi;
00306     //  
00307     xl = vec_mul(x, _mm_set1_ps(0.63661977236f));
00308 
00309     // Find the quadrant the angle falls in
00310     // using:  q = (int) (ceil(abs(xl))*sign(xl))
00311     //
00312     //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0);
00313     vec_int4 q = vec_cts(xl,0);
00314      
00315     // Compute the offset based on the quadrant that the angle falls in.
00316     // Add 1 to the offset for the cosine. 
00317     //
00318     offsetSin = vec_and(q,toM128((int)0x3));
00319         __m128i temp = _mm_add_epi32(_mm_set1_epi32(1),(__m128i &)offsetSin);
00320         offsetCos = (__m128 &)temp;
00321 
00322     // Remainder in range [-pi/4..pi/4]
00323     //
00324     vec_float4 qf = vec_ctf(q,0);
00325     xl  = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x));
00326     
00327     // Compute x^2 and x^3
00328     //
00329     xl2 = vec_mul(xl,xl);
00330     xl3 = vec_mul(xl2,xl);
00331     
00332     // Compute both the sin and cos of the angles
00333     // using a polynomial expression:
00334     //   cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and
00335     //   sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2)
00336     //
00337     vec_float4 cx =
00338                 vec_madd(
00339                         vec_madd(
00340                                 vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f));
00341     vec_float4 sx =
00342                 vec_madd(
00343                         vec_madd(
00344                                 vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl);
00345 
00346     // Use the cosine when the offset is odd and the sin
00347     // when the offset is even
00348     //
00349     vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin,toM128(0x1)),_mm_setzero_ps());
00350     vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos,toM128(0x1)),_mm_setzero_ps());    
00351     *s = vec_sel(cx,sx,sinMask);
00352     *c = vec_sel(cx,sx,cosMask);
00353 
00354     // Flip the sign of the result when (offset mod 4) = 1 or 2
00355     //
00356     sinMask = vec_cmpeq(vec_and(offsetSin,toM128(0x2)),_mm_setzero_ps());
00357     cosMask = vec_cmpeq(vec_and(offsetCos,toM128(0x2)),_mm_setzero_ps());
00358     
00359     *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*s),*s,sinMask);
00360     *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*c),*c,cosMask);    
00361 }
00362 
00363 #include "vecidx_aos.h"
00364 #include "floatInVec.h"
00365 #include "boolInVec.h"
00366 
00367 #ifdef _VECTORMATH_DEBUG
00368 #include <stdio.h>
00369 #endif
00370 namespace Vectormath {
00371 
00372 namespace Aos {
00373 
00374 //-----------------------------------------------------------------------------
00375 // Forward Declarations
00376 //
00377 
00378 class Vector3;
00379 class Vector4;
00380 class Point3;
00381 class Quat;
00382 class Matrix3;
00383 class Matrix4;
00384 class Transform3;
00385 
00386 // A 3-D vector in array-of-structures format
00387 //
00388 class Vector3
00389 {
00390     __m128 mVec128;
00391 
00392         VECTORMATH_FORCE_INLINE void set128(vec_float4 vec);
00393          
00394          VECTORMATH_FORCE_INLINE  vec_float4& get128Ref();
00395 
00396 public:
00397     // Default constructor; does no initialization
00398     // 
00399     VECTORMATH_FORCE_INLINE Vector3( ) { };
00400 
00401         // Default copy constructor
00402     // 
00403         VECTORMATH_FORCE_INLINE Vector3(const Vector3& vec);
00404 
00405     // Construct a 3-D vector from x, y, and z elements
00406     // 
00407     VECTORMATH_FORCE_INLINE Vector3( float x, float y, float z );
00408 
00409     // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type)
00410     // 
00411     VECTORMATH_FORCE_INLINE Vector3( const floatInVec &x, const floatInVec &y, const floatInVec &z );
00412 
00413     // Copy elements from a 3-D point into a 3-D vector
00414     // 
00415     explicit VECTORMATH_FORCE_INLINE Vector3( const Point3 &pnt );
00416 
00417     // Set all elements of a 3-D vector to the same scalar value
00418     // 
00419     explicit VECTORMATH_FORCE_INLINE Vector3( float scalar );
00420 
00421     // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type)
00422     // 
00423     explicit VECTORMATH_FORCE_INLINE Vector3( const floatInVec &scalar );
00424 
00425     // Set vector float data in a 3-D vector
00426     // 
00427     explicit VECTORMATH_FORCE_INLINE Vector3( __m128 vf4 );
00428 
00429     // Get vector float data from a 3-D vector
00430     // 
00431     VECTORMATH_FORCE_INLINE __m128 get128( ) const;
00432 
00433     // Assign one 3-D vector to another
00434     // 
00435     VECTORMATH_FORCE_INLINE Vector3 & operator =( const Vector3 &vec );
00436 
00437     // Set the x element of a 3-D vector
00438     // 
00439     VECTORMATH_FORCE_INLINE Vector3 & setX( float x );
00440 
00441     // Set the y element of a 3-D vector
00442     // 
00443     VECTORMATH_FORCE_INLINE Vector3 & setY( float y );
00444 
00445     // Set the z element of a 3-D vector
00446     // 
00447     VECTORMATH_FORCE_INLINE Vector3 & setZ( float z );
00448 
00449     // Set the x element of a 3-D vector (scalar data contained in vector data type)
00450     // 
00451     VECTORMATH_FORCE_INLINE Vector3 & setX( const floatInVec &x );
00452 
00453     // Set the y element of a 3-D vector (scalar data contained in vector data type)
00454     // 
00455     VECTORMATH_FORCE_INLINE Vector3 & setY( const floatInVec &y );
00456 
00457     // Set the z element of a 3-D vector (scalar data contained in vector data type)
00458     // 
00459     VECTORMATH_FORCE_INLINE Vector3 & setZ( const floatInVec &z );
00460 
00461     // Get the x element of a 3-D vector
00462     // 
00463     VECTORMATH_FORCE_INLINE const floatInVec getX( ) const;
00464 
00465     // Get the y element of a 3-D vector
00466     // 
00467     VECTORMATH_FORCE_INLINE const floatInVec getY( ) const;
00468 
00469     // Get the z element of a 3-D vector
00470     // 
00471     VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const;
00472 
00473     // Set an x, y, or z element of a 3-D vector by index
00474     // 
00475     VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, float value );
00476 
00477     // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type)
00478     // 
00479     VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, const floatInVec &value );
00480 
00481     // Get an x, y, or z element of a 3-D vector by index
00482     // 
00483     VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const;
00484 
00485     // Subscripting operator to set or get an element
00486     // 
00487     VECTORMATH_FORCE_INLINE VecIdx operator []( int idx );
00488 
00489     // Subscripting operator to get an element
00490     // 
00491     VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const;
00492 
00493     // Add two 3-D vectors
00494     // 
00495     VECTORMATH_FORCE_INLINE const Vector3 operator +( const Vector3 &vec ) const;
00496 
00497     // Subtract a 3-D vector from another 3-D vector
00498     // 
00499     VECTORMATH_FORCE_INLINE const Vector3 operator -( const Vector3 &vec ) const;
00500 
00501     // Add a 3-D vector to a 3-D point
00502     // 
00503     VECTORMATH_FORCE_INLINE const Point3 operator +( const Point3 &pnt ) const;
00504 
00505     // Multiply a 3-D vector by a scalar
00506     // 
00507     VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar ) const;
00508 
00509     // Divide a 3-D vector by a scalar
00510     // 
00511     VECTORMATH_FORCE_INLINE const Vector3 operator /( float scalar ) const;
00512 
00513     // Multiply a 3-D vector by a scalar (scalar data contained in vector data type)
00514     // 
00515     VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar ) const;
00516 
00517     // Divide a 3-D vector by a scalar (scalar data contained in vector data type)
00518     // 
00519     VECTORMATH_FORCE_INLINE const Vector3 operator /( const floatInVec &scalar ) const;
00520 
00521     // Perform compound assignment and addition with a 3-D vector
00522     // 
00523     VECTORMATH_FORCE_INLINE Vector3 & operator +=( const Vector3 &vec );
00524 
00525     // Perform compound assignment and subtraction by a 3-D vector
00526     // 
00527     VECTORMATH_FORCE_INLINE Vector3 & operator -=( const Vector3 &vec );
00528 
00529     // Perform compound assignment and multiplication by a scalar
00530     // 
00531     VECTORMATH_FORCE_INLINE Vector3 & operator *=( float scalar );
00532 
00533     // Perform compound assignment and division by a scalar
00534     // 
00535     VECTORMATH_FORCE_INLINE Vector3 & operator /=( float scalar );
00536 
00537     // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)
00538     // 
00539     VECTORMATH_FORCE_INLINE Vector3 & operator *=( const floatInVec &scalar );
00540 
00541     // Perform compound assignment and division by a scalar (scalar data contained in vector data type)
00542     // 
00543     VECTORMATH_FORCE_INLINE Vector3 & operator /=( const floatInVec &scalar );
00544 
00545     // Negate all elements of a 3-D vector
00546     // 
00547     VECTORMATH_FORCE_INLINE const Vector3 operator -( ) const;
00548 
00549     // Construct x axis
00550     // 
00551     static VECTORMATH_FORCE_INLINE const Vector3 xAxis( );
00552 
00553     // Construct y axis
00554     // 
00555     static VECTORMATH_FORCE_INLINE const Vector3 yAxis( );
00556 
00557     // Construct z axis
00558     // 
00559     static VECTORMATH_FORCE_INLINE const Vector3 zAxis( );
00560 
00561 };
00562 
00563 // Multiply a 3-D vector by a scalar
00564 // 
00565 VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec );
00566 
00567 // Multiply a 3-D vector by a scalar (scalar data contained in vector data type)
00568 // 
00569 VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec );
00570 
00571 // Multiply two 3-D vectors per element
00572 // 
00573 VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 );
00574 
00575 // Divide two 3-D vectors per element
00576 // NOTE: 
00577 // Floating-point behavior matches standard library function divf4.
00578 // 
00579 VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 );
00580 
00581 // Compute the reciprocal of a 3-D vector per element
00582 // NOTE: 
00583 // Floating-point behavior matches standard library function recipf4.
00584 // 
00585 VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec );
00586 
00587 // Compute the absolute value of a 3-D vector per element
00588 // 
00589 VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec );
00590 
00591 // Copy sign from one 3-D vector to another, per element
00592 // 
00593 VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 );
00594 
00595 // Maximum of two 3-D vectors per element
00596 // 
00597 VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 );
00598 
00599 // Minimum of two 3-D vectors per element
00600 // 
00601 VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 );
00602 
00603 // Maximum element of a 3-D vector
00604 // 
00605 VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec );
00606 
00607 // Minimum element of a 3-D vector
00608 // 
00609 VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec );
00610 
00611 // Compute the sum of all elements of a 3-D vector
00612 // 
00613 VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec );
00614 
00615 // Compute the dot product of two 3-D vectors
00616 // 
00617 VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 );
00618 
00619 // Compute the square of the length of a 3-D vector
00620 // 
00621 VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec );
00622 
00623 // Compute the length of a 3-D vector
00624 // 
00625 VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec );
00626 
00627 // Normalize a 3-D vector
00628 // NOTE: 
00629 // The result is unpredictable when all elements of vec are at or near zero.
00630 // 
00631 VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec );
00632 
00633 // Compute cross product of two 3-D vectors
00634 // 
00635 VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 );
00636 
00637 // Outer product of two 3-D vectors
00638 // 
00639 VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &vec0, const Vector3 &vec1 );
00640 
00641 // Pre-multiply a row vector by a 3x3 matrix
00642 // NOTE: 
00643 // Slower than column post-multiply.
00644 // 
00645 VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat );
00646 
00647 // Cross-product matrix of a 3-D vector
00648 // 
00649 VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec );
00650 
00651 // Create cross-product matrix and multiply
00652 // NOTE: 
00653 // Faster than separately creating a cross-product matrix and multiplying.
00654 // 
00655 VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat );
00656 
00657 // Linear interpolation between two 3-D vectors
00658 // NOTE: 
00659 // Does not clamp t between 0 and 1.
00660 // 
00661 VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 );
00662 
00663 // Linear interpolation between two 3-D vectors (scalar data contained in vector data type)
00664 // NOTE: 
00665 // Does not clamp t between 0 and 1.
00666 // 
00667 VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 );
00668 
00669 // Spherical linear interpolation between two 3-D vectors
00670 // NOTE: 
00671 // The result is unpredictable if the vectors point in opposite directions.
00672 // Does not clamp t between 0 and 1.
00673 // 
00674 VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 );
00675 
00676 // Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type)
00677 // NOTE: 
00678 // The result is unpredictable if the vectors point in opposite directions.
00679 // Does not clamp t between 0 and 1.
00680 // 
00681 VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 );
00682 
00683 // Conditionally select between two 3-D vectors
00684 // NOTE: 
00685 // This function uses a conditional select instruction to avoid a branch.
00686 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
00687 // Use the boolInVec version for better performance.
00688 // 
00689 VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 );
00690 
00691 // Conditionally select between two 3-D vectors (scalar data contained in vector data type)
00692 // NOTE: 
00693 // This function uses a conditional select instruction to avoid a branch.
00694 // 
00695 VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 );
00696 
00697 // Store x, y, and z elements of 3-D vector in first three words of a quadword, preserving fourth word
00698 // 
00699 VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad );
00700 
00701 // Load four three-float 3-D vectors, stored in three quadwords
00702 // 
00703 VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads );
00704 
00705 // Store four 3-D vectors in three quadwords
00706 // 
00707 VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads );
00708 
00709 // Store eight 3-D vectors as half-floats
00710 // 
00711 VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads );
00712 
00713 #ifdef _VECTORMATH_DEBUG
00714 
00715 // Print a 3-D vector
00716 // NOTE: 
00717 // Function is only defined when _VECTORMATH_DEBUG is defined.
00718 // 
00719 VECTORMATH_FORCE_INLINE void print( const Vector3 &vec );
00720 
00721 // Print a 3-D vector and an associated string identifier
00722 // NOTE: 
00723 // Function is only defined when _VECTORMATH_DEBUG is defined.
00724 // 
00725 VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name );
00726 
00727 #endif
00728 
00729 // A 4-D vector in array-of-structures format
00730 //
00731 class Vector4
00732 {
00733     __m128 mVec128;
00734 
00735 public:
00736     // Default constructor; does no initialization
00737     // 
00738     VECTORMATH_FORCE_INLINE Vector4( ) { };
00739 
00740     // Construct a 4-D vector from x, y, z, and w elements
00741     // 
00742     VECTORMATH_FORCE_INLINE Vector4( float x, float y, float z, float w );
00743 
00744     // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type)
00745     // 
00746     VECTORMATH_FORCE_INLINE Vector4( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w );
00747 
00748     // Construct a 4-D vector from a 3-D vector and a scalar
00749     // 
00750     VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, float w );
00751 
00752     // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type)
00753     // 
00754     VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, const floatInVec &w );
00755 
00756     // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0
00757     // 
00758     explicit VECTORMATH_FORCE_INLINE Vector4( const Vector3 &vec );
00759 
00760     // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1
00761     // 
00762     explicit VECTORMATH_FORCE_INLINE Vector4( const Point3 &pnt );
00763 
00764     // Copy elements from a quaternion into a 4-D vector
00765     // 
00766     explicit VECTORMATH_FORCE_INLINE Vector4( const Quat &quat );
00767 
00768     // Set all elements of a 4-D vector to the same scalar value
00769     // 
00770     explicit VECTORMATH_FORCE_INLINE Vector4( float scalar );
00771 
00772     // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type)
00773     // 
00774     explicit VECTORMATH_FORCE_INLINE Vector4( const floatInVec &scalar );
00775 
00776     // Set vector float data in a 4-D vector
00777     // 
00778     explicit VECTORMATH_FORCE_INLINE Vector4( __m128 vf4 );
00779 
00780     // Get vector float data from a 4-D vector
00781     // 
00782     VECTORMATH_FORCE_INLINE __m128 get128( ) const;
00783 
00784     // Assign one 4-D vector to another
00785     // 
00786     VECTORMATH_FORCE_INLINE Vector4 & operator =( const Vector4 &vec );
00787 
00788     // Set the x, y, and z elements of a 4-D vector
00789     // NOTE: 
00790     // This function does not change the w element.
00791     // 
00792     VECTORMATH_FORCE_INLINE Vector4 & setXYZ( const Vector3 &vec );
00793 
00794     // Get the x, y, and z elements of a 4-D vector
00795     // 
00796     VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const;
00797 
00798     // Set the x element of a 4-D vector
00799     // 
00800     VECTORMATH_FORCE_INLINE Vector4 & setX( float x );
00801 
00802     // Set the y element of a 4-D vector
00803     // 
00804     VECTORMATH_FORCE_INLINE Vector4 & setY( float y );
00805 
00806     // Set the z element of a 4-D vector
00807     // 
00808     VECTORMATH_FORCE_INLINE Vector4 & setZ( float z );
00809 
00810     // Set the w element of a 4-D vector
00811     // 
00812     VECTORMATH_FORCE_INLINE Vector4 & setW( float w );
00813 
00814     // Set the x element of a 4-D vector (scalar data contained in vector data type)
00815     // 
00816     VECTORMATH_FORCE_INLINE Vector4 & setX( const floatInVec &x );
00817 
00818     // Set the y element of a 4-D vector (scalar data contained in vector data type)
00819     // 
00820     VECTORMATH_FORCE_INLINE Vector4 & setY( const floatInVec &y );
00821 
00822     // Set the z element of a 4-D vector (scalar data contained in vector data type)
00823     // 
00824     VECTORMATH_FORCE_INLINE Vector4 & setZ( const floatInVec &z );
00825 
00826     // Set the w element of a 4-D vector (scalar data contained in vector data type)
00827     // 
00828     VECTORMATH_FORCE_INLINE Vector4 & setW( const floatInVec &w );
00829 
00830     // Get the x element of a 4-D vector
00831     // 
00832     VECTORMATH_FORCE_INLINE const floatInVec getX( ) const;
00833 
00834     // Get the y element of a 4-D vector
00835     // 
00836     VECTORMATH_FORCE_INLINE const floatInVec getY( ) const;
00837 
00838     // Get the z element of a 4-D vector
00839     // 
00840     VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const;
00841 
00842     // Get the w element of a 4-D vector
00843     // 
00844     VECTORMATH_FORCE_INLINE const floatInVec getW( ) const;
00845 
00846     // Set an x, y, z, or w element of a 4-D vector by index
00847     // 
00848     VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, float value );
00849 
00850     // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type)
00851     // 
00852     VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, const floatInVec &value );
00853 
00854     // Get an x, y, z, or w element of a 4-D vector by index
00855     // 
00856     VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const;
00857 
00858     // Subscripting operator to set or get an element
00859     // 
00860     VECTORMATH_FORCE_INLINE VecIdx operator []( int idx );
00861 
00862     // Subscripting operator to get an element
00863     // 
00864     VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const;
00865 
00866     // Add two 4-D vectors
00867     // 
00868     VECTORMATH_FORCE_INLINE const Vector4 operator +( const Vector4 &vec ) const;
00869 
00870     // Subtract a 4-D vector from another 4-D vector
00871     // 
00872     VECTORMATH_FORCE_INLINE const Vector4 operator -( const Vector4 &vec ) const;
00873 
00874     // Multiply a 4-D vector by a scalar
00875     // 
00876     VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar ) const;
00877 
00878     // Divide a 4-D vector by a scalar
00879     // 
00880     VECTORMATH_FORCE_INLINE const Vector4 operator /( float scalar ) const;
00881 
00882     // Multiply a 4-D vector by a scalar (scalar data contained in vector data type)
00883     // 
00884     VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar ) const;
00885 
00886     // Divide a 4-D vector by a scalar (scalar data contained in vector data type)
00887     // 
00888     VECTORMATH_FORCE_INLINE const Vector4 operator /( const floatInVec &scalar ) const;
00889 
00890     // Perform compound assignment and addition with a 4-D vector
00891     // 
00892     VECTORMATH_FORCE_INLINE Vector4 & operator +=( const Vector4 &vec );
00893 
00894     // Perform compound assignment and subtraction by a 4-D vector
00895     // 
00896     VECTORMATH_FORCE_INLINE Vector4 & operator -=( const Vector4 &vec );
00897 
00898     // Perform compound assignment and multiplication by a scalar
00899     // 
00900     VECTORMATH_FORCE_INLINE Vector4 & operator *=( float scalar );
00901 
00902     // Perform compound assignment and division by a scalar
00903     // 
00904     VECTORMATH_FORCE_INLINE Vector4 & operator /=( float scalar );
00905 
00906     // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)
00907     // 
00908     VECTORMATH_FORCE_INLINE Vector4 & operator *=( const floatInVec &scalar );
00909 
00910     // Perform compound assignment and division by a scalar (scalar data contained in vector data type)
00911     // 
00912     VECTORMATH_FORCE_INLINE Vector4 & operator /=( const floatInVec &scalar );
00913 
00914     // Negate all elements of a 4-D vector
00915     // 
00916     VECTORMATH_FORCE_INLINE const Vector4 operator -( ) const;
00917 
00918     // Construct x axis
00919     // 
00920     static VECTORMATH_FORCE_INLINE const Vector4 xAxis( );
00921 
00922     // Construct y axis
00923     // 
00924     static VECTORMATH_FORCE_INLINE const Vector4 yAxis( );
00925 
00926     // Construct z axis
00927     // 
00928     static VECTORMATH_FORCE_INLINE const Vector4 zAxis( );
00929 
00930     // Construct w axis
00931     // 
00932     static VECTORMATH_FORCE_INLINE const Vector4 wAxis( );
00933 
00934 };
00935 
00936 // Multiply a 4-D vector by a scalar
00937 // 
00938 VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec );
00939 
00940 // Multiply a 4-D vector by a scalar (scalar data contained in vector data type)
00941 // 
00942 VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec );
00943 
00944 // Multiply two 4-D vectors per element
00945 // 
00946 VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 );
00947 
00948 // Divide two 4-D vectors per element
00949 // NOTE: 
00950 // Floating-point behavior matches standard library function divf4.
00951 // 
00952 VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 );
00953 
00954 // Compute the reciprocal of a 4-D vector per element
00955 // NOTE: 
00956 // Floating-point behavior matches standard library function recipf4.
00957 // 
00958 VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec );
00959 
00960 // Compute the absolute value of a 4-D vector per element
00961 // 
00962 VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec );
00963 
00964 // Copy sign from one 4-D vector to another, per element
00965 // 
00966 VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 );
00967 
00968 // Maximum of two 4-D vectors per element
00969 // 
00970 VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 );
00971 
00972 // Minimum of two 4-D vectors per element
00973 // 
00974 VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 );
00975 
00976 // Maximum element of a 4-D vector
00977 // 
00978 VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec );
00979 
00980 // Minimum element of a 4-D vector
00981 // 
00982 VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec );
00983 
00984 // Compute the sum of all elements of a 4-D vector
00985 // 
00986 VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec );
00987 
00988 // Compute the dot product of two 4-D vectors
00989 // 
00990 VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 );
00991 
00992 // Compute the square of the length of a 4-D vector
00993 // 
00994 VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec );
00995 
00996 // Compute the length of a 4-D vector
00997 // 
00998 VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec );
00999 
01000 // Normalize a 4-D vector
01001 // NOTE: 
01002 // The result is unpredictable when all elements of vec are at or near zero.
01003 // 
01004 VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec );
01005 
01006 // Outer product of two 4-D vectors
01007 // 
01008 VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &vec0, const Vector4 &vec1 );
01009 
01010 // Linear interpolation between two 4-D vectors
01011 // NOTE: 
01012 // Does not clamp t between 0 and 1.
01013 // 
01014 VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 );
01015 
01016 // Linear interpolation between two 4-D vectors (scalar data contained in vector data type)
01017 // NOTE: 
01018 // Does not clamp t between 0 and 1.
01019 // 
01020 VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 );
01021 
01022 // Spherical linear interpolation between two 4-D vectors
01023 // NOTE: 
01024 // The result is unpredictable if the vectors point in opposite directions.
01025 // Does not clamp t between 0 and 1.
01026 // 
01027 VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 );
01028 
01029 // Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type)
01030 // NOTE: 
01031 // The result is unpredictable if the vectors point in opposite directions.
01032 // Does not clamp t between 0 and 1.
01033 // 
01034 VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 );
01035 
01036 // Conditionally select between two 4-D vectors
01037 // NOTE: 
01038 // This function uses a conditional select instruction to avoid a branch.
01039 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
01040 // Use the boolInVec version for better performance.
01041 // 
01042 VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 );
01043 
01044 // Conditionally select between two 4-D vectors (scalar data contained in vector data type)
01045 // NOTE: 
01046 // This function uses a conditional select instruction to avoid a branch.
01047 // 
01048 VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 );
01049 
01050 // Store four 4-D vectors as half-floats
01051 // 
01052 VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads );
01053 
01054 #ifdef _VECTORMATH_DEBUG
01055 
01056 // Print a 4-D vector
01057 // NOTE: 
01058 // Function is only defined when _VECTORMATH_DEBUG is defined.
01059 // 
01060 VECTORMATH_FORCE_INLINE void print( const Vector4 &vec );
01061 
01062 // Print a 4-D vector and an associated string identifier
01063 // NOTE: 
01064 // Function is only defined when _VECTORMATH_DEBUG is defined.
01065 // 
01066 VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name );
01067 
01068 #endif
01069 
01070 // A 3-D point in array-of-structures format
01071 //
01072 class Point3
01073 {
01074     __m128 mVec128;
01075 
01076 public:
01077     // Default constructor; does no initialization
01078     // 
01079     VECTORMATH_FORCE_INLINE Point3( ) { };
01080 
01081     // Construct a 3-D point from x, y, and z elements
01082     // 
01083     VECTORMATH_FORCE_INLINE Point3( float x, float y, float z );
01084 
01085     // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type)
01086     // 
01087     VECTORMATH_FORCE_INLINE Point3( const floatInVec &x, const floatInVec &y, const floatInVec &z );
01088 
01089     // Copy elements from a 3-D vector into a 3-D point
01090     // 
01091     explicit VECTORMATH_FORCE_INLINE Point3( const Vector3 &vec );
01092 
01093     // Set all elements of a 3-D point to the same scalar value
01094     // 
01095     explicit VECTORMATH_FORCE_INLINE Point3( float scalar );
01096 
01097     // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type)
01098     // 
01099     explicit VECTORMATH_FORCE_INLINE Point3( const floatInVec &scalar );
01100 
01101     // Set vector float data in a 3-D point
01102     // 
01103     explicit VECTORMATH_FORCE_INLINE Point3( __m128 vf4 );
01104 
01105     // Get vector float data from a 3-D point
01106     // 
01107     VECTORMATH_FORCE_INLINE __m128 get128( ) const;
01108 
01109     // Assign one 3-D point to another
01110     // 
01111     VECTORMATH_FORCE_INLINE Point3 & operator =( const Point3 &pnt );
01112 
01113     // Set the x element of a 3-D point
01114     // 
01115     VECTORMATH_FORCE_INLINE Point3 & setX( float x );
01116 
01117     // Set the y element of a 3-D point
01118     // 
01119     VECTORMATH_FORCE_INLINE Point3 & setY( float y );
01120 
01121     // Set the z element of a 3-D point
01122     // 
01123     VECTORMATH_FORCE_INLINE Point3 & setZ( float z );
01124 
01125     // Set the x element of a 3-D point (scalar data contained in vector data type)
01126     // 
01127     VECTORMATH_FORCE_INLINE Point3 & setX( const floatInVec &x );
01128 
01129     // Set the y element of a 3-D point (scalar data contained in vector data type)
01130     // 
01131     VECTORMATH_FORCE_INLINE Point3 & setY( const floatInVec &y );
01132 
01133     // Set the z element of a 3-D point (scalar data contained in vector data type)
01134     // 
01135     VECTORMATH_FORCE_INLINE Point3 & setZ( const floatInVec &z );
01136 
01137     // Get the x element of a 3-D point
01138     // 
01139     VECTORMATH_FORCE_INLINE const floatInVec getX( ) const;
01140 
01141     // Get the y element of a 3-D point
01142     // 
01143     VECTORMATH_FORCE_INLINE const floatInVec getY( ) const;
01144 
01145     // Get the z element of a 3-D point
01146     // 
01147     VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const;
01148 
01149     // Set an x, y, or z element of a 3-D point by index
01150     // 
01151     VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, float value );
01152 
01153     // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type)
01154     // 
01155     VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, const floatInVec &value );
01156 
01157     // Get an x, y, or z element of a 3-D point by index
01158     // 
01159     VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const;
01160 
01161     // Subscripting operator to set or get an element
01162     // 
01163     VECTORMATH_FORCE_INLINE VecIdx operator []( int idx );
01164 
01165     // Subscripting operator to get an element
01166     // 
01167     VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const;
01168 
01169     // Subtract a 3-D point from another 3-D point
01170     // 
01171     VECTORMATH_FORCE_INLINE const Vector3 operator -( const Point3 &pnt ) const;
01172 
01173     // Add a 3-D point to a 3-D vector
01174     // 
01175     VECTORMATH_FORCE_INLINE const Point3 operator +( const Vector3 &vec ) const;
01176 
01177     // Subtract a 3-D vector from a 3-D point
01178     // 
01179     VECTORMATH_FORCE_INLINE const Point3 operator -( const Vector3 &vec ) const;
01180 
01181     // Perform compound assignment and addition with a 3-D vector
01182     // 
01183     VECTORMATH_FORCE_INLINE Point3 & operator +=( const Vector3 &vec );
01184 
01185     // Perform compound assignment and subtraction by a 3-D vector
01186     // 
01187     VECTORMATH_FORCE_INLINE Point3 & operator -=( const Vector3 &vec );
01188 
01189 };
01190 
01191 // Multiply two 3-D points per element
01192 // 
01193 VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 );
01194 
01195 // Divide two 3-D points per element
01196 // NOTE: 
01197 // Floating-point behavior matches standard library function divf4.
01198 // 
01199 VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 );
01200 
01201 // Compute the reciprocal of a 3-D point per element
01202 // NOTE: 
01203 // Floating-point behavior matches standard library function recipf4.
01204 // 
01205 VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt );
01206 
01207 // Compute the absolute value of a 3-D point per element
01208 // 
01209 VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt );
01210 
01211 // Copy sign from one 3-D point to another, per element
01212 // 
01213 VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 );
01214 
01215 // Maximum of two 3-D points per element
01216 // 
01217 VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 );
01218 
01219 // Minimum of two 3-D points per element
01220 // 
01221 VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 );
01222 
01223 // Maximum element of a 3-D point
01224 // 
01225 VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt );
01226 
01227 // Minimum element of a 3-D point
01228 // 
01229 VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt );
01230 
01231 // Compute the sum of all elements of a 3-D point
01232 // 
01233 VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt );
01234 
01235 // Apply uniform scale to a 3-D point
01236 // 
01237 VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal );
01238 
01239 // Apply uniform scale to a 3-D point (scalar data contained in vector data type)
01240 // 
01241 VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal );
01242 
01243 // Apply non-uniform scale to a 3-D point
01244 // 
01245 VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec );
01246 
01247 // Scalar projection of a 3-D point on a unit-length 3-D vector
01248 // 
01249 VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec );
01250 
01251 // Compute the square of the distance of a 3-D point from the coordinate-system origin
01252 // 
01253 VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt );
01254 
01255 // Compute the distance of a 3-D point from the coordinate-system origin
01256 // 
01257 VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt );
01258 
01259 // Compute the square of the distance between two 3-D points
01260 // 
01261 VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 );
01262 
01263 // Compute the distance between two 3-D points
01264 // 
01265 VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 );
01266 
01267 // Linear interpolation between two 3-D points
01268 // NOTE: 
01269 // Does not clamp t between 0 and 1.
01270 // 
01271 VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 );
01272 
01273 // Linear interpolation between two 3-D points (scalar data contained in vector data type)
01274 // NOTE: 
01275 // Does not clamp t between 0 and 1.
01276 // 
01277 VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 );
01278 
01279 // Conditionally select between two 3-D points
01280 // NOTE: 
01281 // This function uses a conditional select instruction to avoid a branch.
01282 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
01283 // Use the boolInVec version for better performance.
01284 // 
01285 VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 );
01286 
01287 // Conditionally select between two 3-D points (scalar data contained in vector data type)
01288 // NOTE: 
01289 // This function uses a conditional select instruction to avoid a branch.
01290 // 
01291 VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 );
01292 
01293 // Store x, y, and z elements of 3-D point in first three words of a quadword, preserving fourth word
01294 // 
01295 VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad );
01296 
01297 // Load four three-float 3-D points, stored in three quadwords
01298 // 
01299 VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads );
01300 
01301 // Store four 3-D points in three quadwords
01302 // 
01303 VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads );
01304 
01305 // Store eight 3-D points as half-floats
01306 // 
01307 VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads );
01308 
01309 #ifdef _VECTORMATH_DEBUG
01310 
01311 // Print a 3-D point
01312 // NOTE: 
01313 // Function is only defined when _VECTORMATH_DEBUG is defined.
01314 // 
01315 VECTORMATH_FORCE_INLINE void print( const Point3 &pnt );
01316 
01317 // Print a 3-D point and an associated string identifier
01318 // NOTE: 
01319 // Function is only defined when _VECTORMATH_DEBUG is defined.
01320 // 
01321 VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name );
01322 
01323 #endif
01324 
01325 // A quaternion in array-of-structures format
01326 //
01327 class Quat
01328 {
01329     __m128 mVec128;
01330 
01331 public:
01332     // Default constructor; does no initialization
01333     // 
01334     VECTORMATH_FORCE_INLINE Quat( ) { };
01335 
01336         VECTORMATH_FORCE_INLINE  Quat(const Quat& quat);
01337 
01338     // Construct a quaternion from x, y, z, and w elements
01339     // 
01340     VECTORMATH_FORCE_INLINE Quat( float x, float y, float z, float w );
01341 
01342     // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type)
01343     // 
01344     VECTORMATH_FORCE_INLINE Quat( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w );
01345 
01346     // Construct a quaternion from a 3-D vector and a scalar
01347     // 
01348     VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, float w );
01349 
01350     // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type)
01351     // 
01352     VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, const floatInVec &w );
01353 
01354     // Copy elements from a 4-D vector into a quaternion
01355     // 
01356     explicit VECTORMATH_FORCE_INLINE Quat( const Vector4 &vec );
01357 
01358     // Convert a rotation matrix to a unit-length quaternion
01359     // 
01360     explicit VECTORMATH_FORCE_INLINE Quat( const Matrix3 & rotMat );
01361 
01362     // Set all elements of a quaternion to the same scalar value
01363     // 
01364     explicit VECTORMATH_FORCE_INLINE Quat( float scalar );
01365 
01366     // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type)
01367     // 
01368     explicit VECTORMATH_FORCE_INLINE Quat( const floatInVec &scalar );
01369 
01370     // Set vector float data in a quaternion
01371     // 
01372     explicit VECTORMATH_FORCE_INLINE Quat( __m128 vf4 );
01373 
01374     // Get vector float data from a quaternion
01375     // 
01376     VECTORMATH_FORCE_INLINE __m128 get128( ) const;
01377 
01378         // Set a quaterion from vector float data
01379     //
01380         VECTORMATH_FORCE_INLINE void set128(vec_float4 vec);
01381 
01382     // Assign one quaternion to another
01383     // 
01384     VECTORMATH_FORCE_INLINE Quat & operator =( const Quat &quat );
01385 
01386     // Set the x, y, and z elements of a quaternion
01387     // NOTE: 
01388     // This function does not change the w element.
01389     // 
01390     VECTORMATH_FORCE_INLINE Quat & setXYZ( const Vector3 &vec );
01391 
01392     // Get the x, y, and z elements of a quaternion
01393     // 
01394     VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const;
01395 
01396     // Set the x element of a quaternion
01397     // 
01398     VECTORMATH_FORCE_INLINE Quat & setX( float x );
01399 
01400     // Set the y element of a quaternion
01401     // 
01402     VECTORMATH_FORCE_INLINE Quat & setY( float y );
01403 
01404     // Set the z element of a quaternion
01405     // 
01406     VECTORMATH_FORCE_INLINE Quat & setZ( float z );
01407 
01408     // Set the w element of a quaternion
01409     // 
01410     VECTORMATH_FORCE_INLINE Quat & setW( float w );
01411 
01412     // Set the x element of a quaternion (scalar data contained in vector data type)
01413     // 
01414     VECTORMATH_FORCE_INLINE Quat & setX( const floatInVec &x );
01415 
01416     // Set the y element of a quaternion (scalar data contained in vector data type)
01417     // 
01418     VECTORMATH_FORCE_INLINE Quat & setY( const floatInVec &y );
01419 
01420     // Set the z element of a quaternion (scalar data contained in vector data type)
01421     // 
01422     VECTORMATH_FORCE_INLINE Quat & setZ( const floatInVec &z );
01423 
01424     // Set the w element of a quaternion (scalar data contained in vector data type)
01425     // 
01426     VECTORMATH_FORCE_INLINE Quat & setW( const floatInVec &w );
01427 
01428     // Get the x element of a quaternion
01429     // 
01430     VECTORMATH_FORCE_INLINE const floatInVec getX( ) const;
01431 
01432     // Get the y element of a quaternion
01433     // 
01434     VECTORMATH_FORCE_INLINE const floatInVec getY( ) const;
01435 
01436     // Get the z element of a quaternion
01437     // 
01438     VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const;
01439 
01440     // Get the w element of a quaternion
01441     // 
01442     VECTORMATH_FORCE_INLINE const floatInVec getW( ) const;
01443 
01444     // Set an x, y, z, or w element of a quaternion by index
01445     // 
01446     VECTORMATH_FORCE_INLINE Quat & setElem( int idx, float value );
01447 
01448     // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type)
01449     // 
01450     VECTORMATH_FORCE_INLINE Quat & setElem( int idx, const floatInVec &value );
01451 
01452     // Get an x, y, z, or w element of a quaternion by index
01453     // 
01454     VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const;
01455 
01456     // Subscripting operator to set or get an element
01457     // 
01458     VECTORMATH_FORCE_INLINE VecIdx operator []( int idx );
01459 
01460     // Subscripting operator to get an element
01461     // 
01462     VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const;
01463 
01464     // Add two quaternions
01465     // 
01466     VECTORMATH_FORCE_INLINE const Quat operator +( const Quat &quat ) const;
01467 
01468     // Subtract a quaternion from another quaternion
01469     // 
01470     VECTORMATH_FORCE_INLINE const Quat operator -( const Quat &quat ) const;
01471 
01472     // Multiply two quaternions
01473     // 
01474     VECTORMATH_FORCE_INLINE const Quat operator *( const Quat &quat ) const;
01475 
01476     // Multiply a quaternion by a scalar
01477     // 
01478     VECTORMATH_FORCE_INLINE const Quat operator *( float scalar ) const;
01479 
01480     // Divide a quaternion by a scalar
01481     // 
01482     VECTORMATH_FORCE_INLINE const Quat operator /( float scalar ) const;
01483 
01484     // Multiply a quaternion by a scalar (scalar data contained in vector data type)
01485     // 
01486     VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar ) const;
01487 
01488     // Divide a quaternion by a scalar (scalar data contained in vector data type)
01489     // 
01490     VECTORMATH_FORCE_INLINE const Quat operator /( const floatInVec &scalar ) const;
01491 
01492     // Perform compound assignment and addition with a quaternion
01493     // 
01494     VECTORMATH_FORCE_INLINE Quat & operator +=( const Quat &quat );
01495 
01496     // Perform compound assignment and subtraction by a quaternion
01497     // 
01498     VECTORMATH_FORCE_INLINE Quat & operator -=( const Quat &quat );
01499 
01500     // Perform compound assignment and multiplication by a quaternion
01501     // 
01502     VECTORMATH_FORCE_INLINE Quat & operator *=( const Quat &quat );
01503 
01504     // Perform compound assignment and multiplication by a scalar
01505     // 
01506     VECTORMATH_FORCE_INLINE Quat & operator *=( float scalar );
01507 
01508     // Perform compound assignment and division by a scalar
01509     // 
01510     VECTORMATH_FORCE_INLINE Quat & operator /=( float scalar );
01511 
01512     // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)
01513     // 
01514     VECTORMATH_FORCE_INLINE Quat & operator *=( const floatInVec &scalar );
01515 
01516     // Perform compound assignment and division by a scalar (scalar data contained in vector data type)
01517     // 
01518     VECTORMATH_FORCE_INLINE Quat & operator /=( const floatInVec &scalar );
01519 
01520     // Negate all elements of a quaternion
01521     // 
01522     VECTORMATH_FORCE_INLINE const Quat operator -( ) const;
01523 
01524     // Construct an identity quaternion
01525     // 
01526     static VECTORMATH_FORCE_INLINE const Quat identity( );
01527 
01528     // Construct a quaternion to rotate between two unit-length 3-D vectors
01529     // NOTE: 
01530     // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.
01531     // 
01532     static VECTORMATH_FORCE_INLINE const Quat rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 );
01533 
01534     // Construct a quaternion to rotate around a unit-length 3-D vector
01535     // 
01536     static VECTORMATH_FORCE_INLINE const Quat rotation( float radians, const Vector3 &unitVec );
01537 
01538     // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type)
01539     // 
01540     static VECTORMATH_FORCE_INLINE const Quat rotation( const floatInVec &radians, const Vector3 &unitVec );
01541 
01542     // Construct a quaternion to rotate around the x axis
01543     // 
01544     static VECTORMATH_FORCE_INLINE const Quat rotationX( float radians );
01545 
01546     // Construct a quaternion to rotate around the y axis
01547     // 
01548     static VECTORMATH_FORCE_INLINE const Quat rotationY( float radians );
01549 
01550     // Construct a quaternion to rotate around the z axis
01551     // 
01552     static VECTORMATH_FORCE_INLINE const Quat rotationZ( float radians );
01553 
01554     // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type)
01555     // 
01556     static VECTORMATH_FORCE_INLINE const Quat rotationX( const floatInVec &radians );
01557 
01558     // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type)
01559     // 
01560     static VECTORMATH_FORCE_INLINE const Quat rotationY( const floatInVec &radians );
01561 
01562     // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type)
01563     // 
01564     static VECTORMATH_FORCE_INLINE const Quat rotationZ( const floatInVec &radians );
01565 
01566 };
01567 
01568 // Multiply a quaternion by a scalar
01569 // 
01570 VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat );
01571 
01572 // Multiply a quaternion by a scalar (scalar data contained in vector data type)
01573 // 
01574 VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat );
01575 
01576 // Compute the conjugate of a quaternion
01577 // 
01578 VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat );
01579 
01580 // Use a unit-length quaternion to rotate a 3-D vector
01581 // 
01582 VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &unitQuat, const Vector3 &vec );
01583 
01584 // Compute the dot product of two quaternions
01585 // 
01586 VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 );
01587 
01588 // Compute the norm of a quaternion
01589 // 
01590 VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat );
01591 
01592 // Compute the length of a quaternion
01593 // 
01594 VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat );
01595 
01596 // Normalize a quaternion
01597 // NOTE: 
01598 // The result is unpredictable when all elements of quat are at or near zero.
01599 // 
01600 VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat );
01601 
01602 // Linear interpolation between two quaternions
01603 // NOTE: 
01604 // Does not clamp t between 0 and 1.
01605 // 
01606 VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 );
01607 
01608 // Linear interpolation between two quaternions (scalar data contained in vector data type)
01609 // NOTE: 
01610 // Does not clamp t between 0 and 1.
01611 // 
01612 VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 );
01613 
01614 // Spherical linear interpolation between two quaternions
01615 // NOTE: 
01616 // Interpolates along the shortest path between orientations.
01617 // Does not clamp t between 0 and 1.
01618 // 
01619 VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 );
01620 
01621 // Spherical linear interpolation between two quaternions (scalar data contained in vector data type)
01622 // NOTE: 
01623 // Interpolates along the shortest path between orientations.
01624 // Does not clamp t between 0 and 1.
01625 // 
01626 VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 );
01627 
01628 // Spherical quadrangle interpolation
01629 // 
01630 VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 );
01631 
01632 // Spherical quadrangle interpolation (scalar data contained in vector data type)
01633 // 
01634 VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 );
01635 
01636 // Conditionally select between two quaternions
01637 // NOTE: 
01638 // This function uses a conditional select instruction to avoid a branch.
01639 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
01640 // Use the boolInVec version for better performance.
01641 // 
01642 VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 );
01643 
01644 // Conditionally select between two quaternions (scalar data contained in vector data type)
01645 // NOTE: 
01646 // This function uses a conditional select instruction to avoid a branch.
01647 // 
01648 VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 );
01649 
01650 #ifdef _VECTORMATH_DEBUG
01651 
01652 // Print a quaternion
01653 // NOTE: 
01654 // Function is only defined when _VECTORMATH_DEBUG is defined.
01655 // 
01656 VECTORMATH_FORCE_INLINE void print( const Quat &quat );
01657 
01658 // Print a quaternion and an associated string identifier
01659 // NOTE: 
01660 // Function is only defined when _VECTORMATH_DEBUG is defined.
01661 // 
01662 VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name );
01663 
01664 #endif
01665 
01666 // A 3x3 matrix in array-of-structures format
01667 //
01668 class Matrix3
01669 {
01670     Vector3 mCol0;
01671     Vector3 mCol1;
01672     Vector3 mCol2;
01673 
01674 public:
01675     // Default constructor; does no initialization
01676     // 
01677     VECTORMATH_FORCE_INLINE Matrix3( ) { };
01678 
01679     // Copy a 3x3 matrix
01680     // 
01681     VECTORMATH_FORCE_INLINE Matrix3( const Matrix3 & mat );
01682 
01683     // Construct a 3x3 matrix containing the specified columns
01684     // 
01685     VECTORMATH_FORCE_INLINE Matrix3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2 );
01686 
01687     // Construct a 3x3 rotation matrix from a unit-length quaternion
01688     // 
01689     explicit VECTORMATH_FORCE_INLINE Matrix3( const Quat &unitQuat );
01690 
01691     // Set all elements of a 3x3 matrix to the same scalar value
01692     // 
01693     explicit VECTORMATH_FORCE_INLINE Matrix3( float scalar );
01694 
01695     // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type)
01696     // 
01697     explicit VECTORMATH_FORCE_INLINE Matrix3( const floatInVec &scalar );
01698 
01699     // Assign one 3x3 matrix to another
01700     // 
01701     VECTORMATH_FORCE_INLINE Matrix3 & operator =( const Matrix3 & mat );
01702 
01703     // Set column 0 of a 3x3 matrix
01704     // 
01705     VECTORMATH_FORCE_INLINE Matrix3 & setCol0( const Vector3 &col0 );
01706 
01707     // Set column 1 of a 3x3 matrix
01708     // 
01709     VECTORMATH_FORCE_INLINE Matrix3 & setCol1( const Vector3 &col1 );
01710 
01711     // Set column 2 of a 3x3 matrix
01712     // 
01713     VECTORMATH_FORCE_INLINE Matrix3 & setCol2( const Vector3 &col2 );
01714 
01715     // Get column 0 of a 3x3 matrix
01716     // 
01717     VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const;
01718 
01719     // Get column 1 of a 3x3 matrix
01720     // 
01721     VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const;
01722 
01723     // Get column 2 of a 3x3 matrix
01724     // 
01725     VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const;
01726 
01727     // Set the column of a 3x3 matrix referred to by the specified index
01728     // 
01729     VECTORMATH_FORCE_INLINE Matrix3 & setCol( int col, const Vector3 &vec );
01730 
01731     // Set the row of a 3x3 matrix referred to by the specified index
01732     // 
01733     VECTORMATH_FORCE_INLINE Matrix3 & setRow( int row, const Vector3 &vec );
01734 
01735     // Get the column of a 3x3 matrix referred to by the specified index
01736     // 
01737     VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const;
01738 
01739     // Get the row of a 3x3 matrix referred to by the specified index
01740     // 
01741     VECTORMATH_FORCE_INLINE const Vector3 getRow( int row ) const;
01742 
01743     // Subscripting operator to set or get a column
01744     // 
01745     VECTORMATH_FORCE_INLINE Vector3 & operator []( int col );
01746 
01747     // Subscripting operator to get a column
01748     // 
01749     VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const;
01750 
01751     // Set the element of a 3x3 matrix referred to by column and row indices
01752     // 
01753     VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, float val );
01754 
01755     // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type)
01756     // 
01757     VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, const floatInVec &val );
01758 
01759     // Get the element of a 3x3 matrix referred to by column and row indices
01760     // 
01761     VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const;
01762 
01763     // Add two 3x3 matrices
01764     // 
01765     VECTORMATH_FORCE_INLINE const Matrix3 operator +( const Matrix3 & mat ) const;
01766 
01767     // Subtract a 3x3 matrix from another 3x3 matrix
01768     // 
01769     VECTORMATH_FORCE_INLINE const Matrix3 operator -( const Matrix3 & mat ) const;
01770 
01771     // Negate all elements of a 3x3 matrix
01772     // 
01773     VECTORMATH_FORCE_INLINE const Matrix3 operator -( ) const;
01774 
01775     // Multiply a 3x3 matrix by a scalar
01776     // 
01777     VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar ) const;
01778 
01779     // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type)
01780     // 
01781     VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar ) const;
01782 
01783     // Multiply a 3x3 matrix by a 3-D vector
01784     // 
01785     VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const;
01786 
01787     // Multiply two 3x3 matrices
01788     // 
01789     VECTORMATH_FORCE_INLINE const Matrix3 operator *( const Matrix3 & mat ) const;
01790 
01791     // Perform compound assignment and addition with a 3x3 matrix
01792     // 
01793     VECTORMATH_FORCE_INLINE Matrix3 & operator +=( const Matrix3 & mat );
01794 
01795     // Perform compound assignment and subtraction by a 3x3 matrix
01796     // 
01797     VECTORMATH_FORCE_INLINE Matrix3 & operator -=( const Matrix3 & mat );
01798 
01799     // Perform compound assignment and multiplication by a scalar
01800     // 
01801     VECTORMATH_FORCE_INLINE Matrix3 & operator *=( float scalar );
01802 
01803     // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)
01804     // 
01805     VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const floatInVec &scalar );
01806 
01807     // Perform compound assignment and multiplication by a 3x3 matrix
01808     // 
01809     VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const Matrix3 & mat );
01810 
01811     // Construct an identity 3x3 matrix
01812     // 
01813     static VECTORMATH_FORCE_INLINE const Matrix3 identity( );
01814 
01815     // Construct a 3x3 matrix to rotate around the x axis
01816     // 
01817     static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( float radians );
01818 
01819     // Construct a 3x3 matrix to rotate around the y axis
01820     // 
01821     static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( float radians );
01822 
01823     // Construct a 3x3 matrix to rotate around the z axis
01824     // 
01825     static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( float radians );
01826 
01827     // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type)
01828     // 
01829     static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( const floatInVec &radians );
01830 
01831     // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type)
01832     // 
01833     static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( const floatInVec &radians );
01834 
01835     // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type)
01836     // 
01837     static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( const floatInVec &radians );
01838 
01839     // Construct a 3x3 matrix to rotate around the x, y, and z axes
01840     // 
01841     static VECTORMATH_FORCE_INLINE const Matrix3 rotationZYX( const Vector3 &radiansXYZ );
01842 
01843     // Construct a 3x3 matrix to rotate around a unit-length 3-D vector
01844     // 
01845     static VECTORMATH_FORCE_INLINE const Matrix3 rotation( float radians, const Vector3 &unitVec );
01846 
01847     // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)
01848     // 
01849     static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const floatInVec &radians, const Vector3 &unitVec );
01850 
01851     // Construct a rotation matrix from a unit-length quaternion
01852     // 
01853     static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const Quat &unitQuat );
01854 
01855     // Construct a 3x3 matrix to perform scaling
01856     // 
01857     static VECTORMATH_FORCE_INLINE const Matrix3 scale( const Vector3 &scaleVec );
01858 
01859 };
01860 // Multiply a 3x3 matrix by a scalar
01861 // 
01862 VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat );
01863 
01864 // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type)
01865 // 
01866 VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat );
01867 
01868 // Append (post-multiply) a scale transformation to a 3x3 matrix
01869 // NOTE: 
01870 // Faster than creating and multiplying a scale transformation matrix.
01871 // 
01872 VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec );
01873 
01874 // Prepend (pre-multiply) a scale transformation to a 3x3 matrix
01875 // NOTE: 
01876 // Faster than creating and multiplying a scale transformation matrix.
01877 // 
01878 VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat );
01879 
01880 // Multiply two 3x3 matrices per element
01881 // 
01882 VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );
01883 
01884 // Compute the absolute value of a 3x3 matrix per element
01885 // 
01886 VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat );
01887 
01888 // Transpose of a 3x3 matrix
01889 // 
01890 VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat );
01891 
01892 // Compute the inverse of a 3x3 matrix
01893 // NOTE: 
01894 // Result is unpredictable when the determinant of mat is equal to or near 0.
01895 // 
01896 VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat );
01897 
01898 // Determinant of a 3x3 matrix
01899 // 
01900 VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat );
01901 
01902 // Conditionally select between two 3x3 matrices
01903 // NOTE: 
01904 // This function uses a conditional select instruction to avoid a branch.
01905 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
01906 // Use the boolInVec version for better performance.
01907 // 
01908 VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 );
01909 
01910 // Conditionally select between two 3x3 matrices (scalar data contained in vector data type)
01911 // NOTE: 
01912 // This function uses a conditional select instruction to avoid a branch.
01913 // 
01914 VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 );
01915 
01916 #ifdef _VECTORMATH_DEBUG
01917 
01918 // Print a 3x3 matrix
01919 // NOTE: 
01920 // Function is only defined when _VECTORMATH_DEBUG is defined.
01921 // 
01922 VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat );
01923 
01924 // Print a 3x3 matrix and an associated string identifier
01925 // NOTE: 
01926 // Function is only defined when _VECTORMATH_DEBUG is defined.
01927 // 
01928 VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name );
01929 
01930 #endif
01931 
01932 // A 4x4 matrix in array-of-structures format
01933 //
01934 class Matrix4
01935 {
01936     Vector4 mCol0;
01937     Vector4 mCol1;
01938     Vector4 mCol2;
01939     Vector4 mCol3;
01940 
01941 public:
01942     // Default constructor; does no initialization
01943     // 
01944     VECTORMATH_FORCE_INLINE Matrix4( ) { };
01945 
01946     // Copy a 4x4 matrix
01947     // 
01948     VECTORMATH_FORCE_INLINE Matrix4( const Matrix4 & mat );
01949 
01950     // Construct a 4x4 matrix containing the specified columns
01951     // 
01952     VECTORMATH_FORCE_INLINE Matrix4( const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3 );
01953 
01954     // Construct a 4x4 matrix from a 3x4 transformation matrix
01955     // 
01956     explicit VECTORMATH_FORCE_INLINE Matrix4( const Transform3 & mat );
01957 
01958     // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector
01959     // 
01960     VECTORMATH_FORCE_INLINE Matrix4( const Matrix3 & mat, const Vector3 &translateVec );
01961 
01962     // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector
01963     // 
01964     VECTORMATH_FORCE_INLINE Matrix4( const Quat &unitQuat, const Vector3 &translateVec );
01965 
01966     // Set all elements of a 4x4 matrix to the same scalar value
01967     // 
01968     explicit VECTORMATH_FORCE_INLINE Matrix4( float scalar );
01969 
01970     // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type)
01971     // 
01972     explicit VECTORMATH_FORCE_INLINE Matrix4( const floatInVec &scalar );
01973 
01974     // Assign one 4x4 matrix to another
01975     // 
01976     VECTORMATH_FORCE_INLINE Matrix4 & operator =( const Matrix4 & mat );
01977 
01978     // Set the upper-left 3x3 submatrix
01979     // NOTE: 
01980     // This function does not change the bottom row elements.
01981     // 
01982     VECTORMATH_FORCE_INLINE Matrix4 & setUpper3x3( const Matrix3 & mat3 );
01983 
01984     // Get the upper-left 3x3 submatrix of a 4x4 matrix
01985     // 
01986     VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const;
01987 
01988     // Set translation component
01989     // NOTE: 
01990     // This function does not change the bottom row elements.
01991     // 
01992     VECTORMATH_FORCE_INLINE Matrix4 & setTranslation( const Vector3 &translateVec );
01993 
01994     // Get the translation component of a 4x4 matrix
01995     // 
01996     VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const;
01997 
01998     // Set column 0 of a 4x4 matrix
01999     // 
02000     VECTORMATH_FORCE_INLINE Matrix4 & setCol0( const Vector4 &col0 );
02001 
02002     // Set column 1 of a 4x4 matrix
02003     // 
02004     VECTORMATH_FORCE_INLINE Matrix4 & setCol1( const Vector4 &col1 );
02005 
02006     // Set column 2 of a 4x4 matrix
02007     // 
02008     VECTORMATH_FORCE_INLINE Matrix4 & setCol2( const Vector4 &col2 );
02009 
02010     // Set column 3 of a 4x4 matrix
02011     // 
02012     VECTORMATH_FORCE_INLINE Matrix4 & setCol3( const Vector4 &col3 );
02013 
02014     // Get column 0 of a 4x4 matrix
02015     // 
02016     VECTORMATH_FORCE_INLINE const Vector4 getCol0( ) const;
02017 
02018     // Get column 1 of a 4x4 matrix
02019     // 
02020     VECTORMATH_FORCE_INLINE const Vector4 getCol1( ) const;
02021 
02022     // Get column 2 of a 4x4 matrix
02023     // 
02024     VECTORMATH_FORCE_INLINE const Vector4 getCol2( ) const;
02025 
02026     // Get column 3 of a 4x4 matrix
02027     // 
02028     VECTORMATH_FORCE_INLINE const Vector4 getCol3( ) const;
02029 
02030     // Set the column of a 4x4 matrix referred to by the specified index
02031     // 
02032     VECTORMATH_FORCE_INLINE Matrix4 & setCol( int col, const Vector4 &vec );
02033 
02034     // Set the row of a 4x4 matrix referred to by the specified index
02035     // 
02036     VECTORMATH_FORCE_INLINE Matrix4 & setRow( int row, const Vector4 &vec );
02037 
02038     // Get the column of a 4x4 matrix referred to by the specified index
02039     // 
02040     VECTORMATH_FORCE_INLINE const Vector4 getCol( int col ) const;
02041 
02042     // Get the row of a 4x4 matrix referred to by the specified index
02043     // 
02044     VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const;
02045 
02046     // Subscripting operator to set or get a column
02047     // 
02048     VECTORMATH_FORCE_INLINE Vector4 & operator []( int col );
02049 
02050     // Subscripting operator to get a column
02051     // 
02052     VECTORMATH_FORCE_INLINE const Vector4 operator []( int col ) const;
02053 
02054     // Set the element of a 4x4 matrix referred to by column and row indices
02055     // 
02056     VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, float val );
02057 
02058     // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type)
02059     // 
02060     VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, const floatInVec &val );
02061 
02062     // Get the element of a 4x4 matrix referred to by column and row indices
02063     // 
02064     VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const;
02065 
02066     // Add two 4x4 matrices
02067     // 
02068     VECTORMATH_FORCE_INLINE const Matrix4 operator +( const Matrix4 & mat ) const;
02069 
02070     // Subtract a 4x4 matrix from another 4x4 matrix
02071     // 
02072     VECTORMATH_FORCE_INLINE const Matrix4 operator -( const Matrix4 & mat ) const;
02073 
02074     // Negate all elements of a 4x4 matrix
02075     // 
02076     VECTORMATH_FORCE_INLINE const Matrix4 operator -( ) const;
02077 
02078     // Multiply a 4x4 matrix by a scalar
02079     // 
02080     VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar ) const;
02081 
02082     // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type)
02083     // 
02084     VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar ) const;
02085 
02086     // Multiply a 4x4 matrix by a 4-D vector
02087     // 
02088     VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector4 &vec ) const;
02089 
02090     // Multiply a 4x4 matrix by a 3-D vector
02091     // 
02092     VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector3 &vec ) const;
02093 
02094     // Multiply a 4x4 matrix by a 3-D point
02095     // 
02096     VECTORMATH_FORCE_INLINE const Vector4 operator *( const Point3 &pnt ) const;
02097 
02098     // Multiply two 4x4 matrices
02099     // 
02100     VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Matrix4 & mat ) const;
02101 
02102     // Multiply a 4x4 matrix by a 3x4 transformation matrix
02103     // 
02104     VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Transform3 & tfrm ) const;
02105 
02106     // Perform compound assignment and addition with a 4x4 matrix
02107     // 
02108     VECTORMATH_FORCE_INLINE Matrix4 & operator +=( const Matrix4 & mat );
02109 
02110     // Perform compound assignment and subtraction by a 4x4 matrix
02111     // 
02112     VECTORMATH_FORCE_INLINE Matrix4 & operator -=( const Matrix4 & mat );
02113 
02114     // Perform compound assignment and multiplication by a scalar
02115     // 
02116     VECTORMATH_FORCE_INLINE Matrix4 & operator *=( float scalar );
02117 
02118     // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)
02119     // 
02120     VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const floatInVec &scalar );
02121 
02122     // Perform compound assignment and multiplication by a 4x4 matrix
02123     // 
02124     VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Matrix4 & mat );
02125 
02126     // Perform compound assignment and multiplication by a 3x4 transformation matrix
02127     // 
02128     VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Transform3 & tfrm );
02129 
02130     // Construct an identity 4x4 matrix
02131     // 
02132     static VECTORMATH_FORCE_INLINE const Matrix4 identity( );
02133 
02134     // Construct a 4x4 matrix to rotate around the x axis
02135     // 
02136     static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( float radians );
02137 
02138     // Construct a 4x4 matrix to rotate around the y axis
02139     // 
02140     static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( float radians );
02141 
02142     // Construct a 4x4 matrix to rotate around the z axis
02143     // 
02144     static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( float radians );
02145 
02146     // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type)
02147     // 
02148     static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( const floatInVec &radians );
02149 
02150     // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type)
02151     // 
02152     static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( const floatInVec &radians );
02153 
02154     // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type)
02155     // 
02156     static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( const floatInVec &radians );
02157 
02158     // Construct a 4x4 matrix to rotate around the x, y, and z axes
02159     // 
02160     static VECTORMATH_FORCE_INLINE const Matrix4 rotationZYX( const Vector3 &radiansXYZ );
02161 
02162     // Construct a 4x4 matrix to rotate around a unit-length 3-D vector
02163     // 
02164     static VECTORMATH_FORCE_INLINE const Matrix4 rotation( float radians, const Vector3 &unitVec );
02165 
02166     // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)
02167     // 
02168     static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const floatInVec &radians, const Vector3 &unitVec );
02169 
02170     // Construct a rotation matrix from a unit-length quaternion
02171     // 
02172     static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const Quat &unitQuat );
02173 
02174     // Construct a 4x4 matrix to perform scaling
02175     // 
02176     static VECTORMATH_FORCE_INLINE const Matrix4 scale( const Vector3 &scaleVec );
02177 
02178     // Construct a 4x4 matrix to perform translation
02179     // 
02180     static VECTORMATH_FORCE_INLINE const Matrix4 translation( const Vector3 &translateVec );
02181 
02182     // Construct viewing matrix based on eye, position looked at, and up direction
02183     // 
02184     static VECTORMATH_FORCE_INLINE const Matrix4 lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec );
02185 
02186     // Construct a perspective projection matrix
02187     // 
02188     static VECTORMATH_FORCE_INLINE const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar );
02189 
02190     // Construct a perspective projection matrix based on frustum
02191     // 
02192     static VECTORMATH_FORCE_INLINE const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar );
02193 
02194     // Construct an orthographic projection matrix
02195     // 
02196     static VECTORMATH_FORCE_INLINE const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar );
02197 
02198 };
02199 // Multiply a 4x4 matrix by a scalar
02200 // 
02201 VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat );
02202 
02203 // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type)
02204 // 
02205 VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat );
02206 
02207 // Append (post-multiply) a scale transformation to a 4x4 matrix
02208 // NOTE: 
02209 // Faster than creating and multiplying a scale transformation matrix.
02210 // 
02211 VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec );
02212 
02213 // Prepend (pre-multiply) a scale transformation to a 4x4 matrix
02214 // NOTE: 
02215 // Faster than creating and multiplying a scale transformation matrix.
02216 // 
02217 VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat );
02218 
02219 // Multiply two 4x4 matrices per element
02220 // 
02221 VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );
02222 
02223 // Compute the absolute value of a 4x4 matrix per element
02224 // 
02225 VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat );
02226 
02227 // Transpose of a 4x4 matrix
02228 // 
02229 VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat );
02230 
02231 // Compute the inverse of a 4x4 matrix
02232 // NOTE: 
02233 // Result is unpredictable when the determinant of mat is equal to or near 0.
02234 // 
02235 VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat );
02236 
02237 // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix
02238 // NOTE: 
02239 // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.
02240 // 
02241 VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat );
02242 
02243 // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix
02244 // NOTE: 
02245 // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.
02246 // 
02247 VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat );
02248 
02249 // Determinant of a 4x4 matrix
02250 // 
02251 VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat );
02252 
02253 // Conditionally select between two 4x4 matrices
02254 // NOTE: 
02255 // This function uses a conditional select instruction to avoid a branch.
02256 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
02257 // Use the boolInVec version for better performance.
02258 // 
02259 VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 );
02260 
02261 // Conditionally select between two 4x4 matrices (scalar data contained in vector data type)
02262 // NOTE: 
02263 // This function uses a conditional select instruction to avoid a branch.
02264 // 
02265 VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 );
02266 
02267 #ifdef _VECTORMATH_DEBUG
02268 
02269 // Print a 4x4 matrix
02270 // NOTE: 
02271 // Function is only defined when _VECTORMATH_DEBUG is defined.
02272 // 
02273 VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat );
02274 
02275 // Print a 4x4 matrix and an associated string identifier
02276 // NOTE: 
02277 // Function is only defined when _VECTORMATH_DEBUG is defined.
02278 // 
02279 VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name );
02280 
02281 #endif
02282 
02283 // A 3x4 transformation matrix in array-of-structures format
02284 //
02285 class Transform3
02286 {
02287     Vector3 mCol0;
02288     Vector3 mCol1;
02289     Vector3 mCol2;
02290     Vector3 mCol3;
02291 
02292 public:
02293     // Default constructor; does no initialization
02294     // 
02295     VECTORMATH_FORCE_INLINE Transform3( ) { };
02296 
02297     // Copy a 3x4 transformation matrix
02298     // 
02299     VECTORMATH_FORCE_INLINE Transform3( const Transform3 & tfrm );
02300 
02301     // Construct a 3x4 transformation matrix containing the specified columns
02302     // 
02303     VECTORMATH_FORCE_INLINE Transform3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3 );
02304 
02305     // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector
02306     // 
02307     VECTORMATH_FORCE_INLINE Transform3( const Matrix3 & tfrm, const Vector3 &translateVec );
02308 
02309     // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector
02310     // 
02311     VECTORMATH_FORCE_INLINE Transform3( const Quat &unitQuat, const Vector3 &translateVec );
02312 
02313     // Set all elements of a 3x4 transformation matrix to the same scalar value
02314     // 
02315     explicit VECTORMATH_FORCE_INLINE Transform3( float scalar );
02316 
02317     // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type)
02318     // 
02319     explicit VECTORMATH_FORCE_INLINE Transform3( const floatInVec &scalar );
02320 
02321     // Assign one 3x4 transformation matrix to another
02322     // 
02323     VECTORMATH_FORCE_INLINE Transform3 & operator =( const Transform3 & tfrm );
02324 
02325     // Set the upper-left 3x3 submatrix
02326     // 
02327     VECTORMATH_FORCE_INLINE Transform3 & setUpper3x3( const Matrix3 & mat3 );
02328 
02329     // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix
02330     // 
02331     VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const;
02332 
02333     // Set translation component
02334     // 
02335     VECTORMATH_FORCE_INLINE Transform3 & setTranslation( const Vector3 &translateVec );
02336 
02337     // Get the translation component of a 3x4 transformation matrix
02338     // 
02339     VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const;
02340 
02341     // Set column 0 of a 3x4 transformation matrix
02342     // 
02343     VECTORMATH_FORCE_INLINE Transform3 & setCol0( const Vector3 &col0 );
02344 
02345     // Set column 1 of a 3x4 transformation matrix
02346     // 
02347     VECTORMATH_FORCE_INLINE Transform3 & setCol1( const Vector3 &col1 );
02348 
02349     // Set column 2 of a 3x4 transformation matrix
02350     // 
02351     VECTORMATH_FORCE_INLINE Transform3 & setCol2( const Vector3 &col2 );
02352 
02353     // Set column 3 of a 3x4 transformation matrix
02354     // 
02355     VECTORMATH_FORCE_INLINE Transform3 & setCol3( const Vector3 &col3 );
02356 
02357     // Get column 0 of a 3x4 transformation matrix
02358     // 
02359     VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const;
02360 
02361     // Get column 1 of a 3x4 transformation matrix
02362     // 
02363     VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const;
02364 
02365     // Get column 2 of a 3x4 transformation matrix
02366     // 
02367     VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const;
02368 
02369     // Get column 3 of a 3x4 transformation matrix
02370     // 
02371     VECTORMATH_FORCE_INLINE const Vector3 getCol3( ) const;
02372 
02373     // Set the column of a 3x4 transformation matrix referred to by the specified index
02374     // 
02375     VECTORMATH_FORCE_INLINE Transform3 & setCol( int col, const Vector3 &vec );
02376 
02377     // Set the row of a 3x4 transformation matrix referred to by the specified index
02378     // 
02379     VECTORMATH_FORCE_INLINE Transform3 & setRow( int row, const Vector4 &vec );
02380 
02381     // Get the column of a 3x4 transformation matrix referred to by the specified index
02382     // 
02383     VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const;
02384 
02385     // Get the row of a 3x4 transformation matrix referred to by the specified index
02386     // 
02387     VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const;
02388 
02389     // Subscripting operator to set or get a column
02390     // 
02391     VECTORMATH_FORCE_INLINE Vector3 & operator []( int col );
02392 
02393     // Subscripting operator to get a column
02394     // 
02395     VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const;
02396 
02397     // Set the element of a 3x4 transformation matrix referred to by column and row indices
02398     // 
02399     VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, float val );
02400 
02401     // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type)
02402     // 
02403     VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, const floatInVec &val );
02404 
02405     // Get the element of a 3x4 transformation matrix referred to by column and row indices
02406     // 
02407     VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const;
02408 
02409     // Multiply a 3x4 transformation matrix by a 3-D vector
02410     // 
02411     VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const;
02412 
02413     // Multiply a 3x4 transformation matrix by a 3-D point
02414     // 
02415     VECTORMATH_FORCE_INLINE const Point3 operator *( const Point3 &pnt ) const;
02416 
02417     // Multiply two 3x4 transformation matrices
02418     // 
02419     VECTORMATH_FORCE_INLINE const Transform3 operator *( const Transform3 & tfrm ) const;
02420 
02421     // Perform compound assignment and multiplication by a 3x4 transformation matrix
02422     // 
02423     VECTORMATH_FORCE_INLINE Transform3 & operator *=( const Transform3 & tfrm );
02424 
02425     // Construct an identity 3x4 transformation matrix
02426     // 
02427     static VECTORMATH_FORCE_INLINE const Transform3 identity( );
02428 
02429     // Construct a 3x4 transformation matrix to rotate around the x axis
02430     // 
02431     static VECTORMATH_FORCE_INLINE const Transform3 rotationX( float radians );
02432 
02433     // Construct a 3x4 transformation matrix to rotate around the y axis
02434     // 
02435     static VECTORMATH_FORCE_INLINE const Transform3 rotationY( float radians );
02436 
02437     // Construct a 3x4 transformation matrix to rotate around the z axis
02438     // 
02439     static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( float radians );
02440 
02441     // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type)
02442     // 
02443     static VECTORMATH_FORCE_INLINE const Transform3 rotationX( const floatInVec &radians );
02444 
02445     // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type)
02446     // 
02447     static VECTORMATH_FORCE_INLINE const Transform3 rotationY( const floatInVec &radians );
02448 
02449     // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type)
02450     // 
02451     static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( const floatInVec &radians );
02452 
02453     // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes
02454     // 
02455     static VECTORMATH_FORCE_INLINE const Transform3 rotationZYX( const Vector3 &radiansXYZ );
02456 
02457     // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector
02458     // 
02459     static VECTORMATH_FORCE_INLINE const Transform3 rotation( float radians, const Vector3 &unitVec );
02460 
02461     // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)
02462     // 
02463     static VECTORMATH_FORCE_INLINE const Transform3 rotation( const floatInVec &radians, const Vector3 &unitVec );
02464 
02465     // Construct a rotation matrix from a unit-length quaternion
02466     // 
02467     static VECTORMATH_FORCE_INLINE const Transform3 rotation( const Quat &unitQuat );
02468 
02469     // Construct a 3x4 transformation matrix to perform scaling
02470     // 
02471     static VECTORMATH_FORCE_INLINE const Transform3 scale( const Vector3 &scaleVec );
02472 
02473     // Construct a 3x4 transformation matrix to perform translation
02474     // 
02475     static VECTORMATH_FORCE_INLINE const Transform3 translation( const Vector3 &translateVec );
02476 
02477 };
02478 // Append (post-multiply) a scale transformation to a 3x4 transformation matrix
02479 // NOTE: 
02480 // Faster than creating and multiplying a scale transformation matrix.
02481 // 
02482 VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec );
02483 
02484 // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix
02485 // NOTE: 
02486 // Faster than creating and multiplying a scale transformation matrix.
02487 // 
02488 VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm );
02489 
02490 // Multiply two 3x4 transformation matrices per element
02491 // 
02492 VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );
02493 
02494 // Compute the absolute value of a 3x4 transformation matrix per element
02495 // 
02496 VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm );
02497 
02498 // Inverse of a 3x4 transformation matrix
02499 // NOTE: 
02500 // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.
02501 // 
02502 VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm );
02503 
02504 // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix
02505 // NOTE: 
02506 // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.
02507 // 
02508 VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm );
02509 
02510 // Conditionally select between two 3x4 transformation matrices
02511 // NOTE: 
02512 // This function uses a conditional select instruction to avoid a branch.
02513 // However, the transfer of select1 to a VMX register may use more processing time than a branch.
02514 // Use the boolInVec version for better performance.
02515 // 
02516 VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 );
02517 
02518 // Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type)
02519 // NOTE: 
02520 // This function uses a conditional select instruction to avoid a branch.
02521 // 
02522 VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 );
02523 
02524 #ifdef _VECTORMATH_DEBUG
02525 
02526 // Print a 3x4 transformation matrix
02527 // NOTE: 
02528 // Function is only defined when _VECTORMATH_DEBUG is defined.
02529 // 
02530 VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm );
02531 
02532 // Print a 3x4 transformation matrix and an associated string identifier
02533 // NOTE: 
02534 // Function is only defined when _VECTORMATH_DEBUG is defined.
02535 // 
02536 VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name );
02537 
02538 #endif
02539 
02540 } // namespace Aos
02541 } // namespace Vectormath
02542 
02543 #include "vec_aos.h"
02544 #include "quat_aos.h"
02545 #include "mat_aos.h"
02546 
02547 #endif