NAK_CVR_Mods/.Deprecated/AlternateIKSystem/IK/VRIKHelpers/VRIKUtils.cs

62 lines
No EOL
3 KiB
C#

using RootMotion.FinalIK;
using UnityEngine;
namespace NAK.AlternateIKSystem.VRIKHelpers;
public static class VRIKUtils
{
public static void CalculateInitialIKScaling(VRIK vrik, ref VRIKLocomotionData locomotionData)
{
// Get distance between feet and thighs
float scaleModifier = Mathf.Max(1f, vrik.references.pelvis.lossyScale.x);
float footDistance = Vector3.Distance(vrik.references.leftFoot.position, vrik.references.rightFoot.position);
locomotionData.InitialFootDistance = footDistance * 0.5f;
locomotionData.InitialStepThreshold = footDistance * scaleModifier;
locomotionData.InitialStepHeight = Vector3.Distance(vrik.references.leftFoot.position, vrik.references.leftCalf.position) * 0.2f;
}
public static void CalculateInitialFootsteps(VRIK vrik, ref VRIKLocomotionData locomotionData)
{
Transform root = vrik.references.root;
Transform leftFoot = vrik.references.leftFoot;
Transform rightFoot = vrik.references.rightFoot;
// Calculate the world rotation of the root bone at the current frame
Quaternion rootWorldRot = root.rotation;
// Calculate the world rotation of the left and right feet relative to the root bone
locomotionData.InitialFootPosLeft = root.InverseTransformPoint(leftFoot.position);
locomotionData.InitialFootPosRight = root.InverseTransformPoint(rightFoot.position);
locomotionData.InitialFootRotLeft = Quaternion.Inverse(rootWorldRot) * leftFoot.rotation;
locomotionData.InitialFootRotRight = Quaternion.Inverse(rootWorldRot) * rightFoot.rotation;
}
public static void ResetToInitialFootsteps(VRIK vrik, VRIKLocomotionData locomotionData, float scaleModifier)
{
Transform root = vrik.references.root;
Quaternion rootWorldRot = vrik.references.root.rotation;
// hack, use parent transform instead as setting feet position moves root (root.parent), but does not work for VR
var footsteps = vrik.solver.locomotion.footsteps;
footsteps[0].Reset(rootWorldRot, root.TransformPoint(locomotionData.InitialFootPosLeft * scaleModifier),
rootWorldRot * locomotionData.InitialFootRotLeft);
footsteps[1].Reset(rootWorldRot, root.TransformPoint(locomotionData.InitialFootPosRight * scaleModifier),
rootWorldRot * locomotionData.InitialFootRotRight);
}
public static void ApplyScaleToVRIK(VRIK vrik, VRIKLocomotionData locomotionData, float scaleModifier)
{
IKSolverVR.Locomotion locomotionSolver = vrik.solver.locomotion;
locomotionSolver.footDistance = locomotionData.InitialFootDistance * scaleModifier;
locomotionSolver.stepThreshold = locomotionData.InitialStepThreshold * scaleModifier;
ScaleStepHeight(locomotionSolver.stepHeight, locomotionData.InitialStepHeight * scaleModifier);
}
private static void ScaleStepHeight(AnimationCurve stepHeightCurve, float mag)
{
var keyframes = stepHeightCurve.keys;
keyframes[1].value = mag;
stepHeightCurve.keys = keyframes;
}
}