using UnityEngine; namespace LMWidgets { /// /// Base class for spring. Restrains the widget in its local z-axis. /// It will apply spring physics in ApplyPhysics and translate the button with hand in ApplyInteractions /// public abstract class LeapPhysicsSpring : LeapPhysicsBase { /// /// Spring constant is separated to xyz-axis for more flexible configuration /// public Vector3 springCoefficient = Vector3.one * 10.0f; public bool applyCriticalDamping = true; private Vector3 m_dampingCoefficient = Vector3.zero; private Vector3 m_interactionConstraints = Vector3.one; /// /// Applies Interaction constraints. Takes in a Vector3. If an axis has value > 0.5 then it's allowed to move. Otherwise it won't be /// /// protected void ApplyInteractionConstraints(Vector3 interactionConstraints) { interactionConstraints.x = (interactionConstraints.x > 0.5f) ? 1.0f : 0.0f; interactionConstraints.y = (interactionConstraints.y > 0.5f) ? 1.0f : 0.0f; interactionConstraints.z = (interactionConstraints.z > 0.5f) ? 1.0f : 0.0f; m_interactionConstraints = interactionConstraints; ResetPivots(); } /// /// Apply spring physics /// protected override void ApplyPhysics() { Vector3 springForce = Vector3.Scale(-springCoefficient, transform.localPosition); Vector3 dampingForce = Vector3.zero; if (applyCriticalDamping) { Vector3 instantVelocity = springForce * Time.deltaTime; dampingForce = Vector3.Scale(-m_dampingCoefficient, instantVelocity); } transform.localPosition += (springForce + dampingForce) * Time.deltaTime; } /// /// Translate the widget with the hand during interaction /// protected override void ApplyInteractions() { Vector3 displacement = Vector3.Scale(transform.parent.InverseTransformPoint(m_target.transform.position) - m_targetPivot, m_interactionConstraints); transform.localPosition = displacement + m_pivot; } protected override void Awake() { base.Awake(); Vector3 k = springCoefficient; m_dampingCoefficient = 2 * new Vector3(Mathf.Sqrt(k.x), Mathf.Sqrt(k.y), Mathf.Sqrt(k.z)); } } }