More WIP DearImGUI conversion

This commit is contained in:
Graham Pentheny
2025-07-13 12:43:10 -04:00
parent d534b4dc14
commit 95a7b45c32
10 changed files with 206 additions and 252 deletions

View File

@@ -61,7 +61,7 @@ protected:
int m_maxTiles = 0;
int m_maxPolysPerTile = 0;
float m_tileSize = 48;
int m_tileSize = 48;
public:
Sample_TempObstacles();

View File

@@ -64,7 +64,7 @@ private:
int maxTiles = 0;
int maxPolysPerTile = 0;
/// In cells
float tileSize = 32.0f;
int tileSize = 32;
unsigned int tileColor = duRGBA(0, 0, 0, 32);
float lastBuiltTileBoundsMin[3] = {0.0f, 0.0f, 0.0f};

View File

@@ -883,7 +883,7 @@ void CrowdTool::handleMenu()
paramsChanged |= ImGui::Checkbox("Obstacle Avoidance", &params->m_obstacleAvoidance);
paramsChanged |= ImGui::SliderInt("Avoidance Quality", &params->m_obstacleAvoidanceType, 0, 3);
paramsChanged |= ImGui::Checkbox("Separation", &params->m_separation);
paramsChanged |= ImGui::SliderFloat("Separation Weight", &params->m_separationWeight, 0.0f, 20.0f);
paramsChanged |= ImGui::SliderFloat("##Separation Weight", &params->m_separationWeight, 0.0f, 20.0f, "Separation Weight = %.2f");
if (paramsChanged)
{

View File

@@ -17,6 +17,7 @@
//
#include "SDL_opengl.h"
#include "imguiHelpers.h"
#include <float.h>
#include <cmath>
@@ -55,16 +56,14 @@ void OffMeshConnectionTool::reset()
void OffMeshConnectionTool::handleMenu()
{
#if 0
if (imguiCheck("One Way", !bidir))
if (ImGui::RadioButton("One Way", !bidir))
{
bidir = false;
}
if (imguiCheck("Bidirectional", bidir))
if (ImGui::RadioButton("Bidirectional", bidir))
{
bidir = true;
}
#endif
}
void OffMeshConnectionTool::handleClick(const float* /*rayStartPos*/, const float* rayHitPos, bool shift)
@@ -148,34 +147,22 @@ void OffMeshConnectionTool::handleRender()
void OffMeshConnectionTool::handleRenderOverlay(double* proj, double* model, int* view)
{
#if 0
GLdouble x, y, z;
// Draw start and end point labels
if (hitPosSet && gluProject((GLdouble)hitPos[0], (GLdouble)hitPos[1], (GLdouble)hitPos[2], model, proj, view, &x, &y, &z))
{
imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0, 0, 0, 220));
DrawScreenspaceText(x, y - 25, IM_COL32(0, 0, 0, 220), "Start", true);
}
// Tool help
const int h = view[3];
if (!hitPosSet)
{
imguiDrawText(
280,
h - 40,
IMGUI_ALIGN_LEFT,
"LMB: Create new connection. SHIFT+LMB: Delete existing connection, click close to start or end point.",
imguiRGBA(255, 255, 255, 192));
DrawScreenspaceText(280, h - 40, IM_COL32(255, 255, 255, 192), "LMB: Create new connection. SHIFT+LMB: Delete existing connection, click near start or end point.");
}
else
{
imguiDrawText(
280,
h - 40,
IMGUI_ALIGN_LEFT,
"LMB: Set connection end point and finish.",
imguiRGBA(255, 255, 255, 192));
DrawScreenspaceText(280, h - 40, IM_COL32(255, 255, 255, 192), "LMB: Set connection end point and finish.");
}
#endif
}

View File

