1 /* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef VECMATH_H_ 18 #define VECMATH_H_ 19 20 #include <math.h> 21 #include "JNIHelper.h" 22 23 namespace ndk_helper 24 { 25 26 /****************************************************************** 27 * Helper class for vector math operations 28 * Currently all implementations are in pure C++. 29 * Each class is an opaque class so caller does not have a direct access 30 * to each element. This is for an ease of future optimization to use vector operations. 31 * 32 */ 33 34 class Vec2; 35 class Vec3; 36 class Vec4; 37 class Mat4; 38 39 /****************************************************************** 40 * 2 elements vector class 41 * 42 */ 43 class Vec2 44 { 45 private: 46 float x_; 47 float y_; 48 49 public: 50 friend class Vec3; 51 friend class Vec4; 52 friend class Mat4; 53 friend class Quaternion; 54 55 Vec2() 56 { 57 x_ = y_ = 0.f; 58 } 59 60 Vec2( const float fX, const float fY ) 61 { 62 x_ = fX; 63 y_ = fY; 64 } 65 66 Vec2( const Vec2& vec ) 67 { 68 x_ = vec.x_; 69 y_ = vec.y_; 70 } 71 72 Vec2( const float* pVec ) 73 { 74 x_ = (*pVec++); 75 y_ = (*pVec++); 76 } 77 78 //Operators 79 Vec2 operator*( const Vec2& rhs ) const 80 { 81 Vec2 ret; 82 ret.x_ = x_ * rhs.x_; 83 ret.y_ = y_ * rhs.y_; 84 return ret; 85 } 86 87 Vec2 operator/( const Vec2& rhs ) const 88 { 89 Vec2 ret; 90 ret.x_ = x_ / rhs.x_; 91 ret.y_ = y_ / rhs.y_; 92 return ret; 93 } 94 95 Vec2 operator+( const Vec2& rhs ) const 96 { 97 Vec2 ret; 98 ret.x_ = x_ + rhs.x_; 99 ret.y_ = y_ + rhs.y_; 100 return ret; 101 } 102 103 Vec2 operator-( const Vec2& rhs ) const 104 { 105 Vec2 ret; 106 ret.x_ = x_ - rhs.x_; 107 ret.y_ = y_ - rhs.y_; 108 return ret; 109 } 110 111 Vec2& operator+=( const Vec2& rhs ) 112 { 113 x_ += rhs.x_; 114 y_ += rhs.y_; 115 return *this; 116 } 117 118 Vec2& operator-=( const Vec2& rhs ) 119 { 120 x_ -= rhs.x_; 121 y_ -= rhs.y_; 122 return *this; 123 } 124 125 Vec2& operator*=( const Vec2& rhs ) 126 { 127 x_ *= rhs.x_; 128 y_ *= rhs.y_; 129 return *this; 130 } 131 132 Vec2& operator/=( const Vec2& rhs ) 133 { 134 x_ /= rhs.x_; 135 y_ /= rhs.y_; 136 return *this; 137 } 138 139 //External operators 140 friend Vec2 operator-( const Vec2& rhs ) 141 { 142 return Vec2( rhs ) *= -1; 143 } 144 145 friend Vec2 operator*( const float lhs, const Vec2& rhs ) 146 { 147 Vec2 ret; 148 ret.x_ = lhs * rhs.x_; 149 ret.y_ = lhs * rhs.y_; 150 return ret; 151 } 152 153 friend Vec2 operator/( const float lhs, const Vec2& rhs ) 154 { 155 Vec2 ret; 156 ret.x_ = lhs / rhs.x_; 157 ret.y_ = lhs / rhs.y_; 158 return ret; 159 } 160 161 //Operators with float 162 Vec2 operator*( const float& rhs ) const 163 { 164 Vec2 ret; 165 ret.x_ = x_ * rhs; 166 ret.y_ = y_ * rhs; 167 return ret; 168 } 169 170 Vec2& operator*=( const float& rhs ) 171 { 172 x_ = x_ * rhs; 173 y_ = y_ * rhs; 174 return *this; 175 } 176 177 Vec2 operator/( const float& rhs ) const 178 { 179 Vec2 ret; 180 ret.x_ = x_ / rhs; 181 ret.y_ = y_ / rhs; 182 return ret; 183 } 184 185 Vec2& operator/=( const float& rhs ) 186 { 187 x_ = x_ / rhs; 188 y_ = y_ / rhs; 189 return *this; 190 } 191 192 //Compare 193 bool operator==( const Vec2& rhs ) const 194 { 195 if( x_ != rhs.x_ || y_ != rhs.y_ ) 196 return false; 197 return true; 198 } 199 200 bool operator!=( const Vec2& rhs ) const 201 { 202 if( x_ == rhs.x_ ) 203 return false; 204 205 return true; 206 } 207 208 float Length() const 209 { 210 return sqrtf( x_ * x_ + y_ * y_ ); 211 } 212 213 Vec2 Normalize() 214 { 215 float len = Length(); 216 x_ = x_ / len; 217 y_ = y_ / len; 218 return *this; 219 } 220 221 float Dot( const Vec2& rhs ) 222 { 223 return x_ * rhs.x_ + y_ * rhs.y_; 224 } 225 226 bool Validate() 227 { 228 if( isnan( x_ ) || isnan( y_ ) ) 229 return false; 230 return true; 231 } 232 233 void Value( float& fX, float& fY ) 234 { 235 fX = x_; 236 fY = y_; 237 } 238 239 void Dump() 240 { 241 LOGI( "Vec2 %f %f", x_, y_ ); 242 } 243 }; 244 245 /****************************************************************** 246 * 3 elements vector class 247 * 248 */ 249 class Vec3 250 { 251 private: 252 float x_, y_, z_; 253 254 public: 255 friend class Vec4; 256 friend class Mat4; 257 friend class Quaternion; 258 259 Vec3() 260 { 261 x_ = y_ = z_ = 0.f; 262 } 263 264 Vec3( const float fX, const float fY, const float fZ ) 265 { 266 x_ = fX; 267 y_ = fY; 268 z_ = fZ; 269 } 270 271 Vec3( const Vec3& vec ) 272 { 273 x_ = vec.x_; 274 y_ = vec.y_; 275 z_ = vec.z_; 276 } 277 278 Vec3( const float* pVec ) 279 { 280 x_ = (*pVec++); 281 y_ = (*pVec++); 282 z_ = *pVec; 283 } 284 285 Vec3( const Vec2& vec, float f ) 286 { 287 x_ = vec.x_; 288 y_ = vec.y_; 289 z_ = f; 290 } 291 292 Vec3( const Vec4& vec ); 293 294 //Operators 295 Vec3 operator*( const Vec3& rhs ) const 296 { 297 Vec3 ret; 298 ret.x_ = x_ * rhs.x_; 299 ret.y_ = y_ * rhs.y_; 300 ret.z_ = z_ * rhs.z_; 301 return ret; 302 } 303 304 Vec3 operator/( const Vec3& rhs ) const 305 { 306 Vec3 ret; 307 ret.x_ = x_ / rhs.x_; 308 ret.y_ = y_ / rhs.y_; 309 ret.z_ = z_ / rhs.z_; 310 return ret; 311 } 312 313 Vec3 operator+( const Vec3& rhs ) const 314 { 315 Vec3 ret; 316 ret.x_ = x_ + rhs.x_; 317 ret.y_ = y_ + rhs.y_; 318 ret.z_ = z_ + rhs.z_; 319 return ret; 320 } 321 322 Vec3 operator-( const Vec3& rhs ) const 323 { 324 Vec3 ret; 325 ret.x_ = x_ - rhs.x_; 326 ret.y_ = y_ - rhs.y_; 327 ret.z_ = z_ - rhs.z_; 328 return ret; 329 } 330 331 Vec3& operator+=( const Vec3& rhs ) 332 { 333 x_ += rhs.x_; 334 y_ += rhs.y_; 335 z_ += rhs.z_; 336 return *this; 337 } 338 339 Vec3& operator-=( const Vec3& rhs ) 340 { 341 x_ -= rhs.x_; 342 y_ -= rhs.y_; 343 z_ -= rhs.z_; 344 return *this; 345 } 346 347 Vec3& operator*=( const Vec3& rhs ) 348 { 349 x_ *= rhs.x_; 350 y_ *= rhs.y_; 351 z_ *= rhs.z_; 352 return *this; 353 } 354 355 Vec3& operator/=( const Vec3& rhs ) 356 { 357 x_ /= rhs.x_; 358 y_ /= rhs.y_; 359 z_ /= rhs.z_; 360 return *this; 361 } 362 363 //External operators 364 friend Vec3 operator-( const Vec3& rhs ) 365 { 366 return Vec3( rhs ) *= -1; 367 } 368 369 friend Vec3 operator*( const float lhs, const Vec3& rhs ) 370 { 371 Vec3 ret; 372 ret.x_ = lhs * rhs.x_; 373 ret.y_ = lhs * rhs.y_; 374 ret.z_ = lhs * rhs.z_; 375 return ret; 376 } 377 378 friend Vec3 operator/( const float lhs, const Vec3& rhs ) 379 { 380 Vec3 ret; 381 ret.x_ = lhs / rhs.x_; 382 ret.y_ = lhs / rhs.y_; 383 ret.z_ = lhs / rhs.z_; 384 return ret; 385 } 386 387 //Operators with float 388 Vec3 operator*( const float& rhs ) const 389 { 390 Vec3 ret; 391 ret.x_ = x_ * rhs; 392 ret.y_ = y_ * rhs; 393 ret.z_ = z_ * rhs; 394 return ret; 395 } 396 397 Vec3& operator*=( const float& rhs ) 398 { 399 x_ = x_ * rhs; 400 y_ = y_ * rhs; 401 z_ = z_ * rhs; 402 return *this; 403 } 404 405 Vec3 operator/( const float& rhs ) const 406 { 407 Vec3 ret; 408 ret.x_ = x_ / rhs; 409 ret.y_ = y_ / rhs; 410 ret.z_ = z_ / rhs; 411 return ret; 412 } 413 414 Vec3& operator/=( const float& rhs ) 415 { 416 x_ = x_ / rhs; 417 y_ = y_ / rhs; 418 z_ = z_ / rhs; 419 return *this; 420 } 421 422 //Compare 423 bool operator==( const Vec3& rhs ) const 424 { 425 if( x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ ) 426 return false; 427 return true; 428 } 429 430 bool operator!=( const Vec3& rhs ) const 431 { 432 if( x_ == rhs.x_ ) 433 return false; 434 435 return true; 436 } 437 438 float Length() const 439 { 440 return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ ); 441 } 442 443 Vec3 Normalize() 444 { 445 float len = Length(); 446 x_ = x_ / len; 447 y_ = y_ / len; 448 z_ = z_ / len; 449 return *this; 450 } 451 452 float Dot( const Vec3& rhs ) 453 { 454 return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; 455 } 456 457 Vec3 Cross( const Vec3& rhs ) 458 { 459 Vec3 ret; 460 ret.x_ = y_ * rhs.z_ - z_ * rhs.y_; 461 ret.y_ = z_ * rhs.x_ - x_ * rhs.z_; 462 ret.z_ = x_ * rhs.y_ - y_ * rhs.x_; 463 return ret; 464 } 465 466 bool Validate() 467 { 468 if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) ) 469 return false; 470 return true; 471 } 472 473 void Value( float& fX, float& fY, float& fZ ) 474 { 475 fX = x_; 476 fY = y_; 477 fZ = z_; 478 } 479 480 void Dump() 481 { 482 LOGI( "Vec3 %f %f %f", x_, y_, z_ ); 483 } 484 }; 485 486 /****************************************************************** 487 * 4 elements vector class 488 * 489 */ 490 class Vec4 491 { 492 private: 493 float x_, y_, z_, w_; 494 495 public: 496 friend class Vec3; 497 friend class Mat4; 498 friend class Quaternion; 499 500 Vec4() 501 { 502 x_ = y_ = z_ = w_ = 0.f; 503 } 504 505 Vec4( const float fX, const float fY, const float fZ, const float fW ) 506 { 507 x_ = fX; 508 y_ = fY; 509 z_ = fZ; 510 w_ = fW; 511 } 512 513 Vec4( const Vec4& vec ) 514 { 515 x_ = vec.x_; 516 y_ = vec.y_; 517 z_ = vec.z_; 518 w_ = vec.w_; 519 } 520 521 Vec4( const Vec3& vec, const float fW ) 522 { 523 x_ = vec.x_; 524 y_ = vec.y_; 525 z_ = vec.z_; 526 w_ = fW; 527 } 528 529 Vec4( const float* pVec ) 530 { 531 x_ = (*pVec++); 532 y_ = (*pVec++); 533 z_ = *pVec; 534 w_ = *pVec; 535 } 536 537 //Operators 538 Vec4 operator*( const Vec4& rhs ) const 539 { 540 Vec4 ret; 541 ret.x_ = x_ * rhs.x_; 542 ret.y_ = y_ * rhs.y_; 543 ret.z_ = z_ * rhs.z_; 544 ret.w_ = z_ * rhs.w_; 545 return ret; 546 } 547 548 Vec4 operator/( const Vec4& rhs ) const 549 { 550 Vec4 ret; 551 ret.x_ = x_ / rhs.x_; 552 ret.y_ = y_ / rhs.y_; 553 ret.z_ = z_ / rhs.z_; 554 ret.w_ = z_ / rhs.w_; 555 return ret; 556 } 557 558 Vec4 operator+( const Vec4& rhs ) const 559 { 560 Vec4 ret; 561 ret.x_ = x_ + rhs.x_; 562 ret.y_ = y_ + rhs.y_; 563 ret.z_ = z_ + rhs.z_; 564 ret.w_ = z_ + rhs.w_; 565 return ret; 566 } 567 568 Vec4 operator-( const Vec4& rhs ) const 569 { 570 Vec4 ret; 571 ret.x_ = x_ - rhs.x_; 572 ret.y_ = y_ - rhs.y_; 573 ret.z_ = z_ - rhs.z_; 574 ret.w_ = z_ - rhs.w_; 575 return ret; 576 } 577 578 Vec4& operator+=( const Vec4& rhs ) 579 { 580 x_ += rhs.x_; 581 y_ += rhs.y_; 582 z_ += rhs.z_; 583 w_ += rhs.w_; 584 return *this; 585 } 586 587 Vec4& operator-=( const Vec4& rhs ) 588 { 589 x_ -= rhs.x_; 590 y_ -= rhs.y_; 591 z_ -= rhs.z_; 592 w_ -= rhs.w_; 593 return *this; 594 } 595 596 Vec4& operator*=( const Vec4& rhs ) 597 { 598 x_ *= rhs.x_; 599 y_ *= rhs.y_; 600 z_ *= rhs.z_; 601 w_ *= rhs.w_; 602 return *this; 603 } 604 605 Vec4& operator/=( const Vec4& rhs ) 606 { 607 x_ /= rhs.x_; 608 y_ /= rhs.y_; 609 z_ /= rhs.z_; 610 w_ /= rhs.w_; 611 return *this; 612 } 613 614 //External operators 615 friend Vec4 operator-( const Vec4& rhs ) 616 { 617 return Vec4( rhs ) *= -1; 618 } 619 620 friend Vec4 operator*( const float lhs, const Vec4& rhs ) 621 { 622 Vec4 ret; 623 ret.x_ = lhs * rhs.x_; 624 ret.y_ = lhs * rhs.y_; 625 ret.z_ = lhs * rhs.z_; 626 ret.w_ = lhs * rhs.w_; 627 return ret; 628 } 629 630 friend Vec4 operator/( const float lhs, const Vec4& rhs ) 631 { 632 Vec4 ret; 633 ret.x_ = lhs / rhs.x_; 634 ret.y_ = lhs / rhs.y_; 635 ret.z_ = lhs / rhs.z_; 636 ret.w_ = lhs / rhs.w_; 637 return ret; 638 } 639 640 //Operators with float 641 Vec4 operator*( const float& rhs ) const 642 { 643 Vec4 ret; 644 ret.x_ = x_ * rhs; 645 ret.y_ = y_ * rhs; 646 ret.z_ = z_ * rhs; 647 ret.w_ = w_ * rhs; 648 return ret; 649 } 650 651 Vec4& operator*=( const float& rhs ) 652 { 653 x_ = x_ * rhs; 654 y_ = y_ * rhs; 655 z_ = z_ * rhs; 656 w_ = w_ * rhs; 657 return *this; 658 } 659 660 Vec4 operator/( const float& rhs ) const 661 { 662 Vec4 ret; 663 ret.x_ = x_ / rhs; 664 ret.y_ = y_ / rhs; 665 ret.z_ = z_ / rhs; 666 ret.w_ = w_ / rhs; 667 return ret; 668 } 669 670 Vec4& operator/=( const float& rhs ) 671 { 672 x_ = x_ / rhs; 673 y_ = y_ / rhs; 674 z_ = z_ / rhs; 675 w_ = w_ / rhs; 676 return *this; 677 } 678 679 //Compare 680 bool operator==( const Vec4& rhs ) const 681 { 682 if( x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ || w_ != rhs.w_ ) 683 return false; 684 return true; 685 } 686 687 bool operator!=( const Vec4& rhs ) const 688 { 689 if( x_ == rhs.x_ ) 690 return false; 691 692 return true; 693 } 694 695 Vec4 operator*( const Mat4& rhs ) const; 696 697 float Length() const 698 { 699 return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_ ); 700 } 701 702 Vec4 Normalize() 703 { 704 float len = Length(); 705 x_ = x_ / len; 706 y_ = y_ / len; 707 z_ = z_ / len; 708 w_ = w_ / len; 709 return *this; 710 } 711 712 float Dot( const Vec3& rhs ) 713 { 714 return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; 715 } 716 717 Vec3 Cross( const Vec3& rhs ) 718 { 719 Vec3 ret; 720 ret.x_ = y_ * rhs.z_ - z_ * rhs.y_; 721 ret.y_ = z_ * rhs.x_ - x_ * rhs.z_; 722 ret.z_ = x_ * rhs.y_ - y_ * rhs.x_; 723 return ret; 724 } 725 726 bool Validate() 727 { 728 if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) || isnan( w_ ) ) 729 return false; 730 return true; 731 } 732 733 void Value( float& fX, float& fY, float& fZ, float& fW ) 734 { 735 fX = x_; 736 fY = y_; 737 fZ = z_; 738 fW = w_; 739 } 740 }; 741 742 /****************************************************************** 743 * 4x4 matrix 744 * 745 */ 746 class Mat4 747 { 748 private: 749 float f_[16]; 750 751 public: 752 friend class Vec3; 753 friend class Vec4; 754 friend class Quaternion; 755 756 Mat4(); 757 Mat4( const float* ); 758 759 Mat4 operator*( const Mat4& rhs ) const; 760 Vec4 operator*( const Vec4& rhs ) const; 761 762 Mat4 operator+( const Mat4& rhs ) const 763 { 764 Mat4 ret; 765 for( int32_t i = 0; i < 16; ++i ) 766 { 767 ret.f_[i] = f_[i] + rhs.f_[i]; 768 } 769 return ret; 770 } 771 772 Mat4 operator-( const Mat4& rhs ) const 773 { 774 Mat4 ret; 775 for( int32_t i = 0; i < 16; ++i ) 776 { 777 ret.f_[i] = f_[i] - rhs.f_[i]; 778 } 779 return ret; 780 } 781 782 Mat4& operator+=( const Mat4& rhs ) 783 { 784 for( int32_t i = 0; i < 16; ++i ) 785 { 786 f_[i] += rhs.f_[i]; 787 } 788 return *this; 789 } 790 791 Mat4& operator-=( const Mat4& rhs ) 792 { 793 for( int32_t i = 0; i < 16; ++i ) 794 { 795 f_[i] -= rhs.f_[i]; 796 } 797 return *this; 798 } 799 800 Mat4& operator*=( const Mat4& rhs ) 801 { 802 Mat4 ret; 803 ret.f_[0] = f_[0] * rhs.f_[0] + f_[4] * rhs.f_[1] + f_[8] * rhs.f_[2] 804 + f_[12] * rhs.f_[3]; 805 ret.f_[1] = f_[1] * rhs.f_[0] + f_[5] * rhs.f_[1] + f_[9] * rhs.f_[2] 806 + f_[13] * rhs.f_[3]; 807 ret.f_[2] = f_[2] * rhs.f_[0] + f_[6] * rhs.f_[1] + f_[10] * rhs.f_[2] 808 + f_[14] * rhs.f_[3]; 809 ret.f_[3] = f_[3] * rhs.f_[0] + f_[7] * rhs.f_[1] + f_[11] * rhs.f_[2] 810 + f_[15] * rhs.f_[3]; 811 812 ret.f_[4] = f_[0] * rhs.f_[4] + f_[4] * rhs.f_[5] + f_[8] * rhs.f_[6] 813 + f_[12] * rhs.f_[7]; 814 ret.f_[5] = f_[1] * rhs.f_[4] + f_[5] * rhs.f_[5] + f_[9] * rhs.f_[6] 815 + f_[13] * rhs.f_[7]; 816 ret.f_[6] = f_[2] * rhs.f_[4] + f_[6] * rhs.f_[5] + f_[10] * rhs.f_[6] 817 + f_[14] * rhs.f_[7]; 818 ret.f_[7] = f_[3] * rhs.f_[4] + f_[7] * rhs.f_[5] + f_[11] * rhs.f_[6] 819 + f_[15] * rhs.f_[7]; 820 821 ret.f_[8] = f_[0] * rhs.f_[8] + f_[4] * rhs.f_[9] + f_[8] * rhs.f_[10] 822 + f_[12] * rhs.f_[11]; 823 ret.f_[9] = f_[1] * rhs.f_[8] + f_[5] * rhs.f_[9] + f_[9] * rhs.f_[10] 824 + f_[13] * rhs.f_[11]; 825 ret.f_[10] = f_[2] * rhs.f_[8] + f_[6] * rhs.f_[9] + f_[10] * rhs.f_[10] 826 + f_[14] * rhs.f_[11]; 827 ret.f_[11] = f_[3] * rhs.f_[8] + f_[7] * rhs.f_[9] + f_[11] * rhs.f_[10] 828 + f_[15] * rhs.f_[11]; 829 830 ret.f_[12] = f_[0] * rhs.f_[12] + f_[4] * rhs.f_[13] + f_[8] * rhs.f_[14] 831 + f_[12] * rhs.f_[15]; 832 ret.f_[13] = f_[1] * rhs.f_[12] + f_[5] * rhs.f_[13] + f_[9] * rhs.f_[14] 833 + f_[13] * rhs.f_[15]; 834 ret.f_[14] = f_[2] * rhs.f_[12] + f_[6] * rhs.f_[13] + f_[10] * rhs.f_[14] 835 + f_[14] * rhs.f_[15]; 836 ret.f_[15] = f_[3] * rhs.f_[12] + f_[7] * rhs.f_[13] + f_[11] * rhs.f_[14] 837 + f_[15] * rhs.f_[15]; 838 839 *this = ret; 840 return *this; 841 } 842 843 Mat4 operator*( const float rhs ) 844 { 845 Mat4 ret; 846 for( int32_t i = 0; i < 16; ++i ) 847 { 848 ret.f_[i] = f_[i] * rhs; 849 } 850 return ret; 851 } 852 853 Mat4& operator*=( const float rhs ) 854 { 855 for( int32_t i = 0; i < 16; ++i ) 856 { 857 f_[i] *= rhs; 858 } 859 return *this; 860 } 861 862 Mat4& operator=( const Mat4& rhs ) 863 { 864 for( int32_t i = 0; i < 16; ++i ) 865 { 866 f_[i] = rhs.f_[i]; 867 } 868 return *this; 869 } 870 871 Mat4 Inverse(); 872 873 Mat4 Transpose() 874 { 875 Mat4 ret; 876 ret.f_[0] = f_[0]; 877 ret.f_[1] = f_[4]; 878 ret.f_[2] = f_[8]; 879 ret.f_[3] = f_[12]; 880 ret.f_[4] = f_[1]; 881 ret.f_[5] = f_[5]; 882 ret.f_[6] = f_[9]; 883 ret.f_[7] = f_[13]; 884 ret.f_[8] = f_[2]; 885 ret.f_[9] = f_[6]; 886 ret.f_[10] = f_[10]; 887 ret.f_[11] = f_[14]; 888 ret.f_[12] = f_[3]; 889 ret.f_[13] = f_[7]; 890 ret.f_[14] = f_[11]; 891 ret.f_[15] = f_[15]; 892 *this = ret; 893 return *this; 894 } 895 896 Mat4& PostTranslate( float tx, float ty, float tz ) 897 { 898 f_[12] += (tx * f_[0]) + (ty * f_[4]) + (tz * f_[8]); 899 f_[13] += (tx * f_[1]) + (ty * f_[5]) + (tz * f_[9]); 900 f_[14] += (tx * f_[2]) + (ty * f_[6]) + (tz * f_[10]); 901 f_[15] += (tx * f_[3]) + (ty * f_[7]) + (tz * f_[11]); 902 return *this; 903 } 904 905 float* Ptr() 906 { 907 return f_; 908 } 909 910 //-------------------------------------------------------------------------------- 911 // Misc 912 //-------------------------------------------------------------------------------- 913 static Mat4 Perspective( float width, float height, float nearPlane, float farPlane ); 914 915 static Mat4 LookAt( const Vec3& vEye, const Vec3& vAt, const Vec3& vUp ); 916 917 static Mat4 Translation( const float fX, const float fY, const float fZ ); 918 static Mat4 Translation( const Vec3 vec ); 919 920 static Mat4 RotationX( const float angle ); 921 922 static Mat4 RotationY( const float angle ); 923 924 static Mat4 RotationZ( const float angle ); 925 926 static Mat4 Identity() 927 { 928 Mat4 ret; 929 ret.f_[0] = 1.f; 930 ret.f_[1] = 0; 931 ret.f_[2] = 0; 932 ret.f_[3] = 0; 933 ret.f_[4] = 0; 934 ret.f_[5] = 1.f; 935 ret.f_[6] = 0; 936 ret.f_[7] = 0; 937 ret.f_[8] = 0; 938 ret.f_[9] = 0; 939 ret.f_[10] = 1.f; 940 ret.f_[11] = 0; 941 ret.f_[12] = 0; 942 ret.f_[13] = 0; 943 ret.f_[14] = 0; 944 ret.f_[15] = 1.f; 945 return ret; 946 } 947 948 void Dump() 949 { 950 LOGI( "%f %f %f %f", f_[0], f_[1], f_[2], f_[3] ); 951 LOGI( "%f %f %f %f", f_[4], f_[5], f_[6], f_[7] ); 952 LOGI( "%f %f %f %f", f_[8], f_[9], f_[10], f_[11] ); 953 LOGI( "%f %f %f %f", f_[12], f_[13], f_[14], f_[15] ); 954 } 955 }; 956 957 /****************************************************************** 958 * Quaternion class 959 * 960 */ 961 class Quaternion 962 { 963 private: 964 float x_, y_, z_, w_; 965 966 public: 967 friend class Vec3; 968 friend class Vec4; 969 friend class Mat4; 970 971 Quaternion() 972 { 973 x_ = 0.f; 974 y_ = 0.f; 975 z_ = 0.f; 976 w_ = 1.f; 977 } 978 979 Quaternion( const float fX, const float fY, const float fZ, const float fW ) 980 { 981 x_ = fX; 982 y_ = fY; 983 z_ = fZ; 984 w_ = fW; 985 } 986 987 Quaternion( const Vec3 vec, const float fW ) 988 { 989 x_ = vec.x_; 990 y_ = vec.y_; 991 z_ = vec.z_; 992 w_ = fW; 993 } 994 995 Quaternion( const float* p ) 996 { 997 x_ = *p++; 998 y_ = *p++; 999 z_ = *p++; 1000 w_ = *p++; 1001 } 1002 1003 Quaternion operator*( const Quaternion rhs ) 1004 { 1005 Quaternion ret; 1006 ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_; 1007 ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_; 1008 ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_; 1009 ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_; 1010 return ret; 1011 } 1012 1013 Quaternion& operator*=( const Quaternion rhs ) 1014 { 1015 Quaternion ret; 1016 ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_; 1017 ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_; 1018 ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_; 1019 ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_; 1020 *this = ret; 1021 return *this; 1022 } 1023 1024 Quaternion Conjugate() 1025 { 1026 x_ = -x_; 1027 y_ = -y_; 1028 z_ = -z_; 1029 return *this; 1030 } 1031 1032 //Non destuctive version 1033 Quaternion Conjugated() 1034 { 1035 Quaternion ret; 1036 ret.x_ = -x_; 1037 ret.y_ = -y_; 1038 ret.z_ = -z_; 1039 ret.w_ = w_; 1040 return ret; 1041 } 1042 1043 void ToMatrix( Mat4& mat ) 1044 { 1045 float x2 = x_ * x_ * 2.0f; 1046 float y2 = y_ * y_ * 2.0f; 1047 float z2 = z_ * z_ * 2.0f; 1048 float xy = x_ * y_ * 2.0f; 1049 float yz = y_ * z_ * 2.0f; 1050 float zx = z_ * x_ * 2.0f; 1051 float xw = x_ * w_ * 2.0f; 1052 float yw = y_ * w_ * 2.0f; 1053 float zw = z_ * w_ * 2.0f; 1054 1055 mat.f_[0] = 1.0f - y2 - z2; 1056 mat.f_[1] = xy + zw; 1057 mat.f_[2] = zx - yw; 1058 mat.f_[4] = xy - zw; 1059 mat.f_[5] = 1.0f - z2 - x2; 1060 mat.f_[6] = yz + xw; 1061 mat.f_[8] = zx + yw; 1062 mat.f_[9] = yz - xw; 1063 mat.f_[10] = 1.0f - x2 - y2; 1064 1065 mat.f_[3] = mat.f_[7] = mat.f_[11] = mat.f_[12] = mat.f_[13] = mat.f_[14] = 0.0f; 1066 mat.f_[15] = 1.0f; 1067 } 1068 1069 void ToMatrixPreserveTranslate( Mat4& mat ) 1070 { 1071 float x2 = x_ * x_ * 2.0f; 1072 float y2 = y_ * y_ * 2.0f; 1073 float z2 = z_ * z_ * 2.0f; 1074 float xy = x_ * y_ * 2.0f; 1075 float yz = y_ * z_ * 2.0f; 1076 float zx = z_ * x_ * 2.0f; 1077 float xw = x_ * w_ * 2.0f; 1078 float yw = y_ * w_ * 2.0f; 1079 float zw = z_ * w_ * 2.0f; 1080 1081 mat.f_[0] = 1.0f - y2 - z2; 1082 mat.f_[1] = xy + zw; 1083 mat.f_[2] = zx - yw; 1084 mat.f_[4] = xy - zw; 1085 mat.f_[5] = 1.0f - z2 - x2; 1086 mat.f_[6] = yz + xw; 1087 mat.f_[8] = zx + yw; 1088 mat.f_[9] = yz - xw; 1089 mat.f_[10] = 1.0f - x2 - y2; 1090 1091 mat.f_[3] = mat.f_[7] = mat.f_[11] = 0.0f; 1092 mat.f_[15] = 1.0f; 1093 } 1094 1095 static Quaternion RotationAxis( const Vec3 axis, const float angle ) 1096 { 1097 Quaternion ret; 1098 float s = sinf( angle / 2 ); 1099 ret.x_ = s * axis.x_; 1100 ret.y_ = s * axis.y_; 1101 ret.z_ = s * axis.z_; 1102 ret.w_ = cosf( angle / 2 ); 1103 return ret; 1104 } 1105 1106 void Value( float& fX, float& fY, float& fZ, float& fW ) 1107 { 1108 fX = x_; 1109 fY = y_; 1110 fZ = z_; 1111 fW = w_; 1112 } 1113 }; 1114 1115 } //namespace ndk_helper 1116 #endif /* VECMATH_H_ */ 1117