using System; using Unity.Collections; using UnityEngine.Assertions; namespace UnityEngine.XR.ARSubsystems { /// /// A subsystem for detecting and tracking a preconfigured set of images in the environment. /// /// Low level data describing a tracked image. /// The descriptor used by implementations to describe the feature set of the image tracking subsystem. public abstract class XRImageTrackingSubsystem : TrackingSubsystem { /// /// Constructs a subsystem. Do not invoked directly; call Create on the instead. /// public XRImageTrackingSubsystem() => m_Provider = CreateProvider(); /// /// Starts the subsystem, that is, start 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."); m_Provider.imageLibrary = m_ImageLibrary; } /// /// Stops the subsystem, that is, stops detecting and tracking images. /// protected sealed override void OnStop() => m_Provider.imageLibrary = null; /// /// Destroys the subsystem. /// protected sealed override void OnDestroyed() => m_Provider.Destroy(); /// /// 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 may be modifiable /// (see ). A /// may be created 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("Cannot set imageLibrary to null while subsystem is running."); m_ImageLibrary = value; if (running) m_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 = m_Provider.CreateRuntimeLibrary(serializedLibrary); Assert.IsFalse(ReferenceEquals(library, null)); return library; } /// /// Retrieve the changes in the state of tracked images (added, updated, 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, removed) since the last call to this method. public override TrackableChanges GetChanges(Allocator allocator) { var changes = m_Provider.GetChanges(XRTrackedImage.defaultValue, allocator); #if DEVELOPMENT_BUILD || UNITY_EDITOR m_ValidationUtility.ValidateAndDisposeIfThrown(changes); #endif return changes; } /// /// The 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 maxNumberOfMovingImages { set => m_Provider.maxNumberOfMovingImages = value; } /// /// Methods to implement by the implementing provider. /// protected abstract class Provider { /// /// Called when the subsystem is destroyed. /// public virtual void Destroy() {} /// /// Get the changes (added, updated, removed) to the tracked images 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 addtional fields added to the in the future. /// The allocator to use for the returned data. /// The set of changes (added, updated, removed) tracked images 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 maximum number of moving images to track in realtime. /// /// /// Must be implemented if is true; /// otherwise, this property will never be set and need not be implemented. /// /// Thrown if not overridden by the derived class. public virtual int maxNumberOfMovingImages { set => throw new NotSupportedException("This subsystem does not track moving images."); } } /// /// Create an implementation of the class. This will only be called once. /// /// An instance of the interface. protected abstract Provider CreateProvider(); RuntimeReferenceImageLibrary m_ImageLibrary; Provider m_Provider; #if DEVELOPMENT_BUILD || UNITY_EDITOR ValidationUtility m_ValidationUtility = new ValidationUtility(); #endif } }