PathEngine home previous: Converting to and from PathEngine's Position Representationnext: Collision Queries
Contents, Programmers Guide, Applying the SDK, Obstacle Management

Obstacle Management

PathEngine's dynamic obstacle mechanisms provide a powerful tool for managing the state of collision in a world, or for representing agent knowledge or beliefs about this state of collision.

See this page for an introduction to PathEngine obstacles, and this page for information about placing obstacles through the API.

The 'standard' way to set things up is to place obstacles as PathEngine iAgent objects, and to use the iCollisionContext and iObstacleSet interfaces to control how the iAgent objects are applied to individual queries.
It can also be possible to perform (more expensive) projection of 3D geometry to ground level shapes at runtime, with iMesh::placeProjected3DObstruction(), depending on the exact application requirements.

Obstacles can be 'burnt-in' to a PathEngine ground mesh, so that the obstacles are essentially included as part of the base pathfinding environment, or can be included in queries at runtime.

This page discusses obstacle management at runtime, based on obstacles that have been placed as iAgent objects.

Applying dynamic obstacles to queries

Obstacles that haven't been burnt into a mesh (see Obstacle Placement) need to be either added to a 'collision context' or 'obstacle set' in order to affect pathfinding or collision queries.

Collision contexts

Each collision or pathfinding query in the API takes a collision context argument specifying the state of collision to be applied for that query.
For convenience, a null pointer may be passed into this argument to specify that only static collision should be applied.

A state of collision essentially means a set of dynamic obstacles, so collision contexts started out essentially as a way of representing the set of obstacles to be included for a query.
Obstacles can be included in a collision context directly, or indirectly by being included in an obstacle set that is then included in the collision context.
(In situations where obstacles are naturally organised into groups that need to be added or removed from contexts obstacle sets can greatly simplify obstacle management. In simpler situations adding obstacles directly to collision contexts avoids the need to work with an additional interface object.)

In addition to representing simply a 'state of collision', collision contexts have evolved to also manage information about movement costs for certain types of regions with cost to traverse (see Representing Regions with Cost to Traverse), as well as enabling bounds to be applied to pathfinding queries (see Limiting the Scope for Pathfinding).

Detailed API reference for the iCollisionContext interface class can be found here: Interface iCollisionContext

Free standing obstacle sets

iObstacleSet interface objects add the possibility to organise obstacles into sets which can then be compounded together differently in different collision contexts.

In addition to enabling groups of obstacles to be represented more naturally, some collision preprocess is cached with each obstacle set, which can be an important optimisation for certain situations where collision is being performed against large numbers of dynamic obstacles.

Detailed API reference for the iObstacleSet interface class can be found here: Interface iObstacleSet

Working with multiple or changing sets of static obstacles

Obstacle sets include a feature to enable you to effectively work with multiple or changing sets of 'burnt-in' obstacles, and to modify these sets of obstacles 'semi-dynamically'.
This is implemented in terms of special obstacle sets that are marked for extended preprocessing.

To mark an obstacle set for extended preprocessing the obstacle set should be created with iMesh::newObstacleSet_WithAttributes() (instead of iMesh::newObstacleSet()), with 'markForPreprocessing' supplied, and set to 'true'.

The following code snippet shows how this can be done:

char* attributes[3];
attributes[0] = "markForPreprocessing";
attributes[1] = "true";
attributes[2] = 0;
obstacleSet = mesh->newObstacleSet_WithAttributes(attributes);

With this attribute, the obstacle set will effectively generate a set of unobstructed space preprocess which includes support for both connected region queries and pathfinding.
It is also possible to mark obstacles sets just for fast connected region processing (see below).

The attributes supplied on the creation of a preprocessed obstacle set are also cached and passed in to the actual preprocess generation.
(So if you want to apply the small convex optimisation to this preprocess then the relevant attribute should be supplied on obstacle set creation.)

Only one such obstacle set may be added to any one collision context.
Internally, PathEngine will generate the same kind of preprocess for the obstacle set as is normally generated for the set of obstacles burnt in to a mesh.
When queries are made against a collision context that includes an obstacle set marked in this way, preprocess from the obstacle set is used instead of mesh preprocess.

This feature is very useful in the case where different sets of static obstacles should be applied to different types of agents.
It is also possible to modify the set of obstacles in 'preprocessed obstacle sets' but note that this can incur a (potentially very big) delay when the obstacle preprocess is subsequently updated.
You can use the iObstacleSet::pathfindPreprocessNeedsUpdate() method to test for this condition, and iObstacleSet::updatePathfindPreprocessFor() to force the update of the preprocess after changes.

Double buffered obstacle sets

The semi dynamic obstacles example project demonstrates a technique for double buffering a pair of preprocessed obstacle sets for fast pathfinding and collision around large numbers of run-time determined obstacles.

Using obstacle sets for fast connectivity checking against changing agent state

In addition to full pathfinding preprocess, obstacle sets can also be marked for generation of just the preprocess components required for connected region queries, with the 'markForPreprocessing_ConnectedRegionsOnly' creation attribute.

Connected region queries are an important feature, which may be used for example, for certain kinds of logic relating to movement possibilities (doors and so on), or as a performance optimisation to quickly identify when positions are not reachable.

Generation of the preprocess components for connected region queries is then a much more lightweight operation than full pathfinding preprocess generation, and in many case this can be fast enough to be performed at runtime without the need for a background thread.

Creation of obstacle sets with the 'markForPreprocessing_ConnectedRegionsOnly' attribute is similar to creation with 'markForPreprocessing', but with one difference being that more than one obstacle set created with 'markForPreprocessing_ConnectedRegionsOnly' can then be included in a given collision context.

Note, however, that you then need to call connected region queries directly against the obstacle set (e.g. with iObstacleSet::getConnectedRegionFor()) in order to get connected region values which include the obstacle set collision state. This does not automatically happen for collision contexts including the obstacle set.

Documentation for PathEngine release 6.04 - Copyright © 2002-2024 PathEnginenext: Collision Queries