118 lines
4.3 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|