opensteer/doc/images/beta_250a.gif
opensteer/doc/images/beta_90a.gif
opensteer/doc/images/typical_SteerTest.png
opensteer/doc/contact.html
OpenSteer
Steering Behaviors for Autonomous Characters
HomeSourceForge
project
pageOpen
Discussion forumDownload
softwareDocumentation
Contact
Contact:
If you have questions or comments, the best way
to
communicate with the OpenSteer community is to post a message at the Open
Discussion forum. (Free SourceForge
registration
is required to post there, members can monitor the forum to get
email
notifications of new posts.) You can also subscribe to a low
traffic mailing
list for announcements about OpenSteer.
Alternately you can send email
to the author who will pass it along to the forum. If your
message is not appropriate for the public forum please indicate that
clearly at the beginning of your email.
Credits:
OpenSteer was initially developed by Craig Reynolds
beginning in 2002 at
the Research and Development
group of Sony Computer Entertainment
America. We wish to acknowledge the support of SCEA, SCEI and in
particular these executives who had the foresight to release this code
as open source for all to use: Shin'ichi Okamoto, Masa Chatani and
Dominic Mallinson.
Since OpenSteer's source code was first made
available on May
1, 2003
a group of dedicated volunteers have contributed by testing and
extending the original implementation. Ports to Windows and Mac OS X
were made within a day and the required changes folded back into the
main source. The community continues to discuss, test and imrpove
OpenSteer. To contribute, or to just listen in, please visit the Open
Discussion forum.
Last modified: October 19, 2004
Here is a partial list of those who have
contributed
to OpenSteer,
sorted roughly by the amount and "freshness" of their contributions:
Bjoern Knafla (bknafla),
Nick Porcino (meshula),
Ben Forsyth (bforsyth),
Dominik (inikofdoom),
Paul (spanneradmin),
Leaf Garland (leaf),
Stefan Moises (beffy),
Bruce Mitchener (brucem),
Maciej Sinilo (yarpen),
Michael Holm (gizwiz),
Richard Cannock (perambulator).
Let us know of any omissions from this list.
opensteer/doc/doc.html OpenSteer
Documentation
October 19, 2004
Version 0.8.2 by
Craig ReynoldsResearch and DevelopmentSony Computer Entertainment AmericaTable of Contents
IntroductionWet PaintUsing OpenSteerDemoSample PlugInsWriting PlugInsSteering LibraryIntegrating with Your CodeInstalling OpenSteerKnown Bugs and Missing FeaturesRelated Links
Introduction
OpenSteer is an open source library of components to help
build steering behaviors
for autonomous characters in games and other kinds of multi-agent
simulations. These agents may represent characters (humans, animals,
alien creatures), vehicles (cars, planes, spaceships) or other kinds
of mobile agents. OpenSteer was originally d.
2. communicate with the OpenSteer community is to post a
message at the Open
Discussion forum. (Free SourceForge
registration
is required to post there, members can monitor the forum to get
email
notifications of new posts.) You can also subscribe to a low
traffic mailing
list for announcements about OpenSteer.
Alternately you can send email
to the author who will pass it along to the forum. If your
message is not appropriate for the public forum please indicate
that
clearly at the beginning of your email.
Credits:
OpenSteer was initially developed by Craig Reynolds
beginning in 2002 at
the Research and Development
group of Sony Computer Entertainment
America. We wish to acknowledge the support of SCEA, SCEI
and in
particular these executives who had the foresight to release this
code
as open source for all to use: Shin'ichi Okamoto, Masa Chatani
and
Dominic Mallinson.
3. Since OpenSteer's source code was first made
available on May
1, 2003
a group of dedicated volunteers have contributed by testing and
extending the original implementation. Ports to Windows and
Mac OS X
were made within a day and the required changes folded back
into the
main source. The community continues to discuss, test and
imrpove
OpenSteer. To contribute, or to just listen in, please visit the
Open
Discussion forum.
Last modified: October 19, 2004
Here is a partial list of those who have
contributed
to OpenSteer,
sorted roughly by the amount and "freshness" of their
contributions:
Bjoern Knafla (bknafla),
Nick Porcino (meshula),
Ben Forsyth (bforsyth),
Dominik (inikofdoom),
Paul (spanneradmin),
Leaf Garland (leaf),
Stefan Moises (beffy),
Bruce Mitchener (brucem),
Maciej Sinilo (yarpen),
Michael Holm (gizwiz),
4. Richard Cannock (perambulator).
Let us know of any omissions from this list.
opensteer/doc/doc.html OpenSteer
Documentation
October 19, 2004
Version 0.8.2 by
Craig ReynoldsResearch and DevelopmentSony Computer
Entertainment AmericaTable of Contents
IntroductionWet PaintUsing OpenSteerDemoSample
PlugInsWriting PlugInsSteering LibraryIntegrating with Your
CodeInstalling OpenSteerKnown Bugs and Missing
FeaturesRelated Links
Introduction
OpenSteer is an open source library of components to help
build steering behaviors
for autonomous characters in games and other kinds of multi-
agent
simulations. These agents may represent characters (humans,
animals,
alien creatures), vehicles (cars, planes, spaceships) or other
kinds
of mobile agents. OpenSteer was originally developed on Linux
and
was subsequently ported to Windows and Mac OS X.
5. OpenSteer provides a toolkit of steering behaviors, defined in
terms of an abstract mobile agent called a vehicle. Sample
code
is provided, including a simple vehicle implementation and
examples of
combining simple steering behaviors to produce more complex
behavior. In order to allow flexible integration with existing
game
engines OpenSteer can add its functionality by either layering
or
inheritance. [see "Integrating with Your
Code" below] Note that OpenSteer is intended for use by
programmers. It does not plug into interactive production tools,
nor
does it support behavior authoring by non-programmers.
In addition to the library, OpenSteer provides an
interactive application called OpenSteerDemo which initially
demonstrates several steering behaviors. OpenSteerDemo can
also help
you
create novel steering behaviors, providing facilities to visualize,
annotate and debug your code. OpenSteerDemo is written in
C++ and uses
OpenGL
graphics. All OpenGL calls are segregated in one module, in
case you
need to substitute another graphics API.
OpenSteerDemo is based on a plug-in architecture: an empty
framework into which plug-ins can be added incrementally.
OpenSteerDemo
comes with several sample plug-ins.
[see "Sample PlugIns"
below] You can easily create your own plug-ins by starting
from these examples. A OpenSteerDemo plug-in specifies
several generic
6. actions required by the OpenSteerDemo framework: open, close,
reset,
run
one simulation step, display one frame, and so on. The plug-in
defines
vehicle classes and manages them in simulation. It defines
scene
geometry in terms of obstacles, pathways and so on. Plug-ins
control
the camera and handle Function Keys.
OpenSteerDemo's plug-in framework allows a game AI
programmer to
quickly prototype behaviors during game design, and to develop
behaviors before the main game engine is finished. In
OpenSteer 0.8.2,
OpenSteerDemo allows the user to interactively control
simulation time
(stop, start, single step), select the vehicle/character/agent of
interest, and adjust the
view and tracking behavior of the camera.
OpenSteer is distributed as open source software in accordance
with
the MIT
License.
Wet Paint!
Warning: OpenSteer 0.8.2 is still under active development. It
is
not mature or stable. Its current design is subject to change and
reorganization, although every attempt will be made to avoid
gratuitous changes. We welcome your interest in OpenSteer and
encourage experimentation. However please contact
us before planning to integrate
OpenSteer into any large project.
Note also that the term plug-in is currently misused here.
7. Normally it implies that a new module can be added to an
application
at run time. Whereas in OpenSteer 0.8.2 the "plugging-in" must
happen at application build (link) time. One would hope this
was fixed in a future release (he said, hoping to avoid specific
promises of future enhancements).
Using OpenSteerDemo
After installation [see
"Installing OpenSteer" below] launch the OpenSteerDemo
application. (On Linux, Mac or Windows you can do this by
double clicking on a desktop icon. If you have downloaded the
OpenSteer source code and compiled it yourself, you can also
launch the
application from your IDE build tools. If you use the supplied
Makefile for Linux, you can execute the make run command.)
When you
first use OpenSteerDemo, this quick
reference guide may be helpful. The application will open a
single window labeled "OpenSteerDemo 0.8.2". You should see
a
diagrammatic 3d
view of the default PlugIn. Typically you will see moving
vehicles,
annotation graphics and textual overlays, as shown in [Figure
1].
Figure 1: typical OpenSteerDemo window
8. Eventually OpenSteerDemo may have a menu-based graphical
user
interface. For now it supports limited mouse-based interaction
(camera view adjustment, vehicle selection) and recognizes
several
single key commands:Tabselect next PlugInrrestart current
PlugInsselect next vehicle/agent/character (or
mouse-click to select)cselect next camera aiming modefselect
next preset frame rate
(as-fast-as-possible, 24fps, 60fps)atoggle annotation
on/offSpacetoggle between Run and Pause-> (right arrow)step
forward one frame?print "mini help" on console (or see
the quick reference guide)Escexit OpenSteerDemo
In addition a PlugIn can provide handlers for the Function
Keys (labeled F1 through F12 on most keyboards). Type a ? to
print a list of all recognized
commands, including those handled
by the current PlugIn. (There is an issue with printing [see
"Known Bugs" below].)
OpenSteerDemo keeps track of a single selected agent which
the
camera follows. In some demos additional annotation is
provided for
the selected agent. The user can change selection with the
mouse.
Pointing the mouse near an agent will cause it to highlight (for
example, in the provided 2d demos, a gray disk is drawn under
it).
Clicking the (left) mouse button selects the highlighted agent.
OpenSteerDemo's camera (point of view) adjusts itself
automatically
to keep the selected vehicle in view. Several different camera
aiming
modes are provided:staticfixed
9. camerafixed distance offsetcamera remains a fixed distance
from selected
vehicle fixed local offsetcamera remains fixed in selected
vehicle's
local space straight downcamera looks at selected vehicle from
directly above offset POVcamera looks in selected vehicle's
forward
direction, from a given
offset in the vehicle's local space
You can adjust the camera's view with the mouse (or whatever
input
device you use). OpenSteerDemo lets you adjust the camera's
position
relative to its aimpoint. The aimpoint is defined by
camera
aiming mode and is normally the (predicted future position of
the)
selected vehicle. To adjust the camera: hold down the
keyboard's
control (Ctrl) key while dragging the mouse with its left
button held down. 2D mouse motion is mapped into the camera's
space,
rotating the camera's position around its aimpoint. This allows
the
camera to move on the surface of a sphere centered at the
aimpoint.
The radius of this sphere--the "viewing distance"--can be
adjusted by
dragging the mouse with the middle button held down (vertical
mouse
motion maps to distance). If you use a one- or two-button mouse
(hence no middle button) you can adjust the radius by holding
down
both the Ctrl and Alt ("control-meta-") keys while dragging the
mouse
with its left button held down. Note that adjustments in "offset
10. POV"
camera aiming mode actually translate rather than rotate the
camera
position relative to the selected vehicle.
To preserve a stable view, OpenSteerDemo's camera will
smoothly
interpolate over changes due to: motion of the selected vehicle,
mouse-based camera adjustment, or switching camera aiming
modes.
OpenSteerDemo's clock provides two time streams: real
time and
simulation time. The redraw cycle and camera update are based
on passage of real time. Simulation time normally follows real
time
but can also be paused, freezing simulation of vehicle motion.
Pausing the simulation often helps to allow examining
annotation in
detail, or to interactively reposition the camera. (In the current
implementation: when simulation time is paused, simulation
updates
continue to happen each frame, but the elapsed time ("dt") is
given as zero.) The clock can be set to run in one of three
modes
described in the table below. You can use OpenSteerDemo's
f keyboard command to cycle among several
preset combinations of clock mode and target frame rate. Your
PlugIn code can also set these modes using Clock methods:
get/setFixedFrameRate, get/setAnimationMode,
get/setVariableFrameRateMode, get/set/togglePausedState. For
more detail, see Clock.hvariable frame rateFor viewing real-
time simulations. Updates
run as
fast as possible. Simulation time steps are set equal to the
amount of
real time elapsed since the previous update. Similar to graphics
11. on a PC.
fixed target frame rate For viewing real-time simulations.
Updates
are
constrained to occur at multiples of a fixed frame rate (often 30
or 60
fps) by waiting until the next fame boundary. If the update
takes too long, it has to wait for the second frame boundary (aka
frame out or double
framing). Similar to graphics on a video game console.
animation mode
For running fixed time step simulations,
generally not in real-time,
which may
appear to run in "slow motion". Ignores real time to produce
consistent simulation results.
OpenSteerDemo aims to support a developer's work by
providing tools
and
utilities that while helpful, might not be critical enough to
justify
writing them during a production schedule. This includes
various API
for drawing annotation using elements such as lines, vectors,
boxes,
circles, disks, spheres and text attached to the screen or
positions
in 3d space. A facility is provided for drawing streamers/trails
which display a vehicle's recent motion then fade away. There
are
utilities for drawing a ground plane and highlighting vehicles in
various ways. See Annotation.h and OpenSteerDemo.h for
12. details. You can turn annotation on and off with
OpenSteerDemo's a
command.
Sample PlugIns
OpenSteerDemo is distributed with several PlugIns intended to
serve
both
as demonstrations of steering behaviors, and as sample code:
jumping
off places for you to begin developing your own steering
behaviors.
The current list of sample PlugIns are:
Capture the Flag: a single (bluish) attacker attempts to
reach a central goal while four (reddish) defenders try to
intercept
("tag") the attacker before it gets to the goal. The playing field
is
optionally littered with obstacles. This benchmark was proposed
by
Marcin Chady of the Working Group on Steering of the IGDA's
AI
Interface Standards Committee. The obstacles are spheres,
depicted by
their equator. Press F1 to add an obstacle (up to 100 of them),
F2 to
remove one. The "game" ends when the attacker reaches the
goal or a
defender tags the attacker. The demo automatically restarts a
few
seconds later. The attacker combines three basic steering
behaviors:
13. goal seeking, evasion and obstacle avoidance.
The defenders combine pursuit and obstacle avoidance. A
key to "non-stupid" behavior by the attacker was to notice when
there
is a defender-free "corridor" between it and the goal. When
found,
this corridor is depicted by a green outline. In this case the
attacker uses pure seek and stops evading nearby defenders.
The pursuit behavior of the defenders needed to specialized so
that
they "knew" not to predict the motion of the attacker past its
goal.
The defenders do not otherwise think about global strategy, for
example they don't try to place themselves between the attacker
and
the goal. Currently defenders ignore each other, they probably
should
separate or avoid collisions with each other, ideally they would
coordinate their pursuit. The attacker is easily confused when
several defenders converge from different directions. Obstacles
are
always avoided by going toward the nearer edge, as discussed in
the
Steering Working Group's forum, this is frequently the "wrong"
direction when considering the agent's other goals. I want to
revisit
this later.
MapDrive: path-following
through map-based obstacles using curvature-based prediction
and
steering. This demonstration is inspired by the DARPA Grand
Challenge
cross country race for autonomous vehicles.
A route is defined as a series of (GPS) waypoints and a width
associated with each segment between waypoints. This demo
assumes
14. sensors on-board the vehicle create a binary map classifying the
surrounding terrain into drivable
and not drivable. The vehicle
tries
to follow the route while avoiding obstacles and maximizing
speed. When
the vehicle finds itself in danger of collision, it "gives up"
(turns
yellow) and slows to a stop. If it collides with an obstacle it
turns
red. In both cases the simulation is restarted. (This plug-in
includes
two non-path-following demos of map-based obstacle
avoidance. Use F1 to
select among them.)
Pedestrians: 100 agents follow a path (the red line) and try
not to collide with each other or two large spherical obstacles.
Press F1 to add a Pedestrian and F2 to remove one. This
multiagent
simulation uses a spatial database to accelerate proximity
queries, F3
cycles among types of proximity databases (two exist in
OpenSteer
0.8.2). F4 toggles between two versions of path following: stay
on the
path and directed path
following. The latter means to stay on
the path while moving along it in a given direction. A
Pedestrian's
direction is
reversed when reaches the end of the path. Press F5 to toggle a
Pedestrian's wander
component on and off.
Boids: 200 simulated flocking bird like objects. The
boids model is a simple combination of separation, alignment
15. and cohesion steering behaviors. Press F1 to add a Boid
and F2 to remove one. This multiagent simulation uses a spatial
database to accelerate proximity queries, F3
cycles among types of proximity databases (two exist in
OpenSteer
0.8.2). The flock flies within a sphere, F4 toggles between two
boundary
conditions. One is "steer back when outside" -- when a boid
travels
outside the sphere it begins to seek
towards the center. The other is "wrap around (teleport)" --
boids that fly out of the sphere are instantly repositioned to the
opposite side of the sphere.
Soccer: this simulation of a
simple soccer game was contributed by Michael Holm of IO
Interactive on July 9, 2003.
It consists of a blue and red team of 8 Players each, a green Ball
and
an axis aligned bounding box
class (AABBox) used to represent the field and the two goals.
As
play proceeds the PlugIn keeps score. The ball is derived from
SimpleVehicle but its vehicle-like motion is replaced by bounce
physics. Michael invites others to contribute improved Player
designs.
Multiple Pursuit: a "test fixture" for the pursue
behavior. 30 pursuers chase one wandering quarry. The colored
lines
indicate the predicted future position of the quarry being used
as a
seek target by each pursuer. The colors indicate which of nine
prediction cases is active. When a pursuer reaches the quarry it
16. is
"teleported" away to a random position.
Low Speed Turn: a "test fixture" for evaluating the response
of a vehicle to backward-pointing steering force while moving
at low
speed.
One Turning Away: this was the first one, now it serves as a
minimal example of a PlugIn.
Writing PlugIns
Developing interesting, lifelike steering behaviors is an unique
type of programming. It mixes the mathematical and algorithmic
rigor
of computer programming with a more artistic, aesthetic-based
phase of
parameter tweaking. OpenSteer is intended to allow you to
focus on
developing steering behaviors without having to worry about all
of the
required framework. This is supported through
OpenSteerDemo's PlugIn
mechanism. When you write a PlugIn, you need to provide only
the code
that is specific to your own vehicles and their steering
behaviors.
Currently the best source of detailed information on the PlugIn
interface is in the C++ header file PlugIn.h. See particularly
the commented-out meta-example called
FooPlugIn. That header file defines two classes: AbstractPlugIn
(a pure virtual interface
class) and PlugIn which provides the
base implementation. To create a new OpenSteerDemo PlugIn,
17. you will
define a new class which inherits the base implementation from
PlugIn. It provides some default methods
(see
PlugIn.h for details) which you can overload to customize,
particularly reset. You must implement
six methods on your new class to fulfill the
AbstractPlugIn protocol:namereturns a character string
nameopenallocate and initialize
vehiclesclosedeallocateupdateperform one stimulation
stepredrawdo all graphics for one frameallVehiclesreturn a
group of all this PlugIn's vehicles
For a minimal working PlugIn see "One Turning Away"
(opensteer/plugins/OneTurning.cpp) which defines a single
vehicle with trivial behavior. LowSpeedTurn also has trivial
behavior
and features multiple vehicles, Boids has many vehicles,
MultiplePursuit has two kinds of vehicles, Pedestrian and
CaptureTheFlag are more complicated samples.
Probably the easiest way to get started on your own PlugIn is:
(1)
pick one of the samples that seems most closely related (2)
make a
renamed copy of it (3) build OpenSteerDemo (4) verify that the
new
PlugIn
appears and has its old behavior (5) make
incremental
changes to the working PlugIn to create your own behavior. If
you are
using an IDE (an Integrated Development Environment such as
Xcode or Visual Studio) you will
have to add your new PlugIn's source file to your IDE project
(probably by adding it as a
component to the OpenSteerDemo build target). On Linux using
make (or KDevelop), if you leave your
18. PlugIn's source file in the standard directory
(opensteer/plugins/)
will be compiled automatically. (Ideally compiling a PlugIn
should not require compiling OpenSteerDemo [see
"Known Bugs" below].)
The samples in opensteer/plugins/ each define at least one
new vehicle class and one new PlugIn class. A key requirement
is that
a single instance of the new PlugIn class be statically allocated,
as
in: // define a new Vehicle
class OneTurning : public SimpleVehicle {...}
// define a new PlugIn
class OneTurningPlugIn : public PlugIn {...}
// instantiate the PlugIn
OneTurningPlugIn gOneTurningPlugIn;
The name of that global (gOneTurningPlugIn)
is irrelevant, what
matters is that a single instance of the new PlugIn class
(OneTurningPlugIn) is allocated for the
lifetime of the OpenSteerDemo application. The actual
"plugging in" is
handled by the constructor(/destructor) of the
PlugIn base class. A class which is intended to be
instantiated exactly once is sometimes called a singleton.
PlugIns expect to be instantiated exactly once but do not
enforce or
19. detect violations of that policy. Because PlugIns register
themselves, the samples are defined in .cpp files and there is
no need for .h files. You may wish to organize your PlugIn
differently, perhaps with a .h file or perhaps including one
for a class of vehicle defined elsewhere.
Normally your PlugIn will define one or more classes of
Vehicle.
OpenSteer tries to provide a lot of flexibility in how this can be
done. On the other hand, if you are just trying to get your first
experiment running under OpenSteerDemo, you probably want
what Devo
called
"freedom from choice." The easiest approach, and what all the
provided samples do, is to define a new vehicle class as a
specialization of SimpleVehicle. In
general, all that is required to make use of the OpenSteer
steering
library is to support the
AbstractVehicle protocol in whatever manner you see fit.
OpenSteerDemo and the provided PlugIns make use of two
types defined
in AbstractVehicle: AbstractVehicle::group
and AbstractVehicle::iterator.
These are typedefed to the names AVGroup and
AVIterator. AVGroup is used whenever a group of
AbstractVehicles need to be remembered or
passed as a function argument.
AVIterator is used to iterate over the contents of an AVGroup.
These types are based on the C++
STL
(Standard Template Library) parameterized types
vector and const_iterator. AVGroup
and AVIterator are used inside
the OpenSteer library, but if you wish to avoid using STL it
should be
easy to replace them with your own implementation of
20. collections and
iteration.
Random notes for PlugIn writers:
Time values are currently passed as float values, measured in
seconds. Perhaps there should be a more specific typedef for
time.
Vec3 is the type used
throughout
OpenSteer to represent geometric vectors in 3d Cartesian space.
Colors are currently represented as Vec3s.
Perhaps there should be a
more
specific typedef for color.
One way to help debug or analyze your steering behaviors is to
pick one vehicle and provide additional information about it,
using
graphical annotation or printed output. A convenient choice is
OpenSteerDemo's selected vehicle: the
one the camera normally follows and which can be changed with
a mouse
click (or the OpenSteerDemo s command). To trigger
code
specifically for the selected vehicle, use something like this in
your
vehicle's update method:
if (this == OpenSteerDemo::selectedVehicle) {...}
Steering Library
Note: this section is preliminary and subject to change. The
documentation could conceivably be out of sync with the library
itself.
For the Real Truth always consult the source code.
In current organization of OpenSteer, its main library of
21. steering
behaviors is contained in the class SteerLibraryMixin (defined
in
SteerLibrary.h). A mixin is a class with templated superclass
-- it is used to add a set of methods to a given base class.
[see "Integrating with Your Code"
below] In this case, SteerLibraryMixin adds steering
functionality to a class which supports the AbstractVehicle
interface.
For example, SimpleVehicle combines SteerLibraryMixin and
several
other utilities with AbstractVehicle. As a result, SimpleVehicle
has
all of the methods defined in SteerLibraryMixin, which are
listed
below.
Note that several of the steering behaviors will return a zero
vector value (0, 0, 0) to indicate "no steering is required at this
time" typically because a goal is already met. The caller can
detect
these cases by testing to see if
the returned steering value is equal to zero:
if (steering == Vec3::zero) ...
Wander behavior
Vec3 steerForWander (float dt);
Returns a steering force for wandering behavior. The steering
value is purely tangential (has no Forward component). The
time step
value allows wander rate to be consistent when frame times
vary.
22. Seek behavior
Vec3 steerForSeek (const Vec3& target);
Returns a steering force to seek the given target location.
Causes
a vehicle to turn toward the target and move to it. If this
behavior
is used alone and unconditionally, it will cause the vehicle to
pass
through the target then turn around for another pass.
Flee behavior
Vec3 steerForFlee (const Vec3& target);
Returns a steering force to flee from the given target location.
Causes a vehicle to turn away from the target and move away
from it
it.
Path Following behavior
Vec3 steerToFollowPath (const int direction,
const float predictionTime,
Pathway& path)
Vec3 steerToStayOnPath (const float predictionTime, Pathway&
path)
23. Returns a steering force to follow a given path.
steerToStayOnPath just tries to keep the
vehicle on the path. steerToFollowPath
provides directed path following where
the vehicle both stays on the path and heads in a given direction
along
the path, as indicated by the direction
argument which should be either +1 or -1. The path
defines a tube in terms of a spine and a radius ,
the goal is to keep a vehicle headed toward a point inside that
tube.
(OpenSteer 0.8.2 provides one kind of Path with a polyline
spine:
a
series of connected line segments (see Pathway.h)
and a prototype of another kind of path called GCRoute is
defined in
the MapDrive PlugIn.)
Steering is determined based on a prediction of the vehicle's
position predictionTime seconds into
the
future. If that predicted position is inside the pathway (and in
the
case of directed path following, is headed in the correct
direction)
this
function returns a zero vector value. Otherwise it steers toward
a point on the path.
Obstacle Avoidance behavior
Vec3 steerToAvoidObstacle (const float minTimeToCollision,
24. const Obstacle& obstacle);
Vec3 steerToAvoidObstacles (const float minTimeToCollision,
const ObstacleGroup& obstacles)
Returns a steering force to avoid given obstacles. The obstacles
can be specified as either a single Obstacle or as a
ObstacleGroup (an STL Vector of Obstacle pointers). The
purely
lateral steering force will turn our vehicle towards a silhouette
edge
of the obstacle. Avoidance is required when (1) the obstacle
intersects the vehicle's current path, and (2) it is in front of the
vehicle, and (3) is within minTimeToCollision seconds
of travel at the vehicle's current velocity. If multiple Obstacles
were
specified, and multiple potential collisions exist, the nearest
(most
urgent) one is chosen. When no
avoidance is required this function returns a zero vector value.
Note that the older steerToAvoidObstacle
calling sequence may be changed or removed in the future.
Unaligned Collision Avoidance behavior
Vec3 steerToAvoidNeighbors (const float minTimeToCollision,
const AVGroup& others);
Returns a steering force to avoid colliding with other nearby
vehicles moving in unconstrained directions. Determine which
(if any)
other other vehicle we would collide with first, then steers to
avoid
25. the site of that potential collision. (The current (2D) version
only
steers laterally, it does not speed up or slow down, as described
in
the GDC
1999 paper.) Returns a steering force vector of zero length if
there is no impending collision.
Separation behavior
Vec3 steerForSeparation (const float maxDistance,
const float cosMaxAngle,
const AVGroup& flock);
Returns a steering force to move us away from nearby boids.
Alignment behavior
Vec3 steerForAlignment (const float maxDistance,
const float cosMaxAngle,
const AVGroup& flock);
Returns a steering force to align us with nearby boids.
Cohesion behavior
Vec3 steerForCohesion (const float maxDistance,
const float cosMaxAngle,
const AVGroup& flock);
26. Returns a steering force to move us towards the "center of
mass"
of
nearby boids.
Pursuit behavior
Vec3 steerForPursuit (const AbstractVehicle& quarry);
Vec3 steerForPursuit (const AbstractVehicle& quarry,
const float maxPredictionTime);
Returns a steering force to pursue another moving vehicle.
Heads
towards the predicted point of interception. An alternate version
is
provided to specify a ceiling on the prediction interval: aim for
where the quarry will be in (say) 5 seconds, or the point of
interception, whichever happens sooner.
Evasion behavior
Vec3 steerForEvasion (const AbstractVehicle& menace,
const float maxPredictionTime);
Returns a steering force to evade another moving vehicle. Heads
away from the predicted point of interception.
Speed Maintenance behavior
27. Vec3 steerForTargetSpeed (const float targetSpeed);
Returns a steering force to maintain a given target speed. The
value will be along the vehicle's forward/backward axis and its
length
will be clipped to the vehicle's maxForce parameter.
Annotation "hooks"
These "do nothing" methods are defined by
SteerLibraryMixin. They are called when various steering
behaviors decide to take action. These hook methods are
intended to be
overloaded
by
PlugIn writers to provide graphical annotation, or other side
effects. For
example the Pedestrian vehicle class overloads
annotateAvoidObstacle to draw annotation lines around the
vehicle's obstacle avoidance corridor when an obstacle is found
inside
of it.
// Called when steerToAvoidObstacles decides steering is
required.
virtual void annotateAvoidObstacle (const float
minDistanceToCollision);
// Called when steerToFollowPath decides steering is required.
virtual void annotatePathFollowing (const Vec3& future,
const Vec3& onPath,
const Vec3& target,
const float outside);
// Called when steerToAvoidCloseNeighbors decides steering is
required.
virtual void annotateAvoidCloseNeighbor (const
28. AbstractVehicle& other,
const float additionalDistance);
// Called when steerToAvoidNeighbors decides steering is
required.
virtual void annotateAvoidNeighbor (const AbstractVehicle&
threat,
const float steer,
const Vec3& ourFuture,
const Vec3& threatFuture);
Integrating with Your Code
Note: this section is so preliminary that it is really just a
placeholder...
This section will eventually talk about the structure of
OpenSteer's classes, and how they are designed to provide you
with
flexibility as you integrate OpenSteer with your existing code.
It
will mention that if you were writing new code, you could
always base
your classes on OpenSteer's. More typically you will already
have an
existing code base, a game engine or a procedural animation
system,
into which you want to integrate some of OpenSteer's facilities.
OpenSteer's classes have been designed to allow you freedom to
either inherit its functionality, or to layer its functionality on
top
of your existing classes. The latter approach is supported by the
concept of
mixin classes (essentially a class with templated superclass)
which allows its functionality to be "mixed in with" (or "layered
on
29. top of") your existing classes. A similar effect can be obtained
by
multiple inheritance of your preexisting base classes and
OpenSteer's
classes, but most C++ programmers prefer to avoid multiple
inheritance. Many of OpenSteer's classes are defined in three
parts:
an abstract protocol (aka interface or pure virtual class:
"AbstractLocalSpace"), an implementation expressed as a mixin
("LocalSpaceMixin") and an instantiable class made by layering
the
mixin on top of the abstract protocol ("LocalSpace"). For more
detail
see LocalSpace.h and the discussion at the top of
SimpleVehicle.h
Finally OpenSteer anticipates that it may be used in class
hierarchies based on either the IS-A or the HAS-A architecture.
That
is, you might want an agent in your game to be structured so
that it
IS-A OpenSteer Vehicle or you may want to structure it so that
it HAS-A
Vehicle as a component part. (But no sample of using an
OpenSteer
Vehicle in a HAS-A architecture is provided [see
"Known Bugs" below].)
Installing OpenSteer
OpenSteer can be used several ways. You may want to simply
download
the OpenSteerDemo application to run the demos. You may
want to browse
through some of the source code over the web. You may want to
30. download
a complete copy of the source to try some informal code-
tweaking
experiments.
Or you may be interested in joining with the community of
developers
actively maintaining and improving the OpenSteer software by
using code
from the CVS
repository.
To download an executable copy of the OpenSteerDemo
application,
or a zip archive of the full source, visit
OpenSteer's
file release page at
SourceForge. The OpenSteerDemo application is
available
as precompiled binary executables for Linux, Mac OS X, and
Windows. Source code and compiled applications are grouped
together by release. You can receive notifications of future
releases by subscribing to a low traffic mailing
list for OpenSteer announcements. The current release is
OpenSteer 0.8.2 which contains these files:
OpenSteer_0_8_2_source.zip
Full source code for OpenSteer 0.8.2
OpenSteerDemo_0_8_2_linux.zip
OpenSteerDemo application (Linux .elf)
OpenSteerDemo_0_8_2_macosx.dmg
OpenSteerDemo application (Mac OS X .app)
OpenSteerDemo_0_8_2_win32.zip
31. OpenSteerDemo application (Windows .exe)
Otherwise, use CVS
to obtain the most up-to-date version of the
OpenSteer source code. If you want to be a developer, or at
least
a serious kibitzer, or want to help by testing the newest version
of
the code, or frankly, as long as you feel comfortable doing a
CVScheckout
from SourceForge -- you should
visit OpenSteer's
CVS
repository and checkout the code. CVS
client software is included with
Linux and Mac OS X systems. A free and easy-to-use Windows
CVS
client is TortoiseCVS.Check out
a local
working copy of
OpenSteer from the CVS repository (assumes CVSROOT is set
to
:ext:[email protected]:/cvsroot/opensteer):
cvs
checkout opensteer
If you are not a SourceForge
member, you can do an anonymous checkout:
cvs -z3
32. -
d:pserver:[email protected].sourceforge.net:80/cvsroot/openstee
r
co opensteer
Update your local working copy with recent changes from the
CVS
repository (do it once after checkout to prune obsolete
directories):
cvs
update -dP
This
is the
directory structure
of OpenSteer:
opensteer/main directory
opensteer/src/source code (*.cpp
files)opensteer/include/OpenSteer/headers (*.h
files)opensteer/plugins/source for supplied OpenSteerDemo
PlugIns
(*.cpp
files)opensteer/linux/Makefile (and KDevelop project) for
building
on Linux
opensteer/macosx/files for building with Xcode on Mac OS
X
opensteer/win32/files for building with Visual Studio on
33. Windows
To
build your own copy of OpenSteer's library and application you
will
need: (1) a copy of the source code, (2) copies of two external
libraries (OpenGL and GLUT)
required by OpenSteer, and (3) the
appropriate programmer's tools for your platform. The table
below lists three platforms, four build tools, and which project
file to use for
each. Note that make and Xcode are
supplied free with their respective operating systems, KDevelop
is available for free
download. Visual Studio
and VC++ are
available for sale. Regarding compiler versions: on Windows
please use Visual C++ 7.1
(or newer), on Linux please use GCC 3.0 (or newer), on Mac OS
X if you
have Xcode you have the right compiler.
Linux
make command:
opensteer/linux/Makefile
KDevelop:
opensteer/linux/OpenSteer.kdevelop Mac OS X
Xcode:
opensteer/macosx/OpenSteer.xcode Windows
Visual
Studio (Visual C++):
34. opensteer/win32/OpenSteer.sln
To build using an IDE (Xcode, Visual Studio or KDevelop)
simply
double click on
the project file indicated above, then do a Full Build or Build
Solution
. To run the resulting application, use the IDE's Run
command or double click on the OpenSteerDemo desktop icon.
To use
the Linux Makefile, cd
to opensteer/linux/ -- build
using the make
command, run the application with the make
run command.
Known Bugs and Missing Features
In OpenSteerDemo, it seems like you ought to be able to use the
mouse to interactively adjust position and orientation of the
vehicles.
But you can't. Other things you can't do include interactively
creating
new instances of a PlugIn's vehicle types, or deleting old ones.
As
35. anyone who has tried it knows, the hardest part of creating
interesting
life-like behaviors is tuning the parameters. It sure would be
nice if
OpenSteerDemo provided mouse-driven sliders ("valuators")
PlugIns could
call to interactively adjust behavioral parameters.
Some of the behaviors detailed in the 1999
paper have not been implemented yet in OpenSteer. They are:
offset pursuit, arrival, wall following, containment, flow field
following, and leader following. Also unimplemented are
behaviors
which the paper mentioned in passing: explore, forage,
interpose,
shadow, docking, hide. Eventually OpenSteer should provide all
of
them.
When avoiding obstacles it looks much more sensible, efficient
and lifelike if the vehicle steers toward the nearer edge of a
looming
obstacle. But obstacle avoidance is blended with other
behaviors (say
with evasion, as in the Capture the Flag PlugIn) this will often
steer
the vehicle into a strategically bad position. Much better to go
36. the
"long way" around an obstacle than to go directly in to the path
of
your opponent. Perhaps obstacle avoidance should take an
argument
representing the steering that would be used in the absence of
an
obstacle. This can be used to bias the choice of a path around
the
obstacle. There is an underlying suggestion that effective
blending of
behaviors cannot be cleanly separated from the behaviors
themselves.
(See also Fast, Neat
and Under Control: Inverse Steering Behaviors for Physical
Autonomous
Agents.)
Currently the Pedestrians always move forward at full speed
and
try to avoid collisions purely by turning. They should be
improved so
they modulate both their heading and
their speed, coming to a stop if necessary to avoid a collision.
37. As can be seen occasionally in the Capture the Flag PlugIn,
when
obstacle avoidance steering behavior fails to prevent collisions
(intersection of vehicle and obstacle) the obstacle avoidance
behavior
appears to give up: it ignores the obstacle and steers right
through it.Boids should have a preference for level flight,
perhaps as a
user-selectable option. Right now they are as likely to fly
straight up
and horizontally.
One ought to be able to add a PlugIn to OpenSteerDemo at
runtime. [forum
thread]
Non-penetration constraints should be supported in OpenSteer
so
vehicles can be prevented from intersecting obstacles and other
vehicles.
Current demos use either 2d vehicles on the plane or 3d vehicles
in space. Opensteer should provide support for 2d vehicles on
non-planar surfaces.
38. OpenSteer should divide cleanly into a runtime library and a
demo application. It currently does not. [bug,
forum
thread.]
When OpenSteerDemo is launched from the desktop (say by
double-clicking on an icon) printed messages may
be lost, or at
least not be seen immediately by the user. [forum
thread]
Many of OpenSteer's component APIs (such as: Clock,
Annotation
and SimpleVehicle) are not documented beyond cryptic
comments in header
files. It has been suggested
that perhaps OpenSteer should use comments compatible with
the Doxygen system for
generating API docs.
Stupidly, the various annotation
(deferred graphics) types
(lines, circles) are currently limited to a fixed number of
objects. OpenSteerDemo incessantly prints complaints when
39. these limits
are exceeded.
There should be sample code (in a PlugIn) showing how to use
OpenSteer in a more traditional, non-mixin, HAS-A
architecture. [forum
thread]
Besides, shouldn't all these bugs be listed in the appropriate
place
on SourceForge?
Related Links:
(Please feel free to suggest new links for
this section)
OpenSteer on the web at SourceForge.Net
Steering
Behaviors For Autonomous Characters the GDC 1999 paper on
steering
behaviors, and this companion page with background, updates
and Java demos.AI Interface
40. Standards Committee of the IGDA
which includes a Steering Working Group
Systems that use OpenSteer:
Intelligent
Support of Interactive Manual Control: Haptic Guidance Based
on a
Look-Ahead Predictor by Ben
Forsyth . In his Master's thesis, Ben used OpenSteer as a
framework for his experiments, used path following behavior in
a novel
application, and invented a new and more realistic model of a
steerable
wheeled vehicle.
Pizza GameMessa di Voce
Systems similar to OpenSteer (see also this list of
related simulators):
breve: a 3d
Simulation Environment for Decentralized Simulations and
Artificial Life
MASON
is a fast discrete-event multiagent simulation library core in
Java.
Crowd Simulation Framework
based on steering behaviors
41. Sample applications of steering behaviors (pre-OpenSteer):
Interaction
with Groups of Autonomous Characters (2000) describes a
interactive
system featuring large group of characters based on steering
behaviors,
includes a video.
Video
Game Play and Design: Procedural Directions (2001) includes
video
of the Stuart/Bird/Fish demo with a skinned articulated 3d
character
driven by steering behaviors.
Steering,
planning and learning, a forum thread on advanced steering
architectures which cites several recent publications.
Please feel free to contact us with
comments or suggestions.
Last update: October 19, 2004
42. opensteer/doc/index.html
OpenSteer
Steering Behaviors for Autonomous Characters
Home
SourceForge
project pageOpen
Discussion forumDownload
softwareDocumentationContact
OpenSteer is a C++ library to help construct steering
behaviors
for
43. autonomous characters in games and animation. In addition to
the
library, OpenSteer provides an OpenGL-based application
called
OpenSteerDemo which displays predefined demonstrations of
steering
behaviors. The user can quickly prototype, visualize, annotate
and
debug new steering behaviors by writing a plug-in for
OpenSteerDemo.
OpenSteer provides a toolkit of steering behaviors, defined in
terms of an abstract mobile agent called a "vehicle." Sample
code is
provided, including a simple vehicle implementation and
examples of
combining simple steering behaviors to produce more complex
behavior.
OpenSteer's classes have been designed to flexibly integrate
with
existing game engines by either layering or inheritance.
44. OpenSteerDemo's plug-in framework allows a game AI
programmer
to quickly prototype behaviors during game design, and to
develop
behaviors before the main game engine is finished.
OpenSteerDemo
allows the user to interactively adjust aspects of the simulation.
The user can: start, stop and single step time, select the
vehicle/ character/
agent of interest, adjust the camera's
view
and its tracking behavior.
Last modified: October 12, 2004
OpenSteer is distributed as open source software in accordance
with the MIT
License. OpenSteer was developed with the generous support
of Sony Computer Entertainment
America. OpenSteer was developed on Linux and has
subsequently
been compiled and run on Mac OS X (using Xcode) and on
45. Windows (using
Visual Studio).
opensteer/doc/stref.html
OpenSteerDemo quick reference guide
October 7, 2003
OpenSteer 0.8
After installation [see doc section "Installing OpenSteer"]
launch the
OpenSteerDemo application which opens a window labeled
"OpenSteerDemo
0.8". OpenSteerDemo has a single selected vehicle which the
camera normally tracks. The user can select another vehicle by
46. clicking on it with the left mouse button. OpenSteerDemo
recognizes
several single key commands:Tabselect next PlugInrrestart
current PlugInsselect next vehicle/agent/character
(or mouse-click to select)cselect next camera
aiming modefselect next preset frame rate
(as-fast-as-possible, 24fps, 60fps)atoggle
annotation on/offSpacetoggle between Run and Pause-> (right
arrow)step forward one frame?print "mini help" on
console Escexit OpenSteerDemo
The camera (or "point of view") in OpenSteerDemo is typically
controlled so that it tracks the selected vehicle. Several
different
camera aiming modes are provided:staticfixed
camerafixed distance offset
camera remains a fixed distance from selected vehicle
fixed local offset
camera remains fixed in selected vehicle's local space
straight down
camera looks at selected vehicle from directly above
offset POV
camera looks in selected vehicle's forward direction, from a
given
offset in the vehicle's local space
47. You can adjust the camera's view with the mouse: hold down
the
keyboard's control (Ctrl) key while dragging the mouse with its
left button held down. 2D mouse motion is mapped into the
camera's
space, rotating the camera's position around its aimpoint. This
allows the camera to move on the surface of a sphere centered
at the
aimpoint. The radius of this sphere--the "viewing
distance"--can be adjusted by dragging the mouse with the
middle
button held down (vertical mouse motion maps to distance). If
you use
a one- or two-button mouse (hence no middle button) you can
adjust the
radius by holding down both the Ctrl and Alt ("control-meta-")
keys
while dragging the mouse with its left button held down.
Sample PlugIns:
Capture the Flag: a single (bluish) attacker attempts to reach
a central goal while four (reddish) defenders try to intercept
("tag")
the attacker before it gets to the goal. Press F1 to add an
obstacle
48. (up to 100 of them), F2 to remove one.
Pedestrians: 100 agents follow a path (the red line) while
avoiding collisions with each other and two large spherical
obstacles.
Press F1 to add a Pedestrian and F2 to remove one. F3 cycles
among
types of proximity databases. F4 toggles between two versions
of path
following. F5 toggles a Pedestrian's wander component on and
off.
Boids: 200 simulated flocking "bird like objects". Press F1 to
add a Boid and F2 to remove one. F3 cycles among types of
proximity
databases. F4 toggles between two boundary conditions.
Soccer: a simple soccer game, blue and red teams of 8 Players
each, a green Ball and yellow field and goals. As play proceeds
the
PlugIn keeps score.
Multiple Pursuit: a "test fixture" for the pursue
behavior. 30 pursuers chase one wandering quarry.
49. Low Speed Turn: a "test fixture" for evaluating the response of
a vehicle to backward-pointing steering force while moving at
low
speed.
One Turning Away: this was the first one, now it serves as a
minimal example of a PlugIn.
opensteer/src/Camera.cppopensteer/src/Camera.cpp// ------------
----------------------------------------------------------------
//
//
// OpenSteer -- Steering Behaviors for Autonomous Characters
//
// Copyright (c) 2002-
2003, Sony Computer Entertainment America
// Original author: Craig Reynolds <[email protected]>
//
// Permission is hereby granted, free of charge, to any person ob
taining a
// copy of this software and associated documentation files (the
"Software"),
// to deal in the Software without restriction, including without l
imitation
50. // the rights to use, copy, modify, merge, publish, distribute, sub
license,
// and/or sell copies of the Software, and to permit persons to w
hom the
// Software is furnished to do so, subject to the following condit
ions:
//
// The above copyright notice and this permission notice shall b
e included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARR
ANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WAR
RANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRI
NGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE F
OR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, T
ORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWA
RE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
51. //
// ------------------------------------------------------------------------
----
//
//
// camera control for OpenSteerDemo
//
// a camera ("point of view") with various "aiming modes" to tra
ck a
// moving vehicle
//
// 10-04-04 bk: put everything into the OpenSteer namespace
// 06-26-02 cwr: created
//
//
// ------------------------------------------------------------------------
----
#include"OpenSteer/Camera.h"
#include"OpenSteer/OpenSteerDemo.h"
// ------------------------------------------------------------------------
----
52. // constructor
OpenSteer::Camera::Camera(void)
{
reset ();
}
// ------------------------------------------------------------------------
----
// reset all camera state to default values
void
OpenSteer::Camera::reset (void)
{
// reset camera's position and orientation
resetLocalSpace ();
// "look at" point, center of view
target =Vec3::zero;
// vehicle being tracked
vehicleToTrack = NULL;
53. // aim at predicted position of vehicleToTrack, this far into thef
uture
aimLeadTime =1;
// make first update abrupt
smoothNextMove =false;
// relative rate at which camera transitions proceed
smoothMoveSpeed =1.5f;
// select camera aiming mode
mode = cmFixed;
// "constant distance from vehicle" camera mode parameters
fixedDistDistance =1;
fixedDistVOffset =0;
// "look straight down at vehicle" camera mode parameters
lookdownDistance =30;
// "static" camera mode parameters
fixedPosition.set (75,75,75);
fixedTarget =Vec3::zero;
fixedUp =Vec3::up;
54. // "fixed local offset" camera mode parameters
fixedLocalOffset.set (5,5,-5);
// "offset POV" camera mode parameters
povOffset.set (0,1,-3);
}
// ------------------------------------------------------------------------
----
// called once per frame to update camera state according to curr
ently
// selected mode and per-
mode parameters. Works in position/target/up
// ("look at") space.
//
// parameter names commented out to prevent compiler warning
from "-W"
void
OpenSteer::Camera::update (constfloat/*currentTime*/,
constfloat elapsedTime,
constbool simulationPaused)
55. {
// vehicle being tracked (just a reference with a more concise na
me)
constAbstractVehicle& v =*vehicleToTrack;
constbool noVehicle = vehicleToTrack == NULL;
// new position/target/up, set in switch below, defaults to curren
t
Vec3 newPosition = position();
Vec3 newTarget = target;
Vec3 newUp = up();
// prediction time to compensate for lag caused by smoothing m
oves
constfloat antiLagTime = simulationPaused ?0:1/ smoothMoveS
peed;
// aim at a predicted future position of the target vehicle
constfloat predictionTime = aimLeadTime + antiLagTime;
// set new position/target/up according to camera aim mode
switch(mode)
{
case cmFixed:
57. break;
case cmOffsetPOV:
{
if(noVehicle)break;
newUp = v.up();
constVec3 futurePosition = v.predictFuturePosition (antiLagTim
e);
constVec3 globalOffset = v.globalizeDirection (povOffset);
newPosition = futurePosition + globalOffset;
// XXX hack to improve smoothing between modes (no effect on
aim)
constfloat L =10;
newTarget = newPosition +(v.forward()* L);
break;
}
default:
break;
}
// blend from current position/target/up towards new values
smoothCameraMove (newPosition, newTarget, newUp, elapse
dTime);
// set camera in draw module
58. drawCameraLookAt (position(), target, up());
}
// ------------------------------------------------------------------------
----
// Smoothly move camera: blend (at a rate controlled by smooth
MoveSpeed)
// from current camera state toward newly determined camera st
ate.
//
// The flag smoothNextMove can be set (with doNotSmoothNext
Move()) to
// make next update (say at simulation initialization time).
void
OpenSteer::Camera::smoothCameraMove (constVec3& newPosit
ion,
constVec3& newTarget,
constVec3& newUp,
constfloat elapsedTime)
{
if(smoothNextMove)
{
59. constfloat smoothRate = elapsedTime * smoothMoveSpeed;
Vec3 tempPosition = position();
Vec3 tempUp = up();
blendIntoAccumulator (smoothRate, newPosition, tempPos
ition);
blendIntoAccumulator (smoothRate, newTarget, target);
blendIntoAccumulator (smoothRate, newUp, tempUp);
setPosition (tempPosition);
setUp (tempUp);
// xxx not sure if these are needed, seems like a good idea
// xxx (also if either up or oldUP are zero, use the other?)
// xxx (even better: force up to be perp to target-position axis))
if(up()==Vec3::zero)
setUp (Vec3::up);
else
setUp (up().normalize ());
}
else
{
smoothNextMove =true;
setPosition (newPosition);
target = newTarget;
60. setUp (newUp);
}
}
// ------------------------------------------------------------------------
----
// computes a new camera position which follows "target" at dist
ant of
// "dragTargetDistance"
//
// parameter names commented out to prevent compiler warning
from "-W"
OpenSteer::Vec3
OpenSteer::Camera::constDistHelper (constfloat/*elapsedTime*
/)
{
// is the "global up"/"vertical" offset constraint enabled? (it for
ces
// the camera's global-
up (Y) cordinate to be a above/below the target
// vehicle by a given offset.)
constbool constrainUp =(fixedDistVOffset !=0);
61. // vector offset from target to current camera position
constVec3 adjustedPosition (position().x,
(constrainUp)? target.y : position().y,
position().z);
constVec3 offset = adjustedPosition - target;
// current distance between them
constfloat distance = offset.length();
// move camera only when geometry is well-
defined (avoid degenerate case)
if(distance ==0)
{
return position();
}
else
{
// unit vector along original offset
constVec3 unitOffset = offset / distance;
// new offset of length XXX
constfloat xxxDistance = sqrtXXX (square (fixedDistDistance)-
square (fixedDistVOffset));
constVec3 newOffset = unitOffset * xxxDistance;
62. // return new camera position: adjust distance to target
return target + newOffset +Vec3(0, fixedDistVOffset,0);
}
}
// ------------------------------------------------------------------------
----
// select next camera mode, used by OpenSteerDemo
void
OpenSteer::Camera::selectNextMode (void)
{
mode = successorMode (mode);
if(mode >= cmEndMode) mode = successorMode (cmStartMode)
;
}
// ------------------------------------------------------------------------
----
// cycles through the various camera modes
63. OpenSteer::Camera::cameraMode
OpenSteer::Camera::successorMode (const cameraMode cm)con
st
{
return(cameraMode)(((int)cm)+1);
}
// ------------------------------------------------------------------------
----
// string naming current camera mode, used by OpenSteerDemo
char*
OpenSteer::Camera::modeName (void)
{
switch(mode)
{
case cmFixed:return"static";break;
case cmFixedDistanceOffset:return"fixed distance offset";break
;
case cmFixedLocalOffset:return"fixed local offset";break;
case cmOffsetPOV:return"offset POV";break;
case cmStraightDown:return"straight down";break;
64. default:return"?";
}
}
// ------------------------------------------------------------------------
----
// adjust the offest vector of the current camera mode based on a
// "mouse adjustment vector" from OpenSteerDemo (xxx experi
ment 10-17-02)
void
OpenSteer::Camera::mouseAdjustOffset (constVec3& adjustmen
t)
{
// vehicle being tracked (just a reference with a more concise na
me)
constAbstractVehicle& v =*vehicleToTrack;
switch(mode)
{
case cmFixed:
{
constVec3 offset = fixedPosition - fixedTarget;
65. constVec3 adjusted = mouseAdjustPolar (adjustment, offset);
fixedPosition = fixedTarget + adjusted;
break;
}
case cmFixedDistanceOffset:
{
// XXX this is the oddball case, adjusting "position" instead
// XXX of mode parameters, hence no smoothing during adjustm
ent
// XXX Plus the fixedDistVOffset feature complicates things
constVec3 offset = position()- target;
constVec3 adjusted = mouseAdjustPolar (adjustment, offset);
// XXX --------------------------------------------------
// position = target + adjusted;
// fixedDistDistance = adjusted.length();
// fixedDistVOffset = position.y - target.y;
// XXX --------------------------------------------------
// const float s = smoothMoveSpeed * (1.0f/40f);
// const Vec3 newPosition = target + adjusted;
// position = interpolate (s, position, newPosition);
// fixedDistDistance = interpolate (s, fixedDistDistance,
adjusted.length());
// fixedDistVOffset = interpolate (s, fixedDistVOffset,
position.y - target.y);
// XXX --------------------------------------------------
66. // position = target + adjusted;
setPosition (target + adjusted);
fixedDistDistance = adjusted.length();
// fixedDistVOffset = position.y - target.y;
fixedDistVOffset = position().y - target.y;
// XXX --------------------------------------------------
break;
}
case cmStraightDown:
{
constVec3 offset (0,0, lookdownDistance);
MAT 510 – Homework Assignment
Homework Assignment 3
Due in Week 3 and worth 30 points
The following data consists of the actual time used and
potential (the best time possible for this review process) to
complete each step in the review process. The actual times are
based on the review of 30 projects. The potential times are
67. subjective engineering judgment estimates.
Table: Basic Data Review for Construction Project Equipment
Arrangement
Cycle Time (hours)
Step
Description
Actual
Potential
Difference
1
Read basic data package
4
4
—
2
Write, type, proof, sign, copy, and distribute cover letter
21.9
0.5
21.4
3
68. Queue
40
0
40
4
Lead engineer calls key people to schedule meeting
4
0.25
3.75
5
Write, type, proof, sign, copy, and distribute confirmation letter
25.4
2.1
23.3
6
Hold meeting; develop path forward and concerns
4
4
—
7
Project leader and specialist develop missing information
12
12
—
8
69. Determine plant preferred vendors
12
12
—
9
Review notes from meeting
12
12
—
10
Resolve open issues
106
104
2
11
Write, type, proof, sign, copy, and distribute basic data
acceptance letter
26.5
0.25
26.25
Totals
267.8
151.1
116.7
70. Use the data in the table above and answer the following
questions in the space provided below:
1. What are the sources of value-added and non-value-added
work in this process?
2. Where are the main opportunities to improve the cycle time
of this process, with respect to both actual time used and the
potential best times? What strategy would you use?
3. Step 10: Resolve Open Issues required 104 hours (potential)
versus 106 hours (actual). Is there an OFI here? Why or why
not? If so, how would you attack it?
4. What do you think are the most difficult critical issues to
deal with when designing a sound cycle time study such as this
one?
Type your answers below and submit this file in Week 3 of the
online course shell:
glut32.dll
OpenSteerDemo.exe