/opengles/src/linalg.h

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