mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 14:29:25 +00:00
[EzCurls] Initial tests
This commit is contained in:
parent
686a06fab1
commit
623df261b0
7 changed files with 294 additions and 0 deletions
2
EzCurls/EzCurls.csproj
Normal file
2
EzCurls/EzCurls.csproj
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk"/>
|
141
EzCurls/InputModuleCurlAdjuster.cs
Normal file
141
EzCurls/InputModuleCurlAdjuster.cs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
using ABI_RC.Core.Savior;
|
||||||
|
using ABI_RC.Systems.IK.SubSystems;
|
||||||
|
|
||||||
|
namespace NAK.EzCurls;
|
||||||
|
|
||||||
|
internal class InputModuleCurlAdjuster : CVRInputModule
|
||||||
|
{
|
||||||
|
public static InputModuleCurlAdjuster Instance;
|
||||||
|
|
||||||
|
// Curl clamping/adjustment
|
||||||
|
public bool UseCurlSnapping = false;
|
||||||
|
public float SnappedCurlValue = 0.5f;
|
||||||
|
public float RangeStartPercent = 0.5f;
|
||||||
|
public float RangeEndPercent = 0.8f;
|
||||||
|
|
||||||
|
// Curl smoothing/averaging
|
||||||
|
public bool UseCurlSmoothing = false;
|
||||||
|
public bool DontSmoothExtremes = true;
|
||||||
|
public float CurlSimilarityThreshold = 0.5f;
|
||||||
|
public float CurlSmoothingFactor = 0.5f;
|
||||||
|
|
||||||
|
public new void Start()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
base.Start();
|
||||||
|
EzCurls.OnSettingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateInput() => DoCurlAdjustments();
|
||||||
|
public override void UpdateImportantInput() => DoCurlAdjustments();
|
||||||
|
|
||||||
|
private void DoCurlAdjustments()
|
||||||
|
{
|
||||||
|
if (!_inputManager.individualFingerTracking)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (UseCurlSmoothing)
|
||||||
|
{
|
||||||
|
SmoothCurls(
|
||||||
|
ref _inputManager.fingerCurlLeftIndex,
|
||||||
|
ref _inputManager.fingerCurlLeftMiddle,
|
||||||
|
ref _inputManager.fingerCurlLeftRing,
|
||||||
|
ref _inputManager.fingerCurlLeftPinky
|
||||||
|
);
|
||||||
|
|
||||||
|
SmoothCurls(
|
||||||
|
ref _inputManager.fingerCurlRightIndex,
|
||||||
|
ref _inputManager.fingerCurlRightMiddle,
|
||||||
|
ref _inputManager.fingerCurlRightRing,
|
||||||
|
ref _inputManager.fingerCurlRightPinky
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UseCurlSnapping)
|
||||||
|
{
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlLeftIndex);
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlLeftMiddle);
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlLeftRing);
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlLeftPinky);
|
||||||
|
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlRightIndex);
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlRightMiddle);
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlRightRing);
|
||||||
|
SnapCurls(ref _inputManager.fingerCurlRightPinky);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SnapCurls(ref float fingerCurl)
|
||||||
|
{
|
||||||
|
if (fingerCurl >= RangeStartPercent && fingerCurl <= RangeEndPercent)
|
||||||
|
fingerCurl = SnappedCurlValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SmoothCurls(ref float index, ref float middle, ref float ring, ref float pinky)
|
||||||
|
{
|
||||||
|
List<float> values = new List<float> { index, middle, ring, pinky };
|
||||||
|
|
||||||
|
for (int i = 0; i < values.Count; i++)
|
||||||
|
{
|
||||||
|
for (int j = i + 1; j < values.Count; j++)
|
||||||
|
{
|
||||||
|
if (Math.Abs(values[i] - values[j]) <= CurlSimilarityThreshold)
|
||||||
|
{
|
||||||
|
// Compute new smoothed values
|
||||||
|
float smoothedValue = (values[i] + values[j]) / 2;
|
||||||
|
|
||||||
|
// Calculate smoothing factors for both values
|
||||||
|
float smoothingFactor1 = CalculateSmoothingFactor(values[i]);
|
||||||
|
float smoothingFactor2 = CalculateSmoothingFactor(values[j]);
|
||||||
|
|
||||||
|
// Adjust both values towards the smoothed value
|
||||||
|
values[i] = values[i] + smoothingFactor1 * CurlSmoothingFactor * (smoothedValue - values[i]);
|
||||||
|
values[j] = values[j] + smoothingFactor2 * CurlSmoothingFactor * (smoothedValue - values[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = values[0];
|
||||||
|
middle = values[1];
|
||||||
|
ring = values[2];
|
||||||
|
pinky = values[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SmoothCurlsNear(ref float index, ref float middle, ref float ring, ref float pinky)
|
||||||
|
{
|
||||||
|
List<float> values = new List<float> { index, middle, ring, pinky };
|
||||||
|
|
||||||
|
for (int i = 0; i < values.Count - 1; i++)
|
||||||
|
{
|
||||||
|
if (Math.Abs(values[i] - values[i + 1]) <= CurlSimilarityThreshold)
|
||||||
|
{
|
||||||
|
// Compute new smoothed value
|
||||||
|
float smoothedValue = (values[i] + values[i + 1]) / 2;
|
||||||
|
|
||||||
|
// Calculate smoothing factors for both values
|
||||||
|
float smoothingFactor1 = CalculateSmoothingFactor(values[i]);
|
||||||
|
float smoothingFactor2 = CalculateSmoothingFactor(values[i + 1]);
|
||||||
|
|
||||||
|
// Adjust both values towards the smoothed value
|
||||||
|
values[i] = values[i] + smoothingFactor1 * CurlSmoothingFactor * (smoothedValue - values[i]);
|
||||||
|
values[i + 1] = values[i + 1] + smoothingFactor2 * CurlSmoothingFactor * (smoothedValue - values[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = values[0];
|
||||||
|
middle = values[1];
|
||||||
|
ring = values[2];
|
||||||
|
pinky = values[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the smoothing factor based on the curl value
|
||||||
|
private float CalculateSmoothingFactor(float curlValue)
|
||||||
|
{
|
||||||
|
if (!DontSmoothExtremes)
|
||||||
|
return 1f;
|
||||||
|
|
||||||
|
// Compute the distance from the center (0.5) and square it
|
||||||
|
float dist = curlValue - 0.5f;
|
||||||
|
return 1.0f - 4 * dist * dist;
|
||||||
|
}
|
||||||
|
}
|
79
EzCurls/Main.cs
Normal file
79
EzCurls/Main.cs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
using ABI_RC.Core.Savior;
|
||||||
|
using MelonLoader;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace NAK.EzCurls;
|
||||||
|
|
||||||
|
public class EzCurls : MelonMod
|
||||||
|
{
|
||||||
|
internal const string SettingsCategory = nameof(EzCurls);
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Category Category =
|
||||||
|
MelonPreferences.CreateCategory(SettingsCategory);
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<bool> EntryUseCurlSnapping =
|
||||||
|
Category.CreateEntry("UseCurlSnapping", true,
|
||||||
|
description: "Finger curl snapping to a specified value when in the specified range.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntrySnappedCurlValue =
|
||||||
|
Category.CreateEntry("SnappedCurlValue", 0.5f,
|
||||||
|
description: "The value to which the finger curl snaps within the range.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryRangeStartPercent =
|
||||||
|
Category.CreateEntry("RangeStartPercent", 0.5f,
|
||||||
|
description: "The minimum value for the SnappedCurlValue range.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryRangeEndPercent =
|
||||||
|
Category.CreateEntry("RangeEndPercent", 0.8f,
|
||||||
|
description: "The maximum value for the SnappedCurlValue range.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<bool> EntryUseCurlSmoothing =
|
||||||
|
Category.CreateEntry("UseCurlSmoothing", false,
|
||||||
|
description: "Finger curl smoothing to average out similar finger positions.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<bool> EntryDontSmoothExtremes =
|
||||||
|
Category.CreateEntry("DontSmoothExtremes", true,
|
||||||
|
description: "Should the finger curl smoothing be less effective on curls towards 0 or 1?");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryCurlSimilarityThreshold =
|
||||||
|
Category.CreateEntry("CurlSimilarityThreshold", 0.1f,
|
||||||
|
description: "The threshold for curl similarity during curl smoothing.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryCurlSmoothingFactor =
|
||||||
|
Category.CreateEntry("CurlSmoothingFactor", 0.5f,
|
||||||
|
description: "The multiplier for curl smoothing.");
|
||||||
|
|
||||||
|
public override void OnInitializeMelon()
|
||||||
|
{
|
||||||
|
HarmonyInstance.Patch(
|
||||||
|
typeof(InputModuleSteamVR).GetMethod(nameof(InputModuleSteamVR.Start)),
|
||||||
|
prefix: new HarmonyLib.HarmonyMethod(typeof(EzCurls).GetMethod(nameof(OnInputModuleSteamVRStart_Prefix), BindingFlags.NonPublic | BindingFlags.Static))
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach (MelonPreferences_Entry setting in Category.Entries)
|
||||||
|
setting.OnEntryValueChangedUntyped.Subscribe(OnSettingsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnSettingsChanged(object oldValue = null, object newValue = null)
|
||||||
|
{
|
||||||
|
if (InputModuleCurlAdjuster.Instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// curl snapping
|
||||||
|
InputModuleCurlAdjuster.Instance.UseCurlSnapping = EntryUseCurlSnapping.Value;
|
||||||
|
InputModuleCurlAdjuster.Instance.SnappedCurlValue = EntrySnappedCurlValue.Value;
|
||||||
|
InputModuleCurlAdjuster.Instance.RangeStartPercent = EntryRangeStartPercent.Value;
|
||||||
|
InputModuleCurlAdjuster.Instance.RangeEndPercent = EntryRangeEndPercent.Value;
|
||||||
|
|
||||||
|
// curl smoothing
|
||||||
|
InputModuleCurlAdjuster.Instance.UseCurlSmoothing = EntryUseCurlSmoothing.Value;
|
||||||
|
InputModuleCurlAdjuster.Instance.DontSmoothExtremes = EntryDontSmoothExtremes.Value;
|
||||||
|
InputModuleCurlAdjuster.Instance.CurlSimilarityThreshold = EntryCurlSimilarityThreshold.Value;
|
||||||
|
InputModuleCurlAdjuster.Instance.CurlSmoothingFactor = EntryCurlSmoothingFactor.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnInputModuleSteamVRStart_Prefix(ref InputModuleSteamVR __instance)
|
||||||
|
{
|
||||||
|
__instance.gameObject.AddComponent<InputModuleCurlAdjuster>();
|
||||||
|
}
|
||||||
|
}
|
29
EzCurls/Properties/AssemblyInfo.cs
Normal file
29
EzCurls/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
using MelonLoader;
|
||||||
|
using NAK.EzCurls.Properties;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||||
|
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||||
|
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||||
|
[assembly: AssemblyTitle(nameof(NAK.EzCurls))]
|
||||||
|
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||||
|
[assembly: AssemblyProduct(nameof(NAK.EzCurls))]
|
||||||
|
|
||||||
|
[assembly: MelonInfo(
|
||||||
|
typeof(NAK.EzCurls.EzCurls),
|
||||||
|
nameof(NAK.EzCurls),
|
||||||
|
AssemblyInfoParams.Version,
|
||||||
|
AssemblyInfoParams.Author,
|
||||||
|
downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzCurls"
|
||||||
|
)]
|
||||||
|
|
||||||
|
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||||
|
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
|
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
||||||
|
namespace NAK.EzCurls.Properties;
|
||||||
|
internal static class AssemblyInfoParams
|
||||||
|
{
|
||||||
|
public const string Version = "1.0.0";
|
||||||
|
public const string Author = "NotAKidoS";
|
||||||
|
}
|
14
EzCurls/README.md
Normal file
14
EzCurls/README.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# EzCurls
|
||||||
|
|
||||||
|
A mod that should hopefully make finger curls more predictable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI.
|
||||||
|
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||||
|
|
||||||
|
> This mod is an independent creation and is not affiliated with, supported by or approved by Alpha Blend Interactive.
|
||||||
|
|
||||||
|
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||||
|
|
||||||
|
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
23
EzCurls/format.json
Normal file
23
EzCurls/format.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"_id": -1,
|
||||||
|
"name": "EzCurls",
|
||||||
|
"modversion": "1.0.0",
|
||||||
|
"gameversion": "2022r170p1",
|
||||||
|
"loaderversion": "0.6.1",
|
||||||
|
"modtype": "Mod",
|
||||||
|
"author": "NotAKidoS",
|
||||||
|
"description": "A mod that should hopefully make finger curls more predictable.",
|
||||||
|
"searchtags": [
|
||||||
|
"aas",
|
||||||
|
"sync",
|
||||||
|
"naked",
|
||||||
|
"buffer"
|
||||||
|
],
|
||||||
|
"requirements": [
|
||||||
|
"UIExpansionKit"
|
||||||
|
],
|
||||||
|
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r13/EzCurls.dll",
|
||||||
|
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzCurls/",
|
||||||
|
"changelog": "- Initial CVRMG release",
|
||||||
|
"embedcolor": "7d7d7d"
|
||||||
|
}
|
|
@ -73,6 +73,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FOVAdjustment", "FOVAdjustm
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MuteSFX", "MuteSFX\MuteSFX.csproj", "{77D222FC-4AEC-4672-A87A-B860B4C39E17}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MuteSFX", "MuteSFX\MuteSFX.csproj", "{77D222FC-4AEC-4672-A87A-B860B4C39E17}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EzCurls", "EzCurls\EzCurls.csproj", "{7EF74A8D-0421-4B6D-809E-40F9C2DFC7F8}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -219,6 +221,10 @@ Global
|
||||||
{77D222FC-4AEC-4672-A87A-B860B4C39E17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{77D222FC-4AEC-4672-A87A-B860B4C39E17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{77D222FC-4AEC-4672-A87A-B860B4C39E17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{77D222FC-4AEC-4672-A87A-B860B4C39E17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{77D222FC-4AEC-4672-A87A-B860B4C39E17}.Release|Any CPU.Build.0 = Release|Any CPU
|
{77D222FC-4AEC-4672-A87A-B860B4C39E17}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7EF74A8D-0421-4B6D-809E-40F9C2DFC7F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7EF74A8D-0421-4B6D-809E-40F9C2DFC7F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7EF74A8D-0421-4B6D-809E-40F9C2DFC7F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7EF74A8D-0421-4B6D-809E-40F9C2DFC7F8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue