ENGINE MODIFICATIONS
Walkabout is a significant addition to T3D, and requires a few modifications to its source code. I’ve tried to keep my modifications as self-contained as possible, preferring to add code rather than modifying or replacing it, and adding new classes instead of retrofitting existing ones.
This guide aims to introduce the code changes to you, providing information on why certain changes were made and what they do. If you are integrating Walkabout with your own modifications to T3D and need to know how to merge, or if you’re just trying to gain a better understanding of how the engine and Walkabout work together, you’ve come to the right place.
This class is the most important addition to the engine. A NavMesh represents a navigable volume in your level.
Engine/source/T3D/nav/navMesh.h
Engine/source/T3D/nav/navMesh.cpp
A NavPath stores data about a pathfinding query on a single NavMesh.
Engine/source/T3D/nav/navPath.h
Engine/source/T3D/nav/navPath.cpp
This simple class represents a location where an AI player can take cover. These points can be placed manually by level designers, or generated automatically on a particular NavMesh. A combination of both is usually a good idea!
Engine/source/T3D/nav/coverPoint.h
Engine/source/T3D/nav/coverPoint.cpp
Provides functionality to the Nav editor plugin.
Engine/source/T3D/nav/guiNavEditorCtrl.h
Engine/source/T3D/nav/guiNavEditorCtrl.cpp
This poly list stores its internal data as simple lists of vertex locations and indices in Recast’s coordinate system (where the axes represent different directions than in Torque). It is so named because it is similar in structure to the OBJ file format, and can be easily exported as an OBJ file with the provided console function.
Engine/source/collision/objPolyList.h
Engine/source/collision/objPolyList.cpp
Of course, a significant amount of code has been added to the engine in the form of the Recast/Detour library. For a description of Recast’s operation, visit its official site or group forum. Note that two files have been renamed from the official Recast distribution: files previously named DebugDraw have been renamed duDebugDraw due to a conflict with an existing Torque file.
Engine/source/T3D/nav/recast/*
Walkabout makes significant additions to the AIPlayer class to make pathfinding as simple-to-use as possible. This includes adding new engine and console functions that take care of pathfinding, but also hooking into the callbacks like onStuck. You’ll notice I’ve replaced callbacks in getAIMove with calls to engine functions. In these new functions, I perform logic related to pathfinding (like automatically replanning a path if the character becomes stuck), then call the script-side functions. If you have other callbacks implemented for AIPlayers, this is a good pattern to follow.
Engine/source/T3D/aiPlayer.h
Engine/source/T3D/aiPlayer.cpp
To generate NavMeshes, Walkabout needs to parse a level’s collision geometry. It does this by using the standard buildPolyList function in SceneContainer, which finds objects in a box and calls their buildPolyList methods.
However, several classes do not do a good job of honouring a request to buildPolyList when passed a bounding box. For example, GroundPlane always adds an infinitely large collision plane, no matter what size the query box is. This is bad for Recast, since the library builds a voxel grid based on the dimensions of the input geometry. In early tests, Recast would try to create a nearly-infinitely large grid!
Walkabout leverages the existing PolyListContext feature to tell objects that a given call to buildPolyList is being used for navigation. If you implemented your own custom class, you’d be able to do things like export special geometry to the navigation mesh if you really wanted.
Engine/source/scene/sceneContainer.h
Engine/source/scene/sceneContainer.cpp
The buildPolyList functions of GroundPlane, ConvexShape and TerrainBlock have been modified so they return better data for NavMesh generation. These additional routines are hidden away using the PLC_Navigation context, so they affect the existing code in these methods as little as possible.
Engine/source/T3D/convexShape.cpp
Engine/source/T3D/groundPlane.cpp
Engine/source/terrain/terrCollision.cpp
There was only one change made to the rendering engine to accommodate Recast’s debug draw functionality. The debug draw functions expect an OpenGL-like interface, where a drawer makes arbitrary calls like:
BEGIN(TriangleList);
VERTEX(x1, y1, z1);
VERTEX(x2, y2, z2);
...
VERTEX(xn, yn, zn);
END();
However, the PrimBuilder class expects to know the exact number of vertices beforehand, which Recast does not provide. So we need to make a small change to the macro definitions in PrimBuilder to allow the vertex buffer to grow if the number of vertices exceeds the initial expectation.
Engine/source/gfx/primBuilder.cpp
Torque 3D comes with a handy system to configure your projects and automatically generate Visual Studio solution files. Instead of asking you to add all the new source files manually, a Walkabout install typically involves including a project generator module. This module is defined in Tools/projectGenerator/modules/walkabout.inc so it is available to all your projects. However, you need to include the module in the projectCode.conf file for each project you want to use Walkabout in.
Tools/projectGenerator/modules/walkabout.inc
your project/buildFiles/config/projectCode.conf