Ticket #2094: MoveOptimization.patch
File MoveOptimization.patch, 6.0 KB (added by , 11 years ago) |
---|
-
components/ICmpPosition.h
74 74 virtual void MoveTo(entity_pos_t x, entity_pos_t z) = 0; 75 75 76 76 /** 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 /** 77 82 * Move immediately to the given location, with no interpolation. 78 83 */ 79 84 virtual void JumpTo(entity_pos_t x, entity_pos_t z) = 0; -
components/CCmpPosition.cpp
238 238 239 239 AdvertisePositionChanges(); 240 240 } 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 } 241 258 242 259 virtual void JumpTo(entity_pos_t x, entity_pos_t z) 243 260 { -
components/CCmpUnitMotion.cpp
52 52 * (This could typically be 1, but we need some tolerance in case speeds 53 53 * or turn lengths change.) 54 54 */ 55 static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 4;55 static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 3; 56 56 57 57 /** 58 58 * Maximum range to restrict short path queries to. (Larger ranges are slower, … … 765 765 } 766 766 767 767 if (m_State == STATE_IDLE) 768 {769 768 return; 770 }771 769 772 770 switch (m_PathState) 773 771 { … … 833 831 // We want to move (at most) maxSpeed*dt units from pos towards the next waypoint 834 832 835 833 fixed timeLeft = dt; 836 837 while (timeLeft > fixed::Zero()) 834 fixed zero = fixed::Zero(); 835 836 while (timeLeft > zero) 838 837 { 839 838 // If we ran out of short path, we have to stop 840 839 if (m_ShortPath.m_Waypoints.empty()) … … 843 842 CFixedVector2D target(m_ShortPath.m_Waypoints.back().x, m_ShortPath.m_Waypoints.back().z); 844 843 CFixedVector2D offset = target - pos; 845 844 846 // Face towards the target847 if (!offset.IsZero())848 {849 entity_angle_t angle = atan2_approx(offset.X, offset.Y);850 cmpPosition->TurnTo(angle);851 }852 853 845 // Work out how far we can travel in timeLeft 854 846 fixed maxdist = maxSpeed.Multiply(timeLeft); 855 847 … … 896 888 897 889 // Update the Position component after our movement (if we actually moved anywhere) 898 890 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); 900 897 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 904 902 if (wasObstructed) 905 903 { 906 904 // Oops, we hit something (very likely another unit). 907 905 // Stop, and recompute the whole path. 908 906 // TODO: if the target has UnitMotion and is higher priority, 909 907 // we should wait a little bit. 910 908 // TODO: that's where we would push. 909 910 m_CurSpeed = zero; 911 911 RequestLongPath(pos, m_FinalGoal); 912 912 m_PathState = PATHSTATE_WAITING_REQUESTING_LONG; 913 913 914 914 return; 915 915 } 916 916 … … 925 925 // (or have reached it already), try to extend it 926 926 927 927 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()) 929 932 { 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 { 930 938 // Start the path extension from the end of this short path 931 939 // (or our current position if no short path) 932 940 CFixedVector2D from = pos; 933 if ( !m_ShortPath.m_Waypoints.empty())941 if (distance != zero) 934 942 from = CFixedVector2D(m_ShortPath.m_Waypoints[0].x, m_ShortPath.m_Waypoints[0].z); 935 943 936 944 if (PickNextLongWaypoint(from, ShouldAvoidMovingUnits())) … … 1089 1097 1090 1098 bool CCmpUnitMotion::PathIsShort(const ICmpPathfinder::Path& path, CFixedVector2D from, entity_pos_t minDistance) 1091 1099 { 1092 CFixedVector2D pos = from;1093 1100 entity_pos_t distLeft = minDistance; 1094 1101 1095 1102 for (ssize_t i = (ssize_t)path.m_Waypoints.size()-1; i >= 0; --i) 1096 1103 { 1097 1104 // Check if the next path segment is longer than the requested minimum 1098 1105 CFixedVector2D waypoint(path.m_Waypoints[i].x, path.m_Waypoints[i].z); 1099 CFixedVector2D delta = waypoint - pos;1106 CFixedVector2D delta = waypoint - from; 1100 1107 if (delta.CompareLength(distLeft) > 0) 1101 1108 return false; 1102 1109 1103 1110 // Still short enough - prepare to check the next segment 1104 1111 distLeft -= delta.Length(); 1105 pos= waypoint;1112 from = waypoint; 1106 1113 } 1107 1114 1108 1115 // Reached the end of the path before exceeding minDistance -
components/ICmpPosition.cpp
25 25 DEFINE_INTERFACE_METHOD_0("IsInWorld", bool, ICmpPosition, IsInWorld) 26 26 DEFINE_INTERFACE_METHOD_0("MoveOutOfWorld", void, ICmpPosition, MoveOutOfWorld) 27 27 DEFINE_INTERFACE_METHOD_2("MoveTo", void, ICmpPosition, MoveTo, entity_pos_t, entity_pos_t) 28 DEFINE_INTERFACE_METHOD_3("MoveAndTurnTo", void, ICmpPosition, MoveAndTurnTo, entity_pos_t, entity_pos_t, entity_pos_t) 28 29 DEFINE_INTERFACE_METHOD_2("JumpTo", void, ICmpPosition, JumpTo, entity_pos_t, entity_pos_t) 29 30 DEFINE_INTERFACE_METHOD_1("SetHeightOffset", void, ICmpPosition, SetHeightOffset, entity_pos_t) 30 31 DEFINE_INTERFACE_METHOD_0("GetHeightOffset", entity_pos_t, ICmpPosition, GetHeightOffset)