MPMA Framework 0.4
|
00001 00002 //Luke Lenhart, 2007 00003 //See /docs/License.txt for details on how this code may be used. 00004 00005 //This file is only meant to be included by Geo.h. 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 // -- helpers shared between VectorN and MatrixN 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; //predef 00133 00134 00135 // -- VectorN 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 //ctors 00148 inline VectorN() {} 00149 inline VectorN(const float *array) { AssignFromArray(*this,array); } 00150 inline VectorN(float c) { AssignFromValue(*this,c); } 00151 00152 //access operators 00153 inline float& operator[](nuint index) { return elements[index]; } 00154 inline const float& operator[](nuint index) const { return elements[index]; } 00155 00156 //binary non-altering operators 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 //binary self modifying operators 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 //unary operators 00178 inline VectorN operator-() const { return Neg(*this); } 00179 00180 //comparison 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 //other functions 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 //human readable conversion 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 // -- MatrixN 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 //ctors 00234 inline MatrixN() {} 00235 inline MatrixN(const float *array) { AssignFromArray(*this,array); } 00236 inline MatrixN(float c) { AssignFromValue(*this,c); } 00237 00238 //proxy access class, to allow for both 1d and 2d array notation to work 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); //disable 00252 }; 00253 00254 //access operators 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 //equality operators 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 //access a row(direct) or column(copied out) in the matrix as a vector 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 //binary non-altering operators 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 //binary self-modifying operators 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 //other operators 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 //other operations 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 //human readable conversion 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 //swap the rows and cols, leaving the diagonal alone 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 } //namespace GEO 00379 00380 #endif //#ifdef MPMA_COMPILE_GEO