예제 #1
0
        //void SaveCollisionMap(NavMeshData data)
        public void SaveCollisionMap(string serverPath)
        {
            List <BoundaryEdge> boundary = WG_Helper.GetNavmeshBoundary();

            if (serverPath != null)
            {
                using (StreamWriter outputFile = new StreamWriter(serverPath + @"CollisionMap.txt"))
                {
                    for (int i = 0; i < boundary.Count; i++)
                    {
                        BoundaryEdge edge = boundary[i];
                        outputFile.Write(WG_Helper.Vectro3ToString(edge.start) + "|" + WG_Helper.Vectro3ToString(edge.end) + (i == boundary.Count - 1 ? "" : "|"));
                        //IntIntClass edge = edgesList[boundaryEdges[i]].GetEdgeVertices();

                        //outputFile.Write(WG_Helper.Vectro3ToString(vertexList[edge.value1].position) + "|" + WG_Helper.Vectro3ToString(vertexList[edge.value2].position) + (i == boundaryEdges.Count - 1 ? "" : "|"));
                    }
                }
            }
        }
예제 #2
0
        public static List <BoundaryEdge> GetNavmeshBoundary()
        {
            //copy algorithm
            NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();

            Vector3[]         originalVertices = triangulatedNavMesh.vertices;
            int[]             originalIndexes  = triangulatedNavMesh.indices;
            float             weldValue        = 0.01f;
            List <VertexData> vertexList       = new List <VertexData>();

            for (int i = 0; i < originalVertices.Length; i++)
            {
                Vector3 vPos  = originalVertices[i];
                bool    isNew = true;
                //Try to find this vertex on vertexList
                for (int vIndex = 0; vIndex < vertexList.Count; vIndex++)
                {
                    VertexData v = vertexList[vIndex];
                    if (Vector3.Distance(vPos, v.position) < weldValue)
                    {//i-th vertex placed in the same position as vIndex in the list. Add it index
                        v.indexes.Add(i);
                        vIndex = vertexList.Count;
                        isNew  = false;
                    }
                }
                if (isNew)
                {
                    VertexData newVertex = new VertexData();
                    newVertex.position = vPos;
                    newVertex.indexes  = new List <int>();
                    newVertex.indexes.Add(i);
                    vertexList.Add(newVertex);
                }
            }
            List <EdgeData> edgesList = new List <EdgeData>();
            int             originalTrianglesCount = originalIndexes.Length / 3;

            for (int i = 0; i < originalTrianglesCount; i++)
            {
                int  i1        = WG_Helper.GetVertexIndex(originalIndexes[3 * i], vertexList);
                int  i2        = WG_Helper.GetVertexIndex(originalIndexes[3 * i + 1], vertexList);
                int  i3        = WG_Helper.GetVertexIndex(originalIndexes[3 * i + 2], vertexList);
                bool isFindI12 = false;
                bool isFindI23 = false;
                bool isFindI31 = false;
                for (int eIndex = 0; eIndex < edgesList.Count; eIndex++)
                {
                    isFindI12 = edgesList[eIndex].TryToAdd(i1, i2) || isFindI12;
                    isFindI23 = edgesList[eIndex].TryToAdd(i2, i3) || isFindI23;
                    isFindI31 = edgesList[eIndex].TryToAdd(i3, i1) || isFindI31;
                }
                if (!isFindI12)
                {
                    EdgeData newEdge = new EdgeData(i1, i2);
                    edgesList.Add(newEdge);
                }
                if (!isFindI23)
                {
                    EdgeData newEdge = new EdgeData(i2, i3);
                    edgesList.Add(newEdge);
                }
                if (!isFindI31)
                {
                    EdgeData newEdge = new EdgeData(i3, i1);
                    edgesList.Add(newEdge);
                }
            }

            //filter boundary edges, if it contains vertex of the other boundary edge inside it
            List <int> boundaryIndexes = new List <int>();

            for (int i = 0; i < edgesList.Count; i++)
            {
                if (edgesList[i].IsBoundary())
                {
                    boundaryIndexes.Add(i);
                }
            }

            bool isUpdate = true;

            while (isUpdate)
            {
                isUpdate = false;
                int i = 0;
                while (i < boundaryIndexes.Count)
                {
                    IntInt currentEdge;
                    currentEdge.value01 = edgesList[boundaryIndexes[i]].GetEdgeVertices().value1;
                    currentEdge.value02 = edgesList[boundaryIndexes[i]].GetEdgeVertices().value2;
                    //IntIntClass currentEdge = edgesList[boundaryIndexes[i]].GetEdgeVertices();
                    Vector3 currentStart = vertexList[currentEdge.value01].position;
                    Vector3 currentEnd   = vertexList[currentEdge.value02].position;
                    if (Vector3.Distance(currentStart, currentEnd) < 0.01f)
                    {
                        boundaryIndexes.RemoveAt(i);
                        i        = boundaryIndexes.Count + 1;
                        isUpdate = true;
                    }
                    else
                    {
                        int j = 0;
                        while (j < boundaryIndexes.Count)
                        {
                            IntInt testEdge;
                            testEdge.value01 = edgesList[boundaryIndexes[j]].GetEdgeVertices().value1;
                            testEdge.value02 = edgesList[boundaryIndexes[j]].GetEdgeVertices().value2;
                            //IntIntClass testEdge = edgesList[boundaryIndexes[j]].GetEdgeVertices();
                            Vector3 testStart = vertexList[testEdge.value01].position;
                            Vector3 testEnd   = vertexList[testEdge.value02].position;
                            if (Vector3.Distance(testStart, testEnd) < 0.01f)
                            {
                                boundaryIndexes.RemoveAt(j);
                                j        = boundaryIndexes.Count + 1;
                                i        = boundaryIndexes.Count + 1;
                                isUpdate = true;
                            }
                            else if (i != j && boundaryIndexes[i] < boundaryIndexes[j])
                            {
                                if (IsEdgesCollinear(currentStart, currentEnd, testStart, testEnd))
                                {
                                    if (IsPointsClose(currentStart, testEnd) && IsPointOnTheEdge(testStart, currentStart, currentEnd))
                                    {
                                        EdgeData ith = new EdgeData(testEdge.value01, currentEdge.value02);
                                        EdgeData jth = new EdgeData(currentEdge.value01, testEdge.value02);
                                        edgesList[boundaryIndexes[i]] = ith;
                                        edgesList[boundaryIndexes[j]] = jth;
                                        i        = boundaryIndexes.Count + 1;
                                        j        = boundaryIndexes.Count + 1;
                                        isUpdate = true;
                                    }
                                    else if (IsPointsClose(currentEnd, testStart) && IsPointOnTheEdge(testEnd, currentStart, currentEnd))
                                    {
                                        EdgeData ith = new EdgeData(currentEdge.value01, testEdge.value02);
                                        EdgeData jth = new EdgeData(testEdge.value01, currentEdge.value02);
                                        edgesList[boundaryIndexes[i]] = ith;
                                        edgesList[boundaryIndexes[j]] = jth;
                                        i        = boundaryIndexes.Count + 1;
                                        j        = boundaryIndexes.Count + 1;
                                        isUpdate = true;
                                    }
                                    else if (IsPointsClose(currentStart, testEnd) && IsPointOnTheEdge(currentEnd, testStart, testEnd))
                                    {
                                        EdgeData ith = new EdgeData(currentEdge.value01, testEdge.value02);
                                        EdgeData jth = new EdgeData(testEdge.value01, currentEdge.value02);
                                        edgesList[boundaryIndexes[i]] = ith;
                                        edgesList[boundaryIndexes[j]] = jth;
                                        i        = boundaryIndexes.Count + 1;
                                        j        = boundaryIndexes.Count + 1;
                                        isUpdate = true;
                                    }
                                    else if (IsPointsClose(currentEnd, testStart) && IsPointOnTheEdge(currentStart, testStart, testEnd))
                                    {
                                        EdgeData ith = new EdgeData(testEdge.value01, currentEdge.value02);
                                        EdgeData jth = new EdgeData(currentEdge.value01, testEdge.value02);
                                        edgesList[boundaryIndexes[i]] = ith;
                                        edgesList[boundaryIndexes[j]] = jth;
                                        i        = boundaryIndexes.Count + 1;
                                        j        = boundaryIndexes.Count + 1;
                                        isUpdate = true;
                                    }
                                    else if (IsPointsClose(currentEnd, testStart) && IsPointsClose(currentStart, testEnd))
                                    {
                                        EdgeData ith = new EdgeData(currentEdge.value01, currentEdge.value01);
                                        EdgeData jth = new EdgeData(testEdge.value01, testEdge.value01);
                                        edgesList[boundaryIndexes[i]] = ith;
                                        edgesList[boundaryIndexes[j]] = jth;
                                        i        = boundaryIndexes.Count + 1;
                                        j        = boundaryIndexes.Count + 1;
                                        isUpdate = true;
                                    }
                                }
                            }

                            j++;
                        }
                    }
                    i++;
                }
            }

            //copy to the output
            List <BoundaryEdge> toReturn = new List <BoundaryEdge>();

            for (int i = 0; i < boundaryIndexes.Count; i++)
            {
                int          index   = boundaryIndexes[i];
                IntIntClass  edge    = edgesList[index].GetEdgeVertices();
                BoundaryEdge newEdge = new BoundaryEdge();
                newEdge.index       = index;
                newEdge.start       = vertexList[edge.value1].position;
                newEdge.end         = vertexList[edge.value2].position;
                newEdge.startVertex = edge.value1;
                newEdge.endVertes   = edge.value2;
                toReturn.Add(newEdge);
            }
            return(toReturn);
        }
