m4math.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:13k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file m4math.h
  3.  * @brief LLMatrix4 class header file.
  4.  *
  5.  * $LicenseInfo:firstyear=2000&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2000-2010, 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. #ifndef LL_M4MATH_H
  33. #define LL_M4MATH_H
  34. #include "v3math.h"
  35. class LLVector4;
  36. class LLMatrix3;
  37. class LLQuaternion;
  38. // NOTA BENE: Currently assuming a right-handed, x-forward, y-left, z-up universe
  39. // Us versus OpenGL:
  40. // Even though OpenGL uses column vectors and we use row vectors, we can plug our matrices
  41. // directly into OpenGL.  This is because OpenGL numbers its matrices going columnwise:
  42. //
  43. // OpenGL indexing:          Our indexing:
  44. // 0  4  8 12                [0][0] [0][1] [0][2] [0][3]
  45. // 1  5  9 13                [1][0] [1][1] [1][2] [1][3]
  46. // 2  6 10 14                [2][0] [2][1] [2][2] [2][3]
  47. // 3  7 11 15                [3][0] [3][1] [3][2] [3][3]
  48. //
  49. // So when you're looking at OpenGL related matrices online, our matrices will be
  50. // "transposed".  But our matrices can be plugged directly into OpenGL and work fine!
  51. //
  52. // We're using row vectors - [vx, vy, vz, vw]
  53. //
  54. // There are several different ways of thinking of matrices, if you mix them up, you'll get very confused.
  55. //
  56. // One way to think about it is a matrix that takes the origin frame A
  57. // and rotates it into B': i.e. A*M = B
  58. //
  59. // Vectors:
  60. // f - forward axis of B expressed in A
  61. // l - left axis of B expressed in A
  62. // u - up axis of B expressed in A
  63. //
  64. // |  0: fx  1: fy  2: fz  3:0 |
  65. //  M = |  4: lx  5: ly  6: lz  7:0 |
  66. //      |  8: ux  9: uy 10: uz 11:0 |
  67. //      | 12: 0  13: 0  14:  0 15:1 |
  68. //
  69. //
  70. //
  71. //
  72. // Another way to think of matrices is matrix that takes a point p in frame A, and puts it into frame B:
  73. // This is used most commonly for the modelview matrix.
  74. //
  75. // so p*M = p'
  76. //
  77. // Vectors:
  78. //      f - forward of frame B in frame A
  79. //      l - left of frame B in frame A
  80. //      u - up of frame B in frame A
  81. //      o - origin of frame frame B in frame A
  82. //
  83. // |  0: fx  1: lx  2: ux  3:0 |
  84. //  M = |  4: fy  5: ly  6: uy  7:0 |
  85. //      |  8: fz  9: lz 10: uz 11:0 |
  86. //      | 12:-of 13:-ol 14:-ou 15:1 |
  87. //
  88. // of, ol, and ou mean the component of the "global" origin o in the f axis, l axis, and u axis.
  89. //
  90. static const U32 NUM_VALUES_IN_MAT4 = 4;
  91. class LLMatrix4
  92. {
  93. public:
  94. F32 mMatrix[NUM_VALUES_IN_MAT4][NUM_VALUES_IN_MAT4];
  95. // Initializes Matrix to identity matrix
  96. LLMatrix4()
  97. {
  98. setIdentity();
  99. }
  100. explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat
  101. explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0)
  102. explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0)
  103. LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos
  104. // These are really, really, inefficient as implemented! - djs
  105. LLMatrix4(const LLQuaternion &q, const LLVector4 &pos); // Initializes Matrix with rotation q and position pos
  106. LLMatrix4(F32 angle,
  107.   const LLVector4 &vec, 
  108.   const LLVector4 &pos); // Initializes Matrix with axis-angle and position
  109. LLMatrix4(F32 angle, const LLVector4 &vec); // Initializes Matrix with axis-angle and sets position to (0,0,0)
  110. LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, 
  111.   const LLVector4 &pos); // Initializes Matrix with Euler angles
  112. LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw); // Initializes Matrix with Euler angles
  113. ~LLMatrix4(void); // Destructor
  114. //////////////////////////////
  115. //
  116. // Matrix initializers - these replace any existing values in the matrix
  117. //
  118. void initRows(const LLVector4 &row0,
  119.   const LLVector4 &row1,
  120.   const LLVector4 &row2,
  121.   const LLVector4 &row3);
  122. // various useful matrix functions
  123. const LLMatrix4& setIdentity(); // Load identity matrix
  124. const LLMatrix4& setZero(); // Clears matrix to all zeros.
  125. const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix by rotating angle radians about (x, y, z)
  126. const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis); // Calculate rotation matrix for rotating angle radians about vec
  127. const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
  128. const LLMatrix4& initRotation(const LLQuaternion &q); // Set with Quaternion and position
  129. // Position Only
  130. const LLMatrix4& initMatrix(const LLMatrix3 &mat); //
  131. const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation);
  132. // These operation create a matrix that will rotate and translate by the
  133. // specified amounts.
  134. const LLMatrix4& initRotTrans(const F32 angle,
  135.   const F32 rx, const F32 ry, const F32 rz,
  136.   const F32 px, const F32 py, const F32 pz);
  137. const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation);  // Rotation from axis angle + translation
  138. const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation
  139. const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position
  140. // Set all
  141. const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos);
  142. ///////////////////////////
  143. //
  144. // Matrix setters - set some properties without modifying others
  145. //
  146. const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z); // Sets matrix to translate by (x,y,z)
  147. void setFwdRow(const LLVector3 &row);
  148. void setLeftRow(const LLVector3 &row);
  149. void setUpRow(const LLVector3 &row);
  150. void setFwdCol(const LLVector3 &col);
  151. void setLeftCol(const LLVector3 &col);
  152. void setUpCol(const LLVector3 &col);
  153. const LLMatrix4& setTranslation(const LLVector4 &translation);
  154. const LLMatrix4& setTranslation(const LLVector3 &translation);
  155. ///////////////////////////
  156. //
  157. // Get properties of a matrix
  158. //
  159. F32  determinant(void) const; // Return determinant
  160. LLQuaternion quaternion(void) const; // Returns quaternion
  161. LLVector4 getFwdRow4() const;
  162. LLVector4 getLeftRow4() const;
  163. LLVector4 getUpRow4() const;
  164. LLMatrix3 getMat3() const;
  165. const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; }
  166. ///////////////////////////
  167. //
  168. // Operations on an existing matrix
  169. //
  170. const LLMatrix4& transpose(); // Transpose LLMatrix4
  171. const LLMatrix4& invert(); // Invert LLMatrix4
  172. // Rotate existing matrix
  173. // These are really, really, inefficient as implemented! - djs
  174. const LLMatrix4& rotate(const F32 angle, const F32 x, const F32 y, const F32 z);  // Rotate matrix by rotating angle radians about (x, y, z)
  175. const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec); // Rotate matrix by rotating angle radians about vec
  176. const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw); // Rotate matrix by Euler angles
  177. const LLMatrix4& rotate(const LLQuaternion &q); // Rotate matrix by Quaternion
  178. // Translate existing matrix
  179. const LLMatrix4& translate(const LLVector3 &vec); // Translate matrix by (vec[VX], vec[VY], vec[VZ])
  180. ///////////////////////
  181. //
  182. // Operators
  183. //
  184. // Not implemented to enforce code that agrees with symbolic syntax
  185. // friend LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b); // Apply rotation a to vector b
  186. // friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b
  187. friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b); // Return transform of vector a by matrix b
  188. friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b
  189. friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate
  190. friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate
  191. friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b); // Return a == b
  192. friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b); // Return a != b
  193. friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b); // Return a + b
  194. friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b); // Return a - b
  195. friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b); // Return a * b
  196. friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b); // Return a * b
  197. friend std::ostream&  operator<<(std::ostream& s, const LLMatrix4 &a); // Stream a
  198. };
  199. inline const LLMatrix4& LLMatrix4::setIdentity()
  200. {
  201. mMatrix[0][0] = 1.f;
  202. mMatrix[0][1] = 0.f;
  203. mMatrix[0][2] = 0.f;
  204. mMatrix[0][3] = 0.f;
  205. mMatrix[1][0] = 0.f;
  206. mMatrix[1][1] = 1.f;
  207. mMatrix[1][2] = 0.f;
  208. mMatrix[1][3] = 0.f;
  209. mMatrix[2][0] = 0.f;
  210. mMatrix[2][1] = 0.f;
  211. mMatrix[2][2] = 1.f;
  212. mMatrix[2][3] = 0.f;
  213. mMatrix[3][0] = 0.f;
  214. mMatrix[3][1] = 0.f;
  215. mMatrix[3][2] = 0.f;
  216. mMatrix[3][3] = 1.f;
  217. return (*this);
  218. }
  219. /*
  220. inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b)
  221. {
  222. U32 i, j;
  223. LLMatrix4 mat;
  224. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  225. {
  226. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  227. {
  228. mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + 
  229.     a.mMatrix[j][1] * b.mMatrix[1][i] + 
  230.     a.mMatrix[j][2] * b.mMatrix[2][i] +
  231. a.mMatrix[j][3] * b.mMatrix[3][i];
  232. }
  233. }
  234. return mat;
  235. }
  236. */
  237. inline const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b)
  238. {
  239. U32 i, j;
  240. LLMatrix4 mat;
  241. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  242. {
  243. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  244. {
  245. mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + 
  246.     a.mMatrix[j][1] * b.mMatrix[1][i] + 
  247.     a.mMatrix[j][2] * b.mMatrix[2][i] +
  248. a.mMatrix[j][3] * b.mMatrix[3][i];
  249. }
  250. }
  251. a = mat;
  252. return a;
  253. }
  254. inline const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b)
  255. {
  256. U32 i, j;
  257. LLMatrix4 mat;
  258. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  259. {
  260. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  261. {
  262. mat.mMatrix[j][i] = a.mMatrix[j][i] * b;
  263. }
  264. }
  265. a = mat;
  266. return a;
  267. }
  268. inline const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b)
  269. {
  270. LLMatrix4 mat;
  271. U32 i, j;
  272. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  273. {
  274. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  275. {
  276. mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i];
  277. }
  278. }
  279. a = mat;
  280. return a;
  281. }
  282. inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b)
  283. {
  284. LLMatrix4 mat;
  285. U32 i, j;
  286. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  287. {
  288. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  289. {
  290. mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i];
  291. }
  292. }
  293. a = mat;
  294. return a;
  295. }
  296. // Operates "to the left" on row-vector a
  297. //
  298. // When avatar vertex programs are off, this function is a hot spot in profiles
  299. // due to software skinning in LLViewerJointMesh::updateGeometry().  JC
  300. inline const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b)
  301. {
  302. // This is better than making a temporary LLVector3.  This eliminates an
  303. // unnecessary LLVector3() constructor and also helps the compiler to
  304. // realize that the output floats do not alias the input floats, hence
  305. // eliminating redundant loads of a.mV[0], etc.  JC
  306. return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + 
  307.  a.mV[VY] * b.mMatrix[VY][VX] + 
  308.  a.mV[VZ] * b.mMatrix[VZ][VX] +
  309.  b.mMatrix[VW][VX],
  310.  
  311.  a.mV[VX] * b.mMatrix[VX][VY] + 
  312.  a.mV[VY] * b.mMatrix[VY][VY] + 
  313.  a.mV[VZ] * b.mMatrix[VZ][VY] +
  314.  b.mMatrix[VW][VY],
  315.  
  316.  a.mV[VX] * b.mMatrix[VX][VZ] + 
  317.  a.mV[VY] * b.mMatrix[VY][VZ] + 
  318.  a.mV[VZ] * b.mMatrix[VZ][VZ] +
  319.  b.mMatrix[VW][VZ]);
  320. }
  321. #endif