SteamVR_IK.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System;
  2. using UnityEngine;
  3. public class SteamVR_IK : MonoBehaviour
  4. {
  5. private void LateUpdate()
  6. {
  7. if (this.blendPct < 0.001f)
  8. {
  9. return;
  10. }
  11. Vector3 worldUp = (!this.upVector) ? Vector3.Cross(this.end.position - this.start.position, this.joint.position - this.start.position).normalized : this.upVector.up;
  12. Vector3 position = this.target.position;
  13. Quaternion rotation = this.target.rotation;
  14. Vector3 position2 = this.joint.position;
  15. Vector3 vector;
  16. Vector3 vector2;
  17. SteamVR_IK.Solve(this.start.position, position, this.poleVector.position, (this.joint.position - this.start.position).magnitude, (this.end.position - this.joint.position).magnitude, ref position2, out vector, out vector2);
  18. if (vector2 == Vector3.zero)
  19. {
  20. return;
  21. }
  22. Vector3 position3 = this.start.position;
  23. Vector3 position4 = this.joint.position;
  24. Vector3 position5 = this.end.position;
  25. Quaternion localRotation = this.start.localRotation;
  26. Quaternion localRotation2 = this.joint.localRotation;
  27. Quaternion localRotation3 = this.end.localRotation;
  28. Transform parent = this.start.parent;
  29. Transform parent2 = this.joint.parent;
  30. Transform parent3 = this.end.parent;
  31. Vector3 localScale = this.start.localScale;
  32. Vector3 localScale2 = this.joint.localScale;
  33. Vector3 localScale3 = this.end.localScale;
  34. if (this.startXform == null)
  35. {
  36. this.startXform = new GameObject("startXform").transform;
  37. this.startXform.parent = base.transform;
  38. }
  39. this.startXform.position = position3;
  40. this.startXform.LookAt(this.joint, worldUp);
  41. this.start.parent = this.startXform;
  42. if (this.jointXform == null)
  43. {
  44. this.jointXform = new GameObject("jointXform").transform;
  45. this.jointXform.parent = this.startXform;
  46. }
  47. this.jointXform.position = position4;
  48. this.jointXform.LookAt(this.end, worldUp);
  49. this.joint.parent = this.jointXform;
  50. if (this.endXform == null)
  51. {
  52. this.endXform = new GameObject("endXform").transform;
  53. this.endXform.parent = this.jointXform;
  54. }
  55. this.endXform.position = position5;
  56. this.end.parent = this.endXform;
  57. this.startXform.LookAt(position2, vector2);
  58. this.jointXform.LookAt(position, vector2);
  59. this.endXform.rotation = rotation;
  60. this.start.parent = parent;
  61. this.joint.parent = parent2;
  62. this.end.parent = parent3;
  63. this.end.rotation = rotation;
  64. if (this.blendPct < 1f)
  65. {
  66. this.start.localRotation = Quaternion.Slerp(localRotation, this.start.localRotation, this.blendPct);
  67. this.joint.localRotation = Quaternion.Slerp(localRotation2, this.joint.localRotation, this.blendPct);
  68. this.end.localRotation = Quaternion.Slerp(localRotation3, this.end.localRotation, this.blendPct);
  69. }
  70. this.start.localScale = localScale;
  71. this.joint.localScale = localScale2;
  72. this.end.localScale = localScale3;
  73. }
  74. public static bool Solve(Vector3 start, Vector3 end, Vector3 poleVector, float jointDist, float targetDist, ref Vector3 result, out Vector3 forward, out Vector3 up)
  75. {
  76. float num = jointDist + targetDist;
  77. Vector3 a = end - start;
  78. Vector3 normalized = (poleVector - start).normalized;
  79. float magnitude = a.magnitude;
  80. result = start;
  81. if (magnitude < 0.001f)
  82. {
  83. result += normalized * jointDist;
  84. forward = Vector3.Cross(normalized, Vector3.up);
  85. up = Vector3.Cross(forward, normalized).normalized;
  86. }
  87. else
  88. {
  89. forward = a * (1f / magnitude);
  90. up = Vector3.Cross(forward, normalized).normalized;
  91. if (magnitude + 0.001f < num)
  92. {
  93. float num2 = (num + magnitude) * 0.5f;
  94. if (num2 > jointDist + 0.001f && num2 > targetDist + 0.001f)
  95. {
  96. float num3 = Mathf.Sqrt(num2 * (num2 - jointDist) * (num2 - targetDist) * (num2 - magnitude));
  97. float num4 = 2f * num3 / magnitude;
  98. float d = Mathf.Sqrt(jointDist * jointDist - num4 * num4);
  99. Vector3 a2 = Vector3.Cross(up, forward);
  100. result += forward * d + a2 * num4;
  101. return true;
  102. }
  103. result += normalized * jointDist;
  104. }
  105. else
  106. {
  107. result += forward * jointDist;
  108. }
  109. }
  110. return false;
  111. }
  112. public Transform target;
  113. public Transform start;
  114. public Transform joint;
  115. public Transform end;
  116. public Transform poleVector;
  117. public Transform upVector;
  118. public float blendPct = 1f;
  119. [HideInInspector]
  120. public Transform startXform;
  121. [HideInInspector]
  122. public Transform jointXform;
  123. [HideInInspector]
  124. public Transform endXform;
  125. }