コード例 #1
0
        static bool LoadedTilesCommand(StringArguments args, CommandHandler handler)
        {
            Player player       = handler.GetSession().GetPlayer();
            uint   terrainMapId = PhasingHandler.GetTerrainMapId(player.GetPhaseShift(), player.GetMap(), player.GetPositionX(), player.GetPositionY());

            Detour.dtNavMesh      navmesh      = Global.MMapMgr.GetNavMesh(terrainMapId);
            Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, handler.GetPlayer().GetInstanceId());
            if (navmesh == null || navmeshquery == null)
            {
                handler.SendSysMessage("NavMesh not loaded for current map.");
                return(true);
            }

            handler.SendSysMessage("mmap loadedtiles:");

            for (int i = 0; i < navmesh.getMaxTiles(); ++i)
            {
                Detour.dtMeshTile tile = navmesh.getTile(i);
                if (tile.header == null)
                {
                    continue;
                }

                handler.SendSysMessage("[{0:D2}, {1:D2}]", tile.header.x, tile.header.y);
            }
            return(true);
        }
コード例 #2
0
ファイル: MMapsCommands.cs プロジェクト: Zakkgard/CypherCore
        static bool LoadedTilesCommand(StringArguments args, CommandHandler handler)
        {
            uint mapid = handler.GetPlayer().GetMapId();

            Detour.dtNavMesh      navmesh      = Global.MMapMgr.GetNavMesh(mapid);
            Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(mapid, handler.GetPlayer().GetInstanceId());
            if (navmesh == null || navmeshquery == null)
            {
                handler.SendSysMessage("NavMesh not loaded for current map.");
                return(true);
            }

            handler.SendSysMessage("mmap loadedtiles:");

            for (int i = 0; i < navmesh.getMaxTiles(); ++i)
            {
                Detour.dtMeshTile tile = navmesh.getTile(i);
                if (tile == null)
                {
                    continue;
                }

                handler.SendSysMessage("[{0:D2}, {1:D2}]", tile.header.x, tile.header.y);
            }
            return(true);
        }
コード例 #3
0
    public static void ShowTilePolyDetails(DbgRenderMesh renderMesh, Detour.dtNavMesh navMesh, int tileId)
    {
        renderMesh.Clear();

        UnityEngine.Random.seed = c_RandomSeed;

        if (navMesh == null)
        {
            renderMesh.Rebuild();
            return;
        }

        Detour.dtMeshTile tile = navMesh.getTile(tileId);

        if (tile == null)
        {
            Debug.LogError("RcdtcsUnityUtils.ShowTilePolyDetails : Tile " + tileId + " does not exist.");
            return;
        }

        int detailMeshCount = tile.detailMeshes.Length;

        for (int i = 0; i < detailMeshCount; ++i)
        {
            Detour.dtPolyDetail pd   = tile.detailMeshes[i];
            Detour.dtPoly       poly = tile.polys[i];

            Color col = Color.green;            //new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value);

            for (int j = 0; j < pd.triCount; ++j)
            {
                int       tStart  = (int)(pd.triBase + j) * 4;
                int[]     vStarts = new int[3];
                float[][] vSrc    = new float[3][];
                for (int k = 0; k < 3; ++k)
                {
                    byte tk     = tile.detailTris[tStart + k];
                    byte vCount = poly.vertCount;
                    if (tk < vCount)
                    {
                        vStarts[k] = poly.verts[tk] * 3;
                        vSrc[k]    = tile.verts;
                    }
                    else
                    {
                        vStarts[k] = (int)(pd.vertBase + (tk - vCount)) * 3;
                        vSrc[k]    = tile.detailVerts;
                    }
                }
                Vector3 a = new Vector3(vSrc[0][vStarts[0] + 0], vSrc[0][vStarts[0] + 1], vSrc[0][vStarts[0] + 2]);
                Vector3 b = new Vector3(vSrc[1][vStarts[1] + 0], vSrc[1][vStarts[1] + 1], vSrc[1][vStarts[1] + 2]);
                Vector3 c = new Vector3(vSrc[2][vStarts[2] + 0], vSrc[2][vStarts[2] + 1], vSrc[2][vStarts[2] + 2]);

                col = VaryColor(col);
                renderMesh.AddTriangle(new DbgRenderTriangle(a, b, c, col));
            }
        }
        renderMesh.Rebuild();
    }
コード例 #4
0
        public bool Load(string path)
        {
            navMesh = DetourNavMeshLoader.Load(path);

            if (navMesh != null)
            {
                PrepareRender();
            }

            return(navMesh != null);
        }
コード例 #5
0
        static bool HandleMmapStatsCommand(StringArguments args, CommandHandler handler)
        {
            Player player       = handler.GetSession().GetPlayer();
            uint   terrainMapId = PhasingHandler.GetTerrainMapId(player.GetPhaseShift(), player.GetMap(), player.GetPositionX(), player.GetPositionY());

            handler.SendSysMessage("mmap stats:");
            handler.SendSysMessage("  global mmap pathfinding is {0}abled", Global.DisableMgr.IsPathfindingEnabled(player.GetMapId()) ? "En" : "Dis");
            handler.SendSysMessage(" {0} maps loaded with {1} tiles overall", Global.MMapMgr.getLoadedMapsCount(), Global.MMapMgr.getLoadedTilesCount());

            Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(terrainMapId);
            if (navmesh == null)
            {
                handler.SendSysMessage("NavMesh not loaded for current map.");
                return(true);
            }

            uint tileCount    = 0;
            int  nodeCount    = 0;
            int  polyCount    = 0;
            int  vertCount    = 0;
            int  triCount     = 0;
            int  triVertCount = 0;

            for (int i = 0; i < navmesh.getMaxTiles(); ++i)
            {
                Detour.dtMeshTile tile = navmesh.getTile(i);
                if (tile == null)
                {
                    continue;
                }

                tileCount++;
                nodeCount    += tile.header.bvNodeCount;
                polyCount    += tile.header.polyCount;
                vertCount    += tile.header.vertCount;
                triCount     += tile.header.detailTriCount;
                triVertCount += tile.header.detailVertCount;
            }

            handler.SendSysMessage("Navmesh stats:");
            handler.SendSysMessage(" {0} tiles loaded", tileCount);
            handler.SendSysMessage(" {0} BVTree nodes", nodeCount);
            handler.SendSysMessage(" {0} polygons ({1} vertices)", polyCount, vertCount);
            handler.SendSysMessage(" {0} triangles ({1} vertices)", triCount, triVertCount);
            return(true);
        }
