mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
a
This commit is contained in:
parent
74d44b47ff
commit
54c7c7cb57
7 changed files with 33 additions and 33 deletions
224
IKFixes/HarmonyPatches.cs
Normal file
224
IKFixes/HarmonyPatches.cs
Normal file
|
@ -0,0 +1,224 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Systems.IK;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Systems.MovementSystem;
|
||||
using HarmonyLib;
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.IKFixes.HarmonyPatches;
|
||||
|
||||
internal static class BodySystemPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BodySystem), "SetupOffsets")]
|
||||
private static void Postfix_BodySystem_SetupOffsets(List<TrackingPoint> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(BodySystem), "Update")]
|
||||
private static bool Prefix_BodySystem_Update(ref BodySystem __instance)
|
||||
{
|
||||
if (IKSystem.vrik == null) return false;
|
||||
IKSolverVR solver = IKSystem.vrik.solver;
|
||||
|
||||
// Allow avatar to rotate seperatly from Player (Desktop&VR)
|
||||
// FBT needs avatar root to follow head
|
||||
solver.spine.maxRootAngle = BodySystem.isCalibratedAsFullBody ? 0f : 180f;
|
||||
|
||||
if (BodySystem.TrackingEnabled)
|
||||
{
|
||||
IKSystem.vrik.enabled = true;
|
||||
solver.IKPositionWeight = BodySystem.TrackingPositionWeight;
|
||||
solver.locomotion.weight = BodySystem.TrackingLocomotionEnabled ? 1f : 0f;
|
||||
|
||||
// fixes arm weights not being set if leftArm & rightArm targets are null
|
||||
// game handles TrackingLegs in PlayerSetup, but not for knee goals
|
||||
SetArmWeight(solver.leftArm, BodySystem.TrackingLeftArmEnabled && solver.leftArm.target != null ? 1f : 0f);
|
||||
SetArmWeight(solver.rightArm, BodySystem.TrackingRightArmEnabled && solver.rightArm.target != null ? 1f : 0f);
|
||||
SetLegWeight(solver.leftLeg, BodySystem.TrackingLeftLegEnabled && solver.leftLeg.target != null ? 1f : 0f);
|
||||
SetLegWeight(solver.rightLeg, BodySystem.TrackingRightLegEnabled && solver.leftLeg.target != null ? 1f : 0f);
|
||||
SetPelvisWeight(solver.spine, solver.spine.pelvisTarget != null ? 1f : 0f);
|
||||
|
||||
// makes running animation look better
|
||||
if (BodySystem.isCalibratedAsFullBody)
|
||||
{
|
||||
bool isRunning = BodySystem.PlayRunningAnimationInFullBody && MovementSystem.Instance.movementVector.magnitude > 0f;
|
||||
SetPelvisWeight(solver.spine, isRunning ? 0f : 1f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IKSystem.vrik.enabled = false;
|
||||
solver.IKPositionWeight = 0f;
|
||||
solver.locomotion.weight = 0f;
|
||||
|
||||
SetArmWeight(solver.leftArm, 0f);
|
||||
SetArmWeight(solver.rightArm, 0f);
|
||||
SetLegWeight(solver.leftLeg, 0f);
|
||||
SetLegWeight(solver.rightLeg, 0f);
|
||||
SetPelvisWeight(solver.spine, 0f);
|
||||
}
|
||||
|
||||
int num = 0;
|
||||
int count = IKSystem.Instance.AllTrackingPoints.FindAll((TrackingPoint m) => m.isActive && m.isValid && m.suggestedRole > TrackingPoint.TrackingRole.Invalid).Count;
|
||||
|
||||
// fixes having all tracking points disabled forcing calibration
|
||||
if (count == 0)
|
||||
{
|
||||
__instance._fbtAvailable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// solid body count block
|
||||
if (BodySystem.enableLeftFootTracking) num++;
|
||||
if (BodySystem.enableRightFootTracking) num++;
|
||||
if (BodySystem.enableHipTracking) num++;
|
||||
if (BodySystem.enableLeftKneeTracking) num++;
|
||||
if (BodySystem.enableRightKneeTracking) num++;
|
||||
if (BodySystem.enableChestTracking) num++;
|
||||
if (BodySystem.enableLeftElbowTracking) num++;
|
||||
if (BodySystem.enableRightElbowTracking) num++;
|
||||
|
||||
__instance._fbtAvailable = (count >= num);
|
||||
|
||||
void SetArmWeight(IKSolverVR.Arm arm, float weight)
|
||||
{
|
||||
arm.positionWeight = weight;
|
||||
arm.rotationWeight = weight;
|
||||
arm.shoulderRotationWeight = weight;
|
||||
arm.shoulderTwistWeight = weight;
|
||||
// assumed fix of bend goal weight if arms disabled with elbows (havent tested)
|
||||
arm.bendGoalWeight = arm.bendGoal != null ? weight : 0f;
|
||||
}
|
||||
void SetLegWeight(IKSolverVR.Leg leg, float weight)
|
||||
{
|
||||
leg.positionWeight = weight;
|
||||
leg.rotationWeight = weight;
|
||||
// fixes knees bending to tracker if feet disabled (running anim)
|
||||
leg.bendGoalWeight = leg.bendGoal != null ? weight : 0f;
|
||||
}
|
||||
void SetPelvisWeight(IKSolverVR.Spine spine, float weight)
|
||||
{
|
||||
// looks better when hips are disabled while running
|
||||
if (spine.pelvisTarget != null)
|
||||
{
|
||||
spine.pelvisPositionWeight = weight;
|
||||
spine.pelvisRotationWeight = weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
spine.pelvisPositionWeight = 0f;
|
||||
spine.pelvisRotationWeight = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
internal static class PlayerSetupPatches
|
||||
{
|
||||
// Last Movement Parent Info
|
||||
static Vector3 lastMovementPosition;
|
||||
static Quaternion lastMovementRotation;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerSetup), "ResetIk")]
|
||||
private static bool Prefix_PlayerSetup_ResetIk()
|
||||
{
|
||||
if (IKSystem.vrik == null) return false;
|
||||
|
||||
CVRMovementParent currentParent = MovementSystem.Instance._currentParent;
|
||||
if (currentParent != null && currentParent._referencePoint != null)
|
||||
{
|
||||
// Get current position, VR pivots around VR camera
|
||||
Vector3 currentPosition = MovementSystem.Instance.rotationPivot.transform.position;
|
||||
currentPosition.y = IKSystem.vrik.transform.position.y; // set pivot to floor
|
||||
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
|
||||
|
||||
// Convert to delta position (how much changed since last frame)
|
||||
Vector3 deltaPosition = currentPosition - lastMovementPosition;
|
||||
Quaternion deltaRotation = Quaternion.Inverse(lastMovementRotation) * currentRotation;
|
||||
|
||||
// Add platform motion to IK solver
|
||||
IKSystem.vrik.solver.AddPlatformMotion(deltaPosition, deltaRotation, currentPosition);
|
||||
|
||||
// Store for next frame
|
||||
lastMovementPosition = currentPosition;
|
||||
lastMovementRotation = currentRotation;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
71
IKFixes/IKFixes.csproj
Normal file
71
IKFixes/IKFixes.csproj
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="0Harmony">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\0Harmony.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Aura2_Core">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Aura2_Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BTKUILib">
|
||||
<HintPath>..\..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="cohtml.Net">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\cohtml.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Cohtml.Runtime">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Cohtml.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MelonLoader">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\MelonLoader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SteamVR">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\SteamVR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Postprocessing.Runtime">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Unity.Postprocessing.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Unity.TextMeshPro.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="Deploy" AfterTargets="Build">
|
||||
<Copy SourceFiles="$(TargetPath)" DestinationFolder="C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" />
|
||||
<Message Text="Copied $(TargetPath) to C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" Importance="high" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
25
IKFixes/IKFixes.sln
Normal file
25
IKFixes/IKFixes.sln
Normal file
|
@ -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
|
26
IKFixes/Main.cs
Normal file
26
IKFixes/Main.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using MelonLoader;
|
||||
|
||||
namespace NAK.Melons.IKFixes;
|
||||
|
||||
public class IKFixesMod : MelonMod
|
||||
{
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
ApplyPatches(typeof(HarmonyPatches.VRIKPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.BodySystemPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
|
||||
}
|
||||
|
||||
void ApplyPatches(Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
HarmonyInstance.PatchAll(type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerInstance.Msg($"Failed while patching {type.Name}!");
|
||||
LoggerInstance.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
30
IKFixes/Properties/AssemblyInfo.cs
Normal file
30
IKFixes/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using MelonLoader;
|
||||
using NAK.Melons.IKFixes.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.Melons.IKFixes))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.Melons.IKFixes))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.Melons.IKFixes.IKFixesMod),
|
||||
nameof(NAK.Melons.IKFixes),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidOnSteam/IKFixes"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.Melons.IKFixes.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
23
IKFixes/format.json
Normal file
23
IKFixes/format.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "IKFixes",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2022r170",
|
||||
"loaderversion": "0.5.7",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Small fixes to knee tracking while in FBT, which lead to fixing running animations while in FBT, emotes playing in wrong direction in FBT, being forced to calibrate if all IK Tracking Settings are disabled, and for those not in FBT, VRIK locomotion footsteps on movement parents.",
|
||||
"searchtags": [
|
||||
"knee",
|
||||
"ik",
|
||||
"tracking",
|
||||
"fix"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/IKFixes/releases/download/v1.0.0/IKFixes.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/IKFixes/",
|
||||
"changelog": "Initial Release",
|
||||
"embedcolor": "f46e49"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue