using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace UnityEngine.ProBuilder
{
///
/// An edge connecting two vertices. May point to an index in the vertices or the sharedIndexes array (local / common in ProBuilder terminology).
///
[System.Serializable]
public struct Edge : System.IEquatable
{
///
/// An index corresponding to a mesh vertex array.
///
public int a;
///
/// An index corresponding to a mesh vertex array.
///
public int b;
///
/// An empty edge is defined as -1, -1.
///
public static readonly Edge Empty = new Edge(-1, -1);
///
/// Create a new edge from two vertex indexes.
///
/// An index corresponding to a mesh vertex array.
/// An index corresponding to a mesh vertex array.
public Edge(int a, int b)
{
this.a = a;
this.b = b;
}
///
/// Test if this edge points to valid vertex indexes.
///
/// True if x and y are both greater than -1.
public bool IsValid()
{
return a > -1 && b > -1 && a != b;
}
public override string ToString()
{
return "[" + a + ", " + b + "]";
}
public bool Equals(Edge other)
{
return (a == other.a && b == other.b) || (a == other.b && b == other.a);
}
public override bool Equals(object obj)
{
return obj is Edge && Equals((Edge)obj);
}
public override int GetHashCode()
{
// http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode/263416#263416
int hash = 27;
unchecked
{
hash = hash * 29 + (a < b ? a : b);
hash = hash * 29 + (a < b ? b : a);
}
return hash;
}
public static Edge operator+(Edge a, Edge b)
{
return new Edge(a.a + b.a, a.b + b.b);
}
public static Edge operator-(Edge a, Edge b)
{
return new Edge(a.a - b.a, a.b - b.b);
}
public static Edge operator+(Edge a, int b)
{
return new Edge(a.a + b, a.b + b);
}
public static Edge operator-(Edge a, int b)
{
return new Edge(a.a - b, a.b - b);
}
public static bool operator==(Edge a, Edge b)
{
return a.Equals(b);
}
public static bool operator!=(Edge a, Edge b)
{
return !(a == b);
}
///
/// Add two edges index values.
///
///
/// {0, 1} + {4, 5} = {5, 6}
///
/// Left edge parameter.
/// Right edge parameter.
/// The sum of a + b.
public static Edge Add(Edge a, Edge b)
{
return a + b;
}
///
/// Subtract edge b from a.
///
///
/// Subtract( {7, 10}, {4, 5} ) = {3, 5}
///
/// The edge to subtract from.
/// The value to subtract.
/// The sum of a - b.
public static Edge Subtract(Edge a, Edge b)
{
return a - b;
}
///
/// Compares edges and takes shared triangles into account.
///
/// The edge to compare against.
/// A common vertex indexes lookup dictionary. See pb_IntArray for more information.
/// Generally you just pass ProBuilderMesh.sharedIndexes.ToDictionary() to lookup, but it's more efficient to do it once and reuse that dictionary if possible.
/// True if edges are perceptually equal (that is, they point to the same common indexes).
public bool Equals(Edge other, Dictionary lookup)
{
if (lookup == null)
return Equals(other);
int x0 = lookup[a], y0 = lookup[b], x1 = lookup[other.a], y1 = lookup[other.b];
return (x0 == x1 && y0 == y1) || (x0 == y1 && y0 == x1);
}
///
/// Does this edge contain an index?
///
/// The index to compare against x and y.
/// True if x or y is equal to a. False if not.
public bool Contains(int index)
{
return (a == index || b == index);
}
///
/// Does this edge have any matching index to edge b?
///
/// The edge to compare against.
/// True if x or y matches either b.x or b.y.
public bool Contains(Edge other)
{
return (a == other.a || b == other.a || a == other.b || b == other.a);
}
internal bool Contains(int index, Dictionary lookup)
{
var common = lookup[index];
return lookup[a] == common || lookup[b] == common;
}
internal static void GetIndices(IEnumerable edges, List indices)
{
indices.Clear();
foreach (var edge in edges)
{
indices.Add(edge.a);
indices.Add(edge.b);
}
}
}
}