PathEngine home previous: PathEngine Coordinatesnext: Setting Face Attributes
Contents, Programmers Guide, World Representation, Obstacle Placement

Obstacle Placement

Once PathEngine meshes have been generated to define the ground surfaces of a world, obstacles can now be placed on these surfaces. (See this page for an introduction to PathEngine obstacles.)

When exporting markup from 3DS Max or Maya, obstacles can be represented directly in the scene, as 'pinned shapes', and exported together with the ground surface markup. (See this page, in the content creators guide, for details.)

For other content chains, obstacle placement can be performed directly through the main API.

Using the iAnchorsAndPinnedShapes interface for obstacle placement

One way place to manage obstacle placement is through the Interface iAnchorsAndPinnedShapes interface.

With this approach, all the relevant data should be compiled into an application side object, derived from iAnchorsAndPinnedShapes.
(This can then take the form of a wrapper for existing application side data, or a custom container class, or a mixture of these things.)

The shapes can then be added to a ground mesh directly, with iMesh::addAnchorsAndShapes(), or passed into iPathEngine::newContentChunk(), for incorporation into the resulting content chunk object.

The content plugins use this approach internally, and the plugin source code can be used as an example and a starting point for application specific anchor and shape class implementations.

Managing obstacle placement directly through the API

The functionality described above is implemented as a fairly lightweight layer on top of other, more generic, position and object management code in the API, and it is also possible for application code to perform this kind of position and obstacle management directly, if more control is desired.

In this case, refer to this page, for details about how to resolve ground positions for obstacle placement.
And the iAgent interface class is then used to represent the placement of an object with a given shape at a given position on the surface of a mesh (for both obstacles and pathfinding agents), and is key to the SDK obstacle management in general.

To place an obstacle you essentially need both a position and a shape.
iPathEngine::newShape() can be used to setup an obstacle shape, and then iMesh::placeAgent() to place an obstacle with that shape at a specified position, or iMesh::placeLargeStaticObstacle() can be used to place an obstacle directly.

A 'root position' is required for each of these obstacle placement calls. This root position determines which part of the ground mesh is affected by the obstacle, and enables obstacles to be applied to the appropriate part of the ground mesh when there are multiple overlapping ground layers.

'2D' obstacles

It's also possible to place '2D' obstacles, using the iMesh::placeLargeStatic2DObstacle() method, in which case a root position is not required, and the obstacle then applies to all ground surfaces overlapping the obstacle horizontally.

The main use-case for 2D obstacle placement is for situations where you know that an obstacle doesn't overlap multiple ground layers, and where you want to avoid the need to resolve a root position, or where you want to 'root' an obstacle to more than one distinct piece of ground mesh.

Obstacle validation constraints

Obstacles shapes must be convex, and obstacles shape coordinates are also subject to range constraints (significantly relaxed in the case of large static obstacles).
Refer to this page for full details about the constraints that apply.

Assentially the same set of validation constraints apply to shapes placed through iAnchorsAndPinnedShapes as shapes placed individually through the API, but with iAnchorsAndPinnedShapes PathEngine will take some steps to attempt to resolve any validation errors, as follows:

'Burning in' static obstacles

Obstacles that are completely static (e.g. obstacles that are used to represent scenery objects) should be 'burnt in' for preprocessing.
This enables PathEngine to work with large numbers of these kinds of obstacles very efficiently.

When placing obstacles directly through the main API, iMesh::burnContextIntoMesh() should be used for this.

When adding obstacles through the iAnchorAndPinnedShapes interface, an attribute value is provided for such obstacles, and PathEngine will take care of the call to burnContextIntoMesh internally.

(When exporting data with the content plugins, obstacles can be tagged as burnt in the exported scene - refer to the content creators guide for details.)

Obstacle sets also enable you to effectively work with multiple sets of 'burnt-in' obstacles, and to modify these sets of obstacles semi-dynamically. Refer to Obstacle Management for details about this feature.

Cutting holes in the mesh

Another alternative, for completely static geometry that is fixed at content generation time, can be to cut holes in the base mesh.
Starting from release 5.19, the building entrance connections feature of the PathEngine 2D content processing, can be applied without any building internal shape geometry, as a kind of generalised 'cookie cutter' mechanism.

Built-in projection of 3D objects

PathEngine can take care of projection of 3D objects to convex shapes on the ground mesh surface.
Use iMesh::placeProjected3DObstruction() for this.

What this method does is to effectively clip the 3D object to a specified range, and then generate a convex hull around the clipped geometry.

A pathfinding agent under a basic tree model.

The same scene in the testbed, with an obstruction shape generated by placeProjected3DObstruction() for the tree geometry.

Projection of 3D objects can be done at content time or at run-time, and the iAgent object that is generated can be treated in the same way as other placed obstacle shapes, e.g. this can be burnt-in to a mesh, treated as a 'semi-dynamic' obstacle, or freely added and removed from collision contexts as a completely dynamic obstacle.

Named obstacles

Obstacles can be named and stored with a mesh, but not burnt in, using iMesh::storeNamedObstacle().
This is useful for placing things like doors, switches or other content features that will then be managed dynamically at run-time.

Run-time obstacle management

Refer to this page for information about run-time dynamic obstacle management.

Documentation for PathEngine release 6.04 - Copyright © 2002-2024 PathEnginenext: Setting Face Attributes