Missing files for R197

This commit is contained in:
Mikko Mononen 2010-08-19 09:55:12 +00:00
parent 613d61f453
commit 55360f6ee5
26 changed files with 6902 additions and 1046 deletions

View File

@ -37,4 +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);
#endif // RECAST_DUMP_H

View File

@ -398,3 +398,42 @@ bool duReadCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io)
return true;
}
static void logLine(rcBuildContext* ctx, rcBuilTimeLabel label, const char* name, const float pc)
{
const int t = ctx->getBuildTime(label);
if (t < 0) return;
ctx->log(RC_LOG_PROGRESS, "%s:\t%.2fms\t(%.1f%%)", name, t/1000.0f, t*pc);
}
void duLogBuildTimes(rcBuildContext* 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);
}

View File

@ -871,6 +871,7 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
}
}
// Exhausted all nodes, but could not find path.
if (m_openList->empty())
m_query.state = DT_QUERY_READY;
@ -880,7 +881,11 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
int dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, const int maxPathSize)
{
if (m_query.state != DT_QUERY_READY)
{
// Reset query.
memset(&m_query, 0, sizeof(dtQueryData));
return 0;
}
// Reverse the path.
dtAssert(m_query.lastBestNode);

File diff suppressed because it is too large Load Diff

View File

@ -283,14 +283,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>18</integer>
<integer>11</integer>
<integer>42</integer>
<integer>38</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 107}, {264, 660}}</string>
<string>{{0, 440}, {264, 660}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -325,7 +325,7 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>DetourNavMeshQuery.cpp</string>
<string>Sample_SoloMeshSimple.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -333,15 +333,14 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>DetourNavMeshQuery.cpp</string>
<string>Sample_SoloMeshSimple.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6BAF434F121B00EF008CFCDF</string>
<string>6BAF45C2121D2F68008CFCDF</string>
<key>history</key>
<array>
<string>6BBB4AA5115B4F3400CF791D</string>
<string>6BBB4AA6115B4F3400CF791D</string>
<string>6BBB4C34115B7A3D00CF791D</string>
<string>6BF5F27011747CFA000502A6</string>
<string>6BF5F27311747CFA000502A6</string>
@ -349,28 +348,11 @@
<string>6BF5F2E511748884000502A6</string>
<string>6BF5F2E611748884000502A6</string>
<string>6BF5F2E711748884000502A6</string>
<string>6BF5F32E11759C3C000502A6</string>
<string>6BF5F5041176F5F8000502A6</string>
<string>6B4214D911803923006C347B</string>
<string>6B10011711AD19F90098A59A</string>
<string>6B77655511E3A9490029917E</string>
<string>6B98462E11E6141900FA177B</string>
<string>6B98473011E737D800FA177B</string>
<string>6B9847FE11E9AFC900FA177B</string>
<string>6B98482611E9D23600FA177B</string>
<string>6BF9B12C11EB8CF20043574C</string>
<string>6BF9B12F11EB8CF20043574C</string>
<string>6BF9B13711EB8CF20043574C</string>
<string>6BF9B20B11EC450E0043574C</string>
<string>6BF9B21B11EC49F90043574C</string>
<string>6BAF37D411FEAC16008CFCDF</string>
<string>6BAF382112019EDA008CFCDF</string>
<string>6BAF38471202CC9B008CFCDF</string>
<string>6BAF385C120A8A8E008CFCDF</string>
<string>6BAF3ADA12112A65008CFCDF</string>
<string>6BAF3BA51211425E008CFCDF</string>
<string>6BAF3BB9121146D8008CFCDF</string>
<string>6BAF3C7D121167CA008CFCDF</string>
<string>6BAF3CB012116AD9008CFCDF</string>
<string>6BAF3CB112116AD9008CFCDF</string>
<string>6BAF3CB412116AD9008CFCDF</string>
@ -378,42 +360,64 @@
<string>6BAF3E781212869F008CFCDF</string>
<string>6BAF404F12140B4E008CFCDF</string>
<string>6BAF405112140B4E008CFCDF</string>
<string>6BAF405212140B4E008CFCDF</string>
<string>6BAF409312142142008CFCDF</string>
<string>6BAF409512142142008CFCDF</string>
<string>6BAF40BD12193E77008CFCDF</string>
<string>6BAF40F012197F3D008CFCDF</string>
<string>6BAF40F112197F3D008CFCDF</string>
<string>6BAF40F212197F3D008CFCDF</string>
<string>6BAF40F312197F3D008CFCDF</string>
<string>6BAF40F412197F3D008CFCDF</string>
<string>6BAF41701219811E008CFCDF</string>
<string>6BAF419E12198419008CFCDF</string>
<string>6BAF419F12198419008CFCDF</string>
<string>6BAF41A012198419008CFCDF</string>
<string>6BAF41A312198419008CFCDF</string>
<string>6BAF41A412198419008CFCDF</string>
<string>6BAF41A512198419008CFCDF</string>
<string>6BAF41A612198419008CFCDF</string>
<string>6BAF41A812198419008CFCDF</string>
<string>6BAF41A912198419008CFCDF</string>
<string>6BAF41AB12198419008CFCDF</string>
<string>6BAF41D0121A5AEE008CFCDF</string>
<string>6BAF4250121AD7D7008CFCDF</string>
<string>6BAF4267121AD99B008CFCDF</string>
<string>6BAF4269121AD99B008CFCDF</string>
<string>6BAF427E121ADD46008CFCDF</string>
<string>6BAF427F121ADD46008CFCDF</string>
<string>6BAF4280121ADD46008CFCDF</string>
<string>6BAF4281121ADD46008CFCDF</string>
<string>6BAF42A6121AEFD9008CFCDF</string>
<string>6BAF42E2121AF3B8008CFCDF</string>
<string>6BAF4321121AF998008CFCDF</string>
<string>6BAF4322121AF998008CFCDF</string>
<string>6BAF4323121AF998008CFCDF</string>
<string>6BAF4325121AF998008CFCDF</string>
<string>6BAF4346121AFD0B008CFCDF</string>
<string>6BAF4347121AFD0B008CFCDF</string>
<string>6BAF437D121C1F3D008CFCDF</string>
<string>6BAF43FB121C241D008CFCDF</string>
<string>6BAF43FE121C241D008CFCDF</string>
<string>6BAF43FF121C241D008CFCDF</string>
<string>6BAF4421121C25E3008CFCDF</string>
<string>6BAF4422121C25E3008CFCDF</string>
<string>6BAF4446121C40AC008CFCDF</string>
<string>6BAF446C121C4895008CFCDF</string>
<string>6BAF446E121C4895008CFCDF</string>
<string>6BAF44D9121C4DFC008CFCDF</string>
<string>6BAF44DE121C54D4008CFCDF</string>
<string>6BAF4520121D1723008CFCDF</string>
<string>6BAF4521121D1723008CFCDF</string>
<string>6BAF4522121D1723008CFCDF</string>
<string>6BAF4523121D1723008CFCDF</string>
<string>6BAF4524121D1723008CFCDF</string>
<string>6BAF4525121D1723008CFCDF</string>
<string>6BAF4527121D1723008CFCDF</string>
<string>6BAF452A121D1723008CFCDF</string>
<string>6BAF452B121D1723008CFCDF</string>
<string>6BAF4562121D1849008CFCDF</string>
<string>6BAF4564121D1849008CFCDF</string>
<string>6BAF457C121D19CB008CFCDF</string>
<string>6BAF457D121D19CB008CFCDF</string>
<string>6BAF457E121D19CB008CFCDF</string>
<string>6BAF457F121D19CB008CFCDF</string>
<string>6BAF4580121D19CB008CFCDF</string>
<string>6BAF4581121D19CB008CFCDF</string>
<string>6BAF4582121D19CB008CFCDF</string>
<string>6BAF4592121D1B18008CFCDF</string>
<string>6BAF4593121D1B18008CFCDF</string>
<string>6BAF459B121D1C15008CFCDF</string>
<string>6BAF45A6121D1C49008CFCDF</string>
<string>6BAF45AA121D2C03008CFCDF</string>
<string>6BAF45AB121D2C03008CFCDF</string>
<string>6BAF45AC121D2C03008CFCDF</string>
<string>6BAF45B7121D2F37008CFCDF</string>
<string>6BAF45B8121D2F37008CFCDF</string>
<string>6BAF45C0121D2F57008CFCDF</string>
</array>
<key>nextStack</key>
<array>
<string>6BAF4490121C4895008CFCDF</string>
<string>6BAF4491121C4895008CFCDF</string>
</array>
<key>prevStack</key>
<array>
@ -433,11 +437,7 @@
<string>6BBB4AF8115B4F3400CF791D</string>
<string>6BBB4AF9115B4F3400CF791D</string>
<string>6BBB4AFA115B4F3400CF791D</string>
<string>6BBB4AFB115B4F3400CF791D</string>
<string>6BBB4AFD115B4F3400CF791D</string>
<string>6BBB4B07115B4F3400CF791D</string>
<string>6BBB4B08115B4F3400CF791D</string>
<string>6BBB4B0A115B4F3400CF791D</string>
<string>6BBB4C3B115B7A3D00CF791D</string>
<string>6BF5F27811747CFA000502A6</string>
<string>6BF5F28011747CFA000502A6</string>
@ -446,9 +446,6 @@
<string>6BF5F2EE11748884000502A6</string>
<string>6BF5F33911759C3C000502A6</string>
<string>6B4215D1118066FE006C347B</string>
<string>6B10005C11AD08FA0098A59A</string>
<string>6B10011F11AD19F90098A59A</string>
<string>6BC7619C11B63C7E00FF5E51</string>
<string>6B98458E11E6039A00FA177B</string>
<string>6B98465211E6F9B400FA177B</string>
<string>6B98465411E6F9B400FA177B</string>
@ -456,22 +453,16 @@
<string>6B98471011E734A100FA177B</string>
<string>6B98471211E734A100FA177B</string>
<string>6B98471411E734A100FA177B</string>
<string>6B98477411E7406900FA177B</string>
<string>6B98477911E7433F00FA177B</string>
<string>6B9847C511E752CC00FA177B</string>
<string>6BF9B14A11EB8CF20043574C</string>
<string>6BF9B15511EB8CF20043574C</string>
<string>6BF9B18B11EC2D470043574C</string>
<string>6BF9B14911EB8CF20043574C</string>
<string>6BAF3860120A8A8E008CFCDF</string>
<string>6BAF3861120A8A8E008CFCDF</string>
<string>6BAF386B120A8B78008CFCDF</string>
<string>6BAF3A3B1210235F008CFCDF</string>
<string>6BAF3ABC121038F9008CFCDF</string>
<string>6BAF3B0612112E63008CFCDF</string>
<string>6BAF3B1512112F65008CFCDF</string>
<string>6BAF3BB312114389008CFCDF</string>
<string>6B4215DF1180672F006C347B</string>
<string>6BAF3DAA1211882E008CFCDF</string>
<string>6BAF3E631211B713008CFCDF</string>
<string>6BAF3F5F1213E45B008CFCDF</string>
@ -480,34 +471,19 @@
<string>6BAF405912140B4E008CFCDF</string>
<string>6BAF40A612142254008CFCDF</string>
<string>6BAF410112197F3D008CFCDF</string>
<string>6BAF410212197F3D008CFCDF</string>
<string>6BAF410312197F3D008CFCDF</string>
<string>6BAF410412197F3D008CFCDF</string>
<string>6BAF410512197F3D008CFCDF</string>
<string>6BAF410612197F3D008CFCDF</string>
<string>6BAF410712197F3D008CFCDF</string>
<string>6BAF410812197F3D008CFCDF</string>
<string>6BAF411712197F3D008CFCDF</string>
<string>6BAF411F12197F3D008CFCDF</string>
<string>6BAF412F12197F3D008CFCDF</string>
<string>6BAF414812197F3D008CFCDF</string>
<string>6BAF414912197F3D008CFCDF</string>
<string>6BAF414A12197F3D008CFCDF</string>
<string>6BAF414B12197F3D008CFCDF</string>
<string>6BAF414C12197F3D008CFCDF</string>
<string>6BAF414D12197F3D008CFCDF</string>
<string>6BAF415312197F3D008CFCDF</string>
<string>6BAF415412197F3D008CFCDF</string>
<string>6BAF415512197F3D008CFCDF</string>
<string>6BAF41751219811E008CFCDF</string>
<string>6BAF41761219811E008CFCDF</string>
<string>6BAF41771219811E008CFCDF</string>
<string>6BAF41781219811E008CFCDF</string>
<string>6BAF41791219811E008CFCDF</string>
<string>6BAF417A1219811E008CFCDF</string>
<string>6BAF417B1219811E008CFCDF</string>
<string>6BAF417C1219811E008CFCDF</string>
<string>6BAF417D1219811E008CFCDF</string>
<string>6BAF417E1219811E008CFCDF</string>
<string>6BAF417F1219811E008CFCDF</string>
<string>6BAF41801219811E008CFCDF</string>
@ -515,7 +491,6 @@
<string>6BAF41821219811E008CFCDF</string>
<string>6BAF41831219811E008CFCDF</string>
<string>6BAF41841219811E008CFCDF</string>
<string>6BAF41851219811E008CFCDF</string>
<string>6BAF41861219811E008CFCDF</string>
<string>6BAF41871219811E008CFCDF</string>
<string>6BAF41AE12198419008CFCDF</string>
@ -524,9 +499,7 @@
<string>6BAF41B412198419008CFCDF</string>
<string>6BAF41B612198419008CFCDF</string>
<string>6BAF41B712198419008CFCDF</string>
<string>6BAF41B812198419008CFCDF</string>
<string>6BAF41B912198419008CFCDF</string>
<string>6BAF41BA12198419008CFCDF</string>
<string>6BAF41BC12198419008CFCDF</string>
<string>6BAF41BD12198419008CFCDF</string>
<string>6BAF41BE12198419008CFCDF</string>
@ -534,13 +507,11 @@
<string>6BAF41C012198419008CFCDF</string>
<string>6BAF41C112198419008CFCDF</string>
<string>6BAF41C212198419008CFCDF</string>
<string>6BAF41C312198419008CFCDF</string>
<string>6BAF41C412198419008CFCDF</string>
<string>6BAF41C512198419008CFCDF</string>
<string>6BAF41C712198419008CFCDF</string>
<string>6BAF41C812198419008CFCDF</string>
<string>6BAF41C912198419008CFCDF</string>
<string>6BAF41CA12198419008CFCDF</string>
<string>6BAF41CB12198419008CFCDF</string>
<string>6BAF41CC12198419008CFCDF</string>
<string>6BAF41D3121A5AEE008CFCDF</string>
@ -644,8 +615,213 @@
<string>6BAF433F121AF998008CFCDF</string>
<string>6BAF4340121AF998008CFCDF</string>
<string>6BAF4341121AF998008CFCDF</string>
<string>6BAF4342121AF998008CFCDF</string>
<string>6BAF4348121AFD0B008CFCDF</string>
<string>6BAF438B121C1F3D008CFCDF</string>
<string>6BAF438C121C1F3D008CFCDF</string>
<string>6BAF438D121C1F3D008CFCDF</string>
<string>6BAF4390121C1F3D008CFCDF</string>
<string>6BAF4395121C1F3D008CFCDF</string>
<string>6BAF4396121C1F3D008CFCDF</string>
<string>6BAF4399121C1F3D008CFCDF</string>
<string>6BAF439A121C1F3D008CFCDF</string>
<string>6BAF439C121C1F3D008CFCDF</string>
<string>6BAF439D121C1F3D008CFCDF</string>
<string>6BAF439E121C1F3D008CFCDF</string>
<string>6BAF43A1121C1F3D008CFCDF</string>
<string>6BAF43A2121C1F3D008CFCDF</string>
<string>6BAF43A3121C1F3D008CFCDF</string>
<string>6BAF43A4121C1F3D008CFCDF</string>
<string>6BAF43A6121C1F3D008CFCDF</string>
<string>6BAF43B2121C1F3D008CFCDF</string>
<string>6BAF43B3121C1F3D008CFCDF</string>
<string>6BAF43B4121C1F3D008CFCDF</string>
<string>6BAF43B5121C1F3D008CFCDF</string>
<string>6BAF43B7121C1F3D008CFCDF</string>
<string>6BAF43B8121C1F3D008CFCDF</string>
<string>6BAF43B9121C1F3D008CFCDF</string>
<string>6BAF43BB121C1F3D008CFCDF</string>
<string>6BAF43BC121C1F3D008CFCDF</string>
<string>6BAF43BD121C1F3D008CFCDF</string>
<string>6BAF43BE121C1F3D008CFCDF</string>
<string>6BAF43BF121C1F3D008CFCDF</string>
<string>6BAF43C0121C1F3D008CFCDF</string>
<string>6BAF43C2121C1F3D008CFCDF</string>
<string>6BAF43D1121C2164008CFCDF</string>
<string>6BAF43D2121C2164008CFCDF</string>
<string>6BAF43D3121C2164008CFCDF</string>
<string>6BAF43D4121C2164008CFCDF</string>
<string>6BAF43D5121C2164008CFCDF</string>
<string>6BAF43D6121C2164008CFCDF</string>
<string>6BAF43D7121C2164008CFCDF</string>
<string>6BAF43E3121C225B008CFCDF</string>
<string>6BAF43E4121C225B008CFCDF</string>
<string>6BAF43E5121C225B008CFCDF</string>
<string>6BAF4404121C241D008CFCDF</string>
<string>6BAF4406121C241D008CFCDF</string>
<string>6BAF4408121C241D008CFCDF</string>
<string>6BAF4409121C241D008CFCDF</string>
<string>6BAF440A121C241D008CFCDF</string>
<string>6BAF440B121C241D008CFCDF</string>
<string>6BAF440C121C241D008CFCDF</string>
<string>6BAF440D121C241D008CFCDF</string>
<string>6BAF440E121C241D008CFCDF</string>
<string>6BAF440F121C241D008CFCDF</string>
<string>6BAF4411121C241D008CFCDF</string>
<string>6BAF4412121C241D008CFCDF</string>
<string>6BAF4413121C241D008CFCDF</string>
<string>6BAF4414121C241D008CFCDF</string>
<string>6BAF4415121C241D008CFCDF</string>
<string>6BAF4428121C25E3008CFCDF</string>
<string>6BAF4429121C25E3008CFCDF</string>
<string>6BAF442A121C25E3008CFCDF</string>
<string>6BAF442C121C25E3008CFCDF</string>
<string>6BAF4436121C2A3F008CFCDF</string>
<string>6BAF443D121C2E5D008CFCDF</string>
<string>6BAF444F121C40AC008CFCDF</string>
<string>6BAF4450121C40AC008CFCDF</string>
<string>6BAF4451121C40AC008CFCDF</string>
<string>6BAF4452121C40AC008CFCDF</string>
<string>6BAF4453121C40AC008CFCDF</string>
<string>6BAF4455121C40AC008CFCDF</string>
<string>6BAF4456121C40AC008CFCDF</string>
<string>6BAF4457121C40AC008CFCDF</string>
<string>6BAF4458121C40AC008CFCDF</string>
<string>6BAF4459121C40AC008CFCDF</string>
<string>6BAF445A121C40AC008CFCDF</string>
<string>6BAF445B121C40AC008CFCDF</string>
<string>6BAF445C121C40AC008CFCDF</string>
<string>6BAF445D121C40AC008CFCDF</string>
<string>6BAF445E121C40AC008CFCDF</string>
<string>6BAF445F121C40AC008CFCDF</string>
<string>6BAF4478121C4895008CFCDF</string>
<string>6BAF4479121C4895008CFCDF</string>
<string>6BAF447A121C4895008CFCDF</string>
<string>6BAF447B121C4895008CFCDF</string>
<string>6BAF447C121C4895008CFCDF</string>
<string>6BAF447D121C4895008CFCDF</string>
<string>6BAF447E121C4895008CFCDF</string>
<string>6BAF447F121C4895008CFCDF</string>
<string>6BAF4480121C4895008CFCDF</string>
<string>6BAF4481121C4895008CFCDF</string>
<string>6BAF4482121C4895008CFCDF</string>
<string>6BAF4483121C4895008CFCDF</string>
<string>6BAF4485121C4895008CFCDF</string>
<string>6BAF4486121C4895008CFCDF</string>
<string>6BAF4487121C4895008CFCDF</string>
<string>6BAF4489121C4895008CFCDF</string>
<string>6BAF448B121C4895008CFCDF</string>
<string>6BAF448C121C4895008CFCDF</string>
<string>6BAF448E121C4895008CFCDF</string>
<string>6BAF448F121C4895008CFCDF</string>
<string>6B98477411E7406900FA177B</string>
<string>6BAF3861120A8A8E008CFCDF</string>
<string>6BAF410212197F3D008CFCDF</string>
<string>6BAF44A1121C4A43008CFCDF</string>
<string>6BAF44AD121C4BD8008CFCDF</string>
<string>6BAF44BF121C4D30008CFCDF</string>
<string>6BAF44C0121C4D30008CFCDF</string>
<string>6BAF44C1121C4D30008CFCDF</string>
<string>6BAF44C9121C4D65008CFCDF</string>
<string>6BAF44CA121C4D65008CFCDF</string>
<string>6BAF44D3121C4DB4008CFCDF</string>
<string>6BAF44DB121C4DFC008CFCDF</string>
<string>6BAF44E3121C54D4008CFCDF</string>
<string>6BAF44E4121C54D4008CFCDF</string>
<string>6BAF44E5121C54D4008CFCDF</string>
<string>6BAF44E6121C54D4008CFCDF</string>
<string>6BAF44E7121C54D4008CFCDF</string>
<string>6BAF44E8121C54D4008CFCDF</string>
<string>6BAF44E9121C54D4008CFCDF</string>
<string>6BAF44EB121C54D4008CFCDF</string>
<string>6BAF44ED121C54D4008CFCDF</string>
<string>6BAF44F2121C55F4008CFCDF</string>
<string>6BAF44FA121C5713008CFCDF</string>
<string>6BAF44FB121C5713008CFCDF</string>
<string>6BAF44FC121C5713008CFCDF</string>
<string>6BAF44FD121C5713008CFCDF</string>
<string>6BAF4505121C57D5008CFCDF</string>
<string>6BAF4506121C57D5008CFCDF</string>
<string>6BAF450C121C5810008CFCDF</string>
<string>6BAF450D121C5810008CFCDF</string>
<string>6BAF4512121C5874008CFCDF</string>
<string>6BAF4513121C5874008CFCDF</string>
<string>6BAF4536121D1723008CFCDF</string>
<string>6BAF4537121D1723008CFCDF</string>
<string>6BAF4538121D1723008CFCDF</string>
<string>6BAF4539121D1723008CFCDF</string>
<string>6BAF453A121D1723008CFCDF</string>
<string>6BAF453B121D1723008CFCDF</string>
<string>6BAF453C121D1723008CFCDF</string>
<string>6BAF453D121D1723008CFCDF</string>
<string>6BAF453E121D1723008CFCDF</string>
<string>6BAF453F121D1723008CFCDF</string>
<string>6BAF4540121D1723008CFCDF</string>
<string>6BAF4541121D1723008CFCDF</string>
<string>6BAF4542121D1723008CFCDF</string>
<string>6BAF4543121D1723008CFCDF</string>
<string>6BAF4544121D1723008CFCDF</string>
<string>6BAF4545121D1723008CFCDF</string>
<string>6BAF4546121D1723008CFCDF</string>
<string>6BAF4547121D1723008CFCDF</string>
<string>6BAF4548121D1723008CFCDF</string>
<string>6BAF4549121D1723008CFCDF</string>
<string>6BAF454A121D1723008CFCDF</string>
<string>6BAF454B121D1723008CFCDF</string>
<string>6BAF454C121D1723008CFCDF</string>
<string>6BAF454D121D1723008CFCDF</string>
<string>6BAF454E121D1723008CFCDF</string>
<string>6BAF454F121D1723008CFCDF</string>
<string>6BAF4550121D1723008CFCDF</string>
<string>6BAF4551121D1723008CFCDF</string>
<string>6BAF4552121D1723008CFCDF</string>
<string>6BAF4553121D1723008CFCDF</string>
<string>6BAF4554121D1723008CFCDF</string>
<string>6BAF4555121D1723008CFCDF</string>
<string>6BAF4556121D1723008CFCDF</string>
<string>6BAF4557121D1723008CFCDF</string>
<string>6BAF4558121D1723008CFCDF</string>
<string>6BAF4559121D1723008CFCDF</string>
<string>6BAF455A121D1723008CFCDF</string>
<string>6BAF455B121D1723008CFCDF</string>
<string>6BAF455C121D1723008CFCDF</string>
<string>6BAF455D121D1723008CFCDF</string>
<string>6BAF455E121D1723008CFCDF</string>
<string>6BAF455F121D1723008CFCDF</string>
<string>6BAF4568121D1849008CFCDF</string>
<string>6BAF4569121D1849008CFCDF</string>
<string>6BAF456A121D1849008CFCDF</string>
<string>6BAF456B121D1849008CFCDF</string>
<string>6BAF456C121D1849008CFCDF</string>
<string>6BAF456D121D1849008CFCDF</string>
<string>6BAF456E121D1849008CFCDF</string>
<string>6BAF4575121D18A5008CFCDF</string>
<string>6BAF4576121D18A5008CFCDF</string>
<string>6BAF4577121D18A5008CFCDF</string>
<string>6BAF4578121D18A5008CFCDF</string>
<string>6BAF4584121D19CB008CFCDF</string>
<string>6BAF4585121D19CB008CFCDF</string>
<string>6BAF4586121D19CB008CFCDF</string>
<string>6BAF4587121D19CB008CFCDF</string>
<string>6BAF4588121D19CB008CFCDF</string>
<string>6BAF4589121D19CB008CFCDF</string>
<string>6BAF458A121D19CB008CFCDF</string>
<string>6BAF458B121D19CB008CFCDF</string>
<string>6BAF458F121D1A1C008CFCDF</string>
<string>6BAF4596121D1B18008CFCDF</string>
<string>6BAF4597121D1B18008CFCDF</string>
<string>6BAF4598121D1B18008CFCDF</string>
<string>6BAF4599121D1B18008CFCDF</string>
<string>6BAF459E121D1C15008CFCDF</string>
<string>6BAF459F121D1C15008CFCDF</string>
<string>6BAF45A0121D1C15008CFCDF</string>
<string>6BAF45A1121D1C15008CFCDF</string>
<string>6BAF45A8121D1C49008CFCDF</string>
<string>6BAF45AE121D2C03008CFCDF</string>
<string>6BAF45AF121D2C03008CFCDF</string>
<string>6BAF45B0121D2C03008CFCDF</string>
<string>6BAF45B1121D2C03008CFCDF</string>
<string>6BAF45BA121D2F37008CFCDF</string>
<string>6BAF45BB121D2F37008CFCDF</string>
</array>
</dict>
<key>SplitCount</key>
@ -659,18 +835,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {994, 559}}</string>
<string>{{0, 0}, {994, 575}}</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>559pt</string>
<string>575pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>114pt</string>
<string>98pt</string>
<key>Tabs</key>
<array>
<dict>
@ -700,7 +876,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {994, 268}}</string>
<string>{{10, 27}, {994, 123}}</string>
</dict>
<key>Module</key>
<string>PBXProjectFindModule</string>
@ -738,7 +914,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {994, 87}}</string>
<string>{{10, 27}, {994, 71}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1280 719 0 0 1280 778 </string>
</dict>
@ -823,12 +999,12 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {1280, 289}}</string>
<string>{{0, 0}, {1280, 311}}</string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Proportion</key>
<string>289pt</string>
<string>311pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@ -847,8 +1023,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {577, 94}}</string>
<string>{{577, 0}, {703, 94}}</string>
<string>{{0, 0}, {577, 89}}</string>
<string>{{577, 0}, {703, 89}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@ -863,8 +1039,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {1280, 94}}</string>
<string>{{0, 94}, {1280, 290}}</string>
<string>{{0, 0}, {1280, 89}}</string>
<string>{{0, 89}, {1280, 273}}</string>
</array>
</dict>
</dict>
@ -884,7 +1060,7 @@
<key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string>
<key>Frame</key>
<string>{{0, 294}, {1280, 384}}</string>
<string>{{0, 316}, {1280, 362}}</string>
<key>PBXDebugSessionStackFrameViewKey</key>
<dict>
<key>DebugVariablesTableConfiguration</key>
@ -897,13 +1073,13 @@
<real>410</real>
</array>
<key>Frame</key>
<string>{{577, 0}, {703, 94}}</string>
<string>{{577, 0}, {703, 89}}</string>
</dict>
</dict>
<key>Module</key>
<string>PBXDebugSessionModule</string>
<key>Proportion</key>
<string>384pt</string>
<string>362pt</string>
</dict>
</array>
<key>Name</key>

