Recast: upgrade legacy ImGui implementation to 1.90.4 (WIP)

Major upgrade to newer library. This is still work in progress, there are many bugs.
This commit is contained in:
Kawe Mazidjatari 2024-07-09 01:14:28 +02:00
parent c2df5e19bf
commit e2c48c49db
21 changed files with 964 additions and 1991 deletions

View File

@ -13,16 +13,6 @@ add_sources( SOURCE_GROUP "Builder/Include"
"include/InputGeom.h"
)
add_sources( SOURCE_GROUP "Contrib"
"imgui.cpp"
"imguiRenderGL.cpp"
)
add_sources( SOURCE_GROUP "Contrib/Include"
"include/imgui.h"
"include/imguiRenderGL.h"
)
add_sources( SOURCE_GROUP "Core"
"Editor.cpp"
"main.cpp"
@ -102,11 +92,12 @@ target_precompile_headers( ${PROJECT_NAME} PRIVATE
target_link_libraries( ${PROJECT_NAME} PRIVATE
"navsharedcommon"
"navdebugutils"
"libsdl2"
"libdetour"
"libdetourcrowd"
"libdetourtilecache"
"librecast"
"libsdl2"
"libimgui"
"FastLZ"
"Rpcrt4.lib"
"ws2_32.lib"

View File

@ -114,31 +114,45 @@ void ConvexVolumeTool::reset()
void ConvexVolumeTool::handleMenu()
{
imguiSlider("Shape Height", &m_boxHeight, 0.1f, MAX_COORD_FLOAT, 0.1f);
imguiSlider("Shape Descent", &m_boxDescent, 0.1f, MAX_COORD_FLOAT, 0.1f);
imguiSlider("Poly Offset", &m_polyOffset, 0.0f, MAX_COORD_FLOAT/2, 0.1f);
ImGui::SliderFloat("Shape Height", &m_boxHeight, 0.1f, MAX_COORD_FLOAT);
ImGui::SliderFloat("Shape Descent", &m_boxDescent, 0.1f, MAX_COORD_FLOAT);
ImGui::SliderFloat("Poly Offset", &m_polyOffset, 0.0f, MAX_COORD_FLOAT/2);
imguiSeparator();
ImGui::Separator();
imguiLabel("Area Type");
imguiIndent();
if (imguiCheck("Ground", m_areaType == EDITOR_POLYAREA_GROUND))
ImGui::Text("Area Type");
ImGui::Indent();
bool isEnabled = m_areaType == EDITOR_POLYAREA_GROUND;
if (ImGui::Checkbox("Ground", &isEnabled))
m_areaType = EDITOR_POLYAREA_GROUND;
if (imguiCheck("Water", m_areaType == EDITOR_POLYAREA_WATER))
isEnabled = m_areaType == EDITOR_POLYAREA_WATER;
if (ImGui::Checkbox("Water", &isEnabled))
m_areaType = EDITOR_POLYAREA_WATER;
if (imguiCheck("Road", m_areaType == EDITOR_POLYAREA_ROAD))
isEnabled = m_areaType == EDITOR_POLYAREA_ROAD;
if (ImGui::Checkbox("Road", &isEnabled))
m_areaType = EDITOR_POLYAREA_ROAD;
if (imguiCheck("Door", m_areaType == EDITOR_POLYAREA_DOOR))
isEnabled = m_areaType == EDITOR_POLYAREA_DOOR;
if (ImGui::Checkbox("Door", &isEnabled))
m_areaType = EDITOR_POLYAREA_DOOR;
if (imguiCheck("Grass", m_areaType == EDITOR_POLYAREA_GRASS))
isEnabled = m_areaType == EDITOR_POLYAREA_GRASS;
if (ImGui::Checkbox("Grass", &isEnabled))
m_areaType = EDITOR_POLYAREA_GRASS;
if (imguiCheck("Jump", m_areaType == EDITOR_POLYAREA_JUMP))
isEnabled = m_areaType == EDITOR_POLYAREA_JUMP;
if (ImGui::Checkbox("Jump", &isEnabled))
m_areaType = EDITOR_POLYAREA_JUMP;
imguiUnindent();
imguiSeparator();
ImGui::Unindent();
if (imguiButton("Clear Shape"))
ImGui::Separator();
if (ImGui::Button("Clear Shape"))
{
m_npts = 0;
m_nhull = 0;
@ -282,12 +296,14 @@ void ConvexVolumeTool::handleRenderOverlay(double* /*proj*/, double* /*model*/,
const int h = view[3];
if (!m_npts)
{
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Create new shape. SHIFT+LMB: Delete existing shape (click inside a shape).", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Create new shape. SHIFT+LMB: Delete existing shape (click inside a shape).");
}
else
{
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "Click LMB to add new points. Click on the red point to finish the shape.", imguiRGBA(255,255,255,192));
imguiDrawText(280, h-60, IMGUI_ALIGN_LEFT, "The shape will be convex hull of all added points.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "Click LMB to add new points. Click on the red point to finish the shape.");
ImGui::SetCursorPos(ImVec2(280, (float)h-60));
ImGui::TextColored(ImVec4(255,255,255,192), "The shape will be convex hull of all added points.");
}
}

View File

@ -106,7 +106,7 @@ CrowdToolState::CrowdToolState() :
m_toolParams.m_optimizeVis = true;
m_toolParams.m_optimizeTopo = true;
m_toolParams.m_obstacleAvoidance = true;
m_toolParams.m_obstacleAvoidanceType = 3.0f;
m_toolParams.m_obstacleAvoidanceType = 3;
m_toolParams.m_separation = true;
m_toolParams.m_separationWeight = 20.0f;
m_toolParams.m_maxAcceleration = 800.f;
@ -508,6 +508,10 @@ void CrowdToolState::handleRender()
dd.depthMask(true);
}
namespace ImPlot
{
extern void Demo_ShadedPlots();
};
void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
{
@ -517,11 +521,11 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
if (m_targetRef && gluProject((GLdouble)m_targetPos[0], (GLdouble)m_targetPos[1], (GLdouble)m_targetPos[2],
model, proj, view, &x, &y, &z))
{
imguiDrawText((int)x, (int)(y+25), IMGUI_ALIGN_CENTER, "TARGET", imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y+25));
ImGui::TextColored(ImVec4(0,0,0,220), "TARGET"); // IMGUI_ALIGN_CENTER
}
char label[32];
if (m_toolParams.m_showNodes)
{
dtCrowd* crowd = m_editor->getCrowd();
@ -543,8 +547,9 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
model, proj, view, &x, &y, &z))
{
const float heuristic = node->total;// - node->cost;
snprintf(label, 32, "%.2f", heuristic);
imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y+25));
ImGui::TextColored(ImVec4(0,0,0,220), "%.2f", heuristic);
}
}
}
@ -571,8 +576,8 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
? "none"
: g_traverseAnimTypeNames[animType];
snprintf(label, 32, "%s (%d)", animTypeName, i);
imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y+15));
ImGui::TextColored(ImVec4(0,0,0,220), "%s (%d)", animTypeName, i);
}
}
}
@ -600,8 +605,8 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
if (gluProject((GLdouble)nei->npos[0], (GLdouble)nei->npos[1], (GLdouble)nei->npos[2]+radius,
model, proj, view, &x, &y, &z))
{
snprintf(label, 32, "%.3f", ag->neis[j].dist);
imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(255,255,255,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y+15));
ImGui::TextColored(ImVec4(255,255,255,220), "%.3f", ag->neis[j].dist);
}
}
}
@ -609,21 +614,24 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
}
}
if (m_toolParams.m_showPerfGraph)
{
GraphParams gp;
gp.setRect(300, 10, 500, 200, 8);
gp.setValueRange(0.0f, 2.0f, 4, "ms");
drawGraphBackground(&gp);
drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(255,128,0,255));
gp.setRect(300, 10, 500, 50, 8);
gp.setValueRange(0.0f, 2000.0f, 1, "");
drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(96,96,96,128));
if (!ImPlot::GetCurrentContext())
ImPlot::CreateContext();
//GraphParams gp;
//gp.setRect(300, 10, 500, 200, 8);
//gp.setValueRange(0.0f, 2.0f, 4, "ms");
//
//drawGraphBackground(&gp);
//drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(255,128,0,255));
//
//gp.setRect(300, 10, 500, 50, 8);
//gp.setValueRange(0.0f, 2000.0f, 1, "");
//drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(96,96,96,128));
ImPlot::ShowDemoWindow();
}
}
void CrowdToolState::handleUpdate(const float dt)
@ -892,137 +900,120 @@ void CrowdTool::handleMenu()
return;
CrowdToolParams* params = m_state->getToolParams();
if (imguiCheck("Create Agents", m_mode == TOOLMODE_CREATE))
bool isEnabled = m_mode == TOOLMODE_CREATE;
if (ImGui::Checkbox("Create Agents", &isEnabled))
m_mode = TOOLMODE_CREATE;
if (imguiCheck("Move Target", m_mode == TOOLMODE_MOVE_TARGET))
isEnabled = m_mode == TOOLMODE_MOVE_TARGET;
if (ImGui::Checkbox("Move Target", &isEnabled))
m_mode = TOOLMODE_MOVE_TARGET;
if (imguiCheck("Select Agent", m_mode == TOOLMODE_SELECT))
isEnabled = m_mode == TOOLMODE_SELECT;
if (ImGui::Checkbox("Select Agent", &isEnabled))
m_mode = TOOLMODE_SELECT;
if (imguiCheck("Toggle Polys", m_mode == TOOLMODE_TOGGLE_POLYS))
isEnabled = m_mode == TOOLMODE_TOGGLE_POLYS;
if (ImGui::Checkbox("Toggle Polys", &isEnabled))
m_mode = TOOLMODE_TOGGLE_POLYS;
imguiSeparatorLine();
if (imguiCollapse("Options", 0, params->m_expandOptions))
params->m_expandOptions = !params->m_expandOptions;
ImGui::Separator(); // was imguiSeperatorLine
if (params->m_expandOptions)
if (ImGui::CollapsingHeader("Options"))
{
imguiIndent();
if (imguiCheck("Optimize Visibility", params->m_optimizeVis))
{
params->m_optimizeVis = !params->m_optimizeVis;
ImGui::Indent();
if (ImGui::Checkbox("Optimize Visibility", &params->m_optimizeVis))
m_state->updateAgentParams();
}
if (imguiCheck("Optimize Topology", params->m_optimizeTopo))
{
params->m_optimizeTopo = !params->m_optimizeTopo;
if (ImGui::Checkbox("Optimize Topology", &params->m_optimizeTopo))
m_state->updateAgentParams();
}
if (imguiCheck("Anticipate Turns", params->m_anticipateTurns))
{
params->m_anticipateTurns = !params->m_anticipateTurns;
if (ImGui::Checkbox("Anticipate Turns", &params->m_anticipateTurns))
m_state->updateAgentParams();
}
if (imguiCheck("Obstacle Avoidance", params->m_obstacleAvoidance))
{
params->m_obstacleAvoidance = !params->m_obstacleAvoidance;
if (ImGui::Checkbox("Obstacle Avoidance", &params->m_obstacleAvoidance))
m_state->updateAgentParams();
}
if (imguiSlider("Avoidance Quality", &params->m_obstacleAvoidanceType, 0.0f, 3.0f, 1.0f))
if (ImGui::SliderInt("Avoidance Quality", &params->m_obstacleAvoidanceType, 0, 3))
{
m_state->updateAgentParams();
}
if (imguiCheck("Separation", params->m_separation))
{
params->m_separation = !params->m_separation;
if (ImGui::Checkbox("Separation", &params->m_separation))
m_state->updateAgentParams();
}
if (imguiSlider("Separation Weight", &params->m_separationWeight, 0.0f, 200.0f, 0.01f))
if (ImGui::SliderFloat("Separation Weight", &params->m_separationWeight, 0.0f, 200.0f))
{
m_state->updateAgentParams();
}
if (imguiSlider("Max Acceleration", &params->m_maxAcceleration, 0.0f, 2000.0f, 0.01f))
if (ImGui::SliderFloat("Max Acceleration", &params->m_maxAcceleration, 0.0f, 2000.0f))
{
m_state->updateAgentParams();
}
if (imguiSlider("Max Speed", &params->m_maxSpeed, 0.0f, 2000.0f, 0.01f))
if (ImGui::SliderFloat("Max Speed", &params->m_maxSpeed, 0.0f, 2000.0f))
{
m_state->updateAgentParams();
}
imguiUnindent();
ImGui::Unindent();
}
if (imguiCollapse("Traverse Animation Type", 0, params->m_expandTraversalOptions))
params->m_expandTraversalOptions = !params->m_expandTraversalOptions;
const NavMeshType_e loadedNavMeshType = m_editor->getLoadedNavMeshType();
// TODO: perhaps clamp with m_nav->m_params.traversalTableCount? Technically a navmesh should
// contain all the traversal tables it supports, so if we crash the navmesh is technically corrupt.
const int traverseTableCount = NavMesh_GetTraversalTableCountForNavMeshType(loadedNavMeshType);
const TraverseAnimType_e baseType = NavMesh_GetFirstTraverseAnimTypeForType(loadedNavMeshType);
if (params->m_expandTraversalOptions)
if (ImGui::CollapsingHeader("Traverse Animation Type"))
{
imguiIndent();
const NavMeshType_e loadedNavMeshType = m_editor->getLoadedNavMeshType();
for (int i = ANIMTYPE_NONE; i < traverseTableCount; i++)
// TODO: perhaps clamp with m_nav->m_params.traversalTableCount? Technically a navmesh should
// contain all the traversal tables it supports, so if we crash the navmesh is technically corrupt.
const int traverseTableCount = NavMesh_GetTraversalTableCountForNavMeshType(loadedNavMeshType);
const TraverseAnimType_e baseType = NavMesh_GetFirstTraverseAnimTypeForType(loadedNavMeshType);
if (params->m_expandTraversalOptions)
{
const bool noAnimtype = i == ANIMTYPE_NONE;
ImGui::Indent();
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
if (imguiCheck(animtypeName, params->m_traverseAnimType == animTypeIndex))
for (int i = ANIMTYPE_NONE; i < traverseTableCount; i++)
{
params->m_traverseAnimType = animTypeIndex;
m_state->updateAgentParams();
const bool noAnimtype = i == ANIMTYPE_NONE;
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
bool isAnimTypeEnabled = params->m_traverseAnimType == animTypeIndex;
if (ImGui::Checkbox(animtypeName, &isAnimTypeEnabled))
{
params->m_traverseAnimType = animTypeIndex;
m_state->updateAgentParams();
}
}
ImGui::Unindent();
}
imguiUnindent();
}
if (imguiCollapse("Selected Debug Draw", 0, params->m_expandSelectedDebugDraw))
params->m_expandSelectedDebugDraw = !params->m_expandSelectedDebugDraw;
if (params->m_expandSelectedDebugDraw)
if (ImGui::CollapsingHeader("Selected Debug Draw", 0, params->m_expandSelectedDebugDraw))
{
imguiIndent();
if (imguiCheck("Show Corners", params->m_showCorners))
params->m_showCorners = !params->m_showCorners;
if (imguiCheck("Show Collision Segs", params->m_showCollisionSegments))
params->m_showCollisionSegments = !params->m_showCollisionSegments;
if (imguiCheck("Show Path", params->m_showPath))
params->m_showPath = !params->m_showPath;
if (imguiCheck("Show VO", params->m_showVO))
params->m_showVO = !params->m_showVO;
if (imguiCheck("Show Path Optimization", params->m_showOpt))
params->m_showOpt = !params->m_showOpt;
if (imguiCheck("Show Neighbours", params->m_showNeis))
params->m_showNeis = !params->m_showNeis;
imguiUnindent();
ImGui::Indent();
ImGui::Checkbox("Show Corners", &params->m_showCorners);
ImGui::Checkbox("Show Collision Segs", &params->m_showCollisionSegments);
ImGui::Checkbox("Show Path", &params->m_showPath);
ImGui::Checkbox("Show VO", &params->m_showVO);
ImGui::Checkbox("Show Path Optimization", &params->m_showOpt);
ImGui::Checkbox("Show Neighbours", &params->m_showNeis);
ImGui::Unindent();
}
if (imguiCollapse("Debug Draw", 0, params->m_expandDebugDraw))
params->m_expandDebugDraw = !params->m_expandDebugDraw;
if (params->m_expandDebugDraw)
if (ImGui::CollapsingHeader("Debug Draw", 0, params->m_expandDebugDraw))
{
imguiIndent();
if (imguiCheck("Show Labels", params->m_showLabels))
params->m_showLabels = !params->m_showLabels;
if (imguiCheck("Show Prox Grid", params->m_showGrid))
params->m_showGrid = !params->m_showGrid;
if (imguiCheck("Show Nodes", params->m_showNodes))
params->m_showNodes = !params->m_showNodes;
if (imguiCheck("Show Perf Graph", params->m_showPerfGraph))
params->m_showPerfGraph = !params->m_showPerfGraph;
if (imguiCheck("Show Detail All", params->m_showDetailAll))
params->m_showDetailAll = !params->m_showDetailAll;
imguiUnindent();
ImGui::Indent();
ImGui::Checkbox("Show Labels", &params->m_showLabels);
ImGui::Checkbox("Show Prox Grid", &params->m_showGrid);
ImGui::Checkbox("Show Nodes", &params->m_showNodes);
ImGui::Checkbox("Show Perf Graph", &params->m_showPerfGraph);
ImGui::Checkbox("Show Detail All", &params->m_showDetailAll);
ImGui::Unindent();
}
}
@ -1116,28 +1107,41 @@ void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
// Tool help
const int h = view[3];
int ty = h-40;
float ty = (float)h-40;
if (m_mode == TOOLMODE_CREATE)
{
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: add agent. Shift+LMB: remove agent.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: add agent. Shift+LMB: remove agent.");
}
else if (m_mode == TOOLMODE_MOVE_TARGET)
{
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: set move target. Shift+LMB: adjust set velocity.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: set move target. Shift+LMB: adjust set velocity.");
ty -= 20;
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "Setting velocity will move the agents without pathfinder.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,255,255,192), "Setting velocity will move the agents without pathfinder.");
}
else if (m_mode == TOOLMODE_SELECT)
{
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: select agent.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: select agent.");
}
ty -= 20;
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "SPACE: Run/Pause simulation. 1: Step simulation.", imguiRGBA(255,255,255,192));
ty -= 20;
ty -= 20.f;
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,255,255,192), "SPACE: Run/Pause simulation. 1: Step simulation.");
ty -= 20.f;
if (m_state && m_state->isRunning())
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- RUNNING -", imguiRGBA(255,32,16,255));
else
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- PAUSED -", imguiRGBA(255,255,255,128));
{
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,32,16,255), "- RUNNING -");
}
else
{
ImGui::SetCursorPos(ImVec2(280, ty));
ImGui::TextColored(ImVec4(255,255,255,128), "- PAUSED -");
}
}

