Skip to content

Commit

Permalink
Added IK throttling
Browse files Browse the repository at this point in the history
Added dictionary for IK to be able to throttle IK updates, currently used to cut the update rate in half and falloff update rate based on distance.

Co-Authored-By: LeCloutPanda <53411604+lecloutpanda@users.noreply.github.com>
  • Loading branch information
Raidriar796 and LeCloutPanda committed Oct 22, 2023
1 parent d4b9abf commit 72a1a7b
Showing 1 changed file with 113 additions and 6 deletions.
119 changes: 113 additions & 6 deletions IKCulling/ResoniteIKCulling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@

namespace IkCulling
{
public class Variables
{
public int UpdateIndex = 1;
}

public class IkCulling : ResoniteMod
{
public static ModConfiguration Config;
Expand Down Expand Up @@ -38,9 +43,22 @@ public class IkCulling : ResoniteMod
() => false);

[AutoRegisterConfigKey] public static readonly ModConfigurationKey<bool> UseOtherUserScale =
new ModConfigurationKey<bool>("UseOtherUserScale",
new ModConfigurationKey<bool>(
"UseOtherUserScale",
"Use other user's scale for distance checks.",
() => false);

[AutoRegisterConfigKey] public static readonly ModConfigurationKey<bool> IkUpdateFalloff =
new ModConfigurationKey<bool>(
"IkUpdateFalloff",
"Reduce IK updates as they approach maximum range.",
() => false);

[AutoRegisterConfigKey] public static readonly ModConfigurationKey<bool> HalfRateIkUpdates =
new ModConfigurationKey<bool>(
"HalfRateIkUpdates",
"Cut IK updates in half.",
() => false);

[Range(0f, 360f)]
[AutoRegisterConfigKey] public static readonly ModConfigurationKey<float> FOV =
Expand Down Expand Up @@ -69,7 +87,7 @@ public class IkCulling : ResoniteMod

public override string Name => "ResoniteIkCulling";
public override string Author => "Raidriar796 & KyuubiYoru";
public override string Version => "2.2.1";
public override string Version => "2.3.0";
public override string Link => "https://github.com/Raidriar796/ResoniteIkCulling";

public override void OnEngineInit()
Expand All @@ -94,6 +112,22 @@ public override void OnEngineInit()
public static float Sqr(float num) {
return (num * num);
}

static Dictionary<VRIKAvatar, Variables> vrikList = new Dictionary<VRIKAvatar, Variables>();

[HarmonyPatch("OnAwake")]
[HarmonyPostfix]
private static void AddToList(VRIKAvatar __instance)
{
if (!vrikList.ContainsKey(__instance)) {
vrikList.Add(__instance, new Variables());
}

foreach (var item in vrikList)
{
if (item.Key == null) vrikList.Remove(item.Key);
}
}

[HarmonyPatch(typeof(VRIKAvatar))]
public class IkCullingPatch
Expand All @@ -116,6 +150,9 @@ private static bool OnCommonUpdatePrefix(VRIKAvatar __instance)

//Ik is disabled
if (!__instance.Enabled) return false;

//Too few users
if (__instance.Slot.World.ActiveUserCount < Config.GetValue(MinUserCount)) return true;

//Users not present
if (__instance.Slot.ActiveUser != null && Config.GetValue(DisableAfkUser) &&
Expand All @@ -124,9 +161,6 @@ private static bool OnCommonUpdatePrefix(VRIKAvatar __instance)
//No active user
if (Config.GetValue(DisableIkWithoutUser) && !__instance.IsEquipped) return false;

//Too few users
if (__instance.Slot.World.ActiveUserCount < Config.GetValue(MinUserCount)) return true;


float3 playerPos = __instance.Slot.World.LocalUserViewPosition;
float3 ikPos = __instance.HeadProxy.GlobalPosition;
Expand All @@ -151,6 +185,78 @@ private static bool OnCommonUpdatePrefix(VRIKAvatar __instance)
MathX.Cos(0.01745329 * (Config.GetValue(FOV) * 0.5f)))
return false;

if ((Config.GetValue(IkUpdateFalloff) || Config.GetValue(HalfRateIkUpdates)) && __instance.Slot.ActiveUser != __instance.LocalUser) {

// If not part part of list we add it
if (!vrikList.ContainsKey(__instance))
{
vrikList.Add(__instance, new Variables());
return true;
}

int skipCount = 1;
Variables current = vrikList[__instance];

if (Config.GetValue(IkUpdateFalloff) && !Config.GetValue(HalfRateIkUpdates)) {
if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.9f))
{
skipCount = 6;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.8f))
{
skipCount = 5;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.7f))
{
skipCount = 4;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.6f))
{
skipCount = 3;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.5f))
{
skipCount = 2;
}
}
else if (Config.GetValue(IkUpdateFalloff) && Config.GetValue(HalfRateIkUpdates)) {
skipCount = 2;

if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.9f))
{
skipCount = 12;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.8f))
{
skipCount = 10;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.7f))
{
skipCount = 8;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.6f))
{
skipCount = 6;
}
else if (dist > Sqr(Config.GetValue(MaxViewRange) * 0.5f))
{
skipCount = 4;
}
}
else if (!Config.GetValue(IkUpdateFalloff) && Config.GetValue(HalfRateIkUpdates)) skipCount = 2;

if (vrikList[__instance].UpdateIndex > skipCount) vrikList[__instance].UpdateIndex = 1;
if (vrikList[__instance].UpdateIndex == skipCount)
{
vrikList[__instance].UpdateIndex = 1;
return true;
}
else
{
vrikList[__instance].UpdateIndex += 1;
return false;
}
}
return true;
}
catch (Exception e)
Expand All @@ -171,7 +277,6 @@ public static void CalibratorForceIkAutoUpdate(FullBodyCalibrator __instance) {
}
}


//Forces IK to be active when FBT calibrator is created
[HarmonyPatch(typeof(FullBodyCalibrator), "OnAwake")]
class FullBodyCalibratorPatch {
Expand All @@ -194,5 +299,7 @@ static void Postfix(FullBodyCalibrator __instance) {
}

}


}
}

0 comments on commit 72a1a7b

Please sign in to comment.