Exemplo n.º 1
0
    void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data)
    {
        Movement::SplineBase::ControlArray const& pathPoint = spline.getPoints(); // get ref of whole path points array

        uint32 pathSize = spline.last() - spline.first() - 1; // -1 as we send destination first and last index is destination
        MANGOS_ASSERT(pathSize >= 0);                       // should never be less than 0

        Vector3 destination = pathPoint[spline.last()];     // destination of this path should be send right after path size
        data << pathSize;
        data << destination;

        for (uint32 i = spline.first(); i < spline.first() + pathSize; i++) // from first real index (this array contain also special data)
        {
            Vector3 offset = destination - pathPoint[i];    // we have to send offset relative to destination instead of directly path point.
            data.appendPackXYZ(offset.x, offset.y, offset.z); // we have to pack x,y,z before send
        }
    }
Exemplo n.º 2
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;
}