示例#1
0
    static bool HandleMmapPathCommand(ChatHandler* handler, char const* args)
    {
        if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()))
        {
            handler->PSendSysMessage("NavMesh not loaded for current map.");
            return true;
        }

        handler->PSendSysMessage("mmap path:");

        // units
        Player* player = handler->GetSession()->GetPlayer();
        Unit* target = handler->getSelectedUnit();
        if (!player || !target)
        {
            handler->PSendSysMessage("Invalid target/source selection.");
            return true;
        }

        char* para = strtok((char*)args, " ");

        bool useStraightPath = false;
        if (para && strcmp(para, "true") == 0)
            useStraightPath = true;

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

        // path
        PathGenerator path(target);
        path.SetUseStraightPath(useStraightPath);
        bool result = path.CalculatePath(x, y, z);

        PointsArray pointPath = path.GetPath();
        handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName());
        handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath");
        handler->PSendSysMessage("Result: %s - Length: %i - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());

        Vector3 start = path.GetStartPosition();
        Vector3 end = path.GetEndPosition();
        Vector3 actualEnd = path.GetActualEndPosition();

        handler->PSendSysMessage("StartPosition     (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
        handler->PSendSysMessage("EndPosition       (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
        handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);

        if (!player->isGameMaster())
            handler->PSendSysMessage("Enable GM mode to see the path points.");

        for (uint32 i = 0; i < pointPath.size(); ++i)
            player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);

        return true;
    }
void WalkerDebugInfo::showPath( WalkerPtr walker, gfx::Engine& engine, gfx::Camera* camera, NColor color )
{
  Point camOffset = camera->offset();
  const Pathway& pathway = walker->pathway();

  const TilesArray& tiles = pathway.allTiles();   

  NColor pathColor = color;

  if( color == 0)
  {
    if( walker->agressive() > 0 )
    {
      pathColor = DefaultColors::red;
    }
    else
    {
      pathColor = pathway.isReverse() ? DefaultColors::blue : DefaultColors::green;
    }
  }

  Point pos = walker->mappos();
  Point xOffset( tilemap::cellSize().width(), 0 );
  PointsArray points;
  if( pathway.isReverse() )
  {
    int rStart = pathway.length() - pathway.curStep();
    for( int step=rStart-1; step >= 0; step-- )
    {      
      pos = tiles[ step ]->mappos() + camOffset + xOffset;
      points.push_back( pos );
    }    
  }
  else
  {
    for( unsigned int step=pathway.curStep()+1; step < tiles.size(); step++ )
    {
      pos = tiles[ step ]->mappos() + camOffset + xOffset;
      points.push_back( pos );
    }
  }

  engine.drawLines( pathColor, points );
}
示例#3
0
  void set( Senate::Status status, Picture pic, const Point& offset )
  {
    if( status >= pics.size() )
    {
      pics.resize( status+1 );
      offsets.resize( status+1 );
    }

    offsets[ status ] = offset;
    pics[ status ] = pic;
  }
示例#4
0
 Point getOffset( Senate::Status st ) const { return offsets.valueOrEmpty( st ); }
