Fix0ring r347...

This commit is contained in:
Mikko Mononen 2012-10-21 16:21:47 +00:00
parent 4c6b604ca3
commit 943ce1b263
2 changed files with 43 additions and 132 deletions

View File

@ -131,7 +131,7 @@ public:
m_nav = nav;
return true;
return false;
}
inline void clearAllFlags()
@ -166,7 +166,7 @@ public:
};
static void floodNavmesh(const dtNavMesh* nav, NavmeshFlags* flags, dtPolyRef start, unsigned char flag, PolyRefArray* visited)
static void floodNavmesh(dtNavMesh* nav, NavmeshFlags* flags, dtPolyRef start, unsigned char flag)
{
// If already visited, skip.
if (flags->getFlags(start))
@ -178,8 +178,6 @@ static void floodNavmesh(const dtNavMesh* nav, NavmeshFlags* flags, dtPolyRef st
while (openList.size())
{
const dtPolyRef ref = openList.pop();
if (visited)
visited->push(ref);
// Get current poly and tile.
// The API input has been cheked already, skip checking internal data.
const dtMeshTile* tile = 0;
@ -201,102 +199,7 @@ static void floodNavmesh(const dtNavMesh* nav, NavmeshFlags* flags, dtPolyRef st
}
}
static int getPolyVerts(const dtNavMesh* nav, dtPolyRef ref, float* verts)
{
const dtMeshTile* tile = 0;
const dtPoly* poly = 0;
dtStatus status = nav->getTileAndPolyByRef(ref, &tile, &poly);
if (dtStatusFailed(status))
return 0;
for (int i = 0; i < (int)poly->vertCount; ++i)
dtVcopy(&verts[i*3], &tile->verts[poly->verts[i]*3]);
return (int)poly->vertCount;
}
static void calcBounds(const dtNavMesh* nav, const PolyRefArray& polys, float* bounds)
{
dtVset(&bounds[0], FLT_MAX,FLT_MAX,FLT_MAX);
dtVset(&bounds[3], -FLT_MAX,-FLT_MAX,-FLT_MAX);
float verts[DT_VERTS_PER_POLYGON*3];
for (int i = 0; i < polys.size(); i++)
{
const dtPolyRef ref = polys[i];
int nv = getPolyVerts(nav, ref, verts);
for (int j = 0; j < nv; j++)
{
dtVmin(&bounds[0], &verts[j*3]);
dtVmax(&bounds[3], &verts[j*3]);
}
}
}
static bool selectSmallAreas(const dtNavMesh* nav, NavmeshFlags* flags,
const float minSize, unsigned char flag)
{
PolyRefArray visited;
NavmeshFlags oflags;
if (!oflags.init(nav))
{
return false;
}
for (int i = 0; i < nav->getMaxTiles(); ++i)
{
const dtMeshTile* tile = nav->getTile(i);
if (!tile->header) continue;
dtPolyRef base = nav->getPolyRefBase(tile);
for (int j = 0; j < tile->header->polyCount; j++)
{
dtPolyRef start = base | (dtPolyRef)j;
if (oflags.getFlags(start))
continue;
// Flood connected polygons.
visited.resize(0);
floodNavmesh(nav, &oflags, start, 1, &visited);
if (visited.size() > 0)
{
// Calculate the bbox of the visited polygons
float bounds[6];
calcBounds(nav, visited, bounds);
const float w = bounds[3]-bounds[0];
const float h = bounds[5]-bounds[2];
// The visited area is too small, mark it.
if (w < minSize && h < minSize)
{
for (int k = 0; k < visited.size(); k++)
flags->setFlags(visited[k], flag);
}
}
}
}
return true;
}
static void disableSelectedPolys(dtNavMesh* nav, NavmeshFlags* flags)
{
for (int i = 0; i < nav->getMaxTiles(); ++i)
{
const dtMeshTile* tile = ((const dtNavMesh*)nav)->getTile(i);
if (!tile->header) continue;
const dtPolyRef base = nav->getPolyRefBase(tile);
for (int j = 0; j < tile->header->polyCount; ++j)
{
const dtPolyRef ref = base | (unsigned int)j;
if (flags->getFlags(ref))
{
unsigned short f = 0;
nav->getPolyFlags(ref, &f);
nav->setPolyFlags(ref, f | SAMPLE_POLYFLAGS_DISABLED);
}
}
}
}
static void disableUnselectedPolys(dtNavMesh* nav, NavmeshFlags* flags)
static void disableUnvisitedPolys(dtNavMesh* nav, NavmeshFlags* flags)
{
for (int i = 0; i < nav->getMaxTiles(); ++i)
{
@ -343,39 +246,19 @@ void NavMeshPruneTool::handleMenu()
{
dtNavMesh* nav = m_sample->getNavMesh();
if (!nav) return;
if (imguiButton("Select Small Areas"))
{
if (!m_flags)
{
m_flags = new NavmeshFlags;
m_flags->init(nav);
}
const float minSize = m_sample->getAgentRadius()*2 * 5.0f;
selectSmallAreas(nav, m_flags, minSize, 1);
}
if (!m_flags) return;
if (imguiButton("Clear Selection"))
{
m_flags->clearAllFlags();
}
if (imguiButton("Prune Selected"))
{
disableSelectedPolys(nav, m_flags);
delete m_flags;
m_flags = 0;
}
if (imguiButton("Prune Unselected"))
{
disableUnselectedPolys(nav, m_flags);
disableUnvisitedPolys(nav, m_flags);
delete m_flags;
m_flags = 0;
}
}
void NavMeshPruneTool::handleClick(const float* /*s*/, const float* p, bool shift)
@ -402,7 +285,7 @@ void NavMeshPruneTool::handleClick(const float* /*s*/, const float* p, bool shif
dtPolyRef ref = 0;
query->findNearestPoly(p, ext, &filter, &ref, 0);
floodNavmesh(nav, m_flags, ref, 1, 0);
floodNavmesh(nav, m_flags, ref, 1);
}
void NavMeshPruneTool::handleToggle()

View File

@ -50,6 +50,7 @@ static int loadBin(const char* path, unsigned char** data)
*/
Sample_Debug::Sample_Debug() :
m_chf(0),
m_cset(0),
m_pmesh(0)
{
@ -137,7 +138,7 @@ Sample_Debug::Sample_Debug() :
if (m_cset)
{
FileIO io;
if (io.openForRead("dump.cset"))
if (io.openForRead("PathSet_TMP_NA_PathingTestAReg1_1_2_CS.rc"))
{
duReadContourSet(*m_cset, &io);
@ -145,23 +146,33 @@ Sample_Debug::Sample_Debug() :
m_cset->bmin[0], m_cset->bmin[1], m_cset->bmin[2],
m_cset->bmax[0], m_cset->bmax[1], m_cset->bmax[2]);
printf("cs=%f ch=%f\n", m_cset->cs, m_cset->ch);
m_cset->bmax[1] *= 0.1f;
}
else
{
printf("could not open dump.cset\n");
printf("could not open test.cset\n");
}
}
else
{
printf("Could not alloc cset\n");
}
/* if (m_cset)
{
m_pmesh = rcAllocPolyMesh();
if (m_pmesh)
{
rcBuildPolyMesh(m_ctx, *m_cset, 6, *m_pmesh);
}
}*/
}
}
Sample_Debug::~Sample_Debug()
{
rcFreeCompactHeightfield(m_chf);
rcFreeContourSet(m_cset);
rcFreePolyMesh(m_pmesh);
}
@ -182,6 +193,12 @@ void Sample_Debug::handleRender()
{
DebugDrawGL dd;
if (m_chf)
{
duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
// duDebugDrawCompactHeightfieldSolid(&dd, *m_chf);
}
if (m_navMesh)
duDebugDrawNavMesh(&dd, *m_navMesh, DU_DRAWNAVMESH_OFFMESHCONS);
@ -198,9 +215,6 @@ void Sample_Debug::handleRender()
{
duDebugDrawRawContours(&dd, *m_cset, 0.25f);
duDebugDrawContours(&dd, *m_cset);
const float* bmin = m_cset->bmin;
const float* bmax = m_cset->bmax;
duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
}
if (m_pmesh)
@ -319,6 +333,8 @@ const float* Sample_Debug::getBoundsMin()
{
if (m_cset)
return m_cset->bmin;
if (m_chf)
return m_chf->bmin;
if (m_navMesh)
return m_bmin;
return 0;
@ -328,6 +344,8 @@ const float* Sample_Debug::getBoundsMax()
{
if (m_cset)
return m_cset->bmax;
if (m_chf)
return m_chf->bmax;
if (m_navMesh)
return m_bmax;
return 0;
@ -348,12 +366,22 @@ void Sample_Debug::handleToggle()
bool Sample_Debug::handleBuild()
{
if (m_cset)
if (m_chf)
{
m_pmesh = rcAllocPolyMesh();
if (m_pmesh)
rcFreeContourSet(m_cset);
m_cset = 0;
// Create contours.
m_cset = rcAllocContourSet();
if (!m_cset)
{
rcBuildPolyMesh(m_ctx, *m_cset, 6, *m_pmesh);
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
return false;
}
if (!rcBuildContours(m_ctx, *m_chf, /*m_cfg.maxSimplificationError*/1.3f, /*m_cfg.maxEdgeLen*/12, *m_cset))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
return false;
}
}