using System; using Unity.Collections; using UnityEngine.Assertions; using UnityEngine.SubsystemsImplementation; namespace UnityEngine.XR.ARSubsystems { /// /// A subsystem for detecting and tracking a preconfigured set of images in the environment. /// public class XRImageTrackingSubsystem : TrackingSubsystem { /// /// Constructs a subsystem. Do not invoke directly; call Create on the instead. /// public XRImageTrackingSubsystem() { } /// /// Starts the subsystem, that is, starts detecting images in the scene. must not be null. /// /// Thrown if is null. protected override void OnStart() { if (m_ImageLibrary == null) throw new InvalidOperationException("Cannot start image tracking without an image library."); provider.imageLibrary = m_ImageLibrary; base.OnStart(); } /// /// Stops the subsystem, that is, stops detecting and tracking images. /// protected sealed override void OnStop() { base.OnStop(); provider.imageLibrary = null; } /// /// Get or set the reference image library. This is the set of images to look for in the environment. /// /// /// A is created at runtime and can be modifiable /// (see ). You can create a /// from an using /// . /// /// Thrown if the subsystem has been started, and you attempt to set the image library to null. /// /// /// /// public RuntimeReferenceImageLibrary imageLibrary { get => m_ImageLibrary; set { if (m_ImageLibrary == value) return; if (running && value == null) throw new ArgumentNullException(nameof(value), "Cannot set imageLibrary to null while subsystem is running."); m_ImageLibrary = value; if (running) provider.imageLibrary = m_ImageLibrary; } } /// /// Creates a from an existing , /// or an empty library if is null. /// Use this to construct the runtime representation of an . /// /// /// If the subsystem supports runtime mutable libraries /// (see ), then the returned /// library will be a . /// /// An existing created at edit time, or null to create an empty image library. /// A new representing the deserialized version of /// or an empty library if is null. /// public RuntimeReferenceImageLibrary CreateRuntimeLibrary(XRReferenceImageLibrary serializedLibrary) { var library = provider.CreateRuntimeLibrary(serializedLibrary); Assert.IsFalse(ReferenceEquals(library, null)); return library; } /// /// Retrieve the changes in the state of tracked images (added, updated, and removed) since the last call to GetChanges. /// /// The allocator to use for the returned set of changes. /// The set of tracked image changes (added, updated, and removed) since the last call to this method. public override TrackableChanges GetChanges(Allocator allocator) { var changes = provider.GetChanges(XRTrackedImage.defaultValue, allocator); #if DEVELOPMENT_BUILD || UNITY_EDITOR m_ValidationUtility.ValidateAndDisposeIfThrown(changes); #endif return changes; } /// /// The requested maximum number of moving images to track. /// /// /// Thrown if the subsystem does not support tracking moving images. /// Check for support of this feature with . /// public int requestedMaxNumberOfMovingImages { get => provider.requestedMaxNumberOfMovingImages; set => provider.requestedMaxNumberOfMovingImages = value; } /// /// The current maximum number of moving images to track. /// This can be different from . /// public int currentMaxNumberOfMovingImages => provider.currentMaxNumberOfMovingImages; /// /// Methods to implement by the implementing provider. /// public abstract class Provider : SubsystemProvider { /// /// Get the changes to the tracked images (added, updated, and removed) since the last call to this method. /// /// An populated with default values. /// The implementation should first fill arrays of added, updated, and removed with copies of this /// before copying in its own values. This guards against additional fields added to the in the future. /// The allocator to use for the returned data. /// The set of changes to tracked images (added, updated, and removed) since the last call to this method. public abstract TrackableChanges GetChanges(XRTrackedImage defaultTrackedImage, Allocator allocator); /// /// Sets the set of images to search for in the environment. /// /// /// Setting this to null implies the subsystem should stop detecting and tracking images. /// public abstract RuntimeReferenceImageLibrary imageLibrary { set; } /// /// Creates a from an existing , /// or an empty library if is null. /// /// A to deserialize. /// The runtime version of or an empty library if is null. public abstract RuntimeReferenceImageLibrary CreateRuntimeLibrary(XRReferenceImageLibrary serializedLibrary); /// /// The requested maximum number of moving images to track in real time. /// /// /// Must be implemented if is true; /// otherwise, this property will never be set and doesn't need to be implemented. /// /// Thrown if not overridden by the derived class. public virtual int requestedMaxNumberOfMovingImages { get => 0; set => throw new NotSupportedException("This subsystem does not track moving images."); } /// /// The current maximum number of moving images to track in realtime. /// /// /// Must be implemented if is true. /// public virtual int currentMaxNumberOfMovingImages => 0; } RuntimeReferenceImageLibrary m_ImageLibrary; #if DEVELOPMENT_BUILD || UNITY_EDITOR ValidationUtility m_ValidationUtility = new ValidationUtility(); #endif } }