00001
00008 #ifndef MATRIX_H
00009 #define MATRIX_H
00010
00011 #include "Point3.h"
00012 #include "Vector3.h"
00013
00020 template<class T>
00021 class Matrix
00022 {
00023 public:
00024
00025 union
00026 {
00027 struct
00028 {
00029 T _11, _12, _13, _14;
00030 T _21, _22, _23, _24;
00031 T _31, _32, _33, _34;
00032 T _41, _42, _43, _44;
00033 };
00034 T m[4][4];
00035 };
00036
00037 Matrix() {}
00038
00039 void MakeZero()
00040 {
00041 for(int i = 0; i < 4; i++)
00042 {
00043 for(int j = 0; j < 4; j++)
00044 {
00045 m[i][j] = (T)0.0;
00046 }
00047 }
00048 }
00049
00050 void MakeIdentity()
00051 {
00052 MakeZero();
00053 _11 = _22 = _33 = _44 = (T)1.0;
00054 }
00055
00056 void Transpose()
00057 {
00058 T tmp;
00059 tmp = _12; _12 = _21; _21 = tmp;
00060 tmp = _13; _13 = _31; _31 = tmp;
00061 tmp = _14; _14 = _41; _41 = tmp;
00062 tmp = _23; _23 = _32; _32 = tmp;
00063 tmp = _34; _34 = _43; _43 = tmp;
00064 }
00065
00066 void MakeTranslation(T x, T y, T z)
00067 {
00068 MakeIdentity();
00069 _14 = x;
00070 _24 = y;
00071 _34 = z;
00072 }
00073
00074 void MakeScale(T x, T y, T z)
00075 {
00076 MakeIdentity();
00077 _11 = x;
00078 _22 = y;
00079 _33 = z;
00080 }
00081
00082
00083 void MakeRotationX(T angle)
00084 {
00085 const T s = std::sin(angle);
00086 const T c = std::cos(angle);
00087
00088 MakeIdentity();
00089 _22 = c; _23 = -s;
00090 _32 = s; _33 = c;
00091 }
00092
00093
00094 void MakeRotationY(T angle)
00095 {
00096 const T s = std::sin(angle);
00097 const T c = std::cos(angle);
00098
00099 MakeIdentity();
00100 _11 = c; _13 = s;
00101 _31 = -s; _33 = c;
00102 }
00103
00104
00105 void MakeRotationZ(T angle)
00106 {
00107 const T s = std::sin(angle);
00108 const T c = std::cos(angle);
00109
00110 MakeIdentity();
00111 _11 = c; _12 = -s;
00112 _21 = s; _22 = c;
00113 }
00114
00115
00116
00117 void MakeRotation(const Vector3<T> axis, T angle)
00118 {
00119
00120 const T len = axis.Length();
00121 const T x = axis.x / len;
00122 const T y = axis.y / len;
00123 const T z = axis.z / len;
00124
00125 const T c = std::cos(angle);
00126 const T s = std::sin(angle);
00127 const T t = 1 - c;
00128
00129 MakeIdentity();
00130
00131 _11 = t*x*x + c;
00132 _12 = t*x*y - s*z;
00133 _13 = t*x*z + s*y;
00134
00135 _21 = t*x*y + s*z;
00136 _22 = t*y*y + c;
00137 _23 = t*y*z - s*x;
00138
00139 _31 = t*x*z - s*y;
00140 _32 = t*y*z + s*x;
00141 _33 = t*z*z + c;
00142 }
00143
00144 Point3<T> Transform(const Point3<T> &p) const
00145 {
00146 Point3<T> out;
00147 out.x = p.x*_11 + p.y*_12 + p.z*_13 + _14;
00148 out.y = p.x*_21 + p.y*_22 + p.z*_23 + _24;
00149 out.z = p.x*_31 + p.y*_32 + p.z*_33 + _34;
00150 return out;
00151 }
00152
00153 Vector3<T> Transform(const Vector3<T> &v) const
00154 {
00155 Vector3<T> out;
00156 out.x = v.x*_11 + v.y*_12 + v.z*_13;
00157 out.y = v.x*_21 + v.y*_22 + v.z*_23;
00158 out.z = v.x*_31 + v.y*_32 + v.z*_33;
00159 return out;
00160 }
00161
00162
00163 void MakeView(const Point3<T> eye, const Point3<T> lookAt, const Vector3<T> up)
00164 {
00165 Vector3<T> zaxis = Normalize(lookAt - eye);
00166 Vector3<T> xaxis = Normalize(zaxis.Cross(up));
00167 Vector3<T> yaxis = Normalize(xaxis.Cross(zaxis));
00168
00169 MakeView(eye, xaxis, yaxis, zaxis);
00170 }
00171
00172 void MakeView(const Point3<T> &eye, const Vector3<T> &xaxis, const Vector3<T> &yaxis, const Vector3<T> &zaxis)
00173 {
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 MakeIdentity();
00198 _11 = xaxis.x; _12 = xaxis.y; _13 = xaxis.z;
00199 _21 = yaxis.x; _22 = yaxis.y; _23 = yaxis.z;
00200 _31 = -zaxis.x; _32 = -zaxis.y; _33 = -zaxis.z;
00201
00202 _14 = -Dot(xaxis, eye);
00203 _24 = -Dot(yaxis, eye);
00204 _34 = Dot(zaxis, eye);
00205 }
00206
00207
00208 void MakePerspective(T width, T height, T n, T f)
00209 {
00210 T aspect = width / height;
00211
00212 T dw = aspect / ((T)2);
00213 T dh = ((T)0.5);
00214 MakePerspective(-dw, dw, -dh, dh, n, f);
00215 }
00216
00217 void MakePerspective(T left, T right, T bottom, T top, T n, T f)
00218 {
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 T A = (right + left) / (right - left);
00244 T B = (top + bottom) / (top - bottom);
00245 T C = (f + n) / (f - n);
00246 T D = (((T)2)*f*n) / (f - n);
00247
00248 MakeZero();
00249 _11 = ((T)2)*n / (right - left);
00250 _22 = ((T)2)*n / (top - bottom);
00251 _13 = A;
00252 _23 = B;
00253 _33 = -C;
00254 _34 = -D;
00255 _43 = ((T)-1);
00256 }
00257
00258 T Det() const
00259 {
00260 T a1 = _11*_22*_33*_44 + _11*_23*_34*_42 + _11*_24*_32*_43;
00261 T a2 = _12*_21*_34*_43 + _12*_23*_31*_44 + _12*_24*_33*_41;
00262 T a3 = _13*_21*_32*_44 + _13*_22*_34*_41 + _13*_24*_31*_42;
00263 T a4 = _14*_21*_32*_44 + _14*_22*_31*_43 + _14*_23*_32*_41;
00264 T a5 = _11*_22*_34*_43 + _11*_23*_32*_44 + _11*_24*_33*_42;
00265 T a6 = _12*_21*_33*_44 + _12*_23*_34*_41 + _12*_24*_31*_43;
00266 T a7 = _13*_21*_34*_42 + _13*_22*_31*_44 + _13*_24*_32*_41;
00267 T a8 = _14*_21*_32*_43 + _14*_22*_33*_41 + _14*_23*_31*_42;
00268
00269 return a1 + a2 + a3 + a4 - a5 - a6 - a7 - a8;
00270 }
00271
00272
00273 void GetOpenGLMatrix(T m[16]) const
00274 {
00275
00276 m[0] = _11; m[4] = _12; m[8] = _13; m[12] = _14;
00277 m[1] = _21; m[5] = _22; m[9] = _23; m[13] = _24;
00278 m[2] = _31; m[6] = _32; m[10] = _33; m[14] = _34;
00279 m[3] = _41; m[7] = _42; m[11] = _43; m[15] = _44;
00280 }
00281
00282 Matrix operator+(const Matrix &b) const
00283 {
00284 Matrix c;
00285 for(int i = 0; i < 4; i++)
00286 {
00287 for(int j = 0; j < 4; j++)
00288 {
00289 c.m[i][j] = m[i][j] + b.m[i][j];
00290 }
00291 }
00292 return c;
00293 }
00294
00295 Matrix operator*(const Matrix &b) const
00296 {
00297 Matrix c;
00298 for(int i = 0; i < 4; i++)
00299 {
00300 for(int j = 0; j < 4; j++)
00301 {
00302 T sum = (T)0.0;
00303 for(int k = 0; k < 4; k++)
00304 {
00305 sum += m[i][k] * b.m[k][j];
00306 }
00307 c.m[i][j] = sum;
00308 }
00309 }
00310 return c;
00311 }
00312
00313 Matrix operator*(T k) const
00314 {
00315 Matrix c;
00316 for(int i = 0; i < 4; i++)
00317 {
00318 for(int j = 0; j < 4; j++)
00319 {
00320 c.m[i][j] = k * m[i][j];
00321 }
00322 }
00323 return c;
00324 }
00325
00326 friend Matrix operator*(T k, const Matrix &a)
00327 {
00328 return a*k;
00329 }
00330 };
00331
00332 typedef Matrix<float> Matrixf;
00333 typedef Matrix<double> Matrixd;
00334
00335 #endif