using System;
using System.Text;
using Unity.Collections;
namespace UnityEngine.XR.ARSubsystems
{
///
/// Container for mesh data associated with an . Not all implementations
/// support all data. Check for existence with NativeArray's IsCreated property.
///
public struct XRFaceMesh : IEquatable, IDisposable
{
///
/// Attributes associated with the face mesh, such as normals and texture coordinates.
/// Vertex positions and triangle indices are assumed to exist already. These are
/// optional attributes. Used with .
///
[Flags]
public enum Attributes
{
///
/// No attributes specified.
///
None = 0,
///
/// The face mesh contains normals.
///
Normals = 1 << 0,
///
/// The face mesh contains texture coordinates.
///
UVs = 1 << 1
}
///
/// Resize the NativeArrays held by this struct. This method will deallocate
/// the NativeArrays if they are not needed or if they are not the correct size.
/// If they are already the correct size, this method does not mutate those NativeArrays.
/// This facilitate memory reuse when the number of vertices or triangles in the face does
/// not change frequently.
///
/// The number of vertices in the mesh.
/// The number of triangles in the mesh.
/// Optional mesh attributes. This affects whether
/// and will be (re)allocated or disposed.
/// If a reallocation is required, this allocator will be used.
public void Resize(
int vertexCount,
int triangleCount,
Attributes attributes,
Allocator allocator)
{
Resize(vertexCount, allocator, ref m_Vertices, true);
Resize(vertexCount, allocator, ref m_Normals, (attributes & Attributes.Normals) != 0);
Resize(vertexCount, allocator, ref m_UVs, (attributes & Attributes.UVs) != 0);
Resize(triangleCount * 3, allocator, ref m_Indices, true);
}
///
/// The vertices in the mesh. This is a parallel array to
/// and .
///
public NativeArray vertices => m_Vertices;
NativeArray m_Vertices;
///
/// The normals in the mesh. This is a parallel array to
/// and .
///
public NativeArray normals => m_Normals;
NativeArray m_Normals;
///
/// The triangle indices of the mesh. There are three times as many indices as triangles.
///
public NativeArray indices => m_Indices;
NativeArray m_Indices;
///
/// The texture coordinates for the mesh. This is a parallel
/// array to and .
///
public NativeArray uvs => m_UVs;
NativeArray m_UVs;
///
/// Disposes of the all four native arrays:
/// , , , and .
/// Checking for creation before calling Dispose.
///
public void Dispose()
{
if (m_Vertices.IsCreated)
m_Vertices.Dispose();
if (m_Normals.IsCreated)
m_Normals.Dispose();
if (m_Indices.IsCreated)
m_Indices.Dispose();
if (m_UVs.IsCreated)
m_UVs.Dispose();
}
///
/// 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_Vertices.GetHashCode();
hash = hash * 486187739 + m_Normals.GetHashCode();
hash = hash * 486187739 + m_Indices.GetHashCode();
hash = hash * 486187739 + m_UVs.GetHashCode();
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)
{
if (!(obj is XRFaceMesh))
return false;
return Equals((XRFaceMesh)obj);
}
///
/// Generates a string suitable for debugging purposes.
///
/// A string representation of this .
public override string ToString()
{
return string.Format("XRFaceMesh: {0} vertices {1} normals {2} indices {3} uvs",
m_Vertices.Length, m_Normals.Length, m_Indices.Length, m_UVs.Length);
}
///
/// Tests for equality.
///
/// The other to compare against.
/// `True` if every field in is equal to this , otherwise false.
public bool Equals(XRFaceMesh other)
{
return
m_Vertices.Equals(other.m_Vertices) &&
m_Normals.Equals(other.m_Normals) &&
m_Indices.Equals(other.m_Indices) &&
m_UVs.Equals(other.m_UVs);
}
///
/// 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 ==(XRFaceMesh lhs, XRFaceMesh 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 !=(XRFaceMesh lhs, XRFaceMesh rhs) => !lhs.Equals(rhs);
static void Resize(int length, Allocator allocator, ref NativeArray array, bool shouldExist) where T : struct
{
if (shouldExist)
{
if (array.IsCreated)
{
if (array.Length != length)
{
array.Dispose();
array = new NativeArray(length, allocator);
}
}
else
{
array = new NativeArray(length, allocator);
}
}
else if (array.IsCreated)
{
array.Dispose();
}
}
}
}