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_mat2x2.inl 25/// @date 2005-01-16 / 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 tmat2x2<T, P>::length() const 34 { 35 return 2; 36 } 37 38 ////////////////////////////////////// 39 // Accesses 40 41 template <typename T, precision P> 42 GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type & 43 tmat2x2<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 tmat2x2<T, P>::col_type const & 54 tmat2x2<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 tmat2x2<T, P>::tmat2x2() 68 { 69 this->value[0] = col_type(1, 0); 70 this->value[1] = col_type(0, 1); 71 } 72 73 template <typename T, precision P> 74 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 75 ( 76 tmat2x2<T, P> const & m 77 ) 78 { 79 this->value[0] = m.value[0]; 80 this->value[1] = m.value[1]; 81 } 82 83 template <typename T, precision P> 84 template <precision Q> 85 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2( 86 tmat2x2<T, Q> const & m) 87 { 88 this->value[0] = m.value[0]; 89 this->value[1] = m.value[1]; 90 } 91 92 template <typename T, precision P> 93 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 94 ( 95 ctor 96 ) 97 {} 98 99 template <typename T, precision P> 100 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 101 ( 102 T const & s 103 ) 104 { 105 value_type const Zero(0); 106 this->value[0] = col_type(s, Zero); 107 this->value[1] = col_type(Zero, s); 108 } 109 110 template <typename T, precision P> 111 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 112 ( 113 T const & x0, T const & y0, 114 T const & x1, T const & y1 115 ) 116 { 117 this->value[0] = col_type(x0, y0); 118 this->value[1] = col_type(x1, y1); 119 } 120 121 template <typename T, precision P> 122 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 123 ( 124 col_type const & v0, 125 col_type const & v1 126 ) 127 { 128 this->value[0] = v0; 129 this->value[1] = v1; 130 } 131 132 ////////////////////////////////////// 133 // Conversion constructors 134 template <typename T, precision P> 135 template <typename X1, typename Y1, typename X2, typename Y2> 136 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 137 ( 138 X1 const & x1, Y1 const & y1, 139 X2 const & x2, Y2 const & y2 140 ) 141 { 142 this->value[0] = col_type(static_cast<T>(x1), value_type(y1)); 143 this->value[1] = col_type(static_cast<T>(x2), value_type(y2)); 144 } 145 146 template <typename T, precision P> 147 template <typename V1, typename V2> 148 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 149 ( 150 tvec2<V1, P> const & v1, 151 tvec2<V2, P> const & v2 152 ) 153 { 154 this->value[0] = col_type(v1); 155 this->value[1] = col_type(v2); 156 } 157 158 ////////////////////////////////////////////////////////////// 159 // mat2x2 matrix conversions 160 161 template <typename T, precision P> 162 template <typename U, precision Q> 163 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 164 ( 165 tmat2x2<U, Q> const & m 166 ) 167 { 168 this->value[0] = col_type(m[0]); 169 this->value[1] = col_type(m[1]); 170 } 171 172 template <typename T, precision P> 173 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 174 ( 175 tmat3x3<T, P> const & m 176 ) 177 { 178 this->value[0] = col_type(m[0]); 179 this->value[1] = col_type(m[1]); 180 } 181 182 template <typename T, precision P> 183 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 184 ( 185 tmat4x4<T, P> const & m 186 ) 187 { 188 this->value[0] = col_type(m[0]); 189 this->value[1] = col_type(m[1]); 190 } 191 192 template <typename T, precision P> 193 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 194 ( 195 tmat2x3<T, P> const & m 196 ) 197 { 198 this->value[0] = col_type(m[0]); 199 this->value[1] = col_type(m[1]); 200 } 201 202 template <typename T, precision P> 203 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 204 ( 205 tmat3x2<T, P> const & m 206 ) 207 { 208 this->value[0] = m[0]; 209 this->value[1] = m[1]; 210 } 211 212 template <typename T, precision P> 213 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 214 ( 215 tmat2x4<T, P> const & m 216 ) 217 { 218 this->value[0] = col_type(m[0]); 219 this->value[1] = col_type(m[1]); 220 } 221 222 template <typename T, precision P> 223 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 224 ( 225 tmat4x2<T, P> const & m 226 ) 227 { 228 this->value[0] = m[0]; 229 this->value[1] = m[1]; 230 } 231 232 template <typename T, precision P> 233 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 234 ( 235 tmat3x4<T, P> const & m 236 ) 237 { 238 this->value[0] = col_type(m[0]); 239 this->value[1] = col_type(m[1]); 240 } 241 242 template <typename T, precision P> 243 GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2 244 ( 245 tmat4x3<T, P> const & m 246 ) 247 { 248 this->value[0] = col_type(m[0]); 249 this->value[1] = col_type(m[1]); 250 } 251 252 ////////////////////////////////////////////////////////////// 253 // mat2x2 operators 254 255 // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared 256 template <typename T, precision P> 257 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator= (tmat2x2<T, P> const & m) 258 { 259 this->value[0] = m[0]; 260 this->value[1] = m[1]; 261 return *this; 262 } 263 264 template <typename T, precision P> 265 template <typename U> 266 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator= (tmat2x2<U, P> const & m) 267 { 268 this->value[0] = m[0]; 269 this->value[1] = m[1]; 270 return *this; 271 } 272 273 template <typename T, precision P> 274 template <typename U> 275 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator+= (U s) 276 { 277 this->value[0] += s; 278 this->value[1] += s; 279 return *this; 280 } 281 282 template <typename T, precision P> 283 template <typename U> 284 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator+= (tmat2x2<U, P> const & m) 285 { 286 this->value[0] += m[0]; 287 this->value[1] += m[1]; 288 return *this; 289 } 290 291 template <typename T, precision P> 292 template <typename U> 293 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-= (U s) 294 { 295 this->value[0] -= s; 296 this->value[1] -= s; 297 return *this; 298 } 299 300 template <typename T, precision P> 301 template <typename U> 302 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-= (tmat2x2<U, P> const & m) 303 { 304 this->value[0] -= m[0]; 305 this->value[1] -= m[1]; 306 return *this; 307 } 308 309 template <typename T, precision P> 310 template <typename U> 311 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator*= (U s) 312 { 313 this->value[0] *= s; 314 this->value[1] *= s; 315 return *this; 316 } 317 318 template <typename T, precision P> 319 template <typename U> 320 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator*= (tmat2x2<U, P> const & m) 321 { 322 return (*this = *this * m); 323 } 324 325 template <typename T, precision P> 326 template <typename U> 327 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/= (U s) 328 { 329 this->value[0] /= s; 330 this->value[1] /= s; 331 return *this; 332 } 333 334 template <typename T, precision P> 335 template <typename U> 336 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/= (tmat2x2<U, P> const & m) 337 { 338 return (*this = *this * detail::compute_inverse<detail::tmat2x2, T, P>::call(m)); 339 } 340 341 template <typename T, precision P> 342 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator++() 343 { 344 ++this->value[0]; 345 ++this->value[1]; 346 return *this; 347 } 348 349 template <typename T, precision P> 350 GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator--() 351 { 352 --this->value[0]; 353 --this->value[1]; 354 return *this; 355 } 356 357 template <typename T, precision P> 358 GLM_FUNC_QUALIFIER tmat2x2<T, P> tmat2x2<T, P>::operator++(int) 359 { 360 tmat2x2<T, P> Result(*this); 361 ++*this; 362 return Result; 363 } 364 365 template <typename T, precision P> 366 GLM_FUNC_QUALIFIER tmat2x2<T, P> tmat2x2<T, P>::operator--(int) 367 { 368 tmat2x2<T, P> Result(*this); 369 --*this; 370 return Result; 371 } 372 373 template <typename T, precision P> 374 struct compute_inverse<detail::tmat2x2, T, P> 375 { 376 GLM_FUNC_QUALIFIER static detail::tmat2x2<T, P> call(detail::tmat2x2<T, P> const & m) 377 { 378 T OneOverDeterminant = static_cast<T>(1) / ( 379 + m[0][0] * m[1][1] 380 - m[1][0] * m[0][1]); 381 382 detail::tmat2x2<T, P> Inverse( 383 + m[1][1] * OneOverDeterminant, 384 - m[0][1] * OneOverDeterminant, 385 - m[1][0] * OneOverDeterminant, 386 + m[0][0] * OneOverDeterminant); 387 388 return Inverse; 389 } 390 }; 391 392 ////////////////////////////////////////////////////////////// 393 // Binary operators 394 395 template <typename T, precision P> 396 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+ 397 ( 398 tmat2x2<T, P> const & m, 399 T const & s 400 ) 401 { 402 return tmat2x2<T, P>( 403 m[0] + s, 404 m[1] + s); 405 } 406 407 template <typename T, precision P> 408 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+ 409 ( 410 T const & s, 411 tmat2x2<T, P> const & m 412 ) 413 { 414 return tmat2x2<T, P>( 415 m[0] + s, 416 m[1] + s); 417 } 418 419 template <typename T, precision P> 420 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+ 421 ( 422 tmat2x2<T, P> const & m1, 423 tmat2x2<T, P> const & m2 424 ) 425 { 426 return tmat2x2<T, P>( 427 m1[0] + m2[0], 428 m1[1] + m2[1]); 429 } 430 431 template <typename T, precision P> 432 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator- 433 ( 434 tmat2x2<T, P> const & m, 435 T const & s 436 ) 437 { 438 return tmat2x2<T, P>( 439 m[0] - s, 440 m[1] - s); 441 } 442 443 template <typename T, precision P> 444 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator- 445 ( 446 T const & s, 447 tmat2x2<T, P> const & m 448 ) 449 { 450 return tmat2x2<T, P>( 451 s - m[0], 452 s - m[1]); 453 } 454 455 template <typename T, precision P> 456 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator- 457 ( 458 tmat2x2<T, P> const & m1, 459 tmat2x2<T, P> const & m2 460 ) 461 { 462 return tmat2x2<T, P>( 463 m1[0] - m2[0], 464 m1[1] - m2[1]); 465 } 466 467 template <typename T, precision P> 468 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator* 469 ( 470 tmat2x2<T, P> const & m, 471 T const & s 472 ) 473 { 474 return tmat2x2<T, P>( 475 m[0] * s, 476 m[1] * s); 477 } 478 479 template <typename T, precision P> 480 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator* 481 ( 482 T const & s, 483 tmat2x2<T, P> const & m 484 ) 485 { 486 return tmat2x2<T, P>( 487 m[0] * s, 488 m[1] * s); 489 } 490 491 template <typename T, precision P> 492 GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator* 493 ( 494 tmat2x2<T, P> const & m, 495 typename tmat2x2<T, P>::row_type const & v 496 ) 497 { 498 return detail::tvec2<T, P>( 499 m[0][0] * v.x + m[1][0] * v.y, 500 m[0][1] * v.x + m[1][1] * v.y); 501 } 502 503 template <typename T, precision P> 504 GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator* 505 ( 506 typename tmat2x2<T, P>::col_type const & v, 507 tmat2x2<T, P> const & m 508 ) 509 { 510 return detail::tvec2<T, P>( 511 v.x * m[0][0] + v.y * m[0][1], 512 v.x * m[1][0] + v.y * m[1][1]); 513 } 514 515 template <typename T, precision P> 516 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator* 517 ( 518 tmat2x2<T, P> const & m1, 519 tmat2x2<T, P> const & m2 520 ) 521 { 522 return tmat2x2<T, P>( 523 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], 524 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], 525 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], 526 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]); 527 } 528 529 template <typename T, precision P> 530 GLM_FUNC_QUALIFIER tmat3x2<T, P> operator* 531 ( 532 tmat2x2<T, P> const & m1, 533 tmat3x2<T, P> const & m2 534 ) 535 { 536 return tmat3x2<T, P>( 537 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], 538 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], 539 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], 540 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], 541 m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], 542 m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1]); 543 } 544 545 template <typename T, precision P> 546 GLM_FUNC_QUALIFIER tmat4x2<T, P> operator* 547 ( 548 tmat2x2<T, P> const & m1, 549 tmat4x2<T, P> const & m2 550 ) 551 { 552 return tmat4x2<T, P>( 553 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], 554 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], 555 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], 556 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], 557 m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], 558 m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], 559 m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1], 560 m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1]); 561 } 562 563 template <typename T, precision P> 564 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/ 565 ( 566 tmat2x2<T, P> const & m, 567 T const & s 568 ) 569 { 570 return tmat2x2<T, P>( 571 m[0] / s, 572 m[1] / s); 573 } 574 575 template <typename T, precision P> 576 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/ 577 ( 578 T const & s, 579 tmat2x2<T, P> const & m 580 ) 581 { 582 return tmat2x2<T, P>( 583 s / m[0], 584 s / m[1]); 585 } 586 587 template <typename T, precision P> 588 GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator/ 589 ( 590 tmat2x2<T, P> const & m, 591 typename tmat2x2<T, P>::row_type & v 592 ) 593 { 594 return detail::compute_inverse<detail::tmat2x2, T, P>::call(m) * v; 595 } 596 597 template <typename T, precision P> 598 GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator/ 599 ( 600 typename tmat2x2<T, P>::col_type const & v, 601 tmat2x2<T, P> const & m 602 ) 603 { 604 return v * detail::compute_inverse<detail::tmat2x2, T, P>::call(m); 605 } 606 607 template <typename T, precision P> 608 GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/ 609 ( 610 tmat2x2<T, P> const & m1, 611 tmat2x2<T, P> const & m2 612 ) 613 { 614 tmat2x2<T, P> m1_copy(m1); 615 return m1_copy /= m2; 616 } 617 618 // Unary constant operators 619 template <typename T, precision P> 620 GLM_FUNC_QUALIFIER tmat2x2<T, P> const operator- 621 ( 622 tmat2x2<T, P> const & m 623 ) 624 { 625 return tmat2x2<T, P>( 626 -m[0], 627 -m[1]); 628 } 629 630 ////////////////////////////////////// 631 // Boolean operators 632 633 template <typename T, precision P> 634 GLM_FUNC_QUALIFIER bool operator== 635 ( 636 tmat2x2<T, P> const & m1, 637 tmat2x2<T, P> const & m2 638 ) 639 { 640 return (m1[0] == m2[0]) && (m1[1] == m2[1]); 641 } 642 643 template <typename T, precision P> 644 GLM_FUNC_QUALIFIER bool operator!= 645 ( 646 tmat2x2<T, P> const & m1, 647 tmat2x2<T, P> const & m2 648 ) 649 { 650 return (m1[0] != m2[0]) || (m1[1] != m2[1]); 651 } 652 653} //namespace detail 654} //namespace glm 655