108 lines
2.9 KiB
C#
108 lines
2.9 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace RootMotion.FinalIK
|
|
{
|
|
[Serializable]
|
|
public class IKSolverCCD : IKSolverHeuristic
|
|
{
|
|
public IterationDelegate OnPreIteration;
|
|
|
|
public void FadeOutBoneWeights()
|
|
{
|
|
if (bones.Length >= 2)
|
|
{
|
|
bones[0].weight = 1f;
|
|
float num = 1f / (float)(bones.Length - 1);
|
|
for (int i = 1; i < bones.Length; i++)
|
|
{
|
|
bones[i].weight = num * (float)(bones.Length - 1 - i);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnInitiate()
|
|
{
|
|
if (firstInitiation || !Application.isPlaying)
|
|
{
|
|
IKPosition = bones[bones.Length - 1].transform.position;
|
|
}
|
|
InitiateBones();
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
if (IKPositionWeight <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
IKPositionWeight = Mathf.Clamp(IKPositionWeight, 0f, 1f);
|
|
if (target != null)
|
|
{
|
|
IKPosition = target.position;
|
|
}
|
|
if (XY)
|
|
{
|
|
IKPosition.z = bones[0].transform.position.z;
|
|
}
|
|
Vector3 vector = ((maxIterations > 1) ? GetSingularityOffset() : Vector3.zero);
|
|
for (int i = 0; i < maxIterations && (!(vector == Vector3.zero) || i < 1 || !(tolerance > 0f) || !(base.positionOffset < tolerance * tolerance)); i++)
|
|
{
|
|
lastLocalDirection = localDirection;
|
|
if (OnPreIteration != null)
|
|
{
|
|
OnPreIteration(i);
|
|
}
|
|
Solve(IKPosition + ((i == 0) ? vector : Vector3.zero));
|
|
}
|
|
lastLocalDirection = localDirection;
|
|
}
|
|
|
|
protected void Solve(Vector3 targetPosition)
|
|
{
|
|
if (XY)
|
|
{
|
|
for (int num = bones.Length - 2; num > -1; num--)
|
|
{
|
|
float num2 = bones[num].weight * IKPositionWeight;
|
|
if (num2 > 0f)
|
|
{
|
|
Vector3 vector = bones[bones.Length - 1].transform.position - bones[num].transform.position;
|
|
Vector3 vector2 = targetPosition - bones[num].transform.position;
|
|
float current = Mathf.Atan2(vector.x, vector.y) * 57.29578f;
|
|
float num3 = Mathf.Atan2(vector2.x, vector2.y) * 57.29578f;
|
|
bones[num].transform.rotation = Quaternion.AngleAxis(Mathf.DeltaAngle(current, num3) * num2, Vector3.back) * bones[num].transform.rotation;
|
|
}
|
|
if (useRotationLimits && bones[num].rotationLimit != null)
|
|
{
|
|
bones[num].rotationLimit.Apply();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
for (int num4 = bones.Length - 2; num4 > -1; num4--)
|
|
{
|
|
float num5 = bones[num4].weight * IKPositionWeight;
|
|
if (num5 > 0f)
|
|
{
|
|
Vector3 fromDirection = bones[bones.Length - 1].transform.position - bones[num4].transform.position;
|
|
Vector3 toDirection = targetPosition - bones[num4].transform.position;
|
|
Quaternion quaternion = Quaternion.FromToRotation(fromDirection, toDirection) * bones[num4].transform.rotation;
|
|
if (num5 >= 1f)
|
|
{
|
|
bones[num4].transform.rotation = quaternion;
|
|
}
|
|
else
|
|
{
|
|
bones[num4].transform.rotation = Quaternion.Lerp(bones[num4].transform.rotation, quaternion, num5);
|
|
}
|
|
}
|
|
if (useRotationLimits && bones[num4].rotationLimit != null)
|
|
{
|
|
bones[num4].rotationLimit.Apply();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|