[AlternateIKSystem] Add halfbody support.

This commit is contained in:
NotAKidoS 2023-07-14 01:55:30 -05:00
parent cd34aebeb0
commit 69b84775ec
5 changed files with 143 additions and 131 deletions

View file

@ -41,9 +41,34 @@ internal abstract class IKHandler
public virtual void OnInitializeIk() { }
public virtual void OnPlayerScaled(float scaleDifference) { }
public virtual void OnPlayerScaled(float scaleDifference)
{
VRIKUtils.ApplyScaleToVRIK
(
_vrik,
_locomotionData,
_scaleDifference = scaleDifference
);
}
public virtual void OnPlayerHandleMovementParent(CVRMovementParent currentParent) { }
public virtual void OnPlayerHandleMovementParent(CVRMovementParent currentParent, Vector3 platformPivot)
{
Vector3 currentPosition = currentParent._referencePoint.position;
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
Vector3 deltaPosition = currentPosition - _movementPosition;
Quaternion deltaRotation = Quaternion.Inverse(_movementRotation) * currentRotation;
if (_movementParent == currentParent)
{
_solver.AddPlatformMotion(deltaPosition, deltaRotation, platformPivot);
_ikSimulatedRootAngle = Mathf.Repeat(_ikSimulatedRootAngle + deltaRotation.eulerAngles.y, 360f);
}
_movementParent = currentParent;
_movementPosition = currentPosition;
_movementRotation = currentRotation;
}
#endregion

View file

@ -29,42 +29,6 @@ internal class IKHandlerDesktop : IKHandler
_vrik.onPreSolverUpdate.AddListener(OnPreSolverUpdateDesktop);
}
public override void OnPlayerScaled(float scaleDifference)
{
VRIKUtils.ApplyScaleToVRIK
(
_vrik,
_locomotionData,
_scaleDifference = scaleDifference
);
}
public override void OnPlayerHandleMovementParent(CVRMovementParent currentParent)
{
// Get current position
Vector3 currentPosition = currentParent._referencePoint.position;
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
// Convert to delta position (how much changed since last frame)
Vector3 deltaPosition = currentPosition - _movementPosition;
Quaternion deltaRotation = Quaternion.Inverse(_movementRotation) * currentRotation;
// Desktop pivots from playerlocal transform
Vector3 platformPivot = IKManager.Instance.transform.position;
// Prevent targeting other parent position
if (_movementParent == currentParent)
{
_solver.AddPlatformMotion(deltaPosition, deltaRotation, platformPivot);
_ikSimulatedRootAngle = Mathf.Repeat(_ikSimulatedRootAngle + deltaRotation.eulerAngles.y, 360f);
}
// Store for next frame
_movementParent = currentParent;
_movementPosition = currentPosition;
_movementRotation = currentRotation;
}
#endregion
#region Weight Overrides
@ -81,57 +45,6 @@ internal class IKHandlerDesktop : IKHandler
_solver.spine.positionWeight = 0f;
}
protected override void Update_HeadWeight()
{
float targetWeight = GetTargetWeight(BodyControl.TrackingHead, true);
BodyControl.SetHeadWeight(_solver.spine, targetWeight);
BodyControl.SetLookAtWeight(IKManager.lookAtIk, targetWeight);
}
protected override void Update_LeftArmWeight()
{
float leftArmWeight = GetTargetWeight(BodyControl.TrackingLeftArm, _solver.leftArm.target != null);
BodyControl.SetArmWeight(_solver.leftArm, leftArmWeight);
}
protected override void Update_RightArmWeight()
{
float rightArmWeight = GetTargetWeight(BodyControl.TrackingRightArm, _solver.rightArm.target != null);
BodyControl.SetArmWeight(_solver.rightArm, rightArmWeight);
}
protected override void Update_LeftLegWeight()
{
float leftLegWeight = GetTargetWeight(BodyControl.TrackingLeftLeg, _solver.leftLeg.target != null);
BodyControl.SetLegWeight(_solver.leftLeg, leftLegWeight);
}
protected override void Update_RightLegWeight()
{
float rightLegWeight = GetTargetWeight(BodyControl.TrackingRightLeg, _solver.rightLeg.target != null);
BodyControl.SetLegWeight(_solver.rightLeg, rightLegWeight);
}
protected override void Update_PelvisWeight()
{
float pelvisWeight = GetTargetWeight(BodyControl.TrackingPelvis, _solver.spine.pelvisTarget != null);
BodyControl.SetPelvisWeight(_solver.spine, pelvisWeight);
}
protected override void Update_LocomotionWeight()
{
_locomotionWeight = Mathf.Lerp(_locomotionWeight, BodyControl.TrackingLocomotion ? 1f : 0f,
Time.deltaTime * ModSettings.EntryIKLerpSpeed.Value * 2f);
BodyControl.SetLocomotionWeight(_solver.locomotion, _locomotionWeight);
}
protected override void Update_IKPositionWeight()
{
float ikPositionWeight = BodyControl.TrackingAll ? BodyControl.TrackingIKPositionWeight : 0f;
BodyControl.SetIKPositionWeight(_solver, ikPositionWeight);
BodyControl.SetIKPositionWeight(IKManager.lookAtIk, ikPositionWeight);
}
#endregion
#region VRIK Solver Events

