Merge pull request #122 from Mauler125/recast_imgui_upgrade

Recast NavMesh editor ImGui upgrade
This commit is contained in:
Kawe Mazidjatari 2024-07-09 20:19:26 +02:00 committed by GitHub
commit 2f9908928c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 1256 additions and 2253 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,49 @@ 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::PushItemWidth(120.f);
imguiSeparator();
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);
imguiLabel("Area Type");
imguiIndent();
if (imguiCheck("Ground", m_areaType == EDITOR_POLYAREA_GROUND))
ImGui::PopItemWidth();
ImGui::Separator();
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;
@ -276,18 +294,17 @@ void ConvexVolumeTool::handleRender()
dd.end();
}
void ConvexVolumeTool::handleRenderOverlay(double* /*proj*/, double* /*model*/, int* view)
void ConvexVolumeTool::handleRenderOverlay(double* /*proj*/, double* /*model*/, int* /*view*/)
{
// Tool help
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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, 40), ImVec4(1.0f,1.0f,1.0f,0.75f), "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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, 60), ImVec4(1.0f,1.0f,1.0f,0.75f), "The shape will be convex hull of all added points.");
}
}

View File

@ -85,28 +85,25 @@ CrowdToolState::CrowdToolState() :
m_nav(0),
m_crowd(0),
m_targetRef(0),
m_graphSampleTime(0.0f),
m_run(true)
{
m_toolParams.m_expandSelectedDebugDraw = true;
m_toolParams.m_showCorners = false;
m_toolParams.m_showCollisionSegments = false;
m_toolParams.m_showPath = false;
m_toolParams.m_showVO = false;
m_toolParams.m_showOpt = false;
m_toolParams.m_showNeis = false;
m_toolParams.m_expandDebugDraw = false;
m_toolParams.m_showLabels = false;
m_toolParams.m_showGrid = false;
m_toolParams.m_showNodes = false;
m_toolParams.m_showPerfGraph = false;
m_toolParams.m_showDetailAll = false;
m_toolParams.m_expandOptions = true;
m_toolParams.m_expandTraversalOptions = false;
m_toolParams.m_anticipateTurns = true;
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,20 +505,25 @@ void CrowdToolState::handleRender()
dd.depthMask(true);
}
namespace ImPlot
{
extern void Demo_ShadedPlots();
};
void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
const int windowHeight = view[3];
// Draw start and end point labels
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_RenderText(ImGuiTextAlign_e::kAlignCenter,
ImVec2((float)x, windowHeight-((float)y+25)), ImVec4(0,0,0,0.8f), "TARGET");
}
char label[32];
if (m_toolParams.m_showNodes)
{
dtCrowd* crowd = m_editor->getCrowd();
@ -543,8 +545,8 @@ 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_RenderText(ImGuiTextAlign_e::kAlignCenter,
ImVec2((float)x, windowHeight-((float)y+25)), ImVec4(0,0,0,0.8f), "%.2f", heuristic);
}
}
}
@ -571,10 +573,10 @@ 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_RenderText(ImGuiTextAlign_e::kAlignCenter,
ImVec2((float)x, windowHeight-((float)y+15)), ImVec4(0,0,0,0.8f), "%s (%d)", animTypeName, i);
}
}
}
}
}
if (m_agentDebug.idx != -1)
@ -600,8 +602,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_RenderText(ImGuiTextAlign_e::kAlignCenter,
ImVec2((float)x, windowHeight-((float)y+15)), ImVec4(1.0f,1.0f,1.0f,0.8f), "%.3f", ag->neis[j].dist);
}
}
}
@ -609,21 +611,53 @@ 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));
static const ImPlotAxisFlags flags = ImPlotFlags_None;
ImVec2* totalSample = m_crowdTotalTime.getSampleBuffer();
ImVec2* crowdSample = m_crowdSampleCount.getSampleBuffer();
ImGui::SetNextWindowPos(ImVec2(250.f+30.f, 10.f), ImGuiCond_Once);
ImGui::SetNextWindowSizeConstraints(ImVec2(420, 200), ImVec2(FLT_MAX, FLT_MAX));
if (ImGui::Begin("Graph", nullptr))
{
static const float history = 4.0f;
ImVec2 windowSize = ImGui::GetWindowSize();
if (ImPlot::BeginPlot("##GraphPlotter", ImVec2(windowSize.x-16.f, windowSize.y-52.f)))
{
ImPlot::SetupAxes(nullptr, nullptr, flags, flags);
ImPlot::SetupAxisLimits(ImAxis_X1, m_graphSampleTime - history, m_graphSampleTime, ImGuiCond_Always);
ImPlot::SetupAxisLimits(ImAxis_Y1, 0, 2);
ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.5f);
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f);
ImPlot::PlotShaded("Total Time", &totalSample[0].x, &totalSample[0].y, m_crowdTotalTime.getSampleCount(), -INFINITY, 0, m_crowdTotalTime.getSampleOffset(), 2 * sizeof(float));
ImPlot::PlotShaded("Sample Count", &crowdSample[0].x, &crowdSample[0].y, m_crowdSampleCount.getSampleCount(), -INFINITY, 0, m_crowdSampleCount.getSampleOffset(), 2 * sizeof(float));
ImPlot::PopStyleVar();
ImPlot::PlotLine("Total Time", &totalSample[0].x, &totalSample[0].y, m_crowdTotalTime.getSampleCount(), 0, m_crowdTotalTime.getSampleOffset(), 2 * sizeof(float));
ImPlot::PlotLine("Sample Count", &crowdSample[0].x, &crowdSample[0].y, m_crowdSampleCount.getSampleCount(), 0, m_crowdSampleCount.getSampleOffset(), 2 * sizeof(float));
ImPlot::EndPlot();
char labelBuffer[256];
snprintf(labelBuffer, sizeof(labelBuffer), "Total Time (avg %.2f ms).", m_crowdTotalTime.getAverage());
ImGui::Text(labelBuffer);
ImGui::SameLine();
snprintf(labelBuffer, sizeof(labelBuffer), "Sample Count (avg %.2f).", m_crowdSampleCount.getAverage());
ImGui::Text(labelBuffer);
ImGui::SameLine();
}
}
ImGui::End();
}
}
void CrowdToolState::handleUpdate(const float dt)
@ -849,8 +883,11 @@ void CrowdToolState::updateTick(const float dt)
m_agentDebug.vod->normalizeSamples();
m_crowdSampleCount.addSample((float)crowd->getVelocitySampleCount());
m_crowdTotalTime.addSample(getPerfTimeUsec(endTime - startTime) / 1000.0f);
m_graphSampleTime += ImGui::GetIO().DeltaTime;
m_crowdSampleCount.addSample(m_graphSampleTime, (float)crowd->getVelocitySampleCount());
m_crowdTotalTime.addSample(m_graphSampleTime, getPerfTimeUsec(endTime - startTime) / 1000.0f);
}
@ -892,81 +929,73 @@ 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();
if (params->m_expandOptions)
if (ImGui::CollapsingHeader("Options"))
{
imguiIndent();
if (imguiCheck("Optimize Visibility", params->m_optimizeVis))
{
params->m_optimizeVis = !params->m_optimizeVis;
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))
ImGui::PushItemWidth(90.f);
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::PopItemWidth();
}
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();
// 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);
for (int i = ANIMTYPE_NONE; i < traverseTableCount; i++)
{
@ -975,54 +1004,33 @@ void CrowdTool::handleMenu()
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))
bool isAnimTypeEnabled = params->m_traverseAnimType == animTypeIndex;
if (ImGui::Checkbox(animtypeName, &isAnimTypeEnabled))
{
params->m_traverseAnimType = animTypeIndex;
m_state->updateAgentParams();
}
}
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"))
{
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::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);
}
if (imguiCollapse("Debug Draw", 0, params->m_expandDebugDraw))
params->m_expandDebugDraw = !params->m_expandDebugDraw;
if (params->m_expandDebugDraw)
if (ImGui::CollapsingHeader("Debug Draw"))
{
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::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);
}
}
@ -1113,31 +1121,44 @@ void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
{
rcIgnoreUnused(model);
rcIgnoreUnused(proj);
rcIgnoreUnused(view);
// Tool help
const int h = view[3];
int ty = h-40;
float ty = 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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(1.0f,1.0f,1.0f,0.75f), "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));
ty -= 20;
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "Setting velocity will move the agents without pathfinder.", imguiRGBA(255,255,255,192));
ImGui_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(1.0f,1.0f,1.0f,0.75f), "LMB: set move target. Shift+LMB: adjust set velocity.");
ty += 20;
ImGui_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(1.0f,1.0f,1.0f,0.75f), "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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(1.0f,1.0f,1.0f,0.75f), "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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(1.0f,1.0f,1.0f,0.75f), "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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(0.15f,1.0f,0.05f,0.8f), "- RUNNING -");
}
else
{
ImGui_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, ty), ImVec4(1.0f,0.15f,0.05f,0.8f), "- PAUSED -");
}
}

