using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace UnityEngine.ProBuilder { // This should not be public until there is something meaningful that can be done with it. However it has been // public in the past, so we can't change it until the next major version increment. /// /// Manages object and element selection in the scene. /// [EditorBrowsable(EditorBrowsableState.Never)] public class SceneSelection : IEquatable { /// The Unity GameObject public GameObject gameObject; /// The ProBuilder mesh public ProBuilderMesh mesh; List m_Vertices; List m_Edges; List m_Faces; /// /// Gets or sets the list of vertex indices for the selected mesh. /// public List vertexes { get { return m_Vertices; } set { m_Vertices = value; } } /// /// Gets or sets the list of edges for the selected mesh. /// public List edges { get { return m_Edges; } set { m_Edges = value; } } /// /// Gets or sets the list of faces for the selected mesh. /// public List faces { get { return m_Faces; } set { m_Faces = value; } } /// Obsolete. Use `SetSingleVertex` instead. [Obsolete("Use SetSingleVertex")] public int vertex; /// Obsolete. Use `SetSingleEdge` instead. [Obsolete("Use SetSingleEdge")] public Edge edge; /// Obsolete. Use `SetSingleFace` instead. [Obsolete("Use SetSingleFace")] public Face face; /// /// Creates a SceneSelection object in the [Object editing mode](../manual/modes.html) from the /// specified GameObject. If the GameObject is not specified it creates an empty selection. /// /// The optional GameObject to set as the SceneSelection. public SceneSelection(GameObject gameObject = null) { this.gameObject = gameObject; m_Vertices = new List(); m_Edges = new List(); m_Faces = new List(); } /// /// Creates a SceneSelection object in the [Vertex editing mode](../manual/modes.html) from the specified mesh. /// /// The ProBuilderMesh containing the vertex to select. /// The index of the vertex to set as the SceneSelection. public SceneSelection(ProBuilderMesh mesh, int vertex) : this(mesh, new List() { vertex }) { } /// /// Creates a SceneSelection object in the [Edge editing mode](../manual/modes.html) from the specified mesh. /// /// The ProBuilderMesh containing the edge to select. /// The Edge to set as the SceneSelection. public SceneSelection(ProBuilderMesh mesh, Edge edge) : this(mesh, new List() { edge }) { } /// /// Creates a SceneSelection object in the [Face editing mode](../manual/modes.html) from the specified mesh. /// /// The ProBuilderMesh containing the face to select. /// The Face to set as the SceneSelection. public SceneSelection(ProBuilderMesh mesh, Face face) : this(mesh, new List() { face }) { } internal SceneSelection(ProBuilderMesh mesh, List vertexes) : this(mesh != null ? mesh.gameObject : null) { this.mesh = mesh; m_Vertices = vertexes; m_Edges = new List(); m_Faces = new List(); } internal SceneSelection(ProBuilderMesh mesh, List edges) : this(mesh != null ? mesh.gameObject : null) { this.mesh = mesh; vertexes = new List(); this.edges = edges; faces = new List(); } internal SceneSelection(ProBuilderMesh mesh, List faces) : this(mesh != null ? mesh.gameObject : null) { this.mesh = mesh; vertexes = new List(); edges = new List(); this.faces = faces; } /// /// Resets the selection to the specified face. /// /// The face to select public void SetSingleFace(Face face) { faces.Clear(); faces.Add(face); } /// /// Resets the selection to the specified vertex. /// /// The index of the vertex to select public void SetSingleVertex(int vertex) { vertexes.Clear(); vertexes.Add(vertex); } /// /// Resets the selection to the specified edge. /// /// The edge to select public void SetSingleEdge(Edge edge) { edges.Clear(); edges.Add(edge); } /// /// Empties the selection. /// public void Clear() { gameObject = null; mesh = null; faces.Clear(); edges.Clear(); vertexes.Clear(); } /// /// Copies the list of selected object(s) and element(s) to match this SceneSelection object. /// /// The SceneSelection object to copy this object to. public void CopyTo(SceneSelection dst) { dst.gameObject = gameObject; dst.mesh = mesh; dst.faces.Clear(); dst.edges.Clear(); dst.vertexes.Clear(); dst.faces.AddRange(faces); dst.edges.AddRange(edges); dst.vertexes.AddRange(vertexes); } /// /// Returns a string that represents this SceneSelection. /// /// A multi-line string containing the names of the GameObject and ProBuilderMesh objects, and a string representation of the lists of faces, edges, and vertex indices. public override string ToString() { var sb = new System.Text.StringBuilder(); sb.AppendLine("GameObject: " + (gameObject != null ? gameObject.name : null)); sb.AppendLine("ProBuilderMesh: " + (mesh != null ? mesh.name : null)); sb.AppendLine("Face: " + (faces != null ? faces.ToString() : null)); sb.AppendLine("Edge: " + edges.ToString()); sb.AppendLine("Vertex: " + vertexes); return sb.ToString(); } /// /// Evaluates whether the specified SceneSelection is equivalent to this one. /// /// The SceneSelection object to compare to this object. /// True if the objects are equivalent; false otherwise. public bool Equals(SceneSelection other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(gameObject, other.gameObject) && Equals(mesh, other.mesh) && Enumerable.SequenceEqual(vertexes, other.vertexes) && Enumerable.SequenceEqual(edges, other.edges) && Enumerable.SequenceEqual(faces, other.faces); } /// /// Evaluates whether the specified object is equivalent to this one. /// /// The object to compare to this object. /// True if the objects are equivalent; false otherwise. public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((SceneSelection)obj); } /// /// Returns the hash code for this object. /// /// A hash code for the current object. public override int GetHashCode() { unchecked { int hashCode = (gameObject != null ? gameObject.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (mesh != null ? mesh.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (vertexes != null ? vertexes.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (edges != null ? edges.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (faces != null ? faces.GetHashCode() : 0); return hashCode; } } /// /// Returns true if the two SceneSelection objects are equal. /// /// The first object to compare. /// The second object to compare. /// True if the objects are equal; false otherwise. public static bool operator==(SceneSelection left, SceneSelection right) { return Equals(left, right); } /// /// Returns true if the two SceneSelection objects are not equal. /// /// The first object to compare. /// The second object to compare. /// True if the objects are not equal; false otherwise. public static bool operator!=(SceneSelection left, SceneSelection right) { return !Equals(left, right); } } struct VertexPickerEntry { public ProBuilderMesh mesh; public int vertex; public float screenDistance; public Vector3 worldPosition; } }