SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
8.1 KiB

4 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using UnityEngine.XR.ARSubsystems;
  6. namespace UnityEngine.XR.ARFoundation
  7. {
  8. /// <summary>
  9. /// Represents a plane (i.e., a flat surface) detected by an AR device.
  10. /// </summary>
  11. /// <remarks>
  12. /// Generated by the <see cref="ARPlaneManager"/> when an AR device detects
  13. /// a plane in the environment.
  14. /// </remarks>
  15. [DefaultExecutionOrder(ARUpdateOrder.k_Plane)]
  16. [DisallowMultipleComponent]
  17. [HelpURL("https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@3.0/api/UnityEngine.XR.ARFoundation.ARPlane.html")]
  18. public sealed class ARPlane : ARTrackable<BoundedPlane, ARPlane>
  19. {
  20. [SerializeField]
  21. [Tooltip("The largest value by which a plane's vertex may change before the boundaryChanged event is invoked. Units are in meters.")]
  22. float m_VertexChangedThreshold = 0.01f;
  23. /// <summary>
  24. /// The largest value by which a plane's vertex may change before the mesh is regenerated. Units are in meters.
  25. /// </summary>
  26. public float vertexChangedThreshold
  27. {
  28. get => m_VertexChangedThreshold;
  29. set => m_VertexChangedThreshold = Mathf.Max(0f, value);
  30. }
  31. /// <summary>
  32. /// Invoked when any vertex in the plane's boundary changes by more than <see cref="vertexChangedThreshold"/>.
  33. /// </summary>
  34. public event Action<ARPlaneBoundaryChangedEventArgs> boundaryChanged;
  35. /// <summary>
  36. /// Gets the normal to this plane in world space.
  37. /// </summary>
  38. public Vector3 normal => transform.up;
  39. /// <summary>
  40. /// The <see cref="ARPlane"/> which has subsumed this plane, or <c>null</c>
  41. /// if this plane has not been subsumed.
  42. /// </summary>
  43. public ARPlane subsumedBy { get; internal set; }
  44. /// <summary>
  45. /// The alignment of this plane.
  46. /// </summary>
  47. public PlaneAlignment alignment => sessionRelativeData.alignment;
  48. /// <summary>
  49. /// The classification of this plane.
  50. /// </summary>
  51. public PlaneClassification classification { get { return sessionRelativeData.classification; } }
  52. /// <summary>
  53. /// The 2D center point, in plane space
  54. /// </summary>
  55. public Vector2 centerInPlaneSpace => sessionRelativeData.center;
  56. /// <summary>
  57. /// The 3D center point, in Unity world space.
  58. /// </summary>
  59. public Vector3 center => transform.TransformPoint(new Vector3(centerInPlaneSpace.x, 0, centerInPlaneSpace.y));
  60. /// <summary>
  61. /// The physical extents (half dimensions) of the plane in meters.
  62. /// </summary>
  63. public Vector2 extents => sessionRelativeData.extents;
  64. /// <summary>
  65. /// The physical size (dimensions) of the plane in meters.
  66. /// </summary>
  67. public Vector2 size => sessionRelativeData.size;
  68. /// <summary>
  69. /// Get the infinite plane associated with this <see cref="ARPlane"/>.
  70. /// </summary>
  71. public Plane infinitePlane => new Plane(normal, transform.position);
  72. /// <summary>
  73. /// Get a native pointer associated with this plane.
  74. /// </summary>
  75. /// <remarks>
  76. /// The data pointed to by this member is implementation defined.
  77. /// The lifetime of the pointed to object is also
  78. /// implementation defined, but should be valid at least until the next
  79. /// <see cref="ARSession"/> update.
  80. /// </remarks>
  81. public IntPtr nativePtr => sessionRelativeData.nativePtr;
  82. /// <summary>
  83. /// The plane's boundary points, in plane space, that is, relative to this <see cref="ARPlane"/>'s
  84. /// local position and rotation.
  85. /// </summary>
  86. public unsafe NativeArray<Vector2> boundary
  87. {
  88. get
  89. {
  90. if (!m_Boundary.IsCreated)
  91. return default(NativeArray<Vector2>);
  92. var boundary = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Vector2>(
  93. m_Boundary.GetUnsafePtr(),
  94. m_Boundary.Length,
  95. Allocator.None);
  96. #if ENABLE_UNITY_COLLECTIONS_CHECKS
  97. NativeArrayUnsafeUtility.SetAtomicSafetyHandle(
  98. ref boundary,
  99. NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_Boundary));
  100. #endif
  101. return boundary;
  102. }
  103. }
  104. internal void UpdateBoundary(XRPlaneSubsystem subsystem)
  105. {
  106. // subsystem cannot be null here
  107. if (subsystem.SubsystemDescriptor.supportsBoundaryVertices)
  108. {
  109. subsystem.GetBoundary(trackableId, Allocator.Persistent, ref m_Boundary);
  110. }
  111. else
  112. {
  113. if (!m_Boundary.IsCreated)
  114. {
  115. m_Boundary = new NativeArray<Vector2>(4, Allocator.Persistent);
  116. }
  117. else if (m_Boundary.Length != 4)
  118. {
  119. m_Boundary.Dispose();
  120. m_Boundary = new NativeArray<Vector2>(4, Allocator.Persistent);
  121. }
  122. var extents = sessionRelativeData.extents;
  123. m_Boundary[0] = new Vector2(-extents.x, -extents.y);
  124. m_Boundary[1] = new Vector2(-extents.x, extents.y);
  125. m_Boundary[2] = new Vector2( extents.x, extents.y);
  126. m_Boundary[3] = new Vector2( extents.x, -extents.y);
  127. }
  128. if (boundaryChanged != null)
  129. CheckForBoundaryChanges();
  130. }
  131. void OnValidate()
  132. {
  133. vertexChangedThreshold = Mathf.Max(0f, vertexChangedThreshold);
  134. }
  135. void OnDestroy()
  136. {
  137. if (m_OldBoundary.IsCreated)
  138. m_OldBoundary.Dispose();
  139. if (m_Boundary.IsCreated)
  140. m_Boundary.Dispose();
  141. }
  142. void CheckForBoundaryChanges()
  143. {
  144. if (m_Boundary.Length != m_OldBoundary.Length)
  145. {
  146. CopyBoundaryAndSetChangedFlag();
  147. }
  148. else if (vertexChangedThreshold == 0f)
  149. {
  150. // Don't need to check each vertex because it will always
  151. // be "different" if threshold is zero.
  152. CopyBoundaryAndSetChangedFlag();
  153. }
  154. else
  155. {
  156. // Counts are the same; check each vertex
  157. var thresholdSquared = vertexChangedThreshold * vertexChangedThreshold;
  158. for (int i = 0; i < m_Boundary.Length; ++i)
  159. {
  160. var diffSquared = (m_Boundary[i] - m_OldBoundary[i]).sqrMagnitude;
  161. if (diffSquared > thresholdSquared)
  162. {
  163. CopyBoundaryAndSetChangedFlag();
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. void CopyBoundaryAndSetChangedFlag()
  170. {
  171. // Copy new boundary
  172. if (m_OldBoundary.IsCreated)
  173. {
  174. // If the lengths are different, then we need
  175. // to reallocate, but otherwise, we can reuse
  176. if (m_OldBoundary.Length != m_Boundary.Length)
  177. {
  178. m_OldBoundary.Dispose();
  179. m_OldBoundary = new NativeArray<Vector2>(m_Boundary.Length, Allocator.Persistent);
  180. }
  181. }
  182. else
  183. {
  184. m_OldBoundary = new NativeArray<Vector2>(m_Boundary.Length, Allocator.Persistent);
  185. }
  186. m_OldBoundary.CopyFrom(m_Boundary);
  187. m_HasBoundaryChanged = true;
  188. }
  189. void Update()
  190. {
  191. if (m_HasBoundaryChanged && (boundaryChanged != null))
  192. {
  193. m_HasBoundaryChanged = false;
  194. boundaryChanged(new ARPlaneBoundaryChangedEventArgs(this));
  195. }
  196. }
  197. NativeArray<Vector2> m_Boundary;
  198. NativeArray<Vector2> m_OldBoundary;
  199. bool m_HasBoundaryChanged;
  200. }
  201. }