示例#5
0
void PathFinder::BuildPointPath(const float* startPoint, const float* endPoint)
{
    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,
                m_pointPathLimit);   // 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,
                m_pointPathLimit);    // maximum number of points
    }

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

    uint32 tempPointCounter = 2;
    uint8  cutLimit         = 0;

    PointsArray    tempPathPoints;
    tempPathPoints.resize(pointCount);

    for (uint32 i = 0; i < pointCount; ++i)
        tempPathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]);

    // Optimize points
    for (uint32 i = 1; i < pointCount - 1; ++i)
    {
        G3D::Vector3 p  = tempPathPoints[i];     // Point        
        G3D::Vector3 p1 = tempPathPoints[i - 1]; // PrevPoint
        G3D::Vector3 p2 = tempPathPoints[i + 1]; // NextPoint

        float line = (p1.y - p2.y) * p.x + (p2.x - p1.x) * p.y + (p1.x * p2.y - p2.x * p1.y);

        if (fabs(line) < LINE_FAULT && cutLimit < SKIP_POINT_LIMIT)
        {
            tempPathPoints[i] = Vector3(0, 0, 0);
            ++cutLimit;
        }
        else
        {
            ++tempPointCounter;
            cutLimit = 0;
        }
    }

    m_pathPoints.resize(tempPointCounter);

    uint32 b = 0;
    for (uint32 i = 0; i < pointCount; ++i)
    {
        if (tempPathPoints[i] != Vector3(0, 0, 0))
        {
            m_pathPoints[b] = tempPathPoints[i];
            ++b;
        }
    }

    pointCount = tempPointCounter;

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

    // force the given destination, if needed
    if (m_forceDestination &&
        (!(m_type & PATHFIND_NORMAL) || !inRange(getEndPosition(), getActualEndPosition(), 1.0f, 1.0f)))
    {
        // we may want to keep partial subpath
        if (dist3DSqr(getActualEndPosition(), getEndPosition()) <
            0.3f * dist3DSqr(getStartPosition(), getEndPosition()))
        {
            setActualEndPosition(getEndPosition());
            m_pathPoints[m_pathPoints.size()-1] = getEndPosition();
        }
        else
        {
            setActualEndPosition(getEndPosition());
            BuildShortcut();
        }

        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
    }

    DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ PathFinder::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength);
}
示例#6
0
bool Transport::GenerateWaypoints(uint32 pathid, uint32 moveSpeed, uint32 accelRate, std::set<uint32> &mapids)
{
    if (pathid >= sTaxiPathNodesByPath.size())
        return false;

    TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathid];

    PointsArray splinepath;
    float velocity = moveSpeed;
    uint32 time_step = 500;

    mapids.clear();
    bool never_teleport = true; //if never teleported is cyclic path
    uint32 t = 0;
    uint32 start = 0;
    for (size_t i = 0; i < path.size(); ++i)
    {
        TaxiPathNodeEntry const& node_i = path[i];

        splinepath.push_back(G3D::Vector3(node_i.x, node_i.y, node_i.z));

        //split path in segments
        bool teleport = node_i.mapid != path[(i+1)%path.size()].mapid || (path[i].actionFlag == 1); //teleport on next node?
        if (teleport || i == path.size() - 1)
        {
            never_teleport &= !teleport;

            mapids.insert(node_i.mapid);

            //re-add first node for cyclic path if never teleported
            if(i == path.size() - 1 && never_teleport)
                splinepath.push_back(G3D::Vector3(path[0].x, path[0].y, path[0].z));

            //generate spline for seg
            Spline<int32> spline;
            spline.init_spline(&splinepath[0], splinepath.size(), SplineBase::ModeCatmullrom);
            CommonInitializer init(velocity);
            spline.initLengths(init);

            sLog->outDebug(LOG_FILTER_TRANSPORTS, "[%d] Generate spline for seg: %d-%d (%d-%d)", pathid, start+spline.first()-1, start+spline.last()-1, spline.first(), spline.last());

            //add first point of seg to waypoints
            m_WayPoints[t] = WayPoint(path[start].mapid, path[start].x, path[start].y, path[start].z, false, path[start].index, path[start].arrivalEventID, path[start].departureEventID);
            t += path[start].delay;
            sLog->outDebug(LOG_FILTER_TRANSPORTS, "[%d] %d T: %d, x: %f, y: %f, z: %f, t:%d", pathid, path[start].index, t, path[start].x, path[start].y, path[start].z, false);

            //sample the segment
            for (int32 point_Idx = spline.first(); point_Idx < spline.last(); ++point_Idx)
            {
                uint32 node_Idx = (start + point_Idx) % path.size();
                float u = 1.0f;
                int32 seg_time = spline.length(point_Idx, point_Idx + 1);
                uint32 time_passed = time_step;
                do {
                    if (seg_time > 0)
                        u = time_passed / (float)seg_time;
                    if (u >= 1)
                        break;

                    Location c;
                    spline.evaluate_percent(point_Idx, u, c);

                    if (path[node_Idx].actionFlag == 2)
                        t += time_step / accelRate;     //deceleration
                    else if (node_Idx > 1 && path[node_Idx-1].actionFlag == 2)
                        t += time_step / accelRate;     //acceleration

                    //add sample to waypoints
                    m_WayPoints[t + time_passed] = WayPoint(node_i.mapid, c.x, c.y, c.z, false, 0);
                    sLog->outDebug(LOG_FILTER_TRANSPORTS, "[%d] T: %d, x: %f, y: %f, z: %f, t:%d", pathid, t + time_passed, c.x, c.y, c.z, false);

                    time_passed += time_step;
                } while (u < 1.0f);
                t += seg_time;

                //add point to waypoints (if isn't first)
                if (node_Idx > 0)
                {
                    bool teleport_on_this_node = (point_Idx == spline.last() - 1 ? teleport : false);   //if is the last node of segment -> teleport
                    teleport_on_this_node |= (node_Idx == path.size() -1 ? !never_teleport : false);    //if is the last node of path, teleport if teleported at least one time
                    m_WayPoints[t] = WayPoint(path[node_Idx].mapid, path[node_Idx].x, path[node_Idx].y, path[node_Idx].z, teleport_on_this_node, path[node_Idx].index, path[node_Idx].arrivalEventID, path[node_Idx].departureEventID);
                    sLog->outDebug(LOG_FILTER_TRANSPORTS, "[%d] %d T: %d, x: %f, y: %f, z: %f, t:%d", pathid, path[node_Idx].index, t, path[node_Idx].x, path[node_Idx].y, path[node_Idx].z, teleport_on_this_node);
                    //if (path[node_Idx].actionFlag == 2)    //add delay - always or only on actionFlag == 2?
                    t += path[node_Idx].delay * 1000;
                }
            }

            splinepath.clear();
            start = i + 1;
        }
    }

    m_curr = m_WayPoints.begin();
    m_next = GetNextWayPoint();
    m_pathTime = t;

    return true;
}
示例#7
0
 void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
 {
     args.path_Idx_offset = path_offset;
     args.path.resize(controls.size());
     std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
 }