diff --git a/README.md b/README.md index 9e535ea..218f24b 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,6 @@ Merged set of MelonLoader mods for ChilloutVR. | Avatar Change Info | ml_aci | 1.0.1 | Yes | Working | | Avatar Motion Tweaker | ml_amt | 1.0.6 | Pending | Working | | Desktop Reticle Switch | ml_drs | 1.0.0 | Yes | Working | -| Four Point Tracking | ml_fpt | 1.0.3 | Pending | Working | -| Leap Motion Extension | ml_lme | 1.1.7 | Pending | Working | +| Four Point Tracking | ml_fpt | 1.0.4 | Pending | Working | +| Leap Motion Extension | ml_lme | 1.1.8 | Pending | Working | | Server Connection Info | ml_sci | 1.0.1 | Yes | Working | diff --git a/ml_fpt/Main.cs b/ml_fpt/Main.cs index 25d5b32..57b0ce8 100644 --- a/ml_fpt/Main.cs +++ b/ml_fpt/Main.cs @@ -41,8 +41,7 @@ namespace ml_fpt { if(m_origVrIk != null) m_origVrIk.enabled = false; - - m_indexIk.calibrated = false; + m_ikCalibrator.enabled = false; m_indexIk.enabled = false; Transform l_hips = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Hips); @@ -58,10 +57,13 @@ namespace ml_fpt m_origVrIk.solver.spine.pelvisTarget = PlayerSetup.Instance._trackerManager.trackers[m_hipsTrackerIndex].target; m_origVrIk.solver.spine.pelvisPositionWeight = 1f; m_origVrIk.solver.spine.pelvisRotationWeight = 1f; + m_origVrIk.solver.OnPreUpdate -= this.OverrideIKWeight; + m_origVrIk.solver.IKPositionWeight = 1f; + m_origVrIk.enabled = true; } - m_indexIk.calibrated = true; m_indexIk.enabled = true; + m_ikCalibrator.enabled = true; PlayerSetup.Instance._animator.runtimeAnimatorController = m_oldRuntimeAnimator; @@ -114,7 +116,7 @@ namespace ml_fpt void StartCalibration() { - if(m_playerReady && !m_inCalibration && PlayerSetup.Instance._inVr && !PlayerSetup.Instance.avatarIsLoading && PlayerSetup.Instance._animator.isHuman && !m_ikCalibrator.inFullbodyCalibration && !m_ikCalibrator.avatarCalibratedAsFullBody && m_indexIk.calibrated) + if(m_playerReady && !m_inCalibration && PlayerSetup.Instance._inVr && !PlayerSetup.Instance.avatarIsLoading && PlayerSetup.Instance._animator.isHuman && !m_ikCalibrator.inFullbodyCalibration && !m_ikCalibrator.avatarCalibratedAsFullBody) { for(int i = 0; i < PlayerSetup.Instance._trackerManager.trackerNames.Length; i++) { @@ -131,6 +133,8 @@ namespace ml_fpt PlayerSetup.Instance._animator.runtimeAnimatorController = PlayerSetup.Instance.tPoseAnimatorController; m_origVrIk = PlayerSetup.Instance._animator.GetComponent(); + if(m_origVrIk != null) + m_origVrIk.solver.OnPreUpdate += this.OverrideIKWeight; m_ikCalibrator.leftHandModel.SetActive(true); m_ikCalibrator.rightHandModel.SetActive(true); @@ -157,13 +161,19 @@ namespace ml_fpt m_origVrIk = null; } + void OverrideIKWeight() + { + if(m_inCalibration && (m_origVrIk != null)) + m_origVrIk.solver.IKPositionWeight = 0f; + } + static void OnAvatarClear_Postfix() => ms_instance?.OnAvatarClear(); void OnAvatarClear() { if(m_inCalibration) { - m_indexIk.calibrated = true; m_indexIk.enabled = true; + m_ikCalibrator.enabled = true; m_ikCalibrator.leftHandModel.SetActive(false); m_ikCalibrator.rightHandModel.SetActive(false); diff --git a/ml_fpt/Properties/AssemblyInfo.cs b/ml_fpt/Properties/AssemblyInfo.cs index c0feaf2..101a324 100644 --- a/ml_fpt/Properties/AssemblyInfo.cs +++ b/ml_fpt/Properties/AssemblyInfo.cs @@ -1,10 +1,10 @@ using System.Reflection; [assembly: AssemblyTitle("FourPointTracking")] -[assembly: AssemblyVersion("1.0.3")] -[assembly: AssemblyFileVersion("1.0.3")] +[assembly: AssemblyVersion("1.0.4")] +[assembly: AssemblyFileVersion("1.0.4")] -[assembly: MelonLoader.MelonInfo(typeof(ml_fpt.FourPointTracking), "FourPointTracking", "1.0.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] +[assembly: MelonLoader.MelonInfo(typeof(ml_fpt.FourPointTracking), "FourPointTracking", "1.0.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] [assembly: MelonLoader.MelonGame(null, "ChilloutVR")] [assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] [assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)] \ No newline at end of file diff --git a/ml_fpt/README.md b/ml_fpt/README.md index a2c65b0..9212dbf 100644 --- a/ml_fpt/README.md +++ b/ml_fpt/README.md @@ -8,7 +8,6 @@ This mod adds ability to use 4-point tracking. # Usage * Be sure that your tracker role is set to `Hips` in SteamVR -* Adjust your avatar at forward direction * Go to `Settings - Implementation - 4-Point Tracking` and press `Calibrate` button * Adjust your tracker in a similar way as in FBT calibration * Press trigger on both controllers diff --git a/ml_lme/LeapTracked.cs b/ml_lme/LeapTracked.cs index fe1fc12..c9a7f52 100644 --- a/ml_lme/LeapTracked.cs +++ b/ml_lme/LeapTracked.cs @@ -1,5 +1,6 @@ using ABI_RC.Core.Player; using ABI_RC.Core.Savior; +using RootMotion.FinalIK; using UnityEngine; namespace ml_lme @@ -7,7 +8,12 @@ namespace ml_lme [DisallowMultipleComponent] class LeapTracked : MonoBehaviour { + static readonly Quaternion ms_offsetLeft = Quaternion.Euler(0f, 90f, 330f); + static readonly Quaternion ms_offsetRight = Quaternion.Euler(0f, 270f, 30f); + IndexIK m_indexIK = null; + CVR_IK_Calibrator m_ikCalibrator = null; + VRIK m_vrIK = null; bool m_enabled = true; bool m_fingersOnly = false; @@ -15,10 +21,30 @@ namespace ml_lme LeapIK m_leapIK = null; Transform m_leftHand = null; Transform m_rightHand = null; + Transform m_leftHandTarget = null; + Transform m_rightHandTarget = null; + bool m_leftTargetActive = false; + bool m_rightTargetActive = false; void Start() { m_indexIK = this.GetComponent(); + m_ikCalibrator = this.GetComponent(); + + if(m_leftHand != null) + { + m_leftHandTarget = new GameObject("RotationTarget").transform; + m_leftHandTarget.parent = m_leftHand; + m_leftHandTarget.localPosition = Vector3.zero; + m_leftHandTarget.localRotation = Quaternion.identity; + } + if(m_rightHand != null) + { + m_rightHandTarget = new GameObject("RotationTarget").transform; + m_rightHandTarget.parent = m_rightHand; + m_rightHandTarget.localPosition = Vector3.zero; + m_rightHandTarget.localRotation = Quaternion.identity; + } } public void SetEnabled(bool p_state) @@ -33,6 +59,9 @@ namespace ml_lme if(m_leapIK != null) m_leapIK.SetEnabled(m_enabled); + + if(!m_enabled || m_fingersOnly) + RestoreIK(); } public void SetFingersOnly(bool p_state) @@ -41,6 +70,9 @@ namespace ml_lme if(m_leapIK != null) m_leapIK.SetFingersOnly(m_fingersOnly); + + if(!m_enabled || m_fingersOnly) + RestoreIK(); } public void SetHands(Transform p_left, Transform p_right) @@ -91,18 +123,49 @@ namespace ml_lme CVRInputManager.Instance.fingerCurlRightPinky = p_gesturesData.m_rightFingersBends[4]; } } + + if((m_vrIK != null) && !m_fingersOnly) + { + if(p_gesturesData.m_handsPresenses[0] && !m_leftTargetActive) + { + m_vrIK.solver.leftArm.target = m_leftHandTarget; + m_leftTargetActive = true; + } + if(!p_gesturesData.m_handsPresenses[0] && m_leftTargetActive) + { + m_vrIK.solver.leftArm.target = m_ikCalibrator.leftHandAnchor; + m_leftTargetActive = false; + } + + if(p_gesturesData.m_handsPresenses[1] && !m_rightTargetActive) + { + m_vrIK.solver.rightArm.target = m_rightHandTarget; + m_rightTargetActive = true; + } + if(!p_gesturesData.m_handsPresenses[1] && m_rightTargetActive) + { + m_vrIK.solver.rightArm.target = m_ikCalibrator.rightHandAnchor; + m_rightTargetActive = false; + } + } } } public void OnAvatarClear() { m_leapIK = null; + m_vrIK = null; + m_leftTargetActive = false; + m_rightTargetActive = false; } public void OnSetupAvatarGeneral() { + m_vrIK = PlayerSetup.Instance._animator.GetComponent(); + if(m_indexIK != null) { + m_indexIK.avatarAnimator = PlayerSetup.Instance._animator; m_indexIK.activeControl = (m_enabled || Utils.AreKnucklesInUse()); CVRInputManager.Instance.individualFingerTracking = (m_enabled || Utils.AreKnucklesInUse()); } @@ -114,6 +177,59 @@ namespace ml_lme m_leapIK.SetEnabled(m_enabled); m_leapIK.SetFingersOnly(m_fingersOnly); } + + if((m_vrIK != null) && PlayerSetup.Instance._animator.isHuman) + { + // Here we fokin' go! + m_leftHand.position = Vector3.zero; + m_leftHand.rotation = Quaternion.identity; + Transform l_lowerArm = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftLowerArm); + Transform l_hand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand); + if((l_lowerArm != null) && (l_hand != null)) + { + m_leftHandTarget.SetParent(l_lowerArm); + m_leftHandTarget.localPosition = l_hand.localPosition; + m_leftHandTarget.localRotation = l_hand.localRotation; + m_leftHandTarget.SetParent(m_leftHand, true); + m_leftHandTarget.localPosition = Vector3.zero; + + Quaternion l_rot = m_leftHandTarget.localRotation; + m_leftHandTarget.localRotation = ms_offsetLeft * l_rot; + } + + m_rightHand.position = Vector3.zero; + m_rightHand.rotation = Quaternion.identity; + l_lowerArm = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightLowerArm); + l_hand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightHand); + if((l_lowerArm != null) && (l_hand != null)) + { + m_rightHandTarget.SetParent(l_lowerArm); + m_rightHandTarget.localPosition = l_hand.localPosition; + m_rightHandTarget.localRotation = l_hand.localRotation; + m_rightHandTarget.SetParent(m_rightHand, true); + m_rightHandTarget.localPosition = Vector3.zero; + + Quaternion l_rot = m_rightHandTarget.localRotation; + m_rightHandTarget.localRotation = ms_offsetRight * l_rot; + } + } + } + + void RestoreIK() + { + if((m_ikCalibrator != null) && (m_vrIK != null)) + { + if(m_leftTargetActive) + { + m_vrIK.solver.leftArm.target = m_ikCalibrator.leftHandAnchor; + m_leftTargetActive = false; + } + if(m_rightTargetActive) + { + m_vrIK.solver.rightArm.target = m_ikCalibrator.rightHandAnchor; + m_rightTargetActive = false; + } + } } } } diff --git a/ml_lme/Main.cs b/ml_lme/Main.cs index 8f5822e..cce319a 100644 --- a/ml_lme/Main.cs +++ b/ml_lme/Main.cs @@ -20,8 +20,6 @@ namespace ml_lme GameObject m_leapControllerModel = null; LeapTracked m_leapTracked = null; - static bool ms_vrState = false; - public override void OnApplicationStart() { if(ms_instance == null) @@ -57,7 +55,7 @@ namespace ml_lme ); HarmonyInstance.Patch( typeof(PlayerSetup).GetMethod("SetupAvatarGeneral", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), - new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnSetupAvatarGeneral_Prefix), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)), + null, new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnSetupAvatarGeneral_Postfix), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)) ); @@ -100,7 +98,6 @@ namespace ml_lme } // Player setup - ms_vrState = PlayerSetup.Instance._inVr; m_leapTracked = PlayerSetup.Instance.gameObject.AddComponent(); m_leapTracked.SetHands(m_leapHands[0].transform, m_leapHands[1].transform); @@ -325,18 +322,7 @@ namespace ml_lme } // Sneaky forced IndexIK calibration - static void OnSetupAvatarGeneral_Prefix(ref PlayerSetup __instance) - { - if(__instance != null) - __instance._inVr = true; - } - static void OnSetupAvatarGeneral_Postfix(ref PlayerSetup __instance) - { - if(__instance != null) - __instance._inVr = ms_vrState; - - ms_instance?.OnSetupAvatarGeneral(); - } + static void OnSetupAvatarGeneral_Postfix() => ms_instance?.OnSetupAvatarGeneral(); void OnSetupAvatarGeneral() { if(m_leapTracked != null) diff --git a/ml_lme/Properties/AssemblyInfo.cs b/ml_lme/Properties/AssemblyInfo.cs index cb490f2..e22aa49 100644 --- a/ml_lme/Properties/AssemblyInfo.cs +++ b/ml_lme/Properties/AssemblyInfo.cs @@ -1,10 +1,10 @@ using System.Reflection; [assembly: AssemblyTitle("LeapMotionExtension")] -[assembly: AssemblyVersion("1.1.7")] -[assembly: AssemblyFileVersion("1.1.7")] +[assembly: AssemblyVersion("1.1.8")] +[assembly: AssemblyFileVersion("1.1.8")] -[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.1.7", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] +[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.1.8", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] [assembly: MelonLoader.MelonGame(null, "ChilloutVR")] [assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] [assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)] diff --git a/ml_lme/README.md b/ml_lme/README.md index 5ffb83f..652700e 100644 --- a/ml_lme/README.md +++ b/ml_lme/README.md @@ -20,6 +20,3 @@ Available mod's settings in `Settings - Implementation - Leap Motion Tracking`: * **Offset angle:** rotation around X axis, useful for neck mounts, 0 by default. * **Fingers tracking only:** apply only fingers tracking, disabled by default. * **Model visibility:** show Leap Motion controller model, useful for tracking visualizing, disabled by default. - -# Notes -* Only fingers tracking in VR mode.