예제 #1
0
    public void GetDiagonalOfNeighbor(MeshPolygon nearbyPolygon, out Vector2 left, out Vector2 right)
    {
        int key = m_NeighborPolygons.KeyByValue(nearbyPolygon);

        left  = GetPoint(key);
        right = GetPoint(key + 1);
    }
예제 #2
0
    // Get the mid point of the diagonal between two polygons
    public Vector2 GetMidPointOfDiagonalNeighbor(MeshPolygon nearbyPolygon)
    {
        Vector2 left, right;

        GetDiagonalOfNeighbor(nearbyPolygon, out left, out right);

        return(new Vector2((left.x + right.x) / 2f, (left.y + right.y) / 2f));
    }
예제 #3
0
    // Add a neighbor polygon to this polygon on the NavMesh
    public void AddNeighborPolygon(MeshPolygon poly, int vertexIndex)
    {
        if (m_NeighborPolygons == null)
        {
            m_NeighborPolygons = new Dictionary <int, MeshPolygon>();
        }

        m_NeighborPolygons.Add(vertexIndex, poly);
    }
        // Return a list of triangles with the vertices
        public static List <MeshPolygon> Triangulate(Polygon polygon)
        {
            List <MeshPolygon> triangles = new List <MeshPolygon>();
            MeshPolygon        triangle;

            int earIndex = 0;

            polygon.ReverseWindingOrder();

            // No ears
            if (polygon.GetVerticesCount() < 3)
            {
                return(triangles);
            }

            // Set the values for the vertices
            for (int i = 0; i < polygon.GetVerticesCount(); i++)
            {
                UpdateVertex(i, polygon);
            }

            // Start clipping the ears
            while (polygon.GetVerticesCount() > 3)
            {
                var earFound = false;

                // find the most extruded ear
                for (int j = 0; j < polygon.GetVerticesCount(); j++)
                {
                    if (!polygon.GetVertex(j).isEar)
                    {
                        continue;
                    }

                    if (!earFound)
                    {
                        earFound = true;
                        earIndex = j;
                    }
                    else
                    {
                        float vAngle = GeometryHelper.GetAngle(polygon.GetPoint(j - 1), polygon.GetPoint(j),
                                                               polygon.GetPoint(j + 1));
                        float earAngle = GeometryHelper.GetAngle(polygon.GetPoint(earIndex - 1),
                                                                 polygon.GetPoint(earIndex),
                                                                 polygon.GetPoint(earIndex + 1));

                        if (vAngle > earAngle)
                        {
                            earIndex = j;
                        }
                    }
                }

                if (!earFound)
                {
                    return(triangles);
                }

                triangle = new MeshPolygon();
                triangle.AddPoint(polygon.GetPoint(earIndex - 1));
                triangle.AddPoint(polygon.GetPoint(earIndex));
                triangle.AddPoint(polygon.GetPoint(earIndex + 1));
                triangles.Add(triangle);

                // Clip the ear
                polygon.RemovePoint(earIndex);

                // Update the adjacent vertices
                UpdateVertex(earIndex - 1, polygon);
                UpdateVertex(earIndex, polygon);
            }

            // Add the last ear
            if (polygon.GetVerticesCount() == 3)
            {
                triangle = new MeshPolygon();
                triangle.AddPoint(polygon.GetPoint(0));
                triangle.AddPoint(polygon.GetPoint(1));
                triangle.AddPoint(polygon.GetPoint(2));
                triangles.Add(triangle);
                return(triangles);
            }


            return(triangles);
        }
