This commit is contained in:
NotAKidoS 2023-02-28 07:16:32 -06:00
parent cbd65aa813
commit a27d42d876
3 changed files with 113 additions and 105 deletions

View file

@ -30,7 +30,6 @@ public class DesktopVRIK : MonoBehaviour
private float private float
ik_SimulatedRootAngle; ik_SimulatedRootAngle;
private bool private bool
ms_lastGrounded,
ps_emoteIsPlaying; ps_emoteIsPlaying;
static readonly FieldInfo ms_isGrounded = typeof(MovementSystem).GetField("_isGrounded", BindingFlags.NonPublic | BindingFlags.Instance); static readonly FieldInfo ms_isGrounded = typeof(MovementSystem).GetField("_isGrounded", BindingFlags.NonPublic | BindingFlags.Instance);
@ -45,26 +44,31 @@ public class DesktopVRIK : MonoBehaviour
{ {
if (!Setting_Enabled) return; if (!Setting_Enabled) return;
Calibrator.SetupDesktopVRIK(); Calibrator.SetupDesktopVRIK();
ik_SimulatedRootAngle = transform.eulerAngles.y; ResetDesktopVRIK();
} }
//public void OnReCalibrateAvatar() public bool OnSetupIKScaling(float avatarHeight, float scaleDifference)
//{
// Calibrator.RecalibrateDesktopVRIK();
// ik_SimulatedRootAngle = transform.eulerAngles.y;
//}
public bool OnApplyAvatarScaleToIk(float height)
{ {
if (Calibrator.vrik != null) if (Calibrator.vrik != null)
{ {
Calibrator.vrik.solver.locomotion.footDistance = Calibrator.initialFootDistance * height; Calibrator.vrik.solver.locomotion.footDistance = Calibrator.initialFootDistance * scaleDifference;
Calibrator.vrik.solver.locomotion.stepThreshold = Calibrator.initialStepThreshold * height; Calibrator.vrik.solver.locomotion.stepThreshold = Calibrator.initialStepThreshold * scaleDifference;
DesktopVRIK.ScaleStepHeight(Calibrator.vrik.solver.locomotion.stepHeight, Calibrator.initialStepHeight * scaleDifference);
Calibrator.vrik.solver.Reset();
ResetDesktopVRIK();
return true; return true;
} }
return false; return false;
} }
public static void ScaleStepHeight(AnimationCurve stepHeightCurve, float mag)
{
Keyframe[] keyframes = stepHeightCurve.keys;
keyframes[1].value = mag;
stepHeightCurve.keys = keyframes;
}
public void OnPlayerSetupUpdate(bool isEmotePlaying) public void OnPlayerSetupUpdate(bool isEmotePlaying)
{ {
bool changed = isEmotePlaying != ps_emoteIsPlaying; bool changed = isEmotePlaying != ps_emoteIsPlaying;
@ -79,12 +83,21 @@ public class DesktopVRIK : MonoBehaviour
} }
BodySystem.TrackingEnabled = !isEmotePlaying; BodySystem.TrackingEnabled = !isEmotePlaying;
Calibrator.vrik.solver?.Reset(); Calibrator.vrik.solver?.Reset();
ResetDesktopVRIK();
} }
} }
public void ResetDesktopVRIK()
{
ik_SimulatedRootAngle = transform.eulerAngles.y;
}
public void OnPreSolverUpdate() public void OnPreSolverUpdate()
{ {
if (ps_emoteIsPlaying) return; if (ps_emoteIsPlaying)
{
return;
}
bool isGrounded = (bool)ms_isGrounded.GetValue(MovementSystem.Instance); bool isGrounded = (bool)ms_isGrounded.GetValue(MovementSystem.Instance);
@ -103,16 +116,6 @@ public class DesktopVRIK : MonoBehaviour
// This is nice for walk cycles // This is nice for walk cycles
//Calibrator.vrik.solver.spine.rotateChestByHands = Setting_RotateChestByHands * weight; //Calibrator.vrik.solver.spine.rotateChestByHands = Setting_RotateChestByHands * weight;
//reset solver if weight changes dramatically
if (Setting_ResetOnLand)
{
if (isGrounded && !ms_lastGrounded)
{
Calibrator.vrik.solver.Reset();
}
ms_lastGrounded = isGrounded;
}
// Old VRChat hip movement emulation // Old VRChat hip movement emulation
if (Setting_BodyLeanWeight > 0) if (Setting_BodyLeanWeight > 0)
{ {

View file

@ -40,35 +40,23 @@ public class DesktopVRIKCalibrator
public Transform avatarTransform; public Transform avatarTransform;
public VRIK vrik; public VRIK vrik;
public LookAtIK lookAtIK; public LookAtIK lookAtIK;
// Calibration
public HumanPoseHandler humanPoseHandler; public HumanPoseHandler humanPoseHandler;
public HumanPose initialHumanPose; public HumanPose initialHumanPose;
// Calibrator
public bool fixTransformsRequired; public bool fixTransformsRequired;
public float initialFootDistance; public float initialFootDistance, initialStepThreshold, initialStepHeight;
public float initialStepThreshold;
// Traverse // Traverse
private IKSystem ikSystem; private IKSystem ikSystem;
private PlayerSetup playerSetup; private PlayerSetup playerSetup;
private Traverse _vrikTraverse; private Traverse
private Traverse _lookIKTraverse; _vrikTraverse,
private Traverse _avatarTraverse; _lookIKTraverse,
private Traverse _animatorManagerTraverse; _avatarTraverse,
private Traverse _poseHandlerTraverse; _animatorManagerTraverse,
private Traverse _avatarRootHeightTraverse; _poseHandlerTraverse,
_avatarRootHeightTraverse;
//public void RecalibrateDesktopVRIK()
//{
// if (avatar != null)
// {
// //calibrate VRIK
// CalibrateDesktopVRIK();
// }
// else
// {
// //we never calibrated
// SetupDesktopVRIK();
// }
//}
public void SetupDesktopVRIK() public void SetupDesktopVRIK()
{ {
@ -92,9 +80,9 @@ public class DesktopVRIKCalibrator
//calibrate VRIK //calibrate VRIK
PrepareAvatarVRIK(); PrepareAvatarVRIK();
SetAvatarIKPose(true); SetAvatarIKPose(true);
CalculateInitialIKScaling();
CalibrateHeadIK(); CalibrateHeadIK();
ForceInitiateVRIKSolver(); ForceInitiateVRIKSolver();
CalculateInitialIKScaling();
SetAvatarIKPose(false); SetAvatarIKPose(false);
} }
@ -220,18 +208,19 @@ public class DesktopVRIKCalibrator
private void CalculateInitialIKScaling() private void CalculateInitialIKScaling()
{ {
// Get distance between feets and thighs (fixes some weird armatures) // Get distance between feets and thighs
float footDistance = Vector3.Distance(vrik.references.leftFoot.position, vrik.references.rightFoot.position); float footDistance = Vector3.Distance(vrik.references.leftFoot.position, vrik.references.rightFoot.position);
float thighDistance = Vector3.Distance(vrik.references.leftThigh.position, vrik.references.rightThigh.position); initialFootDistance = footDistance * 0.5f;
float greatestDistance = Mathf.Min(footDistance, thighDistance); initialStepThreshold = footDistance * 0.4f;
initialFootDistance = greatestDistance * 0.5f; initialStepHeight = Vector3.Distance(vrik.references.leftFoot.position, vrik.references.leftCalf.position) * 0.2f;
initialStepThreshold = greatestDistance * 0.4f;
//set initial values now, as avatars without scaling dont apply it // Set initial values
vrik.solver.locomotion.footDistance = initialFootDistance; vrik.solver.locomotion.footDistance = initialFootDistance;
vrik.solver.locomotion.stepThreshold = initialStepThreshold; vrik.solver.locomotion.stepThreshold = initialStepThreshold;
DesktopVRIK.ScaleStepHeight(vrik.solver.locomotion.stepHeight, initialStepHeight);
} }
private void CalibrateHeadIK() private void CalibrateHeadIK()
{ {
// Lazy HeadIKTarget calibration // Lazy HeadIKTarget calibration
@ -262,12 +251,7 @@ public class DesktopVRIKCalibrator
if (enforceTPose) if (enforceTPose)
{ {
humanPoseHandler.GetHumanPose(ref initialHumanPose); humanPoseHandler.GetHumanPose(ref initialHumanPose);
humanPoseHandler.GetHumanPose(ref ikSystem.humanPose); SetCustomPose(IKPoseMuscles);
for (int i = 0; i < IKPoseMuscles.Length; i++)
{
IKSystem.Instance.ApplyMuscleValue((MuscleIndex)i, IKPoseMuscles[i], ref ikSystem.humanPose.muscles);
}
humanPoseHandler.SetHumanPose(ref ikSystem.humanPose);
} }
else else
{ {
@ -275,6 +259,16 @@ public class DesktopVRIKCalibrator
} }
} }
private void SetCustomPose(float[] muscleValues)
{
humanPoseHandler.GetHumanPose(ref ikSystem.humanPose);
for (int i = 0; i < muscleValues.Length; i++)
{
IKSystem.Instance.ApplyMuscleValue((MuscleIndex)i, muscleValues[i], ref ikSystem.humanPose.muscles);
}
humanPoseHandler.SetHumanPose(ref ikSystem.humanPose);
}
private void ForceInitiateVRIKSolver() private void ForceInitiateVRIKSolver()
{ {
//force immediate calibration before animator decides to fuck us //force immediate calibration before animator decides to fuck us
@ -286,17 +280,8 @@ public class DesktopVRIKCalibrator
{ {
fixTransformsRequired = false; fixTransformsRequired = false;
Transform leftShoulderBone = vrik.references.leftShoulder; //might not work over netik
Transform rightShoulderBone = vrik.references.rightShoulder; FixChestAndSpineReferences();
Transform assumedChest = leftShoulderBone?.parent;
// Repair chest & spine bone references (valve models were messed up)
if (assumedChest != null && rightShoulderBone.parent == assumedChest &&
vrik.references.chest != assumedChest)
{
vrik.references.chest = assumedChest;
vrik.references.spine = assumedChest.parent;
}
if (!Setting_UseVRIKToes) if (!Setting_UseVRIKToes)
{ {
@ -304,36 +289,48 @@ public class DesktopVRIKCalibrator
vrik.references.rightToes = null; vrik.references.rightToes = null;
} }
else if (Setting_FindUnmappedToes) else if (Setting_FindUnmappedToes)
{
//doesnt work with netik, but its toes...
FindAndSetUnmappedToes();
}
//bullshit fix to not cause death
FixFingerBonesError();
}
private void FixChestAndSpineReferences()
{
Transform leftShoulderBone = vrik.references.leftShoulder;
Transform rightShoulderBone = vrik.references.rightShoulder;
Transform assumedChest = leftShoulderBone?.parent;
if (assumedChest != null && rightShoulderBone.parent == assumedChest &&
vrik.references.chest != assumedChest)
{
vrik.references.chest = assumedChest;
vrik.references.spine = assumedChest.parent;
}
}
private void FindAndSetUnmappedToes()
{ {
Transform leftToes = vrik.references.leftToes; Transform leftToes = vrik.references.leftToes;
Transform rightToes = vrik.references.rightToes; Transform rightToes = vrik.references.rightToes;
if (leftToes == null && rightToes == null) if (leftToes == null && rightToes == null)
{ {
leftToes = FindUnmappedToe(vrik.references.leftFoot); leftToes = FindUnmappedToe(vrik.references.leftFoot);
rightToes = FindUnmappedToe(vrik.references.rightFoot); rightToes = FindUnmappedToe(vrik.references.rightFoot);
if (leftToes != null && rightToes != null) if (leftToes != null && rightToes != null)
{ {
fixTransformsRequired = true;
vrik.references.leftToes = leftToes; vrik.references.leftToes = leftToes;
vrik.references.rightToes = rightToes; vrik.references.rightToes = rightToes;
fixTransformsRequired = true;
} }
} }
} }
// Fix error when there is no finger bones
// Making up bullshit cause VRIK is evil otherwise
if (vrik.references.leftHand.childCount == 0)
{
vrik.solver.leftArm.wristToPalmAxis = Vector3.up;
vrik.solver.leftArm.palmToThumbAxis = -Vector3.forward;
}
if (vrik.references.rightHand.childCount == 0)
{
vrik.solver.rightArm.wristToPalmAxis = Vector3.up;
vrik.solver.rightArm.palmToThumbAxis = Vector3.forward;
}
}
private Transform FindUnmappedToe(Transform foot) private Transform FindUnmappedToe(Transform foot)
{ {
foreach (Transform bone in foot) foreach (Transform bone in foot)
@ -348,6 +345,21 @@ public class DesktopVRIKCalibrator
return null; return null;
} }
private void FixFingerBonesError()
{
FixFingerBones(vrik.references.leftHand, vrik.solver.leftArm);
FixFingerBones(vrik.references.rightHand, vrik.solver.rightArm);
}
private void FixFingerBones(Transform hand, IKSolverVR.Arm armSolver)
{
if (hand.childCount == 0)
{
armSolver.wristToPalmAxis = Vector3.up;
armSolver.palmToThumbAxis = hand == vrik.references.leftHand ? -Vector3.forward : Vector3.forward;
}
}
private static readonly float[] IKPoseMuscles = new float[] private static readonly float[] IKPoseMuscles = new float[]
{ {
0.00133321f, 0.00133321f,

View file

@ -40,12 +40,12 @@ class PlayerSetupPatches
DesktopVRIK.Instance?.OnPlayerSetupUpdate(____emotePlaying); DesktopVRIK.Instance?.OnPlayerSetupUpdate(____emotePlaying);
} }
//[HarmonyPostfix] [HarmonyPrefix]
//[HarmonyPatch(typeof(PlayerSetup), "ReCalibrateAvatar")] [HarmonyPatch(typeof(PlayerSetup), "SetupIKScaling")]
//static void Postfix_PlayerSetup_ReCalibrateAvatar() private static bool Prefix_PlayerSetup_SetupIKScaling(float height, ref Vector3 ___scaleDifference)
//{ {
// DesktopVRIK.Instance?.OnReCalibrateAvatar(); return !(bool)DesktopVRIK.Instance?.OnSetupIKScaling(height, 1f + ___scaleDifference.y);
//} }
} }
class IKSystemPatches class IKSystemPatches
@ -56,11 +56,4 @@ class IKSystemPatches
{ {
__instance.gameObject.AddComponent<DesktopVRIK>(); __instance.gameObject.AddComponent<DesktopVRIK>();
} }
[HarmonyPrefix]
[HarmonyPatch(typeof(IKSystem), "ApplyAvatarScaleToIk")]
private static bool Prefix_IKSystem_ApplyAvatarScaleToIk(float height)
{
return !(bool)DesktopVRIK.Instance?.OnApplyAvatarScaleToIk(height);
}
} }