View File

@ -177,18 +177,20 @@ 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::PushItemWidth(180.f);
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)
{
@ -198,51 +200,66 @@ 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);
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("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("Partitioning");
if (imguiCheck("Watershed", m_partitionType == EDITOR_PARTITION_WATERSHED))
ImGui::PopItemWidth();
ImGui::PushItemWidth(140.f);
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?
ImGui::PopItemWidth();
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::PushItemWidth(145.f);
ImGui::Separator();
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::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);
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);
ImGui::PopItemWidth();
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();
@ -145,19 +145,19 @@ public:
virtual void handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
const int h = view[3];
if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
model, proj, view, &x, &y, &z))
{
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_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-((float)y-25)), ImVec4(0,0,0,0.8f), "(%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_RenderText(ImGuiTextAlign_e::kAlignLeft, ImVec2(280, 40),
ImVec4(1.0f,1.0f,1.0f,0.75f), "LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.");
}
};
@ -215,11 +215,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)
@ -237,26 +237,25 @@ void Editor_TileMesh::selectNavMeshType(const NavMeshType_e navMeshType)
void Editor_TileMesh::handleSettings()
{
ImGui::Text("NavMesh Type");
for (int i = 0; i < NAVMESH_COUNT; i++)
{
const NavMeshType_e navMeshType = NavMeshType_e(i);
if (imguiButton(NavMesh_GetNameForType(navMeshType)))
if (ImGui::Button(NavMesh_GetNameForType(navMeshType), ImVec2(120, 0)))
{
selectNavMeshType(navMeshType);
}
}
ImGui::Separator();
Editor::handleCommonSettings();
if (imguiCheck("Keep Intermediate Results", m_keepInterResults))
m_keepInterResults = !m_keepInterResults;
if (imguiCheck("Build All Tiles", m_buildAll))
m_buildAll = !m_buildAll;
imguiLabel("Tiling");
imguiSlider("TileSize", &m_tileSize, 8.0f, 1024.0f, 8.0f);
ImGui::Text("Tiling");
ImGui::SliderInt("TileSize", &m_tileSize, 8, 1024);
ImGui::Checkbox("Build All Tiles", &m_buildAll);
ImGui::Checkbox("Keep Intermediate Results", &m_keepInterResults);
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,13 @@ void Editor_TileMesh::handleSettings()
m_maxPolysPerTile = 0;
}
imguiSeparator();
ImGui::Separator();
imguiIndent();
imguiIndent();
if (imguiButton("Load"))
ImGui::Indent();
ImGui::Indent();
if (ImGui::Button("Load", ImVec2(123, 0)))
{
dtFreeNavMesh(m_navMesh);
m_navMesh = Editor::loadAll(m_modelName.c_str());
@ -304,83 +304,83 @@ void Editor_TileMesh::handleSettings()
initToolStates(this);
}
if (imguiButton("Save"))
if (ImGui::Button("Save", ImVec2(123, 0)))
{
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);
imguiSeparator();
ImGui::Text("Build Time: %.1fms", m_totalBuildTimeMs);
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: \n\tX: %g \n\tY: %g \n\tZ: %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);
ImGui::Separator();
}
imguiSeparator();
else
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();
imguiIndent();
ImGui::Indent();
if (m_tool)
m_tool->handleMenu();
imguiUnindent();
ImGui::Unindent();
}
void Editor_TileMesh::handleDebugMode()
@ -419,81 +419,210 @@ 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::Separator();
ImGui::Text("Draw Options");
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 +653,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);
@ -628,14 +757,14 @@ void Editor_TileMesh::handleRender()
void Editor_TileMesh::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
const int h = view[3];
// Draw start and end point labels
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_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-(float)(y-25)),
ImVec4(0,0,0,0.8f), "%.3fms / %dTris / %.1fkB", m_tileBuildTime, m_tileTriCount, m_tileMemUsage);
}
if (m_tool)
@ -810,7 +939,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 +994,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 +1051,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;
@ -308,9 +308,8 @@ void NavMeshPruneTool::handleRenderOverlay(double* proj, double* model, int* vie
{
rcIgnoreUnused(model);
rcIgnoreUnused(proj);
rcIgnoreUnused(view);
// Tool help
const int h = view[3];
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Click fill area.", imguiRGBA(255,255,255,192));
ImGui_RenderText(ImGuiTextAlign_e::kAlignLeft, ImVec2(280, 40), ImVec4(1.0f,1.0f,1.0f,0.75f), "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();
@ -418,14 +480,16 @@ void NavMeshTesterTool::handleMenu()
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
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)
@ -1353,17 +1417,20 @@ void NavMeshTesterTool::handleRender()
void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
const int h = view[3];
// Draw start and end point labels
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_RenderText(ImGuiTextAlign_e::kAlignCenter,
ImVec2((float)x, h-((float)y-25)), ImVec4(0,0,0,0.8f), "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_RenderText(ImGuiTextAlign_e::kAlignCenter,
ImVec2((float)x, h-((float)y-25)), ImVec4(0,0,0,0.8f), "End");
}
// Useful utility to draw all polygroup id's at the center of the polygons.
@ -1391,17 +1458,16 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
// if ((p.second) && gluProject((GLdouble)poly->center[0], (GLdouble)poly->center[1], (GLdouble)poly->center[2] + 30,
// model, proj, view, &x, &y, &z))
// {
// 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_RenderText(ImGuiTextAlign_e::kAlignCenter,
// ImVec2((float)x, h-(float)y), ImVec4(0, 0, 0, 0.8f), "%hu", poly->groupId);
// }
// }
// }
//}
// 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_RenderText(ImGuiTextAlign_e::kAlignLeft, ImVec2(280, 40),
ImVec4(1.0f,1.0f,1.0f,0.75f), "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;
}
@ -143,22 +148,24 @@ void OffMeshConnectionTool::handleRender()
void OffMeshConnectionTool::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
const int h = view[3];
// Draw start and end point labels
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_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-((float)y-25)), ImVec4(0,0,0,0.8f), "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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, 40), ImVec4(1.0f,1.0f,1.0f,0.75f), "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_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, 40), ImVec4(1.0f,1.0f,1.0f,0.75f), "LMB: Set connection end point and finish.");
}
}