コード例 #6
0
ファイル: RcdtcsSystemUtils.cs プロジェクト: zhu1987/rcdtcs
        public void ClearComputedData()
        {
            m_ctx = new Recast.BuildContext();

            m_triareas = null;
            m_solid    = null;
            m_chf      = null;
            m_cset     = null;
            m_pmesh    = null;
            m_cfg      = null;
            m_dmesh    = null;

            m_navMesh  = null;
            m_navQuery = null;

            m_bmin = new float[3];
            m_bmax = new float[3];
        }
コード例 #7
0
ファイル: RcdtcsSystemUtils.cs プロジェクト: zhu1987/rcdtcs
        public bool ComputeSystem(byte[] tileRawData, int start)
        {
            m_ctx.enableLog(true);

            m_ctx.resetTimers();

            // Start the build process.
            m_ctx.startTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            m_rawTileData = new Detour.dtRawTileData();
            m_rawTileData.FromBytes(tileRawData, start);

            m_navMesh = new Detour.dtNavMesh();
            if (m_navMesh == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not create Detour navmesh");
                return(false);
            }

            dtStatus status;

            status = m_navMesh.init(m_rawTileData, (int)Detour.dtTileFlags.DT_TILE_FREE_DATA);
            if (Detour.dtStatusFailed(status))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh");
                return(false);
            }

            m_navQuery = new Detour.dtNavMeshQuery();
            status     = m_navQuery.init(m_navMesh, 2048);
            if (Detour.dtStatusFailed(status))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh query");
                return(false);
            }

            m_ctx.stopTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            //m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, ">> Polymesh: " + m_pmesh.nverts + " vertices  " + m_pmesh.npolys + " polygons");

            m_totalBuildTimeMs = (float)m_ctx.getAccumulatedTime(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            return(true);
        }
コード例 #8
0
        bool loadMapData(uint mapId)
        {
            // we already have this map loaded?
            if (loadedMMaps.ContainsKey(mapId) && loadedMMaps[mapId] != null)
            {
                return(true);
            }

            // load and init dtNavMesh - read parameters from file
            string filename = string.Format(MAP_FILE_NAME_FORMAT, Global.WorldMgr.GetDataPath(), mapId);

            if (!File.Exists(filename))
            {
                Log.outError(LogFilter.Maps, "Could not open mmap file {0}", filename);
                return(false);
            }

            using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read), Encoding.UTF8))
            {
                Detour.dtNavMeshParams Params = new Detour.dtNavMeshParams();
                Params.orig[0] = reader.ReadSingle();
                Params.orig[1] = reader.ReadSingle();
                Params.orig[2] = reader.ReadSingle();

                Params.tileWidth  = reader.ReadSingle();
                Params.tileHeight = reader.ReadSingle();
                Params.maxTiles   = reader.ReadInt32();
                Params.maxPolys   = reader.ReadInt32();

                Detour.dtNavMesh mesh = new Detour.dtNavMesh();
                if (Detour.dtStatusFailed(mesh.init(Params)))
                {
                    Log.outError(LogFilter.Maps, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {0:D4} from file {1}", mapId, filename);
                    return(false);
                }

                Log.outInfo(LogFilter.Maps, "MMAP:loadMapData: Loaded {0:D4}.mmap", mapId);

                // store inside our map list
                loadedMMaps[mapId] = new MMapData(mesh, mapId);
                return(true);
            }
        }
コード例 #9
0
 public MMapData(Detour.dtNavMesh mesh)
 {
     navMesh = mesh;
 }
コード例 #10
0
 public MMapData(Detour.dtNavMesh mesh, uint mapId)
 {
     navMesh = mesh;
     _mapId  = mapId;
 }
