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

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <algorithm>
#include "Recast.h"
#include "InputGeom.h"
#include "ChunkyTriMesh.h"
@@ -107,6 +108,7 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len)
InputGeom::InputGeom() :
m_chunkyMesh(0),
m_mesh(0),
m_hasBuildSettings(false),
m_offMeshConCount(0),
m_volumeCount(0)
{
@@ -118,7 +120,7 @@ InputGeom::~InputGeom()
delete m_mesh;
}
bool InputGeom::loadMesh(rcContext* ctx, const char* filepath)
bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath)
{
if (m_mesh)
{
@@ -138,7 +140,7 @@ bool InputGeom::loadMesh(rcContext* ctx, const char* filepath)
}
if (!m_mesh->load(filepath))
{
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath);
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath.c_str());
return false;
}
@@ -159,10 +161,10 @@ bool InputGeom::loadMesh(rcContext* ctx, const char* filepath)
return true;
}
bool InputGeom::load(rcContext* ctx, const char* filePath)
bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath)
{
char* buf = 0;
FILE* fp = fopen(filePath, "rb");
FILE* fp = fopen(filepath.c_str(), "rb");
if (!fp)
return false;
fseek(fp, 0, SEEK_END);
@@ -243,6 +245,33 @@ bool InputGeom::load(rcContext* ctx, const char* filePath)
}
}
}
else if (row[0] == 's')
{
// Settings
m_hasBuildSettings = true;
sscanf(row + 1, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d %f %f %f %f %f %f %f",
&m_buildSettings.cellSize,
&m_buildSettings.cellHeight,
&m_buildSettings.agentHeight,
&m_buildSettings.agentRadius,
&m_buildSettings.agentMaxClimb,
&m_buildSettings.agentMaxSlope,
&m_buildSettings.regionMinSize,
&m_buildSettings.regionMergeSize,
&m_buildSettings.edgeMaxLen,
&m_buildSettings.edgeMaxError,
&m_buildSettings.vertsPerPoly,
&m_buildSettings.detailSampleDist,
&m_buildSettings.detailSampleMaxError,
&m_buildSettings.partitionType,
&m_buildSettings.navMeshBMin[0],
&m_buildSettings.navMeshBMin[1],
&m_buildSettings.navMeshBMin[2],
&m_buildSettings.navMeshBMax[0],
&m_buildSettings.navMeshBMax[1],
&m_buildSettings.navMeshBMax[2],
&m_buildSettings.tileSize);
}
}
delete [] buf;
@@ -250,15 +279,68 @@ bool InputGeom::load(rcContext* ctx, const char* filePath)
return true;
}
bool InputGeom::save(const char* filepath)
bool InputGeom::load(rcContext* ctx, const std::string& filepath)
{
size_t extensionPos = filepath.find_last_of('.');
if (extensionPos == std::string::npos)
return false;
std::string extension = filepath.substr(extensionPos);
std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
if (extension == ".gset")
return loadGeomSet(ctx, filepath);
if (extension == ".obj")
return loadMesh(ctx, filepath);
return false;
}
bool InputGeom::saveGeomSet(const BuildSettings* settings)
{
if (!m_mesh) return false;
FILE* fp = fopen(filepath, "w");
// Change extension
std::string filepath = m_mesh->getFileName();
size_t extPos = filepath.find_last_of('.');
if (extPos != std::string::npos)
filepath = filepath.substr(0, extPos);
filepath += ".gset";
FILE* fp = fopen(filepath.c_str(), "w");
if (!fp) return false;
// Store mesh filename.
fprintf(fp, "f %s\n", m_mesh->getFileName());
fprintf(fp, "f %s\n", m_mesh->getFileName().c_str());
// Store settings if any
if (settings)
{
fprintf(fp,
"s %f %f %f %f %f %f %f %f %f %f %f %f %f %d %f %f %f %f %f %f %f\n",
settings->cellSize,
settings->cellHeight,
settings->agentHeight,
settings->agentRadius,
settings->agentMaxClimb,
settings->agentMaxSlope,
settings->regionMinSize,
settings->regionMergeSize,
settings->edgeMaxLen,
settings->edgeMaxError,
settings->vertsPerPoly,
settings->detailSampleDist,
settings->detailSampleMaxError,
settings->partitionType,
settings->navMeshBMin[0],
settings->navMeshBMin[1],
settings->navMeshBMin[2],
settings->navMeshBMax[0],
settings->navMeshBMax[1],
settings->navMeshBMax[2],
settings->tileSize);
}
// Store off-mesh links.
for (int i = 0; i < m_offMeshConCount; ++i)