View File

@ -376,7 +376,8 @@ void TestCase::handleRender()
bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
char text[64], subtext[64];
const int h = view[3];
char text[256];
int n = 0;
static const float LABEL_DIST = 1.0f;
@ -406,46 +407,45 @@ 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.0f,0.0f,0.0f,0.5f);
if (iter->expand)
col = imguiRGBA(255,192,0,220);
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, text, col);
col = ImVec4(1.0f,0.75f,0.0f,0.85f);
ImGui_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-((float)y-25)), 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

@ -9,24 +9,24 @@ ValueHistory::ValueHistory() :
m_hsamples(0)
{
for (int i = 0; i < MAX_HISTORY; ++i)
m_samples[i] = 0;
m_samples[i] = ImVec2(0,0);
}
float ValueHistory::getSampleMin() const
{
float val = m_samples[0];
float val = m_samples[0].y;
for (int i = 1; i < MAX_HISTORY; ++i)
if (m_samples[i] < val)
val = m_samples[i];
if (m_samples[i].y < val)
val = m_samples[i].y;
return val;
}
float ValueHistory::getSampleMax() const
{
float val = m_samples[0];
float val = m_samples[0].y;
for (int i = 1; i < MAX_HISTORY; ++i)
if (m_samples[i] > val)
val = m_samples[i];
if (m_samples[i].y > val)
val = m_samples[i].y;
return val;
}
@ -34,79 +34,6 @@ float ValueHistory::getAverage() const
{
float val = 0;
for (int i = 0; i < MAX_HISTORY; ++i)
val += m_samples[i];
val += m_samples[i].y;
return val/(float)MAX_HISTORY;
}
void GraphParams::setRect(int ix, int iy, int iw, int ih, int ipad)
{
x = ix;
y = iy;
w = iw;
h = ih;
pad = ipad;
}
void GraphParams::setValueRange(float ivmin, float ivmax, int indiv, const char* iunits)
{
vmin = ivmin;
vmax = ivmax;
ndiv = indiv;
strcpy(units, iunits);
}
void drawGraphBackground(const GraphParams* p)
{
// 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;
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;
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));
}
}
void drawGraph(const GraphParams* p, const ValueHistory* graph,
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;
// 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;
if (i > 0)
imguiDrawLine(px,py, x,y, 2.0f, col);
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);
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));
}

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,6 @@
struct CrowdToolParams
{
bool m_expandSelectedDebugDraw;
bool m_showCorners;
bool m_showCollisionSegments;
bool m_showPath;
@ -39,20 +38,17 @@ struct CrowdToolParams
bool m_showOpt;
bool m_showNeis;
bool m_expandDebugDraw;
bool m_showLabels;
bool m_showGrid;
bool m_showNodes;
bool m_showPerfGraph;
bool m_showDetailAll;
bool m_expandOptions;
bool m_expandTraversalOptions;
bool m_anticipateTurns;
bool m_optimizeVis;
bool m_optimizeTopo;
bool m_obstacleAvoidance;
float m_obstacleAvoidanceType;
int m_obstacleAvoidanceType;
bool m_separation;
float m_separationWeight;
@ -85,6 +81,7 @@ class CrowdToolState : public EditorToolState
ValueHistory m_crowdTotalTime;
ValueHistory m_crowdSampleCount;
float m_graphSampleTime;
CrowdToolParams m_toolParams;

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

@ -4,47 +4,40 @@
class ValueHistory
{
static const int MAX_HISTORY = 256;
float m_samples[MAX_HISTORY];
ImVec2 m_samples[MAX_HISTORY];
int m_hsamples;
public:
ValueHistory();
inline void addSample(const float val)
inline void addSample(const float x, const float y)
{
m_hsamples = (m_hsamples+MAX_HISTORY-1) % MAX_HISTORY;
m_samples[m_hsamples] = val;
m_samples[m_hsamples] = ImVec2(x, y);
}
inline int getSampleCount() const
{
return MAX_HISTORY;
}
inline int getSampleOffset() const
{
return m_hsamples;
}
inline float getSample(const int i) const
inline ImVec2 getSample(const int i) const
{
return m_samples[(m_hsamples+i) % MAX_HISTORY];
}
inline ImVec2* getSampleBuffer()
{
return m_samples;
}
float getSampleMin() const;
float getSampleMax() const;
float getAverage() const;
};
struct GraphParams
{
void setRect(int ix, int iy, int iw, int ih, int ipad);
void setValueRange(float ivmin, float ivmax, int indiv, const char* iunits);
int x, y, w, h, pad;
float vmin, vmax;
int ndiv;
char units[16];
};
void drawGraphBackground(const GraphParams* p);
void drawGraph(const GraphParams* p, const ValueHistory* graph,
int idx, const char* label, const unsigned int col);
#endif // VALUEHISTORY_H

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,49 @@ 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;
ImPlotContext* const implotContext = ImPlot::CreateContext();
if (!implotContext)
return false;
// Disable ctrl+tab menu.
imguiContext->ConfigNavWindowingKeyNext = 0;
imguiContext->ConfigNavWindowingKeyPrev = 0;
ImGui_SetStyle(ImGuiStyle_t::DEFAULT);
ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_Separator] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
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 +267,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();
@ -236,6 +279,30 @@ bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &hei
return true;
}
// Gradient background
void draw_background(const GLfloat width, const GLfloat height)
{
glBegin(GL_QUADS);
// top-left
glColor3f(0.4f, 0.4f, 0.4f);
glVertex2f(0.0f, 0.0f);
// top-right
glColor3f(0.4f, 0.4f, 0.4f);
glVertex2f(width, 0.0f);
// bottom-right
glColor3f(0.1f, 0.1f, 0.1f);
glVertex2f(width, height);
// bottom-left
glColor3f(0.1f, 0.1f, 0.1f);
glVertex2f(0.0f, height);
glEnd();
}
#if 1
int main(int argc, char** argv)
#else
@ -399,7 +466,7 @@ int not_main(int argc, char** argv)
vector<string> files;
const string meshesFolder = "Levels";
string meshName = "Choose Level...";
string meshName;
const string testCasesFolder = "TestCases";
float markerPosition[3] = {0, 0, 0};
@ -470,9 +537,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 +557,8 @@ int not_main(int argc, char** argv)
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
switch (event.type)
{
case SDL_KEYDOWN:
@ -502,10 +569,12 @@ int not_main(int argc, char** argv)
}
else if (event.key.keysym.sym == SDLK_t)
{
showLevels = false;
showEditor = false;
showTestCases = true;
scanDirectory(testCasesFolder, ".txt", files);
showLevels ^= false;
showEditor ^= false;
showTestCases ^= true;
if (showTestCases)
scanDirectory(testCasesFolder, ".txt", files);
}
else if (event.key.keysym.sym == SDLK_TAB)
{
@ -630,12 +699,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;
@ -708,8 +771,10 @@ int not_main(int argc, char** argv)
glGetIntegerv(GL_VIEWPORT, viewport);
// Clear the screen
glClearColor(0.20f, 0.21f, 0.22f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);
draw_background((GLfloat)width, (GLfloat)height);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
@ -796,9 +861,13 @@ 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();
if (editor)
{
@ -807,117 +876,118 @@ 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));
ImGui_RenderText(ImGuiTextAlign_e::kAlignLeft,
ImVec2(280, 20), ImVec4(1.0f,1.0f,1.0f,0.5f), "W/S/A/D: Move RMB: Rotate");
}
string geom_path;
const ImGuiWindowFlags baseWindowFlags = ImGuiWindowFlags_None;
if (showMenu)
{
if (imguiBeginScrollArea("Properties", width-250-10, 10, 250, height-20, &propScroll))
mouseOverMenu = true;
ImGui::SetNextWindowPos(ImVec2((float)width-300-10, 10.f), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(300, (float)height-20), ImGuiCond_Once);
ImGui::SetNextWindowSizeConstraints(ImVec2(300, 300), ImVec2(FLT_MAX, FLT_MAX));
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.empty() ? "Choose Level..." : 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);
}
imguiSeparator();
}
if (editor)
{
imguiSeparatorLine();
editor->handleDebugMode();
}
ImGui::Separator();
imguiEndScrollArea();
if (geom && editor)
{
editor->handleSettings();
if (ImGui::Button("Build", ImVec2(165, 0)))
{
ctx.resetLog();
if (!editor->handleBuild())
{
showLog = true;
}
ctx.dumpLog("Build log %s:", meshName.c_str());
// Clear test.
delete test;
test = 0;
}
ImGui::Separator();
}
if (editor)
{
editor->handleDebugMode();
}
}
ImGui::End();
}
// Editor selection dialog.
@ -937,40 +1007,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-300, (float)height-10-900), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(250.f, 450.f), ImGuiCond_Once);
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 +1059,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 +1083,127 @@ 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-300, (float)height-10-900), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(250.f, 450.f), ImGuiCond_Once);
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(250.f+30.f, height-450.f-10.f), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f), ImGuiCond_Once);
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), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(260, (float)height-20), ImGuiCond_Once);
ImGui::SetNextWindowSizeConstraints(ImVec2(260, 300), ImVec2(FLT_MAX, FLT_MAX));
if (editor)
editor->handleTools();
if (ImGui::Begin("Tools", nullptr, baseWindowFlags))
{
if (editor)
editor->handleTools();
}
imguiEndScrollArea();
ImGui::End();
}
// Marker
@ -1147,16 +1227,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

