Beispiel #1
0
static void LogPathInfo(const NCBISRAPath* self)
{
    PATH_DEBUG (("NCBISRAPath configuration:\n"));
    DLListForEach ( & self->repos, false, LogRepository, NULL );
    PATH_DEBUG (("default repository:\n"));
    LogRepository( (DLNode*) self->dflt_repo, NULL );
}
Beispiel #2
0
void PathInfo::BuildPointPath(float *startPoint, float *endPoint)
{
    // get the actual reachable point on last poly in path
    float closestPoint[VERTEX_SIZE];
    if ((m_type & PATHFIND_INCOMPLETE)
            && DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(m_pathPolyRefs[m_polyLength-1], endPoint, closestPoint))
    {
        dtVcopy(endPoint, closestPoint);
        setActualEndPosition(PathNode(endPoint[2],endPoint[0],endPoint[1]));
    }

    float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE];
    uint32 pointCount = 0;
    dtStatus dtResult = DT_FAILURE;
    if (m_useStraightPath)
    {
        dtResult = m_navMeshQuery->findStraightPath(
                       startPoint,         // start position
                       endPoint,           // end position
                       m_pathPolyRefs,     // current path
                       m_polyLength,       // lenth of current path
                       pathPoints,         // [out] path corner points
                       NULL,               // [out] flags
                       NULL,               // [out] shortened path
                       (int*)&pointCount,
                       MAX_POINT_PATH_LENGTH);   // maximum number of points/polygons to use
    }
    else
    {
        dtResult = findSmoothPath(
                       startPoint,         // start position
                       endPoint,           // end position
                       m_pathPolyRefs,     // current path
                       m_polyLength,       // length of current path
                       pathPoints,         // [out] path corner points
                       (int*)&pointCount,
                       MAX_POINT_PATH_LENGTH);    // maximum number of points
    }

    if (pointCount < 2 || dtResult != DT_SUCCESS)
    {
        // only happens if pass bad data to findStraightPath or navmesh is broken
        // single point paths can be generated here
        // TODO : check the exact cases
        PATH_DEBUG("++ PathInfo::BuildPointPath FAILED! path sized %d returned\n", pointCount);
        BuildShortcut();
        m_type = PATHFIND_NOPATH;
        return;
    }

    m_pathPoints.resize(pointCount);
    for (uint32 i = 0; i < pointCount; ++i)
        m_pathPoints.set(i, PathNode(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]));

    // first point is always our current location - we need the next one
    setNextPosition(m_pathPoints[1]);

    PATH_DEBUG("++ PathInfo::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength);
}
Beispiel #3
0
void PathInfo::BuildPointPath(float *startPoint, float *endPoint)
{
    float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE];
    uint32 pointCount = 0;
    dtStatus dtResult = DT_FAILURE;
    bool usedOffmesh = false;
    if (m_useStraightPath)
    {
        dtResult = m_navMeshQuery->findStraightPath(
                startPoint,         // start position
                endPoint,           // end position
                m_pathPolyRefs,     // current path
                m_polyLength,       // lenth of current path
                pathPoints,         // [out] path corner points
                NULL,               // [out] flags
                NULL,               // [out] shortened path
                (int*)&pointCount,
                MAX_POINT_PATH_LENGTH);   // maximum number of points/polygons to use
    }
    else
    {
        dtResult = findSmoothPath(
                startPoint,         // start position
                endPoint,           // end position
                m_pathPolyRefs,     // current path
                m_polyLength,       // length of current path
                pathPoints,         // [out] path corner points
                (int*)&pointCount,
                usedOffmesh,
                MAX_POINT_PATH_LENGTH);    // maximum number of points
    }

    if (pointCount < 2 || dtResult != DT_SUCCESS)
    {
        // only happens if pass bad data to findStraightPath or navmesh is broken
        // single point paths can be generated here
        // TODO : check the exact cases
        PATH_DEBUG("++ PathInfo::BuildPointPath FAILED! path sized %d returned\n", pointCount);
        BuildShortcut();
        m_type = PATHFIND_NOPATH;
        return;
    }

    // we need to flash our poly path to prevent it being used as subpath next cycle
    // in case of off mesh connection was used
    if(usedOffmesh)
        m_polyLength = 0;

    m_pathPoints.resize(pointCount);
    for (uint32 i = 0; i < pointCount; ++i)
        m_pathPoints.set(i, PathNode(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]));

    // first point is always our current location - we need the next one
    setNextPosition(m_pathPoints[1]);
    setActualEndPosition(m_pathPoints[pointCount-1]);

    PATH_DEBUG("++ PathInfo::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength);
}
Beispiel #4
0
bool PathInfo::Update(const float destX, const float destY, const float destZ, bool useStraightPath)
{
    PathNode newDest(destX, destY, m_sourceUnit->GetMap()->GetHeight(destX,destY,destZ,100.0f));
    PathNode oldDest = getEndPosition();
    setEndPosition(newDest);

    float x, y, z;
    m_sourceUnit->GetPosition(x, y, z);
    PathNode newStart(x, y, m_sourceUnit->GetMap()->GetHeight(x,y,z,100.0f));
    PathNode oldStart = getStartPosition();
    setStartPosition(newStart);

    m_useStraightPath = useStraightPath;

    PATH_DEBUG("++ PathInfo::Update() for %u \n", m_sourceUnit->GetGUID());

    // make sure navMesh works - we can run on map w/o mmap
    if (!m_navMesh || !m_navMeshQuery)
    {
        BuildShortcut();
        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
        return true;
    }

    float dist = m_sourceUnit->GetObjectBoundingRadius();
    bool oldDestInRange = inRange(oldDest, newDest, dist, dist);

    // this can happen only if caller did a bad job calculating the need for path update
    if (oldDestInRange && inRange(newStart, oldStart, dist, dist))
    {
        setEndPosition(oldDest);
        setStartPosition(oldStart);
        return false;
    }

    // check if destination moved - if not we can optimize something here
    // we are following old, precalculated path?
    if (oldDestInRange && m_pathPoints.size() > 2)
    {
        // our target is not moving - we just coming closer
        // we are moving on precalculated path - enjoy the ride
        PATH_DEBUG("++ PathInfo::Update:: precalculated path\n");

        m_pathPoints.crop(1, 0);
        setNextPosition(m_pathPoints[1]);

        return false;
    }
    else
    {
        // target moved, so we need to update the poly path
        BuildPolyPath(newStart, newDest);
        return true;
    }
}
Beispiel #5
0
static 
void CC LogRepository ( DLNode *n, void *data )
{
    if (n != NULL)
    {
        const NCBIRepository* self = (const NCBIRepository*)n;
        PATH_DEBUG (("    type=%s\n", AlgToStr(self->type)));
        PATH_DEBUG (("    servers:\n"));
        DLListForEach ( & self->repsrv, false, LogServer, NULL );
        PATH_DEBUG (("    volumes:\n"));
        DLListForEach ( & self->vols, false, LogVolume, NULL );
    }
}
Beispiel #6
0
////////////////// PathInfo //////////////////
PathInfo::PathInfo(const Unit* owner, const float destX, const float destY, const float destZ, bool useStraightPath) :
    m_polyLength(0), m_type(PATHFIND_BLANK), m_useStraightPath(useStraightPath),
    m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL)
{
    PathNode endPoint(destX, destY, destZ);
    setEndPosition(endPoint);

    float x,y,z;
    m_sourceUnit->GetPosition(x, y, z);
    PathNode startPoint(x, y, z);
    setStartPosition(startPoint);

    PATH_DEBUG("++ PathInfo::PathInfo for %u \n", m_sourceUnit->GetGUID());

    uint32 mapId = m_sourceUnit->GetMapId();
    if (MMAP::MMapFactory::IsPathfindingEnabled(mapId))
    {
        MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
        m_navMesh = mmap->GetNavMesh(mapId);
        m_navMeshQuery = mmap->GetNavMeshQuery(mapId, m_sourceUnit->GetInstanceId());
    }

    createFilter();

    if (m_navMesh && m_navMeshQuery && !m_sourceUnit->hasUnitState(UNIT_STAT_IGNORE_PATHFINDING) && !(m_sourceUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)m_sourceUnit)->IsWorldBoss() : false))
    {
        BuildPolyPath(startPoint, endPoint);
    }
    else
    {
        BuildShortcut();
        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
    }
}
Beispiel #7
0
PathInfo::~PathInfo()
{
    PATH_DEBUG("++ PathInfo::~PathInfo() for %u \n", m_sourceUnit->GetGUID());

    if (m_pathPolyRefs)
        delete [] m_pathPolyRefs;
}
Beispiel #8
0
/* FindInRepo
 *  find accession in a repository
 */
