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