private void Update(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); }
public void ProcessAnimation(AnimationStream stream) { float weight; if (m_UseAnimatorProperty) { weight = m_AnimatorWeight.GetFloat(stream); weight += m_AnimatorWeightOffset.GetFloat(stream); weight = Mathf.Clamp01(weight); //m_WeightHandle.SetFloat(stream, weight); } else { weight = m_WeightHandle.GetFloat(stream); } weight = 1f; Vector3 effectorPosition; Quaternion effectorRotation; if (m_UseStreamEffector) { effectorPosition = m_EffectorStreamHandle.GetPosition(stream); effectorRotation = m_EffectorStreamHandle.GetRotation(stream); } else { effectorPosition = m_EffectorSceneHandle.GetPosition(stream); effectorRotation = m_EffectorSceneHandle.GetRotation(stream); } effectorRotation *= Quaternion.Euler(m_TargetOffset); if (m_IkType == IkType.Generic) { SolveTwoBoneIK(stream, m_StartHandle, m_MidHandle, m_EndHandle, effectorPosition, effectorRotation, weight, weight); } else if (m_IkType == IkType.Humanoid) { if (stream.isHumanStream) { var humanStream = stream.AsHuman(); humanStream.SetGoalPosition(m_HumanLimb, effectorPosition); humanStream.SetGoalRotation(m_HumanLimb, effectorRotation); humanStream.SetGoalWeightPosition(m_HumanLimb, weight); humanStream.SetGoalWeightRotation(m_HumanLimb, weight); humanStream.SolveIK(); } } }
public void ProcessAnimation(AnimationStream stream) { float weight; if (m_UseAnimatorProperty) { weight = m_AnimatorWeight.GetFloat(stream); weight += m_AnimatorWeightOffset.GetFloat(stream); weight = Mathf.Clamp01(weight); m_WeightHandle.SetFloat(stream, weight); } else { weight = m_WeightHandle.GetFloat(stream); } weight = 1f; Vector3 effectorPosition; Quaternion effectorRotation; if (m_UseStreamEffector) { effectorPosition = m_EffectorStreamHandle.GetPosition(stream); effectorRotation = m_EffectorStreamHandle.GetRotation(stream); } else { effectorPosition = m_EffectorSceneHandle.GetPosition(stream); effectorRotation = m_EffectorSceneHandle.GetRotation(stream); } effectorRotation *= Quaternion.Euler(m_TargetOffset); // Changes to the stream seems to kill the foot ik data in the stream. // TODO: (sunek) Get rid of this workaround once fixed in release if (stream.isHumanStream) { var humanStream = stream.AsHuman(); humanStream.SetGoalPosition(AvatarIKGoal.LeftFoot, humanStream.GetGoalPosition(AvatarIKGoal.LeftFoot)); humanStream.SetGoalRotation(AvatarIKGoal.LeftFoot, humanStream.GetGoalRotation(AvatarIKGoal.LeftFoot)); humanStream.SetGoalPosition(AvatarIKGoal.RightFoot, humanStream.GetGoalPosition(AvatarIKGoal.RightFoot)); humanStream.SetGoalRotation(AvatarIKGoal.RightFoot, humanStream.GetGoalRotation(AvatarIKGoal.RightFoot)); } if (m_IkType == IkType.Generic) { AnimJobUtilities.SolveTwoBoneIK(stream, m_StartHandle, m_MidHandle, m_EndHandle, effectorPosition, effectorRotation, weight, weight); } else if (m_IkType == IkType.Humanoid) { if (stream.isHumanStream) { var humanStream = stream.AsHuman(); humanStream.SetGoalPosition(m_HumanLimb, effectorPosition); humanStream.SetGoalRotation(m_HumanLimb, effectorRotation); humanStream.SetGoalWeightPosition(m_HumanLimb, weight); humanStream.SetGoalWeightRotation(m_HumanLimb, weight); humanStream.SolveIK(); } } }
private void Update(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); }