forked from bit/DotRecastNetSim
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>();
|
||||
}
|
||||
|
||||
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
|
||||
.GetOrAdd(name, _ => new RcAtomicLong(0))
|
||||
.AddAndGet(RcFrequency.Ticks - _timerStart.Value?[name].Read() ?? 0);
|
||||
.GetOrAdd(label.Name, _ => new RcAtomicLong(0))
|
||||
.AddAndGet(RcFrequency.Ticks - _timerStart.Value?[label.Name].Read() ?? 0);
|
||||
}
|
||||
|
||||
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 h = chf.height;
|
||||
ctx.StartTimer("ERODE_AREA");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_ERODE_AREA);
|
||||
|
||||
int[] dist = new int[chf.spanCount];
|
||||
Array.Fill(dist, 255);
|
||||
|
@ -205,8 +205,6 @@ namespace DotRecast.Recast
|
|||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
if (dist[i] < thr)
|
||||
chf.areas[i] = RC_NULL_AREA;
|
||||
|
||||
ctx.StopTimer("ERODE_AREA");
|
||||
}
|
||||
|
||||
/// @par
|
||||
|
@ -220,7 +218,7 @@ namespace DotRecast.Recast
|
|||
int w = chf.width;
|
||||
int h = chf.height;
|
||||
|
||||
ctx.StartTimer("MEDIAN_AREA");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MEDIAN_AREA);
|
||||
|
||||
int[] areas = new int[chf.spanCount];
|
||||
|
||||
|
@ -273,8 +271,6 @@ namespace DotRecast.Recast
|
|||
|
||||
chf.areas = areas;
|
||||
|
||||
ctx.StopTimer("MEDIAN_AREA");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -285,7 +281,7 @@ namespace DotRecast.Recast
|
|||
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
|
||||
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 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)
|
||||
|
@ -360,7 +354,7 @@ namespace DotRecast.Recast
|
|||
public static void MarkConvexPolyArea(RcTelemetry ctx, float[] verts, float hmin, float hmax, AreaModification areaMod,
|
||||
RcCompactHeightfield chf)
|
||||
{
|
||||
ctx.StartTimer("MARK_CONVEXPOLY_AREA");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||
|
||||
RcVec3f bmin = new RcVec3f();
|
||||
RcVec3f bmax = new RcVec3f();
|
||||
|
@ -426,8 +420,6 @@ namespace DotRecast.Recast
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.StopTimer("MARK_CONVEXPOLY_AREA");
|
||||
}
|
||||
|
||||
/// @par
|
||||
|
@ -437,7 +429,7 @@ namespace DotRecast.Recast
|
|||
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
|
||||
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 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,
|
||||
RcHeightfield hf)
|
||||
{
|
||||
ctx.StartTimer("BUILD_COMPACTHEIGHTFIELD");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
|
||||
|
||||
RcCompactHeightfield chf = new RcCompactHeightfield();
|
||||
int w = hf.width;
|
||||
|
@ -161,7 +161,6 @@ namespace DotRecast.Recast
|
|||
+ " (max: " + MAX_LAYERS + ")");
|
||||
}
|
||||
|
||||
ctx.StopTimer("BUILD_COMPACTHEIGHTFIELD");
|
||||
return chf;
|
||||
}
|
||||
|
||||
|
|
|
@ -722,7 +722,8 @@ namespace DotRecast.Recast
|
|||
int borderSize = chf.borderSize;
|
||||
RcContourSet cset = new RcContourSet();
|
||||
|
||||
ctx.StartTimer("CONTOURS");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS);
|
||||
|
||||
cset.bmin = chf.bmin;
|
||||
cset.bmax = chf.bmax;
|
||||
if (borderSize > 0)
|
||||
|
@ -744,7 +745,7 @@ namespace DotRecast.Recast
|
|||
|
||||
int[] flags = new int[chf.spanCount];
|
||||
|
||||
ctx.StartTimer("CONTOURS_TRACE");
|
||||
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_TRACE);
|
||||
|
||||
// Mark boundaries.
|
||||
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> simplified = new List<int>(64);
|
||||
|
@ -808,14 +809,14 @@ namespace DotRecast.Recast
|
|||
verts.Clear();
|
||||
simplified.Clear();
|
||||
|
||||
ctx.StartTimer("CONTOURS_WALK");
|
||||
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_WALK);
|
||||
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);
|
||||
RemoveDegenerateSegments(simplified);
|
||||
ctx.StopTimer("CONTOURS_SIMPLIFY");
|
||||
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
|
||||
|
||||
// Store region->contour remap info.
|
||||
// Create contour.
|
||||
|
@ -956,7 +957,6 @@ namespace DotRecast.Recast
|
|||
}
|
||||
}
|
||||
|
||||
ctx.StopTimer("CONTOURS");
|
||||
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)
|
||||
{
|
||||
ctx.StartTimer("RASTERIZE_SPHERE");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_SPHERE);
|
||||
float[] bounds =
|
||||
{
|
||||
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,
|
||||
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,
|
||||
RcTelemetry ctx)
|
||||
{
|
||||
ctx.StartTimer("RASTERIZE_CAPSULE");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CAPSULE);
|
||||
float[] bounds =
|
||||
{
|
||||
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);
|
||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||
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,
|
||||
RcTelemetry ctx)
|
||||
{
|
||||
ctx.StartTimer("RASTERIZE_CYLINDER");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CYLINDER);
|
||||
float[] bounds =
|
||||
{
|
||||
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);
|
||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||
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,
|
||||
RcTelemetry ctx)
|
||||
{
|
||||
ctx.StartTimer("RASTERIZE_BOX");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_BOX);
|
||||
RcVec3f[] normals =
|
||||
{
|
||||
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));
|
||||
ctx.StopTimer("RASTERIZE_BOX");
|
||||
}
|
||||
|
||||
public static void RasterizeConvex(RcHeightfield hf, float[] vertices, int[] triangles, int area, int flagMergeThr,
|
||||
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] };
|
||||
for (int i = 0; i < vertices.Length; i += 3)
|
||||
{
|
||||
|
@ -179,7 +175,6 @@ namespace DotRecast.Recast
|
|||
|
||||
RasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||
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)
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace DotRecast.Recast
|
|||
/// @see rcHeightfield, rcConfig
|
||||
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 h = solid.height;
|
||||
|
@ -71,8 +71,6 @@ namespace DotRecast.Recast
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.StopTimer("FILTER_LOW_OBSTACLES");
|
||||
}
|
||||
|
||||
/// @par
|
||||
|
@ -87,7 +85,7 @@ namespace DotRecast.Recast
|
|||
/// @see rcHeightfield, rcConfig
|
||||
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 h = solid.height;
|
||||
|
@ -168,8 +166,6 @@ namespace DotRecast.Recast
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.StopTimer("FILTER_LEDGE");
|
||||
}
|
||||
|
||||
/// @par
|
||||
|
@ -180,7 +176,7 @@ namespace DotRecast.Recast
|
|||
/// @see rcHeightfield, rcConfig
|
||||
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 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)
|
||||
{
|
||||
ctx.StartTimer("RC_TIMER_BUILD_LAYERS");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_LAYERS);
|
||||
|
||||
int w = chf.width;
|
||||
int h = chf.height;
|
||||
int borderSize = chf.borderSize;
|
||||
|
@ -397,7 +398,7 @@ namespace DotRecast.Recast
|
|||
// No layers, return empty.
|
||||
if (layerId == 0)
|
||||
{
|
||||
// ctx.StopTimer(RC_TIMER_BUILD_LAYERS);
|
||||
// ctx.Stop(RC_TIMER_BUILD_LAYERS);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -966,7 +966,8 @@ namespace DotRecast.Recast
|
|||
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
|
||||
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();
|
||||
mesh.bmin = cset.bmin;
|
||||
mesh.bmax = cset.bmax;
|
||||
|
@ -1204,7 +1205,6 @@ namespace DotRecast.Recast
|
|||
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
|
||||
}
|
||||
|
||||
ctx.StopTimer("POLYMESH");
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
@ -1214,7 +1214,8 @@ namespace DotRecast.Recast
|
|||
if (nmeshes == 0 || meshes == null)
|
||||
return null;
|
||||
|
||||
ctx.StartTimer("MERGE_POLYMESH");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_MERGE_POLYMESH);
|
||||
|
||||
RcPolyMesh mesh = new RcPolyMesh();
|
||||
mesh.nvp = meshes[0].nvp;
|
||||
mesh.cs = meshes[0].cs;
|
||||
|
@ -1333,8 +1334,6 @@ namespace DotRecast.Recast
|
|||
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
|
||||
}
|
||||
|
||||
ctx.StopTimer("MERGE_POLYMESH");
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -1426,7 +1426,7 @@ namespace DotRecast.Recast
|
|||
public static RcPolyMeshDetail BuildPolyMeshDetail(RcTelemetry ctx, RcPolyMesh mesh, RcCompactHeightfield chf,
|
||||
float sampleDist, float sampleMaxError)
|
||||
{
|
||||
ctx.StartTimer("POLYMESHDETAIL");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||
if (mesh.nverts == 0 || mesh.npolys == 0)
|
||||
{
|
||||
return null;
|
||||
|
@ -1610,16 +1610,15 @@ namespace DotRecast.Recast
|
|||
}
|
||||
}
|
||||
|
||||
ctx.StopTimer("POLYMESHDETAIL");
|
||||
return dmesh;
|
||||
}
|
||||
|
||||
/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail
|
||||
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 maxTris = 0;
|
||||
|
@ -1680,7 +1679,6 @@ namespace DotRecast.Recast
|
|||
}
|
||||
}
|
||||
|
||||
ctx.StopTimer("MERGE_POLYMESHDETAIL");
|
||||
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,
|
||||
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 inverseCellHeight = 1.0f / heightfield.ch;
|
||||
RasterizeTri(verts, v0, v1, v2, area, heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs, inverseCellSize,
|
||||
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,
|
||||
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 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,
|
||||
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,
|
||||
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 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,
|
||||
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
||||
}
|
||||
|
||||
ctx.StopTimer("RASTERIZE_TRIANGLES");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -580,7 +580,6 @@ namespace DotRecast.Recast
|
|||
}
|
||||
|
||||
|
||||
|
||||
private static void RemoveAdjacentNeighbours(RcRegion reg)
|
||||
{
|
||||
// Remove adjacent duplicates.
|
||||
|
@ -1418,16 +1417,16 @@ namespace DotRecast.Recast
|
|||
/// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone
|
||||
public static void BuildDistanceField(RcTelemetry ctx, RcCompactHeightfield chf)
|
||||
{
|
||||
ctx.StartTimer("DISTANCEFIELD");
|
||||
int[] src = new int[chf.spanCount];
|
||||
ctx.StartTimer("DISTANCEFIELD_DIST");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD);
|
||||
|
||||
int[] src = new int[chf.spanCount];
|
||||
|
||||
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
int maxDist = CalculateDistanceField(chf, src);
|
||||
chf.maxDistance = maxDist;
|
||||
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
|
||||
ctx.StopTimer("DISTANCEFIELD_DIST");
|
||||
|
||||
ctx.StartTimer("DISTANCEFIELD_BLUR");
|
||||
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
|
||||
// Blur
|
||||
src = BoxBlur(chf, 1, src);
|
||||
|
@ -1435,9 +1434,7 @@ namespace DotRecast.Recast
|
|||
// Store distance.
|
||||
chf.dist = src;
|
||||
|
||||
ctx.StopTimer("DISTANCEFIELD_BLUR");
|
||||
|
||||
ctx.StopTimer("DISTANCEFIELD");
|
||||
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
}
|
||||
|
||||
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,
|
||||
int mergeRegionArea)
|
||||
{
|
||||
ctx.StartTimer("REGIONS");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
int w = chf.width;
|
||||
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.
|
||||
List<int> overlaps = new List<int>();
|
||||
chf.maxRegions = MergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, id, chf, srcReg, overlaps);
|
||||
|
||||
// Monotone partitioning does not generate overlapping regions.
|
||||
|
||||
ctx.StopTimer("REGIONS_FILTER");
|
||||
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Store the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
{
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
}
|
||||
|
||||
ctx.StopTimer("REGIONS");
|
||||
}
|
||||
|
||||
/// @par
|
||||
|
@ -1665,13 +1658,13 @@ namespace DotRecast.Recast
|
|||
public static void BuildRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
|
||||
int mergeRegionArea)
|
||||
{
|
||||
ctx.StartTimer("REGIONS");
|
||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
int w = chf.width;
|
||||
int h = chf.height;
|
||||
int borderSize = chf.borderSize;
|
||||
|
||||
ctx.StartTimer("REGIONS_WATERSHED");
|
||||
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED);
|
||||
|
||||
int LOG_NB_STACKS = 3;
|
||||
int NB_STACKS = 1 << LOG_NB_STACKS;
|
||||
|
@ -1732,14 +1725,14 @@ namespace DotRecast.Recast
|
|||
|
||||
// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
List<int> overlaps = new List<int>();
|
||||
|
@ -1776,20 +1769,18 @@ namespace DotRecast.Recast
|
|||
ctx.Warn("rcBuildRegions: " + overlaps.Count + " overlapping regions.");
|
||||
}
|
||||
|
||||
ctx.StopTimer("REGIONS_FILTER");
|
||||
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Write the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
{
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
}
|
||||
|
||||
ctx.StopTimer("REGIONS");
|
||||
}
|
||||
|
||||
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 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.
|
||||
List<int> overlaps = new List<int>();
|
||||
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.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
{
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
}
|
||||
|
||||
ctx.StopTimer("REGIONS");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue