Mode switch handling, attempt two

This commit is contained in:
SDraw 2024-01-30 13:57:09 +03:00
parent 66b448a2c3
commit 84b0de7065
No known key found for this signature in database
GPG key ID: BB95B4DAB2BB8BB5
13 changed files with 256 additions and 288 deletions

View file

@ -83,13 +83,7 @@ namespace ml_pam
void OnDestroy()
{
if(m_armIKLeft != null)
Destroy(m_armIKLeft);
m_armIKLeft = null;
if(m_armIKRight != null)
Destroy(m_armIKRight);
m_armIKRight = null;
RemoveArmIK();
if(m_rootLeft != null)
Destroy(m_rootLeft);
@ -331,19 +325,15 @@ namespace ml_pam
internal void OnAvatarSetup()
{
// Recheck if user could switch to VR
RecheckMode();
m_inVR = Utils.IsInVR();
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
if(!m_inVR && PlayerSetup.Instance._animator.isHuman)
ReparentRoots();
if(PlayerSetup.Instance._animator.isHuman)
{
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
TPoseHelper l_tpHelper = new TPoseHelper();
if(m_vrIK == null)
{
l_tpHelper.Assign(PlayerSetup.Instance._animator);
l_tpHelper.Apply();
}
if(!m_inVR)
PoseHelper.ForceTPose(PlayerSetup.Instance._animator);
Transform l_leftHand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand);
if(l_leftHand != null)
@ -352,59 +342,14 @@ namespace ml_pam
if(l_rightHand != null)
m_rightTarget.localRotation = ms_offsetRight * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_rightHand.GetMatrix()).rotation;
if(m_vrIK == null)
{
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_armIKLeft = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_armIKLeft.solver.isLeft = true;
m_armIKLeft.solver.SetChain(
l_chest,
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftShoulder),
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftUpperArm),
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
l_leftHand,
PlayerSetup.Instance._animator.transform
);
m_armIKLeft.solver.arm.target = m_leftTarget;
m_armIKLeft.solver.arm.positionWeight = 1f;
m_armIKLeft.solver.arm.rotationWeight = 1f;
m_armIKLeft.solver.IKPositionWeight = 0f;
m_armIKLeft.solver.IKRotationWeight = 0f;
m_armIKLeft.enabled = false;
m_armLength = m_armIKLeft.solver.arm.mag * 1.25f;
m_armIKRight = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_armIKRight.solver.isLeft = false;
m_armIKRight.solver.SetChain(
l_chest,
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightShoulder),
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
l_rightHand,
PlayerSetup.Instance._animator.transform
);
m_armIKRight.solver.arm.target = m_rightTarget;
m_armIKRight.solver.arm.positionWeight = 1f;
m_armIKRight.solver.arm.rotationWeight = 1f;
m_armIKRight.solver.IKPositionWeight = 0f;
m_armIKRight.solver.IKRotationWeight = 0f;
m_armIKRight.enabled = false;
}
else
if(m_vrIK != null)
{
m_armLength = m_vrIK.solver.leftArm.mag * 1.25f;
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
}
l_tpHelper.Restore();
l_tpHelper.Unassign();
else if(!m_inVR)
SetupArmIK();
}
SetEnabled(m_enabled);
@ -413,14 +358,23 @@ namespace ml_pam
internal void OnAvatarReinitialize()
{
// Old VRIK is destroyed by game
RecheckMode();
m_inVR = Utils.IsInVR();
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
ReparentRoots();
if(m_inVR)
RemoveArmIK();
if(m_vrIK != null)
{
m_armLength = m_vrIK.solver.leftArm.mag * 1.25f;
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
}
else if(!m_inVR)
SetupArmIK();
SetEnabled(m_enabled);
}
internal void OnPickupGrab(CVRPickupObject p_pickup, ControllerRay p_ray, Vector3 p_hit)
@ -494,6 +448,62 @@ namespace ml_pam
}
// Arbitrary
void SetupArmIK()
{
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_armIKLeft = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_armIKLeft.solver.isLeft = true;
m_armIKLeft.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_armIKLeft.solver.arm.target = m_leftTarget;
m_armIKLeft.solver.arm.positionWeight = 1f;
m_armIKLeft.solver.arm.rotationWeight = 1f;
m_armIKLeft.solver.IKPositionWeight = 0f;
m_armIKLeft.solver.IKRotationWeight = 0f;
m_armIKLeft.enabled = false;
m_armLength = m_armIKLeft.solver.arm.mag * 1.25f;
m_armIKRight = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_armIKRight.solver.isLeft = false;
m_armIKRight.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_armIKRight.solver.arm.target = m_rightTarget;
m_armIKRight.solver.arm.positionWeight = 1f;
m_armIKRight.solver.arm.rotationWeight = 1f;
m_armIKRight.solver.IKPositionWeight = 0f;
m_armIKRight.solver.IKRotationWeight = 0f;
m_armIKRight.enabled = false;
}
void RemoveArmIK()
{
if(m_armIKLeft != null)
Object.Destroy(m_armIKLeft);
m_armIKLeft = null;
if(m_armIKRight != null)
Object.Destroy(m_armIKRight);
m_armIKRight = null;
}
void SetArmActive(Settings.LeadHand p_hand, bool p_state, bool p_forced = false)
{
if(m_enabled || p_forced)
@ -513,19 +523,15 @@ namespace ml_pam
}
}
void RecheckMode()
void ReparentRoots()
{
if(m_inVR != Utils.IsInVR())
{
m_rootLeft.parent = PlayerSetup.Instance.GetActiveCamera().transform;
m_rootLeft.localPosition = Vector3.zero;
m_rootLeft.localRotation = Quaternion.identity;
m_rootLeft.parent = PlayerSetup.Instance.GetActiveCamera().transform;
m_rootLeft.localPosition = Vector3.zero;
m_rootLeft.localRotation = Quaternion.identity;
m_rootRight.parent = PlayerSetup.Instance.GetActiveCamera().transform;
m_rootRight.localPosition = Vector3.zero;
m_rootRight.localRotation = Quaternion.identity;
}
m_inVR = Utils.IsInVR();
m_rootRight.parent = PlayerSetup.Instance.GetActiveCamera().transform;
m_rootRight.localPosition = Vector3.zero;
m_rootRight.localRotation = Quaternion.identity;
}
}
}

