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

@ -98,11 +98,8 @@ namespace ml_amt
m_emoteActive = (l_animState.tagHash == ms_emoteHash); m_emoteActive = (l_animState.tagHash == ms_emoteHash);
} }
if(m_parameters.Count > 0) foreach(AvatarParameter l_param in m_parameters)
{ l_param.Update(this);
foreach(AvatarParameter l_param in m_parameters)
l_param.Update(this);
}
} }
} }
@ -214,7 +211,6 @@ namespace ml_amt
m_vrIk.solver.rightLeg.useAnimatedBendNormal = true; m_vrIk.solver.rightLeg.useAnimatedBendNormal = true;
l_locomotionOverride = true; l_locomotionOverride = true;
} }
if(m_ikOverrideFly && BetterBetterCharacterController.Instance.IsFlying()) if(m_ikOverrideFly && BetterBetterCharacterController.Instance.IsFlying())
{ {
m_vrIk.solver.locomotion.weight = 0f; m_vrIk.solver.locomotion.weight = 0f;

View file

@ -152,12 +152,12 @@ namespace ml_dht
bool l_result = false; bool l_result = false;
if(m_enabled && Settings.FaceTracking) if(m_enabled && Settings.FaceTracking)
{ {
p_component.LipSyncWasUpdated = true;
if(!m_lipDataSent) if(!m_lipDataSent)
{ {
FaceTrackingManager.Instance.SubmitNewFacialData(m_lipData); FaceTrackingManager.Instance.SubmitNewFacialData(m_lipData);
m_lipDataSent = true; m_lipDataSent = true;
} }
p_component.LipSyncWasUpdated = true;
p_component.UpdateShapesLocal_Private(); p_component.UpdateShapesLocal_Private();
l_result = true; l_result = true;

View file

@ -94,8 +94,8 @@ namespace ml_lme
MelonLoader.MelonCoroutines.Start(WaitForSettings()); MelonLoader.MelonCoroutines.Start(WaitForSettings());
MelonLoader.MelonCoroutines.Start(WaitForMaterial()); MelonLoader.MelonCoroutines.Start(WaitForMaterial());
VRModeSwitchEvents.OnInitializeXR.AddListener(OnSwitchToVR); VRModeSwitchEvents.OnInitializeXR.AddListener(OnModeSwitch);
VRModeSwitchEvents.OnDeinitializeXR.AddListener(OnSwitchToDesktop); VRModeSwitchEvents.OnDeinitializeXR.AddListener(OnModeSwitch);
} }
IEnumerator WaitForSettings() IEnumerator WaitForSettings()
@ -155,8 +155,8 @@ namespace ml_lme
Settings.FingersOnlyChange -= this.OnFingersOnlyChange; Settings.FingersOnlyChange -= this.OnFingersOnlyChange;
MetaPort.Instance.settings.settingBoolChanged.RemoveListener(this.OnGameSettingBoolChange); MetaPort.Instance.settings.settingBoolChanged.RemoveListener(this.OnGameSettingBoolChange);
VRModeSwitchEvents.OnInitializeXR.RemoveListener(OnSwitchToVR); VRModeSwitchEvents.OnInitializeXR.RemoveListener(OnModeSwitch);
VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(OnSwitchToDesktop); VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(OnModeSwitch);
} }
public override void UpdateInput() public override void UpdateInput()
@ -444,38 +444,20 @@ namespace ml_lme
} }
} }
void OnSwitchToVR() void OnModeSwitch()
{ {
m_inVR = true; m_inVR = Utils.IsInVR();
base._inputManager.SetModuleAsLast(this); base._inputManager.SetModuleAsLast(this);
if(m_handRayLeft != null) if(m_handRayLeft != null)
{ {
m_handRayLeft.isDesktopRay = false; m_handRayLeft.isDesktopRay = !m_inVR;
m_handRayLeft.SetVRActive(true); m_handRayLeft.SetVRActive(m_inVR);
} }
if(m_handRayRight != null) if(m_handRayRight != null)
{ {
m_handRayRight.isDesktopRay = false; m_handRayRight.isDesktopRay = !m_inVR;
m_handRayRight.SetVRActive(true); m_handRayRight.SetVRActive(m_inVR);
}
OnEnableChange(Settings.Enabled);
}
void OnSwitchToDesktop()
{
m_inVR = false;
base._inputManager.SetModuleAsLast(this);
if(m_handRayLeft != null)
{
m_handRayLeft.isDesktopRay = true;
m_handRayLeft.SetVRActive(false);
}
if(m_handRayRight != null)
{
m_handRayRight.isDesktopRay = true;
m_handRayRight.SetVRActive(false);
} }
OnEnableChange(Settings.Enabled); OnEnableChange(Settings.Enabled);

View file

@ -1,8 +1,6 @@
using ABI_RC.Core.Player; using ABI_RC.Core.Player;
using ABI_RC.Systems.IK; using ABI_RC.Systems.IK;
using ABI_RC.Systems.VRModeSwitch;
using RootMotion.FinalIK; using RootMotion.FinalIK;
using System.Reflection;
using UnityEngine; using UnityEngine;
namespace ml_lme namespace ml_lme
@ -67,13 +65,7 @@ namespace ml_lme
void OnDestroy() void OnDestroy()
{ {
if(m_leftArmIK != null) RemoveArmIK();
Destroy(m_leftArmIK);
m_leftArmIK = null;
if(m_rightArmIK != null)
Destroy(m_rightArmIK);
m_rightArmIK = null;
if(m_leftHandTarget != null) if(m_leftHandTarget != null)
Destroy(m_leftHandTarget); Destroy(m_leftHandTarget);
@ -164,27 +156,11 @@ namespace ml_lme
if(PlayerSetup.Instance._animator.isHuman) if(PlayerSetup.Instance._animator.isHuman)
{ {
Vector3 l_hipsPos = Vector3.zero; m_poseHandler = new HumanPoseHandler(PlayerSetup.Instance._animator.avatar, PlayerSetup.Instance._animator.transform);
m_hips = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Hips); m_poseHandler.GetHumanPose(ref m_pose);
if(m_hips != null)
l_hipsPos = m_hips.localPosition;
if(!m_inVR) if(!m_inVR)
{ PoseHelper.ForceTPose(PlayerSetup.Instance._animator);
// Force desktop avatar into T-Pose
m_poseHandler = new HumanPoseHandler(PlayerSetup.Instance._animator.avatar, PlayerSetup.Instance._avatar.transform);
m_poseHandler.GetHumanPose(ref m_pose);
HumanPose l_tPose = new HumanPose
{
bodyPosition = m_pose.bodyPosition,
bodyRotation = m_pose.bodyRotation,
muscles = new float[m_pose.muscles.Length]
};
for(int i = 0; i < l_tPose.muscles.Length; i++)
l_tPose.muscles[i] = MusclePoses.TPoseMuscles[i];
m_poseHandler.SetHumanPose(ref l_tPose);
}
Transform l_hand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand); Transform l_hand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand);
if(l_hand != null) if(l_hand != null)
@ -194,54 +170,13 @@ namespace ml_lme
if(l_hand != null) if(l_hand != null)
m_rightHandTarget.localRotation = ms_offsetRight * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_hand.GetMatrix()).rotation; m_rightHandTarget.localRotation = ms_offsetRight * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_hand.GetMatrix()).rotation;
if(m_vrIK == null) 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_leftArmIK = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_leftArmIK.solver.isLeft = true;
m_leftArmIK.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_leftArmIK.solver.arm.target = m_leftHandTarget;
m_leftArmIK.solver.arm.bendGoal = LeapTracking.Instance.GetLeftElbow();
m_leftArmIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
m_leftArmIK.enabled = (m_enabled && !m_fingersOnly);
m_rightArmIK = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_rightArmIK.solver.isLeft = false;
m_rightArmIK.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_rightArmIK.solver.arm.target = m_rightHandTarget;
m_rightArmIK.solver.arm.bendGoal = LeapTracking.Instance.GetRightElbow();
m_rightArmIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
m_rightArmIK.enabled = (m_enabled && !m_fingersOnly);
m_poseHandler?.SetHumanPose(ref m_pose);
}
else
{ {
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate); m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
} }
else if(!m_inVR)
if(m_hips != null) SetupArmIK();
m_hips.localPosition = l_hipsPos;
} }
} }
@ -250,11 +185,20 @@ namespace ml_lme
// Old VRIK is destroyed by game // Old VRIK is destroyed by game
m_inVR = Utils.IsInVR(); m_inVR = Utils.IsInVR();
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>(); m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
if(m_inVR)
RemoveArmIK();
if(m_vrIK != null) if(m_vrIK != null)
{ {
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate); m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
} }
else if(!m_inVR)
{
PoseHelper.ForceTPose(PlayerSetup.Instance._animator);
SetupArmIK();
}
} }
// VRIK updates // VRIK updates
@ -346,6 +290,56 @@ namespace ml_lme
m_rightTargetActive = false; m_rightTargetActive = false;
} }
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_leftArmIK = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_leftArmIK.solver.isLeft = true;
m_leftArmIK.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_leftArmIK.solver.arm.target = m_leftHandTarget;
m_leftArmIK.solver.arm.bendGoal = LeapTracking.Instance.GetLeftElbow();
m_leftArmIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
m_leftArmIK.enabled = (m_enabled && !m_fingersOnly);
m_rightArmIK = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
m_rightArmIK.solver.isLeft = false;
m_rightArmIK.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_rightArmIK.solver.arm.target = m_rightHandTarget;
m_rightArmIK.solver.arm.bendGoal = LeapTracking.Instance.GetRightElbow();
m_rightArmIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
m_rightArmIK.enabled = (m_enabled && !m_fingersOnly);
}
void RemoveArmIK()
{
if(m_leftArmIK != null)
Object.Destroy(m_leftArmIK);
m_leftArmIK = null;
if(m_rightArmIK != null)
Object.Destroy(m_rightArmIK);
m_rightArmIK = null;
}
void RefreshArmIK() void RefreshArmIK()
{ {
if((m_leftArmIK != null) && (m_rightArmIK != null)) if((m_leftArmIK != null) && (m_rightArmIK != null))

View file

@ -89,8 +89,8 @@ namespace ml_lme
OnTrackingModeChange(Settings.TrackingMode); OnTrackingModeChange(Settings.TrackingMode);
OnRootAngleChange(Settings.RootAngle); OnRootAngleChange(Settings.RootAngle);
VRModeSwitchEvents.OnInitializeXR.AddListener(this.OnSwitchToVR); VRModeSwitchEvents.OnInitializeXR.AddListener(this.OnModeSwitch);
VRModeSwitchEvents.OnDeinitializeXR.AddListener(this.OnSwitchToDesktop); VRModeSwitchEvents.OnDeinitializeXR.AddListener(this.OnModeSwitch);
} }
IEnumerator WaitForLocalPlayer() IEnumerator WaitForLocalPlayer()
@ -141,8 +141,8 @@ namespace ml_lme
Settings.HeadAttachChange -= this.OnHeadAttachChange; Settings.HeadAttachChange -= this.OnHeadAttachChange;
Settings.HeadOffsetChange -= this.OnHeadOffsetChange; Settings.HeadOffsetChange -= this.OnHeadOffsetChange;
VRModeSwitchEvents.OnInitializeXR.RemoveListener(this.OnSwitchToVR); VRModeSwitchEvents.OnInitializeXR.RemoveListener(this.OnModeSwitch);
VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(this.OnSwitchToDesktop); VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(this.OnModeSwitch);
} }
void Update() void Update()
@ -270,14 +270,9 @@ namespace ml_lme
OnHeadAttachChange(Settings.HeadAttach); OnHeadAttachChange(Settings.HeadAttach);
} }
void OnSwitchToVR() void OnModeSwitch()
{ {
m_inVR = true; m_inVR = Utils.IsInVR();
OnHeadAttachChange(Settings.HeadAttach);
}
void OnSwitchToDesktop()
{
m_inVR = false;
OnHeadAttachChange(Settings.HeadAttach); OnHeadAttachChange(Settings.HeadAttach);
} }

