Refactored rcBuildContext to be more customization friendly, changed name to rcContext.
This commit is contained in:
parent
02b189a7cb
commit
5abddbf0cd
@ -37,7 +37,7 @@ bool duReadContourSet(struct rcContourSet& cset, duFileIO* io);
|
||||
bool duDumpCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io);
|
||||
bool duReadCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io);
|
||||
|
||||
void duLogBuildTimes(rcBuildContext* ctx, const int totalTileUsec);
|
||||
void duLogBuildTimes(rcContext& ctx, const int totalTileUsec);
|
||||
|
||||
|
||||
#endif // RECAST_DUMP_H
|
||||
|
@ -399,41 +399,41 @@ bool duReadCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io)
|
||||
}
|
||||
|
||||
|
||||
static void logLine(rcBuildContext* ctx, rcBuildTimeLabel label, const char* name, const float pc)
|
||||
static void logLine(rcContext& ctx, rcTimerLabel label, const char* name, const float pc)
|
||||
{
|
||||
const int t = ctx->getBuildTime(label);
|
||||
const int t = ctx.getAccumulatedTime(label);
|
||||
if (t < 0) return;
|
||||
ctx->log(RC_LOG_PROGRESS, "%s:\t%.2fms\t(%.1f%%)", name, t/1000.0f, t*pc);
|
||||
ctx.log(RC_LOG_PROGRESS, "%s:\t%.2fms\t(%.1f%%)", name, t/1000.0f, t*pc);
|
||||
}
|
||||
|
||||
void duLogBuildTimes(rcBuildContext* ctx, const int totalTimeUsec)
|
||||
void duLogBuildTimes(rcContext& ctx, const int totalTimeUsec)
|
||||
{
|
||||
const float pc = 100.0f / totalTimeUsec;
|
||||
|
||||
ctx->log(RC_LOG_PROGRESS, "Build Times");
|
||||
logLine(ctx, RC_TIME_RASTERIZE_TRIANGLES, "- Rasterize", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_COMPACTHEIGHFIELD, "- Build Compact", pc);
|
||||
logLine(ctx, RC_TIME_FILTER_BORDER, "- Filter Border", pc);
|
||||
logLine(ctx, RC_TIME_FILTER_WALKABLE, "- Filter Walkable", pc);
|
||||
logLine(ctx, RC_TIME_ERODE_AREA, "- Erode Area", pc);
|
||||
logLine(ctx, RC_TIME_MEDIAN_AREA, "- Median Area", pc);
|
||||
logLine(ctx, RC_TIME_MARK_BOX_AREA, "- Mark Box Area", pc);
|
||||
logLine(ctx, RC_TIME_MARK_CONVEXPOLY_AREA, "- Mark Convex Area", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_DISTANCEFIELD, "- Build Disntace Field", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_DISTANCEFIELD_DIST, " - Distance", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_DISTANCEFIELD_BLUR, " - Blur", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_REGIONS, "- Build Regions", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_REGIONS_WATERSHED, " - Watershed", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_REGIONS_EXPAND, " - Expand", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_REGIONS_FLOOD, " - Find Basins", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_REGIONS_FILTER, " - Filter", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_CONTOURS, "- Build Contours", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_CONTOURS_TRACE, " - Trace", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_CONTOURS_SIMPLIFY, " - Simplify", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_POLYMESH, "- Build Polymesh", pc);
|
||||
logLine(ctx, RC_TIME_BUILD_POLYMESHDETAIL, "- Build Polymesh Detail", pc);
|
||||
logLine(ctx, RC_TIME_MERGE_POLYMESH, "- Merge Polymeshes", pc);
|
||||
logLine(ctx, RC_TIME_MERGE_POLYMESHDETAIL, "- Merge Polymesh Details", pc);
|
||||
ctx->log(RC_LOG_PROGRESS, "=== TOTAL:\t%.2fms", totalTimeUsec/1000.0f);
|
||||
ctx.log(RC_LOG_PROGRESS, "Build Times");
|
||||
logLine(ctx, RC_TIMER_RASTERIZE_TRIANGLES, "- Rasterize", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_COMPACTHEIGHFIELD, "- Build Compact", pc);
|
||||
logLine(ctx, RC_TIMER_FILTER_BORDER, "- Filter Border", pc);
|
||||
logLine(ctx, RC_TIMER_FILTER_WALKABLE, "- Filter Walkable", pc);
|
||||
logLine(ctx, RC_TIMER_ERODE_AREA, "- Erode Area", pc);
|
||||
logLine(ctx, RC_TIMER_MEDIAN_AREA, "- Median Area", pc);
|
||||
logLine(ctx, RC_TIMER_MARK_BOX_AREA, "- Mark Box Area", pc);
|
||||
logLine(ctx, RC_TIMER_MARK_CONVEXPOLY_AREA, "- Mark Convex Area", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_DISTANCEFIELD, "- Build Disntace Field", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_DISTANCEFIELD_DIST, " - Distance", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_DISTANCEFIELD_BLUR, " - Blur", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_REGIONS, "- Build Regions", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_REGIONS_WATERSHED, " - Watershed", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_REGIONS_EXPAND, " - Expand", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_REGIONS_FLOOD, " - Find Basins", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_REGIONS_FILTER, " - Filter", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_CONTOURS, "- Build Contours", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_CONTOURS_TRACE, " - Trace", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_CONTOURS_SIMPLIFY, " - Simplify", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_POLYMESH, "- Build Polymesh", pc);
|
||||
logLine(ctx, RC_TIMER_BUILD_POLYMESHDETAIL, "- Build Polymesh Detail", pc);
|
||||
logLine(ctx, RC_TIMER_MERGE_POLYMESH, "- Merge Polymeshes", pc);
|
||||
logLine(ctx, RC_TIMER_MERGE_POLYMESHDETAIL, "- Merge Polymesh Details", pc);
|
||||
ctx.log(RC_LOG_PROGRESS, "=== TOTAL:\t%.2fms", totalTimeUsec/1000.0f);
|
||||
}
|
||||
|
||||
|
@ -19,14 +19,6 @@
|
||||
#ifndef RECAST_H
|
||||
#define RECAST_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <stdint.h>
|
||||
typedef int64_t rcTimeVal;
|
||||
#else
|
||||
typedef __int64 rcTimeVal;
|
||||
#endif
|
||||
|
||||
|
||||
enum rcLogCategory
|
||||
{
|
||||
RC_LOG_PROGRESS = 1,
|
||||
@ -34,55 +26,74 @@ enum rcLogCategory
|
||||
RC_LOG_ERROR,
|
||||
};
|
||||
|
||||
enum rcBuildTimeLabel
|
||||
enum rcTimerLabel
|
||||
{
|
||||
RC_TIME_RASTERIZE_TRIANGLES,
|
||||
RC_TIME_BUILD_COMPACTHEIGHFIELD,
|
||||
RC_TIME_BUILD_CONTOURS,
|
||||
RC_TIME_BUILD_CONTOURS_TRACE,
|
||||
RC_TIME_BUILD_CONTOURS_SIMPLIFY,
|
||||
RC_TIME_FILTER_BORDER,
|
||||
RC_TIME_FILTER_WALKABLE,
|
||||
RC_TIME_MEDIAN_AREA,
|
||||
RC_TIME_FILTER_LOW_OBSTACLES,
|
||||
RC_TIME_BUILD_POLYMESH,
|
||||
RC_TIME_MERGE_POLYMESH,
|
||||
RC_TIME_ERODE_AREA,
|
||||
RC_TIME_MARK_BOX_AREA,
|
||||
RC_TIME_MARK_CONVEXPOLY_AREA,
|
||||
RC_TIME_BUILD_DISTANCEFIELD,
|
||||
RC_TIME_BUILD_DISTANCEFIELD_DIST,
|
||||
RC_TIME_BUILD_DISTANCEFIELD_BLUR,
|
||||
RC_TIME_BUILD_REGIONS,
|
||||
RC_TIME_BUILD_REGIONS_WATERSHED,
|
||||
RC_TIME_BUILD_REGIONS_EXPAND,
|
||||
RC_TIME_BUILD_REGIONS_FLOOD,
|
||||
RC_TIME_BUILD_REGIONS_FILTER,
|
||||
RC_TIME_BUILD_POLYMESHDETAIL,
|
||||
RC_TIME_MERGE_POLYMESHDETAIL,
|
||||
RC_MAX_TIMES
|
||||
RC_TIMER_TOTAL,
|
||||
RC_TIMER_TEMP,
|
||||
RC_TIMER_RASTERIZE_TRIANGLES,
|
||||
RC_TIMER_BUILD_COMPACTHEIGHFIELD,
|
||||
RC_TIMER_BUILD_CONTOURS,
|
||||
RC_TIMER_BUILD_CONTOURS_TRACE,
|
||||
RC_TIMER_BUILD_CONTOURS_SIMPLIFY,
|
||||
RC_TIMER_FILTER_BORDER,
|
||||
RC_TIMER_FILTER_WALKABLE,
|
||||
RC_TIMER_MEDIAN_AREA,
|
||||
RC_TIMER_FILTER_LOW_OBSTACLES,
|
||||
RC_TIMER_BUILD_POLYMESH,
|
||||
RC_TIMER_MERGE_POLYMESH,
|
||||
RC_TIMER_ERODE_AREA,
|
||||
RC_TIMER_MARK_BOX_AREA,
|
||||
RC_TIMER_MARK_CONVEXPOLY_AREA,
|
||||
RC_TIMER_BUILD_DISTANCEFIELD,
|
||||
RC_TIMER_BUILD_DISTANCEFIELD_DIST,
|
||||
RC_TIMER_BUILD_DISTANCEFIELD_BLUR,
|
||||
RC_TIMER_BUILD_REGIONS,
|
||||
RC_TIMER_BUILD_REGIONS_WATERSHED,
|
||||
RC_TIMER_BUILD_REGIONS_EXPAND,
|
||||
RC_TIMER_BUILD_REGIONS_FLOOD,
|
||||
RC_TIMER_BUILD_REGIONS_FILTER,
|
||||
RC_TIMER_BUILD_POLYMESHDETAIL,
|
||||
RC_TIMER_MERGE_POLYMESHDETAIL,
|
||||
RC_MAX_TIMERS
|
||||
};
|
||||
|
||||
// Build context provides several optional utilities needed for the build process,
|
||||
// such as timing, logging, and build time collecting.
|
||||
struct rcBuildContext
|
||||
class rcContext
|
||||
{
|
||||
// Get current time in platform specific units.
|
||||
virtual rcTimeVal getTime() { return 0; }
|
||||
// Returns time passed from 'start' to 'end' in microseconds.
|
||||
virtual int getDeltaTimeUsec(const rcTimeVal /*start*/, const rcTimeVal /*end*/) { return 0; }
|
||||
public:
|
||||
inline rcContext(bool state = true) : m_logEnabled(state), m_timerEnabled(state) {}
|
||||
virtual ~rcContext() {}
|
||||
|
||||
// Enables or disables logging.
|
||||
inline void enableLog(bool state) { m_logEnabled = state; }
|
||||
// Resets log.
|
||||
virtual void resetLog() {}
|
||||
inline void resetLog() { if (m_logEnabled) doResetLog(); }
|
||||
// Logs a message.
|
||||
virtual void log(const rcLogCategory /*category*/, const char* /*format*/, ...) {}
|
||||
void log(const rcLogCategory category, const char* format, ...);
|
||||
|
||||
// Resets build time collecting.
|
||||
virtual void resetBuildTimes() {}
|
||||
// Reports build time of specified label for accumulation.
|
||||
virtual void reportBuildTime(const rcBuildTimeLabel /*label*/, const int /*time*/) {}
|
||||
// Returns accumulated build time for specified label, or -1 if no time was reported.
|
||||
virtual int getBuildTime(const rcBuildTimeLabel /*label*/) { return -1; }
|
||||
// Enables or disables timer.
|
||||
inline void enableTimer(bool state) { m_timerEnabled = state; }
|
||||
// Resets all timers.
|
||||
inline void resetTimers() { if (m_timerEnabled) doResetTimers(); }
|
||||
// Starts timer, used for performance timing.
|
||||
inline void startTimer(const rcTimerLabel label) { if (m_timerEnabled) doStartTimer(label); }
|
||||
// Stops timer, used for performance timing.
|
||||
inline void stopTimer(const rcTimerLabel label) { if (m_timerEnabled) doStopTimer(label); }
|
||||
// Returns time accumulated between timer start/stop.
|
||||
inline int getAccumulatedTime(const rcTimerLabel label) const { return m_timerEnabled ? doGetAccumulatedTime(label) : -1; }
|
||||
|
||||
protected:
|
||||
// Virtual functions to override for custom implementations.
|
||||
virtual void doResetLog() {}
|
||||
virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {}
|
||||
virtual void doResetTimers() {}
|
||||
virtual void doStartTimer(const rcTimerLabel /*label*/) {}
|
||||
virtual void doStopTimer(const rcTimerLabel /*label*/) {}
|
||||
virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; }
|
||||
|
||||
bool m_logEnabled;
|
||||
bool m_timerEnabled;
|
||||
};
|
||||
|
||||
|
||||
@ -143,6 +154,10 @@ struct rcHeightfield
|
||||
rcSpan* freelist; // Pointer to next free span.
|
||||
};
|
||||
|
||||
rcHeightfield* rcAllocHeightfield();
|
||||
void rcFreeHeightField(rcHeightfield* hf);
|
||||
|
||||
|
||||
struct rcCompactCell
|
||||
{
|
||||
unsigned int index : 24; // Index to first span in column.
|
||||
@ -160,9 +175,6 @@ struct rcCompactSpan
|
||||
// Compact static heightfield.
|
||||
struct rcCompactHeightfield
|
||||
{
|
||||
rcCompactHeightfield();
|
||||
~rcCompactHeightfield();
|
||||
|
||||
int width, height; // Width and height of the heighfield.
|
||||
int spanCount; // Number of spans in the heightfield.
|
||||
int walkableHeight, walkableClimb; // Agent properties.
|
||||
@ -176,6 +188,10 @@ struct rcCompactHeightfield
|
||||
unsigned char* areas; // Pointer to per span area ID.
|
||||
};
|
||||
|
||||
rcCompactHeightfield* rcAllocCompactHeightfield();
|
||||
void rcFreeCompactHeightfield(rcCompactHeightfield* chf);
|
||||
|
||||
|
||||
struct rcContour
|
||||
{
|
||||
int* verts; // Vertex coordinates, each vertex contains 4 components.
|
||||
@ -194,6 +210,10 @@ struct rcContourSet
|
||||
float cs, ch; // Cell size and height.
|
||||
};
|
||||
|
||||
rcContourSet* rcAllocContourSet();
|
||||
void rcFreeContourSet(rcContourSet* cset);
|
||||
|
||||
|
||||
// Polymesh store a connected mesh of polygons.
|
||||
// The polygons are store in an array where each polygons takes
|
||||
// 'nvp*2' elements. The first 'nvp' elements are indices to vertices
|
||||
@ -220,6 +240,10 @@ struct rcPolyMesh
|
||||
float cs, ch; // Cell size and height.
|
||||
};
|
||||
|
||||
rcPolyMesh* rcAllocPolyMesh();
|
||||
void rcFreePolyMesh(rcPolyMesh* pmesh);
|
||||
|
||||
|
||||
// Detail mesh generated from a rcPolyMesh.
|
||||
// Each submesh represents a polygon in the polymesh and they are stored in
|
||||
// excatly same order. Each submesh is described as 4 values:
|
||||
@ -240,19 +264,6 @@ struct rcPolyMeshDetail
|
||||
int ntris; // Number of triangles.
|
||||
};
|
||||
|
||||
// Allocators and destructors for Recast objects.
|
||||
rcHeightfield* rcAllocHeightfield();
|
||||
void rcFreeHeightField(rcHeightfield* hf);
|
||||
|
||||
rcCompactHeightfield* rcAllocCompactHeightfield();
|
||||
void rcFreeCompactHeightfield(rcCompactHeightfield* chf);
|
||||
|
||||
rcContourSet* rcAllocContourSet();
|
||||
void rcFreeContourSet(rcContourSet* cset);
|
||||
|
||||
rcPolyMesh* rcAllocPolyMesh();
|
||||
void rcFreePolyMesh(rcPolyMesh* pmesh);
|
||||
|
||||
rcPolyMeshDetail* rcAllocPolyMeshDetail();
|
||||
void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh);
|
||||
|
||||
@ -432,7 +443,7 @@ void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int*
|
||||
// bmin, bmax - (in) bounding box of the heightfield
|
||||
// cs - (in) grid cell size
|
||||
// ch - (in) grid cell height
|
||||
bool rcCreateHeightfield(rcBuildContext* ctx, rcHeightfield& hf, int width, int height,
|
||||
bool rcCreateHeightfield(rcContext* ctx, rcHeightfield& hf, int width, int height,
|
||||
const float* bmin, const float* bmax,
|
||||
float cs, float ch);
|
||||
|
||||
@ -445,7 +456,7 @@ bool rcCreateHeightfield(rcBuildContext* ctx, rcHeightfield& hf, int width, int
|
||||
// tris - (in) array of triangle vertex indices
|
||||
// nt - (in) triangle count
|
||||
// areas - (out) array of triangle area types
|
||||
void rcMarkWalkableTriangles(rcBuildContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
|
||||
void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
|
||||
const int* tris, int nt, unsigned char* areas);
|
||||
|
||||
// Sets the RC_NULL_AREA for every triangle whose slope is steeper than
|
||||
@ -457,7 +468,7 @@ void rcMarkWalkableTriangles(rcBuildContext* ctx, const float walkableSlopeAngle
|
||||
// tris - (in) array of triangle vertex indices
|
||||
// nt - (in) triangle count
|
||||
// areas - (out) array of triangle are types
|
||||
void rcClearUnwalkableTriangles(rcBuildContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
|
||||
void rcClearUnwalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
|
||||
const int* tris, int nt, unsigned char* areas);
|
||||
|
||||
// Adds span to heighfield.
|
||||
@ -470,7 +481,7 @@ void rcClearUnwalkableTriangles(rcBuildContext* ctx, const float walkableSlopeAn
|
||||
// smin,smax - (in) spans min/max height
|
||||
// flags - (in) span flags (zero or WALKABLE)
|
||||
// flagMergeThr - (in) merge threshold.
|
||||
void rcAddSpan(rcBuildContext* ctx, rcHeightfield& solid, const int x, const int y,
|
||||
void rcAddSpan(rcContext* ctx, rcHeightfield& solid, const int x, const int y,
|
||||
const unsigned short smin, const unsigned short smax,
|
||||
const unsigned short area, const int flagMergeThr);
|
||||
|
||||
@ -480,7 +491,7 @@ void rcAddSpan(rcBuildContext* ctx, rcHeightfield& solid, const int x, const int
|
||||
// area - (in) area type of the triangle.
|
||||
// solid - (in) heighfield where the triangle is rasterized
|
||||
// flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable.
|
||||
void rcRasterizeTriangle(rcBuildContext* ctx, const float* v0, const float* v1, const float* v2,
|
||||
void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2,
|
||||
const unsigned char area, rcHeightfield& solid,
|
||||
const int flagMergeThr = 1);
|
||||
|
||||
@ -493,7 +504,7 @@ void rcRasterizeTriangle(rcBuildContext* ctx, const float* v0, const float* v1,
|
||||
// nt - (in) triangle count
|
||||
// solid - (in) heighfield where the triangles are rasterized
|
||||
// flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable.
|
||||
void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int nv,
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv,
|
||||
const int* tris, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr = 1);
|
||||
|
||||
@ -506,7 +517,7 @@ void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int nv,
|
||||
// nt - (in) triangle count
|
||||
// solid - (in) heighfield where the triangles are rasterized
|
||||
// flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable.
|
||||
void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int nv,
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv,
|
||||
const unsigned short* tris, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr = 1);
|
||||
|
||||
@ -516,7 +527,7 @@ void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int nv,
|
||||
// area - (in) array of triangle area types.
|
||||
// nt - (in) triangle count
|
||||
// solid - (in) heighfield where the triangles are rasterized
|
||||
void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const unsigned char* areas, const int nt,
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr = 1);
|
||||
|
||||
// Marks non-walkable low obstacles as walkable if they are closer than walkableClimb
|
||||
@ -526,7 +537,7 @@ void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const unsigne
|
||||
// walkableHeight - (in) minimum height where the agent can still walk
|
||||
// solid - (in/out) heightfield describing the solid space
|
||||
// TODO: Missuses ledge flag, must be called before rcFilterLedgeSpans!
|
||||
void rcFilterLowHangingWalkableObstacles(rcBuildContext* ctx, const int walkableClimb, rcHeightfield& solid);
|
||||
void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid);
|
||||
|
||||
// Removes WALKABLE flag from all spans that are at ledges. This filtering
|
||||
// removes possible overestimation of the conservative voxelization so that
|
||||
@ -535,20 +546,20 @@ void rcFilterLowHangingWalkableObstacles(rcBuildContext* ctx, const int walkable
|
||||
// walkableHeight - (in) minimum height where the agent can still walk
|
||||
// walkableClimb - (in) maximum height between grid cells the agent can climb
|
||||
// solid - (in/out) heightfield describing the solid space
|
||||
void rcFilterLedgeSpans(rcBuildContext* ctx, const int walkableHeight, const int walkableClimb, rcHeightfield& solid);
|
||||
void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walkableClimb, rcHeightfield& solid);
|
||||
|
||||
// Removes WALKABLE flag from all spans which have smaller than
|
||||
// 'walkableHeight' clearane above them.
|
||||
// Params:
|
||||
// walkableHeight - (in) minimum height where the agent can still walk
|
||||
// solid - (in/out) heightfield describing the solid space
|
||||
void rcFilterWalkableLowHeightSpans(rcBuildContext* ctx, int walkableHeight, rcHeightfield& solid);
|
||||
void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid);
|
||||
|
||||
// Returns number of spans contained in a heightfield.
|
||||
// Params:
|
||||
// hf - (in) heightfield to be compacted
|
||||
// Returns number of spans.
|
||||
int rcGetHeightFieldSpanCount(rcBuildContext* ctx, rcHeightfield& hf);
|
||||
int rcGetHeightFieldSpanCount(rcContext* ctx, rcHeightfield& hf);
|
||||
|
||||
// Builds compact representation of the heightfield.
|
||||
// Params:
|
||||
@ -558,7 +569,7 @@ int rcGetHeightFieldSpanCount(rcBuildContext* ctx, rcHeightfield& hf);
|
||||
// hf - (in) heightfield to be compacted
|
||||
// chf - (out) compact heightfield representing the open space.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildCompactHeightfield(rcBuildContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
rcHeightfield& hf, rcCompactHeightfield& chf);
|
||||
|
||||
// Erodes walkable area.
|
||||
@ -566,20 +577,20 @@ bool rcBuildCompactHeightfield(rcBuildContext* ctx, const int walkableHeight, co
|
||||
// radius - (in) radius of erosion (max 255).
|
||||
// chf - (in/out) compact heightfield to erode.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcErodeWalkableArea(rcBuildContext* ctx, int radius, rcCompactHeightfield& chf);
|
||||
bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf);
|
||||
|
||||
// Applies median filter to walkable area types, removing noise.
|
||||
// Params:
|
||||
// chf - (in/out) compact heightfield to erode.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcMedianFilterWalkableArea(rcBuildContext* ctx, rcCompactHeightfield& chf);
|
||||
bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf);
|
||||
|
||||
// Marks the area of the convex polygon into the area type of the compact heighfield.
|
||||
// Params:
|
||||
// bmin/bmax - (in) bounds of the axis aligned box.
|
||||
// areaId - (in) area ID to mark.
|
||||
// chf - (in/out) compact heightfield to mark.
|
||||
void rcMarkBoxArea(rcBuildContext* ctx, const float* bmin, const float* bmax, unsigned char areaId,
|
||||
void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId,
|
||||
rcCompactHeightfield& chf);
|
||||
|
||||
// Marks the area of the convex polygon into the area type of the compact heighfield.
|
||||
@ -589,7 +600,7 @@ void rcMarkBoxArea(rcBuildContext* ctx, const float* bmin, const float* bmax, un
|
||||
// hmin/hmax - (in) min and max height of the polygon.
|
||||
// areaId - (in) area ID to mark.
|
||||
// chf - (in/out) compact heightfield to mark.
|
||||
void rcMarkConvexPolyArea(rcBuildContext* ctx, const float* verts, const int nverts,
|
||||
void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
|
||||
const float hmin, const float hmax, unsigned char areaId,
|
||||
rcCompactHeightfield& chf);
|
||||
|
||||
@ -597,7 +608,7 @@ void rcMarkConvexPolyArea(rcBuildContext* ctx, const float* verts, const int nve
|
||||
// Params:
|
||||
// chf - (in/out) compact heightfield representing the open space.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildDistanceField(rcBuildContext* ctx, rcCompactHeightfield& chf);
|
||||
bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf);
|
||||
|
||||
// Divides the walkable heighfied into simple regions using watershed partitioning.
|
||||
// Each region has only one contour and no overlaps.
|
||||
@ -612,7 +623,7 @@ bool rcBuildDistanceField(rcBuildContext* ctx, rcCompactHeightfield& chf);
|
||||
// minRegionSize - (in) the smallest allowed regions size.
|
||||
// maxMergeRegionSize - (in) the largest allowed regions size which can be merged.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const int borderSize, const int minRegionSize, const int mergeRegionSize);
|
||||
|
||||
// Divides the walkable heighfied into simple regions using simple monotone partitioning.
|
||||
@ -628,7 +639,7 @@ bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
// minRegionSize - (in) the smallest allowed regions size.
|
||||
// maxMergeRegionSize - (in) the largest allowed regions size which can be merged.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildRegionsMonotone(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const int borderSize, const int minRegionSize, const int mergeRegionSize);
|
||||
|
||||
// Builds simplified contours from the regions outlines.
|
||||
@ -639,7 +650,7 @@ bool rcBuildRegionsMonotone(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
// cset - (out) Resulting contour set.
|
||||
// flags - (in) build flags, see rcBuildContoursFlags.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const float maxError, const int maxEdgeLen,
|
||||
rcContourSet& cset, const int flags = RC_CONTOUR_TESS_WALL_EDGES);
|
||||
|
||||
@ -649,9 +660,9 @@ bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
// nvp - (in) maximum number of vertices per polygon.
|
||||
// mesh - (out) poly mesh.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildPolyMesh(rcBuildContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& mesh);
|
||||
bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& mesh);
|
||||
|
||||
bool rcMergePolyMeshes(rcBuildContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh);
|
||||
bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh);
|
||||
|
||||
// Builds detail triangle mesh for each polygon in the poly mesh.
|
||||
// Params:
|
||||
@ -661,11 +672,11 @@ bool rcMergePolyMeshes(rcBuildContext* ctx, rcPolyMesh** meshes, const int nmesh
|
||||
// sampleMaxError - (in) maximum allowed distance between simplified detail mesh and height sample.
|
||||
// pmdtl - (out) detail mesh.
|
||||
// Returns false if operation ran out of memory.
|
||||
bool rcBuildPolyMeshDetail(rcBuildContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
|
||||
bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
|
||||
const float sampleDist, const float sampleMaxError,
|
||||
rcPolyMeshDetail& dmesh);
|
||||
|
||||
bool rcMergePolyMeshDetails(rcBuildContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh);
|
||||
bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh);
|
||||
|
||||
|
||||
#endif // RECAST_H
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "Recast.h"
|
||||
#include "RecastAlloc.h"
|
||||
#include "RecastAssert.h"
|
||||
@ -31,6 +32,25 @@ float rcSqrt(float x)
|
||||
return sqrtf(x);
|
||||
}
|
||||
|
||||
|
||||
void rcContext::log(const rcLogCategory category, const char* format, ...)
|
||||
{
|
||||
if (!m_logEnabled)
|
||||
return;
|
||||
static const int MSG_SIZE = 512;
|
||||
char msg[MSG_SIZE];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
int len = vsnprintf(msg, MSG_SIZE, format, ap);
|
||||
if (len >= MSG_SIZE)
|
||||
{
|
||||
len = MSG_SIZE-1;
|
||||
msg[MSG_SIZE-1] = '\0';
|
||||
}
|
||||
va_end(ap);
|
||||
doLog(category, msg, len);
|
||||
}
|
||||
|
||||
rcHeightfield* rcAllocHeightfield()
|
||||
{
|
||||
rcHeightfield* hf = (rcHeightfield*)rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM);
|
||||
@ -143,7 +163,7 @@ void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int*
|
||||
*h = (int)((bmax[2] - bmin[2])/cs+0.5f);
|
||||
}
|
||||
|
||||
bool rcCreateHeightfield(rcBuildContext* /*ctx*/, rcHeightfield& hf, int width, int height,
|
||||
bool rcCreateHeightfield(rcContext* /*ctx*/, rcHeightfield& hf, int width, int height,
|
||||
const float* bmin, const float* bmax,
|
||||
float cs, float ch)
|
||||
{
|
||||
@ -172,7 +192,7 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo
|
||||
rcVnormalize(norm);
|
||||
}
|
||||
|
||||
void rcMarkWalkableTriangles(rcBuildContext* /*ctx*/, const float walkableSlopeAngle,
|
||||
void rcMarkWalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle,
|
||||
const float* verts, int /*nv*/,
|
||||
const int* tris, int nt,
|
||||
unsigned char* areas)
|
||||
@ -194,7 +214,7 @@ void rcMarkWalkableTriangles(rcBuildContext* /*ctx*/, const float walkableSlopeA
|
||||
}
|
||||
}
|
||||
|
||||
void rcClearUnwalkableTriangles(rcBuildContext* /*ctx*/, const float walkableSlopeAngle,
|
||||
void rcClearUnwalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle,
|
||||
const float* verts, int /*nv*/,
|
||||
const int* tris, int nt,
|
||||
unsigned char* areas)
|
||||
@ -216,7 +236,7 @@ void rcClearUnwalkableTriangles(rcBuildContext* /*ctx*/, const float walkableSlo
|
||||
}
|
||||
}
|
||||
|
||||
int rcGetHeightFieldSpanCount(rcBuildContext* /*ctx*/, rcHeightfield& hf)
|
||||
int rcGetHeightFieldSpanCount(rcContext* /*ctx*/, rcHeightfield& hf)
|
||||
{
|
||||
// TODO: VC complains about unref formal variable, figure out a way to handle this better.
|
||||
// rcAssert(ctx);
|
||||
@ -238,12 +258,12 @@ int rcGetHeightFieldSpanCount(rcBuildContext* /*ctx*/, rcHeightfield& hf)
|
||||
return spanCount;
|
||||
}
|
||||
|
||||
bool rcBuildCompactHeightfield(rcBuildContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
rcHeightfield& hf, rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_COMPACTHEIGHFIELD);
|
||||
|
||||
const int w = hf.width;
|
||||
const int h = hf.height;
|
||||
@ -371,9 +391,7 @@ bool rcBuildCompactHeightfield(rcBuildContext* ctx, const int walkableHeight, co
|
||||
tooHighNeighbour, MAX_LAYERS);
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_COMPACTHEIGHFIELD, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_BUILD_COMPACTHEIGHFIELD);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -27,14 +27,14 @@
|
||||
#include "RecastAssert.h"
|
||||
|
||||
|
||||
bool rcErodeWalkableArea(rcBuildContext* ctx, int radius, rcCompactHeightfield& chf)
|
||||
bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_ERODE_AREA);
|
||||
|
||||
unsigned char* dist = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
|
||||
if (!dist)
|
||||
@ -196,9 +196,7 @@ bool rcErodeWalkableArea(rcBuildContext* ctx, int radius, rcCompactHeightfield&
|
||||
|
||||
rcFree(dist);
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_ERODE_AREA, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_ERODE_AREA);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -216,14 +214,14 @@ static void insertSort(unsigned char* a, const int n)
|
||||
}
|
||||
|
||||
|
||||
bool rcMedianFilterWalkableArea(rcBuildContext* ctx, rcCompactHeightfield& chf)
|
||||
bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_MEDIAN_AREA);
|
||||
|
||||
unsigned char* areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
|
||||
if (!areas)
|
||||
@ -285,19 +283,17 @@ bool rcMedianFilterWalkableArea(rcBuildContext* ctx, rcCompactHeightfield& chf)
|
||||
|
||||
rcFree(areas);
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_MEDIAN_AREA, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_MEDIAN_AREA);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void rcMarkBoxArea(rcBuildContext* ctx, const float* bmin, const float* bmax, unsigned char areaId,
|
||||
void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId,
|
||||
rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_MARK_BOX_AREA);
|
||||
|
||||
int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs);
|
||||
int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch);
|
||||
@ -333,9 +329,7 @@ void rcMarkBoxArea(rcBuildContext* ctx, const float* bmin, const float* bmax, un
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_MARK_BOX_AREA, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_MARK_BOX_AREA);
|
||||
|
||||
}
|
||||
|
||||
@ -354,13 +348,13 @@ static int pointInPoly(int nvert, const float* verts, const float* p)
|
||||
return c;
|
||||
}
|
||||
|
||||
void rcMarkConvexPolyArea(rcBuildContext* ctx, const float* verts, const int nverts,
|
||||
void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
|
||||
const float hmin, const float hmax, unsigned char areaId,
|
||||
rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||
|
||||
float bmin[3], bmax[3];
|
||||
rcVcopy(bmin, verts);
|
||||
@ -419,7 +413,5 @@ void rcMarkConvexPolyArea(rcBuildContext* ctx, const float* verts, const int nve
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_MARK_CONVEXPOLY_AREA, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||
}
|
||||
|
@ -592,7 +592,7 @@ static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const float maxError, const int maxEdgeLen,
|
||||
rcContourSet& cset, const int buildFlags)
|
||||
{
|
||||
@ -601,7 +601,7 @@ bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_CONTOURS);
|
||||
|
||||
rcVcopy(cset.bmin, chf.bmin);
|
||||
rcVcopy(cset.bmax, chf.bmax);
|
||||
@ -621,8 +621,7 @@ bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
return false;
|
||||
}
|
||||
|
||||
rcTimeVal traceStartTime = ctx->getTime();
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_CONTOURS_TRACE);
|
||||
|
||||
// Mark boundaries.
|
||||
for (int y = 0; y < h; ++y)
|
||||
@ -657,9 +656,9 @@ bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal traceEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_TRACE);
|
||||
|
||||
rcTimeVal simplifyStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
|
||||
|
||||
rcIntArray verts(256);
|
||||
rcIntArray simplified(64);
|
||||
@ -797,13 +796,9 @@ bool rcBuildContours(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal simplifyEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_CONTOURS, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_CONTOURS_TRACE, ctx->getDeltaTimeUsec(traceStartTime, traceEndTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_CONTOURS_SIMPLIFY, ctx->getDeltaTimeUsec(simplifyStartTime, simplifyEndTime));
|
||||
ctx->stopTimer(RC_TIMER_BUILD_CONTOURS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -23,11 +23,11 @@
|
||||
#include "RecastAssert.h"
|
||||
|
||||
|
||||
void rcFilterLowHangingWalkableObstacles(rcBuildContext* ctx, const int walkableClimb, rcHeightfield& solid)
|
||||
void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -56,17 +56,15 @@ void rcFilterLowHangingWalkableObstacles(rcBuildContext* ctx, const int walkable
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_FILTER_LOW_OBSTACLES, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
}
|
||||
|
||||
void rcFilterLedgeSpans(rcBuildContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
rcHeightfield& solid)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_FILTER_BORDER);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -148,16 +146,14 @@ void rcFilterLedgeSpans(rcBuildContext* ctx, const int walkableHeight, const int
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_FILTER_BORDER, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_FILTER_BORDER);
|
||||
}
|
||||
|
||||
void rcFilterWalkableLowHeightSpans(rcBuildContext* ctx, int walkableHeight, rcHeightfield& solid)
|
||||
void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_FILTER_WALKABLE);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -179,7 +175,5 @@ void rcFilterWalkableLowHeightSpans(rcBuildContext* ctx, int walkableHeight, rcH
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_FILTER_WALKABLE, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_FILTER_WALKABLE);
|
||||
}
|
||||
|
@ -483,7 +483,7 @@ static void pushBack(int v, int* arr, int& an)
|
||||
an++;
|
||||
}
|
||||
|
||||
static bool canRemoveVertex(rcBuildContext* ctx, rcPolyMesh& mesh, const unsigned short rem)
|
||||
static bool canRemoveVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short rem)
|
||||
{
|
||||
const int nvp = mesh.nvp;
|
||||
|
||||
@ -585,7 +585,7 @@ static bool canRemoveVertex(rcBuildContext* ctx, rcPolyMesh& mesh, const unsigne
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool removeVertex(rcBuildContext* ctx, rcPolyMesh& mesh, const unsigned short rem, const int maxTris)
|
||||
static bool removeVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short rem, const int maxTris)
|
||||
{
|
||||
const int nvp = mesh.nvp;
|
||||
|
||||
@ -893,11 +893,11 @@ static bool removeVertex(rcBuildContext* ctx, rcPolyMesh& mesh, const unsigned s
|
||||
}
|
||||
|
||||
|
||||
bool rcBuildPolyMesh(rcBuildContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
||||
bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_POLYMESH);
|
||||
|
||||
rcVcopy(mesh.bmin, cset.bmin);
|
||||
rcVcopy(mesh.bmax, cset.bmax);
|
||||
@ -1163,21 +1163,19 @@ bool rcBuildPolyMesh(rcBuildContext* ctx, rcContourSet& cset, int nvp, rcPolyMes
|
||||
}
|
||||
memset(mesh.flags, 0, sizeof(unsigned short) * mesh.npolys);
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_POLYMESH, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_BUILD_POLYMESH);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rcMergePolyMeshes(rcBuildContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh)
|
||||
bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
if (!nmeshes || !meshes)
|
||||
return true;
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_MERGE_POLYMESH);
|
||||
|
||||
mesh.nvp = meshes[0]->nvp;
|
||||
mesh.cs = meshes[0]->cs;
|
||||
@ -1300,10 +1298,7 @@ bool rcMergePolyMeshes(rcBuildContext* ctx, rcPolyMesh** meshes, const int nmesh
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_MERGE_POLYMESH, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_MERGE_POLYMESH);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ static int findEdge(const int* edges, int nedges, int s, int t)
|
||||
return UNDEF;
|
||||
}
|
||||
|
||||
static int addEdge(rcBuildContext* ctx, int* edges, int& nedges, const int maxEdges, int s, int t, int l, int r)
|
||||
static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges, int s, int t, int l, int r)
|
||||
{
|
||||
if (nedges >= maxEdges)
|
||||
{
|
||||
@ -317,7 +317,7 @@ static bool overlapEdges(const float* pts, const int* edges, int nedges, int s1,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void completeFacet(rcBuildContext* ctx, const float* pts, int npts, int* edges, int& nedges, const int maxEdges, int& nfaces, int e)
|
||||
static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges, int& nedges, const int maxEdges, int& nfaces, int e)
|
||||
{
|
||||
static const float EPS = 1e-5f;
|
||||
|
||||
@ -413,7 +413,7 @@ static void completeFacet(rcBuildContext* ctx, const float* pts, int npts, int*
|
||||
}
|
||||
}
|
||||
|
||||
static void delaunayHull(rcBuildContext* ctx, const int npts, const float* pts,
|
||||
static void delaunayHull(rcContext* ctx, const int npts, const float* pts,
|
||||
const int nhull, const int* hull,
|
||||
rcIntArray& tris, rcIntArray& edges)
|
||||
{
|
||||
@ -491,7 +491,7 @@ static void delaunayHull(rcBuildContext* ctx, const int npts, const float* pts,
|
||||
|
||||
|
||||
|
||||
static bool buildPolyDetail(rcBuildContext* ctx, const float* in, const int nin,
|
||||
static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
||||
const float sampleDist, const float sampleMaxError,
|
||||
const rcCompactHeightfield& chf, const rcHeightPatch& hp,
|
||||
float* verts, int& nverts, rcIntArray& tris,
|
||||
@ -914,14 +914,14 @@ static unsigned char getTriFlags(const float* va, const float* vb, const float*
|
||||
|
||||
|
||||
|
||||
bool rcBuildPolyMeshDetail(rcBuildContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
|
||||
bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
|
||||
const float sampleDist, const float sampleMaxError,
|
||||
rcPolyMeshDetail& dmesh)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||
|
||||
if (mesh.nverts == 0 || mesh.npolys == 0)
|
||||
return true;
|
||||
|
||||
@ -1126,19 +1126,17 @@ bool rcBuildPolyMeshDetail(rcBuildContext* ctx, const rcPolyMesh& mesh, const rc
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_POLYMESHDETAIL, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rcMergePolyMeshDetails(rcBuildContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh)
|
||||
bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
|
||||
ctx->startTimer(RC_TIMER_MERGE_POLYMESHDETAIL);
|
||||
|
||||
int maxVerts = 0;
|
||||
int maxTris = 0;
|
||||
int maxMeshes = 0;
|
||||
@ -1206,9 +1204,7 @@ bool rcMergePolyMeshDetails(rcBuildContext* ctx, rcPolyMeshDetail** meshes, cons
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_MERGE_POLYMESHDETAIL, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_MERGE_POLYMESHDETAIL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ static void addSpan(rcHeightfield& hf, const int x, const int y,
|
||||
}
|
||||
}
|
||||
|
||||
void rcAddSpan(rcBuildContext* /*ctx*/, rcHeightfield& hf, const int x, const int y,
|
||||
void rcAddSpan(rcContext* /*ctx*/, rcHeightfield& hf, const int x, const int y,
|
||||
const unsigned short smin, const unsigned short smax,
|
||||
const unsigned char area, const int flagMergeThr)
|
||||
{
|
||||
@ -276,30 +276,28 @@ static void rasterizeTri(const float* v0, const float* v1, const float* v2,
|
||||
}
|
||||
}
|
||||
|
||||
void rcRasterizeTriangle(rcBuildContext* ctx, const float* v0, const float* v1, const float* v2,
|
||||
void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2,
|
||||
const unsigned char area, rcHeightfield& solid,
|
||||
const int flagMergeThr)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
rasterizeTri(v0, v1, v2, area, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_RASTERIZE_TRIANGLES, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int /*nv*/,
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/,
|
||||
const int* tris, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -313,18 +311,16 @@ void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int /*n
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_RASTERIZE_TRIANGLES, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int /*nv*/,
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/,
|
||||
const unsigned short* tris, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -338,17 +334,15 @@ void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const int /*n
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_RASTERIZE_TRIANGLES, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const unsigned char* areas, const int nt,
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -362,7 +356,5 @@ void rcRasterizeTriangles(rcBuildContext* ctx, const float* verts, const unsigne
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_RASTERIZE_TRIANGLES, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
@ -687,7 +687,7 @@ static void walkContour(int x, int y, int i, int dir,
|
||||
}
|
||||
}
|
||||
|
||||
static bool filterSmallRegions(rcBuildContext* ctx, int minRegionSize, int mergeRegionSize,
|
||||
static bool filterSmallRegions(rcContext* ctx, int minRegionSize, int mergeRegionSize,
|
||||
unsigned short& maxRegionId,
|
||||
rcCompactHeightfield& chf,
|
||||
unsigned short* srcReg)
|
||||
@ -886,11 +886,11 @@ static bool filterSmallRegions(rcBuildContext* ctx, int minRegionSize, int merge
|
||||
}
|
||||
|
||||
|
||||
bool rcBuildDistanceField(rcBuildContext* ctx, rcCompactHeightfield& chf)
|
||||
bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_DISTANCEFIELD);
|
||||
|
||||
if (chf.dist)
|
||||
{
|
||||
@ -914,14 +914,14 @@ bool rcBuildDistanceField(rcBuildContext* ctx, rcCompactHeightfield& chf)
|
||||
|
||||
unsigned short maxDist = 0;
|
||||
|
||||
rcTimeVal distStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
|
||||
calculateDistanceField(chf, src, maxDist);
|
||||
chf.maxDistance = maxDist;
|
||||
|
||||
rcTimeVal distEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_DISTANCEFIELD_DIST);
|
||||
|
||||
rcTimeVal blurStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
|
||||
// Blur
|
||||
if (boxBlur(chf, 1, src, dst) != src)
|
||||
@ -930,16 +930,10 @@ bool rcBuildDistanceField(rcBuildContext* ctx, rcCompactHeightfield& chf)
|
||||
// Store distance.
|
||||
chf.dist = src;
|
||||
|
||||
rcTimeVal blurEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_DISTANCEFIELD_BLUR);
|
||||
|
||||
rcFree(dst);
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_DISTANCEFIELD, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_DISTANCEFIELD_DIST, ctx->getDeltaTimeUsec(distStartTime, distEndTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_DISTANCEFIELD_BLUR, ctx->getDeltaTimeUsec(blurStartTime, blurEndTime));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -973,12 +967,12 @@ struct rcSweepSpan
|
||||
unsigned short nei; // neighbour id
|
||||
};
|
||||
|
||||
bool rcBuildRegionsMonotone(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const int borderSize, const int minRegionSize, const int mergeRegionSize)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
@ -1101,33 +1095,30 @@ bool rcBuildRegionsMonotone(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal filterStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Filter out small regions.
|
||||
chf.maxRegions = id;
|
||||
if (!filterSmallRegions(ctx, minRegionSize, mergeRegionSize, chf.maxRegions, chf, srcReg))
|
||||
return false;
|
||||
|
||||
rcTimeVal filterEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Store the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS_FILTER, ctx->getDeltaTimeUsec(filterStartTime, filterEndTime));
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const int borderSize, const int minRegionSize, const int mergeRegionSize)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
rcTimeVal startTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
@ -1139,7 +1130,7 @@ bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
return false;
|
||||
}
|
||||
|
||||
rcTimeVal regStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_WATERSHED);
|
||||
|
||||
rcIntArray stack(1024);
|
||||
rcIntArray visited(1024);
|
||||
@ -1166,15 +1157,12 @@ bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
paintRectRegion(w-borderSize, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
|
||||
paintRectRegion(0, w, 0, borderSize, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
|
||||
paintRectRegion(0, w, h-borderSize, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
|
||||
|
||||
rcTimeVal expTime = 0;
|
||||
rcTimeVal floodTime = 0;
|
||||
|
||||
while (level > 0)
|
||||
{
|
||||
level = level >= 2 ? level-2 : 0;
|
||||
|
||||
rcTimeVal expStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||
|
||||
// Expand current regions until no empty connected cells found.
|
||||
if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg)
|
||||
@ -1183,9 +1171,9 @@ bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
rcSwap(srcDist, dstDist);
|
||||
}
|
||||
|
||||
expTime += ctx->getTime() - expStartTime;
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
|
||||
|
||||
rcTimeVal floodStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||
|
||||
// Mark new regions with IDs.
|
||||
for (int y = 0; y < h; ++y)
|
||||
@ -1204,7 +1192,7 @@ bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
}
|
||||
}
|
||||
|
||||
floodTime += ctx->getTime() - floodStartTime;
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FLOOD);
|
||||
|
||||
}
|
||||
|
||||
@ -1215,29 +1203,23 @@ bool rcBuildRegions(rcBuildContext* ctx, rcCompactHeightfield& chf,
|
||||
rcSwap(srcDist, dstDist);
|
||||
}
|
||||
|
||||
rcTimeVal regEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_WATERSHED);
|
||||
|
||||
rcTimeVal filterStartTime = ctx->getTime();
|
||||
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Filter out small regions.
|
||||
chf.maxRegions = regionId;
|
||||
if (!filterSmallRegions(ctx, minRegionSize, mergeRegionSize, chf.maxRegions, chf, srcReg))
|
||||
return false;
|
||||
|
||||
rcTimeVal filterEndTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FILTER);
|
||||
|
||||
// Write the result out.
|
||||
for (int i = 0; i < chf.spanCount; ++i)
|
||||
chf.spans[i].reg = srcReg[i];
|
||||
|
||||
rcTimeVal endTime = ctx->getTime();
|
||||
ctx->stopTimer(RC_TIMER_BUILD_REGIONS);
|
||||
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS, ctx->getDeltaTimeUsec(startTime, endTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS_WATERSHED, ctx->getDeltaTimeUsec(regStartTime, regEndTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS_EXPAND, ctx->getDeltaTimeUsec(0, expTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS_FLOOD, ctx->getDeltaTimeUsec(0, floodTime));
|
||||
ctx->reportBuildTime(RC_TIME_BUILD_REGIONS_FILTER, ctx->getDeltaTimeUsec(filterStartTime, filterEndTime));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -290,7 +290,7 @@
|
||||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 388}, {264, 660}}</string>
|
||||
<string>{{0, 196}, {264, 660}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
@ -337,7 +337,7 @@
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>6BA687751222F02E00730711</string>
|
||||
<string>6BD402B112243CEA00995864</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>6BBB4AA5115B4F3400CF791D</string>
|
||||
@ -348,74 +348,79 @@
|
||||
<string>6BF5F2E511748884000502A6</string>
|
||||
<string>6BF5F2E611748884000502A6</string>
|
||||
<string>6BF5F2E711748884000502A6</string>
|
||||
<string>6BF5F5041176F5F8000502A6</string>
|
||||
<string>6B4214D911803923006C347B</string>
|
||||
<string>6B98462E11E6141900FA177B</string>
|
||||
<string>6B98473011E737D800FA177B</string>
|
||||
<string>6BF9B12C11EB8CF20043574C</string>
|
||||
<string>6BAF3CB012116AD9008CFCDF</string>
|
||||
<string>6BAF3CB112116AD9008CFCDF</string>
|
||||
<string>6BAF3CB412116AD9008CFCDF</string>
|
||||
<string>6BAF3E781212869F008CFCDF</string>
|
||||
<string>6BAF404F12140B4E008CFCDF</string>
|
||||
<string>6BAF405112140B4E008CFCDF</string>
|
||||
<string>6BAF40F412197F3D008CFCDF</string>
|
||||
<string>6BAF427E121ADD46008CFCDF</string>
|
||||
<string>6BAF4280121ADD46008CFCDF</string>
|
||||
<string>6BAF4321121AF998008CFCDF</string>
|
||||
<string>6BAF43FB121C241D008CFCDF</string>
|
||||
<string>6BAF4421121C25E3008CFCDF</string>
|
||||
<string>6BAF4422121C25E3008CFCDF</string>
|
||||
<string>6BAF4446121C40AC008CFCDF</string>
|
||||
<string>6BAF446E121C4895008CFCDF</string>
|
||||
<string>6BAF44D9121C4DFC008CFCDF</string>
|
||||
<string>6BAF44DE121C54D4008CFCDF</string>
|
||||
<string>6BAF4524121D1723008CFCDF</string>
|
||||
<string>6BAF4525121D1723008CFCDF</string>
|
||||
<string>6BAF4562121D1849008CFCDF</string>
|
||||
<string>6BAF457D121D19CB008CFCDF</string>
|
||||
<string>6BAF457E121D19CB008CFCDF</string>
|
||||
<string>6BAF457F121D19CB008CFCDF</string>
|
||||
<string>6BAF4580121D19CB008CFCDF</string>
|
||||
<string>6BAF4581121D19CB008CFCDF</string>
|
||||
<string>6BAF4582121D19CB008CFCDF</string>
|
||||
<string>6BAF4593121D1B18008CFCDF</string>
|
||||
<string>6BAF45B8121D2F37008CFCDF</string>
|
||||
<string>6BAF45E4121D7277008CFCDF</string>
|
||||
<string>6BAF4604121D7388008CFCDF</string>
|
||||
<string>6BAF4605121D7388008CFCDF</string>
|
||||
<string>6BAF4637121D74D3008CFCDF</string>
|
||||
<string>6BAF46A2121D8B41008CFCDF</string>
|
||||
<string>6BAF46D3121D8FF1008CFCDF</string>
|
||||
<string>6BAF4739121D9FBE008CFCDF</string>
|
||||
<string>6BAF473A121D9FBE008CFCDF</string>
|
||||
<string>6BAF4747121D9FED008CFCDF</string>
|
||||
<string>6BAF475A121DA31D008CFCDF</string>
|
||||
<string>6BAF475B121DA31D008CFCDF</string>
|
||||
<string>6BAF475C121DA31D008CFCDF</string>
|
||||
<string>6B1C8D82121E80950048697F</string>
|
||||
<string>6B1C8DA2121E813D0048697F</string>
|
||||
<string>6B1C8DB3121E8D970048697F</string>
|
||||
<string>6B1C8DC0121E8F610048697F</string>
|
||||
<string>6B1C8DC5121E902F0048697F</string>
|
||||
<string>6B1C8E08121EB4FF0048697F</string>
|
||||
<string>6B1C8E0A121EB4FF0048697F</string>
|
||||
<string>6B1C8E24121EB6D30048697F</string>
|
||||
<string>6B1C8E27121EB6D30048697F</string>
|
||||
<string>6B1C8E6A1221BC910048697F</string>
|
||||
<string>6BA687441222EADA00730711</string>
|
||||
<string>6BA687451222EADA00730711</string>
|
||||
<string>6BA687461222EADA00730711</string>
|
||||
<string>6BA687471222EADA00730711</string>
|
||||
<string>6BA687481222EADA00730711</string>
|
||||
<string>6BA6874A1222EADA00730711</string>
|
||||
<string>6BA6874B1222EADA00730711</string>
|
||||
<string>6BA6874C1222EADA00730711</string>
|
||||
<string>6BA6874D1222EADA00730711</string>
|
||||
<string>6BA6876C1222F02E00730711</string>
|
||||
<string>6BA6876D1222F02E00730711</string>
|
||||
<string>6BA6876E1222F02E00730711</string>
|
||||
<string>6BA687701222F02E00730711</string>
|
||||
<string>6BA687831222F42100730711</string>
|
||||
<string>6BA687881222F4DB00730711</string>
|
||||
<string>6BA687CA1222FA9300730711</string>
|
||||
<string>6BA687D81222FC4700730711</string>
|
||||
<string>6BA687E4122300C300730711</string>
|
||||
<string>6BA688091223041E00730711</string>
|
||||
<string>6BA688211223066C00730711</string>
|
||||
<string>6BA6887B1223122200730711</string>
|
||||
<string>6BA688D1122321D800730711</string>
|
||||
<string>6BD4020A1224336600995864</string>
|
||||
<string>6BD4020B1224336600995864</string>
|
||||
<string>6BD4020C1224336600995864</string>
|
||||
<string>6BD4020D1224336600995864</string>
|
||||
<string>6BD4020E1224336600995864</string>
|
||||
<string>6BD4020F1224336600995864</string>
|
||||
<string>6BD402111224336600995864</string>
|
||||
<string>6BD402121224336600995864</string>
|
||||
<string>6BD402161224336600995864</string>
|
||||
<string>6BD402461224345E00995864</string>
|
||||
<string>6BD402481224345E00995864</string>
|
||||
<string>6BD402491224345E00995864</string>
|
||||
<string>6BD4024A1224345E00995864</string>
|
||||
<string>6BD4025F1224387200995864</string>
|
||||
<string>6BD402601224387200995864</string>
|
||||
<string>6BD402611224387200995864</string>
|
||||
<string>6BD402621224387200995864</string>
|
||||
<string>6BD402631224387200995864</string>
|
||||
<string>6BD402641224387200995864</string>
|
||||
<string>6BD402671224387200995864</string>
|
||||
<string>6BD402811224393000995864</string>
|
||||
<string>6BD402871224395C00995864</string>
|
||||
<string>6BD4028C1224399300995864</string>
|
||||
<string>6BD4029B12243A8000995864</string>
|
||||
<string>6BD4029C12243A8000995864</string>
|
||||
<string>6BD4029D12243A8000995864</string>
|
||||
<string>6BD402A612243C8100995864</string>
|
||||
<string>6BD402AB12243CEA00995864</string>
|
||||
<string>6BD402AC12243CEA00995864</string>
|
||||
<string>6BD402AD12243CEA00995864</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
@ -443,7 +448,6 @@
|
||||
<string>6BF5F2ED11748884000502A6</string>
|
||||
<string>6BF5F2EE11748884000502A6</string>
|
||||
<string>6BF5F33911759C3C000502A6</string>
|
||||
<string>6B98465411E6F9B400FA177B</string>
|
||||
<string>6B98466011E6F9B400FA177B</string>
|
||||
<string>6B98471011E734A100FA177B</string>
|
||||
<string>6B98471211E734A100FA177B</string>
|
||||
@ -457,7 +461,6 @@
|
||||
<string>6BAF3A3B1210235F008CFCDF</string>
|
||||
<string>6BAF3ABC121038F9008CFCDF</string>
|
||||
<string>6BAF3B0612112E63008CFCDF</string>
|
||||
<string>6BAF3B1512112F65008CFCDF</string>
|
||||
<string>6BAF3DAA1211882E008CFCDF</string>
|
||||
<string>6BAF3E631211B713008CFCDF</string>
|
||||
<string>6BBB4AE2115B4F3400CF791D</string>
|
||||
@ -467,18 +470,14 @@
|
||||
<string>6BAF4243121AD679008CFCDF</string>
|
||||
<string>6BAF4289121ADD46008CFCDF</string>
|
||||
<string>6BAF4396121C1F3D008CFCDF</string>
|
||||
<string>6BAF43A1121C1F3D008CFCDF</string>
|
||||
<string>6BAF43BE121C1F3D008CFCDF</string>
|
||||
<string>6BAF43D1121C2164008CFCDF</string>
|
||||
<string>6BAF43D2121C2164008CFCDF</string>
|
||||
<string>6BAF4453121C40AC008CFCDF</string>
|
||||
<string>6BAF4456121C40AC008CFCDF</string>
|
||||
<string>6B98477411E7406900FA177B</string>
|
||||
<string>6BAF3861120A8A8E008CFCDF</string>
|
||||
<string>6BAF410212197F3D008CFCDF</string>
|
||||
<string>6BAF44FA121C5713008CFCDF</string>
|
||||
<string>6BAF45E9121D7277008CFCDF</string>
|
||||
<string>6BAF447E121C4895008CFCDF</string>
|
||||
<string>6BAF473D121D9FBE008CFCDF</string>
|
||||
<string>6BAF4749121D9FED008CFCDF</string>
|
||||
<string>6BAF4762121DA31D008CFCDF</string>
|
||||
@ -486,30 +485,89 @@
|
||||
<string>6BAF4768121DA31D008CFCDF</string>
|
||||
<string>6B1C8DDB121EA3470048697F</string>
|
||||
<string>6B1C8E2A121EB6D30048697F</string>
|
||||
<string>6B1C8E2B121EB6D30048697F</string>
|
||||
<string>6B1C8E2D121EB6D30048697F</string>
|
||||
<string>6B1C8E58121EBEBF0048697F</string>
|
||||
<string>6BA6874E1222EADA00730711</string>
|
||||
<string>6BA6874F1222EADA00730711</string>
|
||||
<string>6BA687501222EADA00730711</string>
|
||||
<string>6BA687511222EADA00730711</string>
|
||||
<string>6BA687521222EADA00730711</string>
|
||||
<string>6BA687531222EADA00730711</string>
|
||||
<string>6BA687541222EADA00730711</string>
|
||||
<string>6BA687551222EADA00730711</string>
|
||||
<string>6BA687561222EADA00730711</string>
|
||||
<string>6BA687571222EADA00730711</string>
|
||||
<string>6BA687581222EADA00730711</string>
|
||||
<string>6BA687591222EADA00730711</string>
|
||||
<string>6BA6875A1222EADA00730711</string>
|
||||
<string>6BA6875B1222EADA00730711</string>
|
||||
<string>6BA6875C1222EADA00730711</string>
|
||||
<string>6BA6875D1222EADA00730711</string>
|
||||
<string>6BA6875E1222EADA00730711</string>
|
||||
<string>6BA6875F1222EADA00730711</string>
|
||||
<string>6BA687711222F02E00730711</string>
|
||||
<string>6BA687721222F02E00730711</string>
|
||||
<string>6BA687731222F02E00730711</string>
|
||||
<string>6BA687BC1222F82500730711</string>
|
||||
<string>6BA687BD1222F82500730711</string>
|
||||
<string>6BA6881D1223060400730711</string>
|
||||
<string>6BA688231223066C00730711</string>
|
||||
<string>6BA6885412230ECD00730711</string>
|
||||
<string>6BD402191224336600995864</string>
|
||||
<string>6BD4021A1224336600995864</string>
|
||||
<string>6BD4021B1224336600995864</string>
|
||||
<string>6BD4021C1224336600995864</string>
|
||||
<string>6BD4021D1224336600995864</string>
|
||||
<string>6BD4021E1224336600995864</string>
|
||||
<string>6BD4021F1224336600995864</string>
|
||||
<string>6BD402201224336600995864</string>
|
||||
<string>6BD402211224336600995864</string>
|
||||
<string>6BD402221224336600995864</string>
|
||||
<string>6BD402231224336600995864</string>
|
||||
<string>6BD402241224336600995864</string>
|
||||
<string>6BD402251224336600995864</string>
|
||||
<string>6BD402261224336600995864</string>
|
||||
<string>6BD402271224336600995864</string>
|
||||
<string>6BD402281224336600995864</string>
|
||||
<string>6BD402291224336600995864</string>
|
||||
<string>6BD4022A1224336600995864</string>
|
||||
<string>6BD4022B1224336600995864</string>
|
||||
<string>6BD4022C1224336600995864</string>
|
||||
<string>6BD4022D1224336600995864</string>
|
||||
<string>6BD4022E1224336600995864</string>
|
||||
<string>6BD4022F1224336600995864</string>
|
||||
<string>6BD402301224336600995864</string>
|
||||
<string>6BD402311224336600995864</string>
|
||||
<string>6BD402321224336600995864</string>
|
||||
<string>6BD402331224336600995864</string>
|
||||
<string>6BD402341224336600995864</string>
|
||||
<string>6BD402351224336600995864</string>
|
||||
<string>6BD402361224336600995864</string>
|
||||
<string>6BD402371224336600995864</string>
|
||||
<string>6BD402381224336600995864</string>
|
||||
<string>6BD402391224336600995864</string>
|
||||
<string>6BD4023A1224336600995864</string>
|
||||
<string>6BD4023B1224336600995864</string>
|
||||
<string>6BD4023C1224336600995864</string>
|
||||
<string>6BD4023D1224336600995864</string>
|
||||
<string>6BD4023E1224336600995864</string>
|
||||
<string>6BD4023F1224336600995864</string>
|
||||
<string>6BD402401224336600995864</string>
|
||||
<string>6BD402411224336600995864</string>
|
||||
<string>6BD4024C1224345E00995864</string>
|
||||
<string>6BD4024D1224345E00995864</string>
|
||||
<string>6BD4024E1224345E00995864</string>
|
||||
<string>6BD4024F1224345E00995864</string>
|
||||
<string>6BD402501224345E00995864</string>
|
||||
<string>6BD4026A1224387200995864</string>
|
||||
<string>6BD4026B1224387200995864</string>
|
||||
<string>6BD4026C1224387200995864</string>
|
||||
<string>6BD4026D1224387200995864</string>
|
||||
<string>6BD4026E1224387200995864</string>
|
||||
<string>6BD4026F1224387200995864</string>
|
||||
<string>6BD402701224387200995864</string>
|
||||
<string>6BD402711224387200995864</string>
|
||||
<string>6BD402721224387200995864</string>
|
||||
<string>6BD402731224387200995864</string>
|
||||
<string>6BD402741224387200995864</string>
|
||||
<string>6BD402751224387200995864</string>
|
||||
<string>6BD402761224387200995864</string>
|
||||
<string>6BD402831224393000995864</string>
|
||||
<string>6BD402841224393000995864</string>
|
||||
<string>6BD402891224395C00995864</string>
|
||||
<string>6BD4028E1224399300995864</string>
|
||||
<string>6BD4028F1224399300995864</string>
|
||||
<string>6BD402901224399300995864</string>
|
||||
<string>6BD402911224399300995864</string>
|
||||
<string>6BD402921224399300995864</string>
|
||||
<string>6BD4029F12243A8000995864</string>
|
||||
<string>6BD402A012243A8000995864</string>
|
||||
<string>6BD402A112243A8000995864</string>
|
||||
<string>6BD402A812243C8100995864</string>
|
||||
<string>6BD402AE12243CEA00995864</string>
|
||||
<string>6BD402AF12243CEA00995864</string>
|
||||
<string>6BD402B012243CEA00995864</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
@ -523,18 +581,18 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {994, 381}}</string>
|
||||
<string>{{0, 0}, {994, 493}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>0 59 1280 719 0 0 1280 778 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>381pt</string>
|
||||
<string>493pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>292pt</string>
|
||||
<string>180pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
@ -548,7 +606,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {994, 304}}</string>
|
||||
<string>{{10, 27}, {994, 81}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
@ -564,7 +622,9 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {994, 304}}</string>
|
||||
<string>{{10, 27}, {994, 153}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>0 59 1280 719 0 0 1280 778 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXProjectFindModule</string>
|
||||
@ -602,9 +662,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {994, 265}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>0 59 1280 719 0 0 1280 778 </string>
|
||||
<string>{{10, 27}, {994, 83}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXBuildResultsModule</string>
|
||||
@ -632,11 +690,11 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>6BA687641222EAE200730711</string>
|
||||
<string>6BD401FC1224235500995864</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>6BA687651222EAE200730711</string>
|
||||
<string>6BD401FD1224235500995864</string>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<string>6BA687661222EAE200730711</string>
|
||||
<string>6BD401FE1224235500995864</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
@ -687,12 +745,12 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {1280, 411}}</string>
|
||||
<string>{{0, 0}, {1280, 328}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXDebugCLIModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>411pt</string>
|
||||
<string>328pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ContentConfiguration</key>
|
||||
@ -711,8 +769,8 @@
|
||||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {577, 109}}</string>
|
||||
<string>{{577, 0}, {703, 109}}</string>
|
||||
<string>{{0, 0}, {577, 144}}</string>
|
||||
<string>{{577, 0}, {703, 144}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>VerticalSplitView</key>
|
||||
@ -727,8 +785,8 @@
|
||||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {1280, 109}}</string>
|
||||
<string>{{0, 109}, {1280, 153}}</string>
|
||||
<string>{{0, 0}, {1280, 144}}</string>
|
||||
<string>{{0, 144}, {1280, 201}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
@ -748,7 +806,7 @@
|
||||
<key>DebugSTDIOWindowFrame</key>
|
||||
<string>{{200, 200}, {500, 300}}</string>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 416}, {1280, 262}}</string>
|
||||
<string>{{0, 333}, {1280, 345}}</string>
|
||||
<key>PBXDebugSessionStackFrameViewKey</key>
|
||||
<dict>
|
||||
<key>DebugVariablesTableConfiguration</key>
|
||||
@ -761,13 +819,13 @@
|
||||
<real>410</real>
|
||||
</array>
|
||||
<key>Frame</key>
|
||||
<string>{{577, 0}, {703, 109}}</string>
|
||||
<string>{{577, 0}, {703, 144}}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXDebugSessionModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>262pt</string>
|
||||
<string>345pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
@ -785,14 +843,14 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>6BA687671222EAE200730711</string>
|
||||
<string>6BD402781224387200995864</string>
|
||||
<string>1CCC7628064C1048000F2A68</string>
|
||||
<string>1CCC7629064C1048000F2A68</string>
|
||||
<string>6BA687681222EAE200730711</string>
|
||||
<string>6BA687691222EAE200730711</string>
|
||||
<string>6BA6876A1222EAE200730711</string>
|
||||
<string>6BA6876B1222EAE200730711</string>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<string>6BD402791224387200995864</string>
|
||||
<string>6BD4027A1224387200995864</string>
|
||||
<string>6BD4027B1224387200995864</string>
|
||||
<string>6BD4027C1224387200995864</string>
|
||||
<string>6BD4027D1224387200995864</string>
|
||||
</array>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
|
@ -46,6 +46,7 @@
|
||||
6BB93C7F10CFE1D500F74F2B /* RecastDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93C7C10CFE1D500F74F2B /* RecastDebugDraw.cpp */; };
|
||||
6BB93CF610CFEC4500F74F2B /* RecastDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93CF510CFEC4500F74F2B /* RecastDump.cpp */; };
|
||||
6BCF32361104CD05009445BF /* OffMeshConnectionTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */; };
|
||||
6BD402011224279400995864 /* PerfTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BD402001224279400995864 /* PerfTimer.cpp */; };
|
||||
6BF5F23A11747606000502A6 /* Filelist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5F23911747606000502A6 /* Filelist.cpp */; };
|
||||
6BF5F2401174763B000502A6 /* SlideShow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5F23F1174763B000502A6 /* SlideShow.cpp */; };
|
||||
6BF7C1401111953A002B3F46 /* TestCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BF7C13F1111953A002B3F46 /* TestCase.cpp */; };
|
||||
@ -131,6 +132,8 @@
|
||||
6BB93CF510CFEC4500F74F2B /* RecastDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastDump.cpp; path = ../../../DebugUtils/Source/RecastDump.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BCF32341104CD05009445BF /* OffMeshConnectionTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OffMeshConnectionTool.h; path = ../../Include/OffMeshConnectionTool.h; sourceTree = SOURCE_ROOT; };
|
||||
6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OffMeshConnectionTool.cpp; path = ../../Source/OffMeshConnectionTool.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BD401FF1224278800995864 /* PerfTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerfTimer.h; path = ../../Include/PerfTimer.h; sourceTree = SOURCE_ROOT; };
|
||||
6BD402001224279400995864 /* PerfTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PerfTimer.cpp; path = ../../Source/PerfTimer.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BF5F23911747606000502A6 /* Filelist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Filelist.cpp; path = ../../Source/Filelist.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BF5F23C11747614000502A6 /* Filelist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Filelist.h; path = ../../Include/Filelist.h; sourceTree = SOURCE_ROOT; };
|
||||
6BF5F23E1174763B000502A6 /* SlideShow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SlideShow.h; path = ../../Include/SlideShow.h; sourceTree = SOURCE_ROOT; };
|
||||
@ -188,6 +191,8 @@
|
||||
6BB7FDA410F36F0E006DA0A6 /* InputGeom.cpp */,
|
||||
6BF7C13E11119520002B3F46 /* TestCase.h */,
|
||||
6BF7C13F1111953A002B3F46 /* TestCase.cpp */,
|
||||
6BD401FF1224278800995864 /* PerfTimer.h */,
|
||||
6BD402001224279400995864 /* PerfTimer.cpp */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
@ -441,6 +446,7 @@
|
||||
6BAF3C591211663A008CFCDF /* CrowdTool.cpp in Sources */,
|
||||
6BAF40DB12196A3D008CFCDF /* DetourNavMeshQuery.cpp in Sources */,
|
||||
6BAF4442121C3D26008CFCDF /* SampleInterfaces.cpp in Sources */,
|
||||
6BD402011224279400995864 /* PerfTimer.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -39,6 +39,8 @@ struct ObstacleBody
|
||||
float dp[3], np[3]; // Use for side selection during sampling.
|
||||
bool touch;
|
||||
int type; // Type of the obstacle (see ObstacleType)
|
||||
float dist;
|
||||
int idx;
|
||||
};
|
||||
|
||||
|
||||
@ -120,6 +122,34 @@ struct Agent
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Isect
|
||||
{
|
||||
float u;
|
||||
int inside;
|
||||
};
|
||||
|
||||
static const int FORM_MAX_ISECT = 32;
|
||||
static const int FORM_MAX_SEGS = 16;
|
||||
static const int FORM_MAX_POLYS = 32;
|
||||
|
||||
struct FormationSeg
|
||||
{
|
||||
float p[3], q[3];
|
||||
Isect ints[FORM_MAX_ISECT];
|
||||
int nints;
|
||||
};
|
||||
|
||||
struct Formation
|
||||
{
|
||||
FormationSeg segs[FORM_MAX_SEGS];
|
||||
int nsegs;
|
||||
dtPolyRef polys[FORM_MAX_POLYS];
|
||||
int npolys;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SampleGraph
|
||||
{
|
||||
static const int MAX_SAMPLES = 512;
|
||||
@ -211,6 +241,8 @@ class CrowdTool : public SampleTool
|
||||
float m_targetPos[3];
|
||||
bool m_targetPosSet;
|
||||
|
||||
Formation m_form;
|
||||
|
||||
bool m_expandDebugDraw;
|
||||
bool m_showLabels;
|
||||
bool m_showCorners;
|
||||
|
@ -55,9 +55,9 @@ public:
|
||||
InputGeom();
|
||||
~InputGeom();
|
||||
|
||||
bool loadMesh(struct rcBuildContext* ctx, const char* filepath);
|
||||
bool loadMesh(class rcContext* ctx, const char* filepath);
|
||||
|
||||
bool load(struct rcBuildContext* ctx, const char* filepath);
|
||||
bool load(class rcContext* ctx, const char* filepath);
|
||||
bool save(const char* filepath);
|
||||
|
||||
// Method to return static mesh data.
|
||||
|
@ -94,13 +94,13 @@ protected:
|
||||
|
||||
SampleTool* m_tool;
|
||||
|
||||
rcBuildContext* m_ctx;
|
||||
rcContext* m_ctx;
|
||||
|
||||
public:
|
||||
Sample();
|
||||
virtual ~Sample();
|
||||
|
||||
void setContext(rcBuildContext* ctx) { m_ctx = ctx; }
|
||||
void setContext(rcContext* ctx) { m_ctx = ctx; }
|
||||
|
||||
void setTool(SampleTool* tool);
|
||||
|
||||
|
@ -22,13 +22,15 @@
|
||||
#include "DebugDraw.h"
|
||||
#include "Recast.h"
|
||||
#include "RecastDump.h"
|
||||
#include "PerfTimer.h"
|
||||
|
||||
// These are example implementations of various interfaces used in Recast and Detour.
|
||||
|
||||
// Recast build context.
|
||||
class BuildContext : public rcBuildContext
|
||||
class BuildContext : public rcContext
|
||||
{
|
||||
int m_buildTime[RC_MAX_TIMES];
|
||||
TimeVal m_startTime[RC_MAX_TIMERS];
|
||||
int m_accTime[RC_MAX_TIMERS];
|
||||
|
||||
static const int MAX_MESSAGES = 1000;
|
||||
const char* m_messages[MAX_MESSAGES];
|
||||
@ -39,17 +41,8 @@ class BuildContext : public rcBuildContext
|
||||
|
||||
public:
|
||||
BuildContext();
|
||||
~BuildContext();
|
||||
virtual ~BuildContext();
|
||||
|
||||
// Get current time in platform specific units.
|
||||
virtual rcTimeVal getTime();
|
||||
// Returns time passed from 'start' to 'end' in microseconds.
|
||||
virtual int getDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end);
|
||||
|
||||
// Resets log.
|
||||
virtual void resetLog();
|
||||
// Logs a message.
|
||||
virtual void log(const rcLogCategory category, const char* format, ...);
|
||||
// Dumps the log to stdout.
|
||||
void dumpLog(const char* format, ...);
|
||||
// Returns number of log messages.
|
||||
@ -57,20 +50,16 @@ public:
|
||||
// Returns log message text.
|
||||
const char* getLogText(const int i) const;
|
||||
|
||||
// Resets build time collecting.
|
||||
virtual void resetBuildTimes();
|
||||
// Reports build time of specified label for accumulation.
|
||||
virtual void reportBuildTime(const rcBuildTimeLabel label, const int time);
|
||||
// Returns accumulated build time for specified label, or -1 if no time was reported.
|
||||
virtual int getBuildTime(const rcBuildTimeLabel label);
|
||||
protected:
|
||||
// Virtual functions for custom implementations.
|
||||
virtual void doResetLog();
|
||||
virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/);
|
||||
virtual void doResetTimers();
|
||||
virtual void doStartTimer(const rcTimerLabel /*label*/);
|
||||
virtual void doStopTimer(const rcTimerLabel /*label*/);
|
||||
virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const;
|
||||
};
|
||||
|
||||
|
||||
// TODO: Find better solution. This is useful for timing in some cases when the full build interface would be overkill.
|
||||
rcTimeVal getPerfTime();
|
||||
int getPerfDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end);
|
||||
|
||||
|
||||
// OpenGL debug draw implementation.
|
||||
class DebugDrawGL : public duDebugDraw
|
||||
{
|
||||
|
@ -20,7 +20,6 @@
|
||||
#define TESTCASE_H
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
#include "Recast.h"
|
||||
|
||||
class TestCase
|
||||
{
|
||||
@ -49,9 +48,9 @@ class TestCase
|
||||
dtPolyRef* polys;
|
||||
int npolys;
|
||||
|
||||
rcTimeVal findNearestPolyTime;
|
||||
rcTimeVal findPathTime;
|
||||
rcTimeVal findStraightPathTime;
|
||||
int findNearestPolyTime;
|
||||
int findPathTime;
|
||||
int findStraightPathTime;
|
||||
|
||||
Test* next;
|
||||
};
|
||||
@ -71,7 +70,7 @@ public:
|
||||
inline const char* getSampleName() const { return m_sampleName; }
|
||||
inline const char* getGeomFileName() const { return m_geomFileName; }
|
||||
|
||||
void doTests(rcBuildContext* ctx, class dtNavMesh* navmesh, class dtNavMeshQuery* navquery);
|
||||
void doTests(class dtNavMesh* navmesh, class dtNavMeshQuery* navquery);
|
||||
|
||||
void handleRender();
|
||||
bool handleRenderOverlay(double* proj, double* model, int* view);
|
||||
|
@ -208,25 +208,31 @@ void normalizeSamples(RVODebugData* rvo)
|
||||
}
|
||||
|
||||
|
||||
void setDynCircleBody(ObstacleBody* b, const float* pos, const float rad, const float* vel, const float* dvel)
|
||||
static void setDynCircleBody(ObstacleBody* b, const float* pos, const float rad, const float* vel, const float* dvel,
|
||||
const float dist, const int idx)
|
||||
{
|
||||
b->type = BODY_CIRCLE;
|
||||
dtVcopy(b->p, pos);
|
||||
dtVcopy(b->vel, vel);
|
||||
dtVcopy(b->dvel, dvel);
|
||||
b->rad = rad;
|
||||
b->dist = dist;
|
||||
b->idx = idx;
|
||||
}
|
||||
|
||||
void setStatCircleBody(ObstacleBody* b, const float* pos, const float rad)
|
||||
/*
|
||||
static void setStatCircleBody(ObstacleBody* b, const float* pos, const float rad)
|
||||
{
|
||||
b->type = BODY_CIRCLE;
|
||||
dtVcopy(b->p, pos);
|
||||
dtVset(b->vel, 0,0,0);
|
||||
dtVset(b->dvel, 0,0,0);
|
||||
b->rad = rad;
|
||||
b->idx = -1;
|
||||
}
|
||||
*/
|
||||
|
||||
void setStatSegmentBody(ObstacleBody* b, const float* p, const float* q)
|
||||
static void setStatSegmentBody(ObstacleBody* b, const float* p, const float* q)
|
||||
{
|
||||
b->type = BODY_SEGMENT;
|
||||
dtVcopy(b->p, p);
|
||||
@ -234,6 +240,7 @@ void setStatSegmentBody(ObstacleBody* b, const float* p, const float* q)
|
||||
dtVset(b->vel, 0,0,0);
|
||||
dtVset(b->dvel, 0,0,0);
|
||||
b->rad = 0;
|
||||
b->idx = -1;
|
||||
}
|
||||
|
||||
static const float VEL_WEIGHT = 2.0f;
|
||||
@ -473,6 +480,53 @@ void sampleRVO(ObstacleBody* agent, const float vmax, const ObstacleBody* obs,
|
||||
processSamples(agent, vmax, obs, nobs, rvo, spos, cs/2, nspos, nvel);
|
||||
}
|
||||
|
||||
static void sampleRVOAdaptive(ObstacleBody* agent, const float vmax, const ObstacleBody* obs,
|
||||
const int nobs, RVODebugData* rvo, const float bias, float* nvel)
|
||||
{
|
||||
dtVset(nvel, 0,0,0);
|
||||
|
||||
float spos[MAX_RVO_SAMPLES*3];
|
||||
int nspos = 0;
|
||||
|
||||
rvo->ns = 0;
|
||||
|
||||
int rad;
|
||||
float res[3];
|
||||
float cs;
|
||||
|
||||
// First sample location.
|
||||
rad = 4;
|
||||
res[0] = agent->dvel[0]*bias;
|
||||
res[1] = 0;
|
||||
res[2] = agent->dvel[2]*bias;
|
||||
cs = vmax*(2-bias*2) / (float)(rad-1);
|
||||
|
||||
for (int k = 0; k < 5; ++k)
|
||||
{
|
||||
const float half = (rad-1)*cs*0.5f;
|
||||
|
||||
nspos = 0;
|
||||
for (int y = 0; y < rad; ++y)
|
||||
{
|
||||
for (int x = 0; x < rad; ++x)
|
||||
{
|
||||
const float vx = res[0] + x*cs - half;
|
||||
const float vz = res[2] + y*cs - half;
|
||||
if (dtSqr(vx)+dtSqr(vz) > dtSqr(vmax+cs/2)) continue;
|
||||
spos[nspos*3+0] = vx;
|
||||
spos[nspos*3+1] = 0;
|
||||
spos[nspos*3+2] = vz;
|
||||
nspos++;
|
||||
}
|
||||
}
|
||||
|
||||
processSamples(agent, vmax, obs, nobs, rvo, spos, cs/2, nspos, res);
|
||||
|
||||
cs *= 0.5f;
|
||||
}
|
||||
|
||||
dtVcopy(nvel, res);
|
||||
}
|
||||
|
||||
|
||||
CrowdManager::CrowdManager() :
|
||||
@ -571,12 +625,48 @@ static void calcSmoothSteerDirection(const float* pos, const float* corners, con
|
||||
dvel[2] = dir0[2] - dir1[2]*len0*strength;
|
||||
}
|
||||
|
||||
/*static void sortBodies(ObstacleBody* arr, const int n)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 1; i < n; i++)
|
||||
{
|
||||
const ObstacleBody& v = arr[i];
|
||||
for (j = i - 1; j >= 0 && arr[j].dist > v.dist; j--)
|
||||
memcpy(&arr[j+1], &arr[j], sizeof(ObstacleBody));
|
||||
memcpy(&arr[j+1], &v, sizeof(ObstacleBody));
|
||||
}
|
||||
}*/
|
||||
|
||||
static ObstacleBody* insertBody(const float dist, ObstacleBody* obs, int& nobs)
|
||||
{
|
||||
ObstacleBody* ob = 0;
|
||||
if (!nobs || dist >= obs[nobs-1].dist)
|
||||
{
|
||||
ob = &obs[nobs];
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nobs; ++i)
|
||||
if (dist <= obs[i].dist)
|
||||
break;
|
||||
if (nobs-i > 0)
|
||||
memmove(obs+i+1, obs+i, sizeof(ObstacleBody)*(nobs-i));
|
||||
ob = &obs[i];
|
||||
}
|
||||
|
||||
nobs++;
|
||||
|
||||
return ob;
|
||||
}
|
||||
|
||||
|
||||
void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* navquery)
|
||||
{
|
||||
if (!navquery)
|
||||
return;
|
||||
|
||||
rcTimeVal startTime = getPerfTime();
|
||||
TimeVal startTime = getPerfTime();
|
||||
|
||||
const float ext[3] = {2,4,2};
|
||||
dtQueryFilter filter;
|
||||
@ -716,7 +806,7 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
||||
|
||||
if (!ag->ncorners)
|
||||
{
|
||||
// No corner to steer to,
|
||||
// No corner to steer to, stop.
|
||||
dtVset(ag->dvel, 0,0,0);
|
||||
}
|
||||
else
|
||||
@ -760,7 +850,7 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
||||
}
|
||||
|
||||
// Velocity planning.
|
||||
rcTimeVal rvoStartTime = getPerfTime();
|
||||
TimeVal rvoStartTime = getPerfTime();
|
||||
static const int MAX_BODIES = 32;
|
||||
ObstacleBody bodies[MAX_BODIES];
|
||||
for (int i = 0; i < MAX_AGENTS; ++i)
|
||||
@ -792,11 +882,14 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
||||
|
||||
if (nbodies < MAX_BODIES)
|
||||
{
|
||||
setDynCircleBody(&bodies[nbodies], nei->pos, nei->radius, nei->vel, nei->dvel);
|
||||
nbodies++;
|
||||
ObstacleBody* body = insertBody(dist, bodies, nbodies);
|
||||
setDynCircleBody(body, nei->pos, nei->radius, nei->vel, nei->dvel, dist, j);
|
||||
}
|
||||
}
|
||||
|
||||
// Prune mas number of neighbours.
|
||||
nbodies = dtMin(nbodies, 6);
|
||||
|
||||
// Add static obstacles.
|
||||
for (int j = 0; j < ag->ncolsegs; ++j)
|
||||
{
|
||||
@ -812,20 +905,16 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
||||
}
|
||||
|
||||
ObstacleBody agent;
|
||||
setDynCircleBody(&agent, ag->pos, ag->radius, ag->vel, ag->dvel);
|
||||
setDynCircleBody(&agent, ag->pos, ag->radius, ag->vel, ag->dvel, 0, -1);
|
||||
prepareBodies(&agent, bodies, nbodies);
|
||||
sampleRVO(&agent, ag->maxspeed, bodies, nbodies, &ag->rvo, 0.4f, ag->nvel);
|
||||
|
||||
// Normalize samples for debug draw
|
||||
normalizeSamples(&ag->rvo);
|
||||
sampleRVOAdaptive(&agent, ag->maxspeed, bodies, nbodies, &ag->rvo, 0.4f, ag->nvel);
|
||||
}
|
||||
else
|
||||
{
|
||||
dtVcopy(ag->nvel, ag->dvel);
|
||||
}
|
||||
}
|
||||
rcTimeVal rvoEndTime = getPerfTime();
|
||||
m_rvoTime.addSample(getPerfDeltaTimeUsec(rvoStartTime, rvoEndTime) / 1000.0f);
|
||||
TimeVal rvoEndTime = getPerfTime();
|
||||
|
||||
// Integrate and update perceived velocity.
|
||||
for (int i = 0; i < MAX_AGENTS; ++i)
|
||||
@ -964,12 +1053,117 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = getPerfTime();
|
||||
TimeVal endTime = getPerfTime();
|
||||
|
||||
for (int i = 0; i < MAX_AGENTS; ++i)
|
||||
{
|
||||
if (!m_agents[i].active) continue;
|
||||
if (m_agents[i].targetState != AGENT_TARGET_PATH) continue;
|
||||
Agent* ag = &m_agents[i];
|
||||
if (flags & CROWDMAN_USE_VO)
|
||||
{
|
||||
// Normalize samples for debug draw
|
||||
normalizeSamples(&ag->rvo);
|
||||
}
|
||||
}
|
||||
|
||||
m_totalTime.addSample(getPerfDeltaTimeUsec(startTime, endTime) / 1000.0f);
|
||||
m_rvoTime.addSample(getPerfDeltaTimeUsec(rvoStartTime, rvoEndTime) / 1000.0f);
|
||||
}
|
||||
|
||||
static int insertIsect(float u, int inside, Isect* ints, int nints)
|
||||
{
|
||||
int i;
|
||||
if (nints >= FORM_MAX_ISECT) return nints;
|
||||
if (!nints || u >= ints[nints-1].u)
|
||||
{
|
||||
ints[nints].u = u;
|
||||
ints[nints].inside = inside;
|
||||
return nints+1;
|
||||
}
|
||||
for (i = 0; i < nints; ++i)
|
||||
if (u <= ints[i].u) break;
|
||||
if (nints-i > 0) memmove(ints+i+1,ints+i,sizeof(Isect)*(nints-i));
|
||||
ints[i].u = u;
|
||||
ints[i].inside = inside;
|
||||
return nints+1;
|
||||
}
|
||||
|
||||
static int removeAdjacent(Isect* ints, int nints)
|
||||
{
|
||||
const float eps = 0.0001f;
|
||||
if (nints < 2)
|
||||
return nints;
|
||||
for (int i = 0; i < nints-1; ++i)
|
||||
{
|
||||
if (fabsf(ints[i].u - ints[i+1].u) < eps) // && ints[i].inside != ints[i+1].inside)
|
||||
{
|
||||
nints -= 2;
|
||||
for (int j = i; j < nints; ++j)
|
||||
ints[j] = ints[j+2];
|
||||
// if (nints-i > 0) memmove(ints+i,ints+i+2,sizeof(Isect)*(nints-i));
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return nints;
|
||||
}
|
||||
|
||||
static int getPolyVerts(const dtNavMesh* navMesh, dtPolyRef ref, float* verts)
|
||||
{
|
||||
const dtMeshTile* tile = 0;
|
||||
const dtPoly* poly = 0;
|
||||
if (!navMesh->getTileAndPolyByRef(ref, &tile, &poly))
|
||||
return 0;
|
||||
for (int i = 0; i < (int)poly->vertCount; ++i)
|
||||
dtVcopy(&verts[i*3], &tile->verts[poly->verts[i]*3]);
|
||||
return poly->vertCount;
|
||||
}
|
||||
|
||||
static void createFormation(Formation* form, const dtNavMesh* navmesh)
|
||||
{
|
||||
float verts[DT_VERTS_PER_POLYGON*3];
|
||||
for (int i = 0; i < form->nsegs; i++)
|
||||
{
|
||||
FormationSeg* seg = &form->segs[i];
|
||||
seg->nints = 0;
|
||||
|
||||
int startInside = 0;
|
||||
|
||||
for (int j = 0; j < form->npolys; ++j)
|
||||
{
|
||||
const int nverts = getPolyVerts(navmesh, form->polys[j], verts);
|
||||
if (!nverts) continue;
|
||||
|
||||
float tmin, tmax;
|
||||
int smin, smax;
|
||||
bool res = dtIntersectSegmentPoly2D(seg->p, seg->q, verts, nverts, tmin, tmax, smin, smax);
|
||||
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
if (tmin >= 0.0f && tmin <= 1.0f)
|
||||
seg->nints = insertIsect(tmin, 1, seg->ints, seg->nints);
|
||||
if (tmax >= 0.0f && tmax <= 1.0f)
|
||||
seg->nints = insertIsect(tmax, -1, seg->ints, seg->nints);
|
||||
if (tmin < 0.0f && tmax > 0.0f)
|
||||
startInside++;
|
||||
}
|
||||
|
||||
seg->nints = removeAdjacent(seg->ints, seg->nints);
|
||||
}
|
||||
|
||||
// Calc winding
|
||||
for (int i = 0; i < form->nsegs; ++i)
|
||||
{
|
||||
FormationSeg* seg = &form->segs[i];
|
||||
int inside = 0;
|
||||
for (int j = 0; j < seg->nints; ++j)
|
||||
{
|
||||
inside += seg->ints[j].inside;
|
||||
seg->ints[j].inside = inside;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CrowdTool::CrowdTool() :
|
||||
m_sample(0),
|
||||
@ -989,6 +1183,7 @@ CrowdTool::CrowdTool() :
|
||||
m_run(true),
|
||||
m_mode(TOOLMODE_CREATE)
|
||||
{
|
||||
memset(&m_form, 0, sizeof(Formation));
|
||||
}
|
||||
|
||||
CrowdTool::~CrowdTool()
|
||||
@ -1105,9 +1300,77 @@ void CrowdTool::handleClick(const float* s, const float* p, bool shift)
|
||||
else
|
||||
{
|
||||
// Add
|
||||
int idx = m_crowd.addAgent(p, m_sample->getAgentRadius(), m_sample->getAgentHeight());
|
||||
/* int idx = m_crowd.addAgent(p, m_sample->getAgentRadius(), m_sample->getAgentHeight());
|
||||
if (idx != -1 && m_targetPosSet)
|
||||
m_crowd.setMoveTarget(idx, m_targetPos);
|
||||
m_crowd.setMoveTarget(idx, m_targetPos);*/
|
||||
|
||||
const dtNavMesh* navmesh = m_sample->getNavMesh();
|
||||
const dtNavMeshQuery* navquery = m_sample->getNavMeshQuery();
|
||||
|
||||
memset(&m_form, 0, sizeof(Formation));
|
||||
|
||||
const float ext[3] = {2,4,2};
|
||||
dtQueryFilter filter;
|
||||
|
||||
const float r = m_sample->getAgentRadius();
|
||||
|
||||
float nearest[3];
|
||||
dtPolyRef centerRef = navquery->findNearestPoly(p, ext, &filter, nearest);
|
||||
if (centerRef)
|
||||
{
|
||||
const int rows = 6;
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
const float x0 = -r*2.5f*rows/2 + (i&1)*r;
|
||||
const float x1 = r*2.5f*rows/2 + (i&1)*r;
|
||||
const float z = (i-rows*0.5f)*r*2.5f;
|
||||
dtVset(m_form.segs[m_form.nsegs].p, p[0]+x0, p[1]+2.0f, p[2]+z);
|
||||
dtVset(m_form.segs[m_form.nsegs].q, p[0]+x1, p[1]+2.0f, p[2]+z);
|
||||
m_form.nsegs++;
|
||||
}
|
||||
|
||||
m_form.npolys = navquery->findLocalNeighbourhood(centerRef, p, r*rows*2.5f, &filter, m_form.polys, 0, FORM_MAX_POLYS);
|
||||
|
||||
createFormation(&m_form, navmesh);
|
||||
|
||||
const int createCount = 25;
|
||||
int num = 0;
|
||||
|
||||
const float r = m_sample->getAgentRadius();
|
||||
for (int i = 0; i < m_form.nsegs; ++i)
|
||||
{
|
||||
const FormationSeg* seg = &m_form.segs[i];
|
||||
for (int j = 0; j < seg->nints-1; ++j)
|
||||
{
|
||||
if (seg->ints[j].inside == 0) continue;
|
||||
const float u0 = seg->ints[j].u;
|
||||
const float u1 = seg->ints[j+1].u;
|
||||
float ia[3], ib[3];
|
||||
dtVlerp(ia, seg->p,seg->q, u0);
|
||||
dtVlerp(ib, seg->p,seg->q, u1);
|
||||
|
||||
const float spacing = r*2.5f;
|
||||
float delta[3];
|
||||
dtVsub(delta, ib,ia);
|
||||
float d = dtVlen(delta);
|
||||
int np = (int)floorf(d/spacing);
|
||||
for (int k = 0; k < np; ++k)
|
||||
{
|
||||
float pos[3];
|
||||
dtVmad(pos, ia, delta, (float)(k+0.5f)/(float)np);
|
||||
|
||||
if (num < createCount)
|
||||
{
|
||||
num++;
|
||||
int idx = m_crowd.addAgent(pos, m_sample->getAgentRadius(), m_sample->getAgentHeight());
|
||||
if (idx != -1 && m_targetPosSet)
|
||||
m_crowd.setMoveTarget(idx, m_targetPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_mode == TOOLMODE_MOVE)
|
||||
@ -1306,6 +1569,91 @@ void CrowdTool::handleRender()
|
||||
|
||||
dd.depthMask(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for (int i = 0; i < m_form.npolys; ++i)
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, *nmesh, m_form.polys[i], duRGBA(255,255,255,32));
|
||||
}
|
||||
|
||||
dd.depthMask(false);
|
||||
|
||||
dd.begin(DU_DRAW_POINTS, 4.0f);
|
||||
for (int i = 0; i < m_form.nsegs; ++i)
|
||||
{
|
||||
const FormationSeg* seg = &m_form.segs[i];
|
||||
for (int j = 0; j < seg->nints-1; ++j)
|
||||
{
|
||||
if (seg->ints[j].inside == 0) continue;
|
||||
const float u0 = seg->ints[j].u;
|
||||
const float u1 = seg->ints[j+1].u;
|
||||
float ia[3], ib[3];
|
||||
dtVlerp(ia, seg->p,seg->q, u0);
|
||||
dtVlerp(ib, seg->p,seg->q, u1);
|
||||
dd.vertex(ia,duRGBA(128,0,0,192));
|
||||
dd.vertex(ib,duRGBA(128,0,0,192));
|
||||
}
|
||||
}
|
||||
dd.end();
|
||||
|
||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int i = 0; i < m_form.nsegs; ++i)
|
||||
{
|
||||
const FormationSeg* seg = &m_form.segs[i];
|
||||
dd.vertex(seg->p,duRGBA(255,255,255,128));
|
||||
dd.vertex(seg->q,duRGBA(255,255,255,128));
|
||||
for (int j = 0; j < seg->nints-1; ++j)
|
||||
{
|
||||
if (seg->ints[j].inside == 0) continue;
|
||||
const float u0 = seg->ints[j].u;
|
||||
const float u1 = seg->ints[j+1].u;
|
||||
float ia[3], ib[3];
|
||||
dtVlerp(ia, seg->p,seg->q, u0);
|
||||
dtVlerp(ib, seg->p,seg->q, u1);
|
||||
dd.vertex(ia,duRGBA(128,0,0,192));
|
||||
dd.vertex(ib,duRGBA(128,0,0,192));
|
||||
}
|
||||
}
|
||||
dd.end();
|
||||
|
||||
{
|
||||
const float r = m_sample->getAgentRadius();
|
||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int i = 0; i < m_form.nsegs; ++i)
|
||||
{
|
||||
const FormationSeg* seg = &m_form.segs[i];
|
||||
dd.vertex(seg->p,duRGBA(255,255,255,128));
|
||||
dd.vertex(seg->q,duRGBA(255,255,255,128));
|
||||
for (int j = 0; j < seg->nints-1; ++j)
|
||||
{
|
||||
if (seg->ints[j].inside == 0) continue;
|
||||
const float u0 = seg->ints[j].u;
|
||||
const float u1 = seg->ints[j+1].u;
|
||||
float ia[3], ib[3];
|
||||
dtVlerp(ia, seg->p,seg->q, u0);
|
||||
dtVlerp(ib, seg->p,seg->q, u1);
|
||||
|
||||
const float spacing = r*2.5f;
|
||||
float delta[3];
|
||||
dtVsub(delta, ib,ia);
|
||||
float d = dtVlen(delta);
|
||||
int np = (int)floorf(d/spacing);
|
||||
for (int k = 0; k < np; ++k)
|
||||
{
|
||||
float pos[3];
|
||||
dtVmad(pos, ia, delta, (float)(k+0.5f)/(float)np);
|
||||
dd.vertex(pos[0],pos[1]-1,pos[2],duRGBA(128,0,0,192));
|
||||
dd.vertex(pos[0],pos[1]+2,pos[2],duRGBA(128,0,0,192));
|
||||
}
|
||||
}
|
||||
}
|
||||
dd.end();
|
||||
}
|
||||
|
||||
dd.depthMask(true);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1401,7 +1749,7 @@ void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
}
|
||||
|
||||
const int gx = 300, gy = 10, gw = 500, gh = 200;
|
||||
const float vmin = 0.0f, vmax = 10.0f;
|
||||
const float vmin = 0.0f, vmax = 2.0f;
|
||||
|
||||
drawGraphBackground(gx,gy,gw,gh, vmin,vmax, 4, "ms");
|
||||
drawGraph(m_crowd.getRVOTimeGraph(), gx,gy,gw,gh, vmin,vmax, duRGBA(255,0,0,128));
|
||||
|
@ -118,7 +118,7 @@ InputGeom::~InputGeom()
|
||||
delete m_mesh;
|
||||
}
|
||||
|
||||
bool InputGeom::loadMesh(rcBuildContext* ctx, const char* filepath)
|
||||
bool InputGeom::loadMesh(rcContext* ctx, const char* filepath)
|
||||
{
|
||||
if (m_mesh)
|
||||
{
|
||||
@ -159,7 +159,7 @@ bool InputGeom::loadMesh(rcBuildContext* ctx, const char* filepath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputGeom::load(rcBuildContext* ctx, const char* filePath)
|
||||
bool InputGeom::load(rcContext* ctx, const char* filePath)
|
||||
{
|
||||
char* buf = 0;
|
||||
FILE* fp = fopen(filePath, "rb");
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "Recast.h"
|
||||
#include "RecastDebugDraw.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "PerfTimer.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
|
||||
@ -19,64 +20,23 @@ BuildContext::BuildContext() :
|
||||
m_messageCount(0),
|
||||
m_textPoolSize(0)
|
||||
{
|
||||
resetBuildTimes();
|
||||
resetTimers();
|
||||
}
|
||||
|
||||
BuildContext::~BuildContext()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
// Win32
|
||||
#include <windows.h>
|
||||
|
||||
rcTimeVal BuildContext::getTime()
|
||||
{
|
||||
__int64 count;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&count);
|
||||
return count;
|
||||
}
|
||||
|
||||
int BuildContext::getDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
||||
{
|
||||
static __int64 freq = 0;
|
||||
if (freq == 0)
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
|
||||
__int64 elapsed = end - start;
|
||||
return (int)(elapsed*1000000 / freq);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Linux, BSD, OSX
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
rcTimeVal BuildContext::getTime()
|
||||
{
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
return (rcTimeVal)now.tv_sec*1000000L + (rcTimeVal)now.tv_usec;
|
||||
}
|
||||
|
||||
int BuildContext::getDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
||||
{
|
||||
return (int)(end - start);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void BuildContext::resetLog()
|
||||
// Virtual functions for custom implementations.
|
||||
void BuildContext::doResetLog()
|
||||
{
|
||||
m_messageCount = 0;
|
||||
m_textPoolSize = 0;
|
||||
}
|
||||
|
||||
void BuildContext::log(const rcLogCategory category, const char* format, ...)
|
||||
void BuildContext::doLog(const rcLogCategory category, const char* msg, const int len)
|
||||
{
|
||||
if (!len) return;
|
||||
if (m_messageCount >= MAX_MESSAGES)
|
||||
return;
|
||||
char* dst = &m_textPool[m_textPoolSize];
|
||||
@ -87,15 +47,39 @@ void BuildContext::log(const rcLogCategory category, const char* format, ...)
|
||||
*dst = (char)category;
|
||||
n--;
|
||||
// Store message
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
int ret = vsnprintf(dst+1, n-1, format, ap);
|
||||
va_end(ap);
|
||||
if (ret > 0)
|
||||
m_textPoolSize += ret+2;
|
||||
const int count = rcMin(len+1, n);
|
||||
memcpy(dst+1, msg, count);
|
||||
dst[count+1] = '\0';
|
||||
m_textPoolSize += count+1;
|
||||
m_messages[m_messageCount++] = dst;
|
||||
}
|
||||
|
||||
void BuildContext::doResetTimers()
|
||||
{
|
||||
for (int i = 0; i < RC_MAX_TIMERS; ++i)
|
||||
m_accTime[i] = -1;
|
||||
}
|
||||
|
||||
void BuildContext::doStartTimer(const rcTimerLabel label)
|
||||
{
|
||||
m_startTime[label] = getPerfTime();
|
||||
}
|
||||
|
||||
void BuildContext::doStopTimer(const rcTimerLabel label)
|
||||
{
|
||||
const TimeVal endTime = getPerfTime();
|
||||
const int deltaTime = endTime - m_startTime[label];
|
||||
if (m_accTime[label] == -1)
|
||||
m_accTime[label] = deltaTime;
|
||||
else
|
||||
m_accTime[label] += deltaTime;
|
||||
}
|
||||
|
||||
int BuildContext::doGetAccumulatedTime(const rcTimerLabel label) const
|
||||
{
|
||||
return m_accTime[label];
|
||||
}
|
||||
|
||||
void BuildContext::dumpLog(const char* format, ...)
|
||||
{
|
||||
// Print header.
|
||||
@ -150,70 +134,6 @@ const char* BuildContext::getLogText(const int i) const
|
||||
{
|
||||
return m_messages[i]+1;
|
||||
}
|
||||
|
||||
void BuildContext::resetBuildTimes()
|
||||
{
|
||||
for (int i = 0; i < RC_MAX_TIMES; ++i)
|
||||
m_buildTime[i] = -1;
|
||||
}
|
||||
|
||||
void BuildContext::reportBuildTime(const rcBuildTimeLabel label, const int time)
|
||||
{
|
||||
const int idx = (int)label;
|
||||
// The build times are initialized to negative to indicate no samples collected.
|
||||
if (m_buildTime[idx] < 0)
|
||||
m_buildTime[idx] = time;
|
||||
else
|
||||
m_buildTime[idx] += time;
|
||||
}
|
||||
|
||||
int BuildContext::getBuildTime(const rcBuildTimeLabel label)
|
||||
{
|
||||
return m_buildTime[label];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
// Win32
|
||||
#include <windows.h>
|
||||
|
||||
rcTimeVal getPerfTime()
|
||||
{
|
||||
__int64 count;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&count);
|
||||
return count;
|
||||
}
|
||||
|
||||
int getPerfDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
||||
{
|
||||
static __int64 freq = 0;
|
||||
if (freq == 0)
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
|
||||
__int64 elapsed = end - start;
|
||||
return (int)(elapsed*1000000 / freq);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Linux, BSD, OSX
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
rcTimeVal getPerfTime()
|
||||
{
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
return (rcTimeVal)now.tv_sec*1000000L + (rcTimeVal)now.tv_usec;
|
||||
}
|
||||
|
||||
int getPerfDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
||||
{
|
||||
return (int)(end - start);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -138,7 +138,7 @@ Sample_Debug::Sample_Debug() :
|
||||
if (m_cset)
|
||||
{
|
||||
FileIO io;
|
||||
if (io.openForRead("remove_vertex_issue_contour_cache.rc"))
|
||||
if (io.openForRead("PathSet_TMP_NA_PathingTestAReg1_1_2_CS.rc"))
|
||||
{
|
||||
duReadContourSet(*m_cset, &io);
|
||||
|
||||
@ -158,14 +158,14 @@ Sample_Debug::Sample_Debug() :
|
||||
}
|
||||
|
||||
|
||||
if (m_cset)
|
||||
/* if (m_cset)
|
||||
{
|
||||
m_pmesh = rcAllocPolyMesh();
|
||||
if (m_pmesh)
|
||||
{
|
||||
rcBuildPolyMesh(m_ctx, *m_cset, 6, *m_pmesh);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
@ -214,7 +214,7 @@ void Sample_Debug::handleRender()
|
||||
if (m_cset)
|
||||
{
|
||||
duDebugDrawRawContours(&dd, *m_cset, 0.25f);
|
||||
// duDebugDrawContours(&dd, *m_cset);
|
||||
duDebugDrawContours(&dd, *m_cset);
|
||||
}
|
||||
|
||||
if (m_pmesh)
|
||||
|
@ -389,10 +389,10 @@ bool Sample_SoloMeshSimple::handleBuild()
|
||||
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
|
||||
|
||||
// Reset build times gathering.
|
||||
m_ctx->resetBuildTimes();
|
||||
m_ctx->resetTimers();
|
||||
|
||||
// Start the build process.
|
||||
rcTimeVal totStartTime = m_ctx->getTime();
|
||||
m_ctx->startTimer(RC_TIMER_TOTAL);
|
||||
|
||||
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
|
||||
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
|
||||
@ -653,13 +653,13 @@ bool Sample_SoloMeshSimple::handleBuild()
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal totEndTime = m_ctx->getTime();
|
||||
m_ctx->stopTimer(RC_TIMER_TOTAL);
|
||||
|
||||
// Show performance stats.
|
||||
duLogBuildTimes(m_ctx, m_ctx->getDeltaTimeUsec(totStartTime, totEndTime));
|
||||
duLogBuildTimes(*m_ctx, m_ctx->getAccumulatedTime(RC_TIMER_TOTAL));
|
||||
m_ctx->log(RC_LOG_PROGRESS, ">> Polymesh: %d vertices %d polygons", m_pmesh->nverts, m_pmesh->npolys);
|
||||
|
||||
m_totalBuildTimeMs = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
|
||||
m_totalBuildTimeMs = m_ctx->getAccumulatedTime(RC_TIMER_TOTAL)/1000.0f;
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
|
@ -736,10 +736,10 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
|
||||
|
||||
// Reset build times gathering.
|
||||
m_ctx->resetBuildTimes();
|
||||
m_ctx->resetTimers();
|
||||
|
||||
// Start the build process.
|
||||
rcTimeVal totStartTime = m_ctx->getTime();
|
||||
m_ctx->startTimer(RC_TIMER_TOTAL);
|
||||
|
||||
// Calculate the number of tiles in the output and initialize tiles.
|
||||
m_tileSet = new TileSet;
|
||||
@ -785,7 +785,7 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
{
|
||||
for (int x = 0; x < m_tileSet->width; ++x)
|
||||
{
|
||||
rcTimeVal startTime = m_ctx->getTime();
|
||||
m_ctx->startTimer(RC_TIMER_TEMP);
|
||||
|
||||
Tile& tile = m_tileSet->tiles[x + y*m_tileSet->width];
|
||||
tile.x = x;
|
||||
@ -920,8 +920,9 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
tile.cset = 0;
|
||||
}
|
||||
|
||||
rcTimeVal endTime = m_ctx->getTime();
|
||||
tile.buildTime += m_ctx->getDeltaTimeUsec(startTime, endTime);
|
||||
m_ctx->stopTimer(RC_TIMER_TOTAL);
|
||||
|
||||
tile.buildTime += m_ctx->getAccumulatedTime(RC_TIMER_TOTAL);
|
||||
|
||||
// Some extra code to measure some per tile statistics,
|
||||
// such as build time and how many polygons there are per tile.
|
||||
@ -1092,12 +1093,12 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal totEndTime = m_ctx->getTime();
|
||||
m_ctx->stopTimer(RC_TIMER_TOTAL);
|
||||
|
||||
duLogBuildTimes(m_ctx, m_ctx->getDeltaTimeUsec(totStartTime, totEndTime));
|
||||
duLogBuildTimes(*m_ctx, m_ctx->getAccumulatedTime(RC_TIMER_TOTAL));
|
||||
m_ctx->log(RC_LOG_PROGRESS, ">> Polymesh: %d vertices %d polygons", m_pmesh->nverts, m_pmesh->npolys);
|
||||
|
||||
m_totalBuildTimeMs = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
|
||||
m_totalBuildTimeMs = m_ctx->getAccumulatedTime(RC_TIMER_TOTAL)/1000.0f;
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
|
@ -818,8 +818,8 @@ void Sample_TileMesh::buildAllTiles()
|
||||
const float tcs = m_tileSize*m_cellSize;
|
||||
|
||||
|
||||
// Start the build process.
|
||||
rcTimeVal totStartTime = m_ctx->getTime();
|
||||
// Start the build process.
|
||||
m_ctx->startTimer(RC_TIMER_TEMP);
|
||||
|
||||
for (int y = 0; y < th; ++y)
|
||||
{
|
||||
@ -847,9 +847,9 @@ void Sample_TileMesh::buildAllTiles()
|
||||
}
|
||||
|
||||
// Start the build process.
|
||||
rcTimeVal totEndTime = m_ctx->getTime();
|
||||
m_ctx->startTimer(RC_TIMER_TEMP);
|
||||
|
||||
m_totalBuildTimeMs = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
|
||||
m_totalBuildTimeMs = m_ctx->getAccumulatedTime(RC_TIMER_TEMP)/1000.0f;
|
||||
}
|
||||
|
||||
void Sample_TileMesh::removeAllTiles()
|
||||
@ -913,10 +913,10 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
|
||||
m_cfg.bmax[2] += m_cfg.borderSize*m_cfg.cs;
|
||||
|
||||
// Reset build times gathering.
|
||||
m_ctx->resetBuildTimes();
|
||||
m_ctx->resetTimers();
|
||||
|
||||
// Start the build process.
|
||||
rcTimeVal totStartTime = m_ctx->getTime();
|
||||
// Start the build process.
|
||||
m_ctx->startTimer(RC_TIMER_TOTAL);
|
||||
|
||||
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
|
||||
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
|
||||
@ -1176,13 +1176,13 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
|
||||
}
|
||||
m_tileMemUsage = navDataSize/1024.0f;
|
||||
|
||||
rcTimeVal totEndTime = m_ctx->getTime();
|
||||
m_ctx->stopTimer(RC_TIMER_TOTAL);
|
||||
|
||||
// Show performance stats.
|
||||
duLogBuildTimes(m_ctx, m_ctx->getDeltaTimeUsec(totStartTime, totEndTime));
|
||||
duLogBuildTimes(*m_ctx, m_ctx->getAccumulatedTime(RC_TIMER_TOTAL));
|
||||
m_ctx->log(RC_LOG_PROGRESS, ">> Polymesh: %d vertices %d polygons", m_pmesh->nverts, m_pmesh->npolys);
|
||||
|
||||
m_tileBuildTime = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
|
||||
m_tileBuildTime = m_ctx->getAccumulatedTime(RC_TIMER_TOTAL)/1000.0f;
|
||||
|
||||
dataSize = navDataSize;
|
||||
return navData;
|
||||
|
@ -23,10 +23,11 @@
|
||||
#include "TestCase.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "imgui.h"
|
||||
#include "Recast.h"
|
||||
#include "PerfTimer.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
@ -157,7 +158,7 @@ void TestCase::resetTimes()
|
||||
}
|
||||
}
|
||||
|
||||
void TestCase::doTests(rcBuildContext* ctx, dtNavMesh* navmesh, dtNavMeshQuery* navquery)
|
||||
void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
|
||||
{
|
||||
if (!navmesh || !navquery)
|
||||
return;
|
||||
@ -183,34 +184,34 @@ void TestCase::doTests(rcBuildContext* ctx, dtNavMesh* navmesh, dtNavMeshQuery*
|
||||
filter.setExcludeFlags((unsigned short)iter->excludeFlags);
|
||||
|
||||
// Find start points
|
||||
rcTimeVal findNearestPolyStart = ctx->getTime();
|
||||
TimeVal findNearestPolyStart = getPerfTime();
|
||||
|
||||
dtPolyRef startRef = navquery->findNearestPoly(iter->spos, polyPickExt, &filter, 0);
|
||||
dtPolyRef endRef = navquery->findNearestPoly(iter->epos, polyPickExt, &filter, 0);
|
||||
|
||||
rcTimeVal findNearestPolyEnd = ctx->getTime();
|
||||
iter->findNearestPolyTime += ctx->getDeltaTimeUsec(findNearestPolyStart, findNearestPolyEnd);
|
||||
TimeVal findNearestPolyEnd = getPerfTime();
|
||||
iter->findNearestPolyTime += getPerfDeltaTimeUsec(findNearestPolyStart, findNearestPolyEnd);
|
||||
|
||||
if (!startRef || ! endRef)
|
||||
continue;
|
||||
|
||||
// Find path
|
||||
rcTimeVal findPathStart = ctx->getTime();
|
||||
TimeVal findPathStart = getPerfTime();
|
||||
|
||||
iter->npolys = navquery->findPath(startRef, endRef, iter->spos, iter->epos, &filter, polys, MAX_POLYS);
|
||||
|
||||
rcTimeVal findPathEnd = ctx->getTime();
|
||||
iter->findPathTime += ctx->getDeltaTimeUsec(findPathStart, findPathEnd);
|
||||
TimeVal findPathEnd = getPerfTime();
|
||||
iter->findPathTime += getPerfDeltaTimeUsec(findPathStart, findPathEnd);
|
||||
|
||||
// Find straight path
|
||||
if (iter->npolys)
|
||||
{
|
||||
rcTimeVal findStraightPathStart = ctx->getTime();
|
||||
TimeVal findStraightPathStart = getPerfTime();
|
||||
|
||||
iter->nstraight = navquery->findStraightPath(iter->spos, iter->epos, polys, iter->npolys,
|
||||
straight, 0, 0, MAX_POLYS);
|
||||
rcTimeVal findStraightPathEnd = ctx->getTime();
|
||||
iter->findStraightPathTime += ctx->getDeltaTimeUsec(findStraightPathStart, findStraightPathEnd);
|
||||
TimeVal findStraightPathEnd = getPerfTime();
|
||||
iter->findStraightPathTime += getPerfDeltaTimeUsec(findStraightPathStart, findStraightPathEnd);
|
||||
}
|
||||
|
||||
// Copy results
|
||||
@ -231,7 +232,7 @@ void TestCase::doTests(rcBuildContext* ctx, dtNavMesh* navmesh, dtNavMeshQuery*
|
||||
int n = 0;
|
||||
for (Test* iter = m_tests; iter; iter = iter->next)
|
||||
{
|
||||
rcTimeVal total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
|
||||
const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
|
||||
printf(" - Path %02d: %.4f ms\n", n, (float)total/1000.0f);
|
||||
printf(" - poly: %.4f ms\n", (float)iter->findNearestPolyTime/1000.0f);
|
||||
printf(" - path: %.4f ms\n", (float)iter->findPathTime/1000.0f);
|
||||
@ -247,8 +248,8 @@ void TestCase::handleRender()
|
||||
for (Test* iter = m_tests; iter; iter = iter->next)
|
||||
{
|
||||
float dir[3];
|
||||
rcVsub(dir, iter->epos, iter->spos);
|
||||
rcVnormalize(dir);
|
||||
dtVsub(dir, iter->epos, iter->spos);
|
||||
dtVnormalize(dir);
|
||||
glColor4ub(128,25,0,192);
|
||||
glVertex3f(iter->spos[0],iter->spos[1]-0.3f,iter->spos[2]);
|
||||
glVertex3f(iter->spos[0],iter->spos[1]+0.3f,iter->spos[2]);
|
||||
@ -286,20 +287,20 @@ bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
float pt[3], dir[3];
|
||||
if (iter->nstraight)
|
||||
{
|
||||
rcVcopy(pt, &iter->straight[3]);
|
||||
if (rcVdist(pt, iter->spos) > LABEL_DIST)
|
||||
dtVcopy(pt, &iter->straight[3]);
|
||||
if (dtVdist(pt, iter->spos) > LABEL_DIST)
|
||||
{
|
||||
rcVsub(dir, pt, iter->spos);
|
||||
rcVnormalize(dir);
|
||||
rcVmad(pt, iter->spos, dir, LABEL_DIST);
|
||||
dtVsub(dir, pt, iter->spos);
|
||||
dtVnormalize(dir);
|
||||
dtVmad(pt, iter->spos, dir, LABEL_DIST);
|
||||
}
|
||||
pt[1]+=0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
rcVsub(dir, iter->epos, iter->spos);
|
||||
rcVnormalize(dir);
|
||||
rcVmad(pt, iter->spos, dir, LABEL_DIST);
|
||||
dtVsub(dir, iter->epos, iter->spos);
|
||||
dtVnormalize(dir);
|
||||
dtVmad(pt, iter->spos, dir, LABEL_DIST);
|
||||
pt[1]+=0.5f;
|
||||
}
|
||||
|
||||
@ -322,7 +323,7 @@ bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
n = 0;
|
||||
for (Test* iter = m_tests; iter; iter = iter->next)
|
||||
{
|
||||
rcTimeVal total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
|
||||
const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
|
||||
snprintf(subtext, 64, "%.4f ms", (float)total/1000.0f);
|
||||
snprintf(text, 64, "Path %d", n);
|
||||
|
||||
|
@ -852,7 +852,7 @@ int main(int /*argc*/, char** /*argv*/)
|
||||
|
||||
// Do the tests.
|
||||
if (sample)
|
||||
test->doTests(&ctx, sample->getNavMesh(), sample->getNavMeshQuery());
|
||||
test->doTests(sample->getNavMesh(), sample->getNavMeshQuery());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user