@ -38,8 +38,12 @@ add_sources( SOURCE_GROUP "Misc"
"misc/imgui_plotter_internal.h"
"misc/imgui_snapshot.cpp"
"misc/imgui_snapshot.h"
"misc/imgui_style.cpp"
"misc/imgui_style.h"
"misc/imgui_utility.cpp"
"misc/imgui_utility.h"
"misc/imgui_wrapper.cpp"
"misc/imgui_wrapper.h"
"misc/cpp/imgui_stdlib.cpp"
"misc/cpp/imgui_stdlib.h"
)

View File

@ -97,7 +97,7 @@
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
//struct ImDrawList;

View File

@ -0,0 +1,174 @@
#include "imgui.h"
#include "imgui_style.h"
void ImGui_SetStyle(const ImGuiStyle_t imguiStyle)
{
ImGuiStyle& style = ImGui::GetStyle();
ImVec4* colors = style.Colors;
switch (imguiStyle)
{
case ImGuiStyle_t::LEGACY:
{
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.12f, 0.37f, 0.75f, 0.50f);
colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f);
colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
style.WindowBorderSize = 0.0f;
style.FrameBorderSize = 1.0f;
style.ChildBorderSize = 1.0f;
style.ChildRounding = 1.0f;
style.PopupRounding = 3.0f;
style.ScrollbarRounding = 1.0f;
break;
}
case ImGuiStyle_t::MODERN:
{
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.12f, 0.37f, 0.75f, 0.50f);
colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.15f, 0.18f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.78f);
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.61f, 0.61f, 0.61f, 0.50f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.78f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.04f, 0.06f, 0.10f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.04f, 0.07f, 0.12f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.26f, 0.51f, 0.78f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.26f, 0.51f, 0.78f, 1.00f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.16f, 0.20f, 0.24f, 1.00f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.23f, 0.36f, 0.51f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.30f, 0.46f, 0.65f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.31f, 0.49f, 0.69f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.38f, 0.52f, 0.53f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.38f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 0.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.81f, 0.81f, 0.81f, 0.50f);
colors[ImGuiCol_Tab] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.38f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.14f, 0.19f, 0.24f, 1.00f);
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.20f, 0.26f, 0.33f, 1.00f);
colors[ImGuiCol_TableBorderLight] = ImVec4(0.22f, 0.29f, 0.37f, 1.00f);
style.WindowBorderSize = 1.0f;
style.FrameBorderSize = 0.0f;
style.ChildBorderSize = 0.0f;
style.ChildRounding = 1.0f;
style.PopupRounding = 3.0f;
style.ScrollbarRounding = 3.0f;
break;
}
default:
{
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.12f, 0.37f, 0.75f, 0.50f);
colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.29f, 0.31f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.04f, 0.06f, 0.08f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.29f, 0.31f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.15f, 0.16f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.21f, 0.23f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.26f, 0.28f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.20f, 0.22f, 0.24f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.22f, 0.24f, 0.26f, 1.00f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.24f, 0.26f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.12f, 0.14f, 1.00f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.43f, 0.45f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.65f, 0.67f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.63f, 0.65f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.43f, 0.45f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.37f, 0.39f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.47f, 0.49f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.54f, 0.56f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.35f, 0.37f, 0.39f, 1.00f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.47f, 0.49f, 1.00f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.08f, 0.10f, 0.12f, 0.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.65f, 0.67f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.43f, 0.45f, 1.00f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.54f, 0.56f, 1.00f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.65f, 0.67f, 1.00f);
colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.20f, 0.22f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.41f, 0.43f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.41f, 0.43f, 1.00f);
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.21f, 0.23f, 1.00f);
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.33f, 0.35f, 1.00f);
colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.25f, 0.27f, 1.00f);
style.WindowBorderSize = 1.0f;
style.FrameBorderSize = 1.0f;
style.ChildBorderSize = 0.0f;
style.ChildRounding = 2.0f;
style.PopupRounding = 4.0f;
style.GrabRounding = 1.0f;
style.ScrollbarRounding = 1.0f;
break;
}
}
// Generic style parameters.
style.PopupBorderSize = 1.0f;
style.TabBorderSize = 1.0f;
style.TabBarBorderSize = 1.0f;
style.WindowRounding = 4.0f;
style.FrameRounding = 1.0f;
style.TabRounding = 1.0f;
style.ItemSpacing = ImVec2(5, 4);
style.FramePadding = ImVec2(4, 4);
style.WindowPadding = ImVec2(5, 5);
}

