From 95a7b45c327dddecfa564f4f2a299eb7dbf93abd Mon Sep 17 00:00:00 2001 From: Graham Pentheny Date: Sun, 13 Jul 2025 12:43:10 -0400 Subject: [PATCH] More WIP DearImGUI conversion --- RecastDemo/Include/Sample_TempObstacles.h | 2 +- RecastDemo/Include/Sample_TileMesh.h | 2 +- RecastDemo/Source/CrowdTool.cpp | 2 +- RecastDemo/Source/OffMeshConnectionTool.cpp | 25 +-- RecastDemo/Source/Sample.cpp | 26 +-- RecastDemo/Source/Sample_SoloMesh.cpp | 8 +- RecastDemo/Source/Sample_TempObstacles.cpp | 181 ++++++++++---------- RecastDemo/Source/Sample_TileMesh.cpp | 143 +++++++--------- RecastDemo/Source/TestCase.cpp | 40 ++--- RecastDemo/Source/main.cpp | 29 ++-- 10 files changed, 206 insertions(+), 252 deletions(-) diff --git a/RecastDemo/Include/Sample_TempObstacles.h b/RecastDemo/Include/Sample_TempObstacles.h index 3b82b12d..ccad7bc6 100644 --- a/RecastDemo/Include/Sample_TempObstacles.h +++ b/RecastDemo/Include/Sample_TempObstacles.h @@ -61,7 +61,7 @@ protected: int m_maxTiles = 0; int m_maxPolysPerTile = 0; - float m_tileSize = 48; + int m_tileSize = 48; public: Sample_TempObstacles(); diff --git a/RecastDemo/Include/Sample_TileMesh.h b/RecastDemo/Include/Sample_TileMesh.h index 2fead554..e3cc0ffc 100644 --- a/RecastDemo/Include/Sample_TileMesh.h +++ b/RecastDemo/Include/Sample_TileMesh.h @@ -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}; diff --git a/RecastDemo/Source/CrowdTool.cpp b/RecastDemo/Source/CrowdTool.cpp index 72d2c29d..4c647f84 100644 --- a/RecastDemo/Source/CrowdTool.cpp +++ b/RecastDemo/Source/CrowdTool.cpp @@ -883,7 +883,7 @@ void CrowdTool::handleMenu() paramsChanged |= ImGui::Checkbox("Obstacle Avoidance", ¶ms->m_obstacleAvoidance); paramsChanged |= ImGui::SliderInt("Avoidance Quality", ¶ms->m_obstacleAvoidanceType, 0, 3); paramsChanged |= ImGui::Checkbox("Separation", ¶ms->m_separation); - paramsChanged |= ImGui::SliderFloat("Separation Weight", ¶ms->m_separationWeight, 0.0f, 20.0f); + paramsChanged |= ImGui::SliderFloat("##Separation Weight", ¶ms->m_separationWeight, 0.0f, 20.0f, "Separation Weight = %.2f"); if (paramsChanged) { diff --git a/RecastDemo/Source/OffMeshConnectionTool.cpp b/RecastDemo/Source/OffMeshConnectionTool.cpp index e6a4f066..78761b98 100644 --- a/RecastDemo/Source/OffMeshConnectionTool.cpp +++ b/RecastDemo/Source/OffMeshConnectionTool.cpp @@ -17,6 +17,7 @@ // #include "SDL_opengl.h" +#include "imguiHelpers.h" #include #include @@ -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 } diff --git a/RecastDemo/Source/Sample.cpp b/RecastDemo/Source/Sample.cpp index 5900c8df..03c20a0e 100644 --- a/RecastDemo/Source/Sample.cpp +++ b/RecastDemo/Source/Sample.cpp @@ -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", ®ionMinSize, 0.0f, 150.0f, "Min Region Size = %.3f"); - ImGui::SliderFloat("##Merged Region Size", ®ionMergeSize, 0.0f, 150.0f, "Merged Region Size = %.3f"); + ImGui::SliderFloat("##Min Region Size", ®ionMinSize, 0.0f, 150.0f, "Min Region Size = %.2f"); + ImGui::SliderFloat("##Merged Region Size", ®ionMergeSize, 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(); } diff --git a/RecastDemo/Source/Sample_SoloMesh.cpp b/RecastDemo/Source/Sample_SoloMesh.cpp index 2df8a3f9..6ba446d9 100644 --- a/RecastDemo/Source/Sample_SoloMesh.cpp +++ b/RecastDemo/Source/Sample_SoloMesh.cpp @@ -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(); diff --git a/RecastDemo/Source/Sample_TempObstacles.cpp b/RecastDemo/Source/Sample_TempObstacles.cpp index 0a224c79..8c396bd5 100644 --- a/RecastDemo/Source/Sample_TempObstacles.cpp +++ b/RecastDemo/Source/Sample_TempObstacles.cpp @@ -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(pos[0]), static_cast(pos[1]), static_cast(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(x), static_cast(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(x), static_cast(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(x), static_cast(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(roundf(static_cast(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; diff --git a/RecastDemo/Source/Sample_TileMesh.cpp b/RecastDemo/Source/Sample_TileMesh.cpp index 3d0e0e60..d238c861 100644 --- a/RecastDemo/Source/Sample_TileMesh.cpp +++ b/RecastDemo/Source/Sample_TileMesh.cpp @@ -19,6 +19,7 @@ #include "Sample_TileMesh.h" #include "SDL_opengl.h" +#include "imguiHelpers.h" #include #include @@ -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(x), static_cast(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(roundf(static_cast(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(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(tileSize) - 1) / static_cast(tileSize); - const int tileHeight = (gridHeight + static_cast(tileSize) - 1) / static_cast(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(x), static_cast(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((pos[0] - navMeshBoundsMin[0]) / tileSize); - const int tileY = static_cast((pos[2] - navMeshBoundsMin[2]) / tileSize); + const float tileWorldSize = tileSize * cellSize; + const int tileX = static_cast((pos[0] - navMeshBoundsMin[0]) / tileWorldSize); + const int tileY = static_cast((pos[2] - navMeshBoundsMin[2]) / tileWorldSize); - lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast(tileX) * tileSize; + lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast(tileX) * tileWorldSize; lastBuiltTileBoundsMin[1] = navMeshBoundsMin[1]; - lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast(tileY) * tileSize; + lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast(tileY) * tileWorldSize; - lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast(tileX + 1) * tileSize; + lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast(tileX + 1) * tileWorldSize; lastBuiltTileBoundsMax[1] = navMeshBoundsMax[1]; - lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast(tileY + 1) * tileSize; + lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast(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((pos[0] - navMeshBoundsMin[0]) / tileSize); - const int tileY = static_cast((pos[2] - navMeshBoundsMin[2]) / tileSize); + const float tileWorldSize = tileSize * cellSize; + const int tileX = static_cast((pos[0] - navMeshBoundsMin[0]) / tileWorldSize); + const int tileY = static_cast((pos[2] - navMeshBoundsMin[2]) / tileWorldSize); - lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast(tileX) * tileSize; + lastBuiltTileBoundsMin[0] = navMeshBoundsMin[0] + static_cast(tileX) * tileWorldSize; lastBuiltTileBoundsMin[1] = navMeshBoundsMin[1]; - lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast(tileY) * tileSize; + lastBuiltTileBoundsMin[2] = navMeshBoundsMin[2] + static_cast(tileY) * tileWorldSize; - lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast(tileX + 1) * tileSize; + lastBuiltTileBoundsMax[0] = navMeshBoundsMin[0] + static_cast(tileX + 1) * tileWorldSize; lastBuiltTileBoundsMax[1] = navmeshBoundsMax[1]; - lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast(tileY + 1) * tileSize; + lastBuiltTileBoundsMax[2] = navMeshBoundsMin[2] + static_cast(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(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(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(rcSqr(regionMinSize)); // Note: area = size*size config.mergeRegionArea = static_cast(rcSqr(regionMergeSize)); // Note: area = size*size config.maxVertsPerPoly = static_cast(vertsPerPoly); - config.tileSize = static_cast(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; diff --git a/RecastDemo/Source/TestCase.cpp b/RecastDemo/Source/TestCase.cpp index 79fb7f7d..ab306f5d 100644 --- a/RecastDemo/Source/TestCase.cpp +++ b/RecastDemo/Source/TestCase.cpp @@ -22,6 +22,7 @@ #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" #include "SDL_opengl.h" +#include "imguiHelpers.h" #include #include @@ -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 } diff --git a/RecastDemo/Source/main.cpp b/RecastDemo/Source/main.cpp index 3a6830f7..eda4c612 100644 --- a/RecastDemo/Source/main.cpp +++ b/RecastDemo/Source/main.cpp @@ -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(app.width - 10 - 250 - 10 - 200), static_cast(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::const_iterator fileIter = app.files.begin(); vector::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;