00001
00002
00003
00006
00007
00008
00009
00010
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
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
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
00218 Vec3() {};
00219 Vec3(const Vec3& v3Value) { x = v3Value.x; y = v3Value.y; z = v3Value.z; }
00220 Vec3(float fX, float fY, float fZ) { x = fX; y = fY; z = fZ; }
00221
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; }
00239
00240
00241
00242 operator float* () { return (float*)&x; }
00243 operator const float* () const { return (float*)&x; }
00244
00245
00246 float& operator [] (int nIndex) { return ((float*)&x)[nIndex]; }
00247 const float& operator [] (int nIndex) const { return ((float*)&x)[nIndex]; }
00248
00249
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
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
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;
00309 __forceinline float GetAxis(int nIndex) const { return (*this)[nIndex]; }
00310 static __forceinline const Vec3& TA_VEC3_CALL GetUnitVector(int nIndex);
00311
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.