Skip to content

Commit 5073408

Browse files
committed
fix: Primitive tests.
1 parent f5f9664 commit 5073408

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed

VisualPinball.Engine/Math/Vertex3DNoTex2.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ public bool Equals(Vertex3DNoTex2 other)
122122
{
123123
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && Nx.Equals(other.Nx) && Ny.Equals(other.Ny) && Nz.Equals(other.Nz) && Tu.Equals(other.Tu) && Tv.Equals(other.Tv);
124124
}
125+
126+
public bool Equals(Vertex3DNoTex2 other, int precision)
127+
{
128+
return Round(X, precision) == Round(other.X, precision)
129+
&& Round(Y, precision) == Round(other.Y, precision)
130+
&& Round(Z, precision) == Round(other.Z, precision)
131+
&& Round(Nx, precision) == Round(other.Nx, precision)
132+
&& Round(Ny, precision) == Round(other.Ny, precision)
133+
&& Round(Nz, precision) == Round(other.Nz, precision)
134+
&& Round(Tu, precision) == Round(other.Tu, precision)
135+
&& Round(Tv, precision) == Round(other.Tv, precision);
136+
}
137+
125138
public override bool Equals(object obj)
126139
{
127140
return obj is Vertex3DNoTex2 other && Equals(other);
@@ -131,5 +144,13 @@ public override int GetHashCode()
131144
{
132145
return (X, Y, Z, Nx, Ny, Nz, Tu, Tv).GetHashCode();
133146
}
147+
148+
public int GetRoundedHash(int digits) => (
149+
Round(X, digits), Round(Y, digits), Round(Z, digits),
150+
Round(Nx, digits), Round(Ny, digits), Round(Nz, digits),
151+
Round(Tu, digits), Round(Tv, digits)
152+
).GetHashCode();
153+
154+
private static int Round(float value, int digits) => (int)System.Math.Round(value * System.Math.Pow(10, digits));
134155
}
135156
}

VisualPinball.Engine/VPT/Mesh.cs

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,20 +494,35 @@ public override int GetHashCode()
494494

495495
#region IEquatable
496496

497-
public bool Equals(Mesh other)
497+
public bool SomewhatEquals(Mesh other, float trianglesToBeMatched, int precision)
498498
{
499499
if (ReferenceEquals(null, other)) {
500500
return false;
501501
}
502502
if (ReferenceEquals(this, other)) {
503503
return true;
504504
}
505-
if (!Name.Equals(other.Name) || Vertices.Length != other.Vertices.Length
506-
|| Indices.Length != other.Indices.Length
507-
|| AnimationFrames.Count != other.AnimationFrames.Count
508-
|| !AnimationDefaultPosition.Equals(other.AnimationDefaultPosition)) {
505+
var triangles1 = IndexTriangles(Vertices, Indices, precision);
506+
var triangles2 = IndexTriangles(other.Vertices, other.Indices, precision);
507+
508+
using var enumerator = triangles1.GetEnumerator();
509+
var matched = 0;
510+
foreach (var hash in triangles1.Keys) {
511+
if (triangles2.ContainsKey(hash)) {
512+
matched++;
513+
}
514+
}
515+
return matched / (float)triangles1.Count > trianglesToBeMatched;
516+
}
517+
518+
public bool Equals(Mesh other)
519+
{
520+
if (ReferenceEquals(null, other)) {
509521
return false;
510522
}
523+
if (ReferenceEquals(this, other)) {
524+
return true;
525+
}
511526

512527
for (var i = 0; i < Vertices.Length; i++) {
513528
if (!Vertices[i].Equals(other.Vertices[i])) {
@@ -532,6 +547,43 @@ public bool Equals(Mesh other)
532547
return true;
533548
}
534549

550+
private Vertex3DNoTex2[] Find(IEnumerable<Vertex3DNoTex2> vertices, Vertex3DNoTex2 vertex, int precision)
551+
{
552+
return vertices.Where(v => v.Equals(vertex, precision)).ToArray();
553+
}
554+
555+
private static Dictionary<int, Vertex3DNoTex2[]> IndexTriangles(IReadOnlyList<Vertex3DNoTex2> vertices, IReadOnlyList<int> indices, int precision)
556+
{
557+
var triangles = new Dictionary<int, Vertex3DNoTex2[]>();
558+
for (var i = 0; i < indices.Count; i += 3) {
559+
var hash = HashTriangle(Sort(
560+
vertices[indices[i]],
561+
vertices[indices[i + 1]],
562+
vertices[indices[i + 2]]
563+
), precision);
564+
triangles.Add(hash, new [] { vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]] });
565+
}
566+
return triangles;
567+
}
568+
569+
private static Vertex3DNoTex2[] Sort(params Vertex3DNoTex2[] vertices)
570+
{
571+
var firstVertex = vertices
572+
.OrderBy(s => s.X).ThenBy(s => s.Y).ThenBy(s => s.Z)
573+
.ThenBy(s => s.Nx).ThenBy(s => s.Ny).ThenBy(s => s.Nz)
574+
.ThenBy(s => s.Tu).ThenBy(s => s.Tv)
575+
.First();
576+
var firstVertexIndex = Array.IndexOf(vertices, firstVertex);
577+
return new[] {
578+
vertices[firstVertexIndex],
579+
vertices[(firstVertexIndex + 1) % 3],
580+
vertices[(firstVertexIndex + 2) % 3]
581+
};
582+
}
583+
584+
private static int HashTriangle(IReadOnlyList<Vertex3DNoTex2> vertices, int precision)
585+
=> (vertices[0].GetRoundedHash(precision), vertices[1].GetRoundedHash(precision), vertices[2].GetRoundedHash(precision)).GetHashCode();
586+
535587
public override bool Equals(object obj)
536588
{
537589
if (ReferenceEquals(null, obj)) {

VisualPinball.Unity/VisualPinball.Unity.Test/VPT/PrimitiveTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void ShouldWriteImportedMesh()
5757
var table = FileTableContainer.Load(VpxPath.Primitive);
5858
var originalMesh = table.Primitive(primitiveName).GetMesh();
5959

60-
Assert.AreEqual(originalMesh, writtenMesh);
60+
Assert.IsTrue(originalMesh.SomewhatEquals(writtenMesh, 0.9f, 4));
6161

6262
File.Delete(tmpFileName);
6363
Object.DestroyImmediate(go);

VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ public override PrimitiveData CopyDataTo(PrimitiveData data, string[] materialNa
196196
var mf = GetComponent<MeshFilter>();
197197
if (mf) {
198198
data.Mesh = mf.sharedMesh.ToVpMesh();
199+
data.NumIndices = data.Mesh.Indices.Length;
200+
data.NumVertices = data.Mesh.Vertices.Length;
199201
}
200202
}
201203
}

0 commit comments

Comments
 (0)