00001 #ifndef _MATRIX4X4_H_
00002 #define _MATRIX4X4_H_
00003
00004 #include "cglib/definitions.h"
00005 #include "cglib/vector3.h"
00006 #include "cglib/point3.h"
00007
00009 struct Matrix4x4
00010 {
00011 private:
00013 float m[4][4];
00014
00015 public:
00017 inline Matrix4x4()
00018 {
00019 for(int i=0;i<4;i++)
00020 for(int j=0;j<4;j++)
00021 m[i][j] = 0.0f;
00022 }
00023
00025 inline Matrix4x4(float c)
00026 {
00027 for(int i=0;i<4;i++)
00028 for(int j=0;j<4;j++)
00029 m[i][j] = c;
00030 }
00031
00033
00036 inline Matrix4x4(float mat[4][4])
00037 {
00038 for(int i=0;i<4;i++)
00039 for(int j=0;j<4;j++)
00040 m[i][j] = mat[i][j];
00041 }
00042
00044 inline Matrix4x4(
00045 float m00, float m01, float m02, float m03,
00046 float m10, float m11, float m12, float m13,
00047 float m20, float m21, float m22, float m23,
00048 float m30, float m31, float m32, float m33)
00049 {
00050 m[0][0] = m00;
00051 m[0][1] = m01;
00052 m[0][2] = m02;
00053 m[0][3] = m03;
00054
00055 m[1][0] = m10;
00056 m[1][1] = m11;
00057 m[1][2] = m12;
00058 m[1][3] = m13;
00059
00060 m[2][0] = m20;
00061 m[2][1] = m21;
00062 m[2][2] = m22;
00063 m[2][3] = m23;
00064
00065 m[3][0] = m30;
00066 m[3][1] = m31;
00067 m[3][2] = m32;
00068 m[3][3] = m33;
00069 }
00070
00072
00075 inline float *operator[](int i) const
00076 {
00077 return (float *)m[i];
00078 }
00079
00081 inline Matrix4x4 operator+(const Matrix4x4 &other) const
00082 {
00083 Matrix4x4 result;
00084 FOR(i, 4)
00085 FOR(j, 4)
00086 result.m[i][j] = m[i][j] + other.m[i][j];
00087 return result;
00088 }
00089
00091 inline Matrix4x4 &operator+=(const Matrix4x4 &other)
00092 {
00093 FOR(i, 4)
00094 FOR(j, 4)
00095 m[i][j] += other.m[i][j];
00096 return *this;
00097 }
00098
00100 inline Matrix4x4 operator-(const Matrix4x4 &other) const
00101 {
00102 Matrix4x4 result;
00103 FOR(i, 4)
00104 FOR(j, 4)
00105 result.m[i][j] = m[i][j] - other.m[i][j];
00106 return result;
00107 }
00108
00110 inline Matrix4x4 &operator-=(const Matrix4x4 &other)
00111 {
00112 FOR(i, 4)
00113 FOR(j, 4)
00114 m[i][j] -= other.m[i][j];
00115 return *this;
00116 }
00117
00119 Point3 operator*(const Point3 &p) const;
00120
00122 Vector3 operator*(const Vector3 &v) const;
00123
00125 inline Matrix4x4 operator*(const Matrix4x4 &other) const
00126 {
00127 Matrix4x4 result;
00128 for(int i=0;i<4;i++)
00129 for(int j=0;j<4;j++)
00130 for(int k=0;k<4;k++)
00131 result.m[i][j] += m[i][k] * other.m[k][j];
00132 return result;
00133 }
00134
00136 inline Matrix4x4 &operator*=(const Matrix4x4 &other)
00137 {
00138 Matrix4x4 result = (*this) * other;
00139 FOR(i, 4) FOR(j, 4) m[i][j] = result.m[i][j];
00140 return *this;
00141 }
00142
00144 inline void get_column_major_array(float *result)
00145 {
00146 FOR(col, 4)
00147 FOR(row, 4)
00148 result[4*col + row] = m[row][col];
00149 }
00150
00152
00155 inline bool is_near(const Matrix4x4 &other, float threshold=EPSILON) const
00156 {
00157 FOR(i, 4)
00158 FOR(j, 4)
00159 if (fabs(m[i][j] - other.m[i][j]) >= EPSILON)
00160 return false;
00161 return true;
00162 }
00163
00165 static Matrix4x4 identity();
00166
00168 static Matrix4x4 translate(float x, float y, float z);
00169
00171 static Matrix4x4 translate_x(float x);
00172
00174 static Matrix4x4 translate_y(float y);
00175
00177 static Matrix4x4 translate_z(float z);
00178
00180 static Matrix4x4 scale(float x, float y, float z);
00181
00183 static Matrix4x4 scale(float s);
00184
00186 static Matrix4x4 scale_x(float x);
00187
00189 static Matrix4x4 scale_y(float y);
00190
00192 static Matrix4x4 scale_z(float z);
00193
00195 static Matrix4x4 rotate(float degrees, Vector3 axis);
00196
00198 static Matrix4x4 rotate_x(float degrees);
00199
00201 static Matrix4x4 rotate_y(float degrees);
00202
00204 static Matrix4x4 rotate_z(float degrees);
00205
00207 static Matrix4x4 look_at(Point3 eye, Point3 at, Vector3 up);
00208
00210 static Matrix4x4 orthographic_projection(float left, float right, float bottom, float top, float near=0, float far=1);
00211
00213 static Matrix4x4 perspective_projection(float left, float right, float bottom, float top, float near, float far);
00214
00216 static Matrix4x4 perspective_projection(float fovy, float aspect, float near, float far);
00217 };
00218
00220 inline Matrix4x4 transpose(const Matrix4x4 &A)
00221 {
00222 float *r0 = A[0];
00223 float *r1 = A[1];
00224 float *r2 = A[2];
00225 float *r3 = A[3];
00226
00227 return Matrix4x4(
00228 r0[0], r1[0], r2[0], r3[0],
00229 r0[1], r1[1], r2[1], r3[1],
00230 r0[2], r1[2], r2[2], r3[2],
00231 r0[3], r1[3], r2[3], r3[3]);
00232 }
00233
00234 #endif