## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

No credit card required

mentioned, tweaking the parameters for a weighted sum can be quite a jug
-
gling act!
Weighted Truncated Running Sum with Prioritization
What a mouthful! This is the method used to determine the steering forces
for all the examples used in this book, chosen mainly because it gives a
good compromise between speed and accuracy. This method involves cal
-
culating a prioritized weighted running total that is truncated after the
addition of each force to make sure the magnitude of the steering force
does not exceed the maximum available.
The steering behaviors are prioritized since some behaviors can be con
-
sidered much more important than others. Let’s say a vehicle is using the
behaviors separation, alignment, cohesion, wall avoidance, and obstacle
avoidance. The wall avoidance and obstacle avoidance behaviors should
be given priority over the others as the vehicle should try not to intersect a
wall or an obstacle — it’s more important for a vehicle to avoid a wall than
it is for it to align itself with another vehicle. If what it takes to avoid a wall
is higgledy-piggledy alignment, then that’s probably going to be okay and
certainly preferable to colliding with a wall. It’s also more important for
vehicles to maintain some separation from each other than it is for them to
align. But it’s probably less important for vehicles to maintain separation
than avoid walls. See where I’m going with this? Each behavior is priori-
tized and processed in order. The behaviors with the highest priority are
processed first, the ones with the lowest, last.
In addition to the prioritization, this method iterates through every active
behavior, summing up the forces (with weighting) as it goes. Immediately
after the calculation of each new behavior, the resultant force, together with
the running total, is dispatched to a method called
AccumulateForce. This
function first determines how much of the maximum available steering
force is remaining, and then one of the following happens:
n
If there is a surplus remaining, the new force is added to the running
total.
n
If there is no surplus remaining, the method returns false. When this
happens,
Calculate returns the current value of m_vSteeringForce
immediately and without considering any further active behaviors.
n
If there is still some steering force available, but the magnitude
remaining is less than the magnitude of the new force, the new force
is truncated to the remaining magnitude before it is added.
Here is a snippet of code from the
SteeringBehaviors::Calculate method
SVector2D SteeringBehaviors::Calculate()
{
//reset the force.
How to Create Autonomously Moving Game Agents
| 121
Combining Steering Behaviors
m_vSteeringForce.Zero();
SVector2D force;
if (On(wall_avoidance))
{
force = WallAvoidance(m_pVehicle->World()->Walls()) *
m_dMultWallAvoidance;
if (!AccumulateForce(m_vSteeringForce, force)) return m_vSteeringForce;
}
if (On(obstacle_avoidance))
{
force = ObstacleAvoidance(m_pVehicle->World()->Obstacles()) *
m_dMultObstacleAvoidance;
if (!AccumulateForce(m_vSteeringForce, force)) return m_vSteeringForce;
}
if (On(separation))
{
force = Separation(m_pVehicle->World()->Agents()) *
m_dMultSeparation;
if (!AccumulateForce(m_vSteeringForce, force)) return m_vSteeringForce;
}
/* EXTRANEOUS STEERING FORCES OMITTED */
return m_vSteeringForce;
}
This doesn’t show all the steering forces, just a few so you can get the gen-
eral idea. To see the list of all behaviors and the order of their
prioritization, check out the
SteeringBehaviors::Calculate method in your
IDE. The
AccumulateForce method may also be better explained in code.
Take your time looking over this method and make sure you understand
what it’s doing.
bool SteeringBehaviors::AccumulateForce(Vector2D &RunningTot,
{
//calculate how much steering force the vehicle has used so far
double MagnitudeSoFar = RunningTot.Length();
//calculate how much steering force remains to be used by this vehicle
double MagnitudeRemaining = m_pVehicle->MaxForce() - MagnitudeSoFar;
//return false if there is no more force left to use
if (MagnitudeRemaining <= 0.0) return false;
//calculate the magnitude of the force we want to add