View File

@ -176,18 +176,18 @@ void Editor::resetCommonSettings()
m_agentMaxSlope = 45.0f;
m_regionMinSize = 8;
m_regionMergeSize = 20;
m_edgeMaxLen = 12.0f;
m_edgeMaxLen = 12;
m_edgeMaxError = 1.3f;
m_vertsPerPoly = 6.0f;
m_vertsPerPoly = 6;
m_detailSampleDist = 6.0f;
m_detailSampleMaxError = 1.0f;
m_partitionType = EDITOR_PARTITION_WATERSHED;
}
void Editor::handleCommonSettings()
{
imguiLabel("Rasterization");
imguiSlider("Cell Size", &m_cellSize, 0.1f, 100.0f, 0.01f);
imguiSlider("Cell Height", &m_cellHeight, 0.1f, 100.0f, 0.01f);
ImGui::Text("Rasterization");
ImGui::SliderFloat("Cell Size", &m_cellSize, 0.1f, 100.0f);
ImGui::SliderFloat("Cell Height", &m_cellHeight, 0.1f, 100.0f);
if (m_geom)
{
@ -197,51 +197,57 @@ void Editor::handleCommonSettings()
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
char text[64];
snprintf(text, 64, "Voxels %d x %d", gw, gh);
imguiValue(text);
ImGui::Text(text);
}
imguiSeparator();
imguiLabel("Agent");
imguiSlider("Height", &m_agentHeight, 0.1f, 500.0f, 0.1f);
imguiSlider("Radius", &m_agentRadius, 0.0f, 500.0f, 0.1f);
imguiSlider("Max Climb", &m_agentMaxClimb, 0.1f, 120.0f, 0.1f);
imguiSlider("Max Slope", &m_agentMaxSlope, 0.0f, 90.0f, 1.0f);
ImGui::Separator();
ImGui::Text("Agent");
ImGui::SliderFloat("Height", &m_agentHeight, 0.1f, 500.0f);
ImGui::SliderFloat("Radius", &m_agentRadius, 0.0f, 500.0f);
ImGui::SliderFloat("Max Climb", &m_agentMaxClimb, 0.1f, 120.0f);
ImGui::SliderFloat("Max Slope", &m_agentMaxSlope, 0.0f, 90.0f); // ImGui_Upgrade: Slider step was 1.0f
imguiSeparator();
imguiLabel("Region");
imguiSlider("Min Region Size", &m_regionMinSize, 0.0f, 750.0f, 1.0f);
imguiSlider("Merged Region Size", &m_regionMergeSize, 0.0f, 750.0f, 1.0f);
ImGui::Separator();
ImGui::Text("Region");
ImGui::SliderInt("Min Region Size", &m_regionMinSize, 0, 750); // todo(amos): increase because of larger map scale?
ImGui::SliderInt("Merged Region Size", &m_regionMergeSize, 0, 750); // todo(amos): increase because of larger map scale?
imguiSeparator();
imguiLabel("Partitioning");
if (imguiCheck("Watershed", m_partitionType == EDITOR_PARTITION_WATERSHED))
ImGui::Separator();
ImGui::Text("Partitioning");
bool isEnabled = m_partitionType == EDITOR_PARTITION_WATERSHED;
if (ImGui::Checkbox("Watershed", &isEnabled))
m_partitionType = EDITOR_PARTITION_WATERSHED;
if (imguiCheck("Monotone", m_partitionType == EDITOR_PARTITION_MONOTONE))
isEnabled = m_partitionType == EDITOR_PARTITION_MONOTONE;
if (ImGui::Checkbox("Monotone", &isEnabled))
m_partitionType = EDITOR_PARTITION_MONOTONE;
if (imguiCheck("Layers", m_partitionType == EDITOR_PARTITION_LAYERS))
isEnabled = m_partitionType == EDITOR_PARTITION_LAYERS;
if (ImGui::Checkbox("Layers", &isEnabled))
m_partitionType = EDITOR_PARTITION_LAYERS;
imguiSeparator();
imguiLabel("Filtering");
if (imguiCheck("Low Hanging Obstacles", m_filterLowHangingObstacles))
m_filterLowHangingObstacles = !m_filterLowHangingObstacles;
if (imguiCheck("Ledge Spans", m_filterLedgeSpans))
m_filterLedgeSpans= !m_filterLedgeSpans;
if (imguiCheck("Walkable Low Height Spans", m_filterWalkableLowHeightSpans))
m_filterWalkableLowHeightSpans = !m_filterWalkableLowHeightSpans;
ImGui::Separator();
ImGui::Text("Filtering");
ImGui::Checkbox("Low Hanging Obstacles", &m_filterLowHangingObstacles);
ImGui::Checkbox("Ledge Spans", &m_filterLedgeSpans);
ImGui::Checkbox("Walkable Low Height Spans", &m_filterWalkableLowHeightSpans);
imguiSeparator();
imguiLabel("Polygonization");
imguiSlider("Max Edge Length", &m_edgeMaxLen, 0.0f, 50.0f, 1.0f);
imguiSlider("Max Edge Error", &m_edgeMaxError, 0.1f, 3.0f, 0.1f);
imguiSlider("Verts Per Poly", &m_vertsPerPoly, 3.0f, 6.0f, 1.0f);
ImGui::Separator();
ImGui::Text("Polygonization");
ImGui::SliderInt("Max Edge Length", &m_edgeMaxLen, 0, 50); // todo(amos): increase due to larger scale maps?
ImGui::SliderFloat("Max Edge Error", &m_edgeMaxError, 0.1f, 3.0f);
ImGui::SliderInt("Verts Per Poly", &m_vertsPerPoly, 3, 6);
imguiSeparator();
imguiLabel("Detail Mesh");
imguiSlider("Sample Distance", &m_detailSampleDist, 1.0f, 16.0f, 1.0f);
imguiSlider("Max Sample Error", &m_detailSampleMaxError, 0.0f, 16.0f, 1.0f);
ImGui::Separator();
ImGui::Text("Detail Mesh");
ImGui::SliderFloat("Sample Distance", &m_detailSampleDist, 1.0f, 16.0f);
ImGui::SliderFloat("Max Sample Error", &m_detailSampleMaxError, 0.0f, 16.0f);
imguiSeparator();
ImGui::Separator();
}
void Editor::handleClick(const float* s, const float* p, bool shift)

View File