@@ -199,8 +199,8 @@ void Sample::resetCommonSettings()
void Sample::handleCommonSettings()
{
ImGui::SeparatorText("Rasterization");
ImGui::SliderFloat("##Cell Size", &cellSize, 0.1f, 1.0f, "Cell Size = %.3f");
ImGui::SliderFloat("##Cell Height", &cellHeight, 0.1f, 1.0f, "Cell Height = %.3f");
ImGui::SliderFloat("##Cell Size", &cellSize, 0.1f, 1.0f, "Cell Size = %.2f");
ImGui::SliderFloat("##Cell Height", &cellHeight, 0.1f, 1.0f, "Cell Height = %.2f");
if (inputGeometry)
{
@@ -216,14 +216,14 @@ void Sample::handleCommonSettings()
}
ImGui::SeparatorText("Agent");
ImGui::SliderFloat("##Height", &agentHeight, 0.1f, 5.0f, "Height = %.3f");
ImGui::SliderFloat("##Radius", &agentRadius, 0.0f, 5.0f, "Radius = %.3f");
ImGui::SliderFloat("##Max Climb", &agentMaxClimb, 0.1f, 5.0f, "Max Climb = %.3f");
ImGui::SliderFloat("##Max Slope", &agentMaxSlope, 0.0f, 90.0f, "Max Slope = %.3f");
ImGui::SliderFloat("##Height", &agentHeight, 0.1f, 5.0f, "Height = %.2f");
ImGui::SliderFloat("##Radius", &agentRadius, 0.0f, 5.0f, "Radius = %.2f");
ImGui::SliderFloat("##Max Climb", &agentMaxClimb, 0.1f, 5.0f, "Max Climb = %.2f");
ImGui::SliderFloat("##Max Slope", &agentMaxSlope, 0.0f, 90.0f, "Max Slope = %.2f");
ImGui::SeparatorText("Region");
ImGui::SliderFloat("##Min Region Size", &regionMinSize, 0.0f, 150.0f, "Min Region Size = %.3f");
ImGui::SliderFloat("##Merged Region Size", &regionMergeSize, 0.0f, 150.0f, "Merged Region Size = %.3f");
ImGui::SliderFloat("##Min Region Size", &regionMinSize, 0.0f, 150.0f, "Min Region Size = %.2f");
ImGui::SliderFloat("##Merged Region Size", &regionMergeSize, 0.0f, 150.0f, "Merged Region Size = %.2f");
ImGui::SeparatorText("Partitioning");
if (ImGui::RadioButton("Watershed", partitionType == SAMPLE_PARTITION_WATERSHED))
@@ -245,13 +245,13 @@ void Sample::handleCommonSettings()
ImGui::Checkbox("Walkable Low Height Spans", &filterWalkableLowHeightSpans);
ImGui::SeparatorText("Polygonization");
ImGui::SliderFloat("Max Edge Length", &edgeMaxLen, 0.0f, 50.0f);
ImGui::SliderFloat("Max Edge Error", &edgeMaxError, 0.1f, 3.0f);
ImGui::SliderInt("Verts Per Poly", &vertsPerPoly, 3, 12);
ImGui::SliderFloat("##Max Edge Length", &edgeMaxLen, 0.0f, 50.0f, "Max Edge Length = %.2f");
ImGui::SliderFloat("##Max Edge Error", &edgeMaxError, 0.1f, 3.0f, "Max Edge Error = %.2f");
ImGui::SliderInt("##Verts Per Poly", &vertsPerPoly, 3, 12, "Verts Per Poly = %d");
ImGui::SeparatorText("Detail Mesh");
ImGui::SliderFloat("Sample Distance", &detailSampleDist, 0.0f, 16.0f);
ImGui::SliderFloat("Max Sample Error", &detailSampleMaxError, 0.0f, 16.0f);
ImGui::SliderFloat("##Sample Distance", &detailSampleDist, 0.0f, 16.0f, "Sample Distance = %.2f");
ImGui::SliderFloat("##Max Sample Error", &detailSampleMaxError, 0.0f, 16.0f, "Max Sample Error = %.2f");
ImGui::Separator();
}

View File

@@ -70,14 +70,13 @@ void Sample_SoloMesh::handleSettings()
ImGui::Separator();
ImGui::Indent();
ImGui::Indent();
if (ImGui::Button("Save"))
{
saveAll("solo_navmesh.bin", navMesh);
}
ImGui::SameLine();
if (ImGui::Button("Load"))
{
dtFreeNavMesh(navMesh);
@@ -85,9 +84,6 @@ void Sample_SoloMesh::handleSettings()
navQuery->init(navMesh, 2048);
}
ImGui::Unindent();
ImGui::Unindent();
ImGui::Text("Build Time: %.1fms", totalBuildTimeMs);
ImGui::Separator();

View File

