public pb_Edge[] GetEdges() { pb_Edge[] edges = new pb_Edge[indices.Length]; for (int i = 0; i < indices.Length; i += 3) { edges[i + 0] = new pb_Edge(indices[i + 0], indices[i + 1]); edges[i + 1] = new pb_Edge(indices[i + 1], indices[i + 2]); edges[i + 2] = new pb_Edge(indices[i + 2], indices[i + 0]); } return(edges); }
/** * Slow IndexOf - takes sharedIndices into account when searching the List. */ // public static int IndexOf(this IList<pb_Edge> edges, pb_Edge edge, pb_IntArray[] sharedIndices) // { // for(int i = 0; i < edges.Count; i++) // { // if(edges[i].Equals(edge, sharedIndices)) // return i; // } // return -1; // } public static int IndexOf(this IList <pb_Edge> edges, pb_Edge edge, Dictionary <int, int> lookup) { for (int i = 0; i < edges.Count; i++) { if (edges[i].Equals(edge, lookup)) { return(i); } } return(-1); }
/** * Fast contains - doens't account for shared indices */ public static bool Contains(this pb_Edge[] edges, pb_Edge edge) { for (int i = 0; i < edges.Length; i++) { if (edges[i].Equals(edge)) { return(true); } } return(false); }
public static int IndexOf(this pb_Edge[] edges, pb_Edge edge, pb_IntArray[] sharedIndices) { for (int i = 0; i < edges.Length; i++) { if (edges[i].Equals(edge, sharedIndices)) { return(i); } } return(-1); }
/** * Slow IndexOf - takes sharedIndices into account when searching the List. */ public static int IndexOf(this List <pb_Edge> edges, pb_Edge edge, pb_IntArray[] sharedIndices) { for (int i = 0; i < edges.Count; i++) { if (edges[i].Equals(edge, sharedIndices)) { return(i); } } return(-1); }
/** * Checks for duplicates taking sharedIndices into account */ public static bool ContainsDuplicate(this List <pb_Edge> edges, pb_Edge edge, Dictionary <int, int> lookup)// pb_IntArray[] sharedIndices) { int c = 0; for (int i = 0; i < edges.Count; i++) { if (edges[i].Equals(edge, lookup)) { if (++c > 1) { return(true); } } } return(false); }
/** * Checks if mouse is over an edge, and if so, returns true setting @edge. */ public static bool EdgeRaycast(Camera cam, Vector2 mousePosition, pb_Object mesh, pb_Edge[] edges, Vector3[] verticesInWorldSpace, out pb_Edge edge) { Vector3 v0, v1; float bestDistance = Mathf.Infinity; float distance = 0f; edge = null; GameObject go = ObjectRaycast(cam, mousePosition, (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject))); if (go == null || go != mesh.gameObject) { int width = Screen.width; int height = Screen.height; for (int i = 0; i < edges.Length; i++) { v0 = verticesInWorldSpace[edges[i].x]; v1 = verticesInWorldSpace[edges[i].y]; distance = pb_HandleUtility.DistancePoint2DToLine(cam, mousePosition, v0, v1); if (distance < bestDistance && distance < MAX_EDGE_SELECT_DISTANCE) // && !PointIsOccluded(mesh, (v0+v1)*.5f) ) { Vector3 vs0 = cam.WorldToScreenPoint(v0); // really simple frustum check (will fail on edges that have vertices outside the frustum but is visible) if (vs0.z <= 0 || vs0.x < 0 || vs0.y < 0 || vs0.x > width || vs0.y > height) { continue; } Vector3 vs1 = cam.WorldToScreenPoint(v1); if (vs1.z <= 0 || vs1.x < 0 || vs1.y < 0 || vs1.x > width || vs1.y > height) { continue; } bestDistance = distance; edge = edges[i]; } } } else { // Test culling List <pb_RaycastHit> hits; Ray ray = cam.ScreenPointToRay(mousePosition); // HandleUtility.GUIPointToWorldRay(mousePosition); if (FaceRaycast(ray, mesh, out hits, Mathf.Infinity, Culling.FrontBack)) { // Sort from nearest hit to farthest hits.Sort((x, y) => x.Distance.CompareTo(y.Distance)); // Find the nearest edge in the hit faces Vector3[] v = mesh.vertices; for (int i = 0; i < hits.Count; i++) { if (pb_HandleUtility.PointIsOccluded(cam, mesh, mesh.transform.TransformPoint(hits[i].Point))) { continue; } foreach (pb_Edge e in mesh.faces[hits[i].FaceIndex].GetEdges()) { float d = pb_Math.DistancePointLineSegment(hits[i].Point, v[e.x], v[e.y]); if (d < bestDistance) { bestDistance = d; edge = e; } } if (Vector3.Dot(ray.direction, mesh.transform.TransformDirection(hits[i].Normal)) < 0f) { break; } } if (edge != null && pb_HandleUtility.DistancePoint2DToLine(cam, mousePosition, mesh.transform.TransformPoint(v[edge.x]), mesh.transform.TransformPoint(v[edge.y])) > MAX_EDGE_SELECT_DISTANCE) { edge = null; } // else // { // edge.x = mesh.ToUserIndex(edge.x); // edge.y = mesh.ToUserIndex(edge.y); // } } } return(edge != null); }