@ -91,13 +91,13 @@ public:
virtual void handleMenu()
{
imguiLabel("Create Tiles");
if (imguiButton("Create All"))
ImGui::Text("Create Tiles");
if (ImGui::Button("Create All"))
{
if (m_editor)
m_editor->buildAllTiles();
}
if (imguiButton("Remove All"))
if (ImGui::Button("Remove All"))
{
if (m_editor)
m_editor->removeAllTiles();
@ -150,14 +150,16 @@ public:
{
int tx=0, ty=0;
m_editor->getTilePos(m_hitPos, tx, ty);
char text[32];
snprintf(text,32,"(%d,%d)", tx,ty);
imguiDrawText((int)x, (int)y-25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
ImGui::TextColored(ImVec4(0,0,0,220), "(%d,%d)", tx,ty);
}
// Tool help
const int h = view[3];
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.");
}
};
@ -215,11 +217,11 @@ void Editor_TileMesh::cleanup()
m_dmesh = 0;
}
const hulldef hulls[NAVMESH_COUNT] = {
{ g_navMeshNames[NAVMESH_SMALL] , NAI_Hull::Width(HULL_HUMAN) , NAI_Hull::Height(HULL_HUMAN) * NAI_Hull::Scale(HULL_HUMAN) , 45, 32.0f },
{ g_navMeshNames[NAVMESH_MED_SHORT] , NAI_Hull::Width(HULL_PROWLER), NAI_Hull::Height(HULL_PROWLER) * NAI_Hull::Scale(HULL_PROWLER), 50, 32.0f },
{ g_navMeshNames[NAVMESH_MEDIUM] , NAI_Hull::Width(HULL_MEDIUM) , NAI_Hull::Height(HULL_MEDIUM) * NAI_Hull::Scale(HULL_MEDIUM) , 55, 32.0f },
{ g_navMeshNames[NAVMESH_LARGE] , NAI_Hull::Width(HULL_TITAN) , NAI_Hull::Height(HULL_TITAN) * NAI_Hull::Scale(HULL_TITAN) , 60, 64.0f },
{ g_navMeshNames[NAVMESH_EXTRA_LARGE], NAI_Hull::Width(HULL_GOLIATH), NAI_Hull::Height(HULL_GOLIATH) * NAI_Hull::Scale(HULL_GOLIATH), 65, 64.0f },
{ g_navMeshNames[NAVMESH_SMALL] , NAI_Hull::Width(HULL_HUMAN) , NAI_Hull::Height(HULL_HUMAN) * NAI_Hull::Scale(HULL_HUMAN) , 45, 32 },
{ g_navMeshNames[NAVMESH_MED_SHORT] , NAI_Hull::Width(HULL_PROWLER), NAI_Hull::Height(HULL_PROWLER) * NAI_Hull::Scale(HULL_PROWLER), 50, 32 },
{ g_navMeshNames[NAVMESH_MEDIUM] , NAI_Hull::Width(HULL_MEDIUM) , NAI_Hull::Height(HULL_MEDIUM) * NAI_Hull::Scale(HULL_MEDIUM) , 55, 32 },
{ g_navMeshNames[NAVMESH_LARGE] , NAI_Hull::Width(HULL_TITAN) , NAI_Hull::Height(HULL_TITAN) * NAI_Hull::Scale(HULL_TITAN) , 60, 64 },
{ g_navMeshNames[NAVMESH_EXTRA_LARGE], NAI_Hull::Width(HULL_GOLIATH), NAI_Hull::Height(HULL_GOLIATH) * NAI_Hull::Scale(HULL_GOLIATH), 65, 64 },
};
void Editor_TileMesh::selectNavMeshType(const NavMeshType_e navMeshType)
@ -241,7 +243,7 @@ void Editor_TileMesh::handleSettings()
{
const NavMeshType_e navMeshType = NavMeshType_e(i);
if (imguiButton(NavMesh_GetNameForType(navMeshType)))
if (ImGui::Button(NavMesh_GetNameForType(navMeshType)))
{
selectNavMeshType(navMeshType);
}
@ -249,14 +251,11 @@ void Editor_TileMesh::handleSettings()
Editor::handleCommonSettings();
if (imguiCheck("Keep Intermediate Results", m_keepInterResults))
m_keepInterResults = !m_keepInterResults;
if (imguiCheck("Build All Tiles", m_buildAll))
m_buildAll = !m_buildAll;
ImGui::Checkbox("Keep Intermediate Results", &m_keepInterResults);
ImGui::Checkbox("Build All Tiles", &m_buildAll);
imguiLabel("Tiling");
imguiSlider("TileSize", &m_tileSize, 8.0f, 1024.0f, 8.0f);
ImGui::Text("Tiling");
ImGui::SliderInt("TileSize", &m_tileSize, 8, 1024);
if (m_geom)
{
@ -265,13 +264,13 @@ void Editor_TileMesh::handleSettings()
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
const int ts = m_tileSize;
const int tw = (gw + ts-1) / ts;
const int th = (gh + ts-1) / ts;
snprintf(text, sizeof(text), "Tiles %d x %d", tw, th);
imguiValue(text);
ImGui::Text(text);
snprintf(text, sizeof(text), "Tile Sizes %g x %g (%g)", tw*m_cellSize, th*m_cellSize, m_tileSize*m_cellSize);
imguiValue(text);
ImGui::Text(text);
// Max tiles and max polys affect how the tile IDs are calculated.
// There are 28 bits available for identifying a tile and a polygon.
int tileBits = rcMin((int)ilog2(nextPow2(tw*th)), 16);
@ -279,9 +278,9 @@ void Editor_TileMesh::handleSettings()
m_maxTiles = 1 << tileBits;
m_maxPolysPerTile = 1 << polyBits;
snprintf(text, sizeof(text), "Max Tiles %d", m_maxTiles);
imguiValue(text);
ImGui::Text(text);
snprintf(text, sizeof(text), "Max Polys %d", m_maxPolysPerTile);
imguiValue(text);
ImGui::Text(text);
}
else
{
@ -289,12 +288,12 @@ void Editor_TileMesh::handleSettings()
m_maxPolysPerTile = 0;
}
imguiSeparator();
ImGui::Separator();
imguiIndent();
imguiIndent();
ImGui::Indent();
ImGui::Indent();
if (imguiButton("Load"))
if (ImGui::Button("Load"))
{
dtFreeNavMesh(m_navMesh);
m_navMesh = Editor::loadAll(m_modelName.c_str());
@ -304,83 +303,84 @@ void Editor_TileMesh::handleSettings()
initToolStates(this);
}
if (imguiButton("Save"))
if (ImGui::Button("Save"))
{
Editor::saveAll(m_modelName.c_str(), m_navMesh);
}
imguiUnindent();
imguiUnindent();
ImGui::Unindent();
ImGui::Unindent();
char msg[128];
snprintf(msg, sizeof(msg), "Build Time: %.1fms", m_totalBuildTimeMs);
imguiLabel(msg);
ImGui::Text("Build Time: %.1fms", m_totalBuildTimeMs);
imguiSeparator();
ImGui::Separator();
if (m_navMesh)
{
const dtNavMeshParams& params = m_navMesh->m_params;
const float* origin = m_navMesh->m_orig;
char result[256];
snprintf(result, sizeof(result), "Mesh Origin: <%g, %g, %g>", origin[0], origin[1], origin[2]);
imguiLabel(result);
snprintf(result, sizeof(result), "Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
imguiLabel(result);
snprintf(result, sizeof(result), "Poly Group Count: %d", params.polyGroupCount);
imguiLabel(result);
snprintf(result, sizeof(result), "Traversal Table Size: %d", params.traversalTableSize);
imguiLabel(result);
snprintf(result, sizeof(result), "Traversal Table Count: %d", params.traversalTableCount);
imguiLabel(result);
snprintf(result, sizeof(result), "Max Tiles: %d", params.maxTiles);
imguiLabel(result);
snprintf(result, sizeof(result), "Max Polys: %d", params.maxPolys);
imguiLabel(result);
ImGui::Text("Mesh Origin: <%g, %g, %g>", origin[0], origin[1], origin[2]);
ImGui::Text("Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
ImGui::Text("Poly Group Count: %d", params.polyGroupCount);
ImGui::Text("Traversal Table Size: %d", params.traversalTableSize);
ImGui::Text("Traversal Table Count: %d", params.traversalTableCount);
ImGui::Text("Max Tiles: %d", params.maxTiles);
ImGui::Text("Max Polys: %d", params.maxPolys);
}
imguiSeparator();
ImGui::Separator();
}
void Editor_TileMesh::handleTools()
{
int type = !m_tool ? TOOL_NONE : m_tool->type();
bool isEnabled = type == TOOL_NAVMESH_TESTER;
if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
if (ImGui::Checkbox("Test Navmesh", &isEnabled))
{
setTool(new NavMeshTesterTool);
}
if (imguiCheck("Prune Navmesh", type == TOOL_NAVMESH_PRUNE))
isEnabled = type == TOOL_NAVMESH_PRUNE;
if (ImGui::Checkbox("Prune Navmesh", &isEnabled))
{
setTool(new NavMeshPruneTool);
}
if (imguiCheck("Create Tiles", type == TOOL_TILE_EDIT))
isEnabled = type == TOOL_TILE_EDIT;
if (ImGui::Checkbox("Create Tiles", &isEnabled))
{
setTool(new NavMeshTileTool);
}
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
isEnabled = type == TOOL_OFFMESH_CONNECTION;
if (ImGui::Checkbox("Create Off-Mesh Links", &isEnabled))
{
setTool(new OffMeshConnectionTool);
}
if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
isEnabled = type == TOOL_CONVEX_VOLUME;
if (ImGui::Checkbox("Create Convex Volumes", &isEnabled))
{
setTool(new ConvexVolumeTool);
}
if (imguiCheck("Create Crowds", type == TOOL_CROWD))
isEnabled = type == TOOL_CROWD;
if (ImGui::Checkbox("Create Crowds", &isEnabled))
{
setTool(new CrowdTool);
}
imguiSeparatorLine();
ImGui::Separator(); // was imguiSeperatorLine
imguiIndent();
ImGui::Indent();
if (m_tool)
m_tool->handleMenu();
imguiUnindent();
ImGui::Unindent();
}
void Editor_TileMesh::handleDebugMode()
@ -419,81 +419,209 @@ void Editor_TileMesh::handleDebugMode()
if (unavail == MAX_DRAWMODE)
return;
imguiLabel("Render Options");
ImGui::Text("Render Options");
if (imguiCheck("Draw Off-Mesh Connections", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OFFMESHCONS)))
bool isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OFFMESHCONS);
if (ImGui::Checkbox("Draw Off-Mesh Connections", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OFFMESHCONS);
if (imguiCheck("Draw Closed List", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_CLOSEDLIST)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_CLOSEDLIST);
if (ImGui::Checkbox("Draw Closed List", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_CLOSEDLIST);
if (imguiCheck("Draw Tile ID Colors", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_COLOR_TILES)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_COLOR_TILES);
if (ImGui::Checkbox("Draw Tile ID Colors", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_COLOR_TILES);
if (imguiCheck("Draw Vertex Points", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_VERTS)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_VERTS);
if (ImGui::Checkbox("Draw Vertex Points", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_VERTS);
if (imguiCheck("Draw Inner Poly Boundaries", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_INNERBOUND)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_INNERBOUND);
if (ImGui::Checkbox("Draw Inner Poly Boundaries", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_INNERBOUND);
if (imguiCheck("Draw Outer Poly Boundaries", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OUTERBOUND)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OUTERBOUND);
if (ImGui::Checkbox("Draw Outer Poly Boundaries", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OUTERBOUND);
if (imguiCheck("Draw Poly Centers", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYCENTERS)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYCENTERS);
if (ImGui::Checkbox("Draw Poly Centers", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYCENTERS);
if (imguiCheck("Draw Poly Groups", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYGROUPS)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYGROUPS);
if (ImGui::Checkbox("Draw Poly Groups", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYGROUPS);
if (imguiCheck("Disable NavMesh Depth Mask", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_DEPTH_MASK)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_DEPTH_MASK);
if (ImGui::Checkbox("Disable NavMesh Depth Mask", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_NO_DEPTH_MASK);
if (imguiCheck("Disable NavMesh Transparency", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_ALPHA)))
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_ALPHA);
if (ImGui::Checkbox("Disable NavMesh Transparency", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_NO_ALPHA);
imguiLabel("Draw");
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
ImGui::Text("Draw");
isEnabled = m_drawMode == DRAWMODE_MESH;
ImGui::BeginDisabled(!valid[DRAWMODE_MESH]);
if (ImGui::Checkbox("Input Mesh", &isEnabled))
m_drawMode = DRAWMODE_MESH;
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_NAVMESH;
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH]);
if (ImGui::Checkbox("Navmesh", &isEnabled))
m_drawMode = DRAWMODE_NAVMESH;
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_NAVMESH_INVIS;
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_INVIS]);
if (ImGui::Checkbox("Navmesh Invis", &isEnabled))
m_drawMode = DRAWMODE_NAVMESH_INVIS;
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_NAVMESH_TRANS;
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_TRANS]);
if (ImGui::Checkbox("Navmesh Trans", &isEnabled))
m_drawMode = DRAWMODE_NAVMESH_TRANS;
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_NAVMESH_BVTREE;
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_BVTREE]);
if (ImGui::Checkbox("Navmesh BVTree", &isEnabled))
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_NAVMESH_NODES;
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_NODES]);
if (ImGui::Checkbox("Navmesh Nodes", &isEnabled))
m_drawMode = DRAWMODE_NAVMESH_NODES;
if (imguiCheck("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS, valid[DRAWMODE_NAVMESH_PORTALS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_NAVMESH_PORTALS;
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_PORTALS]);
if (ImGui::Checkbox("Navmesh Portals", &isEnabled))
m_drawMode = DRAWMODE_NAVMESH_PORTALS;
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_VOXELS;
ImGui::BeginDisabled(!valid[DRAWMODE_VOXELS]);
if (ImGui::Checkbox("Voxels", &isEnabled))
m_drawMode = DRAWMODE_VOXELS;
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_VOXELS_WALKABLE;
ImGui::BeginDisabled(!valid[DRAWMODE_VOXELS_WALKABLE]);
if (ImGui::Checkbox("Walkable Voxels", &isEnabled))
m_drawMode = DRAWMODE_VOXELS_WALKABLE;
if (imguiCheck("Compact", m_drawMode == DRAWMODE_COMPACT, valid[DRAWMODE_COMPACT]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_COMPACT;
ImGui::BeginDisabled(!valid[DRAWMODE_COMPACT]);
if (ImGui::Checkbox("Compact", &isEnabled))
m_drawMode = DRAWMODE_COMPACT;
if (imguiCheck("Compact Distance", m_drawMode == DRAWMODE_COMPACT_DISTANCE, valid[DRAWMODE_COMPACT_DISTANCE]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_COMPACT_DISTANCE;
ImGui::BeginDisabled(!valid[DRAWMODE_COMPACT_DISTANCE]);
if (ImGui::Checkbox("Compact Distance", &isEnabled))
m_drawMode = DRAWMODE_COMPACT_DISTANCE;
if (imguiCheck("Compact Regions", m_drawMode == DRAWMODE_COMPACT_REGIONS, valid[DRAWMODE_COMPACT_REGIONS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_COMPACT_REGIONS;
ImGui::BeginDisabled(!valid[DRAWMODE_COMPACT_REGIONS]);
if (ImGui::Checkbox("Compact Regions", &isEnabled))
m_drawMode = DRAWMODE_COMPACT_REGIONS;
if (imguiCheck("Region Connections", m_drawMode == DRAWMODE_REGION_CONNECTIONS, valid[DRAWMODE_REGION_CONNECTIONS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_REGION_CONNECTIONS;
ImGui::BeginDisabled(!valid[DRAWMODE_REGION_CONNECTIONS]);
if (ImGui::Checkbox("Region Connections", &isEnabled))
m_drawMode = DRAWMODE_REGION_CONNECTIONS;
if (imguiCheck("Raw Contours", m_drawMode == DRAWMODE_RAW_CONTOURS, valid[DRAWMODE_RAW_CONTOURS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_RAW_CONTOURS;
ImGui::BeginDisabled(!valid[DRAWMODE_RAW_CONTOURS]);
if (ImGui::Checkbox("Raw Contours", &isEnabled))
m_drawMode = DRAWMODE_RAW_CONTOURS;
if (imguiCheck("Both Contours", m_drawMode == DRAWMODE_BOTH_CONTOURS, valid[DRAWMODE_BOTH_CONTOURS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_BOTH_CONTOURS;
ImGui::BeginDisabled(!valid[DRAWMODE_BOTH_CONTOURS]);
if (ImGui::Checkbox("Both Contours", &isEnabled))
m_drawMode = DRAWMODE_BOTH_CONTOURS;
if (imguiCheck("Contours", m_drawMode == DRAWMODE_CONTOURS, valid[DRAWMODE_CONTOURS]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_CONTOURS;
ImGui::BeginDisabled(!valid[DRAWMODE_CONTOURS]);
if (ImGui::Checkbox("Contours", &isEnabled))
m_drawMode = DRAWMODE_CONTOURS;
if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_POLYMESH;
ImGui::BeginDisabled(!valid[DRAWMODE_POLYMESH]);
if (ImGui::Checkbox("Poly Mesh", &isEnabled))
m_drawMode = DRAWMODE_POLYMESH;
if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL]))
ImGui::EndDisabled();
isEnabled = m_drawMode == DRAWMODE_POLYMESH_DETAIL;
ImGui::BeginDisabled(!valid[DRAWMODE_POLYMESH_DETAIL]);
if (ImGui::Checkbox("Poly Mesh Detail", &isEnabled))
m_drawMode = DRAWMODE_POLYMESH_DETAIL;
ImGui::EndDisabled();
if (unavail)
{
imguiValue("Tick 'Keep Intermediate Results'");
imguiValue("rebuild some tiles to see");
imguiValue("more debug mode options.");
ImGui::Text("Tick 'Keep Intermediate Results'");
ImGui::Text("rebuild some tiles to see");
ImGui::Text("more debug mode options.");
}
}
@ -524,8 +652,8 @@ void Editor_TileMesh::handleRender()
// Tiling grid.
int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_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*m_cellSize;
duDebugDrawGridXY(&m_dd, bmax[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
@ -633,9 +761,8 @@ void Editor_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
if (m_tileBuildTime > 0.0f && gluProject((GLdouble)(m_lastBuiltTileBmin[0]+m_lastBuiltTileBmax[0])/2, (GLdouble)(m_lastBuiltTileBmin[1]+m_lastBuiltTileBmax[1])/2, (GLdouble)(m_lastBuiltTileBmin[2]+m_lastBuiltTileBmax[2])/2,
model, proj, view, &x, &y, &z))
{
char text[32];
snprintf(text,32,"%.3fms / %dTris / %.1fkB", m_tileBuildTime, m_tileTriCount, m_tileMemUsage);
imguiDrawText((int)x, (int)y-25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
ImGui::TextColored(ImVec4(0,0,0,220), "%.3fms / %dTris / %.1fkB", m_tileBuildTime, m_tileTriCount, m_tileMemUsage);
}
if (m_tool)
@ -810,7 +937,7 @@ void Editor_TileMesh::buildAllTiles()
const float* bmax = m_geom->getNavMeshBoundsMax();
int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_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;
@ -865,7 +992,7 @@ void Editor_TileMesh::removeAllTiles()
const float* bmax = m_geom->getNavMeshBoundsMax();
int gw = 0, gh = 0;
rcCalcGridSize(bmin, bmax, m_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;
@ -922,10 +1049,10 @@ unsigned char* Editor_TileMesh::buildTileMesh(const int tx, const int ty, const
m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs);
m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
m_cfg.maxSimplificationError = m_edgeMaxError;
m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
m_cfg.minRegionArea = rcSqr(m_regionMinSize); // Note: area = size*size
m_cfg.mergeRegionArea = rcSqr(m_regionMergeSize); // Note: area = size*size
m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
m_cfg.tileSize = (int)m_tileSize;
m_cfg.tileSize = m_tileSize;
m_cfg.borderSize = m_cfg.walkableRadius + 3; // Reserve enough padding.
m_cfg.width = m_cfg.tileSize + m_cfg.borderSize*2;
m_cfg.height = m_cfg.tileSize + m_cfg.borderSize*2;

View File

@ -312,7 +312,7 @@ bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath)
{
// 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",
sscanf(row + 1, "%f %f %f %f %f %f %d %d %d %f %d %f %f %d %f %f %f %f %f %f %d",
&m_buildSettings.cellSize,
&m_buildSettings.cellHeight,
&m_buildSettings.agentHeight,
@ -384,7 +384,7 @@ bool InputGeom::saveGeomSet(const BuildSettings* settings)
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",
"s %f %f %f %f %f %f %d %d %d %f %d %f %f %d %f %f %f %f %f %f %d\n",
settings->cellSize,
settings->cellHeight,
settings->agentHeight,

View File

@ -211,12 +211,12 @@ void NavMeshPruneTool::handleMenu()
if (!nav) return;
if (!m_flags) return;
if (imguiButton("Clear Selection"))
if (ImGui::Button("Clear Selection"))
{
m_flags->clearAllFlags();
}
if (imguiButton("Prune Unselected"))
if (ImGui::Button("Prune Unselected"))
{
disableUnvisitedPolys(nav, m_flags);
delete m_flags;
@ -312,5 +312,6 @@ void NavMeshPruneTool::handleRenderOverlay(double* proj, double* model, int* vie
// Tool help
const int h = view[3];
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Click fill area.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Click fill area.");
}

View File

@ -212,80 +212,109 @@ void NavMeshTesterTool::init(Editor* editor)
void NavMeshTesterTool::handleMenu()
{
if (imguiCheck("Pathfind Follow", m_toolMode == TOOLMODE_PATHFIND_FOLLOW))
bool isEnabled = m_toolMode == TOOLMODE_PATHFIND_FOLLOW;
if (ImGui::Checkbox("Pathfind Follow", &isEnabled))
{
m_toolMode = TOOLMODE_PATHFIND_FOLLOW;
recalc();
}
if (imguiCheck("Pathfind Straight", m_toolMode == TOOLMODE_PATHFIND_STRAIGHT))
isEnabled = m_toolMode == TOOLMODE_PATHFIND_STRAIGHT;
if (ImGui::Checkbox("Pathfind Straight", &isEnabled))
{
m_toolMode = TOOLMODE_PATHFIND_STRAIGHT;
recalc();
}
if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
{
imguiIndent();
imguiLabel("Vertices at crossings");
if (imguiCheck("None", m_straightPathOptions == 0))
ImGui::Indent();
ImGui::Text("Vertices at crossings");
isEnabled = m_straightPathOptions == 0;
if (ImGui::Checkbox("None", &isEnabled))
{
m_straightPathOptions = 0;
recalc();
}
if (imguiCheck("Area", m_straightPathOptions == DT_STRAIGHTPATH_AREA_CROSSINGS))
isEnabled = m_straightPathOptions == DT_STRAIGHTPATH_AREA_CROSSINGS;
if (ImGui::Checkbox("Area", &isEnabled))
{
m_straightPathOptions = DT_STRAIGHTPATH_AREA_CROSSINGS;
recalc();
}
if (imguiCheck("All", m_straightPathOptions == DT_STRAIGHTPATH_ALL_CROSSINGS))
isEnabled = m_straightPathOptions == DT_STRAIGHTPATH_ALL_CROSSINGS;
if (ImGui::Checkbox("All", &isEnabled))
{
m_straightPathOptions = DT_STRAIGHTPATH_ALL_CROSSINGS;
recalc();
}
imguiUnindent();
ImGui::Unindent();
}
if (imguiCheck("Pathfind Sliced", m_toolMode == TOOLMODE_PATHFIND_SLICED))
isEnabled = m_straightPathOptions == TOOLMODE_PATHFIND_SLICED;
if (ImGui::Checkbox("Pathfind Sliced", &isEnabled))
{
m_toolMode = TOOLMODE_PATHFIND_SLICED;
recalc();
}
imguiSeparator();
ImGui::Separator();
if (imguiCheck("Distance to Wall", m_toolMode == TOOLMODE_DISTANCE_TO_WALL))
isEnabled = m_toolMode == TOOLMODE_DISTANCE_TO_WALL;
if (ImGui::Checkbox("Distance to Wall", &isEnabled))
{
m_toolMode = TOOLMODE_DISTANCE_TO_WALL;
recalc();
}
if (imguiCheck("Raycast", m_toolMode == TOOLMODE_RAYCAST))
isEnabled = m_toolMode == TOOLMODE_RAYCAST;
if (ImGui::Checkbox("Raycast", &isEnabled))
{
m_toolMode = TOOLMODE_RAYCAST;
recalc();
}
imguiSeparator();
ImGui::Separator();
if (imguiCheck("Find Polys in Circle", m_toolMode == TOOLMODE_FIND_POLYS_IN_CIRCLE))
isEnabled = m_toolMode == TOOLMODE_FIND_POLYS_IN_CIRCLE;
if (ImGui::Checkbox("Find Polys in Circle", &isEnabled))
{
m_toolMode = TOOLMODE_FIND_POLYS_IN_CIRCLE;
recalc();
}
if (imguiCheck("Find Polys in Shape", m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE))
isEnabled = m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE;
if (ImGui::Checkbox("Find Polys in Shape", &isEnabled))
{
m_toolMode = TOOLMODE_FIND_POLYS_IN_SHAPE;
recalc();
}
if (imguiCheck("Find Local Neighbourhood", m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD))
isEnabled = m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD;
if (ImGui::Checkbox("Find Local Neighbourhood", &isEnabled))
{
m_toolMode = TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD;
recalc();
}
imguiSeparator();
ImGui::Separator();
if (imguiButton("Set Random Start"))
if (ImGui::Button("Set Random Start"))
{
dtStatus status = m_navQuery->findRandomPoint(&m_filter, frand, &m_startRef, m_spos);
if (dtStatusSucceed(status))
@ -294,7 +323,10 @@ void NavMeshTesterTool::handleMenu()
recalc();
}
}
if (imguiButton("Set Random End", m_sposSet))
ImGui::BeginDisabled(m_sposSet);
if (ImGui::Button("Set Random End"))
{
if (m_sposSet)
{
@ -307,9 +339,11 @@ void NavMeshTesterTool::handleMenu()
}
}
imguiSeparator();
ImGui::EndDisabled();
if (imguiButton("Make Random Points"))
ImGui::Separator();
if (ImGui::Button("Make Random Points"))
{
m_randPointsInCircle = false;
m_nrandPoints = 0;
@ -325,7 +359,10 @@ void NavMeshTesterTool::handleMenu()
}
}
}
if (imguiButton("Make Random Points Around", m_sposSet))
ImGui::BeginDisabled(m_sposSet);
if (ImGui::Button("Make Random Points Around"))
{
if (m_sposSet)
{
@ -345,64 +382,89 @@ void NavMeshTesterTool::handleMenu()
}
}
ImGui::EndDisabled();
imguiSeparator();
ImGui::Separator();
imguiLabel("Include Flags");
ImGui::Text("Include Flags");
imguiIndent();
if (imguiCheck("Walk", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_WALK) != 0))
ImGui::Indent();
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_WALK) != 0;
if (ImGui::Checkbox("Walk", &isEnabled))
{
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_WALK);
recalc();
}
if (imguiCheck("Swim", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0))
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0;
if (ImGui::Checkbox("Swim", &isEnabled))
{
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_SWIM);
recalc();
}
if (imguiCheck("Door", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0))
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0;
if (ImGui::Checkbox("Door", &isEnabled))
{
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_DOOR);
recalc();
}
if (imguiCheck("Jump", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0))
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0;
if (ImGui::Checkbox("Jump", &isEnabled))
{
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_JUMP);
recalc();
}
imguiUnindent();
ImGui::Unindent();
imguiSeparator();
imguiLabel("Exclude Flags");
ImGui::Separator();
ImGui::Text("Exclude Flags");
imguiIndent();
if (imguiCheck("Walk", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_WALK) != 0))
ImGui::Indent();
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_WALK) != 0;
if (ImGui::Checkbox("Walk", &isEnabled))
{
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_WALK);
recalc();
}
if (imguiCheck("Swim", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0))
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0;
if (ImGui::Checkbox("Swim", &isEnabled))
{
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_SWIM);
recalc();
}
if (imguiCheck("Door", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0))
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0;
if (ImGui::Checkbox("Door", &isEnabled))
{
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_DOOR);
recalc();
}
if (imguiCheck("Jump", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0))
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0;
if (ImGui::Checkbox("Jump", &isEnabled))
{
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_JUMP);
recalc();
}
imguiUnindent();
ImGui::Unindent();
imguiSeparator();
imguiLabel("Traverse Anim Type");
ImGui::Separator();
ImGui::Text("Traverse Anim Type");
imguiIndent();
ImGui::Indent();
const NavMeshType_e loadedNavMeshType = m_editor->getLoadedNavMeshType();
@ -416,16 +478,18 @@ void NavMeshTesterTool::handleMenu()
const bool noAnimtype = i == ANIMTYPE_NONE;
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex]; // todo(amos): crashes sometimes when animTypeIndex = ANIMTYPE_NONE
if (imguiCheck(animtypeName, m_traverseAnimType == animTypeIndex))
isEnabled = m_traverseAnimType == animTypeIndex;
if (ImGui::Checkbox(animtypeName, &isEnabled))
{
m_traverseAnimType = animTypeIndex;
}
}
imguiUnindent();
imguiSeparator();
ImGui::Unindent();
ImGui::Separator();
}
void NavMeshTesterTool::handleClick(const float* /*s*/, const float* p, bool shift)
@ -1358,12 +1422,14 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
if (m_sposSet && gluProject((GLdouble)m_spos[0], (GLdouble)m_spos[1], (GLdouble)m_spos[2],
model, proj, view, &x, &y, &z))
{
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
ImGui::TextColored(ImVec4(0,0,0,220), "Start");
}
if (m_eposSet && gluProject((GLdouble)m_epos[0], (GLdouble)m_epos[1], (GLdouble)m_epos[2],
model, proj, view, &x, &y, &z))
{
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "End", imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
ImGui::TextColored(ImVec4(0,0,0,220), "End");
}
// Useful utility to draw all polygroup id's at the center of the polygons.
@ -1393,7 +1459,7 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
// {
// char label[6];
// snprintf(label, sizeof(label), "%hu", poly->groupId);
// imguiDrawText((int)x, (int)y, IMGUI_ALIGN_CENTER, label, imguiRGBA(0, 0, 0, 220));
// ImGui::TextColored((int)x, (int)y, IMGUI_ALIGN_CENTER, label, ImVec4(0, 0, 0, 220));
// }
// }
// }
@ -1401,7 +1467,9 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
// Tool help
const int h = view[3];
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB+SHIFT: Set start location LMB: Set end location", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB+SHIFT: Set start location LMB: Set end location");
}
void NavMeshTesterTool::drawAgent(const float* pos, float r, float h, float c, const unsigned int col)

View File

@ -61,9 +61,14 @@ void OffMeshConnectionTool::reset()
void OffMeshConnectionTool::handleMenu()
{
if (imguiCheck("One Way", !m_bidir))
bool isOneWay = !m_bidir;
if (ImGui::Checkbox("One Way", &isOneWay))
m_bidir = false;
if (imguiCheck("Bidirectional", m_bidir))
bool isBiDirectional = m_bidir;
if (ImGui::Checkbox("Bidirectional", &isBiDirectional))
m_bidir = true;
}
@ -148,17 +153,20 @@ void OffMeshConnectionTool::handleRenderOverlay(double* proj, double* model, int
if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
model, proj, view, &x, &y, &z))
{
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220));
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
ImGui::TextColored(ImVec4(0,0,0,220), "Start");
}
// Tool help
const int h = view[3];
if (!m_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));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Create new connection. SHIFT+LMB: Delete existing connection, click close to start or end point.");
}
else
{
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Set connection end point and finish.", imguiRGBA(255,255,255,192));
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Set connection end point and finish.");
}
}

