Ticket #2094: MoveOptimization.2.patch

File MoveOptimization.2.patch, 6.3 KB (added by wraitii, 11 years ago)
  • source/simulation2/components/CCmpPosition.cpp

      Index: source/simulation2/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    {
  • source/simulation2/components/CCmpUnitMotion.cpp

     
    5353 * (This could typically be 1, but we need some tolerance in case speeds
    5454 * or turn lengths change.)
    5555 */
    56 static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 4;
     56static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 3;
    5757
    5858/**
    5959 * Maximum range to restrict short path queries to. (Larger ranges are slower,
     
    792792    }
    793793
    794794    if (m_State == STATE_IDLE)
    795     {
    796795        return;
    797     }
    798796
    799797    switch (m_PathState)
    800798    {
     
    860858        // We want to move (at most) maxSpeed*dt units from pos towards the next waypoint
    861859
    862860        fixed timeLeft = dt;
    863 
    864         while (timeLeft > fixed::Zero())
     861        fixed zero = fixed::Zero();
     862       
     863        while (timeLeft > zero)
    865864        {
    866865            // If we ran out of short path, we have to stop
    867866            if (m_ShortPath.m_Waypoints.empty())
     
    870869            CFixedVector2D target(m_ShortPath.m_Waypoints.back().x, m_ShortPath.m_Waypoints.back().z);
    871870            CFixedVector2D offset = target - pos;
    872871
    873             // Face towards the target
    874             if (!offset.IsZero())
    875             {
    876                 entity_angle_t angle = atan2_approx(offset.X, offset.Y);
    877                 cmpPosition->TurnTo(angle);
    878             }
    879 
    880872            // Work out how far we can travel in timeLeft
    881873            fixed maxdist = maxSpeed.Multiply(timeLeft);
    882874
     
    923915
    924916        // Update the Position component after our movement (if we actually moved anywhere)
    925917        if (pos != initialPos)
    926             cmpPosition->MoveTo(pos.X, pos.Y);
     918        {
     919            CFixedVector2D offset = pos - initialPos;
     920           
     921            // Face towards the target
     922            entity_angle_t angle = atan2_approx(offset.X, offset.Y);
     923            cmpPosition->MoveAndTurnTo(pos.X,pos.Y, angle);
    927924
    928         // Calculate the mean speed over this past turn.
    929         m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
    930 
     925            // Calculate the mean speed over this past turn.
     926            m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
     927        }
     928       
    931929        if (wasObstructed)
    932930        {
    933931            // Oops, we hit something (very likely another unit).
    934932            // Stop, and recompute the whole path.
    935933            // TODO: if the target has UnitMotion and is higher priority,
    936934            // we should wait a little bit.
    937 
     935            // TODO: that's where we would push.
     936           
     937            m_CurSpeed = zero;
    938938            RequestLongPath(pos, m_FinalGoal);
    939939            m_PathState = PATHSTATE_WAITING_REQUESTING_LONG;
    940 
     940           
    941941            return;
    942942        }
    943943
     
    952952            // (or have reached it already), try to extend it
    953953
    954954            entity_pos_t minDistance = basicSpeed.Multiply(dt) * WAYPOINT_ADVANCE_LOOKAHEAD_TURNS;
    955             if (PathIsShort(m_ShortPath, pos, minDistance))
     955           
     956            CFixedVector2D distance = CFixedVector2D();
     957           
     958            if (!m_ShortPath.m_Waypoints.empty())
    956959            {
     960                CFixedVector2D wpoint(m_ShortPath.m_Waypoints[0].x,m_ShortPath.m_Waypoints[0].z);
     961                distance = wpoint - pos;
     962            }
     963            if (distance.CompareLength(minDistance) <= 0)
     964            {
    957965                // Start the path extension from the end of this short path
    958966                // (or our current position if no short path)
    959967                CFixedVector2D from = pos;
    960                 if (!m_ShortPath.m_Waypoints.empty())
     968                if (!distance.IsZero())
    961969                    from = CFixedVector2D(m_ShortPath.m_Waypoints[0].x, m_ShortPath.m_Waypoints[0].z);
    962970
    963971                if (PickNextLongWaypoint(from, ShouldAvoidMovingUnits()))
     
    11181126
    11191127bool CCmpUnitMotion::PathIsShort(const ICmpPathfinder::Path& path, CFixedVector2D from, entity_pos_t minDistance)
    11201128{
    1121     CFixedVector2D pos = from;
    11221129    entity_pos_t distLeft = minDistance;
    11231130
    11241131    for (ssize_t i = (ssize_t)path.m_Waypoints.size()-1; i >= 0; --i)
    11251132    {
    11261133        // Check if the next path segment is longer than the requested minimum
    11271134        CFixedVector2D waypoint(path.m_Waypoints[i].x, path.m_Waypoints[i].z);
    1128         CFixedVector2D delta = waypoint - pos;
     1135        CFixedVector2D delta = waypoint - from;
    11291136        if (delta.CompareLength(distLeft) > 0)
    11301137            return false;
    11311138
    11321139        // Still short enough - prepare to check the next segment
    11331140        distLeft -= delta.Length();
    1134         pos = waypoint;
     1141        from = waypoint;
    11351142    }
    11361143
    11371144    // Reached the end of the path before exceeding minDistance
  • source/simulation2/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)
  • source/simulation2/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;