Ticket #2094: MoveOptimization.patch

File MoveOptimization.patch, 6.0 KB (added by wraitii, 11 years ago)
  • components/ICmpPosition.h

     
    7474    virtual void MoveTo(entity_pos_t x, entity_pos_t z) = 0;
    7575
    7676    /**
     77     * Combines MoveTo and TurnTo to avoid an uncessary "AdvertisePositionChange"
     78     */
     79    virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry) = 0;
     80
     81    /**
    7782     * Move immediately to the given location, with no interpolation.
    7883     */
    7984    virtual void JumpTo(entity_pos_t x, entity_pos_t z) = 0;
  • components/CCmpPosition.cpp

     
    238238
    239239        AdvertisePositionChanges();
    240240    }
     241   
     242    virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry)
     243    {
     244        m_X = x;
     245        m_Z = z;
     246        m_RotY = ry;
     247       
     248        if (!m_InWorld)
     249        {
     250            m_InWorld = true;
     251            m_LastX = m_PrevX = m_X;
     252            m_LastZ = m_PrevZ = m_Z;
     253            m_LastYOffset = m_YOffset;
     254        }
     255       
     256        AdvertisePositionChanges();
     257    }
    241258
    242259    virtual void JumpTo(entity_pos_t x, entity_pos_t z)
    243260    {
  • components/CCmpUnitMotion.cpp

     
    5252 * (This could typically be 1, but we need some tolerance in case speeds
    5353 * or turn lengths change.)
    5454 */
    55 static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 4;
     55static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 3;
    5656
    5757/**
    5858 * Maximum range to restrict short path queries to. (Larger ranges are slower,
     
    765765    }
    766766
    767767    if (m_State == STATE_IDLE)
    768     {
    769768        return;
    770     }
    771769
    772770    switch (m_PathState)
    773771    {
     
    833831        // We want to move (at most) maxSpeed*dt units from pos towards the next waypoint
    834832
    835833        fixed timeLeft = dt;
    836 
    837         while (timeLeft > fixed::Zero())
     834        fixed zero = fixed::Zero();
     835       
     836        while (timeLeft > zero)
    838837        {
    839838            // If we ran out of short path, we have to stop
    840839            if (m_ShortPath.m_Waypoints.empty())
     
    843842            CFixedVector2D target(m_ShortPath.m_Waypoints.back().x, m_ShortPath.m_Waypoints.back().z);
    844843            CFixedVector2D offset = target - pos;
    845844
    846             // Face towards the target
    847             if (!offset.IsZero())
    848             {
    849                 entity_angle_t angle = atan2_approx(offset.X, offset.Y);
    850                 cmpPosition->TurnTo(angle);
    851             }
    852 
    853845            // Work out how far we can travel in timeLeft
    854846            fixed maxdist = maxSpeed.Multiply(timeLeft);
    855847
     
    896888
    897889        // Update the Position component after our movement (if we actually moved anywhere)
    898890        if (pos != initialPos)
    899             cmpPosition->MoveTo(pos.X, pos.Y);
     891        {
     892            CFixedVector2D offset = pos - initialPos;
     893           
     894            // Face towards the target
     895            entity_angle_t angle = atan2_approx(offset.X, offset.Y);
     896            cmpPosition->MoveAndTurnTo(pos.X,pos.Y, angle);
    900897
    901         // Calculate the mean speed over this past turn.
    902         m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
    903 
     898            // Calculate the mean speed over this past turn.
     899            m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
     900        }
     901       
    904902        if (wasObstructed)
    905903        {
    906904            // Oops, we hit something (very likely another unit).
    907905            // Stop, and recompute the whole path.
    908906            // TODO: if the target has UnitMotion and is higher priority,
    909907            // we should wait a little bit.
    910 
     908            // TODO: that's where we would push.
     909           
     910            m_CurSpeed = zero;
    911911            RequestLongPath(pos, m_FinalGoal);
    912912            m_PathState = PATHSTATE_WAITING_REQUESTING_LONG;
    913 
     913           
    914914            return;
    915915        }
    916916
     
    925925            // (or have reached it already), try to extend it
    926926
    927927            entity_pos_t minDistance = basicSpeed.Multiply(dt) * WAYPOINT_ADVANCE_LOOKAHEAD_TURNS;
    928             if (PathIsShort(m_ShortPath, pos, minDistance))
     928           
     929            fixed distance = zero;
     930           
     931            if (!m_ShortPath.m_Waypoints.empty())
    929932            {
     933                CFixedVector2D wpoint(m_ShortPath.m_Waypoints[0].x,m_ShortPath.m_Waypoints[0].z);
     934                distance = (wpoint - pos).Length();
     935            }
     936            if (distance < minDistance)
     937            {
    930938                // Start the path extension from the end of this short path
    931939                // (or our current position if no short path)
    932940                CFixedVector2D from = pos;
    933                 if (!m_ShortPath.m_Waypoints.empty())
     941                if (distance != zero)
    934942                    from = CFixedVector2D(m_ShortPath.m_Waypoints[0].x, m_ShortPath.m_Waypoints[0].z);
    935943
    936944                if (PickNextLongWaypoint(from, ShouldAvoidMovingUnits()))
     
    10891097
    10901098bool CCmpUnitMotion::PathIsShort(const ICmpPathfinder::Path& path, CFixedVector2D from, entity_pos_t minDistance)
    10911099{
    1092     CFixedVector2D pos = from;
    10931100    entity_pos_t distLeft = minDistance;
    10941101
    10951102    for (ssize_t i = (ssize_t)path.m_Waypoints.size()-1; i >= 0; --i)
    10961103    {
    10971104        // Check if the next path segment is longer than the requested minimum
    10981105        CFixedVector2D waypoint(path.m_Waypoints[i].x, path.m_Waypoints[i].z);
    1099         CFixedVector2D delta = waypoint - pos;
     1106        CFixedVector2D delta = waypoint - from;
    11001107        if (delta.CompareLength(distLeft) > 0)
    11011108            return false;
    11021109
    11031110        // Still short enough - prepare to check the next segment
    11041111        distLeft -= delta.Length();
    1105         pos = waypoint;
     1112        from = waypoint;
    11061113    }
    11071114
    11081115    // Reached the end of the path before exceeding minDistance
  • components/ICmpPosition.cpp

     
    2525DEFINE_INTERFACE_METHOD_0("IsInWorld", bool, ICmpPosition, IsInWorld)
    2626DEFINE_INTERFACE_METHOD_0("MoveOutOfWorld", void, ICmpPosition, MoveOutOfWorld)
    2727DEFINE_INTERFACE_METHOD_2("MoveTo", void, ICmpPosition, MoveTo, entity_pos_t, entity_pos_t)
     28DEFINE_INTERFACE_METHOD_3("MoveAndTurnTo", void, ICmpPosition, MoveAndTurnTo, entity_pos_t, entity_pos_t, entity_pos_t)
    2829DEFINE_INTERFACE_METHOD_2("JumpTo", void, ICmpPosition, JumpTo, entity_pos_t, entity_pos_t)
    2930DEFINE_INTERFACE_METHOD_1("SetHeightOffset", void, ICmpPosition, SetHeightOffset, entity_pos_t)
    3031DEFINE_INTERFACE_METHOD_0("GetHeightOffset", entity_pos_t, ICmpPosition, GetHeightOffset)