阶段性完成

This commit is contained in:
SoulliesOfficial
2025-12-08 05:27:53 -05:00
parent ef7b479712
commit f7af60351b
8770 changed files with 15637030 additions and 208354 deletions

View File

@@ -0,0 +1,62 @@
using System;
using UnityEngine;
namespace FIMSpace.FTools
{
public partial class FimpIK_Arm
{
private Vector3 lastIKBasePosition;
private Quaternion lastIKBaseRotation;
public Vector3 IKTargetPosition;
public Quaternion IKTargetRotation;
/// <summary> Length of whole bones chain (squared and not scalled) </summary>
public float FullLength { get; protected set; }
public bool Initialized { get; set; }
public void PreCalibrate(float blend = 1f)
{
IKBone child = IKBones[0];
if (blend >= 1f)
{
while (child != null)
{
child.transform.localRotation = child.InitialLocalRotation;
child = child.Child;
}
}
else
{
while (child != null)
{
child.transform.localRotation = Quaternion.LerpUnclamped(child.transform.localRotation, child.InitialLocalRotation, blend);
child = child.Child;
}
}
RefreshScaleReference();
}
private float sd_ikBlend = 0f;
public void User_SmoothIKBlend(float target, float duration, float delta, float maxSpeed = 1000f)
{
IKWeight = Mathf.SmoothDamp(IKWeight, target, ref sd_ikBlend, duration, maxSpeed, delta);
}
private Vector3 sd_ikTargetPosition = Vector3.zero;
public void User_SmoothPositionTowards(Vector3 newIKPos, float duration, float delta, float maxSpeed = 1000f)
{
IKTargetPosition = Vector3.SmoothDamp(IKTargetPosition, newIKPos, ref sd_ikTargetPosition, duration, maxSpeed, delta);
}
public Vector3 GetHintDefaultPosition()
{
return ForeArmIKBone.transform.position + ForeArmIKBone.transform.rotation * UpperArmIKBone.GetDefaultPoleNormal();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f474b4b6ec8ec5440a2af7c0db0923d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,183 @@
using System;
using UnityEngine;
namespace FIMSpace.FTools
{
public partial class FimpIK_Arm
{
// Foot/End Bone rotation helper with root reference
public Quaternion HandIKBoneMapping { get; protected set; }
public void SetCustomIKRotationMappingOffset(Quaternion mappingCorrection) { HandIKBoneMapping = mappingCorrection; }
[NonSerialized] public Vector3 HandMiddleOffset;
private Vector3 shoulderForward;
private UniRotateBone shoulderRotate;
private Vector3 initHandRootSpaceFlatTowards;
internal bool UseRotationMapping = true;
/// <summary> >= 1.2 is max </summary>
[NonSerialized] public float MaxStretching = 1.2f;
/// <summary> Assigning helpful reference to main root transform of body to help IK rotations </summary>
public virtual void SetRootReference(Transform mainParentTransform)
{
Root = mainParentTransform;
Quaternion preRot = Root.transform.rotation;
Root.transform.rotation = Quaternion.identity;
Vector3 handForwardWorld = (HandIKBone.transform.position - ForeArmIKBone.transform.position).normalized;
Vector3 handLocalForward = HandIKBone.transform.InverseTransformDirection(handForwardWorld);
Vector3 handLocalRight = mainParentTransform.forward;
Vector3 handLocalUp = Vector3.Cross(handLocalForward, handLocalRight);
Vector3 shoulderForwardWorld = (ShoulderIKBone.transform.position - ShoulderIKBone.transform.parent.position).normalized;
shoulderForward = ShoulderIKBone.transform.InverseTransformDirection(shoulderForwardWorld);
HandIKBoneMapping = Quaternion.FromToRotation(handLocalRight, Vector3.right);
HandIKBoneMapping *= Quaternion.FromToRotation(handLocalUp, Vector3.up);
shoulderRotate = new UniRotateBone(ShoulderTransform, mainParentTransform);
Root.transform.rotation = preRot;
initHandRootSpaceFlatTowards = Root.InverseTransformPoint(HandTransform.position);
initHandRootSpaceFlatTowards.y = 0f;
initHandRootSpaceFlatTowards.Normalize();
}
/// <summary>
/// Put here any euler rotation (like 0,90,0) which will be mapped for correct hand rotation no matter how bones are rotated in skeleton rig (but root reference needed)
/// </summary>
/// <param name="rotation"></param>
public void SetCustomIKRotation(Quaternion rotation, float blend = 1f, bool fromDefault = false)
{
if (blend == 1f)
{
if (UseRotationMapping)
IKTargetRotation = rotation * HandIKBoneMapping;
else
IKTargetRotation = rotation;
}
else
{
if (UseRotationMapping)
{
if (fromDefault)
IKTargetRotation = Quaternion.LerpUnclamped(IKTargetRotation, rotation * HandIKBoneMapping, blend);
else
IKTargetRotation = Quaternion.LerpUnclamped(rotation, rotation * HandIKBoneMapping, blend);
}
else
{
if (fromDefault)
IKTargetRotation = Quaternion.LerpUnclamped(IKTargetRotation, rotation, blend);
else
IKTargetRotation = Quaternion.LerpUnclamped(rotation, rotation, blend);
}
}
}
public void CaptureKeyframeAnimation()
{
shoulderRotate.CaptureKeyframeAnimation();
IKBone child = IKBones[0];
while (child != null)
{
child.CaptureSourceAnimation();
child = (IKBone)child.Child;
}
}
/// <summary> Reference scale for computations - active length from start bone to middle knee </summary>
public float ScaleReference { get; protected set; }
public void RefreshLength()
{
ScaleReference = (UpperArmIKBone.transform.position - ForeArmIKBone.transform.position).magnitude;
}
public void RefreshScaleReference()
{
ScaleReference = (UpperArmIKBone.transform.position - ForeArmIKBone.transform.position).magnitude;
}
/// <summary> Returning >= 1f when max range for IK point is reached </summary>
public float GetStretchValue(Vector3 targetPos)
{
float toGoal = (UpperArmIKBone.transform.position - targetPos).magnitude;
return toGoal / limbLength;
}
public float GetStretchValueSrc(Vector3 targetPos)
{
float toGoal = (UpperArmIKBone.srcPosition - targetPos).magnitude;
return toGoal / limbLength;
}
protected virtual void CalculateLimbLength()
{
limbLength = Mathf.Epsilon;
//if (ShoulderIKBone.transform)
//{
// float shouldLen = (ShoulderIKBone.transform.position - UpperArmIKBone.transform.position).magnitude;
// limbLength += shouldLen * ShoulderBlend;
//}
limbLength += (UpperArmIKBone.transform.position - ForeArmIKBone.transform.position).magnitude;
limbLength += (ForeArmIKBone.transform.position - HandIKBone.transform.position).magnitude;
}
public bool PreventShoulderThirdQuat { get; set; } = true;
/// <summary> By default value is 0.75 </summary>
public float ShoulderSensitivity { get; set; } = 0.75f;
public float PreventShoulderThirdQuatFactor { get; set; } = 0.01f;
public float limbLength { get; private set; } = 0.1f;
// Shoulder -----------------------
void ComputeShoulder(Vector3 finalIKPos)
{
if (!Initialized) return;
if (ShoulderBlend <= 0f) return;
Vector3 toGoal = (finalIKPos - shoulderRotate.transform.position);
Quaternion nRot;
if (Root)
{
//nRot =(Root.rotation) * Quaternion.Euler(rrr);
//nRot *= shoulderRotate.transform.rotation;
Quaternion preRot = shoulderRotate.transform.rotation;
Quaternion q = Quaternion.FromToRotation(Root.InverseTransformDirection(toGoal).normalized, initHandRootSpaceFlatTowards);
Vector3 mappedRotation = -q.eulerAngles;
shoulderRotate.RotateXBy(mappedRotation.x);
shoulderRotate.RotateYBy(mappedRotation.y);
shoulderRotate.RotateZBy(mappedRotation.z);
nRot = shoulderRotate.transform.rotation;
shoulderRotate.transform.rotation = preRot;
}
else
{
nRot = (ShoulderIKBone.GetRotation(toGoal.normalized, ShoulderIKBone.srcRotation * shoulderRotate.upReference));
}
float blend = IKWeight * ShoulderBlend;
float armStretch = GetStretchValue(finalIKPos);
armStretch *= 0.85f;
if (armStretch > 1f) armStretch = 1f;
blend *= Mathf.InverseLerp(0.6f, 1f, armStretch) * 0.9f;
ShoulderIKBone.transform.rotation = Quaternion.Slerp(shoulderRotate.transform.rotation, nRot, blend);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb216e3cea30e5e49b43d367c59d01a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
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); }
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d8206dbc5aff4ee468e860be374a777a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,117 @@
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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3db5be43a8560824cb8442841962e470
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
using System;
using UnityEngine;
namespace FIMSpace.FTools
{
public partial class FimpIK_Arm
{
/*[HideInInspector] */
[Range(0f, 1f)] public float ManualHintPositionWeight = 0f;
[HideInInspector] public Vector3 IKManualHintPosition = Vector3.zero;
protected virtual void Refresh()
{
RefreshAnimatorCoords();
// If limb have more than 3 point bones then we must update some data for main two bones
if (!everyIsChild)
{
UpperArmIKBone.RefreshOrientations(ForeArmIKBone.transform.position, TargetElbowNormal);
ForeArmIKBone.RefreshOrientations(HandIKBone.transform.position, TargetElbowNormal);
}
}
protected virtual void HandBoneRotation()
{
float rotWeight = HandRotationWeight * IKWeight * _internalIKWeight;
if (rotWeight > 0f)
{
if (rotWeight < 1f)
HandIKBone.transform.rotation = Quaternion.LerpUnclamped(HandIKBone.transform.rotation, IKTargetRotation, rotWeight);
else
HandIKBone.transform.rotation = IKTargetRotation;
}
}
public void RefreshAnimatorCoords()
{
if (ShoulderIKBone != null) ShoulderIKBone.CaptureSourceAnimation();
UpperArmIKBone.CaptureSourceAnimation();
ForeArmIKBone.CaptureSourceAnimation();
HandIKBone.CaptureSourceAnimation();
}
private Vector3 GetDefaultFlexNormal()
{
if (ManualHintPositionWeight > 0f)
{
if (ManualHintPositionWeight >= 1f)
return CalculateElbowNormalToPosition(IKManualHintPosition);
else
return Vector3.LerpUnclamped(GetAutomaticFlexNormal().normalized, CalculateElbowNormalToPosition(IKManualHintPosition), ManualHintPositionWeight);
}
else
return GetAutomaticFlexNormal();
}
public Vector3 CalculateElbowNormalToPosition(Vector3 targetElbowPos)
{
return Vector3.Cross(targetElbowPos - UpperArmIKBone.transform.position, HandIKBone.transform.position - UpperArmIKBone.transform.position);
}
public void RefreshDefaultFlexNormal()
{
Vector3 normal = Vector3.Cross(ForeArmIKBone.transform.position - UpperArmIKBone.transform.position, HandIKBone.transform.position - ForeArmIKBone.transform.position);
if (normal != Vector3.zero) TargetElbowNormal = normal;
}
private Vector3 GetOrientationDirection(Vector3 ikPosition, Vector3 orientationNormal)
{
Vector3 direction = ikPosition - UpperArmIKBone.transform.position; // From start bone to target ik position
if (direction == Vector3.zero) return Vector3.zero;
float distSqrStartToGoal = direction.sqrMagnitude; // Computing length for bones
float distStartToGoal = Mathf.Sqrt(distSqrStartToGoal);
float forwardLen = (distSqrStartToGoal + UpperArmIKBone.sqrMagn - ForeArmIKBone.sqrMagn) / 2f / distStartToGoal;
float upLen = Mathf.Sqrt(Mathf.Clamp(UpperArmIKBone.sqrMagn - forwardLen * forwardLen, 0, Mathf.Infinity));
Vector3 perpendicularUp = Vector3.Cross(direction / distStartToGoal, orientationNormal);
return Quaternion.LookRotation(direction, perpendicularUp) * new Vector3(0f, upLen, forwardLen);
}
private float sd_targetIKRotation = 0f;
public void IKHandRotationWeightFadeTo(float to, float duration, float delta)
{
HandRotationWeight = Mathf.SmoothDamp(HandRotationWeight, to, ref sd_targetIKRotation, duration, Mathf.Infinity, delta);
}
private float sd_positionWeight = 0f;
public bool IsCorrect
{
get
{
if (Initialized == false) return false;
if (UpperarmTransform == null) return false;
if (LowerarmTransform == null) return false;
if (shoulderRotate == null) return false;
if (shoulderRotate.transform == null) return false;
return true;
}
}
public void IKHandPositionWeightFadeTo(float to, float duration, float delta)
{
IKPositionWeight = Mathf.SmoothDamp(IKPositionWeight, to, ref sd_positionWeight, duration, Mathf.Infinity, delta);
}
/// <summary>
/// IK position offsetted with hand middle position
/// </summary>
public Vector3 GetMiddleHandPosition(Vector3 tgt)
{
Matrix4x4 mx = Matrix4x4.TRS(IKTargetPosition, IKTargetRotation, HandIKBone.transform.lossyScale);
return tgt - mx.MultiplyVector(HandMiddleOffset);
}
public Vector3 GetLimitedIKPosToMax(Vector3 targetIKPos, float lengthFactor = 1f)
{
Vector3 dir = targetIKPos - UpperArmIKBone.transform.position;
return UpperArmIKBone.transform.position + dir.normalized * lengthFactor * limbLength;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60a2d59ca83150b428c3e0b5e351ee72
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
using System;
using UnityEngine;
namespace FIMSpace.FTools
{
// TODO -> Limiting, Weights, Goal Modes
/// <summary>
/// FC: Class for processing IK logics for 3-bones inverse kinematics
/// </summary>
[System.Serializable]
public partial class FimpIK_Arm
{
[NonSerialized] public float _internalIKWeight = 1f;
[Range(0f, 1f)] public float IKWeight = 1f;
[Tooltip("Blend value for goal position")] [Space(4)] [Range(0f, 1f)] public float IKPositionWeight = 1f;
[Tooltip("Blend value hand rotation")] [Range(0f, 1f)] public float HandRotationWeight = 1f;
[Tooltip("Blend value for shoulder rotation")] [Range(0f, 1f)] public float ShoulderBlend = 1f;
[Tooltip("Flex style algorithm for different limbs")] public FIK_HintMode AutoHintMode = FIK_HintMode.MiddleForward;
[Tooltip("If left limb behaves wrong in comparison to right one")] public bool MirrorMaths = false;
[FPD_Header("Bones References")]
public Transform ShoulderTransform;
public Transform UpperarmTransform;
public Transform LowerarmTransform;
public Transform HandTransform;
[SerializeField] [HideInInspector] private IKBone[] IKBones;
public Vector3 TargetElbowNormal { get; private set; }
public Quaternion UpperarmRotationOffset { get; set; }
/// <summary> Updating processor with 3-bones oriented inverse kinematics </summary>
public void Update()
{
if (!Initialized) return;
CalculateLimbLength();
Refresh();
ComputeShoulder(IKTargetPosition);
Vector3 targetIKPos = IKTargetPosition;
#region Max Stretching Feature
if (MaxStretching < 1.2f)
{
CalculateLimbLength();
float stretch = GetStretchValue(targetIKPos);
if (stretch > MaxStretching)
{
float len = (MaxStretching * limbLength);
targetIKPos = UpperArmIKBone.transform.position + (targetIKPos - UpperArmIKBone.transform.position).normalized * len;
}
}
#endregion
// Arm IK Position ---------------------------------------------------
float posWeight = IKPositionWeight * IKWeight * _internalIKWeight;
UpperArmIKBone.sqrMagn = (ForeArmIKBone.transform.position - UpperArmIKBone.transform.position).sqrMagnitude;
ForeArmIKBone.sqrMagn = (HandIKBone.transform.position - ForeArmIKBone.transform.position).sqrMagnitude;
TargetElbowNormal = GetDefaultFlexNormal();
Vector3 orientationDirection = GetOrientationDirection(targetIKPos, TargetElbowNormal);
if (orientationDirection == Vector3.zero) orientationDirection = ForeArmIKBone.transform.position - UpperArmIKBone.transform.position;
if (posWeight > 0f)
{
Quaternion sBoneRot = UpperArmIKBone.GetRotation(orientationDirection, TargetElbowNormal) * UpperarmRotationOffset;
if (posWeight < 1f) sBoneRot = Quaternion.LerpUnclamped(UpperArmIKBone.transform.rotation, sBoneRot, posWeight);
UpperArmIKBone.transform.rotation = sBoneRot;
Quaternion sMidBoneRot = ForeArmIKBone.GetRotation(targetIKPos - ForeArmIKBone.transform.position, ForeArmIKBone.GetCurrentOrientationNormal());
if (posWeight < 1f) sMidBoneRot = Quaternion.LerpUnclamped(ForeArmIKBone.transform.rotation, sMidBoneRot, posWeight);
ForeArmIKBone.transform.rotation = sMidBoneRot;
}
HandBoneRotation();
}
[NonSerialized] public Vector3 ikCustomHintOffset = Vector3.zero;
/// <summary>
/// Calculating IK pole position normal for desired flexing bend
/// </summary>
private Vector3 GetAutomaticFlexNormal()
{
Vector3 bendNormal = UpperArmIKBone.GetCurrentOrientationNormal() ;
if (ikCustomHintOffset != Vector3.zero) bendNormal = (bendNormal + ikCustomHintOffset).normalized;
switch (AutoHintMode)
{
case FIK_HintMode.MiddleForward:
return Vector3.LerpUnclamped(bendNormal.normalized, ForeArmIKBone.srcRotation * ForeArmIKBone.forward, 0.5f);
case FIK_HintMode.MiddleBack: return ForeArmIKBone.srcRotation * -ForeArmIKBone.right + ikCustomHintOffset;
case FIK_HintMode.EndForward:
Vector3 hintPos = ForeArmIKBone.srcPosition + HandIKBone.srcRotation * HandIKBone.forward * (MirrorMaths ? -1f : 1f);
Vector3 normal = Vector3.Cross(hintPos - UpperArmIKBone.srcPosition, IKTargetPosition - UpperArmIKBone.srcPosition);
if (normal == Vector3.zero) return bendNormal;
return normal;
case FIK_HintMode.OnGoal: return Vector3.LerpUnclamped(bendNormal, IKTargetRotation * HandIKBone.right, 0.5f);
}
return bendNormal;
}
// Drawing helper gizmos for identifying IK process and setup
public void OnDrawGizmos()
{
if (!Initialized) return;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cd8229b9af7c27d4cb030c4ea1034566
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: