您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

56 行
2.1 KiB

using UnityEngine;
using UnityEngine.Experimental.Animations;
public static class AnimJobUtilities
{
public static void SolveTwoBoneIK
(
AnimationStream stream,
TransformStreamHandle topHandle,
TransformStreamHandle midHandle,
TransformStreamHandle lowHandle,
Vector3 effectorPosition,
Quaternion effectorRotation,
float posWeight,
float rotWeight)
{
Quaternion aRotation = topHandle.GetRotation(stream);
Quaternion bRotation = midHandle.GetRotation(stream);
Vector3 aPosition = topHandle.GetPosition(stream);
Vector3 bPosition = midHandle.GetPosition(stream);
Vector3 cPosition = lowHandle.GetPosition(stream);
Vector3 ab = bPosition - aPosition;
Vector3 bc = cPosition - bPosition;
Vector3 ac = cPosition - aPosition;
Vector3 ad = (Vector3.Lerp(cPosition, effectorPosition, posWeight) - aPosition);
float oldAbcAngle = TriangleAngle(ac.magnitude, ab, bc);
float newAbcAngle = TriangleAngle(ad.magnitude, ab, bc);
Vector3 axis = Vector3.Cross(ab, bc).normalized;
float a = 0.5f * (oldAbcAngle - newAbcAngle);
float sin = Mathf.Sin(a);
float cos = Mathf.Cos(a);
Quaternion q = new Quaternion(axis.x * sin, axis.y * sin, axis.z * sin, cos);
Quaternion worldQ = q * bRotation;
midHandle.SetRotation(stream, worldQ);
aRotation = topHandle.GetRotation(stream);
cPosition = lowHandle.GetPosition(stream);
ac = cPosition - aPosition;
Quaternion fromTo = Quaternion.FromToRotation(ac, ad);
topHandle.SetRotation(stream, fromTo * aRotation);
lowHandle.SetRotation(stream, Quaternion.Lerp(lowHandle.GetRotation(stream), effectorRotation, rotWeight));
}
static float TriangleAngle(float aLen, Vector3 v1, Vector3 v2)
{
float aLen1 = v1.magnitude;
float aLen2 = v2.magnitude;
float c = Mathf.Clamp((aLen1 * aLen1 + aLen2 * aLen2 - aLen * aLen) / (aLen1 * aLen2) / 2.0f, -1.0f, 1.0f);
return Mathf.Acos(c);
}
}