From bf1dbf5e0150412d1748600afd1941b794f9d827 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:51:13 -0500 Subject: [PATCH] initial release --- KneeFix/HarmonyPatches.cs | 92 ++++++++++++++++++++++++++++++ KneeFix/KneeFix.csproj | 71 +++++++++++++++++++++++ KneeFix/KneeFix.sln | 25 ++++++++ KneeFix/Main.cs | 25 ++++++++ KneeFix/Properties/AssemblyInfo.cs | 30 ++++++++++ KneeFix/format.json | 23 ++++++++ 6 files changed, 266 insertions(+) create mode 100644 KneeFix/HarmonyPatches.cs create mode 100644 KneeFix/KneeFix.csproj create mode 100644 KneeFix/KneeFix.sln create mode 100644 KneeFix/Main.cs create mode 100644 KneeFix/Properties/AssemblyInfo.cs create mode 100644 KneeFix/format.json diff --git a/KneeFix/HarmonyPatches.cs b/KneeFix/HarmonyPatches.cs new file mode 100644 index 0000000..d458035 --- /dev/null +++ b/KneeFix/HarmonyPatches.cs @@ -0,0 +1,92 @@ +using ABI_RC.Systems.IK; +using ABI_RC.Systems.IK.SubSystems; +using HarmonyLib; +using RootMotion.FinalIK; +using UnityEngine; + +namespace NAK.Melons.KneeFix.HarmonyPatches; + +internal static class BodySystemPatches +{ + [HarmonyPostfix] + [HarmonyPatch(typeof(BodySystem), "SetupOffsets")] + private static void Postfix_BodySystem_SetupOffsets(List trackingPoints) + { + //redo offsets for knees as native is too far from pivot + foreach (TrackingPoint trackingPoint in trackingPoints) + { + Transform parent = null; + if (trackingPoint.assignedRole == TrackingPoint.TrackingRole.LeftKnee) + { + parent = IKSystem.vrik.references.leftCalf; + } + else if (trackingPoint.assignedRole == TrackingPoint.TrackingRole.RightKnee) + { + parent = IKSystem.vrik.references.rightCalf; + } + + if (parent != null) + { + trackingPoint.offsetTransform.parent = parent; + trackingPoint.offsetTransform.localPosition = Vector3.zero; + trackingPoint.offsetTransform.localRotation = Quaternion.identity; + trackingPoint.offsetTransform.parent = trackingPoint.referenceTransform; + + Vector3 b = IKSystem.vrik.references.root.forward * 0.5f; + trackingPoint.offsetTransform.position += b; + } + } + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(BodySystem), "Update")] + private static void Postfix_BodySystem_Update() + { + // FBT needs avatar root to follow head + if (IKSystem.vrik != null) + IKSystem.vrik.solver.spine.maxRootAngle = BodySystem.isCalibratedAsFullBody ? 0f : 180f; + } +} + +internal static class VRIKPatches +{ + /** + Leg solver uses virtual bone calf and foot, plus world tracked knee position for normal maths. + This breaks as you playspace up, because calf and foot position aren't offset yet in solve order. + **/ + + [HarmonyPrefix] + [HarmonyPatch(typeof(IKSolverVR.Leg), "ApplyOffsets")] + private static bool Prefix_IKSolverVR_Leg_ApplyOffsets(ref IKSolverVR.Leg __instance) + { + //This is the second part of the above fix, preventing the solver from calculating a bad bendNormal + //when it doesn't need to. The knee tracker should dictate the bendNormal completely. + + if (__instance.usingKneeTracker) + { + __instance.ApplyPositionOffset(__instance.footPositionOffset, 1f); + __instance.ApplyRotationOffset(__instance.footRotationOffset, 1f); + Quaternion quaternion = Quaternion.FromToRotation(__instance.footPosition - __instance.position, __instance.footPosition + __instance.heelPositionOffset - __instance.position); + __instance.footPosition = __instance.position + quaternion * (__instance.footPosition - __instance.position); + __instance.footRotation = quaternion * __instance.footRotation; + return false; + } + + // run full method like normal otherwise + float num = __instance.bendGoalWeight; + __instance.bendGoalWeight = 0f; + __instance.ApplyOffsetsOld(); + __instance.bendGoalWeight = num; + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(IKSolverVR.Leg), "Solve")] + private static void Prefix_IKSolverVR_Leg_Solve(ref IKSolverVR.Leg __instance) + { + //Turns out VRIK applies bend goal maths before root is offset in solving process. + //We will apply ourselves before then to fix it. + if (__instance.usingKneeTracker) + __instance.ApplyBendGoal(); + } +} \ No newline at end of file diff --git a/KneeFix/KneeFix.csproj b/KneeFix/KneeFix.csproj new file mode 100644 index 0000000..6abdb17 --- /dev/null +++ b/KneeFix/KneeFix.csproj @@ -0,0 +1,71 @@ + + + + + netstandard2.1 + enable + latest + false + True + + + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\0Harmony.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Assembly-CSharp.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Assembly-CSharp-firstpass.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Aura2_Core.dll + + + ..\..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\cohtml.Net.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Cohtml.Runtime.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\MelonLoader.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\SteamVR.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Unity.Postprocessing.Runtime.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Unity.TextMeshPro.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.AnimationModule.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.CoreModule.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.InputLegacyModule.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.PhysicsModule.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.VRModule.dll + + + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.XRModule.dll + + + + + + + + + diff --git a/KneeFix/KneeFix.sln b/KneeFix/KneeFix.sln new file mode 100644 index 0000000..8e3517d --- /dev/null +++ b/KneeFix/KneeFix.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KneeFix", "KneeFix.csproj", "{EF74B9F3-3891-4884-A8E1-B1BEE38E1803}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EF74B9F3-3891-4884-A8E1-B1BEE38E1803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF74B9F3-3891-4884-A8E1-B1BEE38E1803}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF74B9F3-3891-4884-A8E1-B1BEE38E1803}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF74B9F3-3891-4884-A8E1-B1BEE38E1803}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {57B73DF6-AE94-4453-AE6D-CC87E6DE9B97} + EndGlobalSection +EndGlobal diff --git a/KneeFix/Main.cs b/KneeFix/Main.cs new file mode 100644 index 0000000..816a050 --- /dev/null +++ b/KneeFix/Main.cs @@ -0,0 +1,25 @@ +using MelonLoader; + +namespace NAK.Melons.KneeFix; + +public class KneeFixMod : MelonMod +{ + public override void OnInitializeMelon() + { + ApplyPatches(typeof(HarmonyPatches.BodySystemPatches)); + ApplyPatches(typeof(HarmonyPatches.VRIKPatches)); + } + + void ApplyPatches(Type type) + { + try + { + HarmonyInstance.PatchAll(type); + } + catch (Exception e) + { + LoggerInstance.Msg($"Failed while patching {type.Name}!"); + LoggerInstance.Error(e); + } + } +} \ No newline at end of file diff --git a/KneeFix/Properties/AssemblyInfo.cs b/KneeFix/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..35cae8b --- /dev/null +++ b/KneeFix/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using MelonLoader; +using NAK.Melons.KneeFix.Properties; +using System.Reflection; + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(NAK.Melons.KneeFix))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(NAK.Melons.KneeFix))] + +[assembly: MelonInfo( + typeof(NAK.Melons.KneeFix.KneeFixMod), + nameof(NAK.Melons.KneeFix), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "https://github.com/NotAKidOnSteam/KneeFix" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] +[assembly: HarmonyDontPatchAll] + +namespace NAK.Melons.KneeFix.Properties; +internal static class AssemblyInfoParams +{ + public const string Version = "1.0.0"; + public const string Author = "NotAKidoS"; +} \ No newline at end of file diff --git a/KneeFix/format.json b/KneeFix/format.json new file mode 100644 index 0000000..61530f4 --- /dev/null +++ b/KneeFix/format.json @@ -0,0 +1,23 @@ +{ + "_id": -1, + "name": "KneeFix", + "modversion": "1.0.0", + "gameversion": "2022r170", + "loaderversion": "0.5.7", + "modtype": "Mod", + "author": "NotAKidoS", + "description": "Small fix to knee tracking while in FBT.\n\nThis also partially fixes running animations in FBT & emote direction.", + "searchtags": [ + "knee", + "ik", + "tracking", + "fix" + ], + "requirements": [ + "None" + ], + "downloadlink": "https://github.com/NotAKidOnSteam/KneeFix/releases/download/v1.0.0/KneeFix.dll", + "sourcelink": "https://github.com/NotAKidOnSteam/KneeFix/", + "changelog": "Initial Release", + "embedcolor": "7F3F99" +} \ No newline at end of file