public static Polygon PolygonFromClipperPaths(Paths paths, float scale)
        {
            Polygon polygon = null;

            for (int index = 0; index < paths.Count; index++)
            {
                Path    eachPath    = paths[index];
                Polygon eachPolygon = PolygonFromClipperPath(eachPath, scale);

                if (index == 0)
                {
                    polygon = Polygon.PolygonWithPoints(eachPolygon.points);
                }                                                                            // Parent polygon
                else
                {
                    polygon.AddPolygon(eachPolygon);
                }                                                    // Child polygons
            }
            return(polygon);
        }
예제 #2
0
        private void onMouseDown(object sender, MouseButtonEventArgs e)
        {
            //for (int i = 0; i < map.LayerCount; i++)
            //{
            //    map.GetLayer(i).ClearSelection();
            //}
            //Refresh();
            switch (mapMode)
            {
            case Mode.Edit:
                break;

            case Mode.Pan:
                preMouseLocation = e.GetPosition(this);
                break;

            case Mode.ZoomIn:
                ZoomByCenter(e.GetPosition(this), 1.25);
                Refresh();
                break;

            case Mode.ZoomOut:
                ZoomByCenter(e.GetPosition(this), 1 / 1.25);
                Refresh();
                break;

            case Mode.None:
                break;

            case Mode.Select:
                for (int i = 0; i < map.LayerCount; i++)
                {
                    map.GetLayer(i).ClearSelection();
                }
                Refresh();
                preMouseLocation = e.GetPosition(this);
                break;

            case Mode.EditAdd:

                Point curLocation = e.GetPosition(this);
                //Double click to end the input process
                if (e.ClickCount == 2)
                {
                    switch (curLayer.Type)
                    {
                    case LayerType.Point:
                        break;

                    case LayerType.Line:
                        if (tempLine != null)
                        {
                            tempLine.AddLine(tempPart);
                            curLayer.Add(tempLine);
                            tempPart = null;
                            tempLine = null;
                            trackingLine.Clear();
                            Refresh();
                        }
                        break;

                    case LayerType.Polygon:
                        if (tempPolygon != null)
                        {
                            tempPolygon.AddPolygon(tempPart);
                            curLayer.Add(tempPolygon);
                            tempPart    = null;
                            tempPolygon = null;
                            trackingLine.Clear();
                            Refresh();
                        }
                        break;

                    case LayerType.Text:
                        break;

                    default:
                        break;
                    }
                }
                else if (e.ClickCount == 1)
                {
                    trackingPoint = curLocation;
                    switch (curLayer.Type)
                    {
                    case LayerType.Point:
                        curLayer.Add(ToMapPoint(curLocation));
                        Refresh();
                        break;

                    case LayerType.Line:
                        if (tempLine == null)
                        {
                            tempLine = new Line(0);
                            tempPart = new PList(0);
                            tempPart.AddPoint(ToMapPoint(curLocation));
                            trackingLine.Add(new List <Point>());
                            trackingLine.Last().Add(curLocation);
                        }
                        else
                        {
                            if (tempPart == null)
                            {
                                tempPart = new PList(0);
                                tempPart.AddPoint(ToMapPoint(curLocation));
                                trackingLine.Add(new List <Point>());
                                trackingLine.Last().Add(curLocation);
                            }
                            else
                            {
                                tempPart.AddPoint(ToMapPoint(curLocation));
                                trackingLine.Last().Add(curLocation);
                            }
                        }
                        Refresh();
                        break;

                    case LayerType.Polygon:
                        if (tempPolygon == null)
                        {
                            tempPolygon = new Polygon(0);
                            tempPart    = new PList(0);
                            tempPart.AddPoint(ToMapPoint(curLocation));
                            trackingLine.Add(new List <Point>());
                            trackingLine.Last().Add(curLocation);
                        }
                        else
                        {
                            if (tempPart == null)
                            {
                                tempPart = new PList(0);
                                tempPart.AddPoint(ToMapPoint(curLocation));
                                trackingLine.Add(new List <Point>());
                                trackingLine.Last().Add(curLocation);
                            }
                            else
                            {
                                tempPart.AddPoint(ToMapPoint(curLocation));
                                trackingLine.Last().Add(curLocation);
                            }
                        }
                        Refresh();
                        break;

                    case LayerType.Text:
                        break;

                    default:
                        break;
                    }
                }
                break;

            default:
                break;
            }
        }
    public void ComputeNavmesh()
    {
        if (!meshFilter)
        {
            return;
        }

        GameObject[] obstacles = GameObject.FindGameObjectsWithTag("NavMeshObstacle");

        Mesh      mesh   = meshFilter.mesh;
        Matrix4x4 matrix = meshFilter.transform.localToWorldMatrix;

        ClearNavmesh();

        Debug.Log("Begin");

        float cosSlope = Mathf.Cos(slopeAngle * Mathf.Deg2Rad);

        for (int i = 0; i < mesh.triangles.Length; i += 3)
        {
            int idxTri0 = mesh.triangles[i];
            int idxTri1 = mesh.triangles[i + 1];
            int idxTri2 = mesh.triangles[i + 2];

            Vertex v0 = new Vertex(idxTri0, matrix.MultiplyPoint3x4(mesh.vertices[idxTri0]), matrix.MultiplyVector(mesh.normals[idxTri0]));
            Vertex v1 = new Vertex(idxTri1, matrix.MultiplyPoint3x4(mesh.vertices[idxTri1]), matrix.MultiplyVector(mesh.normals[idxTri1]));
            Vertex v2 = new Vertex(idxTri2, matrix.MultiplyPoint3x4(mesh.vertices[idxTri2]), matrix.MultiplyVector(mesh.normals[idxTri2]));

            //Merge vertices that are too close
            foreach (KeyValuePair <int, Vertex> vertexPair in uniqueVertices)
            {
                if (Vector3.Distance(v0.position, vertexPair.Value.position) <= 0.25f)
                {
                    idxTri0 = vertexPair.Key;
                    v0      = vertexPair.Value;
                }
                else if (Vector3.Distance(v1.position, vertexPair.Value.position) <= 0.25f)
                {
                    idxTri1 = vertexPair.Key;
                    v1      = vertexPair.Value;
                }
                else if (Vector3.Distance(v2.position, vertexPair.Value.position) <= 0.25f)
                {
                    idxTri2 = vertexPair.Key;
                    v2      = vertexPair.Value;
                }
            }

            v0.position += v0.normal.normalized * meshHeight;
            v1.position += v1.normal.normalized * meshHeight;
            v2.position += v2.normal.normalized * meshHeight;

            Triangle triangle = new Triangle(v0, v1, v2);
            if (Vector3.Dot(Vector3.up, triangle.normal) >= cosSlope)
            {
                allTriangles.Add(new Triangle(v0, v1, v2));

                if (!uniqueVertices.ContainsKey(idxTri0))
                {
                    uniqueVertices.Add(idxTri0, v0);
                }
                if (!uniqueVertices.ContainsKey(idxTri1))
                {
                    uniqueVertices.Add(idxTri1, v1);
                }
                if (!uniqueVertices.ContainsKey(idxTri2))
                {
                    uniqueVertices.Add(idxTri2, v2);
                }

                if (!uniqueVertices[idxTri0].neighbours.ContainsKey(idxTri1))
                {
                    uniqueVertices[idxTri0].neighbours.Add(idxTri1, v1);
                }
                if (!uniqueVertices[idxTri0].neighbours.ContainsKey(idxTri2))
                {
                    uniqueVertices[idxTri0].neighbours.Add(idxTri2, v2);
                }
                if (!uniqueVertices[idxTri1].neighbours.ContainsKey(idxTri0))
                {
                    uniqueVertices[idxTri1].neighbours.Add(idxTri0, v0);
                }
                if (!uniqueVertices[idxTri1].neighbours.ContainsKey(idxTri2))
                {
                    uniqueVertices[idxTri1].neighbours.Add(idxTri2, v2);
                }
                if (!uniqueVertices[idxTri2].neighbours.ContainsKey(idxTri1))
                {
                    uniqueVertices[idxTri2].neighbours.Add(idxTri1, v1);
                }
                if (!uniqueVertices[idxTri2].neighbours.ContainsKey(idxTri0))
                {
                    uniqueVertices[idxTri2].neighbours.Add(idxTri0, v0);
                }
            }
        }

        Debug.Log("Identify Key Points");

        List <int> keyIds = new List <int>();

        foreach (KeyValuePair <int, Vertex> pair in uniqueVertices)
        {
            Vertex     vertex    = pair.Value;
            List <int> invalidId = new List <int>();
            foreach (KeyValuePair <int, Vertex> neighbourPair in vertex.neighbours)
            {
                Vertex     neighbour = neighbourPair.Value;
                Ray        ray       = new Ray(vertex.position, (neighbour.position - vertex.position).normalized);
                float      dist      = (neighbour.position - vertex.position).magnitude;
                RaycastHit hitInfo;
                foreach (GameObject obstacle in obstacles)
                {
                    Collider collider = obstacle.GetComponent <Collider>();
                    if (!collider)
                    {
                        continue;
                    }

                    if (collider.ClosestPoint(neighbour.position) == neighbour.position)
                    {
                        invalidId.Add(neighbour.id);
                        keyIds.Add(pair.Key);
                    }
                    else if (collider.Raycast(ray, out hitInfo, dist))
                    {
                        invalidId.Add(neighbour.id);
                        keyIds.Add(pair.Key);
                        keyIds.Add(neighbourPair.Key);
                    }
                }
            }
            foreach (int id in invalidId)
            {
                vertex.neighbours.Remove(id);
            }
        }

        foreach (int id in keyIds)
        {
            Vertex vert = uniqueVertices[id];
            vert.isKey         = true;
            uniqueVertices[id] = vert;
        }

        Debug.Log("Group Vertices");
        for (int i = 0; i < allTriangles.Count; ++i)
        {
            Triangle triangle = allTriangles[i];
            Polygon  polygon  = new Polygon(triangle);
            for (int j = allTriangles.Count - 1; j > i; --j)
            {
                Triangle neighbour = allTriangles[j];
                if (Vector3.Dot(polygon.normal, neighbour.normal) == 1.0f)
                {
                    if (polygon.IsConnected(neighbour))
                    {
                        polygon.AddTriangle(neighbour);
                        allTriangles.RemoveAt(j);
                    }
                }
            }
            allPolygons.Add(polygon);
        }

        Debug.Log("Group Polygons");
        bool change = false;

        do
        {
            change = false;
            for (int i = 0; i < allPolygons.Count; ++i)
            {
                Polygon polygon = allPolygons[i];
                for (int j = allPolygons.Count - 1; j > i; --j)
                {
                    Polygon neighbour = allPolygons[j];
                    if (Vector3.Dot(polygon.normal, neighbour.normal) == 1.0f)
                    {
                        if (polygon.IsConnected(neighbour))
                        {
                            polygon.AddPolygon(neighbour);
                            allPolygons.RemoveAt(j);
                            change = true;
                        }
                    }
                }
            }
        }while (change);

        Debug.Log("Remove redundant vertices");
        List <int> idsRemove = new List <int>();

        foreach (KeyValuePair <int, Vertex> vertex in uniqueVertices)
        {
            int multipier = 0;
            foreach (Polygon polygon in allPolygons)
            {
                if (polygon.IsConnected(vertex.Value))
                {
                    ++multipier;
                }
            }
            if (vertex.Value.neighbours.Count > 3 * multipier && !vertex.Value.isKey)
            {
                idsRemove.Add(vertex.Key);
            }
        }

        foreach (KeyValuePair <int, Vertex> vertex in uniqueVertices)
        {
            if (idsRemove.Contains(vertex.Key))
            {
                continue;
            }

            foreach (int id in idsRemove)
            {
                if (vertex.Value.neighbours.ContainsKey(id))
                {
                    vertex.Value.neighbours.Remove(id);
                }
            }
        }
        foreach (int id in idsRemove)
        {
            uniqueVertices.Remove(id);
        }

        //Merge close vertices

        /*foreach (KeyValuePair<int, Vertex> vertex1 in uniqueVertices)
         * {
         *  foreach (KeyValuePair<int, Vertex> vertex2 in uniqueVertices)
         *  {
         *      if (vertex1.Key == vertex2.Key) continue;
         *  }
         * }*/

        for (int i = allPolygons.Count - 1; i >= 0; --i)
        {
            for (int j = allPolygons[i].vertices.Count - 1; j >= 0; --j)
            {
                if (!uniqueVertices.ContainsKey(allPolygons[i].vertices[j].id))
                {
                    allPolygons[i].vertices.RemoveAt(j);
                }
            }

            if (allPolygons[i].vertices.Count < 3)
            {
                allPolygons.RemoveAt(i);
            }
            else
            {
                for (int j = 0; j < allPolygons[i].vertices.Count - 1; ++j)
                {
                    int id = allPolygons[i].vertices[j].id;
                    uniqueVertices[id].neighbours.Clear();
                }
            }
        }

        Debug.Log("Gen Navmesh Triangles");

        for (int i = allPolygons.Count - 1; i >= 0; --i)
        {
            List <Vertex> temp = allPolygons[i].vertices;
            Triangulate(temp, ref obstacles);
        }

        foreach (KeyValuePair <int, NavMeshVertex> navVertexPair in uniqueNavmeshVertices)
        {
            Vertex correspondance = uniqueVertices[navVertexPair.Value.id];
            foreach (KeyValuePair <int, Vertex> vertexPair in correspondance.neighbours)
            {
                navVertexPair.Value.neighbours.Add(uniqueNavmeshVertices[vertexPair.Value.id]);
            }
        }

        for (int i = 0; i < allNavMeshTriangles.Count; ++i)
        {
            for (int j = i + 1; j < allNavMeshTriangles.Count; ++j)
            {
                if (allNavMeshTriangles[i].IsAdjacent(allNavMeshTriangles[j]))
                {
                    allNavMeshTriangles[i].AddNeighbour(allNavMeshTriangles[j]);
                    allNavMeshTriangles[j].AddNeighbour(allNavMeshTriangles[i]);
                }
            }
        }
    }