26
ml_pam/PoseHelper.cs Normal file
View file

@ -0,0 +1,26 @@
using UnityEngine;
using ABI_RC.Systems.IK;
namespace ml_pam
{
static class PoseHelper
{
public static void ForceTPose(Animator p_animator)
{
if(p_animator.isHuman)
{
HumanPoseHandler l_handler = new HumanPoseHandler(p_animator.avatar, p_animator.transform);
HumanPose l_pose = new HumanPose();
l_handler.GetHumanPose(ref l_pose);
for(int i = 0, j = Mathf.Min(l_pose.muscles.Length, MusclePoses.TPoseMuscles.Length); i < j; i++)
l_pose.muscles[i] = MusclePoses.TPoseMuscles[i];
l_pose.bodyPosition = Vector3.up;
l_pose.bodyRotation = Quaternion.identity;
l_handler.SetHumanPose(ref l_pose);
l_handler.Dispose();
}
}
}
}

View file

@ -1,59 +0,0 @@
using UnityEngine;
namespace ml_pam
{
class TPoseHelper
{
HumanPoseHandler m_poseHandler = null;
HumanPose m_oldPose;
HumanPose m_newPose;
Vector3 m_hipsLocalPos = Vector3.zero;
Transform m_hips = null;
public void Assign(Animator p_animator)
{
if(m_poseHandler != null)
{
m_poseHandler = new HumanPoseHandler(p_animator.avatar, p_animator.transform);
m_hips = p_animator.GetBoneTransform(HumanBodyBones.Hips);
}
}
public void Unassign()
{
m_poseHandler?.Dispose();
m_poseHandler = null;
m_oldPose = new HumanPose();
m_newPose = new HumanPose();
m_hips = null;
m_hipsLocalPos = Vector3.zero;
}
public void Apply()
{
if(m_hips != null)
m_hipsLocalPos = m_hips.localPosition;
if(m_poseHandler != null)
{
m_poseHandler.GetHumanPose(ref m_oldPose);
m_newPose.bodyPosition = m_oldPose.bodyPosition;
m_newPose.bodyRotation = m_oldPose.bodyRotation;
m_newPose.muscles = new float[m_oldPose.muscles.Length];
for(int i = 0, j = m_newPose.muscles.Length; i < j; i++)
m_newPose.muscles[i] = ABI_RC.Systems.IK.MusclePoses.TPoseMuscles[i];
m_poseHandler.SetHumanPose(ref m_newPose);
}
}
public void Restore()
{
if(m_poseHandler != null)
m_poseHandler.SetHumanPose(ref m_oldPose);
if(m_hips != null)
m_hips.localPosition = m_hipsLocalPos;
}
}
}