@@ -568,7 +568,7 @@ void drawDetailOverlay(const dtTileCache* tileCache, const int tileX, const int
const int ntiles = tileCache->getTilesAt(tileX, tileY, tiles, MAX_LAYERS);
if (!ntiles) { return; }
//const int rawSize = calcLayerBufferSize(tileCache->getParams()->width, tileCache->getParams()->height);
const int rawSize = calcLayerBufferSize(tileCache->getParams()->width, tileCache->getParams()->height);
for (int i = 0; i < ntiles; ++i)
{
@@ -582,15 +582,13 @@ void drawDetailOverlay(const dtTileCache* tileCache, const int tileX, const int
GLdouble x, y, z;
if (gluProject(static_cast<GLdouble>(pos[0]), static_cast<GLdouble>(pos[1]), static_cast<GLdouble>(pos[2]), model, proj, view, &x, &y, &z))
{
#if 0
char text[128];
snprintf(text, 128, "(%d,%d)/%d", tile->header->tx, tile->header->ty, tile->header->tlayer);
imguiDrawText(static_cast<int>(x), static_cast<int>(y) - 25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0, 0, 0, 220));
DrawScreenspaceText(x, y - 25, IM_COL32(0, 0, 0, 220), text, true);
snprintf(text, 128, "Compressed: %.1f kB", tile->dataSize / 1024.0f);
imguiDrawText(static_cast<int>(x), static_cast<int>(y) - 45, IMGUI_ALIGN_CENTER, text, imguiRGBA(0, 0, 0, 128));
DrawScreenspaceText(x, y - 45, IM_COL32(0, 0, 0, 128), text, true);
snprintf(text, 128, "Raw:%.1fkB", rawSize / 1024.0f);
imguiDrawText(static_cast<int>(x), static_cast<int>(y) - 65, IMGUI_ALIGN_CENTER, text, imguiRGBA(0, 0, 0, 128));
#endif
DrawScreenspaceText(x, y - 65, IM_COL32(0, 0, 0, 128), text, true);
}
}
}
@@ -671,27 +669,25 @@ public:
void handleMenu() override
{
#if 0
imguiLabel("Highlight Tile Cache");
imguiValue("Click LMB to highlight a tile.");
imguiSeparator();
if (imguiCheck("Draw Areas", m_drawType == DRAWDETAIL_AREAS))
ImGui::Text("Highlight Tile Cache");
ImGui::Text("Click LMB to highlight a tile.");
ImGui::Separator();
if (ImGui::RadioButton("Draw Areas", m_drawType == DRAWDETAIL_AREAS))
{
m_drawType = DRAWDETAIL_AREAS;
}
if (imguiCheck("Draw Regions", m_drawType == DRAWDETAIL_REGIONS))
if (ImGui::RadioButton("Draw Regions", m_drawType == DRAWDETAIL_REGIONS))
{
m_drawType = DRAWDETAIL_REGIONS;
}
if (imguiCheck("Draw Contours", m_drawType == DRAWDETAIL_CONTOURS))
if (ImGui::RadioButton("Draw Contours", m_drawType == DRAWDETAIL_CONTOURS))
{
m_drawType = DRAWDETAIL_CONTOURS;
}
if (imguiCheck("Draw Mesh", m_drawType == DRAWDETAIL_MESH))
if (ImGui::RadioButton("Draw Mesh", m_drawType == DRAWDETAIL_MESH))
{
m_drawType = DRAWDETAIL_MESH;
}
#endif
}
void handleClick(const float* /*s*/, const float* p, bool /*shift*/) override
@@ -761,17 +757,17 @@ public:
void handleMenu() override
{
#if 0
imguiLabel("Create Temp Obstacles");
ImGui::Text("Create Temp Obstacles");
if (imguiButton("Remove All"))
if (ImGui::Button("Remove All"))
{
m_sample->clearAllTempObstacles();
}
imguiSeparator();
ImGui::Separator();
imguiValue("Click LMB to create an obstacle.");
imguiValue("Shift+LMB to remove an obstacle.");
#endif
ImGui::Text("Click LMB to create an obstacle.");
ImGui::Text("Shift+LMB to remove an obstacle.");
}
void handleClick(const float* s, const float* p, bool shift) override
@@ -816,28 +812,26 @@ Sample_TempObstacles::~Sample_TempObstacles()
void Sample_TempObstacles::handleSettings()
{
Sample::handleCommonSettings();
#if 0
if (imguiCheck("Keep Itermediate Results", m_keepInterResults))
{
m_keepInterResults = !m_keepInterResults;
}
ImGui::Checkbox("Keep Itermediate Results", &m_keepInterResults);
imguiLabel("Tiling");
imguiSlider("TileSize", &m_tileSize, 16.0f, 128.0f, 8.0f);
ImGui::Text("Tiling");
if (ImGui::SliderInt("TileSize", &m_tileSize, 16, 128))
{
// Snap to multiples of 8
m_tileSize = static_cast<int>(roundf(static_cast<float>(m_tileSize) / 8.0f)) * 8;
}
int gridSize = 1;
if (inputGeometry)
{
const float* bmin = inputGeometry->getNavMeshBoundsMin();
const float* bmax = inputGeometry->getNavMeshBoundsMax();
char text[64];
int gw = 0, gh = 0;
int gw = 0;
int gh = 0;
rcCalcGridSize(bmin, bmax, cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
const int tw = (gw + ts-1) / ts;
const int th = (gh + ts-1) / ts;
snprintf(text, 64, "Tiles %d x %d", tw, th);
imguiValue(text);
const int tw = (gw + m_tileSize-1) / m_tileSize;
const int th = (gh + m_tileSize-1) / m_tileSize;
ImGui::Text("Tiles %d x %d", tw, th);
// Max tiles and max polys affect how the tile IDs are caculated.
// There are 22 bits available for identifying a tile and a polygon.
@@ -846,10 +840,8 @@ void Sample_TempObstacles::handleSettings()
int polyBits = 22 - tileBits;
m_maxTiles = 1 << tileBits;
m_maxPolysPerTile = 1 << polyBits;
snprintf(text, 64, "Max Tiles %d", m_maxTiles);
imguiValue(text);
snprintf(text, 64, "Max Polys %d", m_maxPolysPerTile);
imguiValue(text);
ImGui::Text("Max Tiles %d", m_maxTiles);
ImGui::Text("Max Polys %d", m_maxPolysPerTile);
gridSize = tw*th;
}
else
@@ -858,36 +850,29 @@ void Sample_TempObstacles::handleSettings()
m_maxPolysPerTile = 0;
}
imguiSeparator();
ImGui::Separator();
imguiLabel("Tile Cache");
char msg[64];
ImGui::Text("Tile Cache");
const float compressionRatio = (float)m_cacheCompressedSize / (float)(m_cacheRawSize+1);
snprintf(msg, 64, "Layers %d", m_cacheLayerCount);
imguiValue(msg);
snprintf(msg, 64, "Layers (per tile) %.1f", (float)m_cacheLayerCount/(float)gridSize);
imguiValue(msg);
ImGui::Text("Layers %d", m_cacheLayerCount);
ImGui::Text("Layers (per tile) %.1f", (float)m_cacheLayerCount/(float)gridSize);
snprintf(msg, 64, "Memory %.1f kB / %.1f kB (%.1f%%)", m_cacheCompressedSize/1024.0f, m_cacheRawSize/1024.0f, compressionRatio*100.0f);
imguiValue(msg);
snprintf(msg, 64, "Navmesh Build Time %.1f ms", m_cacheBuildTimeMs);
imguiValue(msg);
snprintf(msg, 64, "Build Peak Mem Usage %.1f kB", m_cacheBuildMemUsage/1024.0f);
imguiValue(msg);
ImGui::Text("Memory %.1f kB / %.1f kB (%.1f%%)", m_cacheCompressedSize/1024.0f, m_cacheRawSize/1024.0f, compressionRatio*100.0f);
ImGui::Text("Navmesh Build Time %.1f ms", m_cacheBuildTimeMs);
ImGui::Text("Build Peak Mem Usage %.1f kB", m_cacheBuildMemUsage/1024.0f);
imguiSeparator();
ImGui::Separator();
imguiIndent();
imguiIndent();
ImGui::Indent();
if (imguiButton("Save"))
if (ImGui::Button("Save"))
{
saveAll("all_tiles_tilecache.bin");
}
if (imguiButton("Load"))
if (ImGui::Button("Load"))
{
dtFreeNavMesh(navMesh);
dtFreeTileCache(m_tileCache);
@@ -895,54 +880,50 @@ void Sample_TempObstacles::handleSettings()
navQuery->init(navMesh, 2048);
}
imguiUnindent();
imguiUnindent();
ImGui::Unindent();
imguiSeparator();
#endif
ImGui::Separator();
}
void Sample_TempObstacles::handleTools()
{
#if 0
const SampleToolType type = !tool ? SampleToolType::NONE : tool->type();
if (imguiCheck("Test Navmesh", type == SampleToolType::NAVMESH_TESTER))
if (ImGui::RadioButton("Test Navmesh", type == SampleToolType::NAVMESH_TESTER))
{
setTool(new NavMeshTesterTool);
}
if (imguiCheck("Highlight Tile Cache", type == SampleToolType::TILE_HIGHLIGHT))
if (ImGui::RadioButton("Highlight Tile Cache", type == SampleToolType::TILE_HIGHLIGHT))
{
setTool(new TempObstacleHilightTool);
}
if (imguiCheck("Create Temp Obstacles", type == SampleToolType::TEMP_OBSTACLE))
if (ImGui::RadioButton("Create Temp Obstacles", type == SampleToolType::TEMP_OBSTACLE))
{
setTool(new TempObstacleCreateTool);
}
if (imguiCheck("Create Off-Mesh Links", type == SampleToolType::OFFMESH_CONNECTION))
if (ImGui::RadioButton("Create Off-Mesh Links", type == SampleToolType::OFFMESH_CONNECTION))
{
setTool(new OffMeshConnectionTool);
}
if (imguiCheck("Create Convex Volumes", type == SampleToolType::CONVEX_VOLUME))
if (ImGui::RadioButton("Create Convex Volumes", type == SampleToolType::CONVEX_VOLUME))
{
setTool(new ConvexVolumeTool);
}
if (imguiCheck("Create Crowds", type == SampleToolType::CROWD))
if (ImGui::RadioButton("Create Crowds", type == SampleToolType::CROWD))
{
setTool(new CrowdTool);
}
imguiSeparatorLine();
ImGui::Separator();
imguiIndent();
ImGui::Indent();
if (tool)
{
tool->handleMenu();
}
imguiUnindent();
#endif
ImGui::Unindent();
}
void Sample_TempObstacles::handleDebugMode()
@@ -980,48 +961,62 @@ void Sample_TempObstacles::handleDebugMode()
return;
}
#if 0
imguiLabel("Draw");
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
ImGui::Text("Draw");
ImGui::BeginDisabled(!valid[DRAWMODE_MESH]);
if (ImGui::RadioButton("Input Mesh", m_drawMode == DRAWMODE_MESH))
{
m_drawMode = DRAWMODE_MESH;
}
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH]);
if (ImGui::RadioButton("Navmesh", m_drawMode == DRAWMODE_NAVMESH))
{
m_drawMode = DRAWMODE_NAVMESH;
}
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_INVIS]);
if (ImGui::RadioButton("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS))
{
m_drawMode = DRAWMODE_NAVMESH_INVIS;
}
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_TRANS]);
if (ImGui::RadioButton("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS))
{
m_drawMode = DRAWMODE_NAVMESH_TRANS;
}
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_BVTREE]);
if (ImGui::RadioButton("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE))
{
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
}
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_NODES]);
if (ImGui::RadioButton("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES))
{
m_drawMode = DRAWMODE_NAVMESH_NODES;
}
if (imguiCheck("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS, valid[DRAWMODE_NAVMESH_PORTALS]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_PORTALS]);
if (ImGui::RadioButton("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS))
{
m_drawMode = DRAWMODE_NAVMESH_PORTALS;
}
if (imguiCheck("Cache Bounds", m_drawMode == DRAWMODE_CACHE_BOUNDS, valid[DRAWMODE_CACHE_BOUNDS]))
ImGui::EndDisabled();
ImGui::BeginDisabled(!valid[DRAWMODE_CACHE_BOUNDS]);
if (ImGui::RadioButton("Cache Bounds", m_drawMode == DRAWMODE_CACHE_BOUNDS))
{
m_drawMode = DRAWMODE_CACHE_BOUNDS;
}
ImGui::EndDisabled();
if (unavail)
{
imguiValue("Tick 'Keep Itermediate Results'");
imguiValue("rebuild some tiles to see");
imguiValue("more debug mode options.");
ImGui::Text("Tick 'Keep Itermediate Results'");
ImGui::Text("rebuild some tiles to see");
ImGui::Text("more debug mode options.");
}
#endif
}
void Sample_TempObstacles::handleRender()
@@ -1067,8 +1062,8 @@ void Sample_TempObstacles::handleRender()
int gw = 0;
int gh = 0;
rcCalcGridSize(bmin, bmax, cellSize, &gw, &gh);
const int tw = (gw + (int)m_tileSize-1) / (int)m_tileSize;
const int th = (gh + (int)m_tileSize-1) / (int)m_tileSize;
const int tw = (gw + m_tileSize-1) / m_tileSize;
const int th = (gh + m_tileSize-1) / m_tileSize;
const float s = m_tileSize*cellSize;
duDebugDrawGridXZ(&debugDraw, bmin[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
@@ -1228,7 +1223,7 @@ bool Sample_TempObstacles::handleBuild()
const float* bmax = inputGeometry->getNavMeshBoundsMax();
int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
const int ts = m_tileSize;
const int tw = (gw + ts-1) / ts;
const int th = (gh + ts-1) / ts;
@@ -1246,7 +1241,7 @@ bool Sample_TempObstacles::handleBuild()
cfg.minRegionArea = (int)rcSqr(regionMinSize); // Note: area = size*size
cfg.mergeRegionArea = (int)rcSqr(regionMergeSize); // Note: area = size*size
cfg.maxVertsPerPoly = (int)vertsPerPoly;
cfg.tileSize = (int)m_tileSize;
cfg.tileSize = m_tileSize;
cfg.borderSize = cfg.walkableRadius + 3; // Reserve enough padding.
cfg.width = cfg.tileSize + cfg.borderSize*2;
cfg.height = cfg.tileSize + cfg.borderSize*2;
@@ -1261,8 +1256,8 @@ bool Sample_TempObstacles::handleBuild()
rcVcopy(tcparams.orig, bmin);
tcparams.cs = cellSize;
tcparams.ch = cellHeight;
tcparams.width = (int)m_tileSize;
tcparams.height = (int)m_tileSize;
tcparams.width = m_tileSize;
tcparams.height = m_tileSize;
tcparams.walkableHeight = agentHeight;
tcparams.walkableRadius = agentRadius;
tcparams.walkableClimb = agentMaxClimb;

View File

@@ -19,6 +19,7 @@
#include "Sample_TileMesh.h"
#include "SDL_opengl.h"
#include "imguiHelpers.h"
#include <cmath>
#include <cstdio>
@@ -95,23 +96,21 @@ public:
void handleMenu() override
{
#if 0
imguiLabel("Create Tiles");
if (imguiButton("Create All"))
ImGui::Text("Create Tiles");
if (ImGui::Button("Create All"))
{
if (m_sample)
{
m_sample->buildAllTiles();
}
}
if (imguiButton("Remove All"))
if (ImGui::Button("Remove All"))
{
if (m_sample)
{
m_sample->removeAllTiles();
}
}
#endif
}
void handleClick(const float* /*s*/, const float* p, bool shift) override
@@ -160,7 +159,6 @@ public:
void handleRenderOverlay(double* proj, double* model, int* view) override
{
#if 0
GLdouble x, y, z;
if (m_hitPosSet && gluProject(m_hitPos[0], m_hitPos[1], m_hitPos[2], model, proj, view, &x, &y, &z))
{
@@ -169,17 +167,15 @@ public:
m_sample->getTilePos(m_hitPos, tx, ty);
char text[32];
snprintf(text, 32, "(%d,%d)", tx, ty);
imguiDrawText(static_cast<int>(x), static_cast<int>(y) - 25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0, 0, 0, 220));
DrawScreenspaceText(x, y, IM_COL32(0, 0, 0, 220), text, true);
}
// Tool help
imguiDrawText(
DrawScreenspaceText(
280,
view[3] - 40,
IMGUI_ALIGN_LEFT,
"LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.",
imguiRGBA(255, 255, 255, 192));
#endif
IM_COL32(255, 255, 255, 192),
"LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.");
}
};
@@ -215,16 +211,17 @@ void Sample_TileMesh::cleanup()
void Sample_TileMesh::handleSettings()
{
Sample::handleCommonSettings();
#if 0
if (imguiCheck("Build All Tiles", buildAll))
ImGui::Checkbox("Build All Tiles", &buildAll);
ImGui::Text("Tiling");
if (ImGui::SliderInt("TileSize", &tileSize, 16, 1024))
{
buildAll = !buildAll;
// Snap to multiples of 16
tileSize = static_cast<int>(roundf(static_cast<float>(tileSize) / 16.0f)) * 16;
}
imguiLabel("Tiling");
imguiSlider("TileSize", &tileSize, 16.0f, 1024.0f, 16.0f);
if (inputGeometry)
{
const float* navMeshBoundsMin = inputGeometry->getNavMeshBoundsMin();
@@ -232,13 +229,10 @@ void Sample_TileMesh::handleSettings()
int gridWidth = 0;
int gridHeight = 0;
rcCalcGridSize(navMeshBoundsMin, navMeshBoundsMax, cellSize, &gridWidth, &gridHeight);
const int tileSize = static_cast<int>(this->tileSize);
const int tileWidth = (gridWidth + tileSize - 1) / tileSize;
const int tileHeight = (gridHeight + tileSize - 1) / tileSize;
char text[64];
snprintf(text, 64, "Tiles %d x %d", tileWidth, tileHeight);
imguiValue(text);
ImGui::Text("Tiles %d x %d", tileWidth, tileHeight);
// Max tiles and max polys affect how the tile IDs are calculated.
// There are 22 bits available for identifying a tile and a polygon.
@@ -247,10 +241,8 @@ void Sample_TileMesh::handleSettings()
int polyBits = 22 - tileBits;
maxTiles = 1 << tileBits;
maxPolysPerTile = 1 << polyBits;
snprintf(text, 64, "Max Tiles %d", maxTiles);
imguiValue(text);
snprintf(text, 64, "Max Polys %d", maxPolysPerTile);
imguiValue(text);
ImGui::Text("Max Tiles %d", maxTiles);
ImGui::Text("Max Polys %d", maxPolysPerTile);
}
else
{
@@ -258,92 +250,84 @@ void Sample_TileMesh::handleSettings()
maxPolysPerTile = 0;
}
imguiSeparator();
ImGui::Separator();
imguiIndent();
imguiIndent();
ImGui::Indent();
if (imguiButton("Save"))
if (ImGui::Button("Save"))
{
Sample::saveAll("all_tiles_navmesh.bin", navMesh);
}
if (imguiButton("Load"))
if (ImGui::Button("Load"))
{
dtFreeNavMesh(navMesh);
navMesh = Sample::loadAll("all_tiles_navmesh.bin");
navQuery->init(navMesh, 2048);
}
imguiUnindent();
imguiUnindent();
ImGui::Unindent();
char msg[64];
snprintf(msg, 64, "Build Time: %.1fms", totalBuildTimeMs);
imguiLabel(msg);
ImGui::Text("Build Time: %.1fms", totalBuildTimeMs);
imguiSeparator();
imguiSeparator();
#endif
ImGui::Separator();
}
void Sample_TileMesh::handleTools()
{
#if 0
const SampleToolType type = !tool ? SampleToolType::NONE : tool->type();
if (imguiCheck("Test Navmesh", type == SampleToolType::NAVMESH_TESTER))
if (ImGui::RadioButton("Test Navmesh", type == SampleToolType::NAVMESH_TESTER))
{
setTool(new NavMeshTesterTool);
}
if (imguiCheck("Prune Navmesh", type == SampleToolType::NAVMESH_PRUNE))
if (ImGui::RadioButton("Prune Navmesh", type == SampleToolType::NAVMESH_PRUNE))
{
setTool(new NavMeshPruneTool);
}
if (imguiCheck("Create Tiles", type == SampleToolType::TILE_EDIT))
if (ImGui::RadioButton("Create Tiles", type == SampleToolType::TILE_EDIT))
{
setTool(new NavMeshTileTool);
}
if (imguiCheck("Create Off-Mesh Links", type == SampleToolType::OFFMESH_CONNECTION))
if (ImGui::RadioButton("Create Off-Mesh Links", type == SampleToolType::OFFMESH_CONNECTION))
{
setTool(new OffMeshConnectionTool);
}
if (imguiCheck("Create Convex Volumes", type == SampleToolType::CONVEX_VOLUME))
if (ImGui::RadioButton("Create Convex Volumes", type == SampleToolType::CONVEX_VOLUME))
{
setTool(new ConvexVolumeTool);
}
if (imguiCheck("Create Crowds", type == SampleToolType::CROWD))
if (ImGui::RadioButton("Create Crowds", type == SampleToolType::CROWD))
{
setTool(new CrowdTool);
}
imguiSeparatorLine();
ImGui::Separator();
imguiIndent();
ImGui::Indent();
if (tool)
{
tool->handleMenu();
}
imguiUnindent();
#endif
ImGui::Unindent();
}
void Sample_TileMesh::UI_DrawModeOption(const char* name, DrawMode drawMode, bool enabled)
{
#if 0
if (imguiCheck(name, this->drawMode == drawMode, enabled))
{
ImGui::BeginDisabled(!enabled);
bool checked = this->drawMode == drawMode;
if (ImGui::Checkbox(name, &checked))
{
this->drawMode = drawMode;
}
#endif
}
ImGui::EndDisabled();
}
void Sample_TileMesh::handleDebugMode()
{
#if 0
imguiLabel("Draw");
ImGui::Text("Draw");
UI_DrawModeOption("Input Mesh", DrawMode::MESH, true);
UI_DrawModeOption("Navmesh", DrawMode::NAVMESH, navMesh != nullptr);
UI_DrawModeOption("Navmesh Invis", DrawMode::NAVMESH_INVIS, navMesh != nullptr);
@@ -362,7 +346,6 @@ void Sample_TileMesh::handleDebugMode()
UI_DrawModeOption("Contours", DrawMode::CONTOURS, contourSet != nullptr);
UI_DrawModeOption("Poly Mesh", DrawMode::POLYMESH, polyMesh != nullptr);
UI_DrawModeOption("Poly Mesh Detail", DrawMode::POLYMESH_DETAIL, detailPolyMesh != nullptr);
#endif
}
void Sample_TileMesh::handleRender()
@@ -410,8 +393,8 @@ void Sample_TileMesh::handleRender()
int gridWith = 0;
int gridHeight = 0;
rcCalcGridSize(navMeshBoundsMin, navMeshBoundsMax, cellSize, &gridWith, &gridHeight);
const int tileWidth = (gridWith + static_cast<int>(tileSize) - 1) / static_cast<int>(tileSize);
const int tileHeight = (gridHeight + static_cast<int>(tileSize) - 1) / static_cast<int>(tileSize);
const int tileWidth = (gridWith + tileSize - 1) / tileSize;
const int tileHeight = (gridHeight + tileSize - 1) / tileSize;
const float size = tileSize * cellSize;
duDebugDrawGridXZ(
&debugDraw,
@@ -541,7 +524,6 @@ void Sample_TileMesh::handleRender()
void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view)
{
#if 0
GLdouble x, y, z;
// Draw start and end point labels
@@ -557,9 +539,9 @@ void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
&z);
if (tileBuildTime > 0.0f && projectResult == GL_TRUE)
{
char text[32];
snprintf(text, 32, "%.3fms / %dTris / %.1fkB", tileBuildTime, tileTriCount, tileMemUsage);
imguiDrawText(static_cast<int>(x), static_cast<int>(y) - 25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0, 0, 0, 220));
char text[64];
snprintf(text, 64, "%.3fms / %dTris / %.1fkB", tileBuildTime, tileTriCount, tileMemUsage);
DrawScreenspaceText(x, y, IM_COL32(0, 0, 0, 220), text);
}
if (tool)
@@ -567,7 +549,6 @@ void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
tool->handleRenderOverlay(proj, model, view);
}
renderOverlayToolStates(proj, model, view);
#endif
}
void Sample_TileMesh::handleMeshChanged(InputGeom* geom)
@@ -667,17 +648,17 @@ void Sample_TileMesh::buildTile(const float* pos)
const float* navMeshBoundsMin = inputGeometry->getNavMeshBoundsMin();
const float* navMeshBoundsMax = inputGeometry->getNavMeshBoundsMax();
const float tileSize = this->tileSize * cellSize;
const int tileX = static_cast<int>((pos[0] - navMeshBoundsMin[0]) / tileSize);
const int tileY = static_cast<int>((pos[2] - navMeshBoundsMin[2]) / tileSize);
const float tileWorldSize = tileSize * cellSize;
const int tileX = static_cast<int>((pos[0] - navMeshBoundsMin[0]) / tileWorldSize);
const int tileY = static_cast<int>((pos[2] - navMeshBoundsMin[2]) / tileWorldSize);
lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast<float>(tileX) * tileSize;
lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast<float>(tileX) * tileWorldSize;
lastBuiltTileBoundsMin[1] = navMeshBoundsMin[1];
lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast<float>(tileY) * tileSize;
lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast<float>(tileY) * tileWorldSize;
lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast<float>(tileX + 1) * tileSize;
lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast<float>(tileX + 1) * tileWorldSize;
lastBuiltTileBoundsMax[1] = navMeshBoundsMax[1];
lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast<float>(tileY + 1) * tileSize;
lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast<float>(tileY + 1) * tileWorldSize;
tileColor = duRGBA(255, 255, 255, 64);
@@ -731,17 +712,17 @@ void Sample_TileMesh::removeTile(const float* pos)
const float* navMeshBoundsMin = inputGeometry->getNavMeshBoundsMin();
const float* navmeshBoundsMax = inputGeometry->getNavMeshBoundsMax();
const float tileSize = this->tileSize * cellSize;
const int tileX = static_cast<int>((pos[0] - navMeshBoundsMin[0]) / tileSize);
const int tileY = static_cast<int>((pos[2] - navMeshBoundsMin[2]) / tileSize);
const float tileWorldSize = tileSize * cellSize;
const int tileX = static_cast<int>((pos[0] - navMeshBoundsMin[0]) / tileWorldSize);
const int tileY = static_cast<int>((pos[2] - navMeshBoundsMin[2]) / tileWorldSize);
lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast<float>(tileX) * tileSize;
lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast<float>(tileX) * tileWorldSize;
lastBuiltTileBoundsMin[1] = navMeshBoundsMin[1];
lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast<float>(tileY) * tileSize;
lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast<float>(tileY) * tileWorldSize;
lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast<float>(tileX + 1) * tileSize;
lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast<float>(tileX + 1) * tileWorldSize;
lastBuiltTileBoundsMax[1] = navmeshBoundsMax[1];
lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast<float>(tileY + 1) * tileSize;
lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast<float>(tileY + 1) * tileWorldSize;
tileColor = duRGBA(128, 32, 16, 64);
@@ -764,7 +745,6 @@ void Sample_TileMesh::buildAllTiles()
int gridWidth = 0;
int gridHeight = 0;
rcCalcGridSize(navMeshBoundsMin, navMeshBoundsMax, cellSize, &gridWidth, &gridHeight);
const int tileSize = static_cast<int>(this->tileSize);
const int tileWidth = (gridWidth + tileSize - 1) / tileSize;
const int tileHeight = (gridHeight + tileSize - 1) / tileSize;
const float tileCellSize = tileSize * cellSize;
@@ -823,7 +803,6 @@ void Sample_TileMesh::removeAllTiles() const
int gridWidth = 0;
int gridHeight = 0;
rcCalcGridSize(navMeshBoundsMin, navMeshBoundsMax, cellSize, &gridWidth, &gridHeight);
const int tileSize = static_cast<int>(this->tileSize);
const int tileWidth = (gridWidth + tileSize - 1) / tileSize;
const int tileHeight = (gridHeight + tileSize - 1) / tileSize;
@@ -872,7 +851,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(
config.minRegionArea = static_cast<int>(rcSqr(regionMinSize)); // Note: area = size*size
config.mergeRegionArea = static_cast<int>(rcSqr(regionMergeSize)); // Note: area = size*size
config.maxVertsPerPoly = static_cast<int>(vertsPerPoly);
config.tileSize = static_cast<int>(tileSize);
config.tileSize = tileSize;
config.borderSize = config.walkableRadius + 3; // Reserve enough padding.
config.width = config.tileSize + config.borderSize * 2;
config.height = config.tileSize + config.borderSize * 2;

View File

@@ -22,6 +22,7 @@
#include "DetourNavMesh.h"
#include "DetourNavMeshQuery.h"
#include "SDL_opengl.h"
#include "imguiHelpers.h"
#include <ctype.h>
#include <math.h>
@@ -425,7 +426,6 @@ void TestCase::handleRender()
bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
{
#if 0
GLdouble x, y, z;
char text[64];
char subtext[64];
@@ -459,51 +459,41 @@ bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
if (gluProject((GLdouble)pt[0], (GLdouble)pt[1], (GLdouble)pt[2], model, proj, view, &x, &y, &z))
{
snprintf(text, 64, "Path %d\n", n);
unsigned int col = imguiRGBA(0, 0, 0, 128);
unsigned int col = IM_COL32(0, 0, 0, 128);
if (iter->expand)
{
col = imguiRGBA(255, 192, 0, 220);
col = IM_COL32(255, 192, 0, 220);
}
imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, text, col);
DrawScreenspaceText(x, y - 25, col, text, true);
}
n++;
}
static int resScroll = 0;
bool mouseOverMenu = imguiBeginScrollArea("Test Results", 10, view[3] - 10 - 350, 200, 350, &resScroll);
ImGui::SetNextWindowPos(ImVec2(10, view[3] - 10 - 350), ImGuiCond_Always); // Position in screen space
ImGui::SetNextWindowSize(ImVec2(200, 350), ImGuiCond_Always); // Size of the window
ImGui::Begin("Test Results");
n = 0;
for (Test* iter = tests; iter; iter = iter->next, n++)
{
const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
snprintf(subtext, 64, "%.4f ms", (float)total / 1000.0f);
snprintf(text, 64, "Path %d", n);
if (imguiCollapse(text, subtext, iter->expand))
if (ImGui::CollapsingHeader(text, ImGuiTreeNodeFlags_DefaultOpen))
{
iter->expand = !iter->expand;
}
ImGui::Text("Total: %.4f ms", (float)total / 1000.0f);
ImGui::Text("Poly: %.4f ms", (float)iter->findNearestPolyTime / 1000.0f);
ImGui::Text("Path: %.4f ms", (float)iter->findPathTime / 1000.0f);
ImGui::Text("Straight: %.4f ms", (float)iter->findStraightPathTime / 1000.0f);
if (iter->expand)
{
snprintf(text, 64, "Poly: %.4f ms", (float)iter->findNearestPolyTime / 1000.0f);
imguiValue(text);
snprintf(text, 64, "Path: %.4f ms", (float)iter->findPathTime / 1000.0f);
imguiValue(text);
snprintf(text, 64, "Straight: %.4f ms", (float)iter->findStraightPathTime / 1000.0f);
imguiValue(text);
imguiSeparator();
ImGui::Separator();
}
}
imguiEndScrollArea();
ImGui::End();
return mouseOverMenu;
#else
return false;
#endif
}

View File

@@ -785,17 +785,9 @@ int main(int /*argc*/, char** /*argv*/)
// Test cases
if (app.showTestCases)
{
static int testScroll = 0;
if (imguiBeginScrollArea(
"Choose Test To Run",
app.width - 10 - 250 - 10 - 200,
app.height - 10 - 450,
200,
450,
&testScroll))
{
app.mouseOverMenu = true;
}
ImGui::SetNextWindowPos(ImVec2(static_cast<float>(app.width - 10 - 250 - 10 - 200), static_cast<float>(app.height - 10 - 450)), ImGuiCond_Always); // Position in screen space
ImGui::SetNextWindowSize(ImVec2(200, 450, ImGuiCond_Always); // Size of the window
ImGui::Begin("Choose Test To Run", nullptr, staticWindowFlags);
vector<string>::const_iterator fileIter = app.files.begin();
vector<string>::const_iterator filesEnd = app.files.end();
@@ -808,6 +800,21 @@ int main(int /*argc*/, char** /*argv*/)
}
}
if (ImGui::BeginCombo("Dropdown", items[current_item].c_str()))
{
for (int i = 0; i < items.size(); i++)
{
bool is_selected = (current_item == i);
if (ImGui::Selectable(items[i].c_str(), is_selected))
{
current_item = i;
}
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
if (testToLoad != filesEnd)
{
string path = app.testCasesFolder + "/" + *testToLoad;