예제 #1
0
 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);
 }
예제 #2
0
        /**
         * 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);
        }
예제 #3
0
        /**
         *	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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        /**
         * 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);
        }
예제 #6
0
        /**
         *	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);
        }
예제 #7
0
        /**
         * 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);
        }