mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
ArmIK usage
Elbows tracking Tracking without VR controllers
This commit is contained in:
parent
3b33dc0cfb
commit
7fcfb04e0f
11 changed files with 238 additions and 121 deletions
|
@ -2,6 +2,7 @@
|
|||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.IK;
|
||||
using RootMotion.FinalIK;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_lme
|
||||
|
@ -9,20 +10,28 @@ namespace ml_lme
|
|||
[DisallowMultipleComponent]
|
||||
class LeapTracked : MonoBehaviour
|
||||
{
|
||||
static readonly float[] ms_tposeMuscles = typeof(ABI_RC.Systems.IK.SubSystems.BodySystem).GetField("TPoseMuscles", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as float[];
|
||||
static readonly Quaternion ms_offsetLeft = Quaternion.Euler(0f, 0f, 270f);
|
||||
static readonly Quaternion ms_offsetRight = Quaternion.Euler(0f, 0f, 90f);
|
||||
static readonly Quaternion ms_offsetLeftDesktop = Quaternion.Euler(0f, 90f, 0f);
|
||||
static readonly Quaternion ms_offsetRightDesktop = Quaternion.Euler(0f, 270f, 0f);
|
||||
|
||||
IndexIK m_indexIK = null;
|
||||
VRIK m_vrIK = null;
|
||||
Vector2 m_armsWeights = Vector2.zero;
|
||||
|
||||
bool m_enabled = true;
|
||||
bool m_fingersOnly = false;
|
||||
bool m_trackElbows = true;
|
||||
|
||||
LeapIK m_leapIK = null;
|
||||
ArmIK m_leftIK = null;
|
||||
ArmIK m_rightIK = null;
|
||||
Transform m_leftHand = null;
|
||||
Transform m_rightHand = null;
|
||||
Transform m_leftHandTarget = null;
|
||||
Transform m_rightHandTarget = null;
|
||||
Transform m_leftElbow = null;
|
||||
Transform m_rightElbow = null;
|
||||
bool m_leftTargetActive = false;
|
||||
bool m_rightTargetActive = false;
|
||||
|
||||
|
@ -56,8 +65,11 @@ namespace ml_lme
|
|||
CVRInputManager.Instance.individualFingerTracking = (m_enabled || Utils.AreKnucklesInUse());
|
||||
}
|
||||
|
||||
if(m_leapIK != null)
|
||||
m_leapIK.SetEnabled(m_enabled);
|
||||
if((m_leftIK != null) && (m_rightIK != null))
|
||||
{
|
||||
m_leftIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
m_rightIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
}
|
||||
|
||||
if(!m_enabled || m_fingersOnly)
|
||||
RestoreIK();
|
||||
|
@ -67,25 +79,55 @@ namespace ml_lme
|
|||
{
|
||||
m_fingersOnly = p_state;
|
||||
|
||||
if(m_leapIK != null)
|
||||
m_leapIK.SetFingersOnly(m_fingersOnly);
|
||||
if((m_leftIK != null) && (m_rightIK != null))
|
||||
{
|
||||
m_leftIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
m_rightIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
}
|
||||
|
||||
if(!m_enabled || m_fingersOnly)
|
||||
RestoreIK();
|
||||
}
|
||||
|
||||
public void SetHands(Transform p_left, Transform p_right)
|
||||
public void SetTrackElbows(bool p_state)
|
||||
{
|
||||
m_trackElbows = p_state;
|
||||
|
||||
if((m_leftIK != null) && (m_rightIK != null))
|
||||
{
|
||||
m_leftIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_rightIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
}
|
||||
|
||||
if(m_vrIK != null)
|
||||
{
|
||||
if(m_leftTargetActive)
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
if(m_rightTargetActive)
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTransforms(Transform p_left, Transform p_right, Transform p_leftElbow, Transform p_rightElbow)
|
||||
{
|
||||
m_leftHand = p_left;
|
||||
m_rightHand = p_right;
|
||||
|
||||
m_leftElbow = p_leftElbow;
|
||||
m_rightElbow = p_rightElbow;
|
||||
}
|
||||
|
||||
public void UpdateTracking(GestureMatcher.GesturesData p_gesturesData)
|
||||
{
|
||||
if(m_enabled && (m_indexIK != null))
|
||||
{
|
||||
if(m_leapIK != null)
|
||||
m_leapIK.SetHandsVisibility(p_gesturesData.m_handsPresenses[0], p_gesturesData.m_handsPresenses[1]);
|
||||
if((m_leftIK != null) && (m_rightIK != null))
|
||||
{
|
||||
m_leftIK.solver.IKPositionWeight = Mathf.Lerp(m_leftIK.solver.IKPositionWeight, (p_gesturesData.m_handsPresenses[0] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_leftIK.solver.IKRotationWeight = Mathf.Lerp(m_leftIK.solver.IKRotationWeight, (p_gesturesData.m_handsPresenses[0] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_rightIK.solver.IKPositionWeight = Mathf.Lerp(m_rightIK.solver.IKPositionWeight, (p_gesturesData.m_handsPresenses[1] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_rightIK.solver.IKRotationWeight = Mathf.Lerp(m_rightIK.solver.IKPositionWeight, (p_gesturesData.m_handsPresenses[1] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
}
|
||||
|
||||
if(p_gesturesData.m_handsPresenses[0])
|
||||
{
|
||||
|
@ -128,22 +170,30 @@ namespace ml_lme
|
|||
if(p_gesturesData.m_handsPresenses[0] && !m_leftTargetActive)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = m_leftHandTarget;
|
||||
m_vrIK.solver.leftArm.bendGoal = m_leftElbow;
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_leftTargetActive = true;
|
||||
}
|
||||
if(!p_gesturesData.m_handsPresenses[0] && m_leftTargetActive)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = IKSystem.Instance.leftHandAnchor;
|
||||
m_vrIK.solver.leftArm.bendGoal = null;
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = 0f;
|
||||
m_leftTargetActive = false;
|
||||
}
|
||||
|
||||
if(p_gesturesData.m_handsPresenses[1] && !m_rightTargetActive)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = m_rightHandTarget;
|
||||
m_vrIK.solver.rightArm.bendGoal = m_rightElbow;
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_rightTargetActive = true;
|
||||
}
|
||||
if(!p_gesturesData.m_handsPresenses[1] && m_rightTargetActive)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = IKSystem.Instance.rightHandAnchor;
|
||||
m_vrIK.solver.rightArm.bendGoal = null;
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = 0f;
|
||||
m_rightTargetActive = false;
|
||||
}
|
||||
}
|
||||
|
@ -152,8 +202,9 @@ namespace ml_lme
|
|||
|
||||
public void OnAvatarClear()
|
||||
{
|
||||
m_leapIK = null;
|
||||
m_vrIK = null;
|
||||
m_leftIK = null;
|
||||
m_rightIK = null;
|
||||
m_leftTargetActive = false;
|
||||
m_rightTargetActive = false;
|
||||
|
||||
|
@ -161,6 +212,8 @@ namespace ml_lme
|
|||
m_leftHandTarget.localRotation = Quaternion.identity;
|
||||
m_rightHandTarget.localPosition = Vector3.zero;
|
||||
m_rightHandTarget.localRotation = Quaternion.identity;
|
||||
|
||||
m_armsWeights.Set(0f, 0f);
|
||||
}
|
||||
|
||||
public void OnCalibrateAvatar()
|
||||
|
@ -176,24 +229,107 @@ namespace ml_lme
|
|||
|
||||
if(PlayerSetup.Instance._animator.isHuman)
|
||||
{
|
||||
HumanPoseHandler l_poseHandler = null;
|
||||
HumanPose l_initPose = new HumanPose();
|
||||
|
||||
// Force desktop non-VRIK avatar into T-Pose
|
||||
if(m_vrIK == null)
|
||||
{
|
||||
l_poseHandler = new HumanPoseHandler(PlayerSetup.Instance._animator.avatar, PlayerSetup.Instance._avatar.transform);
|
||||
l_poseHandler.GetHumanPose(ref l_initPose);
|
||||
|
||||
HumanPose l_tPose = new HumanPose();
|
||||
l_tPose.bodyPosition = l_initPose.bodyPosition;
|
||||
l_tPose.bodyRotation = l_initPose.bodyRotation;
|
||||
l_tPose.muscles = new float[l_initPose.muscles.Length];
|
||||
for(int i = 0; i < l_tPose.muscles.Length; i++)
|
||||
l_tPose.muscles[i] = ms_tposeMuscles[i];
|
||||
|
||||
l_poseHandler.SetHumanPose(ref l_tPose);
|
||||
}
|
||||
|
||||
Transform l_hand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
if(l_hand != null)
|
||||
m_leftHandTarget.localRotation = ms_offsetLeft * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_hand.GetMatrix()).rotation;
|
||||
m_leftHandTarget.localRotation = ((m_vrIK != null) ? ms_offsetLeft : ms_offsetLeftDesktop) * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_hand.GetMatrix()).rotation;
|
||||
|
||||
l_hand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
if(l_hand != null)
|
||||
m_rightHandTarget.localRotation = ms_offsetRight * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_hand.GetMatrix()).rotation;
|
||||
m_rightHandTarget.localRotation = ((m_vrIK != null) ? ms_offsetRight : ms_offsetRightDesktop) * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_hand.GetMatrix()).rotation;
|
||||
|
||||
if(m_vrIK == null)
|
||||
{
|
||||
m_leapIK = PlayerSetup.Instance._animator.gameObject.AddComponent<LeapIK>();
|
||||
m_leapIK.SetHands(m_leftHand, m_rightHand);
|
||||
m_leapIK.SetEnabled(m_enabled);
|
||||
m_leapIK.SetFingersOnly(m_fingersOnly);
|
||||
Transform l_chest = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.UpperChest);
|
||||
if(l_chest == null)
|
||||
l_chest = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Chest);
|
||||
if(l_chest == null)
|
||||
l_chest = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Spine);
|
||||
|
||||
m_leftIK = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
|
||||
m_leftIK.solver.isLeft = true;
|
||||
m_leftIK.solver.SetChain(
|
||||
l_chest,
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftShoulder),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftUpperArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand),
|
||||
PlayerSetup.Instance._animator.transform
|
||||
);
|
||||
m_leftIK.solver.arm.target = m_leftHandTarget;
|
||||
m_leftIK.solver.arm.bendGoal = m_leftElbow;
|
||||
m_leftIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_leftIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
|
||||
m_rightIK = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
|
||||
m_rightIK.solver.isLeft = false;
|
||||
m_rightIK.solver.SetChain(
|
||||
l_chest,
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightShoulder),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightHand),
|
||||
PlayerSetup.Instance._animator.transform
|
||||
);
|
||||
m_rightIK.solver.arm.target = m_rightHandTarget;
|
||||
m_rightIK.solver.arm.bendGoal = m_rightElbow;
|
||||
m_rightIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_rightIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
|
||||
l_poseHandler.SetHumanPose(ref l_initPose);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||
}
|
||||
|
||||
l_poseHandler?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void OnIKPreUpdate()
|
||||
{
|
||||
m_armsWeights.Set(m_vrIK.solver.leftArm.positionWeight, m_vrIK.solver.rightArm.positionWeight);
|
||||
|
||||
if(m_leftTargetActive && Mathf.Approximately(m_armsWeights.x, 0f))
|
||||
{
|
||||
m_vrIK.solver.leftArm.positionWeight = 1f;
|
||||
m_vrIK.solver.leftArm.rotationWeight = 1f;
|
||||
}
|
||||
if(m_rightTargetActive && Mathf.Approximately(m_armsWeights.y, 0f))
|
||||
{
|
||||
m_vrIK.solver.rightArm.positionWeight = 1f;
|
||||
m_vrIK.solver.rightArm.rotationWeight = 1f;
|
||||
}
|
||||
}
|
||||
void OnIKPostUpdate()
|
||||
{
|
||||
m_vrIK.solver.leftArm.positionWeight = m_armsWeights.x;
|
||||
m_vrIK.solver.leftArm.rotationWeight = m_armsWeights.x;
|
||||
|
||||
m_vrIK.solver.rightArm.positionWeight = m_armsWeights.y;
|
||||
m_vrIK.solver.rightArm.rotationWeight = m_armsWeights.y;
|
||||
}
|
||||
|
||||
void RestoreIK()
|
||||
{
|
||||
if(m_vrIK != null)
|
||||
|
@ -201,11 +337,15 @@ namespace ml_lme
|
|||
if(m_leftTargetActive)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = IKSystem.Instance.leftHandAnchor;
|
||||
m_vrIK.solver.leftArm.bendGoal = null;
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = 0f;
|
||||
m_leftTargetActive = false;
|
||||
}
|
||||
if(m_rightTargetActive)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = IKSystem.Instance.rightHandAnchor;
|
||||
m_vrIK.solver.rightArm.bendGoal = null;
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = 0f;
|
||||
m_rightTargetActive = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue