Optimize the "Move()" function by removing unnecessary message broadcast. Fixes #2094

This was SVN commit r14287.
This commit is contained in:
wraitii 2013-12-04 17:38:46 +00:00
parent 5f8b6be833
commit 0ef6397545
4 changed files with 40 additions and 19 deletions

View File

@ -238,6 +238,23 @@ public:
AdvertisePositionChanges();
}
virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry)
{
m_X = x;
m_Z = z;
m_RotY = ry;
if (!m_InWorld)
{
m_InWorld = true;
m_LastX = m_PrevX = m_X;
m_LastZ = m_PrevZ = m_Z;
m_LastYOffset = m_YOffset;
}
AdvertisePositionChanges();
}
virtual void JumpTo(entity_pos_t x, entity_pos_t z)
{

View File

@ -802,9 +802,7 @@ void CCmpUnitMotion::Move(fixed dt)
}
if (m_State == STATE_IDLE)
{
return;
}
switch (m_PathState)
{
@ -870,8 +868,9 @@ void CCmpUnitMotion::Move(fixed dt)
// We want to move (at most) maxSpeed*dt units from pos towards the next waypoint
fixed timeLeft = dt;
while (timeLeft > fixed::Zero())
fixed zero = fixed::Zero();
while (timeLeft > zero)
{
// If we ran out of short path, we have to stop
if (m_ShortPath.m_Waypoints.empty())
@ -880,13 +879,6 @@ void CCmpUnitMotion::Move(fixed dt)
CFixedVector2D target(m_ShortPath.m_Waypoints.back().x, m_ShortPath.m_Waypoints.back().z);
CFixedVector2D offset = target - pos;
// Face towards the target
if (!offset.IsZero())
{
entity_angle_t angle = atan2_approx(offset.X, offset.Y);
cmpPosition->TurnTo(angle);
}
// Work out how far we can travel in timeLeft
fixed maxdist = maxSpeed.Multiply(timeLeft);
@ -933,18 +925,25 @@ void CCmpUnitMotion::Move(fixed dt)
// Update the Position component after our movement (if we actually moved anywhere)
if (pos != initialPos)
cmpPosition->MoveTo(pos.X, pos.Y);
// Calculate the mean speed over this past turn.
m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
{
CFixedVector2D offset = pos - initialPos;
// Face towards the target
entity_angle_t angle = atan2_approx(offset.X, offset.Y);
cmpPosition->MoveAndTurnTo(pos.X,pos.Y, angle);
// Calculate the mean speed over this past turn.
m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
}
if (wasObstructed)
{
// Oops, we hit something (very likely another unit).
// Stop, and recompute the whole path.
// TODO: if the target has UnitMotion and is higher priority,
// we should wait a little bit.
m_CurSpeed = zero;
RequestLongPath(pos, m_FinalGoal);
m_PathState = PATHSTATE_WAITING_REQUESTING_LONG;
@ -1138,20 +1137,19 @@ bool CCmpUnitMotion::CheckTargetMovement(CFixedVector2D from, entity_pos_t minDe
bool CCmpUnitMotion::PathIsShort(const ICmpPathfinder::Path& path, CFixedVector2D from, entity_pos_t minDistance)
{
CFixedVector2D pos = from;
entity_pos_t distLeft = minDistance;
for (ssize_t i = (ssize_t)path.m_Waypoints.size()-1; i >= 0; --i)
{
// Check if the next path segment is longer than the requested minimum
CFixedVector2D waypoint(path.m_Waypoints[i].x, path.m_Waypoints[i].z);
CFixedVector2D delta = waypoint - pos;
CFixedVector2D delta = waypoint - from;
if (delta.CompareLength(distLeft) > 0)
return false;
// Still short enough - prepare to check the next segment
distLeft -= delta.Length();
pos = waypoint;
from = waypoint;
}
// Reached the end of the path before exceeding minDistance

View File

@ -25,6 +25,7 @@ BEGIN_INTERFACE_WRAPPER(Position)
DEFINE_INTERFACE_METHOD_0("IsInWorld", bool, ICmpPosition, IsInWorld)
DEFINE_INTERFACE_METHOD_0("MoveOutOfWorld", void, ICmpPosition, MoveOutOfWorld)
DEFINE_INTERFACE_METHOD_2("MoveTo", void, ICmpPosition, MoveTo, entity_pos_t, entity_pos_t)
DEFINE_INTERFACE_METHOD_3("MoveAndTurnTo", void, ICmpPosition, MoveAndTurnTo, entity_pos_t, entity_pos_t, entity_pos_t)
DEFINE_INTERFACE_METHOD_2("JumpTo", void, ICmpPosition, JumpTo, entity_pos_t, entity_pos_t)
DEFINE_INTERFACE_METHOD_1("SetHeightOffset", void, ICmpPosition, SetHeightOffset, entity_pos_t)
DEFINE_INTERFACE_METHOD_0("GetHeightOffset", entity_pos_t, ICmpPosition, GetHeightOffset)

View File

@ -73,6 +73,11 @@ public:
*/
virtual void MoveTo(entity_pos_t x, entity_pos_t z) = 0;
/**
* Combines MoveTo and TurnTo to avoid an uncessary "AdvertisePositionChange"
*/
virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry) = 0;
/**
* Move immediately to the given location, with no interpolation.
*/