private void Update(UnityEngine.Animations.AnimationStream s) { if (!_target.IsValid(s)) { return; } float w = _IKPositionWeight.GetFloat(s); if (w <= 0) { return; } w = Mathf.Min(w, 1f); Read(s); bool XY = _XY.GetBool(s); float maxIterations = _maxIterations.GetInt(s); float tolerance = _tolerance.GetFloat(s); bool useRotationLimits = _useRotationLimits.GetBool(s); Vector3 IKPosition = _target.GetPosition(s); if (XY) { IKPosition.z = bones[0].GetPosition(s).z; } Vector3 singularityOffset = maxIterations > 1 ? GetSingularityOffset(s, IKPosition, useRotationLimits) : Vector3.zero; // Iterating the solver int it = 1; for (int i = 0; i < maxIterations; i++) { // Optimizations Vector3 localDirection = GetLocalDirection(s); if (singularityOffset == Vector3.zero && i >= 1 && tolerance > 0 && GetPositionOffset(s, localDirection) < tolerance * tolerance) { break; } lastLocalDirection = localDirection; Solve(s, IKPosition + (i == 0 ? singularityOffset : Vector3.zero), XY, w, it, useRotationLimits); it++; if (it >= bones.Length - 1) { it -= bones.Length - 2; } } lastLocalDirection = GetLocalDirection(s); }
private void Update(UnityEngine.Animations.AnimationStream s) { if (!_target.IsValid(s)) { return; } if (!_poleTarget.IsValid(s)) { return; } if (!_transform.IsValid(s)) { return; } Vector3 axis = new Vector3(_axisX.GetFloat(s), _axisY.GetFloat(s), _axisZ.GetFloat(s)); Vector3 poleAxis = new Vector3(_poleAxisX.GetFloat(s), _poleAxisY.GetFloat(s), _poleAxisZ.GetFloat(s)); float poleWeight = _poleWeight.GetFloat(s); poleWeight = Mathf.Clamp(poleWeight, 0f, 1f); if (axis == Vector3.zero) { return; } if (poleAxis == Vector3.zero && poleWeight > 0f) { return; } float IKPositionWeight = _IKPositionWeight.GetFloat(s); if (IKPositionWeight <= 0) { return; } IKPositionWeight = Mathf.Min(IKPositionWeight, 1f); bool XY = _XY.GetBool(s); float maxIterations = _maxIterations.GetInt(s); float tolerance = _tolerance.GetFloat(s); bool useRotationLimits = _useRotationLimits.GetBool(s); Vector3 IKPosition = _target.GetPosition(s); if (XY) { IKPosition.z = bones[0].GetPosition(s).z; } Vector3 polePosition = _poleTarget.GetPosition(s); if (XY) { polePosition.z = IKPosition.z; } float clampWeight = _clampWeight.GetFloat(s); clampWeight = Mathf.Clamp(clampWeight, 0f, 1f); int clampSmoothing = _clampSmoothing.GetInt(s); clampSmoothing = Mathf.Clamp(clampSmoothing, 0, 2); Vector3 transformPosition = _transform.GetPosition(s); Quaternion transformRotation = _transform.GetRotation(s); Vector3 transformAxis = transformRotation * axis; Vector3 clampedIKPosition = GetClampedIKPosition(s, clampWeight, clampSmoothing, IKPosition, transformPosition, transformAxis); Vector3 dir = clampedIKPosition - transformPosition; dir = Vector3.Slerp(transformAxis * dir.magnitude, dir, IKPositionWeight); clampedIKPosition = transformPosition + dir; // Iterating the solver for (int i = 0; i < maxIterations; i++) { // Optimizations if (i >= 0 && tolerance > 0 && GetAngle(s, axis, IKPosition) < tolerance) { break; } lastLocalDirection = GetLocalDirection(s, _transform.GetRotation(s) * axis); for (int n = 0; n < bones.Length - 1; n++) { RotateToTarget(s, clampedIKPosition, polePosition, n, step * (n + 1) * IKPositionWeight * boneWeights[n].GetFloat(s), poleWeight, XY, useRotationLimits, axis, poleAxis); } RotateToTarget(s, clampedIKPosition, polePosition, bones.Length - 1, IKPositionWeight * boneWeights[bones.Length - 1].GetFloat(s), poleWeight, XY, useRotationLimits, axis, poleAxis); } lastLocalDirection = GetLocalDirection(s, _transform.GetRotation(s) * axis); }