A game about forced loneliness, made by TACStudios
1// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled. 2#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) && !UNITY_FORCE_INPUTSYSTEM_XR_OFF || PACKAGE_DOCS_GENERATION 3using System.Runtime.InteropServices; 4using Unity.Collections.LowLevel.Unsafe; 5using UnityEngine.InputSystem.Controls; 6using UnityEngine.InputSystem.Layouts; 7using UnityEngine.InputSystem.LowLevel; 8using UnityEngine.InputSystem.Utilities; 9using UnityEngine.Scripting; 10using TrackingState = UnityEngine.XR.InputTrackingState; 11 12namespace UnityEngine.InputSystem.XR 13{ 14 /// <summary> 15 /// State layout for a single pose. 16 /// </summary> 17 /// <remarks> 18 /// This is the low-level memory representation of a single pose, i.e the 19 /// way poses are internally transmitted and stored in the system. PoseStates are used on devices containing <see cref="PoseControl"/>s. 20 /// </remarks> 21 /// <seealso cref="PoseControl"/> 22 [StructLayout(LayoutKind.Explicit, Size = kSizeInBytes)] 23 public struct PoseState : IInputStateTypeInfo 24 { 25 internal const int kSizeInBytes = 60; 26 27 internal static readonly FourCC s_Format = new FourCC('P', 'o', 's', 'e'); 28 29 /// <summary> 30 /// Memory format tag for PoseState. 31 /// </summary> 32 /// <value>Returns "Pose".</value> 33 /// <seealso cref="InputStateBlock.format"/> 34 public FourCC format => s_Format; 35 36 /// <summary> 37 /// Constructor for PoseStates. 38 /// 39 /// Useful for creating PoseStates locally (not from <see cref="PoseControl"/>). 40 /// </summary> 41 /// <param name="isTracked">Value to use for <see cref="isTracked"/></param> 42 /// <param name="trackingState">Value to use for <see cref="trackingState"/></param> 43 /// <param name="position">Value to use for <see cref="position"/></param> 44 /// <param name="rotation">Value to use for <see cref="rotation"/></param> 45 /// <param name="velocity">Value to use for <see cref="velocity"/></param> 46 /// <param name="angularVelocity">Value to use for <see cref="angularVelocity"/></param> 47 public PoseState(bool isTracked, TrackingState trackingState, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 angularVelocity) 48 { 49 this.isTracked = isTracked; 50 this.trackingState = trackingState; 51 this.position = position; 52 this.rotation = rotation; 53 this.velocity = velocity; 54 this.angularVelocity = angularVelocity; 55 } 56 57 /// <summary> 58 /// Whether the pose is currently being fully tracked. Otherwise, the tracking is either unavailable, or simulated. 59 /// </summary> 60 /// <remarks> 61 /// 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. 62 /// </remarks> 63 [FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 8 /* needed to ensure optimization kicks-in */)] 64 public bool isTracked; 65 66 /// <summary> 67 /// A Flags Enumeration specifying which other fields in the pose state are valid. 68 /// </summary> 69 [FieldOffset(4), InputControl(displayName = "Tracking State", layout = "Integer")] 70 public TrackingState trackingState; 71 72 /// <summary> 73 /// The position in 3D space, relative to the tracking origin where this pose represents. 74 /// </summary> 75 /// <remarks> 76 /// Positions are represented in meters. 77 /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Position"/> value. 78 /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins. 79 /// </remarks> 80 [FieldOffset(8), InputControl(displayName = "Position", noisy = true)] 81 public Vector3 position; 82 83 /// <summary> 84 /// The rotation in 3D space, relative to the tracking origin where this pose represents. 85 /// </summary> 86 /// <remarks> 87 /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Rotation"/> value. 88 /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins. 89 /// </remarks> 90 [FieldOffset(20), InputControl(displayName = "Rotation", noisy = true)] 91 public Quaternion rotation; 92 93 /// <summary> 94 /// The velocity in 3D space, relative to the tracking origin where this pose represents. 95 /// </summary> 96 /// <remarks> 97 /// Velocities are represented in meters per second. 98 /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Velocity"/> value. 99 /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins. 100 /// </remarks> 101 [FieldOffset(36), InputControl(displayName = "Velocity", noisy = true)] 102 public Vector3 velocity; 103 104 /// <summary> 105 /// The angular velocity in 3D space, relative to the tracking origin where this pose represents. 106 /// </summary> 107 /// <remarks> 108 /// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.AngularVelocity"/> value. 109 /// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins. 110 /// </remarks> 111 [FieldOffset(48), InputControl(displayName = "Angular Velocity", noisy = true)] 112 public Vector3 angularVelocity; 113 } 114 115 /// <summary> 116 /// A control representing a Pose in 3D space, relative to an XR tracking origin 117 /// </summary> 118 /// <remarks> 119 /// Note that unlike most other control types, <c>PoseControls</c> do not have 120 /// a flexible memory layout. They are hardwired to <see cref="PoseState"/> and 121 /// will not work correctly with a different memory layouts. Additional fields may 122 /// be appended to the struct but what's there in the struct has to be located 123 /// at exactly those memory addresses. 124 /// 125 /// For more information on tracking origins see <see cref="UnityEngine.XR.TrackingOriginModeFlags"/>. 126 /// </remarks> 127 [Preserve, InputControlLayout(stateType = typeof(PoseState))] 128 public class PoseControl : InputControl<PoseState> 129 { 130 /// <summary> 131 /// Represents whether this pose is fully tracked or unavailable/simulated. 132 /// </summary> 133 /// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.isTracked"/> value.</value> 134 /// <seealso cref="PoseState.isTracked"/> 135 public ButtonControl isTracked { get; set; } 136 137 /// <summary> 138 /// The other controls on this <see cref="PoseControl"/> that are currently reporting data. 139 /// </summary> 140 /// <remarks> 141 /// This can be missing values when the device tracking this pose is restricted or not tracking properly. 142 /// </remarks> 143 /// <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> 144 /// <seealso cref="PoseState.trackingState"/> 145 public IntegerControl trackingState { get; set; } 146 147 /// <summary> 148 /// The position, in meters, of this tracked pose relative to the tracking origin. 149 /// </summary> 150 /// <remarks> 151 /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Position"/> value. 152 /// </remarks> 153 /// <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> 154 /// <seealso cref="PoseState.position"/> 155 public Vector3Control position { get; set; } 156 157 /// <summary> 158 /// The rotation of this tracked pose relative to the tracking origin. 159 /// </summary> 160 /// <remarks> 161 /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Rotation"/> value. 162 /// </remarks> 163 /// <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> 164 /// <seealso cref="PoseState.rotation"/> 165 public QuaternionControl rotation { get; set; } 166 167 /// <summary> 168 /// The velocity, in meters per second, of this tracked pose relative to the tracking origin. 169 /// </summary> 170 /// <remarks> 171 /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Velocity"/> value. 172 /// </remarks> 173 /// <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> 174 /// <seealso cref="PoseState.velocity"/> 175 public Vector3Control velocity { get; set; } 176 177 /// <summary> 178 /// The angular velocity of this tracked pose relative to the tracking origin. 179 /// </summary> 180 /// <remarks> 181 /// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.AngularVelocity"/> value. 182 /// </remarks> 183 /// <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> 184 /// <seealso cref="PoseState.angularVelocity"/> 185 public Vector3Control angularVelocity { get; set; } 186 187 /// <summary> 188 /// Default-initialize the pose control. 189 /// </summary> 190 /// <remarks> 191 /// Sets the <see cref="InputStateBlock.format"/> to <c>"Pose"</c>. 192 /// </remarks> 193 public PoseControl() 194 { 195 m_StateBlock.format = PoseState.s_Format; 196 } 197 198 /// <inheritdoc /> 199 protected override void FinishSetup() 200 { 201 isTracked = GetChildControl<ButtonControl>("isTracked"); 202 trackingState = GetChildControl<IntegerControl>("trackingState"); 203 position = GetChildControl<Vector3Control>("position"); 204 rotation = GetChildControl<QuaternionControl>("rotation"); 205 velocity = GetChildControl<Vector3Control>("velocity"); 206 angularVelocity = GetChildControl<Vector3Control>("angularVelocity"); 207 208 base.FinishSetup(); 209 } 210 211 /// <inheritdoc /> 212 public override unsafe PoseState ReadUnprocessedValueFromState(void* statePtr) 213 { 214 switch (m_OptimizedControlDataType) 215 { 216 case InputStateBlock.kFormatPose: 217 return *(PoseState*)((byte*)statePtr + (int)m_StateBlock.byteOffset); 218 default: 219 return new PoseState() 220 { 221 isTracked = isTracked.ReadUnprocessedValueFromStateWithCaching(statePtr) > 0.5f, 222 trackingState = (TrackingState)trackingState.ReadUnprocessedValueFromStateWithCaching(statePtr), 223 position = position.ReadUnprocessedValueFromStateWithCaching(statePtr), 224 rotation = rotation.ReadUnprocessedValueFromStateWithCaching(statePtr), 225 velocity = velocity.ReadUnprocessedValueFromStateWithCaching(statePtr), 226 angularVelocity = angularVelocity.ReadUnprocessedValueFromStateWithCaching(statePtr), 227 }; 228 } 229 } 230 231 /// <inheritdoc /> 232 public override unsafe void WriteValueIntoState(PoseState value, void* statePtr) 233 { 234 switch (m_OptimizedControlDataType) 235 { 236 case InputStateBlock.kFormatPose: 237 *(PoseState*)((byte*)statePtr + (int)m_StateBlock.byteOffset) = value; 238 break; 239 default: 240 isTracked.WriteValueIntoState(value.isTracked, statePtr); 241 trackingState.WriteValueIntoState((uint)value.trackingState, statePtr); 242 position.WriteValueIntoState(value.position, statePtr); 243 rotation.WriteValueIntoState(value.rotation, statePtr); 244 velocity.WriteValueIntoState(value.velocity, statePtr); 245 angularVelocity.WriteValueIntoState(value.angularVelocity, statePtr); 246 break; 247 } 248 } 249 250 protected override FourCC CalculateOptimizedControlDataType() 251 { 252 if ( 253 m_StateBlock.sizeInBits == PoseState.kSizeInBytes * 8 && 254 m_StateBlock.bitOffset == 0 && 255 isTracked.optimizedControlDataType == InputStateBlock.kFormatByte && 256 trackingState.optimizedControlDataType == InputStateBlock.kFormatInt && 257 position.optimizedControlDataType == InputStateBlock.kFormatVector3 && 258 rotation.optimizedControlDataType == InputStateBlock.kFormatQuaternion && 259 velocity.optimizedControlDataType == InputStateBlock.kFormatVector3 && 260 angularVelocity.optimizedControlDataType == InputStateBlock.kFormatVector3 && 261 trackingState.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 4 && 262 position.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 8 && 263 rotation.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 20 && 264 velocity.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 36 && 265 angularVelocity.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 48 266 ) 267 return InputStateBlock.kFormatPose; 268 269 return InputStateBlock.kFormatInvalid; 270 } 271 } 272} 273#endif