using System; using UnityEngine; public class SteamVR_IK : MonoBehaviour { private void LateUpdate() { if (this.blendPct < 0.001f) { return; } Vector3 worldUp = (!this.upVector) ? Vector3.Cross(this.end.position - this.start.position, this.joint.position - this.start.position).normalized : this.upVector.up; Vector3 position = this.target.position; Quaternion rotation = this.target.rotation; Vector3 position2 = this.joint.position; Vector3 vector; Vector3 vector2; 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); if (vector2 == Vector3.zero) { return; } Vector3 position3 = this.start.position; Vector3 position4 = this.joint.position; Vector3 position5 = this.end.position; Quaternion localRotation = this.start.localRotation; Quaternion localRotation2 = this.joint.localRotation; Quaternion localRotation3 = this.end.localRotation; Transform parent = this.start.parent; Transform parent2 = this.joint.parent; Transform parent3 = this.end.parent; Vector3 localScale = this.start.localScale; Vector3 localScale2 = this.joint.localScale; Vector3 localScale3 = this.end.localScale; if (this.startXform == null) { this.startXform = new GameObject("startXform").transform; this.startXform.parent = base.transform; } this.startXform.position = position3; this.startXform.LookAt(this.joint, worldUp); this.start.parent = this.startXform; if (this.jointXform == null) { this.jointXform = new GameObject("jointXform").transform; this.jointXform.parent = this.startXform; } this.jointXform.position = position4; this.jointXform.LookAt(this.end, worldUp); this.joint.parent = this.jointXform; if (this.endXform == null) { this.endXform = new GameObject("endXform").transform; this.endXform.parent = this.jointXform; } this.endXform.position = position5; this.end.parent = this.endXform; this.startXform.LookAt(position2, vector2); this.jointXform.LookAt(position, vector2); this.endXform.rotation = rotation; this.start.parent = parent; this.joint.parent = parent2; this.end.parent = parent3; this.end.rotation = rotation; if (this.blendPct < 1f) { this.start.localRotation = Quaternion.Slerp(localRotation, this.start.localRotation, this.blendPct); this.joint.localRotation = Quaternion.Slerp(localRotation2, this.joint.localRotation, this.blendPct); this.end.localRotation = Quaternion.Slerp(localRotation3, this.end.localRotation, this.blendPct); } this.start.localScale = localScale; this.joint.localScale = localScale2; this.end.localScale = localScale3; } public static bool Solve(Vector3 start, Vector3 end, Vector3 poleVector, float jointDist, float targetDist, ref Vector3 result, out Vector3 forward, out Vector3 up) { float num = jointDist + targetDist; Vector3 a = end - start; Vector3 normalized = (poleVector - start).normalized; float magnitude = a.magnitude; result = start; if (magnitude < 0.001f) { result += normalized * jointDist; forward = Vector3.Cross(normalized, Vector3.up); up = Vector3.Cross(forward, normalized).normalized; } else { forward = a * (1f / magnitude); up = Vector3.Cross(forward, normalized).normalized; if (magnitude + 0.001f < num) { float num2 = (num + magnitude) * 0.5f; if (num2 > jointDist + 0.001f && num2 > targetDist + 0.001f) { float num3 = Mathf.Sqrt(num2 * (num2 - jointDist) * (num2 - targetDist) * (num2 - magnitude)); float num4 = 2f * num3 / magnitude; float d = Mathf.Sqrt(jointDist * jointDist - num4 * num4); Vector3 a2 = Vector3.Cross(up, forward); result += forward * d + a2 * num4; return true; } result += normalized * jointDist; } else { result += forward * jointDist; } } return false; } public Transform target; public Transform start; public Transform joint; public Transform end; public Transform poleVector; public Transform upVector; public float blendPct = 1f; [HideInInspector] public Transform startXform; [HideInInspector] public Transform jointXform; [HideInInspector] public Transform endXform; }