View file

@ -25,42 +25,33 @@ internal class IKHandlerHalfBody : IKHandler
shouldTrackRightLeg = false;
shouldTrackPelvis = false;
shouldTrackLocomotion = true;
_vrik.onPreSolverUpdate.AddListener(OnPreSolverUpdateHalfBody);
}
#endregion
public override void OnPlayerScaled(float scaleDifference)
#region VRIK Solver Events
private void OnPreSolverUpdateHalfBody()
{
VRIKUtils.ApplyScaleToVRIK
(
_vrik,
_locomotionData,
_scaleDifference = scaleDifference
);
}
_solver.plantFeet = ModSettings.EntryPlantFeet.Value;
public override void OnPlayerHandleMovementParent(CVRMovementParent currentParent)
{
// Get current position
Vector3 currentPosition = currentParent._referencePoint.position;
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
// Convert to delta position (how much changed since last frame)
Vector3 deltaPosition = currentPosition - _movementPosition;
Quaternion deltaRotation = Quaternion.Inverse(_movementRotation) * currentRotation;
// Desktop pivots from playerlocal transform
Vector3 platformPivot = IKManager.Instance.transform.position;
// Prevent targeting other parent position
if (_movementParent == currentParent)
// Make root heading follow within a set limit
if (ModSettings.EntryBodyHeadingLimit.Value > 0)
{
_solver.AddPlatformMotion(deltaPosition, deltaRotation, platformPivot);
_ikSimulatedRootAngle = Mathf.Repeat(_ikSimulatedRootAngle + deltaRotation.eulerAngles.y, 360f);
}
float weightedAngleLimit = ModSettings.EntryBodyHeadingLimit.Value * _solver.locomotion.weight;
float currentRotation = IKManager.Instance.GetPlayerRotation().y;
float deltaAngleRoot = Mathf.DeltaAngle(currentRotation, _ikSimulatedRootAngle);
// Store for next frame
_movementParent = currentParent;
_movementPosition = currentPosition;
_movementRotation = currentRotation;
if (Mathf.Abs(deltaAngleRoot) > weightedAngleLimit)
{
deltaAngleRoot = Mathf.Sign(deltaAngleRoot) * weightedAngleLimit;
_ikSimulatedRootAngle = Mathf.MoveTowardsAngle(_ikSimulatedRootAngle, currentRotation, Mathf.Abs(deltaAngleRoot) - weightedAngleLimit);
}
_solver.spine.rootHeadingOffset = deltaAngleRoot;
}
}
#endregion