Move third party assets to ThirdParty folder

This commit is contained in:
2024-08-08 11:26:28 +02:00
parent 386f303057
commit bd91af6f98
10340 changed files with 100 additions and 175 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 303d8f4b6a2845b499a660366a5a2b9d
timeCreated: 1643966484

View File

@@ -0,0 +1,256 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrDebugControllerPanel.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Avatar;
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UltimateXR.Extensions.Unity;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR;
namespace UltimateXR.Devices.DebugPanels
{
/// <summary>
/// UI panel showing all information related to the current main VR input device.
/// </summary>
public class UxrDebugControllerPanel : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private bool _blinkButtonsOnInput;
[SerializeField] private Text _textDeviceName;
[SerializeField] private Text _textControllerNames;
[SerializeField] private GameObject _containerControllerNames;
[SerializeField] private GameObject _panelInput1D;
[SerializeField] private GameObject _panelInput2D;
[SerializeField] private GameObject _panelInputButtons;
[SerializeField] private GameObject _prefabWidget1D;
[SerializeField] private GameObject _prefabWidget2D;
[SerializeField] private GameObject _prefabWidgetButton;
#endregion
#region Unity
/// <summary>
/// Checks if the current input device changed in order to regenerate the panel.
/// </summary>
private void Update()
{
UxrAvatar avatar = UxrAvatar.LocalAvatar;
UxrControllerInput controllerInput = avatar != null ? avatar.ControllerInput : null;
if (avatar != _avatar || controllerInput != _avatarControllerInput)
{
// Unsubscribe from the current avatar controller events.
if (_avatarControllerInput != null)
{
_avatarControllerInput.ButtonStateChanged -= ControllerInput_ButtonStateChanged;
_avatarControllerInput.Input1DChanged -= ControllerInput_Input1DChanged;
_avatarControllerInput.Input2DChanged -= ControllerInput_Input2DChanged;
}
// Cache the new avatar and regenerate the panel.
_avatar = avatar;
_avatarControllerInput = controllerInput;
RegeneratePanel();
// Subscribe to the input events to update the input UI widgets.
if (_avatarControllerInput != null)
{
_avatarControllerInput.ButtonStateChanged += ControllerInput_ButtonStateChanged;
_avatarControllerInput.Input1DChanged += ControllerInput_Input1DChanged;
_avatarControllerInput.Input2DChanged += ControllerInput_Input2DChanged;
}
}
// This one can change each frame, depending on controllers getting connected/disconnected
UpdateControllerStrings();
}
#endregion
#region Event Handling Methods
/// <summary>
/// Called whenever a VR controller button state changed.
/// </summary>
/// <param name="sender">The controller that generated the event</param>
/// <param name="e">Event arguments</param>
private void ControllerInput_ButtonStateChanged(object sender, UxrInputButtonEventArgs e)
{
UxrControllerInput controllerInput = (UxrControllerInput)sender;
UxrControllerElements controllerElement = UxrControllerInput.ButtonToControllerElement(e.Button);
bool allControllerElementsBlinking = controllerInput.AreAllControllerElementsBlinking(e.HandSide, controllerElement);
if (_blinkButtonsOnInput && controllerElement != UxrControllerElements.None && allControllerElementsBlinking == false)
{
_avatarControllerInput.StartControllerElementsBlinking(e.HandSide, controllerElement, Color.white, 5, 2.0f);
}
}
/// <summary>
/// Called whenever a VR controller single-axis value changed.
/// </summary>
/// <param name="sender">The controller that generated the event</param>
/// <param name="e">Event arguments</param>
private void ControllerInput_Input1DChanged(object sender, UxrInput1DEventArgs e)
{
UxrControllerInput controllerInput = (UxrControllerInput)sender;
UxrControllerElements controllerElement = UxrControllerInput.Input1DToControllerElement(e.Target);
bool allControllerElementsBlinking = controllerInput.AreAllControllerElementsBlinking(e.HandSide, controllerElement);
if (_blinkButtonsOnInput && controllerElement != UxrControllerElements.None && allControllerElementsBlinking == false)
{
_avatarControllerInput.StartControllerElementsBlinking(e.HandSide, controllerElement, Color.white, 5, 2.0f);
}
}
/// <summary>
/// Called whenever a VR controller two-axis value changed.
/// </summary>
/// <param name="sender">The controller that generated the event</param>
/// <param name="e">Event arguments</param>
private void ControllerInput_Input2DChanged(object sender, UxrInput2DEventArgs e)
{
UxrControllerInput controllerInput = (UxrControllerInput)sender;
UxrControllerElements controllerElement = UxrControllerInput.Input2DToControllerElement(e.Target);
bool allControllerElementsBlinking = controllerInput.AreAllControllerElementsBlinking(e.HandSide, controllerElement);
if (_blinkButtonsOnInput && controllerElement != UxrControllerElements.None && allControllerElementsBlinking == false)
{
_avatarControllerInput.StartControllerElementsBlinking(e.HandSide, controllerElement, Color.white, 5, 2.0f);
}
}
#endregion
#region Private Methods
/// <summary>
/// Updates the controller names shown.
/// </summary>
private void UpdateControllerStrings()
{
if (_avatar && _avatarControllerInput)
{
string leftName = _avatarControllerInput.LeftControllerName ?? NoController;
string rightName = _avatarControllerInput.RightControllerName ?? NoController;
_containerControllerNames.SetActive(!string.IsNullOrEmpty(leftName) || !string.IsNullOrEmpty(rightName));
if (_avatarControllerInput.SetupType == UxrControllerSetupType.Single)
{
// Single controller setup. Both sides will return the same name.
_textControllerNames.text = $"Controller: {leftName}";
}
else if (_avatarControllerInput.SetupType == UxrControllerSetupType.Dual)
{
// Dual controller setup.
_textControllerNames.text = $"Left controller: {leftName}, right controller: {rightName}";
}
}
}
/// <summary>
/// Re-generates the panel adding widgets for all input elements present in the current controller(s).
/// </summary>
private void RegeneratePanel()
{
_panelInput1D.transform.DestroyAllChildren();
_panelInput2D.transform.DestroyAllChildren();
_panelInputButtons.transform.DestroyAllChildren();
if (_avatar == null || _avatarControllerInput == null)
{
_textDeviceName.text = $"No {nameof(UxrAvatar)} with an active {nameof(UxrControllerInput)} component found";
return;
}
// Device strings
_textDeviceName.text = $"Device: {UxrTrackingDevice.HeadsetDeviceName}, Loaded: {XRSettings.loadedDeviceName}";
UpdateControllerStrings();
// Dynamically add all current devices' supported Controllers1D elements to the UI
foreach (UxrInput1D input1D in Enum.GetValues(typeof(UxrInput1D)))
{
UxrControllerElements controllerElement = UxrControllerInput.Input1DToControllerElement(input1D);
foreach (UxrHandSide handSide in Enum.GetValues(typeof(UxrHandSide)))
{
if (controllerElement != UxrControllerElements.None && _avatarControllerInput.HasControllerElements(handSide, controllerElement))
{
GameObject newWidget = Instantiate(_prefabWidget1D, _panelInput1D.transform);
UxrDebugInput1dUI uiInput1d = newWidget.GetComponent<UxrDebugInput1dUI>();
uiInput1d.TargetController = _avatarControllerInput;
uiInput1d.TargetHand = handSide;
uiInput1d.Target = input1D;
}
}
}
// Dynamically add all current devices' supported Controllers2D elements to the UI
foreach (UxrInput2D input2D in Enum.GetValues(typeof(UxrInput2D)))
{
UxrControllerElements controllerElement = UxrControllerInput.Input2DToControllerElement(input2D);
foreach (UxrHandSide handSide in Enum.GetValues(typeof(UxrHandSide)))
{
if (controllerElement != UxrControllerElements.None && _avatarControllerInput.HasControllerElements(handSide, controllerElement))
{
GameObject newWidget = Instantiate(_prefabWidget2D, _panelInput2D.transform);
UxrDebugInput2dUI uiInput2d = newWidget.GetComponent<UxrDebugInput2dUI>();
uiInput2d.TargetController = _avatarControllerInput;
uiInput2d.TargetHand = handSide;
uiInput2d.Target = input2D;
}
}
}
// Dynamically add all current devices' supported button elements to the UI
foreach (UxrInputButtons button in Enum.GetValues(typeof(UxrInputButtons)))
{
UxrControllerElements controllerElement = UxrControllerInput.ButtonToControllerElement(button);
foreach (UxrHandSide handSide in Enum.GetValues(typeof(UxrHandSide)))
{
if (controllerElement != UxrControllerElements.None && _avatarControllerInput.HasControllerElements(handSide, controllerElement))
{
GameObject newWidget = Instantiate(_prefabWidgetButton, _panelInputButtons.transform);
UxrDebugInputButtonUI uiButton = newWidget.GetComponent<UxrDebugInputButtonUI>();
uiButton.TargetController = _avatarControllerInput;
uiButton.TargetHand = handSide;
uiButton.Target = button;
}
}
}
}
#endregion
#region Private Types & Data
private const string NoController = "None";
private UxrAvatar _avatar;
private UxrControllerInput _avatarControllerInput;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1b8190b6241a8e44b82f8b0d6e2de329
timeCreated: 1503571160
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrDebugInput1dUI.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UnityEngine;
using UnityEngine.UI;
namespace UltimateXR.Devices.DebugPanels
{
/// <summary>
/// UI Widget for a single-axis input element in a VR input controller. Examples are trigger buttons, grip buttons...
/// </summary>
public class UxrDebugInput1dUI : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private UxrControllerInput _controllerInput;
[SerializeField] private UxrHandSide _hand;
[SerializeField] private UxrInput1D _target;
[SerializeField] private Text _name;
[SerializeField] private RectTransform _cursor;
[SerializeField] private float _coordAmplitude;
#endregion
#region Public Types & Data
/// <summary>
/// Gets or sets the controller(s) to monitor for input.
/// </summary>
public UxrControllerInput TargetController
{
get => _controllerInput;
set => _controllerInput = value;
}
/// <summary>
/// Gets or sets the hand to monitor for input.
/// </summary>
public UxrHandSide TargetHand
{
get => _hand;
set => _hand = value;
}
/// <summary>
/// Gets or sets the single-axis element to monitor.
/// </summary>
public UxrInput1D Target
{
get => _target;
set => _target = value;
}
#endregion
#region Unity
/// <summary>
/// Updates the widget information.
/// </summary>
private void Update()
{
_name.text = $"{_hand} {_target}";
if (_controllerInput != null)
{
_cursor.anchoredPosition = new Vector2(0.0f, 1.0f) * (_coordAmplitude * _controllerInput.GetInput1D(_hand, _target, true));
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 518e7160296b55242853ce5d0cd3edae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrDebugInput2dUI.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UnityEngine;
using UnityEngine.UI;
namespace UltimateXR.Devices.DebugPanels
{
/// <summary>
/// UI Widget for a two-axis input element in a VR input controller. Examples are joysticks, trackpads...
/// </summary>
public class UxrDebugInput2dUI : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private UxrControllerInput _controllerInput;
[SerializeField] private UxrHandSide _hand;
[SerializeField] private UxrInput2D _target;
[SerializeField] private Text _name;
[SerializeField] private RectTransform _cursor;
[SerializeField] private float _coordAmplitude;
#endregion
#region Public Types & Data
/// <summary>
/// Gets the controller to monitor for input.
/// </summary>
public UxrControllerInput TargetController
{
get => _controllerInput;
set => _controllerInput = value;
}
/// <summary>
/// Gets the hand to monitor for input.
/// </summary>
public UxrHandSide TargetHand
{
get => _hand;
set => _hand = value;
}
/// <summary>
/// Gets the two-axis element to monitor for input.
/// </summary>
public UxrInput2D Target
{
get => _target;
set => _target = value;
}
#endregion
#region Unity
/// <summary>
/// Updates the widget information.
/// </summary>
private void Update()
{
_name.text = $"{_hand} {_target}";
if (_controllerInput != null)
{
_cursor.anchoredPosition = Vector2.Scale(Vector2.one * _coordAmplitude, _controllerInput.GetInput2D(_hand, _target, true));
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 156df0def5d48a3489e870c7fb9a1243
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,124 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrDebugInputButtonUI.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UnityEngine;
using UnityEngine.UI;
namespace UltimateXR.Devices.DebugPanels
{
/// <summary>
/// UI Widget for a button in a VR input controller.
/// </summary>
public class UxrDebugInputButtonUI : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private UxrControllerInput _controllerInput;
[SerializeField] private UxrHandSide _hand;
[SerializeField] private UxrInputButtons _button;
[SerializeField] private Text _name;
[SerializeField] private Image _imagePressing;
[SerializeField] private Image _imagePressDown;
[SerializeField] private Image _imagePressUp;
[SerializeField] private Image _imageTouching;
[SerializeField] private Image _imageTouchDown;
[SerializeField] private Image _imageTouchUp;
[SerializeField] private Color _colorEnabled;
[SerializeField] private Color _colorDisabled;
[SerializeField] private float _secondsUpAndDownEnabled = 0.1f;
#endregion
#region Public Types & Data
/// <summary>
/// Gets the controller to monitor for input.
/// </summary>
public UxrControllerInput TargetController
{
get => _controllerInput;
set => _controllerInput = value;
}
/// <summary>
/// Gets the hand to monitor for input.
/// </summary>
public UxrHandSide TargetHand
{
get => _hand;
set => _hand = value;
}
/// <summary>
/// Gets the button to monitor for input.
/// </summary>
public UxrInputButtons Target
{
get => _button;
set => _button = value;
}
#endregion
#region Unity
/// <summary>
/// Updates the widget information.
/// </summary>
private void Update()
{
_name.text = $"{_hand} {_button}";
if (_controllerInput != null)
{
_pressDownTimer -= Time.deltaTime;
_pressUpTimer -= Time.deltaTime;
_touchDownTimer -= Time.deltaTime;
_touchUpTimer -= Time.deltaTime;
if (_controllerInput.GetButtonsPressDown(_hand, _button, true))
{
_pressDownTimer = _secondsUpAndDownEnabled;
}
if (_controllerInput.GetButtonsPressUp(_hand, _button, true))
{
_pressUpTimer = _secondsUpAndDownEnabled;
}
if (_controllerInput.GetButtonsTouchDown(_hand, _button, true))
{
_touchDownTimer = _secondsUpAndDownEnabled;
}
if (_controllerInput.GetButtonsTouchUp(_hand, _button, true))
{
_touchUpTimer = _secondsUpAndDownEnabled;
}
_imagePressing.color = _controllerInput.GetButtonsPress(_hand, _button, true) ? _colorEnabled : _colorDisabled;
_imageTouching.color = _controllerInput.GetButtonsTouch(_hand, _button, true) ? _colorEnabled : _colorDisabled;
_imagePressDown.color = _pressDownTimer > 0.0f ? _colorEnabled : _colorDisabled;
_imagePressUp.color = _pressUpTimer > 0.0f ? _colorEnabled : _colorDisabled;
_imageTouchDown.color = _touchDownTimer > 0.0f ? _colorEnabled : _colorDisabled;
_imageTouchUp.color = _touchUpTimer > 0.0f ? _colorEnabled : _colorDisabled;
}
}
#endregion
#region Private Types & Data
private float _pressDownTimer = -1.0f;
private float _pressUpTimer = -1.0f;
private float _touchDownTimer = -1.0f;
private float _touchUpTimer = -1.0f;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 29e64a41519e9de4096778ead33f9a7d
timeCreated: 1503573723
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,673 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IUxrControllerInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Visualization;
using UltimateXR.Haptics;
using UltimateXR.Manipulation;
using UnityEngine;
namespace UltimateXR.Devices
{
/// <summary>
/// Controller interface for all XR input devices, supporting single controller and dual controller setups.
/// </summary>
public interface IUxrControllerInput : IUxrDevice
{
#region Public Types & Data
/// <summary>
/// Event called right before the controller input state is updated.
/// </summary>
event EventHandler Updating;
/// <summary>
/// Event called right after the controller input state has been updated.
/// </summary>
event EventHandler Updated;
/// <summary>
/// Event called after a controller button state changed.
/// </summary>
event EventHandler<UxrInputButtonEventArgs> ButtonStateChanged;
/// <summary>
/// Event called after a <see cref="UxrInput1D" /> element changed.
/// </summary>
event EventHandler<UxrInput1DEventArgs> Input1DChanged;
/// <summary>
/// Event called after a <see cref="UxrInput2D" /> element changed.
/// </summary>
event EventHandler<UxrInput2DEventArgs> Input2DChanged;
/// <summary>
/// Event called right before haptic feedback was requested.
/// </summary>
event EventHandler<UxrControllerHapticEventArgs> HapticRequesting;
/// <summary>
/// Gets the setup type. See <see cref="UxrControllerSetupType" />.
/// </summary>
UxrControllerSetupType SetupType { get; }
/// <summary>
/// <para>
/// Gets whether <see cref="Handedness" /> can be used. In <see cref="UxrControllerSetupType.Single" /> devices, it
/// may be used to control which hand is holding the controller. In <see cref="UxrControllerSetupType.Dual" />
/// devices it is used to determine which hands have the <see cref="Primary" /> (dominant) and
/// <see cref="Secondary" /> (non-dominant) roles.
/// </para>
/// Devices such as gamepads don't support handedness and will target the single device no matter which
/// <see cref="UxrHandSide" /> is used. In this case it is good practice to use <see cref="Primary" /> to target the
/// device in order to make the code cleaner.
/// </summary>
bool IsHandednessSupported { get; }
/// <summary>
/// <para>
/// Gets which hand is holding the controller in <see cref="UxrControllerSetupType.Single" /> setups where
/// <see cref="IsHandednessSupported" /> is available. In <see cref="UxrControllerSetupType.Dual" /> setups
/// it identifies the dominant hand. In both cases, <see cref="Handedness" /> determines which hand it is.
/// </para>
/// In <see cref="UxrControllerSetupType.Single" /> devices where handedness is not applicable (
/// <see cref="IsHandednessSupported" /> is false) it is good practice to use <see cref="Primary" /> to address the
/// device, even if both left and right can too.
/// </summary>
/// <seealso cref="Handedness" />
UxrHandSide Primary { get; }
/// <summary>
/// Gets which hand is not holding the controller in <see cref="UxrControllerSetupType.Single" /> setups where
/// <see cref="IsHandednessSupported" /> is available. In <see cref="UxrControllerSetupType.Dual" /> setups
/// it identifies the non-dominant hand.
/// </summary>
/// <seealso cref="Handedness" />
UxrHandSide Secondary { get; }
/// <summary>
/// Gets the left controller name, or empty if not connected / doesn't exist. In
/// <see cref="UxrControllerSetupType.Single" /> configurations where <see cref="IsHandednessSupported" /> is not
/// available, both sides will return the same name.
/// </summary>
string LeftControllerName { get; }
/// <summary>
/// Gets the right controller name, or empty if not connected / doesn't exist. In
/// <see cref="UxrControllerSetupType.Single" /> configurations where <see cref="IsHandednessSupported" /> is not
/// available, both sides will return the same name.
/// </summary>
string RightControllerName { get; }
/// <summary>
/// Gets the left instanced 3D controller model, if available. In <see cref="UxrControllerSetupType.Single" />
/// configurations where <see cref="IsHandednessSupported" /> is false, both sides will return the same model.
/// </summary>
UxrController3DModel LeftController3DModel { get; }
/// <summary>
/// Gets the right instanced 3D controller model, if available. In <see cref="UxrControllerSetupType.Single" />
/// configurations where <see cref="IsHandednessSupported" /> is false, both sides will return the same model.
/// </summary>
UxrController3DModel RightController3DModel { get; }
/// <summary>
/// Gets a value indicating whether the main two-axis input element is a touchpad. If false, it usually means the main
/// joystick is a thumbstick.
/// </summary>
bool MainJoystickIsTouchpad { get; }
/// <summary>
/// Gets the controller's joystick dead zone [0.0, 1.0]. Some controllers may have a more sensitive joystick,
/// and this property can be used to compensate in different implementations.
/// </summary>
float JoystickDeadZone { get; }
/// <summary>
/// <para>
/// Gets or sets the handedness, which is the <see cref="Primary" /> -dominant- hand in
/// <see cref="UxrControllerSetupType.Dual" /> controller setups. In <see cref="UxrControllerSetupType.Single" />
/// controller setups where the controller is grabbed with one hand, it determines which hand is being used.
/// </para>
/// If <see cref="IsHandednessSupported" /> false, such as in gamepads, the handedness value should be ignored.
/// </summary>
/// <seealso cref="IsHandednessSupported" />
/// <seealso cref="Primary" />
/// <seealso cref="Secondary" />
UxrHandSide Handedness { get; set; }
#endregion
#region Public Methods
/// <summary>
/// Checks whether the given controller is enabled.
/// </summary>
/// <param name="handSide">
/// Which controller to check. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <returns>Whether the given controller is enabled</returns>
bool IsControllerEnabled(UxrHandSide handSide);
/// <summary>
/// Checks if the given controller has specific elements.
/// </summary>
/// <param name="handSide">
/// Which controller to check. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="controllerElements">Flags indicating the element(s) to look for</param>
/// <returns>True if the controller has all the elements specified. If one is missing, it will return false</returns>
bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements);
/// <summary>
/// Gets the capabilities of the XR controller.
/// </summary>
/// <param name="handSide">
/// Which controller to check. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <returns>Device capabilities flags</returns>
UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide);
/// <summary>
/// Gets the state of an analog controller input element.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="input1D">Element to get the input from</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>Input value [0.0, 1.0]</returns>
float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false);
/// <summary>
/// Gets the state of a 2D input element (joystick, touchpad...).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="input2D">Element to get the input from</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// Vector2 telling the state of the controller element. Each component between [-1.0, 1.0]
/// </returns>
Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false);
/// <summary>
/// Gets an uint value representing touch states for each the controller <see cref="UxrInputButtons" /> flags in the
/// current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>Button flags representing touch states for each controller button in the current frame</returns>
/// <seealso cref="UxrInputButtons" />
uint GetButtonTouchFlags(UxrHandSide handSide, bool getIgnoredInput = false);
/// <summary>
/// Gets an uint value representing touch states for each the controller <see cref="UxrInputButtons" /> flags in the
/// last frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>Button flags representing touch states for each controller button in the last frame</returns>
/// <seealso cref="UxrInputButtons" />
uint GetButtonTouchFlagsLastFrame(UxrHandSide handSide, bool getIgnoredInput = false);
/// <summary>
/// Gets an uint value representing press states for each the controller <see cref="UxrInputButtons" /> flags in the
/// current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>Button flags representing press states for each controller button in the current frame</returns>
/// <seealso cref="UxrInputButtons" />
uint GetButtonPressFlags(UxrHandSide handSide, bool getIgnoredInput = false);
/// <summary>
/// Gets an uint value representing press states for each the in the last frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>Button flags representing press states for each controller button in the last frame</returns>
/// <seealso cref="UxrInputButtons" />
uint GetButtonPressFlagsLastFrame(UxrHandSide handSide, bool getIgnoredInput = false);
/// <summary>
/// Checks if a given input event took place for a button or all buttons in a set in the current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">
/// Button (or buttons by flag composition) to check. If it's a combination, all buttons require to
/// meet the event criteria
/// </param>
/// <param name="buttonEventType">Input event type to check for</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given event happened during the current frame for the specified button. If more than one button
/// was specified by using flags it will return true only if the input event happened for all the given buttons.
/// </returns>
bool GetButtonsEvent(UxrHandSide handSide, UxrInputButtons buttons, UxrButtonEventType buttonEventType, bool getIgnoredInput = false);
/// <summary>
/// Checks if a given input event took place for a button or any button in a set in the current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">
/// Button (or buttons by flag composition) to check. If it's a combination, any button that meets
/// the event criteria will be enough
/// </param>
/// <param name="buttonEventType">Input event type to check for</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given event happened during the current frame for the specified button. If more than one button
/// was specified by using flags it will return true as long as any button had the event.
/// </returns>
bool GetButtonsEventAny(UxrHandSide handSide, UxrInputButtons buttons, UxrButtonEventType buttonEventType, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or all buttons in a set are being touched in the current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being touched in the current frame. If more than one button was specified by using
/// flags it will return true only if all are being touched.
/// </returns>
bool GetButtonsTouch(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or any button in a set is being touched in the current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being touched in the current frame. If more than one button was specified by using
/// flags it will return true if any button in the set is being touched.
/// </returns>
bool GetButtonsTouchAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or buttons are being touched in the current frame but weren't the previous frame
/// (touch-down).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is just started being touched in the current frame. If more than one button was specified
/// by using flags it will return true only if all meet the condition.
/// </returns>
bool GetButtonsTouchDown(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or any button in a set is being touched in the current frame but not in the previous
/// frame (touch-down).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is just started being touched in the current frame. If more than one button was specified
/// by using flags it will return true if any meets the condition.
/// </returns>
bool GetButtonsTouchDownAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or buttons aren't being touched in the current frame but were during the previous frame
/// (release touch).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being released from touching in the current frame. If more than one button was
/// specified by using flags it will return true only if all meet the condition.
/// </returns>
bool GetButtonsTouchUp(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or any button in a set isn't being touched in the current frame but was during the
/// previous frame (release touch).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being released from touching in the current frame. If more than one button was
/// specified by using flags it will return true as long as any meets the condition.
/// </returns>
bool GetButtonsTouchUpAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or buttons are being pressed in the current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being pressed in the current frame. If more than one button was specified by using
/// flags it will return true only if all are being pressed.
/// </returns>
bool GetButtonsPress(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or any button in a set is being pressed in the current frame.
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being pressed in the current frame. If more than one button was specified by using
/// flags it will return true as long as any is being pressed.
/// </returns>
bool GetButtonsPressAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or buttons are being pressed in the current frame but weren't the previous frame
/// (press-down).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is just started being pressed in the current frame. If more than one button was specified
/// by using flags it will return true only if all meet the condition.
/// </returns>
bool GetButtonsPressDown(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or any button in a set is being pressed in the current frame but wasn't the previous
/// frame (press-down).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is just started being pressed in the current frame. If more than one button was specified
/// by using flags it will return true only if any meets the condition.
/// </returns>
bool GetButtonsPressDownAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or buttons aren't being pressed in the current frame but were during the previous frame
/// (release press).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being released from pressing in the current frame. If more than one button was
/// specified by using flags it will return true only if all meet the condition.
/// </returns>
bool GetButtonsPressUp(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Checks if the given button or any button in a set isn't being pressed in the current frame but was during the
/// previous frame (release press).
/// </summary>
/// <param name="handSide">
/// Which controller to get input from. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="buttons">Button (or buttons by flag composition) to check</param>
/// <param name="getIgnoredInput">Whether to return ignored input by <see cref="SetIgnoreControllerInput" /></param>
/// <returns>
/// True if the given button is being released from pressing in the current frame. If more than one button was
/// specified by using flags it will return true if any meets the condition.
/// </returns>
bool GetButtonsPressUpAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false);
/// <summary>
/// Sends haptic feedback to a controller if the controller supports it.
/// </summary>
/// <param name="handSide">
/// Which controller to send the haptic feedback to. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="hapticClip">Clip to send</param>
void SendHapticFeedback(UxrHandSide handSide, UxrHapticClip hapticClip);
/// <summary>
/// Sends haptic feedback to a controller if the controller supports it.
/// </summary>
/// <param name="handSide">
/// Which controller to send the haptic feedback to. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="frequency">Frequency of the feedback in hz</param>
/// <param name="amplitude">Amplitude of the feedback between range [0.0, 1.0]</param>
/// <param name="durationSeconds">Feedback duration in seconds</param>
/// <param name="hapticMode">The mode (stop and override all current haptics or mix it with the current existing haptics)</param>
void SendHapticFeedback(UxrHandSide handSide,
float frequency,
float amplitude,
float durationSeconds,
UxrHapticMode hapticMode = UxrHapticMode.Mix);
/// <summary>
/// Sends a predefined haptic clip to a controller.
/// </summary>
/// <param name="handSide">
/// Which controller to send the haptic feedback to. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="clipType">The clip type from a set of predefined clips</param>
/// <param name="amplitude">The intensity of the haptic feedback</param>
/// <param name="durationSeconds">The duration in seconds. A zero/negative value will use a default duration.</param>
/// <param name="hapticMode">Whether the clip will stop all currently playing haptics or mix with them</param>
public void SendHapticFeedback(UxrHandSide handSide,
UxrHapticClipType clipType,
float amplitude,
float durationSeconds = -1.0f,
UxrHapticMode hapticMode = UxrHapticMode.Mix);
/// <summary>
/// Sends haptic feedback to XR controllers that are being used to manipulate a grabbable object.
/// Each hand associated to an XR controller that is grabbing the object will receive haptic feedback.
/// </summary>
/// <param name="grabbableObject">Grabbable object</param>
/// <param name="clipType">Clip type to send</param>
/// <param name="amplitude">Intensity of the haptic feedback</param>
/// <param name="durationSeconds">Duration in seconds</param>
/// <param name="hapticMode">Override current haptic feedback or mix it?</param>
public void SendGrabbableHapticFeedback(UxrGrabbableObject grabbableObject,
UxrHapticClipType clipType,
float amplitude,
float durationSeconds = -1.0f,
UxrHapticMode hapticMode = UxrHapticMode.Mix);
/// <summary>
/// Sends haptic feedback to XR controllers that are being used to manipulate a grabbable object.
/// Each hand associated to an XR controller that is grabbing the object will receive haptic feedback.
/// </summary>
/// <param name="grabbableObject">Grabbable object</param>
/// <param name="hapticClip">Haptic clip to send</param>
public void SendGrabbableHapticFeedback(UxrGrabbableObject grabbableObject, UxrHapticClip hapticClip);
/// <summary>
/// Stops all current haptics in a given controller.
/// </summary>
/// <param name="handSide">
/// Which controller to stop sending haptic feedback to. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
void StopHapticFeedback(UxrHandSide handSide);
/// <summary>
/// Gets the instanced controller 3D model for a given hand.
/// </summary>
/// <param name="handSide">
/// Which controller to get the 3D model of. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
UxrController3DModel GetController3DModel(UxrHandSide handSide);
/// <summary>
/// Returns a list of GameObjects that represent parts of the instantiated controller. This can be useful
/// to highlight buttons or other elements during tutorials.
/// Functionality to make these elements blink is also provided by the framework.
/// </summary>
/// <param name="handSide">
/// Which controller to get the elements of. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="controllerElements">Element (or elements using flags) to retrieve the GameObject(s) for</param>
/// <returns>A list of GameObject, one for each element requested</returns>
/// <seealso cref="StartControllerElementsBlinking" />
/// <seealso cref="StopControllerElementsBlinking" />
/// <seealso cref="StopAllBlinking" />
/// <seealso cref="IsAnyControllerElementBlinking" />
/// <seealso cref="AreAllControllerElementsBlinking" />
IEnumerable<GameObject> GetControllerElementsGameObjects(UxrHandSide handSide, UxrControllerElements controllerElements);
/// <summary>
/// Starts blinking one or more elements in a controller. This can be useful during tutorials to highlight which
/// button(s) to press.
/// </summary>
/// <param name="handSide">
/// Which controller. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="controllerElements">Element (or elements using flags) that should blink</param>
/// <param name="emissionColor">
/// Emission color use to blink. Usually it can be set to white with a mid alpha value to avoid
/// too much brightness
/// </param>
/// <param name="blinksPerSec">Blinks per second</param>
/// <param name="durationSeconds">Duration in seconds that it should blink</param>
/// <seealso cref="GetControllerElementsGameObjects" />
/// <seealso cref="StopControllerElementsBlinking" />
/// <seealso cref="StopAllBlinking" />
/// <seealso cref="IsAnyControllerElementBlinking" />
/// <seealso cref="AreAllControllerElementsBlinking" />
void StartControllerElementsBlinking(UxrHandSide handSide,
UxrControllerElements controllerElements,
Color emissionColor,
float blinksPerSec = 3.0f,
float durationSeconds = -1.0f);
/// <summary>
/// Stops controller elements to blink
/// </summary>
/// <param name="handSide">
/// Which controller. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="controllerElements">Element (or elements using flags) that should stop blinking</param>
/// <seealso cref="GetControllerElementsGameObjects" />
/// <seealso cref="StartControllerElementsBlinking" />
/// <seealso cref="StopAllBlinking" />
/// <seealso cref="IsAnyControllerElementBlinking" />
/// <seealso cref="AreAllControllerElementsBlinking" />
void StopControllerElementsBlinking(UxrHandSide handSide, UxrControllerElements controllerElements);
/// <summary>
/// Stops all controller elements to blink
/// </summary>
/// <param name="handSide">
/// Which controller. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <seealso cref="GetControllerElementsGameObjects" />
/// <seealso cref="StartControllerElementsBlinking" />
/// <seealso cref="StopControllerElementsBlinking" />
/// <seealso cref="IsAnyControllerElementBlinking" />
/// <seealso cref="AreAllControllerElementsBlinking" />
void StopAllBlinking(UxrHandSide handSide);
/// <summary>
/// Checks if any specific controller element is currently blinking
/// </summary>
/// <param name="handSide">
/// Which controller. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="controllerElements">Element (or elements using flags) that should be checked</param>
/// <returns>True if any of the given elements is blinking</returns>
/// <seealso cref="GetControllerElementsGameObjects" />
/// <seealso cref="StartControllerElementsBlinking" />
/// <seealso cref="StopControllerElementsBlinking" />
/// <seealso cref="StopAllBlinking" />
/// <seealso cref="AreAllControllerElementsBlinking" />
bool IsAnyControllerElementBlinking(UxrHandSide handSide, UxrControllerElements controllerElements);
/// <summary>
/// Checks if all elements of a specific controller element are currently blinking
/// </summary>
/// <param name="handSide">
/// Which controller. In <see cref="UxrControllerSetupType.Single" /> devices where
/// <see cref="IsHandednessSupported" /> is false, such as in gamepads, both hands will address the single device.
/// </param>
/// <param name="controllerElements">Element (or elements using flags) that should be checked</param>
/// <returns>True if all of the given elements are blinking</returns>
/// <seealso cref="GetControllerElementsGameObjects" />
/// <seealso cref="StartControllerElementsBlinking" />
/// <seealso cref="StopControllerElementsBlinking" />
/// <seealso cref="StopAllBlinking" />
/// <seealso cref="IsAnyControllerElementBlinking" />
bool AreAllControllerElementsBlinking(UxrHandSide handSide, UxrControllerElements controllerElements);
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 018d0996b6db42708de31cb550c16688
timeCreated: 1623869089

View File

@@ -0,0 +1,22 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IUxrControllerInputUpdater.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace UltimateXR.Devices
{
/// <summary>
/// Internal interface to be able to update controller states only from the UltimateXR assembly.
/// </summary>
internal interface IUxrControllerInputUpdater
{
#region Public Methods
/// <summary>
/// Updates the input state.
/// </summary>
void UpdateInput();
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8803bd8d1c0b41f886f44c8db3162329
timeCreated: 1623948920

View File

@@ -0,0 +1,81 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IUxrControllerTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UnityEngine;
namespace UltimateXR.Devices
{
/// <summary>
/// Controller tracking interface for all VR input devices, supporting single controllers and dual controller setups.
/// </summary>
public interface IUxrControllerTracking
{
#region Public Types & Data
/// <summary>
/// Gets the type of the input controller component that handles input for the same kind of controller this component
/// handles the tracking for.
/// </summary>
Type RelatedControllerInputType { get; }
/// <summary>
/// Gets whether the camera of the tracking setup has 6 degrees of freedom
/// </summary>
bool HeadsetIs6Dof { get; }
/// <summary>
/// Gets if the left hand sensor in the component inspector has been set up
/// </summary>
bool HasLeftHandSensorSetup { get; }
/// <summary>
/// Gets if the right hand sensor in the component inspector has been set up
/// </summary>
bool HasRightHandSensorSetup { get; }
/// <summary>
/// Gets the world-space position of the left controller sensor.
/// </summary>
Vector3 SensorLeftPos { get; }
/// <summary>
/// Gets the world-space position of the right controller sensor.
/// </summary>
Vector3 SensorRightPos { get; }
/// <summary>
/// Gets the world-space rotation of the left controller sensor.
/// </summary>
Quaternion SensorLeftRot { get; }
/// <summary>
/// Gets the world-space rotation of the right controller sensor.
/// </summary>
Quaternion SensorRightRot { get; }
/// <summary>
/// Gets the world-space position where the left hand bone should be, using the left sensor data.
/// </summary>
Vector3 SensorLeftHandPos { get; }
/// <summary>
/// Gets the world-space position where the right hand bone should be, using the right sensor data.
/// </summary>
Vector3 SensorRightHandPos { get; }
/// <summary>
/// Gets the world-space rotation that the left hand bone should have using the left sensor data.
/// </summary>
Quaternion SensorLeftHandRot { get; }
/// <summary>
/// Gets the world-space rotation that the right hand bone should have using the right sensor data.
/// </summary>
Quaternion SensorRightHandRot { get; }
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c6981f02714143445ab49885ae53c070
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IUxrDevice.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices
{
/// <summary>
/// Interface for VR devices, mainly designed to abstract tracking/input devices.
/// </summary>
public interface IUxrDevice
{
#region Public Types & Data
/// <summary>
/// Event called whenever the device is connected or disconnected
/// </summary>
event EventHandler<UxrDeviceConnectEventArgs> DeviceConnected;
/// <summary>
/// Gets the SDK the implemented device needs in order to be available.
/// It should be null or empty if there is no SDK dependency. Otherwise is should use any of the SDK names in
/// <see cref="UxrManager" />. For example if requires the Oculus SDK, it should return
/// <see cref="UxrConstants.SdkOculus" />.
/// </summary>
string SDKDependency { get; }
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ee460a37faca4b859f529fb605cc0674
timeCreated: 1623869076

View File

@@ -0,0 +1,39 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IUxrTrackingDevice.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
namespace UltimateXR.Devices
{
/// <summary>
/// Interface for tracking devices.
/// </summary>
public interface IUxrTrackingDevice : IUxrDevice
{
#region Public Types & Data
/// <summary>
/// Event called right before updating sensor data.
/// </summary>
event EventHandler SensorsUpdating;
/// <summary>
/// Event called right after updating sensor data.
/// </summary>
event EventHandler SensorsUpdated;
/// <summary>
/// Event called right before updating an avatar with the current sensor data.
/// </summary>
event EventHandler AvatarUpdating;
/// <summary>
/// Event called right after updating an avatar with the current sensor data.
/// </summary>
event EventHandler AvatarUpdated;
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5cb414fd58964cf0adf5fca3e80e33ac
timeCreated: 1623869113

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IUxrTrackingUpdater.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace UltimateXR.Devices
{
/// <summary>
/// Internal interface to be able to update the tracking information only from the UltimateXR assembly.
/// </summary>
internal interface IUxrTrackingUpdater
{
#region Public Methods
/// <summary>
/// Updates the sensor information
/// </summary>
void UpdateSensors();
/// <summary>
/// Updates the avatar using the current sensor information
/// </summary>
void UpdateAvatar();
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8e06d850879a4fd689fc9820731b8d22
timeCreated: 1623948856

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 832e6197d4b89214eb31fd28f93035c5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 32f22795408987f42bb073e358835363
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHpReverbG2Input.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.Microsoft;
namespace UltimateXR.Devices.Integrations.HP
{
/// <summary>
/// HP Reverb G2 Input.
/// </summary>
public class UxrHpReverbG2Input : UxrWindowsMixedRealityInput
{
#region Public Overrides UxrWindowsMixedRealityInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "HP Reverb G2 Controller";
yield return "HP Reverb G2 Controller OpenXR";
}
}
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Joystick2 |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cd7aa825077847641b535866ae4258b9
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHpReverbG2Tracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.Microsoft;
namespace UltimateXR.Devices.Integrations.HP
{
/// <summary>
/// Tracking component for HP Reverb G2.
/// </summary>
public class UxrHpReverbG2Tracking : UxrWindowsMixedRealityTracking
{
#region Public Overrides UxrWindowsMixedRealityTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrHpReverbG2Input);
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 85e5b3a94d5599c4982fe887142e1201
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e7ef432f4a08f6348b5b1e4e3ca778e4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHtcViveCosmosInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.HTC
{
/// <summary>
/// HTC Vive Cosmos controllers input using SteamVR.
/// </summary>
public class UxrHtcViveCosmosInput : UxrSteamVRControllerInput
{
#region Public Overrides UxrSteamVRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get { yield return ControllerNameHtcViveCosmos; }
}
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
UxrControllerElements.Grip | // Grip
UxrControllerElements.Bumper | // Bumper
UxrControllerElements.Trigger | // Trigger
UxrControllerElements.Button1 | // Button A/X
UxrControllerElements.Button2 | // Button B/Y
UxrControllerElements.DPad); // Joystick
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
/// <inheritdoc />
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
{
return UxrControllerInputCapabilities.HapticImpulses;
}
#endregion
#region Private Types & Data
private const string ControllerNameHtcViveCosmos = "vive_cosmos_controller";
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: aeb548548ec3cdb489de559527782aee
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHtcViveCosmosTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.HTC
{
/// <summary>
/// Tracking for HTC Vive Cosmos controllers using SteamVR SDK.
/// </summary>
public class UxrHtcViveCosmosTracking : UxrSteamVRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrHtcViveCosmosInput);
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7aaab42f00bf7ad4bb5388a08c575a4d
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,85 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHtcViveFocus3Input.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.HTC
{
/// <summary>
/// HTC Vive Focus 3 controller input using WaveXR SDK's UnityXR support.
/// </summary>
public class UxrHtcViveFocus3Input : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: Wave XR.
/// </summary>
public override string SDKDependency => UxrConstants.SdkWaveXR;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Right)
{
// Remove menu button from right controller, which is reserved.
validElements = validElements & ~(uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "WVR_CR_Left_001";
yield return "WVR_CR_Right_001";
}
}
#endregion
#region Protected Overrides UxrUnityXRControllerInput
/// <inheritdoc />
protected override void UpdateInput()
{
base.UpdateInput();
// To avoid grip requiring to press the whole button, we use the analog value and a threshold
float gripThreshold = 0.7f;
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Grip, GetInput1D(UxrHandSide.Left, UxrInput1D.Grip) > gripThreshold);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Grip, GetInput1D(UxrHandSide.Right, UxrInput1D.Grip) > gripThreshold);
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99f34313b313be54fa63910a496c06a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHtcViveFocus3Tracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.HTC
{
/// <summary>
/// Tracking for HTC Vive Focus 3 controllers using WaveXR SDK's UnityXR support.
/// </summary>
public class UxrHtcViveFocus3Tracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrHtcViveFocus3Input);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkWaveXR;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 74d5790b838df3441b94784597d32e7a
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHtcViveInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.HTC
{
/// <summary>
/// HTC Vive controllers input using SteamVR.
/// </summary>
public class UxrHtcViveInput : UxrSteamVRControllerInput
{
#region Public Overrides UxrSteamVRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "controller_vive";
yield return "Vive. Controller MV";
yield return "Vive. Controller Pro MV";
yield return "VIVE Controller MV";
yield return "VIVE Controller Pro MV";
}
}
/// <inheritdoc />
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
{
// Since Vive controllers don't have an analog grip button, make sure the analog
// grip functionality is supported.
if (input1D == UxrInput1D.Grip)
{
return GetButtonsPress(handSide, UxrInputButtons.Grip, getIgnoredInput) ? 1.0f : 0.0f;
}
return 0.0f;
}
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => true;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
UxrControllerElements.Grip | // Grip
UxrControllerElements.Trigger | // Trigger
UxrControllerElements.Button1 | // Button A,
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad); // Joystick
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
/// <inheritdoc />
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
{
return UxrControllerInputCapabilities.HapticImpulses;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9ab26074711a00449bb89e018281422d
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHtcViveTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.HTC
{
/// <summary>
/// Tracking for HTC Vive controllers using SteamVR SDK.
/// </summary>
public class UxrHtcViveTracking : UxrSteamVRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrHtcViveInput);
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f9f613010cce8f0408243773fe913d9f
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 570a4a7e3a0905c42a29df863535996b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,126 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMagicLeap2Input.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.MagicLeap
{
/// <summary>
/// Magic Leap 2 controller input using Magic Leap SDK.
/// </summary>
public class UxrMagicLeap2Input : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: Magic Leap 2.
/// </summary>
public override string SDKDependency => UxrConstants.SdkMagicLeap;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => true;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Trigger |
UxrControllerElements.Grip |
UxrControllerElements.Bumper |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get { yield return "MagicLeap Controller"; }
}
#endregion
#region Event Trigger Methods
/// <inheritdoc />
protected override void OnDeviceConnected(UxrDeviceConnectEventArgs e)
{
base.OnDeviceConnected(e);
#if ULTIMATEXR_USE_MAGICLEAP_SDK
if (e.IsConnected)
{
_mlInputs = new MagicLeapInputs();
_mlInputs.Enable();
}
else
{
if (_mlInputs != null)
{
_mlInputs.Dispose();
_mlInputs = null;
}
}
#endif
}
#endregion
#region Protected Overrides UxrUnityXRControllerInput
/// <inheritdoc />
protected override void UpdateInput()
{
base.UpdateInput();
// Propagate touchpad touch to press, since only touch is signaled by the API
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, GetButtonsTouch(UxrHandSide.Left, UxrInputButtons.Joystick));
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Joystick, GetButtonsTouch(UxrHandSide.Right, UxrInputButtons.Joystick));
}
/// <inheritdoc />
protected override bool HasButtonContactOther(UxrHandSide handSide, UxrInputButtons button, ButtonContact buttonContact)
{
#if ULTIMATEXR_USE_MAGICLEAP_SDK
if (button == UxrInputButtons.Bumper)
{
return _mlInputs.Controller.Bumper.IsPressed();
}
// To allow quick integration with UltimateXR manipulation, and since the ML2 doesn't have a grip button, we map
// the bumper to the grip too.
if (button == UxrInputButtons.Grip)
{
return _mlInputs.Controller.Bumper.IsPressed();
}
#endif
return false;
}
#endregion
#region Private Types & Data
#if ULTIMATEXR_USE_MAGICLEAP_SDK
private MagicLeapInputs _mlInputs;
#endif
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3110ba3566d315a41af6c0e8535ee19b
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMagicLeap2Tracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.MagicLeap
{
/// <summary>
/// Tracking for Magic Leap 2 devices using the Magic Leap SDK.
/// </summary>
public class UxrMagicLeap2Tracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrMagicLeap2Input);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override bool IsMixedRealityDevice => true;
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkMagicLeap;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 207d5725f18c1eb4eaba95a17cdf1794
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dc2e3b5030e4f874b8db7909c4b35781
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaHandTracking.FlipMode.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace UltimateXR.Devices.Integrations.Meta
{
public partial class UxrMetaHandTracking
{
#region Private Types & Data
/// <summary>
/// Enumerates the different ways to retrieve an Oculus SDK Quaternion.
/// </summary>
private enum FlipMode
{
None,
FlipX,
FlipZ
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 42cd7d7680024864810a8c3cf3a42dbc
timeCreated: 1654777476

View File

@@ -0,0 +1,266 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaHandTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core;
#if ULTIMATEXR_USE_OCULUS_SDK
using UltimateXR.Avatar.Rig;
using UltimateXR.Core.Math;
using UltimateXR.Extensions.Unity.Math;
using UnityEngine;
#endif
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Hand tracking for Meta devices.
/// </summary>
public partial class UxrMetaHandTracking : UxrHandTracking
{
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkOculus;
#endregion
#region Public Overrides UxrHandTracking
/// <inheritdoc />
public override bool IsLeftHandAvailable
{
get
{
#if ULTIMATEXR_USE_OCULUS_SDK
if (OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandLeft, ref _leftHandState))
{
_isLeftHandAvailable = _leftHandState.Status.HasFlag(OVRPlugin.HandStatus.HandTracked);
}
else
{
_isLeftHandAvailable = false;
}
return _isLeftHandAvailable;
#else
return false;
#endif
}
}
/// <inheritdoc />
public override bool IsRightHandAvailable
{
get
{
#if ULTIMATEXR_USE_OCULUS_SDK
if (OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandRight, ref _rightHandState))
{
_isRightHandAvailable = _rightHandState.Status.HasFlag(OVRPlugin.HandStatus.HandTracked);
}
else
{
_isRightHandAvailable = false;
}
return _isRightHandAvailable;
#else
return false;
#endif
}
}
#endregion
#region Unity
/// <summary>
/// Subscribes to events so that the component can be enabled or disabled based on the presence of hand tracking.
/// </summary>
protected override void Awake()
{
base.Awake();
#if ULTIMATEXR_USE_OCULUS_SDK
// Initialize axis system
if (Avatar != null && Avatar.LeftHand.HasFullHandData())
{
_leftHandOculusRotation = Quaternion.LookRotation(Vector3.right, -Vector3.up);
_leftFingerOculusRotation = Quaternion.LookRotation(-Vector3.right, -Vector3.up);
}
if (Avatar != null && Avatar.RightHand.HasFullHandData())
{
_rightHandOculusRotation = Quaternion.LookRotation(Vector3.right, Vector3.up);
_rightFingerOculusRotation = Quaternion.LookRotation(Vector3.right, Vector3.up);
}
#endif
}
#endregion
#region Protected Overrides UxrTrackingDevice
/// <inheritdoc />
protected override void UpdateSensors()
{
#if ULTIMATEXR_USE_OCULUS_SDK
_isLeftHandAvailable = OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandLeft, ref _leftHandState);
_isRightHandAvailable = OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandRight, ref _rightHandState);
#endif
}
/// <inheritdoc />
protected override void UpdateAvatar()
{
#if ULTIMATEXR_USE_OCULUS_SDK
Transform wristLeft = Avatar.LeftHandBone;
Transform wristRight = Avatar.RightHandBone;
if (_isLeftHandAvailable && wristLeft != null)
{
if (UseCalibration)
{
SetCalibrationPose(UxrHandSide.Left);
}
UxrAvatarArmInfo leftArmInfo = Avatar.AvatarRigInfo.GetArmInfo(UxrHandSide.Left);
UxrUniversalLocalAxes leftHandParentAxes = wristLeft.parent == Avatar.AvatarRig.LeftArm.Forearm ? leftArmInfo.ForearmUniversalLocalAxes : leftArmInfo.HandUniversalLocalAxes;
Vector3 sensorLeftPos = Avatar.transform.TransformPoint(_leftHandState.RootPose.Position.FromFlippedZVector3f());
Quaternion sensorLeftRot = Avatar.transform.rotation * ToCorrectCoordinateSystem(_leftHandState.RootPose.Orientation, FlipMode.FlipZ, _leftHandOculusRotation, leftHandParentAxes, leftArmInfo.HandUniversalLocalAxes);
wristLeft.position = sensorLeftPos;
wristLeft.rotation = sensorLeftRot;
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Index, OVRPlugin.BoneId.Hand_Index1, 3, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Middle, OVRPlugin.BoneId.Hand_Middle1, 3, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Ring, OVRPlugin.BoneId.Hand_Ring1, 3, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Little, OVRPlugin.BoneId.Hand_Pinky0, 4, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Thumb, OVRPlugin.BoneId.Hand_Thumb0, 4, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
}
if (_isRightHandAvailable && wristRight != null)
{
if (UseCalibration)
{
SetCalibrationPose(UxrHandSide.Right);
}
UxrAvatarArmInfo rightArmInfo = Avatar.AvatarRigInfo.GetArmInfo(UxrHandSide.Right);
UxrUniversalLocalAxes rightHandParentAxes = wristRight.parent == Avatar.AvatarRig.RightArm.Forearm ? rightArmInfo.ForearmUniversalLocalAxes : rightArmInfo.HandUniversalLocalAxes;
Vector3 sensorRightPos = Avatar.transform.TransformPoint(_rightHandState.RootPose.Position.FromFlippedZVector3f());
Quaternion sensorRightRot = Avatar.transform.rotation * ToCorrectCoordinateSystem(_rightHandState.RootPose.Orientation, FlipMode.FlipZ, _rightHandOculusRotation, rightHandParentAxes, rightArmInfo.HandUniversalLocalAxes);
wristRight.position = sensorRightPos;
wristRight.rotation = sensorRightRot;
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Index, OVRPlugin.BoneId.Hand_Index1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Middle, OVRPlugin.BoneId.Hand_Middle1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Ring, OVRPlugin.BoneId.Hand_Ring1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Little, OVRPlugin.BoneId.Hand_Pinky1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Thumb, OVRPlugin.BoneId.Hand_Thumb0, 4, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
}
#endif
}
#endregion
#if ULTIMATEXR_USE_OCULUS_SDK
/// <summary>
/// Updates a finger using tracking information.
/// </summary>
/// <param name="handSide">Which hand the finger belongs to</param>
/// <param name="avatarFinger">The avatar finger to update</param>
/// <param name="baseBoneId">The oculus bone base id</param>
/// <param name="boneCount">The number of bones to update, usually 2, 3 or 4</param>
/// <param name="fingerOculusRotation">Oculus finger coordinate system</param>
/// <param name="wristUniversalLocalAxes">Avatar wrist coordinate system</param>
/// <param name="fingerUniversalLocalAxes">Avatar finger coordinate system</param>
private void UpdateFinger(UxrHandSide handSide, UxrAvatarFinger avatarFinger, OVRPlugin.BoneId baseBoneId, int boneCount, Quaternion fingerOculusRotation, UxrUniversalLocalAxes wristUniversalLocalAxes, UxrUniversalLocalAxes fingerUniversalLocalAxes)
{
int baseIndex = (int)baseBoneId;
OVRPlugin.HandState handState = handSide == UxrHandSide.Left ? _leftHandState : _rightHandState;
FlipMode flipMode = handSide == UxrHandSide.Left ? FlipMode.FlipX : FlipMode.FlipZ;
if (boneCount > 3)
{
if (avatarFinger.Metacarpal != null)
{
avatarFinger.Metacarpal.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex], flipMode, fingerOculusRotation, wristUniversalLocalAxes, fingerUniversalLocalAxes);
ApplyBoneCalibration(avatarFinger.Metacarpal);
}
baseIndex++;
}
if (boneCount > 2)
{
avatarFinger.Proximal.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex], flipMode, fingerOculusRotation, avatarFinger.Metacarpal == null ? wristUniversalLocalAxes : fingerUniversalLocalAxes, fingerUniversalLocalAxes);
ApplyBoneCalibration(avatarFinger.Proximal);
baseIndex++;
}
avatarFinger.Intermediate.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex], flipMode, fingerOculusRotation, fingerUniversalLocalAxes, fingerUniversalLocalAxes);
avatarFinger.Distal.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex + 1], flipMode, fingerOculusRotation, fingerUniversalLocalAxes, fingerUniversalLocalAxes);
ApplyBoneCalibration(avatarFinger.Intermediate);
ApplyBoneCalibration(avatarFinger.Distal);
}
/// <summary>
/// Converts a rotation from the Oculus SDK coordinate system to the avatar coordinate system.
/// </summary>
/// <param name="oculusRotation">Oculus rotation to convert</param>
/// <param name="flipRotation">How to process the rotation</param>
/// <param name="oculusAxes">
/// Information that converts from the "universal" coordinate system to the coordinate
/// system used by the parent's node.
/// </param>
/// <param name="parentUniversalLocalAxes"></param>
/// <param name="universalLocalAxes">
/// Information that converts from the "universal" coordinate system to the coordinate
/// system used by the node.
/// </param>
/// <returns>Rotation in the avatar coordinate system</returns>
private Quaternion ToCorrectCoordinateSystem(OVRPlugin.Quatf oculusRotation, FlipMode flipRotation, Quaternion oculusAxes, UxrUniversalLocalAxes parentUniversalLocalAxes, UxrUniversalLocalAxes universalLocalAxes)
{
Quaternion rotation = oculusRotation.FromQuatf();
switch (flipRotation)
{
case FlipMode.FlipX:
rotation = oculusRotation.FromFlippedXQuatf();
break;
case FlipMode.FlipZ:
rotation = oculusRotation.FromFlippedZQuatf();
break;
}
Quaternion finalRotation = Quaternion.Inverse(parentUniversalLocalAxes.UniversalToActualAxesRotation) * universalLocalAxes.UniversalToActualAxesRotation * rotation * Quaternion.Inverse(oculusAxes) * universalLocalAxes.UniversalToActualAxesRotation;
return finalRotation.IsValid() ? finalRotation : Quaternion.identity;
}
#endif
#if ULTIMATEXR_USE_OCULUS_SDK
private bool _isLeftHandAvailable;
private bool _isRightHandAvailable;
private OVRPlugin.HandState _leftHandState;
private OVRPlugin.HandState _rightHandState;
private Quaternion _leftHandOculusRotation;
private Quaternion _rightHandOculusRotation;
private Quaternion _leftFingerOculusRotation;
private Quaternion _rightFingerOculusRotation;
#endif
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5d33e531453e48da93053497271b4abd
timeCreated: 1654764133

View File

@@ -0,0 +1,72 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest2Input.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Oculus Touch controller input using Oculus SDK.
/// </summary>
public class UxrMetaTouchQuest2Input : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: Oculus SDK.
/// </summary>
public override string SDKDependency => UxrConstants.SdkOculus;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.ThumbCapSense |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Right)
{
// Remove menu button from right controller, which is reserved.
validElements = validElements & ~(uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
if (UxrTrackingDevice.HeadsetDeviceName is "Oculus Quest2")
{
yield return "Oculus Touch Controller - Left";
yield return "Oculus Touch Controller - Right";
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4ff66b86132a55f4a9f6efea46da64bb
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest2InputSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Oculus Touch controllers input using SteamVR.
/// </summary>
public class UxrMetaTouchQuest2InputSteamVR : UxrSteamVRControllerInput
{
#region Public Overrides UxrSteamVRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "Oculus Quest2 (Left Controller)";
yield return "Oculus Quest2 (Right Controller)";
}
}
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
UxrControllerElements.Grip | // Grip
UxrControllerElements.Trigger | // Trigger
UxrControllerElements.Button1 | // Button A
UxrControllerElements.Button2 | // Button B
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Left)
{
validElements |= (uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
/// <inheritdoc />
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
{
return UxrControllerInputCapabilities.HapticImpulses;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e34315eb5a4f11d41ade48a0c1a86715
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest2Tracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Tracking for Oculus Touch devices using the Oculus SDK.
/// </summary>
public class UxrMetaTouchQuest2Tracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest2Input);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkOculus;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 793d8fce02a8c7a42a9414fb6f5d3dc1
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest2TrackingSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Tracking for Oculus Touch controllers using SteamVR SDK.
/// </summary>
public class UxrMetaTouchQuest2TrackingSteamVR : UxrSteamVRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest2InputSteamVR);
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 813e0bb28152bed4ea5c634099e04934
timeCreated: 1624443263

View File

@@ -0,0 +1,72 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest3Input.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Oculus Touch controller input using Oculus SDK.
/// </summary>
public class UxrMetaTouchQuest3Input : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: Oculus SDK.
/// </summary>
public override string SDKDependency => UxrConstants.SdkOculus;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.ThumbCapSense |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Right)
{
// Remove menu button from right controller, which is reserved.
validElements = validElements & ~(uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
if (UxrTrackingDevice.HeadsetDeviceName is "Oculus Quest3" or "Meta Quest 3" or "Oculus Headset2")
{
yield return "Oculus Touch Controller - Left";
yield return "Oculus Touch Controller - Right";
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fd07cb58266720f478deb9264c45c614
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest3InputSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Oculus Touch controllers input using SteamVR.
/// </summary>
public class UxrMetaTouchQuest3InputSteamVR : UxrSteamVRControllerInput
{
#region Public Overrides UxrSteamVRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "Oculus Quest3 (Left Controller)";
yield return "Oculus Quest3 (Right Controller)";
yield return "Meta Quest 3 (Left Controller)";
yield return "Meta Quest 3 (Right Controller)";
}
}
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
UxrControllerElements.Grip | // Grip
UxrControllerElements.Trigger | // Trigger
UxrControllerElements.Button1 | // Button A
UxrControllerElements.Button2 | // Button B
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Left)
{
validElements |= (uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
/// <inheritdoc />
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
{
return UxrControllerInputCapabilities.HapticImpulses;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a0acc555071f36c4fb74251d9a25c5ae
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest3Tracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Tracking for Oculus Touch devices using the Oculus SDK.
/// </summary>
public class UxrMetaTouchQuest3Tracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest3Input);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkOculus;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6cc855f608e72a745b7a79e8ca93ba67
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrMetaTouchQuest3TrackingSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Meta
{
/// <summary>
/// Tracking for Oculus Touch controllers using SteamVR SDK.
/// </summary>
public class UxrMetaTouchQuest3TrackingSteamVR : UxrSteamVRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest3InputSteamVR);
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 07ea441b9add1fd4fb72713dd14725cb
timeCreated: 1624443263

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 30f0aa17591f44647ac57e3b104cc1dc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrWindowsMixedRealityInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UnityEngine;
namespace UltimateXR.Devices.Integrations.Microsoft
{
/// <summary>
/// Windows Mixed Reality input using Unity XR.
/// </summary>
public class UxrWindowsMixedRealityInput : UxrUnityXRControllerInput
{
#region Inspector Properties/Serialized Fields
[Header("Windows Mixed Reality:")] [SerializeField] private float _joystickDeadZone = 0.15f;
#endregion
#region Public Overrides UxrControllerInput
/// <summary>
/// Requires WMR SDK using OpenXR.
/// </summary>
public override string SDKDependency => UxrConstants.SdkWindowsMixedReality;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override float JoystickDeadZone => _joystickDeadZone;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Joystick2 |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "Windows MR Controller";
yield return "Windows MR Controller OpenXR";
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3e6fba2dada135740a5cc23e3c44ab6b
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrWindowsMixedRealityTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Microsoft
{
/// <summary>
/// Tracking component for devices based on Windows Mixed Reality.
/// </summary>
public class UxrWindowsMixedRealityTracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrWindowsMixedRealityInput);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkWindowsMixedReality;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6e44a53324016f44da8b9fb0183ace63
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6e1369784c4dde144b2b46e73bd11505
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Oculus Touch controller input using Oculus SDK.
/// </summary>
public class UxrOculusTouchRiftInput : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: Oculus SDK.
/// </summary>
public override string SDKDependency => UxrConstants.SdkOculus;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.ThumbCapSense |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Right)
{
// Remove menu button from right controller, which is reserved.
validElements = validElements & ~(uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
if (UxrTrackingDevice.HeadsetDeviceName == "Oculus Rift CV1")
{
yield return "Oculus Touch Controller - Left";
yield return "Oculus Touch Controller - Right";
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7e00e8773baf4604392a82350eee8671
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftInputSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Oculus Touch controllers input using SteamVR.
/// </summary>
public class UxrOculusTouchRiftInputSteamVR : UxrSteamVRControllerInput
{
#region Public Overrides UxrSteamVRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "Oculus Rift CV1 (Left Controller)";
yield return "Oculus Rift CV1 (Right Controller)";
}
}
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
UxrControllerElements.Grip | // Grip
UxrControllerElements.Trigger | // Trigger
UxrControllerElements.Button1 | // Button A
UxrControllerElements.Button2 | // Button B
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Left)
{
validElements |= (uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
/// <inheritdoc />
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
{
return UxrControllerInputCapabilities.HapticImpulses;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e41f3824310273441b1a66dc33fc3bc6
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftSQuestInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Oculus Touch controller input using Oculus SDK.
/// </summary>
public class UxrOculusTouchRiftSQuestInput : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: Oculus SDK.
/// </summary>
public override string SDKDependency => UxrConstants.SdkOculus;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.ThumbCapSense |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Right)
{
// Remove menu button from right controller, which is reserved.
validElements = validElements & ~(uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
if (UxrTrackingDevice.HeadsetDeviceName is "Oculus Rift S" or "Oculus Quest")
{
yield return "Oculus Touch Controller - Left";
yield return "Oculus Touch Controller - Right";
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c97b7d15f1e96f445a4e33190f9a5020
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftSQuestInputSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Oculus Touch controllers input using SteamVR.
/// </summary>
public class UxrOculusTouchRiftSQuestInputSteamVR : UxrSteamVRControllerInput
{
#region Public Overrides UxrSteamVRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "Oculus Quest (Left Controller)";
yield return "Oculus Quest (Right Controller)";
yield return "Oculus Rift S (Left Controller)";
yield return "Oculus Rift S (Right Controller)";
}
}
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
UxrControllerElements.Grip | // Grip
UxrControllerElements.Trigger | // Trigger
UxrControllerElements.Button1 | // Button A
UxrControllerElements.Button2 | // Button B
UxrControllerElements.DPad);
if (handSide == UxrHandSide.Left)
{
validElements |= (uint)UxrControllerElements.Menu;
}
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
/// <inheritdoc />
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
{
return UxrControllerInputCapabilities.HapticImpulses;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 46ee2d04c77b0bd4383d6231da50d980
timeCreated: 1499677449
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftSQuestTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Tracking for Oculus Touch devices using the Oculus SDK.
/// </summary>
public class UxrOculusTouchRiftSQuestTracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftSQuestInput);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkOculus;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1d9733f867143cc499549d95ef911b9b
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftSQuestTrackingSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Tracking for Oculus Touch controllers using SteamVR SDK.
/// </summary>
public class UxrOculusTouchRiftSQuestTrackingSteamVR : UxrSteamVRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftSQuestInputSteamVR);
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f6d431e33dfaa8a49b2c2572cdf2c202
timeCreated: 1624443263

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Tracking for Oculus Touch devices using the Oculus SDK.
/// </summary>
public class UxrOculusTouchRiftTracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftInput);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkOculus;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8c997e1e44845a44599cad72e2f63768
timeCreated: 1499842642
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrOculusTouchRiftTrackingSteamVR.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Devices.Integrations.SteamVR;
namespace UltimateXR.Devices.Integrations.Oculus
{
/// <summary>
/// Tracking for Oculus Touch controllers using SteamVR SDK.
/// </summary>
public class UxrOculusTouchRiftTrackingSteamVR : UxrSteamVRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftInputSteamVR);
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d9f2ab5b48994c7b933178d3fea37f60
timeCreated: 1624443263

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 836a0efbc8d36a546be3937cb7d41b41
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrPicoNeo3Input.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Pico
{
/// <summary>
/// Pico Neo 3 controller input using PicoXR SDK.
/// </summary>
public class UxrPicoNeo3Input : UxrUnityXRControllerInput
{
#region Public Overrides UxrControllerInput
/// <summary>
/// Gets the SDK dependency: PicoXR.
/// </summary>
public override string SDKDependency => UxrConstants.SdkPicoXR;
/// <inheritdoc />
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <inheritdoc />
public override bool MainJoystickIsTouchpad => false;
/// <inheritdoc />
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
{
uint validElements = (uint)(UxrControllerElements.Joystick |
UxrControllerElements.Grip |
UxrControllerElements.Trigger |
UxrControllerElements.Button1 |
UxrControllerElements.Button2 |
UxrControllerElements.Menu |
UxrControllerElements.Back |
UxrControllerElements.DPad);
return (validElements & (uint)controllerElements) == (uint)controllerElements;
}
#endregion
#region Public Overrides UxrUnityXRControllerInput
/// <inheritdoc />
public override IEnumerable<string> ControllerNames
{
get
{
yield return "PicoXR Controller-Left";
yield return "PicoXR Controller-Right";
yield return "PICO Controller-Left";
yield return "PICO Controller-Right";
yield return "PICO Live Preview Controller-Left";
yield return "PICO Live Preview Controller-Right";
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0343e6207db6ea84a9a8d40c5170d7f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrPicoNeo3Tracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
namespace UltimateXR.Devices.Integrations.Pico
{
/// <summary>
/// Tracking for Pico Neo 3 devices using the PicoXR SDK.
/// </summary>
public class UxrPicoNeo3Tracking : UxrUnityXRControllerTracking
{
#region Public Overrides UxrControllerTracking
/// <inheritdoc />
public override Type RelatedControllerInputType => typeof(UxrPicoNeo3Input);
#endregion
#region Public Overrides UxrTrackingDevice
/// <inheritdoc />
public override string SDKDependency => UxrConstants.SdkPicoXR + "";
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91427e7abc5228c44af202060dafa3af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d71f258a02cff25498b3607eb0dcc4e8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrSteamVRConstants.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace UltimateXR.Devices.Integrations.SteamVR
{
/// <summary>
/// SteamVR constants needed across our framework. At runtime and also for editor classes.
/// </summary>
public static class UxrSteamVRConstants
{
#region Public Types & Data
public const string ActionSetName = "ultimatexr";
public const string ActionNameHandSkeletonLeft = "hand_left_skeleton";
public const string ActionNameHandSkeletonRight = "hand_right_skeleton";
public const string ActionNameHandHaptics = "hand_haptics";
public const string BindingInputClick = "click";
public const string BindingInputTouch = "touch";
public const string BindingVarBool = "boolean";
public const string BindingVarVector1 = "vector1";
public const string BindingVarVector2 = "vector2";
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4b308562c7bd4762ba25e88f5f3a5aa4
timeCreated: 1623420066

View File

@@ -0,0 +1,658 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrSteamVRControllerInput.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Avatar.Controllers;
using UltimateXR.Core;
using UltimateXR.Haptics;
using UnityEngine;
#if ULTIMATEXR_USE_STEAMVR_SDK
using System;
using System.Linq;
using System.Text;
using Valve.VR;
using UltimateXR.Avatar.Rig;
using UltimateXR.Core.Settings;
using UltimateXR.Manipulation;
#endif
#pragma warning disable 414 // Disable warnings due to unused values
namespace UltimateXR.Devices.Integrations.SteamVR
{
/// <summary>
/// Base class for all SteamVR input devices.
/// Provides common input handling thanks to using the actions exported by the
/// SteamVRActionsExporter.
/// Child classes will require some overrides and minimal input handling if necessary.
/// </summary>
public abstract class UxrSteamVRControllerInput : UxrControllerInput
{
#region Inspector Properties/Serialized Fields
// These will be shown only in custom inspectors for controllers that use them (f.e. index controllers).
[SerializeField] [HideInInspector] private string _openHandPoseName;
[SerializeField] [HideInInspector] private float _indexCurlAmount = 60.0f;
[SerializeField] [HideInInspector] private float _middleCurlAmount = 60.0f;
[SerializeField] [HideInInspector] private float _ringCurlAmount = 60.0f;
[SerializeField] [HideInInspector] private float _littleCurlAmount = 60.0f;
[SerializeField] [HideInInspector] private float _thumbCurlAmount = 60.0f;
[SerializeField] [HideInInspector] private float _thumbSpreadAmount = 30.0f;
#endregion
#region Public Types & Data
/// <summary>
/// Gets list of controller names that the component can handle.
/// </summary>
public abstract IEnumerable<string> ControllerNames { get; }
/// <summary>
/// Gets if the class will use hand skeletons.
/// </summary>
public virtual bool UsesHandSkeletons => false;
#endregion
#region Public Overrides UxrControllerInput
/// <inheritdoc />
public override bool IsHandednessSupported => true;
/// <summary>
/// SteamVR child classes will require SteamVR SDK to access functionality.
/// </summary>
public override string SDKDependency => UxrConstants.SdkSteamVR;
/// <inheritdoc />
public override bool IsControllerEnabled(UxrHandSide handSide)
{
#if ULTIMATEXR_USE_STEAMVR_SDK
if (s_controllerList.TryGetValue(GetType().Name, out List<int> controllerIndices))
{
return controllerIndices.Contains(handSide == UxrHandSide.Left
? (int)OpenVR.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.LeftHand)
: (int)OpenVR.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.RightHand));
}
return false;
#else
return false;
#endif
}
/// <inheritdoc />
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
{
if (ShouldIgnoreInput(handSide, getIgnoredInput))
{
return 0.0f;
}
#if ULTIMATEXR_USE_STEAMVR_SDK
SteamVR_Input_Sources source = handSide == UxrHandSide.Left ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand;
if (_actionsInput1D.TryGetValue(input1D, out SteamVR_Action_Single action))
{
return action[source].axis;
}
#endif
return 0.0f;
}
/// <inheritdoc />
public override Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false)
{
if (ShouldIgnoreInput(handSide, getIgnoredInput))
{
return Vector2.zero;
}
#if ULTIMATEXR_USE_STEAMVR_SDK
SteamVR_Input_Sources source = handSide == UxrHandSide.Left ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand;
if (_actionsInput2D.TryGetValue(input2D, out SteamVR_Action_Vector2 action))
{
return FilterTwoAxesDeadZone(action[source].axis, JoystickDeadZone);
}
#endif
return Vector2.zero;
}
/// <inheritdoc />
public override void SendHapticFeedback(UxrHandSide handSide, UxrHapticClip hapticClip)
{
if (hapticClip.FallbackClipType != UxrHapticClipType.None)
{
SendHapticFeedback(handSide, hapticClip.FallbackClipType, hapticClip.FallbackAmplitude, hapticClip.FallbackDurationSeconds, hapticClip.HapticMode);
}
}
/// <inheritdoc />
public override void SendHapticFeedback(UxrHandSide handSide,
float frequency,
float amplitude,
float durationSeconds,
UxrHapticMode hapticMode = UxrHapticMode.Mix)
{
#if ULTIMATEXR_USE_STEAMVR_SDK
SteamVR_Input_Sources source = handSide == UxrHandSide.Left ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand;
_handHapticsAction.Execute(0.0f, durationSeconds, frequency, amplitude, source);
#endif
}
/// <inheritdoc />
public override void StopHapticFeedback(UxrHandSide handSide)
{
// TODO. Doesn't seem to be supported.
}
#endregion
#region Unity
/// <summary>
/// Takes care of registering the component in the global list of SteamVR input components.
/// Builds the action list to access input and starts listening for device connections.
/// </summary>
protected override void Awake()
{
base.Awake();
#if ULTIMATEXR_USE_STEAMVR_SDK
// Build actions
BuildActionObjects();
if (enabled)
{
// Listen to device connected events
SteamVR_Events.DeviceConnected.Remove(OnDeviceConnected);
SteamVR_Events.DeviceConnected.Listen(OnDeviceConnected);
}
_awakeFinished = true;
if (enabled)
{
// Disabled by default at the beginning, unless we already these controllers registered.
// If we already have the controllers registered it is due to an Awake() when loading a new scene.
enabled = s_controllerList.TryGetValue(InputClassName, out List<int> controllerIndices) && controllerIndices.Count > 0;
RaiseConnectOnStart = enabled;
if (!s_initializedSteamVR)
{
global::Valve.VR.SteamVR.Initialize();
SteamVR_Input.GetActionSet(UxrSteamVRConstants.ActionSetName).Activate();
s_initializedSteamVR = true;
}
}
#else
enabled = false;
#endif
}
/// <summary>
/// Called when the component is disabled. In the case the component was using skeletal
/// input, the hand will be driven by the Avatar Animator back again.
/// </summary>
protected override void OnDisable()
{
base.OnDisable();
if (UsesHandSkeletons)
{
if (!_awakeFinished || !UxrManager.Instance || !Avatar || !Avatar.AvatarController)
{
return;
}
UxrStandardAvatarController standardAvatarController = Avatar.AvatarController as UxrStandardAvatarController;
if (standardAvatarController == null)
{
return;
}
if (!string.IsNullOrEmpty(_openHandPoseName))
{
standardAvatarController.LeftHandDefaultPoseNameOverride = null;
standardAvatarController.RightHandDefaultPoseNameOverride = null;
standardAvatarController.LeftHandGrabPoseNameOverride = null;
standardAvatarController.RightHandGrabPoseNameOverride = null;
}
}
}
/// <summary>
/// Initializes SteamVR if necessary and activates the UltimateXR action set.
/// Will initialize skeleton functionality if necessary.
/// </summary>
protected override void Start()
{
base.Start();
#if ULTIMATEXR_USE_STEAMVR_SDK
if (UsesHandSkeletons)
{
_handSkeletonActionLeft.SetSkeletalTransformSpace(EVRSkeletalTransformSpace.Model);
_handSkeletonActionRight.SetSkeletalTransformSpace(EVRSkeletalTransformSpace.Model);
}
#endif
}
/// <summary>
/// If the component has skeleton capabilities, the hand bones will be updated here.
/// </summary>
private void LateUpdate()
{
if (Avatar == null)
{
}
#if ULTIMATEXR_USE_STEAMVR_SDK
// Update using skeleton if necessary
if (UsesHandSkeletons)
{
UxrStandardAvatarController avatarControllerStandard = Avatar.AvatarController as UxrStandardAvatarController;
UxrAvatarRig avatarRig = Avatar.AvatarRig;
if (avatarControllerStandard == null)
{
return;
}
float curlIndex = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.index] * _indexCurlAmount;
float curlMiddle = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.middle] * _middleCurlAmount;
float curlRing = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.ring] * _ringCurlAmount;
float curlLittle = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.pinky] * _littleCurlAmount;
float curlThumb = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbCurlAmount;
float splayThumb = _handSkeletonActionLeft.fingerSplays[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbSpreadAmount;
if (!UxrGrabManager.Instance.IsHandGrabbing(Avatar, UxrHandSide.Left) && !avatarControllerStandard.IsLeftHandInsideFingerPointingVolume)
{
if (!string.IsNullOrEmpty(_openHandPoseName))
{
avatarControllerStandard.LeftHandDefaultPoseNameOverride = _openHandPoseName;
avatarControllerStandard.LeftHandGrabPoseNameOverride = _openHandPoseName;
Avatar.SetCurrentHandPoseImmediately(UxrHandSide.Left, _openHandPoseName);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Index, curlIndex, curlIndex, curlIndex);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Middle, curlMiddle, curlMiddle, curlMiddle);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Ring, curlRing, curlRing, curlRing);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Little, curlLittle, curlLittle, curlLittle);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Thumb, curlThumb * 0.1f, curlThumb * 0.3f, curlThumb * 1.0f, splayThumb);
}
}
else
{
if (!string.IsNullOrEmpty(_openHandPoseName))
{
avatarControllerStandard.LeftHandDefaultPoseNameOverride = null;
}
}
curlIndex = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.index] * _indexCurlAmount;
curlMiddle = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.middle] * _middleCurlAmount;
curlRing = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.ring] * _ringCurlAmount;
curlLittle = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.pinky] * _littleCurlAmount;
curlThumb = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbCurlAmount;
splayThumb = _handSkeletonActionRight.fingerSplays[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbSpreadAmount;
if (!UxrGrabManager.Instance.IsHandGrabbing(Avatar, UxrHandSide.Right) && !avatarControllerStandard.IsRightHandInsideFingerPointingVolume)
{
if (!string.IsNullOrEmpty(_openHandPoseName))
{
avatarControllerStandard.RightHandDefaultPoseNameOverride = _openHandPoseName;
avatarControllerStandard.RightHandGrabPoseNameOverride = _openHandPoseName;
Avatar.SetCurrentHandPoseImmediately(UxrHandSide.Right, _openHandPoseName);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Index, curlIndex, curlIndex, curlIndex);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Middle, curlMiddle, curlMiddle, curlMiddle);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Ring, curlRing, curlRing, curlRing);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Little, curlLittle, curlLittle, curlLittle);
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Thumb, curlThumb * 0.1f, curlThumb * 0.3f, curlThumb * 1.0f, splayThumb);
}
}
else
{
if (!string.IsNullOrEmpty(_openHandPoseName))
{
avatarControllerStandard.RightHandDefaultPoseNameOverride = null;
}
}
}
#endif
}
#endregion
#region Protected Overrides UxrControllerInput
/// <summary>
/// Updates the complete input state using our common SteamVR actions. This allows to use the same interface
/// for all controllers and enables the implementation of new devices with minimal effort.
/// </summary>
protected override void UpdateInput()
{
base.UpdateInput();
// Get joystick values
Vector2 leftJoystickValue = GetInput2D(UxrHandSide.Left, UxrInput2D.Joystick);
Vector2 rightJoystickValue = GetInput2D(UxrHandSide.Right, UxrInput2D.Joystick);
Vector2 leftJoystick2Value = GetInput2D(UxrHandSide.Left, UxrInput2D.Joystick2);
Vector2 rightJoystick2Value = GetInput2D(UxrHandSide.Right, UxrInput2D.Joystick2);
#if ULTIMATEXR_USE_STEAMVR_SDK
var system = OpenVR.System;
if (system == null)
{
return;
}
// Update buttons
foreach (UxrInputButtons button in Enum.GetValues(typeof(UxrInputButtons)))
{
if (button != UxrInputButtons.None && button != UxrInputButtons.Any && button != UxrInputButtons.Everything)
{
SetButtonFlags(ButtonFlags.PressFlagsLeft, button, _actionsButtonClick[button][SteamVR_Input_Sources.LeftHand].state);
SetButtonFlags(ButtonFlags.PressFlagsRight, button, _actionsButtonClick[button][SteamVR_Input_Sources.RightHand].state);
SetButtonFlags(ButtonFlags.TouchFlagsLeft, button, _actionsButtonTouch[button][SteamVR_Input_Sources.LeftHand].state);
SetButtonFlags(ButtonFlags.TouchFlagsRight, button, _actionsButtonTouch[button][SteamVR_Input_Sources.RightHand].state);
}
}
#endif
// These ones are mainly for teleporting functionality when we don't get touch values out of joysticks:
if (leftJoystickValue != Vector2.zero && leftJoystickValue.magnitude > AnalogAsDPadThreshold)
{
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Joystick, true);
}
if (rightJoystickValue != Vector2.zero && rightJoystickValue.magnitude > AnalogAsDPadThreshold)
{
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Joystick, true);
}
// Same for joystick2 just in case
if (leftJoystick2Value != Vector2.zero && leftJoystick2Value.magnitude > AnalogAsDPadThreshold)
{
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Joystick2, true);
}
if (rightJoystick2Value != Vector2.zero && rightJoystick2Value.magnitude > AnalogAsDPadThreshold)
{
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Joystick2, true);
}
// Update joystick/DPad direction buttons using joystick analog value and pressed state
uint leftDirectionFlags = GetButtonFlags(MainJoystickIsTouchpad ? ButtonFlags.PressFlagsLeft : ButtonFlags.TouchFlagsLeft);
if (leftJoystickValue != Vector2.zero && leftJoystickValue.magnitude > AnalogAsDPadThreshold && (leftDirectionFlags & (int)UxrInputButtons.Joystick) != 0)
{
float leftJoystickAngle = Input2DToAngle(leftJoystickValue);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, IsInput2dDPadLeft(leftJoystickAngle));
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, IsInput2dDPadRight(leftJoystickAngle));
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, IsInput2dDPadUp(leftJoystickAngle));
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, IsInput2dDPadDown(leftJoystickAngle));
}
else
{
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, false);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, false);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, false);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, false);
}
uint leftButtonPressFlags = GetButtonFlags(ButtonFlags.PressFlagsLeft);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, (leftButtonPressFlags & (uint)UxrInputButtons.DPadLeft) != 0);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, (leftButtonPressFlags & (uint)UxrInputButtons.DPadRight) != 0);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, (leftButtonPressFlags & (uint)UxrInputButtons.DPadUp) != 0);
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, (leftButtonPressFlags & (uint)UxrInputButtons.DPadDown) != 0);
uint rightDirectionFlags = GetButtonFlags(MainJoystickIsTouchpad ? ButtonFlags.PressFlagsRight : ButtonFlags.TouchFlagsRight);
if (rightJoystickValue != Vector2.zero && rightJoystickValue.magnitude > AnalogAsDPadThreshold && (rightDirectionFlags & (int)UxrInputButtons.Joystick) != 0)
{
float rightJoystickAngle = Input2DToAngle(rightJoystickValue);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadLeft, IsInput2dDPadLeft(rightJoystickAngle));
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadRight, IsInput2dDPadRight(rightJoystickAngle));
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadUp, IsInput2dDPadUp(rightJoystickAngle));
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadDown, IsInput2dDPadDown(rightJoystickAngle));
}
else
{
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadLeft, false);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadRight, false);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadUp, false);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadDown, false);
}
uint rightButtonPressFlags = GetButtonFlags(ButtonFlags.PressFlagsRight);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickLeft, (rightButtonPressFlags & (uint)UxrInputButtons.DPadLeft) != 0);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickRight, (rightButtonPressFlags & (uint)UxrInputButtons.DPadRight) != 0);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickUp, (rightButtonPressFlags & (uint)UxrInputButtons.DPadUp) != 0);
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickDown, (rightButtonPressFlags & (uint)UxrInputButtons.DPadDown) != 0);
}
#endregion
#region Private Types & Data
private string InputClassName => GetType().Name;
// Global data
private static readonly Dictionary<string, List<int>> s_controllerList = new Dictionary<string, List<int>>();
private static bool s_initializedSteamVR;
// Local data
private bool _awakeFinished;
#endregion
#if ULTIMATEXR_USE_STEAMVR_SDK
/// <summary>
/// Given a controller name, gets a list of controller names using the Virtual Desktop controller naming convention.
/// </summary>
/// <param name="controllerName">Controller name to get the virtual desktop controller names for</param>
/// <returns>List of virtual desktop controller names</returns>
private static IEnumerable<string> GetVirtualDesktopWrappedControllerNames(string controllerName)
{
yield return $"OpenVR Controller({controllerName}) - Left";
yield return $"OpenVR Controller({controllerName}) - Right";
}
/// <summary>
/// Called when a SteamVR device is connected
/// </summary>
/// <param name="index">Device index</param>
/// <param name="connected">True if connected, false if disconnected</param>
private static void OnDeviceConnected(int index, bool connected)
{
if (OpenVR.System == null)
{
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Errors)
{
Debug.LogError($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: OpenVR.System is null");
}
return;
}
if (OpenVR.System.GetTrackedDeviceClass((uint)index) != ETrackedDeviceClass.Controller)
{
// Ignore devices that aren't controllers
return;
}
var renderModelName = new StringBuilder(ModelNameMaxLength);
var error = ETrackedPropertyError.TrackedProp_Success;
OpenVR.System.GetStringTrackedDeviceProperty((uint)index, ETrackedDeviceProperty.Prop_ModelNumber_String, renderModelName, ModelNameMaxLength, ref error);
string modelNameString = renderModelName.ToString();
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
{
Debug.Log($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: connected={connected}, model={modelNameString}");
}
IEnumerable<UxrSteamVRControllerInput> inputsSteamVR = AllComponents.Where(i => i is UxrSteamVRControllerInput).Cast<UxrSteamVRControllerInput>();
UxrSteamVRControllerInput inputSteamVR = inputsSteamVR.FirstOrDefault(i =>
i.ControllerNames.Any(n => string.Equals(n, modelNameString)) || i.ControllerNames.SelectMany(GetVirtualDesktopWrappedControllerNames).Any(n => string.Equals(n, modelNameString)));
if (inputSteamVR != null)
{
// Model is one of the registered SteamVR inputs and needs to be processed
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
{
Debug.Log($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: Device name {modelNameString} was registered by {inputSteamVR.InputClassName} and is being processed!");
}
if (!s_controllerList.TryGetValue(inputSteamVR.InputClassName, out List<int> controllerIndices))
{
controllerIndices = new List<int>();
s_controllerList.Add(inputSteamVR.InputClassName, controllerIndices);
}
if (connected)
{
// Connected
controllerIndices.Add(index);
if (inputSteamVR.enabled == false)
{
// First controller: Notify device is connected since we consider the device the whole setup
inputSteamVR.enabled = true;
inputSteamVR.OnDeviceConnected(new UxrDeviceConnectEventArgs(true));
}
}
else
{
// Disconnected
controllerIndices.Remove(index);
if (controllerIndices.Count == 0)
{
// Last controller disconnected: Notify device is disconnected.
inputSteamVR.enabled = false;
inputSteamVR.OnDeviceConnected(new UxrDeviceConnectEventArgs(false));
}
}
}
else
{
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
{
Debug.Log($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: Device is not recognized as input by any of {inputsSteamVR.Count()} components");
}
}
}
/// <summary>
/// Gets the action bound to the given button and input type.
/// </summary>
/// <param name="button">Button to look for</param>
/// <param name="inputType">Type of input to handle. Use <see cref="UxrSteamVRConstants" />.</param>
/// <returns>
/// Action bound to the given button and input type. If the button doesn't exist
/// in the current controller it will return a fake action showing no input
/// </returns>
private static SteamVR_Action_Boolean GetButtonAction(UxrInputButtons button, string inputType)
{
return SteamVR_Input.GetAction<SteamVR_Action_Boolean>(UxrSteamVRConstants.ActionSetName, $"{button.ToString().ToLower()}_{inputType}_{UxrSteamVRConstants.BindingVarBool}");
}
/// <summary>
/// Gets the action bound to the given <see cref="UxrInput1D" />.
/// </summary>
/// <param name="input1D">Element to look for</param>
/// <returns>
/// Action bound to the given 1D input. If the element doesn't exist in the current controller it will return a
/// fake action showing no input
/// </returns>
private static SteamVR_Action_Single GetInput1DAction(UxrInput1D input1D)
{
return SteamVR_Input.GetAction<SteamVR_Action_Single>(UxrSteamVRConstants.ActionSetName, $"{input1D.ToString().ToLower()}_{UxrSteamVRConstants.BindingVarVector1}");
}
/// <summary>
/// Gets the action bound to the given <see cref="UxrInput2D" />.
/// </summary>
/// <param name="input2D">Element to look for</param>
/// <returns>
/// Action bound to the given 2D input. If the element doesn't exist in the current controller it will return a fake
/// action showing no input
/// </returns>
private static SteamVR_Action_Vector2 GetInput2DAction(UxrInput2D input2D)
{
return SteamVR_Input.GetAction<SteamVR_Action_Vector2>(UxrSteamVRConstants.ActionSetName, $"{input2D.ToString().ToLower()}_{UxrSteamVRConstants.BindingVarVector2}");
}
/// <summary>
/// Builds all action objects needed to check for input using SteamVR.
/// We use enumeration of all elements inside an Enum to build our action list and,
/// thanks to the functionality of SteamVR, when an action doesn't exist it will
/// generate a fake action showing no input.
/// </summary>
private void BuildActionObjects()
{
// Buttons
foreach (UxrInputButtons button in Enum.GetValues(typeof(UxrInputButtons)))
{
if (button != UxrInputButtons.None && button != UxrInputButtons.Any && button != UxrInputButtons.Everything)
{
_actionsButtonClick.Add(button, GetButtonAction(button, UxrSteamVRConstants.BindingInputClick));
_actionsButtonTouch.Add(button, GetButtonAction(button, UxrSteamVRConstants.BindingInputTouch));
}
}
// UxrInput1D
foreach (UxrInput1D input1D in Enum.GetValues(typeof(UxrInput1D)))
{
if (input1D != UxrInput1D.None)
{
_actionsInput1D.Add(input1D, GetInput1DAction(input1D));
}
}
// UxrInput2D
foreach (UxrInput2D input2D in Enum.GetValues(typeof(UxrInput2D)))
{
if (input2D != UxrInput2D.None)
{
_actionsInput2D.Add(input2D, GetInput2DAction(input2D));
}
}
}
#endif
#if ULTIMATEXR_USE_STEAMVR_SDK
private const int ModelNameMaxLength = 256;
private readonly Dictionary<UxrInputButtons, SteamVR_Action_Boolean> _actionsButtonClick = new Dictionary<UxrInputButtons, SteamVR_Action_Boolean>();
private readonly Dictionary<UxrInputButtons, SteamVR_Action_Boolean> _actionsButtonTouch = new Dictionary<UxrInputButtons, SteamVR_Action_Boolean>();
private readonly Dictionary<UxrInput1D, SteamVR_Action_Single> _actionsInput1D = new Dictionary<UxrInput1D, SteamVR_Action_Single>();
private readonly Dictionary<UxrInput2D, SteamVR_Action_Vector2> _actionsInput2D = new Dictionary<UxrInput2D, SteamVR_Action_Vector2>();
private readonly SteamVR_Action_Skeleton _handSkeletonActionLeft = SteamVR_Input.GetAction<SteamVR_Action_Skeleton>(UxrSteamVRConstants.ActionSetName, UxrSteamVRConstants.ActionNameHandSkeletonLeft);
private readonly SteamVR_Action_Skeleton _handSkeletonActionRight = SteamVR_Input.GetAction<SteamVR_Action_Skeleton>(UxrSteamVRConstants.ActionSetName, UxrSteamVRConstants.ActionNameHandSkeletonRight);
private readonly SteamVR_Action_Vibration _handHapticsAction = SteamVR_Input.GetAction<SteamVR_Action_Vibration>(UxrSteamVRConstants.ActionSetName, UxrSteamVRConstants.ActionNameHandHaptics);
#endif
}
}
#pragma warning restore 414 // Restore warnings due to unused values

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e95eafbdf5bd474e8b9b19b85ed37f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrSteamVRControllerTracking.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core;
#if ULTIMATEXR_USE_STEAMVR_SDK
using Valve.VR;
#endif
namespace UltimateXR.Devices.Integrations.SteamVR
{
/// <summary>
/// Base class for tracking devices that use SteamVR.
/// </summary>
public abstract class UxrSteamVRControllerTracking : UxrControllerTracking
{
#region Public Overrides UxrTrackingDevice
/// <summary>
/// Gets SDK dependency. SteamVR tracking devices require SteamVR SDK installed.
/// </summary>
public override string SDKDependency => UxrConstants.SdkSteamVR;
#endregion
#region MonoBehaviour
/// <summary>
/// Subscribes to SteamVR pose update events
/// </summary>
protected override void OnEnable()
{
base.OnEnable();
#if ULTIMATEXR_USE_STEAMVR_SDK
global::Valve.VR.SteamVR.Initialize();
if (global::Valve.VR.SteamVR.initializedState is global::Valve.VR.SteamVR.InitializedStates.Initializing or global::Valve.VR.SteamVR.InitializedStates.InitializeSuccess)
{
if (poseAction != null)
{
poseAction[SteamVR_Input_Sources.LeftHand].onUpdate += PoseAction_OnUpdate;
poseAction[SteamVR_Input_Sources.RightHand].onUpdate += PoseAction_OnUpdate;
}
}
#endif
}
/// <summary>
/// Subscribes from SteamVR pose update events
/// </summary>
protected override void OnDisable()
{
base.OnDisable();
#if ULTIMATEXR_USE_STEAMVR_SDK
if (global::Valve.VR.SteamVR.initializedState is global::Valve.VR.SteamVR.InitializedStates.Initializing or global::Valve.VR.SteamVR.InitializedStates.InitializeSuccess)
{
if (poseAction != null)
{
poseAction[SteamVR_Input_Sources.LeftHand].onUpdate -= PoseAction_OnUpdate;
poseAction[SteamVR_Input_Sources.RightHand].onUpdate -= PoseAction_OnUpdate;
}
}
#endif
}
#endregion
#region Event Handling Methods
#if ULTIMATEXR_USE_STEAMVR_SDK
/// <summary>
/// Handles the pose action update
/// </summary>
/// <param name="fromAction">The action that triggered the event</param>
/// <param name="fromSource">The source that was updated</param>
private void PoseAction_OnUpdate(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource)
{
if (fromSource == SteamVR_Input_Sources.LeftHand)
{
UpdateSensor(UxrHandSide.Left, poseAction[fromSource].localPosition, poseAction[fromSource].localRotation);
}
else if (fromSource == SteamVR_Input_Sources.RightHand)
{
UpdateSensor(UxrHandSide.Right, poseAction[fromSource].localPosition, poseAction[fromSource].localRotation);
}
}
#endif
#endregion
#region Private types & Data
#if ULTIMATEXR_USE_STEAMVR_SDK
private readonly SteamVR_Action_Pose poseAction = SteamVR_Input.GetAction<SteamVR_Action_Pose>("Pose");
#endif
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ada8ee64cca041b7bab08de0867749c2
timeCreated: 1624002590

Some files were not shown because too many files have changed in this diff Show More