예제 #1
0
        public override void Init(INavData data)
        {
            Grid3DNavData navData = data as Grid3DNavData;

            ParseNavData(navData);

#if !UNITY_EDITOR
            // release memory
            navData.ReleaseMemory();
#endif
        }
예제 #2
0
        private void ParseNavData(Grid3DNavData navData)
        {
            navGraphData = navData;
            nodeMatrix   = new Grid3DNode[navData.buildConfig.cellCount.x, navData.buildConfig.cellCount.y, navData.buildConfig.cellCount.z];
            for (int i = 0; i < navData.nodeList.Count; ++i)
            {
                Grid3DNode node = null;
                if (navData.bytesMode)
                {
                    node = navData.ParseNode(i);
                }
                else
                {
                    node = navData.nodeList[i];
                }
                nodeMatrix[node.x, node.y, node.z] = node;
                this.AddNode(node);
#if UNITY_EDITOR
                nodeList.Add(node);
                nodeDic.Add(node.id, node);
#endif
            }
            for (int i = 0; i < navData.edgeList.Count; ++i)
            {
                Grid3DEdge edge = null;
                if (navData.bytesMode)
                {
                    edge = navData.ParseEdge(i);
                }
                else
                {
                    edge = navData.edgeList[i];
                }

                Grid3DEdge edgeToFrom = new Grid3DEdge(edge.to, edge.from, edge.cost);

                this.AddEdge(edge);
                this.AddEdge(edgeToFrom);
#if UNITY_EDITOR
                edgeList.Add(edge);
                edgeList.Add(edgeToFrom);
#endif
            }
        }
예제 #3
0
        private void CellsToGraph()
        {
            navData = ScriptableObject.CreateInstance <Grid3DNavData>();
            navData.Init(cfg);

            int   count    = 0;
            float cellSize = cfg.cellSize / 1000f;

            // make nodes
            for (int i = 0; i < rawCells.Count; ++i)
            {
                count++;
                if (count % 10 == 0)
                {
                    EditorUtility.DisplayProgressBar(string.Format("Building graph nodes {0}/{1}", count, rawCells.Count), "", (float)count / rawCells.Count);
                }

                var cell = rawCells[i];
                if (cell == null || !cell.walkable)
                {
                    continue;
                }

                int x  = cell.pos.x;
                int y  = cell.pos.y;
                int z  = cell.pos.z;
                int id = cell.id;

                var node = new Grid3DNode();
                node.id            = id;
                node.x             = (ushort)x;
                node.y             = (ushort)y;
                node.z             = (ushort)z;
                node.worldPosition = new Int3(cell.worldPosition);
                //node.walkable = cell.walkable;
                navData.AddNode(node);
            }

            // make edges
            HashSet <string> edgeKeySet = new HashSet <string>();

            for (int i = 0; i < rawCells.Count; ++i)
            {
                if (i % 10 == 0)
                {
                    EditorUtility.DisplayProgressBar(string.Format("Building graph edges {0}/{1}", i, rawCells.Count), "", (float)i / rawCells.Count);
                }

                var cell = rawCells[i];
                if (cell == null || !cell.walkable)
                {
                    continue;
                }

                int x  = cell.pos.x;
                int y  = cell.pos.y;
                int z  = cell.pos.z;
                int id = cell.id;

                for (int ix = -1; ix <= 1; ix++)
                {
                    for (int iy = -1; iy <= 1; iy++)
                    {
                        for (int iz = -1; iz <= 1; iz++)
                        {
                            int realx = x + ix;
                            int realy = y + iy;
                            int realz = z + iz;
                            if (realx >= 0 && realx < cfg.cellCount.x &&
                                realy >= 0 && realy < cfg.cellCount.y &&
                                realz >= 0 && realz < cfg.cellCount.z)
                            {
                                if (ix == 0 && iz == 0)
                                {
                                    continue;
                                }

                                if (!Enable8Directions && ix != 0 && iz != 0)
                                {
                                    continue;
                                }

                                var neighbor = cellArray[realx, realy, realz];
                                if (neighbor != null)
                                {
                                    int nbId     = neighbor.id;
                                    int cost     = int.MaxValue;
                                    int absDelta = Math.Abs(ix) + Math.Abs(iy) + Math.Abs(iz);
                                    if (neighbor.walkable)
                                    {
                                        // to_from edge has been already added, so ignore it
                                        if (edgeKeySet.Contains(string.Format("{0}_{1}", nbId, id)))
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            edgeKeySet.Add(string.Format("{0}_{1}", id, nbId));
                                        }

                                        float tan      = 0;
                                        float dx       = cellSize;
                                        float dy       = Math.Abs(neighbor.worldPosition.y - cell.worldPosition.y);
                                        float dz       = cellSize;
                                        float distance = (cell.worldPosition - neighbor.worldPosition).magnitude;
                                        cost = (int)Math.Round(distance / (cfg.cellSize / 1000f) * 10);
                                        if (absDelta == 1)
                                        {
                                            if (ix == 0)
                                            {
                                                tan = dy / dz;
                                            }
                                            else if (iz == 0)
                                            {
                                                tan = dy / dx;
                                            }
                                            else
                                            {
                                                tan = 0;
                                            }
                                        }
                                        else if (absDelta == 2)
                                        {
                                            if (iy == 0)
                                            {
                                                tan = dy / cellSize * 1.414f;
                                            }
                                            else
                                            {
                                                tan = dy / cellSize;
                                            }
                                        }
                                        else if (absDelta == 3)
                                        {
                                            tan = dy / cellSize * 1.414f;
                                        }
                                        if (tan > cfg.tanSlope)
                                        {
                                            cost = int.MaxValue;
                                        }

                                        if (cost != int.MaxValue)
                                        {
                                            var edge = new Grid3DEdge(id, nbId, cost);
                                            navData.AddEdge(edge);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            graphMap = new Grid3DGraph();
            graphMap.Init(navData);
        }