mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 14:29:25 +00:00
[EzCurls] Cleanup before CVRMG
This commit is contained in:
parent
a92e478eb9
commit
7e1445912d
7 changed files with 366 additions and 306 deletions
|
@ -1,2 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk"/>
|
||||
<Project Sdk="Microsoft.NET.Sdk" />
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
using ABI_RC.Systems.InputManagement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.EzCurls;
|
||||
|
||||
internal class InputModuleCurlAdjuster : CVRInputModule
|
||||
{
|
||||
public static InputModuleCurlAdjuster Instance;
|
||||
|
||||
// Curl clamping/adjustment
|
||||
public bool UseCurlSnapping = false;
|
||||
public float SnappedCurlValue = 0.4f;
|
||||
public float RangeStartPercent = 0.25f;
|
||||
public float RangeEndPercent = 0.5f;
|
||||
|
||||
// Curl smoothing/averaging
|
||||
public bool UseCurlSmoothing = true;
|
||||
public bool DontSmoothExtremes = true;
|
||||
public bool OnlySmoothNearbyCurl = false;
|
||||
public float CurlSimilarityThreshold = 0.5f;
|
||||
public float CurlSmoothingFactor = 0.4f;
|
||||
|
||||
// Curve control
|
||||
public bool UseCurveControl = false;
|
||||
public AnimationCurve DensityCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0));
|
||||
|
||||
// Tuned Curve control
|
||||
public bool UseTunedCurveControl = false;
|
||||
private readonly AnimationCurve TunedDensityCurve = new AnimationCurve(
|
||||
new Keyframe(0, 0), // Start at (0, 0)
|
||||
new Keyframe(0.5f, 0.5f), // Normal behavior up to (0.3, 0.3)
|
||||
new Keyframe(0.85f, 0.6f), // Only 0.1f movement from 0.5 to 0.9
|
||||
new Keyframe(1, 1) // Normal behavior from 0.9 to 1
|
||||
);
|
||||
|
||||
public override void ModuleAdded()
|
||||
{
|
||||
Instance = this;
|
||||
base.ModuleAdded();
|
||||
EzCurls.OnSettingsChanged();
|
||||
}
|
||||
|
||||
public override void UpdateInput() => DoCurlAdjustments();
|
||||
|
||||
private void DoCurlAdjustments()
|
||||
{
|
||||
if (!_inputManager.individualFingerTracking)
|
||||
return;
|
||||
|
||||
if (UseCurlSmoothing)
|
||||
{
|
||||
if (OnlySmoothNearbyCurl)
|
||||
{
|
||||
SmoothCurlsNear(
|
||||
ref _inputManager.fingerCurlLeftIndex,
|
||||
ref _inputManager.fingerCurlLeftMiddle,
|
||||
ref _inputManager.fingerCurlLeftRing,
|
||||
ref _inputManager.fingerCurlLeftPinky
|
||||
);
|
||||
|
||||
SmoothCurlsNear(
|
||||
ref _inputManager.fingerCurlRightIndex,
|
||||
ref _inputManager.fingerCurlRightMiddle,
|
||||
ref _inputManager.fingerCurlRightRing,
|
||||
ref _inputManager.fingerCurlRightPinky
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
if (UseCurveControl)
|
||||
{
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftIndex);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftMiddle);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftRing);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftPinky);
|
||||
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightIndex);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightMiddle);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightRing);
|
||||
AdjustCurlUsingCurve(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;
|
||||
}
|
||||
|
||||
// middle of curve is more "dense"
|
||||
private void AdjustCurlUsingCurve(ref float fingerCurl)
|
||||
{
|
||||
if (UseTunedCurveControl)
|
||||
{
|
||||
fingerCurl = TunedDensityCurve.Evaluate(fingerCurl);
|
||||
return;
|
||||
}
|
||||
fingerCurl = DensityCurve.Evaluate(fingerCurl);
|
||||
}
|
||||
}
|
236
EzCurls/InputModules/InputModuleCurlAdjuster.cs
Normal file
236
EzCurls/InputModules/InputModuleCurlAdjuster.cs
Normal file
|
@ -0,0 +1,236 @@
|
|||
using ABI_RC.Systems.InputManagement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.EzCurls;
|
||||
|
||||
internal class InputModuleCurlAdjuster : CVRInputModule
|
||||
{
|
||||
public static InputModuleCurlAdjuster Instance { get; private set; }
|
||||
|
||||
#region Variables
|
||||
|
||||
public bool enabled = false;
|
||||
|
||||
// Curl clamping/adjustment
|
||||
public bool UseCurlSnapping = false;
|
||||
public float SnappedCurlValue = 0.4f;
|
||||
public float RangeStartPercent = 0.25f;
|
||||
public float RangeEndPercent = 0.5f;
|
||||
|
||||
// Curl smoothing/averaging
|
||||
public bool UseCurlSmoothing = true;
|
||||
public bool DontSmoothExtremes = true;
|
||||
public bool OnlySmoothNearbyCurl = false;
|
||||
public float CurlSimilarityThreshold = 0.5f;
|
||||
public float CurlSmoothingFactor = 0.4f;
|
||||
|
||||
// Curve control
|
||||
public bool UseCurveControl = false;
|
||||
public AnimationCurve DensityCurve = new(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0));
|
||||
|
||||
// Tuned Curve control
|
||||
public bool UseTunedCurveControl = false;
|
||||
|
||||
private readonly AnimationCurve TunedDensityCurve = new(
|
||||
new Keyframe(0, 0), // Start at (0, 0)
|
||||
new Keyframe(0.5f, 0.5f), // Normal behavior up to (0.3, 0.3)
|
||||
new Keyframe(0.85f, 0.6f), // Only 0.1f movement from 0.5 to 0.9
|
||||
new Keyframe(1, 1) // Normal behavior from 0.9 to 1
|
||||
);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
public override void ModuleAdded()
|
||||
{
|
||||
if (Instance != null
|
||||
&& Instance != this)
|
||||
return;
|
||||
|
||||
Instance = this;
|
||||
|
||||
base.ModuleAdded();
|
||||
ModSettings.OnSettingsChanged();
|
||||
}
|
||||
|
||||
public override void UpdateInput()
|
||||
=> DoCurlAdjustments();
|
||||
|
||||
#endregion
|
||||
|
||||
private void DoCurlAdjustments()
|
||||
{
|
||||
if (!enabled
|
||||
|| !_inputManager.individualFingerTracking)
|
||||
return;
|
||||
|
||||
DoCurlSmoothing();
|
||||
DoCurlSnapping();
|
||||
DoCurlCurveControl();
|
||||
}
|
||||
|
||||
#region Smooth Curls
|
||||
|
||||
private void DoCurlSmoothing()
|
||||
{
|
||||
if (!UseCurlSmoothing)
|
||||
return;
|
||||
|
||||
if (OnlySmoothNearbyCurl)
|
||||
{
|
||||
SmoothCurlsNear(
|
||||
ref _inputManager.fingerCurlLeftIndex,
|
||||
ref _inputManager.fingerCurlLeftMiddle,
|
||||
ref _inputManager.fingerCurlLeftRing,
|
||||
ref _inputManager.fingerCurlLeftPinky
|
||||
);
|
||||
|
||||
SmoothCurlsNear(
|
||||
ref _inputManager.fingerCurlRightIndex,
|
||||
ref _inputManager.fingerCurlRightMiddle,
|
||||
ref _inputManager.fingerCurlRightRing,
|
||||
ref _inputManager.fingerCurlRightPinky
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void SmoothCurls(ref float index, ref float middle, ref float ring, ref float pinky)
|
||||
{
|
||||
var values = new List<float> { index, middle, ring, pinky };
|
||||
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
for (var j = i + 1; j < values.Count; j++)
|
||||
if (Math.Abs(values[i] - values[j]) <= CurlSimilarityThreshold)
|
||||
{
|
||||
// Compute new smoothed values
|
||||
var smoothedValue = (values[i] + values[j]) / 2;
|
||||
|
||||
// Calculate smoothing factors for both values
|
||||
var smoothingFactor1 = CalculateSmoothingFactor(values[i]);
|
||||
var 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)
|
||||
{
|
||||
var values = new List<float> { index, middle, ring, pinky };
|
||||
|
||||
for (var i = 0; i < values.Count - 1; i++)
|
||||
if (Math.Abs(values[i] - values[i + 1]) <= CurlSimilarityThreshold)
|
||||
{
|
||||
// Compute new smoothed value
|
||||
var smoothedValue = (values[i] + values[i + 1]) / 2;
|
||||
|
||||
// Calculate smoothing factors for both values
|
||||
var smoothingFactor1 = CalculateSmoothingFactor(values[i]);
|
||||
var 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
|
||||
var dist = curlValue - 0.5f;
|
||||
return 1.0f - 4 * dist * dist;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Snap Curls
|
||||
|
||||
private void DoCurlSnapping()
|
||||
{
|
||||
if (!UseCurlSnapping)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Curve Curls
|
||||
|
||||
private void DoCurlCurveControl()
|
||||
{
|
||||
if (!UseCurveControl)
|
||||
return;
|
||||
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftIndex);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftMiddle);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftRing);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftPinky);
|
||||
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightIndex);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightMiddle);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightRing);
|
||||
AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightPinky);
|
||||
}
|
||||
|
||||
// middle of curve is more "dense"
|
||||
private void AdjustCurlUsingCurve(ref float fingerCurl)
|
||||
{
|
||||
if (UseTunedCurveControl)
|
||||
{
|
||||
fingerCurl = TunedDensityCurve.Evaluate(fingerCurl);
|
||||
return;
|
||||
}
|
||||
|
||||
fingerCurl = DensityCurve.Evaluate(fingerCurl);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
102
EzCurls/Main.cs
102
EzCurls/Main.cs
|
@ -1,77 +1,12 @@
|
|||
using ABI_RC.Core.Savior;
|
||||
using MelonLoader;
|
||||
using MelonLoader;
|
||||
using System.Reflection;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using ABI_RC.Systems.InputManagement.InputModules;
|
||||
using UnityEngine;
|
||||
|
||||
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> EntryOnlySmoothNearbyCurl =
|
||||
Category.CreateEntry("OnlySmoothNearbyCurl", false,
|
||||
description: "Should the curl smoothing only influence the nearest curl?");
|
||||
|
||||
|
||||
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.");
|
||||
|
||||
// Curve control settings
|
||||
public static readonly MelonPreferences_Entry<bool> EntryUseCurveControl =
|
||||
Category.CreateEntry("UseCurveControl", false,
|
||||
description: "Enable curve control mode to make the midrange of the curl more dense.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> EntryUseTunedCurveControl =
|
||||
Category.CreateEntry("UseTunedCurveControl", false,
|
||||
description: "Enables a pre-tuned curve.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryCurveMin =
|
||||
Category.CreateEntry("CurveMin", 0.0f,
|
||||
description: "The minimum value of the density curve.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryCurveMiddle =
|
||||
Category.CreateEntry("CurveMiddle", 0.5f,
|
||||
description: "The middle value of the density curve.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryCurveMax =
|
||||
Category.CreateEntry("CurveMax", 1.0f,
|
||||
description: "The maximum value of the density curve.");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
HarmonyInstance.Patch(
|
||||
|
@ -79,40 +14,9 @@ public class EzCurls : MelonMod
|
|||
postfix: new HarmonyLib.HarmonyMethod(typeof(EzCurls).GetMethod(nameof(OnCVRInputModule_XRModuleAdded_Postfix), 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.OnlySmoothNearbyCurl = EntryOnlySmoothNearbyCurl.Value;
|
||||
InputModuleCurlAdjuster.Instance.DontSmoothExtremes = EntryDontSmoothExtremes.Value;
|
||||
InputModuleCurlAdjuster.Instance.CurlSimilarityThreshold = EntryCurlSimilarityThreshold.Value;
|
||||
InputModuleCurlAdjuster.Instance.CurlSmoothingFactor = EntryCurlSmoothingFactor.Value;
|
||||
|
||||
// curve control
|
||||
InputModuleCurlAdjuster.Instance.UseCurveControl = EntryUseCurveControl.Value;
|
||||
InputModuleCurlAdjuster.Instance.UseTunedCurveControl = EntryUseTunedCurveControl.Value;
|
||||
InputModuleCurlAdjuster.Instance.DensityCurve = new AnimationCurve(
|
||||
new Keyframe(0, EntryCurveMin.Value),
|
||||
new Keyframe(0.5f, EntryCurveMiddle.Value),
|
||||
new Keyframe(1, EntryCurveMax.Value)
|
||||
);
|
||||
ModSettings.Initialize();
|
||||
}
|
||||
|
||||
private static void OnCVRInputModule_XRModuleAdded_Postfix()
|
||||
{
|
||||
CVRInputManager.Instance.AddInputModule(new InputModuleCurlAdjuster());
|
||||
}
|
||||
=> CVRInputManager.Instance.AddInputModule(new InputModuleCurlAdjuster());
|
||||
}
|
116
EzCurls/ModSettings.cs
Normal file
116
EzCurls/ModSettings.cs
Normal file
|
@ -0,0 +1,116 @@
|
|||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.EzCurls;
|
||||
|
||||
public static class ModSettings
|
||||
{
|
||||
#region Melon Prefs
|
||||
|
||||
private const string SettingsCategory = nameof(EzCurls);
|
||||
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(SettingsCategory);
|
||||
|
||||
// Tuned to the values Liquid uses, sign language nerd
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryEnabled =
|
||||
Category.CreateEntry("Enabled", true,
|
||||
description: "Enable EzCurls.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryUseCurlSnapping =
|
||||
Category.CreateEntry("UseCurlSnapping", true,
|
||||
description: "Finger curl snapping to a specified value when in the specified range.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntrySnappedCurlValue =
|
||||
Category.CreateEntry("SnappedCurlValue", 0.4f,
|
||||
description: "The value to which the finger curl snaps within the range.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryRangeStartPercent =
|
||||
Category.CreateEntry("RangeStartPercent", 0.25f,
|
||||
description: "The minimum value for the SnappedCurlValue range.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryRangeEndPercent =
|
||||
Category.CreateEntry("RangeEndPercent", 0.5f,
|
||||
description: "The maximum value for the SnappedCurlValue range.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryUseCurlSmoothing =
|
||||
Category.CreateEntry("UseCurlSmoothing", true,
|
||||
description: "Finger curl smoothing to average out similar finger positions.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryOnlySmoothNearbyCurl =
|
||||
Category.CreateEntry("OnlySmoothNearbyCurl", false,
|
||||
description: "Should the curl smoothing only influence the nearest curl?");
|
||||
|
||||
private 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?");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryCurlSimilarityThreshold =
|
||||
Category.CreateEntry("CurlSimilarityThreshold", 0.5f,
|
||||
description: "The threshold for curl similarity during curl smoothing.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryCurlSmoothingFactor =
|
||||
Category.CreateEntry("CurlSmoothingFactor", 0.4f,
|
||||
description: "The multiplier for curl smoothing.");
|
||||
|
||||
// Curve control settings
|
||||
private static readonly MelonPreferences_Entry<bool> EntryUseCurveControl =
|
||||
Category.CreateEntry("UseCurveControl", true,
|
||||
description: "Enable curve control mode to make the midrange of the curl more dense.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryUseTunedCurveControl =
|
||||
Category.CreateEntry("UseTunedCurveControl", true,
|
||||
description: "Enables a pre-tuned curve.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryCurveMin =
|
||||
Category.CreateEntry("CurveMin", 0.0f,
|
||||
description: "The minimum value of the density curve.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryCurveMiddle =
|
||||
Category.CreateEntry("CurveMiddle", 0.5f,
|
||||
description: "The middle value of the density curve.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryCurveMax =
|
||||
Category.CreateEntry("CurveMax", 1.0f,
|
||||
description: "The maximum value of the density curve.");
|
||||
|
||||
#endregion
|
||||
|
||||
internal static void Initialize()
|
||||
{
|
||||
foreach (MelonPreferences_Entry setting in Category.Entries)
|
||||
setting.OnEntryValueChangedUntyped.Subscribe(OnSettingsChanged);
|
||||
}
|
||||
|
||||
internal static void OnSettingsChanged(object oldValue = null, object newValue = null)
|
||||
{
|
||||
if (InputModuleCurlAdjuster.Instance == null)
|
||||
return;
|
||||
|
||||
// enabled
|
||||
InputModuleCurlAdjuster.Instance.enabled = EntryEnabled.Value;
|
||||
|
||||
// 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.OnlySmoothNearbyCurl = EntryOnlySmoothNearbyCurl.Value;
|
||||
InputModuleCurlAdjuster.Instance.DontSmoothExtremes = EntryDontSmoothExtremes.Value;
|
||||
InputModuleCurlAdjuster.Instance.CurlSimilarityThreshold = EntryCurlSimilarityThreshold.Value;
|
||||
InputModuleCurlAdjuster.Instance.CurlSmoothingFactor = EntryCurlSmoothingFactor.Value;
|
||||
|
||||
// curve control
|
||||
InputModuleCurlAdjuster.Instance.UseCurveControl = EntryUseCurveControl.Value;
|
||||
InputModuleCurlAdjuster.Instance.UseTunedCurveControl = EntryUseTunedCurveControl.Value;
|
||||
InputModuleCurlAdjuster.Instance.DensityCurve = new AnimationCurve(
|
||||
new Keyframe(0, EntryCurveMin.Value),
|
||||
new Keyframe(0.5f, EntryCurveMiddle.Value),
|
||||
new Keyframe(1, EntryCurveMax.Value)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
# EzCurls
|
||||
|
||||
A mod that should hopefully make finger curls more predictable.
|
||||
A mod that allows you to tune your finger curls to your liking. Supposedly can help with VR sign language, as raw finger curls are not that great for quick and precise gestures.
|
||||
|
||||
The settings are not too coherent, it is mostly a bunch of things thrown at the wall, but it works for me. I hope it works for you too.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
"_id": -1,
|
||||
"name": "EzCurls",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2022r170p1",
|
||||
"gameversion": "2023r173",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "A mod that should hopefully make finger curls more predictable.",
|
||||
"description": "A mod that allows you to tune your finger curls to your liking. Supposedly can help with VR sign language, as raw finger curls are not that great for quick and precise gestures.\n\nThe settings are not too coherent, it is mostly a bunch of things thrown at the wall, but it works for me. I hope it works for you too.",
|
||||
"searchtags": [
|
||||
"aas",
|
||||
"sync",
|
||||
"naked",
|
||||
"buffer"
|
||||
"curls",
|
||||
"fingers",
|
||||
"index",
|
||||
"knuckles"
|
||||
],
|
||||
"requirements": [
|
||||
"UIExpansionKit"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r13/EzCurls.dll",
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r24/EzCurls.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzCurls/",
|
||||
"changelog": "- Initial CVRMG release",
|
||||
"embedcolor": "7d7d7d"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue