To reduce nav link generation time, we enabled ai.nav.UseAsymetricBorderSizes, which cut generation time by about 50%. It’s been stable so far and appears safe, since it only removes buffer voxels on one side of a tile that should already be covered by neighboring tiles.
I’m considering an additional optimization in RecastRasterization.cpp (rcRasterizeTriangles) that could reduce time by another ~50%. If we skip triangles marked as RC_NULL_AREA, are there any risks or edge cases we should be aware of? For example, could some geometry stop carving nav as expected?
void rcRasterizeTriangles(rcContext* ctx, const rcReal* verts, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr, const int rasterizationFlags, const int* rasterizationMasks, //UE
const rcReal* vertsbmin, const rcReal* vertsbmax) //UE
{
if (ctx)
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
const rcReal ics = 1.0f/solid.cs;
const rcReal ich = 1.0f/solid.ch;
const bool bAsFilledVerticalConvexVolume = rasterizationFlags & RC_RASTERIZE_AS_FILLED_CONVEX;
if (!bAsFilledVerticalConvexVolume)
{
AddSpanInHeightfield Func;
// Rasterize triangles.
for (int i = 0; i < nt; ++i)
{
// MOD - BEGIN
if (areas[i] == RC_NULL_AREA)
{
continue;
}
// MOD - END
const rcReal* v0 = &verts[(i*3+0)*3];
const rcReal* v1 = &verts[(i*3+1)*3];
const rcReal* v2 = &verts[(i*3+2)*3];
// Rasterize.
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr, rasterizationFlags, rasterizationMasks, Func); //UE
}
}
else
{
AddSpanInTempColumns Func(ctx, solid, ics, vertsbmin, vertsbmax);
if (Func.IsValid())
{
for (int i = 0; i < nt; ++i)
{
// MOD - BEGIN
if (areas[i] == RC_NULL_AREA)
{
continue;
}
// MOD - END
const rcReal* v0 = &verts[(i*3+0)*3];
const rcReal* v1 = &verts[(i*3+1)*3];
const rcReal* v2 = &verts[(i*3+2)*3];
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr, rasterizationFlags, rasterizationMasks, Func); //UE
}
Func.TransferColumnsToHeightfield(solid, flagMergeThr);
}
}
if (ctx)
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
}