diff --git a/Assets/Scripts/ServerShared/Delaunay.cs b/Assets/Scripts/ServerShared/Delaunay.cs new file mode 100644 index 000000000..b6a25bba6 --- /dev/null +++ b/Assets/Scripts/ServerShared/Delaunay.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using CultMath; + +// The Delaunay triangulation of a galaxy's zone positions, as the edges Galaxy links zones along. Bowyer-Watson +// (Bowyer 1981, Watson 1981) in double precision: each point is inserted by removing every triangle whose +// circumcircle holds it and fanning the cavity's boundary to it. Every point lands in the triangulation, so for two or +// more distinct points the edge graph is connected. +public static class Delaunay +{ + // Each edge once, as (lower index, higher index), in ascending order. + public static List<(int a, int b)> Edges(IReadOnlyList points) + { + var n = points.Count; + var x = new double[n + 3]; + var y = new double[n + 3]; + double minX = double.MaxValue, minY = double.MaxValue, maxX = double.MinValue, maxY = double.MinValue; + for (var i = 0; i < n; i++) + { + x[i] = points[i].x; + y[i] = points[i].y; + minX = Math.Min(minX, x[i]); + minY = Math.Min(minY, y[i]); + maxX = Math.Max(maxX, x[i]); + maxY = Math.Max(maxY, y[i]); + } + + // A super-triangle far outside the points, so its vertices bend no edge between them; its triangles are + // dropped at the end. + var size = Math.Max(Math.Max(maxX - minX, maxY - minY), 1e-6) * 1000; + double midX = (minX + maxX) / 2, midY = (minY + maxY) / 2; + x[n] = midX - size; y[n] = midY - size; + x[n + 1] = midX + size; y[n + 1] = midY - size; + x[n + 2] = midX; y[n + 2] = midY + size; + + var triangles = new List { new Triangle(n, n + 1, n + 2, x, y) }; + var cavity = new Dictionary<(int, int), int>(); + for (var p = 0; p < n; p++) + { + cavity.Clear(); + for (var t = triangles.Count - 1; t >= 0; t--) + { + var triangle = triangles[t]; + var dx = x[p] - triangle.CenterX; + var dy = y[p] - triangle.CenterY; + if (dx * dx + dy * dy >= triangle.RadiusSquared) continue; + Count(cavity, triangle.A, triangle.B); + Count(cavity, triangle.B, triangle.C); + Count(cavity, triangle.C, triangle.A); + triangles[t] = triangles[triangles.Count - 1]; + triangles.RemoveAt(triangles.Count - 1); + } + + // The cavity's boundary is every edge only one removed triangle had. + foreach (var edge in cavity) + if (edge.Value == 1) + triangles.Add(new Triangle(edge.Key.Item1, edge.Key.Item2, p, x, y)); + } + + var edges = new SortedSet<(int a, int b)>(); + foreach (var triangle in triangles) + { + if (triangle.A >= n || triangle.B >= n || triangle.C >= n) continue; + edges.Add(Ordered(triangle.A, triangle.B)); + edges.Add(Ordered(triangle.B, triangle.C)); + edges.Add(Ordered(triangle.C, triangle.A)); + } + return new List<(int a, int b)>(edges); + } + + private static void Count(Dictionary<(int, int), int> cavity, int a, int b) + { + var key = Ordered(a, b); + cavity[key] = cavity.TryGetValue(key, out var seen) ? seen + 1 : 1; + } + + private static (int a, int b) Ordered(int a, int b) => a < b ? (a, b) : (b, a); + + private readonly struct Triangle + { + public readonly int A, B, C; + public readonly double CenterX, CenterY, RadiusSquared; + + public Triangle(int a, int b, int c, double[] x, double[] y) + { + A = a; + B = b; + C = c; + double ax = x[a], ay = y[a], bx = x[b], by = y[b], cx = x[c], cy = y[c]; + var d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)); + double a2 = ax * ax + ay * ay, b2 = bx * bx + by * by, c2 = cx * cx + cy * cy; + CenterX = (a2 * (by - cy) + b2 * (cy - ay) + c2 * (ay - by)) / d; + CenterY = (a2 * (cx - bx) + b2 * (ax - cx) + c2 * (bx - ax)) / d; + RadiusSquared = (ax - CenterX) * (ax - CenterX) + (ay - CenterY) * (ay - CenterY); + } + } +} diff --git a/Assets/Scripts/ServerShared/Delaunay.cs.meta b/Assets/Scripts/ServerShared/Delaunay.cs.meta new file mode 100644 index 000000000..917f6e6b4 --- /dev/null +++ b/Assets/Scripts/ServerShared/Delaunay.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a05b77dab9114e19b222b79a8403fc21 diff --git a/Assets/Scripts/ServerShared/Galaxy.cs b/Assets/Scripts/ServerShared/Galaxy.cs index 7291a0c38..bcdf7a2f8 100644 --- a/Assets/Scripts/ServerShared/Galaxy.cs +++ b/Assets/Scripts/ServerShared/Galaxy.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using DataStructures.ViliWonka.Heap; using Ink.Runtime; -using MIConvexHull; using JM.LinqFaster; using UniRx; using CultMath; @@ -361,22 +360,10 @@ public class Galaxy progressCallback?.Invoke("Triangulating Zone Positions"); if (progressCallback != null) Thread.Sleep(500); // Inserting Delay to make it seem like it's doing more work lmao - // Create a delaunay triangulation to connect adjacent sectors - var triangulation = DelaunayTriangulation, Cell2> - .Create(Zones.Select(z => new Vertex2(z.Position, z)).ToList(), 1e-7f); - var links = new HashSet<(GalaxyZone, GalaxyZone)>(); - foreach (var cell in triangulation.Cells) - { - if (!links.Contains((cell.Vertices[0].StoredObject, cell.Vertices[1].StoredObject)) && - !links.Contains((cell.Vertices[1].StoredObject, cell.Vertices[0].StoredObject))) - links.Add((cell.Vertices[0].StoredObject, cell.Vertices[1].StoredObject)); - if (!links.Contains((cell.Vertices[1].StoredObject, cell.Vertices[2].StoredObject)) && - !links.Contains((cell.Vertices[2].StoredObject, cell.Vertices[1].StoredObject))) - links.Add((cell.Vertices[1].StoredObject, cell.Vertices[2].StoredObject)); - if (!links.Contains((cell.Vertices[0].StoredObject, cell.Vertices[2].StoredObject)) && - !links.Contains((cell.Vertices[2].StoredObject, cell.Vertices[0].StoredObject))) - links.Add((cell.Vertices[0].StoredObject, cell.Vertices[2].StoredObject)); - } + // The Delaunay triangulation connects adjacent sectors, every zone among them + var links = Delaunay.Edges(Zones.Select(z => z.Position).ToArray()) + .Select(edge => (Zones[edge.a], Zones[edge.b])) + .ToList(); progressCallback?.Invoke("Eliminating Zone Links"); if (progressCallback != null) Thread.Sleep(500); // Inserting Delay to make it seem like it's doing more work lmao diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull.meta deleted file mode 100644 index 5f927b59d..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4a109a0b0bb6e8f40935ca2ec55e5bd7 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2.cs deleted file mode 100644 index 6e8a8d2f9..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Collections; -using System.Linq; -using MIConvexHull; -using CultMath; -using static CultMath.math; - -/// -/// A vertex is a simple class that stores the postion of a point, node or vertex. -/// -public class Cell2 : TriangulationCell -{ - float2? circumCenter, centroid; - - public float2 Circumcenter { - get { - circumCenter = circumCenter ?? GetCircumcenter(); - return circumCenter.Value; - } - } - - public float2 Centroid { - get { - centroid = centroid ?? GetCentroid(); - return centroid.Value; - } - } - - public Cell2 () - { - - } - - double LengthSquared (float[] v) - { - float norm = 0; - for (int i = 0; i < v.Length; i++) { - var t = v [i]; - norm += t * t; - } - return norm; - } - - float Determinant(float[,] m) - { - float fCofactor00 = m[1,1] * m[2,2] - m[1,2] * m[2,1]; - float fCofactor10 = m[1,2] * m[2,0] - m[1,0] * m[2,2]; - float fCofactor20 = m[1,0] * m[2,1] - m[1,1] * m[2,0]; - - float fDet = m[0,0] * fCofactor00 + m[0,1] * fCofactor10 + m[0,2] * fCofactor20; - - return fDet; - } - - float2 GetCircumcenter () - { - // From MathWorld: http://mathworld.wolfram.com/Circumcircle.html - - var points = Vertices; - - float[,] m = new float[3, 3]; - - // x, y, 1 - for (int i = 0; i < 3; i++) { - m[i, 0] = points[i].x; - m[i, 1] = points[i].y; - m[i, 2] = 1; - } - var a = Determinant(m); - - // size, y, 1 - for (int i = 0; i < 3; i++) { - m[i, 0] = lengthsq(points[i].StoredPosition); - } - var dx = -Determinant(m); - - // size, x, 1 - for (int i = 0; i < 3; i++) { - m[i, 1] = points[i].x; - } - var dy = Determinant(m); - - // size, x, y - //for (int i = 0; i < 3; i++) { - // m[i, 2] = points[i].y; - //} - //var c = -Det(m); - - var s = -1.0f / (2.0f * a); - //var r = System.Math.Abs(s) * System.Math.Sqrt(dx * dx + dy * dy - 4 * a * c); - - return new float2(s * dx, s * dy); - } - - float2 GetCentroid () - { - return new float2(Vertices.Select(v => v.Position[0]).Average(), Vertices.Select(v => v.Position[1]).Average()); - } - -} - - - - - - - - - - - - - - - diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2.cs.meta deleted file mode 100644 index 52993549b..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: adf902e96e0c51049b65bc002d6ef4ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2Object.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2Object.cs deleted file mode 100644 index d23fbac51..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2Object.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Collections; -using System.Linq; -using MIConvexHull; -using CultMath; -using static CultMath.math; - -/// -/// A vertex is a simple class that stores the postion of a point, node or vertex. -/// -public class Cell2 : TriangulationCell, Cell2> -{ - float2? circumCenter, centroid; - - public float2 Circumcenter { - get { - circumCenter = circumCenter ?? GetCircumcenter(); - return circumCenter.Value; - } - } - - public float2 Centroid { - get { - centroid = centroid ?? GetCentroid(); - return centroid.Value; - } - } - - public Cell2 () - { - - } - - double LengthSquared (float[] v) - { - float norm = 0; - for (int i = 0; i < v.Length; i++) { - var t = v [i]; - norm += t * t; - } - return norm; - } - - float Determinant(float[,] m) - { - float fCofactor00 = m[1,1] * m[2,2] - m[1,2] * m[2,1]; - float fCofactor10 = m[1,2] * m[2,0] - m[1,0] * m[2,2]; - float fCofactor20 = m[1,0] * m[2,1] - m[1,1] * m[2,0]; - - float fDet = m[0,0] * fCofactor00 + m[0,1] * fCofactor10 + m[0,2] * fCofactor20; - - return fDet; - } - - float2 GetCircumcenter () - { - // From MathWorld: http://mathworld.wolfram.com/Circumcircle.html - - var points = Vertices; - - float[,] m = new float[3, 3]; - - // x, y, 1 - for (int i = 0; i < 3; i++) { - m[i, 0] = points[i].x; - m[i, 1] = points[i].y; - m[i, 2] = 1; - } - var a = Determinant(m); - - // size, y, 1 - for (int i = 0; i < 3; i++) { - m[i, 0] = lengthsq(points[i].StoredPosition); - } - var dx = -Determinant(m); - - // size, x, 1 - for (int i = 0; i < 3; i++) { - m[i, 1] = points[i].x; - } - var dy = Determinant(m); - - // size, x, y - //for (int i = 0; i < 3; i++) { - // m[i, 2] = points[i].y; - //} - //var c = -Det(m); - - var s = -1.0f / (2.0f * a); - //var r = System.Math.Abs(s) * System.Math.Sqrt(dx * dx + dy * dy - 4 * a * c); - - return new float2(s * dx, s * dy); - } - - float2 GetCentroid () - { - return new float2(Vertices.Select(v => v.Position[0]).Average(), Vertices.Select(v => v.Position[1]).Average()); - } - -} - - - - - - - - - - - - - - - diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2Object.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2Object.cs.meta deleted file mode 100644 index d47180ee1..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Cell2Object.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ea854ab9e5204f92828e92ffb1244964 -timeCreated: 1615420193 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Constants.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Constants.cs deleted file mode 100644 index 20948bc1a..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Constants.cs +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; - -namespace MIConvexHull -{ - internal static class Constants - { - /// - /// The default plane distance tolerance - /// - internal const float DefaultPlaneDistanceTolerance = 1e-10f; - /// - /// The starting delta dot product in simplex - /// - internal const float StartingDeltaDotProductInSimplex = 0.5f; - /// - /// The connector table size - /// - internal const int ConnectorTableSize = 2017; - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Constants.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Constants.cs.meta deleted file mode 100644 index 3c5287e11..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Constants.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ee065f025d2f5374db2ceaa973b822d4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.cs deleted file mode 100644 index 1ef83b8a9..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.cs +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MIConvexHull -{ - /// - /// Factory class for computing convex hulls. - /// - public static class ConvexHull - { - /// - /// Creates a convex hull of the input data. - /// - /// The type of the t vertex. - /// The type of the t face. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// - /// ConvexHull<TVertex, TFace>. - /// - public static ConvexHull Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - where TFace : ConvexFace, new() - { - return ConvexHull.Create(data, PlaneDistanceTolerance); - } - - /// - /// Creates a convex hull of the input data. - /// - /// The type of the t vertex. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// - /// ConvexHull<TVertex, DefaultConvexFace<TVertex>>. - /// - public static ConvexHull> Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - { - return ConvexHull>.Create(data, PlaneDistanceTolerance); - } - - /// - /// Creates a convex hull of the input data. - /// - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// - /// ConvexHull<DefaultVertex, DefaultConvexFace<DefaultVertex>>. - /// - public static ConvexHull> Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - { - var points = data.Select(p => new DefaultVertex { Position = p }).ToList(); - return ConvexHull>.Create(points, PlaneDistanceTolerance); - } - } - - /// - /// Representation of a convex hull. - /// - /// The type of the t vertex. - /// The type of the t face. - public class ConvexHull - where TVertex : IVertex - where TFace : ConvexFace, new() - { - /// - /// Can only be created using a factory method. - /// - internal ConvexHull() - { - } - - /// - /// Points of the convex hull. - /// - /// The points. - public IEnumerable Points { get; internal set; } - - /// - /// Faces of the convex hull. - /// - /// The faces. - public IEnumerable Faces { get; internal set; } - - /// - /// Creates the convex hull. - /// - /// The data. - /// The plane distance tolerance. - /// - /// ConvexHull<TVertex, TFace>. - /// - /// The supplied data is null. - /// data - public static ConvexHull Create(IList data, float PlaneDistanceTolerance) - { - if (data == null) throw new ArgumentNullException("The supplied data is null."); - return ConvexHullAlgorithm.GetConvexHull(data, PlaneDistanceTolerance); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.cs.meta deleted file mode 100644 index 0be10d4af..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 447289e858e19c14abbe91dfbd0e3089 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.meta deleted file mode 100644 index 6a291ff20..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a6e88469e3b81a541a0bc8a66e60d0c7 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/Collections.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/Collections.cs deleted file mode 100644 index ace305648..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/Collections.cs +++ /dev/null @@ -1,304 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; - -namespace MIConvexHull -{ - /// - /// A more lightweight alternative to List of T. - /// On clear, only resets the count and does not clear the references - /// => this works because of the ObjectManager. - /// Includes a stack functionality. - /// - /// - internal class SimpleList - { - /// - /// The capacity - /// - private int capacity; - - /// - /// The count - /// - public int Count; - /// - /// The items - /// - private T[] items; - - /// - /// Get the i-th element. - /// - /// The i. - /// T. - public T this[int i] - { - get { return items[i]; } - set { items[i] = value; } - } - - /// - /// Size matters. - /// - private void EnsureCapacity() - { - if (capacity == 0) - { - capacity = 32; - items = new T[32]; - } - else - { - var newItems = new T[capacity*2]; - Array.Copy(items, newItems, capacity); - capacity = 2*capacity; - items = newItems; - } - } - - /// - /// Adds a vertex to the buffer. - /// - /// The item. - public void Add(T item) - { - if (Count + 1 > capacity) EnsureCapacity(); - items[Count++] = item; - } - - /// - /// Pushes the value to the back of the list. - /// - /// The item. - public void Push(T item) - { - if (Count + 1 > capacity) EnsureCapacity(); - items[Count++] = item; - } - - /// - /// Pops the last value from the list. - /// - /// T. - public T Pop() - { - return items[--Count]; - } - - /// - /// Sets the Count to 0, otherwise does nothing. - /// - public void Clear() - { - Count = 0; - } - } - - - /// - /// Class IndexBuffer. - /// A fancy name for a list of integers. - /// - internal class IndexBuffer : SimpleList - { - } - - /// - /// A priority based linked list. - /// - internal sealed class FaceList - { - /// - /// The last - /// - private ConvexFaceInternal last; - - /// - /// Get the first element. - /// - /// The first. - public ConvexFaceInternal First { get; private set; } - - /// - /// Adds the element to the beginning. - /// - /// The face. - private void AddFirst(ConvexFaceInternal face) - { - face.InList = true; - First.Previous = face; - face.Next = First; - First = face; - } - - /// - /// Adds a face to the list. - /// - /// The face. - public void Add(ConvexFaceInternal face) - { - if (face.InList) - { - if (First.VerticesBeyond.Count < face.VerticesBeyond.Count) - { - Remove(face); - AddFirst(face); - } - return; - } - - face.InList = true; - - if (First != null && First.VerticesBeyond.Count < face.VerticesBeyond.Count) - { - First.Previous = face; - face.Next = First; - First = face; - } - else - { - if (last != null) - { - last.Next = face; - } - face.Previous = last; - last = face; - if (First == null) - { - First = face; - } - } - } - - /// - /// Removes the element from the list. - /// - /// The face. - public void Remove(ConvexFaceInternal face) - { - if (!face.InList) return; - - face.InList = false; - - if (face.Previous != null) - { - face.Previous.Next = face.Next; - } - else if ( /*first == face*/ face.Previous == null) - { - First = face.Next; - } - - if (face.Next != null) - { - face.Next.Previous = face.Previous; - } - else if ( /*last == face*/ face.Next == null) - { - last = face.Previous; - } - - face.Next = null; - face.Previous = null; - } - } - - /// - /// Connector list. - /// - internal sealed class ConnectorList - { - /// - /// The last - /// - private FaceConnector last; - - /// - /// Get the first element. - /// - /// The first. - public FaceConnector First { get; private set; } - - /// - /// Adds the element to the beginning. - /// - /// The connector. - private void AddFirst(FaceConnector connector) - { - First.Previous = connector; - connector.Next = First; - First = connector; - } - - /// - /// Adds a face to the list. - /// - /// The element. - public void Add(FaceConnector element) - { - if (last != null) - { - last.Next = element; - } - element.Previous = last; - last = element; - if (First == null) - { - First = element; - } - } - - /// - /// Removes the element from the list. - /// - /// The connector. - public void Remove(FaceConnector connector) - { - if (connector.Previous != null) - { - connector.Previous.Next = connector.Next; - } - else if ( /*first == face*/ connector.Previous == null) - { - First = connector.Next; - } - - if (connector.Next != null) - { - connector.Next.Previous = connector.Previous; - } - else if ( /*last == face*/ connector.Next == null) - { - last = connector.Previous; - } - - connector.Next = null; - connector.Previous = null; - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/Collections.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/Collections.cs.meta deleted file mode 100644 index 323e260ef..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/Collections.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3969283304824fe4a8eca1eb522fd3a7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexFace.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexFace.cs deleted file mode 100644 index 34fab61b2..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexFace.cs +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -namespace MIConvexHull -{ - /// - /// A convex face representation containing adjacency information. - /// - /// The type of the t vertex. - /// The type of the t face. - public abstract class ConvexFace - where TVertex : IVertex - where TFace : ConvexFace - { - /// - /// Adjacency. Array of length "dimension". - /// If F = Adjacency[i] then the vertices shared with F are Vertices[j] where j != i. - /// In the context of triangulation, can be null (indicates the cell is at boundary). - /// - /// The adjacency. - public TFace[] Adjacency { get; set; } - - /// - /// The vertices stored in clockwise order for dimensions 2 - 4, in higher dimensions the order is arbitrary. - /// Unless I accidentally switch some index somewhere in which case the order is CCW. Either way, it is consistent. - /// 3D Normal = (V[1] - V[0]) x (V[2] - V[1]). - /// - /// The vertices. - public TVertex[] Vertices { get; set; } - - /// - /// The normal vector of the face. Null if used in triangulation. - /// - /// The normal. - public float[] Normal { get; set; } - } - - /// - /// A default convex face representation. - /// - /// The type of the t vertex. - public class DefaultConvexFace : ConvexFace> - where TVertex : IVertex - { - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexFace.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexFace.cs.meta deleted file mode 100644 index 40c26cd01..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexFace.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5db1a96860ec6d949930695ae9bedcc0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.Initialize.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.Initialize.cs deleted file mode 100644 index e4b8477ae..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.Initialize.cs +++ /dev/null @@ -1,721 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MIConvexHull -{ - /* - * This part of the implementation handles initialization of the convex hull algorithm: - * - Constructor & Process initiation - * - Determine the dimension by looking at length of Position vector of 10 random data points from the input. - * - Identify bounding box points in each direction. - * - Pick (Dimension + 1) points from the extremes and construct the initial simplex. - */ - - /// - /// Class ConvexHullAlgorithm. - /// - internal partial class ConvexHullAlgorithm - { - #region Starting functions and constructor - /// - /// The main function for the Convex Hull algorithm. It is static, but it creates - /// an instantiation of this class in order to allow for parallel execution. - /// Following this simple function, the constructor and the main function "FindConvexHull" is listed. - /// - /// The type of the vertices in the data. - /// The desired type of the faces. - /// The data is the vertices as a collection of IVertices. - /// The plane distance tolerance. - /// - /// MIConvexHull.ConvexHull<TVertex, TFace>. - /// - internal static ConvexHull GetConvexHull(IList data, - float PlaneDistanceTolerance) - where TFace : ConvexFace, new() - where TVertex : IVertex - { - var ch = new ConvexHullAlgorithm(data.Cast().ToArray(), false, PlaneDistanceTolerance); - ch.GetConvexHull(); - - if (ch.NumOfDimensions == 2) return ch.Return2DResultInOrder(data); - return new ConvexHull - { - Points = ch.GetHullVertices(data), - Faces = ch.GetConvexFaces() - }; - } - - /// - /// Initializes a new instance of the class. - /// - /// The vertices. - /// if set to true [lift]. - /// The plane distance tolerance. - /// Dimension of the input must be 2 or greater. - /// There are too few vertices (m) for the n-dimensional space. (m must be greater + - /// than the n, but m is + NumberOfVertices + and n is + NumOfDimensions - /// PointTranslationGenerator cannot be null if PointTranslationType is enabled. - /// or - /// Dimension of the input must be 2 or greater. - /// There are too few vertices (m) for the n-dimensional space. (m must be greater " + - /// "than the n, but m is " + NumberOfVertices + " and n is " + Dimension - private ConvexHullAlgorithm(IVertex[] vertices, bool lift, float PlaneDistanceTolerance) - { - IsLifted = lift; - Vertices = vertices; - NumberOfVertices = vertices.Length; - - NumOfDimensions = DetermineDimension(); - if (IsLifted) NumOfDimensions++; - if (NumOfDimensions < 2) throw new InvalidOperationException("Dimension of the input must be 2 or greater."); - if (NumberOfVertices <= NumOfDimensions) - throw new ArgumentException( - "There are too few vertices (m) for the n-dimensional space. (m must be greater " + - "than the n, but m is " + NumberOfVertices + " and n is " + NumOfDimensions); - this.PlaneDistanceTolerance = PlaneDistanceTolerance; - UnprocessedFaces = new FaceList(); - ConvexFaces = new IndexBuffer(); - - FacePool = new ConvexFaceInternal[(NumOfDimensions + 1) * 10]; // must be initialized before object manager - AffectedFaceFlags = new bool[(NumOfDimensions + 1) * 10]; - ObjectManager = new ObjectManager(this); - - Center = new float[NumOfDimensions]; - TraverseStack = new IndexBuffer(); - UpdateBuffer = new int[NumOfDimensions]; - UpdateIndices = new int[NumOfDimensions]; - EmptyBuffer = new IndexBuffer(); - AffectedFaceBuffer = new IndexBuffer(); - ConeFaceBuffer = new SimpleList(); - SingularVertices = new HashSet(); - BeyondBuffer = new IndexBuffer(); - - ConnectorTable = new ConnectorList[Constants.ConnectorTableSize]; - for (var i = 0; i < Constants.ConnectorTableSize; i++) ConnectorTable[i] = new ConnectorList(); - - VertexVisited = new bool[NumberOfVertices]; - Positions = new float[NumberOfVertices * NumOfDimensions]; - boundingBoxPoints = new List[NumOfDimensions]; - minima = new float[NumOfDimensions]; - maxima = new float[NumOfDimensions]; - mathHelper = new MathHelper(NumOfDimensions, Positions); - } - /// - /// Check the dimensionality of the input data. - /// - /// System.Int32. - /// Invalid input data (non-uniform dimension). - private int DetermineDimension() - { - var r = new Random(); - var dimensions = new List(); - for (var i = 0; i < 10; i++) - dimensions.Add(Vertices[r.Next(NumberOfVertices)].Position.Length); - var dimension = dimensions.Min(); - if (dimension != dimensions.Max()) - throw new ArgumentException("Invalid input data (non-uniform dimension)."); - return dimension; - } - - - /// - /// Gets/calculates the convex hull. This is - /// - private void GetConvexHull() - { - // accessing a 1D array is quicker than a jagged array, so the first step is to make this array - SerializeVerticesToPositions(); - // next the bounding box extremes are found. This is used to shift, scale and find the starting simplex. - FindBoundingBoxPoints(); - // the positions are shifted to avoid divide by zero problems - // and if Delaunay or Voronoi, then the parabola terms are scaled back to match the size of the other coords - ShiftAndScalePositions(); - // Find the (dimension+1) initial points and create the simplexes. - CreateInitialSimplex(); - - // Now, the main loop. These initial faces of a simplex are replaced and expanded - // outwards to make the convex hull and faces. - while (UnprocessedFaces.First != null) - { - var currentFace = UnprocessedFaces.First; - CurrentVertex = currentFace.FurthestVertex; - - UpdateCenter(); - - // The affected faces get tagged - TagAffectedFaces(currentFace); - - // Create the cone from the currentVertex and the affected faces horizon. - if (!SingularVertices.Contains(CurrentVertex) && CreateCone()) CommitCone(); - else HandleSingular(); - - // Need to reset the tags - var count = AffectedFaceBuffer.Count; - for (var i = 0; i < count; i++) AffectedFaceFlags[AffectedFaceBuffer[i]] = false; - } - } - - #endregion - - /// - /// Serializes the vertices into the 1D array, Positions. The 1D array has much quicker access in C#. - /// - private void SerializeVerticesToPositions() - { - var index = 0; - if (IsLifted) // "Lifted" means that the last dimension is the sum of the squares of the others. - { - foreach (var v in Vertices) - { - var parabolaTerm = 0.0f; // the lifted term is a sum of squares. - var origNumDim = NumOfDimensions - 1; - for (var i = 0; i < origNumDim; i++) - { - var coordinate = v.Position[i]; - Positions[index++] = coordinate; - parabolaTerm += coordinate * coordinate; - } - Positions[index++] = parabolaTerm; - } - } - else - foreach (var v in Vertices) - { - for (var i = 0; i < NumOfDimensions; i++) - Positions[index++] = v.Position[i]; - } - } - - - - /// - /// Finds the bounding box points. - /// - private void FindBoundingBoxPoints() - { - indexOfDimensionWithLeastExtremes = -1; - var minNumExtremes = int.MaxValue; - for (var i = 0; i < NumOfDimensions; i++) - { - var minIndices = new List(); - var maxIndices = new List(); - float min = float.PositiveInfinity, max = float.NegativeInfinity; - for (var j = 0; j < NumberOfVertices; j++) - { - var v = GetCoordinate(j, i); - var difference = min - v; - if (difference >= PlaneDistanceTolerance) - { - // you found a better solution than before, clear out the list and store new value - min = v; - minIndices.Clear(); - minIndices.Add(j); - } - else if (difference > 0) - { - // you found a solution slightly better than before, clear out those that are no longer on the list and store new value - min = v; - minIndices.RemoveAll(index => min - GetCoordinate(index, i) > PlaneDistanceTolerance); - minIndices.Add(j); - } - else if (difference > -PlaneDistanceTolerance) - { - //same or almost as good as current limit, so store it - minIndices.Add(j); - } - difference = v - max; - if (difference >= PlaneDistanceTolerance) - { - // you found a better solution than before, clear out the list and store new value - max = v; - maxIndices.Clear(); - maxIndices.Add(j); - } - else if (difference > 0) - { - // you found a solution slightly better than before, clear out those that are no longer on the list and store new value - max = v; - maxIndices.RemoveAll(index => min - GetCoordinate(index, i) > PlaneDistanceTolerance); - maxIndices.Add(j); - } - else if (difference > -PlaneDistanceTolerance) - { - //same or almost as good as current limit, so store it - maxIndices.Add(j); - } - } - minima[i] = min; - maxima[i] = max; - minIndices.AddRange(maxIndices); - if (minIndices.Count < minNumExtremes) - { - minNumExtremes = minIndices.Count; - indexOfDimensionWithLeastExtremes = i; - } - boundingBoxPoints[i] = minIndices; - } - } - - /// - /// Shifts and scales the Positions to avoid future errors. This does not alter the original data. - /// - private void ShiftAndScalePositions() - { - var positionsLength = Positions.Length; - if (IsLifted) - { - var origNumDim = NumOfDimensions - 1; - var parabolaScale = 2 / (minima.Sum(x => Math.Abs(x)) + maxima.Sum(x => Math.Abs(x)) - - Math.Abs(maxima[origNumDim]) - Math.Abs(minima[origNumDim])); - // the parabola scale is 1 / average of the sum of the other dimensions. - // multiplying this by the parabola will scale it back to be on near similar size to the - // other dimensions. Without this, the term is much larger than the others, which causes - // problems for roundoff error and finding the normal of faces. - minima[origNumDim] *= parabolaScale; // change the extreme values as well - maxima[origNumDim] *= parabolaScale; - // it is done here because - for (int i = origNumDim; i < positionsLength; i += NumOfDimensions) - Positions[i] *= parabolaScale; - } - var shiftAmount = new float[NumOfDimensions]; - for (int i = 0; i < NumOfDimensions; i++) - // now the entire model is shifted to all positive numbers...plus some more. - // why? - // 1) to avoid dealing with a point at the origin {0,0,...,0} which causes problems - // for future normal finding - // 2) note that weird shift that is used (max - min - min). This is to avoid scaling - // issues. this shift means that the minima in a dimension will always be a positive - // number (no points at zero), and the minima [in a given dimension] will always be - // half of the maxima. 'Half' is much preferred to 'thousands of times' - // Think of the first term as the range (max - min), then the second term avoids cases - // where there are both positive and negative numbers. - if (maxima[i] == minima[i]) shiftAmount[i] = 0.0f; - else shiftAmount[i] = (maxima[i] - minima[i]) - minima[i]; - for (int i = 0; i < positionsLength; i++) - Positions[i] += shiftAmount[i % NumOfDimensions]; - } - - /// - /// Find the (dimension+1) initial points and create the simplexes. - /// Creates the initial simplex of n+1 vertices by using points from the bounding box. - /// Special care is taken to ensure that the vertices chosen do not result in a degenerate shape - /// where vertices are collinear (co-planar, etc). This would technically be resolved when additional - /// vertices are checked in the main loop, but: 1) a degenerate simplex would not eliminate any other - /// vertices (thus no savings there), 2) the creation of the face normal is prone to error. - /// - private void CreateInitialSimplex() - { - var initialPoints = FindInitialPoints(); - #region Create the first faces from (dimension + 1) vertices. - - var faces = new int[NumOfDimensions + 1]; - - for (var i = 0; i < NumOfDimensions + 1; i++) - { - var vertices = new int[NumOfDimensions]; - for (int j = 0, k = 0; j <= NumOfDimensions; j++) - { - if (i != j) vertices[k++] = initialPoints[j]; - } - var newFace = FacePool[ObjectManager.GetFace()]; - newFace.Vertices = vertices; - Array.Sort(vertices); - mathHelper.CalculateFacePlane(newFace, Center); - faces[i] = newFace.Index; - } - // update the adjacency (check all pairs of faces) - for (var i = 0; i < NumOfDimensions; i++) - for (var j = i + 1; j < NumOfDimensions + 1; j++) UpdateAdjacency(FacePool[faces[i]], FacePool[faces[j]]); - - #endregion - - #region Init the vertex beyond buffers. - - foreach (var faceIndex in faces) - { - var face = FacePool[faceIndex]; - FindBeyondVertices(face); - if (face.VerticesBeyond.Count == 0) ConvexFaces.Add(face.Index); // The face is on the hull - else UnprocessedFaces.Add(face); - } - - #endregion - - // Set all vertices to false (unvisited). - foreach (var vertex in initialPoints) VertexVisited[vertex] = false; - } - - /// - /// Finds (dimension + 1) initial points. - /// - /// List<System.Int32>. - /// The input data is degenerate. It appears to exist in " + NumOfDimensions + - /// " dimensions, but it is a " + (NumOfDimensions - 1) + " dimensional set (i.e. the point of collinear," - /// + " coplanar, or co-hyperplanar.) - private List FindInitialPoints() - { - var bigNumber = maxima.Sum() * NumOfDimensions * NumberOfVertices; - // the first two points are taken from the dimension that had the fewest extremes - // well, in most cases there will only be 2 in all dimensions: one min and one max - // but a lot of engineering part shapes are nice and square and can have hundreds of - // parallel vertices at the extremes - var vertex1 = boundingBoxPoints[indexOfDimensionWithLeastExtremes].First(); // these are min and max vertices along - var vertex2 = boundingBoxPoints[indexOfDimensionWithLeastExtremes].Last(); // the dimension that had the fewest points - boundingBoxPoints[indexOfDimensionWithLeastExtremes].RemoveAt(0); - boundingBoxPoints[indexOfDimensionWithLeastExtremes].RemoveAt(boundingBoxPoints[indexOfDimensionWithLeastExtremes].Count - 1); - var initialPoints = new List { vertex1, vertex2 }; - VertexVisited[vertex1] = VertexVisited[vertex2] = true; - CurrentVertex = vertex1; UpdateCenter(); - CurrentVertex = vertex2; UpdateCenter(); - var edgeVectors = new float[NumOfDimensions][]; - edgeVectors[0] = mathHelper.VectorBetweenVertices(vertex2, vertex1); - // now the remaining vertices are just combined in one big list - var extremes = boundingBoxPoints.SelectMany(x => x).ToList(); - // otherwise find the remaining points by maximizing the initial simplex volume - var index = 1; - while (index < NumOfDimensions && extremes.Any()) - { - var bestVertex = -1; - var bestEdgeVector = new float[] { }; - var maxVolume = Constants.DefaultPlaneDistanceTolerance; - for (var i = extremes.Count - 1; i >= 0; i--) - { - // count backwards in order to remove potential duplicates - var vIndex = extremes[i]; - if (initialPoints.Contains(vIndex)) extremes.RemoveAt(i); - else - { - edgeVectors[index] = mathHelper.VectorBetweenVertices(vIndex, vertex1); - var volume = mathHelper.GetSimplexVolume(edgeVectors, index, bigNumber); - if (maxVolume < volume) - { - maxVolume = volume; - bestVertex = vIndex; - bestEdgeVector = edgeVectors[index]; - } - } - } - extremes.Remove(bestVertex); - if (bestVertex == -1) break; - initialPoints.Add(bestVertex); - edgeVectors[index++] = bestEdgeVector; - CurrentVertex = bestVertex; UpdateCenter(); - } - // hmm, there are not enough points on the bounding box to make a simplex. It is rare but entirely possibly. - // As an extreme, the bounding box can be made in n dimensions from only 2 unique points. When we can't find - // enough unique points, we start again with ALL the vertices. The following is a near replica of the code - // above, but instead of extremes, we consider "allVertices". - if (initialPoints.Count <= NumOfDimensions && !IsLifted) - { - var allVertices = Enumerable.Range(0, NumberOfVertices).ToList(); - while (index < NumOfDimensions && allVertices.Any()) - { - var bestVertex = -1; - var bestEdgeVector = new float[] { }; - var maxVolume = 0.0; - for (var i = allVertices.Count - 1; i >= 0; i--) - { - // count backwards in order to remove potential duplicates - var vIndex = allVertices[i]; - if (initialPoints.Contains(vIndex)) allVertices.RemoveAt(i); - else - { - edgeVectors[index] = mathHelper.VectorBetweenVertices(vIndex, vertex1); - var volume = mathHelper.GetSimplexVolume(edgeVectors, index, bigNumber); - if (maxVolume < volume) - { - maxVolume = volume; - bestVertex = vIndex; - bestEdgeVector = edgeVectors[index]; - } - } - } - allVertices.Remove(bestVertex); - if (bestVertex == -1) break; - initialPoints.Add(bestVertex); - edgeVectors[index++] = bestEdgeVector; - CurrentVertex = bestVertex; UpdateCenter(); - } - } - if (initialPoints.Count <= NumOfDimensions && IsLifted) - { - var allVertices = Enumerable.Range(0, NumberOfVertices).ToList(); - while (index < NumOfDimensions && allVertices.Any()) - { - var bestVertex = -1; - var bestEdgeVector = new float[] { }; - var maxVolume = 0.0; - for (var i = allVertices.Count - 1; i >= 0; i--) - { - // count backwards in order to remove potential duplicates - var vIndex = allVertices[i]; - if (initialPoints.Contains(vIndex)) allVertices.RemoveAt(i); - else - { - mathHelper.RandomOffsetToLift(vIndex, maxima.Last()-minima.Last()); - edgeVectors[index] = mathHelper.VectorBetweenVertices(vIndex, vertex1); - var volume = mathHelper.GetSimplexVolume(edgeVectors, index, bigNumber); - if (maxVolume < volume) - { - maxVolume = volume; - bestVertex = vIndex; - bestEdgeVector = edgeVectors[index]; - } - } - } - allVertices.Remove(bestVertex); - if (bestVertex == -1) break; - initialPoints.Add(bestVertex); - edgeVectors[index++] = bestEdgeVector; - CurrentVertex = bestVertex; UpdateCenter(); - } - } - if (initialPoints.Count <= NumOfDimensions && IsLifted) - throw new ArgumentException("The input data is degenerate. It appears to exist in " + NumOfDimensions + - " dimensions, but it is a " + (NumOfDimensions - 1) + " dimensional set (i.e. the point of collinear," - + " coplanar, or co-hyperplanar.)"); - return initialPoints; - } - - /// - /// Check if 2 faces are adjacent and if so, update their AdjacentFaces array. - /// - /// The l. - /// The r. - private void UpdateAdjacency(ConvexFaceInternal l, ConvexFaceInternal r) - { - var lv = l.Vertices; - var rv = r.Vertices; - int i; - - // reset marks on the 1st face - for (i = 0; i < lv.Length; i++) VertexVisited[lv[i]] = false; - - // mark all vertices on the 2nd face - for (i = 0; i < rv.Length; i++) VertexVisited[rv[i]] = true; - - // find the 1st false index - for (i = 0; i < lv.Length; i++) if (!VertexVisited[lv[i]]) break; - - // no vertex was marked - if (i == NumOfDimensions) return; - - // check if only 1 vertex wasn't marked - for (var j = i + 1; j < lv.Length; j++) if (!VertexVisited[lv[j]]) return; - - // if we are here, the two faces share an edge - l.AdjacentFaces[i] = r.Index; - - // update the adj. face on the other face - find the vertex that remains marked - for (i = 0; i < lv.Length; i++) VertexVisited[lv[i]] = false; - for (i = 0; i < rv.Length; i++) - { - if (VertexVisited[rv[i]]) break; - } - r.AdjacentFaces[i] = l.Index; - } - - /// - /// Used in the "initialization" code. - /// - /// The face. - private void FindBeyondVertices(ConvexFaceInternal face) - { - var beyondVertices = face.VerticesBeyond; - MaxDistance = float.NegativeInfinity; - FurthestVertex = 0; - for (var i = 0; i < NumberOfVertices; i++) - { - if (VertexVisited[i]) continue; - IsBeyond(face, beyondVertices, i); - } - - face.FurthestVertex = FurthestVertex; - } - #region Fields - - /// - /// Corresponds to the dimension of the data. - /// When the "lifted" hull is computed, Dimension is automatically incremented by one. - /// - internal readonly int NumOfDimensions; - - /// - /// Are we on a paraboloid? - /// - private readonly bool IsLifted; - - /// - /// Explained in ConvexHullComputationConfig. - /// - private readonly float PlaneDistanceTolerance; - - /* - * Representation of the input vertices. - * - * - In the algorithm, a vertex is represented by its index in the Vertices array. - * This makes the algorithm a lot faster (up to 30%) than using object reference everywhere. - * - Positions are stored as a single array of values. Coordinates for vertex with index i - * are stored at indices - /// The vertices - /// - private readonly IVertex[] Vertices; - /// - /// The positions - /// - private float[] Positions; - /// - /// The vertex marks - /// - private readonly bool[] VertexVisited; - - private readonly int NumberOfVertices; - - /* - * The triangulation faces are represented in a single pool for objects that are being reused. - * This allows for represent the faces as integers and significantly speeds up many computations. - * - AffectedFaceFlags are used to mark affected faces/ - */ - /// - /// The face pool - /// - internal ConvexFaceInternal[] FacePool; - /// - /// The affected face flags - /// - internal bool[] AffectedFaceFlags; - - /// - /// Used to track the size of the current hull in the Update/RollbackCenter functions. - /// - private int ConvexHullSize; - - /// - /// A list of faces that that are not a part of the final convex hull and still need to be processed. - /// - private readonly FaceList UnprocessedFaces; - - /// - /// A list of faces that form the convex hull. - /// - private readonly IndexBuffer ConvexFaces; - - /// - /// The vertex that is currently being processed. - /// - private int CurrentVertex; - - /// - /// A helper variable to determine the furthest vertex for a particular convex face. - /// - private double MaxDistance; - - /// - /// A helper variable to help determine the index of the vertex that is furthest from the face that is currently being - /// processed. - /// - private int FurthestVertex; - - /// - /// The centroid of the currently computed hull. - /// - private readonly float[] Center; - - /* - * Helper arrays to store faces for adjacency update. - * This is just to prevent unnecessary allocations. - */ - /// - /// The update buffer - /// - private readonly int[] UpdateBuffer; - /// - /// The update indices - /// - private readonly int[] UpdateIndices; - - /// - /// Used to determine which faces need to be updated at each step of the algorithm. - /// - private readonly IndexBuffer TraverseStack; - - /// - /// Used for VerticesBeyond for faces that are on the convex hull. - /// - private readonly IndexBuffer EmptyBuffer; - - /// - /// Used to determine which vertices are "above" (or "beyond") a face - /// - private IndexBuffer BeyondBuffer; - - /// - /// Stores faces that are visible from the current vertex. - /// - private readonly IndexBuffer AffectedFaceBuffer; - - /// - /// Stores faces that form a "cone" created by adding new vertex. - /// - private readonly SimpleList ConeFaceBuffer; - - /// - /// Stores a list of "singular" (or "generate", "planar", etc.) vertices that cannot be part of the hull. - /// - private readonly HashSet SingularVertices; - - /// - /// The connector table helps to determine the adjacency of convex faces. - /// Hashing is used instead of pairwise comparison. This significantly speeds up the computations, - /// especially for higher dimensions. - /// - private readonly ConnectorList[] ConnectorTable; - - /// - /// Manages the memory allocations and storage of unused objects. - /// Saves the garbage collector a lot of work. - /// - private readonly ObjectManager ObjectManager; - - /// - /// Helper class for handling math related stuff. - /// - private readonly MathHelper mathHelper; - private readonly List[] boundingBoxPoints; - private int indexOfDimensionWithLeastExtremes; - private readonly float[] minima; - private readonly float[] maxima; - #endregion - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.Initialize.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.Initialize.cs.meta deleted file mode 100644 index 35319f3c2..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.Initialize.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 48bd00cb6ec8d244f90e1c1608f39074 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.MainLoop.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.MainLoop.cs deleted file mode 100644 index 058b82640..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.MainLoop.cs +++ /dev/null @@ -1,635 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System.Collections.Generic; - -namespace MIConvexHull -{ - /* - * Main part of the algorithm - * Basic idea: - * - Create the initial hull (done in Initialize.cs) - * - * For each face there are "vertices beyond" which are "visible" from it. - * If there are no such vertices, the face is on the hull. - * - * - While there is at least one face with at least one "vertex beyond": - * * Pick the furthest beyond vertex - * * For this vertex: - * > find all faces that are visible from it (TagAffectedFaces) - * > remove them and replace them with a "cone" created by the vertex and the boundary - * of the affected faces, and for each new face, compute "beyond vertices" - * (CreateCone + CommitCone) - * - * + Implement it in way that is fast, but hard to understand and maintain. - */ - - /// - /// Class ConvexHullAlgorithm. - /// - internal partial class ConvexHullAlgorithm - { - /// - /// Tags all faces seen from the current vertex with 1. - /// - /// The current face. - private void TagAffectedFaces(ConvexFaceInternal currentFace) - { - AffectedFaceBuffer.Clear(); - AffectedFaceBuffer.Add(currentFace.Index); - TraverseAffectedFaces(currentFace.Index); - } - - /// - /// Recursively traverse all the relevant faces. - /// - /// The current face. - private void TraverseAffectedFaces(int currentFace) - { - TraverseStack.Clear(); - TraverseStack.Push(currentFace); - AffectedFaceFlags[currentFace] = true; - - while (TraverseStack.Count > 0) - { - var top = FacePool[TraverseStack.Pop()]; - for (var i = 0; i < NumOfDimensions; i++) - { - var adjFace = top.AdjacentFaces[i]; - - if (!AffectedFaceFlags[adjFace] && - mathHelper.GetVertexDistance(CurrentVertex, FacePool[adjFace]) >= PlaneDistanceTolerance) - { - AffectedFaceBuffer.Add(adjFace); - AffectedFaceFlags[adjFace] = true; - TraverseStack.Push(adjFace); - } - } - } - } - - /// - /// Creates a new deferred face. - /// - /// The face. - /// Index of the face. - /// The pivot. - /// Index of the pivot. - /// The old face. - /// DeferredFace. - private DeferredFace MakeDeferredFace(ConvexFaceInternal face, int faceIndex, ConvexFaceInternal pivot, - int pivotIndex, ConvexFaceInternal oldFace) - { - var ret = ObjectManager.GetDeferredFace(); - - ret.Face = face; - ret.FaceIndex = faceIndex; - ret.Pivot = pivot; - ret.PivotIndex = pivotIndex; - ret.OldFace = oldFace; - - return ret; - } - - /// - /// Connect faces using a connector. - /// - /// The connector. - private void ConnectFace(FaceConnector connector) - { - var index = connector.HashCode % Constants.ConnectorTableSize; - var list = ConnectorTable[index]; - - for (var current = list.First; current != null; current = current.Next) - { - if (FaceConnector.AreConnectable(connector, current, NumOfDimensions)) - { - list.Remove(current); - FaceConnector.Connect(current, connector); - current.Face = null; - connector.Face = null; - ObjectManager.DepositConnector(current); - ObjectManager.DepositConnector(connector); - return; - } - } - - list.Add(connector); - } - - /// - /// Removes the faces "covered" by the current vertex and adds the newly created ones. - /// - /// true if XXXX, false otherwise. - private bool CreateCone() - { - var currentVertexIndex = CurrentVertex; - ConeFaceBuffer.Clear(); - - for (var fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++) - { - var oldFaceIndex = AffectedFaceBuffer[fIndex]; - var oldFace = FacePool[oldFaceIndex]; - - // Find the faces that need to be updated - var updateCount = 0; - for (var i = 0; i < NumOfDimensions; i++) - { - var af = oldFace.AdjacentFaces[i]; - if (!AffectedFaceFlags[af]) // Tag == false when oldFaces does not contain af - { - UpdateBuffer[updateCount] = af; - UpdateIndices[updateCount] = i; - ++updateCount; - } - } - - for (var i = 0; i < updateCount; i++) - { - var adjacentFace = FacePool[UpdateBuffer[i]]; - - var oldFaceAdjacentIndex = 0; - var adjFaceAdjacency = adjacentFace.AdjacentFaces; - for (var j = 0; j < adjFaceAdjacency.Length; j++) - { - if (oldFaceIndex == adjFaceAdjacency[j]) - { - oldFaceAdjacentIndex = j; - break; - } - } - - var forbidden = UpdateIndices[i]; // Index of the face that corresponds to this adjacent face - - int oldVertexIndex; - int[] vertices; - - var newFaceIndex = ObjectManager.GetFace(); - var newFace = FacePool[newFaceIndex]; - vertices = newFace.Vertices; - for (var j = 0; j < NumOfDimensions; j++) vertices[j] = oldFace.Vertices[j]; - oldVertexIndex = vertices[forbidden]; - - int orderedPivotIndex; - - // correct the ordering - if (currentVertexIndex < oldVertexIndex) - { - orderedPivotIndex = 0; - for (var j = forbidden - 1; j >= 0; j--) - { - if (vertices[j] > currentVertexIndex) vertices[j + 1] = vertices[j]; - else - { - orderedPivotIndex = j + 1; - break; - } - } - } - else - { - orderedPivotIndex = NumOfDimensions - 1; - for (var j = forbidden + 1; j < NumOfDimensions; j++) - { - if (vertices[j] < currentVertexIndex) vertices[j - 1] = vertices[j]; - else - { - orderedPivotIndex = j - 1; - break; - } - } - } - - vertices[orderedPivotIndex] = CurrentVertex; - - if (!mathHelper.CalculateFacePlane(newFace, Center)) - { - return false; - } - - ConeFaceBuffer.Add(MakeDeferredFace(newFace, orderedPivotIndex, adjacentFace, oldFaceAdjacentIndex, - oldFace)); - } - } - - return true; - } - - /// - /// Commits a cone and adds a vertex to the convex hull. - /// - private void CommitCone() - { - // Fill the adjacency. - for (var i = 0; i < ConeFaceBuffer.Count; i++) - { - var face = ConeFaceBuffer[i]; - - var newFace = face.Face; - var adjacentFace = face.Pivot; - var oldFace = face.OldFace; - var orderedPivotIndex = face.FaceIndex; - - newFace.AdjacentFaces[orderedPivotIndex] = adjacentFace.Index; - adjacentFace.AdjacentFaces[face.PivotIndex] = newFace.Index; - - // let there be a connection. - for (var j = 0; j < NumOfDimensions; j++) - { - if (j == orderedPivotIndex) continue; - var connector = ObjectManager.GetConnector(); - connector.Update(newFace, j, NumOfDimensions); - ConnectFace(connector); - } - - // the id adjacent face on the hull? If so, we can use simple method to find beyond vertices. - if (adjacentFace.VerticesBeyond.Count == 0) - FindBeyondVertices(newFace, oldFace.VerticesBeyond); - // it is slightly more effective if the face with the lower number of beyond vertices comes first. - else if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count) - FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond); - else - FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond); - - // This face will definitely lie on the hull - if (newFace.VerticesBeyond.Count == 0) - { - ConvexFaces.Add(newFace.Index); - UnprocessedFaces.Remove(newFace); - ObjectManager.DepositVertexBuffer(newFace.VerticesBeyond); - newFace.VerticesBeyond = EmptyBuffer; - } - else // Add the face to the list - { - UnprocessedFaces.Add(newFace); - } - - // recycle the object. - ObjectManager.DepositDeferredFace(face); - } - - // Recycle the affected faces. - for (var fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++) - { - var face = AffectedFaceBuffer[fIndex]; - UnprocessedFaces.Remove(FacePool[face]); - ObjectManager.DepositFace(face); - } - } - - /// - /// Check whether the vertex v is beyond the given face. If so, add it to beyondVertices. - /// - /// The face. - /// The beyond vertices. - /// The v. - private void IsBeyond(ConvexFaceInternal face, IndexBuffer beyondVertices, int v) - { - var distance = mathHelper.GetVertexDistance(v, face); - if (distance >= PlaneDistanceTolerance) - { - if (distance > MaxDistance) - { - // If it's within the tolerance distance, use the lex. larger point - if (distance - MaxDistance < PlaneDistanceTolerance) - { // todo: why is this LexCompare necessary. Would seem to favor x over y over z (etc.)? - if (LexCompare(v, FurthestVertex) > 0) - { - MaxDistance = distance; - FurthestVertex = v; - } - } - else - { - MaxDistance = distance; - FurthestVertex = v; - } - } - beyondVertices.Add(v); - } - } - - - /// - /// Compares the values of two vertices. The return value (-1, 0 or +1) are found - /// by first checking the first coordinate and then progressing through the rest. - /// In this way {2, 8} will be a "-1" (less than) {3, 1}. - /// - /// The base vertex index, u. - /// The compared vertex index, v. - /// System.Int32. - private int LexCompare(int u, int v) - { - int uOffset = u * NumOfDimensions, vOffset = v * NumOfDimensions; - for (var i = 0; i < NumOfDimensions; i++) - { - double x = Positions[uOffset + i], y = Positions[vOffset + i]; - var comp = x.CompareTo(y); - if (comp != 0) return comp; - } - return 0; - } - - - /// - /// Used by update faces. - /// - /// The face. - /// The beyond. - /// The beyond1. - private void FindBeyondVertices(ConvexFaceInternal face, IndexBuffer beyond, IndexBuffer beyond1) - { - var beyondVertices = BeyondBuffer; - - MaxDistance = double.NegativeInfinity; - FurthestVertex = 0; - int v; - - for (var i = 0; i < beyond1.Count; i++) VertexVisited[beyond1[i]] = true; - VertexVisited[CurrentVertex] = false; - for (var i = 0; i < beyond.Count; i++) - { - v = beyond[i]; - if (v == CurrentVertex) continue; - VertexVisited[v] = false; - IsBeyond(face, beyondVertices, v); - } - - for (var i = 0; i < beyond1.Count; i++) - { - v = beyond1[i]; - if (VertexVisited[v]) IsBeyond(face, beyondVertices, v); - } - - face.FurthestVertex = FurthestVertex; - - // Pull the old switch a roo (switch the face beyond buffers) - var temp = face.VerticesBeyond; - face.VerticesBeyond = beyondVertices; - if (temp.Count > 0) temp.Clear(); - BeyondBuffer = temp; - } - - /// - /// Finds the beyond vertices. - /// - /// The face. - /// The beyond. - private void FindBeyondVertices(ConvexFaceInternal face, IndexBuffer beyond) - { - var beyondVertices = BeyondBuffer; - - MaxDistance = double.NegativeInfinity; - FurthestVertex = 0; - int v; - - for (var i = 0; i < beyond.Count; i++) - { - v = beyond[i]; - if (v == CurrentVertex) continue; - IsBeyond(face, beyondVertices, v); - } - - face.FurthestVertex = FurthestVertex; - - // Pull the old switch a roo (switch the face beyond buffers) - var temp = face.VerticesBeyond; - face.VerticesBeyond = beyondVertices; - if (temp.Count > 0) temp.Clear(); - BeyondBuffer = temp; - } - - /// - /// Recalculates the centroid of the current hull. - /// - private void UpdateCenter() - { - for (var i = 0; i < NumOfDimensions; i++) Center[i] *= ConvexHullSize; - ConvexHullSize += 1; - var f = 1.0f / ConvexHullSize; - var co = CurrentVertex * NumOfDimensions; - for (var i = 0; i < NumOfDimensions; i++) Center[i] = f * (Center[i] + Positions[co + i]); - } - - /// - /// Removes the last vertex from the center. - /// - private void RollbackCenter() - { - for (var i = 0; i < NumOfDimensions; i++) Center[i] *= ConvexHullSize; - ConvexHullSize -= 1; - var f = ConvexHullSize > 0 ? 1.0f / ConvexHullSize : 0.0f; - var co = CurrentVertex * NumOfDimensions; - for (var i = 0; i < NumOfDimensions; i++) Center[i] = f * (Center[i] - Positions[co + i]); - } - - /// - /// Handles singular vertex. - /// - private void HandleSingular() - { - RollbackCenter(); - SingularVertices.Add(CurrentVertex); - - // This means that all the affected faces must be on the hull and that all their "vertices beyond" are singular. - for (var fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++) - { - var face = FacePool[AffectedFaceBuffer[fIndex]]; - var vb = face.VerticesBeyond; - for (var i = 0; i < vb.Count; i++) - { - SingularVertices.Add(vb[i]); - } - - ConvexFaces.Add(face.Index); - UnprocessedFaces.Remove(face); - ObjectManager.DepositVertexBuffer(face.VerticesBeyond); - face.VerticesBeyond = EmptyBuffer; - } - } - - /// - /// Get a vertex coordinate. In order to reduce speed, all vertex coordinates - /// have been placed in a single array. - /// - /// The vertex index. - /// The index of the dimension. - /// System.Double. - private float GetCoordinate(int vIndex, int dimension) - { - return Positions[vIndex * NumOfDimensions + dimension]; - } - - #region Returning the Results in the proper format - - /// - /// Gets the hull vertices. - /// - /// The type of the t vertex. - /// The data. - /// TVertex[]. - private TVertex[] GetHullVertices(IList data) - { - var cellCount = ConvexFaces.Count; - var hullVertexCount = 0; - - for (var i = 0; i < NumberOfVertices; i++) VertexVisited[i] = false; - - for (var i = 0; i < cellCount; i++) - { - var vs = FacePool[ConvexFaces[i]].Vertices; - for (var j = 0; j < vs.Length; j++) - { - var v = vs[j]; - if (!VertexVisited[v]) - { - VertexVisited[v] = true; - hullVertexCount++; - } - } - } - - var result = new TVertex[hullVertexCount]; - for (var i = 0; i < NumberOfVertices; i++) - { - if (VertexVisited[i]) result[--hullVertexCount] = data[i]; - } - - return result; - } - - /// - /// Finds the convex hull and creates the TFace objects. - /// - /// The type of the t face. - /// The type of the t vertex. - /// TFace[]. - private TFace[] GetConvexFaces() - where TFace : ConvexFace, new() - where TVertex : IVertex - { - var faces = ConvexFaces; - var cellCount = faces.Count; - var cells = new TFace[cellCount]; - - for (var i = 0; i < cellCount; i++) - { - var face = FacePool[faces[i]]; - var vertices = new TVertex[NumOfDimensions]; - for (var j = 0; j < NumOfDimensions; j++) - { - vertices[j] = (TVertex)Vertices[face.Vertices[j]]; - } - - cells[i] = new TFace - { - Vertices = vertices, - Adjacency = new TFace[NumOfDimensions], - Normal = IsLifted ? null : face.Normal - }; - face.Tag = i; - } - - for (var i = 0; i < cellCount; i++) - { - var face = FacePool[faces[i]]; - var cell = cells[i]; - for (var j = 0; j < NumOfDimensions; j++) - { - if (face.AdjacentFaces[j] < 0) continue; - cell.Adjacency[j] = cells[FacePool[face.AdjacentFaces[j]].Tag]; - } - - // Fix the vertex orientation. - if (face.IsNormalFlipped) - { - var tempVert = cell.Vertices[0]; - cell.Vertices[0] = cell.Vertices[NumOfDimensions - 1]; - cell.Vertices[NumOfDimensions - 1] = tempVert; - - var tempAdj = cell.Adjacency[0]; - cell.Adjacency[0] = cell.Adjacency[NumOfDimensions - 1]; - cell.Adjacency[NumOfDimensions - 1] = tempAdj; - } - } - - return cells; - } - - /// - /// For 2D only: Returns the result in counter-clockwise order starting with the element with the lowest X value. - /// If there are multiple vertices with the same minimum X, then the one with the lowest Y is chosen. - /// - /// The type of the vertex. - /// The type of the face. - /// The data. - /// - private ConvexHull Return2DResultInOrder(IList data) - where TVertex : IVertex - where TFace : ConvexFace, new() - { - TFace[] faces = GetConvexFaces(); - var numPoints = faces.Length; - var orderDictionary = new Dictionary(); - foreach (var face in faces) - orderDictionary.Add(face.Vertices[1], face); - var firstPoint = faces[0].Vertices[1]; - var nextPoint = faces[0].Vertices[0]; - var orderedPointList = new List(); - orderedPointList.Add(firstPoint); - var orderedFaceList = new List(); - orderedFaceList.Add(faces[1]); - var lowestXMinIndex = 0; - var k = 0; - while (!nextPoint.Equals(firstPoint)) - { - orderedPointList.Add(nextPoint); - var nextFace = orderDictionary[nextPoint]; - orderedFaceList.Add(nextFace); - if (nextPoint.Position[0] < orderedPointList[lowestXMinIndex].Position[0] - || (nextPoint.Position[0] == orderedPointList[lowestXMinIndex].Position[0] - && nextPoint.Position[1] <= orderedPointList[lowestXMinIndex].Position[1])) - lowestXMinIndex = k; - k++; - nextPoint = nextFace.Vertices[0]; - } - TVertex[] points = new TVertex[numPoints]; - for (int i = 0; i < numPoints; i++) - { - var j = (i + lowestXMinIndex) % numPoints; - points[i] = orderedPointList[j]; - faces[i] = orderedFaceList[j]; - } - return new ConvexHull - { - Points = points, - Faces = faces - }; - } - - #endregion - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.MainLoop.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.MainLoop.cs.meta deleted file mode 100644 index 8eb122b5b..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ConvexHullAlgorithm.MainLoop.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f7f265217d00ea340b87645242a45181 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/DataModel.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/DataModel.cs deleted file mode 100644 index 761dd1ccf..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/DataModel.cs +++ /dev/null @@ -1,237 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -namespace MIConvexHull -{ - /// - /// For deferred face addition. - /// - internal sealed class DeferredFace - { - /// - /// The faces. - /// - public ConvexFaceInternal Face, Pivot, OldFace; - - /// - /// The indices. - /// - public int FaceIndex, PivotIndex; - } - - /// - /// A helper class used to connect faces. - /// - internal sealed class FaceConnector - { - /// - /// The edge to be connected. - /// - public int EdgeIndex; - - /// - /// The face. - /// - public ConvexFaceInternal Face; - - /// - /// The hash code computed from indices. - /// - public uint HashCode; - - /// - /// Next node in the list. - /// - public FaceConnector Next; - - /// - /// Prev node in the list. - /// - public FaceConnector Previous; - - /// - /// The vertex indices. - /// - public int[] Vertices; - - /// - /// Ctor. - /// - /// The dimension. - public FaceConnector(int dimension) - { - Vertices = new int[dimension - 1]; - } - - /// - /// Updates the connector. - /// - /// The face. - /// Index of the edge. - /// The dim. - public void Update(ConvexFaceInternal face, int edgeIndex, int dim) - { - Face = face; - EdgeIndex = edgeIndex; - - uint hashCode = 23; - - unchecked - { - var vs = face.Vertices; - int i, c = 0; - for (i = 0; i < edgeIndex; i++) - { - Vertices[c++] = vs[i]; - hashCode += 31*hashCode + (uint) vs[i]; - } - for (i = edgeIndex + 1; i < vs.Length; i++) - { - Vertices[c++] = vs[i]; - hashCode += 31*hashCode + (uint) vs[i]; - } - } - - HashCode = hashCode; - } - - /// - /// Can two faces be connected. - /// - /// a. - /// The b. - /// The dim. - /// true if XXXX, false otherwise. - public static bool AreConnectable(FaceConnector a, FaceConnector b, int dim) - { - if (a.HashCode != b.HashCode) return false; - - var av = a.Vertices; - var bv = b.Vertices; - for (var i = 0; i < av.Length; i++) - { - if (av[i] != bv[i]) return false; - } - - return true; - } - - /// - /// Connect two faces. - /// - /// a. - /// The b. - public static void Connect(FaceConnector a, FaceConnector b) - { - a.Face.AdjacentFaces[a.EdgeIndex] = b.Face.Index; - b.Face.AdjacentFaces[b.EdgeIndex] = a.Face.Index; - } - } - - /// - /// This internal class manages the faces of the convex hull. It is a - /// separate class from the desired user class. - /// - internal sealed class ConvexFaceInternal - { - /// - /// Gets or sets the adjacent face data. - /// - public int[] AdjacentFaces; - - /// - /// The furthest vertex. - /// - public int FurthestVertex; - - /// - /// Index of the face inside the pool. - /// - public int Index; - - /// - /// Is it present in the list. - /// - public bool InList; - - /// - /// Is the normal flipped? - /// - public bool IsNormalFlipped; - - /// - /// Next node in the list. - /// - public ConvexFaceInternal Next; - - /// - /// Gets or sets the normal vector. - /// - public float[] Normal; - - /// - /// Face plane constant element. - /// - public float Offset; - - //public int UnprocessedIndex; - - /// - /// Prev node in the list. - /// - public ConvexFaceInternal Previous; - - /// - /// Used to traverse affected faces and create the Delaunay representation. - /// - public int Tag; - - /// - /// Gets or sets the vertices. - /// - public int[] Vertices; - - /// - /// Gets or sets the vertices beyond. - /// - public IndexBuffer VerticesBeyond; - - /// - /// Initializes a new instance of the class. - /// - /// The dimension. - /// The index. - /// The beyond list. - public ConvexFaceInternal(int dimension, int index, IndexBuffer beyondList) - { - Index = index; - AdjacentFaces = new int[dimension]; - VerticesBeyond = beyondList; - Normal = new float[dimension]; - Vertices = new int[dimension]; - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/DataModel.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/DataModel.cs.meta deleted file mode 100644 index 411bcb0d5..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/DataModel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 58c58e163f4c86e48a6df3ee6c5056c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/MathHelper.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/MathHelper.cs deleted file mode 100644 index 0f030c59d..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/MathHelper.cs +++ /dev/null @@ -1,480 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; -using System.Collections.Generic; -using CultMath; -using static CultMath.math; -using Random = CultMath.Random; - -namespace MIConvexHull -{ - /// - /// A helper class mostly for normal computation. If convex hulls are computed - /// in higher dimensions, it might be a good idea to add a specific - /// FindNormalVectorND function. - /// - internal class MathHelper - { - /// - /// The dimension - /// - private readonly int Dimension; - /// - /// The matrix pivots - /// - private readonly int[] matrixPivots; - /// - /// The n d matrix - /// - private readonly float[] nDMatrix; - /// - /// The n d normal helper vector - /// - private readonly float[] nDNormalHelperVector; - - /// - /// The nt x - /// - private readonly float[] ntX; - /// - /// The nt y - /// - private readonly float[] ntY; - /// - /// The nt z - /// - private readonly float[] ntZ; - - /// - /// The position data - /// - private readonly float[] PositionData; - - private static Random _random = new Random((uint) (DateTime.Now.Ticks % uint.MaxValue)); - - /// - /// Initializes a new instance of the class. - /// - /// The dimension. - /// The positions. - internal MathHelper(int dimension, float[] positions) - { - PositionData = positions; - Dimension = dimension; - - ntX = new float[Dimension]; - ntY = new float[Dimension]; - ntZ = new float[Dimension]; - - nDNormalHelperVector = new float[Dimension]; - nDMatrix = new float[Dimension * Dimension]; - matrixPivots = new int[Dimension]; - } - - /// - /// Calculates the normal and offset of the hyper-plane given by the face's vertices. - /// - /// The face. - /// The center. - /// true if XXXX, false otherwise. - internal bool CalculateFacePlane(ConvexFaceInternal face, float[] center) - { - var vertices = face.Vertices; - var normal = face.Normal; - FindNormalVector(vertices, normal); - - if (float.IsNaN(normal[0])) - { - return false; - } - - var offset = 0.0f; - var centerDistance = 0.0f; - var fi = vertices[0] * Dimension; - for (var i = 0; i < Dimension; i++) - { - var n = normal[i]; - offset += n * PositionData[fi + i]; - centerDistance += n * center[i]; - } - face.Offset = -offset; - centerDistance -= offset; - - if (centerDistance > 0) - { - for (var i = 0; i < Dimension; i++) normal[i] = -normal[i]; - face.Offset = offset; - face.IsNormalFlipped = true; - } - else face.IsNormalFlipped = false; - - return true; - } - - /// - /// Check if the vertex is "visible" from the face. - /// The vertex is "over face" if the return value is > Constants.PlaneDistanceTolerance. - /// - /// The v. - /// The f. - /// The vertex is "over face" if the result is positive. - internal double GetVertexDistance(int v, ConvexFaceInternal f) - { - var normal = f.Normal; - var x = v * Dimension; - var distance = f.Offset; - for (var i = 0; i < normal.Length; i++) distance += normal[i] * PositionData[x + i]; - return distance; - } - - /// - /// Returns the vector the between vertices. - /// - /// To index. - /// From index. - /// System.Double[]. - internal float[] VectorBetweenVertices(int toIndex, int fromIndex) - { - var target = new float[Dimension]; - VectorBetweenVertices(toIndex, fromIndex, target); - return target; - } - /// - /// Returns the vector the between vertices. - /// - /// From index. - /// To index. - /// The target. - /// - private void VectorBetweenVertices(int toIndex, int fromIndex, float[] target) - { - int u = toIndex * Dimension, v = fromIndex * Dimension; - for (var i = 0; i < Dimension; i++) - { - target[i] = PositionData[u + i] - PositionData[v + i]; - } - } - - internal void RandomOffsetToLift(int index, float maxHeight) - { - var liftIndex = (index * Dimension) + Dimension - 1; - PositionData[liftIndex] += 0.0001f * maxHeight * (_random.NextFloat() - 0.5f); - } - #region Find the normal vector of the face - /// - /// Finds normal vector of a hyper-plane given by vertices. - /// Stores the results to normalData. - /// - /// The vertices. - /// The normal data. - private void FindNormalVector(int[] vertices, float[] normalData) - { - switch (Dimension) - { - case 2: - FindNormalVector2D(vertices, normalData); - break; - case 3: - FindNormalVector3D(vertices, normalData); - break; - case 4: - FindNormalVector4D(vertices, normalData); - break; - default: - FindNormalVectorND(vertices, normalData); - break; - } - } - /// - /// Finds 2D normal vector. - /// - /// The vertices. - /// The normal. - private void FindNormalVector2D(int[] vertices, float[] normal) - { - VectorBetweenVertices(vertices[1], vertices[0], ntX); - - var nx = -ntX[1]; - var ny = ntX[0]; - - var norm = sqrt(nx * nx + ny * ny); - - var f = 1.0f / norm; - normal[0] = f * nx; - normal[1] = f * ny; - } - /// - /// Finds 3D normal vector. - /// - /// The vertices. - /// The normal. - private void FindNormalVector3D(int[] vertices, float[] normal) - { - VectorBetweenVertices(vertices[1], vertices[0], ntX); - VectorBetweenVertices(vertices[2], vertices[1], ntY); - - var nx = ntX[1] * ntY[2] - ntX[2] * ntY[1]; - var ny = ntX[2] * ntY[0] - ntX[0] * ntY[2]; - var nz = ntX[0] * ntY[1] - ntX[1] * ntY[0]; - - var norm = sqrt(nx * nx + ny * ny + nz * nz); - - var f = 1.0f / norm; - normal[0] = f * nx; - normal[1] = f * ny; - normal[2] = f * nz; - } - /// - /// Finds 4D normal vector. - /// - /// The vertices. - /// The normal. - private void FindNormalVector4D(int[] vertices, float[] normal) - { - VectorBetweenVertices(vertices[1], vertices[0], ntX); - VectorBetweenVertices(vertices[2], vertices[1], ntY); - VectorBetweenVertices(vertices[3], vertices[2], ntZ); - - var x = ntX; - var y = ntY; - var z = ntZ; - - // This was generated using Mathematica - var nx = x[3] * (y[2] * z[1] - y[1] * z[2]) - + x[2] * (y[1] * z[3] - y[3] * z[1]) - + x[1] * (y[3] * z[2] - y[2] * z[3]); - var ny = x[3] * (y[0] * z[2] - y[2] * z[0]) - + x[2] * (y[3] * z[0] - y[0] * z[3]) - + x[0] * (y[2] * z[3] - y[3] * z[2]); - var nz = x[3] * (y[1] * z[0] - y[0] * z[1]) - + x[1] * (y[0] * z[3] - y[3] * z[0]) - + x[0] * (y[3] * z[1] - y[1] * z[3]); - var nw = x[2] * (y[0] * z[1] - y[1] * z[0]) - + x[1] * (y[2] * z[0] - y[0] * z[2]) - + x[0] * (y[1] * z[2] - y[2] * z[1]); - - var norm = sqrt(nx * nx + ny * ny + nz * nz + nw * nw); - - var f = 1.0f / norm; - normal[0] = f * nx; - normal[1] = f * ny; - normal[2] = f * nz; - normal[3] = f * nw; - } - - /// - /// Finds the normal vector nd. - /// - /// The vertices. - /// The normal. - private void FindNormalVectorND(int[] vertices, float[] normal) - { - /* We need to solve the matrix A n = B where - * - A contains coordinates of vertices as columns - * - B is vector with all 1's. Really, it should be the distance of - * the plane from the origin, but - since we're not worried about that - * here and we will normalize the normal anyway - all 1's suffices. - */ - var iPiv = matrixPivots; - var data = nDMatrix; - var norm = 0.0f; - - // Solve determinants by replacing x-th column by all 1. - for (var x = 0; x < Dimension; x++) - { - for (var i = 0; i < Dimension; i++) - { - var offset = vertices[i] * Dimension; - for (var j = 0; j < Dimension; j++) - { - // maybe I got the i/j mixed up here regarding the representation Math.net uses... - // ...but it does not matter since Det(A) = Det(Transpose(A)). - data[Dimension * i + j] = j == x ? 1.0f : PositionData[offset + j]; - } - } - LUFactor(data, Dimension, iPiv, nDNormalHelperVector); - var coord = 1.0f; - for (var i = 0; i < Dimension; i++) - { - if (iPiv[i] != i) coord *= -data[Dimension * i + i]; // the determinant sign changes on row swap. - else coord *= data[Dimension * i + i]; - } - normal[x] = coord; - norm += coord * coord; - } - - // Normalize the result - var f = 1.0f / sqrt(norm); - for (var i = 0; i < normal.Length; i++) normal[i] *= f; - } - #endregion - - #region Simplex Volume - /// - /// Gets the simplex volume. Prior to having enough edge vectors, the method pads the remaining with all - /// "other numbers". So, yes, this method is not really finding the volume. But a relative volume-like measure. It - /// uses the magnitude of the determinant as the volume stand-in following the Cayley-Menger theorem. - /// - /// The edge vectors. - /// The last index. - /// The big number. - /// System.Double. - internal float GetSimplexVolume(float[][] edgeVectors, int lastIndex, float bigNumber) - { - var A = new float[Dimension * Dimension]; - var index = 0; - for (int i = 0; i < Dimension; i++) - for (int j = 0; j < Dimension; j++) - if (i <= lastIndex) - A[index++] = edgeVectors[i][j]; - else A[index] = (pow(-1, index) * index++) / bigNumber; - // this last term is used for all the vertices in the comparison for the yet determined vertices - // the idea is to come up with sets of numbers that are orthogonal so that an non-zero value will result - // and to choose smallish numbers since the choice of vectors will affect what the end volume is. - // A better way (todo?) is to solve a smaller matrix. However, cases were found in which the obvious smaller vector - // (the upper left) had too many zeros. So, one would need to find the right subset. Indeed choosing a subset - // biases the first dimensions of the others. Perhaps a larger volume would be created from a different vertex - // if another subset of dimensions were used. - return abs(DeterminantDestructive(A)); - } - - /// - /// Determinants the destructive. - /// - /// a. - /// System.Double. - private float DeterminantDestructive(float[] A) - { - switch (Dimension) - { - case 0: - return 0.0f; - case 1: - return A[0]; - case 2: - return A[0] * A[3] - A[1] * A[2]; - case 3: - return A[0] * A[4] * A[8] + A[1] * A[5] * A[6] + A[2] * A[3] * A[7] - - A[0] * A[5] * A[7] - A[1] * A[3] * A[8] - A[2] * A[4] * A[6]; - default: - { - var iPiv = new int[Dimension]; - var helper = new float[Dimension]; - LUFactor(A, Dimension, iPiv, helper); - var det = 1.0f; - for (var i = 0; i < iPiv.Length; i++) - { - det *= A[Dimension * i + i]; - if (iPiv[i] != i) det *= -1; // the determinant sign changes on row swap. - } - return det; - } - } - } - #endregion - - - // Modified from Math.NET - // Copyright (c) 2009-2013 Math.NET - /// - /// Lus the factor. - /// - /// The data. - /// The order. - /// The ipiv. - /// The vec l ucolj. - private static void LUFactor(float[] data, int order, int[] ipiv, float[] vecLUcolj) - { - // Initialize the pivot matrix to the identity permutation. - for (var i = 0; i < order; i++) - { - ipiv[i] = i; - } - - // Outer loop. - for (var j = 0; j < order; j++) - { - var indexj = j * order; - var indexjj = indexj + j; - - // Make a copy of the j-th column to localize references. - for (var i = 0; i < order; i++) - { - vecLUcolj[i] = data[indexj + i]; - } - - // Apply previous transformations. - for (var i = 0; i < order; i++) - { - // Most of the time is spent in the following dot product. - var kmax = Math.Min(i, j); - var s = 0.0f; - for (var k = 0; k < kmax; k++) - { - s += data[k * order + i] * vecLUcolj[k]; - } - - data[indexj + i] = vecLUcolj[i] -= s; - } - - // Find pivot and exchange if necessary. - var p = j; - for (var i = j + 1; i < order; i++) - { - if (abs(vecLUcolj[i]) > abs(vecLUcolj[p])) - { - p = i; - } - } - - if (p != j) - { - for (var k = 0; k < order; k++) - { - var indexk = k * order; - var indexkp = indexk + p; - var indexkj = indexk + j; - var temp = data[indexkp]; - data[indexkp] = data[indexkj]; - data[indexkj] = temp; - } - - ipiv[j] = p; - } - - // Compute multipliers. - if (j < order & data[indexjj] != 0.0f) - { - for (var i = j + 1; i < order; i++) - { - data[indexj + i] /= data[indexjj]; - } - } - } - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/MathHelper.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/MathHelper.cs.meta deleted file mode 100644 index 920a8673d..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/MathHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8bb3327041efa18479319ec117493f8c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ObjectManager.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ObjectManager.cs deleted file mode 100644 index 66333b74f..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ObjectManager.cs +++ /dev/null @@ -1,218 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; - -namespace MIConvexHull -{ - /// - /// A helper class for object allocation/storage. - /// This helps the GC a lot as it prevents the creation of about 75% of - /// new face objects (in the case of ConvexFaceInternal). In the case of - /// FaceConnectors and DefferedFaces, the difference is even higher (in most - /// cases O(1) vs O(number of created faces)). - /// - internal class ObjectManager - { - /// - /// The dimension - /// - private readonly int Dimension; - /// - /// The connector stack - /// - private FaceConnector ConnectorStack; - /// - /// The deferred face stack - /// - private readonly SimpleList DeferredFaceStack; - /// - /// The empty buffer stack - /// - private readonly SimpleList EmptyBufferStack; - /// - /// The face pool - /// - private ConvexFaceInternal[] FacePool; - /// - /// The face pool size - /// - private int FacePoolSize; - /// - /// The face pool capacity - /// - private int FacePoolCapacity; - /// - /// The free face indices - /// - private readonly IndexBuffer FreeFaceIndices; - - /// - /// The hull - /// - private readonly ConvexHullAlgorithm Hull; - - /// - /// Create the manager. - /// - /// The hull. - public ObjectManager(ConvexHullAlgorithm hull) - { - Dimension = hull.NumOfDimensions; - Hull = hull; - FacePool = hull.FacePool; - FacePoolSize = 0; - FacePoolCapacity = hull.FacePool.Length; - FreeFaceIndices = new IndexBuffer(); - - EmptyBufferStack = new SimpleList(); - DeferredFaceStack = new SimpleList(); - } - - /// - /// Return the face to the pool for later use. - /// - /// Index of the face. - public void DepositFace(int faceIndex) - { - var face = FacePool[faceIndex]; - var af = face.AdjacentFaces; - for (var i = 0; i < af.Length; i++) - { - af[i] = -1; - } - FreeFaceIndices.Push(faceIndex); - } - - /// - /// Reallocate the face pool, including the AffectedFaceFlags - /// - private void ReallocateFacePool() - { - var newPool = new ConvexFaceInternal[2*FacePoolCapacity]; - var newTags = new bool[2*FacePoolCapacity]; - Array.Copy(FacePool, newPool, FacePoolCapacity); - Buffer.BlockCopy(Hull.AffectedFaceFlags, 0, newTags, 0, FacePoolCapacity*sizeof (bool)); - FacePoolCapacity = 2*FacePoolCapacity; - Hull.FacePool = newPool; - FacePool = newPool; - Hull.AffectedFaceFlags = newTags; - } - - /// - /// Create a new face and put it in the pool. - /// - /// System.Int32. - private int CreateFace() - { - var index = FacePoolSize; - var face = new ConvexFaceInternal(Dimension, index, GetVertexBuffer()); - FacePoolSize++; - if (FacePoolSize > FacePoolCapacity) ReallocateFacePool(); - FacePool[index] = face; - return index; - } - - /// - /// Return index of an unused face or creates a new one. - /// - /// System.Int32. - public int GetFace() - { - if (FreeFaceIndices.Count > 0) return FreeFaceIndices.Pop(); - return CreateFace(); - } - - /// - /// Store a face connector in the "embedded" linked list. - /// - /// The connector. - public void DepositConnector(FaceConnector connector) - { - if (ConnectorStack == null) - { - connector.Next = null; - ConnectorStack = connector; - } - else - { - connector.Next = ConnectorStack; - ConnectorStack = connector; - } - } - - /// - /// Get an unused face connector. If none is available, create it. - /// - /// FaceConnector. - public FaceConnector GetConnector() - { - if (ConnectorStack == null) return new FaceConnector(Dimension); - - var ret = ConnectorStack; - ConnectorStack = ConnectorStack.Next; - ret.Next = null; - return ret; - } - - /// - /// Deposit the index buffer. - /// - /// The buffer. - public void DepositVertexBuffer(IndexBuffer buffer) - { - buffer.Clear(); - EmptyBufferStack.Push(buffer); - } - - /// - /// Get a store index buffer or create a new instance. - /// - /// IndexBuffer. - public IndexBuffer GetVertexBuffer() - { - return EmptyBufferStack.Count != 0 ? EmptyBufferStack.Pop() : new IndexBuffer(); - } - - /// - /// Deposit the deferred face. - /// - /// The face. - public void DepositDeferredFace(DeferredFace face) - { - DeferredFaceStack.Push(face); - } - - /// - /// Get the deferred face. - /// - /// DeferredFace. - public DeferredFace GetDeferredFace() - { - return DeferredFaceStack.Count != 0 ? DeferredFaceStack.Pop() : new DeferredFace(); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ObjectManager.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ObjectManager.cs.meta deleted file mode 100644 index cb1cf125b..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/ConvexHull/ObjectManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e8d582e97c6824740ba9e1a41641b372 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Face3.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Face3.cs deleted file mode 100644 index 980e442d0..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Face3.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections; -using MIConvexHull; - -public class Face3 : ConvexFace -{ - - -} diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Face3.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Face3.cs.meta deleted file mode 100644 index ab550e9ac..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Face3.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 30a2635ffe51545499499ce392b234c8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/IVertex.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/IVertex.cs deleted file mode 100644 index b7217c074..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/IVertex.cs +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -namespace MIConvexHull -{ - /// - /// An interface for a structure with nD position. - /// - public interface IVertex - { - /// - /// Position of the vertex. - /// - /// The position. - float[] Position { get; } - } - - /// - /// "Default" vertex. - /// - /// - public class DefaultVertex : IVertex - { - /// - /// Position of the vertex. - /// - /// The position. - public float[] Position { get; set; } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/IVertex.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/IVertex.cs.meta deleted file mode 100644 index 06195b473..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/IVertex.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a55f713690988bb48aef7cbd4f01ebc7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.cs deleted file mode 100644 index 690071bec..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.cs +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System.Collections.Generic; -using System.Linq; - -namespace MIConvexHull -{ - /// - /// Simple interface to unify different types of triangulations in the future. - /// - /// The type of the t vertex. - /// The type of the t cell. - public interface ITriangulation - where TCell : TriangulationCell, new() - where TVertex : IVertex - { - /// - /// Triangulation simplexes. For 2D - triangles, 3D - tetrahedrons, etc ... - /// - /// The cells. - IEnumerable Cells { get; } - } - - /// - /// Factory class for creating triangulations. - /// - public static class Triangulation - { - /// - /// Creates the Delaunay triangulation of the input data. - /// - /// The type of the t vertex. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// ITriangulation<TVertex, DefaultTriangulationCell<TVertex>>. - public static ITriangulation> CreateDelaunay( - IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - { - return DelaunayTriangulation>.Create(data, PlaneDistanceTolerance); - } - - /// - /// Creates the Delaunay triangulation of the input data. - /// - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// ITriangulation<DefaultVertex, DefaultTriangulationCell<DefaultVertex>>. - public static ITriangulation> CreateDelaunay( - IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - { - var points = data.Select(p => new DefaultVertex { Position = p }).ToList(); - return DelaunayTriangulation>.Create(points, PlaneDistanceTolerance); - } - - /// - /// Creates the Delaunay triangulation of the input data. - /// - /// The type of the t vertex. - /// The type of the t face. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// ITriangulation<TVertex, TFace>. - public static ITriangulation CreateDelaunay(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - where TFace : TriangulationCell, new() - { - return DelaunayTriangulation.Create(data, PlaneDistanceTolerance); - } - - - /// - /// Create the voronoi mesh. - /// - /// The type of the t vertex. - /// The type of the t cell. - /// The type of the t edge. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// VoronoiMesh<TVertex, TCell, TEdge>. - public static VoronoiMesh CreateVoronoi(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TCell : TriangulationCell, new() - where TVertex : IVertex - where TEdge : VoronoiEdge, new() - { - return VoronoiMesh.Create(data, PlaneDistanceTolerance); - } - - /// - /// Create the voronoi mesh. - /// - /// The type of the t vertex. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// VoronoiMesh<TVertex, DefaultTriangulationCell<TVertex>, VoronoiEdge<TVertex, DefaultTriangulationCell<TVertex>>>. - public static - VoronoiMesh - , VoronoiEdge>> - CreateVoronoi(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - { - return - VoronoiMesh - , VoronoiEdge> - >.Create(data, PlaneDistanceTolerance); - } - - /// - /// Create the voronoi mesh. - /// - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// VoronoiMesh<DefaultVertex, DefaultTriangulationCell<DefaultVertex>, VoronoiEdge<DefaultVertex, DefaultTriangulationCell<DefaultVertex>>>. - public static - VoronoiMesh - , - VoronoiEdge>> - CreateVoronoi(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - { - var points = data.Select(p => new DefaultVertex { Position = p.ToArray() }).ToList(); - return - VoronoiMesh - , - VoronoiEdge>>.Create(points, PlaneDistanceTolerance); - } - - /// - /// Create the voronoi mesh. - /// - /// The type of the t vertex. - /// The type of the t cell. - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// VoronoiMesh<TVertex, TCell, VoronoiEdge<TVertex, TCell>>. - public static VoronoiMesh> CreateVoronoi( - IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - where TCell : TriangulationCell, new() - { - return VoronoiMesh>.Create(data, PlaneDistanceTolerance); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.cs.meta deleted file mode 100644 index 2f8f75a85..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0762bfe861ed97749a222fb1c217788a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.meta deleted file mode 100644 index 346f5fafe..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5bf99a94223c6e1458c243cb68091852 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTrianglationInternal.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTrianglationInternal.cs deleted file mode 100644 index 7209c0ccc..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTrianglationInternal.cs +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System.Collections.Generic; -using System.Linq; - -namespace MIConvexHull -{ - /* - * Code here handles triangulation related stuff. - */ - - /// - /// Class ConvexHullAlgorithm. - /// - internal partial class ConvexHullAlgorithm - { - /// - /// Computes the Delaunay triangulation. - /// - /// The type of the t vertex. - /// The type of the t cell. - /// The data. - /// The plane distance tolerance. - /// TCell[]. - internal static TCell[] GetDelaunayTriangulation(IList data, - float PlaneDistanceTolerance ) - where TCell : TriangulationCell, new() - where TVertex : IVertex - { - var ch = new ConvexHullAlgorithm(data.Cast().ToArray(), true, PlaneDistanceTolerance); - ch.GetConvexHull(); - ch.RemoveUpperFaces(); - return ch.GetConvexFaces(); - } - - /// - /// Removes up facing Tetrahedrons from the triangulation. - /// - private void RemoveUpperFaces() - { - var delaunayFaces = ConvexFaces; - var dimension = NumOfDimensions - 1; - - // Remove the "upper" faces - for (var i = delaunayFaces.Count - 1; i >= 0; i--) - { - var candidateIndex = delaunayFaces[i]; - var candidate = FacePool[candidateIndex]; - if (candidate.Normal[dimension] >= 0.0) - { - for (var fi = 0; fi < candidate.AdjacentFaces.Length; fi++) - { - var af = candidate.AdjacentFaces[fi]; - if (af >= 0) - { - var face = FacePool[af]; - for (var j = 0; j < face.AdjacentFaces.Length; j++) - { - if (face.AdjacentFaces[j] == candidateIndex) - { - face.AdjacentFaces[j] = -1; - } - } - } - } - delaunayFaces[i] = delaunayFaces[delaunayFaces.Count - 1]; - delaunayFaces.Pop(); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTrianglationInternal.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTrianglationInternal.cs.meta deleted file mode 100644 index d78b006e2..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTrianglationInternal.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: de8661d86f2667647b9dca59c1c97e9a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTriangulation.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTriangulation.cs deleted file mode 100644 index a22962b23..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTriangulation.cs +++ /dev/null @@ -1,75 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; -using System.Collections.Generic; - -namespace MIConvexHull -{ - /// - /// Calculation and representation of Delaunay triangulation. - /// - /// The type of the t vertex. - /// The type of the t cell. - /// - public class DelaunayTriangulation : ITriangulation - where TCell : TriangulationCell, new() - where TVertex : IVertex - { - /// - /// Can only be created using a factory method. - /// - private DelaunayTriangulation() - { - } - - /// - /// Cells of the triangulation. - /// - /// The cells. - public IEnumerable Cells { get; private set; } - - /// - /// Creates the Delaunay triangulation of the input data. - /// - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// DelaunayTriangulation<TVertex, TCell>. - /// data - /// data - public static DelaunayTriangulation Create(IList data, - float PlaneDistanceTolerance)// = Constants.DefaultPlaneDistanceTolerance) - { - if (data == null) throw new ArgumentNullException("data"); - if (data.Count == 0) return new DelaunayTriangulation { Cells = new TCell[0] }; - - var cells = ConvexHullAlgorithm.GetDelaunayTriangulation(data, PlaneDistanceTolerance); - - return new DelaunayTriangulation { Cells = cells }; - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTriangulation.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTriangulation.cs.meta deleted file mode 100644 index fc2ba273c..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/DelaunayTriangulation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4b0e872e78d2ab8428b446cfa5c06580 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/TriangulationCell.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/TriangulationCell.cs deleted file mode 100644 index 63e9d1f5a..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/TriangulationCell.cs +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -namespace MIConvexHull -{ - /// - /// Representation of the triangulation cell. Pretty much the same as ConvexFace, - /// just wanted to distinguish the two. - /// To declare your own face type, use class Face : DelaunayFace(of Vertex, of Face) - /// - /// The type of the t vertex. - /// The type of the t cell. - /// - public abstract class TriangulationCell : ConvexFace - where TVertex : IVertex - where TCell : ConvexFace - { - } - - /// - /// Default triangulation cell. - /// - /// The type of the t vertex. - public class DefaultTriangulationCell : TriangulationCell> - where TVertex : IVertex - { - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/TriangulationCell.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/TriangulationCell.cs.meta deleted file mode 100644 index 29dcef792..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/TriangulationCell.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 808182249e0e66143b65945d9aeb37fe -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiEdge.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiEdge.cs deleted file mode 100644 index 1557352d6..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiEdge.cs +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -namespace MIConvexHull -{ - /// - /// A class representing an (undirected) edge of the Voronoi graph. - /// - /// The type of the t vertex. - /// The type of the t cell. - public class VoronoiEdge - where TVertex : IVertex - where TCell : TriangulationCell - { - /// - /// Create an instance of the edge. - /// - public VoronoiEdge() - { - } - - /// - /// Create an instance of the edge. - /// - /// The source. - /// The target. - public VoronoiEdge(TCell source, TCell target) - { - Source = source; - Target = target; - } - - /// - /// Source of the edge. - /// - /// The source. - public TCell Source { get; internal set; } - - /// - /// Target of the edge. - /// - /// The target. - public TCell Target { get; internal set; } - - /// - /// ... - /// - /// The object to compare with the current object. - /// true if the specified is equal to this instance; otherwise, false. - public override bool Equals(object obj) - { - var other = obj as VoronoiEdge; - if (other == null) return false; - if (ReferenceEquals(this, other)) return true; - return (Source == other.Source && Target == other.Target) - || (Source == other.Target && Target == other.Source); - } - - /// - /// ... - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - public override int GetHashCode() - { - var hash = 23; - hash = hash*31 + Source.GetHashCode(); - return hash*31 + Target.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiEdge.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiEdge.cs.meta deleted file mode 100644 index 71c57ddb7..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiEdge.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2f5c388c78c121a47b14c2f4ed26af38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiMesh.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiMesh.cs deleted file mode 100644 index 3142af854..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiMesh.cs +++ /dev/null @@ -1,203 +0,0 @@ -/****************************************************************************** - * - * The MIT License (MIT) - * - * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MIConvexHull -{ - /// - /// A factory class for creating a Voronoi mesh. - /// - public static class VoronoiMesh - { - /// - /// Create the voronoi mesh. - /// - /// The type of the t vertex. - /// The type of the t cell. - /// The type of the t edge. - /// The data. - /// VoronoiMesh<TVertex, TCell, TEdge>. - public static VoronoiMesh Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TCell : TriangulationCell, new() - where TVertex : IVertex - where TEdge : VoronoiEdge, new() - { - return VoronoiMesh.Create(data, PlaneDistanceTolerance); - } - - /// - /// Create the voronoi mesh. - /// - /// The type of the t vertex. - /// The data. - /// VoronoiMesh<TVertex, DefaultTriangulationCell<TVertex>, VoronoiEdge<TVertex, DefaultTriangulationCell<TVertex>>>. - public static - VoronoiMesh - , VoronoiEdge>> - Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - { - return - VoronoiMesh - , VoronoiEdge> - >.Create(data, PlaneDistanceTolerance); - } - - /// - /// Create the voronoi mesh. - /// - /// The data. - /// VoronoiMesh<DefaultVertex, DefaultTriangulationCell<DefaultVertex>, VoronoiEdge<DefaultVertex, DefaultTriangulationCell<DefaultVertex>>>. - public static - VoronoiMesh - , - VoronoiEdge>> - Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - { - var points = data.Select(p => new DefaultVertex { Position = p.ToArray() }).ToList(); - return - VoronoiMesh - , - VoronoiEdge>>.Create(points, PlaneDistanceTolerance); - } - - /// - /// Create the voronoi mesh. - /// - /// The type of the t vertex. - /// The type of the t cell. - /// The data. - /// VoronoiMesh<TVertex, TCell, VoronoiEdge<TVertex, TCell>>. - public static VoronoiMesh> Create( - IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - where TVertex : IVertex - where TCell : TriangulationCell, new() - { - return VoronoiMesh>.Create(data, PlaneDistanceTolerance); - } - } - - /// - /// A representation of a voronoi mesh. - /// - /// The type of the t edge. - /// The type of the t vertex. - /// The type of the t cell. - public class VoronoiMesh - where TCell : TriangulationCell, new() - where TVertex : IVertex - where TEdge : VoronoiEdge, new() - { - /// - /// Can only be created using a factory method. - /// - private VoronoiMesh() - { - } - - /// - /// Vertices of the diagram. - /// - /// The vertices. - public IEnumerable Vertices { get; private set; } - - /// - /// Edges connecting the cells. - /// The same information can be retrieved Cells' Adjacency. - /// - /// The edges. - public IEnumerable Edges { get; private set; } - - /// - /// Create a Voronoi diagram of the input data. - /// - /// The data. - /// The plane distance tolerance (default is 1e-10). If too high, points - /// will be missed. If too low, the algorithm may break. Only adjust if you notice problems. - /// VoronoiMesh<TVertex, TCell, TEdge>. - /// data - /// data - public static VoronoiMesh Create(IList data, - float PlaneDistanceTolerance = Constants.DefaultPlaneDistanceTolerance) - { - if (data == null) throw new ArgumentNullException("data"); - - var t = DelaunayTriangulation.Create(data, PlaneDistanceTolerance); - var vertices = t.Cells.ToList(); - var edges = new HashSet(new EdgeComparer()); - - foreach (var f in vertices) - { - for (var i = 0; i < f.Adjacency.Length; i++) - { - var af = f.Adjacency[i]; - if (af != null) edges.Add(new TEdge { Source = f, Target = af }); - } - } - - return new VoronoiMesh - { - Vertices = vertices, - Edges = edges.ToList() - }; - } - - /// - /// This is probably not needed, but might make things a tiny bit faster. - /// - /// - private class EdgeComparer : IEqualityComparer - { - /// - /// Equals the specified x. - /// - /// The x. - /// The y. - /// System.Boolean. - public bool Equals(TEdge x, TEdge y) - { - return (x.Source == y.Source && x.Target == y.Target) || (x.Source == y.Target && x.Target == y.Source); - } - - /// - /// Returns a hash code for this instance. - /// - /// The for which a hash code is to be returned. - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - public int GetHashCode(TEdge obj) - { - return obj.Source.GetHashCode() ^ obj.Target.GetHashCode(); - } - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiMesh.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiMesh.cs.meta deleted file mode 100644 index c87b2415b..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Triangulation/VoronoiMesh.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fbb5750f20479844eb4e504302755db9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2.cs deleted file mode 100644 index e00c7deef..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections; -using MIConvexHull; -using CultMath; -using static CultMath.math; - -public class Vertex2 : IVertex -{ - public float[] Position => new[] {StoredPosition.x, StoredPosition.y}; - - public float2 StoredPosition; - - public float x { get { return StoredPosition.x; } } - public float y { get { return StoredPosition.y; } } - - public Vertex2(float x, float y) - { - StoredPosition = float2(x, y); - } - - public Vertex2(float2 pos) - { - StoredPosition = pos; - } - - public float2 ToFloat2() { - return StoredPosition; - } - - public float Distance(Vertex2 v) - { - return length(StoredPosition-v.StoredPosition); - } -} diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2.cs.meta deleted file mode 100644 index a314ce4ec..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 67d3ec22ea52a2642a14ff864e3017b0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2Object.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2Object.cs deleted file mode 100644 index a266ddaec..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2Object.cs +++ /dev/null @@ -1,16 +0,0 @@ -using CultMath; - -public class Vertex2 : Vertex2 -{ - public T StoredObject { get; } - - public Vertex2(float x, float y, T obj) : base(x, y) - { - StoredObject = obj; - } - - public Vertex2(float2 pos, T obj) : base(pos) - { - StoredObject = obj; - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2Object.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2Object.cs.meta deleted file mode 100644 index 24639c89b..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex2Object.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e42612a273ec490380eaa67bed216a6d -timeCreated: 1615418804 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex3.cs b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex3.cs deleted file mode 100644 index a14aea5b1..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex3.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections; -using MIConvexHull; -using CultMath; -using static CultMath.math; - -public class Vertex3 : IVertex -{ - public float[] Position => new[] {StoredPosition.x, StoredPosition.y}; - - public float3 StoredPosition; - - public Vertex3(float x, float y, float z) - { - StoredPosition = float3(x, y, z); - } - - public Vertex3(float3 pos) - { - StoredPosition = pos; - } - - public float3 ToFloat3() { - return StoredPosition; - } - - public float Distance(Vertex3 v) - { - return length(StoredPosition-v.StoredPosition); - } -} diff --git a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex3.cs.meta b/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex3.cs.meta deleted file mode 100644 index fc1115c36..000000000 --- a/Assets/Scripts/ServerShared/NIH/MIConvexHull/Vertex3.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3553f231414f28347996a803a79425fa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/tests/Aetheria.Shared.Tests/RestoredHullsTests.cs b/tests/Aetheria.Shared.Tests/RestoredHullsTests.cs index 6a70f9a43..ed7756a5a 100644 --- a/tests/Aetheria.Shared.Tests/RestoredHullsTests.cs +++ b/tests/Aetheria.Shared.Tests/RestoredHullsTests.cs @@ -282,25 +282,14 @@ public sealed class RestoredHullsTests var background = TutorialBackgroundSettings(); var names = TutorialNameSettings(); var gameData = Path.Combine(FindRepoRoot(), "GameData", "Aetheria.cc"); - - // Galaxy zone-graph generation has a pre-existing, seed-dependent flakiness of its own (a disconnected - // zone graph throws inside the Galaxy constructor on roughly 1 seed in 15, confirmed unrelated to this - // cut: it reproduces identically against the pre-fix-batch catalog). That failure belongs to Galaxy.cs, - // not to ZoneGenerator's entrance-station override this test is pinning, so it is skipped rather than - // asserted on; every seed whose Galaxy actually builds must still get a docked entrance station. - var succeeded = 0; var sawGenuineLagrangeOrbit = false; for (uint seed = 1; seed <= 25; seed++) { var scratchRun = Path.Combine(Path.GetTempPath(), $"aetheria-entrance-station-{Guid.NewGuid():N}.cc"); try { - // Galaxy mutates Faction.InfluenceDistance in place; a fresh catalog open per seed keeps runs independent. using var cache = OpenReadOnlyRealCatalogWithScratchRun(gameData, scratchRun); - Galaxy galaxy; - try { galaxy = new Galaxy(tutorialSettings, background, names, cache, new PlayerSettings(), new DirectoryInfo(Path.GetTempPath()), _ => { }, null, seed); } - catch (Exception) { continue; } - succeeded++; + var galaxy = new Galaxy(tutorialSettings, background, names, cache, new PlayerSettings(), new DirectoryInfo(Path.GetTempPath()), _ => { }, null, seed); var items = new ItemManager(cache, new ProvenanceLedger(), Settings(), _ => { }); var pack = ZoneGenerator.GenerateZone(items, zoneSettings, galaxy, galaxy.Entrance, isTutorial: true); @@ -317,8 +306,6 @@ public sealed class RestoredHullsTests if (File.Exists(scratchRun)) File.Delete(scratchRun); } } - - Assert.True(succeeded >= 15, $"only {succeeded} of 25 seeds produced a Galaxy at all; too few runs to trust this result."); Assert.True(sawGenuineLagrangeOrbit, "none of the 25 seeds seated the entrance station on a genuine (non-rosette) Lagrange orbit."); } @@ -336,8 +323,6 @@ public sealed class RestoredHullsTests var background = TutorialBackgroundSettings(); var names = TutorialNameSettings(); var gameData = Path.Combine(FindRepoRoot(), "GameData", "Aetheria.cc"); - - var succeeded = 0; var sawGenuineCandidate = false; for (uint seed = 1; seed <= 25; seed++) { @@ -345,10 +330,7 @@ public sealed class RestoredHullsTests try { using var cache = OpenReadOnlyRealCatalogWithScratchRun(gameData, scratchRun); - Galaxy galaxy; - try { galaxy = new Galaxy(tutorialSettings, background, names, cache, new PlayerSettings(), new DirectoryInfo(Path.GetTempPath()), _ => { }, null, seed); } - catch (Exception) { continue; } - succeeded++; + var galaxy = new Galaxy(tutorialSettings, background, names, cache, new PlayerSettings(), new DirectoryInfo(Path.GetTempPath()), _ => { }, null, seed); var items = new ItemManager(cache, new ProvenanceLedger(), Settings(), _ => { }); var pack = ZoneGenerator.GenerateZone(items, zoneSettings, galaxy, galaxy.Entrance, isTutorial: true); @@ -369,8 +351,6 @@ public sealed class RestoredHullsTests if (File.Exists(scratchRun)) File.Delete(scratchRun); } } - - Assert.True(succeeded >= 15, $"only {succeeded} of 25 seeds produced a Galaxy at all; too few runs to trust this result."); Assert.True(sawGenuineCandidate, "none of the 25 seeds had a genuine Lagrange candidate at all; too few runs to trust this result."); } @@ -477,9 +457,7 @@ public sealed class RestoredHullsTests try { using var cache = OpenReadOnlyRealCatalogWithScratchRun(gameData, scratchRun); - Galaxy galaxy; - try { galaxy = new Galaxy(tutorialSettings, background, names, cache, new PlayerSettings(), new DirectoryInfo(Path.GetTempPath()), _ => { }, null, seed); } - catch (Exception) { continue; } + var galaxy = new Galaxy(tutorialSettings, background, names, cache, new PlayerSettings(), new DirectoryInfo(Path.GetTempPath()), _ => { }, null, seed); var items = new ItemManager(cache, new ProvenanceLedger(), Settings(), _ => { }); var pack = ZoneGenerator.GenerateZone(items, zoneSettings, galaxy, galaxy.Entrance, isTutorial: true); diff --git a/tests/Aetheria.Shared.Tests/ScenarioTests.cs b/tests/Aetheria.Shared.Tests/ScenarioTests.cs index cebf564d6..ac57abce9 100644 --- a/tests/Aetheria.Shared.Tests/ScenarioTests.cs +++ b/tests/Aetheria.Shared.Tests/ScenarioTests.cs @@ -171,6 +171,65 @@ public sealed partial class RunStartTests Assert.All(authored, pair => Assert.Equal(pair.Value, pair.Key.InfluenceDistance)); } + // Every zone is linked into one graph. These seeds left zones with no link at all (the vendored float-precision + // convex-hull triangulation dropped them), so the constructor threw KeyNotFoundException placing homes (prelude) + // or the entrance (main). Each galaxy's links are a subset of its zone positions' Delaunay edges, and the + // triangulation agrees with a brute-force empty-circumcircle oracle. + [Theory] + [InlineData(103u, true)] + [InlineData(134u, true)] + [InlineData(137u, true)] + [InlineData(173u, true)] + [InlineData(227u, true)] + [InlineData(285u, true)] + [InlineData(34u, false)] + public void EveryZoneIsLinked(uint seed, bool prelude) + { + var galaxy = RunStart.Generate(new Scripted(true, _ => { }, seed, stage => prelude ? stage.Prelude() : stage.Main()), Inputs()); + Assert.All(galaxy.Zones, zone => Assert.Equal(galaxy.Zones.Length, zone.Distance.Count)); + + var positions = galaxy.Zones.Select(zone => zone.Position).ToArray(); + var edges = Delaunay.Edges(positions); + Assert.Equal(BruteForceDelaunay(positions), edges); + var delaunay = new HashSet<(int, int)>(edges); + for (var i = 0; i < galaxy.Zones.Length; i++) + foreach (var adjacent in galaxy.Zones[i].AdjacentZones) + { + var j = Array.IndexOf(galaxy.Zones, adjacent); + Assert.Contains((Math.Min(i, j), Math.Max(i, j)), delaunay); + } + } + + // Every triangle whose circumcircle holds no other point, as sorted edges. + private static List<(int a, int b)> BruteForceDelaunay(float2[] points) + { + var edges = new SortedSet<(int a, int b)>(); + for (var i = 0; i < points.Length; i++) + for (var j = i + 1; j < points.Length; j++) + for (var k = j + 1; k < points.Length; k++) + { + double ax = points[i].x, ay = points[i].y, bx = points[j].x, by = points[j].y, cx = points[k].x, cy = points[k].y; + var d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)); + if (d == 0) continue; + double a2 = ax * ax + ay * ay, b2 = bx * bx + by * by, c2 = cx * cx + cy * cy; + var ux = (a2 * (by - cy) + b2 * (cy - ay) + c2 * (ay - by)) / d; + var uy = (a2 * (cx - bx) + b2 * (ax - cx) + c2 * (bx - ax)) / d; + var r2 = (ax - ux) * (ax - ux) + (ay - uy) * (ay - uy); + var empty = true; + for (var m = 0; m < points.Length && empty; m++) + if (m != i && m != j && m != k) + { + double dx = points[m].x - ux, dy = points[m].y - uy; + empty = dx * dx + dy * dy >= r2; + } + if (!empty) continue; + edges.Add((i, j)); + edges.Add((j, k)); + edges.Add((i, k)); + } + return edges.ToList(); + } + // A scenario naming one unknown design admits nothing, not even the parts that built, and names the design. [Fact] public void StagingIsAllOrNothing()