Ticket #2094: MoveOptimization.2.patch
File MoveOptimization.2.patch, 6.3 KB (added by , 11 years ago) |
---|
-
source/simulation2/components/CCmpPosition.cpp
Index: source/simulation2/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 { -
source/simulation2/components/CCmpUnitMotion.cpp
53 53 * (This could typically be 1, but we need some tolerance in case speeds 54 54 * or turn lengths change.) 55 55 */ 56 static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 4;56 static const int WAYPOINT_ADVANCE_LOOKAHEAD_TURNS = 3; 57 57 58 58 /** 59 59 * Maximum range to restrict short path queries to. (Larger ranges are slower, … … 792 792 } 793 793 794 794 if (m_State == STATE_IDLE) 795 {796 795 return; 797 }798 796 799 797 switch (m_PathState) 800 798 { … … 860 858 // We want to move (at most) maxSpeed*dt units from pos towards the next waypoint 861 859 862 860 fixed timeLeft = dt; 863 864 while (timeLeft > fixed::Zero()) 861 fixed zero = fixed::Zero(); 862 863 while (timeLeft > zero) 865 864 { 866 865 // If we ran out of short path, we have to stop 867 866 if (m_ShortPath.m_Waypoints.empty()) … … 870 869 CFixedVector2D target(m_ShortPath.m_Waypoints.back().x, m_ShortPath.m_Waypoints.back().z); 871 870 CFixedVector2D offset = target - pos; 872 871 873 // Face towards the target874 if (!offset.IsZero())875 {876 entity_angle_t angle = atan2_approx(offset.X, offset.Y);877 cmpPosition->TurnTo(angle);878 }879 880 872 // Work out how far we can travel in timeLeft 881 873 fixed maxdist = maxSpeed.Multiply(timeLeft); 882 874 … … 923 915 924 916 // Update the Position component after our movement (if we actually moved anywhere) 925 917 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); 927 924 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 931 929 if (wasObstructed) 932 930 { 933 931 // Oops, we hit something (very likely another unit). 934 932 // Stop, and recompute the whole path. 935 933 // TODO: if the target has UnitMotion and is higher priority, 936 934 // we should wait a little bit. 937 935 // TODO: that's where we would push. 936 937 m_CurSpeed = zero; 938 938 RequestLongPath(pos, m_FinalGoal); 939 939 m_PathState = PATHSTATE_WAITING_REQUESTING_LONG; 940 940 941 941 return; 942 942 } 943 943 … … 952 952 // (or have reached it already), try to extend it 953 953 954 954 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()) 956 959 { 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 { 957 965 // Start the path extension from the end of this short path 958 966 // (or our current position if no short path) 959 967 CFixedVector2D from = pos; 960 if (! m_ShortPath.m_Waypoints.empty())968 if (!distance.IsZero()) 961 969 from = CFixedVector2D(m_ShortPath.m_Waypoints[0].x, m_ShortPath.m_Waypoints[0].z); 962 970 963 971 if (PickNextLongWaypoint(from, ShouldAvoidMovingUnits())) … … 1118 1126 1119 1127 bool CCmpUnitMotion::PathIsShort(const ICmpPathfinder::Path& path, CFixedVector2D from, entity_pos_t minDistance) 1120 1128 { 1121 CFixedVector2D pos = from;1122 1129 entity_pos_t distLeft = minDistance; 1123 1130 1124 1131 for (ssize_t i = (ssize_t)path.m_Waypoints.size()-1; i >= 0; --i) 1125 1132 { 1126 1133 // Check if the next path segment is longer than the requested minimum 1127 1134 CFixedVector2D waypoint(path.m_Waypoints[i].x, path.m_Waypoints[i].z); 1128 CFixedVector2D delta = waypoint - pos;1135 CFixedVector2D delta = waypoint - from; 1129 1136 if (delta.CompareLength(distLeft) > 0) 1130 1137 return false; 1131 1138 1132 1139 // Still short enough - prepare to check the next segment 1133 1140 distLeft -= delta.Length(); 1134 pos= waypoint;1141 from = waypoint; 1135 1142 } 1136 1143 1137 1144 // Reached the end of the path before exceeding minDistance -
source/simulation2/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) -
source/simulation2/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;