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

/indra/llmath/llv4matrix3.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 220 lines | 135 code | 40 blank | 45 comment | 1 complexity | 3e9ae5e7f75f8843a2a53865e6d4559b 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_LLV4MATRIX3_H
  27. #define LL_LLV4MATRIX3_H
  28. #include "llv4math.h"
  29. #include "llv4vector3.h"
  30. #include "m3math.h" // for operator LLMatrix3()
  31. //-----------------------------------------------------------------------------
  32. //-----------------------------------------------------------------------------
  33. // LLV4Matrix3
  34. //-----------------------------------------------------------------------------
  35. //-----------------------------------------------------------------------------
  36. LL_LLV4MATH_ALIGN_PREFIX
  37. class LLV4Matrix3
  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 LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w);
  45. void multiply(const LLVector3 &a, LLVector3& out) const;
  46. void multiply(const LLVector4 &a, LLV4Vector3& out) const;
  47. void multiply(const LLVector3 &a, LLV4Vector3& out) const;
  48. const LLV4Matrix3& transpose();
  49. const LLV4Matrix3& operator=(const LLMatrix3& a);
  50. operator LLMatrix3() const { return (reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0])))->getMat3(); }
  51. friend LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b);
  52. }
  53. LL_LLV4MATH_ALIGN_POSTFIX;
  54. //-----------------------------------------------------------------------------
  55. //-----------------------------------------------------------------------------
  56. // LLV4Matrix3 - SSE
  57. //-----------------------------------------------------------------------------
  58. //-----------------------------------------------------------------------------
  59. #if LL_VECTORIZE
  60. inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
  61. {
  62. __m128 vw = _mm_set1_ps(w);
  63. 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
  64. mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
  65. mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
  66. }
  67. inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
  68. {
  69. LLV4Vector3 j;
  70. j.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
  71. j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
  72. j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
  73. o.setVec(j.mV);
  74. }
  75. inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
  76. {
  77. o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
  78. o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
  79. o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
  80. }
  81. inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
  82. {
  83. o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
  84. o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
  85. o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
  86. }
  87. //-----------------------------------------------------------------------------
  88. //-----------------------------------------------------------------------------
  89. // LLV4Matrix3
  90. //-----------------------------------------------------------------------------
  91. //-----------------------------------------------------------------------------
  92. #else
  93. inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
  94. {
  95. mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
  96. mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
  97. mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
  98. mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
  99. mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
  100. mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
  101. mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
  102. mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
  103. mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
  104. }
  105. inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
  106. {
  107. o.setVec( a.mV[VX] * mMatrix[VX][VX] +
  108. a.mV[VY] * mMatrix[VY][VX] +
  109. a.mV[VZ] * mMatrix[VZ][VX],
  110. a.mV[VX] * mMatrix[VX][VY] +
  111. a.mV[VY] * mMatrix[VY][VY] +
  112. a.mV[VZ] * mMatrix[VZ][VY],
  113. a.mV[VX] * mMatrix[VX][VZ] +
  114. a.mV[VY] * mMatrix[VY][VZ] +
  115. a.mV[VZ] * mMatrix[VZ][VZ]);
  116. }
  117. inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
  118. {
  119. o.setVec( a.mV[VX] * mMatrix[VX][VX] +
  120. a.mV[VY] * mMatrix[VY][VX] +
  121. a.mV[VZ] * mMatrix[VZ][VX],
  122. a.mV[VX] * mMatrix[VX][VY] +
  123. a.mV[VY] * mMatrix[VY][VY] +
  124. a.mV[VZ] * mMatrix[VZ][VY],
  125. a.mV[VX] * mMatrix[VX][VZ] +
  126. a.mV[VY] * mMatrix[VY][VZ] +
  127. a.mV[VZ] * mMatrix[VZ][VZ]);
  128. }
  129. inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
  130. {
  131. o.setVec( a.mV[VX] * mMatrix[VX][VX] +
  132. a.mV[VY] * mMatrix[VY][VX] +
  133. a.mV[VZ] * mMatrix[VZ][VX],
  134. a.mV[VX] * mMatrix[VX][VY] +
  135. a.mV[VY] * mMatrix[VY][VY] +
  136. a.mV[VZ] * mMatrix[VZ][VY],
  137. a.mV[VX] * mMatrix[VX][VZ] +
  138. a.mV[VY] * mMatrix[VY][VZ] +
  139. a.mV[VZ] * mMatrix[VZ][VZ]);
  140. }
  141. //-----------------------------------------------------------------------------
  142. //-----------------------------------------------------------------------------
  143. // LLV4Matrix3
  144. //-----------------------------------------------------------------------------
  145. //-----------------------------------------------------------------------------
  146. #endif
  147. inline const LLV4Matrix3& LLV4Matrix3::transpose()
  148. {
  149. #if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
  150. _MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
  151. return *this;
  152. #else
  153. F32 temp;
  154. temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
  155. temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
  156. temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
  157. #endif
  158. return *this;
  159. }
  160. inline const LLV4Matrix3& LLV4Matrix3::operator=(const LLMatrix3& a)
  161. {
  162. memcpy(mMatrix[VX], a.mMatrix[VX], sizeof(F32) * 3 );
  163. memcpy(mMatrix[VY], a.mMatrix[VY], sizeof(F32) * 3 );
  164. memcpy(mMatrix[VZ], a.mMatrix[VZ], sizeof(F32) * 3 );
  165. return *this;
  166. }
  167. inline LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b)
  168. {
  169. return LLVector3(
  170. a.mV[VX] * b.mMatrix[VX][VX] +
  171. a.mV[VY] * b.mMatrix[VY][VX] +
  172. a.mV[VZ] * b.mMatrix[VZ][VX],
  173. a.mV[VX] * b.mMatrix[VX][VY] +
  174. a.mV[VY] * b.mMatrix[VY][VY] +
  175. a.mV[VZ] * b.mMatrix[VZ][VY],
  176. a.mV[VX] * b.mMatrix[VX][VZ] +
  177. a.mV[VY] * b.mMatrix[VY][VZ] +
  178. a.mV[VZ] * b.mMatrix[VZ][VZ] );
  179. }
  180. #endif