00001 #include "gui_gl_matrix4.hpp"
00002 #include <iostream>
00003
00004 namespace gui {
00005 namespace gl
00006 {
00007 const matrix4 matrix4::IDENTITY = {
00008 1.0f,0.0f,0.0f,0.0f,
00009 0.0f,1.0f,0.0f,0.0f,
00010 0.0f,0.0f,1.0f,0.0f,
00011 0.0f,0.0f,0.0f,1.0f
00012 };
00013
00014 matrix4::matrix4()
00015 {
00016 }
00017
00018 matrix4::matrix4(std::initializer_list<T> mList)
00019 {
00020 int i = 0;
00021 for (const T* p = mList.begin(); p != mList.end() && i < 16; ++p)
00022 {
00023 i = p-mList.begin();
00024 (*this)(i/4,i%4) = *p;
00025 }
00026 }
00027
00028 matrix4::matrix4(T* mat)
00029 {
00030 for (int i = 0; i < 16; ++i)
00031 (*this)(i/4,i%4) = mat[i];
00032 }
00033
00034 void matrix4::make_translation(const vector2f& dx)
00035 {
00036 (*this)(0,0) = 1.0f; (*this)(0,1) = 0.0f; (*this)(0,2) = 0.0f; (*this)(0,3) = dx.x;
00037 (*this)(1,0) = 0.0f; (*this)(1,1) = 1.0f; (*this)(1,2) = 0.0f; (*this)(1,3) = dx.y;
00038 (*this)(2,0) = 0.0f; (*this)(2,1) = 0.0f; (*this)(2,2) = 1.0f; (*this)(2,3) = 0.0f;
00039 (*this)(3,0) = 0.0f; (*this)(3,1) = 0.0f; (*this)(3,2) = 0.0f; (*this)(3,3) = 1.0f;
00040 }
00041
00042 void matrix4::make_scaling(const vector2f& scale)
00043 {
00044 (*this)(0,0) = scale.x; (*this)(0,1) = 0.0f; (*this)(0,2) = 0.0f; (*this)(0,3) = 0.0f;
00045 (*this)(1,0) = 0.0f; (*this)(1,1) = scale.y; (*this)(1,2) = 0.0f; (*this)(1,3) = 0.0f;
00046 (*this)(2,0) = 0.0f; (*this)(2,1) = 0.0f; (*this)(2,2) = 1.0f; (*this)(2,3) = 0.0f;
00047 (*this)(3,0) = 0.0f; (*this)(3,1) = 0.0f; (*this)(3,2) = 0.0f; (*this)(3,3) = 1.0f;
00048 }
00049
00050 void matrix4::make_rotation(float rot)
00051 {
00052 float co = cos(rot), si = sin(rot);
00053
00054 (*this)(0,0) = co; (*this)(0,1) = -si; (*this)(0,2) = 0.0f; (*this)(0,3) = 0.0f;
00055 (*this)(1,0) = si; (*this)(1,1) = co; (*this)(1,2) = 0.0f; (*this)(1,3) = 0.0f;
00056 (*this)(2,0) = 0.0f; (*this)(2,1) = 0.0f; (*this)(2,2) = 1.0f; (*this)(2,3) = 0.0f;
00057 (*this)(3,0) = 0.0f; (*this)(3,1) = 0.0f; (*this)(3,2) = 0.0f; (*this)(3,3) = 1.0f;
00058 }
00059
00060 void matrix4::make_transformation(const vector2f& dx, const vector2f& scale, float rot)
00061 {
00062 float co = cos(rot), si = sin(rot);
00063
00064 (*this)(0,0) = scale.x*co; (*this)(0,1) = -scale.y*si; (*this)(0,2) = 0.0f; (*this)(0,3) = dx.x;
00065 (*this)(1,0) = scale.x*si; (*this)(1,1) = scale.y*co; (*this)(1,2) = 0.0f; (*this)(1,3) = dx.y;
00066 (*this)(2,0) = 0.0f; (*this)(2,1) = 0.0f; (*this)(2,2) = 1.0f; (*this)(2,3) = 0.0f;
00067 (*this)(3,0) = 0.0f; (*this)(3,1) = 0.0f; (*this)(3,2) = 0.0f; (*this)(3,3) = 1.0f;
00068 }
00069
00070 void matrix4::transpose()
00071 {
00072 T fTemp;
00073 for (int i = 0; i < 4; ++i)
00074 for (int j = 0; j < 4; ++j)
00075 {
00076 if (i != j)
00077 {
00078 fTemp = (*this)(i,j);
00079 (*this)(i,j) = (*this)(j,i);
00080 (*this)(j,i) = fTemp;
00081 }
00082 }
00083 }
00084
00085 void matrix4::invert()
00086 {
00087 *this = invert(*this);
00088 }
00089
00090 matrix4 matrix4::translation(const vector2f& dx)
00091 {
00092 matrix4 m; m.make_translation(dx);
00093 return m;
00094 }
00095
00096 matrix4 matrix4::scaling(const vector2f& scale)
00097 {
00098 matrix4 m; m.make_scaling(scale);
00099 return m;
00100 }
00101
00102 matrix4 matrix4::rotation(float rot)
00103 {
00104 matrix4 m; m.make_rotation(rot);
00105 return m;
00106 }
00107
00108 matrix4 matrix4::transformation(const vector2f& dx, const vector2f& scale, float rot)
00109 {
00110 matrix4 m; m.make_transformation(dx, scale, rot);
00111 return m;
00112 }
00113
00114 matrix4 matrix4::transpose(const matrix4& m)
00115 {
00116 return {
00117 m(0,0), m(1,0), m(2,0), m(3,0),
00118 m(0,1), m(1,1), m(2,1), m(3,1),
00119 m(0,2), m(1,2), m(2,2), m(3,2),
00120 m(0,3), m(1,3), m(2,3), m(3,3)
00121 };
00122 }
00123
00124 matrix4 matrix4::invert(const matrix4& m)
00125 {
00126 T m00 = m(0,0), m01 = m(0,1), m02 = m(0,2), m03 = m(0,3);
00127 T m10 = m(1,0), m11 = m(1,1), m12 = m(1,2), m13 = m(1,3);
00128 T m20 = m(2,0), m21 = m(2,1), m22 = m(2,2), m23 = m(2,3);
00129 T m30 = m(3,0), m31 = m(3,1), m32 = m(3,2), m33 = m(3,3);
00130
00131 T v0 = m20*m31 - m21*m30;
00132 T v1 = m20*m32 - m22*m30;
00133 T v2 = m20*m33 - m23*m30;
00134 T v3 = m21*m32 - m22*m31;
00135 T v4 = m21*m33 - m23*m31;
00136 T v5 = m22*m33 - m23*m32;
00137
00138 T t00 = (v5*m11 - v4*m12 + v3*m13);
00139 T t10 = -(v5*m10 - v2*m12 + v1*m13);
00140 T t20 = (v4*m10 - v2*m11 + v0*m13);
00141 T t30 = -(v3*m10 - v1*m11 + v0*m12);
00142
00143 T invDet = 1.0f/(t00*m00 + t10*m01 + t20*m02 + t30*m03);
00144
00145 T d00 = t00*invDet;
00146 T d10 = t10*invDet;
00147 T d20 = t20*invDet;
00148 T d30 = t30*invDet;
00149
00150 T d01 = -(v5*m01 - v4*m02 + v3*m03)*invDet;
00151 T d11 = (v5*m00 - v2*m02 + v1*m03)*invDet;
00152 T d21 = -(v4*m00 - v2*m01 + v0*m03)*invDet;
00153 T d31 = (v3*m00 - v1*m01 + v0*m02)*invDet;
00154
00155 v0 = m10*m31 - m11*m30;
00156 v1 = m10*m32 - m12*m30;
00157 v2 = m10*m33 - m13*m30;
00158 v3 = m11*m32 - m12*m31;
00159 v4 = m11*m33 - m13*m31;
00160 v5 = m12*m33 - m13*m32;
00161
00162 T d02 = (v5*m01 - v4*m02 + v3*m03)*invDet;
00163 T d12 = -(v5*m00 - v2*m02 + v1*m03)*invDet;
00164 T d22 = (v4*m00 - v2*m01 + v0*m03)*invDet;
00165 T d32 = -(v3*m00 - v1*m01 + v0*m02)*invDet;
00166
00167 v0 = m21*m10 - m20*m11;
00168 v1 = m22*m10 - m20*m12;
00169 v2 = m23*m10 - m20*m13;
00170 v3 = m22*m11 - m21*m12;
00171 v4 = m23*m11 - m21*m13;
00172 v5 = m23*m12 - m22*m13;
00173
00174 T d03 = -(v5*m01 - v4*m02 + v3*m03)*invDet;
00175 T d13 = (v5*m00 - v2*m02 + v1*m03)*invDet;
00176 T d23 = -(v4*m00 - v2*m01 + v0*m03)*invDet;
00177 T d33 = (v3*m00 - v1*m01 + v0*m02)*invDet;
00178
00179 return {
00180 d00, d01, d02, d03,
00181 d10, d11, d12, d13,
00182 d20, d21, d22, d23,
00183 d30, d31, d32, d33
00184 };
00185 }
00186
00187 matrix4 matrix4::operator + (const matrix4& m)
00188 {
00189 matrix4 r;
00190
00191 r(0,0) = (*this)(0,0) + m(0,0);
00192 r(0,1) = (*this)(0,1) + m(0,1);
00193 r(0,2) = (*this)(0,2) + m(0,2);
00194 r(0,3) = (*this)(0,3) + m(0,3);
00195
00196 r(1,0) = (*this)(1,0) + m(1,0);
00197 r(1,1) = (*this)(1,1) + m(1,1);
00198 r(1,2) = (*this)(1,2) + m(1,2);
00199 r(1,3) = (*this)(1,3) + m(1,3);
00200
00201 r(2,0) = (*this)(2,0) + m(2,0);
00202 r(2,1) = (*this)(2,1) + m(2,1);
00203 r(2,2) = (*this)(2,2) + m(2,2);
00204 r(2,3) = (*this)(2,3) + m(2,3);
00205
00206 r(3,0) = (*this)(3,0) + m(3,0);
00207 r(3,1) = (*this)(3,1) + m(3,1);
00208 r(3,2) = (*this)(3,2) + m(3,2);
00209 r(3,3) = (*this)(3,3) + m(3,3);
00210
00211 return r;
00212 }
00213
00214
00215 matrix4 matrix4::operator - (const matrix4& m)
00216 {
00217 matrix4 r;
00218
00219 r(0,0) = (*this)(0,0) - m(0,0);
00220 r(0,1) = (*this)(0,1) - m(0,1);
00221 r(0,2) = (*this)(0,2) - m(0,2);
00222 r(0,3) = (*this)(0,3) - m(0,3);
00223
00224 r(1,0) = (*this)(1,0) - m(1,0);
00225 r(1,1) = (*this)(1,1) - m(1,1);
00226 r(1,2) = (*this)(1,2) - m(1,2);
00227 r(1,3) = (*this)(1,3) - m(1,3);
00228
00229 r(2,0) = (*this)(2,0) - m(2,0);
00230 r(2,1) = (*this)(2,1) - m(2,1);
00231 r(2,2) = (*this)(2,2) - m(2,2);
00232 r(2,3) = (*this)(2,3) - m(2,3);
00233
00234 r(3,0) = (*this)(3,0) - m(3,0);
00235 r(3,1) = (*this)(3,1) - m(3,1);
00236 r(3,2) = (*this)(3,2) - m(3,2);
00237 r(3,3) = (*this)(3,3) - m(3,3);
00238
00239 return r;
00240 }
00241
00242 matrix4 matrix4::operator * (const matrix4& m)
00243 {
00244 matrix4 r;
00245
00246 r(0,0) = (*this)(0,0)*m(0,0) + (*this)(0,1)*m(1,0) + (*this)(0,2)*m(2,0) + (*this)(0,3)*m(3,0);
00247 r(0,1) = (*this)(0,0)*m(0,1) + (*this)(0,1)*m(1,1) + (*this)(0,2)*m(2,1) + (*this)(0,3)*m(3,1);
00248 r(0,2) = (*this)(0,0)*m(0,2) + (*this)(0,1)*m(1,2) + (*this)(0,2)*m(2,2) + (*this)(0,3)*m(3,2);
00249 r(0,3) = (*this)(0,0)*m(0,3) + (*this)(0,1)*m(1,3) + (*this)(0,2)*m(2,3) + (*this)(0,3)*m(3,3);
00250
00251 r(1,0) = (*this)(1,0)*m(0,0) + (*this)(1,1)*m(1,0) + (*this)(1,2)*m(2,0) + (*this)(1,3)*m(3,0);
00252 r(1,1) = (*this)(1,0)*m(0,1) + (*this)(1,1)*m(1,1) + (*this)(1,2)*m(2,1) + (*this)(1,3)*m(3,1);
00253 r(1,2) = (*this)(1,0)*m(0,2) + (*this)(1,1)*m(1,2) + (*this)(1,2)*m(2,2) + (*this)(1,3)*m(3,2);
00254 r(1,3) = (*this)(1,0)*m(0,3) + (*this)(1,1)*m(1,3) + (*this)(1,2)*m(2,3) + (*this)(1,3)*m(3,3);
00255
00256 r(2,0) = (*this)(2,0)*m(0,0) + (*this)(2,1)*m(1,0) + (*this)(2,2)*m(2,0) + (*this)(2,3)*m(3,0);
00257 r(2,1) = (*this)(2,0)*m(0,1) + (*this)(2,1)*m(1,1) + (*this)(2,2)*m(2,1) + (*this)(2,3)*m(3,1);
00258 r(2,2) = (*this)(2,0)*m(0,2) + (*this)(2,1)*m(1,2) + (*this)(2,2)*m(2,2) + (*this)(2,3)*m(3,2);
00259 r(2,3) = (*this)(2,0)*m(0,3) + (*this)(2,1)*m(1,3) + (*this)(2,2)*m(2,3) + (*this)(2,3)*m(3,3);
00260
00261 r(3,0) = (*this)(3,0)*m(0,0) + (*this)(3,1)*m(1,0) + (*this)(3,2)*m(2,0) + (*this)(3,3)*m(3,0);
00262 r(3,1) = (*this)(3,0)*m(0,1) + (*this)(3,1)*m(1,1) + (*this)(3,2)*m(2,1) + (*this)(3,3)*m(3,1);
00263 r(3,2) = (*this)(3,0)*m(0,2) + (*this)(3,1)*m(1,2) + (*this)(3,2)*m(2,2) + (*this)(3,3)*m(3,2);
00264 r(3,3) = (*this)(3,0)*m(0,3) + (*this)(3,1)*m(1,3) + (*this)(3,2)*m(2,3) + (*this)(3,3)*m(3,3);
00265
00266 return r;
00267 }
00268
00269 vector2f matrix4::operator*(const vector2f& v)
00270 {
00271 vector2f r;
00272
00273 T fInvW = 1.0f/((*this)(3,0)*v.x + (*this)(3,1)*v.y + (*this)(3,3));
00274
00275 r.x = ((*this)(0,0)*v.x + (*this)(0,1)*v.y + (*this)(0,3))*fInvW;
00276 r.y = ((*this)(1,0)*v.x + (*this)(1,1)*v.y + (*this)(1,3))*fInvW;
00277
00278 return r;
00279 }
00280
00281 std::ostream& operator << (std::ostream& o, const matrix4& m)
00282 {
00283 return o << "(" << m(0,0) << ", " << m(0,1) << ", " << m(0,2) << ", " << m(0,3) << ")\n"
00284 << "(" << m(1,0) << ", " << m(1,1) << ", " << m(1,2) << ", " << m(1,3) << ")\n"
00285 << "(" << m(2,0) << ", " << m(2,1) << ", " << m(2,2) << ", " << m(2,3) << ")\n"
00286 << "(" << m(3,0) << ", " << m(3,1) << ", " << m(3,2) << ", " << m(3,3) << ")\n";
00287 }
00288 }
00289 }