14
src/thirdparty/imgui/misc/imgui_style.h vendored Normal file
View File

@ -0,0 +1,14 @@
#ifndef IMGUI_STYLE_H
#define IMGUI_STYLE_H
enum class ImGuiStyle_t
{
NONE = -1,
DEFAULT,
LEGACY,
MODERN
};
void ImGui_SetStyle(const ImGuiStyle_t style);
#endif // IMGUI_STYLE_H

View File

@ -68,173 +68,23 @@ void ImGuiConfig::Save()
ImGuiStyle_t ImGuiConfig::InitStyle() const
{
ImGuiStyle_t result = ImGuiStyle_t::NONE;
ImGuiStyle& style = ImGui::GetStyle();
ImVec4* colors = style.Colors;
ImGuiStyle_t selected = ImGuiStyle_t::NONE;
if (strcmp(CommandLine()->ParmValue("-imgui_theme", ""), "legacy") == 0)
{
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.12f, 0.37f, 0.75f, 0.50f);
colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f);
colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
style.WindowBorderSize = 0.0f;
style.FrameBorderSize = 1.0f;
style.ChildBorderSize = 1.0f;
style.ChildRounding = 1.0f;
style.PopupRounding = 3.0f;
style.ScrollbarRounding = 1.0f;
result = ImGuiStyle_t::LEGACY;
selected = ImGuiStyle_t::LEGACY;
}
else if (strcmp(CommandLine()->ParmValue("-imgui_theme", ""), "modern") == 0)
{
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.12f, 0.37f, 0.75f, 0.50f);
colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.15f, 0.18f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.78f);
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.61f, 0.61f, 0.61f, 0.50f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.78f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.04f, 0.06f, 0.10f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.04f, 0.07f, 0.12f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.26f, 0.51f, 0.78f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.26f, 0.51f, 0.78f, 1.00f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.16f, 0.20f, 0.24f, 1.00f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.23f, 0.36f, 0.51f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.30f, 0.46f, 0.65f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.31f, 0.49f, 0.69f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.38f, 0.52f, 0.53f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.38f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 0.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.81f, 0.81f, 0.81f, 0.50f);
colors[ImGuiCol_Tab] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.38f, 0.53f, 0.53f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.14f, 0.19f, 0.24f, 1.00f);
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.20f, 0.26f, 0.33f, 1.00f);
colors[ImGuiCol_TableBorderLight] = ImVec4(0.22f, 0.29f, 0.37f, 1.00f);
style.WindowBorderSize = 1.0f;
style.FrameBorderSize = 0.0f;
style.ChildBorderSize = 0.0f;
style.ChildRounding = 1.0f;
style.PopupRounding = 3.0f;
style.ScrollbarRounding = 3.0f;
result = ImGuiStyle_t::MODERN;
selected = ImGuiStyle_t::MODERN;
}
else
{
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.12f, 0.37f, 0.75f, 0.50f);
colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.29f, 0.31f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.04f, 0.06f, 0.08f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.29f, 0.31f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.15f, 0.16f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.21f, 0.23f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.26f, 0.28f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.20f, 0.22f, 0.24f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.22f, 0.24f, 0.26f, 1.00f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.24f, 0.26f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.12f, 0.14f, 1.00f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.43f, 0.45f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.65f, 0.67f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.63f, 0.65f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.43f, 0.45f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.37f, 0.39f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.47f, 0.49f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.54f, 0.56f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.35f, 0.37f, 0.39f, 1.00f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.47f, 0.49f, 1.00f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.08f, 0.10f, 0.12f, 0.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.55f, 0.57f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.65f, 0.67f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.43f, 0.45f, 1.00f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.54f, 0.56f, 1.00f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.65f, 0.67f, 1.00f);
colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.20f, 0.22f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.41f, 0.43f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.41f, 0.43f, 1.00f);
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.21f, 0.23f, 1.00f);
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.33f, 0.35f, 1.00f);
colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.25f, 0.27f, 1.00f);
style.WindowBorderSize = 1.0f;
style.FrameBorderSize = 1.0f;
style.ChildBorderSize = 0.0f;
style.ChildRounding = 2.0f;
style.PopupRounding = 4.0f;
style.GrabRounding = 1.0f;
style.ScrollbarRounding = 1.0f;
result = ImGuiStyle_t::DEFAULT;
selected = ImGuiStyle_t::DEFAULT;
}
style.PopupBorderSize = 1.0f;
style.TabBorderSize = 1.0f;
style.TabBarBorderSize = 1.0f;
style.WindowRounding = 4.0f;
style.FrameRounding = 1.0f;
style.TabRounding = 1.0f;
style.ItemSpacing = ImVec2(5, 4);
style.FramePadding = ImVec2(4, 4);
style.WindowPadding = ImVec2(5, 5);
return result;
ImGui_SetStyle(selected);
return selected;
}
ImGuiConfig g_ImGuiConfig;

