00001
00002
00003
00004
00005
00006
00007 #pragma once
00008 #include "../base/Vary.h"
00009
00010 namespace
00011 {
00012
00013
00014 template <typename VecType>
00015 inline void AssignFromArray(VecType &v, const float *arr)
00016 {
00017 for (uint i=0; i<v.ElementCount(); ++i)
00018 v[i]=arr[i];
00019 }
00020
00021 template <typename VecType>
00022 inline void AssignFromValue(VecType &v, float val)
00023 {
00024 for (uint i=0; i<v.ElementCount(); ++i)
00025 v[i]=val;
00026 }
00027
00028 template <typename VecType>
00029 inline VecType Scale(const VecType &v, const float &s)
00030 {
00031 VecType r;
00032 for (uint i=0; i<v.ElementCount(); ++i)
00033 r[i]=v[i]*s;
00034 return r;
00035 }
00036
00037 template <typename VecType>
00038 inline VecType Scale(const VecType &v1, const VecType &v2)
00039 {
00040 VecType r;
00041 for (uint i=0; i<v1.ElementCount(); ++i)
00042 r[i]=v1[i]*v2[i];
00043 return r;
00044 }
00045
00046 template <typename VecType>
00047 inline VecType Add(const VecType &v1, const VecType &v2)
00048 {
00049 VecType r;
00050 for (uint i=0; i<v1.ElementCount(); ++i)
00051 r[i]=v1[i]+v2[i];
00052 return r;
00053 }
00054
00055 template <typename VecType>
00056 inline VecType Sub(const VecType &v1, const VecType &v2)
00057 {
00058 VecType r;
00059 for (uint i=0; i<v1.ElementCount(); ++i)
00060 r[i]=v1[i]-v2[i];
00061 return r;
00062 }
00063
00064 template <typename VecType>
00065 inline VecType Neg(const VecType &v)
00066 {
00067 VecType r;
00068 for (uint i=0; i<v.ElementCount(); ++i)
00069 r[i]=-v[i];
00070 return r;
00071 }
00072
00073 template <typename VecType>
00074 inline VecType Div(const VecType &v1, const VecType &v2)
00075 {
00076 VecType r;
00077 for (uint i=0; i<v1.ElementCount(); ++i)
00078 r[i]=v1[i]/v2[i];
00079 return r;
00080 }
00081
00082 template <typename VecType>
00083 inline void ScaleSelf(VecType &v, const float &s)
00084 {
00085 for (uint i=0; i<v.ElementCount(); ++i)
00086 v[i]*=s;
00087 }
00088
00089 template <typename VecType>
00090 inline void ScaleSelf(VecType &v1, const VecType &v2)
00091 {
00092 for (uint i=0; i<v1.ElementCount(); ++i)
00093 v1[i]*=v2[i];
00094 }
00095
00096 template <typename VecType>
00097 inline void AddSelf(VecType &v1, const VecType &v2)
00098 {
00099 for (uint i=0; i<v1.ElementCount(); ++i)
00100 v1[i]+=v2[i];
00101 }
00102
00103 template <typename VecType>
00104 inline void SubSelf(VecType &v1, const VecType &v2)
00105 {
00106 for (uint i=0; i<v1.ElementCount(); ++i)
00107 v1[i]-=v2[i];
00108 }
00109
00110 template <typename VecType>
00111 inline void NegSelf(VecType &v)
00112 {
00113 for (uint i=0; i<v.ElementCount(); ++i)
00114 v[i]=-v[i];
00115 }
00116
00117 template <typename VecType>
00118 inline void DivSelf(VecType &v1, const VecType &v2)
00119 {
00120 for (uint i=0; i<v1.ElementCount(); ++i)
00121 v1[i]/=v2[i];
00122 }
00123 }
00124
00125 namespace GEO
00126 {
00127 template <uint elemCount> struct MatrixN;
00128
00129
00130
00131
00133 template <uint elemCount>
00134 struct VectorN
00135 {
00136 typedef MatrixN<elemCount> MatrixType;
00137 typedef MatrixN<elemCount+1> GreaterMatrixType;
00138
00139 float elements[elemCount];
00140 inline uint ElementCount() const { return elemCount; }
00141
00142
00143 inline VectorN() {}
00144 inline VectorN(const float *array) { AssignFromArray(*this,array); }
00145 inline VectorN(float c) { AssignFromValue(*this,c); }
00146
00147
00148 inline float& operator[](uint index) { return elements[index]; }
00149 inline const float& operator[](uint index) const { return elements[index]; }
00150
00151
00152 inline VectorN operator*(const VectorN &o) const { return Scale(*this,o); }
00153 inline VectorN operator*(const float &o) const { return Scale<VectorN>(*this,o); }
00154 friend inline VectorN operator*(const float &o, const VectorN &me) { return Scale<VectorN>(me,o); }
00155 inline VectorN operator/(const VectorN &o) const { return Div(*this,o); }
00156 inline VectorN operator/(const float &o) const { return Scale<VectorN>(*this,1/o); }
00157 inline VectorN operator+(const VectorN &o) const { return Add(*this,o); }
00158 inline VectorN operator+(const float &o) const { return Add(*this,VectorN(o)); }
00159 inline VectorN operator-(const VectorN &o) const { return Sub(*this,o); }
00160 inline VectorN operator-(const float &o) const { return Sub(*this,VectorN(o)); }
00161
00162
00163 inline void operator*=(const VectorN &o) { ScaleSelf(*this,o); }
00164 inline void operator*=(const float &o) { ScaleSelf<VectorN>(*this,o); }
00165 inline void operator/=(const VectorN &o) { DivSelf(*this,o); }
00166 inline void operator/=(const float &o) { ScaleSelf<VectorN>(*this,1/o); }
00167 inline void operator+=(const VectorN &o) { AddSelf(*this,o); }
00168 inline void operator+=(const float &o) { AddSelf(*this,VectorN(o)); }
00169 inline void operator-=(const VectorN &o) { SubSelf(*this,o); }
00170 inline void operator-=(const float &o) { SubSelf(*this,VectorN(o)); }
00171
00172
00173 inline VectorN operator-() const { return Neg(*this); }
00174
00175
00176 inline friend bool operator==(const VectorN &v1, const VectorN &v2) { return NearEqual(v1,v2); }
00177 inline friend bool operator==(const VectorN &v, const float &c) { return NearEqual(v,c); }
00178
00179 inline friend bool operator!=(const VectorN &v1, const VectorN &v2) { return !NearEqual(v1,v2); }
00180 inline friend bool operator!=(const VectorN &v, const float &c) { return !NearEqual(v,c); }
00181
00182
00183 inline float LengthSquared() const { return VecDot(*this,*this); }
00184 inline float Length() const { return std::sqrt(LengthSquared()); }
00185 inline VectorN Normal() const { return VecNormal(*this); }
00186 inline void Normalize() { VecNormalize(*this); }
00187 inline float Dot(const VectorN &o) const { return VecDot(*this,o); }
00188 inline float AngleBetween(const VectorN &o) const { return VecAngleBetween(*this,o); }
00189 inline void Transform(const MatrixType &m) const { *this=TransformVector(m,*this); }
00190
00191
00192 operator const std::string() const;
00193 };
00194
00195 template <uint elemCount>
00196 VectorN<elemCount>::operator const std::string() const
00197 {
00198 std::string s="(";
00199
00200 for (uint i=0; i<ElementCount(); ++i)
00201 {
00202 s+=MPMA::Vary(elements[i]);
00203 if (i!=ElementCount()-1) s+=", ";
00204 }
00205
00206 s+=")";
00207 return s;
00208 }
00209
00210
00211
00212
00214 template <uint rowCount>
00215 struct MatrixN
00216 {
00217 typedef VectorN<rowCount> VectorType;
00218 typedef VectorN<rowCount-1> LesserVectorType;
00219
00220 union
00221 {
00222 float elements[rowCount*rowCount];
00223 float rowcol[rowCount][rowCount];
00224 };
00225 inline uint RowColCount() const { return rowCount; }
00226 inline uint ElementCount() const { return rowCount*rowCount; }
00227
00228
00229 inline MatrixN() {}
00230 inline MatrixN(const float *array) { AssignFromArray(*this,array); }
00231 inline MatrixN(float c) { AssignFromValue(*this,c); }
00232
00233
00234 template <typename T, typename TRet>
00235 class Proxy
00236 {
00237 public:
00238 inline Proxy(T &mat, int ind): mat(mat), ind(ind) {}
00239 inline operator TRet&() { return mat.elements[ind]; }
00240 inline TRet& operator[](uint offset) { return mat.rowcol[ind][offset]; }
00241 void operator=(const float val) {mat.elements[ind]=val;}
00242
00243 private:
00244 T &mat;
00245 int ind;
00246 };
00247
00248
00249 inline Proxy<MatrixN, float> operator[](uint ind) { return Proxy<MatrixN, float>(*this,ind); }
00250 inline Proxy<const MatrixN, const float> operator[](uint ind) const { return Proxy<const MatrixN, const float>(*this,ind); }
00251
00252 inline float m(int row, int col) const { return rowcol[row][col]; }
00253 inline float& m(int row, int col) { return rowcol[row][col]; }
00254
00255
00256 inline friend bool operator==(const MatrixN &m1, const MatrixN &m2) { return NearEqual(m1,m2); }
00257 inline friend bool operator!=(const MatrixN &m1, const MatrixN &m2) { return !NearEqual(m1,m2); }
00258
00259
00260 inline VectorType& Row(uint r) { return *(VectorType*)rowcol[r]; }
00261 inline const VectorType& Row(uint r) const { return *(const VectorType*)rowcol[r]; }
00262 inline const VectorType GetColumn(uint col) const;
00263 inline void SetColumn(uint col, const VectorType &vec);
00264 inline void SetColumn(uint col, const LesserVectorType &vec);
00265
00266
00267 inline MatrixN operator*(const float &o) const { return Scale<MatrixN>(*this,o); }
00268 inline MatrixN operator*(const int &o) const { return Scale<MatrixN>(*this,(float)o); }
00269 friend inline MatrixN operator*(const float &o, const MatrixN &me) { return Scale(me,o); }
00270 inline MatrixN operator/(const float &o) const { return Scale<MatrixN>(*this,1/o); }
00271 inline MatrixN operator/(const int &o) const { return Scale<MatrixN>(*this,1.0f/o); }
00272 inline MatrixN operator+(const MatrixN &o) const { return Add(*this,o); }
00273 inline MatrixN operator+(const float &o) const { return Add(*this,MatrixN(o)); }
00274 inline MatrixN operator-(const MatrixN &o) const { return Sub(*this,o); }
00275 inline MatrixN operator-(const float &o) const { return Sub(*this,MatrixN(o)); }
00276
00277 inline MatrixN operator-() const { return Neg(*this); }
00278
00279
00280 inline void operator*=(const float &o) { ScaleSelf<MatrixN>(*this,o); }
00281 inline void operator/=(const float &o) { ScaleSelf<MatrixN>(*this,1/o); }
00282 inline void operator+=(const MatrixN &o) { AddSelf(*this,o); }
00283 inline void operator+=(const float &o) { AddSelf(*this,MatrixN(o)); }
00284 inline void operator-=(const MatrixN &o) { SubSelf(*this,o); }
00285 inline void operator-=(const float &o) { SubSelf(*this,MatrixN(o)); }
00286
00287
00288 inline MatrixN operator*(const MatrixN &o) const { return MatMul(*this,o); }
00289 inline void operator*=(const MatrixN &o) { *this=MatMul(*this,o); }
00290 inline VectorType operator*(const VectorType &v) const { return TransformVector(*this,v); }
00291
00292
00293 inline MatrixN Transpose() const;
00294 inline void SetTranspose();
00295 inline void MakeIdentity();
00296 inline LesserVectorType GetTranslation() const { return LesserVectorType(GetColumn(RowColCount()-1)); }
00297 inline void SetTranslation(const LesserVectorType &v) { SetColumn(RowColCount()-1,v); }
00298
00299
00300 operator const std::string() const;
00301 };
00302
00303 template <uint rowCount>
00304 inline const typename MatrixN<rowCount>::VectorType MatrixN<rowCount>::GetColumn(uint col) const
00305 {
00306 VectorType vec;
00307 for (uint i=0; i<RowColCount(); ++i)
00308 vec[i]=rowcol[i][col];
00309 return vec;
00310 }
00311
00312 template <uint rowCount>
00313 inline void MatrixN<rowCount>::SetColumn(uint col, const VectorType &vec)
00314 {
00315 for (uint i=0; i<RowColCount(); ++i)
00316 rowcol[i][col]=vec[i];
00317 }
00318
00319 template <uint rowCount>
00320 inline void MatrixN<rowCount>::SetColumn(uint col, const LesserVectorType &vec)
00321 {
00322 for (uint i=0; i<vec.ElementCount(); ++i)
00323 rowcol[i][col]=vec[i];
00324 }
00325
00326 template <uint rowCount>
00327 MatrixN<rowCount> MatrixN<rowCount>::Transpose() const
00328 {
00329 return MatTranspose(*this);
00330 }
00331
00332 template <uint rowCount>
00333 void MatrixN<rowCount>::SetTranspose()
00334 {
00335
00336 for (uint r=1; r<RowColCount(); ++r)
00337 {
00338 for (uint c=0; c<r; ++c)
00339 {
00340 float tmp=rowcol[r][c];
00341 rowcol[r][c]=rowcol[c][r];
00342 rowcol[c][r]=tmp;
00343 }
00344 }
00345 }
00346
00347 template <uint rowCount>
00348 inline void MatrixN<rowCount>::MakeIdentity()
00349 {
00350 for (uint x=0; x<RowColCount(); ++x)
00351 for (uint y=0; y<RowColCount(); ++y)
00352 rowcol[x][y]=0;
00353
00354 for (uint i=0; i<RowColCount(); ++i)
00355 rowcol[i][i]=1;
00356 }
00357
00358 template <uint rowCount>
00359 MatrixN<rowCount>::operator const std::string() const
00360 {
00361 std::string s="[";
00362 for (uint i=0; i<RowColCount(); ++i)
00363 {
00364 s+=Row(i);
00365 if (i!=RowColCount()-1) s+=", ";
00366 }
00367
00368 s+="]";
00369 return s;
00370 }
00371
00372 }