static
rc_t SRAPathFindInRepo ( const NCBISRAPath *self, NCBIRepository *repo, const char *accession, 
                         char *path, size_t path_max, size_t *rep_len, int vol_type )
{
    SRAPathString *srv;

    PATH_DEBUG (("SRAPathFindInRepo(%s)\n", AlgToStr(repo->type)));

    /* look for accession on a rep-server */
    for ( srv = ( SRAPathString* ) DLListHead ( & repo -> repsrv ); srv != NULL; srv = ( SRAPathString* ) DLNodeNext ( & srv -> n ) )
    {
        /* try with this server */
        rc_t rc = SRAPathFindOnServer ( self, repo, srv, accession, path, path_max, vol_type );
        if ( rc == 0 )
        {
            /* make sure server is at head of list */
            if ( DLNodePrev ( & srv -> n ) != NULL )
            {
                DLListUnlink ( & repo -> repsrv, & srv -> n );
                DLListPushHead ( & repo -> repsrv, & srv -> n );
            }

            if ( rep_len != NULL )
                * rep_len = strlen ( srv -> path );
            
            return 0;
        }

        if ( GetRCState ( rc ) != rcNotFound )
            return rc;
    }

    return RC ( rcSRA, rcMgr, rcSelecting, rcPath, rcNotFound );
}
Beispiel #9
0
////////////////// PathInfo //////////////////
PathInfo::PathInfo(const Unit* owner, const float destX, const float destY, const float destZ, bool useStraightPath) :
    m_pathPolyRefs(NULL), m_polyLength(0), m_type(PATHFIND_BLANK), m_useStraightPath(useStraightPath),
    m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL)
{
    PathNode endPoint(destX, destY, destZ);
    setEndPosition(endPoint);

    float x,y,z;
    m_sourceUnit->GetPosition(x, y, z);
    PathNode startPoint(x, y, m_sourceUnit->GetMap()->GetHeight(x,y,z,100.0f));
    setStartPosition(startPoint);

    PATH_DEBUG("++ PathInfo::PathInfo for %u \n", m_sourceUnit->GetGUID());

    uint32 mapId = m_sourceUnit->GetMapId();
    MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
    m_navMesh = mmap->GetNavMesh(mapId);
    m_navMeshQuery = mmap->GetNavMeshQuery(mapId);

    if (m_navMesh && m_navMeshQuery)
    {
        BuildPolyPath(startPoint, endPoint);
    }
    else
    {
        BuildShortcut();
        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
    }
}
Beispiel #10
0
bool PathInfo::Update(const float destX, const float destY, const float destZ, bool useStraightPath)
{
    PathNode newDest(destX, destY, destZ);
    PathNode oldDest = getEndPosition();
    setEndPosition(newDest);

    float x, y, z;
    m_sourceUnit->GetPosition(x, y, z);
    PathNode newStart(x, y, z);
    PathNode oldStart = getStartPosition();
    setStartPosition(newStart);

    m_useStraightPath = useStraightPath;

    PATH_DEBUG("++ PathInfo::Update() for %u \n", m_sourceUnit->GetGUID());

    // make sure navMesh works - we can run on map w/o mmap
    if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->hasUnitState(UNIT_STAT_IGNORE_PATHFINDING) || (m_sourceUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)m_sourceUnit)->IsWorldBoss() : false))
    {
        BuildShortcut();
        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
        return true;
    }

    updateFilter();

    // check if destination moved - if not we can optimize something here
    // we are following old, precalculated path?
    float dist = m_sourceUnit->GetObjectBoundingRadius();
    if (inRange(oldDest, newDest, dist, dist) && m_pathPoints.size() > 2)
    {
        // our target is not moving - we just coming closer
        // we are moving on precalculated path - enjoy the ride
        PATH_DEBUG("++ PathInfo::Update:: precalculated path\n");

        m_pathPoints.crop(1, 0);
        setNextPosition(m_pathPoints[1]);

        return false;
    }
    else
    {
        // target moved, so we need to update the poly path
        BuildPolyPath(newStart, newDest);
        return true;
    }
}
Beispiel #11
0
static 
void CC LogVolume( DLNode *n, void *data )
{
    const SRAPathString* self = (const SRAPathString*)n;
    PATH_DEBUG (("        \"%s\", type=%s\n", 
                  self->path,
                  AlgToStr(self->alg)));
}
Beispiel #12
0
PathInfo::~PathInfo()
{
    PATH_DEBUG("++ PathInfo::~PathInfo() for %u \n", m_sourceUnit->GetGUID());

    if (m_pathPolyRefs)
        delete [] m_pathPolyRefs;

    // m_navMesh is not ours to delete
    if (m_navMesh && m_navMeshQuery)
        dtFreeNavMeshQuery(m_navMeshQuery);
}
Beispiel #13
0
void PathInfo::BuildShortcut()
{
    PATH_DEBUG("++ BuildShortcut :: making shortcut\n");

    clear();

    // make two point path, our curr pos is the start, and dest is the end
    m_pathPoints.resize(2);

    // set start and a default next position
    m_pathPoints.set(0, getStartPosition());
    m_pathPoints.set(1, getActualEndPosition());

    setNextPosition(getActualEndPosition());
    m_type = PATHFIND_SHORTCUT;
}
Beispiel #14
0
/* Find
 *  finds location of run within rep-server/volume matrix
 *
 *  "accession" [ IN ] - NUL terminated run accession,
 *   e.g. "SRR000001"
 *
 *  "path" [ OUT ] and "path_max" [ IN ] - return buffer for
 *  NUL-terminated full path to accession.
 *
 *  returns 0 if path exists, rc state rcNotFound if
 *  path cannot be found, and rcInsufficient if buffer is
 *  too small.
 */
