New in version 0.50, MV3D has a path-finding system. It is based on a plugin system to allow multiple path-finding systems. Currently the only useful system is the NavMesh system. For more information on Navigation Meshes, see the Wikipedia article. The system has three levels which all implement different interfaces. At the top, there's the IPathSystem. This hands out INavagationMaps, which managing the path-finding on a per area basis.

A INavagationMap can be queried for a path, which is implemented as an IPath. Paths are made up of IPathSegments. Here's a visualization of a NavMesh built by MV3D:

A navmesh generated automatically.

Generating a NavMesh

Here's how to generate a NavMesh for a given area:

from twisted.internet.defer import inlineCallbacks

from mv3d.path.navmesh import NavMesh

@inlineCallbacks
def generateMesh(area):
    mesh = NavMesh(area)
    yield mesh.update()

The constructor to NavMesh takes two other optional parameters for resolution and maxSlope. The generation algorithm works by voxelizing the area. The resolution parameter sets the size of each voxel cube. The default is 5. The maxSlope is how many voxels up a path can jump. The default is 1.

Note that generation can take a good amount of time. It is fairly linear with the size of the area.

Pathing on a NavMesh

Once the NavMesh is generated, paths can be generated between any two points on the mesh using the getPath method. It also returns a deferred. That method uses A* for solving the shortest path. The path is automatically smoothed as well.

With the path, in order to make a body follow it, the body will need to implement mv3d.path.ipath.IPathableBody. Here's a code snippet for generating a path and sending a body down it.

@inlineCallbacks
def getPath(navMesh, body, start, dest, speed):
    path = yield navMesh.getPath(start, dest)
    yield path.follow(body, speed)
    print "Reached the destination."