VR4Medical/ICI/Library/PackageCache/com.unity.xr.interaction.toolkit@42ef3600567b/Runtime/AR/Inputs/ScreenSpaceRotateInput.cs
2025-07-29 13:45:50 +03:00

145 lines
5.3 KiB
C#

using System.Diagnostics;
using UnityEngine.XR.Interaction.Toolkit.Inputs.Readers;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
namespace UnityEngine.XR.Interaction.Toolkit.AR.Inputs
{
/// <summary>
/// Component that provides the twist rotation or two finger drag value from a touchscreen for mobile AR.
/// Intended to be used with an <see cref="XRInputValueReader"/> as its object reference
/// to provide a rotation value.
/// </summary>
/// <seealso cref="XRRayInteractor.rotateManipulationInput"/>
/// <seealso cref="XRRayInteractor.RotateMode.RotateOverTime"/>
[AddComponentMenu("XR/Input/Screen Space Rotate Input", 11)]
[HelpURL(XRHelpURLConstants.k_ScreenSpaceRotateInput)]
public class ScreenSpaceRotateInput : MonoBehaviour, IXRInputValueReader<Vector2>
{
[SerializeField]
[Tooltip("The ray interactor to get the attach transform from.")]
XRRayInteractor m_RayInteractor;
/// <summary>
/// The ray interactor to get the attach transform from.
/// </summary>
public XRRayInteractor rayInteractor
{
get => m_RayInteractor;
set => m_RayInteractor = value;
}
[SerializeField]
[Tooltip("The input used to read the twist delta rotation value.")]
XRInputValueReader<float> m_TwistDeltaRotationInput = new XRInputValueReader<float>("Twist Delta Rotation");
/// <summary>
/// Input to use for the screen twist delta relative to the previous frame.
/// </summary>
/// <seealso cref="TouchscreenGestureInputController.twistDeltaRotation"/>
public XRInputValueReader<float> twistDeltaRotationInput
{
get => m_TwistDeltaRotationInput;
set => XRInputReaderUtility.SetInputProperty(ref m_TwistDeltaRotationInput, value, this);
}
[SerializeField]
[Tooltip("The input used to read the drag delta value.")]
XRInputValueReader<Vector2> m_DragDeltaInput = new XRInputValueReader<Vector2>("Drag Delta");
/// <summary>
/// Input to use for the screen drag delta relative to the previous frame.
/// </summary>
/// <seealso cref="TouchscreenGestureInputController.dragDelta"/>
public XRInputValueReader<Vector2> dragDeltaInput
{
get => m_DragDeltaInput;
set => XRInputReaderUtility.SetInputProperty(ref m_DragDeltaInput, value, this);
}
[SerializeField]
[Tooltip("The input used to read the screen touch count value.")]
XRInputValueReader<int> m_ScreenTouchCountInput = new XRInputValueReader<int>("Screen Touch Count");
/// <summary>
/// The input used to read the screen touch count value.
/// </summary>
/// <seealso cref="TouchscreenGestureInputController.fingerCount"/>
public XRInputValueReader<int> screenTouchCountInput
{
get => m_ScreenTouchCountInput;
set => XRInputReaderUtility.SetInputProperty(ref m_ScreenTouchCountInput, value, this);
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
[Conditional("UNITY_EDITOR")]
protected void Reset()
{
#if UNITY_EDITOR
m_RayInteractor = GetComponentInParent<XRRayInteractor>(true);
#endif
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
protected void Awake()
{
if (m_RayInteractor == null)
m_RayInteractor = GetComponentInParent<XRRayInteractor>(true);
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
protected void OnEnable()
{
m_TwistDeltaRotationInput.EnableDirectActionIfModeUsed();
m_DragDeltaInput.EnableDirectActionIfModeUsed();
m_ScreenTouchCountInput.EnableDirectActionIfModeUsed();
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
protected void OnDisable()
{
m_TwistDeltaRotationInput.DisableDirectActionIfModeUsed();
m_DragDeltaInput.DisableDirectActionIfModeUsed();
m_ScreenTouchCountInput.DisableDirectActionIfModeUsed();
}
/// <inheritdoc />
public Vector2 ReadValue()
{
TryReadValue(out var value);
return value;
}
/// <inheritdoc />
public bool TryReadValue(out Vector2 value)
{
if (m_TwistDeltaRotationInput.TryReadValue(out var twistDeltaRotation))
{
value = new Vector2(-twistDeltaRotation, 0f);
return true;
}
if (m_ScreenTouchCountInput.ReadValue() > 1 &&
m_DragDeltaInput.TryReadValue(out var dragDeltaRotation))
{
var attachTransform = m_RayInteractor.attachTransform;
var worldToVerticalOrientedDevice = Quaternion.Inverse(Quaternion.LookRotation(attachTransform.forward, Vector3.up));
var rotatedDelta = worldToVerticalOrientedDevice * attachTransform.rotation * dragDeltaRotation;
value = new Vector2((rotatedDelta.x / Screen.dpi) * -50f, 0f);
return true;
}
value = Vector2.zero;
return false;
}
}
}