예제 #1
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);
    }
예제 #2
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();
    }
예제 #3
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);
        }