コード例 #11
0
ファイル: RcdtcsSystemUtils.cs プロジェクト: jlalleve/rcdtcs
        public bool ComputeSystem(byte[] tileRawData, int start)
        {
            m_ctx.enableLog(true);

            m_ctx.resetTimers();

            // Start the build process.
            m_ctx.startTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            m_rawTileData = new Detour.dtRawTileData();
            m_rawTileData.FromBytes(tileRawData, start);

            m_navMesh = new Detour.dtNavMesh();
            if (m_navMesh == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not create Detour navmesh");
                return false;
            }

            dtStatus status;

            status = m_navMesh.init(m_rawTileData, (int)Detour.dtTileFlags.DT_TILE_FREE_DATA);
            if (Detour.dtStatusFailed(status)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh");
                return false;
            }

            m_navQuery = new Detour.dtNavMeshQuery();
            status = m_navQuery.init(m_navMesh, 2048);
            if (Detour.dtStatusFailed(status)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh query");
                return false;
            }

            m_ctx.stopTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            //m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, ">> Polymesh: " + m_pmesh.nverts + " vertices  " + m_pmesh.npolys + " polygons");

            m_totalBuildTimeMs = (float) m_ctx.getAccumulatedTime(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            return true;
        }
コード例 #12
0
ファイル: RcdtcsSystemUtils.cs プロジェクト: jlalleve/rcdtcs
        public void ClearComputedData()
        {
            m_ctx = new Recast.BuildContext();

            m_triareas = null;
            m_solid = null;
            m_chf = null;
            m_cset = null;
            m_pmesh = null;
            m_cfg = null;
            m_dmesh = null;

            m_navMesh = null;
            m_navQuery = null;

            m_bmin = new float[3];
            m_bmax = new float[3];
        }
コード例 #13
0
        static bool LocCommand(StringArguments args, CommandHandler handler)
        {
            handler.SendSysMessage("mmap tileloc:");

            // grid tile location
            Player player = handler.GetPlayer();

            int gx = (int)(32 - player.GetPositionX() / MapConst.SizeofGrids);
            int gy = (int)(32 - player.GetPositionY() / MapConst.SizeofGrids);

            float x, y, z;

            player.GetPosition(out x, out y, out z);

            handler.SendSysMessage("{0:D4}{1:D2}{2:D2}.mmtile", player.GetMapId(), gy, gx);
            handler.SendSysMessage("gridloc [{0}, {1}]", gx, gy);

            // calculate navmesh tile location
            uint terrainMapId = PhasingHandler.GetTerrainMapId(player.GetPhaseShift(), player.GetMap(), x, y);

            Detour.dtNavMesh      navmesh      = Global.MMapMgr.GetNavMesh(terrainMapId);
            Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, player.GetInstanceId());
            if (navmesh == null || navmeshquery == null)
            {
                handler.SendSysMessage("NavMesh not loaded for current map.");
                return(true);
            }

            float[] min      = navmesh.getParams().orig;
            float[] location = { y, z, x };
            float[] extents  = { 3.0f, 5.0f, 3.0f };

            int tilex = (int)((y - min[0]) / MapConst.SizeofGrids);
            int tiley = (int)((x - min[2]) / MapConst.SizeofGrids);

            handler.SendSysMessage("Calc   [{0:D2}, {1:D2}]", tilex, tiley);

            // navmesh poly . navmesh tile location
            Detour.dtQueryFilter filter = new Detour.dtQueryFilter();
            float[] nothing             = new float[3];
            ulong   polyRef             = 0;

            if (Detour.dtStatusFailed(navmeshquery.findNearestPoly(location, extents, filter, ref polyRef, ref nothing)))
            {
                handler.SendSysMessage("Dt     [??,??] (invalid poly, probably no tile loaded)");
                return(true);
            }

            if (polyRef == 0)
            {
                handler.SendSysMessage("Dt     [??, ??] (invalid poly, probably no tile loaded)");
            }
            else
            {
                Detour.dtMeshTile tile = new Detour.dtMeshTile();
                Detour.dtPoly     poly = new Detour.dtPoly();
                if (Detour.dtStatusSucceed(navmesh.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
                {
                    if (tile != null)
                    {
                        handler.SendSysMessage("Dt     [{0:D2},{1:D2}]", tile.header.x, tile.header.y);
                        return(false);
                    }
                }

                handler.SendSysMessage("Dt     [??,??] (no tile loaded)");
            }
            return(true);
        }
コード例 #14
0
ファイル: RcdtcsSystemUtils.cs プロジェクト: jlalleve/rcdtcs
        //Compute Recast and Detour navmesh
        public bool ComputeSystem()
        {
            ClearComputedData();

            Recast.rcCalcBounds(m_verts, m_vertCount, m_bmin, m_bmax);

            //
            // Step 1. Initialize build config.
            //

            // Init build configuration from GUI
            m_cfg = new Recast.rcConfig();

            m_cfg.cs = m_RecastMeshParams.m_cellSize;
            m_cfg.ch = m_RecastMeshParams.m_cellHeight;
            m_cfg.walkableSlopeAngle = m_RecastMeshParams.m_agentMaxSlope;
            m_cfg.walkableHeight = (int)Math.Ceiling(m_RecastMeshParams.m_agentHeight / m_cfg.ch);
            m_cfg.walkableClimb = (int)Math.Floor(m_RecastMeshParams.m_agentMaxClimb / m_cfg.ch);
            m_cfg.walkableRadius = (int)Math.Ceiling(m_RecastMeshParams.m_agentRadius / m_cfg.cs);
            m_cfg.maxEdgeLen = (int)(m_RecastMeshParams.m_edgeMaxLen / m_RecastMeshParams.m_cellSize);
            m_cfg.maxSimplificationError = m_RecastMeshParams.m_edgeMaxError;
            m_cfg.minRegionArea = (int)(m_RecastMeshParams.m_regionMinSize * m_RecastMeshParams.m_regionMinSize);		// Note: area = size*size
            m_cfg.mergeRegionArea = (int)(m_RecastMeshParams.m_regionMergeSize * m_RecastMeshParams.m_regionMergeSize);	// Note: area = size*size
            m_cfg.maxVertsPerPoly = (int)m_RecastMeshParams.m_vertsPerPoly;
            m_cfg.detailSampleDist = m_RecastMeshParams.m_detailSampleDist < 0.9f ? 0 : m_RecastMeshParams.m_cellSize * m_RecastMeshParams.m_detailSampleDist;
            m_cfg.detailSampleMaxError = m_RecastMeshParams.m_cellHeight * m_RecastMeshParams.m_detailSampleMaxError;

            // Set the area where the navigation will be build.
            // Here the bounds of the input mesh are used, but the
            // area could be specified by an user defined box, etc.
            Recast.rcVcopy(m_cfg.bmin, m_bmin);
            Recast.rcVcopy(m_cfg.bmax, m_bmax);
            Recast.rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, out m_cfg.width, out m_cfg.height);

            // Reset build times gathering.
            m_ctx.resetTimers();

            // Start the build process.
            m_ctx.startTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, "Building navigation:");
            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, " - " + m_cfg.width + " x " + m_cfg.height + " cells");
            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, " - " + m_vertCount / 1000.0f + "K verts, " + m_triCount / 1000.0f + "K tris");

            //
            // Step 2. Rasterize input polygon soup.
            //

            // Allocate voxel heightfield where we rasterize our input data to.
            m_solid = new Recast.rcHeightfield();
            if (m_solid == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
                return false;
            }
            if (!Recast.rcCreateHeightfield(m_ctx, m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
                return false;
            }

            // Allocate array that can hold triangle area types.
            // If you have multiple meshes you need to process, allocate
            // and array which can hold the max number of triangles you need to process.
            m_triareas = new byte[m_triCount];
            if (m_triareas == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (" + m_triCount + ").");
                return false;
            }

            // Find triangles which are walkable based on their slope and rasterize them.
            // If your input data is multiple meshes, you can transform them here, calculate
            // the are type for each of the meshes and rasterize them.
            //memset(m_triareas, 0, ntris*sizeof(byte));

            Recast.rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, m_verts, m_vertCount, m_tris, m_triCount, m_triareas);
            Recast.rcRasterizeTriangles(m_ctx, m_verts, m_vertCount, m_tris, m_triareas, m_triCount, m_solid, m_cfg.walkableClimb);

            if (!m_keepInterResults) {
                m_triareas = null;
            }

            //
            // Step 3. Filter walkables surfaces.
            //

            // Once all geoemtry is rasterized, we do initial pass of filtering to
            // remove unwanted overhangs caused by the conservative rasterization
            // as well as filter spans where the character cannot possibly stand.
            Recast.rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, m_solid);
            Recast.rcFilterLedgeSpans(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, m_solid);
            Recast.rcFilterWalkableLowHeightSpans(m_ctx, m_cfg.walkableHeight, m_solid);

            //
            // Step 4. Partition walkable surface to simple regions.
            //

            // Compact the heightfield so that it is faster to handle from now on.
            // This will result more cache coherent data as well as the neighbours
            // between walkable cells will be calculated.
            m_chf = new Recast.rcCompactHeightfield();
            if (m_chf == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
                return false;
            }
            if (!Recast.rcBuildCompactHeightfield(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, m_solid, m_chf)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
                return false;
            }

            if (!m_keepInterResults) {
                m_solid = null;
            }

            // Erode the walkable area by agent radius.
            if (!Recast.rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, m_chf)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not erode.");
                return false;
            }

            /*
                // (Optional) Mark areas.
                ConvexVolume[] vols = m_geom.getConvexVolumes();
                for (int i  = 0; i < m_geom.getConvexVolumeCount(); ++i)
                    rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (byte)vols[i].area, *m_chf);
                */

            if (m_RecastMeshParams.m_monotonePartitioning) {
                // Partition the walkable surface into simple regions without holes.
                // Monotone partitioning does not need distancefield.
                if (!Recast.rcBuildRegionsMonotone(m_ctx, m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea)) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build regions.");
                    return false;
                }
            } else {
                // Prepare for region partitioning, by calculating distance field along the walkable surface.
                if (!Recast.rcBuildDistanceField(m_ctx, m_chf)) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
                    return false;
                }

                // Partition the walkable surface into simple regions without holes.
                if (!Recast.rcBuildRegions(m_ctx, m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea)) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build regions.");
                    return false;
                }
            }

            //
            // Step 5. Trace and simplify region contours.
            //

            // Create contours.
            m_cset = new Recast.rcContourSet();
            if (m_cset == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
                return false;
            }
            if (!Recast.rcBuildContours(m_ctx, m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, m_cset, -1)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not create contours.");
                return false;
            }

            //m_cset.dumpToTxt("Data/CSET_dump.txt");

            //
            // Step 6. Build polygons mesh from contours.
            //

            // Build polygon navmesh from the contours.
            m_pmesh = new Recast.rcPolyMesh();
            if (m_pmesh == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
                return false;
            }
            if (!Recast.rcBuildPolyMesh(m_ctx, m_cset, m_cfg.maxVertsPerPoly, m_pmesh)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
                return false;
            }

            //m_pmesh.dumpToObj("Data/navmesh.obj");
            //m_pmesh.dumpToText("Data/navmesh.txt");

            //
            // Step 7. Create detail mesh which allows to access approximate height on each polygon.
            //

            m_dmesh = new Recast.rcPolyMeshDetail();//rcAllocPolyMeshDetail();
            if (m_dmesh == null) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'.");
                return false;
            }

            if (!Recast.rcBuildPolyMeshDetail(m_ctx, m_pmesh, m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, m_dmesh)) {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build detail mesh.");
                return false;
            }

            //m_dmesh.dumpToText("Data/polymeshdetail_cs.txt");
            //m_dmesh.dumpToObj("Data/polymeshdetail_cs.obj");

            if (!m_keepInterResults) {

                m_chf = null;
                m_cset = null;
            }

            // At this point the navigation mesh data is ready, you can access it from m_pmesh.
            // See duDebugDrawPolyMesh or dtCreateNavMeshData as examples how to access the data.

            //
            // (Optional) Step 8. Create Detour data from Recast poly mesh.
            //

            // The GUI may allow more max points per polygon than Detour can handle.
            // Only build the detour navmesh if we do not exceed the limit.
            if (m_cfg.maxVertsPerPoly <= Detour.DT_VERTS_PER_POLYGON) {
                //unsigned char* navData = 0;
                Detour.dtRawTileData navData = null;
                //int navDataSize = 0;

                // Update poly flags from areas.
                for (int i = 0; i < m_pmesh.npolys; ++i) {
                    if (m_pmesh.areas[i] == Recast.RC_WALKABLE_AREA)
                        m_pmesh.areas[i] = (byte)SamplePolyAreas.GROUND;

                    if (m_pmesh.areas[i] == (byte)SamplePolyAreas.GROUND) {
                        m_pmesh.flags[i] = (ushort)SamplePolyFlags.WALK;
                    }

                    /*
                        if (m_pmesh.areas[i] == Recast.RC_WALKABLE_AREA)
                            m_pmesh.areas[i] =  SAMPLE_POLYAREA_GROUND;

                        if (m_pmesh.areas[i] == SAMPLE_POLYAREA_GROUND ||
                            m_pmesh.areas[i] == SAMPLE_POLYAREA_GRASS ||
                            m_pmesh.areas[i] == SAMPLE_POLYAREA_ROAD)
                        {
                            m_pmesh.flags[i] = SAMPLE_POLYFLAGS_WALK;
                        }
                        else if (m_pmesh.areas[i] == SAMPLE_POLYAREA_WATER)
                        {
                            m_pmesh.flags[i] = SAMPLE_POLYFLAGS_SWIM;
                        }
                        else if (m_pmesh.areas[i] == SAMPLE_POLYAREA_DOOR)
                        {
                            m_pmesh.flags[i] = SAMPLE_POLYFLAGS_WALK | SAMPLE_POLYFLAGS_DOOR;
                        }*/
                }

                Detour.dtNavMeshCreateParams navMeshCreateParams = new Detour.dtNavMeshCreateParams();
                navMeshCreateParams.verts = m_pmesh.verts;
                navMeshCreateParams.vertCount = m_pmesh.nverts;
                navMeshCreateParams.polys = m_pmesh.polys;
                navMeshCreateParams.polyAreas = m_pmesh.areas;
                navMeshCreateParams.polyFlags = m_pmesh.flags;
                navMeshCreateParams.polyCount = m_pmesh.npolys;
                navMeshCreateParams.nvp = m_pmesh.nvp;
                navMeshCreateParams.detailMeshes = m_dmesh.meshes;
                navMeshCreateParams.detailVerts = m_dmesh.verts;
                navMeshCreateParams.detailVertsCount = m_dmesh.nverts;
                navMeshCreateParams.detailTris = m_dmesh.tris;
                navMeshCreateParams.detailTriCount = m_dmesh.ntris;
                navMeshCreateParams.offMeshConVerts = null;//m_geom.getOffMeshConnectionVerts();
                navMeshCreateParams.offMeshConRad = null;//m_geom.getOffMeshConnectionRads();
                navMeshCreateParams.offMeshConDir = null;//m_geom.getOffMeshConnectionDirs();
                navMeshCreateParams.offMeshConAreas = null;//m_geom.getOffMeshConnectionAreas();
                navMeshCreateParams.offMeshConFlags = null;//m_geom.getOffMeshConnectionFlags();
                navMeshCreateParams.offMeshConUserID = null;//m_geom.getOffMeshConnectionId();
                navMeshCreateParams.offMeshConCount = 0;//m_geom.getOffMeshConnectionCount();
                navMeshCreateParams.walkableHeight = m_RecastMeshParams.m_agentHeight;
                navMeshCreateParams.walkableRadius = m_RecastMeshParams.m_agentRadius;
                navMeshCreateParams.walkableClimb = m_RecastMeshParams.m_agentMaxClimb;
                Recast.rcVcopy(navMeshCreateParams.bmin, m_pmesh.bmin);
                Recast.rcVcopy(navMeshCreateParams.bmax, m_pmesh.bmax);
                navMeshCreateParams.cs = m_cfg.cs;
                navMeshCreateParams.ch = m_cfg.ch;
                navMeshCreateParams.buildBvTree = true;

                if (!Detour.dtCreateNavMeshData(navMeshCreateParams, out navData)) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not build Detour navmesh.");
                    return false;
                }

                m_navMesh = new Detour.dtNavMesh();
                if (m_navMesh == null) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not create Detour navmesh");
                    return false;
                }

                dtStatus status;

                status = m_navMesh.init(navData, (int)Detour.dtTileFlags.DT_TILE_FREE_DATA);
                if (Detour.dtStatusFailed(status)) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh");
                    return false;
                }

                m_navQuery = new Detour.dtNavMeshQuery();
                status = m_navQuery.init(m_navMesh, 2048);
                if (Detour.dtStatusFailed(status)) {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh query");
                    return false;
                }

                m_rawTileData = navData;
            } else {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_WARNING, "Detour does not support more than " + Detour.DT_VERTS_PER_POLYGON + " verts per polygon. A navmesh has not been generated.");
            }

            m_ctx.stopTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            // Show performance stats.
            m_ctx.logBuildTimes();
            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, ">> Polymesh: " + m_pmesh.nverts + " vertices  " + m_pmesh.npolys + " polygons");

            m_totalBuildTimeMs = (float) m_ctx.getAccumulatedTime(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            return true;
        }
