123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- // 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) && !UNITY_FORCE_INPUTSYSTEM_XR_OFF || PACKAGE_DOCS_GENERATION
- using System.Runtime.InteropServices;
- using Unity.Collections.LowLevel.Unsafe;
- using UnityEngine.InputSystem.Controls;
- using UnityEngine.InputSystem.Layouts;
- using UnityEngine.InputSystem.LowLevel;
- using UnityEngine.InputSystem.Utilities;
- using UnityEngine.Scripting;
- using TrackingState = UnityEngine.XR.InputTrackingState;
-
- namespace UnityEngine.InputSystem.XR
- {
- /// <summary>
- /// State layout for a single pose.
- /// </summary>
- /// <remarks>
- /// This is the low-level memory representation of a single pose, i.e the
- /// way poses are internally transmitted and stored in the system. PoseStates are used on devices containing <see cref="PoseControl"/>s.
- /// </remarks>
- /// <seealso cref="PoseControl"/>
- [StructLayout(LayoutKind.Explicit, Size = kSizeInBytes)]
- public struct PoseState : IInputStateTypeInfo
- {
- internal const int kSizeInBytes = 60;
-
- internal static readonly FourCC s_Format = new FourCC('P', 'o', 's', 'e');
-
- /// <summary>
- /// Memory format tag for PoseState.
- /// </summary>
- /// <value>Returns "Pose".</value>
- /// <seealso cref="InputStateBlock.format"/>
- public FourCC format => s_Format;
-
- /// <summary>
- /// Constructor for PoseStates.
- ///
- /// Useful for creating PoseStates locally (not from <see cref="PoseControl"/>).
- /// </summary>
- /// <param name="isTracked">Value to use for <see cref="isTracked"/></param>
- /// <param name="trackingState">Value to use for <see cref="trackingState"/></param>
- /// <param name="position">Value to use for <see cref="position"/></param>
- /// <param name="rotation">Value to use for <see cref="rotation"/></param>
- /// <param name="velocity">Value to use for <see cref="velocity"/></param>
- /// <param name="angularVelocity">Value to use for <see cref="angularVelocity"/></param>
- public PoseState(bool isTracked, TrackingState trackingState, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 angularVelocity)
- {
- this.isTracked = isTracked;
- this.trackingState = trackingState;
- this.position = position;
- this.rotation = rotation;
- this.velocity = velocity;
- this.angularVelocity = angularVelocity;
- }
-
- /// <summary>
- /// Whether the pose is currently being fully tracked. Otherwise, the tracking is either unavailable, or simulated.
- /// </summary>
- /// <remarks>
- /// Fully tracked means that the pose is accurate and not using any simulated or extrapolated positions, and the system tracking this pose is able to confidently track this object.
- /// </remarks>
- [FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 8 /* needed to ensure optimization kicks-in */)]
- public bool isTracked;
-
- /// <summary>
- /// A Flags Enumeration specifying which other fields in the pose state are valid.
- /// </summary>
- [FieldOffset(4), InputControl(displayName = "Tracking State", layout = "Integer")]
- public TrackingState trackingState;
-
- /// <summary>
- /// The position in 3D space, relative to the tracking origin where this pose represents.
- /// </summary>
- /// <remarks>
- /// Positions are represented in meters.
- /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Position"/> value.
- /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
- /// </remarks>
- [FieldOffset(8), InputControl(displayName = "Position", noisy = true)]
- public Vector3 position;
-
- /// <summary>
- /// The rotation in 3D space, relative to the tracking origin where this pose represents.
- /// </summary>
- /// <remarks>
- /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Rotation"/> value.
- /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
- /// </remarks>
- [FieldOffset(20), InputControl(displayName = "Rotation", noisy = true)]
- public Quaternion rotation;
-
- /// <summary>
- /// The velocity in 3D space, relative to the tracking origin where this pose represents.
- /// </summary>
- /// <remarks>
- /// Velocities are represented in meters per second.
- /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Velocity"/> value.
- /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
- /// </remarks>
- [FieldOffset(36), InputControl(displayName = "Velocity", noisy = true)]
- public Vector3 velocity;
-
- /// <summary>
- /// The angular velocity in 3D space, relative to the tracking origin where this pose represents.
- /// </summary>
- /// <remarks>
- /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.AngularVelocity"/> value.
- /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
- /// </remarks>
- [FieldOffset(48), InputControl(displayName = "Angular Velocity", noisy = true)]
- public Vector3 angularVelocity;
- }
-
- /// <summary>
- /// A control representing a Pose in 3D space, relative to an XR tracking origin
- /// </summary>
- /// <remarks>
- /// Note that unlike most other control types, <c>PoseControls</c> do not have
- /// a flexible memory layout. They are hardwired to <see cref="PoseState"/> and
- /// will not work correctly with a different memory layouts. Additional fields may
- /// be appended to the struct but what's there in the struct has to be located
- /// at exactly those memory addresses.
- ///
- /// For more information on tracking origins see <see cref="UnityEngine.XR.TrackingOriginModeFlags"/>.
- /// </remarks>
- [Preserve, InputControlLayout(stateType = typeof(PoseState))]
- public class PoseControl : InputControl<PoseState>
- {
- /// <summary>
- /// Represents whether this pose is fully tracked or unavailable/simulated.
- /// </summary>
- /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.isTracked"/> value.</value>
- /// <seealso cref="PoseState.isTracked"/>
- public ButtonControl isTracked { get; set; }
-
- /// <summary>
- /// The other controls on this <see cref="PoseControl"/> that are currently reporting data.
- /// </summary>
- /// <remarks>
- /// This can be missing values when the device tracking this pose is restricted or not tracking properly.
- /// </remarks>
- /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.trackingState"/> value of the pose retrieved from this control.</value>
- /// <seealso cref="PoseState.trackingState"/>
- public IntegerControl trackingState { get; set; }
-
- /// <summary>
- /// The position, in meters, of this tracked pose relative to the tracking origin.
- /// </summary>
- /// <remarks>
- /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Position"/> value.
- /// </remarks>
- /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.position"/> value of the pose retrieved from this control.</value>
- /// <seealso cref="PoseState.position"/>
- public Vector3Control position { get; set; }
-
- /// <summary>
- /// The rotation of this tracked pose relative to the tracking origin.
- /// </summary>
- /// <remarks>
- /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Rotation"/> value.
- /// </remarks>
- /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.rotation"/> value of the pose retrieved from this control.</value>
- /// <seealso cref="PoseState.rotation"/>
- public QuaternionControl rotation { get; set; }
-
- /// <summary>
- /// The velocity, in meters per second, of this tracked pose relative to the tracking origin.
- /// </summary>
- /// <remarks>
- /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Velocity"/> value.
- /// </remarks>
- /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.velocity"/> value of the pose retrieved from this control.</value>
- /// <seealso cref="PoseState.velocity"/>
- public Vector3Control velocity { get; set; }
-
- /// <summary>
- /// The angular velocity of this tracked pose relative to the tracking origin.
- /// </summary>
- /// <remarks>
- /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.AngularVelocity"/> value.
- /// </remarks>
- /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.angularVelocity"/> value of the pose retrieved from this control.</value>
- /// <seealso cref="PoseState.angularVelocity"/>
- public Vector3Control angularVelocity { get; set; }
-
- /// <summary>
- /// Default-initialize the pose control.
- /// </summary>
- /// <remarks>
- /// Sets the <see cref="InputStateBlock.format"/> to <c>"Pose"</c>.
- /// </remarks>
- public PoseControl()
- {
- m_StateBlock.format = PoseState.s_Format;
- }
-
- /// <inheritdoc />
- protected override void FinishSetup()
- {
- isTracked = GetChildControl<ButtonControl>("isTracked");
- trackingState = GetChildControl<IntegerControl>("trackingState");
- position = GetChildControl<Vector3Control>("position");
- rotation = GetChildControl<QuaternionControl>("rotation");
- velocity = GetChildControl<Vector3Control>("velocity");
- angularVelocity = GetChildControl<Vector3Control>("angularVelocity");
-
- base.FinishSetup();
- }
-
- /// <inheritdoc />
- public override unsafe PoseState ReadUnprocessedValueFromState(void* statePtr)
- {
- switch (m_OptimizedControlDataType)
- {
- case InputStateBlock.kFormatPose:
- return *(PoseState*)((byte*)statePtr + (int)m_StateBlock.byteOffset);
- default:
- return new PoseState()
- {
- isTracked = isTracked.ReadUnprocessedValueFromStateWithCaching(statePtr) > 0.5f,
- trackingState = (TrackingState)trackingState.ReadUnprocessedValueFromStateWithCaching(statePtr),
- position = position.ReadUnprocessedValueFromStateWithCaching(statePtr),
- rotation = rotation.ReadUnprocessedValueFromStateWithCaching(statePtr),
- velocity = velocity.ReadUnprocessedValueFromStateWithCaching(statePtr),
- angularVelocity = angularVelocity.ReadUnprocessedValueFromStateWithCaching(statePtr),
- };
- }
- }
-
- /// <inheritdoc />
- public override unsafe void WriteValueIntoState(PoseState value, void* statePtr)
- {
- switch (m_OptimizedControlDataType)
- {
- case InputStateBlock.kFormatPose:
- *(PoseState*)((byte*)statePtr + (int)m_StateBlock.byteOffset) = value;
- break;
- default:
- isTracked.WriteValueIntoState(value.isTracked, statePtr);
- trackingState.WriteValueIntoState((uint)value.trackingState, statePtr);
- position.WriteValueIntoState(value.position, statePtr);
- rotation.WriteValueIntoState(value.rotation, statePtr);
- velocity.WriteValueIntoState(value.velocity, statePtr);
- angularVelocity.WriteValueIntoState(value.angularVelocity, statePtr);
- break;
- }
- }
-
- protected override FourCC CalculateOptimizedControlDataType()
- {
- if (
- m_StateBlock.sizeInBits == PoseState.kSizeInBytes * 8 &&
- m_StateBlock.bitOffset == 0 &&
- isTracked.optimizedControlDataType == InputStateBlock.kFormatByte &&
- trackingState.optimizedControlDataType == InputStateBlock.kFormatInt &&
- position.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
- rotation.optimizedControlDataType == InputStateBlock.kFormatQuaternion &&
- velocity.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
- angularVelocity.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
- trackingState.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 4 &&
- position.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 8 &&
- rotation.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 20 &&
- velocity.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 36 &&
- angularVelocity.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 48
- )
- return InputStateBlock.kFormatPose;
-
- return InputStateBlock.kFormatInvalid;
- }
- }
- }
- #endif
|