Ejemplo n.º 1
0
void PathInfo::Build()
{
    float x, y, z;
    // set start and a default next position
    m_sourceObject->GetPosition(x, y, z);
    setStartPosition(x, y, z);
    setNextPosition(x, y, z);

    // get nav mesh
    m_navMesh = m_sourceObject->GetMap()->GetNavMesh();

    if(!m_navMesh)
    {
        // if there is no navmesh, just move to destination
        shortcut();
        return;
    }

    float extents[3] = {2.0f, 4.0f, 2.0f};      // defines bounds of box for search area
    dtQueryFilter filter = dtQueryFilter();     // use general filter so we know if we are near navmesh

    // get start and end positions
    getStartPosition(x, y, z);
    float startPos[3] = {y, z, x};
    getEndPosition(x, y, z);
    float endPos[3] = {y, z, x};

    // find start and end poly
    dtPolyRef startPoly = m_navMesh->findNearestPoly(startPos, extents, &filter, 0);
    dtPolyRef endPoly = m_navMesh->findNearestPoly(endPos, extents, &filter, 0);

    Build(startPoly, endPoly);
}
Ejemplo n.º 2
0
        static bool HandleMmapLocCommand(ChatHandler* handler, const char* /*args*/)
        {
            handler->PSendSysMessage("mmap tileloc:");

            // grid tile location
            Player* player = handler->GetSession()->GetPlayer();

            int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
            int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;

            handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx);
            handler->PSendSysMessage("gridloc [%i,%i]", gx, gy);

            // calculate navmesh tile location
            const dtNavMesh* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(player->GetMapId());
            const dtNavMeshQuery* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(player->GetMapId(), player->GetInstanceId());
            if (!navmesh || !navmeshquery)
            {
                handler->PSendSysMessage("NavMesh not loaded for current map.");
                return true;
            }

            const float* min = navmesh->getParams()->orig;

            float x, y, z;
            player->GetPosition(x, y, z);
            float location[VERTEX_SIZE] = {y, z, x};
            float extents[VERTEX_SIZE] = {2.f,4.f,2.f};

            int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
            int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);

            handler->PSendSysMessage("Calc   [%02i,%02i]", tilex, tiley);

            // navmesh poly -> navmesh tile location
            dtQueryFilter filter = dtQueryFilter();
            dtPolyRef polyRef = INVALID_POLYREF;
            navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL);

            if (polyRef == INVALID_POLYREF)
                handler->PSendSysMessage("Dt     [??,??] (invalid poly, probably no tile loaded)");
            else
            {
                const dtMeshTile* tile;
                const dtPoly* poly;
                navmesh->getTileAndPolyByRef(polyRef, &tile, &poly);
                if (tile)
                    handler->PSendSysMessage("Dt     [%02i,%02i]", tile->header->x, tile->header->y);
                else
                    handler->PSendSysMessage("Dt     [??,??] (no tile loaded)");
            }

            return true;
        }
Ejemplo n.º 3
0
void Sample_Debug::setHighlightedTile(const float* pos)
{

	if (!pos || !m_navMesh)
	{
		m_highLightedTileX = -1;
		m_highLightedTileY = -1;
		return;
	}
    float extents[3] = {2.f, 4.f, 2.f};
    dtPolyRef polyRef = m_navMesh->findNearestPoly(pos, extents, &dtQueryFilter(), 0);
    unsigned char area = m_navMesh->getPolyArea(polyRef);
    unsigned short flags = m_navMesh->getPolyFlags(polyRef);
    const dtMeshTile* tile = m_navMesh->getTileByPolyRef(polyRef, 0);
    if(!tile)
    {
		m_highLightedTileX = -1;
		m_highLightedTileY = -1;
		return;
    }
    m_highLightedTileX = tile->header->x;
	m_highLightedTileY = tile->header->y;
}
Ejemplo n.º 4
0
    static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/)
    {
        handler->PSendSysMessage("mmap tileloc:");

        // grid tile location
        Player* player = handler->GetSession()->GetPlayer();

        int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
        int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;

        float x, y, z;
        player->GetPosition(x, y, z);

        handler->PSendSysMessage("%04u%02i%02i.mmtile", player->GetMapId(), gx, gy);
        handler->PSendSysMessage("gridloc [%i, %i]", gy, gx);

        // calculate navmesh tile location
        uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), x, y);
        dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId);
        dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId());
        if (!navmesh || !navmeshquery)
        {
            handler->PSendSysMessage("NavMesh not loaded for current map.");
            return true;
        }

        float const* min = navmesh->getParams()->orig;
        float location[VERTEX_SIZE] = { y, z, x };
        float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f };

        int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
        int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);

        handler->PSendSysMessage("Calc   [%02i, %02i]", tilex, tiley);

        // navmesh poly -> navmesh tile location
        dtQueryFilter filter = dtQueryFilter();
        dtPolyRef polyRef = INVALID_POLYREF;
        if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL)))
        {
            handler->PSendSysMessage("Dt     [??,??] (invalid poly, probably no tile loaded)");
            return true;
        }

        if (polyRef == INVALID_POLYREF)
            handler->PSendSysMessage("Dt     [??, ??] (invalid poly, probably no tile loaded)");
        else
        {
            dtMeshTile const* tile;
            dtPoly const* poly;
            if (dtStatusSucceed(navmesh->getTileAndPolyByRef(polyRef, &tile, &poly)))
            {
                if (tile)
                {
                    handler->PSendSysMessage("Dt     [%02i,%02i]", tile->header->x, tile->header->y);
                    return false;
                }
            }

            handler->PSendSysMessage("Dt     [??,??] (no tile loaded)");
        }

        return true;
    }
