Esempio n. 1
0
        /**
         * Get an array of qe_Edge from this mesh (three per-triangle).
         */
        public qe_Edge[] GetEdges()
        {
            int[] tris = cloneMesh.triangles;

            qe_Edge[] edges = new qe_Edge[tris.Length];

            for (int i = 0; i < tris.Length; i += 3)
            {
                edges[i + 0] = new qe_Edge(tris[i + 0], tris[i + 1]);
                edges[i + 1] = new qe_Edge(tris[i + 1], tris[i + 2]);
                edges[i + 2] = new qe_Edge(tris[i + 2], tris[i + 0]);
            }

            return(edges);
        }
Esempio n. 2
0
        /**
         * Checks if mouse is over an edge, and if so, returns true setting @edge.
         */
        public static bool EdgeRaycast(Vector2 mousePosition, ElementCache selection, out qe_Edge edge)
        {
            qe_Mesh mesh = selection.mesh;

            Vector3 v0, v1;
            float   bestDistance = Mathf.Infinity;
            float   distance     = 0f;

            edge = null;

            GameObject go = HandleUtility.PickGameObject(mousePosition, false);

            if (go == null || go != selection.transform.gameObject)
            {
                qe_Edge[] edges = mesh.userEdges;

                int width  = Screen.width;
                int height = Screen.height;

                for (int i = 0; i < edges.Length; i++)
                {
                    v0 = selection.verticesInWorldSpace[edges[i].x];
                    v1 = selection.verticesInWorldSpace[edges[i].y];

                    distance = HandleUtility.DistanceToLine(v0, v1);

                    if (distance < bestDistance && distance < MAX_EDGE_SELECT_DISTANCE)                      // && !PointIsOccluded(mesh, (v0+v1)*.5f) )
                    {
                        Vector3 vs0 = SceneView.lastActiveSceneView.camera.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 = SceneView.lastActiveSceneView.camera.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 <qe_RaycastHit> hits;
                Ray ray = HandleUtility.GUIPointToWorldRay(mousePosition);

                if (MeshRaycast(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 (PointIsOccluded(mesh, mesh.transform.TransformPoint(hits[i].Point)))
                        {
                            continue;
                        }

                        foreach (qe_Edge e in mesh.faces[hits[i].FaceIndex].GetEdges())
                        {
                            float d = HandleUtility.DistancePointLine(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 && HandleUtility.DistanceToLine(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);
        }