コード例 #15
0
ファイル: RcdtcsSystemUtils.cs プロジェクト: zhu1987/rcdtcs
        //Compute Recast and Detour navmesh
        public bool ComputeSystem()
        {
            ClearComputedData();

            Recast.rcCalcBounds(m_verts, m_vertCount, m_bmin, m_bmax);

            //
            // Step 1. Initialize build config.
            //

            // Init build configuration from GUI
            m_cfg = new Recast.rcConfig();

            m_cfg.cs = m_RecastMeshParams.m_cellSize;
            m_cfg.ch = m_RecastMeshParams.m_cellHeight;
            m_cfg.walkableSlopeAngle     = m_RecastMeshParams.m_agentMaxSlope;
            m_cfg.walkableHeight         = (int)Math.Ceiling(m_RecastMeshParams.m_agentHeight / m_cfg.ch);
            m_cfg.walkableClimb          = (int)Math.Floor(m_RecastMeshParams.m_agentMaxClimb / m_cfg.ch);
            m_cfg.walkableRadius         = (int)Math.Ceiling(m_RecastMeshParams.m_agentRadius / m_cfg.cs);
            m_cfg.maxEdgeLen             = (int)(m_RecastMeshParams.m_edgeMaxLen / m_RecastMeshParams.m_cellSize);
            m_cfg.maxSimplificationError = m_RecastMeshParams.m_edgeMaxError;
            m_cfg.minRegionArea          = (int)(m_RecastMeshParams.m_regionMinSize * m_RecastMeshParams.m_regionMinSize);              // Note: area = size*size
            m_cfg.mergeRegionArea        = (int)(m_RecastMeshParams.m_regionMergeSize * m_RecastMeshParams.m_regionMergeSize);          // Note: area = size*size
            m_cfg.maxVertsPerPoly        = (int)m_RecastMeshParams.m_vertsPerPoly;
            m_cfg.detailSampleDist       = m_RecastMeshParams.m_detailSampleDist < 0.9f ? 0 : m_RecastMeshParams.m_cellSize * m_RecastMeshParams.m_detailSampleDist;
            m_cfg.detailSampleMaxError   = m_RecastMeshParams.m_cellHeight * m_RecastMeshParams.m_detailSampleMaxError;

            // Set the area where the navigation will be build.
            // Here the bounds of the input mesh are used, but the
            // area could be specified by an user defined box, etc.
            Recast.rcVcopy(m_cfg.bmin, m_bmin);
            Recast.rcVcopy(m_cfg.bmax, m_bmax);
            Recast.rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, out m_cfg.width, out m_cfg.height);

            // Reset build times gathering.
            m_ctx.resetTimers();

            // Start the build process.
            m_ctx.startTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, "Building navigation:");
            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, " - " + m_cfg.width + " x " + m_cfg.height + " cells");
            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, " - " + m_vertCount / 1000.0f + "K verts, " + m_triCount / 1000.0f + "K tris");

            //
            // Step 2. Rasterize input polygon soup.
            //

            // Allocate voxel heightfield where we rasterize our input data to.
            m_solid = new Recast.rcHeightfield();
            if (m_solid == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
                return(false);
            }
            if (!Recast.rcCreateHeightfield(m_ctx, m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
                return(false);
            }

            // Allocate array that can hold triangle area types.
            // If you have multiple meshes you need to process, allocate
            // and array which can hold the max number of triangles you need to process.
            m_triareas = new byte[m_triCount];
            if (m_triareas == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (" + m_triCount + ").");
                return(false);
            }

            // Find triangles which are walkable based on their slope and rasterize them.
            // If your input data is multiple meshes, you can transform them here, calculate
            // the are type for each of the meshes and rasterize them.
            //memset(m_triareas, 0, ntris*sizeof(byte));

            Recast.rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, m_verts, m_vertCount, m_tris, m_triCount, m_triareas);
            Recast.rcRasterizeTriangles(m_ctx, m_verts, m_vertCount, m_tris, m_triareas, m_triCount, m_solid, m_cfg.walkableClimb);

            if (!m_keepInterResults)
            {
                m_triareas = null;
            }

            //
            // Step 3. Filter walkables surfaces.
            //

            // Once all geoemtry is rasterized, we do initial pass of filtering to
            // remove unwanted overhangs caused by the conservative rasterization
            // as well as filter spans where the character cannot possibly stand.
            Recast.rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, m_solid);
            Recast.rcFilterLedgeSpans(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, m_solid);
            Recast.rcFilterWalkableLowHeightSpans(m_ctx, m_cfg.walkableHeight, m_solid);


            //
            // Step 4. Partition walkable surface to simple regions.
            //

            // Compact the heightfield so that it is faster to handle from now on.
            // This will result more cache coherent data as well as the neighbours
            // between walkable cells will be calculated.
            m_chf = new Recast.rcCompactHeightfield();
            if (m_chf == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
                return(false);
            }
            if (!Recast.rcBuildCompactHeightfield(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, m_solid, m_chf))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
                return(false);
            }

            if (!m_keepInterResults)
            {
                m_solid = null;
            }

            // Erode the walkable area by agent radius.
            if (!Recast.rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, m_chf))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not erode.");
                return(false);
            }

            /*
             * // (Optional) Mark areas.
             * ConvexVolume[] vols = m_geom.getConvexVolumes();
             * for (int i  = 0; i < m_geom.getConvexVolumeCount(); ++i)
             * rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (byte)vols[i].area, *m_chf);
             */

            if (m_RecastMeshParams.m_monotonePartitioning)
            {
                // Partition the walkable surface into simple regions without holes.
                // Monotone partitioning does not need distancefield.
                if (!Recast.rcBuildRegionsMonotone(m_ctx, m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea))
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build regions.");
                    return(false);
                }
            }
            else
            {
                // Prepare for region partitioning, by calculating distance field along the walkable surface.
                if (!Recast.rcBuildDistanceField(m_ctx, m_chf))
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
                    return(false);
                }

                // Partition the walkable surface into simple regions without holes.
                if (!Recast.rcBuildRegions(m_ctx, m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea))
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build regions.");
                    return(false);
                }
            }

            //
            // Step 5. Trace and simplify region contours.
            //

            // Create contours.
            m_cset = new Recast.rcContourSet();
            if (m_cset == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
                return(false);
            }
            if (!Recast.rcBuildContours(m_ctx, m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, m_cset, -1))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not create contours.");
                return(false);
            }

            //m_cset.dumpToTxt("Data/CSET_dump.txt");

            //
            // Step 6. Build polygons mesh from contours.
            //

            // Build polygon navmesh from the contours.
            m_pmesh = new Recast.rcPolyMesh();
            if (m_pmesh == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
                return(false);
            }
            if (!Recast.rcBuildPolyMesh(m_ctx, m_cset, m_cfg.maxVertsPerPoly, m_pmesh))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
                return(false);
            }

            //m_pmesh.dumpToObj("Data/navmesh.obj");
            //m_pmesh.dumpToText("Data/navmesh.txt");

            //
            // Step 7. Create detail mesh which allows to access approximate height on each polygon.
            //

            m_dmesh = new Recast.rcPolyMeshDetail();            //rcAllocPolyMeshDetail();
            if (m_dmesh == null)
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'.");
                return(false);
            }

            if (!Recast.rcBuildPolyMeshDetail(m_ctx, m_pmesh, m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, m_dmesh))
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "buildNavigation: Could not build detail mesh.");
                return(false);
            }

            //m_dmesh.dumpToText("Data/polymeshdetail_cs.txt");
            //m_dmesh.dumpToObj("Data/polymeshdetail_cs.obj");

            if (!m_keepInterResults)
            {
                m_chf  = null;
                m_cset = null;
            }

            // At this point the navigation mesh data is ready, you can access it from m_pmesh.
            // See duDebugDrawPolyMesh or dtCreateNavMeshData as examples how to access the data.

            //
            // (Optional) Step 8. Create Detour data from Recast poly mesh.
            //

            // The GUI may allow more max points per polygon than Detour can handle.
            // Only build the detour navmesh if we do not exceed the limit.
            if (m_cfg.maxVertsPerPoly <= Detour.DT_VERTS_PER_POLYGON)
            {
                //unsigned char* navData = 0;
                Detour.dtRawTileData navData = null;
                //int navDataSize = 0;

                // Update poly flags from areas.
                for (int i = 0; i < m_pmesh.npolys; ++i)
                {
                    if (m_pmesh.areas[i] == Recast.RC_WALKABLE_AREA)
                    {
                        m_pmesh.areas[i] = (byte)SamplePolyAreas.GROUND;
                    }

                    if (m_pmesh.areas[i] == (byte)SamplePolyAreas.GROUND)
                    {
                        m_pmesh.flags[i] = (ushort)SamplePolyFlags.WALK;
                    }

                    /*
                     * if (m_pmesh.areas[i] == Recast.RC_WALKABLE_AREA)
                     * m_pmesh.areas[i] =  SAMPLE_POLYAREA_GROUND;
                     *
                     * if (m_pmesh.areas[i] == SAMPLE_POLYAREA_GROUND ||
                     * m_pmesh.areas[i] == SAMPLE_POLYAREA_GRASS ||
                     * m_pmesh.areas[i] == SAMPLE_POLYAREA_ROAD)
                     * {
                     * m_pmesh.flags[i] = SAMPLE_POLYFLAGS_WALK;
                     * }
                     * else if (m_pmesh.areas[i] == SAMPLE_POLYAREA_WATER)
                     * {
                     * m_pmesh.flags[i] = SAMPLE_POLYFLAGS_SWIM;
                     * }
                     * else if (m_pmesh.areas[i] == SAMPLE_POLYAREA_DOOR)
                     * {
                     * m_pmesh.flags[i] = SAMPLE_POLYFLAGS_WALK | SAMPLE_POLYFLAGS_DOOR;
                     * }*/
                }

                Detour.dtNavMeshCreateParams navMeshCreateParams = new Detour.dtNavMeshCreateParams();
                navMeshCreateParams.verts            = m_pmesh.verts;
                navMeshCreateParams.vertCount        = m_pmesh.nverts;
                navMeshCreateParams.polys            = m_pmesh.polys;
                navMeshCreateParams.polyAreas        = m_pmesh.areas;
                navMeshCreateParams.polyFlags        = m_pmesh.flags;
                navMeshCreateParams.polyCount        = m_pmesh.npolys;
                navMeshCreateParams.nvp              = m_pmesh.nvp;
                navMeshCreateParams.detailMeshes     = m_dmesh.meshes;
                navMeshCreateParams.detailVerts      = m_dmesh.verts;
                navMeshCreateParams.detailVertsCount = m_dmesh.nverts;
                navMeshCreateParams.detailTris       = m_dmesh.tris;
                navMeshCreateParams.detailTriCount   = m_dmesh.ntris;
                navMeshCreateParams.offMeshConVerts  = null;            //m_geom.getOffMeshConnectionVerts();
                navMeshCreateParams.offMeshConRad    = null;            //m_geom.getOffMeshConnectionRads();
                navMeshCreateParams.offMeshConDir    = null;            //m_geom.getOffMeshConnectionDirs();
                navMeshCreateParams.offMeshConAreas  = null;            //m_geom.getOffMeshConnectionAreas();
                navMeshCreateParams.offMeshConFlags  = null;            //m_geom.getOffMeshConnectionFlags();
                navMeshCreateParams.offMeshConUserID = null;            //m_geom.getOffMeshConnectionId();
                navMeshCreateParams.offMeshConCount  = 0;               //m_geom.getOffMeshConnectionCount();
                navMeshCreateParams.walkableHeight   = m_RecastMeshParams.m_agentHeight;
                navMeshCreateParams.walkableRadius   = m_RecastMeshParams.m_agentRadius;
                navMeshCreateParams.walkableClimb    = m_RecastMeshParams.m_agentMaxClimb;
                Recast.rcVcopy(navMeshCreateParams.bmin, m_pmesh.bmin);
                Recast.rcVcopy(navMeshCreateParams.bmax, m_pmesh.bmax);
                navMeshCreateParams.cs          = m_cfg.cs;
                navMeshCreateParams.ch          = m_cfg.ch;
                navMeshCreateParams.buildBvTree = true;

                if (!Detour.dtCreateNavMeshData(navMeshCreateParams, out navData))
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not build Detour navmesh.");
                    return(false);
                }

                m_navMesh = new Detour.dtNavMesh();
                if (m_navMesh == null)
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not create Detour navmesh");
                    return(false);
                }

                dtStatus status;

                status = m_navMesh.init(navData, (int)Detour.dtTileFlags.DT_TILE_FREE_DATA);
                if (Detour.dtStatusFailed(status))
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh");
                    return(false);
                }

                m_navQuery = new Detour.dtNavMeshQuery();
                status     = m_navQuery.init(m_navMesh, 2048);
                if (Detour.dtStatusFailed(status))
                {
                    m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh query");
                    return(false);
                }

                m_rawTileData = navData;
            }
            else
            {
                m_ctx.log(Recast.rcLogCategory.RC_LOG_WARNING, "Detour does not support more than " + Detour.DT_VERTS_PER_POLYGON + " verts per polygon. A navmesh has not been generated.");
            }

            m_ctx.stopTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            // Show performance stats.
            m_ctx.logBuildTimes();
            m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, ">> Polymesh: " + m_pmesh.nverts + " vertices  " + m_pmesh.npolys + " polygons");

            m_totalBuildTimeMs = (float)m_ctx.getAccumulatedTime(Recast.rcTimerLabel.RC_TIMER_TOTAL);

            return(true);
        }
