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
}
}