rename Telemetry -> RcTelemetry, add RcTelemetryTick

This commit is contained in:
ikpil 2023-07-01 12:50:25 +09:00
parent f2d2288283
commit 8bc3afa2ec
31 changed files with 105 additions and 81 deletions

View File

@ -29,6 +29,7 @@ namespace DotRecast.Detour.Crowd
public const int TIMING_SAMPLES = 10; public const int TIMING_SAMPLES = 10;
private float _maxTimeToEnqueueRequest; private float _maxTimeToEnqueueRequest;
private float _maxTimeToFindPath; private float _maxTimeToFindPath;
private readonly Dictionary<string, long> _executionTimings = new Dictionary<string, long>(); private readonly Dictionary<string, long> _executionTimings = new Dictionary<string, long>();
private readonly Dictionary<string, List<long>> _executionTimingSamples = new Dictionary<string, List<long>>(); private readonly Dictionary<string, List<long>> _executionTimingSamples = new Dictionary<string, List<long>>();

View File

@ -38,6 +38,6 @@ namespace DotRecast.Detour.Dynamic.Colliders
return _bounds; return _bounds;
} }
public abstract void Rasterize(RcHeightfield hf, Telemetry telemetry); public abstract void Rasterize(RcHeightfield hf, RcTelemetry telemetry);
} }
} }

View File

@ -60,7 +60,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
return bounds; return bounds;
} }
public override void Rasterize(RcHeightfield hf, Telemetry telemetry) public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
RecastFilledVolumeRasterization.RasterizeBox( RecastFilledVolumeRasterization.RasterizeBox(
hf, center, halfEdges, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); hf, center, halfEdges, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry);

View File

@ -36,7 +36,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
this.radius = radius; this.radius = radius;
} }
public override void Rasterize(RcHeightfield hf, Telemetry telemetry) public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
RecastFilledVolumeRasterization.RasterizeCapsule(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), RecastFilledVolumeRasterization.RasterizeCapsule(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch),
telemetry); telemetry);

View File

@ -66,7 +66,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
return bounds; return bounds;
} }
public void Rasterize(RcHeightfield hf, Telemetry telemetry) public void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
foreach (var c in colliders) foreach (var c in colliders)
c.Rasterize(hf, telemetry); c.Rasterize(hf, telemetry);

View File

@ -40,7 +40,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
this.triangles = triangles; this.triangles = triangles;
} }
public override void Rasterize(RcHeightfield hf, Telemetry telemetry) public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
RecastFilledVolumeRasterization.RasterizeConvex(hf, vertices, triangles, area, RecastFilledVolumeRasterization.RasterizeConvex(hf, vertices, triangles, area,
(int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry);

View File

@ -36,7 +36,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
this.radius = radius; this.radius = radius;
} }
public override void Rasterize(RcHeightfield hf, Telemetry telemetry) public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
RecastFilledVolumeRasterization.RasterizeCylinder(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), RecastFilledVolumeRasterization.RasterizeCylinder(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch),
telemetry); telemetry);

View File

@ -23,6 +23,6 @@ namespace DotRecast.Detour.Dynamic.Colliders
public interface ICollider public interface ICollider
{ {
float[] Bounds(); float[] Bounds();
void Rasterize(RcHeightfield hf, Telemetry telemetry); void Rasterize(RcHeightfield hf, RcTelemetry telemetry);
} }
} }

View File

@ -34,7 +34,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
this.radius = radius; this.radius = radius;
} }
public override void Rasterize(RcHeightfield hf, Telemetry telemetry) public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
RecastFilledVolumeRasterization.RasterizeSphere(hf, center, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), RecastFilledVolumeRasterization.RasterizeSphere(hf, center, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch),
telemetry); telemetry);

View File

@ -56,7 +56,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
return bounds; return bounds;
} }
public override void Rasterize(RcHeightfield hf, Telemetry telemetry) public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry)
{ {
for (int i = 0; i < triangles.Length; i += 3) for (int i = 0; i < triangles.Length; i += 3)
{ {

View File

@ -35,7 +35,7 @@ namespace DotRecast.Detour.Dynamic
public readonly DynamicNavMeshConfig config; public readonly DynamicNavMeshConfig config;
private readonly RecastBuilder builder; private readonly RecastBuilder builder;
private readonly Dictionary<long, DynamicTile> _tiles = new Dictionary<long, DynamicTile>(); private readonly Dictionary<long, DynamicTile> _tiles = new Dictionary<long, DynamicTile>();
private readonly Telemetry telemetry; private readonly RcTelemetry telemetry;
private readonly DtNavMeshParams navMeshParams; private readonly DtNavMeshParams navMeshParams;
private readonly BlockingCollection<IUpdateQueueItem> updateQueue = new BlockingCollection<IUpdateQueueItem>(); private readonly BlockingCollection<IUpdateQueueItem> updateQueue = new BlockingCollection<IUpdateQueueItem>();
private readonly RcAtomicLong currentColliderId = new RcAtomicLong(0); private readonly RcAtomicLong currentColliderId = new RcAtomicLong(0);
@ -72,7 +72,7 @@ namespace DotRecast.Detour.Dynamic
} }
; ;
telemetry = new Telemetry(); telemetry = new RcTelemetry();
} }
public DtNavMesh NavMesh() public DtNavMesh NavMesh()

