Nav apraksta
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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