View File

@ -17,11 +17,9 @@
6B137C8B0F7FCC1100459200 /* Recast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; };
6B137C8C0F7FCC1100459200 /* RecastContour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; };
6B137C8E0F7FCC1100459200 /* RecastFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C850F7FCC1100459200 /* RecastFilter.cpp */; };
6B137C8F0F7FCC1100459200 /* RecastLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C860F7FCC1100459200 /* RecastLog.cpp */; };
6B137C900F7FCC1100459200 /* RecastMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */; };
6B137C910F7FCC1100459200 /* RecastRasterization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */; };
6B137C920F7FCC1100459200 /* RecastRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C890F7FCC1100459200 /* RecastRegion.cpp */; };
6B137C930F7FCC1100459200 /* RecastTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */; };
6B25B6190FFA62BE004F1BC4 /* Sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B25B6140FFA62BE004F1BC4 /* Sample.cpp */; };
6B25B61D0FFA62BE004F1BC4 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B25B6180FFA62BE004F1BC4 /* main.cpp */; };
6B2AEC530FFB8958005BE9CC /* Sample_TileMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; };
@ -39,6 +37,7 @@
6BA1E88B10C7BFC9008007F6 /* Sample_SoloMeshSimple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BA1E88810C7BFC9008007F6 /* Sample_SoloMeshSimple.cpp */; };
6BAF3C591211663A008CFCDF /* CrowdTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BAF3C581211663A008CFCDF /* CrowdTool.cpp */; };
6BAF40DB12196A3D008CFCDF /* DetourNavMeshQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BAF40DA12196A3D008CFCDF /* DetourNavMeshQuery.cpp */; };
6BAF4442121C3D26008CFCDF /* SampleInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BAF4441121C3D26008CFCDF /* SampleInterfaces.cpp */; };
6BB788170FC0472B003C24DB /* ChunkyTriMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB788160FC0472B003C24DB /* ChunkyTriMesh.cpp */; };
6BB7FC0B10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */; };
6BB7FDA510F36F0E006DA0A6 /* InputGeom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7FDA410F36F0E006DA0A6 /* InputGeom.cpp */; };
@ -75,16 +74,12 @@
6B137C7B0F7FCBE400459200 /* MeshLoaderObj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeshLoaderObj.h; path = ../../Include/MeshLoaderObj.h; sourceTree = SOURCE_ROOT; };
6B137C7C0F7FCBE400459200 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLMain.h; path = ../../Include/SDLMain.h; sourceTree = SOURCE_ROOT; };
6B137C7E0F7FCBFE00459200 /* Recast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Recast.h; path = ../../../Recast/Include/Recast.h; sourceTree = SOURCE_ROOT; };
6B137C800F7FCBFE00459200 /* RecastLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecastLog.h; path = ../../../Recast/Include/RecastLog.h; sourceTree = SOURCE_ROOT; };
6B137C810F7FCBFE00459200 /* RecastTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecastTimer.h; path = ../../../Recast/Include/RecastTimer.h; sourceTree = SOURCE_ROOT; };
6B137C820F7FCC1100459200 /* Recast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Recast.cpp; path = ../../../Recast/Source/Recast.cpp; sourceTree = SOURCE_ROOT; };
6B137C830F7FCC1100459200 /* RecastContour.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastContour.cpp; path = ../../../Recast/Source/RecastContour.cpp; sourceTree = SOURCE_ROOT; };
6B137C850F7FCC1100459200 /* RecastFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastFilter.cpp; path = ../../../Recast/Source/RecastFilter.cpp; sourceTree = SOURCE_ROOT; };
6B137C860F7FCC1100459200 /* RecastLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastLog.cpp; path = ../../../Recast/Source/RecastLog.cpp; sourceTree = SOURCE_ROOT; };
6B137C870F7FCC1100459200 /* RecastMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastMesh.cpp; path = ../../../Recast/Source/RecastMesh.cpp; sourceTree = SOURCE_ROOT; };
6B137C880F7FCC1100459200 /* RecastRasterization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastRasterization.cpp; path = ../../../Recast/Source/RecastRasterization.cpp; sourceTree = SOURCE_ROOT; };
6B137C890F7FCC1100459200 /* RecastRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastRegion.cpp; path = ../../../Recast/Source/RecastRegion.cpp; sourceTree = SOURCE_ROOT; };
6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastTimer.cpp; path = ../../../Recast/Source/RecastTimer.cpp; sourceTree = SOURCE_ROOT; };
6B25B6100FFA62AD004F1BC4 /* Sample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sample.h; path = ../../Include/Sample.h; sourceTree = SOURCE_ROOT; };
6B25B6140FFA62BE004F1BC4 /* Sample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sample.cpp; path = ../../Source/Sample.cpp; sourceTree = SOURCE_ROOT; };
6B25B6180FFA62BE004F1BC4 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../../Source/main.cpp; sourceTree = SOURCE_ROOT; };
@ -117,6 +112,9 @@
6BAF40D912196A25008CFCDF /* DetourNavMeshQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetourNavMeshQuery.h; path = ../../../Detour/Include/DetourNavMeshQuery.h; sourceTree = SOURCE_ROOT; };
6BAF40DA12196A3D008CFCDF /* DetourNavMeshQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DetourNavMeshQuery.cpp; path = ../../../Detour/Source/DetourNavMeshQuery.cpp; sourceTree = SOURCE_ROOT; };
6BAF427A121ADCC2008CFCDF /* DetourAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetourAssert.h; path = ../../../Detour/Include/DetourAssert.h; sourceTree = SOURCE_ROOT; };
6BAF4440121C3D0A008CFCDF /* SampleInterfaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SampleInterfaces.h; path = ../../Include/SampleInterfaces.h; sourceTree = SOURCE_ROOT; };
6BAF4441121C3D26008CFCDF /* SampleInterfaces.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleInterfaces.cpp; path = ../../Source/SampleInterfaces.cpp; sourceTree = SOURCE_ROOT; };
6BAF4561121D173A008CFCDF /* RecastAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecastAssert.h; path = ../../../Recast/Include/RecastAssert.h; sourceTree = SOURCE_ROOT; };
6BB788160FC0472B003C24DB /* ChunkyTriMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ChunkyTriMesh.cpp; path = ../../Source/ChunkyTriMesh.cpp; sourceTree = SOURCE_ROOT; };
6BB788180FC04753003C24DB /* ChunkyTriMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChunkyTriMesh.h; path = ../../Include/ChunkyTriMesh.h; sourceTree = SOURCE_ROOT; };
6BB7FC0910EBB6AA006DA0A6 /* NavMeshTesterTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NavMeshTesterTool.h; path = ../../Include/NavMeshTesterTool.h; sourceTree = SOURCE_ROOT; };
@ -168,6 +166,8 @@
6B555DF5100B25FC00247EA3 /* Samples */,
6BB7FE8E10F4A175006DA0A6 /* Tools */,
6B25B6180FFA62BE004F1BC4 /* main.cpp */,
6BAF4440121C3D0A008CFCDF /* SampleInterfaces.h */,
6BAF4441121C3D26008CFCDF /* SampleInterfaces.cpp */,
6BF5F2C511747E9F000502A6 /* stb_image.h */,
6BF5F23E1174763B000502A6 /* SlideShow.h */,
6BF5F23F1174763B000502A6 /* SlideShow.cpp */,
@ -263,12 +263,9 @@
6B137C7D0F7FCBE800459200 /* Recast */ = {
isa = PBXGroup;
children = (
6BAF4561121D173A008CFCDF /* RecastAssert.h */,
6B137C7E0F7FCBFE00459200 /* Recast.h */,
6B137C800F7FCBFE00459200 /* RecastLog.h */,
6B137C810F7FCBFE00459200 /* RecastTimer.h */,
6B137C820F7FCC1100459200 /* Recast.cpp */,
6B137C860F7FCC1100459200 /* RecastLog.cpp */,
6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */,
6B137C880F7FCC1100459200 /* RecastRasterization.cpp */,
6B137C850F7FCC1100459200 /* RecastFilter.cpp */,
6BF7C4531115C277002B3F46 /* RecastArea.cpp */,
@ -411,11 +408,9 @@
6B137C8B0F7FCC1100459200 /* Recast.cpp in Sources */,
6B137C8C0F7FCC1100459200 /* RecastContour.cpp in Sources */,
6B137C8E0F7FCC1100459200 /* RecastFilter.cpp in Sources */,
6B137C8F0F7FCC1100459200 /* RecastLog.cpp in Sources */,
6B137C900F7FCC1100459200 /* RecastMesh.cpp in Sources */,
6B137C910F7FCC1100459200 /* RecastRasterization.cpp in Sources */,
6B137C920F7FCC1100459200 /* RecastRegion.cpp in Sources */,
6B137C930F7FCC1100459200 /* RecastTimer.cpp in Sources */,
6BB788170FC0472B003C24DB /* ChunkyTriMesh.cpp in Sources */,
6B25B6190FFA62BE004F1BC4 /* Sample.cpp in Sources */,
6B25B61D0FFA62BE004F1BC4 /* main.cpp in Sources */,
@ -445,6 +440,7 @@
6B9847B811E7519A00FA177B /* RecastAlloc.cpp in Sources */,
6BAF3C591211663A008CFCDF /* CrowdTool.cpp in Sources */,
6BAF40DB12196A3D008CFCDF /* DetourNavMeshQuery.cpp in Sources */,
6BAF4442121C3D26008CFCDF /* SampleInterfaces.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -55,9 +55,9 @@ public:
InputGeom();
~InputGeom();
bool loadMesh(const char* filepath);
bool loadMesh(struct rcBuildContext* ctx, const char* filepath);
bool load(const char* filepath);
bool load(struct rcBuildContext* ctx, const char* filepath);
bool save(const char* filepath);
// Method to return static mesh data.

View File

@ -19,10 +19,22 @@
#ifndef RECASTSAMPLE_H
#define RECASTSAMPLE_H
#include "DebugDraw.h"
#include "RecastDump.h"
#include "Recast.h"
#include "SampleInterfaces.h"
// Tool types.
enum SampleToolType
{
TOOL_NONE = 0,
TOOL_TILE_EDIT,
TOOL_TILE_HIGHLIGHT,
TOOL_NAVMESH_TESTER,
TOOL_OFFMESH_CONNECTION,
TOOL_CONVEX_VOLUME,
TOOL_CROWD,
};
// These are just sample areas to use consistent values across the samples.
// The use should specify these base on his needs.
enum SamplePolyAreas
@ -43,46 +55,6 @@ enum SamplePolyFlags
SAMPLE_POLYFLAGS_ALL = 0xffff // All abilities.
};
// OpenGL debug draw implementation.
class DebugDrawGL : public duDebugDraw
{
public:
virtual void depthMask(bool state);
virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f);
virtual void vertex(const float* pos, unsigned int color);
virtual void vertex(const float x, const float y, const float z, unsigned int color);
virtual void end();
};
// stdio file implementation.
class FileIO : public duFileIO
{
FILE* m_fp;
int m_mode;
public:
FileIO();
virtual ~FileIO();
bool openForWrite(const char* path);
bool openForRead(const char* path);
virtual bool isWriting() const;
virtual bool isReading() const;
virtual bool write(const void* ptr, const size_t size);
virtual bool read(void* ptr, const size_t size);
};
// Tool types.
enum SampleToolType
{
TOOL_NONE = 0,
TOOL_TILE_EDIT,
TOOL_TILE_HIGHLIGHT,
TOOL_NAVMESH_TESTER,
TOOL_OFFMESH_CONNECTION,
TOOL_CONVEX_VOLUME,
TOOL_CROWD,
};
struct SampleTool
{
virtual ~SampleTool() {}
@ -122,10 +94,14 @@ protected:
SampleTool* m_tool;
rcBuildContext* m_ctx;
public:
Sample();
virtual ~Sample();
void setContext(rcBuildContext* ctx) { m_ctx = ctx; }
void setTool(SampleTool* tool);
virtual void handleSettings();

View File

@ -0,0 +1,90 @@
//
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
#include "DebugDraw.h"
#include "Recast.h"
#include "RecastDump.h"
// These are example implementations of various interfaces used in Recast and Detour.
// Recast build context.
class BuildContext : public rcBuildContext
{
int m_buildTime[RC_MAX_TIMES];
static const int MAX_MESSAGES = 1000;
const char* m_messages[MAX_MESSAGES];
int m_messageCount;
static const int TEXT_POOL_SIZE = 8000;
char m_textPool[TEXT_POOL_SIZE];
int m_textPoolSize;
public:
BuildContext();
~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.
int getLogCount() const;
// 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 rcBuilTimeLabel label, const int time);
// Returns accumulated build time for specified label, or -1 if no time was reported.
virtual int getBuildTime(const rcBuilTimeLabel label);
};
// OpenGL debug draw implementation.
class DebugDrawGL : public duDebugDraw
{
public:
virtual void depthMask(bool state);
virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f);
virtual void vertex(const float* pos, unsigned int color);
virtual void vertex(const float x, const float y, const float z, unsigned int color);
virtual void end();
};
// stdio file implementation.
class FileIO : public duFileIO
{
FILE* m_fp;
int m_mode;
public:
FileIO();
virtual ~FileIO();
bool openForWrite(const char* path);
bool openForRead(const char* path);
virtual bool isWriting() const;
virtual bool isReading() const;
virtual bool write(const void* ptr, const size_t size);
virtual bool read(void* ptr, const size_t size);
};

View File

@ -22,7 +22,6 @@
#include "Sample.h"
#include "DetourNavMesh.h"
#include "Recast.h"
#include "RecastLog.h"
// Sample used for random debugging.
class Sample_Debug : public Sample

View File

@ -22,13 +22,11 @@
#include "Sample.h"
#include "DetourNavMesh.h"
#include "Recast.h"
#include "RecastLog.h"
class Sample_SoloMeshSimple : public Sample
{
protected:
bool m_keepInterResults;
rcBuildTimes m_buildTimes;
float m_totalBuildTimeMs;
unsigned char* m_triareas;

View File

@ -22,7 +22,6 @@
#include "Sample.h"
#include "DetourNavMesh.h"
#include "Recast.h"
#include "RecastLog.h"
#include "ChunkyTriMesh.h"
class Sample_SoloMeshTiled : public Sample
@ -61,7 +60,6 @@ protected:
bool m_measurePerTileTimings;
bool m_keepInterResults;
float m_tileSize;
rcBuildTimes m_buildTimes;
float m_totalBuildTimeMs;
rcPolyMesh* m_pmesh;

View File

@ -22,7 +22,6 @@
#include "Sample.h"
#include "DetourNavMesh.h"
#include "Recast.h"
#include "RecastLog.h"
#include "ChunkyTriMesh.h"
class Sample_TileMesh : public Sample
@ -30,7 +29,6 @@ class Sample_TileMesh : public Sample
protected:
bool m_keepInterResults;
bool m_buildAll;
rcBuildTimes m_buildTimes;
float m_totalBuildTimeMs;
bool m_drawPortals;
@ -42,6 +40,30 @@ protected:
rcPolyMeshDetail* m_dmesh;
rcConfig m_cfg;
enum DrawMode
{
DRAWMODE_NAVMESH,
DRAWMODE_NAVMESH_TRANS,
DRAWMODE_NAVMESH_BVTREE,
DRAWMODE_NAVMESH_PORTALS,
DRAWMODE_NAVMESH_INVIS,
DRAWMODE_MESH,
DRAWMODE_VOXELS,
DRAWMODE_VOXELS_WALKABLE,
DRAWMODE_COMPACT,
DRAWMODE_COMPACT_DISTANCE,
DRAWMODE_COMPACT_REGIONS,
DRAWMODE_REGION_CONNECTIONS,
DRAWMODE_RAW_CONTOURS,
DRAWMODE_BOTH_CONTOURS,
DRAWMODE_CONTOURS,
DRAWMODE_POLYMESH,
DRAWMODE_POLYMESH_DETAIL,
MAX_DRAWMODE
};
DrawMode m_drawMode;
int m_maxTiles;
int m_maxPolysPerTile;
float m_tileSize;

View File

@ -20,7 +20,7 @@
#define TESTCASE_H
#include "DetourNavMesh.h"
#include "RecastTimer.h"
#include "Recast.h"
class TestCase
{
@ -71,7 +71,7 @@ public:
inline const char* getSampleName() const { return m_sampleName; }
inline const char* getGeomFileName() const { return m_geomFileName; }
void doTests(class dtNavMesh* navmesh, class dtNavMeshQuery* navquery);
void doTests(rcBuildContext* ctx, class dtNavMesh* navmesh, class dtNavMeshQuery* navquery);
void handleRender();
bool handleRenderOverlay(double* proj, double* model, int* view);

View File

@ -22,7 +22,6 @@
#include <ctype.h>
#include <string.h>
#include "Recast.h"
#include "RecastLog.h"
#include "InputGeom.h"
#include "ChunkyTriMesh.h"
#include "MeshLoaderObj.h"
@ -119,7 +118,7 @@ InputGeom::~InputGeom()
delete m_mesh;
}
bool InputGeom::loadMesh(const char* filepath)
bool InputGeom::loadMesh(rcBuildContext* ctx, const char* filepath)
{
if (m_mesh)
{
@ -134,14 +133,12 @@ bool InputGeom::loadMesh(const char* filepath)
m_mesh = new rcMeshLoaderObj;
if (!m_mesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "loadMesh: Out of memory 'm_mesh'.");
ctx->log(RC_LOG_ERROR, "loadMesh: Out of memory 'm_mesh'.");
return false;
}
if (!m_mesh->load(filepath))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath);
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath);
return false;
}
@ -150,21 +147,19 @@ bool InputGeom::loadMesh(const char* filepath)
m_chunkyMesh = new rcChunkyTriMesh;
if (!m_chunkyMesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'm_chunkyMesh'.");
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'm_chunkyMesh'.");
return false;
}
if (!rcCreateChunkyTriMesh(m_mesh->getVerts(), m_mesh->getTris(), m_mesh->getTriCount(), 256, m_chunkyMesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Failed to build chunky mesh.");
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Failed to build chunky mesh.");
return false;
}
return true;
}
bool InputGeom::load(const char* filePath)
bool InputGeom::load(rcBuildContext* ctx, const char* filePath)
{
char* buf = 0;
FILE* fp = fopen(filePath, "rb");
@ -204,7 +199,7 @@ bool InputGeom::load(const char* filePath)
name++;
if (*name)
{
if (!loadMesh(name))
if (!loadMesh(ctx, name))
{
delete [] buf;
return false;

View File

@ -26,7 +26,6 @@
#include "NavMeshTesterTool.h"
#include "Sample.h"
#include "Recast.h"
#include "RecastTimer.h"
#include "RecastDebugDraw.h"
#include "DetourNavMesh.h"
#include "DetourNavMeshBuilder.h"

View File

@ -34,114 +34,13 @@
# define snprintf _snprintf
#endif
void DebugDrawGL::depthMask(bool state)
{
glDepthMask(state ? GL_TRUE : GL_FALSE);
}
void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
{
switch (prim)
{
case DU_DRAW_POINTS:
glPointSize(size);
glBegin(GL_POINTS);
break;
case DU_DRAW_LINES:
glLineWidth(size);
glBegin(GL_LINES);
break;
case DU_DRAW_TRIS:
glBegin(GL_TRIANGLES);
break;
case DU_DRAW_QUADS:
glBegin(GL_QUADS);
break;
};
}
void DebugDrawGL::vertex(const float* pos, unsigned int color)
{
glColor4ubv((GLubyte*)&color);
glVertex3fv(pos);
}
void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color)
{
glColor4ubv((GLubyte*)&color);
glVertex3f(x,y,z);
}
void DebugDrawGL::end()
{
glEnd();
glLineWidth(1.0f);
glPointSize(1.0f);
}
FileIO::FileIO() :
m_fp(0),
m_mode(-1)
{
}
FileIO::~FileIO()
{
if (m_fp) fclose(m_fp);
}
bool FileIO::openForWrite(const char* path)
{
if (m_fp) return false;
m_fp = fopen(path, "wb");
if (!m_fp) return false;
m_mode = 1;
return true;
}
bool FileIO::openForRead(const char* path)
{
if (m_fp) return false;
m_fp = fopen(path, "rb");
if (!m_fp) return false;
m_mode = 2;
return true;
}
bool FileIO::isWriting() const
{
return m_mode == 1;
}
bool FileIO::isReading() const
{
return m_mode == 2;
}
bool FileIO::write(const void* ptr, const size_t size)
{
if (!m_fp || m_mode != 1) return false;
fwrite(ptr, size, 1, m_fp);
return true;
}
bool FileIO::read(void* ptr, const size_t size)
{
if (!m_fp || m_mode != 2) return false;
fread(ptr, size, 1, m_fp);
return true;
}
Sample::Sample() :
m_geom(0),
m_navMesh(0),
m_navQuery(0),
m_navMeshDrawFlags(DU_DRAWNAVMESH_OFFMESHCONS),
m_tool(0)
m_tool(0),
m_ctx(0)
{
resetCommonSettings();
m_navQuery = dtAllocNavMeshQuery();

View File

@ -0,0 +1,277 @@
#define _USE_MATH_DEFINES
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include "SampleInterfaces.h"
#include "Recast.h"
#include "RecastDebugDraw.h"
#include "DetourDebugDraw.h"
#include "SDL.h"
#include "SDL_opengl.h"
#ifdef WIN32
# define snprintf _snprintf
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
BuildContext::BuildContext() :
m_messageCount(0),
m_textPoolSize(0)
{
resetBuildTimes();
}
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()
{
m_messageCount = 0;
m_textPoolSize = 0;
}
void BuildContext::log(const rcLogCategory category, const char* format, ...)
{
if (m_messageCount >= MAX_MESSAGES)
return;
char* dst = &m_textPool[m_textPoolSize];
int n = TEXT_POOL_SIZE - m_textPoolSize;
if (n < 2)
return;
// Store category
*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;
m_messages[m_messageCount++] = dst;
}
void BuildContext::dumpLog(const char* format, ...)
{
// Print header.
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
printf("\n");
// Print messages
const int TAB_STOPS[4] = { 28, 36, 44, 52 };
for (int i = 0; i < m_messageCount; ++i)
{
const char* msg = m_messages[i]+1;
int n = 0;
while (*msg)
{
if (*msg == '\t')
{
int count = 1;
for (int j = 0; j < 4; ++j)
{
if (n < TAB_STOPS[j])
{
count = TAB_STOPS[j] - n;
break;
}
}
while (--count)
{
putchar(' ');
n++;
}
}
else
{
putchar(*msg);
n++;
}
msg++;
}
putchar('\n');
}
}
int BuildContext::getLogCount() const
{
return m_messageCount;
}
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 rcBuilTimeLabel 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 rcBuilTimeLabel label)
{
return m_buildTime[label];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void DebugDrawGL::depthMask(bool state)
{
glDepthMask(state ? GL_TRUE : GL_FALSE);
}
void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
{
switch (prim)
{
case DU_DRAW_POINTS:
glPointSize(size);
glBegin(GL_POINTS);
break;
case DU_DRAW_LINES:
glLineWidth(size);
glBegin(GL_LINES);
break;
case DU_DRAW_TRIS:
glBegin(GL_TRIANGLES);
break;
case DU_DRAW_QUADS:
glBegin(GL_QUADS);
break;
};
}
void DebugDrawGL::vertex(const float* pos, unsigned int color)
{
glColor4ubv((GLubyte*)&color);
glVertex3fv(pos);
}
void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color)
{
glColor4ubv((GLubyte*)&color);
glVertex3f(x,y,z);
}
void DebugDrawGL::end()
{
glEnd();
glLineWidth(1.0f);
glPointSize(1.0f);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
FileIO::FileIO() :
m_fp(0),
m_mode(-1)
{
}
FileIO::~FileIO()
{
if (m_fp) fclose(m_fp);
}
bool FileIO::openForWrite(const char* path)
{
if (m_fp) return false;
m_fp = fopen(path, "wb");
if (!m_fp) return false;
m_mode = 1;
return true;
}
bool FileIO::openForRead(const char* path)
{
if (m_fp) return false;
m_fp = fopen(path, "rb");
if (!m_fp) return false;
m_mode = 2;
return true;
}
bool FileIO::isWriting() const
{
return m_mode == 1;
}
bool FileIO::isReading() const
{
return m_mode == 2;
}
bool FileIO::write(const void* ptr, const size_t size)
{
if (!m_fp || m_mode != 1) return false;
fwrite(ptr, size, 1, m_fp);
return true;
}
bool FileIO::read(void* ptr, const size_t size)
{
if (!m_fp || m_mode != 2) return false;
fread(ptr, size, 1, m_fp);
return true;
}

View File

@ -23,7 +23,6 @@
#include "InputGeom.h"
#include "Recast.h"
#include "DetourNavMesh.h"
#include "RecastLog.h"
#include "RecastDebugDraw.h"
#include "DetourDebugDraw.h"
#include "RecastDump.h"
@ -164,7 +163,7 @@ Sample_Debug::Sample_Debug() :
m_pmesh = rcAllocPolyMesh();
if (m_pmesh)
{
rcBuildPolyMesh(*m_cset, 6, *m_pmesh);
rcBuildPolyMesh(m_ctx, *m_cset, 6, *m_pmesh);
}
}
}
@ -376,14 +375,12 @@ bool Sample_Debug::handleBuild()
m_cset = rcAllocContourSet();
if (!m_cset)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
return false;
}
if (!rcBuildContours(*m_chf, /*m_cfg.maxSimplificationError*/1.3f, /*m_cfg.maxEdgeLen*/12, *m_cset))
if (!rcBuildContours(m_ctx, *m_chf, /*m_cfg.maxSimplificationError*/1.3f, /*m_cfg.maxEdgeLen*/12, *m_cset))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
return false;
}
}

