コード例 #1
0
ファイル: TiledNavMesh.cs プロジェクト: dol-leodagan/SharpNav
        /// <summary>
        /// Build a tile and link all the polygons togther, both internally and externally.
        /// Make sure to link off-mesh connections as well.
        /// </summary>
        /// <param name="data">Navigation Mesh data</param>
        /// <param name="lastRef">Last polygon reference</param>
        /// <param name="result">Last tile reference</param>
        public void AddTile(NavMeshBuilder data, PolyId lastRef, out PolyId result)
        {
            result = PolyId.Null;

            //make sure data is in right format
            PathfindingCommon.NavMeshInfo header = data.Header;

            //make sure location is free
            if (GetTileAt(header.X, header.Y, header.Layer) != null)
            {
                return;
            }

            //allocate a tile
            MeshTile tile = null;

            if (lastRef == PolyId.Null)
            {
                if (nextFree != null)
                {
                    tile      = nextFree;
                    nextFree  = tile.Next;
                    tile.Next = null;
                }
            }
            else
            {
                //try to relocate tile to specific index with the same salt
                int tileIndex = lastRef.DecodeTileIndex(polyBits, tileBits);
                if (tileIndex >= maxTiles)
                {
                    return;
                }

                //try to find specific tile id from free list
                MeshTile target = tiles[tileIndex];
                MeshTile prev   = null;
                tile = nextFree;
                while (tile != null && tile != target)
                {
                    prev = tile;
                    tile = tile.Next;
                }

                //couldn't find correct location
                if (tile != target)
                {
                    return;
                }

                //remove from freelist
                if (prev == null)
                {
                    nextFree = tile.Next;
                }
                else
                {
                    prev.Next = tile.Next;
                }

                //restore salt
                tile.Salt = lastRef.DecodeSalt(polyBits, tileBits, saltBits);
            }

            //make sure we could allocate a tile
            if (tile == null)
            {
                return;
            }

            //insert tile into position LookUp Table (lut)
            int h = ComputeTileHash(header.X, header.Y, tileLookupTableMask);

            tile.Next    = posLookup[h];
            posLookup[h] = tile;

            if (header.BvNodeCount == 0)
            {
                tile.BVTree = null;
            }

            //patch header
            tile.Verts              = data.NavVerts;
            tile.Polys              = data.NavPolys;
            tile.DetailMeshes       = data.NavDMeshes;
            tile.DetailVerts        = data.NavDVerts;
            tile.DetailTris         = data.NavDTris;
            tile.BVTree             = data.NavBvTree;
            tile.OffMeshConnections = data.OffMeshCons;

            //build links freelist
            tile.LinksFreeList = 0;
            tile.Links         = new Link[header.MaxLinkCount];
            for (int i = 0; i < header.MaxLinkCount; i++)
            {
                tile.Links[i] = new Link();
            }

            tile.Links[header.MaxLinkCount - 1].Next = Link.Null;
            for (int i = 0; i < header.MaxLinkCount - 1; i++)
            {
                tile.Links[i].Next = i + 1;
            }

            //init tile
            tile.Header = header;
            tile.Data   = data;

            ConnectIntLinks(ref tile);
            BaseOffMeshLinks(ref tile);

            //create connections with neighbor tiles
            MeshTile[] neis = new MeshTile[32];
            int        nneis;

            //connect with layers in current tile
            nneis = GetTilesAt(header.X, header.Y, neis);
            for (int j = 0; j < nneis; j++)
            {
                if (neis[j] != tile)
                {
                    ConnectExtLinks(ref tile, ref neis[j], BoundarySide.Internal);
                    ConnectExtLinks(ref neis[j], ref tile, BoundarySide.Internal);
                }

                ConnectExtOffMeshLinks(ref tile, ref neis[j], BoundarySide.Internal);
                ConnectExtOffMeshLinks(ref neis[j], ref tile, BoundarySide.Internal);
            }

            //connect with neighbour tiles
            for (int i = 0; i < 8; i++)
            {
                BoundarySide b  = (BoundarySide)i;
                BoundarySide bo = b.GetOpposite();
                nneis = GetNeighbourTilesAt(header.X, header.Y, b, neis);
                for (int j = 0; j < nneis; j++)
                {
                    ConnectExtLinks(ref tile, ref neis[j], b);
                    ConnectExtLinks(ref neis[j], ref tile, bo);
                    ConnectExtOffMeshLinks(ref tile, ref neis[j], b);
                    ConnectExtOffMeshLinks(ref neis[j], ref tile, bo);
                }
            }

            result = GetTileRef(tile);
        }
