mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 14:29:25 +00:00
204 lines
No EOL
6.7 KiB
C#
204 lines
No EOL
6.7 KiB
C#
using ABI_RC.Core.InteractionSystem;
|
|
using ABI_RC.Systems.IK;
|
|
using ABI_RC.Systems.IK.SubSystems;
|
|
using ABI_RC.Systems.InputManagement;
|
|
using UnityEngine;
|
|
|
|
namespace NAK.IKAdjustments.Systems;
|
|
|
|
public class IKAdjuster : MonoBehaviour
|
|
{
|
|
#region Grab Definitions
|
|
|
|
public class GrabState
|
|
{
|
|
public bool handGrabbed;
|
|
public TrackingPoint tracker;
|
|
public Vector3 displayOffset;
|
|
public Quaternion displayOffsetRotation;
|
|
public GrabState otherGrab;
|
|
}
|
|
|
|
public enum AdjustMode
|
|
{
|
|
Position = 0,
|
|
Rotation,
|
|
Both
|
|
}
|
|
|
|
#endregion
|
|
|
|
public static IKAdjuster Instance;
|
|
|
|
public bool isAdjustMode;
|
|
|
|
public float Setting_MaxGrabDistance = 0.2f;
|
|
public AdjustMode Setting_AdjustMode = AdjustMode.Position;
|
|
|
|
private GrabState leftGrabState = new();
|
|
private GrabState rightGrabState = new();
|
|
|
|
#region Unity Events
|
|
|
|
private void Start()
|
|
{
|
|
Instance = this;
|
|
|
|
leftGrabState.otherGrab = rightGrabState;
|
|
rightGrabState.otherGrab = leftGrabState;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!isAdjustMode) return;
|
|
if (BodySystem.isCalibrating)
|
|
{
|
|
isAdjustMode = false;
|
|
return;
|
|
}
|
|
|
|
UpdateGrabbing(true, ref leftGrabState);
|
|
UpdateGrabbing(false, ref rightGrabState);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
public void EnterAdjustMode()
|
|
{
|
|
if (isAdjustMode)
|
|
return;
|
|
|
|
isAdjustMode = true;
|
|
IKSystem.Instance.TrackingSystem.SetTrackingPointVisibility(true);
|
|
CVR_MenuManager.Instance.ToggleQuickMenu(false);
|
|
foreach (TrackingPoint tracker in IKSystem.Instance.TrackingSystem.AllTrackingPoints) tracker.ClearLineTarget();
|
|
}
|
|
|
|
public void ExitAdjustMode()
|
|
{
|
|
if (!isAdjustMode)
|
|
return;
|
|
|
|
isAdjustMode = false;
|
|
IKSystem.Instance.TrackingSystem.SetTrackingPointVisibility(false);
|
|
}
|
|
|
|
public void ResetAllOffsets()
|
|
{
|
|
foreach (TrackingPoint tracker in IKSystem.Instance.TrackingSystem.AllTrackingPoints)
|
|
{
|
|
tracker.offsetTransform.SetParent(tracker.displayObject.transform, true);
|
|
tracker.displayObject.transform.localPosition = Vector3.zero;
|
|
tracker.displayObject.transform.localRotation = Quaternion.identity;
|
|
tracker.offsetTransform.SetParent(tracker.referenceTransform, true);
|
|
}
|
|
}
|
|
|
|
public void CycleAdjustMode()
|
|
{
|
|
var currentValue = (int)Setting_AdjustMode;
|
|
var numValues = Enum.GetValues(typeof(AdjustMode)).Length;
|
|
var nextValue = (currentValue + 1) % numValues;
|
|
Setting_AdjustMode = (AdjustMode)nextValue;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
private void UpdateGrabbing(bool isLeft, ref GrabState grabState)
|
|
{
|
|
var isGrabbing = isLeft
|
|
? CVRInputManager.Instance.gripLeftValue > 0.9f
|
|
: CVRInputManager.Instance.gripRightValue > 0.9f;
|
|
var isInteracting = isLeft
|
|
? CVRInputManager.Instance.interactLeftValue > 0.9f
|
|
: CVRInputManager.Instance.interactRightValue > 0.9f;
|
|
Transform handTracker = isLeft
|
|
? IKSystem.Instance.leftController.transform
|
|
: IKSystem.Instance.rightController.transform;
|
|
|
|
if (grabState.tracker == null && !grabState.handGrabbed && isGrabbing)
|
|
{
|
|
OnGrab(handTracker, grabState);
|
|
}
|
|
else if (grabState.tracker != null)
|
|
{
|
|
if (!isGrabbing)
|
|
OnRelease(grabState);
|
|
else if (isInteracting)
|
|
OnReset(grabState);
|
|
else
|
|
Holding(handTracker, grabState);
|
|
}
|
|
|
|
grabState.handGrabbed = isGrabbing;
|
|
}
|
|
|
|
private void OnGrab(Transform handTracker, GrabState grabState)
|
|
{
|
|
Transform nearestTransform = FindNearestTransform(handTracker);
|
|
if (nearestTransform != null &&
|
|
Vector3.Distance(nearestTransform.GetChild(0).position, handTracker.position) <=
|
|
Setting_MaxGrabDistance)
|
|
{
|
|
grabState.tracker =
|
|
IKSystem.Instance.TrackingSystem.AllTrackingPoints.Find(tp => tp.referenceTransform == nearestTransform);
|
|
if (grabState.otherGrab.tracker == grabState.tracker) OnRelease(grabState.otherGrab);
|
|
grabState.displayOffset = grabState.tracker.displayObject.transform.position - handTracker.position;
|
|
grabState.displayOffsetRotation = Quaternion.Inverse(handTracker.rotation) *
|
|
grabState.tracker.displayObject.transform.rotation;
|
|
grabState.tracker.offsetTransform.SetParent(grabState.tracker.displayObject.transform, true);
|
|
}
|
|
}
|
|
|
|
private void OnRelease(GrabState grabState)
|
|
{
|
|
grabState.tracker.offsetTransform.SetParent(grabState.tracker.referenceTransform, true);
|
|
grabState.tracker.ClearLineTarget();
|
|
grabState.tracker = null;
|
|
}
|
|
|
|
private void OnReset(GrabState grabState)
|
|
{
|
|
grabState.tracker.displayObject.transform.localRotation = Quaternion.identity;
|
|
grabState.tracker.displayObject.transform.localPosition = Vector3.zero;
|
|
|
|
grabState.tracker.offsetTransform.SetParent(grabState.tracker.referenceTransform, true);
|
|
grabState.tracker.ClearLineTarget();
|
|
grabState.tracker = null;
|
|
}
|
|
|
|
private void Holding(Transform handTracker, GrabState grabState)
|
|
{
|
|
switch (Setting_AdjustMode)
|
|
{
|
|
case AdjustMode.Position:
|
|
grabState.tracker.displayObject.transform.position = handTracker.position + grabState.displayOffset;
|
|
break;
|
|
case AdjustMode.Rotation:
|
|
grabState.tracker.displayObject.transform.rotation =
|
|
handTracker.rotation * grabState.displayOffsetRotation;
|
|
break;
|
|
case AdjustMode.Both:
|
|
grabState.tracker.displayObject.transform.rotation =
|
|
handTracker.rotation * grabState.displayOffsetRotation;
|
|
grabState.tracker.displayObject.transform.position = handTracker.position + grabState.displayOffset;
|
|
break;
|
|
}
|
|
|
|
grabState.tracker.SetLineTarget(grabState.tracker.referenceTransform.position);
|
|
}
|
|
|
|
private Transform FindNearestTransform(Transform handTransform)
|
|
{
|
|
var validTrackingPointTransforms = TrackingSystem.ValidTrackingPointTransforms;
|
|
if (validTrackingPointTransforms == null || validTrackingPointTransforms.Count == 0) return null;
|
|
return validTrackingPointTransforms
|
|
.OrderBy(t => Vector3.Distance(handTransform.position, t.GetChild(0).position)).FirstOrDefault();
|
|
}
|
|
|
|
#endregion
|
|
} |