12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- using UnityEngine.Scripting.APIUpdating;
-
- namespace UnityEngine.U2D.IK
- {
- /// <summary>
- /// Utility for 2D based Cyclic Coordinate Descent (CCD) IK Solver.
- /// </summary>
- [MovedFrom("UnityEngine.Experimental.U2D.IK")]
- public static class CCD2D
- {
- /// <summary>
- /// Solve IK Chain based on CCD.
- /// </summary>
- /// <param name="targetPosition">Target position.</param>
- /// <param name="forward">Forward vector for solver.</param>
- /// <param name="solverLimit">Solver iteration count.</param>
- /// <param name="tolerance">Target position's tolerance.</param>
- /// <param name="velocity">Velocity towards target position.</param>
- /// <param name="positions">Chain positions.</param>
- /// <returns>Returns true if solver successfully completes within iteration limit. False otherwise.</returns>
- public static bool Solve(Vector3 targetPosition, Vector3 forward, int solverLimit, float tolerance, float velocity, ref Vector3[] positions)
- {
- var last = positions.Length - 1;
- var iterations = 0;
- var sqrTolerance = tolerance * tolerance;
- var sqrDistanceToTarget = (targetPosition - positions[last]).sqrMagnitude;
- while (sqrDistanceToTarget > sqrTolerance)
- {
- DoIteration(targetPosition, forward, last, velocity, ref positions);
- sqrDistanceToTarget = (targetPosition - positions[last]).sqrMagnitude;
- if (++iterations >= solverLimit)
- break;
- }
-
- return iterations != 0;
- }
-
- static void DoIteration(Vector3 targetPosition, Vector3 forward, int last, float velocity, ref Vector3[] positions)
- {
- for (var i = last - 1; i >= 0; --i)
- {
- var toTarget = targetPosition - positions[i];
- var toLast = positions[last] - positions[i];
-
- var angle = Vector3.SignedAngle(toLast, toTarget, forward);
- angle = Mathf.Lerp(0f, angle, velocity);
-
- var deltaRotation = Quaternion.AngleAxis(angle, forward);
- for (var j = last; j > i; --j)
- positions[j] = RotatePositionFrom(positions[j], positions[i], deltaRotation);
- }
- }
-
- static Vector3 RotatePositionFrom(Vector3 position, Vector3 pivot, Quaternion rotation)
- {
- var v = position - pivot;
- v = rotation * v;
- return pivot + v;
- }
- }
- }
|