The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
6.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. namespace juce
  20. {
  21. //==============================================================================
  22. /**
  23. A 4x4 3D transformation matrix.
  24. @see Vector3D, Quaternion, AffineTransform
  25. @tags{OpenGL}
  26. */
  27. template <typename Type>
  28. class Matrix3D
  29. {
  30. public:
  31. /** Creates an identity matrix. */
  32. Matrix3D() noexcept
  33. {
  34. mat[0] = Type (1); mat[1] = 0; mat[2] = 0; mat[3] = 0;
  35. mat[4] = 0; mat[5] = Type (1); mat[6] = 0; mat[7] = 0;
  36. mat[8] = 0; mat[9] = 0; mat[10] = Type (1); mat[11] = 0;
  37. mat[12] = 0; mat[13] = 0; mat[14] = 0; mat[15] = Type (1);
  38. }
  39. /** Creates a copy of another matrix. */
  40. Matrix3D (const Matrix3D& other) noexcept
  41. {
  42. memcpy (mat, other.mat, sizeof (mat));
  43. }
  44. /** Copies another matrix. */
  45. Matrix3D& operator= (const Matrix3D& other) noexcept
  46. {
  47. memcpy (mat, other.mat, sizeof (mat));
  48. return *this;
  49. }
  50. /** Creates a matrix from its raw 4x4 values. */
  51. Matrix3D (Type m00, Type m10, Type m20, Type m30,
  52. Type m01, Type m11, Type m21, Type m31,
  53. Type m02, Type m12, Type m22, Type m32,
  54. Type m03, Type m13, Type m23, Type m33) noexcept
  55. {
  56. mat[0] = m00; mat[1] = m10; mat[2] = m20; mat[3] = m30;
  57. mat[4] = m01; mat[5] = m11; mat[6] = m21; mat[7] = m31;
  58. mat[8] = m02; mat[9] = m12; mat[10] = m22; mat[11] = m32;
  59. mat[12] = m03; mat[13] = m13; mat[14] = m23; mat[15] = m33;
  60. }
  61. /** Creates a matrix from an array of 16 raw values. */
  62. Matrix3D (const Type* values) noexcept
  63. {
  64. memcpy (mat, values, sizeof (mat));
  65. }
  66. /** Creates a matrix from a 2D affine transform. */
  67. Matrix3D (const AffineTransform& transform) noexcept
  68. {
  69. mat[0] = transform.mat00; mat[1] = transform.mat10; mat[2] = 0; mat[3] = 0;
  70. mat[4] = transform.mat01; mat[5] = transform.mat11; mat[6] = 0; mat[7] = 0;
  71. mat[8] = 0; mat[9] = 0; mat[10] = Type (1); mat[11] = 0;
  72. mat[12] = transform.mat02; mat[13] = transform.mat12; mat[14] = 0; mat[15] = Type (1);
  73. }
  74. /** Creates a matrix from a 3D vector translation. */
  75. Matrix3D (Vector3D<Type> vector) noexcept
  76. {
  77. mat[0] = Type (1); mat[1] = 0; mat[2] = 0; mat[3] = 0;
  78. mat[4] = 0; mat[5] = Type (1); mat[6] = 0; mat[7] = 0;
  79. mat[8] = 0; mat[9] = 0; mat[10] = Type (1); mat[11] = 0;
  80. mat[12] = vector.x; mat[13] = vector.y; mat[14] = vector.z; mat[15] = Type (1);
  81. }
  82. /** Returns a new matrix from the given frustum values. */
  83. static Matrix3D fromFrustum (Type left, Type right, Type bottom, Type top, Type nearDistance, Type farDistance) noexcept
  84. {
  85. return { (Type (2) * nearDistance) / (right - left), 0, 0, 0,
  86. 0, (Type (2) * nearDistance) / (top - bottom), 0, 0,
  87. (right + left) / (right - left), (top + bottom) / (top - bottom), -(farDistance + nearDistance) / (farDistance - nearDistance), Type (-1),
  88. 0, 0, -(Type (2) * farDistance * nearDistance) / (farDistance - nearDistance), 0 };
  89. }
  90. /** Returns a matrix which will apply a rotation through the Y, X and Z angles specified by a vector. */
  91. static Matrix3D rotation (Vector3D<Type> eulerAngleRadians) noexcept
  92. {
  93. auto cx = std::cos (eulerAngleRadians.x), sx = std::sin (eulerAngleRadians.x),
  94. cy = std::cos (eulerAngleRadians.y), sy = std::sin (eulerAngleRadians.y),
  95. cz = std::cos (eulerAngleRadians.z), sz = std::sin (eulerAngleRadians.z);
  96. return { (cy * cz) + (sx * sy * sz), cx * sz, (cy * sx * sz) - (cz * sy), 0,
  97. (cz * sx * sy) - (cy * sz), cx * cz, (cy * cz * sx) + (sy * sz), 0,
  98. cx * sy, -sx, cx * cy, 0,
  99. 0, 0, 0, Type (1) };
  100. }
  101. /** Multiplies this matrix by another. */
  102. Matrix3D& operator*= (const Matrix3D& other) noexcept
  103. {
  104. return *this = *this * other;
  105. }
  106. /** Multiplies this matrix by another, and returns the result. */
  107. Matrix3D operator* (const Matrix3D& other) const noexcept
  108. {
  109. auto&& m2 = other.mat;
  110. return { mat[0] * m2[0] + mat[1] * m2[4] + mat[2] * m2[8] + mat[3] * m2[12],
  111. mat[0] * m2[1] + mat[1] * m2[5] + mat[2] * m2[9] + mat[3] * m2[13],
  112. mat[0] * m2[2] + mat[1] * m2[6] + mat[2] * m2[10] + mat[3] * m2[14],
  113. mat[0] * m2[3] + mat[1] * m2[7] + mat[2] * m2[11] + mat[3] * m2[15],
  114. mat[4] * m2[0] + mat[5] * m2[4] + mat[6] * m2[8] + mat[7] * m2[12],
  115. mat[4] * m2[1] + mat[5] * m2[5] + mat[6] * m2[9] + mat[7] * m2[13],
  116. mat[4] * m2[2] + mat[5] * m2[6] + mat[6] * m2[10] + mat[7] * m2[14],
  117. mat[4] * m2[3] + mat[5] * m2[7] + mat[6] * m2[11] + mat[7] * m2[15],
  118. mat[8] * m2[0] + mat[9] * m2[4] + mat[10] * m2[8] + mat[11] * m2[12],
  119. mat[8] * m2[1] + mat[9] * m2[5] + mat[10] * m2[9] + mat[11] * m2[13],
  120. mat[8] * m2[2] + mat[9] * m2[6] + mat[10] * m2[10] + mat[11] * m2[14],
  121. mat[8] * m2[3] + mat[9] * m2[7] + mat[10] * m2[11] + mat[11] * m2[15],
  122. mat[12] * m2[0] + mat[13] * m2[4] + mat[14] * m2[8] + mat[15] * m2[12],
  123. mat[12] * m2[1] + mat[13] * m2[5] + mat[14] * m2[9] + mat[15] * m2[13],
  124. mat[12] * m2[2] + mat[13] * m2[6] + mat[14] * m2[10] + mat[15] * m2[14],
  125. mat[12] * m2[3] + mat[13] * m2[7] + mat[14] * m2[11] + mat[15] * m2[15] };
  126. }
  127. /** The 4x4 matrix values. These are stored in the standard OpenGL order. */
  128. Type mat[16];
  129. };
  130. } // namespace juce