static
rc_t CC NCBISRAPathFindWithRepLen ( const NCBISRAPath *cself, const char *accession, char *path, size_t path_max, size_t *rep_len )
{
    rc_t rc;
    NCBIRepository *repo;

    PATH_DEBUG(("NCBISRAPathFindWithRepLen(%s)\n", accession));

    rc = FindFast( cself, accession, path, path_max, rep_len );
    if ( rc == 0 )
        return 0;
        
    /* loop through all repositories */ 
    for ( repo = ( NCBIRepository* ) DLListHead ( & cself -> repos ); repo != NULL; repo = ( NCBIRepository* ) DLNodeNext ( & repo -> n ) )
    {
        rc = SRAPathFindInRepo(cself, repo, accession, path, path_max, rep_len, alg_none);
        if ( rc == 0 )
            return 0;
    }
    /* default repository */
    return SRAPathFindInRepo(cself, cself -> dflt_repo, accession, path, path_max, rep_len, alg_none);
}
Beispiel #15
0
////////////////// PathInfo //////////////////
PathInfo::PathInfo(const Unit* owner, const float destX, const float destY, const float destZ, bool useStraightPath) : m_pathPolyRefs(NULL),
    m_polyLength(0), m_type(PATHFIND_BLANK), m_useStraightPath(useStraightPath), m_sourceUnit(owner),
    m_navMesh(NULL), m_navMeshQuery(NULL)
{
    PathNode endPoint(destX, destY, destZ);
    setEndPosition(endPoint);

    float x,y,z;
    m_sourceUnit->GetPosition(x, y, z);
    PathNode startPoint(x, y, z);
    setStartPosition(startPoint);

    PATH_DEBUG("++ PathInfo::PathInfo for %u \n", m_sourceUnit->GetGUID());

    const Map* map = m_sourceUnit->GetMap();
    if (map->IsPathfindingEnabled())
        m_navMesh = map->GetNavMesh();

    if (m_navMesh)
    {
        m_navMeshQuery = dtAllocNavMeshQuery();
        ASSERT(m_navMeshQuery);
        if(DT_SUCCESS != m_navMeshQuery->init(m_navMesh, MESH_MAX_NODES))
        {
            sLog->outError("%u's PathInfo navMeshQuery failed to init", m_sourceUnit->GetGUID());
            return;
        }

        BuildPolyPath(startPoint, endPoint);
    }
    else
    {
        BuildShortcut();
        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
    }
}
Beispiel #16
0
PathInfo::~PathInfo()
{
    PATH_DEBUG("++ PathInfo::~PathInfo() for %u \n", m_sourceUnit->GetGUID());
}
Beispiel #17
0
void PathInfo::BuildPolyPath(PathNode startPos, PathNode endPos)
{
    // *** getting start/end poly logic ***

    float distToStartPoly, distToEndPoly;
    float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x};
    float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x};

    dtPolyRef startPoly = getPolyByLocation(startPoint, &distToStartPoly);
    dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly);

    // we have a hole in our mesh
    // make shortcut path and mark it as NOPATH ( with flying exception )
    // its up to caller how he will use this info
    if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF)
    {
        PATH_DEBUG("++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n");
        BuildShortcut();
        m_type = (m_sourceUnit->GetTypeId() == TYPEID_UNIT && ((Creature*)m_sourceUnit)->canFly())
                 ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH;
        return;
    }

    // we may need a better number here
    bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f);
    if (farFromPoly)
    {
        PATH_DEBUG("++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly);

        bool buildShotrcut = false;
        if (m_sourceUnit->GetTypeId() == TYPEID_UNIT)
        {
            Creature* owner = (Creature*)m_sourceUnit;

            PathNode p = (distToStartPoly > 7.0f) ? startPos : endPos;
            if (m_sourceUnit->GetMap()->IsUnderWater(p.x, p.y, p.z))
            {
                PATH_DEBUG("++ BuildPolyPath :: underWater case\n");
                if (owner->canSwim() || owner->isPet())
                    buildShotrcut = true;
            }
            else
            {
                PATH_DEBUG("++ BuildPolyPath :: flying case\n");
                if (owner->canFly())
                    buildShotrcut = true;
            }
        }

        if (buildShotrcut)
        {
            BuildShortcut();
            m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
            return;
        }
        else
        {
            float closestPoint[VERTEX_SIZE];
            // we may want to use closestPointOnPolyBoundary instead
            if (DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))
            {
                dtVcopy(endPoint, closestPoint);
                setActualEndPosition(PathNode(endPoint[2],endPoint[0],endPoint[1]));
            }

            m_type = PATHFIND_INCOMPLETE;
        }
    }

    // *** poly path generating logic ***

    // start and end are on same polygon
    // just need to move in straight line
    if (startPoly == endPoly)
    {
        PATH_DEBUG("++ BuildPolyPath :: (startPoly == endPoly)\n");

        BuildShortcut();

        m_pathPolyRefs = new dtPolyRef[1];
        m_pathPolyRefs[0] = startPoly;
        m_polyLength = 1;

        m_type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL;
        PATH_DEBUG("++ BuildPolyPath :: path type %d\n", m_type);
        return;
    }

    // look for startPoly/endPoly in current path
    // TODO: we can merge it with getPathPolyByPosition() loop
    bool startPolyFound = false;
    bool endPolyFound = false;
    uint32 pathStartIndex, pathEndIndex;

    if (m_polyLength)
    {
        for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex)
            if (m_pathPolyRefs[pathStartIndex] == startPoly)
            {
                startPolyFound = true;
                break;
            }

        for (pathEndIndex = m_polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex)
            if (m_pathPolyRefs[pathEndIndex] == endPoly)
            {
                endPolyFound = true;
                break;
            }
    }

    if (startPolyFound && endPolyFound)
    {
        PATH_DEBUG("++ BuildPolyPath :: (startPolyFound && endPolyFound)\n");

        // we moved along the path and the target did not move out of our old poly-path
        // our path is a simple subpath case, we have all the data we need
        // just "cut" it out

        m_polyLength = pathEndIndex - pathStartIndex + 1;

        dtPolyRef* newPolyRefs = new dtPolyRef[m_polyLength];
        memcpy(newPolyRefs, m_pathPolyRefs+pathStartIndex, m_polyLength*sizeof(dtPolyRef));

        delete [] m_pathPolyRefs;
        m_pathPolyRefs = newPolyRefs;
    }
    else if (startPolyFound && !endPolyFound)
    {
        PATH_DEBUG("++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n");

        // we are moving on the old path but target moved out
        // so we have atleast part of poly-path ready

        m_polyLength -= pathStartIndex;

        // try to adjust the suffix of the path instead of recalculating entire length
        // at given interval the target cannot get too far from its last location
        // thus we have less poly to cover
        // sub-path of optimal path is optimal

        // take ~80% of the original length
        // TODO : play with the values here
        uint32 prefixPolyLength = uint32(m_polyLength*0.8f + 0.5f);
        dtPolyRef prefixPathPolys[MAX_PATH_LENGTH];
        memcpy(prefixPathPolys, m_pathPolyRefs+pathStartIndex, prefixPolyLength*sizeof(dtPolyRef));

        dtPolyRef suffixStartPoly = prefixPathPolys[prefixPolyLength-1];

        // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
        float suffixEndPoint[VERTEX_SIZE];
        if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
        {
            // suffixStartPoly is invalid somehow, or the navmesh is broken => error state
            sLog.outError("%u's Path Build failed: invalid polyRef in path", m_sourceUnit->GetGUID());

            BuildShortcut();
            m_type = PATHFIND_NOPATH;
            return;
        }

        // generate suffix
        dtQueryFilter filter = createFilter();
        dtPolyRef suffixPathPolys[MAX_PATH_LENGTH];
        uint32 suffixPolyLength = 0;

        dtStatus dtResult = m_navMeshQuery->findPath(
                                suffixStartPoly,    // start polygon
                                endPoly,            // end polygon
                                suffixEndPoint,     // start position
                                endPoint,           // end position
                                &filter,            // polygon search filter
                                suffixPathPolys,    // [out] path
                                (int*)&suffixPolyLength,
                                MAX_PATH_LENGTH-prefixPolyLength);   // max number of polygons in output path

        if (!suffixPolyLength || dtResult != DT_SUCCESS)
        {
            // this is probably an error state, but we'll leave it
            // and hopefully recover on the next Update
            // we still need to copy our preffix
            sLog.outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUID());
        }

        PATH_DEBUG("++  m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength);

        // new path = prefix + suffix - overlap
        m_polyLength = prefixPolyLength + suffixPolyLength - 1;
        delete [] m_pathPolyRefs;
        m_pathPolyRefs = new dtPolyRef[m_polyLength];

        // copy the part of the old path we keep - prefix
        memcpy(m_pathPolyRefs, prefixPathPolys, prefixPolyLength*sizeof(dtPolyRef));

        // copy the newly created suffix - skip first poly, we have it at prefix end
        if (suffixPathPolys)
            memcpy(m_pathPolyRefs+prefixPolyLength, suffixPathPolys+1, (suffixPolyLength-1)*sizeof(dtPolyRef));
    }
    else
    {
        PATH_DEBUG("++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n");

        // either we have no path at all -> first run
        // or something went really wrong -> we aren't moving along the path to the target
        // just generate new path

        // free and invalidate old path data
        clear();

        dtQueryFilter filter = createFilter();      // use special filter so we use proper terrain types
        dtPolyRef pathPolys[MAX_PATH_LENGTH];
        m_polyLength = 0;

        dtStatus dtResult = m_navMeshQuery->findPath(
                                startPoly,          // start polygon
                                endPoly,            // end polygon
                                startPoint,         // start position
                                endPoint,           // end position
                                &filter,            // polygon search filter
                                pathPolys,          // [out] path
                                (int*)&m_polyLength,
                                MAX_PATH_LENGTH);   // max number of polygons in output path

        if (!m_polyLength || dtResult != DT_SUCCESS)
        {
            // only happens if we passed bad data to findPath(), or navmesh is messed up
            sLog.outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUID());
            BuildShortcut();
            m_type = PATHFIND_NOPATH;
            return;
        }

        m_pathPolyRefs = new dtPolyRef[m_polyLength];
        memcpy(m_pathPolyRefs, pathPolys, m_polyLength*sizeof(dtPolyRef));
    }

    // by now we know what type of path we can get
    if (m_pathPolyRefs[m_polyLength - 1] == endPoly && !(m_type & PATHFIND_INCOMPLETE))
        m_type = PATHFIND_NORMAL;
    else
        m_type = PATHFIND_INCOMPLETE;

    // generate the point-path out of our up-to-date poly-path
    BuildPointPath(startPoint, endPoint);
}
Beispiel #18
0
static 
void CC LogServer( DLNode *n, void *data )
{
    const SRAPathString* self = (const SRAPathString*)n;
    PATH_DEBUG (("        \"%s\"\n", self->path));
}
Beispiel #19
0
/* FindOnServer
 *  find accession on rep-server 
 */