예제 #3
0
        void OnDrawGizmos()
        {
            #if UNITY_EDITOR
            if (visualMap != null && visualizeMap)
            {
                for (int x = 0; x < visualMap.GetLength(0); x++)
                {
                    for (int y = 0; y < visualMap.GetLength(1); y++)
                    {
                        Gizmos.color = (visualMap[x, y]) ? new Color(0, 0, 0, gizmoAlpha) : new Color(1, 1, 1, gizmoAlpha);
                        Vector3 pos = new Vector3(-visualAreaSize / 2 + (x + 0.5f) * visualSquareSize + visualAreaCenter.position.x, 0, -visualAreaSize / 2 + (y + 0.5f) * visualSquareSize + visualAreaCenter.position.z);
                        Gizmos.DrawCube(pos, new Vector3(visualSquareSize * 0.75f, 0.0f, visualSquareSize * 0.75f));
                    }
                }

                Vector2 minCorner = new Vector2(visualAreaCenter.position.x - visualAreaSize / 2, visualAreaCenter.position.z - visualAreaSize / 2);
                Vector2 maxCorner = new Vector2(visualAreaCenter.position.x + visualAreaSize / 2, visualAreaCenter.position.z + visualAreaSize / 2);

                int minX = (int)(minCorner.x / (segmentSize / 2)) + (minCorner.x > 0 ? 1 : 0);
                int maxX = (int)(maxCorner.x / (segmentSize / 2)) + (maxCorner.x > 0 ? 1 : 0);

                int minY = (int)(minCorner.y / (segmentSize / 2)) + (minCorner.y > 0 ? 1 : 0);
                int maxY = (int)(maxCorner.y / (segmentSize / 2)) + (maxCorner.y > 0 ? 1 : 0);

                Gizmos.color = visualZoneLine;
                for (int x = minX - 1; x < maxX + 1; x++)
                {
                    for (int y = minY - 1; y < maxY + 1; y++)
                    {
                        if (x % 2 == 0 && y % 2 == 0)
                        {
                            Gizmos.DrawLine(GetPositionOfSegmetnCorner(x - 1, y - 1), GetPositionOfSegmetnCorner(x + 1, y - 1));
                            Gizmos.DrawLine(GetPositionOfSegmetnCorner(x + 1, y - 1), GetPositionOfSegmetnCorner(x + 1, y + 1));
                            Gizmos.DrawLine(GetPositionOfSegmetnCorner(x + 1, y + 1), GetPositionOfSegmetnCorner(x - 1, y + 1));
                            Gizmos.DrawLine(GetPositionOfSegmetnCorner(x - 1, y + 1), GetPositionOfSegmetnCorner(x - 1, y - 1));

                            string  labelString = "(" + (x / 2).ToString() + ", " + (y / 2).ToString() + ")";
                            Vector3 labelPos    = new Vector3(x * segmentSize / 2, 2.0f, y * segmentSize / 2);
                            Handles.Label(labelPos, labelString);
                        }
                    }
                }
            }

            if (visualizeBoundaryEdges)
            {
                List <BoundaryEdge> boundary = WG_Helper.GetNavmeshBoundary();

                Gizmos.color = boundaryLine;
                for (int i = 0; i < boundary.Count; i++)
                {
                    BoundaryEdge edge = boundary[i];
                    if (true)
                    {
                        Gizmos.DrawLine(edge.start, edge.end);
                        //Handles.DrawSolidDisc(edge.start, Vector3.up, 0.03f);
                        //Handles.Label(edge.start, edge.startVertex.ToString());
                        //Handles.DrawSolidDisc(edge.end, Vector3.up, 0.03f);
                        //Handles.Label(edge.end, edge.endVertes.ToString());
                        //Handles.Label((edge.start + edge.end) / 2.0f, edge.index.ToString());
                    }
                }
            }
            #endif
        }