Files
bansonic_beta_main/Assets/openFracture/OpenFracture-main/Tests/Runtime/SlicedMeshDataTests.cs
T

383 lines
13 KiB
C#

using NUnit.Framework;
using UnityEngine;
public class FragmentDataTests
{
[Test]
public void EmptyInit()
{
int vertexCount = 101;
FragmentData data = new FragmentData(vertexCount, 0);
// Verify initialization
Assert.AreEqual(vertexCount, data.Vertices.Capacity);
Assert.AreEqual(vertexCount, data.IndexMap.Length);
Assert.Zero(data.Vertices.Count);
Assert.Zero(data.CutVertices.Count);
Assert.Zero(data.Constraints.Count);
Assert.Zero(data.triangleCount);
Assert.Zero(data.vertexCount);
// Assume two submeshes for now
Assert.AreEqual(data.Triangles.Length, 2);
}
[Test]
public void MeshInit()
{
// Test mesh data
var vertices = new Vector3[] {
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(0, 1, 0),
new Vector3(1, 1, 0)
};
var normals = new Vector3[] {
new Vector3(-0.1f, -0.1f, 1).normalized,
new Vector3(0.1f, -0.1f, 1).normalized,
new Vector3(-0.1f, 0.1f, 1).normalized,
new Vector3(0.1f, 0.1f, 1).normalized
};
var uv = new Vector2[] {
new Vector3(0, 0),
new Vector3(1, 0),
new Vector3(0, 1),
new Vector3(1, 1)
};
var triangles = new int[] { 0, 2, 1, 1, 2, 3 };
// Setup the test mesh
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.normals = normals;
mesh.uv = uv;
// Generate the sliced mesh data from the mesh
FragmentData meshData = new FragmentData(mesh);
// Verify sliced mesh data was initialized properly
// Check vertex data
Assert.AreEqual(mesh.vertexCount, meshData.Vertices.Count);
for(int i = 0; i < meshData.Vertices.Count; i++)
{
var vertex = meshData.Vertices[i];
Assert.AreEqual(vertices[i], vertex.position);
Assert.AreEqual(normals[i], vertex.normal);
Assert.AreEqual(uv[i], vertex.uv);
}
// Check triangle data
Assert.AreEqual(mesh.triangles.Length, meshData.Triangles[0].Count);
// Assume two submeshes for now
Assert.AreEqual(2, meshData.Triangles.Length);
Assert.Zero(meshData.CutVertices.Count);
Assert.Zero(meshData.Constraints.Count);
Assert.AreEqual(mesh.vertexCount, meshData.IndexMap.Length);
}
[Test]
public void AddCutFaceVertex()
{
int vertexCount = 10;
var meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
meshData.AddCutFaceVertex(
new Vector3(i + 1, i + 2, i + 3),
new Vector3(i + 4, i + 5, i + 6),
new Vector2(i + 7, i + 8)
);
}
// Vertex add to both main vertex data and cut-face vertex data
Assert.AreEqual(vertexCount, meshData.Vertices.Count);
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
// Index map should be updated as well
for (int i = 0; i < vertexCount; i++)
{
Assert.AreEqual(new Vector3(i + 1, i + 2, i + 3), meshData.Vertices[i].position);
Assert.AreEqual(new Vector3(i + 4, i + 5, i + 6), meshData.Vertices[i].normal);
Assert.AreEqual(new Vector2(i + 7, i + 8), meshData.Vertices[i].uv);
Assert.AreEqual(new Vector3(i + 1, i + 2, i + 3), meshData.CutVertices[i].position);
Assert.AreEqual(new Vector3(i + 4, i + 5, i + 6), meshData.CutVertices[i].normal);
Assert.AreEqual(new Vector2(i + 7, i + 8), meshData.CutVertices[i].uv);
}
}
[Test]
public void AddMappedVertex()
{
int vertexCount = 10;
var meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
MeshVertex vertex = new MeshVertex(
new Vector3(i + 1, i + 2, i + 3),
new Vector3(i + 4, i + 5, i + 6),
new Vector2(i + 7, i + 8));
meshData.AddMappedVertex(vertex, i);
}
// Vertex added only to main vertex data
Assert.AreEqual(vertexCount, meshData.Vertices.Count);
Assert.AreEqual(0, meshData.CutVertices.Count);
// Index map should be updated as well
for (int i = 0; i < vertexCount; i++)
{
Assert.AreEqual(new Vector3(i + 1, i + 2, i + 3), meshData.Vertices[i].position);
Assert.AreEqual(new Vector3(i + 4, i + 5, i + 6), meshData.Vertices[i].normal);
Assert.AreEqual(new Vector2(i + 7, i + 8), meshData.Vertices[i].uv);
Assert.AreEqual(i, meshData.IndexMap[i]);
}
}
[Test]
public void AddTriangle()
{
FragmentData meshData = new FragmentData(0, 0);
int v1 = 1;
int v2 = 2;
int v3 = 3;
meshData.AddTriangle(v1, v2, v3, SlicedMeshSubmesh.Default);
Assert.AreEqual(3, meshData.Triangles[(int)SlicedMeshSubmesh.Default].Count);
Assert.AreEqual(v1, meshData.Triangles[(int)SlicedMeshSubmesh.Default][0]);
Assert.AreEqual(v2, meshData.Triangles[(int)SlicedMeshSubmesh.Default][1]);
Assert.AreEqual(v3, meshData.Triangles[(int)SlicedMeshSubmesh.Default][2]);
}
[Test]
public void AddMappedTriangle()
{
int vertexCount = 46;
FragmentData meshData = new FragmentData(vertexCount, 0);
// Indices of the vertices in the original mesh (arbitary indices)
int v1 = 11;
int v2 = 23;
int v3 = 45;
// First, add the vertx data. v1, v2, v3 will be mapped to the indices
// 0, 1, 2 (respectively) since that is the order they are added
meshData.AddMappedVertex(new MeshVertex(Vector3.zero), v1);
int v1Mapped = meshData.vertexCount - 1;
meshData.AddMappedVertex(new MeshVertex(Vector3.zero), v2);
int v2Mapped = meshData.vertexCount - 1;
meshData.AddMappedVertex(new MeshVertex(Vector3.zero), v3);
int v3Mapped = meshData.vertexCount - 1;
// Add the triangle, but map v1, v2, v3 to the indices for the sliced mesh
meshData.AddMappedTriangle(v1, v2, v3, SlicedMeshSubmesh.Default);
Assert.AreEqual(3, meshData.Triangles[(int)SlicedMeshSubmesh.Default].Count);
Assert.AreEqual(v1Mapped, meshData.Triangles[(int)SlicedMeshSubmesh.Default][0]);
Assert.AreEqual(v2Mapped, meshData.Triangles[(int)SlicedMeshSubmesh.Default][1]);
Assert.AreEqual(v3Mapped, meshData.Triangles[(int)SlicedMeshSubmesh.Default][2]);
}
[Test]
public void WeldCutFaceVertices_AllVerticesUnique()
{
int vertexCount = 10;
FragmentData meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
meshData.AddCutFaceVertex(
new Vector3(i + 1, i + 2, i + 3),
Vector3.zero,
Vector2.zero
);
}
// Verify vertex count prior to weld
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
meshData.WeldCutFaceVertices();
// # of cut vertices should remain unchanged after weld
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
}
[Test]
public void WeldCutFaceVertices_OneDuplicateVertex()
{
int vertexCount = 10;
FragmentData meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
meshData.AddCutFaceVertex(
new Vector3(i + 1, i + 2, i + 3),
Vector3.zero,
Vector2.zero
);
}
// Duplicate one of the vertices
meshData.CutVertices[vertexCount - 1] = meshData.CutVertices[0];
// Verify vertex count prior to weld
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
meshData.WeldCutFaceVertices();
// Expect two vertices welded, so final count is one less vertex
Assert.AreEqual(vertexCount - 1, meshData.CutVertices.Count);
}
[Test]
public void WeldCutFaceVertices_GreaterThanEpsilon()
{
int vertexCount = 10;
FragmentData meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
meshData.AddCutFaceVertex(
new Vector3(i + 1, i + 2, i + 3),
Vector3.zero,
Vector2.zero
);
}
var magnitude = meshData.CutVertices[0].position.magnitude;
// According to Unity documentation, == comparison between two vectors
// returns true if their magnitude is less than 1E-5. We make two vertices
// differ by slightly larger than this amount so that they are not welded together.
meshData.CutVertices[vertexCount - 1] = new MeshVertex(
(magnitude + 1.1E-5f) * meshData.CutVertices[0].position.normalized,
Vector3.zero,
Vector2.zero
);
// Verify vertex count prior to weld
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
meshData.WeldCutFaceVertices();
// Expect same vertex count since no vertices welded
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
}
[Test]
public void WeldCutFaceVertices_LessThanEpsilon()
{
int vertexCount = 10;
FragmentData meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
meshData.AddCutFaceVertex(
new Vector3(i + 1, i + 2, i + 3),
Vector3.zero,
Vector2.zero
);
}
var magnitude = meshData.CutVertices[0].position.magnitude;
// According to Unity documentation, == comparison between two vectors
// returns true if their magnitude is less than 1E-5. We make two vertices
// differ by slightly less than this amount so that they are welded together.
meshData.CutVertices[vertexCount - 1] = new MeshVertex(
(magnitude + 0.9E-5f) * meshData.CutVertices[0].position.normalized,
Vector3.zero,
Vector2.zero
);
// Verify vertex count prior to weld
Assert.AreEqual(vertexCount, meshData.CutVertices.Count);
meshData.WeldCutFaceVertices();
// Expect two vertices welded, so final count is one less vertex
Assert.AreEqual(vertexCount - 1, meshData.CutVertices.Count);
}
[Test]
public void WeldCutFaceVertices_CutEdgeUpdate()
{
int vertexCount = 10;
FragmentData meshData = new FragmentData(vertexCount, 0);
for (int i = 0; i < vertexCount; i++)
{
meshData.AddCutFaceVertex(
new Vector3(i + 1, i + 2, i + 3),
Vector3.zero,
Vector2.zero
);
}
// Last vertex is equal to the first vertex
meshData.CutVertices[vertexCount - 1] = meshData.CutVertices[0];
// Add cut edges that map to the duplicate vertex
meshData.Constraints.Add(new EdgeConstraint(0, vertexCount - 1));
// Assert expected edge state prior to weld
Assert.AreEqual(0, meshData.Constraints[0].v1);
Assert.AreEqual(vertexCount - 1, meshData.Constraints[0].v2);
meshData.WeldCutFaceVertices();
// Assert expected edge state after the weld
Assert.AreEqual(0, meshData.Constraints[0].v1);
Assert.AreEqual(0, meshData.Constraints[0].v2);
}
[Test]
public void ToMesh()
{
int vertexCount = 100;
int cutVertexCount = 50;
int triangleCount1 = 10;
int triangleCount2 = 15;
FragmentData meshData = new FragmentData(vertexCount, 0);
// Add some fake data
for (int i = 0; i < vertexCount; i++)
{
meshData.AddMappedVertex(new MeshVertex(), 0);
}
for (int i = 0; i < cutVertexCount; i++)
{
meshData.AddCutFaceVertex(Vector3.zero, Vector3.zero, Vector2.zero);
}
for (int i = 0; i < triangleCount1; i++)
{
meshData.AddTriangle(0, 0, 0, SlicedMeshSubmesh.Default);
}
for (int i = 0; i < triangleCount2; i++)
{
meshData.AddTriangle(0, 0, 0, SlicedMeshSubmesh.CutFace);
}
Mesh mesh = meshData.ToMesh();
// Each time we add a cut face vertex, it adds two vertices, one for the
// original sub mesh and another for the cut face sub mesh.
Assert.AreEqual(vertexCount + 2 * cutVertexCount, mesh.vertexCount);
Assert.AreEqual(2, mesh.subMeshCount);
// Three indices for each triangle
Assert.AreEqual(3 * triangleCount1, mesh.GetTriangles(0).Length);
Assert.AreEqual(3 * triangleCount2, mesh.GetTriangles(1).Length);
}
}