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
{
get { return m_Vertices; }
}
NativeArray m_Vertices;
///
/// The normals in the mesh. This is a parallel array to
/// and .
///
public NativeArray normals
{
get { return m_Normals; }
}
NativeArray m_Normals;
///
/// The triangle indices of the mesh. There are three times as many indices as triangles.
///
public NativeArray indices
{
get { return m_Indices; }
}
NativeArray m_Indices;
///
/// The texture coordinates for the mesh. This is a parallel
/// array to and .
///
public NativeArray uvs
{
get { return 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();
}
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;
}
}
public override bool Equals(object obj)
{
if (!(obj is XRFaceMesh))
return false;
return Equals((XRFaceMesh)obj);
}
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);
}
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);
}
public static bool operator ==(XRFaceMesh lhs, XRFaceMesh rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(XRFaceMesh lhs, XRFaceMesh rhs)
{
return !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();
}
}
}
}