コード例 #2
0
ファイル: TiledNavMesh.cs プロジェクト: keedongpark/SharpNav
        /// <summary>
        /// Build a tile and link all the polygons togther, both internally and externally.
        /// Make sure to link off-mesh connections as well.
        /// </summary>
        /// <param name="data">Navigation Mesh data</param>
        /// <param name="lastRef">Last polygon reference</param>
        /// <param name="result">Last tile reference</param>
        public void AddTile(NavMeshBuilder data, PolyId lastRef, out PolyId result)
        {
            result = PolyId.Null;

            //make sure data is in right format
            PathfindingCommon.NavMeshInfo header = data.Header;

            //make sure location is free
            if (GetTileAt(header.X, header.Y, header.Layer) != null)
                return;

            //allocate a tile
            MeshTile tile = null;
            if (lastRef == PolyId.Null)
            {
                if (nextFree != null)
                {
                    tile = nextFree;
                    nextFree = tile.Next;
                    tile.Next = null;
                }
            }
            else
            {
                //try to relocate tile to specific index with the same salt
                int tileIndex = lastRef.DecodeTileIndex(polyBits, tileBits);
                if (tileIndex >= maxTiles)
                    return;

                //try to find specific tile id from free list
                MeshTile target = tiles[tileIndex];
                MeshTile prev = null;
                tile = nextFree;
                while (tile != null && tile != target)
                {
                    prev = tile;
                    tile = tile.Next;
                }

                //couldn't find correct location
                if (tile != target)
                    return;

                //remove from freelist
                if (prev == null)
                    nextFree = tile.Next;
                else
                    prev.Next = tile.Next;

                //restore salt
                tile.Salt = lastRef.DecodeSalt(polyBits, tileBits, saltBits);
            }

            //make sure we could allocate a tile
            if (tile == null)
                return;

            //insert tile into position LookUp Table (lut)
            int h = ComputeTileHash(header.X, header.Y, tileLookupTableMask);
            tile.Next = posLookup[h];
            posLookup[h] = tile;

            if (header.BvNodeCount == 0)
                tile.BVTree = null;

            //patch header
            tile.Verts = data.NavVerts;
            tile.Polys = data.NavPolys;
            tile.DetailMeshes = data.NavDMeshes;
            tile.DetailVerts = data.NavDVerts;
            tile.DetailTris = data.NavDTris;
            tile.BVTree = data.NavBvTree;
            tile.OffMeshConnections = data.OffMeshCons;

            //build links freelist
            tile.LinksFreeList = 0;
            tile.Links = new Link[header.MaxLinkCount];
            for (int i = 0; i < header.MaxLinkCount; i++)
                tile.Links[i] = new Link();

            tile.Links[header.MaxLinkCount - 1].Next = Link.Null;
            for (int i = 0; i < header.MaxLinkCount - 1; i++)
                tile.Links[i].Next = i + 1;

            //init tile
            tile.Header = header;
            tile.Data = data;

            ConnectIntLinks(ref tile);
            BaseOffMeshLinks(ref tile);

            //create connections with neighbor tiles
            MeshTile[] neis = new MeshTile[32];
            int nneis;

            //connect with layers in current tile
            nneis = GetTilesAt(header.X, header.Y, neis);
            for (int j = 0; j < nneis; j++)
            {
                if (neis[j] != tile)
                {
                    ConnectExtLinks(ref tile, ref neis[j], BoundarySide.Internal);
                    ConnectExtLinks(ref neis[j], ref tile, BoundarySide.Internal);
                }

                ConnectExtOffMeshLinks(ref tile, ref neis[j], BoundarySide.Internal);
                ConnectExtOffMeshLinks(ref neis[j], ref tile, BoundarySide.Internal);
            }

            //connect with neighbour tiles
            for (int i = 0; i < 8; i++)
            {
                BoundarySide b = (BoundarySide)i;
                BoundarySide bo = b.GetOpposite();
                nneis = GetNeighbourTilesAt(header.X, header.Y, b, neis);
                for (int j = 0; j < nneis; j++)
                {
                    ConnectExtLinks(ref tile, ref neis[j], b);
                    ConnectExtLinks(ref neis[j], ref tile, bo);
                    ConnectExtOffMeshLinks(ref tile, ref neis[j], b);
                    ConnectExtOffMeshLinks(ref neis[j], ref tile, bo);
                }
            }

            result = GetTileRef(tile);
        }