using System; using System.Collections.Generic; namespace UnityEngine.XR.ARSubsystems { /// /// Represents a 3D scan of a real object that can be recognized in the environment. /// /// /// Reference objects contain a list of provider-specific entries. /// Each entry must have previously been generated in a /// format specific to its implementation of the . /// /// /// [Serializable] public struct XRReferenceObject : IEquatable { /// /// Creates a new reference object. This is most commonly used to construct a new reference object at runtime. /// See /// /// The name of the new reference object. public XRReferenceObject(string name) { m_Name = name; (m_GuidLow, m_GuidHigh) = GuidUtil.Decompose(Guid.NewGuid()); m_Entries = new List(); } /// /// Adds a provider-specific entry to this reference object. /// /// The entry to add. /// Thrown if an entry of the same type as /// has already been added. public void AddEntry(XRReferenceObjectEntry entry) { if (FindEntry(entry.GetType()) != null) throw new ArgumentException($"The {nameof(XRReferenceObject)} already contains an entry for type {entry.GetType()}"); m_Entries.Add(entry); } /// /// A string name for this reference object. /// public string name => m_Name; /// /// A GUID unique to this reference object. /// public Guid guid => GuidUtil.Compose(m_GuidLow, m_GuidHigh); /// /// Finds an by type. /// /// The specific type of to find. /// The provider-specific if found, otherwise null. /// public T FindEntry() where T : XRReferenceObjectEntry => FindEntry(typeof(T)) as T; /// /// Finds an by type. /// /// The specific type of to find. /// The provider-specific if found, otherwise null. /// /// Thrown if is null. public XRReferenceObjectEntry FindEntry(Type type) { if (type == null) throw new ArgumentNullException(nameof(type)); foreach (var entry in m_Entries) { if (entry != null && entry.GetType() == type) { return entry; } } return null; } internal void OnAddToLibrary(XRReferenceObjectLibrary library) { foreach (var entry in m_Entries) { entry.OnAddToLibrary(library, this); } } /// /// Tests for equality. /// /// The other to compare against. /// `True` if every field in is equal to this , otherwise `false`. public bool Equals(XRReferenceObject other) { return (m_GuidLow == other.m_GuidLow) && (m_GuidHigh == other.m_GuidHigh) && string.Equals(m_Name, other.m_Name) && ReferenceEquals(m_Entries, other.m_Entries); } /// /// Generates a hash suitable for use with containers like `HashSet` and `Dictionary`. /// /// A hash code generated from this object's fields. public override int GetHashCode() { unchecked { var hash = m_GuidLow.GetHashCode(); hash = hash * 486187739 + m_GuidHigh.GetHashCode(); hash = hash * 486187739 + HashCodeUtil.ReferenceHash(m_Name); hash = hash * 486187739 + HashCodeUtil.ReferenceHash(m_Entries); return hash; } } /// /// Tests for equality. /// /// The `object` to compare against. /// `True` if is of type and /// also returns `true`; otherwise `false`. public override bool Equals(object obj) => obj is XRReferenceObject && Equals((XRReferenceObject)obj); /// /// Tests for equality. Same as . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// `True` if is equal to , otherwise `false`. public static bool operator ==(XRReferenceObject lhs, XRReferenceObject rhs) => lhs.Equals(rhs); /// /// Tests for inequality. Same as `!`. /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// `True` if is not equal to , otherwise `false`. public static bool operator !=(XRReferenceObject lhs, XRReferenceObject rhs) => !lhs.Equals(rhs); #pragma warning disable CS0649 [SerializeField] internal ulong m_GuidLow; [SerializeField] internal ulong m_GuidHigh; [SerializeField] internal string m_Name; [SerializeField] internal List m_Entries; #pragma warning restore CS0649 } }