ShaderQuat.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2025 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. inline float3 JPH_QuatMulVec3(JPH_Quat inLHS, float3 inRHS)
  5. {
  6. float3 v_xyz = inLHS.xyz;
  7. float3 v_yzx = inLHS.yzx;
  8. float3 q_cross_p = (inRHS.yzx * v_xyz - v_yzx * inRHS).yzx;
  9. float3 q_cross_q_cross_p = (q_cross_p.yzx * v_xyz - v_yzx * q_cross_p).yzx;
  10. float3 v = inLHS.w * q_cross_p + q_cross_q_cross_p;
  11. return inRHS + (v + v);
  12. }
  13. inline JPH_Quat JPH_QuatMulQuat(JPH_Quat inLHS, JPH_Quat inRHS)
  14. {
  15. float x = inLHS.w * inRHS.x + inLHS.x * inRHS.w + inLHS.y * inRHS.z - inLHS.z * inRHS.y;
  16. float y = inLHS.w * inRHS.y - inLHS.x * inRHS.z + inLHS.y * inRHS.w + inLHS.z * inRHS.x;
  17. float z = inLHS.w * inRHS.z + inLHS.x * inRHS.y - inLHS.y * inRHS.x + inLHS.z * inRHS.w;
  18. float w = inLHS.w * inRHS.w - inLHS.x * inRHS.x - inLHS.y * inRHS.y - inLHS.z * inRHS.z;
  19. return JPH_Quat(x, y, z, w);
  20. }
  21. inline JPH_Quat JPH_QuatImaginaryMulQuat(float3 inLHS, JPH_Quat inRHS)
  22. {
  23. float x = +inLHS.x * inRHS.w + inLHS.y * inRHS.z - inLHS.z * inRHS.y;
  24. float y = -inLHS.x * inRHS.z + inLHS.y * inRHS.w + inLHS.z * inRHS.x;
  25. float z = +inLHS.x * inRHS.y - inLHS.y * inRHS.x + inLHS.z * inRHS.w;
  26. float w = -inLHS.x * inRHS.x - inLHS.y * inRHS.y - inLHS.z * inRHS.z;
  27. return JPH_Quat(x, y, z, w);
  28. }
  29. inline float3 JPH_QuatRotateAxisZ(JPH_Quat inRotation)
  30. {
  31. return (inRotation.z + inRotation.z) * inRotation.xyz + (inRotation.w + inRotation.w) * float3(inRotation.y, -inRotation.x, inRotation.w) - float3(0, 0, 1);
  32. }
  33. inline JPH_Quat JPH_QuatConjugate(JPH_Quat inRotation)
  34. {
  35. return JPH_Quat(-inRotation.x, -inRotation.y, -inRotation.z, inRotation.w);
  36. }
  37. inline JPH_Quat JPH_QuatDecompress(uint inValue)
  38. {
  39. const float cOneOverSqrt2 = 0.70710678f;
  40. const uint cNumBits = 9;
  41. const uint cMask = (1u << cNumBits) - 1;
  42. const uint cMaxValue = cMask - 1; // Need odd number of buckets to quantize to or else we can't encode 0
  43. const float cScale = 2.0f * cOneOverSqrt2 / float(cMaxValue);
  44. // Restore two components
  45. float3 v3 = float3(float(inValue & cMask), float((inValue >> cNumBits) & cMask), float((inValue >> (2 * cNumBits)) & cMask)) * cScale - float3(cOneOverSqrt2, cOneOverSqrt2, cOneOverSqrt2);
  46. // Restore the highest component
  47. float4 v = float4(v3, sqrt(max(1.0f - dot(v3, v3), 0.0f)));
  48. // Extract sign
  49. if ((inValue & 0x80000000u) != 0)
  50. v = -v;
  51. // Swizzle the components in place
  52. uint max_element = (inValue >> 29) & 3;
  53. v = max_element == 0? v.wxyz : (max_element == 1? v.xwyz : (max_element == 2? v.xywz : v));
  54. return v;
  55. }
  56. inline JPH_Quat JPH_QuatFromMat33(float3 inCol0, float3 inCol1, float3 inCol2)
  57. {
  58. float tr = inCol0.x + inCol1.y + inCol2.z;
  59. if (tr >= 0.0f)
  60. {
  61. float s = sqrt(tr + 1.0f);
  62. float is = 0.5f / s;
  63. return JPH_Quat(
  64. (inCol1.z - inCol2.y) * is,
  65. (inCol2.x - inCol0.z) * is,
  66. (inCol0.y - inCol1.x) * is,
  67. 0.5f * s);
  68. }
  69. else
  70. {
  71. if (inCol0.x > inCol1.y && inCol0.x > inCol2.z)
  72. {
  73. float s = sqrt(inCol0.x - (inCol1.y + inCol2.z) + 1);
  74. float is = 0.5f / s;
  75. return JPH_Quat(
  76. 0.5f * s,
  77. (inCol1.x + inCol0.y) * is,
  78. (inCol0.z + inCol2.x) * is,
  79. (inCol1.z - inCol2.y) * is);
  80. }
  81. else if (inCol1.y > inCol2.z)
  82. {
  83. float s = sqrt(inCol1.y - (inCol2.z + inCol0.x) + 1);
  84. float is = 0.5f / s;
  85. return JPH_Quat(
  86. (inCol1.x + inCol0.y) * is,
  87. 0.5f * s,
  88. (inCol2.y + inCol1.z) * is,
  89. (inCol2.x - inCol0.z) * is);
  90. }
  91. else
  92. {
  93. float s = sqrt(inCol2.z - (inCol0.x + inCol1.y) + 1);
  94. float is = 0.5f / s;
  95. return JPH_Quat(
  96. (inCol0.z + inCol2.x) * is,
  97. (inCol2.y + inCol1.z) * is,
  98. 0.5f * s,
  99. (inCol0.y - inCol1.x) * is);
  100. }
  101. }
  102. }