[This is preliminary documentation and is subject to change.]
Areas in CAINav are represented by a byte value between zero and 63. In the navigation mesh they are assigned to polygons and used to assign traversal cost. For example, all polygons assigned an area of 24 may be assigned a cost of 1.5 while polygons assigned an area of 63 may be assigned a cost of 1.0. The meaning and cost associated with each area is defined by the end user. The only exception is 0, which is always considered to mean 'unwalkable'.
Areas are also used in the NMGen build process. But while their purpose and use in the navigation mesh is fairly straight forward, things can get complicated in the build process. This topic covers various ways of using areas during the build process to get the navigation mesh you want.
Why Use Areas in the Build Process
If you assign everything to only a single area during the NMGen build process then polygons will form based solely on the structure of the source geometry. Polygon edges will form along the borders of obstructions, in structural portals such as doorways, etc. The surface type of the source geometry is unknown and can't be taken into account. So, for example, a single polygon may cover both meadow and swamp surfaces, even though the cost of traversing the surfaces is different.
Essentially, areas allow you to specify surface type so that the build process can make sure that polygons are formed such that they don't overlap different area types. Polygon edges will always form at the boundry between different areas.
The obvious benefit of forming polygons based on surface type is that it allows you to properly control traversal cost. But there are other purposes. One example is flag assignment. Polygons have an associated 16-bit flags field. These flags are used to filter polygons during pathfinding. For example, you can specify that all polygons with the 0x10 flag are inaccessible, so pathfinding will ignore the polygons. Areas can be used to ensure that polygons form in a way that allow flags to be used properly.
Let's say you have a bridge that can partially collapse. There is no way for the build process to know exaclty which part of the bridge can collapse, so you can't guarentee that separate polygons will exist at the proper location. Unless, of course, you mark the collapse location with a different area than the rest of the bridge.
In the below example, cylinder and convex areas are marked into the mesh. The convex marker was given a higher priority so that it overwrites part of the cyclinder area.
As you can see, areas provide a powerful method of ensuring the final mesh structure is what you need it to be.
The Power of Zero
The zero area is called the 'NullArea' and has a special meaning to the NMGen build process. Any surface marked as NullArea is unwalkable and no polygons will form. All NullArea surfaces are considered obstacles.
The build process automatically handles NullArea assignment for most cases. The surface's slope may be too steep. (E.g. Walls) The polygons formed on the surface may be too small to be of use. (E.g. Stairway railings or a counter top.) The surface may be inaccessible due to height restrictions. (E.g. The floor under a table.)
But sometimes you may want to manually block off an area. For example, let's say you have a surface covered by burning rubbish. The structure of the surface may be walkable, but you never want it to be walkable. In cases such as this you can manually mark the surface as a NullArea and the build process will treat it as an obstacle.
The NullArea is treated differently than other areas in another way. Normal areas can be reassigned at will. You can assign a surface to area 15 during one part of the build process then reassign part of it to area 22 later on. A NullArea can never be reassigned. Once a NullArea, always a NullArea. You never have to worry about accidentally making a NullArea walkable again.
How to Assign Areas
There are three points in the build process where you can assign areas:
- To the source geometry triangles when compiling the input.
- To convex areas in the CompactHeightfield object.
- To polygons in the PolyMesh object.
Technically, you can't perform a NMGen build without assigning areas. At some point in the build it will detect that you haven't assigned areas and will assign all surfaces to a default area.
Source Geometry Area Assignment
The first point at which you can assign areas is during the input compile. You can assign each source geometry triangle to an area. This is a great place to assign areas if your source geometry is inherently categorized by surface type. E.g. All bridge and sidewalk meshes get one area while all water meshes get a different area.
Marking the CompactHeightfield
In some cases it either isn't possible or isn't appropriate to assign areas to the source geometry. The next option is to mark areas directly into the CompactHeightfield during its post-processing step. The AreaBoxMarker, AreaCylinderMarker, and AreaConvexMarker classes can be used to mark arbitrary convex areas into the heightfield.
This is the most accurate method of marking an area since marking occurs at the resolution of the heightfield. (I.e. The cell size.) However, if abused it can create a lot of extra polygons.
The above area markers and the build process supports priority assignment, so it is possible to use overlapping markers. The overlapped area will be assigned the area of the highest priority marker.
Area Assignment in the PolyMesh
Each polygon in the PolyMesh has an area assignment that is inherited from the earlier in the build process. This is the value that will be assigned to the polygon once it is added to the navigation mesh. At this point the polygons are pretty much fixed, so it isn't particularly useful to assign the NullArea. But sometimes it is useful to perform some final area adjustements. For example, if you assigned an area only to ensure proper polygon formation, and the area isn't needed for adjusting traversal cost in the navigation mesh, you can re-assign the area to a default area. (I.e. Clean things up.)