using System; using Unity.Collections; using UnityEngine.SubsystemsImplementation; namespace UnityEngine.XR.ARSubsystems { /// /// Base class for plane subsystems. /// /// /// This subsystem surfaces information regarding the detection of planes (that is, flat surfaces) in the physical environment. /// Implementations are typically found in other provider or platform-specific packages. /// public class XRPlaneSubsystem : TrackingSubsystem { /// /// Constructs a plane subsystem. Do not invoke directly; call Create on the instead. /// public XRPlaneSubsystem() { } /// /// Get or set the requested , for example, /// to enable different modes of detection. /// /// Thrown if is set to /// something other than when plane detection is not supported. public PlaneDetectionMode requestedPlaneDetectionMode { get => provider.requestedPlaneDetectionMode; set => provider.requestedPlaneDetectionMode = value; } /// /// Get the current in use by the provider. /// public PlaneDetectionMode currentPlaneDetectionMode => provider.currentPlaneDetectionMode; /// /// Get the changes to planes (added, updated, and removed) since the last call to . /// /// An Allocator to use when allocating the returned NativeArrays. /// /// that describes the planes that have been added, updated, and removed /// since the last call to . The caller owns the memory allocated with Allocator. /// public override TrackableChanges GetChanges(Allocator allocator) { var changes = provider.GetChanges(BoundedPlane.defaultValue, allocator); #if DEVELOPMENT_BUILD || UNITY_EDITOR m_ValidationUtility.ValidateAndDisposeIfThrown(changes); #endif return changes; } /// /// Gets the boundary polygon describing the plane. /// /// The associated with the plane of which to retrieve the boundary. /// An Allocator to use if needs to be created. Allocator.Temp is not supported; use Allocator.TempJob if you need temporary memory. /// The boundary will be stored here. If boundary is the same length as the new boundary, /// it is overwritten with the new data. Otherwise, it is disposed and recreated with the correct length. public void GetBoundary( TrackableId trackableId, Allocator allocator, ref NativeArray boundary) { if (allocator == Allocator.Temp) throw new InvalidOperationException("Allocator.Temp is not supported. Use Allocator.TempJob if you wish to use a temporary allocator."); if (allocator == Allocator.None) throw new InvalidOperationException("Allocator.None is not a valid allocator."); provider.GetBoundary(trackableId, allocator, ref boundary); } /// /// Creates or resizes the if necessary. If /// has been allocated and its length is equal to , then this method /// does nothing. If its length is different, then it is first disposed before being assigned /// to a new NativeArray. /// /// The length that will have after this method returns. /// If allocation is necessary, this allocator will be used to create the new NativeArray. /// The array to create or resize. /// The type of elements held by the . protected static void CreateOrResizeNativeArrayIfNecessary( int length, Allocator allocator, ref NativeArray array) where T : struct { if (array.IsCreated) { if (array.Length != length) { array.Dispose(); array = new NativeArray(length, allocator); } } else { array = new NativeArray(length, allocator); } } /// /// The API that derived classes must implement. /// public abstract class Provider : SubsystemProvider { /// /// Creates or resizes the if necessary. If /// has been allocated and its length is equal to , then this method /// does nothing. If its length is different, then it is first disposed before being assigned /// to a new NativeArray. /// /// The length that will have after this method returns. /// If allocation is necessary, this allocator will be used to create the new NativeArray. /// The array to create or resize. /// The type of elements held by the . protected static void CreateOrResizeNativeArrayIfNecessary( int length, Allocator allocator, ref NativeArray array) where T : struct { if (array.IsCreated) { if (array.Length != length) { array.Dispose(); array = new NativeArray(length, allocator); } } else { array = new NativeArray(length, allocator); } } /// /// Retrieves the boundary points of the plane with . /// /// The id of the plane. /// An Allocator to use for the returned NativeArray. /// An existing NativeArray to update or recreate if necessary. /// See . public virtual void GetBoundary( TrackableId trackableId, Allocator allocator, ref NativeArray boundary) { throw new NotSupportedException("Boundary vertices are not supported."); } /// /// Get the changes to planes (added, updated, and removed) since the last call to /// . /// /// /// The default plane. This should be used to initialize the returned NativeArrays for backwards compatibility. /// See . /// /// An Allocator to use when allocating the returned NativeArrays. /// /// describing the planes that have been added, updated, and removed /// since the last call to . The changes should be allocated using /// . /// public abstract TrackableChanges GetChanges(BoundedPlane defaultPlane, Allocator allocator); /// /// Get or set the requested . /// public virtual PlaneDetectionMode requestedPlaneDetectionMode { get => PlaneDetectionMode.None; set { if (value != PlaneDetectionMode.None) { throw new NotSupportedException("Plane detection is not supported."); } } } /// /// Get the current plane detection mode in use by the provider. /// public virtual PlaneDetectionMode currentPlaneDetectionMode => PlaneDetectionMode.None; } #if DEVELOPMENT_BUILD || UNITY_EDITOR ValidationUtility m_ValidationUtility = new ValidationUtility(); #endif } }