using System; using System.Runtime.InteropServices; namespace UnityEngine.XR.ARSubsystems { /// /// The session-relative data associated with a plane. /// /// [StructLayout(LayoutKind.Sequential)] public struct BoundedPlane : ITrackable, IEquatable { static readonly BoundedPlane s_Default = new BoundedPlane( TrackableId.invalidId, TrackableId.invalidId, Pose.identity, Vector2.zero, Vector2.zero, PlaneAlignment.None, TrackingState.None, IntPtr.Zero, PlaneClassification.None); /// /// Gets a default-initialized . This can be /// different from the zero-initialized version, e.g., the /// is Pose.identity instead of zero-initialized. /// public static BoundedPlane defaultValue => s_Default; /// /// Constructs a new . This is just a data container /// for a plane's session relative data. These are typically created by /// . /// /// The associated with the plane. /// The plane which subsumed this one. Use if it has not been subsumed. /// The Pose associated with the plane. /// The center of the plane, in plane space (relative to ). /// The dimensions associated with the plane. /// The associated with the plane. /// The associated with the plane. /// The native pointer associated with the plane. /// The associated with the plane. public BoundedPlane( TrackableId trackableId, TrackableId subsumedBy, Pose pose, Vector2 center, Vector2 size, PlaneAlignment alignment, TrackingState trackingState, IntPtr nativePtr, PlaneClassification classification) { m_TrackableId = trackableId; m_SubsumedById = subsumedBy; m_Pose = pose; m_Center = center; m_Size = size; m_Alignment = alignment; m_TrackingState = trackingState; m_NativePtr = nativePtr; m_Classification = classification; } /// /// The associated with this plane. /// public TrackableId trackableId => m_TrackableId; /// /// The associated with the plane which subsumed this one. Will be /// if this plane has not been subsumed. /// public TrackableId subsumedById => m_SubsumedById; /// /// The Pose, in session space, of the plane. /// public Pose pose => m_Pose; /// /// The center of the plane in plane space (relative to its ). /// public Vector2 center => m_Center; /// /// The extents of the plane (half dimensions) in meters. /// public Vector2 extents => m_Size * 0.5f; /// /// The size (dimensions) of the plane in meters. /// public Vector2 size => m_Size; /// /// The of the plane. /// public PlaneAlignment alignment => m_Alignment; /// /// The of the plane. /// public TrackingState trackingState => m_TrackingState; /// /// A native pointer associated with this plane. /// The data pointer to by this pointer is implementation defined. /// public IntPtr nativePtr => m_NativePtr; /// /// The of the plane. /// public PlaneClassification classification => m_Classification; /// /// The width of the plane in meters. /// public float width => m_Size.x; /// /// The height (or depth) of the plane in meters. /// public float height => m_Size.y; /// /// The normal of the plane in session space. /// public Vector3 normal => m_Pose.up; /// /// Gets an infinite plane in session space. /// public Plane plane => new Plane(normal, center); /// /// Get the four corners of the plane in session space, in clockwise order. /// /// The first vertex. /// The second vertex. /// The third vertex. /// The fourth vertex. public void GetCorners( out Vector3 p0, out Vector3 p1, out Vector3 p2, out Vector3 p3) { var sessionCenter = m_Pose.rotation * center + m_Pose.position; var sessionHalfX = (m_Pose.right) * (width * .5f); var sessionHalfZ = (m_Pose.forward) * (height * .5f); p0 = sessionCenter - sessionHalfX - sessionHalfZ; p1 = sessionCenter - sessionHalfX + sessionHalfZ; p2 = sessionCenter + sessionHalfX + sessionHalfZ; p3 = sessionCenter + sessionHalfX - sessionHalfZ; } /// /// Generates a new string that describes the plane's properties, suitable for debugging purposes. /// /// A string that describes the plane's properties. public override string ToString() { return string.Format( "Plane:\n\ttrackableId: {0}\n\tsubsumedById: {1}\n\tpose: {2}\n\tcenter: {3}\n\tsize: {4}\n\talignment: {5}\n\tclassification: {6}\n\ttrackingState: {7}\n\tnativePtr: {8:X16}", trackableId, subsumedById, pose, center, size, alignment, classification, trackingState, nativePtr.ToInt64()); } /// /// 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 BoundedPlane other) && Equals(other); /// /// 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 hashCode = m_TrackableId.GetHashCode(); hashCode = (hashCode * 486187739) + m_SubsumedById.GetHashCode(); hashCode = (hashCode * 486187739) + m_Pose.GetHashCode(); hashCode = (hashCode * 486187739) + m_Center.GetHashCode(); hashCode = (hashCode * 486187739) + m_Size.GetHashCode(); hashCode = (hashCode * 486187739) + ((int)m_Alignment).GetHashCode(); hashCode = (hashCode * 486187739) + ((int)m_Classification).GetHashCode(); hashCode = (hashCode * 486187739) + ((int)m_TrackingState).GetHashCode(); hashCode = (hashCode * 486187739) + m_NativePtr.GetHashCode(); return hashCode; } } /// /// 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 ==(BoundedPlane lhs, BoundedPlane 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 !=(BoundedPlane lhs, BoundedPlane rhs) => !lhs.Equals(rhs); /// /// Tests for equality. /// /// The other to compare against. /// `True` if every field in is equal to this , otherwise false. public bool Equals(BoundedPlane other) { return m_TrackableId.Equals(other.m_TrackableId) && m_SubsumedById.Equals(other.m_SubsumedById) && m_Pose.Equals(other.m_Pose) && m_Center.Equals(other.m_Center) && m_Size.Equals(other.m_Size) && (m_Alignment == other.m_Alignment) && (m_Classification == other.m_Classification) && (m_TrackingState == other.m_TrackingState) && (m_NativePtr == other.m_NativePtr); } TrackableId m_TrackableId; TrackableId m_SubsumedById; Vector2 m_Center; Pose m_Pose; Vector2 m_Size; PlaneAlignment m_Alignment; TrackingState m_TrackingState; IntPtr m_NativePtr; PlaneClassification m_Classification; } }