// 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; }