View File

@ -27,7 +27,6 @@
#include "Sample.h"
#include "Sample_SoloMeshSimple.h"
#include "Recast.h"
#include "RecastTimer.h"
#include "RecastDebugDraw.h"
#include "RecastDump.h"
#include "DetourNavMesh.h"
@ -343,8 +342,7 @@ bool Sample_SoloMeshSimple::handleBuild()
{
if (!m_geom || !m_geom->getMesh())
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
return false;
}
@ -385,18 +383,14 @@ bool Sample_SoloMeshSimple::handleBuild()
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
// Reset build times gathering.
memset(&m_buildTimes, 0, sizeof(m_buildTimes));
rcSetBuildTimes(&m_buildTimes);
m_ctx->resetBuildTimes();
// Start the build process.
rcTimeVal totStartTime = rcGetPerformanceTimer();
rcTimeVal totStartTime = m_ctx->getTime();
if (rcGetLog())
{
rcGetLog()->log(RC_LOG_PROGRESS, "Building navigation:");
rcGetLog()->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
rcGetLog()->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
}
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
m_ctx->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
//
// Step 2. Rasterize input polygon soup.
@ -406,14 +400,12 @@ bool Sample_SoloMeshSimple::handleBuild()
m_solid = rcAllocHeightfield();
if (!m_solid)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
return false;
}
if (!rcCreateHeightfield(*m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
if (!rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
return false;
}
@ -423,8 +415,7 @@ bool Sample_SoloMeshSimple::handleBuild()
m_triareas = new unsigned char[ntris];
if (!m_triareas)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris);
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris);
return false;
}
@ -432,8 +423,8 @@ bool Sample_SoloMeshSimple::handleBuild()
// If your input data is multiple meshes, you can transform them here, calculate
// the are type for each of the meshes and rasterize them.
memset(m_triareas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas);
rcRasterizeTriangles(verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas);
rcRasterizeTriangles(m_ctx, verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
if (!m_keepInterResults)
{
@ -448,9 +439,9 @@ bool Sample_SoloMeshSimple::handleBuild()
// Once all geoemtry is rasterized, we do initial pass of filtering to
// remove unwanted overhangs caused by the conservative rasterization
// as well as filter spans where the character cannot possibly stand.
rcFilterLowHangingWalkableObstacles(m_cfg.walkableClimb, *m_solid);
rcFilterLedgeSpans(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid);
rcFilterWalkableLowHeightSpans(m_cfg.walkableHeight, *m_solid);
rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, *m_solid);
rcFilterLedgeSpans(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid);
rcFilterWalkableLowHeightSpans(m_ctx, m_cfg.walkableHeight, *m_solid);
//
@ -463,14 +454,12 @@ bool Sample_SoloMeshSimple::handleBuild()
m_chf = rcAllocCompactHeightfield();
if (!m_chf)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
return false;
}
if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
if (!rcBuildCompactHeightfield(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
return false;
}
@ -481,31 +470,29 @@ bool Sample_SoloMeshSimple::handleBuild()
}
// Erode the walkable area by agent radius.
if (!rcErodeWalkableArea(m_cfg.walkableRadius, *m_chf))
if (!rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, *m_chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
return false;
}
// (Optional) Mark areas.
const ConvexVolume* vols = m_geom->getConvexVolumes();
for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i)
rcMarkConvexPolyArea(vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf);
rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf);
// Prepare for region partitioning, by calculating distance field along the walkable surface.
if (!rcBuildDistanceField(*m_chf))
if (!rcBuildDistanceField(m_ctx, *m_chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
return false;
}
// Partition the walkable surface into simple regions without holes.
if (!rcBuildRegions(*m_chf, m_cfg.borderSize, m_cfg.minRegionSize, m_cfg.mergeRegionSize))
if (!rcBuildRegions(m_ctx, *m_chf, m_cfg.borderSize, m_cfg.minRegionSize, m_cfg.mergeRegionSize))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build regions.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build regions.");
return false;
}
//
@ -516,14 +503,12 @@ bool Sample_SoloMeshSimple::handleBuild()
m_cset = rcAllocContourSet();
if (!m_cset)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
return false;
}
if (!rcBuildContours(*m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset))
if (!rcBuildContours(m_ctx, *m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
return false;
}
@ -535,14 +520,12 @@ bool Sample_SoloMeshSimple::handleBuild()
m_pmesh = rcAllocPolyMesh();
if (!m_pmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
return false;
}
if (!rcBuildPolyMesh(*m_cset, m_cfg.maxVertsPerPoly, *m_pmesh))
if (!rcBuildPolyMesh(m_ctx, *m_cset, m_cfg.maxVertsPerPoly, *m_pmesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
return false;
}
@ -553,15 +536,14 @@ bool Sample_SoloMeshSimple::handleBuild()
m_dmesh = rcAllocPolyMeshDetail();
if (!m_dmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'.");
return false;
}
if (!rcBuildPolyMeshDetail(*m_pmesh, *m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, *m_dmesh))
if (!rcBuildPolyMeshDetail(m_ctx, *m_pmesh, *m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, *m_dmesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build detail mesh.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build detail mesh.");
return false;
}
if (!m_keepInterResults)
@ -639,8 +621,7 @@ bool Sample_SoloMeshSimple::handleBuild()
if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
m_ctx->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
return false;
}
@ -648,68 +629,31 @@ bool Sample_SoloMeshSimple::handleBuild()
if (!m_navMesh)
{
dtFree(navData);
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not create Detour navmesh");
m_ctx->log(RC_LOG_ERROR, "Could not create Detour navmesh");
return false;
}
if (!m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA))
{
dtFree(navData);
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not init Detour navmesh");
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh");
return false;
}
if (!m_navQuery->init(m_navMesh, 2048))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
return false;
}
}
rcTimeVal totEndTime = rcGetPerformanceTimer();
rcTimeVal totEndTime = m_ctx->getTime();
// Show performance stats.
if (rcGetLog())
{
const float pc = 100.0f / rcGetDeltaTimeUsec(totStartTime, totEndTime);
rcGetLog()->log(RC_LOG_PROGRESS, "Rasterize: %.1fms (%.1f%%)", m_buildTimes.rasterizeTriangles/1000.0f, m_buildTimes.rasterizeTriangles*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Compact: %.1fms (%.1f%%)", m_buildTimes.buildCompact/1000.0f, m_buildTimes.buildCompact*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Border: %.1fms (%.1f%%)", m_buildTimes.filterBorder/1000.0f, m_buildTimes.filterBorder*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Walkable: %.1fms (%.1f%%)", m_buildTimes.filterWalkable/1000.0f, m_buildTimes.filterWalkable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Median area: %.1fms (%.1f%%)", m_buildTimes.filterMedian/1000.0f, m_buildTimes.filterMedian*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - blur: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldBlur/1000.0f, m_buildTimes.buildDistanceFieldBlur*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Regions: %.1fms (%.1f%%)", m_buildTimes.buildRegions/1000.0f, m_buildTimes.buildRegions*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - watershed: %.1fms (%.1f%%)", m_buildTimes.buildRegionsReg/1000.0f, m_buildTimes.buildRegionsReg*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - expand: %.1fms (%.1f%%)", m_buildTimes.buildRegionsExp/1000.0f, m_buildTimes.buildRegionsExp*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - find catchment basins: %.1fms (%.1f%%)", m_buildTimes.buildRegionsFlood/1000.0f, m_buildTimes.buildRegionsFlood*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.1fms (%.1f%%)", m_buildTimes.buildRegionsFilter/1000.0f, m_buildTimes.buildRegionsFilter*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Contours: %.1fms (%.1f%%)", m_buildTimes.buildContours/1000.0f, m_buildTimes.buildContours*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - trace: %.1fms (%.1f%%)", m_buildTimes.buildContoursTrace/1000.0f, m_buildTimes.buildContoursTrace*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - simplify: %.1fms (%.1f%%)", m_buildTimes.buildContoursSimplify/1000.0f, m_buildTimes.buildContoursSimplify*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh Detail: %.1fms (%.1f%%)", m_buildTimes.buildDetailMesh/1000.0f, m_buildTimes.buildDetailMesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_pmesh->nverts, m_pmesh->npolys);
rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f);
}
duLogBuildTimes(m_ctx, m_ctx->getDeltaTimeUsec(totStartTime, totEndTime));
m_ctx->log(RC_LOG_PROGRESS, ">> Polymesh: %d vertices %d polygons", m_pmesh->nverts, m_pmesh->npolys);
m_totalBuildTimeMs = rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
m_totalBuildTimeMs = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
if (m_tool)
m_tool->init(this);

