mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Initial commit
This commit is contained in:
commit
3c7cc0c973
8391 changed files with 704313 additions and 0 deletions
|
@ -0,0 +1,270 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="DcelMesh.cs">
|
||||
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace UnityEngine.U2D.Animation.TriangleNet
|
||||
.Topology.DCEL
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Animation.TriangleNet.Geometry;
|
||||
|
||||
internal class DcelMesh
|
||||
{
|
||||
protected List<Vertex> vertices;
|
||||
protected List<HalfEdge> edges;
|
||||
protected List<Face> faces;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DcelMesh" /> class.
|
||||
/// </summary>
|
||||
public DcelMesh()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="" /> class.
|
||||
/// </summary>
|
||||
/// <param name="initialize">If false, lists will not be initialized.</param>
|
||||
protected DcelMesh(bool initialize)
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
vertices = new List<Vertex>();
|
||||
edges = new List<HalfEdge>();
|
||||
faces = new List<Face>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertices of the Voronoi diagram.
|
||||
/// </summary>
|
||||
public List<Vertex> Vertices
|
||||
{
|
||||
get { return vertices; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of half-edges specify the Voronoi diagram topology.
|
||||
/// </summary>
|
||||
public List<HalfEdge> HalfEdges
|
||||
{
|
||||
get { return edges; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the faces of the Voronoi diagram.
|
||||
/// </summary>
|
||||
public List<Face> Faces
|
||||
{
|
||||
get { return faces; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of edges of the Voronoi diagram.
|
||||
/// </summary>
|
||||
public IEnumerable<IEdge> Edges
|
||||
{
|
||||
get { return EnumerateEdges(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the DCEL is consistend.
|
||||
/// </summary>
|
||||
/// <param name="closed">If true, faces are assumed to be closed (i.e. all edges must have
|
||||
/// a valid next pointer).</param>
|
||||
/// <param name="depth">Maximum edge count of faces (default = 0 means skip check).</param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsConsistent(bool closed = true, int depth = 0)
|
||||
{
|
||||
// Check vertices for null pointers.
|
||||
foreach (var vertex in vertices)
|
||||
{
|
||||
if (vertex.id < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vertex.leaving == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vertex.Leaving.Origin.id != vertex.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check faces for null pointers.
|
||||
foreach (var face in faces)
|
||||
{
|
||||
if (face.ID < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (face.edge == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (face.id != face.edge.face.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check half-edges for null pointers.
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
if (edge.id < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (edge.twin == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (edge.origin == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (edge.face == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (closed && edge.next == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check half-edges (topology).
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
if (edge.id < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var twin = edge.twin;
|
||||
var next = edge.next;
|
||||
|
||||
if (edge.id != twin.twin.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (closed)
|
||||
{
|
||||
if (next.origin.id != twin.origin.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (next.twin.next.origin.id != edge.twin.origin.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closed && depth > 0)
|
||||
{
|
||||
// Check if faces are closed.
|
||||
foreach (var face in faces)
|
||||
{
|
||||
if (face.id < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var edge = face.edge;
|
||||
var next = edge.next;
|
||||
|
||||
int id = edge.id;
|
||||
int k = 0;
|
||||
|
||||
while (next.id != id && k < depth)
|
||||
{
|
||||
next = next.next;
|
||||
k++;
|
||||
}
|
||||
|
||||
if (next.id != id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search for half-edge without twin and add a twin. Connect twins to form connected
|
||||
/// boundary contours.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method assumes that all faces are closed (i.e. no edge.next pointers are null).
|
||||
/// </remarks>
|
||||
public void ResolveBoundaryEdges()
|
||||
{
|
||||
// Maps vertices to leaving boundary edge.
|
||||
var map = new Dictionary<int, HalfEdge>();
|
||||
|
||||
// TODO: parallel?
|
||||
foreach (var edge in this.edges)
|
||||
{
|
||||
if (edge.twin == null)
|
||||
{
|
||||
var twin = edge.twin = new HalfEdge(edge.next.origin, Face.Empty);
|
||||
twin.twin = edge;
|
||||
|
||||
map.Add(twin.origin.id, twin);
|
||||
}
|
||||
}
|
||||
|
||||
int j = edges.Count;
|
||||
|
||||
foreach (var edge in map.Values)
|
||||
{
|
||||
edge.id = j++;
|
||||
edge.next = map[edge.twin.origin.id];
|
||||
|
||||
this.edges.Add(edge);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all edges of the DCEL.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method assumes that each half-edge has a twin (i.e. NOT null).
|
||||
/// </remarks>
|
||||
protected virtual IEnumerable<IEdge> EnumerateEdges()
|
||||
{
|
||||
var edges = new List<IEdge>(this.edges.Count / 2);
|
||||
|
||||
foreach (var edge in this.edges)
|
||||
{
|
||||
var twin = edge.twin;
|
||||
|
||||
// Report edge only once.
|
||||
if (edge.id < twin.id)
|
||||
{
|
||||
edges.Add(new Edge(edge.origin.id, twin.origin.id));
|
||||
}
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7c725737cdc184d969ef5d53b813d1b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,114 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="Face.cs">
|
||||
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace UnityEngine.U2D.Animation.TriangleNet
|
||||
.Topology.DCEL
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Animation.TriangleNet.Geometry;
|
||||
|
||||
/// <summary>
|
||||
/// A face of DCEL mesh.
|
||||
/// </summary>
|
||||
internal class Face
|
||||
{
|
||||
#region Static initialization of "Outer Space" face
|
||||
|
||||
internal static readonly Face Empty;
|
||||
|
||||
static Face()
|
||||
{
|
||||
Empty = new Face(null);
|
||||
Empty.id = -1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal int id;
|
||||
internal int mark = 0;
|
||||
|
||||
internal Point generator;
|
||||
|
||||
internal HalfEdge edge;
|
||||
internal bool bounded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the face id.
|
||||
/// </summary>
|
||||
public int ID
|
||||
{
|
||||
get { return id; }
|
||||
set { id = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a half-edge connected to the face.
|
||||
/// </summary>
|
||||
public HalfEdge Edge
|
||||
{
|
||||
get { return edge; }
|
||||
set { edge = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value, indicating if the face is bounded (for Voronoi diagram).
|
||||
/// </summary>
|
||||
public bool Bounded
|
||||
{
|
||||
get { return bounded; }
|
||||
set { bounded = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Face" /> class.
|
||||
/// </summary>
|
||||
/// <param name="generator">The generator of this face (for Voronoi diagram)</param>
|
||||
public Face(Point generator)
|
||||
: this(generator, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Face" /> class.
|
||||
/// </summary>
|
||||
/// <param name="generator">The generator of this face (for Voronoi diagram)</param>
|
||||
/// <param name="edge">The half-edge connected to this face.</param>
|
||||
public Face(Point generator, HalfEdge edge)
|
||||
{
|
||||
this.generator = generator;
|
||||
this.edge = edge;
|
||||
this.bounded = true;
|
||||
|
||||
if (generator != null)
|
||||
{
|
||||
this.id = generator.ID;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all half-edges of the face boundary.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<HalfEdge> EnumerateEdges()
|
||||
{
|
||||
var edge = this.Edge;
|
||||
int first = edge.ID;
|
||||
|
||||
do
|
||||
{
|
||||
yield return edge;
|
||||
|
||||
edge = edge.Next;
|
||||
}
|
||||
while (edge.ID != first);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("F-ID {0}", id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 448d8fb02c0a5495ea149174a75f80c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,102 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="HalfEdge.cs">
|
||||
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace UnityEngine.U2D.Animation.TriangleNet
|
||||
.Topology.DCEL
|
||||
{
|
||||
internal class HalfEdge
|
||||
{
|
||||
internal int id;
|
||||
internal int mark;
|
||||
|
||||
internal Vertex origin;
|
||||
internal Face face;
|
||||
internal HalfEdge twin;
|
||||
internal HalfEdge next;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the half-edge id.
|
||||
/// </summary>
|
||||
public int ID
|
||||
{
|
||||
get { return id; }
|
||||
set { id = value; }
|
||||
}
|
||||
|
||||
public int Boundary
|
||||
{
|
||||
get { return mark; }
|
||||
set { mark = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the origin of the half-edge.
|
||||
/// </summary>
|
||||
public Vertex Origin
|
||||
{
|
||||
get { return origin; }
|
||||
set { origin = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the face connected to the half-edge.
|
||||
/// </summary>
|
||||
public Face Face
|
||||
{
|
||||
get { return face; }
|
||||
set { face = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the twin of the half-edge.
|
||||
/// </summary>
|
||||
public HalfEdge Twin
|
||||
{
|
||||
get { return twin; }
|
||||
set { twin = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next pointer of the half-edge.
|
||||
/// </summary>
|
||||
public HalfEdge Next
|
||||
{
|
||||
get { return next; }
|
||||
set { next = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HalfEdge" /> class.
|
||||
/// </summary>
|
||||
/// <param name="origin">The origin of this half-edge.</param>
|
||||
public HalfEdge(Vertex origin)
|
||||
{
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HalfEdge" /> class.
|
||||
/// </summary>
|
||||
/// <param name="origin">The origin of this half-edge.</param>
|
||||
/// <param name="face">The face connected to this half-edge.</param>
|
||||
public HalfEdge(Vertex origin, Face face)
|
||||
{
|
||||
this.origin = origin;
|
||||
this.face = face;
|
||||
|
||||
// IMPORTANT: do not remove the (face.edge == null) check!
|
||||
if (face != null && face.edge == null)
|
||||
{
|
||||
face.edge = this;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("HE-ID {0} (Origin = VID-{1})", id, origin.id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 456daa24c602c419ba5653d9dac96c28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,70 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="Vertex.cs">
|
||||
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace UnityEngine.U2D.Animation.TriangleNet
|
||||
.Topology.DCEL
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class Vertex : Animation.TriangleNet.Geometry.Point
|
||||
{
|
||||
internal HalfEdge leaving;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a half-edge leaving the vertex.
|
||||
/// </summary>
|
||||
public HalfEdge Leaving
|
||||
{
|
||||
get { return leaving; }
|
||||
set { leaving = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Vertex" /> class.
|
||||
/// </summary>
|
||||
/// <param name="x">The x coordinate.</param>
|
||||
/// <param name="y">The y coordinate.</param>
|
||||
public Vertex(double x, double y)
|
||||
: base(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Vertex" /> class.
|
||||
/// </summary>
|
||||
/// <param name="x">The x coordinate.</param>
|
||||
/// <param name="y">The y coordinate.</param>
|
||||
/// <param name="leaving">A half-edge leaving this vertex.</param>
|
||||
public Vertex(double x, double y, HalfEdge leaving)
|
||||
: base(x, y)
|
||||
{
|
||||
this.leaving = leaving;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all half-edges leaving this vertex.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<HalfEdge> EnumerateEdges()
|
||||
{
|
||||
var edge = this.Leaving;
|
||||
int first = edge.ID;
|
||||
|
||||
do
|
||||
{
|
||||
yield return edge;
|
||||
|
||||
edge = edge.Twin.Next;
|
||||
}
|
||||
while (edge.ID != first);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("V-ID {0}", base.id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 87a0e38ad31404f7285fa9bf6fa08eaa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue