using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ProceduralToolkit.Skeleton { /// /// Representation of the active plan during generation process /// public class Plan : IEnumerable { public int Count => vertices.Count; public Vertex First => vertices[0]; private readonly List vertices = new List(); private Plan() { } public Plan(IEnumerable polygon) { foreach (var vertex in polygon) { vertices.Add(new Vertex(vertex)); } for (int i = 0; i < Count; i++) { var vertex = vertices[i]; vertex.previous = vertices.GetLooped(i - 1); vertex.next = vertices.GetLooped(i + 1); } } private void Add(Vertex vertex) { vertices.Add(vertex); } public void Insert(Vertex vertex, Vertex previous, Vertex next) { vertices.Add(vertex); LinkVertices(previous, vertex, next); } public bool Remove(Vertex vertex) { return vertices.Remove(vertex); } public void Offset(float offset) { foreach (var vertex in vertices) { vertex.position -= vertex.bisector*Geometry.GetAngleOffset(offset, vertex.angle); } } public List Split() { var plans = new List(); while (Count > 0) { int i = 0; int max = Count; var plan = new Plan(); var startVertex = First; var currentVertex = startVertex; do { if (i >= max) { Debug.LogError("Invalid connectivity"); break; } Remove(currentVertex); plan.Add(currentVertex); currentVertex = currentVertex.next; i++; } while (!currentVertex.Equals(startVertex)); plans.Add(plan); } return plans; } public IEnumerator GetEnumerator() { if (Count == 0) { yield break; } var startVertex = vertices[0]; var currentVertex = startVertex; int i = 0; int max = Count; do { if (i >= max) { Debug.LogError("Invalid connectivity"); yield break; } yield return currentVertex; currentVertex = currentVertex.next; i++; } while (!currentVertex.Equals(startVertex)); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static void LinkVertices(Vertex a, Vertex b) { a.next = b; b.previous = a; } private static void LinkVertices(Vertex a, Vertex b, Vertex c) { LinkVertices(a, b); LinkVertices(b, c); } public class Vertex { public Vector2 position; public float angle; public Vector2 bisector; public Vertex previous; public Vertex next; public bool inEvent; public int previousPolygonIndex; public int nextPolygonIndex; public bool reflect => angle >= 180; public Vertex(Vector2 position) { this.position = position; } public override string ToString() { return string.Format("{0} inEvent: {1}", position, inEvent); } } } }