1/////////////////////////////////////////////////////////////////////////////////// 2/// OpenGL Mathematics (glm.g-truc.net) 3/// 4/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) 5/// Permission is hereby granted, free of charge, to any person obtaining a copy 6/// of this software and associated documentation files (the "Software"), to deal 7/// in the Software without restriction, including without limitation the rights 8/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9/// copies of the Software, and to permit persons to whom the Software is 10/// furnished to do so, subject to the following conditions: 11/// 12/// The above copyright notice and this permission notice shall be included in 13/// all copies or substantial portions of the Software. 14/// 15/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21/// THE SOFTWARE. 22/// 23/// @ref core 24/// @file glm/core/type_mat4x4.inl 25/// @date 2005-01-27 / 2011-06-15 26/// @author Christophe Riccio 27/////////////////////////////////////////////////////////////////////////////////// 28 29namespace glm{ 30namespace detail 31{ 32 template <typename T, precision P> 33 GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t tmat4x4<T, P>::length() const 34 { 35 return 4; 36 } 37 38 ////////////////////////////////////// 39 // Accesses 40 41 template <typename T, precision P> 42 GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type & 43 tmat4x4<T, P>::operator[] 44 ( 45 length_t i 46 ) 47 { 48 assert(i < this->length()); 49 return this->value[i]; 50 } 51 52 template <typename T, precision P> 53 GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type const & 54 tmat4x4<T, P>::operator[] 55 ( 56 length_t i 57 ) const 58 { 59 assert(i < this->length()); 60 return this->value[i]; 61 } 62 63 ////////////////////////////////////////////////////////////// 64 // Constructors 65 66 template <typename T, precision P> 67 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4() 68 { 69 T Zero(0); 70 T One(1); 71 this->value[0] = col_type(One, Zero, Zero, Zero); 72 this->value[1] = col_type(Zero, One, Zero, Zero); 73 this->value[2] = col_type(Zero, Zero, One, Zero); 74 this->value[3] = col_type(Zero, Zero, Zero, One); 75 } 76 77 template <typename T, precision P> 78 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 79 ( 80 tmat4x4<T, P> const & m 81 ) 82 { 83 this->value[0] = m[0]; 84 this->value[1] = m[1]; 85 this->value[2] = m[2]; 86 this->value[3] = m[3]; 87 } 88 89 template <typename T, precision P> 90 template <precision Q> 91 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 92 ( 93 tmat4x4<T, Q> const & m 94 ) 95 { 96 this->value[0] = m[0]; 97 this->value[1] = m[1]; 98 this->value[2] = m[2]; 99 this->value[3] = m[3]; 100 } 101 102 template <typename T, precision P> 103 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 104 ( 105 ctor 106 ) 107 {} 108 109 template <typename T, precision P> 110 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 111 ( 112 T const & s 113 ) 114 { 115 value_type const Zero(0); 116 this->value[0] = col_type(s, Zero, Zero, Zero); 117 this->value[1] = col_type(Zero, s, Zero, Zero); 118 this->value[2] = col_type(Zero, Zero, s, Zero); 119 this->value[3] = col_type(Zero, Zero, Zero, s); 120 } 121 122 template <typename T, precision P> 123 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 124 ( 125 T const & x0, T const & y0, T const & z0, T const & w0, 126 T const & x1, T const & y1, T const & z1, T const & w1, 127 T const & x2, T const & y2, T const & z2, T const & w2, 128 T const & x3, T const & y3, T const & z3, T const & w3 129 ) 130 { 131 this->value[0] = col_type(x0, y0, z0, w0); 132 this->value[1] = col_type(x1, y1, z1, w1); 133 this->value[2] = col_type(x2, y2, z2, w2); 134 this->value[3] = col_type(x3, y3, z3, w3); 135 } 136 137 template <typename T, precision P> 138 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 139 ( 140 col_type const & v0, 141 col_type const & v1, 142 col_type const & v2, 143 col_type const & v3 144 ) 145 { 146 this->value[0] = v0; 147 this->value[1] = v1; 148 this->value[2] = v2; 149 this->value[3] = v3; 150 } 151 152 template <typename T, precision P> 153 template <typename U, precision Q> 154 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 155 ( 156 tmat4x4<U, Q> const & m 157 ) 158 { 159 this->value[0] = col_type(m[0]); 160 this->value[1] = col_type(m[1]); 161 this->value[2] = col_type(m[2]); 162 this->value[3] = col_type(m[3]); 163 } 164 165 ////////////////////////////////////// 166 // Conversion constructors 167 template <typename T, precision P> 168 template < 169 typename X1, typename Y1, typename Z1, typename W1, 170 typename X2, typename Y2, typename Z2, typename W2, 171 typename X3, typename Y3, typename Z3, typename W3, 172 typename X4, typename Y4, typename Z4, typename W4> 173 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 174 ( 175 X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1, 176 X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2, 177 X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3, 178 X4 const & x4, Y4 const & y4, Z4 const & z4, W4 const & w4 179 ) 180 { 181 GLM_STATIC_ASSERT(std::numeric_limits<X1>::is_iec559 || std::numeric_limits<X1>::is_integer, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid."); 182 GLM_STATIC_ASSERT(std::numeric_limits<Y1>::is_iec559 || std::numeric_limits<Y1>::is_integer, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid."); 183 GLM_STATIC_ASSERT(std::numeric_limits<Z1>::is_iec559 || std::numeric_limits<Z1>::is_integer, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid."); 184 GLM_STATIC_ASSERT(std::numeric_limits<W1>::is_iec559 || std::numeric_limits<W1>::is_integer, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid."); 185 186 GLM_STATIC_ASSERT(std::numeric_limits<X2>::is_iec559 || std::numeric_limits<X2>::is_integer, "*mat4x4 constructor only takes float and integer types, 5th parameter type invalid."); 187 GLM_STATIC_ASSERT(std::numeric_limits<Y2>::is_iec559 || std::numeric_limits<Y2>::is_integer, "*mat4x4 constructor only takes float and integer types, 6th parameter type invalid."); 188 GLM_STATIC_ASSERT(std::numeric_limits<Z2>::is_iec559 || std::numeric_limits<Z2>::is_integer, "*mat4x4 constructor only takes float and integer types, 7th parameter type invalid."); 189 GLM_STATIC_ASSERT(std::numeric_limits<W2>::is_iec559 || std::numeric_limits<W2>::is_integer, "*mat4x4 constructor only takes float and integer types, 8th parameter type invalid."); 190 191 GLM_STATIC_ASSERT(std::numeric_limits<X3>::is_iec559 || std::numeric_limits<X3>::is_integer, "*mat4x4 constructor only takes float and integer types, 9th parameter type invalid."); 192 GLM_STATIC_ASSERT(std::numeric_limits<Y3>::is_iec559 || std::numeric_limits<Y3>::is_integer, "*mat4x4 constructor only takes float and integer types, 10th parameter type invalid."); 193 GLM_STATIC_ASSERT(std::numeric_limits<Z3>::is_iec559 || std::numeric_limits<Z3>::is_integer, "*mat4x4 constructor only takes float and integer types, 11th parameter type invalid."); 194 GLM_STATIC_ASSERT(std::numeric_limits<W3>::is_iec559 || std::numeric_limits<W3>::is_integer, "*mat4x4 constructor only takes float and integer types, 12th parameter type invalid."); 195 196 GLM_STATIC_ASSERT(std::numeric_limits<X4>::is_iec559 || std::numeric_limits<X4>::is_integer, "*mat4x4 constructor only takes float and integer types, 13th parameter type invalid."); 197 GLM_STATIC_ASSERT(std::numeric_limits<Y4>::is_iec559 || std::numeric_limits<Y4>::is_integer, "*mat4x4 constructor only takes float and integer types, 14th parameter type invalid."); 198 GLM_STATIC_ASSERT(std::numeric_limits<Z4>::is_iec559 || std::numeric_limits<Z4>::is_integer, "*mat4x4 constructor only takes float and integer types, 15th parameter type invalid."); 199 GLM_STATIC_ASSERT(std::numeric_limits<W4>::is_iec559 || std::numeric_limits<W4>::is_integer, "*mat4x4 constructor only takes float and integer types, 16th parameter type invalid."); 200 201 this->value[0] = col_type(static_cast<T>(x1), value_type(y1), value_type(z1), value_type(w1)); 202 this->value[1] = col_type(static_cast<T>(x2), value_type(y2), value_type(z2), value_type(w2)); 203 this->value[2] = col_type(static_cast<T>(x3), value_type(y3), value_type(z3), value_type(w3)); 204 this->value[3] = col_type(static_cast<T>(x4), value_type(y4), value_type(z4), value_type(w4)); 205 } 206 207 template <typename T, precision P> 208 template <typename V1, typename V2, typename V3, typename V4> 209 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 210 ( 211 tvec4<V1, P> const & v1, 212 tvec4<V2, P> const & v2, 213 tvec4<V3, P> const & v3, 214 tvec4<V4, P> const & v4 215 ) 216 { 217 GLM_STATIC_ASSERT(std::numeric_limits<V1>::is_iec559 || std::numeric_limits<V1>::is_integer, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid."); 218 GLM_STATIC_ASSERT(std::numeric_limits<V2>::is_iec559 || std::numeric_limits<V2>::is_integer, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid."); 219 GLM_STATIC_ASSERT(std::numeric_limits<V3>::is_iec559 || std::numeric_limits<V3>::is_integer, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid."); 220 GLM_STATIC_ASSERT(std::numeric_limits<V4>::is_iec559 || std::numeric_limits<V4>::is_integer, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid."); 221 222 this->value[0] = col_type(v1); 223 this->value[1] = col_type(v2); 224 this->value[2] = col_type(v3); 225 this->value[3] = col_type(v4); 226 } 227 228 ////////////////////////////////////// 229 // Matrix convertion constructors 230 template <typename T, precision P> 231 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 232 ( 233 tmat2x2<T, P> const & m 234 ) 235 { 236 this->value[0] = col_type(m[0], detail::tvec2<T, P>(0)); 237 this->value[1] = col_type(m[1], detail::tvec2<T, P>(0)); 238 this->value[2] = col_type(static_cast<T>(0)); 239 this->value[3] = col_type(static_cast<T>(0), value_type(0), value_type(0), value_type(1)); 240 } 241 242 template <typename T, precision P> 243 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 244 ( 245 tmat3x3<T, P> const & m 246 ) 247 { 248 this->value[0] = col_type(m[0], value_type(0)); 249 this->value[1] = col_type(m[1], value_type(0)); 250 this->value[2] = col_type(m[2], value_type(0)); 251 this->value[3] = col_type(static_cast<T>(0), value_type(0), value_type(0), value_type(1)); 252 } 253 254 template <typename T, precision P> 255 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 256 ( 257 tmat2x3<T, P> const & m 258 ) 259 { 260 this->value[0] = col_type(m[0], value_type(0)); 261 this->value[1] = col_type(m[1], value_type(0)); 262 this->value[2] = col_type(static_cast<T>(0)); 263 this->value[3] = col_type(static_cast<T>(0), value_type(0), value_type(0), value_type(1)); 264 } 265 266 template <typename T, precision P> 267 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 268 ( 269 tmat3x2<T, P> const & m 270 ) 271 { 272 this->value[0] = col_type(m[0], detail::tvec2<T, P>(0)); 273 this->value[1] = col_type(m[1], detail::tvec2<T, P>(0)); 274 this->value[2] = col_type(m[2], detail::tvec2<T, P>(0)); 275 this->value[3] = col_type(static_cast<T>(0), value_type(0), value_type(0), value_type(1)); 276 } 277 278 template <typename T, precision P> 279 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 280 ( 281 tmat2x4<T, P> const & m 282 ) 283 { 284 this->value[0] = m[0]; 285 this->value[1] = m[1]; 286 this->value[2] = col_type(T(0)); 287 this->value[3] = col_type(T(0), T(0), T(0), T(1)); 288 } 289 290 template <typename T, precision P> 291 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 292 ( 293 tmat4x2<T, P> const & m 294 ) 295 { 296 this->value[0] = col_type(m[0], detail::tvec2<T, P>(0)); 297 this->value[1] = col_type(m[1], detail::tvec2<T, P>(0)); 298 this->value[2] = col_type(T(0)); 299 this->value[3] = col_type(T(0), T(0), T(0), T(1)); 300 } 301 302 template <typename T, precision P> 303 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 304 ( 305 tmat3x4<T, P> const & m 306 ) 307 { 308 this->value[0] = m[0]; 309 this->value[1] = m[1]; 310 this->value[2] = m[2]; 311 this->value[3] = col_type(T(0), T(0), T(0), T(1)); 312 } 313 314 template <typename T, precision P> 315 GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4 316 ( 317 tmat4x3<T, P> const & m 318 ) 319 { 320 this->value[0] = col_type(m[0], T(0)); 321 this->value[1] = col_type(m[1], T(0)); 322 this->value[2] = col_type(m[2], T(0)); 323 this->value[3] = col_type(m[3], T(1)); 324 } 325 326 ////////////////////////////////////////////////////////////// 327 // Operators 328 329 template <typename T, precision P> 330 GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator= 331 ( 332 tmat4x4<T, P> const & m 333 ) 334 { 335 //memcpy could be faster 336 //memcpy(&this->value, &m.value, 16 * sizeof(valType)); 337 this->value[0] = m[0]; 338 this->value[1] = m[1]; 339 this->value[2] = m[2]; 340 this->value[3] = m[3]; 341 return *this; 342 } 343 344 template <typename T, precision P> 345 template <typename U> 346 GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator= 347 ( 348 tmat4x4<U, P> const & m 349 ) 350 { 351 //memcpy could be faster 352 //memcpy(&this->value, &m.value, 16 * sizeof(valType)); 353 this->value[0] = m[0]; 354 this->value[1] = m[1]; 355 this->value[2] = m[2]; 356 this->value[3] = m[3]; 357 return *this; 358 } 359 360 template <typename T, precision P> 361 template <typename U> 362 GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator+= (U s) 363 { 364 this->value[0] += s; 365 this->value[1] += s; 366 this->value[2] += s; 367 this->value[3] += s; 368 return *this; 369 } 370 371 template <typename T, precision P> 372 template <typename U> 373 GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator+= (tmat4x4<U, P> const & m) 374 { 375 this->value[0] += m[0]; 376 this->value[1] += m[1]; 377 this->value[2] += m[2]; 378 this->value[3] += m[3]; 379 return *this; 380 } 381 382 template <typename T, precision P> 383 template <typename U> 384 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator-= (U s) 385 { 386 this->value[0] -= s; 387 this->value[1] -= s; 388 this->value[2] -= s; 389 this->value[3] -= s; 390 return *this; 391 } 392 393 template <typename T, precision P> 394 template <typename U> 395 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator-= (tmat4x4<U, P> const & m) 396 { 397 this->value[0] -= m[0]; 398 this->value[1] -= m[1]; 399 this->value[2] -= m[2]; 400 this->value[3] -= m[3]; 401 return *this; 402 } 403 404 template <typename T, precision P> 405 template <typename U> 406 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator*= (U s) 407 { 408 this->value[0] *= s; 409 this->value[1] *= s; 410 this->value[2] *= s; 411 this->value[3] *= s; 412 return *this; 413 } 414 415 template <typename T, precision P> 416 template <typename U> 417 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator*= (tmat4x4<U, P> const & m) 418 { 419 return (*this = *this * m); 420 } 421 422 template <typename T, precision P> 423 template <typename U> 424 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator/= (U s) 425 { 426 this->value[0] /= s; 427 this->value[1] /= s; 428 this->value[2] /= s; 429 this->value[3] /= s; 430 return *this; 431 } 432 433 template <typename T, precision P> 434 template <typename U> 435 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator/= (tmat4x4<U, P> const & m) 436 { 437 return (*this = *this * detail::compute_inverse<detail::tmat4x4, T, P>::call(m)); 438 } 439 440 template <typename T, precision P> 441 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator++ () 442 { 443 ++this->value[0]; 444 ++this->value[1]; 445 ++this->value[2]; 446 ++this->value[3]; 447 return *this; 448 } 449 450 template <typename T, precision P> 451 GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator-- () 452 { 453 --this->value[0]; 454 --this->value[1]; 455 --this->value[2]; 456 --this->value[3]; 457 return *this; 458 } 459 460 template <typename T, precision P> 461 GLM_FUNC_QUALIFIER tmat4x4<T, P> tmat4x4<T, P>::operator++(int) 462 { 463 tmat4x4<T, P> Result(*this); 464 ++*this; 465 return Result; 466 } 467 468 template <typename T, precision P> 469 GLM_FUNC_QUALIFIER tmat4x4<T, P> tmat4x4<T, P>::operator--(int) 470 { 471 tmat4x4<T, P> Result(*this); 472 --*this; 473 return Result; 474 } 475 476 template <typename T, precision P> 477 struct compute_inverse<detail::tmat4x4, T, P> 478 { 479 static detail::tmat4x4<T, P> call(detail::tmat4x4<T, P> const & m) 480 { 481 T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; 482 T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; 483 T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; 484 485 T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; 486 T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; 487 T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; 488 489 T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; 490 T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; 491 T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; 492 493 T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; 494 T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; 495 T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; 496 497 T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; 498 T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; 499 T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; 500 501 T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; 502 T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; 503 T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; 504 505 detail::tvec4<T, P> Fac0(Coef00, Coef00, Coef02, Coef03); 506 detail::tvec4<T, P> Fac1(Coef04, Coef04, Coef06, Coef07); 507 detail::tvec4<T, P> Fac2(Coef08, Coef08, Coef10, Coef11); 508 detail::tvec4<T, P> Fac3(Coef12, Coef12, Coef14, Coef15); 509 detail::tvec4<T, P> Fac4(Coef16, Coef16, Coef18, Coef19); 510 detail::tvec4<T, P> Fac5(Coef20, Coef20, Coef22, Coef23); 511 512 detail::tvec4<T, P> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]); 513 detail::tvec4<T, P> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]); 514 detail::tvec4<T, P> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]); 515 detail::tvec4<T, P> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]); 516 517 detail::tvec4<T, P> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2); 518 detail::tvec4<T, P> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4); 519 detail::tvec4<T, P> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5); 520 detail::tvec4<T, P> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5); 521 522 detail::tvec4<T, P> SignA(+1, -1, +1, -1); 523 detail::tvec4<T, P> SignB(-1, +1, -1, +1); 524 detail::tmat4x4<T, P> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB); 525 526 detail::tvec4<T, P> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]); 527 528 detail::tvec4<T, P> Dot0(m[0] * Row0); 529 T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w); 530 531 T OneOverDeterminant = static_cast<T>(1) / Dot1; 532 533 return Inverse * OneOverDeterminant; 534 } 535 }; 536 537 // Binary operators 538 template <typename T, precision P> 539 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator+ 540 ( 541 tmat4x4<T, P> const & m, 542 T const & s 543 ) 544 { 545 return tmat4x4<T, P>( 546 m[0] + s, 547 m[1] + s, 548 m[2] + s, 549 m[3] + s); 550 } 551 552 template <typename T, precision P> 553 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator+ 554 ( 555 T const & s, 556 tmat4x4<T, P> const & m 557 ) 558 { 559 return tmat4x4<T, P>( 560 m[0] + s, 561 m[1] + s, 562 m[2] + s, 563 m[3] + s); 564 } 565 566 template <typename T, precision P> 567 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator+ 568 ( 569 tmat4x4<T, P> const & m1, 570 tmat4x4<T, P> const & m2 571 ) 572 { 573 return tmat4x4<T, P>( 574 m1[0] + m2[0], 575 m1[1] + m2[1], 576 m1[2] + m2[2], 577 m1[3] + m2[3]); 578 } 579 580 template <typename T, precision P> 581 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator- 582 ( 583 tmat4x4<T, P> const & m, 584 T const & s 585 ) 586 { 587 return tmat4x4<T, P>( 588 m[0] - s, 589 m[1] - s, 590 m[2] - s, 591 m[3] - s); 592 } 593 594 template <typename T, precision P> 595 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator- 596 ( 597 T const & s, 598 tmat4x4<T, P> const & m 599 ) 600 { 601 return tmat4x4<T, P>( 602 s - m[0], 603 s - m[1], 604 s - m[2], 605 s - m[3]); 606 } 607 608 template <typename T, precision P> 609 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator- 610 ( 611 tmat4x4<T, P> const & m1, 612 tmat4x4<T, P> const & m2 613 ) 614 { 615 return tmat4x4<T, P>( 616 m1[0] - m2[0], 617 m1[1] - m2[1], 618 m1[2] - m2[2], 619 m1[3] - m2[3]); 620 } 621 622 template <typename T, precision P> 623 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator* 624 ( 625 tmat4x4<T, P> const & m, 626 T const & s 627 ) 628 { 629 return tmat4x4<T, P>( 630 m[0] * s, 631 m[1] * s, 632 m[2] * s, 633 m[3] * s); 634 } 635 636 template <typename T, precision P> 637 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator* 638 ( 639 T const & s, 640 tmat4x4<T, P> const & m 641 ) 642 { 643 return tmat4x4<T, P>( 644 m[0] * s, 645 m[1] * s, 646 m[2] * s, 647 m[3] * s); 648 } 649 650 template <typename T, precision P> 651 GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type operator* 652 ( 653 tmat4x4<T, P> const & m, 654 typename tmat4x4<T, P>::row_type const & v 655 ) 656 { 657/* 658 __m128 v0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0)); 659 __m128 v1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1)); 660 __m128 v2 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2)); 661 __m128 v3 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3)); 662 663 __m128 m0 = _mm_mul_ps(m[0].data, v0); 664 __m128 m1 = _mm_mul_ps(m[1].data, v1); 665 __m128 a0 = _mm_add_ps(m0, m1); 666 667 __m128 m2 = _mm_mul_ps(m[2].data, v2); 668 __m128 m3 = _mm_mul_ps(m[3].data, v3); 669 __m128 a1 = _mm_add_ps(m2, m3); 670 671 __m128 a2 = _mm_add_ps(a0, a1); 672 673 return typename tmat4x4<T, P>::col_type(a2); 674*/ 675 676 typename tmat4x4<T, P>::col_type const Mov0(v[0]); 677 typename tmat4x4<T, P>::col_type const Mov1(v[1]); 678 typename tmat4x4<T, P>::col_type const Mul0 = m[0] * Mov0; 679 typename tmat4x4<T, P>::col_type const Mul1 = m[1] * Mov1; 680 typename tmat4x4<T, P>::col_type const Add0 = Mul0 + Mul1; 681 typename tmat4x4<T, P>::col_type const Mov2(v[2]); 682 typename tmat4x4<T, P>::col_type const Mov3(v[3]); 683 typename tmat4x4<T, P>::col_type const Mul2 = m[2] * Mov2; 684 typename tmat4x4<T, P>::col_type const Mul3 = m[3] * Mov3; 685 typename tmat4x4<T, P>::col_type const Add1 = Mul2 + Mul3; 686 typename tmat4x4<T, P>::col_type const Add2 = Add0 + Add1; 687 return Add2; 688 689/* 690 return typename tmat4x4<T, P>::col_type( 691 m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3], 692 m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3], 693 m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3], 694 m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3]); 695*/ 696 } 697 698 template <typename T, precision P> 699 GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::row_type operator* 700 ( 701 typename tmat4x4<T, P>::col_type const & v, 702 tmat4x4<T, P> const & m 703 ) 704 { 705 return typename tmat4x4<T, P>::row_type( 706 m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3], 707 m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3], 708 m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3], 709 m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]); 710 } 711 712 template <typename T, precision P> 713 GLM_FUNC_QUALIFIER tmat2x4<T, P> operator* 714 ( 715 tmat4x4<T, P> const & m1, 716 tmat2x4<T, P> const & m2 717 ) 718 { 719 return tmat2x4<T, P>( 720 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], 721 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], 722 m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], 723 m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3], 724 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], 725 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], 726 m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], 727 m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3]); 728 } 729 730 template <typename T, precision P> 731 GLM_FUNC_QUALIFIER tmat3x4<T, P> operator* 732 ( 733 tmat4x4<T, P> const & m1, 734 tmat3x4<T, P> const & m2 735 ) 736 { 737 return tmat3x4<T, P>( 738 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], 739 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], 740 m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], 741 m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3], 742 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], 743 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], 744 m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], 745 m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3], 746 m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], 747 m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], 748 m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3], 749 m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]); 750 } 751 752 template <typename T, precision P> 753 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator* 754 ( 755 tmat4x4<T, P> const & m1, 756 tmat4x4<T, P> const & m2 757 ) 758 { 759 typename tmat4x4<T, P>::col_type const SrcA0 = m1[0]; 760 typename tmat4x4<T, P>::col_type const SrcA1 = m1[1]; 761 typename tmat4x4<T, P>::col_type const SrcA2 = m1[2]; 762 typename tmat4x4<T, P>::col_type const SrcA3 = m1[3]; 763 764 typename tmat4x4<T, P>::col_type const SrcB0 = m2[0]; 765 typename tmat4x4<T, P>::col_type const SrcB1 = m2[1]; 766 typename tmat4x4<T, P>::col_type const SrcB2 = m2[2]; 767 typename tmat4x4<T, P>::col_type const SrcB3 = m2[3]; 768 769 tmat4x4<T, P> Result(tmat4x4<T, P>::_null); 770 Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3]; 771 Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3]; 772 Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3]; 773 Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3]; 774 return Result; 775 } 776 777 template <typename T, precision P> 778 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator/ 779 ( 780 tmat4x4<T, P> const & m, 781 T const & s 782 ) 783 { 784 return tmat4x4<T, P>( 785 m[0] / s, 786 m[1] / s, 787 m[2] / s, 788 m[3] / s); 789 } 790 791 template <typename T, precision P> 792 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator/ 793 ( 794 T const & s, 795 tmat4x4<T, P> const & m 796 ) 797 { 798 return tmat4x4<T, P>( 799 s / m[0], 800 s / m[1], 801 s / m[2], 802 s / m[3]); 803 } 804 805 template <typename T, precision P> 806 GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type operator/ 807 ( 808 tmat4x4<T, P> const & m, 809 typename tmat4x4<T, P>::row_type const & v 810 ) 811 { 812 return detail::compute_inverse<detail::tmat4x4, T, P>::call(m) * v; 813 } 814 815 template <typename T, precision P> 816 GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::row_type operator/ 817 ( 818 typename tmat4x4<T, P>::col_type const & v, 819 tmat4x4<T, P> const & m 820 ) 821 { 822 return v * detail::compute_inverse<detail::tmat4x4, T, P>::call(m); 823 } 824 825 template <typename T, precision P> 826 GLM_FUNC_QUALIFIER tmat4x4<T, P> operator/ 827 ( 828 tmat4x4<T, P> const & m1, 829 tmat4x4<T, P> const & m2 830 ) 831 { 832 tmat4x4<T, P> m1_copy(m1); 833 return m1_copy /= m2; 834 } 835 836 // Unary constant operators 837 template <typename T, precision P> 838 GLM_FUNC_QUALIFIER tmat4x4<T, P> const operator- 839 ( 840 tmat4x4<T, P> const & m 841 ) 842 { 843 return tmat4x4<T, P>( 844 -m[0], 845 -m[1], 846 -m[2], 847 -m[3]); 848 } 849 850 template <typename T, precision P> 851 GLM_FUNC_QUALIFIER tmat4x4<T, P> const operator++ 852 ( 853 tmat4x4<T, P> const & m, 854 int 855 ) 856 { 857 return tmat4x4<T, P>( 858 m[0] + static_cast<T>(1), 859 m[1] + static_cast<T>(1), 860 m[2] + static_cast<T>(1), 861 m[3] + static_cast<T>(1)); 862 } 863 864 template <typename T, precision P> 865 GLM_FUNC_QUALIFIER tmat4x4<T, P> const operator-- 866 ( 867 tmat4x4<T, P> const & m, 868 int 869 ) 870 { 871 return tmat4x4<T, P>( 872 m[0] - static_cast<T>(1), 873 m[1] - static_cast<T>(1), 874 m[2] - static_cast<T>(1), 875 m[3] - static_cast<T>(1)); 876 } 877 878 ////////////////////////////////////// 879 // Boolean operators 880 881 template <typename T, precision P> 882 GLM_FUNC_QUALIFIER bool operator== 883 ( 884 tmat4x4<T, P> const & m1, 885 tmat4x4<T, P> const & m2 886 ) 887 { 888 return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); 889 } 890 891 template <typename T, precision P> 892 GLM_FUNC_QUALIFIER bool operator!= 893 ( 894 tmat4x4<T, P> const & m1, 895 tmat4x4<T, P> const & m2 896 ) 897 { 898 return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); 899 } 900 901} //namespace detail 902} //namespace glm 903