PageRenderTime 36ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmath/llv4matrix4.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 249 lines | 161 code | 43 blank | 45 comment | 1 complexity | 5af2d25193d3c0f74f5cfac279f80f2b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewerjointmesh.cpp
  3. * @brief LLV4* class header file - vector processor enabled math
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLV4MATRIX4_H
  27. #define LL_LLV4MATRIX4_H
  28. #include "llv4math.h"
  29. #include "llv4matrix3.h" // just for operator LLV4Matrix3()
  30. #include "llv4vector3.h"
  31. //-----------------------------------------------------------------------------
  32. //-----------------------------------------------------------------------------
  33. // LLV4Matrix4
  34. //-----------------------------------------------------------------------------
  35. //-----------------------------------------------------------------------------
  36. LL_LLV4MATH_ALIGN_PREFIX
  37. class LLV4Matrix4
  38. {
  39. public:
  40. union {
  41. F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
  42. V4F32 mV[LLV4_NUM_AXIS];
  43. };
  44. void lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w);
  45. void multiply(const LLVector3 &a, LLVector3& o) const;
  46. void multiply(const LLVector3 &a, LLV4Vector3& o) const;
  47. const LLV4Matrix4& transpose();
  48. const LLV4Matrix4& translate(const LLVector3 &vec);
  49. const LLV4Matrix4& translate(const LLV4Vector3 &vec);
  50. const LLV4Matrix4& operator=(const LLMatrix4& a);
  51. operator LLMatrix4() const { return *(reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0]))); }
  52. operator LLV4Matrix3() const { return *(reinterpret_cast<const LLV4Matrix3*>(const_cast<const F32*>(&mMatrix[0][0]))); }
  53. friend LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b);
  54. }
  55. LL_LLV4MATH_ALIGN_POSTFIX;
  56. //-----------------------------------------------------------------------------
  57. //-----------------------------------------------------------------------------
  58. // LLV4Matrix4 - SSE
  59. //-----------------------------------------------------------------------------
  60. //-----------------------------------------------------------------------------
  61. #if LL_VECTORIZE
  62. inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
  63. {
  64. __m128 vw = _mm_set1_ps(w);
  65. mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
  66. mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
  67. mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
  68. mV[VW] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VW], a.mV[VW]), vw), a.mV[VW]);
  69. }
  70. inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
  71. {
  72. LLV4Vector3 j;
  73. j.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
  74. j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
  75. j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
  76. o.setVec(j.mV);
  77. }
  78. inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
  79. {
  80. o.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
  81. o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
  82. o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
  83. }
  84. inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
  85. {
  86. mV[VW] = _mm_add_ps(mV[VW], vec.v);
  87. return (*this);
  88. }
  89. //-----------------------------------------------------------------------------
  90. //-----------------------------------------------------------------------------
  91. // LLV4Matrix4
  92. //-----------------------------------------------------------------------------
  93. //-----------------------------------------------------------------------------
  94. #else
  95. inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
  96. {
  97. mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
  98. mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
  99. mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
  100. mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
  101. mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
  102. mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
  103. mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
  104. mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
  105. mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
  106. mMatrix[VW][VX] = llv4lerp(a.mMatrix[VW][VX], b.mMatrix[VW][VX], w);
  107. mMatrix[VW][VY] = llv4lerp(a.mMatrix[VW][VY], b.mMatrix[VW][VY], w);
  108. mMatrix[VW][VZ] = llv4lerp(a.mMatrix[VW][VZ], b.mMatrix[VW][VZ], w);
  109. }
  110. inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
  111. {
  112. o.setVec( a.mV[VX] * mMatrix[VX][VX] +
  113. a.mV[VY] * mMatrix[VY][VX] +
  114. a.mV[VZ] * mMatrix[VZ][VX] +
  115. mMatrix[VW][VX],
  116. a.mV[VX] * mMatrix[VX][VY] +
  117. a.mV[VY] * mMatrix[VY][VY] +
  118. a.mV[VZ] * mMatrix[VZ][VY] +
  119. mMatrix[VW][VY],
  120. a.mV[VX] * mMatrix[VX][VZ] +
  121. a.mV[VY] * mMatrix[VY][VZ] +
  122. a.mV[VZ] * mMatrix[VZ][VZ] +
  123. mMatrix[VW][VZ]);
  124. }
  125. inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
  126. {
  127. o.setVec( a.mV[VX] * mMatrix[VX][VX] +
  128. a.mV[VY] * mMatrix[VY][VX] +
  129. a.mV[VZ] * mMatrix[VZ][VX] +
  130. mMatrix[VW][VX],
  131. a.mV[VX] * mMatrix[VX][VY] +
  132. a.mV[VY] * mMatrix[VY][VY] +
  133. a.mV[VZ] * mMatrix[VZ][VY] +
  134. mMatrix[VW][VY],
  135. a.mV[VX] * mMatrix[VX][VZ] +
  136. a.mV[VY] * mMatrix[VY][VZ] +
  137. a.mV[VZ] * mMatrix[VZ][VZ] +
  138. mMatrix[VW][VZ]);
  139. }
  140. inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
  141. {
  142. mMatrix[3][0] += vec.mV[0];
  143. mMatrix[3][1] += vec.mV[1];
  144. mMatrix[3][2] += vec.mV[2];
  145. return (*this);
  146. }
  147. //-----------------------------------------------------------------------------
  148. //-----------------------------------------------------------------------------
  149. // LLV4Matrix4
  150. //-----------------------------------------------------------------------------
  151. //-----------------------------------------------------------------------------
  152. #endif
  153. inline const LLV4Matrix4& LLV4Matrix4::operator=(const LLMatrix4& a)
  154. {
  155. memcpy(mMatrix, a.mMatrix, sizeof(F32) * 16 );
  156. return *this;
  157. }
  158. inline const LLV4Matrix4& LLV4Matrix4::transpose()
  159. {
  160. #if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
  161. _MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
  162. #else
  163. LLV4Matrix4 mat;
  164. mat.mMatrix[0][0] = mMatrix[0][0];
  165. mat.mMatrix[1][0] = mMatrix[0][1];
  166. mat.mMatrix[2][0] = mMatrix[0][2];
  167. mat.mMatrix[3][0] = mMatrix[0][3];
  168. mat.mMatrix[0][1] = mMatrix[1][0];
  169. mat.mMatrix[1][1] = mMatrix[1][1];
  170. mat.mMatrix[2][1] = mMatrix[1][2];
  171. mat.mMatrix[3][1] = mMatrix[1][3];
  172. mat.mMatrix[0][2] = mMatrix[2][0];
  173. mat.mMatrix[1][2] = mMatrix[2][1];
  174. mat.mMatrix[2][2] = mMatrix[2][2];
  175. mat.mMatrix[3][2] = mMatrix[2][3];
  176. mat.mMatrix[0][3] = mMatrix[3][0];
  177. mat.mMatrix[1][3] = mMatrix[3][1];
  178. mat.mMatrix[2][3] = mMatrix[3][2];
  179. mat.mMatrix[3][3] = mMatrix[3][3];
  180. *this = mat;
  181. #endif
  182. return *this;
  183. }
  184. inline const LLV4Matrix4& LLV4Matrix4::translate(const LLVector3 &vec)
  185. {
  186. mMatrix[3][0] += vec.mV[0];
  187. mMatrix[3][1] += vec.mV[1];
  188. mMatrix[3][2] += vec.mV[2];
  189. return (*this);
  190. }
  191. inline LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b)
  192. {
  193. return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] +
  194. a.mV[VY] * b.mMatrix[VY][VX] +
  195. a.mV[VZ] * b.mMatrix[VZ][VX] +
  196. b.mMatrix[VW][VX],
  197. a.mV[VX] * b.mMatrix[VX][VY] +
  198. a.mV[VY] * b.mMatrix[VY][VY] +
  199. a.mV[VZ] * b.mMatrix[VZ][VY] +
  200. b.mMatrix[VW][VY],
  201. a.mV[VX] * b.mMatrix[VX][VZ] +
  202. a.mV[VY] * b.mMatrix[VY][VZ] +
  203. a.mV[VZ] * b.mMatrix[VZ][VZ] +
  204. b.mMatrix[VW][VZ]);
  205. }
  206. #endif