Files

64 lines
3.2 KiB
C#

using FIMSpace.AnimationTools;
using FIMSpace.FTools;
using UnityEngine;
namespace FIMSpace.FProceduralAnimation
{
[System.Serializable]
public class AxisLockableIK : FimpIK_Limb
{
public enum EIKAxisLock { None = 0, X = 2, Y = 4, Z = 8 }
public EIKAxisLock FirstBoneAxisLock = EIKAxisLock.None;
public override void Update()
{
if (!Initialized) return;
Refresh();
// Foot IK Position ---------------------------------------------------
float posWeight = IKPositionWeight * IKWeight;
StartIKBone.sqrMagn = (MiddleIKBone.transform.position - StartIKBone.transform.position).sqrMagnitude;
MiddleIKBone.sqrMagn = (EndIKBone.transform.position - MiddleIKBone.transform.position).sqrMagnitude;
targetElbowNormal = GetDefaultFlexNormal();
if (ExtraHintAdjustementOffset != Vector3.zero)
{
targetElbowNormal = Vector3.Lerp(targetElbowNormal, CalculateElbowNormalToPosition(EndIKBone.transform.position + EndIKBone.transform.rotation * ExtraHintAdjustementOffset), ExtraHintAdjustementOffset.magnitude).normalized;
}
Vector3 orientationDirection = GetOrientationDirection(IKTargetPosition, InverseHint ? -targetElbowNormal : targetElbowNormal);
if (orientationDirection == Vector3.zero) orientationDirection = MiddleIKBone.transform.position - StartIKBone.transform.position;
if (posWeight > 0f)
{
Quaternion sBoneRot = StartIKBone.GetRotation(orientationDirection, targetElbowNormal) * StartBoneRotationOffset;
if (posWeight < 1f) sBoneRot = Quaternion.LerpUnclamped(StartIKBone.srcRotation, sBoneRot, posWeight);
if (FirstBoneAxisLock != EIKAxisLock.None) ApplyAxisLock(FirstBoneAxisLock, StartIKBone, ref sBoneRot);
StartIKBone.transform.rotation = sBoneRot;
Quaternion sMidBoneRot = MiddleIKBone.GetRotation(IKTargetPosition - MiddleIKBone.transform.position, MiddleIKBone.GetCurrentOrientationNormal());
if (posWeight < 1f) sMidBoneRot = Quaternion.LerpUnclamped(MiddleIKBone.srcRotation, sMidBoneRot, posWeight);
//if (SecondBoneAxisLock != EIKAxisLock.None) ApplyAxisLock(SecondBoneAxisLock, MiddleIKBone, ref sMidBoneRot);
MiddleIKBone.transform.rotation = sMidBoneRot;
}
postIKAnimatorEndBoneRot = EndIKBone.transform.rotation;
EndBoneRotation();
}
void ApplyAxisLock(EIKAxisLock axisLock, IKBone ikBone, ref Quaternion targetRotation)
{
Vector3 local = FEngineering.QToLocal(ikBone.transform.parent.rotation, targetRotation).eulerAngles;
if ((axisLock & EIKAxisLock.X) != 0) local.x = ikBone.LastKeyLocalRotation.eulerAngles.x;
if ((axisLock & EIKAxisLock.Y) != 0) local.y = ikBone.LastKeyLocalRotation.eulerAngles.y;
if ((axisLock & EIKAxisLock.Z) != 0) local.z = ikBone.LastKeyLocalRotation.eulerAngles.z;
targetRotation = FEngineering.QToWorld(ikBone.transform.parent.rotation, AnimationGenerateUtils.EnsureQuaternionContinuity(targetRotation, Quaternion.Euler(local)));
}
}
}