/opengles/src/linalg.h
C++ Header | 855 lines | 428 code | 150 blank | 277 comment | 9 complexity | f3cb75fe7ecce2b010b48c1dbf96bb71 MD5 | raw file
1#ifndef EGL_LINALG_H 2#define EGL_LINALG_H 1 3 4// ========================================================================== 5// 6// linalg.h Implementation of Linear Algebra using Fixed Point Arithmetic 7// 8// -------------------------------------------------------------------------- 9// 10// 10-02-2003 Hans-Martin Will initial version 11// 12// -------------------------------------------------------------------------- 13// 14// Copyright (c) 2004, Hans-Martin Will. All rights reserved. 15// 16// Redistribution and use in source and binary forms, with or without 17// modification, are permitted provided that the following conditions are 18// met: 19// 20// * Redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer. 22// * Redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 27// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 30// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 36// THE POSSIBILITY OF SUCH DAMAGE. 37// 38// ========================================================================== 39 40 41#include "OGLES.h" 42#include "fixed.h" 43 44namespace EGL { 45 46 // -------------------------------------------------------------------------- 47 // 3-D Vector class 48 // -------------------------------------------------------------------------- 49 50 51 class Vec3D { 52 53 // element names compatible to GPP_VEC3D 54 EGL_Fixed m_x, m_y, m_z; 55 56 public: 57 // ---------------------------------------------------------------------- 58 // Constructor 59 // ---------------------------------------------------------------------- 60 inline Vec3D() { 61 m_x = m_y = m_z = 0; 62 } 63 64 // ---------------------------------------------------------------------- 65 // Constructor 66 // 67 // Parameters: 68 // x, y, z - individual coordinates of 3-D vector 69 // ---------------------------------------------------------------------- 70 inline Vec3D(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z) { 71 m_x = x; 72 m_y = y; 73 m_z = z; 74 } 75 76 // ---------------------------------------------------------------------- 77 // Constructor 78 // 79 // Parameters: 80 // coords - individual coordinates of 3-D vector 81 // ---------------------------------------------------------------------- 82 inline Vec3D(const EGL_Fixed * coords) { 83 m_x = coords[0]; 84 m_y = coords[1]; 85 m_z = coords[2]; 86 } 87 88 // ---------------------------------------------------------------------- 89 // Copy constructor 90 // ---------------------------------------------------------------------- 91 inline Vec3D(const Vec3D& other) { 92 m_x = other.m_x; 93 m_y = other.m_y; 94 m_z = other.m_z; 95 } 96 97 // ---------------------------------------------------------------------- 98 // Assignment operator 99 // ---------------------------------------------------------------------- 100 inline Vec3D& operator=(const Vec3D& other) { 101 m_x = other.m_x; 102 m_y = other.m_y; 103 m_z = other.m_z; 104 return *this; 105 } 106 107 // ---------------------------------------------------------------------- 108 // Vector addition 109 // ---------------------------------------------------------------------- 110 inline Vec3D operator+(const Vec3D& other) const { 111 return Vec3D(m_x + other.m_x, m_y + other.m_y, m_z + other.m_z); 112 } 113 114 inline Vec3D& operator +=(const Vec3D& other) { 115 m_x += other.m_x; 116 m_y += other.m_y; 117 m_z += other.m_z; 118 return *this; 119 } 120 121 inline Vec3D operator-(const Vec3D& other) const { 122 return Vec3D(m_x - other.m_x, m_y - other.m_y, m_z - other.m_z); 123 } 124 125 inline Vec3D& operator -=(const Vec3D& other) { 126 m_x -= other.m_x; 127 m_y -= other.m_y; 128 m_z -= other.m_z; 129 return *this; 130 } 131 132 // ---------------------------------------------------------------------- 133 // Scaling of vector 134 // 135 // Parameters: 136 // factor - scale factor 137 // ---------------------------------------------------------------------- 138 inline Vec3D operator*(EGL_Fixed factor) const { 139 return Vec3D(EGL_Mul(m_x, factor), 140 EGL_Mul(m_y, factor), 141 EGL_Mul(m_z, factor)); 142 } 143 144 inline Vec3D& operator *=(EGL_Fixed factor) { 145 m_x = EGL_Mul(m_x, factor); 146 m_y = EGL_Mul(m_y, factor); 147 m_z = EGL_Mul(m_z, factor); 148 return *this; 149 } 150 151 // ---------------------------------------------------------------------- 152 // Dot product between two vectors 153 // 154 // Parameters: 155 // other - second operand 156 // ---------------------------------------------------------------------- 157 inline EGL_Fixed operator*(const Vec3D& other) const { 158 return EGL_Mul(m_x, other.m_x) + 159 EGL_Mul(m_y, other.m_y) + 160 EGL_Mul(m_z, other.m_z); 161 } 162 163 // ---------------------------------------------------------------------- 164 // Cross product for two vectors 165 // 166 // Parameters: 167 // other - second operand 168 // ---------------------------------------------------------------------- 169 inline Vec3D Cross(const Vec3D& other) const { 170 return Vec3D(EGL_Mul(m_y, other.m_z) - EGL_Mul(m_z, other.m_y), 171 -EGL_Mul(m_x, other.m_z) + EGL_Mul(m_z, other.m_x), 172 EGL_Mul(m_x, other.m_y) - EGL_Mul(m_y, other.m_x)); 173 } 174 175 // ---------------------------------------------------------------------- 176 // Euclidean length of vector 177 // ---------------------------------------------------------------------- 178 inline EGL_Fixed Length() const { 179 return EGL_Sqrt(LengthSq()); 180 } 181 182 // ---------------------------------------------------------------------- 183 // Square of Euclidean length of vector 184 // ---------------------------------------------------------------------- 185 inline EGL_Fixed LengthSq() const { 186 return (*this) * (*this); 187 } 188 189 // ---------------------------------------------------------------------- 190 // Normalize the vector to unit length 191 // ---------------------------------------------------------------------- 192 inline void Normalize() { 193 *this *= EGL_InvSqrt(LengthSq()); 194 } 195 196 // ---------------------------------------------------------------------- 197 // Element accessors 198 // ---------------------------------------------------------------------- 199 200 inline EGL_Fixed x() const { 201 return m_x; 202 } 203 204 inline EGL_Fixed y() const { 205 return m_y; 206 } 207 208 inline EGL_Fixed z() const { 209 return m_z; 210 } 211 212 inline void setX(EGL_Fixed value) { 213 m_x = value; 214 } 215 216 inline void setY(EGL_Fixed value) { 217 m_y = value; 218 } 219 220 inline void setZ(EGL_Fixed value) { 221 m_z = value; 222 } 223 }; 224 225 226 inline OGLES_API Vec3D operator*(EGL_Fixed factor, const Vec3D& vector) { 227 return vector * factor; 228 } 229 230 231 232 // -------------------------------------------------------------------------- 233 // 4-D Vector class 234 // -------------------------------------------------------------------------- 235 236 237 class Vec4D { 238 239 // element names compatible to GPP_VEC4D 240 EGL_Fixed m_x, m_y, m_z, m_w; 241 242 public: 243 // ---------------------------------------------------------------------- 244 // Constructor 245 // ---------------------------------------------------------------------- 246 inline Vec4D() { 247 m_x = m_y = m_z = 0; 248 m_w = 1; 249 } 250 251 // ---------------------------------------------------------------------- 252 // Constructor, canonical embedding of R^3 in SO^2 253 // 254 // Parameters: 255 // x, y, z - individual coordinates of 3-D vector 256 // ---------------------------------------------------------------------- 257 inline Vec4D(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z) { 258 m_x = x; 259 m_y = y; 260 m_z = z; 261 m_w = EGL_ONE; 262 } 263 264 // ---------------------------------------------------------------------- 265 // Constructor 266 // 267 // Parameters: 268 // coords - individual coordinates of 3-D vector 269 // ---------------------------------------------------------------------- 270 inline Vec4D(const EGL_Fixed * coords) { 271 m_x = coords[0]; 272 m_y = coords[1]; 273 m_z = coords[2]; 274 m_w = coords[3]; 275 } 276 277 // ---------------------------------------------------------------------- 278 // Constructor 279 // 280 // Parameters: 281 // x, y, z, w - individual coordinates of 4-D vector 282 // ---------------------------------------------------------------------- 283 inline Vec4D(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z, EGL_Fixed w) { 284 m_x = x; 285 m_y = y; 286 m_z = z; 287 m_w = w; 288 } 289 290 // ---------------------------------------------------------------------- 291 // Copy constructor 292 // ---------------------------------------------------------------------- 293 inline Vec4D(const Vec4D& other) { 294 m_x = other.m_x; 295 m_y = other.m_y; 296 m_z = other.m_z; 297 m_w = other.m_w; 298 } 299 300 301 // ---------------------------------------------------------------------- 302 // Assignment operator 303 // ---------------------------------------------------------------------- 304 inline Vec4D& operator=(const Vec4D& other) { 305 m_x = other.m_x; 306 m_y = other.m_y; 307 m_z = other.m_z; 308 m_w = other.m_w; 309 return *this; 310 } 311 312 // ---------------------------------------------------------------------- 313 // Projection operator 314 // ---------------------------------------------------------------------- 315 inline operator Vec3D() const { 316 EGL_Fixed factor = EGL_Inverse(m_w); 317 318 return Vec3D(EGL_Mul(m_x, factor), EGL_Mul(m_y, factor), EGL_Mul(m_z, factor)); 319 } 320 321 // ---------------------------------------------------------------------- 322 // Projection operator 323 // ---------------------------------------------------------------------- 324 inline Vec3D Project() const { 325 return Vec3D(m_x, m_y, m_z); 326 } 327 328 // ---------------------------------------------------------------------- 329 // Vector addition 330 // ---------------------------------------------------------------------- 331 inline Vec4D operator+(const Vec4D& other) const { 332 return Vec4D(m_x + other.m_x, m_y + other.m_y, m_z + other.m_z, m_w + other.m_w); 333 } 334 335 inline Vec4D& operator +=(const Vec4D& other) { 336 m_x += other.m_x; 337 m_y += other.m_y; 338 m_z += other.m_z; 339 m_w += other.m_w; 340 return *this; 341 } 342 343 inline Vec4D operator-(const Vec4D& other) const { 344 return Vec4D(m_x - other.m_x, m_y - other.m_y, m_z - other.m_z, m_w - other.m_w); 345 } 346 347 inline Vec4D& operator -=(const Vec4D& other) { 348 m_x -= other.m_x; 349 m_y -= other.m_y; 350 m_z -= other.m_z; 351 m_w -= other.m_w; 352 return *this; 353 } 354 355 inline Vec4D operator-() const { 356 return Vec4D(-m_x, -m_y, -m_z, -m_w); 357 } 358 359 // ---------------------------------------------------------------------- 360 // Scaling of vector 361 // 362 // Parameters: 363 // factor - scale factor 364 // ---------------------------------------------------------------------- 365 inline Vec4D operator*(EGL_Fixed factor) const { 366 return Vec4D(EGL_Mul(m_x, factor), 367 EGL_Mul(m_y, factor), 368 EGL_Mul(m_z, factor), 369 EGL_Mul(m_w, factor)); 370 } 371 372 inline Vec4D& operator *=(EGL_Fixed factor) { 373 m_x = EGL_Mul(m_x, factor); 374 m_y = EGL_Mul(m_y, factor); 375 m_z = EGL_Mul(m_z, factor); 376 m_w = EGL_Mul(m_w, factor); 377 378 return *this; 379 } 380 381 // ---------------------------------------------------------------------- 382 // Dot product between two vectors 383 // 384 // Parameters: 385 // other - second operand 386 // ---------------------------------------------------------------------- 387 inline EGL_Fixed operator*(const Vec4D& other) const { 388 return EGL_Mul(m_x, other.m_x) + 389 EGL_Mul(m_y, other.m_y) + 390 EGL_Mul(m_z, other.m_z) + 391 EGL_Mul(m_w, other.m_w); 392 } 393 394 inline I64 longProduct(const Vec4D& other) const { 395 return 396 (static_cast<I64>(m_x) * static_cast<I64>(other.m_x) + 397 static_cast<I64>(m_y) * static_cast<I64>(other.m_y) + 398 static_cast<I64>(m_z) * static_cast<I64>(other.m_z) + 399 static_cast<I64>(m_w) * static_cast<I64>(other.m_w)) >> EGL_PRECISION; 400 } 401 402 // ---------------------------------------------------------------------- 403 // Euclidean length of vector 404 // ---------------------------------------------------------------------- 405 inline EGL_Fixed Length() const { 406 return EGL_Sqrt(LengthSq()); 407 } 408 409 // ---------------------------------------------------------------------- 410 // Square of Euclidean length of vector 411 // ---------------------------------------------------------------------- 412 inline EGL_Fixed LengthSq() const { 413 return (*this) * (*this); 414 } 415 416 // ---------------------------------------------------------------------- 417 // Normalize the vector to unit length 418 // ---------------------------------------------------------------------- 419 inline void Normalize() { 420 *this *= EGL_InvSqrt(LengthSq()); 421 } 422 423 // ---------------------------------------------------------------------- 424 // Element accessors 425 // ---------------------------------------------------------------------- 426 427 inline EGL_Fixed x() const { 428 return m_x; 429 } 430 431 inline EGL_Fixed y() const { 432 return m_y; 433 } 434 435 inline EGL_Fixed z() const { 436 return m_z; 437 } 438 439 inline EGL_Fixed w() const { 440 return m_w; 441 } 442 443 inline void setX(EGL_Fixed value) { 444 m_x = value; 445 } 446 447 inline void setY(EGL_Fixed value) { 448 m_y = value; 449 } 450 451 inline void setZ(EGL_Fixed value) { 452 m_z = value; 453 } 454 455 inline void setW(EGL_Fixed value) { 456 m_w = value; 457 } 458 }; 459 460 461 inline OGLES_API Vec3D EGL_Direction(const Vec4D& from, const Vec4D& to) { 462 Vec3D result (EGL_Mul(to.x(), from.w()) - EGL_Mul(from.x(), to.w()), 463 EGL_Mul(to.y(), from.w()) - EGL_Mul(from.y(), to.w()), 464 EGL_Mul(to.z(), from.w()) - EGL_Mul(from.z(), to.w())); 465 466 return result; 467 } 468 469 inline OGLES_API Vec4D operator*(EGL_Fixed factor, const Vec4D& vector) { 470 return vector * factor; 471 } 472 473 474 // -------------------------------------------------------------------------- 475 // 4x4 Matrix class 476 // -------------------------------------------------------------------------- 477 478 479 class Matrix4x4 { 480 481 enum { 482 ROWS = 4, // number of rows per matrix 483 COLUMNS = 4, // number of columns per matrix 484 ELEMENTS = 16, // total number of elements 485 }; 486 487 EGL_Fixed m_elements[16]; 488 bool m_identity; // flag to mark identity matrix 489 490 public: 491 // ---------------------------------------------------------------------- 492 // This function effectively defines the order in which individual 493 // matrix elements are stored in the underlying 1-D vector. 494 // 495 // Parameters: 496 // row - row index into the matrix 497 // column - column index into the matrix 498 // 499 // Returns: 500 // Reference to the indexed matrix element 501 // ---------------------------------------------------------------------- 502 inline EGL_Fixed& Element(int row, int column) { 503 return m_elements[row + column * ROWS]; 504 } 505 506 inline const EGL_Fixed& Element(int row, int column) const { 507 return m_elements[row + column * ROWS]; 508 } 509 510 inline EGL_Fixed& Element(int index) { 511 return m_elements[index]; 512 } 513 514 inline const EGL_Fixed& Element(int index) const { 515 return m_elements[index]; 516 } 517 518 inline bool IsIdentity() const { 519 return m_identity; 520 } 521 522 // ---------------------------------------------------------------------- 523 // Default constructor: Initialize the matrix as identity matrix 524 // ---------------------------------------------------------------------- 525 inline Matrix4x4() { 526 MakeIdentity(); 527 } 528 529 530 // ---------------------------------------------------------------------- 531 // Construct matrix from vector of elements 532 // 533 // Parameters: 534 // elements - Pointer to array of elements, which are stored 535 // column by column 536 // ---------------------------------------------------------------------- 537 inline Matrix4x4(const EGL_Fixed * elements) { 538 for (int index = 0; index < ELEMENTS; ++index) { 539 m_elements[index] = elements[index]; 540 } 541 542 m_identity = false; 543 } 544 545 546 // ---------------------------------------------------------------------- 547 // Construct matrix from individual elements 548 // 549 // Parameters: 550 // m00,...,m33 - mij specifies the value of Element(i, j) 551 // ---------------------------------------------------------------------- 552 inline Matrix4x4(EGL_Fixed m00, EGL_Fixed m01, EGL_Fixed m02, EGL_Fixed m03, 553 EGL_Fixed m10, EGL_Fixed m11, EGL_Fixed m12, EGL_Fixed m13, 554 EGL_Fixed m20, EGL_Fixed m21, EGL_Fixed m22, EGL_Fixed m23, 555 EGL_Fixed m30, EGL_Fixed m31, EGL_Fixed m32, EGL_Fixed m33) { 556 557 Element(0, 0) = m00; 558 Element(1, 0) = m10; 559 Element(2, 0) = m20; 560 Element(3, 0) = m30; 561 562 Element(0, 1) = m01; 563 Element(1, 1) = m11; 564 Element(2, 1) = m21; 565 Element(3, 1) = m31; 566 567 Element(0, 2) = m02; 568 Element(1, 2) = m12; 569 Element(2, 2) = m22; 570 Element(3, 2) = m32; 571 572 Element(0, 3) = m03; 573 Element(1, 3) = m13; 574 Element(2, 3) = m23; 575 Element(3, 3) = m33; 576 577 m_identity = false; 578 } 579 580 581 // ---------------------------------------------------------------------- 582 // Copy constructor 583 // ---------------------------------------------------------------------- 584 inline Matrix4x4(const Matrix4x4& other) { 585 for (int index = 0; index < ELEMENTS; ++index) { 586 m_elements[index] = other.m_elements[index]; 587 } 588 589 m_identity = other.m_identity; 590 } 591 592 593 // ---------------------------------------------------------------------- 594 // Assignment operator 595 // ---------------------------------------------------------------------- 596 inline Matrix4x4& operator=(const Matrix4x4& other) { 597 for (int index = 0; index < ELEMENTS; ++index) { 598 m_elements[index] = other.m_elements[index]; 599 } 600 601 m_identity = other.m_identity; 602 603 return *this; 604 } 605 606 607 // ---------------------------------------------------------------------- 608 // Reset matrix to be an identity matrix 609 // ---------------------------------------------------------------------- 610 inline void MakeIdentity() { 611 Element(0, 0) = Element(1, 1) = Element(2, 2) = Element(3, 3) = EGL_ONE; 612 Element(0, 1) = Element(0, 2) = Element(0, 3) = 0; 613 Element(1, 0) = Element(1, 2) = Element(1, 3) = 0; 614 Element(2, 0) = Element(2, 1) = Element(2, 3) = 0; 615 Element(3, 0) = Element(3, 1) = Element(3, 2) = 0; 616 m_identity = true; 617 } 618 619 620 // ---------------------------------------------------------------------- 621 // Matrix multiplication as (*this) * other 622 // 623 // Parameters: 624 // other - RHS in matrix multiplication 625 // ---------------------------------------------------------------------- 626 inline Matrix4x4 operator*(const Matrix4x4& other) const { 627 Matrix4x4 result; 628 629 for (int i = 0; i < ROWS; ++i) { 630 for (int j = 0; j < COLUMNS; ++j) { 631 EGL_Fixed sum = 0; 632 633 for (int k = 0; k < COLUMNS; ++k) { 634 sum += EGL_Mul(Element(i, k), other.Element(k, j)); 635 } 636 637 result.Element(i, j) = sum; 638 } 639 } 640 641 result.m_identity = m_identity && other.m_identity; 642 return result; 643 } 644 645 646 // ---------------------------------------------------------------------- 647 // Transform a 3-D vector using this matrix. The vector is extended 648 // with a homogenuous coordinate of 1 before being multiplied. 649 // 650 // Parameters: 651 // vector - The vector to be transformed 652 // ---------------------------------------------------------------------- 653 inline Vec4D operator*(const Vec3D& vector) const { 654 return Vec4D( 655 EGL_Mul(vector.x(), Element(0, 0)) + 656 EGL_Mul(vector.y(), Element(0, 1)) + 657 EGL_Mul(vector.z(), Element(0, 2)) + 658 Element(0, 3), 659 660 EGL_Mul(vector.x(), Element(1, 0)) + 661 EGL_Mul(vector.y(), Element(1, 1)) + 662 EGL_Mul(vector.z(), Element(1, 2)) + 663 Element(1, 3), 664 665 EGL_Mul(vector.x(), Element(2, 0)) + 666 EGL_Mul(vector.y(), Element(2, 1)) + 667 EGL_Mul(vector.z(), Element(2, 2)) + 668 Element(2, 3), 669 670 EGL_Mul(vector.x(), Element(3, 0)) + 671 EGL_Mul(vector.y(), Element(3, 1)) + 672 EGL_Mul(vector.z(), Element(3, 2)) + 673 Element(3, 3)); 674 } 675 676 677 // ---------------------------------------------------------------------- 678 // Transform a 3-D vector using this matrix using only the upper right 679 // 3x3 sub-matrix. The vector is extended 680 // with a homogenuous coordinate of 1 before being multiplied. 681 // 682 // Parameters: 683 // vector - The vector to be transformed 684 // ---------------------------------------------------------------------- 685 inline Vec3D Multiply3x3(const Vec3D& vector) const { 686 return Vec3D( 687 EGL_Mul(vector.x(), Element(0, 0)) + 688 EGL_Mul(vector.y(), Element(0, 1)) + 689 EGL_Mul(vector.z(), Element(0, 2)), 690 691 EGL_Mul(vector.x(), Element(1, 0)) + 692 EGL_Mul(vector.y(), Element(1, 1)) + 693 EGL_Mul(vector.z(), Element(1, 2)), 694 695 EGL_Mul(vector.x(), Element(2, 0)) + 696 EGL_Mul(vector.y(), Element(2, 1)) + 697 EGL_Mul(vector.z(), Element(2, 2))); 698 } 699 700 701 702 // ---------------------------------------------------------------------- 703 // Return the Z coordinate after transformation using this matrix 704 // Used for fog calculation, which requires eye distance 705 // ---------------------------------------------------------------------- 706 inline EGL_Fixed GetTransformedZ(const Vec3D& vector) const { 707 return 708 EGL_Mul(vector.x(), Element(2, 0)) + 709 EGL_Mul(vector.y(), Element(2, 1)) + 710 EGL_Mul(vector.z(), Element(2, 2)) + 711 Element(2, 3); 712 } 713 714 715 // ---------------------------------------------------------------------- 716 // Transform a 4-D vector using this matrix. 717 // 718 // Parameters: 719 // vector - The vector to be transformed 720 // ---------------------------------------------------------------------- 721 inline Vec4D operator*(const Vec4D& vector) const { 722 return Vec4D( 723 EGL_Mul(vector.x(), Element(0, 0)) + 724 EGL_Mul(vector.y(), Element(0, 1)) + 725 EGL_Mul(vector.z(), Element(0, 2)) + 726 EGL_Mul(vector.w(), Element(0, 3)), 727 728 EGL_Mul(vector.x(), Element(1, 0)) + 729 EGL_Mul(vector.y(), Element(1, 1)) + 730 EGL_Mul(vector.z(), Element(1, 2)) + 731 EGL_Mul(vector.w(), Element(1, 3)), 732 733 EGL_Mul(vector.x(), Element(2, 0)) + 734 EGL_Mul(vector.y(), Element(2, 1)) + 735 EGL_Mul(vector.z(), Element(2, 2)) + 736 EGL_Mul(vector.w(), Element(2, 3)), 737 738 EGL_Mul(vector.x(), Element(3, 0)) + 739 EGL_Mul(vector.y(), Element(3, 1)) + 740 EGL_Mul(vector.z(), Element(3, 2)) + 741 EGL_Mul(vector.w(), Element(3, 3))); 742 } 743 744 745 inline void Multiply(const Vec4D& vector, Vec4D& result) const { 746 result = Vec4D( 747 EGL_Mul(vector.x(), Element(0, 0)) + 748 EGL_Mul(vector.y(), Element(0, 1)) + 749 EGL_Mul(vector.z(), Element(0, 2)) + 750 EGL_Mul(vector.w(), Element(0, 3)), 751 752 EGL_Mul(vector.x(), Element(1, 0)) + 753 EGL_Mul(vector.y(), Element(1, 1)) + 754 EGL_Mul(vector.z(), Element(1, 2)) + 755 EGL_Mul(vector.w(), Element(1, 3)), 756 757 EGL_Mul(vector.x(), Element(2, 0)) + 758 EGL_Mul(vector.y(), Element(2, 1)) + 759 EGL_Mul(vector.z(), Element(2, 2)) + 760 EGL_Mul(vector.w(), Element(2, 3)), 761 762 EGL_Mul(vector.x(), Element(3, 0)) + 763 EGL_Mul(vector.y(), Element(3, 1)) + 764 EGL_Mul(vector.z(), Element(3, 2)) + 765 EGL_Mul(vector.w(), Element(3, 3))); 766 } 767 768 769 // ---------------------------------------------------------------------- 770 // Calculate the matrix for which the upper left 3x3 matrix is the 771 // inverse of the upper left 3x3 matrix of the receiver canconically 772 // embedded into 4-dimensional space 773 // ---------------------------------------------------------------------- 774 Matrix4x4 InverseUpper3(bool rescale) const; 775 776 // ---------------------------------------------------------------------- 777 // Compute general inverse of a 4 by 4 matrix 778 // ---------------------------------------------------------------------- 779 Matrix4x4 Inverse() const; 780 781 Matrix4x4 Transpose() const { 782 Matrix4x4 result; 783 784 for (int i = 0; i < ROWS; ++i) { 785 for (int j = 0; j < COLUMNS; ++j) { 786 result.Element(i, j) = Element(j, i); 787 } 788 } 789 790 result.m_identity = m_identity; 791 return result; 792 } 793 794 // ---------------------------------------------------------------------- 795 // Create a transformation matrix that scales in x, y and z direction 796 // according to the given scale factors. 797 // 798 // Parameters: 799 // x - scale factor in x direction 800 // y - scale factor in y direction 801 // z - scale factor in z direction 802 // ---------------------------------------------------------------------- 803 static Matrix4x4 CreateScale(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z); 804 805 806 // ---------------------------------------------------------------------- 807 // Create a transformation matrix that rotates around the axis specified 808 // by x, and and z by a the given angle. 809 // 810 // Parameters: 811 // angle - the angle in degrees 812 // x, y, z - the direction of the axis as vector from the origin 813 // ---------------------------------------------------------------------- 814 static Matrix4x4 CreateRotate(EGL_Fixed angle, EGL_Fixed x, 815 EGL_Fixed y, EGL_Fixed z); 816 817 818 // ---------------------------------------------------------------------- 819 // Create a transformation matrix that translates in x, y and z direction 820 // according to the given translation values. 821 // 822 // Parameters: 823 // x - translation in x direction 824 // y - translation in y direction 825 // z - translation in z direction 826 // ---------------------------------------------------------------------- 827 static Matrix4x4 CreateTranslate(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z); 828 829 830 // ---------------------------------------------------------------------- 831 // Create a transformation matrix for a perspective projection of the 832 // cube described by its corners into the unit volume. 833 // 834 // Parameters: 835 // l, b, -n - lower left point to be mapped into lower left front 836 // r, t, -f - upper right point and maximum depth coordinate 837 // ---------------------------------------------------------------------- 838 static Matrix4x4 CreateFrustrum(EGL_Fixed left, EGL_Fixed right, 839 EGL_Fixed bottom, EGL_Fixed top, EGL_Fixed zNear, EGL_Fixed zFar); 840 841 842 // ---------------------------------------------------------------------- 843 // Create a transformation matrix for an orthographic projection of the 844 // cube described by its corners into the unit volume. 845 // 846 // Parameters: 847 // l, b, -n - lower left point to be mapped into lower left front 848 // r, t, -f - upper right point and maximum depth coordinate 849 // ---------------------------------------------------------------------- 850 static Matrix4x4 CreateOrtho(EGL_Fixed left, EGL_Fixed right, 851 EGL_Fixed bottom, EGL_Fixed top, EGL_Fixed zNear, EGL_Fixed zFar); 852 }; 853} 854 855#endif // ndef EGL_LINALG_H