View File

@ -42,7 +42,7 @@ namespace DotRecast.Detour.Dynamic
this.voxelTile = voxelTile; this.voxelTile = voxelTile;
} }
public bool Build(RecastBuilder builder, DynamicNavMeshConfig config, Telemetry telemetry) public bool Build(RecastBuilder builder, DynamicNavMeshConfig config, RcTelemetry telemetry)
{ {
if (dirty) if (dirty)
{ {
@ -57,7 +57,7 @@ namespace DotRecast.Detour.Dynamic
return false; return false;
} }
private RcHeightfield BuildHeightfield(DynamicNavMeshConfig config, Telemetry telemetry) private RcHeightfield BuildHeightfield(DynamicNavMeshConfig config, RcTelemetry telemetry)
{ {
ICollection<long> rasterizedColliders = checkpoint != null ? checkpoint.colliders : ImmutableHashSet<long>.Empty; ICollection<long> rasterizedColliders = checkpoint != null ? checkpoint.colliders : ImmutableHashSet<long>.Empty;
RcHeightfield heightfield = checkpoint != null ? checkpoint.heightfield : voxelTile.Heightfield(); RcHeightfield heightfield = checkpoint != null ? checkpoint.heightfield : voxelTile.Heightfield();
@ -79,7 +79,7 @@ namespace DotRecast.Detour.Dynamic
} }
private RecastBuilderResult BuildRecast(RecastBuilder builder, DynamicNavMeshConfig config, VoxelTile vt, private RecastBuilderResult BuildRecast(RecastBuilder builder, DynamicNavMeshConfig config, VoxelTile vt,
RcHeightfield heightfield, Telemetry telemetry) RcHeightfield heightfield, RcTelemetry telemetry)
{ {
RcConfig rcConfig = new RcConfig(config.useTiles, config.tileSizeX, config.tileSizeZ, vt.borderSize, RcConfig rcConfig = new RcConfig(config.useTiles, config.tileSizeX, config.tileSizeZ, vt.borderSize,
config.partitionType, vt.cellSize, vt.cellHeight, config.walkableSlopeAngle, true, true, true, config.partitionType, vt.cellSize, vt.cellHeight, config.walkableSlopeAngle, true, true, true,

View File

@ -611,8 +611,8 @@ public class RecastDemo
var telemetries = buildResult.RecastBuilderResults var telemetries = buildResult.RecastBuilderResults
.Select(x => x.GetTelemetry()) .Select(x => x.GetTelemetry())
.SelectMany(x => x.ToList()) .SelectMany(x => x.ToList())
.GroupBy(x => x.Item1) .GroupBy(x => x.Key)
.ToImmutableSortedDictionary(x => x.Key, x => x.Sum(y => y.Item2)); .ToImmutableSortedDictionary(x => x.Key, x => x.Sum(y => y.Millis));
foreach (var (key, millis) in telemetries) foreach (var (key, millis) in telemetries)
{ {

View File

@ -26,32 +26,38 @@ using DotRecast.Core;
namespace DotRecast.Recast namespace DotRecast.Recast
{ {
public class Telemetry public class RcTelemetry
{ {
private readonly ThreadLocal<Dictionary<string, RcAtomicLong>> timerStart = new ThreadLocal<Dictionary<string, RcAtomicLong>>(() => new Dictionary<string, RcAtomicLong>()); private readonly ThreadLocal<Dictionary<string, RcAtomicLong>> _timerStart;
private readonly ConcurrentDictionary<string, RcAtomicLong> timerAccum = new ConcurrentDictionary<string, RcAtomicLong>(); private readonly ConcurrentDictionary<string, RcAtomicLong> _timerAccum;
public RcTelemetry()
{
_timerStart = new ThreadLocal<Dictionary<string, RcAtomicLong>>(() => new Dictionary<string, RcAtomicLong>());
_timerAccum = new ConcurrentDictionary<string, RcAtomicLong>();
}
public void StartTimer(string name) public void StartTimer(string name)
{ {
timerStart.Value[name] = new RcAtomicLong(RcFrequency.Ticks); _timerStart.Value[name] = new RcAtomicLong(RcFrequency.Ticks);
} }
public void StopTimer(string name) public void StopTimer(string name)
{ {
timerAccum _timerAccum
.GetOrAdd(name, _ => new RcAtomicLong(0)) .GetOrAdd(name, _ => new RcAtomicLong(0))
.AddAndGet(RcFrequency.Ticks - timerStart.Value?[name].Read() ?? 0); .AddAndGet(RcFrequency.Ticks - _timerStart.Value?[name].Read() ?? 0);
} }
public void Warn(string @string) public void Warn(string message)
{ {
Console.WriteLine(@string); Console.WriteLine(message);
} }
public List<Tuple<string, long>> ToList() public List<RcTelemetryTick> ToList()
{ {
return timerAccum return _timerAccum
.Select(x => Tuple.Create(x.Key, x.Value.Read() / TimeSpan.TicksPerMillisecond)) .Select(x => new RcTelemetryTick(x.Key, x.Value.Read()))
.ToList(); .ToList();
} }
} }

View File

@ -0,0 +1,17 @@
using System;
namespace DotRecast.Recast
{
public readonly struct RcTelemetryTick
{
public readonly string Key;
public readonly long Ticks;
public long Millis => Ticks / TimeSpan.TicksPerMillisecond;
public RcTelemetryTick(string key, long ticks)
{
Key = key;
Ticks = ticks;
}
}
}

View File

@ -67,7 +67,7 @@ namespace DotRecast.Recast
/// See the #rcConfig documentation for more information on the configuration parameters. /// See the #rcConfig documentation for more information on the configuration parameters.
/// ///
/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles /// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles
public static int[] MarkWalkableTriangles(Telemetry ctx, float walkableSlopeAngle, float[] verts, int[] tris, int nt, AreaModification areaMod) public static int[] MarkWalkableTriangles(RcTelemetry ctx, float walkableSlopeAngle, float[] verts, int[] tris, int nt, AreaModification areaMod)
{ {
int[] areas = new int[nt]; int[] areas = new int[nt];
float walkableThr = (float)Math.Cos(walkableSlopeAngle / 180.0f * Math.PI); float walkableThr = (float)Math.Cos(walkableSlopeAngle / 180.0f * Math.PI);
@ -103,7 +103,7 @@ namespace DotRecast.Recast
/// See the #rcConfig documentation for more information on the configuration parameters. /// See the #rcConfig documentation for more information on the configuration parameters.
/// ///
/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles /// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles
public static void ClearUnwalkableTriangles(Telemetry ctx, float walkableSlopeAngle, float[] verts, int nv, int[] tris, int nt, int[] areas) public static void ClearUnwalkableTriangles(RcTelemetry ctx, float walkableSlopeAngle, float[] verts, int nv, int[] tris, int nt, int[] areas)
{ {
float walkableThr = (float)Math.Cos(walkableSlopeAngle / 180.0f * Math.PI); float walkableThr = (float)Math.Cos(walkableSlopeAngle / 180.0f * Math.PI);

View File

@ -35,7 +35,7 @@ namespace DotRecast.Recast
/// This method is usually called immediately after the heightfield has been built. /// This method is usually called immediately after the heightfield has been built.
/// ///
/// @see rcCompactHeightfield, rcBuildCompactHeightfield, rcConfig::walkableRadius /// @see rcCompactHeightfield, rcBuildCompactHeightfield, rcConfig::walkableRadius
public static void ErodeWalkableArea(Telemetry ctx, int radius, RcCompactHeightfield chf) public static void ErodeWalkableArea(RcTelemetry ctx, int radius, RcCompactHeightfield chf)
{ {
int w = chf.width; int w = chf.width;
int h = chf.height; int h = chf.height;
@ -215,7 +215,7 @@ namespace DotRecast.Recast
/// such as #rcMarkBoxArea, #rcMarkConvexPolyArea, and #rcMarkCylinderArea. /// such as #rcMarkBoxArea, #rcMarkConvexPolyArea, and #rcMarkCylinderArea.
/// ///
/// @see rcCompactHeightfield /// @see rcCompactHeightfield
public static bool MedianFilterWalkableArea(Telemetry ctx, RcCompactHeightfield chf) public static bool MedianFilterWalkableArea(RcTelemetry ctx, RcCompactHeightfield chf)
{ {
int w = chf.width; int w = chf.width;
int h = chf.height; int h = chf.height;
@ -283,7 +283,7 @@ namespace DotRecast.Recast
/// The value of spacial parameters are in world units. /// The value of spacial parameters are in world units.
/// ///
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea /// @see rcCompactHeightfield, rcMedianFilterWalkableArea
public static void MarkBoxArea(Telemetry 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"); ctx.StartTimer("MARK_BOX_AREA");
@ -357,7 +357,7 @@ namespace DotRecast.Recast
/// projected onto the xz-plane at @p hmin, then extruded to @p hmax. /// projected onto the xz-plane at @p hmin, then extruded to @p hmax.
/// ///
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea /// @see rcCompactHeightfield, rcMedianFilterWalkableArea
public static void MarkConvexPolyArea(Telemetry 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"); ctx.StartTimer("MARK_CONVEXPOLY_AREA");
@ -513,7 +513,7 @@ namespace DotRecast.Recast
/// The value of spacial parameters are in world units. /// The value of spacial parameters are in world units.
/// ///
/// @see rcCompactHeightfield, rcMedianFilterWalkableArea /// @see rcCompactHeightfield, rcMedianFilterWalkableArea
public static void MarkCylinderArea(Telemetry 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"); ctx.StartTimer("MARK_CYLINDER_AREA");

View File

@ -158,7 +158,7 @@ namespace DotRecast.Recast
public RecastBuilderResult Build(IInputGeomProvider geom, RecastBuilderConfig builderCfg) public RecastBuilderResult Build(IInputGeomProvider geom, RecastBuilderConfig builderCfg)
{ {
RcConfig cfg = builderCfg.cfg; RcConfig cfg = builderCfg.cfg;
Telemetry ctx = new Telemetry(); RcTelemetry ctx = new RcTelemetry();
// //
// Step 1. Rasterize input polygon soup. // Step 1. Rasterize input polygon soup.
// //
@ -167,7 +167,7 @@ namespace DotRecast.Recast
} }
public RecastBuilderResult Build(int tileX, int tileZ, IConvexVolumeProvider geom, RcConfig cfg, RcHeightfield solid, public RecastBuilderResult Build(int tileX, int tileZ, IConvexVolumeProvider geom, RcConfig cfg, RcHeightfield solid,
Telemetry ctx) RcTelemetry ctx)
{ {
FilterHeightfield(solid, cfg, ctx); FilterHeightfield(solid, cfg, ctx);
RcCompactHeightfield chf = BuildCompactHeightfield(geom, cfg, ctx, solid); RcCompactHeightfield chf = BuildCompactHeightfield(geom, cfg, ctx, solid);
@ -257,7 +257,7 @@ namespace DotRecast.Recast
/* /*
* Step 2. Filter walkable surfaces. * Step 2. Filter walkable surfaces.
*/ */
private void FilterHeightfield(RcHeightfield solid, RcConfig cfg, Telemetry ctx) private void FilterHeightfield(RcHeightfield solid, RcConfig cfg, RcTelemetry ctx)
{ {
// Once all geometry is rasterized, we do initial pass of filtering to // Once all geometry is rasterized, we do initial pass of filtering to
// remove unwanted overhangs caused by the conservative rasterization // remove unwanted overhangs caused by the conservative rasterization
@ -281,7 +281,7 @@ namespace DotRecast.Recast
/* /*
* Step 3. Partition walkable surface to simple regions. * Step 3. Partition walkable surface to simple regions.
*/ */
private RcCompactHeightfield BuildCompactHeightfield(IConvexVolumeProvider volumeProvider, RcConfig cfg, Telemetry ctx, private RcCompactHeightfield BuildCompactHeightfield(IConvexVolumeProvider volumeProvider, RcConfig cfg, RcTelemetry ctx,
RcHeightfield solid) RcHeightfield solid)
{ {
// Compact the heightfield so that it is faster to handle from now on. // Compact the heightfield so that it is faster to handle from now on.
@ -305,7 +305,7 @@ namespace DotRecast.Recast
public RcHeightfieldLayerSet BuildLayers(IInputGeomProvider geom, RecastBuilderConfig builderCfg) public RcHeightfieldLayerSet BuildLayers(IInputGeomProvider geom, RecastBuilderConfig builderCfg)
{ {
Telemetry ctx = new Telemetry(); RcTelemetry ctx = new RcTelemetry();
RcHeightfield solid = RecastVoxelization.BuildSolidHeightfield(geom, builderCfg, ctx); RcHeightfield solid = RecastVoxelization.BuildSolidHeightfield(geom, builderCfg, ctx);
FilterHeightfield(solid, builderCfg.cfg, ctx); FilterHeightfield(solid, builderCfg.cfg, ctx);
RcCompactHeightfield chf = BuildCompactHeightfield(geom, builderCfg.cfg, ctx, solid); RcCompactHeightfield chf = BuildCompactHeightfield(geom, builderCfg.cfg, ctx, solid);

View File

@ -9,9 +9,9 @@
private readonly RcPolyMesh pmesh; private readonly RcPolyMesh pmesh;
private readonly RcPolyMeshDetail dmesh; private readonly RcPolyMeshDetail dmesh;
private readonly RcHeightfield solid; private readonly RcHeightfield solid;
private readonly Telemetry telemetry; private readonly RcTelemetry telemetry;
public RecastBuilderResult(int tileX, int tileZ, RcHeightfield solid, RcCompactHeightfield chf, RcContourSet cs, RcPolyMesh pmesh, RcPolyMeshDetail dmesh, Telemetry ctx) public RecastBuilderResult(int tileX, int tileZ, RcHeightfield solid, RcCompactHeightfield chf, RcContourSet cs, RcPolyMesh pmesh, RcPolyMeshDetail dmesh, RcTelemetry ctx)
{ {
this.tileX = tileX; this.tileX = tileX;
this.tileZ = tileZ; this.tileZ = tileZ;
@ -48,7 +48,7 @@
return solid; return solid;
} }
public Telemetry GetTelemetry() public RcTelemetry GetTelemetry()
{ {
return telemetry; return telemetry;
} }

View File

@ -37,7 +37,7 @@ namespace DotRecast.Recast
/// See the #rcConfig documentation for more information on the configuration parameters. /// See the #rcConfig documentation for more information on the configuration parameters.
/// ///
/// @see rcAllocCompactHeightfield, rcHeightfield, rcCompactHeightfield, rcConfig /// @see rcAllocCompactHeightfield, rcHeightfield, rcCompactHeightfield, rcConfig
public static RcCompactHeightfield BuildCompactHeightfield(Telemetry ctx, int walkableHeight, int walkableClimb, public static RcCompactHeightfield BuildCompactHeightfield(RcTelemetry ctx, int walkableHeight, int walkableClimb,
RcHeightfield hf) RcHeightfield hf)
{ {
ctx.StartTimer("BUILD_COMPACTHEIGHTFIELD"); ctx.StartTimer("BUILD_COMPACTHEIGHTFIELD");

View File

@ -607,7 +607,7 @@ namespace DotRecast.Recast
return new int[] { minx, minz, leftmost }; return new int[] { minx, minz, leftmost };
} }
private static void MergeRegionHoles(Telemetry ctx, RcContourRegion region) private static void MergeRegionHoles(RcTelemetry ctx, RcContourRegion region)
{ {
// Sort holes from left to right. // Sort holes from left to right.
for (int i = 0; i < region.nholes; i++) for (int i = 0; i < region.nholes; i++)
@ -713,7 +713,7 @@ namespace DotRecast.Recast
/// See the #rcConfig documentation for more information on the configuration parameters. /// See the #rcConfig documentation for more information on the configuration parameters.
/// ///
/// @see rcAllocContourSet, rcCompactHeightfield, rcContourSet, rcConfig /// @see rcAllocContourSet, rcCompactHeightfield, rcContourSet, rcConfig
public static RcContourSet BuildContours(Telemetry ctx, RcCompactHeightfield chf, float maxError, int maxEdgeLen, public static RcContourSet BuildContours(RcTelemetry ctx, RcCompactHeightfield chf, float maxError, int maxEdgeLen,
int buildFlags) int buildFlags)
{ {
int w = chf.width; int w = chf.width;

View File

@ -29,7 +29,7 @@ namespace DotRecast.Recast
private const float EPSILON = 0.00001f; private const float EPSILON = 0.00001f;
private static readonly int[] BOX_EDGES = new[] { 0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7 }; private static readonly int[] BOX_EDGES = new[] { 0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7 };
public static void RasterizeSphere(RcHeightfield hf, RcVec3f center, float radius, int area, int flagMergeThr, Telemetry ctx) public static void RasterizeSphere(RcHeightfield hf, RcVec3f center, float radius, int area, int flagMergeThr, RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_SPHERE"); ctx.StartTimer("RASTERIZE_SPHERE");
float[] bounds = float[] bounds =
@ -43,7 +43,7 @@ namespace DotRecast.Recast
} }
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,
Telemetry ctx) RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_CAPSULE"); ctx.StartTimer("RASTERIZE_CAPSULE");
float[] bounds = float[] bounds =
@ -59,7 +59,7 @@ namespace DotRecast.Recast
} }
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,
Telemetry ctx) RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_CYLINDER"); ctx.StartTimer("RASTERIZE_CYLINDER");
float[] bounds = float[] bounds =
@ -75,7 +75,7 @@ namespace DotRecast.Recast
} }
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,
Telemetry ctx) RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_BOX"); ctx.StartTimer("RASTERIZE_BOX");
RcVec3f[] normals = RcVec3f[] normals =
@ -127,7 +127,7 @@ namespace DotRecast.Recast
} }
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,
Telemetry ctx) RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_CONVEX"); ctx.StartTimer("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] };

View File

@ -37,7 +37,7 @@ namespace DotRecast.Recast
/// #rcFilterLedgeSpans after calling this filter. /// #rcFilterLedgeSpans after calling this filter.
/// ///
/// @see rcHeightfield, rcConfig /// @see rcHeightfield, rcConfig
public static void FilterLowHangingWalkableObstacles(Telemetry ctx, int walkableClimb, RcHeightfield solid) public static void FilterLowHangingWalkableObstacles(RcTelemetry ctx, int walkableClimb, RcHeightfield solid)
{ {
ctx.StartTimer("FILTER_LOW_OBSTACLES"); ctx.StartTimer("FILTER_LOW_OBSTACLES");
@ -84,7 +84,7 @@ namespace DotRecast.Recast
/// A span is a ledge if: <tt>RcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb</tt> /// A span is a ledge if: <tt>RcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb</tt>
/// ///
/// @see rcHeightfield, rcConfig /// @see rcHeightfield, rcConfig
public static void FilterLedgeSpans(Telemetry ctx, int walkableHeight, int walkableClimb, RcHeightfield solid) public static void FilterLedgeSpans(RcTelemetry ctx, int walkableHeight, int walkableClimb, RcHeightfield solid)
{ {
ctx.StartTimer("FILTER_LEDGE"); ctx.StartTimer("FILTER_LEDGE");
@ -177,7 +177,7 @@ namespace DotRecast.Recast
/// maximum to the next higher span's minimum. (Same grid column.) /// maximum to the next higher span's minimum. (Same grid column.)
/// ///
/// @see rcHeightfield, rcConfig /// @see rcHeightfield, rcConfig
public static void FilterWalkableLowHeightSpans(Telemetry ctx, int walkableHeight, RcHeightfield solid) public static void FilterWalkableLowHeightSpans(RcTelemetry ctx, int walkableHeight, RcHeightfield solid)
{ {
ctx.StartTimer("FILTER_WALKABLE"); ctx.StartTimer("FILTER_WALKABLE");

View File

@ -51,7 +51,7 @@ namespace DotRecast.Recast
return (amin > bmax || amax < bmin) ? false : true; return (amin > bmax || amax < bmin) ? false : true;
} }
public static RcHeightfieldLayerSet BuildHeightfieldLayers(Telemetry ctx, RcCompactHeightfield chf, int walkableHeight) public static RcHeightfieldLayerSet BuildHeightfieldLayers(RcTelemetry ctx, RcCompactHeightfield chf, int walkableHeight)
{ {
ctx.StartTimer("RC_TIMER_BUILD_LAYERS"); ctx.StartTimer("RC_TIMER_BUILD_LAYERS");
int w = chf.width; int w = chf.width;

View File

@ -574,7 +574,7 @@ namespace DotRecast.Recast
return an; return an;
} }
private static bool CanRemoveVertex(Telemetry ctx, RcPolyMesh mesh, int rem) private static bool CanRemoveVertex(RcTelemetry ctx, RcPolyMesh mesh, int rem)
{ {
int nvp = mesh.nvp; int nvp = mesh.nvp;
@ -677,7 +677,7 @@ namespace DotRecast.Recast
return true; return true;
} }
private static void RemoveVertex(Telemetry ctx, RcPolyMesh mesh, int rem, int maxTris) private static void RemoveVertex(RcTelemetry ctx, RcPolyMesh mesh, int rem, int maxTris)
{ {
int nvp = mesh.nvp; int nvp = mesh.nvp;
@ -964,7 +964,7 @@ namespace DotRecast.Recast
/// limit must be retricted to <= #DT_VERTS_PER_POLYGON. /// limit must be retricted to <= #DT_VERTS_PER_POLYGON.
/// ///
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig /// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
public static RcPolyMesh BuildPolyMesh(Telemetry ctx, RcContourSet cset, int nvp) public static RcPolyMesh BuildPolyMesh(RcTelemetry ctx, RcContourSet cset, int nvp)
{ {
ctx.StartTimer("POLYMESH"); ctx.StartTimer("POLYMESH");
RcPolyMesh mesh = new RcPolyMesh(); RcPolyMesh mesh = new RcPolyMesh();
@ -1209,7 +1209,7 @@ namespace DotRecast.Recast
} }
/// @see rcAllocPolyMesh, rcPolyMesh /// @see rcAllocPolyMesh, rcPolyMesh
public static RcPolyMesh MergePolyMeshes(Telemetry ctx, RcPolyMesh[] meshes, int nmeshes) public static RcPolyMesh MergePolyMeshes(RcTelemetry ctx, RcPolyMesh[] meshes, int nmeshes)
{ {
if (nmeshes == 0 || meshes == null) if (nmeshes == 0 || meshes == null)
return null; return null;
@ -1338,7 +1338,7 @@ namespace DotRecast.Recast
return mesh; return mesh;
} }
public static RcPolyMesh CopyPolyMesh(Telemetry ctx, RcPolyMesh src) public static RcPolyMesh CopyPolyMesh(RcTelemetry ctx, RcPolyMesh src)
{ {
RcPolyMesh dst = new RcPolyMesh(); RcPolyMesh dst = new RcPolyMesh();

View File

@ -442,7 +442,7 @@ namespace DotRecast.Recast
return EV_UNDEF; return EV_UNDEF;
} }
private static void AddEdge(Telemetry ctx, List<int> edges, int maxEdges, int s, int t, int l, int r) private static void AddEdge(RcTelemetry ctx, List<int> edges, int maxEdges, int s, int t, int l, int r)
{ {
if (edges.Count / 4 >= maxEdges) if (edges.Count / 4 >= maxEdges)
{ {
@ -510,7 +510,7 @@ namespace DotRecast.Recast
return false; return false;
} }
static int CompleteFacet(Telemetry ctx, float[] pts, int npts, List<int> edges, int maxEdges, int nfaces, int e) static int CompleteFacet(RcTelemetry ctx, float[] pts, int npts, List<int> edges, int maxEdges, int nfaces, int e)
{ {
const float EPS = 1e-5f; const float EPS = 1e-5f;
@ -627,7 +627,7 @@ namespace DotRecast.Recast
return nfaces; return nfaces;
} }
private static void DelaunayHull(Telemetry ctx, int npts, float[] pts, int nhull, int[] hull, List<int> tris) private static void DelaunayHull(RcTelemetry ctx, int npts, float[] pts, int nhull, int[] hull, List<int> tris)
{ {
int nfaces = 0; int nfaces = 0;
int maxEdges = npts * 10; int maxEdges = npts * 10;
@ -831,7 +831,7 @@ namespace DotRecast.Recast
return (((i * 0xd8163841) & 0xffff) / 65535.0f * 2.0f) - 1.0f; return (((i * 0xd8163841) & 0xffff) / 65535.0f * 2.0f) - 1.0f;
} }
static int BuildPolyDetail(Telemetry ctx, float[] @in, int nin, float sampleDist, float sampleMaxError, static int BuildPolyDetail(RcTelemetry ctx, float[] @in, int nin, float sampleDist, float sampleMaxError,
int heightSearchRadius, RcCompactHeightfield chf, RcHeightPatch hp, float[] verts, List<int> tris) int heightSearchRadius, RcCompactHeightfield chf, RcHeightPatch hp, float[] verts, List<int> tris)
{ {
List<int> samples = new List<int>(512); List<int> samples = new List<int>(512);
@ -1113,7 +1113,7 @@ namespace DotRecast.Recast
return nverts; return nverts;
} }
static void SeedArrayWithPolyCenter(Telemetry ctx, RcCompactHeightfield chf, int[] meshpoly, int poly, int npoly, static void SeedArrayWithPolyCenter(RcTelemetry ctx, RcCompactHeightfield chf, int[] meshpoly, int poly, int npoly,
int[] verts, int bs, RcHeightPatch hp, List<int> array) int[] verts, int bs, RcHeightPatch hp, List<int> array)
{ {
// Note: Reads to the compact heightfield are offset by border size (bs) // Note: Reads to the compact heightfield are offset by border size (bs)
@ -1271,7 +1271,7 @@ namespace DotRecast.Recast
queue.Add(v3); queue.Add(v3);
} }
static void GetHeightData(Telemetry ctx, RcCompactHeightfield chf, int[] meshpolys, int poly, int npoly, int[] verts, static void GetHeightData(RcTelemetry ctx, RcCompactHeightfield chf, int[] meshpolys, int poly, int npoly, int[] verts,
int bs, RcHeightPatch hp, int region) int bs, RcHeightPatch hp, int region)
{ {
// Note: Reads to the compact heightfield are offset by border size (bs) // Note: Reads to the compact heightfield are offset by border size (bs)
@ -1423,7 +1423,7 @@ namespace DotRecast.Recast
/// See the #rcConfig documentation for more information on the configuration parameters. /// See the #rcConfig documentation for more information on the configuration parameters.
/// ///
/// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig /// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig
public static RcPolyMeshDetail BuildPolyMeshDetail(Telemetry 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"); ctx.StartTimer("POLYMESHDETAIL");
@ -1615,7 +1615,7 @@ namespace DotRecast.Recast
} }
/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail /// @see rcAllocPolyMeshDetail, rcPolyMeshDetail
private static RcPolyMeshDetail MergePolyMeshDetails(Telemetry ctx, RcPolyMeshDetail[] meshes, int nmeshes) private static RcPolyMeshDetail MergePolyMeshDetails(RcTelemetry ctx, RcPolyMeshDetail[] meshes, int nmeshes)
{ {
RcPolyMeshDetail mesh = new RcPolyMeshDetail(); RcPolyMeshDetail mesh = new RcPolyMeshDetail();

View File

@ -398,7 +398,7 @@ namespace DotRecast.Recast
* @see Heightfield * @see Heightfield
*/ */
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, Telemetry ctx) int flagMergeThreshold, RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_TRIANGLES"); ctx.StartTimer("RASTERIZE_TRIANGLES");
@ -429,7 +429,7 @@ namespace DotRecast.Recast
* @see Heightfield * @see Heightfield
*/ */
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, Telemetry ctx) int flagMergeThreshold, RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_TRIANGLES"); ctx.StartTimer("RASTERIZE_TRIANGLES");
@ -466,7 +466,7 @@ namespace DotRecast.Recast
* @see Heightfield * @see Heightfield
*/ */
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, Telemetry ctx) int flagMergeThreshold, RcTelemetry ctx)
{ {
ctx.StartTimer("RASTERIZE_TRIANGLES"); ctx.StartTimer("RASTERIZE_TRIANGLES");

View File

@ -847,7 +847,7 @@ namespace DotRecast.Recast
} }
} }
private static int MergeAndFilterRegions(Telemetry ctx, int minRegionArea, int mergeRegionSize, int maxRegionId, private static int MergeAndFilterRegions(RcTelemetry ctx, int minRegionArea, int mergeRegionSize, int maxRegionId,
RcCompactHeightfield chf, int[] srcReg, List<int> overlaps) RcCompactHeightfield chf, int[] srcReg, List<int> overlaps)
{ {
int w = chf.width; int w = chf.width;
@ -1169,7 +1169,7 @@ namespace DotRecast.Recast
} }
} }
private static int MergeAndFilterLayerRegions(Telemetry ctx, int minRegionArea, int maxRegionId, private static int MergeAndFilterLayerRegions(RcTelemetry ctx, int minRegionArea, int maxRegionId,
RcCompactHeightfield chf, int[] srcReg, List<int> overlaps) RcCompactHeightfield chf, int[] srcReg, List<int> overlaps)
{ {
int w = chf.width; int w = chf.width;
@ -1415,7 +1415,7 @@ namespace DotRecast.Recast
/// and rcCompactHeightfield::dist fields. /// and rcCompactHeightfield::dist fields.
/// ///
/// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone /// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone
public static void BuildDistanceField(Telemetry ctx, RcCompactHeightfield chf) public static void BuildDistanceField(RcTelemetry ctx, RcCompactHeightfield chf)
{ {
ctx.StartTimer("DISTANCEFIELD"); ctx.StartTimer("DISTANCEFIELD");
int[] src = new int[chf.spanCount]; int[] src = new int[chf.spanCount];
@ -1478,7 +1478,7 @@ namespace DotRecast.Recast
/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. /// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions.
/// ///
/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig /// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig
public static void BuildRegionsMonotone(Telemetry ctx, RcCompactHeightfield chf, int minRegionArea, public static void BuildRegionsMonotone(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
int mergeRegionArea) int mergeRegionArea)
{ {
ctx.StartTimer("REGIONS"); ctx.StartTimer("REGIONS");
@ -1661,7 +1661,7 @@ namespace DotRecast.Recast
/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. /// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions.
/// ///
/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig /// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig
public static void BuildRegions(Telemetry ctx, RcCompactHeightfield chf, int minRegionArea, public static void BuildRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea,
int mergeRegionArea) int mergeRegionArea)
{ {
ctx.StartTimer("REGIONS"); ctx.StartTimer("REGIONS");
@ -1786,7 +1786,7 @@ namespace DotRecast.Recast
ctx.StopTimer("REGIONS"); ctx.StopTimer("REGIONS");
} }
public static void BuildLayerRegions(Telemetry ctx, RcCompactHeightfield chf, int minRegionArea) public static void BuildLayerRegions(RcTelemetry ctx, RcCompactHeightfield chf, int minRegionArea)
{ {
ctx.StartTimer("REGIONS"); ctx.StartTimer("REGIONS");

View File

@ -23,7 +23,7 @@ namespace DotRecast.Recast
{ {
public static class RecastVoxelization public static class RecastVoxelization
{ {
public static RcHeightfield BuildSolidHeightfield(IInputGeomProvider geomProvider, RecastBuilderConfig builderCfg, Telemetry ctx) public static RcHeightfield BuildSolidHeightfield(IInputGeomProvider geomProvider, RecastBuilderConfig builderCfg, RcTelemetry ctx)
{ {
RcConfig cfg = builderCfg.cfg; RcConfig cfg = builderCfg.cfg;

View File

@ -100,7 +100,7 @@ public class RecastSoloMeshTest
long time = RcFrequency.Ticks; long time = RcFrequency.Ticks;
RcVec3f bmin = geomProvider.GetMeshBoundsMin(); RcVec3f bmin = geomProvider.GetMeshBoundsMin();
RcVec3f bmax = geomProvider.GetMeshBoundsMax(); RcVec3f bmax = geomProvider.GetMeshBoundsMax();
Telemetry m_ctx = new Telemetry(); RcTelemetry m_ctx = new RcTelemetry();
// //
// Step 1. Initialize build config. // Step 1. Initialize build config.
// //
@ -262,9 +262,9 @@ public class RecastSoloMeshTest
Console.WriteLine(" " + (time3 - time) / TimeSpan.TicksPerMillisecond + " ms"); Console.WriteLine(" " + (time3 - time) / TimeSpan.TicksPerMillisecond + " ms");
SaveObj(filename.Substring(0, filename.LastIndexOf('.')) + "_" + partitionType + "_detail.obj", m_dmesh); SaveObj(filename.Substring(0, filename.LastIndexOf('.')) + "_" + partitionType + "_detail.obj", m_dmesh);
SaveObj(filename.Substring(0, filename.LastIndexOf('.')) + "_" + partitionType + ".obj", m_pmesh); SaveObj(filename.Substring(0, filename.LastIndexOf('.')) + "_" + partitionType + ".obj", m_pmesh);
foreach (var (key, millis) in m_ctx.ToList()) foreach (var rtt in m_ctx.ToList())
{ {
Console.WriteLine($"{key} : {millis} ms"); Console.WriteLine($"{rtt.Key} : {rtt.Millis} ms");
} }
} }

View File

@ -35,7 +35,7 @@ public class RecastTest
int[] unwalkable_tri = { 0, 2, 1 }; int[] unwalkable_tri = { 0, 2, 1 };
int nt = 1; int nt = 1;
Telemetry ctx = new Telemetry(); RcTelemetry ctx = new RcTelemetry();
{ {
int[] areas = { 42 }; int[] areas = { 42 };
Recast.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, unwalkable_tri, nt, areas); Recast.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, unwalkable_tri, nt, areas);