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

118 lines
4.3 KiB
C#

using System;
using System.Linq;
using UnityEngine;
namespace FIMSpace.FTools
{
public partial class FimpIK_Arm
{
public Transform Root { get; protected set; }
public IKBone ChestIKBone;
public IKBone ShoulderIKBone { get { return IKBones[0]; } }
public IKBone UpperArmIKBone { get { return IKBones[1]; } }
public IKBone ForeArmIKBone { get { return IKBones[2]; } }
public IKBone HandIKBone { get { return IKBones[3]; } }
public IKBone GetBone(int index) { return IKBones[index]; }
public int BonesCount { get { return IKBones.Length; } }
public enum FIK_HintMode { Default, MiddleForward, MiddleBack, OnGoal, EndForward }
private bool everyIsChild;
public void Init(Transform root)
{
if (Initialized) return;
if (IKBones == null) return;
if (IKBones.Length == 0)
{
SetBones(ShoulderTransform, UpperarmTransform, LowerarmTransform, HandTransform);
}
UpperarmRotationOffset = Quaternion.identity;
TargetElbowNormal = Vector3.right;
Vector3 preNormal = Vector3.Cross(ForeArmIKBone.transform.position - UpperArmIKBone.transform.position, HandIKBone.transform.position - ForeArmIKBone.transform.position);
if (preNormal != Vector3.zero) TargetElbowNormal = preNormal;
FullLength = 0f;
ShoulderIKBone.Init(root, UpperArmIKBone.transform.position, TargetElbowNormal);
UpperArmIKBone.Init(root, ForeArmIKBone.transform.position, TargetElbowNormal);
ForeArmIKBone.Init(root, HandIKBone.transform.position, TargetElbowNormal);
HandIKBone.Init(root, HandIKBone.transform.position + (HandIKBone.transform.position - ForeArmIKBone.transform.position), TargetElbowNormal);
FullLength = IKBones[1].BoneLength + IKBones[2].BoneLength;
RefreshDefaultFlexNormal();
// Checking if bones hierarchy is fully connected and straight forward direct
if (HandIKBone.transform.parent != ForeArmIKBone.transform) everyIsChild = false;
else
if (ForeArmIKBone.transform.parent != UpperArmIKBone.transform) everyIsChild = false;
else everyIsChild = true;
ChestIKBone = new IKBone(ShoulderIKBone.transform.parent);
ChestIKBone.Init(root, ShoulderIKBone.transform.position, TargetElbowNormal);
SetRootReference(root);
// Calculating Hand middle
HandMiddleOffset = Vector3.zero;
if (HandIKBone.transform.childCount > 0)
{
HandMiddleOffset = HandIKBone.transform.GetChild(0).position;
for (int i = 1; i < HandIKBone.transform.childCount; i++)
{
HandMiddleOffset = Vector3.Lerp(HandMiddleOffset, HandIKBone.transform.GetChild(i).position, 0.5f);
}
HandMiddleOffset = Vector3.Lerp(HandMiddleOffset, HandIKBone.transform.position, 0.4f);
HandMiddleOffset = HandIKBone.transform.InverseTransformPoint(HandMiddleOffset);
}
Initialized = true;
}
public void SetBones(Transform shoulder, Transform upperArm, Transform forearm, Transform hand)
{
if (upperArm == null || forearm == null || hand == null) return;
ShoulderTransform = shoulder;
UpperarmTransform = upperArm;
LowerarmTransform = forearm;
HandTransform = hand;
int i = 0;
if ( shoulder == null)
{
IKBones = new IKBone[3];
}
else
{
IKBones = new IKBone[4];
IKBones[0] = new IKBone(shoulder);
i = 1;
}
IKBones[i] = new IKBone(upperArm);
IKBones[i+1] = new IKBone(forearm);
IKBones[i+2] = new IKBone(hand);
IKBones[0].SetChild(IKBones[1]);
IKBones[1].SetChild(IKBones[2]);
if ( shoulder != null) IKBones[2].SetChild(IKBones[3]);
IKTargetPosition = hand.position; IKTargetRotation = hand.rotation;
}
public void SetBones()
{
SetBones(ShoulderTransform, UpperarmTransform, LowerarmTransform, HandTransform);
}
}
}