From b4fb9e62e618d01eb96e2dc702705706ab96f19c Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Mon, 16 Jan 2023 01:57:30 -0600 Subject: [PATCH 1/2] fucked --- .../BTKUI_Integration/BTKUI_Integration.cs | 32 ++++-- DesktopVRIK/DesktopVRIK.cs | 99 ++++++++-------- DesktopVRIK/DesktopVRIK_Helper.cs | 108 ++++++++++++++++++ DesktopVRIK/HarmonyPatches.cs | 43 +++++-- DesktopVRIK/Main.cs | 14 ++- 5 files changed, 220 insertions(+), 76 deletions(-) create mode 100644 DesktopVRIK/DesktopVRIK_Helper.cs diff --git a/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs b/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs index a752328..ed962e7 100644 --- a/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs +++ b/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs @@ -9,22 +9,38 @@ public static class BTKUI_Integration [MethodImpl(MethodImplOptions.NoInlining)] public static void Init() { - Page miscPage = QuickMenuAPI.MiscTabPage; - Category CategoryUI = miscPage.AddCategory("DesktopVRIK"); + //Add myself to the Misc Menu - var setting_Enabled = CategoryUI.AddToggle(DesktopVRIKMod.m_entryEnabled.DisplayName, DesktopVRIKMod.m_entryEnabled.Description, DesktopVRIKMod.m_entryEnabled.Value); + Page miscPage = QuickMenuAPI.MiscTabPage; + Category miscCategory = miscPage.AddCategory("DesktopVRIK"); + + var setting_Enabled = miscCategory.AddToggle(DesktopVRIKMod.m_entryEnabled.DisplayName, DesktopVRIKMod.m_entryEnabled.Description, DesktopVRIKMod.m_entryEnabled.Value); setting_Enabled.OnValueUpdated += b => DesktopVRIKMod.m_entryEnabled.Value = b; - var setting_EnforceViewPosition = CategoryUI.AddToggle(DesktopVRIKMod.m_entryEnforceViewPosition.DisplayName, DesktopVRIKMod.m_entryEnforceViewPosition.Description, DesktopVRIKMod.m_entryEnforceViewPosition.Value); + //Add my own page to not clog up Misc Menu + + Page desktopVRIKPage = miscCategory.AddPage("DesktopVRIK Settings", "", "Configure the settings for DesktopVRIK.", "DesktopVRIK"); + desktopVRIKPage.MenuTitle = "DesktopVRIK Settings"; + desktopVRIKPage.MenuSubtitle = "Simplified settings for VRIK on Desktop."; + + Category desktopVRIKCategory = desktopVRIKPage.AddCategory("DesktopVRIK"); + + var setting_Enabled_2 = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEnabled.DisplayName, DesktopVRIKMod.m_entryEnabled.Description, DesktopVRIKMod.m_entryEnabled.Value); + setting_Enabled_2.OnValueUpdated += b => DesktopVRIKMod.m_entryEnabled.Value = b; + + var setting_EnforceViewPosition = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEnforceViewPosition.DisplayName, DesktopVRIKMod.m_entryEnforceViewPosition.Description, DesktopVRIKMod.m_entryEnforceViewPosition.Value); setting_EnforceViewPosition.OnValueUpdated += b => DesktopVRIKMod.m_entryEnforceViewPosition.Value = b; - var setting_DisableEmoteVRIK = CategoryUI.AddToggle(DesktopVRIKMod.m_entryEmoteVRIK.DisplayName, DesktopVRIKMod.m_entryEmoteVRIK.Description, DesktopVRIKMod.m_entryEmoteVRIK.Value); + var setting_DisableEmoteVRIK = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEmoteVRIK.DisplayName, DesktopVRIKMod.m_entryEmoteVRIK.Description, DesktopVRIKMod.m_entryEmoteVRIK.Value); setting_DisableEmoteVRIK.OnValueUpdated += b => DesktopVRIKMod.m_entryEmoteVRIK.Value = b; - var setting_DisableEmoteLookAtIK = CategoryUI.AddToggle(DesktopVRIKMod.m_entryEmoteLookAtIK.DisplayName, DesktopVRIKMod.m_entryEmoteLookAtIK.Description, DesktopVRIKMod.m_entryEmoteLookAtIK.Value); + var setting_DisableEmoteLookAtIK = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEmoteLookAtIK.DisplayName, DesktopVRIKMod.m_entryEmoteLookAtIK.Description, DesktopVRIKMod.m_entryEmoteLookAtIK.Value); setting_DisableEmoteLookAtIK.OnValueUpdated += b => DesktopVRIKMod.m_entryEmoteLookAtIK.Value = b; - var setting_EmulateHipMovementWeight = miscPage.AddSlider(DesktopVRIKMod.m_entryEmulateVRChatHipMovementWeight.DisplayName, DesktopVRIKMod.m_entryEmulateVRChatHipMovementWeight.Description, DesktopVRIKMod.m_entryEmulateVRChatHipMovementWeight.Value, 0f, 1f); - setting_EmulateHipMovementWeight.OnValueUpdated += f => DesktopVRIKMod.m_entryEmulateVRChatHipMovementWeight.Value = f; + var setting_BodyLeanWeight = desktopVRIKPage.AddSlider(DesktopVRIKMod.m_entryBodyLeanWeight.DisplayName, DesktopVRIKMod.m_entryBodyLeanWeight.Description, DesktopVRIKMod.m_entryBodyLeanWeight.Value, 0f, 1f, 1); + setting_BodyLeanWeight.OnValueUpdated += f => DesktopVRIKMod.m_entryBodyLeanWeight.Value = f; + + var setting_BodyAngleLimit = desktopVRIKPage.AddSlider(DesktopVRIKMod.m_entryBodyAngleLimit.DisplayName, DesktopVRIKMod.m_entryBodyAngleLimit.Description, DesktopVRIKMod.m_entryBodyAngleLimit.Value, 0f, 90f, 0); + setting_BodyAngleLimit.OnValueUpdated += f => DesktopVRIKMod.m_entryBodyAngleLimit.Value = f; } } \ No newline at end of file diff --git a/DesktopVRIK/DesktopVRIK.cs b/DesktopVRIK/DesktopVRIK.cs index ab82ebd..4de314b 100644 --- a/DesktopVRIK/DesktopVRIK.cs +++ b/DesktopVRIK/DesktopVRIK.cs @@ -13,27 +13,23 @@ public class DesktopVRIK : MonoBehaviour { public static DesktopVRIK Instance; - public static bool Setting_Enabled, + public static bool + Setting_Enabled, Setting_EnforceViewPosition, Setting_EmoteVRIK, - Setting_EmoteLookAtIK; - public static float Setting_EmulateVRChatHipMovementWeight; - public static float Setting_HipThrustMultiplier = 0.1f; + Setting_EmoteLookAtIK, + Setting_Internal_PlantFeet = true; + + public static float + Setting_BodyLeanWeight = 0.3f, + Setting_BodyAngleLimit = 45f; public Transform viewpoint; - public Vector3 initialCamPos; - - Transform headIKTarget; - Transform avatarHeadBone; + public Vector3 eyeOffset; void Start() { Instance = this; - // create the shared Head IK Target - headIKTarget = new GameObject("[DesktopVRIK] Head IK Target").transform; - headIKTarget.parent = PlayerSetup.Instance.transform; - headIKTarget.localPosition = new Vector3(0f, 1.8f, 0f); - headIKTarget.localRotation = Quaternion.identity; } public void ChangeViewpointHandling(bool enabled) @@ -45,51 +41,30 @@ public class DesktopVRIK : MonoBehaviour PlayerSetup.Instance.desktopCamera.transform.localPosition = Vector3.zero; return; } - PlayerSetup.Instance.desktopCamera.transform.localPosition = initialCamPos; + PlayerSetup.Instance.desktopCamera.transform.localPosition = eyeOffset; } public void AlternativeOnPreSolverUpdate() { - //this order matters, rotation offset will be choppy if avatar is not cenetered first - - if (headIKTarget != null && avatarHeadBone != null) - { - headIKTarget.position = new Vector3(headIKTarget.position.x, avatarHeadBone.position.y, headIKTarget.position.z); - } + //set IK offsets (this is a really fucking weird way to do this) + DesktopVRIK_Helper.Instance?.OnUpdateVRIK(); //Reset avatar offset (VRIK will literally make you walk away from root otherwise) IKSystem.vrik.transform.localPosition = Vector3.zero; IKSystem.vrik.transform.localRotation = Quaternion.identity; - float movementVector = (1 - MovementSystem.Instance.movementVector.magnitude); - IKSystem.vrik.solver.spine.positionWeight = Setting_HipThrustMultiplier * movementVector; - - //VRChat hip movement emulation - if (Setting_EmulateVRChatHipMovementWeight != 0) - { - float angle = PlayerSetup.Instance.desktopCamera.transform.localEulerAngles.x; - if (angle > 180) angle -= 360; - float leanAmount = angle * movementVector * Setting_EmulateVRChatHipMovementWeight; - Quaternion rotation = Quaternion.AngleAxis(leanAmount, IKSystem.Instance.avatar.transform.right); - IKSystem.vrik.solver.AddRotationOffset(IKSolverVR.RotationOffset.Head, rotation); - } - - IKSystem.vrik.solver.plantFeet = true; + IKSystem.vrik.solver.plantFeet = Setting_Internal_PlantFeet; } public Animator animator; - //public Quaternion originalRotation; - public RuntimeAnimatorController runtimeAnimatorController; public VRIK AlternativeCalibration(CVRAvatar avatar) { animator = avatar.GetComponent(); - avatarHeadBone = animator.GetBoneTransform(HumanBodyBones.Head); + Transform avatarHeadBone = animator.GetBoneTransform(HumanBodyBones.Head); //Stuff to make bad armatures work (Fuck you Default Robot Kyle) avatar.transform.localPosition = Vector3.zero; - //originalRotation = avatar.transform.rotation; - //avatar.transform.rotation = Quaternion.identity; //ikpose layer (specified by avatar author) int ikposeLayerIndex = animator.GetLayerIndex("IKPose"); @@ -114,12 +89,7 @@ public class DesktopVRIK : MonoBehaviour vrik.solver.locomotion.angleThreshold = 30f; vrik.solver.locomotion.maxLegStretch = 0.75f; //nuke weights - vrik.solver.spine.headClampWeight = 1f; vrik.solver.spine.minHeadHeight = 0f; - - //calm ur ass - vrik.solver.spine.positionWeight = 0.1f; - vrik.solver.spine.pelvisPositionWeight = 0f; vrik.solver.leftArm.positionWeight = 0f; vrik.solver.leftArm.rotationWeight = 0f; @@ -131,6 +101,19 @@ public class DesktopVRIK : MonoBehaviour vrik.solver.rightLeg.rotationWeight = 0f; vrik.solver.IKPositionWeight = 0f; + //calm ur ass + vrik.solver.spine.positionWeight = 0f; + + + //related to body & head rotation offset/limit + vrik.solver.spine.headClampWeight = 1f; + vrik.solver.spine.bodyRotStiffness = 0.8f; + //makes chest between feet and head direction + vrik.solver.spine.chestClampWeight = 0.5f; + //needed to make head 1:1 with camera still + vrik.solver.spine.neckStiffness = 1f; + + //ChilloutVR specific BodySystem.TrackingLeftArmEnabled = false; BodySystem.TrackingRightArmEnabled = false; @@ -141,17 +124,19 @@ public class DesktopVRIK : MonoBehaviour IKSystem.Instance.headAnchorPositionOffset = Vector3.zero; //Custom funky AF head ik shit - foreach (Transform transform in headIKTarget) + foreach (Transform transform in DesktopVRIK_Helper.Instance.ik_HeadFollower) { if (transform.name == "Head IK Target") { Destroy(transform.gameObject); } } - headIKTarget.position = avatarHeadBone.position; - headIKTarget.rotation = Quaternion.identity; - VRIKCalibrator.CalibrateHead(vrik, headIKTarget.transform, IKSystem.Instance.headAnchorPositionOffset, IKSystem.Instance.headAnchorRotationOffset); - headIKTarget.localRotation = Quaternion.identity; + + DesktopVRIK_Helper.Instance.avatar_HeadBone = avatarHeadBone; + DesktopVRIK_Helper.Instance.ik_HeadFollower.position = avatarHeadBone.position; + DesktopVRIK_Helper.Instance.ik_HeadFollower.rotation = Quaternion.identity; + VRIKCalibrator.CalibrateHead(vrik, DesktopVRIK_Helper.Instance.ik_HeadFollower.transform, IKSystem.Instance.headAnchorPositionOffset, IKSystem.Instance.headAnchorRotationOffset); + DesktopVRIK_Helper.Instance.ik_HeadFollower.localRotation = Quaternion.identity; //force immediate calibration before animator decides to fuck us vrik.solver.SetToReferences(vrik.references); @@ -167,17 +152,23 @@ public class DesktopVRIK : MonoBehaviour } //Find eyeoffset - initialCamPos = PlayerSetup.Instance.desktopCamera.transform.localPosition; + eyeOffset = PlayerSetup.Instance.desktopCamera.transform.localPosition; viewpoint = avatarHeadBone.Find("LocalHeadPoint"); ChangeViewpointHandling(Setting_EnforceViewPosition); - if (vrik != null) + //reset ikpose layer + if (ikposeLayerIndex != -1) { - vrik.onPreSolverUpdate.AddListener(new UnityAction(this.AlternativeOnPreSolverUpdate)); + animator.SetLayerWeight(ikposeLayerIndex, 0f); + if (locoLayerIndex != -1) + { + animator.SetLayerWeight(locoLayerIndex, 1f); + } } - //avatar.transform.rotation = originalRotation; - IKSystem.Instance.ResetIK(); + vrik?.onPreSolverUpdate.AddListener(new UnityAction(this.AlternativeOnPreSolverUpdate)); + + DesktopVRIK_Helper.Instance?.OnResetIK(); return vrik; } diff --git a/DesktopVRIK/DesktopVRIK_Helper.cs b/DesktopVRIK/DesktopVRIK_Helper.cs new file mode 100644 index 0000000..bcab58f --- /dev/null +++ b/DesktopVRIK/DesktopVRIK_Helper.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; +using ABI_RC.Systems.IK.SubSystems; +using ABI_RC.Systems.MovementSystem; +using RootMotion.FinalIK; + +namespace NAK.Melons.DesktopVRIK; + +internal class DesktopVRIK_Helper : MonoBehaviour +{ + public static DesktopVRIK_Helper Instance; + + //Avatar + public Transform avatar_HeadBone; + + //DesktopVRIK + public Transform ik_HeadFollower; + public Quaternion ik_HeadRotation; + + public static void CreateInstance() + { + Transform helper = new GameObject("[DesktopVRIK] Virtual Rig").transform; + helper.parent = PlayerSetup.Instance.transform; + helper.localPosition = Vector3.zero; + helper.localRotation = Quaternion.identity; + helper.gameObject.AddComponent(); + } + + void Start() + { + Instance = this; + + Transform headFollower = new GameObject("HeadBone_Follower").transform; + headFollower.parent = transform; + headFollower.localPosition = new Vector3(0f, 1.8f, 0f); + headFollower.localRotation = Quaternion.identity; + ik_HeadFollower = headFollower; + } + + public void OnUpdateVRIK() + { + if (avatar_HeadBone != null) + { + float globalWeight = (1 - MovementSystem.Instance.movementVector.magnitude); + globalWeight *= IKSystem.vrik.solver.locomotion.weight; + + //the most important thing ever + IKSystem.vrik.solver.spine.rotationWeight = globalWeight; + + HeadIK_FollowPosition(); + + HeadIK_RotateWithWeight(globalWeight); + HeadIK_FollowWithinAngle(globalWeight); + ik_HeadFollower.rotation = ik_HeadRotation; + } + } + + public void OnResetIK() + { + ik_HeadRotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z); + } + + public void HeadIK_FollowPosition() + { + ik_HeadFollower.position = new Vector3(transform.position.x, avatar_HeadBone.position.y, transform.position.z); + } + + public void HeadIK_FollowWithinAngle(float weight) + { + if (DesktopVRIK.Setting_BodyAngleLimit != 0) + { + float weightedAngle = DesktopVRIK.Setting_BodyAngleLimit * weight; + float currentAngle = Mathf.DeltaAngle(transform.eulerAngles.y, ik_HeadRotation.eulerAngles.y); + if (Mathf.Abs(currentAngle) > weightedAngle) + { + float fixedCurrentAngle = currentAngle > 0 ? currentAngle : -currentAngle; + float clampedAngle = Mathf.MoveTowardsAngle(ik_HeadRotation.eulerAngles.y, transform.eulerAngles.y, fixedCurrentAngle - weightedAngle); + ik_HeadRotation = Quaternion.Euler(ik_HeadRotation.eulerAngles.x, clampedAngle, 0); + } + } + else + { + ik_HeadRotation = Quaternion.Euler(ik_HeadRotation.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z); + } + } + + public void HeadIK_RotateWithWeight(float weight) + { + //VRChat hip movement emulation + if (DesktopVRIK.Setting_BodyLeanWeight != 0) + { + float angle = PlayerSetup.Instance.desktopCamera.transform.localEulerAngles.x; + if (angle > 180) angle -= 360; + float leanAmount = angle * weight * DesktopVRIK.Setting_BodyLeanWeight; + ik_HeadRotation = Quaternion.Euler(leanAmount * 0.33f, ik_HeadRotation.eulerAngles.y, 0); + } + else + { + ik_HeadRotation = Quaternion.Euler(transform.eulerAngles.x, ik_HeadRotation.eulerAngles.y, transform.eulerAngles.z); + } + } +} \ No newline at end of file diff --git a/DesktopVRIK/HarmonyPatches.cs b/DesktopVRIK/HarmonyPatches.cs index c32f443..6925207 100644 --- a/DesktopVRIK/HarmonyPatches.cs +++ b/DesktopVRIK/HarmonyPatches.cs @@ -72,26 +72,47 @@ class PlayerSetupPatches { BodySystem.TrackingEnabled = !____emotePlaying; IKSystem.vrik.solver?.Reset(); + DesktopVRIK_Helper.Instance?.OnResetIK(); } } } } - [HarmonyPostfix] + + //should probably patch movement system instead + [HarmonyPrefix] [HarmonyPatch(typeof(PlayerSetup), "HandleDesktopCameraPosition")] - private static void Postfix_PlayerSetup_HandleDesktopCameraPosition(bool ignore, ref PlayerSetup __instance, ref MovementSystem ____movementSystem, ref int ___headBobbingLevel) + private static void Prefix_PlayerSetup_HandleDesktopCameraPosition + ( + bool ignore, + ref PlayerSetup __instance, + ref MovementSystem + ____movementSystem, + ref int ___headBobbingLevel + ) { - if (DesktopVRIK.Setting_Enabled && DesktopVRIK.Setting_EnforceViewPosition) + if (___headBobbingLevel != 2) { - if (!____movementSystem.disableCameraControl || ignore) - { - if (___headBobbingLevel == 2 && DesktopVRIK.Instance.viewpoint != null) - { - __instance.desktopCamera.transform.localPosition = Vector3.zero; - __instance.desktopCameraRig.transform.position = DesktopVRIK.Instance.viewpoint.position; - } - } + return; } + + if (!DesktopVRIK.Setting_Enabled || !DesktopVRIK.Setting_EnforceViewPosition) + { + return; + } + + if (____movementSystem.disableCameraControl && !ignore) + { + return; + } + + if (DesktopVRIK.Instance.viewpoint == null) + { + return; + } + + __instance.desktopCamera.transform.position = DesktopVRIK.Instance.viewpoint.position; + return; } } diff --git a/DesktopVRIK/Main.cs b/DesktopVRIK/Main.cs index 8fd3cc4..23644b2 100644 --- a/DesktopVRIK/Main.cs +++ b/DesktopVRIK/Main.cs @@ -13,16 +13,20 @@ public class DesktopVRIKMod : MelonMod m_entryEmoteVRIK, m_entryEmoteLookAtIK, m_entryAllowRootSlipping; - internal static MelonPreferences_Entry m_entryEmulateVRChatHipMovementWeight; + internal static MelonPreferences_Entry + m_entryBodyLeanWeight, + m_entryBodyAngleLimit; public override void OnInitializeMelon() { m_categoryDesktopVRIK = MelonPreferences.CreateCategory(SettingsCategory); m_entryEnabled = m_categoryDesktopVRIK.CreateEntry("Enabled", true, description: "Toggle DesktopVRIK entirely. Requires avatar reload."); - m_entryEmulateVRChatHipMovementWeight = m_categoryDesktopVRIK.CreateEntry("Body Movement Weight", 0.5f, description: "Emulates VRChat-like body movement when looking up/down. Set to 0 to disable."); m_entryEnforceViewPosition = m_categoryDesktopVRIK.CreateEntry("Enforce View Position", false, description: "Corrects view position to use VRIK offsets."); m_entryEmoteVRIK = m_categoryDesktopVRIK.CreateEntry("Disable Emote VRIK", true, description: "Disable VRIK while emoting. Only disable if you are ok with looking dumb."); m_entryEmoteLookAtIK = m_categoryDesktopVRIK.CreateEntry("Disable Emote LookAtIK", true, description: "Disable LookAtIK while emoting. This setting doesn't really matter, as LookAtIK isn't networked while doing an emote."); + m_entryBodyLeanWeight = m_categoryDesktopVRIK.CreateEntry("Body Lean Weight", 0.3f, description: "Emulates old VRChat-like body leaning when looking up/down. Set to 0 to disable."); + m_entryBodyAngleLimit = m_categoryDesktopVRIK.CreateEntry("Body Angle Limit", 45f, description: "Emulates VRChat-like body and head offset when rotating left/right. Set to 0 to disable."); + foreach (var setting in m_categoryDesktopVRIK.Entries) { setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); @@ -46,7 +50,10 @@ public class DesktopVRIKMod : MelonMod { while (PlayerSetup.Instance == null) yield return null; + + DesktopVRIK_Helper.CreateInstance(); PlayerSetup.Instance.gameObject.AddComponent(); + while (DesktopVRIK.Instance == null) yield return null; UpdateAllSettings(); @@ -56,7 +63,8 @@ public class DesktopVRIKMod : MelonMod { if (!DesktopVRIK.Instance) return; DesktopVRIK.Setting_Enabled = m_entryEnabled.Value; - DesktopVRIK.Setting_EmulateVRChatHipMovementWeight = Mathf.Clamp01(m_entryEmulateVRChatHipMovementWeight.Value); + DesktopVRIK.Setting_BodyLeanWeight = Mathf.Clamp01(m_entryBodyLeanWeight.Value); + DesktopVRIK.Setting_BodyAngleLimit = Mathf.Clamp(m_entryBodyAngleLimit.Value, 0f, 90f); DesktopVRIK.Setting_EmoteVRIK = m_entryEmoteVRIK.Value; DesktopVRIK.Setting_EmoteLookAtIK = m_entryEmoteLookAtIK.Value; DesktopVRIK.Instance.ChangeViewpointHandling(m_entryEnforceViewPosition.Value); From d3d058607f660c7733bf94401000d7b4d20d1bb1 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 2 Feb 2023 20:38:22 -0600 Subject: [PATCH 2/2] tweaks to not make PAM and BID wonky also fuck vrik toes, those literally stink --- .../BTKUI_Integration/BTKUI_Integration.cs | 46 ------------------ DesktopVRIK/DesktopVRIK.cs | 46 ++++++++---------- DesktopVRIK/DesktopVRIK_Helper.cs | 2 +- DesktopVRIK/HarmonyPatches.cs | 2 +- DesktopVRIK/Integrations/BTKUIAddon.cs | 48 +++++++++++++++++++ DesktopVRIK/Main.cs | 11 ++--- DesktopVRIK/format.json | 8 ++-- 7 files changed, 79 insertions(+), 84 deletions(-) delete mode 100644 DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs create mode 100644 DesktopVRIK/Integrations/BTKUIAddon.cs diff --git a/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs b/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs deleted file mode 100644 index ed962e7..0000000 --- a/DesktopVRIK/BTKUI_Integration/BTKUI_Integration.cs +++ /dev/null @@ -1,46 +0,0 @@ -using BTKUILib; -using BTKUILib.UIObjects; -using System.Runtime.CompilerServices; - -namespace NAK.Melons.DesktopVRIK.BTKUI_Integration; - -public static class BTKUI_Integration -{ - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Init() - { - //Add myself to the Misc Menu - - Page miscPage = QuickMenuAPI.MiscTabPage; - Category miscCategory = miscPage.AddCategory("DesktopVRIK"); - - var setting_Enabled = miscCategory.AddToggle(DesktopVRIKMod.m_entryEnabled.DisplayName, DesktopVRIKMod.m_entryEnabled.Description, DesktopVRIKMod.m_entryEnabled.Value); - setting_Enabled.OnValueUpdated += b => DesktopVRIKMod.m_entryEnabled.Value = b; - - //Add my own page to not clog up Misc Menu - - Page desktopVRIKPage = miscCategory.AddPage("DesktopVRIK Settings", "", "Configure the settings for DesktopVRIK.", "DesktopVRIK"); - desktopVRIKPage.MenuTitle = "DesktopVRIK Settings"; - desktopVRIKPage.MenuSubtitle = "Simplified settings for VRIK on Desktop."; - - Category desktopVRIKCategory = desktopVRIKPage.AddCategory("DesktopVRIK"); - - var setting_Enabled_2 = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEnabled.DisplayName, DesktopVRIKMod.m_entryEnabled.Description, DesktopVRIKMod.m_entryEnabled.Value); - setting_Enabled_2.OnValueUpdated += b => DesktopVRIKMod.m_entryEnabled.Value = b; - - var setting_EnforceViewPosition = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEnforceViewPosition.DisplayName, DesktopVRIKMod.m_entryEnforceViewPosition.Description, DesktopVRIKMod.m_entryEnforceViewPosition.Value); - setting_EnforceViewPosition.OnValueUpdated += b => DesktopVRIKMod.m_entryEnforceViewPosition.Value = b; - - var setting_DisableEmoteVRIK = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEmoteVRIK.DisplayName, DesktopVRIKMod.m_entryEmoteVRIK.Description, DesktopVRIKMod.m_entryEmoteVRIK.Value); - setting_DisableEmoteVRIK.OnValueUpdated += b => DesktopVRIKMod.m_entryEmoteVRIK.Value = b; - - var setting_DisableEmoteLookAtIK = desktopVRIKCategory.AddToggle(DesktopVRIKMod.m_entryEmoteLookAtIK.DisplayName, DesktopVRIKMod.m_entryEmoteLookAtIK.Description, DesktopVRIKMod.m_entryEmoteLookAtIK.Value); - setting_DisableEmoteLookAtIK.OnValueUpdated += b => DesktopVRIKMod.m_entryEmoteLookAtIK.Value = b; - - var setting_BodyLeanWeight = desktopVRIKPage.AddSlider(DesktopVRIKMod.m_entryBodyLeanWeight.DisplayName, DesktopVRIKMod.m_entryBodyLeanWeight.Description, DesktopVRIKMod.m_entryBodyLeanWeight.Value, 0f, 1f, 1); - setting_BodyLeanWeight.OnValueUpdated += f => DesktopVRIKMod.m_entryBodyLeanWeight.Value = f; - - var setting_BodyAngleLimit = desktopVRIKPage.AddSlider(DesktopVRIKMod.m_entryBodyAngleLimit.DisplayName, DesktopVRIKMod.m_entryBodyAngleLimit.Description, DesktopVRIKMod.m_entryBodyAngleLimit.Value, 0f, 90f, 0); - setting_BodyAngleLimit.OnValueUpdated += f => DesktopVRIKMod.m_entryBodyAngleLimit.Value = f; - } -} \ No newline at end of file diff --git a/DesktopVRIK/DesktopVRIK.cs b/DesktopVRIK/DesktopVRIK.cs index 4de314b..5e73a26 100644 --- a/DesktopVRIK/DesktopVRIK.cs +++ b/DesktopVRIK/DesktopVRIK.cs @@ -17,12 +17,11 @@ public class DesktopVRIK : MonoBehaviour Setting_Enabled, Setting_EnforceViewPosition, Setting_EmoteVRIK, - Setting_EmoteLookAtIK, - Setting_Internal_PlantFeet = true; + Setting_EmoteLookAtIK; public static float - Setting_BodyLeanWeight = 0.3f, - Setting_BodyAngleLimit = 45f; + Setting_BodyLeanWeight = 0.5f, + Setting_BodyAngleLimit = 0f; public Transform viewpoint; public Vector3 eyeOffset; @@ -46,14 +45,15 @@ public class DesktopVRIK : MonoBehaviour public void AlternativeOnPreSolverUpdate() { - //set IK offsets (this is a really fucking weird way to do this) + //this order matters, rotation offset will be choppy if avatar is not cenetered first + DesktopVRIK_Helper.Instance?.OnUpdateVRIK(); //Reset avatar offset (VRIK will literally make you walk away from root otherwise) IKSystem.vrik.transform.localPosition = Vector3.zero; IKSystem.vrik.transform.localRotation = Quaternion.identity; - IKSystem.vrik.solver.plantFeet = Setting_Internal_PlantFeet; + IKSystem.vrik.solver.plantFeet = true; } public Animator animator; @@ -79,17 +79,27 @@ public class DesktopVRIK : MonoBehaviour animator.Update(0f); } - //Generic VRIK calibration shit VRIK vrik = avatar.gameObject.AddComponent(); vrik.AutoDetectReferences(); + //fuck toes + vrik.references.leftToes = null; + vrik.references.rightToes = null; + vrik.fixTransforms = true; vrik.solver.plantFeet = false; - vrik.solver.locomotion.weight = 0f; vrik.solver.locomotion.angleThreshold = 30f; vrik.solver.locomotion.maxLegStretch = 0.75f; - //nuke weights - vrik.solver.spine.minHeadHeight = 0f; + vrik.solver.spine.minHeadHeight = -100f; + + vrik.solver.spine.bodyRotStiffness = 0.15f; + vrik.solver.spine.headClampWeight = 1f; + vrik.solver.spine.maintainPelvisPosition = 1f; + vrik.solver.spine.neckStiffness = 0f; + + vrik.solver.locomotion.weight = 0f; + vrik.solver.spine.bodyPosStiffness = 0f; + vrik.solver.spine.positionWeight = 0f; vrik.solver.spine.pelvisPositionWeight = 0f; vrik.solver.leftArm.positionWeight = 0f; vrik.solver.leftArm.rotationWeight = 0f; @@ -101,27 +111,11 @@ public class DesktopVRIK : MonoBehaviour vrik.solver.rightLeg.rotationWeight = 0f; vrik.solver.IKPositionWeight = 0f; - //calm ur ass - vrik.solver.spine.positionWeight = 0f; - - - //related to body & head rotation offset/limit - vrik.solver.spine.headClampWeight = 1f; - vrik.solver.spine.bodyRotStiffness = 0.8f; - //makes chest between feet and head direction - vrik.solver.spine.chestClampWeight = 0.5f; - //needed to make head 1:1 with camera still - vrik.solver.spine.neckStiffness = 1f; - - - //ChilloutVR specific BodySystem.TrackingLeftArmEnabled = false; BodySystem.TrackingRightArmEnabled = false; BodySystem.TrackingLeftLegEnabled = false; BodySystem.TrackingRightLegEnabled = false; BodySystem.TrackingPositionWeight = 0f; - IKSystem.Instance.headAnchorRotationOffset = Vector3.zero; - IKSystem.Instance.headAnchorPositionOffset = Vector3.zero; //Custom funky AF head ik shit foreach (Transform transform in DesktopVRIK_Helper.Instance.ik_HeadFollower) diff --git a/DesktopVRIK/DesktopVRIK_Helper.cs b/DesktopVRIK/DesktopVRIK_Helper.cs index bcab58f..ae4f433 100644 --- a/DesktopVRIK/DesktopVRIK_Helper.cs +++ b/DesktopVRIK/DesktopVRIK_Helper.cs @@ -51,7 +51,7 @@ internal class DesktopVRIK_Helper : MonoBehaviour globalWeight *= IKSystem.vrik.solver.locomotion.weight; //the most important thing ever - IKSystem.vrik.solver.spine.rotationWeight = globalWeight; + //IKSystem.vrik.solver.spine.rotationWeight = globalWeight; HeadIK_FollowPosition(); diff --git a/DesktopVRIK/HarmonyPatches.cs b/DesktopVRIK/HarmonyPatches.cs index 6925207..2a9a6b1 100644 --- a/DesktopVRIK/HarmonyPatches.cs +++ b/DesktopVRIK/HarmonyPatches.cs @@ -139,7 +139,7 @@ class IKSystemPatches ____poseHandler.SetHumanPose(ref ___humanPose); ____vrik = DesktopVRIK.Instance.AlternativeCalibration(avatar); - IKSystem.Instance.ApplyAvatarScaleToIk(avatar.viewPosition.y); + IKSystem.Instance.ApplyAvatarScaleToIk(avatar.viewPosition.y); } } } diff --git a/DesktopVRIK/Integrations/BTKUIAddon.cs b/DesktopVRIK/Integrations/BTKUIAddon.cs new file mode 100644 index 0000000..e2ab2ab --- /dev/null +++ b/DesktopVRIK/Integrations/BTKUIAddon.cs @@ -0,0 +1,48 @@ +using BTKUILib; +using BTKUILib.UIObjects; +using System.Runtime.CompilerServices; + +namespace NAK.Melons.DesktopVRIK; + +public static class BTKUIAddon +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Init() + { + //Add myself to the Misc Menu + + Page miscPage = QuickMenuAPI.MiscTabPage; + Category miscCategory = miscPage.AddCategory(DesktopVRIKMod.SettingsCategory); + + AddMelonToggle(ref miscCategory, DesktopVRIKMod.m_entryEnabled); + + //Add my own page to not clog up Misc Menu + + Page desktopVRIKPage = miscCategory.AddPage("DesktopVRIK Settings", "", "Configure the settings for DesktopVRIK.", "DesktopVRIK"); + desktopVRIKPage.MenuTitle = "DesktopVRIK Settings"; + desktopVRIKPage.MenuSubtitle = "Simplified settings for VRIK on Desktop."; + + Category desktopVRIKCategory = desktopVRIKPage.AddCategory("DesktopVRIK"); + + AddMelonToggle(ref desktopVRIKCategory, DesktopVRIKMod.m_entryEnabled); + + AddMelonToggle(ref desktopVRIKCategory, DesktopVRIKMod.m_entryEnforceViewPosition); + + AddMelonToggle(ref desktopVRIKCategory, DesktopVRIKMod.m_entryEmoteVRIK); + + AddMelonToggle(ref desktopVRIKCategory, DesktopVRIKMod.m_entryEmoteLookAtIK); + + AddMelonSlider(ref desktopVRIKPage, DesktopVRIKMod.m_entryBodyLeanWeight, 0, 1f); + + AddMelonSlider(ref desktopVRIKPage, DesktopVRIKMod.m_entryBodyAngleLimit, 0, 90f); + } + private static void AddMelonToggle(ref Category category, MelonLoader.MelonPreferences_Entry entry) + { + category.AddToggle(entry.DisplayName, entry.Description, entry.Value).OnValueUpdated += b => entry.Value = b; + } + + private static void AddMelonSlider(ref Page page, MelonLoader.MelonPreferences_Entry entry, float min, float max) + { + page.AddSlider(entry.DisplayName, entry.Description, entry.Value, min, max).OnValueUpdated += f => entry.Value = f; + } +} \ No newline at end of file diff --git a/DesktopVRIK/Main.cs b/DesktopVRIK/Main.cs index 23644b2..524f85b 100644 --- a/DesktopVRIK/Main.cs +++ b/DesktopVRIK/Main.cs @@ -11,9 +11,8 @@ public class DesktopVRIKMod : MelonMod internal static MelonPreferences_Entry m_entryEnabled, m_entryEnforceViewPosition, m_entryEmoteVRIK, - m_entryEmoteLookAtIK, - m_entryAllowRootSlipping; - internal static MelonPreferences_Entry + m_entryEmoteLookAtIK; + internal static MelonPreferences_Entry m_entryBodyLeanWeight, m_entryBodyAngleLimit; public override void OnInitializeMelon() @@ -24,8 +23,8 @@ public class DesktopVRIKMod : MelonMod m_entryEmoteVRIK = m_categoryDesktopVRIK.CreateEntry("Disable Emote VRIK", true, description: "Disable VRIK while emoting. Only disable if you are ok with looking dumb."); m_entryEmoteLookAtIK = m_categoryDesktopVRIK.CreateEntry("Disable Emote LookAtIK", true, description: "Disable LookAtIK while emoting. This setting doesn't really matter, as LookAtIK isn't networked while doing an emote."); - m_entryBodyLeanWeight = m_categoryDesktopVRIK.CreateEntry("Body Lean Weight", 0.3f, description: "Emulates old VRChat-like body leaning when looking up/down. Set to 0 to disable."); - m_entryBodyAngleLimit = m_categoryDesktopVRIK.CreateEntry("Body Angle Limit", 45f, description: "Emulates VRChat-like body and head offset when rotating left/right. Set to 0 to disable."); + m_entryBodyLeanWeight = m_categoryDesktopVRIK.CreateEntry("Body Lean Weight", 0.5f, description: "Emulates old VRChat-like body leaning when looking up/down. Set to 0 to disable."); + m_entryBodyAngleLimit = m_categoryDesktopVRIK.CreateEntry("Body Angle Limit", 0f, description: "Emulates VRChat-like body and head offset when rotating left/right. Set to 0 to disable. (this setting only affects the feet due to chillout not setting up the player controller for VRIK)"); foreach (var setting in m_categoryDesktopVRIK.Entries) { @@ -36,7 +35,7 @@ public class DesktopVRIKMod : MelonMod if (MelonMod.RegisteredMelons.Any(it => it.Info.Name == "BTKUILib")) { MelonLogger.Msg("Initializing BTKUILib support."); - BTKUI_Integration.BTKUI_Integration.Init(); + BTKUIAddon.Init(); } //Apply patches (i stole) diff --git a/DesktopVRIK/format.json b/DesktopVRIK/format.json index d145c52..c7ab85f 100644 --- a/DesktopVRIK/format.json +++ b/DesktopVRIK/format.json @@ -1,7 +1,7 @@ { "_id": 117, "name": "DesktopVRIK", - "modversion": "2.0.2", + "modversion": "2.0.3", "gameversion": "2022r170", "loaderversion": "0.5.7", "modtype": "Mod", @@ -14,10 +14,10 @@ "feet" ], "requirements": [ - "None" + "BTKUILib" ], - "downloadlink": "https://github.com/NotAKidOnSteam/DesktopVRIK/releases/download/v2.0.2/DesktopVRIK.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/DesktopVRIK/releases/download/v2.0.3/DesktopVRIK.dll", "sourcelink": "https://github.com/NotAKidOnSteam/DesktopVRIK/", - "changelog": "- Fixed butt from slipping out underneath you and thrusting when leaning.\n- Fixed VRIK bleeding into locomotion animations.", + "changelog": "- Tweaks to VRIK settings so BetterInteractDesktop & PickupArmMovement better behave alongside VRIK.\n- Tweaks to BTKUI integration.", "embedcolor": "9b59b6" } \ No newline at end of file