00001 #ifndef __MATH_MAT44_H__
00002 #define __MATH_MAT44_H__
00003
00004 #include <cstdlib>
00005
00006 #include <math/config.hpp>
00007 #include <math/vecbase.hpp>
00008
00009 namespace math {
00010 template <typename T> class mat44: public math::matsqu<T,4> {
00011 public:
00012 mat44() { matsqu<T,4>::loadIdentity(); }
00013 mat44(T e0, T e1, T e2, T e3, T e4, T e5, T e6, T e7, T e8, T e9, T e10, T e11, T e12, T e13, T e14, T e15) {
00014 matbase<T,4,4>::v(0,0) = e0;
00015 matbase<T,4,4>::v(0,1) = e1;
00016 matbase<T,4,4>::v(0,2) = e2;
00017 matbase<T,4,4>::v(0,3) = e3;
00018 matbase<T,4,4>::v(1,0) = e4;
00019 matbase<T,4,4>::v(1,1) = e5;
00020 matbase<T,4,4>::v(1,2) = e6;
00021 matbase<T,4,4>::v(1,3) = e7;
00022 matbase<T,4,4>::v(2,0) = e8;
00023 matbase<T,4,4>::v(2,1) = e9;
00024 matbase<T,4,4>::v(2,2) = e10;
00025 matbase<T,4,4>::v(2,3) = e11;
00026 matbase<T,4,4>::v(3,0) = e12;
00027 matbase<T,4,4>::v(3,1) = e13;
00028 matbase<T,4,4>::v(3,2) = e14;
00029 matbase<T,4,4>::v(3,3) = e15;
00030 }
00031 mat44(const mat44<T> & rhs): matbase<T,4,4>(rhs) {}
00032 mat44(const T * rhs): matbase<T,4,4>(rhs) {}
00033 mat44(const math::quat<T> & q) {
00034 const T x = q.x;
00035 const T y = q.y;
00036 const T z = q.z;
00037 const T w = q.w;
00038
00039 const T x2 = x + x;
00040 const T y2 = y + y;
00041 const T z2 = z + z;
00042
00043 const T xx = x2*x;
00044 const T yy = y2*y;
00045 const T zz = z2*z;
00046
00047 const T xy = x2*y;
00048 const T xz = x2*z;
00049 const T xw = x2*w;
00050
00051 const T yz = y2*z;
00052 const T yw = y2*w;
00053 const T zw = z2*w;
00054
00055 matbase<T,4,4>::v(0,0) = 1.0f - yy - zz;
00056 matbase<T,4,4>::v(0,1) = xy + zw;
00057 matbase<T,4,4>::v(0,2) = xz - yw;
00058 matbase<T,4,4>::v(0,3) = 0.0f;
00059 matbase<T,4,4>::v(1,0) = xy - zw;
00060 matbase<T,4,4>::v(1,1) = 1.0f - xx - zz;
00061 matbase<T,4,4>::v(1,2) = yz + xw;
00062 matbase<T,4,4>::v(1,3) = 0.0f;
00063 matbase<T,4,4>::v(2,0) = xz + yw;
00064 matbase<T,4,4>::v(2,1) = yz - xw;
00065 matbase<T,4,4>::v(2,2) = 1.0f - xx - yy;
00066 matbase<T,4,4>::v(2,3) = 0.0f;
00067 matbase<T,4,4>::v(3,0) = 0.0f;
00068 matbase<T,4,4>::v(3,1) = 0.0f;
00069 matbase<T,4,4>::v(3,2) = 0.0f;
00070 matbase<T,4,4>::v(3,3) = 1.0f;
00071 }
00072 mat44(math::transform<T> const & t)
00073 {
00074 matsqu<T,4>::loadIdentity();
00075
00076 set_rotation(t.q);
00077 SetTranslationPart(t.p);
00078 }
00079 T& v(int r, int c) {
00080 return matbase<T,4,4>::v(r,c);
00081 }
00082 void set_rotation(math::quat<T> const & q)
00083 {
00084 const T x = q.x;
00085 const T y = q.y;
00086 const T z = q.z;
00087 const T w = q.w;
00088
00089 const T x2 = x + x;
00090 const T y2 = y + y;
00091 const T z2 = z + z;
00092
00093 const T xx = x2*x;
00094 const T yy = y2*y;
00095 const T zz = z2*z;
00096
00097 const T xy = x2*y;
00098 const T xz = x2*z;
00099 const T xw = x2*w;
00100
00101 const T yz = y2*z;
00102 const T yw = y2*w;
00103 const T zw = z2*w;
00104
00105 matbase<T,4,4>::v(0,0) = 1.0f - yy - zz;
00106 matbase<T,4,4>::v(0,1) = xy + zw;
00107 matbase<T,4,4>::v(0,2) = xz - yw;
00108
00109 matbase<T,4,4>::v(1,0) = xy - zw;
00110 matbase<T,4,4>::v(1,1) = 1.0f - xx - zz;
00111 matbase<T,4,4>::v(1,2) = yz + xw;
00112
00113 matbase<T,4,4>::v(2,0) = xz + yw;
00114 matbase<T,4,4>::v(2,1) = yz - xw;
00115 matbase<T,4,4>::v(2,2) = 1.0f - xx - yy;
00116 }
00117 math::vec4<T> getRow(int r) const {
00118 return math::vec4<T>(matbase<T,4,4>::getRow(r));
00119 }
00120 math::vec4<T> getColumn(int c) const {
00121 return math::vec4<T>(matbase<T,4,4>::getColumn(c));
00122 }
00123 mat44<T> operator+(const mat44<T> & rhs) const {
00124 return matbase<T,4,4>::operator+(rhs);
00125 }
00126 mat44<T> operator-(const mat44<T> & rhs) const {
00127 return matbase<T,4,4>::operator-(rhs);
00128 }
00129 mat44<T> operator*(const mat44<T> & rhs) const {
00130
00131
00132 if(matbase<T,4,4>::v(0,3)==0.0f && matbase<T,4,4>::v(1,3)==0.0f && matbase<T,4,4>::v(2,3)==0.0f && matbase<T,4,4>::v(3,3)==1.0f &&
00133 rhs.matbase<T,4,4>::v(0,3)==0.0f && rhs.matbase<T,4,4>::v(1,3)==0.0f &&
00134 rhs.matbase<T,4,4>::v(2,3)==0.0f && rhs.matbase<T,4,4>::v(3,3)==1.0f)
00135 {
00136 return math::mat44<T>(
00137 v(0,0)*rhs.v(0,0)+v(1,0)*rhs.v(0,1)+v(2,0)*rhs.v(0,2),
00138 v(0,1)*rhs.v(0,0)+v(1,1)*rhs.v(0,1)+v(2,1)*rhs.v(0,2),
00139 v(0,2)*rhs.v(0,0)+v(1,2)*rhs.v(0,1)+v(2,2)*rhs.v(0,2),
00140 0.0f,
00141 v(0,0)*rhs.v(1,0)+v(1,0)*rhs.v(1,1)+v(2,0)*rhs.v(1,2),
00142 v(0,1)*rhs.v(1,0)+v(1,1)*rhs.v(1,1)+v(2,1)*rhs.v(1,2),
00143 v(0,2)*rhs.v(1,0)+v(1,2)*rhs.v(1,1)+v(2,2)*rhs.v(1,2),
00144 0.0f,
00145 v(0,0)*rhs.v(2,0)+v(1,0)*rhs.v(2,1)+v(2,0)*rhs.v(2,2),
00146 v(0,1)*rhs.v(2,0)+v(1,1)*rhs.v(2,1)+v(2,1)*rhs.v(2,2),
00147 v(0,2)*rhs.v(2,0)+v(1,2)*rhs.v(2,1)+v(2,2)*rhs.v(2,2),
00148 0.0f,
00149 v(0,0)*rhs.v(3,0)+v(1,0)*rhs.v(3,1)+v(2,0)*rhs.v(3,2)+v(3,0),
00150 v(0,1)*rhs.v(3,0)+v(1,1)*rhs.v(3,1)+v(2,1)*rhs.v(3,2)+v(3,1),
00151 v(0,2)*rhs.v(3,0)+v(1,2)*rhs.v(3,1)+v(2,2)*rhs.v(3,2)+v(3,2),
00152 1.0f);
00153 }
00154
00155
00156 if( matbase<T,4,4>::v(0,3)==0.0f && matbase<T,4,4>::v(1,3)==0.0f && matbase<T,4,4>::v(2,3)==0.0f && matbase<T,4,4>::v(3,3)==1.0f)
00157 {
00158 return math::mat44<T>(
00159 v(0,0)*rhs.v(0,0)+v(1,0)*rhs.v(0,1)+v(2,0)*rhs.v(0,2)+v(3,0)*rhs.v(0,3),
00160 v(0,1)*rhs.v(0,0)+v(1,1)*rhs.v(0,1)+v(2,1)*rhs.v(0,2)+v(3,1)*rhs.v(0,3),
00161 v(0,2)*rhs.v(0,0)+v(1,2)*rhs.v(0,1)+v(2,2)*rhs.v(0,2)+v(3,2)*rhs.v(0,3),
00162 rhs.v(0,3),
00163 v(0,0)*rhs.v(1,0)+v(1,0)*rhs.v(1,1)+v(2,0)*rhs.v(1,2)+v(3,0)*rhs.v(1,3),
00164 v(0,1)*rhs.v(1,0)+v(1,1)*rhs.v(1,1)+v(2,1)*rhs.v(1,2)+v(3,1)*rhs.v(1,3),
00165 v(0,2)*rhs.v(1,0)+v(1,2)*rhs.v(1,1)+v(2,2)*rhs.v(1,2)+v(3,2)*rhs.v(1,3),
00166 rhs.v(1,3),
00167 v(0,0)*rhs.v(2,0)+v(1,0)*rhs.v(2,1)+v(2,0)*rhs.v(2,2)+v(3,0)*rhs.v(2,3),
00168 v(0,1)*rhs.v(2,0)+v(1,1)*rhs.v(2,1)+v(2,1)*rhs.v(2,2)+v(3,1)*rhs.v(2,3),
00169 v(0,2)*rhs.v(2,0)+v(1,2)*rhs.v(2,1)+v(2,2)*rhs.v(2,2)+v(3,2)*rhs.v(2,3),
00170 rhs.v(2,3),
00171 v(0,0)*rhs.v(3,0)+v(1,0)*rhs.v(3,1)+v(2,0)*rhs.v(3,2)+v(3,0)*rhs.v(3,3),
00172 v(0,1)*rhs.v(3,0)+v(1,1)*rhs.v(3,1)+v(2,1)*rhs.v(3,2)+v(3,1)*rhs.v(3,3),
00173 v(0,2)*rhs.v(3,0)+v(1,2)*rhs.v(3,1)+v(2,2)*rhs.v(3,2)+v(3,2)*rhs.v(3,3),
00174 rhs.v(3,3));
00175 }
00176
00177
00178 if(rhs.v(0,3)==0.0f && rhs.v(1,3)==0.0f && rhs.v(2,3)==0.0f && rhs.v(3,3)==1.0f) {
00179 return math::mat44<T>(
00180 v(0,0)*rhs.v(0,0)+v(1,0)*rhs.v(0,1)+v(2,0)*rhs.v(0,2),
00181 v(0,1)*rhs.v(0,0)+v(1,1)*rhs.v(0,1)+v(2,1)*rhs.v(0,2),
00182 v(0,2)*rhs.v(0,0)+v(1,2)*rhs.v(0,1)+v(2,2)*rhs.v(0,2),
00183 v(0,3)*rhs.v(0,0)+v(1,3)*rhs.v(0,1)+v(2,3)*rhs.v(0,2),
00184 v(0,0)*rhs.v(1,0)+v(1,0)*rhs.v(1,1)+v(2,0)*rhs.v(1,2),
00185 v(0,1)*rhs.v(1,0)+v(1,1)*rhs.v(1,1)+v(2,1)*rhs.v(1,2),
00186 v(0,2)*rhs.v(1,0)+v(1,2)*rhs.v(1,1)+v(2,2)*rhs.v(1,2),
00187 v(0,3)*rhs.v(1,0)+v(1,3)*rhs.v(1,1)+v(2,3)*rhs.v(1,2),
00188 v(0,0)*rhs.v(2,0)+v(1,0)*rhs.v(2,1)+v(2,0)*rhs.v(2,2),
00189 v(0,1)*rhs.v(2,0)+v(1,1)*rhs.v(2,1)+v(2,1)*rhs.v(2,2),
00190 v(0,2)*rhs.v(2,0)+v(1,2)*rhs.v(2,1)+v(2,2)*rhs.v(2,2),
00191 v(0,3)*rhs.v(2,0)+v(1,3)*rhs.v(2,1)+v(2,3)*rhs.v(2,2),
00192 v(0,0)*rhs.v(3,0)+v(1,0)*rhs.v(3,1)+v(2,0)*rhs.v(3,2)+v(3,0),
00193 v(0,1)*rhs.v(3,0)+v(1,1)*rhs.v(3,1)+v(2,1)*rhs.v(3,2)+v(3,1),
00194 v(0,2)*rhs.v(3,0)+v(1,2)*rhs.v(3,1)+v(2,2)*rhs.v(3,2)+v(3,2),
00195 v(0,3)*rhs.v(3,0)+v(1,3)*rhs.v(3,1)+v(2,3)*rhs.v(3,2)+v(3,3));
00196 }
00197
00198 return math::mat44<T>(
00199 v(0,0)*rhs.v(0,0)+v(1,0)*rhs.v(0,1)+v(2,0)*rhs.v(0,2)+v(3,0)*rhs.v(0,3),
00200 v(0,1)*rhs.v(0,0)+v(1,1)*rhs.v(0,1)+v(2,1)*rhs.v(0,2)+v(3,1)*rhs.v(0,3),
00201 v(0,2)*rhs.v(0,0)+v(1,2)*rhs.v(0,1)+v(2,2)*rhs.v(0,2)+v(3,2)*rhs.v(0,3),
00202 v(0,3)*rhs.v(0,0)+v(1,3)*rhs.v(0,1)+v(2,3)*rhs.v(0,2)+v(3,3)*rhs.v(0,3),
00203 v(0,0)*rhs.v(1,0)+v(1,0)*rhs.v(1,1)+v(2,0)*rhs.v(1,2)+v(3,0)*rhs.v(1,3),
00204 v(0,1)*rhs.v(1,0)+v(1,1)*rhs.v(1,1)+v(2,1)*rhs.v(1,2)+v(3,1)*rhs.v(1,3),
00205 v(0,2)*rhs.v(1,0)+v(1,2)*rhs.v(1,1)+v(2,2)*rhs.v(1,2)+v(3,2)*rhs.v(1,3),
00206 v(0,3)*rhs.v(1,0)+v(1,3)*rhs.v(1,1)+v(2,3)*rhs.v(1,2)+v(3,3)*rhs.v(1,3),
00207 v(0,0)*rhs.v(2,0)+v(1,0)*rhs.v(2,1)+v(2,0)*rhs.v(2,2)+v(3,0)*rhs.v(2,3),
00208 v(0,1)*rhs.v(2,0)+v(1,1)*rhs.v(2,1)+v(2,1)*rhs.v(2,2)+v(3,1)*rhs.v(2,3),
00209 v(0,2)*rhs.v(2,0)+v(1,2)*rhs.v(2,1)+v(2,2)*rhs.v(2,2)+v(3,2)*rhs.v(2,3),
00210 v(0,3)*rhs.v(2,0)+v(1,3)*rhs.v(2,1)+v(2,3)*rhs.v(2,2)+v(3,3)*rhs.v(2,3),
00211 v(0,0)*rhs.v(3,0)+v(1,0)*rhs.v(3,1)+v(2,0)*rhs.v(3,2)+v(3,0)*rhs.v(3,3),
00212 v(0,1)*rhs.v(3,0)+v(1,1)*rhs.v(3,1)+v(2,1)*rhs.v(3,2)+v(3,1)*rhs.v(3,3),
00213 v(0,2)*rhs.v(3,0)+v(1,2)*rhs.v(3,1)+v(2,2)*rhs.v(3,2)+v(3,2)*rhs.v(3,3),
00214 v(0,3)*rhs.v(3,0)+v(1,3)*rhs.v(3,1)+v(2,3)*rhs.v(3,2)+v(3,3)*rhs.v(3,3));
00215 }
00216 mat44<T> operator*(const T rhs) const {
00217 return matbase<T,4,4>::operator*(rhs);
00218 }
00219 mat44<T> operator/(const T rhs) const
00220 {
00221 if (rhs==0.0f || rhs==1.0f)
00222 return (*this);
00223
00224 T temp=1/rhs;
00225
00226 return (*this)*temp;
00227 }
00228 bool operator==(const mat44<T> & rhs) const {
00229 return vecbase<T,16>::operator==(rhs);
00230 }
00231 bool operator!=(const mat44<T> & rhs) const {
00232 return vecbase<T,16>::operator==(rhs);
00233 }
00234 void operator+=(const mat44<T> & rhs) {
00235 (*this)=(*this)+rhs;
00236 }
00237 void operator-=(const mat44<T> & rhs) {
00238 (*this)=(*this)-rhs;
00239 }
00240 void operator*=(const mat44<T> & rhs) {
00241 (*this)=(*this)*rhs;
00242 }
00243 void operator*=(const T rhs) {
00244 (*this)=(*this)*rhs;
00245 }
00246 void operator/=(const T rhs) {
00247 (*this)=(*this)/rhs;
00248 }
00249 mat44<T> operator-() const {
00250 return vecbase<T,16>::operator-();
00251 }
00252 math::vec4<T> operator*(const vec4<T> rhs) const
00253 {
00254
00255 if(v(0,3)==0.0f && v(1,3)==0.0f && v(2,3)==0.0f && v(3,3)==1.0f)
00256 {
00257 return vec4<T>(
00258 v(0,0)*rhs.x + v(1,0)*rhs.y + v(2,0)*rhs.z + v(3,0)*rhs.w,
00259 v(0,1)*rhs.x + v(1,1)*rhs.y + v(2,1)*rhs.z + v(3,1)*rhs.w,
00260 v(0,2)*rhs.x + v(1,2)*rhs.y + v(2,2)*rhs.z + v(3,2)*rhs.w,
00261 rhs.w);
00262 }
00263 return matbase<T,4,4>::operator*(rhs);
00264 return vec4<T>(
00265 v(0,0) * rhs.x + v(1,0) * rhs.y + v(2,0) * rhs.z + v(3,0) * rhs.w,
00266 v(0,1) * rhs.x + v(1,1) * rhs.y + v(2,1) * rhs.z + v(3,1) * rhs.w,
00267 v(0,2) * rhs.x + v(1,2) * rhs.y + v(2,2) * rhs.z + v(3,2) * rhs.w,
00268 v(0,3) * rhs.x + v(1,3) * rhs.y + v(2,3) * rhs.z + v(3,3) * rhs.w);
00269
00270 }
00271 math::vec3<T> GetRotatedVector3D(const vec3<T> & rhs) const {
00272 return vec3<T>(
00273 matbase<T,4,4>::v(0,0)*rhs.v[0] + matbase<T,4,4>::v(1,0)*rhs.v[1] + matbase<T,4,4>::v(2,0) *rhs.v[2],
00274 matbase<T,4,4>::v(0,1)*rhs.v[0] + matbase<T,4,4>::v(1,1)*rhs.v[1] + matbase<T,4,4>::v(2,1) *rhs.v[2],
00275 matbase<T,4,4>::v(0,2)*rhs.v[0] + matbase<T,4,4>::v(1,2)*rhs.v[1] + matbase<T,4,4>::v(2,2)*rhs.v[2]);
00276 }
00277 math::vec3<T> GetInverseRotatedVector3D(const vec3<T> & rhs) const
00278 {
00279
00280 return vec3<T>(
00281 matbase<T,4,4>::v(0,0)*rhs.v[0] + matbase<T,4,4>::v(0,1)*rhs.v[1] + matbase<T,4,4>::v(0,2) *rhs.v[2],
00282 matbase<T,4,4>::v(1,0)*rhs.v[0] + matbase<T,4,4>::v(1,1)*rhs.v[1] + matbase<T,4,4>::v(1,2) *rhs.v[2],
00283 matbase<T,4,4>::v(2,0)*rhs.v[0] + matbase<T,4,4>::v(2,1)*rhs.v[1] + matbase<T,4,4>::v(2,2)*rhs.v[2]);
00284 }
00285 math::vec3<T> GetTranslatedVector3D(const vec3<T> & rhs) const {
00286
00287 return vec3<T>(rhs.v[0]+matbase<T,4,4>::v(3,0), rhs.v[1]+matbase<T,4,4>::v(3,1), rhs.v[2]+matbase<T,4,4>::v(3,2));
00288 }
00289 math::vec3<T> GetInverseTranslatedVector3D(const vec3<T> & rhs) const
00290 {
00291 return vec3<T>(rhs.v[0]-matbase<T,4,4>::v(3,0), rhs.v[1]-matbase<T,4,4>::v(3,1), rhs.v[2]-matbase<T,4,4>::v(3,2));
00292 }
00293 void Invert(void) {
00294 *this = getInverse();
00295 }
00296 mat44<T> getInverse(void) const {
00297 mat44<T> result = getInverseTranspose();
00298
00299 result.Transpose();
00300
00301 return result;
00302 }
00303 void Transpose(void)
00304 {
00305 *this = getTranspose();
00306 }
00307 mat44<T> getTranspose() const {
00308 return math::mat44<T>(
00309 matbase<T,4,4>::v(0,0), matbase<T,4,4>::v(1,0), matbase<T,4,4>::v(2,0), matbase<T,4,4>::v(3,0),
00310 matbase<T,4,4>::v(0,1), matbase<T,4,4>::v(1,1), matbase<T,4,4>::v(2,1), matbase<T,4,4>::v(3,1),
00311 matbase<T,4,4>::v(0,2), matbase<T,4,4>::v(1,2), matbase<T,4,4>::v(2,2), matbase<T,4,4>::v(3,2),
00312 matbase<T,4,4>::v(0,3), matbase<T,4,4>::v(1,3), matbase<T,4,4>::v(2,3), matbase<T,4,4>::v(3,3));
00313 }
00314 void invertTranspose() {
00315 *this = getInverseTranspose();
00316 }
00317 mat44<T> getInverseTranspose() const {
00318 mat44<T> result;
00319
00320 T tmp[12];
00321 T det;
00322
00323
00324 tmp[0] = matbase<T,4,4>::v(2,2) * matbase<T,4,4>::v(3,3);
00325 tmp[1] = matbase<T,4,4>::v(2,3) * matbase<T,4,4>::v(3,2);
00326 tmp[2] = matbase<T,4,4>::v(2,1) * matbase<T,4,4>::v(3,3);
00327 tmp[3] = matbase<T,4,4>::v(2,3) * matbase<T,4,4>::v(3,1);
00328 tmp[4] = matbase<T,4,4>::v(2,1) * matbase<T,4,4>::v(3,2);
00329 tmp[5] = matbase<T,4,4>::v(2,2) * matbase<T,4,4>::v(3,1);
00330 tmp[6] = matbase<T,4,4>::v(2,0) * matbase<T,4,4>::v(3,3);
00331 tmp[7] = matbase<T,4,4>::v(2,3) * matbase<T,4,4>::v(3,0);
00332 tmp[8] = matbase<T,4,4>::v(2,0) * matbase<T,4,4>::v(3,2);
00333 tmp[9] = matbase<T,4,4>::v(2,2) * matbase<T,4,4>::v(3,0);
00334 tmp[10] = matbase<T,4,4>::v(2,0) * matbase<T,4,4>::v(3,1);
00335 tmp[11] = matbase<T,4,4>::v(2,1) * matbase<T,4,4>::v(3,0);
00336
00337
00338 result.SetEntry(0, tmp[0]*matbase<T,4,4>::v(1,1) + tmp[3]*matbase<T,4,4>::v(1,2) + tmp[4]*matbase<T,4,4>::v(1,3)
00339 - tmp[1]*matbase<T,4,4>::v(1,1) - tmp[2]*matbase<T,4,4>::v(1,2) - tmp[5]*matbase<T,4,4>::v(1,3));
00340
00341 result.SetEntry(1, tmp[1]*matbase<T,4,4>::v(1,0) + tmp[6]*matbase<T,4,4>::v(1,2) + tmp[9]*matbase<T,4,4>::v(1,3)
00342 - tmp[0]*matbase<T,4,4>::v(1,0) - tmp[7]*matbase<T,4,4>::v(1,2) - tmp[8]*matbase<T,4,4>::v(1,3));
00343
00344 result.SetEntry(2, tmp[2]*matbase<T,4,4>::v(1,0) + tmp[7]*matbase<T,4,4>::v(1,1) + tmp[10]*matbase<T,4,4>::v(1,3)
00345 - tmp[3]*matbase<T,4,4>::v(1,0) - tmp[6]*matbase<T,4,4>::v(1,1) - tmp[11]*matbase<T,4,4>::v(1,3));
00346
00347 result.SetEntry(3, tmp[5]*matbase<T,4,4>::v(1,0) + tmp[8]*matbase<T,4,4>::v(1,1) + tmp[11]*matbase<T,4,4>::v(1,2)
00348 - tmp[4]*matbase<T,4,4>::v(1,0) - tmp[9]*matbase<T,4,4>::v(1,1) - tmp[10]*matbase<T,4,4>::v(1,2));
00349
00350 result.SetEntry(4, tmp[1]*matbase<T,4,4>::v(0,1) + tmp[2]*matbase<T,4,4>::v(0,2) + tmp[5]*matbase<T,4,4>::v(0,3)
00351 - tmp[0]*matbase<T,4,4>::v(0,1) - tmp[3]*matbase<T,4,4>::v(0,2) - tmp[4]*matbase<T,4,4>::v(0,3));
00352
00353 result.SetEntry(5, tmp[0]*matbase<T,4,4>::v(0,0) + tmp[7]*matbase<T,4,4>::v(0,2) + tmp[8]*matbase<T,4,4>::v(0,3)
00354 - tmp[1]*matbase<T,4,4>::v(0,0) - tmp[6]*matbase<T,4,4>::v(0,2) - tmp[9]*matbase<T,4,4>::v(0,3));
00355
00356 result.SetEntry(6, tmp[3]*matbase<T,4,4>::v(0,0) + tmp[6]*matbase<T,4,4>::v(0,1) + tmp[11]*matbase<T,4,4>::v(0,3)
00357 - tmp[2]*matbase<T,4,4>::v(0,0) - tmp[7]*matbase<T,4,4>::v(0,1) - tmp[10]*matbase<T,4,4>::v(0,3));
00358
00359 result.SetEntry(7, tmp[4]*matbase<T,4,4>::v(0,0) + tmp[9]*matbase<T,4,4>::v(0,1) + tmp[10]*matbase<T,4,4>::v(0,2)
00360 - tmp[5]*matbase<T,4,4>::v(0,0) - tmp[8]*matbase<T,4,4>::v(0,1) - tmp[11]*matbase<T,4,4>::v(0,2));
00361
00362
00363 tmp[0] = matbase<T,4,4>::v(0,2)*matbase<T,4,4>::v(1,3);
00364 tmp[1] = matbase<T,4,4>::v(0,3)*matbase<T,4,4>::v(1,2);
00365 tmp[2] = matbase<T,4,4>::v(0,1)*matbase<T,4,4>::v(1,3);
00366 tmp[3] = matbase<T,4,4>::v(0,3)*matbase<T,4,4>::v(1,1);
00367 tmp[4] = matbase<T,4,4>::v(0,1)*matbase<T,4,4>::v(1,2);
00368 tmp[5] = matbase<T,4,4>::v(0,2)*matbase<T,4,4>::v(1,1);
00369 tmp[6] = matbase<T,4,4>::v(0,0)*matbase<T,4,4>::v(1,3);
00370 tmp[7] = matbase<T,4,4>::v(0,3)*matbase<T,4,4>::v(1,0);
00371 tmp[8] = matbase<T,4,4>::v(0,0)*matbase<T,4,4>::v(1,2);
00372 tmp[9] = matbase<T,4,4>::v(0,2)*matbase<T,4,4>::v(1,0);
00373 tmp[10] = matbase<T,4,4>::v(0,0)*matbase<T,4,4>::v(1,1);
00374 tmp[11] = matbase<T,4,4>::v(0,1)*matbase<T,4,4>::v(1,0);
00375
00376
00377 result.SetEntry(8, tmp[0]*matbase<T,4,4>::v(3,1) + tmp[3]*matbase<T,4,4>::v(3,2) + tmp[4]*matbase<T,4,4>::v(3,3)
00378 - tmp[1]*matbase<T,4,4>::v(3,1) - tmp[2]*matbase<T,4,4>::v(3,2) - tmp[5]*matbase<T,4,4>::v(3,3));
00379
00380 result.SetEntry(9, tmp[1]*matbase<T,4,4>::v(3,0) + tmp[6]*matbase<T,4,4>::v(3,2) + tmp[9]*matbase<T,4,4>::v(3,3)
00381 - tmp[0]*matbase<T,4,4>::v(3,0) - tmp[7]*matbase<T,4,4>::v(3,2) - tmp[8]*matbase<T,4,4>::v(3,3));
00382
00383 result.SetEntry(10, tmp[2]*matbase<T,4,4>::v(3,0) + tmp[7]*matbase<T,4,4>::v(3,1) + tmp[10]*matbase<T,4,4>::v(3,3)
00384 - tmp[3]*matbase<T,4,4>::v(3,0) - tmp[6]*matbase<T,4,4>::v(3,1) - tmp[11]*matbase<T,4,4>::v(3,3));
00385
00386 result.SetEntry(11, tmp[5]*matbase<T,4,4>::v(3,0) + tmp[8]*matbase<T,4,4>::v(3,1) + tmp[11]*matbase<T,4,4>::v(3,2)
00387 - tmp[4]*matbase<T,4,4>::v(3,0) - tmp[9]*matbase<T,4,4>::v(3,1) - tmp[10]*matbase<T,4,4>::v(3,2));
00388
00389 result.SetEntry(12, tmp[2]*matbase<T,4,4>::v(2,2) + tmp[5]*matbase<T,4,4>::v(2,3) + tmp[1]*matbase<T,4,4>::v(2,1)
00390 - tmp[4]*matbase<T,4,4>::v(2,3) - tmp[0]*matbase<T,4,4>::v(2,1) - tmp[3]*matbase<T,4,4>::v(2,2));
00391
00392 result.SetEntry(13, tmp[8]*matbase<T,4,4>::v(2,3) + tmp[0]*matbase<T,4,4>::v(2,0) + tmp[7]*matbase<T,4,4>::v(2,2)
00393 - tmp[6]*matbase<T,4,4>::v(2,2) - tmp[9]*matbase<T,4,4>::v(2,3) - tmp[1]*matbase<T,4,4>::v(2,0));
00394
00395 result.SetEntry(14, tmp[6]*matbase<T,4,4>::v(2,1) + tmp[11]*matbase<T,4,4>::v(2,3) + tmp[3]*matbase<T,4,4>::v(2,0)
00396 - tmp[10]*matbase<T,4,4>::v(2,3) - tmp[2]*matbase<T,4,4>::v(2,0) - tmp[7]*matbase<T,4,4>::v(2,1));
00397
00398 result.SetEntry(15, tmp[10]*matbase<T,4,4>::v(2,2) + tmp[4]*matbase<T,4,4>::v(2,0) + tmp[9]*matbase<T,4,4>::v(2,1)
00399 - tmp[8]*matbase<T,4,4>::v(2,1) - tmp[11]*matbase<T,4,4>::v(2,2) - tmp[5]*matbase<T,4,4>::v(2,0));
00400
00401
00402 det = matbase<T,4,4>::v(0,0)*result.GetEntry(0)
00403 +matbase<T,4,4>::v(0,1)*result.GetEntry(1)
00404 +matbase<T,4,4>::v(0,2)*result.GetEntry(2)
00405 +matbase<T,4,4>::v(0,3)*result.GetEntry(3);
00406
00407 if(det==0.0f)
00408 {
00409 mat44<T> id;
00410 return id;
00411 }
00412
00413 result=result/det;
00414
00415 return result;
00416 }
00417 void AffineInvert() {
00418 (*this) = getAffineInverse();
00419 }
00420 mat44<T> getAffineInverse() const {
00421
00422
00423 return math::mat44<T>(
00424 matbase<T,4,4>::v(0,0),matbase<T,4,4>::v(1,0),matbase<T,4,4>::v(2,0),0.0f,
00425 matbase<T,4,4>::v(0,1),matbase<T,4,4>::v(1,1),matbase<T,4,4>::v(2,1),0.0f,
00426 matbase<T,4,4>::v(0,2),matbase<T,4,4>::v(1,2),matbase<T,4,4>::v(2,2),0.0f,
00427 -(matbase<T,4,4>::v(0,0)*matbase<T,4,4>::v(3,0)+matbase<T,4,4>::v(0,1)*matbase<T,4,4>::v(3,1)+matbase<T,4,4>::v(0,2)*matbase<T,4,4>::v(3,2)),
00428 -(matbase<T,4,4>::v(1,0)*matbase<T,4,4>::v(3,0)+matbase<T,4,4>::v(1,1)*matbase<T,4,4>::v(3,1)+matbase<T,4,4>::v(1,2)*matbase<T,4,4>::v(3,2)),
00429 -(matbase<T,4,4>::v(2,0)*matbase<T,4,4>::v(3,0)+matbase<T,4,4>::v(2,1)*matbase<T,4,4>::v(3,1)+matbase<T,4,4>::v(2,2)*matbase<T,4,4>::v(3,2)),
00430 1.0f);
00431 }
00432 void affineInvertTranspose(void) {
00433 (*this)=getAffineInverseTranspose();
00434 }
00435 mat44<T> getAffineInverseTranspose(void) const
00436 {
00437
00438
00439
00440 return math::mat44<T>(
00441 matbase<T,4,4>::v(0,0),
00442 matbase<T,4,4>::v(0,1),
00443 matbase<T,4,4>::v(0,2),
00444 -(matbase<T,4,4>::v(0,0)*matbase<T,4,4>::v(3,0)+matbase<T,4,4>::v(0,1)*matbase<T,4,4>::v(3,1)+matbase<T,4,4>::v(0,2)*matbase<T,4,4>::v(3,2)),
00445 matbase<T,4,4>::v(1,0),
00446 matbase<T,4,4>::v(1,1),
00447 matbase<T,4,4>::v(1,2),
00448 -(matbase<T,4,4>::v(1,0)*matbase<T,4,4>::v(3,0)+matbase<T,4,4>::v(1,1)*matbase<T,4,4>::v(3,1)+matbase<T,4,4>::v(1,2)*matbase<T,4,4>::v(3,2)),
00449 matbase<T,4,4>::v(2,0),
00450 matbase<T,4,4>::v(2,1),
00451 matbase<T,4,4>::v(2,2),
00452 -(matbase<T,4,4>::v(2,0)*matbase<T,4,4>::v(3,0)+matbase<T,4,4>::v(2,1)*matbase<T,4,4>::v(3,1)+matbase<T,4,4>::v(2,2)*matbase<T,4,4>::v(3,2)),
00453 0.0f, 0.0f, 0.0f, 1.0f);
00454 }
00455 void SetTranslation(const vec3<T> & translation)
00456 {
00457 matsqu<T,4>::loadIdentity();
00458
00459 SetTranslationPart(translation);
00460 }
00461 void SetScale(const vec3<T> & scaleFactor)
00462 {
00463 matsqu<T,4>::loadIdentity();
00464
00465 matbase<T,4,4>::v(0,0)=scaleFactor.v[0];
00466 matbase<T,4,4>::v(1,1)=scaleFactor.v[1];
00467 matbase<T,4,4>::v(2,2)=scaleFactor.v[2];
00468 }
00469 void SetUniformScale(const T scaleFactor)
00470 {
00471 matsqu<T,4>::loadIdentity();
00472
00473 matbase<T,4,4>::v(0,0)=matbase<T,4,4>::v(1,1)=matbase<T,4,4>::v(2,2)=scaleFactor;
00474 }
00475 void SetRotationAxis(const T angle, const vec3<T> & axis)
00476 {
00477 vec3<T> u=axis.GetNormalized();
00478
00479 T sinAngle=(T)sin(M_PI*angle/180);
00480 T cosAngle=(T)cos(M_PI*angle/180);
00481 T oneMinusCosAngle=1.0f-cosAngle;
00482
00483 matsqu<T,4>::loadIdentity();
00484
00485 matbase<T,4,4>::v(0,0)=(u.v[0])*(u.v[0]) + cosAngle*(1-(u.v[0])*(u.v[0]));
00486 matbase<T,4,4>::v(1,0)=(u.v[0])*(u.v[1])*(oneMinusCosAngle) - sinAngle*u.v[2];
00487 matbase<T,4,4>::v(2,0)=(u.v[0])*(u.v[2])*(oneMinusCosAngle) + sinAngle*u.v[1];
00488
00489 matbase<T,4,4>::v(0,1)=(u.v[0])*(u.v[1])*(oneMinusCosAngle) + sinAngle*u.v[2];
00490 matbase<T,4,4>::v(1,1)=(u.v[1])*(u.v[1]) + cosAngle*(1-(u.v[1])*(u.v[1]));
00491 matbase<T,4,4>::v(2,1)=(u.v[1])*(u.v[2])*(oneMinusCosAngle) - sinAngle*u.v[0];
00492
00493 matbase<T,4,4>::v(0,2)=(u.v[0])*(u.v[2])*(oneMinusCosAngle) - sinAngle*u.v[1];
00494 matbase<T,4,4>::v(1,2)=(u.v[1])*(u.v[2])*(oneMinusCosAngle) + sinAngle*u.v[0];
00495 matbase<T,4,4>::v(2,2)=(u.v[2])*(u.v[2]) + cosAngle*(1-(u.v[2])*(u.v[2]));
00496 }
00497 void SetRotationX(const T angle)
00498 {
00499 matsqu<T,4>::loadIdentity();
00500
00501 matbase<T,4,4>::v(1,1)=(T)cos(M_PI*angle/180);
00502 matbase<T,4,4>::v(1,2)=(T)sin(M_PI*angle/180);
00503
00504 matbase<T,4,4>::v(2,1)=-matbase<T,4,4>::v(1,2);
00505 matbase<T,4,4>::v(2,2)=matbase<T,4,4>::v(1,1);
00506 }
00507 void SetRotationY(const T angle)
00508 {
00509 matsqu<T,4>::loadIdentity();
00510
00511 matbase<T,4,4>::v(0,0)=(T)cos(M_PI*angle/180);
00512 matbase<T,4,4>::v(0,2)=-(T)sin(M_PI*angle/180);
00513
00514 matbase<T,4,4>::v(2,0)=-matbase<T,4,4>::v(0,2);
00515 matbase<T,4,4>::v(2,2)=matbase<T,4,4>::v(0,0);
00516 }
00517 void SetRotationZ(const T angle)
00518 {
00519 matsqu<T,4>::loadIdentity();
00520
00521 matbase<T,4,4>::v(0,0)=(T)cos(M_PI*angle/180);
00522 matbase<T,4,4>::v(0,1)=(T)sin(M_PI*angle/180);
00523
00524 matbase<T,4,4>::v(1,0)=-matbase<T,4,4>::v(0,1);
00525 matbase<T,4,4>::v(1,1)=matbase<T,4,4>::v(0,0);
00526 }
00527 void SetRotationEuler(const T angleX, const T angleY, const T angleZ)
00528 {
00529 matsqu<T,4>::loadIdentity();
00530
00531 SetRotationPartEuler(angleX, angleY, angleZ);
00532 }
00533 void SetPerspective(T left, T right, T bottom, T top, T n, T f)
00534 {
00535 T nudge=0.999f;
00536
00537 matbase<T,4,4>::loadZero();
00538
00539
00540 if(left==right || top==bottom || n==f)
00541 {
00542 printf("invalid perspective");
00543 exit(0);
00544 }
00545 matbase<T,4,4>::v(0,0)=(2*n)/(right-left);
00546
00547 matbase<T,4,4>::v(1,1)=(2*n)/(top-bottom);
00548
00549 matbase<T,4,4>::v(2,0)=(right+left)/(right-left);
00550 matbase<T,4,4>::v(2,1)=(top+bottom)/(top-bottom);
00551
00552 if(f!=-1)
00553 {
00554 matbase<T,4,4>::v(2,2)=-(f+n)/(f-n);
00555 }
00556 else
00557 {
00558 matbase<T,4,4>::v(2,2)=-nudge;
00559 }
00560
00561 matbase<T,4,4>::v(2,3)=-1;
00562
00563 if(f!=-1)
00564 {
00565 matbase<T,4,4>::v(3,2)=-(2*f*n)/(f-n);
00566 }
00567 else
00568 {
00569 matbase<T,4,4>::v(3,2)=-2*n*nudge;
00570 }
00571 }
00572 void SetPerspective(T fovy, T aspect, T n, T f)
00573 {
00574 T left, right, top, bottom;
00575
00576
00577 fovy *= (T)M_PI / 180.0f;
00578
00579 top = n*tanf(fovy/2.0f);
00580 bottom=-top;
00581
00582 left=aspect*bottom;
00583 right=aspect*top;
00584
00585 SetPerspective(left, right, bottom, top, n, f);
00586 }
00587 void SetOrtho( T left, T right, T bottom, T top, T n, T f)
00588 {
00589 matsqu<T,4>::loadIdentity();
00590
00591 matbase<T,4,4>::v(0,0)=2.0f/(right-left);
00592
00593 matbase<T,4,4>::v(1,1)=2.0f/(top-bottom);
00594
00595 matbase<T,4,4>::v(2,2)=-2.0f/(f-n);
00596
00597 matbase<T,4,4>::v(3,0)=-(right+left)/(right-left);
00598 matbase<T,4,4>::v(3,1)=-(top+bottom)/(top-bottom);
00599 matbase<T,4,4>::v(3,2)=-(f+n)/(f-n);
00600 }
00601 void SetTranslationPart(const vec3<T> & translation)
00602 {
00603 matbase<T,4,4>::v(3,0)=translation.v[0];
00604 matbase<T,4,4>::v(3,1)=translation.v[1];
00605 matbase<T,4,4>::v(3,2)=translation.v[2];
00606 }
00607 void SetRotationPartEuler(const T angleX, const T angleY, const T angleZ)
00608 {
00609 T cr = cos( M_PI*angleX/180 );
00610 T sr = sin( M_PI*angleX/180 );
00611 T cp = cos( M_PI*angleY/180 );
00612 T sp = sin( M_PI*angleY/180 );
00613 T cy = cos( M_PI*angleZ/180 );
00614 T sy = sin( M_PI*angleZ/180 );
00615
00616 matbase<T,4,4>::v(0,0) = ( T )( cp*cy );
00617 matbase<T,4,4>::v(0,1) = ( T )( cp*sy );
00618 matbase<T,4,4>::v(0,2) = ( T )( -sp );
00619
00620 T srsp = sr*sp;
00621 T crsp = cr*sp;
00622
00623 matbase<T,4,4>::v(1,0) = ( T )( srsp*cy-cr*sy );
00624 matbase<T,4,4>::v(1,1) = ( T )( srsp*sy+cr*cy );
00625 matbase<T,4,4>::v(1,2) = ( T )( sr*cp );
00626
00627 matbase<T,4,4>::v(2,0) = ( T )( crsp*cy+sr*sy );
00628 matbase<T,4,4>::v(2,1) = ( T )( crsp*sy-sr*cy );
00629 matbase<T,4,4>::v(2,2) = ( T )( cr*cp );
00630 }
00631 void RotateVector3D(math::vec3<T> & rhs) const {
00632 rhs=GetRotatedVector3D(rhs);
00633 }
00634 void InverseRotateVector3D(math::vec3<T> & rhs) const
00635 {
00636 rhs=GetInverseRotatedVector3D(rhs);
00637 }
00638 void TranslateVector3D(vec3<T> & rhs) const
00639 {
00640 rhs=GetTranslatedVector3D(rhs);
00641 }
00642 void InverseTranslateVector3D(vec3<T> & rhs) const
00643 {
00644 rhs=GetInverseTranslatedVector3D(rhs);
00645 }
00646 void SetRotationPartEuler(const math::vec3<T> & rotations)
00647 {
00648 SetRotationPartEuler((T)rotations.v[0], (T)rotations.v[1], (T)rotations.v[2]);
00649 }
00650 mat44<T> lookat(math::vec3<T> eye, math::vec3<T> center, math::vec3<T> up) {
00651 vec3<T> F = center - eye;
00652 vec3<T> f = F.GetNormalized();
00653
00654 vec3<T> UP = up.GetNormalized();
00655
00656 vec3<T> s = f.cross(UP);
00657 s.Normalize();
00658
00659 vec3<T> u = s.cross(f);
00660
00661
00662
00663
00664 mat44 M(
00665 s.v[0], u.v[0], -f.v[0] , 0.0f,
00666 s.v[1], u.v[1], -f.v[1] , 0.0f,
00667 s.v[2], u.v[2], -f.v[2] , 0.0f,
00668 0.0f, 0.0f, 0.0f, 1.0f);
00669
00670
00671
00672 mat44<T> t;
00673 t.SetTranslation(-eye);
00674
00675
00676
00677
00678
00679
00680
00681 return M*t;
00682 }
00683 void SetReflection(math::plane<T> const & p)
00684 {
00685 math::vec3<T> n = p.n.GetNormalized();
00686
00687 mat44<T> A;
00688 A.SetTranslation(n * -p.d);
00689
00690 mat44<T> I;
00691
00692 mat44<T> RA = I - math::vec4<T>(n,0) * math::vec4<T>(n,0) * 2.0;
00693
00694
00695 *this = A.GetInverse() * RA * A;
00696 }
00697 void SetCoordinateTransform(math::vec3<T> const x, math::vec3<T> const y) {
00698
00699
00700 math::vec3<T> Z = x.cross(y);
00701
00702 math::vec3<T> X = y.cross(Z);
00703
00704 X.Normalize();
00705 math::vec3<T> Y = y.GetNormalized();
00706 Z.Normalize();
00707
00708 mat44<T> m(
00709 X.v[0], Y.v[0], Z.v[0] , 0.0f,
00710 X.v[1], Y.v[1], Z.v[1] , 0.0f,
00711 X.v[2], Y.v[2], Z.v[2] , 0.0f,
00712 0.0f, 0.0f, 0.0f, 1.0f);
00713
00714 *this = m;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723 ~mat44() {}
00724
00725 void SetEntry(int position, T value);
00726
00727
00728 mat44 operator+(void) const {return (*this);}
00729
00730
00731
00732 operator T* () const {return (T*) this;}
00733 operator const T* () const {return (const T*) this;}
00734
00735
00736
00737 };
00738
00739
00740
00741
00742 }
00743
00744 #endif //mat44_H