00001 #ifndef MATRIX_H
00002 #define MATRIX_H
00003
00004 #include <cassert>
00005 #include <iosfwd>
00006
00007 #include "Vec3f.h"
00008 #include "Ray.h"
00009
00010
00015 class Matrix
00016 {
00017
00018 friend Matrix operator*(const Matrix & m, const float f);
00019 friend Matrix operator*(const float f, const Matrix & m);
00020 friend Vec3f operator*(const Matrix & m, const Vec3f & v);
00021 friend Vec3f operator*(const Vec3f & v, const Matrix & m);
00022 friend Ray operator*(const Matrix & m, const Ray & r);
00023 friend Ray operator*(const Ray & r, const Matrix & m);
00024 friend Matrix operator*(const Matrix & m1, const Matrix & m2);
00025 friend std::ostream & operator<<(std::ostream & o, const Matrix & m);
00026
00027 public:
00035 Matrix()
00036 {
00037
00038 for (int i = 0; i < 4; i++)
00039 {
00040 for (int j = 0; j < 4; j++)
00041 {
00042 if (i != j)
00043 mValues[i][j] = 0.0f;
00044 else
00045 mValues[i][j] = 1.0f;
00046 }
00047 }
00048 }
00049
00057 Matrix(const float f)
00058 {
00059 for(int i=0; i<4; i++)
00060 {
00061 for(int j=0; j<4; j++)
00062 {
00063 mValues[i][j] = f;
00064 }
00065 }
00066 }
00067
00079 Matrix(const float x, const float y, const float z)
00080 {
00081 for (int i = 0; i < 4; i++)
00082 {
00083 for (int j = 0; j < 4; j++)
00084 {
00085 if (i != j)
00086 mValues[i][j] = 0.0f;
00087 }
00088 }
00089 mValues[0][0] = x;
00090 mValues[1][1] = y;
00091 mValues[2][2] = z;
00092 mValues[3][3] = 1.0f;
00093 }
00094
00104 Matrix(const Vec3f & t)
00105 {
00106 for (int i = 0; i < 4; i++)
00107 {
00108 for (int j = 0; j < 3; j++)
00109 {
00110 if (i != j)
00111 mValues[i][j] = 0.0f;
00112 else
00113 mValues[i][j] = 1.0f;
00114 }
00115 }
00116 mValues[0][3] = t.x();
00117 mValues[1][3] = t.y();
00118 mValues[2][3] = t.z();
00119 mValues[3][3] = 1.0f;
00120 }
00121
00137 Matrix(const float angle, const Vec3f & axis)
00138 {
00139 const Vec3f a(axis.normal());
00140 const float c = cosf(angle);
00141 const float s = sinf(angle);
00142
00143 mValues[0][0] = a.x()*a.x()*(1.0f - c) + c;
00144 mValues[0][1] = a.x()*a.y()*(1.0f - c) - a.z()*s;
00145 mValues[0][2] = a.x()*a.z()*(1.0f - c) + a.y()*s;
00146 mValues[0][3] = 0.0f;
00147
00148 mValues[1][0] = a.y()*a.x()*(1.0f - c) + a.z()*s;
00149 mValues[1][1] = a.y()*a.y()*(1.0f - c) + c;
00150 mValues[1][2] = a.y()*a.z()*(1.0f - c) - a.x()*s;
00151 mValues[1][3] = 0.0f;
00152
00153 mValues[2][0] = a.x()*a.z()*(1.0f - c) - a.y()*s;
00154 mValues[2][1] = a.y()*a.z()*(1.0f - c) + a.x()*s;
00155 mValues[2][2] = a.z()*a.z()*(1.0f - c) + c;
00156 mValues[2][3] = 0.0f;
00157
00158 mValues[3][0] = 0.0f;
00159 mValues[3][1] = 0.0f;
00160 mValues[3][2] = 0.0f;
00161 mValues[3][3] = 1.0f;
00162 }
00163
00170 void set(int x, int y, float value)
00171 {
00172 assert(x>=0 && x<4);
00173 assert(y>=0 && y<4);
00174
00175 mValues[x][y] = value;
00176 }
00177
00189 float get(int x, int y) const
00190 {
00191 assert(x>=0 && x<4);
00192 assert(y>=0 && y<4);
00193
00194 return mValues[x][y];
00195 }
00196
00199 inline Matrix & operator*=(const Matrix & m)
00200 {
00201 *this = (*this) * m;
00202 return *this;
00203 }
00204
00208 inline Vec3f transformVector(const Vec3f & vector) const
00209 {
00210 float result[3];
00211 for(int i=0; i<3; i++)
00212 {
00213 result[i] = 0.0f;
00214 for(int j=0; j<3; j++)
00215 {
00216 result[i] += (mValues[i][j] * vector[j]);
00217 }
00218
00219 }
00220 return Vec3f( result[0], result[1], result[2] );
00221 }
00222
00223 private:
00224 float mValues[4][4];
00225 };
00226
00227
00230 inline Matrix operator*(const Matrix & m, const float f)
00231 {
00232 Matrix result;
00233 for(int x=0; x<4; x++)
00234 {
00235 for(int y=0; y<4; y++)
00236 {
00237 result.mValues[x][y] = m.mValues[x][y] * f;
00238 }
00239 }
00240 return result;
00241 }
00242
00243
00246 inline Matrix operator*(const float f, const Matrix & m)
00247 {
00248 Matrix result;
00249 for(int x=0; x<4; x++)
00250 {
00251 for(int y=0; y<4; y++)
00252 {
00253 result.mValues[x][y] = m.mValues[x][y] * f;
00254 }
00255 }
00256 return result;
00257 }
00258
00259
00262 inline Vec3f operator*(const Matrix & m, const Vec3f & point)
00263 {
00264 float result[4];
00265 for(int i=0; i<4; i++)
00266 {
00267 result[i] = 0.0f;
00268 for(int j=0; j<3; j++)
00269 {
00270 result[i] += (m.mValues[i][j] * point[j]);
00271 }
00272 result[i] += (m.mValues[i][3]);
00273 }
00274
00275 return Vec3f( result[0]/result[3], result[1]/result[3], result[2]/result[3] );
00276 }
00277
00278
00281 inline Vec3f operator*(const Vec3f & point, const Matrix & m)
00282 {
00283 LOG("Multiplying a 3D-point with the matrix should not be used unless you really know what you're doing");
00284 assert(false);
00285 float result[4];
00286 for(int i=0; i<4; i++)
00287 {
00288 result[i] = 0.0f;
00289 for(int j=0; j<3; j++)
00290 {
00291 result[i] += (point[i] * m.mValues[i][j]);
00292 }
00293 result[i] += m.mValues[i][3];
00294 }
00295 return Vec3f( result[0]/result[3], result[1]/result[3], result[2]/result[3] );
00296 }
00297
00298
00306 inline Ray operator*(const Matrix & m, const Ray & r)
00307 {
00308 Vec3f org = m * r.org();
00309 Vec3f dir = m.transformVector(r.dir());
00310
00311
00312 float t = dir.length() * r.t();
00313
00314 Ray result;
00315 result.init(org, dir);
00316 result.setHit(r.hit(), t);
00317 result.setObj(r.obj());
00318 result.setUV(r.u(), r.v());
00319 result.setInfluence(r.influence(), r.recDeep());
00320 return result;
00321 }
00322
00323
00326 inline Ray operator*(const Ray & , const Matrix & )
00327 {
00328 LOG("Left-sided multiplication of Ray and Matrix does not make any sense");
00329 assert(false);
00330 return Ray();
00331 }
00332
00333
00336 inline Matrix operator*(const Matrix & m1, const Matrix & m2)
00337 {
00338 Matrix result;
00339 for(int i=0; i<4; i++)
00340 {
00341 for(int j=0; j<4; j++)
00342 {
00343 float f = 0.0f;
00344 for(int k = 0; k<4; k++)
00345 {
00346 f += m1.mValues[i][k] * m2.mValues[k][j];
00347 }
00348 result.mValues[i][j] = f;
00349 }
00350 }
00351 return result;
00352 }
00353
00354
00357 std::ostream & operator<<(std::ostream & o, const Matrix & m);
00358
00359
00360 #endif
00361