Handling of "VR <-> Desktop" switch, attempt one

This commit is contained in:
SDraw 2024-01-29 23:11:01 +03:00
parent c2a219dfa3
commit 66b448a2c3
No known key found for this signature in database
GPG key ID: BB95B4DAB2BB8BB5
20 changed files with 356 additions and 77 deletions

View file

@ -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<LineRenderer>();
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<LineRenderer>();
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)
{

View file

@ -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);

View file

@ -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<VRIK>();
if(m_vrIK != null)
{
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
}
}
// VRIK updates
void OnIKPreUpdate()
{

View file

@ -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)

View file

@ -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)
{

View file

@ -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<CVRInputModule> l_modules = ms_inputModules.GetValue(p_instance) as List<CVRInputModule>;
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<T>(ref T lhs, ref T rhs)