Add settings storage to geometry sets

This adds the ability for geometry sets to store build settings that can
be automatically applied when they are loaded. This should allow sharing
of .gset files to demonstrate problems with certain settings on certain
files. It also allows people to diagnose problems more easily by being
able to dump their own triangle meshes and settings and load them in the
demo, with all of its visualization options. .gset files can be created
from the current mesh and settings by pressing the 9 key, which will
generate it in the same folder as the input mesh.

Also converts more of the demo to use STL.
This commit is contained in:
Jakob Botsch Nielsen
2016-01-17 18:55:54 +01:00
parent f8d6d3976d
commit a31da928ba
16 changed files with 333 additions and 216 deletions

View File

@@ -195,8 +195,8 @@ Sample_TileMesh::Sample_TileMesh() :
m_tileTriCount(0)
{
resetCommonSettings();
memset(m_tileBmin, 0, sizeof(m_tileBmin));
memset(m_tileBmax, 0, sizeof(m_tileBmax));
memset(m_lastBuiltTileBmin, 0, sizeof(m_lastBuiltTileBmin));
memset(m_lastBuiltTileBmax, 0, sizeof(m_lastBuiltTileBmax));
setTool(new NavMeshTileTool);
}
@@ -359,10 +359,10 @@ void Sample_TileMesh::handleSettings()
if (m_geom)
{
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
char text[64];
int gw = 0, gh = 0;
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
const int tw = (gw + ts-1) / ts;
@@ -561,8 +561,8 @@ void Sample_TileMesh::handleRender()
glDepthMask(GL_FALSE);
// Draw bounds
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
// Tiling grid.
@@ -574,8 +574,8 @@ void Sample_TileMesh::handleRender()
duDebugDrawGridXZ(&dd, bmin[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
// 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, 1.0f);
duDebugDrawBoxWire(&dd, m_lastBuiltTileBmin[0],m_lastBuiltTileBmin[1],m_lastBuiltTileBmin[2],
m_lastBuiltTileBmax[0],m_lastBuiltTileBmax[1],m_lastBuiltTileBmax[2], m_tileCol, 1.0f);
if (m_navMesh && m_navQuery &&
(m_drawMode == DRAWMODE_NAVMESH ||
@@ -674,7 +674,7 @@ void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
GLdouble x, y, z;
// Draw start and end point labels
if (m_tileBuildTime > 0.0f && gluProject((GLdouble)(m_tileBmin[0]+m_tileBmax[0])/2, (GLdouble)(m_tileBmin[1]+m_tileBmax[1])/2, (GLdouble)(m_tileBmin[2]+m_tileBmax[2])/2,
if (m_tileBuildTime > 0.0f && gluProject((GLdouble)(m_lastBuiltTileBmin[0]+m_lastBuiltTileBmax[0])/2, (GLdouble)(m_lastBuiltTileBmin[1]+m_lastBuiltTileBmax[1])/2, (GLdouble)(m_lastBuiltTileBmin[2]+m_lastBuiltTileBmax[2])/2,
model, proj, view, &x, &y, &z))
{
char text[32];
@@ -687,10 +687,14 @@ void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
renderOverlayToolStates(proj, model, view);
}
void Sample_TileMesh::handleMeshChanged(class InputGeom* geom)
void Sample_TileMesh::handleMeshChanged(InputGeom* geom)
{
Sample::handleMeshChanged(geom);
const BuildSettings* buildSettings = geom->getBuildSettings();
if (buildSettings && buildSettings->tileSize > 0)
m_tileSize = buildSettings->tileSize;
cleanup();
dtFreeNavMesh(m_navMesh);
@@ -723,7 +727,7 @@ bool Sample_TileMesh::handleBuild()
}
dtNavMeshParams params;
rcVcopy(params.orig, m_geom->getMeshBoundsMin());
rcVcopy(params.orig, m_geom->getNavMeshBoundsMin());
params.tileWidth = m_tileSize*m_cellSize;
params.tileHeight = m_tileSize*m_cellSize;
params.maxTiles = m_maxTiles;
@@ -755,32 +759,39 @@ bool Sample_TileMesh::handleBuild()
return true;
}
void Sample_TileMesh::collectSettings(BuildSettings& settings)
{
Sample::collectSettings(settings);
settings.tileSize = m_tileSize;
}
void Sample_TileMesh::buildTile(const float* pos)
{
if (!m_geom) return;
if (!m_navMesh) return;
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
const float ts = m_tileSize*m_cellSize;
const int tx = (int)((pos[0] - bmin[0]) / ts);
const int ty = (int)((pos[2] - bmin[2]) / ts);
m_tileBmin[0] = bmin[0] + tx*ts;
m_tileBmin[1] = bmin[1];
m_tileBmin[2] = bmin[2] + ty*ts;
m_lastBuiltTileBmin[0] = bmin[0] + tx*ts;
m_lastBuiltTileBmin[1] = bmin[1];
m_lastBuiltTileBmin[2] = bmin[2] + ty*ts;
m_tileBmax[0] = bmin[0] + (tx+1)*ts;
m_tileBmax[1] = bmax[1];
m_tileBmax[2] = bmin[2] + (ty+1)*ts;
m_lastBuiltTileBmax[0] = bmin[0] + (tx+1)*ts;
m_lastBuiltTileBmax[1] = bmax[1];
m_lastBuiltTileBmax[2] = bmin[2] + (ty+1)*ts;
m_tileCol = duRGBA(255,255,255,64);
m_ctx->resetLog();
int dataSize = 0;
unsigned char* data = buildTileMesh(tx, ty, m_tileBmin, m_tileBmax, dataSize);
unsigned char* data = buildTileMesh(tx, ty, m_lastBuiltTileBmin, m_lastBuiltTileBmax, dataSize);
// Remove any previous data (navmesh owns and deletes the data).
m_navMesh->removeTile(m_navMesh->getTileRefAt(tx,ty,0),0,0);
@@ -801,7 +812,7 @@ void Sample_TileMesh::getTilePos(const float* pos, int& tx, int& ty)
{
if (!m_geom) return;
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmin = m_geom->getNavMeshBoundsMin();
const float ts = m_tileSize*m_cellSize;
tx = (int)((pos[0] - bmin[0]) / ts);
@@ -813,20 +824,20 @@ void Sample_TileMesh::removeTile(const float* pos)
if (!m_geom) return;
if (!m_navMesh) return;
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
const float ts = m_tileSize*m_cellSize;
const int tx = (int)((pos[0] - bmin[0]) / ts);
const int ty = (int)((pos[2] - bmin[2]) / ts);
m_tileBmin[0] = bmin[0] + tx*ts;
m_tileBmin[1] = bmin[1];
m_tileBmin[2] = bmin[2] + ty*ts;
m_lastBuiltTileBmin[0] = bmin[0] + tx*ts;
m_lastBuiltTileBmin[1] = bmin[1];
m_lastBuiltTileBmin[2] = bmin[2] + ty*ts;
m_tileBmax[0] = bmin[0] + (tx+1)*ts;
m_tileBmax[1] = bmax[1];
m_tileBmax[2] = bmin[2] + (ty+1)*ts;
m_lastBuiltTileBmax[0] = bmin[0] + (tx+1)*ts;
m_lastBuiltTileBmax[1] = bmax[1];
m_lastBuiltTileBmax[2] = bmin[2] + (ty+1)*ts;
m_tileCol = duRGBA(128,32,16,64);
@@ -838,8 +849,8 @@ void Sample_TileMesh::buildAllTiles()
if (!m_geom) return;
if (!m_navMesh) return;
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
@@ -855,16 +866,16 @@ void Sample_TileMesh::buildAllTiles()
{
for (int x = 0; x < tw; ++x)
{
m_tileBmin[0] = bmin[0] + x*tcs;
m_tileBmin[1] = bmin[1];
m_tileBmin[2] = bmin[2] + y*tcs;
m_lastBuiltTileBmin[0] = bmin[0] + x*tcs;
m_lastBuiltTileBmin[1] = bmin[1];
m_lastBuiltTileBmin[2] = bmin[2] + y*tcs;
m_tileBmax[0] = bmin[0] + (x+1)*tcs;
m_tileBmax[1] = bmax[1];
m_tileBmax[2] = bmin[2] + (y+1)*tcs;
m_lastBuiltTileBmax[0] = bmin[0] + (x+1)*tcs;
m_lastBuiltTileBmax[1] = bmax[1];
m_lastBuiltTileBmax[2] = bmin[2] + (y+1)*tcs;
int dataSize = 0;
unsigned char* data = buildTileMesh(x, y, m_tileBmin, m_tileBmax, dataSize);
unsigned char* data = buildTileMesh(x, y, m_lastBuiltTileBmin, m_lastBuiltTileBmax, dataSize);
if (data)
{
// Remove any previous data (navmesh owns and deletes the data).
@@ -886,8 +897,11 @@ void Sample_TileMesh::buildAllTiles()
void Sample_TileMesh::removeAllTiles()
{
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
if (!m_geom || !m_navMesh)
return;
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
@@ -1106,14 +1120,14 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
if (!rcBuildDistanceField(m_ctx, *m_chf))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
return false;
return 0;
}
// Partition the walkable surface into simple regions without holes.
if (!rcBuildRegions(m_ctx, *m_chf, m_cfg.borderSize, m_cfg.minRegionArea, m_cfg.mergeRegionArea))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build watershed regions.");
return false;
return 0;
}
}
else if (m_partitionType == SAMPLE_PARTITION_MONOTONE)
@@ -1123,7 +1137,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
if (!rcBuildRegionsMonotone(m_ctx, *m_chf, m_cfg.borderSize, m_cfg.minRegionArea, m_cfg.mergeRegionArea))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build monotone regions.");
return false;
return 0;
}
}
else // SAMPLE_PARTITION_LAYERS
@@ -1132,7 +1146,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
if (!rcBuildLayerRegions(m_ctx, *m_chf, m_cfg.borderSize, m_cfg.minRegionArea))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build layer regions.");
return false;
return 0;
}
}