View File

@ -376,7 +376,7 @@ void TestCase::handleRender()
bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
char text[64], subtext[64];
char text[256];
int n = 0;
static const float LABEL_DIST = 1.0f;
@ -406,46 +406,46 @@ 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);
ImVec4 col = ImVec4(0,0,0,128);
if (iter->expand)
col = imguiRGBA(255,192,0,220);
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, text, col);
col = ImVec4(255,192,0,220);
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
ImGui::TextColored(col, "Path %d\n", n);
}
n++;
}
static int resScroll = 0;
bool mouseOverMenu = imguiBeginScrollArea("Test Results", 10, view[3] - 10 - 350, 200, 350, &resScroll);
// mouseOverMenu = true;
n = 0;
for (Test* iter = m_tests; iter; iter = iter->next)
if (ImGui::BeginChild("Test Results", ImVec2(200, 350)))
{
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))
iter->expand = !iter->expand;
if (iter->expand)
n = 0;
for (Test* iter = m_tests; iter; iter = iter->next)
{
snprintf(text, 64, "Poly: %.4f ms", (float)iter->findNearestPolyTime/1000.0f);
imguiValue(text);
const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
snprintf(text, sizeof(text), "Path %d %.4f ms", n, (float)total / 1000.0f);
snprintf(text, 64, "Path: %.4f ms", (float)iter->findPathTime/1000.0f);
imguiValue(text);
if (ImGui::CollapsingHeader(text))
{
iter->expand = true;
snprintf(text, 64, "Straight: %.4f ms", (float)iter->findStraightPathTime/1000.0f);
imguiValue(text);
imguiSeparator();
snprintf(text, sizeof(text), "Poly: %.4f ms", (float)iter->findNearestPolyTime / 1000.0f);
ImGui::Text(text);
snprintf(text, sizeof(text), "Path: %.4f ms", (float)iter->findPathTime / 1000.0f);
ImGui::Text(text);
snprintf(text, sizeof(text), "Straight: %.4f ms", (float)iter->findStraightPathTime / 1000.0f);
ImGui::Text(text);
ImGui::Separator();
}
else
iter->expand = false;
n++;
}
n++;
}
imguiEndScrollArea();
return mouseOverMenu;
ImGui::EndChild();
return true;
}

