00001 #ifndef MATRIX_H_
00002 #define MATRIX_H_
00003
00004 #include <assert.h>
00005 #define _USE_MATH_DEFINES
00006 #include <math.h>
00007
00008 #include "Vector.h"
00009
00013 template<class Type = float, int size = 4>
00014 class Matrix {
00015 public:
00019 Matrix();
00020
00021
00022
00023 Matrix& operator +=(const Matrix& m);
00024 Matrix operator +(const Matrix& m) const;
00025
00026 Type* operator [](int col) {
00027 assert(col < size);
00028 return mMatrix[col];
00029 }
00030
00031 const Type* operator [](int col) const {
00032 assert(col < size);
00033 return mMatrix[col];
00034 }
00035
00036 Matrix& operator *=(const Matrix& other);
00037 Matrix operator *(const Matrix& other) const;
00038
00039 void loadIdentity();
00040
00041 Type* matrix() { return &mMatrix[0][0]; }
00042
00043
00044 private:
00045 Type mMatrix[size][size];
00046 };
00047
00048 template<class Type, int size>
00049 Matrix<Type, size>::Matrix() {
00050 loadIdentity();
00051 }
00052
00053 template<class Type, int size>
00054 void Matrix<Type, size>::loadIdentity(){
00055 for (int x = 0; x < size; ++x) {
00056 for (int y = 0; y < size; ++y) {
00057 if (x == y)
00058 mMatrix[x][y] = 1;
00059 else
00060 mMatrix[x][y] = 0;
00061 }
00062 }
00063 }
00064
00065 template<class Type, int size>
00066 Matrix<Type, size> Matrix<Type, size>::operator+(const Matrix& m) const {
00067 Matrix ret(*this);
00068 return ret += m;
00069 }
00070
00071 template<class Type, int size>
00072 Matrix<Type, size>& Matrix<Type, size>::operator+=(const Matrix& m) {
00073 for (int x = 0; x < size; ++x) {
00074 for (int y = 0; y < size; ++y) {
00075 mMatrix[x][y] += m[x][y];
00076 }
00077 }
00078 return *this;
00079 }
00080
00081 template<class Type, int size>
00082 Matrix<Type, size> Matrix<Type, size>::operator*(const Matrix& m) const {
00083 Matrix ret(*this);
00084 return ret *= m;
00085 }
00086
00087 template<class Type, int size>
00088 Matrix<Type, size>& Matrix<Type, size>::operator*=(const Matrix& m) {
00089 Matrix<> rv(*this);
00090 for(int rowL = 0; rowL < size; ++rowL) {
00091 for(int columnR = 0; columnR < size; ++columnR) {
00092 Type val = 0;
00093 for (int el = 0; el < size; ++el) {
00094 val += mMatrix[rowL][el] * m[el][columnR];
00095 }
00096 rv[rowL][columnR] = val;
00097 }
00098 }
00099 *this = rv;
00100 return *this;
00101 }
00102
00103 template<class Type>
00104 Vector<> operator*(Matrix<Type, 4>& m, const Vector<>& v) {
00105 Type vals[4];
00106 for(int rowL = 0; rowL < 3; ++rowL) {
00107 vals[rowL] = 0;
00108 for (int el = 0; el < 3; ++el) {
00109 vals[rowL] += m[rowL][el] * v.vector()[el];
00110 }
00111 }
00112 return Vector<>(vals[0], vals[1], vals[2]);
00113 }
00114
00115 enum Axis {
00116 AXIS_X,
00117 AXIS_Y,
00118 AXIS_Z
00119 };
00120
00121 template<class Type>
00122 Matrix<Type, 4> makeRotationMatrix(Type angle, Axis axis) {
00123 Type cosa = cos(angle), sina = sin(angle);
00124 Matrix<Type, 4> m;
00125 switch (axis) {
00126 case AXIS_X:
00127 m[1][1] = cosa;
00128 m[1][2] = -sina;
00129 m[2][1] = sina;
00130 m[2][2] = cosa;
00131 break;
00132 case AXIS_Y:
00133 m[0][0] = cosa;
00134 m[0][2] = sina;
00135 m[2][0] = -sina;
00136 m[2][2] = cosa;
00137 break;
00138 case AXIS_Z:
00139 m[0][0] = cosa;
00140 m[0][1] = -sina;
00141 m[1][0] = sina;
00142 m[1][1] = cosa;
00143 break;
00144 }
00145 return m;
00146 }
00147
00151 template<class Type>
00152 void rotate(Matrix<Type, 4>& m, Type angle, Axis axis) {
00153 Matrix<Type> rotMatrix = makeRotationMatrix(angle, axis);
00154 m *= rotMatrix;
00155 }
00156
00157 template<class Type>
00158 void translate(Matrix<Type, 4>&m, const Vector<Type>& aTranslateBy) {
00159 Matrix<Type> translateMatrix;
00160 translateMatrix[3][0] = aTranslateBy.x();
00161 translateMatrix[3][1] = aTranslateBy.y();
00162 translateMatrix[3][2] = aTranslateBy.z();
00163 m *= translateMatrix;
00164 }
00165
00166
00167
00168 #endif
00169