From 66b448a2c3c3b4f9d62c07d85faa08bd4392d2d2 Mon Sep 17 00:00:00 2001 From: SDraw Date: Mon, 29 Jan 2024 23:11:01 +0300 Subject: [PATCH] Handling of "VR <-> Desktop" switch, attempt one --- ml_amt/Main.cs | 15 +++++---- ml_amt/MotionTweaker.cs | 39 ++++++++-------------- ml_amt/Utils.cs | 3 +- ml_dht/HeadTracked.cs | 12 +++++-- ml_dht/Main.cs | 20 ++++++++++++ ml_lme/LeapInput.cs | 64 ++++++++++++++++++++++++++++++------- ml_lme/LeapManager.cs | 8 +++-- ml_lme/LeapTracked.cs | 24 ++++++++++---- ml_lme/LeapTracking.cs | 19 +++++++++++ ml_lme/Main.cs | 20 ++++++++++++ ml_lme/Utils.cs | 21 ++++++++++-- ml_pam/ArmMover.cs | 44 +++++++++++++++++-------- ml_pam/Main.cs | 20 ++++++++++++ ml_pam/Utils.cs | 5 +-- ml_pmc/Main.cs | 20 ++++++++++++ ml_pmc/PoseCopycat.cs | 36 +++++++++++++++++++-- ml_pmc/Utils.cs | 2 +- ml_prm/Main.cs | 33 +++++++++++++++++++ ml_prm/RagdollController.cs | 26 +++++++++++++++ ml_prm/Utils.cs | 2 +- 20 files changed, 356 insertions(+), 77 deletions(-) diff --git a/ml_amt/Main.cs b/ml_amt/Main.cs index 7e73e3d..ff51ec3 100644 --- a/ml_amt/Main.cs +++ b/ml_amt/Main.cs @@ -1,4 +1,5 @@ using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; using ABI_RC.Systems.IK.SubSystems; using System; using System.Collections; @@ -30,9 +31,9 @@ namespace ml_amt new HarmonyLib.HarmonyMethod(typeof(AvatarMotionTweaker).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); HarmonyInstance.Patch( - typeof(BodySystem).GetMethod(nameof(BodySystem.Calibrate)), + typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), null, - new HarmonyLib.HarmonyMethod(typeof(AvatarMotionTweaker).GetMethod(nameof(OnCalibrate_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) + new HarmonyLib.HarmonyMethod(typeof(AvatarMotionTweaker).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); HarmonyInstance.Patch( typeof(PlayerSetup).GetMethod("SetPlaySpaceScale", BindingFlags.NonPublic | BindingFlags.Instance), @@ -89,17 +90,17 @@ namespace ml_amt } } - static void OnCalibrate_Postfix() => ms_instance?.OnCalibrate(); - void OnCalibrate() + static void OnAvatarReinitialize_Postfix() => ms_instance?.OnAvatarReinitialize(); + void OnAvatarReinitialize() { try { if(m_localTweaker != null) - m_localTweaker.OnCalibrate(); + m_localTweaker.OnAvatarReinitialize(); } - catch(Exception l_exception) + catch(System.Exception e) { - MelonLoader.MelonLogger.Error(l_exception); + MelonLoader.MelonLogger.Error(e); } } diff --git a/ml_amt/MotionTweaker.cs b/ml_amt/MotionTweaker.cs index ae10b6a..42b1df4 100644 --- a/ml_amt/MotionTweaker.cs +++ b/ml_amt/MotionTweaker.cs @@ -28,7 +28,6 @@ namespace ml_amt int m_locomotionLayer = 0; float m_avatarScale = 1f; Vector3 m_locomotionOffset = Vector3.zero; // Original locomotion offset - bool m_inVR = false; bool m_avatarReady = false; bool m_grounded = false; @@ -55,8 +54,6 @@ namespace ml_amt // Unity events void Start() { - m_inVR = Utils.IsInVR(); - SetCrouchLimit(Settings.CrouchLimit); SetProneLimit(Settings.ProneLimit); SetIKOverrideFly(Settings.IKOverrideFly); @@ -131,7 +128,6 @@ namespace ml_amt internal void OnSetupAvatar() { - m_inVR = Utils.IsInVR(); m_vrIk = PlayerSetup.Instance._avatar.GetComponent(); m_locomotionLayer = PlayerSetup.Instance._animator.GetLayerIndex("Locomotion/Emotes"); m_avatarScale = Mathf.Abs(PlayerSetup.Instance._avatar.transform.localScale.y); @@ -177,34 +173,25 @@ namespace ml_amt m_avatarReady = true; } - internal void OnCalibrate() - { - if(m_avatarReady && (m_vrIk != null) && (m_vrIk.solver.spine.pelvisTarget != null) && (m_vrIk.solver.leftLeg.target == null) && (m_vrIk.solver.rightLeg.target == null)) - { - // Do not consider 4PT as FBT (!!!) - m_vrIk.solver.spine.bodyPosStiffness = 0.55f; - m_vrIk.solver.spine.bodyRotStiffness = 0.1f; - m_vrIk.solver.spine.neckStiffness = 0.5f; - m_vrIk.solver.spine.chestClampWeight = 0.55f; - m_vrIk.solver.spine.moveBodyBackWhenCrouching = 0.5f; - m_vrIk.solver.spine.maxRootAngle = 25f; - m_vrIk.fixTransforms = false; - - BodySystem.isCalibratedAsFullBody = false; - BodySystem.TrackingLeftLegEnabled = false; - BodySystem.TrackingRightLegEnabled = false; - BodySystem.TrackingLocomotionEnabled = true; - - IKSystem.Instance.applyOriginalHipRotation = true; - } - } - internal void OnPlayspaceScale() { if((m_vrIk != null) && Settings.MassCenter) m_vrIk.solver.locomotion.offset = m_massCenter * GetRelativeScale(); } + internal void OnAvatarReinitialize() + { + // Old VRIK is destroyed by game + m_vrIk = PlayerSetup.Instance._animator.GetComponent(); + if(m_vrIk != null) + { + m_vrIk.solver.locomotion.offset = (Settings.MassCenter ? m_massCenter : m_locomotionOffset); + + m_vrIk.onPreSolverUpdate.AddListener(this.OnIKPreUpdate); + m_vrIk.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); + } + } + // IK events void OnIKPreUpdate() { diff --git a/ml_amt/Utils.cs b/ml_amt/Utils.cs index a228c13..e9aca84 100644 --- a/ml_amt/Utils.cs +++ b/ml_amt/Utils.cs @@ -1,4 +1,5 @@ using ABI.CCK.Components; +using ABI_RC.Core.Savior; using ABI_RC.Core.UI; using RootMotion.FinalIK; using System.Reflection; @@ -11,7 +12,7 @@ namespace ml_amt static readonly FieldInfo ms_hasToes = typeof(IKSolverVR).GetField("hasToes", BindingFlags.NonPublic | BindingFlags.Instance); static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.NonPublic | BindingFlags.Instance); - public static bool IsInVR() => ((ABI_RC.Core.Savior.CheckVR.Instance != null) && ABI_RC.Core.Savior.CheckVR.Instance.hasVrDeviceLoaded); + public static bool IsInVR() => ((MetaPort.Instance != null) && MetaPort.Instance.isUsingVr); public static bool HasToes(this IKSolverVR p_instance) => (bool)ms_hasToes.GetValue(p_instance); diff --git a/ml_dht/HeadTracked.cs b/ml_dht/HeadTracked.cs index ffe8125..1c5591d 100644 --- a/ml_dht/HeadTracked.cs +++ b/ml_dht/HeadTracked.cs @@ -2,6 +2,7 @@ using ABI_RC.Core.Player; using ABI_RC.Core.Player.EyeMovement; using ABI_RC.Systems.FaceTracking; +using ABI_RC.Systems.VRModeSwitch; using RootMotion.FinalIK; using System; using System.Reflection; @@ -65,7 +66,7 @@ namespace ml_dht void Update() { - if(m_enabled && Settings.FaceTracking) + if(m_lipDataSent) m_lipDataSent = false; } @@ -107,7 +108,7 @@ namespace ml_dht m_bindRotation = (m_avatarDescriptor.transform.GetMatrix().inverse * m_headBone.GetMatrix()).rotation; if(m_lookIK != null) - m_lookIK.solver.OnPostUpdate += this.OnLookIKPostUpdate; + m_lookIK.onPostSolverUpdate.AddListener(this.OnLookIKPostUpdate); } internal void OnAvatarClear() @@ -118,6 +119,13 @@ namespace ml_dht m_lastHeadRotation = Quaternion.identity; m_bindRotation = Quaternion.identity; } + internal void OnAvatarReinitialize() + { + m_camera = PlayerSetup.Instance.GetActiveCamera().transform; + m_lookIK = PlayerSetup.Instance._avatar.GetComponent(); + if(m_lookIK != null) + m_lookIK.onPostSolverUpdate.AddListener(this.OnLookIKPostUpdate); + } internal void OnEyeControllerUpdate(EyeMovementController p_component) { diff --git a/ml_dht/Main.cs b/ml_dht/Main.cs index 60dd20f..c701136 100644 --- a/ml_dht/Main.cs +++ b/ml_dht/Main.cs @@ -2,6 +2,7 @@ using ABI.CCK.Components; using ABI_RC.Core.Player; using ABI_RC.Core.Player.EyeMovement; using ABI_RC.Core.Savior; +using ABI_RC.Systems.IK; using System.Reflection; namespace ml_dht @@ -31,6 +32,11 @@ namespace ml_dht null, new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); + HarmonyInstance.Patch( + typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), + null, + new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) + ); MelonLoader.MelonCoroutines.Start(WaitForInstances()); } @@ -105,6 +111,20 @@ namespace ml_dht } } + static void OnAvatarReinitialize_Postfix() => ms_instance?.OnAvatarReinitialize(); + void OnAvatarReinitialize() + { + try + { + if(m_localTracked != null) + m_localTracked.OnAvatarReinitialize(); + } + catch(System.Exception e) + { + MelonLoader.MelonLogger.Error(e); + } + } + static void OnEyeControllerUpdate_Postfix(ref EyeMovementController __instance) => ms_instance?.OnEyeControllerUpdate(__instance); void OnEyeControllerUpdate(EyeMovementController p_component) { diff --git a/ml_lme/LeapInput.cs b/ml_lme/LeapInput.cs index b7a27c4..b9dea38 100644 --- a/ml_lme/LeapInput.cs +++ b/ml_lme/LeapInput.cs @@ -4,6 +4,7 @@ using ABI_RC.Core.Player; using ABI_RC.Core.Savior; using ABI_RC.Systems.IK; using ABI_RC.Systems.InputManagement; +using ABI_RC.Systems.VRModeSwitch; using System.Collections; using UnityEngine; @@ -41,7 +42,7 @@ namespace ml_lme m_handRayLeft.holderRoot = m_handRayLeft.gameObject; m_handRayLeft.attachmentDistance = 0f; m_handRayLeft.uiMask = 32; - m_handRayLeft.isDesktopRay = true; + m_handRayLeft.isDesktopRay = !m_inVR; m_lineLeft = m_handRayLeft.gameObject.AddComponent(); m_lineLeft.endWidth = 1f; @@ -63,7 +64,7 @@ namespace ml_lme m_handRayRight.holderRoot = m_handRayRight.gameObject; m_handRayRight.attachmentDistance = 0f; m_handRayRight.uiMask = 32; - m_handRayRight.isDesktopRay = true; + m_handRayRight.isDesktopRay = !m_inVR; m_lineRight = m_handRayRight.gameObject.AddComponent(); m_lineRight.endWidth = 1f; @@ -92,6 +93,9 @@ namespace ml_lme MelonLoader.MelonCoroutines.Start(WaitForSettings()); MelonLoader.MelonCoroutines.Start(WaitForMaterial()); + + VRModeSwitchEvents.OnInitializeXR.AddListener(OnSwitchToVR); + VRModeSwitchEvents.OnDeinitializeXR.AddListener(OnSwitchToDesktop); } IEnumerator WaitForSettings() @@ -117,10 +121,12 @@ namespace ml_lme m_lineLeft.material = PlayerSetup.Instance.vrRayLeft.lineRenderer.material; m_lineLeft.gameObject.layer = PlayerSetup.Instance.vrRayLeft.gameObject.layer; m_handRayLeft.highlightMaterial = PlayerSetup.Instance.vrRayLeft.highlightMaterial; + m_handRayLeft.SetVRActive(m_inVR); m_lineRight.material = PlayerSetup.Instance.vrRayLeft.lineRenderer.material; m_lineRight.gameObject.layer = PlayerSetup.Instance.vrRayLeft.gameObject.layer; - m_handRayLeft.highlightMaterial = PlayerSetup.Instance.vrRayLeft.highlightMaterial; + m_handRayRight.highlightMaterial = PlayerSetup.Instance.vrRayLeft.highlightMaterial; + m_handRayRight.SetVRActive(m_inVR); } public override void ModuleDestroyed() @@ -149,6 +155,8 @@ namespace ml_lme Settings.FingersOnlyChange -= this.OnFingersOnlyChange; MetaPort.Instance.settings.settingBoolChanged.RemoveListener(this.OnGameSettingBoolChange); + VRModeSwitchEvents.OnInitializeXR.RemoveListener(OnSwitchToVR); + VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(OnSwitchToDesktop); } public override void UpdateInput() @@ -290,7 +298,7 @@ namespace ml_lme { LeapParser.LeapData l_data = LeapManager.Instance.GetLatestData(); - if(m_handVisibleLeft && (!m_inVR || !Utils.IsLeftHandTracked()) && !Settings.FingersOnly) + if(m_handVisibleLeft && !Settings.FingersOnly) { float l_strength = l_data.m_leftHand.m_grabStrength; @@ -318,7 +326,7 @@ namespace ml_lme } } - if(m_handVisibleRight && (!m_inVR || !Utils.IsRightHandTracked()) && !Settings.FingersOnly) + if(m_handVisibleRight && !Settings.FingersOnly) { float l_strength = l_data.m_rightHand.m_grabStrength; @@ -346,8 +354,8 @@ namespace ml_lme } } - ToggleHandRay(m_handVisibleLeft && (!m_inVR || !Utils.IsLeftHandTracked()) && !Settings.FingersOnly, true); - ToggleHandRay(m_handVisibleRight && (!m_inVR || !Utils.IsRightHandTracked()) && !Settings.FingersOnly, false); + ToggleHandRay(m_handVisibleLeft && !Settings.FingersOnly, true); + ToggleHandRay(m_handVisibleRight && !Settings.FingersOnly, false); } } @@ -413,11 +421,6 @@ namespace ml_lme } // Game events - internal void OnAvatarSetup() - { - m_inVR = Utils.IsInVR(); - } - internal void OnRayScale(float p_scale) { m_handRayLeft.SetRayScale(p_scale); @@ -441,6 +444,43 @@ namespace ml_lme } } + void OnSwitchToVR() + { + m_inVR = true; + base._inputManager.SetModuleAsLast(this); + + if(m_handRayLeft != null) + { + m_handRayLeft.isDesktopRay = false; + m_handRayLeft.SetVRActive(true); + } + if(m_handRayRight != null) + { + m_handRayRight.isDesktopRay = false; + m_handRayRight.SetVRActive(true); + } + + 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); + } + // Arbitrary void SetFingersInput(LeapParser.HandData p_hand, bool p_left) { diff --git a/ml_lme/LeapManager.cs b/ml_lme/LeapManager.cs index 5dc80f1..f9fd020 100644 --- a/ml_lme/LeapManager.cs +++ b/ml_lme/LeapManager.cs @@ -180,12 +180,16 @@ namespace ml_lme if(m_leapTracking != null) m_leapTracking.OnAvatarSetup(); - m_leapInput?.OnAvatarSetup(); - if(m_leapTracked != null) m_leapTracked.OnAvatarSetup(); } + internal void OnAvatarReinitialize() + { + if(m_leapTracked != null) + m_leapTracked.OnAvatarReinitialize(); + } + internal void OnRayScale(float p_scale) { m_leapInput?.OnRayScale(p_scale); diff --git a/ml_lme/LeapTracked.cs b/ml_lme/LeapTracked.cs index e23ac8b..6d98ece 100644 --- a/ml_lme/LeapTracked.cs +++ b/ml_lme/LeapTracked.cs @@ -1,5 +1,6 @@ using ABI_RC.Core.Player; using ABI_RC.Systems.IK; +using ABI_RC.Systems.VRModeSwitch; using RootMotion.FinalIK; using System.Reflection; using UnityEngine; @@ -121,7 +122,7 @@ namespace ml_lme void LateUpdate() { - if(m_enabled && !m_inVR && (m_poseHandler != null)) + if(m_enabled && (m_vrIK == null) && (m_poseHandler != null)) { LeapParser.LeapData l_data = LeapManager.Instance.GetLatestData(); @@ -147,8 +148,7 @@ namespace ml_lme m_leftTargetActive = false; m_rightTargetActive = false; - if(!m_inVR) - m_poseHandler?.Dispose(); + m_poseHandler?.Dispose(); m_poseHandler = null; m_leftHandTarget.localPosition = Vector3.zero; @@ -169,7 +169,7 @@ namespace ml_lme if(m_hips != null) l_hipsPos = m_hips.localPosition; - if(m_vrIK == null) + if(!m_inVR) { // Force desktop avatar into T-Pose m_poseHandler = new HumanPoseHandler(PlayerSetup.Instance._animator.avatar, PlayerSetup.Instance._avatar.transform); @@ -236,8 +236,8 @@ namespace ml_lme } else { - m_vrIK.solver.OnPreUpdate += this.OnIKPreUpdate; - m_vrIK.solver.OnPostUpdate += this.OnIKPostUpdate; + m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate); + m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); } if(m_hips != null) @@ -245,6 +245,18 @@ namespace ml_lme } } + internal void OnAvatarReinitialize() + { + // Old VRIK is destroyed by game + m_inVR = Utils.IsInVR(); + m_vrIK = PlayerSetup.Instance._animator.GetComponent(); + if(m_vrIK != null) + { + m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate); + m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); + } + } + // VRIK updates void OnIKPreUpdate() { diff --git a/ml_lme/LeapTracking.cs b/ml_lme/LeapTracking.cs index 684c679..1a5abf2 100644 --- a/ml_lme/LeapTracking.cs +++ b/ml_lme/LeapTracking.cs @@ -1,4 +1,5 @@ using ABI_RC.Core.Player; +using ABI_RC.Systems.VRModeSwitch; using System.Collections; using UnityEngine; @@ -87,6 +88,9 @@ namespace ml_lme OnVisualHandsChange(Settings.VisualHands); OnTrackingModeChange(Settings.TrackingMode); OnRootAngleChange(Settings.RootAngle); + + VRModeSwitchEvents.OnInitializeXR.AddListener(this.OnSwitchToVR); + VRModeSwitchEvents.OnDeinitializeXR.AddListener(this.OnSwitchToDesktop); } IEnumerator WaitForLocalPlayer() @@ -136,6 +140,9 @@ namespace ml_lme Settings.RootAngleChange -= this.OnRootAngleChange; Settings.HeadAttachChange -= this.OnHeadAttachChange; Settings.HeadOffsetChange -= this.OnHeadOffsetChange; + + VRModeSwitchEvents.OnInitializeXR.RemoveListener(this.OnSwitchToVR); + VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(this.OnSwitchToDesktop); } void Update() @@ -263,6 +270,18 @@ namespace ml_lme OnHeadAttachChange(Settings.HeadAttach); } + void OnSwitchToVR() + { + m_inVR = true; + OnHeadAttachChange(Settings.HeadAttach); + } + void OnSwitchToDesktop() + { + m_inVR = false; + OnHeadAttachChange(Settings.HeadAttach); + } + + // Utils static void OrientationAdjustment(ref Vector3 p_pos, ref Quaternion p_rot, Settings.LeapTrackingMode p_mode) { switch(p_mode) diff --git a/ml_lme/Main.cs b/ml_lme/Main.cs index 5ad5406..5ee3cc0 100644 --- a/ml_lme/Main.cs +++ b/ml_lme/Main.cs @@ -1,5 +1,6 @@ using ABI.CCK.Components; using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; using System.Collections; using System.Reflection; using UnityEngine; @@ -33,6 +34,11 @@ namespace ml_lme null, new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); + HarmonyInstance.Patch( + typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), + null, + new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) + ); HarmonyInstance.Patch( typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetControllerRayScale)), null, @@ -101,6 +107,20 @@ namespace ml_lme } } + static void OnAvatarReinitialize_Postfix() => ms_instance?.OnAvatarReinitialize(); + void OnAvatarReinitialize() + { + try + { + if(m_leapManager != null) + m_leapManager.OnAvatarReinitialize(); + } + catch(System.Exception e) + { + MelonLoader.MelonLogger.Error(e); + } + } + static void OnRayScale_Postfix(float __0) => ms_instance?.OnRayScale(__0); void OnRayScale(float p_scale) { diff --git a/ml_lme/Utils.cs b/ml_lme/Utils.cs index a3888db..3958d09 100644 --- a/ml_lme/Utils.cs +++ b/ml_lme/Utils.cs @@ -1,6 +1,8 @@ -using ABI_RC.Core.Savior; +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Savior; using ABI_RC.Core.UI; using ABI_RC.Systems.InputManagement; +using System.Collections.Generic; using System.Reflection; using UnityEngine; @@ -9,8 +11,10 @@ namespace ml_lme static class Utils { static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.NonPublic | BindingFlags.Instance); + static readonly FieldInfo ms_vrActive = typeof(ControllerRay).GetField("vrActive", BindingFlags.NonPublic | BindingFlags.Instance); + static readonly FieldInfo ms_inputModules = typeof(CVRInputManager).GetField("_inputModules", BindingFlags.NonPublic | BindingFlags.Instance); - public static bool IsInVR() => ((CheckVR.Instance != null) && CheckVR.Instance.hasVrDeviceLoaded); + public static bool IsInVR() => ((MetaPort.Instance != null) && MetaPort.Instance.isUsingVr); public static bool AreKnucklesInUse() => ((CVRInputManager.Instance._leftController == ABI_RC.Systems.InputManagement.XR.eXRControllerType.Index) || (CVRInputManager.Instance._rightController == ABI_RC.Systems.InputManagement.XR.eXRControllerType.Index)); public static bool IsLeftHandTracked() => (CVRInputManager.Instance._leftController != ABI_RC.Systems.InputManagement.XR.eXRControllerType.None); public static bool IsRightHandTracked() => (CVRInputManager.Instance._rightController != ABI_RC.Systems.InputManagement.XR.eXRControllerType.None); @@ -31,6 +35,19 @@ namespace ml_lme } } + public static void SetVRActive(this ControllerRay p_instance, bool p_state) => ms_vrActive?.SetValue(p_instance, p_state); + + public static void SetModuleAsLast(this CVRInputManager p_instance, CVRInputModule p_module) + { + List l_modules = ms_inputModules.GetValue(p_instance) as List; + int l_index = l_modules.FindIndex(p => p == p_module); + if(l_index != -1) + { + l_modules[l_index] = l_modules[l_modules.Count - 1]; + l_modules[l_modules.Count - 1] = p_module; + } + } + static public void ExecuteScript(this CohtmlControlledViewWrapper p_instance, string p_script) => ((cohtml.Net.View)ms_view.GetValue(p_instance)).ExecuteScript(p_script); public static void Swap(ref T lhs, ref T rhs) diff --git a/ml_pam/ArmMover.cs b/ml_pam/ArmMover.cs index 47757f7..6c6b946 100644 --- a/ml_pam/ArmMover.cs +++ b/ml_pam/ArmMover.cs @@ -332,17 +332,7 @@ namespace ml_pam internal void OnAvatarSetup() { // Recheck if user could switch to VR - if(m_inVR != Utils.IsInVR()) - { - 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(); + RecheckMode(); if(!m_inVR && PlayerSetup.Instance._animator.isHuman) { @@ -409,8 +399,8 @@ namespace ml_pam else { m_armLength = m_vrIK.solver.leftArm.mag * 1.25f; - m_vrIK.solver.OnPreUpdate += this.OnIKPreUpdate; - m_vrIK.solver.OnPostUpdate += this.OnIKPostUpdate; + m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate); + m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); } l_tpHelper.Restore(); @@ -420,6 +410,19 @@ namespace ml_pam SetEnabled(m_enabled); } + internal void OnAvatarReinitialize() + { + // Old VRIK is destroyed by game + RecheckMode(); + m_vrIK = PlayerSetup.Instance._animator.GetComponent(); + 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); + } + } + internal void OnPickupGrab(CVRPickupObject p_pickup, ControllerRay p_ray, Vector3 p_hit) { if(p_ray == ViewManager.Instance.desktopControllerRay) @@ -509,5 +512,20 @@ namespace ml_pam } } } + + void RecheckMode() + { + if(m_inVR != Utils.IsInVR()) + { + 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(); + } } } diff --git a/ml_pam/Main.cs b/ml_pam/Main.cs index 9ad1bc5..b6e17a9 100644 --- a/ml_pam/Main.cs +++ b/ml_pam/Main.cs @@ -1,6 +1,7 @@ using ABI.CCK.Components; using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; using System; using System.Reflection; using UnityEngine; @@ -30,6 +31,11 @@ namespace ml_pam null, new HarmonyLib.HarmonyMethod(typeof(PickupArmMovement).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); + HarmonyInstance.Patch( + typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), + null, + new HarmonyLib.HarmonyMethod(typeof(PickupArmMovement).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) + ); HarmonyInstance.Patch( typeof(CVRPickupObject).GetMethod(nameof(CVRPickupObject.Grab)), null, @@ -95,6 +101,20 @@ namespace ml_pam } } + static void OnAvatarReinitialize_Postfix() => ms_instance?.OnAvatarReinitialize(); + void OnAvatarReinitialize() + { + try + { + if(m_localMover != null) + m_localMover.OnAvatarReinitialize(); + } + catch(System.Exception e) + { + MelonLoader.MelonLogger.Error(e); + } + } + static void OnCVRPickupObjectGrab_Postfix(ref CVRPickupObject __instance, ControllerRay __1, Vector3 __2) => ms_instance?.OnCVRPickupObjectGrab(__instance, __1, __2); void OnCVRPickupObjectGrab(CVRPickupObject p_pickup, ControllerRay p_ray, Vector3 p_hit) { diff --git a/ml_pam/Utils.cs b/ml_pam/Utils.cs index d8d76c4..ec4513b 100644 --- a/ml_pam/Utils.cs +++ b/ml_pam/Utils.cs @@ -1,4 +1,5 @@ -using ABI_RC.Core.UI; +using ABI_RC.Core.Savior; +using ABI_RC.Core.UI; using System.Reflection; using UnityEngine; @@ -8,7 +9,7 @@ namespace ml_pam { static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.NonPublic | BindingFlags.Instance); - public static bool IsInVR() => ((ABI_RC.Core.Savior.CheckVR.Instance != null) && ABI_RC.Core.Savior.CheckVR.Instance.hasVrDeviceLoaded); + public static bool IsInVR() => ((MetaPort.Instance != null) && MetaPort.Instance.isUsingVr); static public void ExecuteScript(this CohtmlControlledViewWrapper p_instance, string p_script) => ((cohtml.Net.View)ms_view.GetValue(p_instance)).ExecuteScript(p_script); diff --git a/ml_pmc/Main.cs b/ml_pmc/Main.cs index 62392e1..072f7eb 100644 --- a/ml_pmc/Main.cs +++ b/ml_pmc/Main.cs @@ -1,5 +1,6 @@ using ABI_RC.Core.Networking.IO.Social; using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; using ABI_RC.Systems.Movement; using System; using System.Collections.Generic; @@ -33,6 +34,11 @@ namespace ml_pmc null, new HarmonyLib.HarmonyMethod(typeof(PlayerMovementCopycat).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); + HarmonyInstance.Patch( + typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), + null, + new HarmonyLib.HarmonyMethod(typeof(PlayerMovementCopycat).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) + ); MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); } @@ -133,5 +139,19 @@ namespace ml_pmc MelonLoader.MelonLogger.Error(e); } } + + static void OnAvatarReinitialize_Postfix() => ms_instance?.OnAvatarReinitialize(); + void OnAvatarReinitialize() + { + try + { + if(m_localCopycat != null) + m_localCopycat.OnAvatarReinitialize(); + } + catch(System.Exception e) + { + MelonLoader.MelonLogger.Error(e); + } + } } } diff --git a/ml_pmc/PoseCopycat.cs b/ml_pmc/PoseCopycat.cs index d4400b4..ebe1821 100644 --- a/ml_pmc/PoseCopycat.cs +++ b/ml_pmc/PoseCopycat.cs @@ -3,6 +3,7 @@ using ABI_RC.Systems.IK; using ABI_RC.Systems.IK.SubSystems; using ABI_RC.Systems.InputManagement; using ABI_RC.Systems.Movement; +using ABI_RC.Systems.VRModeSwitch; using RootMotion.FinalIK; using UnityEngine; @@ -36,6 +37,9 @@ namespace ml_pmc { if(Instance == null) Instance = this; + + VRModeSwitchEvents.OnInitializeXR.AddListener(this.OnSwitchToVR); + VRModeSwitchEvents.OnDeinitializeXR.AddListener(this.OnSwitchToDesktop); } void OnDestroy() { @@ -52,6 +56,9 @@ namespace ml_pmc m_animator = null; m_vrIk = null; m_lookAtIk = null; + + VRModeSwitchEvents.OnInitializeXR.RemoveListener(this.OnSwitchToVR); + VRModeSwitchEvents.OnDeinitializeXR.RemoveListener(this.OnSwitchToDesktop); } // Unity events @@ -177,8 +184,6 @@ namespace ml_pmc } m_active = false; - m_inVr = Utils.IsInVR(); - if(m_puppetParser != null) Object.Destroy(m_puppetParser); m_puppetParser = null; @@ -220,6 +225,33 @@ namespace ml_pmc else m_animator = null; } + internal void OnAvatarReinitialize() + { + // Old VRIK and LookAtIK are destroyed by game + m_vrIk = PlayerSetup.Instance._avatar.GetComponent(); + m_lookAtIk = PlayerSetup.Instance._avatar.GetComponent(); + + if(m_vrIk != null) + { + m_vrIk.onPreSolverUpdate.AddListener(this.OnVRIKPreUpdate); + m_vrIk.onPostSolverUpdate.AddListener(this.OnVRIKPostUpdate); + } + + if(m_lookAtIk != null) + { + m_lookAtIk.onPreSolverUpdate.AddListener(this.OnLookAtIKPreUpdate); + m_lookAtIk.onPostSolverUpdate.AddListener(this.OnLookAtIKPostUpdate); + } + } + + void OnSwitchToVR() + { + m_inVr = true; + } + void OnSwitchToDesktop() + { + m_inVr = false; + } // IK updates void OnVRIKPreUpdate() diff --git a/ml_pmc/Utils.cs b/ml_pmc/Utils.cs index c09cc09..0235eda 100644 --- a/ml_pmc/Utils.cs +++ b/ml_pmc/Utils.cs @@ -16,7 +16,7 @@ namespace ml_pmc }; static readonly int[] ms_centralMuscles = new int[] { 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 18, 20 }; - public static bool IsInVR() => ((CheckVR.Instance != null) && CheckVR.Instance.hasVrDeviceLoaded); + public static bool IsInVR() => ((MetaPort.Instance != null) && MetaPort.Instance.isUsingVr); public static bool AreKnucklesInUse() => ((CVRInputManager.Instance._leftController == ABI_RC.Systems.InputManagement.XR.eXRControllerType.Index) || (CVRInputManager.Instance._rightController == ABI_RC.Systems.InputManagement.XR.eXRControllerType.Index)); public static bool IsWorldSafe() => ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying); diff --git a/ml_prm/Main.cs b/ml_prm/Main.cs index fda596e..e26d045 100644 --- a/ml_prm/Main.cs +++ b/ml_prm/Main.cs @@ -40,6 +40,11 @@ namespace ml_prm null, new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) ); + HarmonyInstance.Patch( + typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public), + new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnAvatarReinitialize_Prefix), BindingFlags.Static | BindingFlags.NonPublic)), + new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnAvatarReinitialize_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) + ); HarmonyInstance.Patch( typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.NonPublic | BindingFlags.Instance), null, @@ -137,6 +142,34 @@ namespace ml_prm } } + static void OnAvatarReinitialize_Prefix() => ms_instance?.OnPreAvatarReinitialize(); + void OnPreAvatarReinitialize() + { + try + { + if(m_localController != null) + m_localController.OnPreAvatarReinitialize(); + } + catch(System.Exception e) + { + MelonLoader.MelonLogger.Error(e); + } + } + + static void OnAvatarReinitialize_Postfix() => ms_instance?.OnPostAvatarReinitialize(); + void OnPostAvatarReinitialize() + { + try + { + if(m_localController != null) + m_localController.OnPostAvatarReinitialize(); + } + catch(System.Exception e) + { + MelonLoader.MelonLogger.Error(e); + } + } + static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference) => ms_instance?.OnSetupIKScaling(___scaleDifference.y); void OnSetupIKScaling(float p_scaleDifference) { diff --git a/ml_prm/RagdollController.cs b/ml_prm/RagdollController.cs index 2da4694..7a69197 100644 --- a/ml_prm/RagdollController.cs +++ b/ml_prm/RagdollController.cs @@ -427,6 +427,32 @@ namespace ml_prm OnAngularDragChange(Settings.AngularDrag); } + internal void OnPreAvatarReinitialize() + { + if(m_avatarReady && m_enabled) + { + m_forcedSwitch = true; + SwitchRagdoll(); + m_forcedSwitch = false; + } + } + internal void OnPostAvatarReinitialize() + { + m_inVR = Utils.IsInVR(); + m_vrIK = PlayerSetup.Instance._avatar.GetComponent(); + + if(m_vrIK != null) + m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); + + if(m_avatarReady && m_enabled) + { + m_forcedSwitch = true; + SwitchRagdoll(); + m_forcedSwitch = false; + } + + } + internal void OnAvatarScaling(float p_scaleDifference) { if(m_puppetRoot != null) diff --git a/ml_prm/Utils.cs b/ml_prm/Utils.cs index ff88aae..41b3ba0 100644 --- a/ml_prm/Utils.cs +++ b/ml_prm/Utils.cs @@ -14,7 +14,7 @@ namespace ml_prm static readonly FieldInfo ms_influencerTouchingVolumes = typeof(PhysicsInfluencer).GetField("_touchingVolumes", BindingFlags.NonPublic | BindingFlags.Instance); static readonly FieldInfo ms_influencerSubmergedColliders = typeof(PhysicsInfluencer).GetField("_submergedColliders", BindingFlags.NonPublic | BindingFlags.Instance); - public static bool IsInVR() => ((CheckVR.Instance != null) && CheckVR.Instance.hasVrDeviceLoaded); + public static bool IsInVR() => ((MetaPort.Instance != null) && MetaPort.Instance.isUsingVr); public static bool IsWorldSafe() => ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying); public static float GetWorldMovementLimit() {