Ejemplo n.º 5
0
void PathInfo::Update(const float destX, const float destY, const float destZ)
{
    float x, y, z;

    // update start and end
    m_sourceObject->GetPosition(x, y, z);
    setStartPosition(x, y, z);
    setEndPosition(destX, destY, destZ);

    // make sure navMesh works
    if(!m_navMesh)
    {
        m_sourceObject->GetPosition(x, y, z);
        m_navMesh = m_sourceObject->GetMap()->GetNavMesh();

        if(!m_navMesh)
        {
            // can't pathfind if navmesh doesn't exist
            shortcut();
            return;
        }
    }

    if(!m_pathPolyRefs)
    {
        // path was not built before, most likely because navmesh wasn't working
        // start from scratch, then return
        Build();
        return;
    }

    // should be safe to update path now

    bool startOffPath = false;
    bool endOffPath = false;

    // find start and end poly
    // navMesh.findNearestPoly is expensive, so first we check just the current path
    getStartPosition(x, y, z);
    dtPolyRef startPoly = getPathPolyByPosition(x, y, z);
    getEndPosition(x, y, z);
    dtPolyRef endPoly = getPathPolyByPosition(x, y, z);

    if(startPoly != 0 && endPoly != 0)
        trim(startPoly, endPoly);
    else
    {
        // start or end is off the path, need to find the polygon

        float extents[3] = {2.f, 4.f, 2.f};      // bounds of poly search area
        dtQueryFilter filter = dtQueryFilter();     // filter for poly search

        if(!startPoly)
        {
            getStartPosition(x, y, z);
            float startPos[3] = {y, z, x};
            startOffPath = true;
            startPoly = m_navMesh->findNearestPoly(startPos, extents, &filter, 0);
        }
        if(!endPoly)
        {
            getEndPosition(x, y, z);
            float endPos[3] = {y, z, x};
            endOffPath = true;
            endPoly = m_navMesh->findNearestPoly(endPos, extents, &filter, 0);
        }

        if(startPoly == 0 || endPoly == 0)
        {
            // source or dest not near navmesh polygons:
            // flying, falling, swimming, or navmesh has a hole

            // ignore obstacles/terrain is better than giving up
            // PATHFIND TODO: prevent walking/swimming mobs from flying into the air
            shortcut();
            return;
        }
    }

    if(startPoly == endPoly)
    {
        // start and end are on same polygon
        // just need to move in straight line

        // PATHFIND TODO: prevent walking/swimming mobs from flying into the air

        clear();
        m_pathPolyRefs = new dtPolyRef[1];
        m_pathPolyRefs[0] = startPoly;
        m_length = 1;
        getEndPosition(x, y, z);
        setNextPosition(x, y, z);
        m_type = PathType(m_type | PATHFIND_NORMAL);
        return;
    }

    if(startOffPath)
    {
        bool adjacent = false;
        int i;
        for(i = 0; i < DT_VERTS_PER_POLYGON; ++i)
            if(startPoly == m_navMesh->getPolyByRef(m_pathPolyRefs[0])->neis[i])
            {
                adjacent = true;
                break;
            }

        if(adjacent)
        {
            // startPoly is adjacent to the path, we can add it to the start of the path
            // 50th poly will fall off of path, shouldn't be an issue because most paths aren't that long
            m_length = m_length < MAX_PATH_LENGTH ? m_length + 1 : m_length;
            dtPolyRef* temp = new dtPolyRef[m_length];
            temp[0] = startPoly;

            for(i = 1; i < m_length; ++i)
                temp[i] = m_pathPolyRefs[i - 1];

            delete [] m_pathPolyRefs;
            m_pathPolyRefs = temp;
        }
        else
        {
            // waste of time to optimize, just find brand new path
            Build(startPoly, endPoly);
            return;
        }
    }

    if(endOffPath)
    {
        bool adjacent = false;
        int i;
        for(i = 0; i < DT_VERTS_PER_POLYGON; ++i)
            if(startPoly == m_navMesh->getPolyByRef(m_pathPolyRefs[0])->neis[i])
            {
                adjacent = true;
                break;
            }

        if(adjacent)
        {
            if(m_length < MAX_PATH_LENGTH)
            {
                // endPoly is adjacent to the path, and we have enough room to add it to the end
                dtPolyRef* temp = new dtPolyRef[m_length + 1];
                for(i = 0; i < m_length; ++i)
                    temp[i] = m_pathPolyRefs[i];

                temp[i] = endPoly;

                delete [] m_pathPolyRefs;
                m_pathPolyRefs = temp;
            }
            //else
            //    ;   // endPoly is adjacent to the path, we just don't have room to store it
        }
        else
        {
            // waste of time to optimize, just find brand new path
            Build(startPoly, endPoly);
            return;
        }
    }

    updateNextPosition();
}