Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
with:
name: Plugins
path: VisualPinball.Unity/Plugins
- uses: actions/cache@v2
- uses: actions/cache@v3.0.1
with:
path: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Library
key: Library-Test-Project
Expand All @@ -67,14 +67,13 @@ jobs:
- uses: game-ci/unity-test-runner@main
id: test
with:
unityVersion: '2021.2.8f1'
projectPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~
artifactsPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/artifacts
testMode: all
customParameters: -debugCodeOptimization -enableCodeCoverage -burst-disable-compilation -coverageOptions enableCyclomaticComplexity;assemblyFilters:+VisualPinball.Engine;pathFilters:-**/VisualPinball.Engine/Math/Triangulator/**,-**/VisualPinball.Engine/Math/Mesh/** -coverageResultsPath artifacts
- run: |
curl -s https://codecov.io/bash | bash -s - -f ${{ steps.test.outputs.artifactsPath }}/TestProject~-opencov/EditMode/TestCoverageResults_0000.xml
- uses: MirrorNG/nunit-reporter@v1.0.11
- uses: MirrorNG/nunit-reporter@v1.1.0
if: always()
with:
path: ${{ steps.test.outputs.artifactsPath }}/*.xml
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Built with Unity 2021.2.
- Native trough component ([#229](https://github.com/freezy/VisualPinball.Engine/pull/229), [#248](https://github.com/freezy/VisualPinball.Engine/pull/248), [#256](https://github.com/freezy/VisualPinball.Engine/pull/256), [Documentation](https://docs.visualpinball.org/creators-guide/manual/mechanisms/troughs.html)).

### Changed

- When importing, meshes are now saved as easily editable `.fbx` files instead of Unity's internal format ([#387](https://github.com/freezy/VisualPinball.Engine/pull/387)).
- Revised rubber mesh generation ([#384](https://github.com/freezy/VisualPinball.Engine/pull/384)).
- APIs for RGB lamps and Visual Scripting ([#382](https://github.com/freezy/VisualPinball.Engine/pull/382)).
- Playfield is now rotated to the correct angle during gameplay ([#370](https://github.com/freezy/VisualPinball.Engine/pull/370)).
Expand All @@ -51,8 +51,8 @@ Built with Unity 2021.2.
- Put game-, mesh-, collision- animation data into separate components ([#227](https://github.com/freezy/VisualPinball.Engine/pull/227), [Documentation](https://docs.visualpinball.org/creators-guide/editor/unity-components.html)).

### Fixed

- Remaining ball spinning issue should now be solved ([#397](https://github.com/freezy/VisualPinball.Engine/pull/397)).
- Physics error when the ball would stop rotate ([#393](https://github.com/freezy/VisualPinball.Engine/pull/393)).
- Finally, ball rotation is rendered correctly ([#386](https://github.com/freezy/VisualPinball.Engine/pull/386)).
- Ball stuttering when rolling over dropped target ([#375](https://github.com/freezy/VisualPinball.Engine/pull/375)).
- Plunger disappearing due to too small bounding box.
Expand Down
21 changes: 21 additions & 0 deletions VisualPinball.Engine/Math/Vertex3DNoTex2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ public bool Equals(Vertex3DNoTex2 other)
{
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);
}

public bool Equals(Vertex3DNoTex2 other, int precision)
{
return Round(X, precision) == Round(other.X, precision)
&& Round(Y, precision) == Round(other.Y, precision)
&& Round(Z, precision) == Round(other.Z, precision)
&& Round(Nx, precision) == Round(other.Nx, precision)
&& Round(Ny, precision) == Round(other.Ny, precision)
&& Round(Nz, precision) == Round(other.Nz, precision)
&& Round(Tu, precision) == Round(other.Tu, precision)
&& Round(Tv, precision) == Round(other.Tv, precision);
}

public override bool Equals(object obj)
{
return obj is Vertex3DNoTex2 other && Equals(other);
Expand All @@ -131,5 +144,13 @@ public override int GetHashCode()
{
return (X, Y, Z, Nx, Ny, Nz, Tu, Tv).GetHashCode();
}

public int GetRoundedHash(int digits) => (
Round(X, digits), Round(Y, digits), Round(Z, digits),
Round(Nx, digits), Round(Ny, digits), Round(Nz, digits),
Round(Tu, digits), Round(Tv, digits)
).GetHashCode();

private static int Round(float value, int digits) => (int)System.Math.Round(value * System.Math.Pow(10, digits));
}
}
62 changes: 57 additions & 5 deletions VisualPinball.Engine/VPT/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -494,20 +494,35 @@ public override int GetHashCode()

#region IEquatable

public bool Equals(Mesh other)
public bool SomewhatEquals(Mesh other, float trianglesToBeMatched, int precision)
{
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
if (!Name.Equals(other.Name) || Vertices.Length != other.Vertices.Length
|| Indices.Length != other.Indices.Length
|| AnimationFrames.Count != other.AnimationFrames.Count
|| !AnimationDefaultPosition.Equals(other.AnimationDefaultPosition)) {
var triangles1 = IndexTriangles(Vertices, Indices, precision);
var triangles2 = IndexTriangles(other.Vertices, other.Indices, precision);

using var enumerator = triangles1.GetEnumerator();
var matched = 0;
foreach (var hash in triangles1.Keys) {
if (triangles2.ContainsKey(hash)) {
matched++;
}
}
return matched / (float)triangles1.Count > trianglesToBeMatched;
}

public bool Equals(Mesh other)
{
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}

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

private Vertex3DNoTex2[] Find(IEnumerable<Vertex3DNoTex2> vertices, Vertex3DNoTex2 vertex, int precision)
{
return vertices.Where(v => v.Equals(vertex, precision)).ToArray();
}

private static Dictionary<int, Vertex3DNoTex2[]> IndexTriangles(IReadOnlyList<Vertex3DNoTex2> vertices, IReadOnlyList<int> indices, int precision)
{
var triangles = new Dictionary<int, Vertex3DNoTex2[]>();
for (var i = 0; i < indices.Count; i += 3) {
var hash = HashTriangle(Sort(
vertices[indices[i]],
vertices[indices[i + 1]],
vertices[indices[i + 2]]
), precision);
triangles.Add(hash, new [] { vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]] });
}
return triangles;
}

private static Vertex3DNoTex2[] Sort(params Vertex3DNoTex2[] vertices)
{
var firstVertex = vertices
.OrderBy(s => s.X).ThenBy(s => s.Y).ThenBy(s => s.Z)
.ThenBy(s => s.Nx).ThenBy(s => s.Ny).ThenBy(s => s.Nz)
.ThenBy(s => s.Tu).ThenBy(s => s.Tv)
.First();
var firstVertexIndex = Array.IndexOf(vertices, firstVertex);
return new[] {
vertices[firstVertexIndex],
vertices[(firstVertexIndex + 1) % 3],
vertices[(firstVertexIndex + 2) % 3]
};
}

private static int HashTriangle(IReadOnlyList<Vertex3DNoTex2> vertices, int precision)
=> (vertices[0].GetRoundedHash(precision), vertices[1].GetRoundedHash(precision), vertices[2].GetRoundedHash(precision)).GetHashCode();

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) {
Expand Down
Loading