Merge pull request #160 from Janiels/settings-presets

Add settings storage to geometry sets
This commit is contained in:
Graham Pentheny 2016-01-18 15:58:21 -05:00
commit 451c87b687
16 changed files with 333 additions and 216 deletions

4
.gitignore vendored
View File

@ -16,8 +16,8 @@ RecastDemo/Bin/Tests
# Build directory # Build directory
RecastDemo/Build RecastDemo/Build
# Ignore some meshes based on name # Ignore meshes
RecastDemo/Bin/Meshes/_* RecastDemo/Bin/Meshes/*
## Logs and databases # ## Logs and databases #
*.log *.log

View File

@ -22,6 +22,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
void scanDirectory(std::string path, std::string ext, std::vector<std::string>& fileList); void scanDirectoryAppend(const std::string& path, const std::string& ext, std::vector<std::string>& fileList);
void scanDirectory(const std::string& path, const std::string& ext, std::vector<std::string>& fileList);
#endif // FILELIST_H #endif // FILELIST_H

View File

@ -31,11 +31,51 @@ struct ConvexVolume
int area; int area;
}; };
struct BuildSettings
{
// Cell size in world units
float cellSize;
// Cell height in world units
float cellHeight;
// Agent height in world units
float agentHeight;
// Agent radius in world units
float agentRadius;
// Agent max climb in world units
float agentMaxClimb;
// Agent max slope in degrees
float agentMaxSlope;
// Region minimum size in voxels.
// regionMinSize = sqrt(regionMinArea)
float regionMinSize;
// Region merge size in voxels.
// regionMergeSize = sqrt(regionMergeArea)
float regionMergeSize;
// Edge max length in world units
float edgeMaxLen;
// Edge max error in voxels
float edgeMaxError;
float vertsPerPoly;
// Detail sample distance in voxels
float detailSampleDist;
// Detail sample max error in voxel heights.
float detailSampleMaxError;
// Partition type, see SamplePartitionType
int partitionType;
// Bounds of the area to mesh
float navMeshBMin[3];
float navMeshBMax[3];
// Size of the tiles in voxels
float tileSize;
};
class InputGeom class InputGeom
{ {
rcChunkyTriMesh* m_chunkyMesh; rcChunkyTriMesh* m_chunkyMesh;
rcMeshLoaderObj* m_mesh; rcMeshLoaderObj* m_mesh;
float m_meshBMin[3], m_meshBMax[3]; float m_meshBMin[3], m_meshBMax[3];
BuildSettings m_buildSettings;
bool m_hasBuildSettings;
/// @name Off-Mesh connections. /// @name Off-Mesh connections.
///@{ ///@{
@ -56,20 +96,24 @@ class InputGeom
int m_volumeCount; int m_volumeCount;
///@} ///@}
bool loadMesh(class rcContext* ctx, const std::string& filepath);
bool loadGeomSet(class rcContext* ctx, const std::string& filepath);
public: public:
InputGeom(); InputGeom();
~InputGeom(); ~InputGeom();
bool loadMesh(class rcContext* ctx, const char* filepath);
bool load(class rcContext* ctx, const char* filepath); bool load(class rcContext* ctx, const std::string& filepath);
bool save(const char* filepath); bool saveGeomSet(const BuildSettings* settings);
/// Method to return static mesh data. /// Method to return static mesh data.
inline const rcMeshLoaderObj* getMesh() const { return m_mesh; } const rcMeshLoaderObj* getMesh() const { return m_mesh; }
inline const float* getMeshBoundsMin() const { return m_meshBMin; } const float* getMeshBoundsMin() const { return m_meshBMin; }
inline const float* getMeshBoundsMax() const { return m_meshBMax; } const float* getMeshBoundsMax() const { return m_meshBMax; }
inline const rcChunkyTriMesh* getChunkyMesh() const { return m_chunkyMesh; } const float* getNavMeshBoundsMin() const { return m_hasBuildSettings ? m_buildSettings.navMeshBMin : m_meshBMin; }
const float* getNavMeshBoundsMax() const { return m_hasBuildSettings ? m_buildSettings.navMeshBMax : m_meshBMax; }
const rcChunkyTriMesh* getChunkyMesh() const { return m_chunkyMesh; }
const BuildSettings* getBuildSettings() const { return m_hasBuildSettings ? &m_buildSettings : 0; }
bool raycastMesh(float* src, float* dst, float& tmin); bool raycastMesh(float* src, float* dst, float& tmin);
/// @name Off-Mesh connections. /// @name Off-Mesh connections.

View File

@ -19,27 +19,29 @@
#ifndef MESHLOADER_OBJ #ifndef MESHLOADER_OBJ
#define MESHLOADER_OBJ #define MESHLOADER_OBJ
#include <string>
class rcMeshLoaderObj class rcMeshLoaderObj
{ {
public: public:
rcMeshLoaderObj(); rcMeshLoaderObj();
~rcMeshLoaderObj(); ~rcMeshLoaderObj();
bool load(const char* fileName); bool load(const std::string& fileName);
inline const float* getVerts() const { return m_verts; } const float* getVerts() const { return m_verts; }
inline const float* getNormals() const { return m_normals; } const float* getNormals() const { return m_normals; }
inline const int* getTris() const { return m_tris; } const int* getTris() const { return m_tris; }
inline int getVertCount() const { return m_vertCount; } int getVertCount() const { return m_vertCount; }
inline int getTriCount() const { return m_triCount; } int getTriCount() const { return m_triCount; }
inline const char* getFileName() const { return m_filename; } const std::string& getFileName() const { return m_filename; }
private: private:
void addVertex(float x, float y, float z, int& cap); void addVertex(float x, float y, float z, int& cap);
void addTriangle(int a, int b, int c, int& cap); void addTriangle(int a, int b, int c, int& cap);
char m_filename[260]; std::string m_filename;
float m_scale; float m_scale;
float* m_verts; float* m_verts;
int* m_tris; int* m_tris;

View File

@ -141,6 +141,7 @@ public:
virtual void handleMeshChanged(class InputGeom* geom); virtual void handleMeshChanged(class InputGeom* geom);
virtual bool handleBuild(); virtual bool handleBuild();
virtual void handleUpdate(const float dt); virtual void handleUpdate(const float dt);
virtual void collectSettings(struct BuildSettings& settings);
virtual class InputGeom* getInputGeom() { return m_geom; } virtual class InputGeom* getInputGeom() { return m_geom; }
virtual class dtNavMesh* getNavMesh() { return m_navMesh; } virtual class dtNavMesh* getNavMesh() { return m_navMesh; }
@ -149,11 +150,9 @@ public:
virtual float getAgentRadius() { return m_agentRadius; } virtual float getAgentRadius() { return m_agentRadius; }
virtual float getAgentHeight() { return m_agentHeight; } virtual float getAgentHeight() { return m_agentHeight; }
virtual float getAgentClimb() { return m_agentMaxClimb; } virtual float getAgentClimb() { return m_agentMaxClimb; }
virtual const float* getBoundsMin();
virtual const float* getBoundsMax();
inline unsigned char getNavMeshDrawFlags() const { return m_navMeshDrawFlags; } unsigned char getNavMeshDrawFlags() const { return m_navMeshDrawFlags; }
inline void setNavMeshDrawFlags(unsigned char flags) { m_navMeshDrawFlags = flags; } void setNavMeshDrawFlags(unsigned char flags) { m_navMeshDrawFlags = flags; }
void updateToolStates(const float dt); void updateToolStates(const float dt);
void initToolStates(Sample* sample); void initToolStates(Sample* sample);

View File

@ -69,8 +69,8 @@ protected:
float m_tileSize; float m_tileSize;
unsigned int m_tileCol; unsigned int m_tileCol;
float m_tileBmin[3]; float m_lastBuiltTileBmin[3];
float m_tileBmax[3]; float m_lastBuiltTileBmax[3];
float m_tileBuildTime; float m_tileBuildTime;
float m_tileMemUsage; float m_tileMemUsage;
int m_tileTriCount; int m_tileTriCount;
@ -93,6 +93,7 @@ public:
virtual void handleRenderOverlay(double* proj, double* model, int* view); virtual void handleRenderOverlay(double* proj, double* model, int* view);
virtual void handleMeshChanged(class InputGeom* geom); virtual void handleMeshChanged(class InputGeom* geom);
virtual bool handleBuild(); virtual bool handleBuild();
virtual void collectSettings(struct BuildSettings& settings);
void getTilePos(const float* pos, int& tx, int& ty); void getTilePos(const float* pos, int& tx, int& ty);

View File

@ -19,6 +19,7 @@
#ifndef TESTCASE_H #ifndef TESTCASE_H
#define TESTCASE_H #define TESTCASE_H
#include <string>
#include "DetourNavMesh.h" #include "DetourNavMesh.h"
class TestCase class TestCase
@ -60,8 +61,8 @@ class TestCase
Test* next; Test* next;
}; };
char m_sampleName[256]; std::string m_sampleName;
char m_geomFileName[256]; std::string m_geomFileName;
Test* m_tests; Test* m_tests;
void resetTimes(); void resetTimes();
@ -70,10 +71,10 @@ public:
TestCase(); TestCase();
~TestCase(); ~TestCase();
bool load(const char* filePath); bool load(const std::string& filePath);
inline const char* getSampleName() const { return m_sampleName; } const std::string& getSampleName() const { return m_sampleName; }
inline const char* getGeomFileName() const { return m_geomFileName; } const std::string& getGeomFileName() const { return m_geomFileName; }
void doTests(class dtNavMesh* navmesh, class dtNavMeshQuery* navquery); void doTests(class dtNavMesh* navmesh, class dtNavMeshQuery* navquery);

View File

@ -29,10 +29,8 @@
using std::vector; using std::vector;
using std::string; using std::string;
void scanDirectory(string path, string ext, vector<string>& filelist) void scanDirectoryAppend(const string& path, const string& ext, vector<string>& filelist)
{ {
filelist.clear();
#ifdef WIN32 #ifdef WIN32
string pathWithExt = path + "/*" + ext; string pathWithExt = path + "/*" + ext;
@ -71,3 +69,9 @@ void scanDirectory(string path, string ext, vector<string>& filelist)
// Sort the list of files alphabetically. // Sort the list of files alphabetically.
std::sort(filelist.begin(), filelist.end()); std::sort(filelist.begin(), filelist.end());
} }
void scanDirectory(const string& path, const string& ext, vector<string>& filelist)
{
filelist.clear();
scanDirectoryAppend(path, ext, filelist);
}

View File

@ -21,6 +21,7 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <algorithm>
#include "Recast.h" #include "Recast.h"
#include "InputGeom.h" #include "InputGeom.h"
#include "ChunkyTriMesh.h" #include "ChunkyTriMesh.h"
@ -107,6 +108,7 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len)
InputGeom::InputGeom() : InputGeom::InputGeom() :
m_chunkyMesh(0), m_chunkyMesh(0),
m_mesh(0), m_mesh(0),
m_hasBuildSettings(false),
m_offMeshConCount(0), m_offMeshConCount(0),
m_volumeCount(0) m_volumeCount(0)
{ {
@ -118,7 +120,7 @@ InputGeom::~InputGeom()
delete m_mesh; delete m_mesh;
} }
bool InputGeom::loadMesh(rcContext* ctx, const char* filepath) bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath)
{ {
if (m_mesh) if (m_mesh)
{ {
@ -138,7 +140,7 @@ bool InputGeom::loadMesh(rcContext* ctx, const char* filepath)
} }
if (!m_mesh->load(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; return false;
} }
@ -159,10 +161,10 @@ bool InputGeom::loadMesh(rcContext* ctx, const char* filepath)
return true; return true;
} }
bool InputGeom::load(rcContext* ctx, const char* filePath) bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath)
{ {
char* buf = 0; char* buf = 0;
FILE* fp = fopen(filePath, "rb"); FILE* fp = fopen(filepath.c_str(), "rb");
if (!fp) if (!fp)
return false; return false;
fseek(fp, 0, SEEK_END); 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; delete [] buf;
@ -250,15 +279,68 @@ bool InputGeom::load(rcContext* ctx, const char* filePath)
return true; 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; 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; if (!fp) return false;
// Store mesh filename. // 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. // Store off-mesh links.
for (int i = 0; i < m_offMeshConCount; ++i) for (int i = 0; i < m_offMeshConCount; ++i)

View File

@ -19,7 +19,7 @@
#include "MeshLoaderObj.h" #include "MeshLoaderObj.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <cstring>
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <math.h> #include <math.h>
@ -135,10 +135,10 @@ static int parseFace(char* row, int* data, int n, int vcnt)
return j; return j;
} }
bool rcMeshLoaderObj::load(const char* filename) bool rcMeshLoaderObj::load(const std::string& filename)
{ {
char* buf = 0; char* buf = 0;
FILE* fp = fopen(filename, "rb"); FILE* fp = fopen(filename.c_str(), "rb");
if (!fp) if (!fp)
return false; return false;
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
@ -226,8 +226,6 @@ bool rcMeshLoaderObj::load(const char* filename)
} }
} }
strncpy(m_filename, filename, sizeof(m_filename)); m_filename = filename;
m_filename[sizeof(m_filename)-1] = '\0';
return true; return true;
} }

View File

@ -105,19 +105,45 @@ void Sample::handleRenderOverlay(double* /*proj*/, double* /*model*/, int* /*vie
void Sample::handleMeshChanged(InputGeom* geom) void Sample::handleMeshChanged(InputGeom* geom)
{ {
m_geom = geom; m_geom = geom;
const BuildSettings* buildSettings = geom->getBuildSettings();
if (buildSettings)
{
m_cellSize = buildSettings->cellSize;
m_cellHeight = buildSettings->cellHeight;
m_agentHeight = buildSettings->agentHeight;
m_agentRadius = buildSettings->agentRadius;
m_agentMaxClimb = buildSettings->agentMaxClimb;
m_agentMaxSlope = buildSettings->agentMaxSlope;
m_regionMinSize = buildSettings->regionMinSize;
m_regionMergeSize = buildSettings->regionMergeSize;
m_edgeMaxLen = buildSettings->edgeMaxLen;
m_edgeMaxError = buildSettings->edgeMaxError;
m_vertsPerPoly = buildSettings->vertsPerPoly;
m_detailSampleDist = buildSettings->detailSampleDist;
m_detailSampleMaxError = buildSettings->detailSampleMaxError;
m_partitionType = buildSettings->partitionType;
}
} }
const float* Sample::getBoundsMin() void Sample::collectSettings(BuildSettings& settings)
{ {
if (!m_geom) return 0; settings.cellSize = m_cellSize;
return m_geom->getMeshBoundsMin(); settings.cellHeight = m_cellHeight;
settings.agentHeight = m_agentHeight;
settings.agentRadius = m_agentRadius;
settings.agentMaxClimb = m_agentMaxClimb;
settings.agentMaxSlope = m_agentMaxSlope;
settings.regionMinSize = m_regionMinSize;
settings.regionMergeSize = m_regionMergeSize;
settings.edgeMaxLen = m_edgeMaxLen;
settings.edgeMaxError = m_edgeMaxError;
settings.vertsPerPoly = m_vertsPerPoly;
settings.detailSampleDist = m_detailSampleDist;
settings.detailSampleMaxError = m_detailSampleMaxError;
settings.partitionType = m_partitionType;
} }
const float* Sample::getBoundsMax()
{
if (!m_geom) return 0;
return m_geom->getMeshBoundsMax();
}
void Sample::resetCommonSettings() void Sample::resetCommonSettings()
{ {
@ -145,8 +171,8 @@ void Sample::handleCommonSettings()
if (m_geom) if (m_geom)
{ {
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); const float* bmax = m_geom->getNavMeshBoundsMax();
int gw = 0, gh = 0; int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh); rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
char text[64]; char text[64];

View File

@ -235,8 +235,8 @@ void Sample_SoloMesh::handleRender()
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
// Draw bounds // Draw bounds
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); 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); duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
dd.begin(DU_DRAW_POINTS, 5.0f); dd.begin(DU_DRAW_POINTS, 5.0f);
dd.vertex(bmin[0],bmin[1],bmin[2],duRGBA(255,255,255,128)); dd.vertex(bmin[0],bmin[1],bmin[2],duRGBA(255,255,255,128));
@ -362,8 +362,8 @@ bool Sample_SoloMesh::handleBuild()
cleanup(); cleanup();
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); const float* bmax = m_geom->getNavMeshBoundsMax();
const float* verts = m_geom->getMesh()->getVerts(); const float* verts = m_geom->getMesh()->getVerts();
const int nverts = m_geom->getMesh()->getVertCount(); const int nverts = m_geom->getMesh()->getVertCount();
const int* tris = m_geom->getMesh()->getTris(); const int* tris = m_geom->getMesh()->getTris();

View File

@ -866,8 +866,8 @@ void Sample_TempObstacles::handleSettings()
int gridSize = 1; int gridSize = 1;
if (m_geom) if (m_geom)
{ {
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); const float* bmax = m_geom->getNavMeshBoundsMax();
char text[64]; char text[64];
int gw = 0, gh = 0; int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh); rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
@ -1059,8 +1059,8 @@ void Sample_TempObstacles::handleRender()
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
// Draw bounds // Draw bounds
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); 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); duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
// Tiling grid. // Tiling grid.
@ -1208,8 +1208,8 @@ bool Sample_TempObstacles::handleBuild()
m_tmproc->init(m_geom); m_tmproc->init(m_geom);
// Init cache // Init cache
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); const float* bmax = m_geom->getNavMeshBoundsMax();
int gw = 0, gh = 0; int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh); rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
const int ts = (int)m_tileSize; const int ts = (int)m_tileSize;
@ -1280,7 +1280,7 @@ bool Sample_TempObstacles::handleBuild()
dtNavMeshParams params; dtNavMeshParams params;
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
rcVcopy(params.orig, m_geom->getMeshBoundsMin()); rcVcopy(params.orig, bmin);
params.tileWidth = m_tileSize*m_cellSize; params.tileWidth = m_tileSize*m_cellSize;
params.tileHeight = m_tileSize*m_cellSize; params.tileHeight = m_tileSize*m_cellSize;
params.maxTiles = m_maxTiles; params.maxTiles = m_maxTiles;
@ -1380,7 +1380,7 @@ void Sample_TempObstacles::getTilePos(const float* pos, int& tx, int& ty)
{ {
if (!m_geom) return; if (!m_geom) return;
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getNavMeshBoundsMin();
const float ts = m_tileSize*m_cellSize; const float ts = m_tileSize*m_cellSize;
tx = (int)((pos[0] - bmin[0]) / ts); tx = (int)((pos[0] - bmin[0]) / ts);

View File

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

View File

@ -88,18 +88,18 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len)
return buf; return buf;
} }
static void copyName(char* dst, const char* src) static void copyName(std::string& dst, const char* src)
{ {
// Skip white spaces // Skip white spaces
while (*src && isspace(*src)) while (*src && isspace(*src))
src++; src++;
strcpy(dst, src); dst = src;
} }
bool TestCase::load(const char* filePath) bool TestCase::load(const std::string& filePath)
{ {
char* buf = 0; char* buf = 0;
FILE* fp = fopen(filePath, "rb"); FILE* fp = fopen(filePath.c_str(), "rb");
if (!fp) if (!fp)
return false; return false;
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);

View File

@ -56,7 +56,7 @@ using std::vector;
struct SampleItem struct SampleItem
{ {
Sample* (*create)(); Sample* (*create)();
const char* name; const string name;
}; };
Sample* createSolo() { return new Sample_SoloMesh(); } Sample* createSolo() { return new Sample_SoloMesh(); }
Sample* createTile() { return new Sample_TileMesh(); } Sample* createTile() { return new Sample_TileMesh(); }
@ -167,10 +167,11 @@ int main(int /*argc*/, char** /*argv*/)
int logScroll = 0; int logScroll = 0;
int toolsScroll = 0; int toolsScroll = 0;
char sampleName[64] = "Choose Sample..."; string sampleName = "Choose Sample...";
vector<string> files; vector<string> files;
char meshName[128] = "Choose Mesh..."; const string meshesFolder = "Meshes";
string meshName = "Choose Mesh...";
float markerPosition[3] = {0, 0, 0}; float markerPosition[3] = {0, 0, 0};
bool markerPositionSet = false; bool markerPositionSet = false;
@ -180,6 +181,8 @@ int main(int /*argc*/, char** /*argv*/)
InputGeom* geom = 0; InputGeom* geom = 0;
Sample* sample = 0; Sample* sample = 0;
const string testCasesFolder = "TestCases";
TestCase* test = 0; TestCase* test = 0;
BuildContext ctx; BuildContext ctx;
@ -219,7 +222,7 @@ int main(int /*argc*/, char** /*argv*/)
showLevels = false; showLevels = false;
showSample = false; showSample = false;
showTestCases = true; showTestCases = true;
scanDirectory("TestCases", ".txt", files); scanDirectory(testCasesFolder, ".txt", files);
} }
else if (event.key.keysym.sym == SDLK_TAB) else if (event.key.keysym.sym == SDLK_TAB)
{ {
@ -237,56 +240,18 @@ int main(int /*argc*/, char** /*argv*/)
} }
else if (event.key.keysym.sym == SDLK_9) else if (event.key.keysym.sym == SDLK_9)
{ {
if (geom)
geom->save("geomset.txt");
}
else if (event.key.keysym.sym == SDLK_0)
{
delete geom;
geom = new InputGeom;
if (!geom || !geom->load(&ctx, "geomset.txt"))
{
delete geom;
geom = 0;
showLog = true;
logScroll = 0;
ctx.dumpLog("Geom load log %s:", meshName);
}
if (sample && geom) if (sample && geom)
{ {
sample->handleMeshChanged(geom); string savePath = meshesFolder + "/";
} BuildSettings settings;
memset(&settings, 0, sizeof(settings));
if (geom || sample) rcVcopy(settings.navMeshBMin, geom->getNavMeshBoundsMin());
{ rcVcopy(settings.navMeshBMax, geom->getNavMeshBoundsMax());
const float* bmin = 0;
const float* bmax = 0; sample->collectSettings(settings);
if (sample)
{ geom->saveGeomSet(&settings);
bmin = sample->getBoundsMin();
bmax = sample->getBoundsMax();
}
else if (geom)
{
bmin = geom->getMeshBoundsMin();
bmax = geom->getMeshBoundsMax();
}
// Reset camera and fog to match the mesh bounds.
if (bmin && bmax)
{
camr = sqrtf(rcSqr(bmax[0] - bmin[0]) +
rcSqr(bmax[1] - bmin[1]) +
rcSqr(bmax[2] - bmin[2])) / 2;
cameraPos[0] = (bmax[0] + bmin[0]) / 2 + camr;
cameraPos[1] = (bmax[1] + bmin[1]) / 2 + camr;
cameraPos[2] = (bmax[2] + bmin[2]) / 2 + camr;
camr *= 3;
}
cameraEulers[0] = 45;
cameraEulers[1] = -45;
glFogf(GL_FOG_START, camr * 0.2f);
glFogf(GL_FOG_END, camr * 1.25f);
} }
} }
else if (event.key.keysym.sym == SDLK_RIGHT) else if (event.key.keysym.sym == SDLK_RIGHT)
@ -577,7 +542,7 @@ int main(int /*argc*/, char** /*argv*/)
imguiSeparator(); imguiSeparator();
imguiLabel("Sample"); imguiLabel("Sample");
if (imguiButton(sampleName)) if (imguiButton(sampleName.c_str()))
{ {
if (showSample) if (showSample)
{ {
@ -593,7 +558,7 @@ int main(int /*argc*/, char** /*argv*/)
imguiSeparator(); imguiSeparator();
imguiLabel("Input Mesh"); imguiLabel("Input Mesh");
if (imguiButton(meshName)) if (imguiButton(meshName.c_str()))
{ {
if (showLevels) if (showLevels)
{ {
@ -604,7 +569,8 @@ int main(int /*argc*/, char** /*argv*/)
showSample = false; showSample = false;
showTestCases = false; showTestCases = false;
showLevels = true; showLevels = true;
scanDirectory("Meshes", ".obj", files); scanDirectory(meshesFolder, ".obj", files);
scanDirectoryAppend(meshesFolder, ".gset", files);
} }
} }
if (geom) if (geom)
@ -631,7 +597,7 @@ int main(int /*argc*/, char** /*argv*/)
showLog = true; showLog = true;
logScroll = 0; logScroll = 0;
} }
ctx.dumpLog("Build log %s:", meshName); ctx.dumpLog("Build log %s:", meshName.c_str());
// Clear test. // Clear test.
delete test; delete test;
@ -660,11 +626,11 @@ int main(int /*argc*/, char** /*argv*/)
Sample* newSample = 0; Sample* newSample = 0;
for (int i = 0; i < g_nsamples; ++i) for (int i = 0; i < g_nsamples; ++i)
{ {
if (imguiItem(g_samples[i].name)) if (imguiItem(g_samples[i].name.c_str()))
{ {
newSample = g_samples[i].create(); newSample = g_samples[i].create();
if (newSample) if (newSample)
strcpy(sampleName, g_samples[i].name); sampleName = g_samples[i].name;
} }
} }
if (newSample) if (newSample)
@ -683,15 +649,10 @@ int main(int /*argc*/, char** /*argv*/)
{ {
const float* bmin = 0; const float* bmin = 0;
const float* bmax = 0; const float* bmax = 0;
if (sample) if (geom)
{ {
bmin = sample->getBoundsMin(); bmin = geom->getNavMeshBoundsMin();
bmax = sample->getBoundsMax(); bmax = geom->getNavMeshBoundsMax();
}
else if (geom)
{
bmin = geom->getMeshBoundsMin();
bmax = geom->getMeshBoundsMax();
} }
// Reset camera and fog to match the mesh bounds. // Reset camera and fog to match the mesh bounds.
if (bmin && bmax) if (bmin && bmax)
@ -733,26 +694,23 @@ int main(int /*argc*/, char** /*argv*/)
if (levelToLoad != filesEnd) if (levelToLoad != filesEnd)
{ {
strncpy(meshName, levelToLoad->c_str(), sizeof(meshName)); meshName = *levelToLoad;
meshName[sizeof(meshName)-1] = '\0';
showLevels = false; showLevels = false;
delete geom; delete geom;
geom = 0; geom = 0;
char path[256]; string path = meshesFolder + "/" + meshName;
strcpy(path, "Meshes/");
strcat(path, meshName);
geom = new InputGeom; geom = new InputGeom;
if (!geom || !geom->loadMesh(&ctx, path)) if (!geom->load(&ctx, path))
{ {
delete geom; delete geom;
geom = 0; geom = 0;
showLog = true; showLog = true;
logScroll = 0; logScroll = 0;
ctx.dumpLog("Geom load log %s:", meshName); ctx.dumpLog("Geom load log %s:", meshName.c_str());
} }
if (sample && geom) if (sample && geom)
{ {
@ -763,15 +721,10 @@ int main(int /*argc*/, char** /*argv*/)
{ {
const float* bmin = 0; const float* bmin = 0;
const float* bmax = 0; const float* bmax = 0;
if (sample) if (geom)
{ {
bmin = sample->getBoundsMin(); bmin = geom->getNavMeshBoundsMin();
bmax = sample->getBoundsMax(); bmax = geom->getNavMeshBoundsMax();
}
else if (geom)
{
bmin = geom->getMeshBoundsMin();
bmax = geom->getMeshBoundsMax();
} }
// Reset camera and fog to match the mesh bounds. // Reset camera and fog to match the mesh bounds.
if (bmin && bmax) if (bmin && bmax)
@ -815,9 +768,7 @@ int main(int /*argc*/, char** /*argv*/)
if (testToLoad != filesEnd) if (testToLoad != filesEnd)
{ {
char path[256]; string path = testCasesFolder + "/" + *testToLoad;
strcpy(path, "TestCases/");
strcat(path, testToLoad->c_str());
test = new TestCase; test = new TestCase;
if (test) if (test)
{ {
@ -832,10 +783,11 @@ int main(int /*argc*/, char** /*argv*/)
Sample* newSample = 0; Sample* newSample = 0;
for (int i = 0; i < g_nsamples; ++i) for (int i = 0; i < g_nsamples; ++i)
{ {
if (strcmp(g_samples[i].name, test->getSampleName()) == 0) if (g_samples[i].name == test->getSampleName())
{ {
newSample = g_samples[i].create(); newSample = g_samples[i].create();
if (newSample) strcpy(sampleName, g_samples[i].name); if (newSample)
sampleName = g_samples[i].name;
} }
} }
if (newSample) if (newSample)
@ -847,23 +799,21 @@ int main(int /*argc*/, char** /*argv*/)
} }
// Load geom. // Load geom.
strcpy(meshName, test->getGeomFileName()); meshName = test->getGeomFileName();
meshName[sizeof(meshName)-1] = '\0';
delete geom; delete geom;
geom = 0; geom = 0;
strcpy(path, "Meshes/"); path = meshesFolder + "/" + meshName;
strcat(path, meshName);
geom = new InputGeom; geom = new InputGeom;
if (!geom || !geom->loadMesh(&ctx, path)) if (!geom || !geom->load(&ctx, path))
{ {
delete geom; delete geom;
geom = 0; geom = 0;
showLog = true; showLog = true;
logScroll = 0; logScroll = 0;
ctx.dumpLog("Geom load log %s:", meshName); ctx.dumpLog("Geom load log %s:", meshName.c_str());
} }
if (sample && geom) if (sample && geom)
{ {
@ -877,22 +827,17 @@ int main(int /*argc*/, char** /*argv*/)
ctx.resetLog(); ctx.resetLog();
if (sample && !sample->handleBuild()) if (sample && !sample->handleBuild())
{ {
ctx.dumpLog("Build log %s:", meshName); ctx.dumpLog("Build log %s:", meshName.c_str());
} }
if (geom || sample) if (geom || sample)
{ {
const float* bmin = 0; const float* bmin = 0;
const float* bmax = 0; const float* bmax = 0;
if (sample) if (geom)
{ {
bmin = sample->getBoundsMin(); bmin = geom->getNavMeshBoundsMin();
bmax = sample->getBoundsMax(); bmax = geom->getNavMeshBoundsMax();
}
else if (geom)
{
bmin = geom->getMeshBoundsMin();
bmax = geom->getMeshBoundsMax();
} }
// Reset camera and fog to match the mesh bounds. // Reset camera and fog to match the mesh bounds.
if (bmin && bmax) if (bmin && bmax)