View File

@ -1,15 +1,8 @@
#pragma once
#include "imgui_style.h"
constexpr char IMGUI_BIND_FILE[] = "keymap.vdf";
enum class ImGuiStyle_t
{
NONE = -1,
DEFAULT,
LEGACY,
MODERN
};
class ImGuiConfig
{
public:

View File

@ -0,0 +1,34 @@
//============================================================================//
//
// Purpose: Set of Dear ImGui wrappers
//
//============================================================================//
#include "imgui.h"
#include "imgui_wrapper.h"
#include "stdio.h"
void ImGui_RenderText(const ImGuiTextAlign_e align, const ImVec2 pos, const ImVec4& color, const char* const fmt, ...)
{
ImDrawList* const drawList = ImGui::GetBackgroundDrawList();
assert(drawList);
va_list argsCopy;
va_start(argsCopy, fmt);
char textBuffer[2048];
const int numChars = vsnprintf(textBuffer, sizeof(textBuffer), fmt, argsCopy);
va_end(argsCopy);
// nb(amos): 'vsnprintf' does not count the terminating null, so no -1 here.
const char* const textEnd = &textBuffer[numChars];
ImVec2 alignedPos = pos;
if (align == ImGuiTextAlign_e::kAlignCenter)
alignedPos.x -= ImGui::CalcTextSize(textBuffer, textEnd).x / 2;
else if (align == ImGuiTextAlign_e::kAlignRight)
alignedPos.x -= ImGui::CalcTextSize(textBuffer, textEnd).x;
drawList->AddText(alignedPos, ImGui::ColorConvertFloat4ToU32(color), textBuffer, textEnd);
}

View File

@ -0,0 +1,13 @@
#ifndef IMGUI_WRAPPER_H
#define IMGUI_WRAPPER_H
enum class ImGuiTextAlign_e
{
kAlignLeft,
kAlignCenter,
kAlignRight,
};
extern void ImGui_RenderText(const ImGuiTextAlign_e align, const ImVec2 pos, const ImVec4& color, const char* const fmt, ...);
#endif // IMGUI_WRAPPER_H

View File

@ -51,8 +51,15 @@
# 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_style.h"
#include "thirdparty/imgui/misc/imgui_wrapper.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"