static
rc_t SRAPathFindOnServer ( const NCBISRAPath *self, const NCBIRepository *repo, const SRAPathString *srv,
    const char *accession, char *path, size_t path_max, int vol_type )
{
    const SRAPathString *vol;

    PATH_DEBUG (("SRAPathFindOnServer(%s)\n", srv->path));

    for ( vol = ( const SRAPathString* ) DLListHead ( & repo -> vols );
          vol != NULL; vol = ( const SRAPathString* ) DLNodeNext ( & vol -> n ) )
    {
        if ( vol_type == alg_none || vol_type == vol->alg )
        {
            rc_t rc;

            PATH_DEBUG (("SRAPathFindOnServer trying volume %s\n", vol->path));

            switch ( vol -> alg )
            {
            case alg_ebi:
                rc = SRAPathFullEBI ( self, srv -> path, vol -> path, accession, path, path_max );
                break;
            case alg_refseq:
                rc = SRAPathFullREFSEQ ( self, srv -> path, vol -> path, accession, path, path_max );
                if ( rc == 0) /* check for existence of accession at the root of the volume, and if not found try to apply the default path-building scheme */
                {
                    switch ( KDirectoryPathType ( self -> dir, path ) )
                    {
                    case kptNotFound:
                    case kptBadPath:
                        rc = SRAPathFullREFSEQArchive( self, srv -> path, vol -> path, accession, path, path_max );
                        if (rc == 0) {
                            PATH_DEBUG (("SRAPathFindOnServer: found(%s)\n", path));
                            return 0;
                        }
                        break;
                    default:
                    	return 0;
                    }
                }
                break;
            case alg_wgs:
                rc = SRAPathFullWGS ( self, srv -> path, vol -> path, accession, path, path_max );
                break;
            default:
                rc = SRAPathFullInt ( self, srv -> path, vol -> path, accession, path, path_max, 1024 );
                break;
            }
            if ( rc == 0 )
            {
                switch ( KDirectoryPathType ( self -> dir, path ) )
                {
                case kptNotFound:
                case kptBadPath:
                    break;
                default:
                    PATH_DEBUG (("SRAPathFindOnServer: found(%s)\n", path));
                    return 0;
                }
            }
            else
            {
                if ( GetRCState( rc ) == rcInsufficient )
                    return rc;
            }
        }
    }

    return RC ( rcSRA, rcMgr, rcSelecting, rcPath, rcNotFound );
}