コード例 #16
0
ファイル: NavMesh.cs プロジェクト: jondwillis/EasyFarm
 public void Unload()
 {
     dtNavMesh = null;
 }
コード例 #17
0
ファイル: NavMesh.cs プロジェクト: jondwillis/EasyFarm
    public bool LoadZone(Zone zone)

    {
        if (zone == Zone.Unknown)
        {
            Unload();
            return(false);
        }

        string path = "navmeshes\\" + zone.ToString() + ".nav";

        if (_zone == zone && dtNavMesh != null)
        {
            return(true);
        }
        else
        {
            Unload();
        }

        _zone = zone;

        var headerBufferSize = NavMeshSetHeader.ByteSize();
        var headerBuffer     = new byte[headerBufferSize];

        if (!File.Exists(path))
        {
            return(false);
        }

        var file = File.OpenRead(path);

        file.Read(headerBuffer, 0, headerBufferSize);

        NavMeshSetHeader header = new NavMeshSetHeader();
        var headerBytesRead     = header.FromBytes(headerBuffer, 0);

        if (header.magic != NAVMESHSET_MAGIC)
        {
            return(false);
        }

        if (header.version != NAVMESHSET_VERSION)
        {
            return(false);
        }

        var navMesh = new Detour.dtNavMesh();

        navMesh.init(header.meshParams);

        for (int i = 0; i < header.numTiles; ++i)
        {
            var tileHeaderBuffer = new byte[NavMeshTileHeader.ByteSize()];
            file.Read(tileHeaderBuffer, 0, tileHeaderBuffer.Length);
            var tileHeader = new NavMeshTileHeader();
            tileHeader.FromBytes(tileHeaderBuffer, 0);
            if (tileHeader.dataSize == 0 || tileHeader.tileRef == 0)
            {
                break;
            }
            var rawTileData = new Detour.dtRawTileData();
            var data        = new byte[tileHeader.dataSize];
            file.Read(data, 0, data.Length);
            rawTileData.FromBytes(data, 0);
            uint result = 0;
            navMesh.addTile(rawTileData, tileHeader.dataSize, 0x01 /*DT_TILE_FREE_DATA*/, tileHeader.tileRef, ref result);
            if (Detour.dtStatusFailed(result))
            {
                return(false);
            }
        }

        // hard-code to make sure it is compatible with expectation.
        var maxPolys = header.meshParams.maxPolys;

        var status = new Detour.dtNavMeshQuery().init(navMesh, maxPolys);

        if (Detour.dtStatusFailed(status))
        {
            return(false);
        }

        dtNavMesh = navMesh;

        return(headerBytesRead > 0);
    }