View File

@ -55,58 +55,85 @@ void GraphParams::setValueRange(float ivmin, float ivmax, int indiv, const char*
strcpy(units, iunits);
}
const static ImGuiWindowFlags s_graphWindowFlags = ImGuiWindowFlags_NoBackground|ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove;
void drawGraphBackground(const GraphParams* p)
{
ImGui::Begin("GraphBackGround", nullptr, s_graphWindowFlags);
ImDrawList* drawList = ImGui::GetWindowDrawList();
// BG
imguiDrawRoundedRect((float)p->x, (float)p->y, (float)p->w, (float)p->h, (float)p->pad, imguiRGBA(64,64,64,128));
const float sy = (p->h-p->pad*2) / (p->vmax-p->vmin);
const float oy = p->y+p->pad-p->vmin*sy;
drawList->AddRectFilled(
ImVec2(static_cast<float>(p->x), static_cast<float>(p->y)),
ImVec2(static_cast<float>(p->x + p->w), static_cast<float>(p->y + p->h)),
IM_COL32(64, 64, 64, 128), 0.0f);
const float sy = (p->h - p->pad * 2) / (p->vmax - p->vmin);
const float oy = p->y + p->pad - p->vmin * sy;
char text[64];
// Divider Lines
for (int i = 0; i <= p->ndiv; ++i)
{
const float u = (float)i/(float)p->ndiv;
const float v = p->vmin + (p->vmax-p->vmin)*u;
const float u = static_cast<float>(i) / static_cast<float>(p->ndiv);
const float v = p->vmin + (p->vmax - p->vmin) * u;
snprintf(text, 64, "%.2f %s", v, p->units);
const float fy = oy + v*sy;
imguiDrawText(p->x + p->w - p->pad, (int)fy-4, IMGUI_ALIGN_RIGHT, text, imguiRGBA(0,0,0,255));
imguiDrawLine((float)p->x + (float)p->pad, fy, (float)p->x + (float)p->w - (float)p->pad - 50, fy, 1.0f, imguiRGBA(0,0,0,64));
float fy = oy + v * sy;
drawList->AddText(
ImVec2(static_cast<float>(p->x + p->w - p->pad), fy - 4),
IM_COL32(0, 0, 0, 255), text);
drawList->AddLine(
ImVec2(static_cast<float>(p->x + p->pad), fy),
ImVec2(static_cast<float>(p->x + p->w - p->pad - 50), fy),
IM_COL32(0, 0, 0, 64), 1.0f);
}
ImGui::End();
}
void drawGraph(const GraphParams* p, const ValueHistory* graph,
int idx, const char* label, const unsigned int col)
int idx, const char* label, const unsigned int col)
{
const float sx = (p->w - p->pad*2) / (float)graph->getSampleCount();
const float sy = (p->h - p->pad*2) / (p->vmax - p->vmin);
const float ox = (float)p->x + (float)p->pad;
const float oy = (float)p->y + (float)p->pad - p->vmin*sy;
ImGui::Begin("Graph", nullptr, s_graphWindowFlags);
ImDrawList* drawList = ImGui::GetWindowDrawList();
const float sx = (p->w - p->pad * 2) / static_cast<float>(graph->getSampleCount());
const float sy = (p->h - p->pad * 2) / (p->vmax - p->vmin);
const float ox = static_cast<float>(p->x) + static_cast<float>(p->pad);
const float oy = static_cast<float>(p->y) + static_cast<float>(p->pad) - p->vmin * sy;
// Values
float px=0, py=0;
for (int i = 0; i < graph->getSampleCount()-1; ++i)
{
const float x = ox + i*sx;
const float y = oy + graph->getSample(i)*sy;
float px = 0, py = 0;
for (int i = 0; i < graph->getSampleCount() - 1; ++i) {
const float x = ox + i * sx;
const float y = oy + graph->getSample(i) * sy;
if (i > 0)
imguiDrawLine(px,py, x,y, 2.0f, col);
drawList->AddLine(
ImVec2(px, py), ImVec2(x, y), col, 2.0f);
px = x;
py = y;
}
// Label
const int size = 15;
const int spacing = 10;
int ix = p->x + p->w + 5;
int iy = p->y + p->h - (idx+1)*(size+spacing);
imguiDrawRoundedRect((float)ix, (float)iy, (float)size, (float)size, 2.0f, col);
int iy = p->y + p->h - (idx + 1) * (size + spacing);
drawList->AddRectFilled(
ImVec2(static_cast<float>(ix), static_cast<float>(iy)),
ImVec2(static_cast<float>(ix + size), static_cast<float>(iy + size)),
col);
char text[64];
snprintf(text, 64, "%.2f %s", graph->getAverage(), p->units);
imguiDrawText(ix+size+5, iy+3, IMGUI_ALIGN_LEFT, label, imguiRGBA(255,255,255,192));
imguiDrawText(ix+size+150, iy+3, IMGUI_ALIGN_RIGHT, text, imguiRGBA(255,255,255,128));
drawList->AddText(
ImVec2(static_cast<float>(ix + size + 5), static_cast<float>(iy + 3)),
IM_COL32(255, 255, 255, 192), label);
drawList->AddText(
ImVec2(static_cast<float>(ix + size + 150), static_cast<float>(iy + 3)),
IM_COL32(255, 255, 255, 128), text);
ImGui::End(); // Zijn toch die enge dinge mannn
}

View File

@ -1,672 +0,0 @@
//
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
#include "Pch.h"
#ifdef WIN32
# define snprintf _snprintf
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const unsigned TEXT_POOL_SIZE = 50000;
static char g_textPool[TEXT_POOL_SIZE];
static unsigned g_textPoolSize = 0;
static const char* allocText(const char* text)
{
unsigned len = static_cast<unsigned>(strlen(text)+1);
if (g_textPoolSize + len >= TEXT_POOL_SIZE)
return 0;
char* dst = &g_textPool[g_textPoolSize];
memcpy(dst, text, len);
g_textPoolSize += len;
return dst;
}
static const unsigned GFXCMD_QUEUE_SIZE = 5000;
static imguiGfxCmd g_gfxCmdQueue[GFXCMD_QUEUE_SIZE];
static unsigned g_gfxCmdQueueSize = 0;
static void resetGfxCmdQueue()
{
g_gfxCmdQueueSize = 0;
g_textPoolSize = 0;
}
static void addGfxCmdScissor(int x, int y, int w, int h)
{
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
return;
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
cmd.type = IMGUI_GFXCMD_SCISSOR;
cmd.flags = x < 0 ? 0 : 1; // on/off flag.
cmd.col = 0;
cmd.rect.x = (short)x;
cmd.rect.y = (short)y;
cmd.rect.w = (short)w;
cmd.rect.h = (short)h;
}
static void addGfxCmdRect(float x, float y, float w, float h, unsigned int color)
{
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
return;
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
cmd.type = IMGUI_GFXCMD_RECT;
cmd.flags = 0;
cmd.col = color;
cmd.rect.x = (short)(x*8.0f);
cmd.rect.y = (short)(y*8.0f);
cmd.rect.w = (short)(w*8.0f);
cmd.rect.h = (short)(h*8.0f);
cmd.rect.r = 0;
}
static void addGfxCmdLine(float x0, float y0, float x1, float y1, float r, unsigned int color)
{
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
return;
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
cmd.type = IMGUI_GFXCMD_LINE;
cmd.flags = 0;
cmd.col = color;
cmd.line.x0 = (short)(x0*8.0f);
cmd.line.y0 = (short)(y0*8.0f);
cmd.line.x1 = (short)(x1*8.0f);
cmd.line.y1 = (short)(y1*8.0f);
cmd.line.r = (short)(r*8.0f);
}
static void addGfxCmdRoundedRect(float x, float y, float w, float h, float r, unsigned int color)
{
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
return;
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
cmd.type = IMGUI_GFXCMD_RECT;
cmd.flags = 0;
cmd.col = color;
cmd.rect.x = (short)(x*8.0f);
cmd.rect.y = (short)(y*8.0f);
cmd.rect.w = (short)(w*8.0f);
cmd.rect.h = (short)(h*8.0f);
cmd.rect.r = (short)(r*8.0f);
}
static void addGfxCmdTriangle(int x, int y, int w, int h, int flags, unsigned int color)
{
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
return;
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
cmd.type = IMGUI_GFXCMD_TRIANGLE;
cmd.flags = (char)flags;
cmd.col = color;
cmd.rect.x = (short)(x*8.0f);
cmd.rect.y = (short)(y*8.0f);
cmd.rect.w = (short)(w*8.0f);
cmd.rect.h = (short)(h*8.0f);
}
static void addGfxCmdText(int x, int y, int align, const char* text, unsigned int color)
{
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
return;
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
cmd.type = IMGUI_GFXCMD_TEXT;
cmd.flags = 0;
cmd.col = color;
cmd.text.x = (short)x;
cmd.text.y = (short)y;
cmd.text.align = (short)align;
cmd.text.text = allocText(text);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct GuiState
{
GuiState() :
left(false), leftPressed(false), leftReleased(false),
mx(-1), my(-1), scroll(0),
active(0), hot(0), hotToBe(0), isHot(false), isActive(false), wentActive(false),
dragX(0), dragY(0), dragOrig(0), widgetX(0), widgetY(0), widgetW(100),
insideCurrentScroll(false), areaId(0), widgetId(0)
{
}
bool left;
bool leftPressed, leftReleased;
int mx,my;
int scroll;
unsigned int active;
unsigned int hot;
unsigned int hotToBe;
bool isHot;
bool isActive;
bool wentActive;
int dragX, dragY;
float dragOrig;
int widgetX, widgetY, widgetW;
bool insideCurrentScroll;
unsigned int areaId;
unsigned int widgetId;
};
static GuiState g_state;
inline bool anyActive()
{
return g_state.active != 0;
}
inline bool isActive(unsigned int id)
{
return g_state.active == id;
}
inline bool isHot(unsigned int id)
{
return g_state.hot == id;
}
inline bool inRect(int x, int y, int w, int h, bool checkScroll = true)
{
return (!checkScroll || g_state.insideCurrentScroll) && g_state.mx >= x && g_state.mx <= x+w && g_state.my >= y && g_state.my <= y+h;
}
inline void clearInput()
{
g_state.leftPressed = false;
g_state.leftReleased = false;
g_state.scroll = 0;
}
inline void clearActive()
{
g_state.active = 0;
// mark all UI for this frame as processed
clearInput();
}
inline void setActive(unsigned int id)
{
g_state.active = id;
g_state.wentActive = true;
}
inline void setHot(unsigned int id)
{
g_state.hotToBe = id;
}
static bool buttonLogic(unsigned int id, bool over)
{
bool res = false;
// process down
if (!anyActive())
{
if (over)
setHot(id);
if (isHot(id) && g_state.leftPressed)
setActive(id);
}
// if button is active, then react on left up
if (isActive(id))
{
g_state.isActive = true;
if (over)
setHot(id);
if (g_state.leftReleased)
{
if (isHot(id))
res = true;
clearActive();
}
}
if (isHot(id))
g_state.isHot = true;
return res;
}
static void updateInput(int mx, int my, unsigned char mbut, int scroll)
{
bool left = (mbut & IMGUI_MBUT_LEFT) != 0;
g_state.mx = mx;
g_state.my = my;
g_state.leftPressed = !g_state.left && left;
g_state.leftReleased = g_state.left && !left;
g_state.left = left;
g_state.scroll = scroll;
}
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll)
{
updateInput(mx,my,mbut,scroll);
g_state.hot = g_state.hotToBe;
g_state.hotToBe = 0;
g_state.wentActive = false;
g_state.isActive = false;
g_state.isHot = false;
g_state.widgetX = 0;
g_state.widgetY = 0;
g_state.widgetW = 0;
g_state.areaId = 1;
g_state.widgetId = 1;
resetGfxCmdQueue();
}
void imguiEndFrame()
{
clearInput();
}
const imguiGfxCmd* imguiGetRenderQueue()
{
return g_gfxCmdQueue;
}
int imguiGetRenderQueueSize()
{
return g_gfxCmdQueueSize;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const int BUTTON_HEIGHT = 20;
static const int SLIDER_HEIGHT = 20;
static const int SLIDER_MARKER_WIDTH = 10;
static const int CHECK_SIZE = 8;
static const int DEFAULT_SPACING = 4;
static const int TEXT_HEIGHT = 8;
static const int SCROLL_AREA_PADDING = 6;
static const int INDENT_SIZE = 16;
static const int AREA_HEADER = 28;
static int g_scrollTop = 0;
static int g_scrollBottom = 0;
static int g_scrollRight = 0;
static int g_scrollAreaTop = 0;
static int* g_scrollVal = 0;
static int g_focusTop = 0;
static int g_focusBottom = 0;
static unsigned int g_scrollId = 0;
static bool g_insideScrollArea = false;
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll)
{
g_state.areaId++;
g_state.widgetId = 0;
g_scrollId = (g_state.areaId<<16) | g_state.widgetId;
g_state.widgetX = x + SCROLL_AREA_PADDING;
g_state.widgetY = y+h-AREA_HEADER + (*scroll);
g_state.widgetW = w - SCROLL_AREA_PADDING*4;
g_scrollTop = y-AREA_HEADER+h;
g_scrollBottom = y+SCROLL_AREA_PADDING;
g_scrollRight = x+w - SCROLL_AREA_PADDING*3;
g_scrollVal = scroll;
g_scrollAreaTop = g_state.widgetY;
g_focusTop = y-AREA_HEADER;
g_focusBottom = y-AREA_HEADER+h;
g_insideScrollArea = inRect(x, y, w, h, false);
g_state.insideCurrentScroll = g_insideScrollArea;
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, imguiRGBA(0,0,0,192));
addGfxCmdText(x+AREA_HEADER/2, y+h-AREA_HEADER/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, name, imguiRGBA(255,255,255,128));
addGfxCmdScissor(x+SCROLL_AREA_PADDING, y+SCROLL_AREA_PADDING, w-SCROLL_AREA_PADDING*4, h-AREA_HEADER-SCROLL_AREA_PADDING);
return g_insideScrollArea;
}
void imguiEndScrollArea()
{
// Disable scissoring.
addGfxCmdScissor(-1,-1,-1,-1);
// Draw scroll bar
int x = g_scrollRight+SCROLL_AREA_PADDING/2;
int y = g_scrollBottom;
int w = SCROLL_AREA_PADDING*2;
int h = g_scrollTop - g_scrollBottom;
int stop = g_scrollAreaTop;
int sbot = g_state.widgetY;
int sh = stop - sbot; // The scrollable area height.
float barHeight = (float)h/(float)sh;
if (barHeight < 1)
{
float barY = (float)(y - sbot)/(float)sh;
if (barY < 0) barY = 0;
if (barY > 1) barY = 1;
// Handle scroll bar logic.
unsigned int hid = g_scrollId;
int hx = x;
int hy = y + (int)(barY*h);
int hw = w;
int hh = (int)(barHeight*h);
const int range = h - (hh-1);
bool over = inRect(hx, hy, hw, hh);
buttonLogic(hid, over);
if (isActive(hid))
{
float u = (float)(hy-y) / (float)range;
if (g_state.wentActive)
{
g_state.dragY = g_state.my;
g_state.dragOrig = u;
}
if (g_state.dragY != g_state.my)
{
u = g_state.dragOrig + (g_state.my - g_state.dragY) / (float)range;
if (u < 0) u = 0;
if (u > 1) u = 1;
*g_scrollVal = (int)((1-u) * (sh - h));
}
}
// BG
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)w/2-1, imguiRGBA(0,0,0,196));
// Bar
if (isActive(hid))
addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, imguiRGBA(255,196,0,196));
else
addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, isHot(hid) ? imguiRGBA(255,196,0,96) : imguiRGBA(255,255,255,64));
// Handle mouse scrolling.
if (g_insideScrollArea) // && !anyActive())
{
if (g_state.scroll)
{
*g_scrollVal += 120*g_state.scroll;
if (*g_scrollVal < 0) *g_scrollVal = 0;
if (*g_scrollVal > (sh - h)) *g_scrollVal = (sh - h);
}
}
}
g_state.insideCurrentScroll = false;
}
bool imguiButton(const char* text, bool enabled)
{
g_state.widgetId++;
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
int x = g_state.widgetX;
int y = g_state.widgetY - BUTTON_HEIGHT;
int w = g_state.widgetW;
int h = BUTTON_HEIGHT;
g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
bool over = enabled && inRect(x, y, w, h);
bool res = buttonLogic(id, over);
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)BUTTON_HEIGHT/2-1, imguiRGBA(128,128,128, isActive(id)?196:96));
if (enabled)
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
else
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
return res;
}
bool imguiItem(const char* text, bool enabled)
{
g_state.widgetId++;
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
int x = g_state.widgetX;
int y = g_state.widgetY - BUTTON_HEIGHT;
int w = g_state.widgetW;
int h = BUTTON_HEIGHT;
g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
bool over = enabled && inRect(x, y, w, h);
bool res = buttonLogic(id, over);
if (isHot(id))
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 2.0f, imguiRGBA(255,196,0,isActive(id)?196:96));
if (enabled)
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,200));
else
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
return res;
}
bool imguiCheck(const char* text, bool checked, bool enabled)
{
g_state.widgetId++;
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
int x = g_state.widgetX;
int y = g_state.widgetY - BUTTON_HEIGHT;
int w = g_state.widgetW;
int h = BUTTON_HEIGHT;
g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
bool over = enabled && inRect(x, y, w, h);
bool res = buttonLogic(id, over);
const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2;
const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2;
addGfxCmdRoundedRect((float)cx-3, (float)cy-3, (float)CHECK_SIZE+6, (float)CHECK_SIZE+6, 4, imguiRGBA(128,128,128, isActive(id)?196:96));
if (checked)
{
if (enabled)
addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(255,255,255,isActive(id)?255:200));
else
addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(128,128,128,200));
}
if (enabled)
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
else
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
return res;
}
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled)
{
g_state.widgetId++;
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
int x = g_state.widgetX;
int y = g_state.widgetY - BUTTON_HEIGHT;
int w = g_state.widgetW;
int h = BUTTON_HEIGHT;
g_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING;
const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2;
const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2;
bool over = enabled && inRect(x, y, w, h);
bool res = buttonLogic(id, over);
if (checked)
addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 2, imguiRGBA(255,255,255,isActive(id)?255:200));
else
addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 1, imguiRGBA(255,255,255,isActive(id)?255:200));
if (enabled)
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
else
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
if (subtext)
addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, subtext, imguiRGBA(255,255,255,128));
return res;
}
void imguiLabel(const char* text)
{
int x = g_state.widgetX;
int y = g_state.widgetY - BUTTON_HEIGHT;
g_state.widgetY -= BUTTON_HEIGHT;
addGfxCmdText(x, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,255));
}
void imguiValue(const char* text)
{
const int x = g_state.widgetX;
const int y = g_state.widgetY - BUTTON_HEIGHT;
const int w = g_state.widgetW;
g_state.widgetY -= BUTTON_HEIGHT;
addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, text, imguiRGBA(255,255,255,200));
}
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled)
{
g_state.widgetId++;
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
int x = g_state.widgetX;
int y = g_state.widgetY - BUTTON_HEIGHT;
int w = g_state.widgetW;
int h = SLIDER_HEIGHT;
g_state.widgetY -= SLIDER_HEIGHT + DEFAULT_SPACING;
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, imguiRGBA(0,0,0,128));
const int range = w - SLIDER_MARKER_WIDTH;
float u = (*val - vmin) / (vmax-vmin);
if (u < 0) u = 0;
if (u > 1) u = 1;
int m = (int)(u * range);
bool over = enabled && inRect(x+m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT);
bool res = buttonLogic(id, over);
bool valChanged = false;
if (isActive(id))
{
if (g_state.wentActive)
{
g_state.dragX = g_state.mx;
g_state.dragOrig = u;
}
if (g_state.dragX != g_state.mx)
{
u = g_state.dragOrig + (float)(g_state.mx - g_state.dragX) / (float)range;
if (u < 0) u = 0;
if (u > 1) u = 1;
*val = vmin + u*(vmax-vmin);
*val = floorf(*val/vinc+0.5f)*vinc; // Snap to vinc
m = (int)(u * range);
valChanged = true;
}
}
if (isActive(id))
addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, imguiRGBA(255,255,255,255));
else
addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? imguiRGBA(255,196,0,128) : imguiRGBA(255,255,255,64));
// TODO: fix this, take a look at 'nicenum'.
int digits = (int)(ceilf(log10f(vinc)));
char fmt[16];
snprintf(fmt, 16, "%%.%df", digits >= 0 ? 0 : -digits);
char msg[128];
snprintf(msg, 128, fmt, *val);
if (enabled)
{
addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
}
else
{
addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, imguiRGBA(128,128,128,200));
}
return res || valChanged;
}
void imguiIndent()
{
g_state.widgetX += INDENT_SIZE;
g_state.widgetW -= INDENT_SIZE;
}
void imguiUnindent()
{
g_state.widgetX -= INDENT_SIZE;
g_state.widgetW += INDENT_SIZE;
}
void imguiSeparator()
{
g_state.widgetY -= DEFAULT_SPACING*3;
}
void imguiSeparatorLine()
{
int x = g_state.widgetX;
int y = g_state.widgetY - DEFAULT_SPACING*2;
int w = g_state.widgetW;
int h = 1;
g_state.widgetY -= DEFAULT_SPACING*4;
addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255,255,255,32));
}
void imguiDrawText(int x, int y, int align, const char* text, unsigned int color)
{
addGfxCmdText(x, y, align, text, color);
}
void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color)
{
addGfxCmdLine(x0, y0, x1, y1, r, color);
}
void imguiDrawRect(float x, float y, float w, float h, unsigned int color)
{
addGfxCmdRect(x, y, w, h, color);
}
void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color)
{
addGfxCmdRoundedRect(x, y, w, h, r, color);
}

