Beispiel #1
0
        void buildNavMesh(uint mapID, out dtNavMesh navMesh)
        {
            // if map has a parent we use that to generate dtNavMeshParams - worldserver will load all missing tiles from that map
            int navMeshParamsMapId = _vmapManager.GetParentMapId(mapID);

            if (navMeshParamsMapId == -1)
            {
                navMeshParamsMapId = (int)mapID;
            }

            SortedSet <uint> tiles = getTileList((uint)navMeshParamsMapId);

            // old code for non-statically assigned bitmask sizes:
            ///*** calculate number of bits needed to store tiles & polys ***/
            //int tileBits = dtIlog2(dtNextPow2(tiles.size()));
            //if (tileBits < 1) tileBits = 1;                                     // need at least one bit!
            //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits;

            int polyBits = SharedConst.DT_POLY_BITS;

            int maxTiles        = tiles.Count;
            int maxPolysPerTile = 1 << polyBits;

            /***          calculate bounds of map         ***/

            uint tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0;

            foreach (var it in tiles)
            {
                StaticMapTree.UnpackTileID(it, out uint tileX, out uint tileY);

                if (tileX > tileXMax)
                {
                    tileXMax = tileX;
                }
                else if (tileX < tileXMin)
                {
                    tileXMin = tileX;
                }

                if (tileY > tileYMax)
                {
                    tileYMax = tileY;
                }
                else if (tileY < tileYMin)
                {
                    tileYMin = tileY;
                }
            }

            // use Max because '32 - tileX' is negative for values over 32
            float[] bmin;
            float[] bmax;
            getTileBounds(tileXMax, tileYMax, null, 0, out bmin, out bmax);

            /***       now create the navmesh       ***/

            // navmesh creation params
            dtNavMeshParams navMeshParams = new dtNavMeshParams();

            navMeshParams.tileWidth  = SharedConst.GRID_SIZE;
            navMeshParams.tileHeight = SharedConst.GRID_SIZE;
            rcVcopy(navMeshParams.orig, bmin);
            navMeshParams.maxTiles = maxTiles;
            navMeshParams.maxPolys = maxPolysPerTile;

            navMesh = new dtNavMesh();
            if (dtStatusFailed(navMesh.init(navMeshParams)))
            {
                Console.WriteLine($"[Map: {mapID:D4}] Failed creating navmesh!");
                return;
            }

            string fileName = $"mmaps/{mapID:D4}.mmap";

            using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create, FileAccess.Write)))
            {
                // now that we know navMesh params are valid, we can write them to file
                writer.Write(bmin[0]);
                writer.Write(bmin[1]);
                writer.Write(bmin[2]);
                writer.Write(SharedConst.GRID_SIZE);
                writer.Write(SharedConst.GRID_SIZE);
                writer.Write(maxTiles);
                writer.Write(maxPolysPerTile);
            }
        }
Beispiel #2
0
        /// Initializes the navigation mesh for single tile use.
        ///  @param[in]	data		Data of the new tile. (See: #dtCreateNavMeshData)
        ///  @param[in]	dataSize	The data size of the new tile.
        ///  @param[in]	flags		The tile flags. (See: #dtTileFlags)
        /// @return The status flags for the operation.
        ///  @see dtCreateNavMeshData
        public dtStatus init(dtRawTileData rawTile, int flags)
        {
            //C#: Using an intermediate class dtRawTileData because Cpp uses a binary buffer.

            // Make sure the data is in right format.
            //dtMeshHeader header = (dtMeshHeader*)data;
            dtMeshHeader header = rawTile.header;
            if (header.magic != DT_NAVMESH_MAGIC)
                return DT_FAILURE | DT_WRONG_MAGIC;
            if (header.version != DT_NAVMESH_VERSION)
                return DT_FAILURE | DT_WRONG_VERSION;

            dtNavMeshParams navMeshParams = new dtNavMeshParams();
            dtVcopy(navMeshParams.orig, header.bmin);
            navMeshParams.tileWidth = header.bmax[0] - header.bmin[0];
            navMeshParams.tileHeight = header.bmax[2] - header.bmin[2];
            navMeshParams.maxTiles = 1;
            navMeshParams.maxPolys = header.polyCount;

            dtStatus status = init(navMeshParams);
            if (dtStatusFailed(status))
                return status;

            //return addTile(data, dataSize, flags, 0, 0);
            dtTileRef dummyResult = 0;
            return addTile(rawTile, flags, 0,ref dummyResult);
        }
Beispiel #3
0
        uint m_polyBits; //< Number of poly bits in the tile ID.
        #endif

        #region Constructors

        public dtNavMesh()
        {
            #if DT_POLYREF64
            m_saltBits = 0;
            m_tileBits = 0;
            m_polyBits = 0;
            #endif
            m_params = new dtNavMeshParams();
            m_orig[0] = 0;
            m_orig[1] = 0;
            m_orig[2] = 0;
        }
Beispiel #4
0
        /// @{
        /// @name Initialization and Tile Management
        /// Initializes the navigation mesh for tiled use.
        ///  @param[in]	params		Initialization parameters.
        /// @return The status flags for the operation.
        public dtStatus init(dtNavMeshParams navMeshParams)
        {
            //memcpy(&m_params, params, sizeof(dtNavMeshParams));
            m_params = navMeshParams.Clone();
            dtVcopy(m_orig, navMeshParams.orig);
            m_tileWidth = navMeshParams.tileWidth;
            m_tileHeight = navMeshParams.tileHeight;

            // Init tiles
            m_maxTiles = navMeshParams.maxTiles;
            m_tileLutSize = (int)dtNextPow2((uint)(navMeshParams.maxTiles/4));
            if (m_tileLutSize == 0)
                m_tileLutSize = 1;
            m_tileLutMask = m_tileLutSize-1;

            //m_tiles = (dtMeshTile*)dtAlloc(sizeof(dtMeshTile)*m_maxTiles, DT_ALLOC_PERM);
            m_tiles = new dtMeshTile[m_maxTiles];
            dtcsArrayItemsCreate(m_tiles);

            if (m_tiles == null)
                return (DT_FAILURE | DT_OUT_OF_MEMORY);
            //m_posLookup = (dtMeshTile**)dtAlloc(sizeof(dtMeshTile*)*m_tileLutSize, DT_ALLOC_PERM);
            m_posLookup = new dtMeshTile[m_tileLutSize];
            dtcsArrayItemsCreate(m_posLookup);
            if (m_posLookup == null)
                return DT_FAILURE | DT_OUT_OF_MEMORY;
            //memset(m_tiles, 0, sizeof(dtMeshTile)*m_maxTiles);
            //memset(m_posLookup, 0, sizeof(dtMeshTile*)*m_tileLutSize);
            m_nextFree = null;
            for (int i = m_maxTiles-1; i >= 0; --i)
            {
                m_tiles[i].salt = 1;
                m_tiles[i].next = m_nextFree;
                m_nextFree = m_tiles[i];
            }

            // Init ID generator values.
            #if DT_POLYREF64
            #else
            m_tileBits = (dtStatus)dtIlog2(dtNextPow2((uint)navMeshParams.maxTiles));
            m_polyBits = (dtStatus)dtIlog2(dtNextPow2((uint)navMeshParams.maxPolys));
            // Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow.
            m_saltBits = Math.Min((uint)31, 32 - m_tileBits - m_polyBits);

            if (m_saltBits < 10)
                return DT_FAILURE | DT_INVALID_PARAM;
            #endif

            return DT_SUCCESS;
        }