True Axis Physics SDK 1.2.0.1 Beta Documentation
www.trueaxis.com

Vec3MT.h

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------------
00002 // File Name: Vec3MT.h
00003 // Description:
00006 //
00007 // Copyright (C) 2004 - 2006 True Axis Pty Ltd, Australia. 
00008 // All Rights Reserved.
00009 //
00010 // History:
00011 //---------------------------------------------------------------------------------
00012 
00013 #ifndef TA_VEC3MT_H
00014 #define TA_VEC3MT_H
00015 
00016 #ifndef DOXYGEN
00017 
00018 namespace TA
00019 {
00020 
00021 struct Vec3;
00022 
00023 namespace Meta
00024 {
00025 
00026 TA_ALIGN_16 struct _Vec3 
00027 {
00028     float x;
00029     float y;
00030     float z;
00031     float w;
00032 
00033     __forceinline float _EvaluateX() const { return x; }
00034     __forceinline float _EvaluateY() const { return y; }
00035     __forceinline float _EvaluateZ() const { return z; }
00036 };
00037 
00038 template <class Type>
00039 struct Vec3Tmp : public Type, public _Vec3
00040 {
00041 };
00042 
00043 template <class Type>
00044 struct Vec3Evaluator
00045 {
00046     __forceinline float EvaluateX() const { return ((Type&)(*this))._EvaluateX(); }
00047     __forceinline float EvaluateY() const { return ((Type&)(*this))._EvaluateY(); }
00048     __forceinline float EvaluateZ() const { return ((Type&)(*this))._EvaluateZ(); }
00049 
00050     template<class TypeA, class TypeB>
00051     static __forceinline float Dot(const Vec3Evaluator<TypeA>& a, const Vec3Evaluator<TypeB>& b)
00052     {
00053         // better had not dot something with its self!
00054         return a.EvaluateX() * b.EvaluateX() + a.EvaluateY() * b.EvaluateY() + a.EvaluateZ() * b.EvaluateZ();
00055     }
00056     template<class TypeA>
00057     __forceinline float Dot(const Vec3Evaluator<TypeA>& src) const { return Dot(*this, src); }
00058 
00059     template<class TypeA, class TypeB>
00060     static __forceinline Vec3Tmp< Vec3Evaluator<_Vec3> > Cross(const Vec3Evaluator<TypeA>& a, const Vec3Evaluator<TypeB>& b)
00061     {
00062         _Vec3 v3A;
00063         v3A.x = a.EvaluateX();
00064         v3A.y = a.EvaluateY();
00065         v3A.z = a.EvaluateZ();
00066         _Vec3 v3B;
00067         v3B.x = b.EvaluateX();
00068         v3B.y = b.EvaluateY();
00069         v3B.z = b.EvaluateZ();
00070         Vec3Tmp< Vec3Evaluator<_Vec3> > v3Dst ;
00071         v3Dst.x = v3A.y * v3B.z - v3A.z * v3B.y;
00072         v3Dst.y = v3A.z * v3B.x - v3A.x * v3B.z;
00073         v3Dst.z = v3A.x * v3B.y - v3A.y * v3B.x;
00074         return v3Dst;
00075     }
00076     template<class TypeA>
00077     __forceinline Vec3Tmp< Vec3Evaluator<_Vec3> > Cross(const Vec3Evaluator<TypeA>& b) const { return Cross(*this, b); }    
00078     
00079     __forceinline float GetMagnitude() const 
00080     {   
00081         float fX = EvaluateX();
00082         float fDot = fX * fX;
00083         float fY = EvaluateY();
00084         fDot += fY * fY;
00085         float fZ = EvaluateZ();
00086         fDot += fZ * fZ;
00087         return Sqrt(fDot); 
00088     }
00089     template<class TypeA>
00090     static inline float TA_VEC3_CALL GetMagnitude(const Vec3Evaluator<TypeA>& a) { return a.GetMagnitude(); }
00091 
00092     __forceinline float GetMagnitudeSqrd() const 
00093     { 
00094         float fX = EvaluateX();
00095         float fDot = fX * fX;
00096         float fY = EvaluateY();
00097         fDot += fY * fY;
00098         float fZ = EvaluateZ();
00099         fDot += fZ * fZ;
00100         return fDot;
00101     }
00102     template<class TypeA>
00103     static inline float TA_VEC3_CALL GetMagnitudeSqrd(const Vec3Evaluator<TypeA>& a) { return a.GetMagnitudeSqrd(); }
00104 
00105     __forceinline Vec3 GetNormal() const; 
00106     template<class TypeA>
00107     static __forceinline Vec3Tmp< Vec3Evaluator<_Vec3> > GetNormal(const Vec3Evaluator<TypeA>& b) 
00108     { 
00109         return b.GetNormal(); 
00110     }
00111 };
00112 
00113 struct Add
00114 {
00115     static __forceinline float EvaluateX(float a, float b) { return a + b; }
00116     static __forceinline float EvaluateY(float a, float b) { return a + b; }
00117     static __forceinline float EvaluateZ(float a, float b) { return a + b; }
00118     static __forceinline float EvaluateW(float a, float b) { return a + b; }
00119 };
00120 struct Sub
00121 {
00122     static __forceinline float EvaluateX(float a, float b) { return a - b; }
00123     static __forceinline float EvaluateY(float a, float b) { return a - b; }
00124     static __forceinline float EvaluateZ(float a, float b) { return a - b; }
00125     static __forceinline float EvaluateW(float a, float b) { return a - b; }
00126 };
00127 struct Mul
00128 {
00129     static __forceinline float EvaluateX(float a, float b) { return a * b; }
00130     static __forceinline float EvaluateY(float a, float b) { return a * b; }
00131     static __forceinline float EvaluateZ(float a, float b) { return a * b; }
00132     static __forceinline float EvaluateW(float a, float b) { return a * b; }
00133 };
00134 // todo: test not separating the divide so we can do an inverse and multiply
00135 struct Div
00136 {
00137     static __forceinline float EvaluateX(float a, float b) { return a / b; }
00138     static __forceinline float EvaluateY(float a, float b) { return a / b; }
00139     static __forceinline float EvaluateZ(float a, float b) { return a / b; }
00140     static __forceinline float EvaluateW(float a, float b) { return a / b; }
00141 };
00142 struct Nothing
00143 {
00144     static __forceinline float EvaluateX(float a) { return a; }
00145     static __forceinline float EvaluateY(float a) { return a; }
00146     static __forceinline float EvaluateZ(float a) { return a; }
00147     static __forceinline float EvaluateW(float a) { return a; }
00148 };
00149 struct Negate
00150 {
00151     static __forceinline float EvaluateX(float a) { return -a; }
00152     static __forceinline float EvaluateY(float a) { return -a; }
00153     static __forceinline float EvaluateZ(float a) { return -a; }
00154     static __forceinline float EvaluateW(float a) { return -a; }
00155 };
00156 
00157 template <class TypeA, class TypeB, class Vec3Function>
00158 struct BinaryOp : public Vec3Evaluator<BinaryOp>
00159 {
00160     const TypeA& m_a;
00161     const TypeB& m_b;
00162     __forceinline BinaryOp(const TypeA& a, const TypeB& b) : m_a(a), m_b(b) {}
00163     __forceinline float _EvaluateX() const { return Vec3Function::EvaluateX(m_a.EvaluateX(), m_b.EvaluateX()); }
00164     __forceinline float _EvaluateY() const { return Vec3Function::EvaluateY(m_a.EvaluateY(), m_b.EvaluateY()); }
00165     __forceinline float _EvaluateZ() const { return Vec3Function::EvaluateZ(m_a.EvaluateZ(), m_b.EvaluateZ()); }
00166 
00167 };
00168 
00169 template <class TypeA, class Vec3Function>
00170 struct UnaryOp : public Vec3Evaluator<UnaryOp>
00171 {
00172     const TypeA& m_a;
00173     __forceinline UnaryOp(const TypeA& a) : m_a(a) {}
00174     __forceinline float _EvaluateX() const { return Vec3Function::EvaluateX(m_a.EvaluateX()); }
00175     __forceinline float _EvaluateY() const { return Vec3Function::EvaluateY(m_a.EvaluateY()); }
00176     __forceinline float _EvaluateZ() const { return Vec3Function::EvaluateZ(m_a.EvaluateZ()); }
00177 
00178 };
00179 
00180 template <class TypeA, class Vec3Function>
00181 struct BinaryOpVS : public Vec3Evaluator<BinaryOpVS>
00182 {
00183     const TypeA& m_a;
00184     const float m_b;
00185     __forceinline BinaryOpVS(const TypeA& a, const float b) : m_a(a), m_b(b) {}
00186     __forceinline float _EvaluateX() const { return Vec3Function::EvaluateX(m_a.EvaluateX(), m_b); }
00187     __forceinline float _EvaluateY() const { return Vec3Function::EvaluateY(m_a.EvaluateY(), m_b); }
00188     __forceinline float _EvaluateZ() const { return Vec3Function::EvaluateZ(m_a.EvaluateZ(), m_b); }
00189 
00190 };
00191 
00192 template <class TypeB, class Vec3Function>
00193 struct BinaryOpSV : public Vec3Evaluator<BinaryOpSV>
00194 {
00195     const float m_a;
00196     const TypeB& m_b;
00197     __forceinline BinaryOpSV(const float a, const TypeB& b) : m_a(a), m_b(b) {}
00198     __forceinline float _EvaluateX() const { return Vec3Function::EvaluateX(m_a, m_b.EvaluateX()); }
00199     __forceinline float _EvaluateY() const { return Vec3Function::EvaluateY(m_a, m_b.EvaluateY()); }
00200     __forceinline float _EvaluateZ() const { return Vec3Function::EvaluateZ(m_a, m_b.EvaluateZ()); }
00201 
00202 };
00203 
00204 }
00205 
00206 //---------------------------------------------------------------------------------
00207 //---------------------------------------------------------------------------------
00208 struct TACOMMON_CLASS Vec3 : public Meta::_Vec3, public Meta::Vec3Evaluator<Vec3>
00209 {   
00210     enum Axis
00211     {
00212         AXIS_X = 0,
00213         AXIS_Y,
00214         AXIS_Z,
00215     };
00216 
00217     // Initialisation
00218     Vec3() {};
00219     Vec3(const Vec3& v3Value) { x = v3Value.x; y = v3Value.y; z = v3Value.z; /*z = 0.0f;*/ }
00220     Vec3(float fX, float fY, float fZ) { x = fX; y = fY; z = fZ;  /*z = 0.0f;*/ }   
00221     //__forceinline Vec3(const _Vec3& v3Src) { (_Vec3&)*this = v3Src; }
00222     template <class Type>
00223     __forceinline Vec3& operator = (const Meta::Vec3Evaluator<Type>& src)
00224     {
00225         x = src.EvaluateX();
00226         y = src.EvaluateY();
00227         z = src.EvaluateZ();
00228         return *this;
00229     }   
00230     template <class Type>
00231     __forceinline Vec3(const Meta::Vec3Evaluator<Type>& src)
00232     {
00233         x = src.EvaluateX();
00234         y = src.EvaluateY();
00235         z = src.EvaluateZ();
00236     }
00237 
00238     __forceinline void Initialise(float fX, float fY, float fZ) { x = fX; y = fY; z = fZ; /*z = 0.0f;*/ }
00239 
00240 
00241     // Casting
00242     operator float* () { return (float*)&x; }
00243     operator const float* () const { return (float*)&x; }
00244 
00245     // Array operators
00246     float& operator [] (int nIndex) { return ((float*)&x)[nIndex]; }
00247     const float& operator [] (int nIndex) const { return ((float*)&x)[nIndex]; }
00248 
00249     // Assignment operators
00250     template <class Type>
00251     __forceinline Vec3& operator += (const Meta::Vec3Evaluator<Type>& src) 
00252     { 
00253         x += src.EvaluateX(); 
00254         y += src.EvaluateY(); 
00255         z += src.EvaluateZ(); 
00256         return *this; 
00257     }
00258     template <class Type>
00259     __forceinline Vec3& operator -= (const Meta::Vec3Evaluator<Type>& src) 
00260     { 
00261         x -= src.EvaluateX(); 
00262         y -= src.EvaluateY(); 
00263         z -= src.EvaluateZ(); 
00264         return *this; 
00265     }
00266     __forceinline Vec3& operator *= (float fValue) { x *= fValue; y *= fValue; z *= fValue; return *this; }
00267     __forceinline Vec3& operator /= (float fValue) { float fDiv = 1.0f / fValue; x *= fDiv; y *= fDiv; z *= fDiv; return *this; }
00268 
00269     // cross product
00270     static inline Vec3 TA_VEC3_CALL CrossWithUnitX(const Vec3& v3Value) { return Vec3(0.0f, v3Value.z, -v3Value.y); }
00271     inline Vec3 CrossWithUnitX() const { return CrossWithUnitX(*this); }
00272     static inline Vec3 TA_VEC3_CALL CrossWithUnitY(const Vec3& v3Value) { return Vec3(-v3Value.z, 0.0f, v3Value.x); }
00273     inline Vec3 CrossWithUnitY() const { return CrossWithUnitY(*this); }
00274     static inline Vec3 TA_VEC3_CALL CrossWithUnitZ(const Vec3& v3Value) { return Vec3(v3Value.y, -v3Value.x, 0.0f); }
00275     inline Vec3 CrossWithUnitZ() const { return CrossWithUnitZ(*this); }
00276     static inline float TA_VEC3_CALL CrossX(const Vec3& v3A, const Vec3& v3B) { return v3A.y * v3B.z - v3A.z * v3B.y; }
00277     inline float CrossX(const Vec3& v3Value) const { return CrossX(*this, v3Value); }
00278     static inline float TA_VEC3_CALL CrossY(const Vec3& v3A, const Vec3& v3B) { return v3A.z * v3B.x - v3A.x * v3B.z; }
00279     inline float CrossY(const Vec3& v3Value) const { return CrossY(*this, v3Value); }
00280     static inline float TA_VEC3_CALL CrossZ(const Vec3& v3A, const Vec3& v3B) { return v3A.x * v3B.y - v3A.y * v3B.x; }
00281     inline float CrossZ(const Vec3& v3Value) const { return CrossZ(*this, v3Value); }
00282 
00283 
00284     // min / max
00285     static inline Vec3 TA_VEC3_CALL Min(const Vec3& v3A, const Vec3& v3B)
00286     {
00287         Vec3 v3Result;
00288         v3Result.x = v3A.x < v3B.x ? v3A.x : v3B.x;
00289         v3Result.y = v3A.y < v3B.y ? v3A.y : v3B.y;
00290         v3Result.z = v3A.z < v3B.z ? v3A.z : v3B.z;
00291         return v3Result;
00292     }
00293     static inline Vec3 TA_VEC3_CALL Max(const Vec3& v3A, const Vec3& v3B)
00294     {
00295         Vec3 v3Result;
00296         v3Result.x = v3A.x > v3B.x ? v3A.x : v3B.x;
00297         v3Result.y = v3A.y > v3B.y ? v3A.y : v3B.y;
00298         v3Result.z = v3A.z > v3B.z ? v3A.z : v3B.z;
00299         return v3Result;
00300     }
00301 
00302 
00303     __forceinline void Normalise() { (*this) *= ReciprocalSqrt(GetMagnitudeSqrd()); }
00304     __forceinline void Clear() { x = 0.0f; y = 0.0f; z = 0.0f; }
00305     __forceinline bool IsNormalised() const { return IsEqualToOneWithInError(GetMagnitudeSqrd()); }
00306     __forceinline bool IsZero() const { return GetMagnitudeSqrd() == 0.0f; }
00307     __forceinline int GetGreatestAxis() const;
00308     __forceinline void GetAxisOrder(int pnAxisOrder[3]) const; // Axis order from biggest to smallest
00309     __forceinline float GetAxis(int nIndex) const { return (*this)[nIndex]; }
00310     static __forceinline const Vec3& TA_VEC3_CALL GetUnitVector(int nIndex);
00311     //inline void IsEqualWithInError()
00312 };
00313 
00314 const Vec3 k_v3Zero(0.0f, 0.0f, 0.0f);
00315 const Vec3 k_v3UnitX(1.0f, 0.0f, 0.0f);
00316 const Vec3 k_v3UnitY(0.0f, 1.0f, 0.0f);
00317 const Vec3 k_v3UnitZ(0.0f, 0.0f, 1.0f);
00318 
00319 
00320 }
00321 
00322 #include "Vec3MT.inl"
00323 
00324 #endif // DOXYGEN
00325 
00326 #endif // TA_VEC3MT_H


© Copyright 2004-2006 TRUE AXIS PTY LTD Australia. All rights reserved.