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 }