View File

@ -1,524 +0,0 @@
//
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
#include "Pch.h"
// Some math headers don't have PI defined.
static const float PI = 3.14159265f;
void imguifree(void* ptr, void* userptr);
void* imguimalloc(size_t size, void* userptr);
#define STBTT_malloc(x,y) imguimalloc(x,y)
#define STBTT_free(x,y) imguifree(x,y)
#define STB_TRUETYPE_IMPLEMENTATION
#include "thirdparty/imgui/imstb_truetype.h"
void imguifree(void* ptr, void* /*userptr*/)
{
free(ptr);
}
void* imguimalloc(size_t size, void* /*userptr*/)
{
return malloc(size);
}
static const unsigned TEMP_COORD_COUNT = 100;
static float g_tempCoords[TEMP_COORD_COUNT*2];
static float g_tempNormals[TEMP_COORD_COUNT*2];
static const int CIRCLE_VERTS = 8*4;
static float g_circleVerts[CIRCLE_VERTS*2];
static stbtt_bakedchar g_cdata[96]; // ASCII 32..126 is 95 glyphs
static GLuint g_ftex = 0;
inline unsigned int RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
return (r) | (g << 8) | (b << 16) | (a << 24);
}
static void drawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col)
{
if (numCoords > TEMP_COORD_COUNT) numCoords = TEMP_COORD_COUNT;
for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++)
{
const float* v0 = &coords[j*2];
const float* v1 = &coords[i*2];
float dx = v1[0] - v0[0];
float dy = v1[1] - v0[1];
float d = sqrtf(dx*dx+dy*dy);
if (d > 0)
{
d = 1.0f/d;
dx *= d;
dy *= d;
}
g_tempNormals[j*2+0] = dy;
g_tempNormals[j*2+1] = -dx;
}
for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++)
{
float dlx0 = g_tempNormals[j*2+0];
float dly0 = g_tempNormals[j*2+1];
float dlx1 = g_tempNormals[i*2+0];
float dly1 = g_tempNormals[i*2+1];
float dmx = (dlx0 + dlx1) * 0.5f;
float dmy = (dly0 + dly1) * 0.5f;
float dmr2 = dmx*dmx + dmy*dmy;
if (dmr2 > 0.000001f)
{
float scale = 1.0f / dmr2;
if (scale > 10.0f) scale = 10.0f;
dmx *= scale;
dmy *= scale;
}
g_tempCoords[i*2+0] = coords[i*2+0]+dmx*r;
g_tempCoords[i*2+1] = coords[i*2+1]+dmy*r;
}
unsigned int colTrans = RGBA(col&0xff, (col>>8)&0xff, (col>>16)&0xff, 0);
glBegin(GL_TRIANGLES);
glColor4ubv((GLubyte*)&col);
for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++)
{
glVertex2fv(&coords[i*2]);
glVertex2fv(&coords[j*2]);
glColor4ubv((GLubyte*)&colTrans);
glVertex2fv(&g_tempCoords[j*2]);
glVertex2fv(&g_tempCoords[j*2]);
glVertex2fv(&g_tempCoords[i*2]);
glColor4ubv((GLubyte*)&col);
glVertex2fv(&coords[i*2]);
}
glColor4ubv((GLubyte*)&col);
for (unsigned i = 2; i < numCoords; ++i)
{
glVertex2fv(&coords[0]);
glVertex2fv(&coords[(i-1)*2]);
glVertex2fv(&coords[i*2]);
}
glEnd();
}
static void drawRect(float x, float y, float w, float h, float fth, unsigned int col)
{
float verts[4*2] =
{
x+0.5f, y+0.5f,
x+w-0.5f, y+0.5f,
x+w-0.5f, y+h-0.5f,
x+0.5f, y+h-0.5f,
};
drawPolygon(verts, 4, fth, col);
}
/*
static void drawEllipse(float x, float y, float w, float h, float fth, unsigned int col)
{
float verts[CIRCLE_VERTS*2];
const float* cverts = g_circleVerts;
float* v = verts;
for (int i = 0; i < CIRCLE_VERTS; ++i)
{
*v++ = x + cverts[i*2]*w;
*v++ = y + cverts[i*2+1]*h;
}
drawPolygon(verts, CIRCLE_VERTS, fth, col);
}
*/
static void drawRoundedRect(float x, float y, float w, float h, float r, float fth, unsigned int col)
{
const unsigned n = CIRCLE_VERTS/4;
float verts[(n+1)*4*2];
const float* cverts = g_circleVerts;
float* v = verts;
for (unsigned i = 0; i <= n; ++i)
{
*v++ = x+w-r + cverts[i*2]*r;
*v++ = y+h-r + cverts[i*2+1]*r;
}
for (unsigned i = n; i <= n*2; ++i)
{
*v++ = x+r + cverts[i*2]*r;
*v++ = y+h-r + cverts[i*2+1]*r;
}
for (unsigned i = n*2; i <= n*3; ++i)
{
*v++ = x+r + cverts[i*2]*r;
*v++ = y+r + cverts[i*2+1]*r;
}
for (unsigned i = n*3; i < n*4; ++i)
{
*v++ = x+w-r + cverts[i*2]*r;
*v++ = y+r + cverts[i*2+1]*r;
}
*v++ = x+w-r + cverts[0]*r;
*v++ = y+r + cverts[1]*r;
drawPolygon(verts, (n+1)*4, fth, col);
}
static void drawLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col)
{
float dx = x1-x0;
float dy = y1-y0;
float d = sqrtf(dx*dx+dy*dy);
if (d > 0.0001f)
{
d = 1.0f/d;
dx *= d;
dy *= d;
}
float nx = dy;
float ny = -dx;
float verts[4*2];
r -= fth;
r *= 0.5f;
if (r < 0.01f) r = 0.01f;
dx *= r;
dy *= r;
nx *= r;
ny *= r;
verts[0] = x0-dx-nx;
verts[1] = y0-dy-ny;
verts[2] = x0-dx+nx;
verts[3] = y0-dy+ny;
verts[4] = x1+dx+nx;
verts[5] = y1+dy+ny;
verts[6] = x1+dx-nx;
verts[7] = y1+dy-ny;
drawPolygon(verts, 4, fth, col);
}
//bool imguiRenderGLInit(const char* fontpath)
//{
// for (int i = 0; i < CIRCLE_VERTS; ++i)
// {
// float a = (float)i/(float)CIRCLE_VERTS * PI*2;
// g_circleVerts[i*2+0] = cosf(a);
// g_circleVerts[i*2+1] = sinf(a);
// }
//
// // Load font.
// FILE* fp = fopen(fontpath, "rb");
// if (!fp) return false;
// if (fseek(fp, 0, SEEK_END) != 0)
// {
// fclose(fp);
// return false;
// }
// long size = ftell(fp);
// if (size < 0)
// {
// fclose(fp);
// return false;
// }
// if (fseek(fp, 0, SEEK_SET) != 0)
// {
// fclose(fp);
// return false;
// }
//
// unsigned char* ttfBuffer = (unsigned char*)malloc(size);
// if (!ttfBuffer)
// {
// fclose(fp);
// return false;
// }
//
// size_t readLen = fread(ttfBuffer, 1, size, fp);
// fclose(fp);
// if (readLen != static_cast<size_t>(size))
// {
// free(ttfBuffer);
// return false;
// }
//
// fp = 0;
//
// unsigned char* bmap = (unsigned char*)malloc(512*512);
// if (!bmap)
// {
// free(ttfBuffer);
// return false;
// }
//
// stbtt_BakeFontBitmap(ttfBuffer,0, 15.0f, bmap,512,512, 32,96, g_cdata);
//
// // can free ttf_buffer at this point
// glGenTextures(1, &g_ftex);
// glBindTexture(GL_TEXTURE_2D, g_ftex);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bmap);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//
// free(ttfBuffer);
// free(bmap);
//
// return true;
//}
bool imguiRenderGLInit(const unsigned int* ttfBuffer)
{
for (int i = 0; i < CIRCLE_VERTS; ++i)
{
float a = (float)i / (float)CIRCLE_VERTS * PI * 2;
g_circleVerts[i * 2 + 0] = cosf(a);
g_circleVerts[i * 2 + 1] = sinf(a);
}
unsigned char* bmap = (unsigned char*)malloc(512 * 512);
if (!bmap)
{
return false;
}
stbtt_BakeFontBitmap((unsigned char*)ttfBuffer, 0, 15.0f, bmap, 512, 512, 32, 96, g_cdata);
// can free ttf_buffer at this point
glGenTextures(1, &g_ftex);
glBindTexture(GL_TEXTURE_2D, g_ftex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bmap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
free(bmap);
return true;
}
void imguiRenderGLDestroy()
{
if (g_ftex)
{
glDeleteTextures(1, &g_ftex);
g_ftex = 0;
}
}
static void getBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index,
float *xpos, float *ypos, stbtt_aligned_quad *q)
{
stbtt_bakedchar *b = chardata + char_index;
int round_x = STBTT_ifloor(*xpos + b->xoff);
int round_y = STBTT_ifloor(*ypos - b->yoff);
q->x0 = (float)round_x;
q->y0 = (float)round_y;
q->x1 = (float)round_x + b->x1 - b->x0;
q->y1 = (float)round_y - b->y1 + b->y0;
q->s0 = b->x0 / (float)pw;
q->t0 = b->y0 / (float)pw;
q->s1 = b->x1 / (float)ph;
q->t1 = b->y1 / (float)ph;
*xpos += b->xadvance;
}
static const float g_tabStops[4] = {150, 210, 270, 330};
static float getTextLength(stbtt_bakedchar *chardata, const char* text)
{
float xpos = 0;
float len = 0;
while (*text)
{
int c = (unsigned char)*text;
if (c == '\t')
{
for (int i = 0; i < 4; ++i)
{
if (xpos < g_tabStops[i])
{
xpos = g_tabStops[i];
break;
}
}
}
else if (c >= 32 && c < 128)
{
stbtt_bakedchar *b = chardata + c-32;
int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5);
len = round_x + b->x1 - b->x0 + 0.5f;
xpos += b->xadvance;
}
++text;
}
return len;
}
static void drawText(float x, float y, const char *text, int align, unsigned int col)
{
if (!g_ftex) return;
if (!text) return;
if (align == IMGUI_ALIGN_CENTER)
x -= getTextLength(g_cdata, text)/2;
else if (align == IMGUI_ALIGN_RIGHT)
x -= getTextLength(g_cdata, text);
glColor4ub(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff);
glEnable(GL_TEXTURE_2D);
// assume orthographic projection with units = screen pixels, origin at top left
glBindTexture(GL_TEXTURE_2D, g_ftex);
glBegin(GL_TRIANGLES);
const float ox = x;
while (*text)
{
int c = (unsigned char)*text;
if (c == '\t')
{
for (int i = 0; i < 4; ++i)
{
if (x < g_tabStops[i]+ox)
{
x = g_tabStops[i]+ox;
break;
}
}
}
else if (c >= 32 && c < 128)
{
stbtt_aligned_quad q;
getBakedQuad(g_cdata, 512,512, c-32, &x,&y,&q);
glTexCoord2f(q.s0, q.t0);
glVertex2f(q.x0, q.y0);
glTexCoord2f(q.s1, q.t1);
glVertex2f(q.x1, q.y1);
glTexCoord2f(q.s1, q.t0);
glVertex2f(q.x1, q.y0);
glTexCoord2f(q.s0, q.t0);
glVertex2f(q.x0, q.y0);
glTexCoord2f(q.s0, q.t1);
glVertex2f(q.x0, q.y1);
glTexCoord2f(q.s1, q.t1);
glVertex2f(q.x1, q.y1);
}
++text;
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
void imguiRenderGLDraw()
{
const imguiGfxCmd* q = imguiGetRenderQueue();
int nq = imguiGetRenderQueueSize();
const float s = 1.0f/8.0f;
glDisable(GL_SCISSOR_TEST);
for (int i = 0; i < nq; ++i)
{
const imguiGfxCmd& cmd = q[i];
if (cmd.type == IMGUI_GFXCMD_RECT)
{
if (cmd.rect.r == 0)
{
drawRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f,
(float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1,
1.0f, cmd.col);
}
else
{
drawRoundedRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f,
(float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1,
(float)cmd.rect.r*s, 1.0f, cmd.col);
}
}
else if (cmd.type == IMGUI_GFXCMD_LINE)
{
drawLine(cmd.line.x0*s, cmd.line.y0*s, cmd.line.x1*s, cmd.line.y1*s, cmd.line.r*s, 1.0f, cmd.col);
}
else if (cmd.type == IMGUI_GFXCMD_TRIANGLE)
{
if (cmd.flags == 1)
{
const float verts[3*2] =
{
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f,
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s/2-0.5f,
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
};
drawPolygon(verts, 3, 1.0f, cmd.col);
}
if (cmd.flags == 2)
{
const float verts[3*2] =
{
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s/2-0.5f, (float)cmd.rect.y*s+0.5f,
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
};
drawPolygon(verts, 3, 1.0f, cmd.col);
}
}
else if (cmd.type == IMGUI_GFXCMD_TEXT)
{
drawText(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col);
}
else if (cmd.type == IMGUI_GFXCMD_SCISSOR)
{
if (cmd.flags)
{
glEnable(GL_SCISSOR_TEST);
glScissor(cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h);
}
else
{
glDisable(GL_SCISSOR_TEST);
}
}
}
glDisable(GL_SCISSOR_TEST);
}

View File

@ -31,7 +31,7 @@
struct CrowdToolParams
{
bool m_expandSelectedDebugDraw;
bool m_expandSelectedDebugDraw; // todo(amos): imgui upgrade; needed?
bool m_showCorners;
bool m_showCollisionSegments;
bool m_showPath;
@ -39,20 +39,20 @@ struct CrowdToolParams
bool m_showOpt;
bool m_showNeis;
bool m_expandDebugDraw;
bool m_expandDebugDraw; // todo(amos): imgui upgrade; needed?
bool m_showLabels;
bool m_showGrid;
bool m_showNodes;
bool m_showPerfGraph;
bool m_showDetailAll;
bool m_expandOptions;
bool m_expandTraversalOptions;
bool m_expandOptions; // todo(amos): imgui upgrade; needed?
bool m_expandTraversalOptions; // todo(amos): imgui upgrade; needed?
bool m_anticipateTurns;
bool m_optimizeVis;
bool m_optimizeTopo;
bool m_obstacleAvoidance;
float m_obstacleAvoidanceType;
int m_obstacleAvoidanceType;
bool m_separation;
float m_separationWeight;

View File

@ -30,7 +30,7 @@ struct hulldef
float radius;
float height;
float climbHeight;
float tileSize;
int tileSize;
};
extern const hulldef hulls[5];
@ -126,11 +126,11 @@ protected:
float m_agentRadius;
float m_agentMaxClimb;
float m_agentMaxSlope;
float m_regionMinSize;
float m_regionMergeSize;
float m_edgeMaxLen;
int m_regionMinSize;
int m_regionMergeSize;
int m_edgeMaxLen;
float m_edgeMaxError;
float m_vertsPerPoly;
int m_vertsPerPoly;
float m_detailSampleDist;
float m_detailSampleMaxError;
int m_partitionType;

View File

@ -66,7 +66,7 @@ protected:
int m_maxTiles;
int m_maxPolysPerTile;
float m_tileSize;
int m_tileSize;
unsigned int m_tileCol;
float m_lastBuiltTileBmin[3];

View File

@ -47,15 +47,15 @@ struct BuildSettings
float agentMaxSlope;
// Region minimum size in voxels.
// regionMinSize = sqrt(regionMinArea)
float regionMinSize;
int regionMinSize;
// Region merge size in voxels.
// regionMergeSize = sqrt(regionMergeArea)
float regionMergeSize;
int regionMergeSize;
// Edge max length in world units
float edgeMaxLen;
int edgeMaxLen;
// Edge max error in voxels
float edgeMaxError;
float vertsPerPoly;
int vertsPerPoly;
// Detail sample distance in voxels
float detailSampleDist;
// Detail sample max error in voxel heights.
@ -66,7 +66,7 @@ struct BuildSettings
float navMeshBMin[3];
float navMeshBMax[3];
// Size of the tiles in voxels
float tileSize;
int tileSize;
};
class InputGeom

View File

@ -1,108 +0,0 @@
//
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
#ifndef IMGUI_H
#define IMGUI_H
enum imguiMouseButton
{
IMGUI_MBUT_LEFT = 0x01,
IMGUI_MBUT_RIGHT = 0x02,
};
enum imguiTextAlign
{
IMGUI_ALIGN_LEFT,
IMGUI_ALIGN_CENTER,
IMGUI_ALIGN_RIGHT,
};
inline unsigned int imguiRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255)
{
return (r) | (g << 8) | (b << 16) | (a << 24);
}
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll);
void imguiEndFrame();
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll);
void imguiEndScrollArea();
void imguiIndent();
void imguiUnindent();
void imguiSeparator();
void imguiSeparatorLine();
bool imguiButton(const char* text, bool enabled = true);
bool imguiItem(const char* text, bool enabled = true);
bool imguiCheck(const char* text, bool checked, bool enabled = true);
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled = true);
void imguiLabel(const char* text);
void imguiValue(const char* text);
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled = true);
void imguiDrawText(int x, int y, int align, const char* text, unsigned int color);
void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color);
void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color);
void imguiDrawRect(float x, float y, float w, float h, unsigned int color);
// Pull render interface.
enum imguiGfxCmdType
{
IMGUI_GFXCMD_RECT,
IMGUI_GFXCMD_TRIANGLE,
IMGUI_GFXCMD_LINE,
IMGUI_GFXCMD_TEXT,
IMGUI_GFXCMD_SCISSOR,
};
struct imguiGfxRect
{
short x,y,w,h,r;
};
struct imguiGfxText
{
short x,y,align;
const char* text;
};
struct imguiGfxLine
{
short x0,y0,x1,y1,r;
};
struct imguiGfxCmd
{
char type;
char flags;
char pad[2];
unsigned int col;
union
{
imguiGfxLine line;
imguiGfxRect rect;
imguiGfxText text;
};
};
const imguiGfxCmd* imguiGetRenderQueue();
int imguiGetRenderQueueSize();
#endif // IMGUI_H

