forked from mirror/DotRecast
add scoped timer
This commit is contained in:
parent
deeee5e9d2
commit
bc14092125
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DotRecast.Core
|
||||||
|
{
|
||||||
|
public struct RcAnonymousDisposable : IDisposable
|
||||||
|
{
|
||||||
|
private Action _dispose;
|
||||||
|
|
||||||
|
public RcAnonymousDisposable(Action dispose)
|
||||||
|
{
|
||||||
|
_dispose = dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_dispose?.Invoke();
|
||||||
|
_dispose = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,16 +35,23 @@ namespace DotRecast.Core
|
||||||
_timerAccum = new ConcurrentDictionary<string, RcAtomicLong>();
|
_timerAccum = new ConcurrentDictionary<string, RcAtomicLong>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartTimer(string name)
|
public IDisposable ScopedTimer(RcTimerLabel label)
|
||||||
{
|
{
|
||||||
_timerStart.Value[name] = new RcAtomicLong(RcFrequency.Ticks);
|
StartTimer(label);
|
||||||
|
return new RcAnonymousDisposable(() => StopTimer(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopTimer(string name)
|
public void StartTimer(RcTimerLabel label)
|
||||||
|
{
|
||||||
|
_timerStart.Value[label.Name] = new RcAtomicLong(RcFrequency.Ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void StopTimer(RcTimerLabel label)
|
||||||
{
|
{
|
||||||
_timerAccum
|
_timerAccum
|
||||||
.GetOrAdd(name, _ => new RcAtomicLong(0))
|
.GetOrAdd(label.Name, _ => new RcAtomicLong(0))
|
||||||
.AddAndGet(RcFrequency.Ticks - _timerStart.Value?[name].Read() ?? 0);
|
.AddAndGet(RcFrequency.Ticks - _timerStart.Value?[label.Name].Read() ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Warn(string message)
|
public void Warn(string message)
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
namespace DotRecast.Core
|
||||||
|
{
|
||||||
|
/// Recast performance timer categories.
|
||||||
|
/// @see rcContext
|
||||||
|
public class RcTimerLabel
|
||||||
|
{
|
||||||
|
/// The user defined total time of the build.
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_TOTAL = new RcTimerLabel(nameof(RC_TIMER_TOTAL));
|
||||||
|
|
||||||
|
/// A user defined build time.
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_TEMP = new RcTimerLabel(nameof(RC_TIMER_TEMP));
|
||||||
|
|
||||||
|
/// The time to rasterize the triangles. (See: #rcRasterizeTriangle)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_RASTERIZE_TRIANGLES = new RcTimerLabel(nameof(RC_TIMER_RASTERIZE_TRIANGLES));
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_RASTERIZE_SPHERE = new RcTimerLabel(nameof(RC_TIMER_RASTERIZE_SPHERE));
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_RASTERIZE_CAPSULE = new RcTimerLabel(nameof(RC_TIMER_RASTERIZE_CAPSULE));
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_RASTERIZE_CYLINDER = new RcTimerLabel(nameof(RC_TIMER_RASTERIZE_CYLINDER));
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_RASTERIZE_BOX = new RcTimerLabel(nameof(RC_TIMER_RASTERIZE_BOX));
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_RASTERIZE_CONVEX = new RcTimerLabel(nameof(RC_TIMER_RASTERIZE_CONVEX));
|
||||||
|
|
||||||
|
/// The time to build the compact heightfield. (See: #rcBuildCompactHeightfield)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_COMPACTHEIGHTFIELD = new RcTimerLabel(nameof(RC_TIMER_BUILD_COMPACTHEIGHTFIELD));
|
||||||
|
|
||||||
|
/// The total time to build the contours. (See: #rcBuildContours)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_CONTOURS = new RcTimerLabel(nameof(RC_TIMER_BUILD_CONTOURS));
|
||||||
|
|
||||||
|
/// The time to trace the boundaries of the contours. (See: #rcBuildContours)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_CONTOURS_TRACE = new RcTimerLabel(nameof(RC_TIMER_BUILD_CONTOURS_TRACE));
|
||||||
|
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_CONTOURS_WALK = new RcTimerLabel(nameof(RC_TIMER_BUILD_CONTOURS_WALK));
|
||||||
|
|
||||||
|
/// The time to simplify the contours. (See: #rcBuildContours)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_CONTOURS_SIMPLIFY = new RcTimerLabel(nameof(RC_TIMER_BUILD_CONTOURS_SIMPLIFY));
|
||||||
|
|
||||||
|
/// The time to filter ledge spans. (See: #rcFilterLedgeSpans)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_FILTER_BORDER = new RcTimerLabel(nameof(RC_TIMER_FILTER_BORDER));
|
||||||
|
|
||||||
|
/// The time to filter low height spans. (See: #rcFilterWalkableLowHeightSpans)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_FILTER_WALKABLE = new RcTimerLabel(nameof(RC_TIMER_FILTER_WALKABLE));
|
||||||
|
|
||||||
|
/// The time to apply the median filter. (See: #rcMedianFilterWalkableArea)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_MEDIAN_AREA = new RcTimerLabel(nameof(RC_TIMER_MEDIAN_AREA));
|
||||||
|
|
||||||
|
/// The time to filter low obstacles. (See: #rcFilterLowHangingWalkableObstacles)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_FILTER_LOW_OBSTACLES = new RcTimerLabel(nameof(RC_TIMER_FILTER_LOW_OBSTACLES));
|
||||||
|
|
||||||
|
/// The time to build the polygon mesh. (See: #rcBuildPolyMesh)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_POLYMESH = new RcTimerLabel(nameof(RC_TIMER_BUILD_POLYMESH));
|
||||||
|
|
||||||
|
/// The time to merge polygon meshes. (See: #rcMergePolyMeshes)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_MERGE_POLYMESH = new RcTimerLabel(nameof(RC_TIMER_MERGE_POLYMESH));
|
||||||
|
|
||||||
|
/// The time to erode the walkable area. (See: #rcErodeWalkableArea)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_ERODE_AREA = new RcTimerLabel(nameof(RC_TIMER_ERODE_AREA));
|
||||||
|
|
||||||
|
/// The time to mark a box area. (See: #rcMarkBoxArea)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_MARK_BOX_AREA = new RcTimerLabel(nameof(RC_TIMER_MARK_BOX_AREA));
|
||||||
|
|
||||||
|
/// The time to mark a cylinder area. (See: #rcMarkCylinderArea)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_MARK_CYLINDER_AREA = new RcTimerLabel(nameof(RC_TIMER_MARK_CYLINDER_AREA));
|
||||||
|
|
||||||
|
/// The time to mark a convex polygon area. (See: #rcMarkConvexPolyArea)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_MARK_CONVEXPOLY_AREA = new RcTimerLabel(nameof(RC_TIMER_MARK_CONVEXPOLY_AREA));
|
||||||
|
|
||||||
|
/// The total time to build the distance field. (See: #rcBuildDistanceField)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_DISTANCEFIELD = new RcTimerLabel(nameof(RC_TIMER_BUILD_DISTANCEFIELD));
|
||||||
|
|
||||||
|
/// The time to build the distances of the distance field. (See: #rcBuildDistanceField)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_DISTANCEFIELD_DIST = new RcTimerLabel(nameof(RC_TIMER_BUILD_DISTANCEFIELD_DIST));
|
||||||
|
|
||||||
|
/// The time to blur the distance field. (See: #rcBuildDistanceField)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_DISTANCEFIELD_BLUR = new RcTimerLabel(nameof(RC_TIMER_BUILD_DISTANCEFIELD_BLUR));
|
||||||
|
|
||||||
|
/// The total time to build the regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_REGIONS = new RcTimerLabel(nameof(RC_TIMER_BUILD_REGIONS));
|
||||||
|
|
||||||
|
/// The total time to apply the watershed algorithm. (See: #rcBuildRegions)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_REGIONS_WATERSHED = new RcTimerLabel(nameof(RC_TIMER_BUILD_REGIONS_WATERSHED));
|
||||||
|
|
||||||
|
/// The time to expand regions while applying the watershed algorithm. (See: #rcBuildRegions)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_REGIONS_EXPAND = new RcTimerLabel(nameof(RC_TIMER_BUILD_REGIONS_EXPAND));
|
||||||
|
|
||||||
|
/// The time to flood regions while applying the watershed algorithm. (See: #rcBuildRegions)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_REGIONS_FLOOD = new RcTimerLabel(nameof(RC_TIMER_BUILD_REGIONS_FLOOD));
|
||||||
|
|
||||||
|
/// The time to filter out small regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_REGIONS_FILTER = new RcTimerLabel(nameof(RC_TIMER_BUILD_REGIONS_FILTER));
|
||||||
|
|
||||||
|
/// The time to build heightfield layers. (See: #rcBuildHeightfieldLayers)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_LAYERS = new RcTimerLabel(nameof(RC_TIMER_BUILD_LAYERS));
|
||||||
|
|
||||||
|
/// The time to build the polygon mesh detail. (See: #rcBuildPolyMeshDetail)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_BUILD_POLYMESHDETAIL = new RcTimerLabel(nameof(RC_TIMER_BUILD_POLYMESHDETAIL));
|
||||||
|
|
||||||
|
/// The time to merge polygon mesh details. (See: #rcMergePolyMeshDetails)
|
||||||
|
public static readonly RcTimerLabel RC_TIMER_MERGE_POLYMESHDETAIL = new RcTimerLabel(nameof(RC_TIMER_MERGE_POLYMESHDETAIL));
|
||||||
|
|
||||||
|
|
||||||
|
/// The maximum number of timers. (Used for iterating timers.)
|
||||||
|
public static readonly RcTimerLabel RC_MAX_TIMERS = new RcTimerLabel(nameof(RC_MAX_TIMERS));
|
||||||
|
|
||||||
|
public readonly string Name;
|
||||||
|
|
||||||
|
private RcTimerLabel(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
int w = chf.width;
|
int w = chf.width;
|
||||||
int h = chf.height;
|
int h = chf.height;
|
||||||
ctx.StartTimer("ERODE_AREA");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_ERODE_AREA);
|
||||||
|
|
||||||
int[] dist = new int[chf.spanCount];
|
int[] dist = new int[chf.spanCount];
|
||||||
Array.Fill(dist, 255);
|
Array.Fill(dist, 255);
|
||||||
|
@ -205,8 +205,6 @@ namespace DotRecast.Recast
|
||||||
for (int i = 0; i < chf.spanCount; ++i)
|
for (int i = 0; i < chf.spanCount; ++i)
|
||||||
if (dist[i] < thr)
|
if (dist[i] < thr)
|
||||||
chf.areas[i] = RC_NULL_AREA;
|
chf.areas[i] = RC_NULL_AREA;
|
||||||
|
|
||||||
ctx.StopTimer("ERODE_AREA");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -220,7 +218,7 @@ namespace DotRecast.Recast
|
||||||
int w = chf.width;
|
int w = chf.width;
|
||||||
int h = chf.height;
|
int h = chf.height;
|
||||||
|
|
||||||
ctx.StartTimer("MEDIAN_AREA");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MEDIAN_AREA);
|
||||||
|
|
||||||
int[] areas = new int[chf.spanCount];
|
int[] areas = new int[chf.spanCount];
|
||||||
|
|
||||||
|
@ -273,8 +271,6 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
chf.areas = areas;
|
chf.areas = areas;
|
||||||
|
|
||||||
ctx.StopTimer("MEDIAN_AREA");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +281,7 @@ namespace DotRecast.Recast
|
||||||
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
|
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
|
||||||
public static void MarkBoxArea(RcTelemetry ctx, float[] bmin, float[] bmax, AreaModification areaMod, RcCompactHeightfield chf)
|
public static void MarkBoxArea(RcTelemetry ctx, float[] bmin, float[] bmax, AreaModification areaMod, RcCompactHeightfield chf)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("MARK_BOX_AREA");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MARK_BOX_AREA);
|
||||||
|
|
||||||
int minx = (int)((bmin[0] - chf.bmin.x) / chf.cs);
|
int minx = (int)((bmin[0] - chf.bmin.x) / chf.cs);
|
||||||
int miny = (int)((bmin[1] - chf.bmin.y) / chf.ch);
|
int miny = (int)((bmin[1] - chf.bmin.y) / chf.ch);
|
||||||
|
@ -328,8 +324,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("MARK_BOX_AREA");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PointInPoly(float[] verts, RcVec3f p)
|
static bool PointInPoly(float[] verts, RcVec3f p)
|
||||||
|
@ -360,7 +354,7 @@ namespace DotRecast.Recast
|
||||||
public static void MarkConvexPolyArea(RcTelemetry ctx, float[] verts, float hmin, float hmax, AreaModification areaMod,
|
public static void MarkConvexPolyArea(RcTelemetry ctx, float[] verts, float hmin, float hmax, AreaModification areaMod,
|
||||||
RcCompactHeightfield chf)
|
RcCompactHeightfield chf)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("MARK_CONVEXPOLY_AREA");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||||
|
|
||||||
RcVec3f bmin = new RcVec3f();
|
RcVec3f bmin = new RcVec3f();
|
||||||
RcVec3f bmax = new RcVec3f();
|
RcVec3f bmax = new RcVec3f();
|
||||||
|
@ -426,8 +420,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("MARK_CONVEXPOLY_AREA");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -437,7 +429,7 @@ namespace DotRecast.Recast
|
||||||
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
|
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
|
||||||
public static void MarkCylinderArea(RcTelemetry ctx, float[] pos, float r, float h, AreaModification areaMod, RcCompactHeightfield chf)
|
public static void MarkCylinderArea(RcTelemetry ctx, float[] pos, float r, float h, AreaModification areaMod, RcCompactHeightfield chf)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("MARK_CYLINDER_AREA");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MARK_CYLINDER_AREA);
|
||||||
|
|
||||||
RcVec3f bmin = new RcVec3f();
|
RcVec3f bmin = new RcVec3f();
|
||||||
RcVec3f bmax = new RcVec3f();
|
RcVec3f bmax = new RcVec3f();
|
||||||
|
@ -501,8 +493,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("MARK_CYLINDER_AREA");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -41,7 +41,7 @@ namespace DotRecast.Recast
|
||||||
public static RcCompactHeightfield BuildCompactHeightfield(RcTelemetry ctx, int walkableHeight, int walkableClimb,
|
public static RcCompactHeightfield BuildCompactHeightfield(RcTelemetry ctx, int walkableHeight, int walkableClimb,
|
||||||
RcHeightfield hf)
|
RcHeightfield hf)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("BUILD_COMPACTHEIGHTFIELD");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
|
||||||
|
|
||||||
RcCompactHeightfield chf = new RcCompactHeightfield();
|
RcCompactHeightfield chf = new RcCompactHeightfield();
|
||||||
int w = hf.width;
|
int w = hf.width;
|
||||||
|
@ -161,7 +161,6 @@ namespace DotRecast.Recast
|
||||||
+ " (max: " + MAX_LAYERS + ")");
|
+ " (max: " + MAX_LAYERS + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("BUILD_COMPACTHEIGHTFIELD");
|
|
||||||
return chf;
|
return chf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -722,7 +722,8 @@ namespace DotRecast.Recast
|
||||||
int borderSize = chf.borderSize;
|
int borderSize = chf.borderSize;
|
||||||
RcContourSet cset = new RcContourSet();
|
RcContourSet cset = new RcContourSet();
|
||||||
|
|
||||||
ctx.StartTimer("CONTOURS");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS);
|
||||||
|
|
||||||
cset.bmin = chf.bmin;
|
cset.bmin = chf.bmin;
|
||||||
cset.bmax = chf.bmax;
|
cset.bmax = chf.bmax;
|
||||||
if (borderSize > 0)
|
if (borderSize > 0)
|
||||||
|
@ -744,7 +745,7 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
int[] flags = new int[chf.spanCount];
|
int[] flags = new int[chf.spanCount];
|
||||||
|
|
||||||
ctx.StartTimer("CONTOURS_TRACE");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_TRACE);
|
||||||
|
|
||||||
// Mark boundaries.
|
// Mark boundaries.
|
||||||
for (int y = 0; y < h; ++y)
|
for (int y = 0; y < h; ++y)
|
||||||
|
@ -782,7 +783,7 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("CONTOURS_TRACE");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_TRACE);
|
||||||
|
|
||||||
List<int> verts = new List<int>(256);
|
List<int> verts = new List<int>(256);
|
||||||
List<int> simplified = new List<int>(64);
|
List<int> simplified = new List<int>(64);
|
||||||
|
@ -808,14 +809,14 @@ namespace DotRecast.Recast
|
||||||
verts.Clear();
|
verts.Clear();
|
||||||
simplified.Clear();
|
simplified.Clear();
|
||||||
|
|
||||||
ctx.StartTimer("CONTOURS_WALK");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_WALK);
|
||||||
WalkContour(x, y, i, chf, flags, verts);
|
WalkContour(x, y, i, chf, flags, verts);
|
||||||
ctx.StopTimer("CONTOURS_WALK");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_WALK);
|
||||||
|
|
||||||
ctx.StartTimer("CONTOURS_SIMPLIFY");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
|
||||||
SimplifyContour(verts, simplified, maxError, maxEdgeLen, buildFlags);
|
SimplifyContour(verts, simplified, maxError, maxEdgeLen, buildFlags);
|
||||||
RemoveDegenerateSegments(simplified);
|
RemoveDegenerateSegments(simplified);
|
||||||
ctx.StopTimer("CONTOURS_SIMPLIFY");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
|
||||||
|
|
||||||
// Store region->contour remap info.
|
// Store region->contour remap info.
|
||||||
// Create contour.
|
// Create contour.
|
||||||
|
@ -956,7 +957,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("CONTOURS");
|
|
||||||
return cset;
|
return cset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
public static void RasterizeSphere(RcHeightfield hf, RcVec3f center, float radius, int area, int flagMergeThr, RcTelemetry ctx)
|
public static void RasterizeSphere(RcHeightfield hf, RcVec3f center, float radius, int area, int flagMergeThr, RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_SPHERE");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_SPHERE);
|
||||||
float[] bounds =
|
float[] bounds =
|
||||||
{
|
{
|
||||||
center.x - radius, center.y - radius, center.z - radius, center.x + radius, center.y + radius,
|
center.x - radius, center.y - radius, center.z - radius, center.x + radius, center.y + radius,
|
||||||
|
@ -39,13 +39,12 @@ namespace DotRecast.Recast
|
||||||
};
|
};
|
||||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||||
rectangle => IntersectSphere(rectangle, center, radius * radius));
|
rectangle => IntersectSphere(rectangle, center, radius * radius));
|
||||||
ctx.StopTimer("RASTERIZE_SPHERE");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RasterizeCapsule(RcHeightfield hf, RcVec3f start, RcVec3f end, float radius, int area, int flagMergeThr,
|
public static void RasterizeCapsule(RcHeightfield hf, RcVec3f start, RcVec3f end, float radius, int area, int flagMergeThr,
|
||||||
RcTelemetry ctx)
|
RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_CAPSULE");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CAPSULE);
|
||||||
float[] bounds =
|
float[] bounds =
|
||||||
{
|
{
|
||||||
Math.Min(start.x, end.x) - radius, Math.Min(start.y, end.y) - radius,
|
Math.Min(start.x, end.x) - radius, Math.Min(start.y, end.y) - radius,
|
||||||
|
@ -55,13 +54,12 @@ namespace DotRecast.Recast
|
||||||
RcVec3f axis = RcVec3f.Of(end.x - start.x, end.y - start.y, end.z - start.z);
|
RcVec3f axis = RcVec3f.Of(end.x - start.x, end.y - start.y, end.z - start.z);
|
||||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||||
rectangle => IntersectCapsule(rectangle, start, end, axis, radius * radius));
|
rectangle => IntersectCapsule(rectangle, start, end, axis, radius * radius));
|
||||||
ctx.StopTimer("RASTERIZE_CAPSULE");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RasterizeCylinder(RcHeightfield hf, RcVec3f start, RcVec3f end, float radius, int area, int flagMergeThr,
|
public static void RasterizeCylinder(RcHeightfield hf, RcVec3f start, RcVec3f end, float radius, int area, int flagMergeThr,
|
||||||
RcTelemetry ctx)
|
RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_CYLINDER");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CYLINDER);
|
||||||
float[] bounds =
|
float[] bounds =
|
||||||
{
|
{
|
||||||
Math.Min(start.x, end.x) - radius, Math.Min(start.y, end.y) - radius,
|
Math.Min(start.x, end.x) - radius, Math.Min(start.y, end.y) - radius,
|
||||||
|
@ -71,13 +69,12 @@ namespace DotRecast.Recast
|
||||||
RcVec3f axis = RcVec3f.Of(end.x - start.x, end.y - start.y, end.z - start.z);
|
RcVec3f axis = RcVec3f.Of(end.x - start.x, end.y - start.y, end.z - start.z);
|
||||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||||
rectangle => IntersectCylinder(rectangle, start, end, axis, radius * radius));
|
rectangle => IntersectCylinder(rectangle, start, end, axis, radius * radius));
|
||||||
ctx.StopTimer("RASTERIZE_CYLINDER");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RasterizeBox(RcHeightfield hf, RcVec3f center, RcVec3f[] halfEdges, int area, int flagMergeThr,
|
public static void RasterizeBox(RcHeightfield hf, RcVec3f center, RcVec3f[] halfEdges, int area, int flagMergeThr,
|
||||||
RcTelemetry ctx)
|
RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_BOX");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_BOX);
|
||||||
RcVec3f[] normals =
|
RcVec3f[] normals =
|
||||||
{
|
{
|
||||||
RcVec3f.Of(halfEdges[0].x, halfEdges[0].y, halfEdges[0].z),
|
RcVec3f.Of(halfEdges[0].x, halfEdges[0].y, halfEdges[0].z),
|
||||||
|
@ -123,13 +120,12 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr, rectangle => IntersectBox(rectangle, vertices, planes));
|
RasterizationFilledShape(hf, bounds, area, flagMergeThr, rectangle => IntersectBox(rectangle, vertices, planes));
|
||||||
ctx.StopTimer("RASTERIZE_BOX");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RasterizeConvex(RcHeightfield hf, float[] vertices, int[] triangles, int area, int flagMergeThr,
|
public static void RasterizeConvex(RcHeightfield hf, float[] vertices, int[] triangles, int area, int flagMergeThr,
|
||||||
RcTelemetry ctx)
|
RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_CONVEX");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CONVEX);
|
||||||
float[] bounds = new float[] { vertices[0], vertices[1], vertices[2], vertices[0], vertices[1], vertices[2] };
|
float[] bounds = new float[] { vertices[0], vertices[1], vertices[2], vertices[0], vertices[1], vertices[2] };
|
||||||
for (int i = 0; i < vertices.Length; i += 3)
|
for (int i = 0; i < vertices.Length; i += 3)
|
||||||
{
|
{
|
||||||
|
@ -179,7 +175,6 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||||
rectangle => IntersectConvex(rectangle, triangles, vertices, planes, triBounds));
|
rectangle => IntersectConvex(rectangle, triangles, vertices, planes, triBounds));
|
||||||
ctx.StopTimer("RASTERIZE_CONVEX");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Plane(float[][] planes, int p, float[] v1, float[] v2, float[] vertices, int vert)
|
private static void Plane(float[][] planes, int p, float[] v1, float[] v2, float[] vertices, int vert)
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace DotRecast.Recast
|
||||||
/// @see rcHeightfield, rcConfig
|
/// @see rcHeightfield, rcConfig
|
||||||
public static void FilterLowHangingWalkableObstacles(RcTelemetry ctx, int walkableClimb, RcHeightfield solid)
|
public static void FilterLowHangingWalkableObstacles(RcTelemetry ctx, int walkableClimb, RcHeightfield solid)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("FILTER_LOW_OBSTACLES");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||||
|
|
||||||
int w = solid.width;
|
int w = solid.width;
|
||||||
int h = solid.height;
|
int h = solid.height;
|
||||||
|
@ -71,8 +71,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("FILTER_LOW_OBSTACLES");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -87,7 +85,7 @@ namespace DotRecast.Recast
|
||||||
/// @see rcHeightfield, rcConfig
|
/// @see rcHeightfield, rcConfig
|
||||||
public static void FilterLedgeSpans(RcTelemetry ctx, int walkableHeight, int walkableClimb, RcHeightfield solid)
|
public static void FilterLedgeSpans(RcTelemetry ctx, int walkableHeight, int walkableClimb, RcHeightfield solid)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("FILTER_LEDGE");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_FILTER_BORDER);
|
||||||
|
|
||||||
int w = solid.width;
|
int w = solid.width;
|
||||||
int h = solid.height;
|
int h = solid.height;
|
||||||
|
@ -168,8 +166,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("FILTER_LEDGE");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -180,7 +176,7 @@ namespace DotRecast.Recast
|
||||||
/// @see rcHeightfield, rcConfig
|
/// @see rcHeightfield, rcConfig
|
||||||
public static void FilterWalkableLowHeightSpans(RcTelemetry ctx, int walkableHeight, RcHeightfield solid)
|
public static void FilterWalkableLowHeightSpans(RcTelemetry ctx, int walkableHeight, RcHeightfield solid)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("FILTER_WALKABLE");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_FILTER_WALKABLE);
|
||||||
|
|
||||||
int w = solid.width;
|
int w = solid.width;
|
||||||
int h = solid.height;
|
int h = solid.height;
|
||||||
|
@ -200,8 +196,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("FILTER_WALKABLE");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,7 +53,8 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
public static RcHeightfieldLayerSet BuildHeightfieldLayers(RcTelemetry ctx, RcCompactHeightfield chf, int walkableHeight)
|
public static RcHeightfieldLayerSet BuildHeightfieldLayers(RcTelemetry ctx, RcCompactHeightfield chf, int walkableHeight)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RC_TIMER_BUILD_LAYERS");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_LAYERS);
|
||||||
|
|
||||||
int w = chf.width;
|
int w = chf.width;
|
||||||
int h = chf.height;
|
int h = chf.height;
|
||||||
int borderSize = chf.borderSize;
|
int borderSize = chf.borderSize;
|
||||||
|
@ -397,7 +398,7 @@ namespace DotRecast.Recast
|
||||||
// No layers, return empty.
|
// No layers, return empty.
|
||||||
if (layerId == 0)
|
if (layerId == 0)
|
||||||
{
|
{
|
||||||
// ctx.StopTimer(RC_TIMER_BUILD_LAYERS);
|
// ctx.Stop(RC_TIMER_BUILD_LAYERS);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -966,7 +966,8 @@ namespace DotRecast.Recast
|
||||||
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
|
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
|
||||||
public static RcPolyMesh BuildPolyMesh(RcTelemetry ctx, RcContourSet cset, int nvp)
|
public static RcPolyMesh BuildPolyMesh(RcTelemetry ctx, RcContourSet cset, int nvp)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("POLYMESH");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_POLYMESH);
|
||||||
|
|
||||||
RcPolyMesh mesh = new RcPolyMesh();
|
RcPolyMesh mesh = new RcPolyMesh();
|
||||||
mesh.bmin = cset.bmin;
|
mesh.bmin = cset.bmin;
|
||||||
mesh.bmax = cset.bmax;
|
mesh.bmax = cset.bmax;
|
||||||
|
@ -1204,7 +1205,6 @@ namespace DotRecast.Recast
|
||||||
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
|
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("POLYMESH");
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1214,7 +1214,8 @@ namespace DotRecast.Recast
|
||||||
if (nmeshes == 0 || meshes == null)
|
if (nmeshes == 0 || meshes == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
ctx.StartTimer("MERGE_POLYMESH");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MERGE_POLYMESH);
|
||||||
|
|
||||||
RcPolyMesh mesh = new RcPolyMesh();
|
RcPolyMesh mesh = new RcPolyMesh();
|
||||||
mesh.nvp = meshes[0].nvp;
|
mesh.nvp = meshes[0].nvp;
|
||||||
mesh.cs = meshes[0].cs;
|
mesh.cs = meshes[0].cs;
|
||||||
|
@ -1333,8 +1334,6 @@ namespace DotRecast.Recast
|
||||||
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
|
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("MERGE_POLYMESH");
|
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1426,7 +1426,7 @@ namespace DotRecast.Recast
|
||||||
public static RcPolyMeshDetail BuildPolyMeshDetail(RcTelemetry ctx, RcPolyMesh mesh, RcCompactHeightfield chf,
|
public static RcPolyMeshDetail BuildPolyMeshDetail(RcTelemetry ctx, RcPolyMesh mesh, RcCompactHeightfield chf,
|
||||||
float sampleDist, float sampleMaxError)
|
float sampleDist, float sampleMaxError)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("POLYMESHDETAIL");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||||
if (mesh.nverts == 0 || mesh.npolys == 0)
|
if (mesh.nverts == 0 || mesh.npolys == 0)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -1610,16 +1610,15 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("POLYMESHDETAIL");
|
|
||||||
return dmesh;
|
return dmesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail
|
/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail
|
||||||
private static RcPolyMeshDetail MergePolyMeshDetails(RcTelemetry ctx, RcPolyMeshDetail[] meshes, int nmeshes)
|
private static RcPolyMeshDetail MergePolyMeshDetails(RcTelemetry ctx, RcPolyMeshDetail[] meshes, int nmeshes)
|
||||||
{
|
{
|
||||||
RcPolyMeshDetail mesh = new RcPolyMeshDetail();
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MERGE_POLYMESHDETAIL);
|
||||||
|
|
||||||
ctx.StartTimer("MERGE_POLYMESHDETAIL");
|
RcPolyMeshDetail mesh = new RcPolyMeshDetail();
|
||||||
|
|
||||||
int maxVerts = 0;
|
int maxVerts = 0;
|
||||||
int maxTris = 0;
|
int maxTris = 0;
|
||||||
|
@ -1680,7 +1679,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("MERGE_POLYMESHDETAIL");
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,14 +400,12 @@ namespace DotRecast.Recast
|
||||||
public static void RasterizeTriangle(RcHeightfield heightfield, float[] verts, int v0, int v1, int v2, int area,
|
public static void RasterizeTriangle(RcHeightfield heightfield, float[] verts, int v0, int v1, int v2, int area,
|
||||||
int flagMergeThreshold, RcTelemetry ctx)
|
int flagMergeThreshold, RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_TRIANGLES");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
||||||
|
|
||||||
float inverseCellSize = 1.0f / heightfield.cs;
|
float inverseCellSize = 1.0f / heightfield.cs;
|
||||||
float inverseCellHeight = 1.0f / heightfield.ch;
|
float inverseCellHeight = 1.0f / heightfield.ch;
|
||||||
RasterizeTri(verts, v0, v1, v2, area, heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs, inverseCellSize,
|
RasterizeTri(verts, v0, v1, v2, area, heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs, inverseCellSize,
|
||||||
inverseCellHeight, flagMergeThreshold);
|
inverseCellHeight, flagMergeThreshold);
|
||||||
|
|
||||||
ctx.StopTimer("RASTERIZE_TRIANGLES");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -431,7 +429,7 @@ namespace DotRecast.Recast
|
||||||
public static void RasterizeTriangles(RcHeightfield heightfield, float[] verts, int[] tris, int[] areaIds, int numTris,
|
public static void RasterizeTriangles(RcHeightfield heightfield, float[] verts, int[] tris, int[] areaIds, int numTris,
|
||||||
int flagMergeThreshold, RcTelemetry ctx)
|
int flagMergeThreshold, RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_TRIANGLES");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
||||||
|
|
||||||
float inverseCellSize = 1.0f / heightfield.cs;
|
float inverseCellSize = 1.0f / heightfield.cs;
|
||||||
float inverseCellHeight = 1.0f / heightfield.ch;
|
float inverseCellHeight = 1.0f / heightfield.ch;
|
||||||
|
@ -443,8 +441,6 @@ namespace DotRecast.Recast
|
||||||
RasterizeTri(verts, v0, v1, v2, areaIds[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs,
|
RasterizeTri(verts, v0, v1, v2, areaIds[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs,
|
||||||
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("RASTERIZE_TRIANGLES");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -468,7 +464,7 @@ namespace DotRecast.Recast
|
||||||
public static void RasterizeTriangles(RcHeightfield heightfield, float[] verts, int[] areaIds, int numTris,
|
public static void RasterizeTriangles(RcHeightfield heightfield, float[] verts, int[] areaIds, int numTris,
|
||||||
int flagMergeThreshold, RcTelemetry ctx)
|
int flagMergeThreshold, RcTelemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("RASTERIZE_TRIANGLES");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
||||||
|
|
||||||
float inverseCellSize = 1.0f / heightfield.cs;
|
float inverseCellSize = 1.0f / heightfield.cs;
|
||||||
float inverseCellHeight = 1.0f / heightfield.ch;
|
float inverseCellHeight = 1.0f / heightfield.ch;
|
||||||
|
@ -480,8 +476,6 @@ namespace DotRecast.Recast
|
||||||
RasterizeTri(verts, v0, v1, v2, areaIds[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs,
|
RasterizeTri(verts, v0, v1, v2, areaIds[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs,
|
||||||
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("RASTERIZE_TRIANGLES");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -580,7 +580,6 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void RemoveAdjacentNeighbours(RcRegion reg)
|
private static void RemoveAdjacentNeighbours(RcRegion reg)
|
||||||
{
|
{
|
||||||
// Remove adjacent duplicates.
|
// Remove adjacent duplicates.
|
||||||
|
@ -1418,16 +1417,16 @@ namespace DotRecast.Recast
|
||||||
/// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone
|
/// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone
|
||||||
public static void BuildDistanceField(RcTelemetry ctx, RcCompactHeightfield chf)
|
public static void BuildDistanceField(RcTelemetry ctx, RcCompactHeightfield chf)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("DISTANCEFIELD");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD);
|
||||||
int[] src = new int[chf.spanCount];
|
|
||||||
ctx.StartTimer("DISTANCEFIELD_DIST");
|
|
||||||
|
|
||||||
|
int[] src = new int[chf.spanCount];
|
||||||
|
|
||||||
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||||
int maxDist = CalculateDistanceField(chf, src);
|
int maxDist = CalculateDistanceField(chf, src);
|
||||||
chf.maxDistance = maxDist;
|
chf.maxDistance = maxDist;
|
||||||
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||||
|
|
||||||
ctx.StopTimer("DISTANCEFIELD_DIST");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||||
|
|
||||||
ctx.StartTimer("DISTANCEFIELD_BLUR");
|
|
||||||
|
|
||||||
// Blur
|
// Blur
|
||||||
src = BoxBlur(chf, 1, src);
|
src = BoxBlur(chf, 1, src);
|
||||||
|
@ -1435,9 +1434,7 @@ namespace DotRecast.Recast
|
||||||
// Store distance.
|
// Store distance.
|
||||||
chf.dist = src;
|
chf.dist = src;
|
||||||
|
|
||||||
ctx.StopTimer("DISTANCEFIELD_BLUR");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||||
|
|
||||||
ctx.StopTimer("DISTANCEFIELD");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PaintRectRegion(int minx, int maxx, int miny, int maxy, int regId, RcCompactHeightfield chf,
|
private static void PaintRectRegion(int minx, int maxx, int miny, int maxy, int regId, RcCompactHeightfield chf,
|
||||||
|
@ -1482,7 +1479,7 @@ namespace DotRecast.Recast
|
||||||
public static void BuildRegionsMonotone(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
|
public static void BuildRegionsMonotone(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
|
||||||
int mergeRegionArea)
|
int mergeRegionArea)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("REGIONS");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS);
|
||||||
|
|
||||||
int w = chf.width;
|
int w = chf.width;
|
||||||
int h = chf.height;
|
int h = chf.height;
|
||||||
|
@ -1624,23 +1621,19 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StartTimer("REGIONS_FILTER");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||||
|
|
||||||
// Merge regions and filter out small regions.
|
// Merge regions and filter out small regions.
|
||||||
List<int> overlaps = new List<int>();
|
List<int> overlaps = new List<int>();
|
||||||
chf.maxRegions = MergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, id, chf, srcReg, overlaps);
|
chf.maxRegions = MergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, id, chf, srcReg, overlaps);
|
||||||
|
|
||||||
// Monotone partitioning does not generate overlapping regions.
|
// Monotone partitioning does not generate overlapping regions.
|
||||||
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||||
ctx.StopTimer("REGIONS_FILTER");
|
|
||||||
|
|
||||||
// Store the result out.
|
// Store the result out.
|
||||||
for (int i = 0; i < chf.spanCount; ++i)
|
for (int i = 0; i < chf.spanCount; ++i)
|
||||||
{
|
{
|
||||||
chf.spans[i].reg = srcReg[i];
|
chf.spans[i].reg = srcReg[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -1665,13 +1658,13 @@ namespace DotRecast.Recast
|
||||||
public static void BuildRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
|
public static void BuildRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
|
||||||
int mergeRegionArea)
|
int mergeRegionArea)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("REGIONS");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS);
|
||||||
|
|
||||||
int w = chf.width;
|
int w = chf.width;
|
||||||
int h = chf.height;
|
int h = chf.height;
|
||||||
int borderSize = chf.borderSize;
|
int borderSize = chf.borderSize;
|
||||||
|
|
||||||
ctx.StartTimer("REGIONS_WATERSHED");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED);
|
||||||
|
|
||||||
int LOG_NB_STACKS = 3;
|
int LOG_NB_STACKS = 3;
|
||||||
int NB_STACKS = 1 << LOG_NB_STACKS;
|
int NB_STACKS = 1 << LOG_NB_STACKS;
|
||||||
|
@ -1732,14 +1725,14 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
// ctx->StopTimer(RC_TIMER_DIVIDE_TO_LEVELS);
|
// ctx->StopTimer(RC_TIMER_DIVIDE_TO_LEVELS);
|
||||||
|
|
||||||
ctx.StartTimer("REGIONS_EXPAND");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||||
|
|
||||||
// Expand current regions until no empty connected cells found.
|
// Expand current regions until no empty connected cells found.
|
||||||
ExpandRegions(expandIters, level, chf, srcReg, srcDist, lvlStacks[sId], false);
|
ExpandRegions(expandIters, level, chf, srcReg, srcDist, lvlStacks[sId], false);
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS_EXPAND");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||||
|
|
||||||
ctx.StartTimer("REGIONS_FLOOD");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||||
|
|
||||||
// Mark new regions with IDs.
|
// Mark new regions with IDs.
|
||||||
for (int j = 0; j < lvlStacks[sId].Count; j += 3)
|
for (int j = 0; j < lvlStacks[sId].Count; j += 3)
|
||||||
|
@ -1756,15 +1749,15 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS_FLOOD");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand current regions until no empty connected cells found.
|
// Expand current regions until no empty connected cells found.
|
||||||
ExpandRegions(expandIters * 8, 0, chf, srcReg, srcDist, stack, true);
|
ExpandRegions(expandIters * 8, 0, chf, srcReg, srcDist, stack, true);
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS_WATERSHED");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED);
|
||||||
|
|
||||||
ctx.StartTimer("REGIONS_FILTER");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||||
|
|
||||||
// Merge regions and filter out smalle regions.
|
// Merge regions and filter out smalle regions.
|
||||||
List<int> overlaps = new List<int>();
|
List<int> overlaps = new List<int>();
|
||||||
|
@ -1776,20 +1769,18 @@ namespace DotRecast.Recast
|
||||||
ctx.Warn("rcBuildRegions: " + overlaps.Count + " overlapping regions.");
|
ctx.Warn("rcBuildRegions: " + overlaps.Count + " overlapping regions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS_FILTER");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||||
|
|
||||||
// Write the result out.
|
// Write the result out.
|
||||||
for (int i = 0; i < chf.spanCount; ++i)
|
for (int i = 0; i < chf.spanCount; ++i)
|
||||||
{
|
{
|
||||||
chf.spans[i].reg = srcReg[i];
|
chf.spans[i].reg = srcReg[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BuildLayerRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea)
|
public static void BuildLayerRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea)
|
||||||
{
|
{
|
||||||
ctx.StartTimer("REGIONS");
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS);
|
||||||
|
|
||||||
int w = chf.width;
|
int w = chf.width;
|
||||||
int h = chf.height;
|
int h = chf.height;
|
||||||
|
@ -1930,21 +1921,19 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StartTimer("REGIONS_FILTER");
|
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||||
|
|
||||||
// Merge monotone regions to layers and remove small regions.
|
// Merge monotone regions to layers and remove small regions.
|
||||||
List<int> overlaps = new List<int>();
|
List<int> overlaps = new List<int>();
|
||||||
chf.maxRegions = MergeAndFilterLayerRegions(ctx, minRegionArea, id, chf, srcReg, overlaps);
|
chf.maxRegions = MergeAndFilterLayerRegions(ctx, minRegionArea, id, chf, srcReg, overlaps);
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS_FILTER");
|
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||||
|
|
||||||
// Store the result out.
|
// Store the result out.
|
||||||
for (int i = 0; i < chf.spanCount; ++i)
|
for (int i = 0; i < chf.spanCount; ++i)
|
||||||
{
|
{
|
||||||
chf.spans[i].reg = srcReg[i];
|
chf.spans[i].reg = srcReg[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StopTimer("REGIONS");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue