Files
Cielonos/Assets/OtherPlugins/FImpossible Creations/Plugins - Shared/IK/Arm/FimpIK_Arm.IKBone.cs
SoulliesOfficial f7af60351b 阶段性完成
2025-12-08 05:27:53 -05:00

109 lines
3.9 KiB
C#

using System;
using UnityEngine;
namespace FIMSpace.FTools
{
public partial class FimpIK_Arm
{
[System.Serializable]
public class IKBone
{
// Base variables -----------------------
public IKBone Child { get; private set; }
public Transform transform { get; protected set; }
public float sqrMagn = 0.1f;
public float BoneLength = 0.1f;
public float MotionWeight = 1f;
public Vector3 InitialLocalPosition;
public Quaternion InitialLocalRotation;
public Quaternion LastKeyLocalRotation;
// Arm ik specific -----------------------
[SerializeField] private Quaternion targetToLocalSpace;
[SerializeField] private Vector3 defaultLocalPoleNormal;
public Vector3 GetDefaultPoleNormal() { return defaultLocalPoleNormal; }
public Vector3 right { get; private set; }
public Vector3 up { get; private set; }
public Vector3 forward { get; private set; }
public Vector3 srcPosition { get; private set; }
public Quaternion srcRotation { get; private set; }
public IKBone(Transform t)
{
if (t == null) return;
transform = t;
InitialLocalPosition = transform.localPosition;
InitialLocalRotation = transform.localRotation;
LastKeyLocalRotation = t.localRotation;
}
public virtual void SetChild(IKBone child)
{
if (child.transform == null) return;
Child = child;
sqrMagn = (child.transform.position - transform.position).sqrMagnitude;
BoneLength = (child.transform.position - transform.position).magnitude;
}
public Vector3 Dir(Vector3 local)
{
return transform.TransformDirection(local);
}
public void Init(Transform root, Vector3 childPosition, Vector3 orientationNormal)
{
RefreshOrientations(childPosition, orientationNormal);
sqrMagn = (childPosition - transform.position).sqrMagnitude;
LastKeyLocalRotation = transform.localRotation;
right = transform.InverseTransformDirection(root.right);
up = transform.InverseTransformDirection(root.up);
forward = transform.InverseTransformDirection(root.forward);
CaptureSourceAnimation();
}
public void RefreshOrientations(Vector3 childPosition, Vector3 orientationNormal)
{
if (transform == null) return;
Vector3 dir = childPosition - transform.position;
Quaternion defaultTargetRotation;
if (dir == Vector3.zero) defaultTargetRotation = Quaternion.identity;
else
defaultTargetRotation = Quaternion.LookRotation(dir, orientationNormal);
targetToLocalSpace = RotationToLocal(transform.rotation, defaultTargetRotation);
defaultLocalPoleNormal = Quaternion.Inverse(transform.rotation) * orientationNormal;
}
public void CaptureSourceAnimation()
{
srcPosition = transform.position;
srcRotation = transform.rotation;
}
public static Quaternion RotationToLocal(Quaternion parent, Quaternion rotation)
{ return Quaternion.Inverse(Quaternion.Inverse(parent) * rotation); }
public Quaternion GetRotation(Vector3 direction, Vector3 orientationNormal)
{ return Quaternion.LookRotation(direction, orientationNormal) * targetToLocalSpace; }
public Vector3 GetCurrentOrientationNormal()
{ return transform.rotation * (defaultLocalPoleNormal); }
}
}
}