View File

@ -27,7 +27,6 @@
#include "Sample.h"
#include "Sample_SoloMeshTiled.h"
#include "Recast.h"
#include "RecastTimer.h"
#include "RecastDebugDraw.h"
#include "DetourNavMesh.h"
#include "DetourNavMeshBuilder.h"
@ -684,8 +683,7 @@ bool Sample_SoloMeshTiled::handleBuild()
{
if (!m_geom || !m_geom->getMesh() || !m_geom->getChunkyMesh())
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
return false;
}
@ -732,18 +730,16 @@ bool Sample_SoloMeshTiled::handleBuild()
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
// Reset build times gathering.
memset(&m_buildTimes, 0, sizeof(m_buildTimes));
rcSetBuildTimes(&m_buildTimes);
m_ctx->resetBuildTimes();
// Start the build process.
rcTimeVal totStartTime = rcGetPerformanceTimer();
rcTimeVal totStartTime = m_ctx->getTime();
// Calculate the number of tiles in the output and initialize tiles.
m_tileSet = new TileSet;
if (!m_tileSet)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'tileSet'.");
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'tileSet'.");
return false;
}
rcVcopy(m_tileSet->bmin, m_cfg.bmin);
@ -755,18 +751,14 @@ bool Sample_SoloMeshTiled::handleBuild()
m_tileSet->tiles = new Tile[m_tileSet->height * m_tileSet->width];
if (!m_tileSet->tiles)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'tileSet->tiles' (%d).", m_tileSet->height * m_tileSet->width);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'tileSet->tiles' (%d).", m_tileSet->height * m_tileSet->width);
return false;
}
if (rcGetLog())
{
rcGetLog()->log(RC_LOG_PROGRESS, "Building navigation:");
rcGetLog()->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
rcGetLog()->log(RC_LOG_PROGRESS, " - %d x %d tiles", m_tileSet->width, m_tileSet->height);
rcGetLog()->log(RC_LOG_PROGRESS, " - %.1f verts, %.1f tris", nverts/1000.0f, ntris/1000.0f);
}
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d tiles", m_tileSet->width, m_tileSet->height);
m_ctx->log(RC_LOG_PROGRESS, " - %.1f verts, %.1f tris", nverts/1000.0f, ntris/1000.0f);
// Initialize per tile config.
rcConfig tileCfg;
@ -778,23 +770,16 @@ bool Sample_SoloMeshTiled::handleBuild()
unsigned char* triangleAreas = new unsigned char[chunkyMesh->maxTrisPerChunk];
if (!triangleAreas)
{
if (rcGetLog())
{
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'triangleAreas' (%d).",
chunkyMesh->maxTrisPerChunk);
}
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'triangleAreas' (%d).",
chunkyMesh->maxTrisPerChunk);
return false;
}
/* rcHeightfield* solid = 0;
rcCompactHeightfield* chf = 0;
rcContourSet* cset = 0;*/
for (int y = 0; y < m_tileSet->height; ++y)
{
for (int x = 0; x < m_tileSet->width; ++x)
{
rcTimeVal startTime = rcGetPerformanceTimer();
rcTimeVal startTime = m_ctx->getTime();
Tile& tile = m_tileSet->tiles[x + y*m_tileSet->width];
tile.x = x;
@ -819,14 +804,12 @@ bool Sample_SoloMeshTiled::handleBuild()
tile.solid = rcAllocHeightfield();
if (!tile.solid)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'solid'.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'solid'.", x, y);
continue;
}
if (!rcCreateHeightfield(*tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch))
if (!rcCreateHeightfield(m_ctx, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create solid heightfield.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create solid heightfield.", x, y);
continue;
}
@ -837,98 +820,87 @@ bool Sample_SoloMeshTiled::handleBuild()
const int ntris = node.n;
memset(triangleAreas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(tileCfg.walkableSlopeAngle,
rcMarkWalkableTriangles(m_ctx, tileCfg.walkableSlopeAngle,
verts, nverts, tris, ntris, triangleAreas);
rcRasterizeTriangles(verts, nverts, tris, triangleAreas, ntris, *tile.solid, m_cfg.walkableClimb);
rcRasterizeTriangles(m_ctx, verts, nverts, tris, triangleAreas, ntris, *tile.solid, m_cfg.walkableClimb);
}
rcFilterLowHangingWalkableObstacles(m_cfg.walkableClimb, *tile.solid);
rcFilterLedgeSpans(tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid);
rcFilterWalkableLowHeightSpans(tileCfg.walkableHeight, *tile.solid);
rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, *tile.solid);
rcFilterLedgeSpans(m_ctx, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid);
rcFilterWalkableLowHeightSpans(m_ctx, tileCfg.walkableHeight, *tile.solid);
tile.chf = rcAllocCompactHeightfield();
if (!tile.chf)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'chf'.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'chf'.", x, y);
continue;
}
if (!rcBuildCompactHeightfield(tileCfg.walkableHeight, tileCfg.walkableClimb,
if (!rcBuildCompactHeightfield(m_ctx, tileCfg.walkableHeight, tileCfg.walkableClimb,
*tile.solid, *tile.chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build compact data.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build compact data.", x, y);
continue;
}
// Erode the walkable area by agent radius.
if (!rcErodeWalkableArea(m_cfg.walkableRadius, *tile.chf))
if (!rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, *tile.chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not erode.");
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not erode.");
continue;
}
// (Optional) Mark areas.
const ConvexVolume* vols = m_geom->getConvexVolumes();
for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i)
rcMarkConvexPolyArea(vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *tile.chf);
rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *tile.chf);
if (!rcBuildDistanceField(*tile.chf))
if (!rcBuildDistanceField(m_ctx, *tile.chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build distance fields.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build distance fields.", x, y);
continue;
}
if (!rcBuildRegions(*tile.chf, tileCfg.borderSize, tileCfg.minRegionSize, tileCfg.mergeRegionSize))
if (!rcBuildRegions(m_ctx, *tile.chf, tileCfg.borderSize, tileCfg.minRegionSize, tileCfg.mergeRegionSize))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build regions.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build regions.", x, y);
continue;
}
tile.cset = rcAllocContourSet();
if (!tile.cset)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'cset'.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'cset'.", x, y);
continue;
}
if (!rcBuildContours(*tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset))
if (!rcBuildContours(m_ctx, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create contours.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create contours.", x, y);
continue;
}
tile.pmesh = rcAllocPolyMesh();
if (!tile.pmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'pmesh'.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'pmesh'.", x, y);
continue;
}
if (!rcBuildPolyMesh(*tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh))
if (!rcBuildPolyMesh(m_ctx, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create poly mesh.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create poly mesh.", x, y);
continue;
}
tile.dmesh = rcAllocPolyMeshDetail();
if (!tile.dmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'dmesh'.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'dmesh'.", x, y);
continue;
}
if (!rcBuildPolyMeshDetail(*tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh))
if (!rcBuildPolyMeshDetail(m_ctx, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build detail mesh.", x, y);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build detail mesh.", x, y);
continue;
}
@ -942,8 +914,8 @@ bool Sample_SoloMeshTiled::handleBuild()
tile.cset = 0;
}
rcTimeVal endTime = rcGetPerformanceTimer();
tile.buildTime += rcGetDeltaTimeUsec(startTime, endTime);
rcTimeVal endTime = m_ctx->getTime();
tile.buildTime += m_ctx->getDeltaTimeUsec(startTime, endTime);
// Some extra code to measure some per tile statistics,
// such as build time and how many polygons there are per tile.
@ -969,16 +941,14 @@ bool Sample_SoloMeshTiled::handleBuild()
rcPolyMesh** pmmerge = new rcPolyMesh*[m_tileSet->width*m_tileSet->height];
if (!pmmerge)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'pmmerge' (%d).", m_tileSet->width*m_tileSet->height);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'pmmerge' (%d).", m_tileSet->width*m_tileSet->height);
return false;
}
rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[m_tileSet->width*m_tileSet->height];
if (!dmmerge)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'dmmerge' (%d).", m_tileSet->width*m_tileSet->height);
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'dmmerge' (%d).", m_tileSet->width*m_tileSet->height);
return false;
}
@ -1000,20 +970,18 @@ bool Sample_SoloMeshTiled::handleBuild()
m_pmesh = rcAllocPolyMesh();
if (!m_pmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
return false;
}
rcMergePolyMeshes(pmmerge, nmerge, *m_pmesh);
rcMergePolyMeshes(m_ctx, pmmerge, nmerge, *m_pmesh);
m_dmesh = rcAllocPolyMeshDetail();
if (!m_dmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'dmesh'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'dmesh'.");
return false;
}
rcMergePolyMeshDetails(dmmerge, nmerge, *m_dmesh);
rcMergePolyMeshDetails(m_ctx, dmmerge, nmerge, *m_dmesh);
delete [] pmmerge;
delete [] dmmerge;
@ -1092,8 +1060,7 @@ bool Sample_SoloMeshTiled::handleBuild()
if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
m_ctx->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
return false;
}
@ -1101,70 +1068,30 @@ bool Sample_SoloMeshTiled::handleBuild()
if (!m_navMesh)
{
dtFree(navData);
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not create Detour navmesh");
m_ctx->log(RC_LOG_ERROR, "Could not create Detour navmesh");
return false;
}
if (!m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA))
{
dtFree(navData);
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not init Detour navmesh");
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh");
return false;
}
if (!m_navQuery->init(m_navMesh, 2048))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
return false;
}
}
rcTimeVal totEndTime = rcGetPerformanceTimer();
rcTimeVal totEndTime = m_ctx->getTime();
if (rcGetLog())
{
const float pc = 100.0f / rcGetDeltaTimeUsec(totStartTime, totEndTime);
duLogBuildTimes(m_ctx, m_ctx->getDeltaTimeUsec(totStartTime, totEndTime));
m_ctx->log(RC_LOG_PROGRESS, ">> Polymesh: %d vertices %d polygons", m_pmesh->nverts, m_pmesh->npolys);
rcGetLog()->log(RC_LOG_PROGRESS, "Rasterize: %.1fms (%.1f%%)", m_buildTimes.rasterizeTriangles/1000.0f, m_buildTimes.rasterizeTriangles*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Compact: %.1fms (%.1f%%)", m_buildTimes.buildCompact/1000.0f, m_buildTimes.buildCompact*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Border: %.1fms (%.1f%%)", m_buildTimes.filterBorder/1000.0f, m_buildTimes.filterBorder*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Walkable: %.1fms (%.1f%%)", m_buildTimes.filterWalkable/1000.0f, m_buildTimes.filterWalkable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Median area: %.1fms (%.1f%%)", m_buildTimes.filterMedian/1000.0f, m_buildTimes.filterMedian*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - blur: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldBlur/1000.0f, m_buildTimes.buildDistanceFieldBlur*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Regions: %.1fms (%.1f%%)", m_buildTimes.buildRegions/1000.0f, m_buildTimes.buildRegions*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - watershed: %.1fms (%.1f%%)", m_buildTimes.buildRegionsReg/1000.0f, m_buildTimes.buildRegionsReg*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - expand: %.1fms (%.1f%%)", m_buildTimes.buildRegionsExp/1000.0f, m_buildTimes.buildRegionsExp*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - find catchment basins: %.1fms (%.1f%%)", m_buildTimes.buildRegionsFlood/1000.0f, m_buildTimes.buildRegionsFlood*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.1fms (%.1f%%)", m_buildTimes.buildRegionsFilter/1000.0f, m_buildTimes.buildRegionsFilter*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Contours: %.1fms (%.1f%%)", m_buildTimes.buildContours/1000.0f, m_buildTimes.buildContours*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - trace: %.1fms (%.1f%%)", m_buildTimes.buildContoursTrace/1000.0f, m_buildTimes.buildContoursTrace*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - simplify: %.1fms (%.1f%%)", m_buildTimes.buildContoursSimplify/1000.0f, m_buildTimes.buildContoursSimplify*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh Detail: %.1fms (%.1f%%)", m_buildTimes.buildDetailMesh/1000.0f, m_buildTimes.buildDetailMesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymeshes: %.1fms (%.1f%%)", m_buildTimes.mergePolyMesh/1000.0f, m_buildTimes.mergePolyMesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymesh Details: %.1fms (%.1f%%)", m_buildTimes.mergePolyMeshDetail/1000.0f, m_buildTimes.mergePolyMeshDetail*pc);
if (m_pmesh)
rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_pmesh->nverts, m_pmesh->npolys);
rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f);
}
m_totalBuildTimeMs = rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
m_totalBuildTimeMs = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
if (m_tool)
m_tool->init(this);