View File

@ -1,26 +0,0 @@
//
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
#ifndef IMGUI_RENDER_GL_H
#define IMGUI_RENDER_GL_H
bool imguiRenderGLInit(const unsigned int* ttfBuffer);
void imguiRenderGLDestroy();
void imguiRenderGLDraw();
#endif // IMGUI_RENDER_GL_H

View File

@ -172,6 +172,45 @@ void update_camera(const float* bmin, const float* bmax,float* cameraPos,float*
glFogf(GL_FOG_END, camr * 1.25f);
}
bool imgui_init(SDL_Window* window, SDL_Renderer* /*renderer*/, SDL_GLContext context)
{
IMGUI_CHECKVERSION();
ImGuiContext* const imguiContext = ImGui::CreateContext();
if (!imguiContext)
return false;
// todo(amos): check if this is required.
//imguiContext->ConfigNavWindowingKeyNext = 0;
//imguiContext->ConfigNavWindowingKeyPrev = 0;
// todo(amos): check if this is required.
//ImGuiIO& io = ImGui::GetIO();
//io.ConfigFlags |= ImGuiConfigFlags_IsSRGB;
ImGui::StyleColorsDark();
if (!ImGui_ImplSDL2_InitForOpenGL(window, context))
{
return false;
}
if (!ImGui_ImplOpenGL2_Init())
{
return false;
}
return true;
}
void imgui_shutdown()
{
ImGui_ImplOpenGL2_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
}
bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &height, bool presentationMode)
{
// Init SDL
@ -224,9 +263,9 @@ bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &hei
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_GL_CreateContext(window);
SDL_GLContext context = SDL_GL_CreateContext(window);
if (!imguiRenderGLInit(droidsans_data))
if (!imgui_init(window, renderer, context))
{
printf("Could not initialise GUI renderer.\n");
SDL_Quit();
@ -470,9 +509,7 @@ int not_main(int argc, char** argv)
bool showTestCases = false;
// Window scroll positions.
int propScroll = 0;
int logScroll = 0;
int toolsScroll = 0;
//int propScroll = 0;
float t = 0.0f;
float timeAcc = 0.0f;
@ -492,6 +529,8 @@ int not_main(int argc, char** argv)
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
switch (event.type)
{
case SDL_KEYDOWN:
@ -630,12 +669,6 @@ int not_main(int argc, char** argv)
break;
}
}
unsigned char mouseButtonMask = 0;
if (SDL_GetMouseState(0, 0) & SDL_BUTTON_LMASK)
mouseButtonMask |= IMGUI_MBUT_LEFT;
if (SDL_GetMouseState(0, 0) & SDL_BUTTON_RMASK)
mouseButtonMask |= IMGUI_MBUT_RIGHT;
Uint32 time = SDL_GetTicks();
float dt = (time - prevFrameTime) / 1000.0f;
@ -796,9 +829,15 @@ int not_main(int argc, char** argv)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
mouseOverMenu = false;
ImGuiIO& io = ImGui::GetIO();
mouseOverMenu = io.WantCaptureMouse;
imguiBeginFrame(mousePos[0], mousePos[1], mouseButtonMask, mouseScroll);
ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();
//imguiBeginFrame(mousePos[0], mousePos[1], mouseButtonMask, mouseScroll);
if (editor)
{
@ -807,117 +846,119 @@ int not_main(int argc, char** argv)
}
if (test)
{
if (test->handleRenderOverlay(reinterpret_cast<double*>(projectionMatrix), reinterpret_cast<double*>(modelviewMatrix), reinterpret_cast<int*>(viewport)))
mouseOverMenu = true;
test->handleRenderOverlay(reinterpret_cast<double*>(projectionMatrix), reinterpret_cast<double*>(modelviewMatrix), reinterpret_cast<int*>(viewport));
}
// Help text.
if (showMenu)
{
const char msg[] = "W/S/A/D: Move RMB: Rotate";
imguiDrawText(280, height-20, IMGUI_ALIGN_LEFT, msg, imguiRGBA(255,255,255,128));
// todo(amos): imgui
//ImGui::SetCursorPos(ImVec2(280, (float)height-20));
ImGui::TextColored(ImVec4(255,255,255,128), "W/S/A/D: Move RMB: Rotate", ImVec4(255,255,255,128));
}
string geom_path;
const ImGuiWindowFlags baseWindowFlags = ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
if (showMenu)
{
if (imguiBeginScrollArea("Properties", width-250-10, 10, 250, height-20, &propScroll))
mouseOverMenu = true;
ImGui::SetNextWindowPos(ImVec2((float)width-250-10, 10.f));
ImGui::SetNextWindowSize(ImVec2(250, (float)height-20));
if (imguiCheck("Show Log", showLog))
showLog = !showLog;
if (imguiCheck("Show Tools", showTools))
showTools = !showTools;
imguiSeparator();
imguiLabel("Input Level");
if (imguiButton("Load Level..."))
if (ImGui::Begin("Properties", nullptr, baseWindowFlags))
{
char szFile[260];
OPENFILENAMEA diag = { 0 };
diag.lStructSize = sizeof(diag);
ImGui::Checkbox("Show Log", &showLog);
ImGui::Checkbox("Show Tools", &showTools);
SDL_SysWMinfo sdlinfo;
SDL_version sdlver;
SDL_VERSION(&sdlver);
sdlinfo.version = sdlver;
SDL_GetWindowWMInfo(window, &sdlinfo);
ImGui::Separator();
ImGui::Text("Input Level");
diag.hwndOwner = sdlinfo.info.win.window;
diag.lpstrFile = szFile;
diag.lpstrFile[0] = 0;
diag.nMaxFile = sizeof(szFile);
diag.lpstrFilter = "OBJ\0*.obj\0Ply\0*.ply\0All\0*.*\0"; //TODO: BSP\0*.bsp\0
diag.nFilterIndex = 1;
diag.lpstrFileTitle = NULL;
diag.nMaxFileTitle = 0;
diag.lpstrInitialDir = NULL;
diag.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(&diag))
if (ImGui::Button("Load Level..."))
{
geom_path = std::string(szFile);
meshName = geom_path.substr(geom_path.rfind("\\")+1);
}
}
if (imguiButton(meshName.c_str()))
{
if (showLevels)
{
showLevels = false;
}
else
{
showEditor = false;
showTestCases = false;
showLevels = true;
scanDirectory(meshesFolder, ".obj", files);
scanDirectoryAppend(meshesFolder, ".gset", files);
scanDirectoryAppend(meshesFolder, ".ply", files);
}
}
if (geom)
{
char text[64];
snprintf(text, 64, "Verts: %.1fk Tris: %.1fk",
geom->getMesh()->getVertCount()/1000.0f,
geom->getMesh()->getTriCount()/1000.0f);
imguiValue(text);
}
imguiSeparator();
char szFile[260];
OPENFILENAMEA diag = { 0 };
diag.lStructSize = sizeof(diag);
if (geom && editor)
{
imguiSeparatorLine();
editor->handleSettings();
SDL_SysWMinfo sdlinfo;
SDL_version sdlver;
SDL_VERSION(&sdlver);
sdlinfo.version = sdlver;
SDL_GetWindowWMInfo(window, &sdlinfo);
if (imguiButton("Build"))
{
ctx.resetLog();
if (!editor->handleBuild())
diag.hwndOwner = sdlinfo.info.win.window;
diag.lpstrFile = szFile;
diag.lpstrFile[0] = 0;
diag.nMaxFile = sizeof(szFile);
diag.lpstrFilter = "OBJ\0*.obj\0Ply\0*.ply\0All\0*.*\0"; //TODO: BSP\0*.bsp\0
diag.nFilterIndex = 1;
diag.lpstrFileTitle = NULL;
diag.nMaxFileTitle = 0;
diag.lpstrInitialDir = NULL;
diag.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(&diag))
{
showLog = true;
logScroll = 0;
geom_path = std::string(szFile);
meshName = geom_path.substr(geom_path.rfind("\\") + 1);
}
ctx.dumpLog("Build log %s:", meshName.c_str());
// Clear test.
delete test;
test = 0;
}
if (ImGui::Button(meshName.c_str()))
{
if (showLevels)
{
showLevels = false;
}
else
{
showEditor = false;
showTestCases = false;
showLevels = true;
scanDirectory(meshesFolder, ".obj", files);
scanDirectoryAppend(meshesFolder, ".gset", files);
scanDirectoryAppend(meshesFolder, ".ply", files);
}
}
if (geom)
{
char text[64];
snprintf(text, 64, "Verts: %.1fk Tris: %.1fk",
geom->getMesh()->getVertCount() / 1000.0f,
geom->getMesh()->getTriCount() / 1000.0f);
ImGui::Text(text);
}
ImGui::Separator();
if (geom && editor)
{
ImGui::Separator(); // was imguiSeperatorLine
editor->handleSettings();
if (ImGui::Button("Build"))
{
ctx.resetLog();
if (!editor->handleBuild())
{
showLog = true;
}
ctx.dumpLog("Build log %s:", meshName.c_str());
// Clear test.
delete test;
test = 0;
}
ImGui::Separator();
}
imguiSeparator();
if (editor)
{
ImGui::Separator(); // was imguiSeperatorLine
editor->handleDebugMode();
}
}
if (editor)
{
imguiSeparatorLine();
editor->handleDebugMode();
}
imguiEndScrollArea();
ImGui::End();
}
// Editor selection dialog.
@ -937,40 +978,41 @@ int not_main(int argc, char** argv)
update_camera(bmin, bmax, cameraPos, cameraEulers, camr);
}
imguiEndScrollArea();
//ImGui::EndChild();
}
// Level selection dialog.
if (showLevels)
{
static int levelScroll = 0;
if (imguiBeginScrollArea("Choose Level", width - 10 - 250 - 10 - 200, height - 10 - 450, 200, 450, &levelScroll))
mouseOverMenu = true;
vector<string>::const_iterator fileIter = files.begin();
vector<string>::const_iterator filesEnd = files.end();
vector<string>::const_iterator levelToLoad = filesEnd;
for (; fileIter != filesEnd; ++fileIter)
ImGui::SetNextWindowPos(ImVec2((float)width-10-250-10-200, (float)height-10-900));
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f));
if (ImGui::Begin("Choose Level", nullptr, baseWindowFlags))
{
if (imguiItem(fileIter->c_str()))
vector<string>::const_iterator fileIter = files.begin();
vector<string>::const_iterator filesEnd = files.end();
vector<string>::const_iterator levelToLoad = filesEnd;
for (; fileIter != filesEnd; ++fileIter)
{
levelToLoad = fileIter;
// was imguiItem
if (ImGui::MenuItem(fileIter->c_str()))
{
levelToLoad = fileIter;
}
}
if (levelToLoad != filesEnd)
{
meshName = *levelToLoad;
showLevels = false;
delete geom;
geom = 0;
geom_path = meshesFolder + "/" + meshName;
}
}
if (levelToLoad != filesEnd)
{
meshName = *levelToLoad;
showLevels = false;
delete geom;
geom = 0;
geom_path= meshesFolder + "/" + meshName;
}
imguiEndScrollArea();
ImGui::End();
}
if (!geom_path.empty())
{
@ -988,7 +1030,6 @@ int not_main(int argc, char** argv)
}
showLog = true;
logScroll = 0;
ctx.dumpLog("Geom load log %s:", meshName.c_str());
}
if (editor && geom)
@ -1013,117 +1054,126 @@ int not_main(int argc, char** argv)
// Test cases
if (showTestCases)
{
static int testScroll = 0;
if (imguiBeginScrollArea("Choose Test To Run", width-10-250-10-200, height-10-450, 200, 450, &testScroll))
mouseOverMenu = true;
ImGui::SetNextWindowPos(ImVec2((float)width-10-250-10-200, (float)height-10-900));
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f));
vector<string>::const_iterator fileIter = files.begin();
vector<string>::const_iterator filesEnd = files.end();
vector<string>::const_iterator testToLoad = filesEnd;
for (; fileIter != filesEnd; ++fileIter)
if (ImGui::Begin("Choose Test To Run", nullptr, baseWindowFlags))
{
if (imguiItem(fileIter->c_str()))
vector<string>::const_iterator fileIter = files.begin();
vector<string>::const_iterator filesEnd = files.end();
vector<string>::const_iterator testToLoad = filesEnd;
for (; fileIter != filesEnd; ++fileIter)
{
testToLoad = fileIter;
if (ImGui::MenuItem(fileIter->c_str()))
{
testToLoad = fileIter;
}
}
if (testToLoad != filesEnd)
{
string path = testCasesFolder + "/" + *testToLoad;
test = new TestCase;
if (test)
{
// Load the test.
if (!test->load(path))
{
delete test;
test = 0;
}
if (editor)
{
editor->setContext(&ctx);
showEditor = false;
}
// Load geom.
meshName = test->getGeomFileName();
path = meshesFolder + "/" + meshName;
delete geom;
geom = new InputGeom;
if (!geom || !geom->load(&ctx, path))
{
delete geom;
geom = 0;
delete editor;
editor = 0;
showLog = true;
ctx.dumpLog("Geom load log %s:", meshName.c_str());
}
if (editor && geom)
{
editor->handleMeshChanged(geom);
get_model_name(meshName, editor->m_modelName);
}
// This will ensure that tile & poly bits are updated in tiled editor.
if (editor)
editor->handleSettings();
ctx.resetLog();
if (editor && !editor->handleBuild())
{
ctx.dumpLog("Build log %s:", meshName.c_str());
}
if (geom || editor)
{
const float* bmin = 0;
const float* bmax = 0;
if (geom)
{
bmin = geom->getNavMeshBoundsMin();
bmax = geom->getNavMeshBoundsMax();
}
// Reset camera and fog to match the mesh bounds.
update_camera(bmin, bmax, cameraPos, cameraEulers, camr);
}
// Do the tests.
if (editor)
test->doTests(editor->getNavMesh(), editor->getNavMeshQuery());
}
}
}
if (testToLoad != filesEnd)
{
string path = testCasesFolder + "/" + *testToLoad;
test = new TestCase;
if (test)
{
// Load the test.
if (!test->load(path))
{
delete test;
test = 0;
}
if (editor)
{
editor->setContext(&ctx);
showEditor = false;
}
// Load geom.
meshName = test->getGeomFileName();
path = meshesFolder + "/" + meshName;
delete geom;
geom = new InputGeom;
if (!geom || !geom->load(&ctx, path))
{
delete geom;
geom = 0;
delete editor;
editor = 0;
showLog = true;
logScroll = 0;
ctx.dumpLog("Geom load log %s:", meshName.c_str());
}
if (editor && geom)
{
editor->handleMeshChanged(geom);
get_model_name(meshName, editor->m_modelName);
}
// This will ensure that tile & poly bits are updated in tiled editor.
if (editor)
editor->handleSettings();
ctx.resetLog();
if (editor && !editor->handleBuild())
{
ctx.dumpLog("Build log %s:", meshName.c_str());
}
if (geom || editor)
{
const float* bmin = 0;
const float* bmax = 0;
if (geom)
{
bmin = geom->getNavMeshBoundsMin();
bmax = geom->getNavMeshBoundsMax();
}
// Reset camera and fog to match the mesh bounds.
update_camera(bmin, bmax, cameraPos, cameraEulers, camr);
}
// Do the tests.
if (editor)
test->doTests(editor->getNavMesh(), editor->getNavMeshQuery());
}
}
imguiEndScrollArea();
ImGui::End();
}
// Log
if (showLog && showMenu)
{
if (imguiBeginScrollArea("Log", 250 + 20, 10, width - 300 - 250, 200, &logScroll))
mouseOverMenu = true;
for (int i = 0; i < ctx.getLogCount(); ++i)
imguiLabel(ctx.getLogText(i));
imguiEndScrollArea();
ImGui::SetNextWindowPos(ImVec2((float)250+20, 10.f));
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f));
if (ImGui::Begin("Log"))
{
for (int i = 0; i < ctx.getLogCount(); ++i)
ImGui::Text(ctx.getLogText(i));
}
ImGui::End();
}
// Left column tools menu
if (!showTestCases && showTools && showMenu) // && geom && editor)
{
if (imguiBeginScrollArea("Tools", 10, 10, 250, height - 20, &toolsScroll))
mouseOverMenu = true;
ImGui::SetNextWindowPos(ImVec2(10.f, 10.f));
ImGui::SetNextWindowSize(ImVec2(250, (float)height-20));
if (editor)
editor->handleTools();
if (ImGui::Begin("Tools", nullptr, baseWindowFlags))
{
if (editor)
editor->handleTools();
}
imguiEndScrollArea();
ImGui::End();
}
// Marker
@ -1147,16 +1197,16 @@ int not_main(int argc, char** argv)
glLineWidth(1.0f);
}
imguiEndFrame();
imguiRenderGLDraw();
ImGui::EndFrame();
ImGui::Render();
glEnable(GL_DEPTH_TEST);
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
}
imguiRenderGLDestroy();
imgui_shutdown();
SDL_Quit();
delete editor;

View File

@ -51,8 +51,13 @@
# include <cstring>
#endif
#include "NavEditor/Include/imgui.h"
#include "NavEditor/Include/imguiRenderGL.h"
// todo(amos): we need to make a new PCH dedicated for the recast editor and
// move the SDL2 and ImGui includes there!
#include "thirdparty/imgui/imgui.h"
#include "thirdparty/imgui/imgui_internal.h"
#include "thirdparty/imgui/misc/imgui_plotter.h"
#include "thirdparty/imgui/backends/imgui_impl_sdl2.h"
#include "thirdparty/imgui/backends/imgui_impl_opengl2.h"
// SDK types
#include "tier0/basetypes.h"