// From root to end-effector
        public void DoBackwardPass()
        {
            Vector2 targetCenter = lastTargetCenter;

            for (int boneIdx = bones.Count - 1; boneIdx >= 0; --boneIdx)
            {
                Vector2 currentEnd    = positions[boneIdx];
                Vector2 currentCenter = positions[boneIdx + 1];

                float targetRotationDelta = Vector2Utils.AngleBetween(
                    currentEnd - currentCenter,
                    currentEnd - targetCenter);
                float   unconstrainedTargetRotation = rotations[boneIdx] + targetRotationDelta;
                float   targetRotation = ConstraintRotationAgainstParent(boneIdx, unconstrainedTargetRotation);
                Vector2 targetEnd      = targetCenter + Vector2Utils.RotateBy(targetRotation, unposedBoneVectors[boneIdx]);

                positions[boneIdx + 1] = targetCenter;
                rotations[boneIdx]     = targetRotation;
                targetCenter           = targetEnd;
            }

            positions[0] = targetCenter;
        }
        //From end-effector to root
        public void DoForwardPass()
        {
            Vector2 targetEnd = firstTargetEnd;

            for (int boneIdx = 0; boneIdx < bones.Count; ++boneIdx)
            {
                Vector2 currentEnd    = positions[boneIdx];
                Vector2 currentCenter = positions[boneIdx + 1];

                float targetRotationDelta = Vector2Utils.AngleBetween(
                    currentEnd - currentCenter,
                    targetEnd - currentCenter);
                float   unconstrainedTargetRotation = rotations[boneIdx] + targetRotationDelta;
                float   targetRotation = ConstrainRotationAgainstChild(boneIdx, unconstrainedTargetRotation);
                Vector2 targetCenter   = targetEnd - Vector2Utils.RotateBy(targetRotation, unposedBoneVectors[boneIdx]);

                positions[boneIdx] = targetEnd;
                rotations[boneIdx] = targetRotation;
                targetEnd          = targetCenter;
            }

            positions[bones.Count] = targetEnd;
        }