2023-03-28 13:24:16 -04:00
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
#if UNITY_INPUT_SYSTEM_ENABLE_XR & & ( ENABLE_VR | | UNITY_GAMECORE ) | | PACKAGE_DOCS_GENERATION
using System ;
using System.Collections.Generic ;
using UnityEngine.InputSystem.Layouts ;
using UnityEngine.InputSystem.Controls ;
using UnityEngine.XR ;
namespace UnityEngine.InputSystem.XR
{
/// <summary>
/// A set of static utilities for registering XR Input Devices externally.
/// </summary>
public static class XRUtilities
{
/// <summary>
/// A simple Regex pattern that allows InputDeviceMatchers to match to any version of the XRInput interface.
/// </summary>
public const string InterfaceMatchAnyVersion = "^(XRInput)" ;
/// <summary>
/// The initial, now deprecated interface for XRInput. This version handles button packing for Android differently from current.
/// </summary>
public const string InterfaceV1 = "XRInput" ;
/// <summary>
/// The current interface code sent with devices to identify as XRInput devices.
/// </summary>
public const string InterfaceCurrent = "XRInputV1" ;
}
// Sync to UnityXRInputFeatureType in IUnityXRInput.h
/// <summary>
/// The type of data a <see cref="XRFeatureDescriptor"/> exposes.
/// </summary>
public enum FeatureType
{
Custom = 0 ,
Binary ,
DiscreteStates ,
Axis1D ,
Axis2D ,
Axis3D ,
Rotation ,
Hand ,
Bone ,
Eyes
}
/// <summary>
/// Contextual strings that identify the contextual, cross-platform use that a feature represents. <see cref="UnityEngine.XR.CommonUsages"/> for a list of unity's built-in shared usages.
/// </summary>
#pragma warning disable 0649
[Serializable]
public struct UsageHint
{
public string content ;
}
//Sync to XRInputFeatureDefinition in XRInputDeviceDefinition.h
/// <summary>
/// Describes an individual input on a device, such as a trackpad, or button, or trigger.
/// </summary>
[Serializable]
public struct XRFeatureDescriptor
{
/// <summary>
/// The name of the feature.
/// </summary>
public string name ;
/// <summary>
/// The uses that this feature should represent, such as trigger, or grip, or touchpad.
/// </summary>
public List < UsageHint > usageHints ;
/// <summary>
/// The type of data this feature exposes.
/// </summary>
public FeatureType featureType ;
/// <summary>
/// The overall size of the feature. This is only filled in when the <see cref="featureType"/> is <see cref="FeatureType.Custom"/>.
/// </summary>
public uint customSize ;
}
//Sync to XRInputDeviceDefinition in XRInputDeviceDefinition.h
/// <summary>
/// Describes an input device: what it can do and how it should be used. These are reported during device connection, and help identify devices and map input data to the right controls.
/// </summary>
[Serializable]
public class XRDeviceDescriptor
{
/// <summary>
/// The name of the device.
/// </summary>
public string deviceName ;
/// <summary>
/// The manufacturer of the device.
/// </summary>
public string manufacturer ;
/// <summary>
/// The serial number of the device. An empty string if no serial number is available.
/// </summary>
public string serialNumber ;
/// <summary>
/// The capabilities of the device, used to help filter and identify devices that server a certain purpose (e.g. controller, or headset, or hardware tracker).
/// </summary>
public InputDeviceCharacteristics characteristics ;
/// <summary>
/// The underlying deviceId, this can be used with <see cref="UnityEngine.XR.InputDevices"/> to create a device.
/// </summary>
public int deviceId ;
/// <summary>
/// A list of all input features. <seealso cref="XRFeatureDescriptor"/>
/// </summary>
public List < XRFeatureDescriptor > inputFeatures ;
/// <summary>
/// Converts this structure to a JSON string.
/// </summary>
/// <returns></returns>
public string ToJson ( )
{
return JsonUtility . ToJson ( this ) ;
}
/// <summary>
/// Converts a json string to a new <see cref="XRDeviceDescriptor"/>.
/// </summary>
/// <param name="json">The JSON string containing <see cref="XRDeviceDescriptor"/> data.</param>
/// <returns>A new <see cref="XRDeviceDescriptor"/></returns>
public static XRDeviceDescriptor FromJson ( string json )
{
return JsonUtility . FromJson < XRDeviceDescriptor > ( json ) ;
}
}
/// <summary>
/// Represents a 3 dimensional, tracked bone within a hierarchy of other bones.
/// </summary>
public struct Bone
{
/// <summary>
/// The index with the device's controls array where the parent bone resides.
/// </summary>
2023-05-07 18:43:11 -04:00
public uint m_ParentBoneIndex ;
2023-03-28 13:24:16 -04:00
/// <summary>
/// The tracked position of the bone.
/// </summary>
2023-05-07 18:43:11 -04:00
public Vector3 m_Position ;
2023-03-28 13:24:16 -04:00
/// <summary>
/// The tracked rotation of the bone.
/// </summary>
2023-05-07 18:43:11 -04:00
public Quaternion m_Rotation ;
/// <summary>
/// The index with the device's controls array where the parent bone resides.
/// </summary>
public uint parentBoneIndex
{
get = > m_ParentBoneIndex ;
set = > m_ParentBoneIndex = value ;
}
/// <summary>
/// The tracked position of the bone.
/// </summary>
public Vector3 position
{
get = > m_Position ;
set = > m_Position = value ;
}
/// <summary>
/// The tracked rotation of the bone.
/// </summary>
public Quaternion rotation
{
get = > m_Rotation ;
set = > m_Rotation = value ;
}
2023-03-28 13:24:16 -04:00
}
/// <summary>
/// Represents a pair of tracked eyes.
/// </summary>
public struct Eyes
{
/// <summary>
/// The tracked position of the left eye.
/// </summary>
2023-05-07 18:43:11 -04:00
public Vector3 m_LeftEyePosition ;
/// <summary>
/// The tracked rotation of the left eye.
/// </summary>
public Quaternion m_LeftEyeRotation ;
/// <summary>
/// The tracked position of the right eye.
/// </summary>
public Vector3 m_RightEyePosition ;
/// <summary>
/// The tracked rotation of the right eye.
/// </summary>
public Quaternion m_RightEyeRotation ;
/// <summary>
/// The point in 3D space that the pair of eyes is looking.
/// </summary>
public Vector3 m_FixationPoint ;
/// <summary>
/// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
/// </summary>
public float m_LeftEyeOpenAmount ;
/// <summary>
/// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
/// </summary>
public float m_RightEyeOpenAmount ;
/// <summary>
/// The tracked position of the left eye.
/// </summary>
public Vector3 leftEyePosition
{
get = > m_LeftEyePosition ;
set = > m_LeftEyePosition = value ;
}
2023-03-28 13:24:16 -04:00
/// <summary>
/// The tracked rotation of the left eye.
/// </summary>
2023-05-07 18:43:11 -04:00
public Quaternion leftEyeRotation
{
get = > m_LeftEyeRotation ;
set = > m_LeftEyeRotation = value ;
}
2023-03-28 13:24:16 -04:00
/// <summary>
/// The tracked position of the right eye.
/// </summary>
2023-05-07 18:43:11 -04:00
public Vector3 rightEyePosition
{
get = > m_RightEyePosition ;
set = > m_RightEyePosition = value ;
}
2023-03-28 13:24:16 -04:00
/// <summary>
/// The tracked rotation of the right eye.
/// </summary>
2023-05-07 18:43:11 -04:00
public Quaternion rightEyeRotation
{
get = > m_RightEyeRotation ;
set = > m_RightEyeRotation = value ;
}
2023-03-28 13:24:16 -04:00
/// <summary>
/// The point in 3D space that the pair of eyes is looking.
/// </summary>
2023-05-07 18:43:11 -04:00
public Vector3 fixationPoint
{
get = > m_FixationPoint ;
set = > m_FixationPoint = value ;
}
2023-03-28 13:24:16 -04:00
/// <summary>
/// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
/// </summary>
2023-05-07 18:43:11 -04:00
public float leftEyeOpenAmount
{
get = > m_LeftEyeOpenAmount ;
set = > m_LeftEyeOpenAmount = value ;
}
2023-03-28 13:24:16 -04:00
/// <summary>
/// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
/// </summary>
2023-05-07 18:43:11 -04:00
public float rightEyeOpenAmount
{
get = > m_RightEyeOpenAmount ;
set = > m_RightEyeOpenAmount = value ;
}
2023-03-28 13:24:16 -04:00
}
public class BoneControl : InputControl < Bone >
{
[InputControl(offset = 0, displayName = "parentBoneIndex")]
public IntegerControl parentBoneIndex { get ; private set ; }
[InputControl(offset = 4, displayName = "Position")]
public Vector3Control position { get ; private set ; }
[InputControl(offset = 16, displayName = "Rotation")]
public QuaternionControl rotation { get ; private set ; }
protected override void FinishSetup ( )
{
parentBoneIndex = GetChildControl < IntegerControl > ( "parentBoneIndex" ) ;
position = GetChildControl < Vector3Control > ( "position" ) ;
rotation = GetChildControl < QuaternionControl > ( "rotation" ) ;
base . FinishSetup ( ) ;
}
public override unsafe Bone ReadUnprocessedValueFromState ( void * statePtr )
{
return new Bone ( )
{
2023-05-07 18:43:11 -04:00
parentBoneIndex = ( uint ) parentBoneIndex . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
position = position . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
rotation = rotation . ReadUnprocessedValueFromStateWithCaching ( statePtr )
2023-03-28 13:24:16 -04:00
} ;
}
public override unsafe void WriteValueIntoState ( Bone value , void * statePtr )
{
parentBoneIndex . WriteValueIntoState ( ( int ) value . parentBoneIndex , statePtr ) ;
position . WriteValueIntoState ( value . position , statePtr ) ;
rotation . WriteValueIntoState ( value . rotation , statePtr ) ;
}
}
public class EyesControl : InputControl < Eyes >
{
[InputControl(offset = 0, displayName = "LeftEyePosition")]
public Vector3Control leftEyePosition { get ; private set ; }
[InputControl(offset = 12, displayName = "LeftEyeRotation")]
public QuaternionControl leftEyeRotation { get ; private set ; }
[InputControl(offset = 28, displayName = "RightEyePosition")]
public Vector3Control rightEyePosition { get ; private set ; }
[InputControl(offset = 40, displayName = "RightEyeRotation")]
public QuaternionControl rightEyeRotation { get ; private set ; }
[InputControl(offset = 56, displayName = "FixationPoint")]
public Vector3Control fixationPoint { get ; private set ; }
[InputControl(offset = 68, displayName = "LeftEyeOpenAmount")]
public AxisControl leftEyeOpenAmount { get ; private set ; }
[InputControl(offset = 72, displayName = "RightEyeOpenAmount")]
public AxisControl rightEyeOpenAmount { get ; private set ; }
protected override void FinishSetup ( )
{
leftEyePosition = GetChildControl < Vector3Control > ( "leftEyePosition" ) ;
leftEyeRotation = GetChildControl < QuaternionControl > ( "leftEyeRotation" ) ;
rightEyePosition = GetChildControl < Vector3Control > ( "rightEyePosition" ) ;
rightEyeRotation = GetChildControl < QuaternionControl > ( "rightEyeRotation" ) ;
fixationPoint = GetChildControl < Vector3Control > ( "fixationPoint" ) ;
leftEyeOpenAmount = GetChildControl < AxisControl > ( "leftEyeOpenAmount" ) ;
rightEyeOpenAmount = GetChildControl < AxisControl > ( "rightEyeOpenAmount" ) ;
base . FinishSetup ( ) ;
}
public override unsafe Eyes ReadUnprocessedValueFromState ( void * statePtr )
{
return new Eyes ( )
{
2023-05-07 18:43:11 -04:00
leftEyePosition = leftEyePosition . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
leftEyeRotation = leftEyeRotation . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
rightEyePosition = rightEyePosition . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
rightEyeRotation = rightEyeRotation . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
fixationPoint = fixationPoint . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
leftEyeOpenAmount = leftEyeOpenAmount . ReadUnprocessedValueFromStateWithCaching ( statePtr ) ,
rightEyeOpenAmount = rightEyeOpenAmount . ReadUnprocessedValueFromStateWithCaching ( statePtr )
2023-03-28 13:24:16 -04:00
} ;
}
public override unsafe void WriteValueIntoState ( Eyes value , void * statePtr )
{
leftEyePosition . WriteValueIntoState ( value . leftEyePosition , statePtr ) ;
leftEyeRotation . WriteValueIntoState ( value . leftEyeRotation , statePtr ) ;
rightEyePosition . WriteValueIntoState ( value . rightEyePosition , statePtr ) ;
rightEyeRotation . WriteValueIntoState ( value . rightEyeRotation , statePtr ) ;
fixationPoint . WriteValueIntoState ( value . fixationPoint , statePtr ) ;
leftEyeOpenAmount . WriteValueIntoState ( value . leftEyeOpenAmount , statePtr ) ;
rightEyeOpenAmount . WriteValueIntoState ( value . rightEyeOpenAmount , statePtr ) ;
}
}
#pragma warning restore 0649
/// <summary>
/// A small helper class to aid in initializing and registering XR devices and layout builders.
/// </summary>
#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
public
#else
internal
#endif
static class XRSupport
{
/// <summary>
/// Registers all initial templates and the generalized layout builder with the InputSystem.
/// </summary>
public static void Initialize ( )
{
#if ! UNITY_FORCE_INPUTSYSTEM_XR_OFF
InputSystem . RegisterLayout < PoseControl > ( "Pose" ) ;
InputSystem . RegisterLayout < BoneControl > ( "Bone" ) ;
InputSystem . RegisterLayout < EyesControl > ( "Eyes" ) ;
InputSystem . RegisterLayout < XRHMD > ( ) ;
InputSystem . RegisterLayout < XRController > ( ) ;
InputSystem . onFindLayoutForDevice + = XRLayoutBuilder . OnFindLayoutForDevice ;
// Built-in layouts replaced by the com.unity.xr.windowsmr package.
#if ! DISABLE_BUILTIN_INPUT_SYSTEM_WINDOWSMR
InputSystem . RegisterLayout < UnityEngine . XR . WindowsMR . Input . WMRHMD > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "(Windows Mixed Reality HMD)|(Microsoft HoloLens)|(^(WindowsMR Headset))" )
) ;
InputSystem . RegisterLayout < UnityEngine . XR . WindowsMR . Input . WMRSpatialController > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( @"(^(Spatial Controller))|(^(OpenVR Controller\(WindowsMR))" )
) ;
InputSystem . RegisterLayout < UnityEngine . XR . WindowsMR . Input . HololensHand > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( @"(^(Hand -))" )
) ;
#endif
// Built-in layouts replaced by the com.unity.xr.oculus package.
#if ! DISABLE_BUILTIN_INPUT_SYSTEM_OCULUS
InputSystem . RegisterLayout < Unity . XR . Oculus . Input . OculusHMD > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "^(Oculus Rift)|^(Oculus Quest)|^(Oculus Go)" ) ) ;
InputSystem . RegisterLayout < Unity . XR . Oculus . Input . OculusTouchController > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( @"(^(Oculus Touch Controller))|(^(Oculus Quest Controller))" ) ) ;
InputSystem . RegisterLayout < Unity . XR . Oculus . Input . OculusRemote > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( @"Oculus Remote" ) ) ;
InputSystem . RegisterLayout < Unity . XR . Oculus . Input . OculusTrackingReference > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( @"((Tracking Reference)|(^(Oculus Rift [a-zA-Z0-9]* \(Camera)))" ) ) ;
InputSystem . RegisterLayout < Unity . XR . Oculus . Input . OculusHMDExtended > (
name : "GearVR" ,
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "Oculus HMD" ) ) ;
InputSystem . RegisterLayout < Unity . XR . Oculus . Input . GearVRTrackedController > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "^(Oculus Tracked Remote)" ) ) ;
#endif
// Built-in layouts replaced by the com.unity.xr.googlevr package.
#if ! DISABLE_BUILTIN_INPUT_SYSTEM_GOOGLEVR
InputSystem . RegisterLayout < Unity . XR . GoogleVr . DaydreamHMD > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "Daydream HMD" ) ) ;
InputSystem . RegisterLayout < Unity . XR . GoogleVr . DaydreamController > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "^(Daydream Controller)" ) ) ;
#endif
// Built-in layouts replaced by the com.unity.xr.openvr package.
#if ! DISABLE_BUILTIN_INPUT_SYSTEM_OPENVR
InputSystem . RegisterLayout < Unity . XR . OpenVR . OpenVRHMD > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "^(OpenVR Headset)|^(Vive Pro)" )
) ;
InputSystem . RegisterLayout < Unity . XR . OpenVR . OpenVRControllerWMR > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( "^(OpenVR Controller\\(WindowsMR)" )
) ;
InputSystem . RegisterLayout < Unity . XR . OpenVR . ViveWand > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithManufacturer ( "HTC" )
. WithProduct ( @"^(OpenVR Controller\(((Vive. Controller)|(VIVE. Controller)|(Vive Controller)))" )
) ;
InputSystem . RegisterLayout < Unity . XR . OpenVR . OpenVROculusTouchController > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithProduct ( @"^(OpenVR Controller\(Oculus)" )
) ;
InputSystem . RegisterLayout < Unity . XR . OpenVR . ViveTracker > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithManufacturer ( "HTC" )
. WithProduct ( @"^(VIVE Tracker)" )
) ;
InputSystem . RegisterLayout < Unity . XR . OpenVR . HandedViveTracker > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithManufacturer ( "HTC" )
. WithProduct ( @"^(OpenVR Controller\(VIVE Tracker)" )
) ;
InputSystem . RegisterLayout < Unity . XR . OpenVR . ViveLighthouse > (
matches : new InputDeviceMatcher ( )
. WithInterface ( XRUtilities . InterfaceMatchAnyVersion )
. WithManufacturer ( "HTC" )
. WithProduct ( @"^(HTC V2-XD/XE)" )
) ;
#endif
#endif
}
}
}
#endif