llmatrix3.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /**
  2. * @file llmatrix3.h
  3. * @brief LLMatrix3 class header file.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. // Rotation matrix hints...
  33. // Inverse of Rotation Matrices
  34. // ----------------------------
  35. // If R is a rotation matrix that rotate vectors from Frame-A to Frame-B,
  36. // then the transpose of R will rotate vectors from Frame-B to Frame-A.
  37. // Creating Rotation Matricies From Object Axes
  38. // --------------------------------------------
  39. // Suppose you know the three axes of some object in some "absolute-frame".
  40. // If you take those three vectors and throw them into the rows of
  41. // a rotation matrix what do you get?
  42. //
  43. // R = | X0 X1 X2 |
  44. // | Y0 Y1 Y2 |
  45. // | Z0 Z1 Z2 |
  46. //
  47. // Yeah, but what does it mean?
  48. //
  49. // Transpose the matrix and have it operate on a vector...
  50. //
  51. // V * R_transpose = [ V0 V1 V2 ] * | X0 Y0 Z0 |
  52. // | X1 Y1 Z1 |
  53. // | X2 Y2 Z2 |
  54. //
  55. // = [ V*X V*Y V*Z ]
  56. //
  57. // = components of V that are parallel to the three object axes
  58. //
  59. // = transformation of V into object frame
  60. //
  61. // Since the transformation of a rotation matrix is its inverse, then
  62. // R must rotate vectors from the object-frame into the absolute-frame.
  63. #ifndef LL_M3MATH_H
  64. #define LL_M3MATH_H
  65. #include "llerror.h"
  66. #include "stdtypes.h"
  67. class LLVector4;
  68. class LLVector3;
  69. class LLVector3d;
  70. class LLQuaternion;
  71. // NOTA BENE: Currently assuming a right-handed, z-up universe
  72. // ji
  73. // LLMatrix3 = | 00 01 02 |
  74. // | 10 11 12 |
  75. // | 20 21 22 |
  76. // LLMatrix3 = | fx fy fz | forward-axis
  77. // | lx ly lz | left-axis
  78. // | ux uy uz | up-axis
  79. // NOTE: The world of computer graphics uses column-vectors and matricies that
  80. // "operate to the left".
  81. constexpr U32 NUM_VALUES_IN_MAT3 = 3;
  82. class LLMatrix3
  83. {
  84. public:
  85. LLMatrix3() noexcept; /// Initializes Matrix to identity matrix
  86. // Initializes Matrix to values in mat
  87. explicit LLMatrix3(const F32* mat) noexcept;
  88. // Initializes Matrix with rotation q
  89. explicit LLMatrix3(const LLQuaternion& q) noexcept;
  90. // Initializes Matrix with axis angle
  91. LLMatrix3(F32 angle, const LLVector3& vec) noexcept;
  92. // Initializes Matrix with axis angle
  93. LLMatrix3(F32 angle, const LLVector3d& vec) noexcept;
  94. // Initializes Matrix with axis angle
  95. LLMatrix3(F32 angle, const LLVector4& vec) noexcept;
  96. // Initializes Matrix with Euler angles
  97. LLMatrix3(F32 roll, F32 pitch, F32 yaw) noexcept;
  98. // Allow the use of the default C++11 move constructor and assignation
  99. LLMatrix3(LLMatrix3&& other) noexcept = default;
  100. LLMatrix3& operator=(LLMatrix3&& other) noexcept = default;
  101. LLMatrix3(const LLMatrix3& other) = default;
  102. LLMatrix3& operator=(const LLMatrix3& other) = default;
  103. // Returns a "this" as an F32 pointer.
  104. LL_INLINE F32* getF32ptr()
  105. {
  106. return (F32*)mMatrix;
  107. }
  108. // Returns a "this" as a const F32 pointer.
  109. LL_INLINE const F32* const getF32ptr() const
  110. {
  111. return (const F32* const)mMatrix;
  112. }
  113. //////////////////////////////
  114. // Matrix initializers - these replace any existing values in the matrix
  115. // Various useful matrix functions
  116. const LLMatrix3& setIdentity(); // Load identity matrix
  117. const LLMatrix3& clear(); // Clears Matrix to zero
  118. const LLMatrix3& setZero(); // Clears Matrix to zero
  119. ///////////////////////////
  120. // Matrix setters - set some properties without modifying others
  121. // These functions take Rotation arguments
  122. // Calculate rotation matrix for rotating angle radians about vec
  123. const LLMatrix3& setRot(F32 angle, const LLVector3& vec);
  124. // Calculate rotation matrix from Euler angles
  125. const LLMatrix3& setRot(F32 roll, F32 pitch, F32 yaw);
  126. // Transform matrix by Euler angles and translating by pos
  127. const LLMatrix3& setRot(const LLQuaternion& q);
  128. const LLMatrix3& setRows(const LLVector3& x_axis,
  129. const LLVector3& y_axis,
  130. const LLVector3& z_axis);
  131. const LLMatrix3& setRow(U32 rowIndex, const LLVector3& row);
  132. const LLMatrix3& setCol(U32 col_idx, const LLVector3& col);
  133. ///////////////////////////
  134. // Get properties of a matrix
  135. // Returns quaternion from mat
  136. LLQuaternion quaternion() const;
  137. // Returns Euler angles, in radians
  138. void getEulerAngles(F32* roll, F32* pitch, F32* yaw) const;
  139. // Axis extraction routines
  140. LLVector3 getFwdRow() const;
  141. LLVector3 getLeftRow() const;
  142. LLVector3 getUpRow() const;
  143. // Returns determinant
  144. F32 determinant() const;
  145. ///////////////////////////
  146. // Operations on an existing matrix
  147. const LLMatrix3& transpose(); // Transpose MAT4
  148. const LLMatrix3& orthogonalize(); // Orthogonalizes X, then Y, then Z
  149. void invert(); // Invert MAT4
  150. // returns transpose of matrix adjoint, for multiplying normals
  151. const LLMatrix3& adjointTranspose();
  152. // Rotate existing matrix. Note: the two lines below are equivalent:
  153. // foo.rotate(bar)
  154. // foo = foo * bar
  155. // That is, foo.rotate(bar) multiplies foo by bar FROM THE RIGHT
  156. // Rotate matrix by rotating angle radians about vec
  157. const LLMatrix3& rotate(F32 angle, const LLVector3& vec);
  158. // Rotate matrix by roll (about x), pitch (about y), and yaw (about z)
  159. const LLMatrix3& rotate(F32 roll, F32 pitch, F32 yaw);
  160. // Transform matrix by Euler angles and translating by pos
  161. const LLMatrix3& rotate(const LLQuaternion& q);
  162. void add(const LLMatrix3& other_matrix); // add other_matrix to this one
  163. #if 0 // This operator is misleading as to operation direction
  164. // Apply rotation a to vector b
  165. friend LLVector3 operator*(const LLMatrix3& a, const LLVector3& b);
  166. #endif
  167. // Applies rotation b to vector a
  168. friend LLVector3 operator*(const LLVector3& a, const LLMatrix3& b);
  169. // Applies rotation b to vector a
  170. friend LLVector3d operator*(const LLVector3d& a, const LLMatrix3& b);
  171. // Returns a * b
  172. friend LLMatrix3 operator*(const LLMatrix3& a, const LLMatrix3& b);
  173. friend bool operator==(const LLMatrix3& a, const LLMatrix3& b);
  174. friend bool operator!=(const LLMatrix3& a, const LLMatrix3& b);
  175. // Returns a * b
  176. friend const LLMatrix3& operator*=(LLMatrix3& a, const LLMatrix3& b);
  177. // Returns a * scalar
  178. friend const LLMatrix3& operator*=(LLMatrix3& a, F32 scalar);
  179. // Streams a
  180. friend std::ostream& operator<<(std::ostream& s, const LLMatrix3& a);
  181. public:
  182. F32 mMatrix[NUM_VALUES_IN_MAT3][NUM_VALUES_IN_MAT3];
  183. };
  184. LL_INLINE LLMatrix3::LLMatrix3() noexcept
  185. {
  186. mMatrix[0][0] = 1.f;
  187. mMatrix[0][1] = 0.f;
  188. mMatrix[0][2] = 0.f;
  189. mMatrix[1][0] = 0.f;
  190. mMatrix[1][1] = 1.f;
  191. mMatrix[1][2] = 0.f;
  192. mMatrix[2][0] = 0.f;
  193. mMatrix[2][1] = 0.f;
  194. mMatrix[2][2] = 1.f;
  195. }
  196. LL_INLINE LLMatrix3::LLMatrix3(const F32* mat) noexcept
  197. {
  198. mMatrix[0][0] = mat[0];
  199. mMatrix[0][1] = mat[1];
  200. mMatrix[0][2] = mat[2];
  201. mMatrix[1][0] = mat[3];
  202. mMatrix[1][1] = mat[4];
  203. mMatrix[1][2] = mat[5];
  204. mMatrix[2][0] = mat[6];
  205. mMatrix[2][1] = mat[7];
  206. mMatrix[2][2] = mat[8];
  207. }
  208. #endif