llmatrix3a.inl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /**
  2. * @file llmatrix3a.inl
  3. * @brief LLMatrix3a inline definitions
  4. *
  5. * $LicenseInfo:firstyear=2010&license=viewergpl$
  6. *
  7. * Copyright (C) 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_INL_INCLUDE
  33. # error "You cannot #include this file yourself, #include llmath.h instead !"
  34. #endif
  35. LL_INLINE LLMatrix3a::LLMatrix3a(const LLVector4a& c0, const LLVector4a& c1,
  36. const LLVector4a& c2)
  37. {
  38. setColumns(c0, c1, c2);
  39. }
  40. LL_INLINE void LLMatrix3a::loadu(const LLMatrix3& src)
  41. {
  42. mColumns[0].load3(src.mMatrix[0]);
  43. mColumns[1].load3(src.mMatrix[1]);
  44. mColumns[2].load3(src.mMatrix[2]);
  45. }
  46. LL_INLINE void LLMatrix3a::setRows(const LLVector4a& r0,
  47. const LLVector4a& r1,
  48. const LLVector4a& r2)
  49. {
  50. mColumns[0] = r0;
  51. mColumns[1] = r1;
  52. mColumns[2] = r2;
  53. setTranspose(*this);
  54. }
  55. LL_INLINE void LLMatrix3a::setColumns(const LLVector4a& c0,
  56. const LLVector4a& c1,
  57. const LLVector4a& c2)
  58. {
  59. mColumns[0] = c0;
  60. mColumns[1] = c1;
  61. mColumns[2] = c2;
  62. }
  63. LL_INLINE void LLMatrix3a::setTranspose(const LLMatrix3a& src)
  64. {
  65. const LLQuad srcCol0 = src.mColumns[0];
  66. const LLQuad srcCol1 = src.mColumns[1];
  67. const LLQuad unpacklo = _mm_unpacklo_ps(srcCol0, srcCol1);
  68. mColumns[0] = _mm_movelh_ps(unpacklo, src.mColumns[2]);
  69. mColumns[1] = _mm_shuffle_ps(_mm_movehl_ps(srcCol0, unpacklo),
  70. src.mColumns[2],
  71. _MM_SHUFFLE(0, 1, 1, 0));
  72. mColumns[2] = _mm_shuffle_ps(_mm_unpackhi_ps(srcCol0, srcCol1),
  73. src.mColumns[2],
  74. _MM_SHUFFLE(0, 2, 1, 0));
  75. }
  76. LL_INLINE const LLVector4a& LLMatrix3a::getColumn(U32 column) const
  77. {
  78. llassert(column < 3);
  79. return mColumns[column];
  80. }
  81. LL_INLINE void LLMatrix3a::setLerp(const LLMatrix3a& a,
  82. const LLMatrix3a& b, F32 w)
  83. {
  84. mColumns[0].setLerp(a.mColumns[0], b.mColumns[0], w);
  85. mColumns[1].setLerp(a.mColumns[1], b.mColumns[1], w);
  86. mColumns[2].setLerp(a.mColumns[2], b.mColumns[2], w);
  87. }
  88. LL_INLINE LLBool32 LLMatrix3a::isFinite() const
  89. {
  90. return mColumns[0].isFinite3() && mColumns[1].isFinite3() &&
  91. mColumns[2].isFinite3();
  92. }
  93. LL_INLINE void LLMatrix3a::getDeterminant(LLVector4a& dest) const
  94. {
  95. LLVector4a col1xcol2; col1xcol2.setCross3(mColumns[1], mColumns[2]);
  96. dest.setAllDot3(col1xcol2, mColumns[0]);
  97. }
  98. LL_INLINE LLSimdScalar LLMatrix3a::getDeterminant() const
  99. {
  100. LLVector4a col1xcol2; col1xcol2.setCross3(mColumns[1], mColumns[2]);
  101. return col1xcol2.dot3(mColumns[0]);
  102. }
  103. LL_INLINE bool LLMatrix3a::isApproximatelyEqual(const LLMatrix3a& rhs,
  104. F32 tolerance) const
  105. {
  106. return rhs.getColumn(0).equals3(mColumns[0], tolerance) &&
  107. rhs.getColumn(1).equals3(mColumns[1], tolerance) &&
  108. rhs.getColumn(2).equals3(mColumns[2], tolerance);
  109. }
  110. LL_INLINE const LLMatrix3a& LLMatrix3a::getIdentity()
  111. {
  112. extern const LLMatrix3a LL_M3A_IDENTITY;
  113. return LL_M3A_IDENTITY;
  114. }
  115. LL_INLINE bool LLRotation::isOkRotation() const
  116. {
  117. LLMatrix3a transpose; transpose.setTranspose(*this);
  118. LLMatrix3a product; product.setMul(*this, transpose);
  119. LLSimdScalar detMinusOne = getDeterminant() - 1.f;
  120. return product.isApproximatelyEqual(LLMatrix3a::getIdentity()) &&
  121. detMinusOne.getAbs() < F_APPROXIMATELY_ZERO;
  122. }