View File

@ -27,7 +27,6 @@
#include "Sample.h"
#include "Sample_TileMesh.h"
#include "Recast.h"
#include "RecastTimer.h"
#include "RecastDebugDraw.h"
#include "DetourNavMesh.h"
#include "DetourNavMeshBuilder.h"
@ -179,6 +178,7 @@ Sample_TileMesh::Sample_TileMesh() :
m_cset(0),
m_pmesh(0),
m_dmesh(0),
m_drawMode(DRAWMODE_NAVMESH),
m_maxTiles(0),
m_maxPolysPerTile(0),
m_tileSize(32),
@ -368,6 +368,9 @@ void Sample_TileMesh::handleSettings()
imguiSeparator();
imguiIndent();
imguiIndent();
if (imguiButton("Save"))
{
saveAll("all_tiles_navmesh.bin", m_navMesh);
@ -379,6 +382,9 @@ void Sample_TileMesh::handleSettings()
m_navMesh = loadAll("all_tiles_navmesh.bin");
m_navQuery->init(m_navMesh, 2048);
}
imguiUnindent();
imguiUnindent();
char msg[64];
snprintf(msg, 64, "Build Time: %.1fms", m_totalBuildTimeMs);
@ -427,22 +433,80 @@ void Sample_TileMesh::handleTools()
void Sample_TileMesh::handleDebugMode()
{
if (m_navMesh)
{
if (imguiCheck("Draw Portals", m_drawPortals))
m_drawPortals = !m_drawPortals;
imguiSeparator();
// Check which modes are valid.
bool valid[MAX_DRAWMODE];
for (int i = 0; i < MAX_DRAWMODE; ++i)
valid[i] = false;
imguiValue("Navmesh ready.");
imguiValue("Use 'Create Tiles' tool to experiment.");
imguiValue("LMB: (Re)Create tiles.");
imguiValue("LMB+SHIFT: Remove tiles.");
}
else
if (m_geom)
{
imguiValue("Press [Build] to create tile mesh");
imguiValue("with specified parameters.");
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_PORTALS] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
valid[DRAWMODE_MESH] = true;
valid[DRAWMODE_VOXELS] = m_solid != 0;
valid[DRAWMODE_VOXELS_WALKABLE] = m_solid != 0;
valid[DRAWMODE_COMPACT] = m_chf != 0;
valid[DRAWMODE_COMPACT_DISTANCE] = m_chf != 0;
valid[DRAWMODE_COMPACT_REGIONS] = m_chf != 0;
valid[DRAWMODE_REGION_CONNECTIONS] = m_cset != 0;
valid[DRAWMODE_RAW_CONTOURS] = m_cset != 0;
valid[DRAWMODE_BOTH_CONTOURS] = m_cset != 0;
valid[DRAWMODE_CONTOURS] = m_cset != 0;
valid[DRAWMODE_POLYMESH] = m_pmesh != 0;
valid[DRAWMODE_POLYMESH_DETAIL] = m_dmesh != 0;
}
int unavail = 0;
for (int i = 0; i < MAX_DRAWMODE; ++i)
if (!valid[i]) unavail++;
if (unavail == MAX_DRAWMODE)
return;
imguiLabel("Draw");
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
m_drawMode = DRAWMODE_MESH;
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
m_drawMode = DRAWMODE_NAVMESH;
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
m_drawMode = DRAWMODE_NAVMESH_INVIS;
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
m_drawMode = DRAWMODE_NAVMESH_TRANS;
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
if (imguiCheck("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS, valid[DRAWMODE_NAVMESH_PORTALS]))
m_drawMode = DRAWMODE_NAVMESH_PORTALS;
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
m_drawMode = DRAWMODE_VOXELS;
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
m_drawMode = DRAWMODE_VOXELS_WALKABLE;
if (imguiCheck("Compact", m_drawMode == DRAWMODE_COMPACT, valid[DRAWMODE_COMPACT]))
m_drawMode = DRAWMODE_COMPACT;
if (imguiCheck("Compact Distance", m_drawMode == DRAWMODE_COMPACT_DISTANCE, valid[DRAWMODE_COMPACT_DISTANCE]))
m_drawMode = DRAWMODE_COMPACT_DISTANCE;
if (imguiCheck("Compact Regions", m_drawMode == DRAWMODE_COMPACT_REGIONS, valid[DRAWMODE_COMPACT_REGIONS]))
m_drawMode = DRAWMODE_COMPACT_REGIONS;
if (imguiCheck("Region Connections", m_drawMode == DRAWMODE_REGION_CONNECTIONS, valid[DRAWMODE_REGION_CONNECTIONS]))
m_drawMode = DRAWMODE_REGION_CONNECTIONS;
if (imguiCheck("Raw Contours", m_drawMode == DRAWMODE_RAW_CONTOURS, valid[DRAWMODE_RAW_CONTOURS]))
m_drawMode = DRAWMODE_RAW_CONTOURS;
if (imguiCheck("Both Contours", m_drawMode == DRAWMODE_BOTH_CONTOURS, valid[DRAWMODE_BOTH_CONTOURS]))
m_drawMode = DRAWMODE_BOTH_CONTOURS;
if (imguiCheck("Contours", m_drawMode == DRAWMODE_CONTOURS, valid[DRAWMODE_CONTOURS]))
m_drawMode = DRAWMODE_CONTOURS;
if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH]))
m_drawMode = DRAWMODE_POLYMESH;
if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL]))
m_drawMode = DRAWMODE_POLYMESH_DETAIL;
if (unavail)
{
imguiValue("Tick 'Keep Itermediate Results'");
imguiValue("rebuild some tiles to see");
imguiValue("more debug mode options.");
}
}
@ -454,9 +518,25 @@ void Sample_TileMesh::handleRender()
DebugDrawGL dd;
// Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
if (m_drawMode == DRAWMODE_MESH)
{
// Draw mesh
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
m_agentMaxSlope);
m_geom->drawOffMeshConnections(&dd);
}
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{
// Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd);
}
/* duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd);
m_geom->drawOffMeshConnections(&dd);*/
glDepthMask(GL_FALSE);
@ -476,19 +556,96 @@ void Sample_TileMesh::handleRender()
// Draw active tile
duDebugDrawBoxWire(&dd, m_tileBmin[0],m_tileBmin[1],m_tileBmin[2], m_tileBmax[0],m_tileBmax[1],m_tileBmax[2], m_tileCol, 2.0f);
if (m_navMesh)
/* if (m_navMesh)
{
duDebugDrawNavMeshWithClosedList(&dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
if (m_drawPortals)
duDebugDrawNavMeshPortals(&dd, *m_navMesh);
}*/
if (m_navMesh &&
(m_drawMode == DRAWMODE_NAVMESH ||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
m_drawMode == DRAWMODE_NAVMESH_PORTALS ||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
{
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
duDebugDrawNavMeshWithClosedList(&dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
if (m_drawMode == DRAWMODE_NAVMESH_PORTALS)
duDebugDrawNavMeshPortals(&dd, *m_navMesh);
}
glDepthMask(GL_TRUE);
if (m_chf && m_drawMode == DRAWMODE_COMPACT)
duDebugDrawCompactHeightfieldSolid(&dd, *m_chf);
if (m_chf && m_drawMode == DRAWMODE_COMPACT_DISTANCE)
duDebugDrawCompactHeightfieldDistance(&dd, *m_chf);
if (m_chf && m_drawMode == DRAWMODE_COMPACT_REGIONS)
duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
if (m_solid && m_drawMode == DRAWMODE_VOXELS)
{
glEnable(GL_FOG);
duDebugDrawHeightfieldSolid(&dd, *m_solid);
glDisable(GL_FOG);
}
if (m_solid && m_drawMode == DRAWMODE_VOXELS_WALKABLE)
{
glEnable(GL_FOG);
duDebugDrawHeightfieldWalkable(&dd, *m_solid);
glDisable(GL_FOG);
}
if (m_cset && m_drawMode == DRAWMODE_RAW_CONTOURS)
{
glDepthMask(GL_FALSE);
duDebugDrawRawContours(&dd, *m_cset);
glDepthMask(GL_TRUE);
}
if (m_cset && m_drawMode == DRAWMODE_BOTH_CONTOURS)
{
glDepthMask(GL_FALSE);
duDebugDrawRawContours(&dd, *m_cset, 0.5f);
duDebugDrawContours(&dd, *m_cset);
glDepthMask(GL_TRUE);
}
if (m_cset && m_drawMode == DRAWMODE_CONTOURS)
{
glDepthMask(GL_FALSE);
duDebugDrawContours(&dd, *m_cset);
glDepthMask(GL_TRUE);
}
if (m_chf && m_cset && m_drawMode == DRAWMODE_REGION_CONNECTIONS)
{
duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
glDepthMask(GL_FALSE);
duDebugDrawRegionConnections(&dd, *m_cset);
glDepthMask(GL_TRUE);
}
if (m_pmesh && m_drawMode == DRAWMODE_POLYMESH)
{
glDepthMask(GL_FALSE);
duDebugDrawPolyMesh(&dd, *m_pmesh);
glDepthMask(GL_TRUE);
}
if (m_dmesh && m_drawMode == DRAWMODE_POLYMESH_DETAIL)
{
glDepthMask(GL_FALSE);
duDebugDrawPolyMeshDetail(&dd, *m_dmesh);
glDepthMask(GL_TRUE);
}
m_geom->drawConvexVolumes(&dd);
if (m_tool)
m_tool->handleRender();
m_geom->drawConvexVolumes(&dd);
glDepthMask(GL_TRUE);
glDepthMask(GL_TRUE);
}
void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view)
@ -528,8 +685,7 @@ bool Sample_TileMesh::handleBuild()
{
if (!m_geom || !m_geom->getMesh())
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: No vertices and triangles.");
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: No vertices and triangles.");
return false;
}
@ -538,8 +694,7 @@ bool Sample_TileMesh::handleBuild()
m_navMesh = dtAllocNavMesh();
if (!m_navMesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not allocate navmesh.");
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not allocate navmesh.");
return false;
}
@ -551,15 +706,13 @@ bool Sample_TileMesh::handleBuild()
params.maxPolys = m_maxPolysPerTile;
if (!m_navMesh->init(&params))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh.");
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh.");
return false;
}
if (!m_navQuery->init(m_navMesh, 2048))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init Detour navmesh query");
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init Detour navmesh query");
return false;
}
@ -660,14 +813,12 @@ void Sample_TileMesh::buildAllTiles()
// Start the build process.
rcTimeVal totStartTime = rcGetPerformanceTimer();
rcTimeVal totStartTime = m_ctx->getTime();
for (int y = 0; y < th; ++y)
{
for (int x = 0; x < tw; ++x)
{
printf("processing: %d,%d\n", x,y);
m_tileBmin[0] = bmin[0] + x*tcs;
m_tileBmin[1] = bmin[1];
m_tileBmin[2] = bmin[2] + y*tcs;
@ -690,9 +841,9 @@ void Sample_TileMesh::buildAllTiles()
}
// Start the build process.
rcTimeVal totEndTime = rcGetPerformanceTimer();
rcTimeVal totEndTime = m_ctx->getTime();
m_totalBuildTimeMs = rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
m_totalBuildTimeMs = m_ctx->getDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
}
void Sample_TileMesh::removeAllTiles()
@ -714,11 +865,13 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
{
if (!m_geom || !m_geom->getMesh() || !m_geom->getChunkyMesh())
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
return 0;
}
m_tileMemUsage = 0;
m_tileBuildTime = 0;
cleanup();
const float* verts = m_geom->getMesh()->getVerts();
@ -754,31 +907,25 @@ 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.
memset(&m_buildTimes, 0, sizeof(m_buildTimes));
rcSetBuildTimes(&m_buildTimes);
m_ctx->resetBuildTimes();
// Start the build process.
rcTimeVal totStartTime = rcGetPerformanceTimer();
rcTimeVal totStartTime = m_ctx->getTime();
if (rcGetLog())
{
rcGetLog()->log(RC_LOG_PROGRESS, "Building navigation:");
rcGetLog()->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
rcGetLog()->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
}
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
m_ctx->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
// Allocate voxel heighfield where we rasterize our input data to.
m_solid = rcAllocHeightfield();
if (!m_solid)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
return 0;
}
if (!rcCreateHeightfield(*m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
if (!rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
return 0;
}
@ -788,12 +935,10 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_triareas = new unsigned char[chunkyMesh->maxTrisPerChunk];
if (!m_triareas)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", chunkyMesh->maxTrisPerChunk);
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", chunkyMesh->maxTrisPerChunk);
return 0;
}
float tbmin[2], tbmax[2];
tbmin[0] = m_cfg.bmin[0];
tbmin[1] = m_cfg.bmin[2];
@ -815,10 +960,10 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_tileTriCount += ntris;
memset(m_triareas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle,
rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle,
verts, nverts, tris, ntris, m_triareas);
rcRasterizeTriangles(verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
rcRasterizeTriangles(m_ctx, verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
}
if (!m_keepInterResults)
@ -830,9 +975,9 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
// Once all geometry is rasterized, we do initial pass of filtering to
// remove unwanted overhangs caused by the conservative rasterization
// as well as filter spans where the character cannot possibly stand.
rcFilterLowHangingWalkableObstacles(m_cfg.walkableClimb, *m_solid);
rcFilterLedgeSpans(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid);
rcFilterWalkableLowHeightSpans(m_cfg.walkableHeight, *m_solid);
rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, *m_solid);
rcFilterLedgeSpans(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid);
rcFilterWalkableLowHeightSpans(m_ctx, m_cfg.walkableHeight, *m_solid);
// Compact the heightfield so that it is faster to handle from now on.
// This will result more cache coherent data as well as the neighbours
@ -840,14 +985,12 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_chf = rcAllocCompactHeightfield();
if (!m_chf)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
return 0;
}
if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
if (!rcBuildCompactHeightfield(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
return 0;
}
@ -858,31 +1001,28 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
}
// Erode the walkable area by agent radius.
if (!rcErodeWalkableArea(m_cfg.walkableRadius, *m_chf))
if (!rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, *m_chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
return false;
}
// (Optional) Mark areas.
const ConvexVolume* vols = m_geom->getConvexVolumes();
for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i)
rcMarkConvexPolyArea(vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf);
rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf);
// Prepare for region partitioning, by calculating distance field along the walkable surface.
if (!rcBuildDistanceField(*m_chf))
if (!rcBuildDistanceField(m_ctx, *m_chf))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
return 0;
}
// Partition the walkable surface into simple regions without holes.
if (!rcBuildRegions(*m_chf, m_cfg.borderSize, m_cfg.minRegionSize, m_cfg.mergeRegionSize))
if (!rcBuildRegions(m_ctx, *m_chf, m_cfg.borderSize, m_cfg.minRegionSize, m_cfg.mergeRegionSize))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build regions.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build regions.");
return 0;
}
@ -890,14 +1030,12 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_cset = rcAllocContourSet();
if (!m_cset)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
return 0;
}
if (!rcBuildContours(*m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset))
if (!rcBuildContours(m_ctx, *m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
return 0;
}
@ -910,14 +1048,12 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_pmesh = rcAllocPolyMesh();
if (!m_pmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
return 0;
}
if (!rcBuildPolyMesh(*m_cset, m_cfg.maxVertsPerPoly, *m_pmesh))
if (!rcBuildPolyMesh(m_ctx, *m_cset, m_cfg.maxVertsPerPoly, *m_pmesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
return 0;
}
@ -925,17 +1061,15 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_dmesh = rcAllocPolyMeshDetail();
if (!m_dmesh)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'dmesh'.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'dmesh'.");
return 0;
}
if (!rcBuildPolyMeshDetail(*m_pmesh, *m_chf,
if (!rcBuildPolyMeshDetail(m_ctx, *m_pmesh, *m_chf,
m_cfg.detailSampleDist, m_cfg.detailSampleMaxError,
*m_dmesh))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could build polymesh detail.");
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could build polymesh detail.");
return 0;
}
@ -962,8 +1096,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
if (m_pmesh->nverts >= 0xffff)
{
// The vertex indices are ushorts, and cannot point to more than 0xffff vertices.
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Too many vertices per tile %d (max: %d).", m_pmesh->nverts, 0xffff);
m_ctx->log(RC_LOG_ERROR, "Too many vertices per tile %d (max: %d).", m_pmesh->nverts, 0xffff);
return false;
}
@ -1022,60 +1155,29 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
m_ctx->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
return 0;
}
// Restore padding so that the debug visualization is correct.
for (int i = 0; i < m_pmesh->nverts; ++i)
{
unsigned short* v = &m_pmesh->verts[i*3];
v[0] += (unsigned short)m_cfg.borderSize;
v[2] += (unsigned short)m_cfg.borderSize;
}
}
m_tileMemUsage = navDataSize/1024.0f;
rcTimeVal totEndTime = rcGetPerformanceTimer();
rcTimeVal totEndTime = m_ctx->getTime();
// Show performance stats.
if (rcGetLog())
{
const float pc = 100.0f / rcGetDeltaTimeUsec(totStartTime, totEndTime);
rcGetLog()->log(RC_LOG_PROGRESS, "Rasterize: %.1fms (%.1f%%)", m_buildTimes.rasterizeTriangles/1000.0f, m_buildTimes.rasterizeTriangles*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Compact: %.1fms (%.1f%%)", m_buildTimes.buildCompact/1000.0f, m_buildTimes.buildCompact*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Border: %.1fms (%.1f%%)", m_buildTimes.filterBorder/1000.0f, m_buildTimes.filterBorder*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Walkable: %.1fms (%.1f%%)", m_buildTimes.filterWalkable/1000.0f, m_buildTimes.filterWalkable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Median area: %.1fms (%.1f%%)", m_buildTimes.filterMedian/1000.0f, m_buildTimes.filterMedian*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - blur: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldBlur/1000.0f, m_buildTimes.buildDistanceFieldBlur*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Regions: %.1fms (%.1f%%)", m_buildTimes.buildRegions/1000.0f, m_buildTimes.buildRegions*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - watershed: %.1fms (%.1f%%)", m_buildTimes.buildRegionsReg/1000.0f, m_buildTimes.buildRegionsReg*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - expand: %.1fms (%.1f%%)", m_buildTimes.buildRegionsExp/1000.0f, m_buildTimes.buildRegionsExp*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - find catchment basins: %.1fms (%.1f%%)", m_buildTimes.buildRegionsFlood/1000.0f, m_buildTimes.buildRegionsFlood*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.1fms (%.1f%%)", m_buildTimes.buildRegionsFilter/1000.0f, m_buildTimes.buildRegionsFilter*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Contours: %.1fms (%.1f%%)", m_buildTimes.buildContours/1000.0f, m_buildTimes.buildContours*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - trace: %.1fms (%.1f%%)", m_buildTimes.buildContoursTrace/1000.0f, m_buildTimes.buildContoursTrace*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - simplify: %.1fms (%.1f%%)", m_buildTimes.buildContoursSimplify/1000.0f, m_buildTimes.buildContoursSimplify*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh Detail: %.1fms (%.1f%%)", m_buildTimes.buildDetailMesh/1000.0f, m_buildTimes.buildDetailMesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymeshes: %.1fms (%.1f%%)", m_buildTimes.mergePolyMesh/1000.0f, m_buildTimes.mergePolyMesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymesh Details: %.1fms (%.1f%%)", m_buildTimes.mergePolyMeshDetail/1000.0f, m_buildTimes.mergePolyMeshDetail*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_pmesh->nverts, m_pmesh->npolys);
rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f);
}
m_tileBuildTime = rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f;
duLogBuildTimes(m_ctx, m_ctx->getDeltaTimeUsec(totStartTime, totEndTime));
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;
dataSize = navDataSize;
return navData;
}

