示例#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
    // This function checks if the path has a small U-turn, that is,
    // a polygon further in the path is adjacent to the first polygon
    // in the path. If that happens, a shortcut is taken.
    // This can happen if the target (T) location is at tile boundary,
    // and we're (S) approaching it parallel to the tile edge.
    // The choice at the vertex can be arbitrary,
    //  +---+---+
    //  |:::|:::|
    //  +-S-+-T-+
    //  |:::|   | <-- the step can end up in here, resulting U-turn path.
    //  +---+---+
    static int fixupShortcuts(dtPolyRef[] path, int npath, Detour.dtNavMeshQuery navQuery)
    {
        if (npath < 3)
        {
            return(npath);
        }

        // Get connected polygons
        const int maxNeis = 16;

        dtPolyRef[] neis  = new dtPolyRef[maxNeis];
        int         nneis = 0;

        Detour.dtMeshTile tile = null;
        Detour.dtPoly     poly = null;
        if (Detour.dtStatusFailed(navQuery.getAttachedNavMesh().getTileAndPolyByRef(path[0], ref tile, ref poly)))
        {
            return(npath);
        }

        for (uint k = poly.firstLink; k != Detour.DT_NULL_LINK; k = tile.links[k].next)
        {
            Detour.dtLink link = tile.links[k];
            if (link.polyRef != 0)
            {
                if (nneis < maxNeis)
                {
                    neis[nneis++] = link.polyRef;
                }
            }
        }

        // If any of the neighbour polygons is within the next few polygons
        // in the path, short cut to that polygon directly.
        const int maxLookAhead = 6;
        int       cut          = 0;

        for (int i = Math.Min(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--)
        {
            for (int j = 0; j < nneis; j++)
            {
                if (path[i] == neis[j])
                {
                    cut = i;
                    break;
                }
            }
        }
        if (cut > 1)
        {
            int offset = cut - 1;
            npath -= offset;
            for (int i = 1; i < npath; i++)
            {
                path[i] = path[i + offset];
            }
        }

        return(npath);
    }
示例#3
0
        private void PrepareRender()
        {
            // Add to scene after building a mesh

            vertices = new List <Vertex>();
            indices  = new List <int>();

            for (int i = 0; i < navMesh.getMaxTiles(); ++i)
            {
                Detour.dtMeshTile tile = navMesh.getTile(i);

                if (tile.header != null)
                {
                    AddMeshTile(tile);
                }
            }

            var geom = new Mesh();

            geom.Load(vertices, indices, indices.Count / 3);

            var mat = new MaterialDiffuse()
            {
                ShaderProgram = "diffuse", Tex = ""
            };

            node = new Scene.Node()
            {
                Name = "NaviMesh", Material = mat, Mesh = geom
            };
            scene.Add(node);
        }
示例#4
0
        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);
        }
示例#5
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();
    }
示例#6
0
        void AddSwap(PhasedTile ptile, uint swap, uint packedXY)
        {
            uint x = (packedXY >> 16);
            uint y = (packedXY & 0x0000FFFF);

            if (!loadedTileRefs.ContainsKey(packedXY))
            {
                Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: phased mmtile {0:D4}[{1:D2}, {2:D2}] load skipped, due to not loaded base tile on map {3}", swap, x, y, _mapId);
                return;
            }
            if (loadedPhasedTiles[swap].Contains(packedXY))
            {
                Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: WARNING! phased mmtile {0:D4}[{1:D2}, {2:D2}] load skipped, due to already loaded on map {3}", swap, x, y, _mapId);
                return;
            }

            Detour.dtMeshHeader header = ptile.data.header;

            Detour.dtMeshTile oldTile = navMesh.getTileByRef(loadedTileRefs[packedXY]);
            if (oldTile == null)
            {
                Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: phased mmtile {0:D4}[{1:D2}, {2:D2}] load skipped, due to not loaded base tile ref on map {3}", swap, x, y, _mapId);
                return;
            }

            // header xy is based on the swap map's tile set, wich doesn't have all the same tiles as root map, so copy the xy from the orignal header
            header.x = oldTile.header.x;
            header.y = oldTile.header.y;

            Detour.dtRawTileData data;
            // remove old tile
            if (Detour.dtStatusFailed(navMesh.removeTile(loadedTileRefs[packedXY], out data)))
            {
                Log.outError(LogFilter.Maps, "MMapData.AddSwap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", _mapId, x, y);
            }
            else
            {
                Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: Unloaded {0:D4}{1:D2}{2:D2}.mmtile from navmesh", _mapId, x, y);

                _activeSwaps.Add(swap);
                loadedPhasedTiles.Add(swap, packedXY);

                // add new swapped tile
                ulong loadedRef = 0;
                if (Detour.dtStatusSucceed(navMesh.addTile(ptile.data, 0, 0, ref loadedRef)))
                {
                    Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: Loaded phased mmtile {0:D4}[{1:D2}, {2:D2}] into {0:D4}[{1:D2}, {2:D2}]", swap, x, y, _mapId, header.x, header.y);
                }
                else
                {
                    Log.outError(LogFilter.Maps, "MMapData.AddSwap: Could not load {0:D4}{1:D2}{2:D2}.mmtile to navmesh", swap, x, y);
                }

                loadedTileRefs[packedXY] = loadedRef;
            }
        }
示例#7
0
        private void AddMeshTile(Detour.dtMeshTile tile)
        {
            var  basePoly = navMesh.getPolyRefBase(tile);
            uint tileNum  = navMesh.decodePolyIdTile(basePoly);

            for (int i = 0; i < tile.header.polyCount; ++i)
            {
                var p = tile.polys[i];

                if (p.getType() == (byte)Detour.dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)                 // Skip off-mesh links.
                {
                    continue;
                }

                var pd = tile.detailMeshes[i];

                for (int j = 0; j < pd.triCount; ++j)
                {
                    var triIndex = (pd.triBase + j) * 4;

                    for (int k = 0; k < 3; ++k)
                    {
                        if (tile.detailTris[triIndex + k] < p.vertCount)
                        {
                            var detailIndex = tile.detailTris[triIndex + k];
                            var vertIndex   = p.verts[detailIndex] * 3;
                            var vertex      = new Vertex()
                            {
                                Position = new OpenTK.Vector3(tile.verts[vertIndex + 0], tile.verts[vertIndex + 2], tile.verts[vertIndex + 1]),
                                Normal   = new OpenTK.Vector3(),
                                Color    = new OpenTK.Vector4(0, 0, 1, 1)
                            };
                            vertices.Add(vertex);
                            indices.Add(vertices.Count - 1);
                        }
                        else
                        {
                            var detailIndex = tile.detailTris[triIndex + k];
                            var vertIndex   = (pd.vertBase + detailIndex - p.vertCount) * 3;
                            var vertex      = new Vertex()
                            {
                                Position = new OpenTK.Vector3(tile.detailVerts[vertIndex + 0], tile.detailVerts[vertIndex + 2], tile.detailVerts[vertIndex + 1]),
                                Normal   = new OpenTK.Vector3(),
                                Color    = new OpenTK.Vector4(0, 0, 1, 1)
                            };
                            vertices.Add(vertex);
                            indices.Add(vertices.Count - 1);
                        }
                    }
                }
            }
        }
示例#8
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);
        }
示例#9
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);
        }