Merge pull request #137 from rafzi/scopedtimer
add rcScopedTimer to fix timers not being stopped on all paths and to…
This commit is contained in:
commit
724092a9ec
@ -127,7 +127,7 @@ public:
|
||||
inline void resetTimers() { if (m_timerEnabled) doResetTimers(); }
|
||||
|
||||
/// Starts the specified performance timer.
|
||||
/// @param label The category of timer.
|
||||
/// @param label The category of the timer.
|
||||
inline void startTimer(const rcTimerLabel label) { if (m_timerEnabled) doStartTimer(label); }
|
||||
|
||||
/// Stops the specified performance timer.
|
||||
@ -173,6 +173,22 @@ protected:
|
||||
bool m_timerEnabled;
|
||||
};
|
||||
|
||||
/// A helper to first start a timer and then stop it when this helper goes out of scope.
|
||||
/// @see rcContext
|
||||
class rcScopedTimer
|
||||
{
|
||||
public:
|
||||
/// Constructs an instance and starts the timer.
|
||||
/// @param[in] ctx The context to use.
|
||||
/// @param[in] label The category of the timer.
|
||||
inline rcScopedTimer(rcContext* ctx, const rcTimerLabel label) : m_ctx(ctx), m_label(label) { m_ctx->startTimer(m_label); }
|
||||
inline ~rcScopedTimer() { m_ctx->stopTimer(m_label); }
|
||||
|
||||
private:
|
||||
rcContext* const m_ctx;
|
||||
const rcTimerLabel m_label;
|
||||
};
|
||||
|
||||
/// Specifies a configuration to use when performing Recast builds.
|
||||
/// @ingroup recast
|
||||
struct rcConfig
|
||||
|
@ -329,7 +329,7 @@ bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const i
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
|
||||
|
||||
const int w = hf.width;
|
||||
const int h = hf.height;
|
||||
@ -457,8 +457,6 @@ bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const i
|
||||
tooHighNeighbour, MAX_LAYERS);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf)
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
|
||||
ctx->startTimer(RC_TIMER_ERODE_AREA);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_ERODE_AREA);
|
||||
|
||||
unsigned char* dist = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
|
||||
if (!dist)
|
||||
@ -215,8 +215,6 @@ bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf)
|
||||
|
||||
rcFree(dist);
|
||||
|
||||
ctx->stopTimer(RC_TIMER_ERODE_AREA);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -245,7 +243,7 @@ bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf)
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
|
||||
ctx->startTimer(RC_TIMER_MEDIAN_AREA);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_MEDIAN_AREA);
|
||||
|
||||
unsigned char* areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
|
||||
if (!areas)
|
||||
@ -307,8 +305,6 @@ bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf)
|
||||
|
||||
rcFree(areas);
|
||||
|
||||
ctx->stopTimer(RC_TIMER_MEDIAN_AREA);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -322,7 +318,7 @@ void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigne
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_MARK_BOX_AREA);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_MARK_BOX_AREA);
|
||||
|
||||
int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs);
|
||||
int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch);
|
||||
@ -357,9 +353,6 @@ void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigne
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_MARK_BOX_AREA);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -391,7 +384,7 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||
|
||||
float bmin[3], bmax[3];
|
||||
rcVcopy(bmin, verts);
|
||||
@ -448,8 +441,6 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||
}
|
||||
|
||||
int rcOffsetPoly(const float* verts, const int nverts, const float offset,
|
||||
@ -541,7 +532,7 @@ void rcMarkCylinderArea(rcContext* ctx, const float* pos,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_MARK_CYLINDER_AREA);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_MARK_CYLINDER_AREA);
|
||||
|
||||
float bmin[3], bmax[3];
|
||||
bmin[0] = pos[0] - r;
|
||||
@ -597,6 +588,4 @@ void rcMarkCylinderArea(rcContext* ctx, const float* pos,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_MARK_CYLINDER_AREA);
|
||||
}
|
||||
|
@ -831,7 +831,7 @@ bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const int h = chf.height;
|
||||
const int borderSize = chf.borderSize;
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_CONTOURS);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_CONTOURS);
|
||||
|
||||
rcVcopy(cset.bmin, chf.bmin);
|
||||
rcVcopy(cset.bmax, chf.bmax);
|
||||
@ -1100,7 +1100,5 @@ bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_CONTOURS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -67,8 +67,6 @@ void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
@ -86,7 +84,7 @@ void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walk
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_FILTER_BORDER);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_FILTER_BORDER);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -167,8 +165,6 @@ void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_FILTER_BORDER);
|
||||
}
|
||||
|
||||
/// @par
|
||||
@ -181,7 +177,7 @@ void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeight
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_FILTER_WALKABLE);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_FILTER_WALKABLE);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -202,6 +198,4 @@ void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_FILTER_WALKABLE);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_LAYERS);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_LAYERS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
@ -446,10 +446,7 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
|
||||
// No layers, return empty.
|
||||
if (layerId == 0)
|
||||
{
|
||||
ctx->stopTimer(RC_TIMER_BUILD_LAYERS);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create layers.
|
||||
rcAssert(lset.layers == 0);
|
||||
@ -612,7 +609,5 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
layer->miny = layer->maxy = 0;
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_LAYERS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -983,7 +983,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_POLYMESH);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_POLYMESH);
|
||||
|
||||
rcVcopy(mesh.bmin, cset.bmin);
|
||||
rcVcopy(mesh.bmax, cset.bmax);
|
||||
@ -1293,8 +1293,6 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_POLYMESH);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1306,7 +1304,7 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
|
||||
if (!nmeshes || !meshes)
|
||||
return true;
|
||||
|
||||
ctx->startTimer(RC_TIMER_MERGE_POLYMESH);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_MERGE_POLYMESH);
|
||||
|
||||
mesh.nvp = meshes[0]->nvp;
|
||||
mesh.cs = meshes[0]->cs;
|
||||
@ -1474,8 +1472,6 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
|
||||
ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_MERGE_POLYMESH);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1120,7 +1120,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||
|
||||
if (mesh.nverts == 0 || mesh.npolys == 0)
|
||||
return true;
|
||||
@ -1327,8 +1327,6 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1337,7 +1335,7 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_MERGE_POLYMESHDETAIL);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_MERGE_POLYMESHDETAIL);
|
||||
|
||||
int maxVerts = 0;
|
||||
int maxTris = 0;
|
||||
@ -1406,7 +1404,5 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_MERGE_POLYMESHDETAIL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -331,13 +331,11 @@ void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
rasterizeTri(v0, v1, v2, area, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
@ -351,7 +349,7 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -364,8 +362,6 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/,
|
||||
// Rasterize.
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
@ -379,7 +375,7 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -392,8 +388,6 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/,
|
||||
// Rasterize.
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
@ -406,7 +400,7 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned cha
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -419,6 +413,4 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned cha
|
||||
// Rasterize.
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
@ -1257,7 +1257,7 @@ bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_DISTANCEFIELD);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_DISTANCEFIELD);
|
||||
|
||||
if (chf.dist)
|
||||
{
|
||||
@ -1281,25 +1281,23 @@ bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf)
|
||||
|
||||
unsigned short maxDist = 0;
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
{
|
||||
rcScopedTimer timerDist(ctx, RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
|
||||
calculateDistanceField(chf, src, maxDist);
|
||||
chf.maxDistance = maxDist;
|
||||
calculateDistanceField(chf, src, maxDist);
|
||||
chf.maxDistance = maxDist;
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
{
|
||||
rcScopedTimer timerBlur(ctx, RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
// Blur
|
||||
if (boxBlur(chf, 1, src, dst) != src)
|
||||
rcSwap(src, dst);
|
||||
|
||||
// Blur
|
||||
if (boxBlur(chf, 1, src, dst) != src)
|
||||
rcSwap(src, dst);
|
||||
|
||||
// Store distance.
|
||||
chf.dist = src;
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_DISTANCEFIELD);
|
||||
// Store distance.
|
||||
chf.dist = src;
|
||||
}
|
||||
|
||||
rcFree(dst);
|
||||
|
||||
@ -1359,7 +1357,7 @@ bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
@ -1489,24 +1487,22 @@ bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
}
|
||||
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
{
|
||||
rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Merge regions and filter out small regions.
|
||||
rcIntArray overlaps;
|
||||
chf.maxRegions = id;
|
||||
if (!mergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg, overlaps))
|
||||
return false;
|
||||
// Merge regions and filter out small regions.
|
||||
rcIntArray overlaps;
|
||||
chf.maxRegions = id;
|
||||
if (!mergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg, overlaps))
|
||||
return false;
|
||||
|
||||
// Monotone partitioning does not generate overlapping regions.
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
// Monotone partitioning does not generate overlapping regions.
|
||||
}
|
||||
|
||||
// Store the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1534,7 +1530,7 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
@ -1603,33 +1599,33 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
|
||||
// ctx->stopTimer(RC_TIMER_DIVIDE_TO_LEVELS);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||
|
||||
// Expand current regions until no empty connected cells found.
|
||||
if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, lvlStacks[sId], false) != srcReg)
|
||||
{
|
||||
rcSwap(srcReg, dstReg);
|
||||
rcSwap(srcDist, dstDist);
|
||||
}
|
||||
rcScopedTimer timerExpand(ctx, RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||
|
||||
// Mark new regions with IDs.
|
||||
for (int j=0; j<lvlStacks[sId].size(); j+=3)
|
||||
{
|
||||
int x = lvlStacks[sId][j];
|
||||
int y = lvlStacks[sId][j+1];
|
||||
int i = lvlStacks[sId][j+2];
|
||||
if (i >= 0 && srcReg[i] == 0)
|
||||
// Expand current regions until no empty connected cells found.
|
||||
if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, lvlStacks[sId], false) != srcReg)
|
||||
{
|
||||
if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack))
|
||||
regionId++;
|
||||
rcSwap(srcReg, dstReg);
|
||||
rcSwap(srcDist, dstDist);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||
{
|
||||
rcScopedTimer timerFloor(ctx, RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||
|
||||
// Mark new regions with IDs.
|
||||
for (int j = 0; j<lvlStacks[sId].size(); j += 3)
|
||||
{
|
||||
int x = lvlStacks[sId][j];
|
||||
int y = lvlStacks[sId][j+1];
|
||||
int i = lvlStacks[sId][j+2];
|
||||
if (i >= 0 && srcReg[i] == 0)
|
||||
{
|
||||
if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack))
|
||||
regionId++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expand current regions until no empty connected cells found.
|
||||
@ -1641,28 +1637,26 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_WATERSHED);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Merge regions and filter out smalle regions.
|
||||
rcIntArray overlaps;
|
||||
chf.maxRegions = regionId;
|
||||
if (!mergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg, overlaps))
|
||||
return false;
|
||||
|
||||
// If overlapping regions were found during merging, split those regions.
|
||||
if (overlaps.size() > 0)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildRegions: %d overlapping regions.", overlaps.size());
|
||||
}
|
||||
rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
// Merge regions and filter out smalle regions.
|
||||
rcIntArray overlaps;
|
||||
chf.maxRegions = regionId;
|
||||
if (!mergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg, overlaps))
|
||||
return false;
|
||||
|
||||
// If overlapping regions were found during merging, split those regions.
|
||||
if (overlaps.size() > 0)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildRegions: %d overlapping regions.", overlaps.size());
|
||||
}
|
||||
}
|
||||
|
||||
// Write the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1672,7 +1666,7 @@ bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
|
||||
rcScopedTimer timer(ctx, RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
@ -1802,22 +1796,20 @@ bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
}
|
||||
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
{
|
||||
rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Merge monotone regions to layers and remove small regions.
|
||||
rcIntArray overlaps;
|
||||
chf.maxRegions = id;
|
||||
if (!mergeAndFilterLayerRegions(ctx, minRegionArea, chf.maxRegions, chf, srcReg, overlaps))
|
||||
return false;
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
// Merge monotone regions to layers and remove small regions.
|
||||
rcIntArray overlaps;
|
||||
chf.maxRegions = id;
|
||||
if (!mergeAndFilterLayerRegions(ctx, minRegionArea, chf.maxRegions, chf, srcReg, overlaps))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Store the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user