View File

@ -157,7 +157,7 @@ void TestCase::resetTimes()
}
}
void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
void TestCase::doTests(rcBuildContext* ctx, dtNavMesh* navmesh, dtNavMeshQuery* navquery)
{
if (!navmesh || !navquery)
return;
@ -183,34 +183,34 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
filter.excludeFlags = (unsigned short)iter->excludeFlags;
// Find start points
rcTimeVal findNearestPolyStart = rcGetPerformanceTimer();
rcTimeVal findNearestPolyStart = ctx->getTime();
dtPolyRef startRef = navquery->findNearestPoly(iter->spos, polyPickExt, &filter, 0);
dtPolyRef endRef = navquery->findNearestPoly(iter->epos, polyPickExt, &filter, 0);
rcTimeVal findNearestPolyEnd = rcGetPerformanceTimer();
iter->findNearestPolyTime += rcGetDeltaTimeUsec(findNearestPolyStart, findNearestPolyEnd);
rcTimeVal findNearestPolyEnd = ctx->getTime();
iter->findNearestPolyTime += ctx->getDeltaTimeUsec(findNearestPolyStart, findNearestPolyEnd);
if (!startRef || ! endRef)
continue;
// Find path
rcTimeVal findPathStart = rcGetPerformanceTimer();
rcTimeVal findPathStart = ctx->getTime();
iter->npolys = navquery->findPath(startRef, endRef, iter->spos, iter->epos, &filter, polys, MAX_POLYS);
rcTimeVal findPathEnd = rcGetPerformanceTimer();
iter->findPathTime += rcGetDeltaTimeUsec(findPathStart, findPathEnd);
rcTimeVal findPathEnd = ctx->getTime();
iter->findPathTime += ctx->getDeltaTimeUsec(findPathStart, findPathEnd);
// Find straight path
if (iter->npolys)
{
rcTimeVal findStraightPathStart = rcGetPerformanceTimer();
rcTimeVal findStraightPathStart = ctx->getTime();
iter->nstraight = navquery->findStraightPath(iter->spos, iter->epos, polys, iter->npolys,
straight, 0, 0, MAX_POLYS);
rcTimeVal findStraightPathEnd = rcGetPerformanceTimer();
iter->findStraightPathTime += rcGetDeltaTimeUsec(findStraightPathStart, findStraightPathEnd);
rcTimeVal findStraightPathEnd = ctx->getTime();
iter->findStraightPathTime += ctx->getDeltaTimeUsec(findStraightPathStart, findStraightPathEnd);
}
// Copy results

View File

@ -308,6 +308,8 @@ static void getBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_ind
*xpos += b->xadvance;
}
static const float g_tabStops[4] = {150, 210, 270, 330};
static float getTextLength(stbtt_bakedchar *chardata, const char* text)
{
float xpos = 0;
@ -315,7 +317,18 @@ static float getTextLength(stbtt_bakedchar *chardata, const char* text)
while (*text)
{
int c = (unsigned char)*text;
if (c >= 32 && c < 128)
if (c == '\t')
{
for (int i = 0; i < 4; ++i)
{
if (xpos < g_tabStops[i])
{
xpos = g_tabStops[i];
break;
}
}
}
else if (c >= 32 && c < 128)
{
stbtt_bakedchar *b = chardata + c-32;
int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5);
@ -346,10 +359,23 @@ static void drawText(float x, float y, const char *text, int align, unsigned int
glBegin(GL_TRIANGLES);
const float ox = x;
while (*text)
{
int c = (unsigned char)*text;
if (c >= 32 && c < 128)
if (c == '\t')
{
for (int i = 0; i < 4; ++i)
{
if (x < g_tabStops[i]+ox)
{
x = g_tabStops[i]+ox;
break;
}
}
}
else if (c >= 32 && c < 128)
{
stbtt_aligned_quad q;
getBakedQuad(g_cdata, 512,512, c-32, &x,&y,&q);

View File

@ -155,9 +155,7 @@ int main(int /*argc*/, char** /*argv*/)
Sample* sample = 0;
TestCase* test = 0;
rcLog log;
log.clear();
rcSetLog(&log);
BuildContext ctx;
glEnable(GL_CULL_FACE);
@ -217,16 +215,14 @@ int main(int /*argc*/, char** /*argv*/)
{
delete geom;
geom = new InputGeom;
if (!geom || !geom->load("geomset.txt"))
if (!geom || !geom->load(&ctx, "geomset.txt"))
{
delete geom;
geom = 0;
showLog = true;
logScroll = 0;
printf("Geom load log %s:\n", meshName);
for (int i = 0; i < log.getMessageCount(); ++i)
printf("%s\n", log.getMessageText(i));
ctx.dumpLog("Geom load log %s:", meshName);
}
if (sample && geom)
{
@ -572,15 +568,13 @@ int main(int /*argc*/, char** /*argv*/)
if (imguiButton("Build"))
{
log.clear();
ctx.resetLog();
if (!sample->handleBuild())
{
showLog = true;
logScroll = 0;
}
printf("Build log %s:\n", meshName);
for (int i = 0; i < log.getMessageCount(); ++i)
printf("%s\n", log.getMessageText(i));
ctx.dumpLog("Build log %s:", meshName);
// Clear test.
delete test;
@ -619,13 +613,15 @@ int main(int /*argc*/, char** /*argv*/)
if (imguiItem(g_samples[i].name))
{
newSample = g_samples[i].create();
if (newSample) strcpy(sampleName, g_samples[i].name);
if (newSample)
strcpy(sampleName, g_samples[i].name);
}
}
if (newSample)
{
delete sample;
sample = newSample;
sample->setContext(&ctx);
if (geom && sample)
{
sample->handleMeshChanged(geom);
@ -695,16 +691,14 @@ int main(int /*argc*/, char** /*argv*/)
strcat(path, meshName);
geom = new InputGeom;
if (!geom || !geom->loadMesh(path))
if (!geom || !geom->loadMesh(&ctx, path))
{
delete geom;
geom = 0;
showLog = true;
logScroll = 0;
printf("Geom load log %s:\n", meshName);
for (int i = 0; i < log.getMessageCount(); ++i)
printf("%s\n", log.getMessageText(i));
ctx.dumpLog("Geom load log %s:", meshName);
}
if (sample && geom)
{
@ -790,6 +784,7 @@ int main(int /*argc*/, char** /*argv*/)
{
delete sample;
sample = newSample;
sample->setContext(&ctx);
showSample = false;
}
@ -804,28 +799,24 @@ int main(int /*argc*/, char** /*argv*/)
strcat(path, meshName);
geom = new InputGeom;
if (!geom || !geom->loadMesh(path))
if (!geom || !geom->loadMesh(&ctx, path))
{
delete geom;
geom = 0;
showLog = true;
logScroll = 0;
printf("Geom load log %s:\n", meshName);
for (int i = 0; i < log.getMessageCount(); ++i)
printf("%s\n", log.getMessageText(i));
ctx.dumpLog("Geom load log %s:", meshName);
}
if (sample && geom)
{
sample->handleMeshChanged(geom);
}
log.clear();
ctx.resetLog();
if (sample && !sample->handleBuild())
{
printf("Build log %s:\n", meshName);
for (int i = 0; i < log.getMessageCount(); ++i)
printf("%s\n", log.getMessageText(i));
ctx.dumpLog("Build log %s:", meshName);
}
if (geom || sample)
@ -861,7 +852,7 @@ int main(int /*argc*/, char** /*argv*/)
// Do the tests.
if (sample)
test->doTests(sample->getNavMesh(), sample->getNavMeshQuery());
test->doTests(&ctx, sample->getNavMesh(), sample->getNavMeshQuery());
}
}
@ -874,8 +865,8 @@ int main(int /*argc*/, char** /*argv*/)
{
if (imguiBeginScrollArea("Log", 10, 10, width - 300, 200, &logScroll))
mouseOverMenu = true;
for (int i = 0; i < log.getMessageCount(); ++i)
imguiLabel(log.getMessageText(i));
for (int i = 0; i < ctx.getLogCount(); ++i)
imguiLabel(ctx.getLogText(i));
imguiEndScrollArea();
}