26
ml_lme/PoseHelper.cs Normal file
View file

@ -0,0 +1,26 @@
using UnityEngine;
using ABI_RC.Systems.IK;
namespace ml_lme
{
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

@ -40,11 +40,12 @@ namespace ml_lme
public static void SetModuleAsLast(this CVRInputManager p_instance, CVRInputModule p_module) public static void SetModuleAsLast(this CVRInputManager p_instance, CVRInputModule p_module)
{ {
List<CVRInputModule> l_modules = ms_inputModules.GetValue(p_instance) as List<CVRInputModule>; List<CVRInputModule> l_modules = ms_inputModules.GetValue(p_instance) as List<CVRInputModule>;
int l_lastIndex = l_modules.Count - 1;
int l_index = l_modules.FindIndex(p => p == p_module); int l_index = l_modules.FindIndex(p => p == p_module);
if(l_index != -1) if((l_index != -1) && (l_index != l_lastIndex))
{ {
l_modules[l_index] = l_modules[l_modules.Count - 1]; l_modules[l_index] = l_modules[l_lastIndex];
l_modules[l_modules.Count - 1] = p_module; l_modules[l_lastIndex] = p_module;
} }
} }

View file

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

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;
}
}
}

View file

@ -36,7 +36,7 @@ namespace ml_pmc
); );
HarmonyInstance.Patch( HarmonyInstance.Patch(
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
null, new HarmonyLib.HarmonyMethod(typeof(PlayerMovementCopycat).GetMethod(nameof(OnAvatarReinitialize_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
new HarmonyLib.HarmonyMethod(typeof(PlayerMovementCopycat).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) new HarmonyLib.HarmonyMethod(typeof(PlayerMovementCopycat).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
); );
@ -140,13 +140,27 @@ namespace ml_pmc
} }
} }
static void OnAvatarReinitialize_Postfix() => ms_instance?.OnAvatarReinitialize(); static void OnAvatarReinitialize_Prefix() => ms_instance?.OnPreAvatarReinitialize();
void OnAvatarReinitialize() void OnPreAvatarReinitialize()
{ {
try try
{ {
if(m_localCopycat != null) if(m_localCopycat != null)
m_localCopycat.OnAvatarReinitialize(); m_localCopycat.OnPreAvatarReinitialize();
}
catch(System.Exception e)
{
MelonLoader.MelonLogger.Error(e);
}
}
static void OnAvatarReinitialize_Postfix() => ms_instance?.OnPostAvatarReinitialize();
void OnPostAvatarReinitialize()
{
try
{
if(m_localCopycat != null)
m_localCopycat.OnPostAvatarReinitialize();
} }
catch(System.Exception e) catch(System.Exception e)
{ {

View file

@ -37,9 +37,6 @@ namespace ml_pmc
{ {
if(Instance == null) if(Instance == null)
Instance = this; Instance = this;
VRModeSwitchEvents.OnInitializeXR.AddListener(this.OnSwitchToVR);
VRModeSwitchEvents.OnDeinitializeXR.AddListener(this.OnSwitchToDesktop);
} }
void OnDestroy() void OnDestroy()
{ {
@ -56,9 +53,6 @@ namespace ml_pmc
m_animator = null; m_animator = null;
m_vrIk = null; m_vrIk = null;
m_lookAtIk = null; m_lookAtIk = null;
VRModeSwitchEvents.OnInitializeXR.RemoveListener(this.OnSwitchToVR);
VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(this.OnSwitchToDesktop);
} }
// Unity events // Unity events
@ -201,6 +195,7 @@ namespace ml_pmc
} }
internal void OnAvatarSetup() internal void OnAvatarSetup()
{ {
m_inVr = Utils.IsInVR();
m_animator = PlayerSetup.Instance._animator; m_animator = PlayerSetup.Instance._animator;
m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>(); m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
m_lookAtIk = PlayerSetup.Instance._avatar.GetComponent<LookAtIK>(); m_lookAtIk = PlayerSetup.Instance._avatar.GetComponent<LookAtIK>();
@ -225,8 +220,16 @@ namespace ml_pmc
else else
m_animator = null; m_animator = null;
} }
internal void OnAvatarReinitialize()
internal void OnPreAvatarReinitialize()
{ {
if(m_active)
SetTarget(null);
}
internal void OnPostAvatarReinitialize()
{
m_inVr = Utils.IsInVR();
// Old VRIK and LookAtIK are destroyed by game // Old VRIK and LookAtIK are destroyed by game
m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>(); m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
m_lookAtIk = PlayerSetup.Instance._avatar.GetComponent<LookAtIK>(); m_lookAtIk = PlayerSetup.Instance._avatar.GetComponent<LookAtIK>();
@ -244,15 +247,6 @@ namespace ml_pmc
} }
} }
void OnSwitchToVR()
{
m_inVr = true;
}
void OnSwitchToDesktop()
{
m_inVr = false;
}
// IK updates // IK updates
void OnVRIKPreUpdate() void OnVRIKPreUpdate()
{ {

View file

@ -111,6 +111,7 @@ namespace ml_prm
if(m_puppetRoot != null) if(m_puppetRoot != null)
Object.Destroy(m_puppetRoot); Object.Destroy(m_puppetRoot);
m_puppetRoot = null; m_puppetRoot = null;
m_puppet = null; m_puppet = null;
m_rigidBodies.Clear(); m_rigidBodies.Clear();
m_colliders.Clear(); m_colliders.Clear();
@ -443,14 +444,6 @@ namespace ml_prm
if(m_vrIK != null) if(m_vrIK != null)
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
if(m_avatarReady && m_enabled)
{
m_forcedSwitch = true;
SwitchRagdoll();
m_forcedSwitch = false;
}
} }
internal void OnAvatarScaling(float p_scaleDifference) internal void OnAvatarScaling(float p_scaleDifference)
@ -536,7 +529,7 @@ namespace ml_prm
} }
} }
// IK updates // VRIK updates
void OnIKPostUpdate() void OnIKPostUpdate()
{ {
if(!m_enabled) if(!m_enabled)