예제 #5
0
 public void SetPreviousPolygon(MeshPolygon prev)
 {
     m_previousPolygon = prev;
 }
        // Remove the nonessential diagonals
        public static List <MeshPolygon> RemoveNonEssentialDiagonals(List <MeshPolygon> triangles)
        {
            MeshPolygon poly2 = null;
            int         i21 = 0, i22 = 0;


            // Loop through the triangles
            int currentPoly = 0;

            while (currentPoly < triangles.Count)
            {
                var poly1 = triangles[currentPoly];

                int i11;
                for (i11 = 0; i11 < poly1.GetVerticesCount(); i11++)
                {
                    // Get the first line in the polygon
                    var d1  = poly1.GetPoint(i11);
                    var i12 = i11 + 1;
                    var d2  = poly1.GetPoint(i12);

                    // Find another polygon who shares this line
                    var isDiagonal = false;
                    for (int j1 = currentPoly; j1 < triangles.Count; j1++)
                    {
                        poly2 = triangles[j1];

                        if (poly1 == poly2)
                        {
                            continue;
                        }

                        // Find a common line with the next polygon to determine if it is a diagonal
                        for (i21 = 0; i21 < poly2.GetVerticesCount(); i21++)
                        {
                            if ((d2.x != poly2.GetPoint(i21).x) || (d2.y != poly2.GetPoint(i21).y))
                            {
                                continue;
                            }

                            i22 = i21 + 1;

                            if ((d1.x != poly2.GetPoint(i22).x) || (d1.y != poly2.GetPoint(i22).y))
                            {
                                continue;
                            }

                            // The line is found in an adjacent polygon
                            isDiagonal = true;
                            break;
                        }

                        if (isDiagonal)
                        {
                            break;
                        }
                    }


                    // If no diagonal has been found between the current polygon and all the others then move to the next
                    if (!isDiagonal)
                    {
                        continue;
                    }


                    // First point of the diagonal
                    var p2 = poly1.GetPoint(i11);

                    // Get the previous vertex
                    var i13 = i11 - 1;
                    var p1  = poly1.GetPoint(i13);

                    // Get the next vertex on the other polygon
                    var i23 = i22 + 1;
                    var p3  = poly2.GetPoint(i23);

                    // If the formed angle is reflex then the diagonal is essential
                    if (GeometryHelper.IsReflex(p1, p2, p3))
                    {
                        continue;
                    }

                    // Get vertex on the other end of the diagonal
                    p2 = poly1.GetPoint(i12);

                    // Get the next vertex on the first polygon
                    i13 = i12 + 1;
                    p3  = poly1.GetPoint(i13);

                    // Get the previous vertex on the other polygon
                    i23 = i21 - 1;
                    p1  = poly2.GetPoint(i23);

                    // If the formed angle is reflex then the diagonal is essential
                    if (GeometryHelper.IsReflex(p1, p2, p3))
                    {
                        continue;
                    }


                    var newPoly = new MeshPolygon();

                    int j;
                    for (j = i12; j != i11; j = (j + 1) % (poly1.GetVerticesCount()))
                    {
                        newPoly.AddPoint(poly1.GetPoint(j));
                    }


                    for (j = i22; j != i21; j = (j + 1) % (poly2.GetVerticesCount()))
                    {
                        newPoly.AddPoint(poly2.GetPoint(j));
                    }

                    triangles.Remove(poly2);
                    poly1 = newPoly;
                    triangles[currentPoly] = poly1;

                    i11 = -1;
                }

                currentPoly++;
            }


            return(triangles);
        }
        // Build NavMesh connections
        public static void BuildNavMesh(List <MeshPolygon> navMeshPolygons)
        {
            MeshPolygon poly2 = null;
            int         i21   = 0;

            // Loop through the polygons
            int currentPoly = 0;

            while (currentPoly < navMeshPolygons.Count)
            {
                var poly1 = navMeshPolygons[currentPoly];

                int i11;
                for (i11 = 0; i11 < poly1.GetVerticesCount(); i11++)
                {
                    // Get the first line in the polygon
                    var d1  = poly1.GetPoint(i11);
                    var i12 = i11 + 1;
                    var d2  = poly1.GetPoint(i12);

                    // Find another polygon who shares this line
                    var isDiagonal = false;
                    for (int j1 = currentPoly; j1 < navMeshPolygons.Count; j1++)
                    {
                        poly2 = navMeshPolygons[j1];

                        if (poly1 == poly2)
                        {
                            continue;
                        }

                        // Find a common line with the next polygon to determine if it is a diagonal
                        for (i21 = 0; i21 < poly2.GetVerticesCount(); i21++)
                        {
                            if ((d2.x != poly2.GetPoint(i21).x) || (d2.y != poly2.GetPoint(i21).y))
                            {
                                continue;
                            }

                            var i22 = i21 + 1;

                            if ((d1.x != poly2.GetPoint(i22).x) || (d1.y != poly2.GetPoint(i22).y))
                            {
                                continue;
                            }

                            // The line is found in an adjacent polygon
                            isDiagonal = true;
                            break;
                        }

                        if (isDiagonal)
                        {
                            break;
                        }
                    }

                    // If no diagonal has been found between the current polygon and all the others then move to the next
                    if (!isDiagonal)
                    {
                        continue;
                    }

                    poly1.AddNeighborPolygon(poly2, i11);
                    poly2.AddNeighborPolygon(poly1, i21);
                }

                currentPoly++;
            }
        }