mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: upgrade legacy ImGui implementation to 1.90.4 (WIP)
Major upgrade to newer library. This is still work in progress, there are many bugs.
This commit is contained in:
parent
c2df5e19bf
commit
e2c48c49db
@ -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"
|
||||
|
@ -114,31 +114,45 @@ void ConvexVolumeTool::reset()
|
||||
|
||||
void ConvexVolumeTool::handleMenu()
|
||||
{
|
||||
imguiSlider("Shape Height", &m_boxHeight, 0.1f, MAX_COORD_FLOAT, 0.1f);
|
||||
imguiSlider("Shape Descent", &m_boxDescent, 0.1f, MAX_COORD_FLOAT, 0.1f);
|
||||
imguiSlider("Poly Offset", &m_polyOffset, 0.0f, MAX_COORD_FLOAT/2, 0.1f);
|
||||
ImGui::SliderFloat("Shape Height", &m_boxHeight, 0.1f, MAX_COORD_FLOAT);
|
||||
ImGui::SliderFloat("Shape Descent", &m_boxDescent, 0.1f, MAX_COORD_FLOAT);
|
||||
ImGui::SliderFloat("Poly Offset", &m_polyOffset, 0.0f, MAX_COORD_FLOAT/2);
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiLabel("Area Type");
|
||||
imguiIndent();
|
||||
if (imguiCheck("Ground", m_areaType == EDITOR_POLYAREA_GROUND))
|
||||
ImGui::Text("Area Type");
|
||||
ImGui::Indent();
|
||||
|
||||
bool isEnabled = m_areaType == EDITOR_POLYAREA_GROUND;
|
||||
|
||||
if (ImGui::Checkbox("Ground", &isEnabled))
|
||||
m_areaType = EDITOR_POLYAREA_GROUND;
|
||||
if (imguiCheck("Water", m_areaType == EDITOR_POLYAREA_WATER))
|
||||
|
||||
isEnabled = m_areaType == EDITOR_POLYAREA_WATER;
|
||||
if (ImGui::Checkbox("Water", &isEnabled))
|
||||
m_areaType = EDITOR_POLYAREA_WATER;
|
||||
if (imguiCheck("Road", m_areaType == EDITOR_POLYAREA_ROAD))
|
||||
|
||||
isEnabled = m_areaType == EDITOR_POLYAREA_ROAD;
|
||||
if (ImGui::Checkbox("Road", &isEnabled))
|
||||
m_areaType = EDITOR_POLYAREA_ROAD;
|
||||
if (imguiCheck("Door", m_areaType == EDITOR_POLYAREA_DOOR))
|
||||
|
||||
isEnabled = m_areaType == EDITOR_POLYAREA_DOOR;
|
||||
if (ImGui::Checkbox("Door", &isEnabled))
|
||||
m_areaType = EDITOR_POLYAREA_DOOR;
|
||||
if (imguiCheck("Grass", m_areaType == EDITOR_POLYAREA_GRASS))
|
||||
|
||||
isEnabled = m_areaType == EDITOR_POLYAREA_GRASS;
|
||||
if (ImGui::Checkbox("Grass", &isEnabled))
|
||||
m_areaType = EDITOR_POLYAREA_GRASS;
|
||||
if (imguiCheck("Jump", m_areaType == EDITOR_POLYAREA_JUMP))
|
||||
|
||||
isEnabled = m_areaType == EDITOR_POLYAREA_JUMP;
|
||||
if (ImGui::Checkbox("Jump", &isEnabled))
|
||||
m_areaType = EDITOR_POLYAREA_JUMP;
|
||||
imguiUnindent();
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Unindent();
|
||||
|
||||
if (imguiButton("Clear Shape"))
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button("Clear Shape"))
|
||||
{
|
||||
m_npts = 0;
|
||||
m_nhull = 0;
|
||||
@ -282,12 +296,14 @@ void ConvexVolumeTool::handleRenderOverlay(double* /*proj*/, double* /*model*/,
|
||||
const int h = view[3];
|
||||
if (!m_npts)
|
||||
{
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Create new shape. SHIFT+LMB: Delete existing shape (click inside a shape).", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Create new shape. SHIFT+LMB: Delete existing shape (click inside a shape).");
|
||||
}
|
||||
else
|
||||
{
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "Click LMB to add new points. Click on the red point to finish the shape.", imguiRGBA(255,255,255,192));
|
||||
imguiDrawText(280, h-60, IMGUI_ALIGN_LEFT, "The shape will be convex hull of all added points.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "Click LMB to add new points. Click on the red point to finish the shape.");
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-60));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "The shape will be convex hull of all added points.");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ CrowdToolState::CrowdToolState() :
|
||||
m_toolParams.m_optimizeVis = true;
|
||||
m_toolParams.m_optimizeTopo = true;
|
||||
m_toolParams.m_obstacleAvoidance = true;
|
||||
m_toolParams.m_obstacleAvoidanceType = 3.0f;
|
||||
m_toolParams.m_obstacleAvoidanceType = 3;
|
||||
m_toolParams.m_separation = true;
|
||||
m_toolParams.m_separationWeight = 20.0f;
|
||||
m_toolParams.m_maxAcceleration = 800.f;
|
||||
@ -508,6 +508,10 @@ void CrowdToolState::handleRender()
|
||||
dd.depthMask(true);
|
||||
}
|
||||
|
||||
namespace ImPlot
|
||||
{
|
||||
extern void Demo_ShadedPlots();
|
||||
};
|
||||
|
||||
void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
{
|
||||
@ -517,11 +521,11 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
if (m_targetRef && gluProject((GLdouble)m_targetPos[0], (GLdouble)m_targetPos[1], (GLdouble)m_targetPos[2],
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
imguiDrawText((int)x, (int)(y+25), IMGUI_ALIGN_CENTER, "TARGET", imguiRGBA(0,0,0,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y+25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "TARGET"); // IMGUI_ALIGN_CENTER
|
||||
}
|
||||
|
||||
char label[32];
|
||||
|
||||
|
||||
if (m_toolParams.m_showNodes)
|
||||
{
|
||||
dtCrowd* crowd = m_editor->getCrowd();
|
||||
@ -543,8 +547,9 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
const float heuristic = node->total;// - node->cost;
|
||||
snprintf(label, 32, "%.2f", heuristic);
|
||||
imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220));
|
||||
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y+25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "%.2f", heuristic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -571,8 +576,8 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
? "none"
|
||||
: g_traverseAnimTypeNames[animType];
|
||||
|
||||
snprintf(label, 32, "%s (%d)", animTypeName, i);
|
||||
imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y+15));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "%s (%d)", animTypeName, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -600,8 +605,8 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
if (gluProject((GLdouble)nei->npos[0], (GLdouble)nei->npos[1], (GLdouble)nei->npos[2]+radius,
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
snprintf(label, 32, "%.3f", ag->neis[j].dist);
|
||||
imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(255,255,255,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y+15));
|
||||
ImGui::TextColored(ImVec4(255,255,255,220), "%.3f", ag->neis[j].dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -609,21 +614,24 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_toolParams.m_showPerfGraph)
|
||||
{
|
||||
GraphParams gp;
|
||||
gp.setRect(300, 10, 500, 200, 8);
|
||||
gp.setValueRange(0.0f, 2.0f, 4, "ms");
|
||||
|
||||
drawGraphBackground(&gp);
|
||||
drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(255,128,0,255));
|
||||
|
||||
gp.setRect(300, 10, 500, 50, 8);
|
||||
gp.setValueRange(0.0f, 2000.0f, 1, "");
|
||||
drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(96,96,96,128));
|
||||
if (!ImPlot::GetCurrentContext())
|
||||
ImPlot::CreateContext();
|
||||
|
||||
//GraphParams gp;
|
||||
//gp.setRect(300, 10, 500, 200, 8);
|
||||
//gp.setValueRange(0.0f, 2.0f, 4, "ms");
|
||||
//
|
||||
//drawGraphBackground(&gp);
|
||||
//drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(255,128,0,255));
|
||||
//
|
||||
//gp.setRect(300, 10, 500, 50, 8);
|
||||
//gp.setValueRange(0.0f, 2000.0f, 1, "");
|
||||
//drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(96,96,96,128));
|
||||
|
||||
ImPlot::ShowDemoWindow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CrowdToolState::handleUpdate(const float dt)
|
||||
@ -892,137 +900,120 @@ void CrowdTool::handleMenu()
|
||||
return;
|
||||
CrowdToolParams* params = m_state->getToolParams();
|
||||
|
||||
if (imguiCheck("Create Agents", m_mode == TOOLMODE_CREATE))
|
||||
bool isEnabled = m_mode == TOOLMODE_CREATE;
|
||||
|
||||
if (ImGui::Checkbox("Create Agents", &isEnabled))
|
||||
m_mode = TOOLMODE_CREATE;
|
||||
if (imguiCheck("Move Target", m_mode == TOOLMODE_MOVE_TARGET))
|
||||
|
||||
isEnabled = m_mode == TOOLMODE_MOVE_TARGET;
|
||||
|
||||
if (ImGui::Checkbox("Move Target", &isEnabled))
|
||||
m_mode = TOOLMODE_MOVE_TARGET;
|
||||
if (imguiCheck("Select Agent", m_mode == TOOLMODE_SELECT))
|
||||
|
||||
isEnabled = m_mode == TOOLMODE_SELECT;
|
||||
|
||||
if (ImGui::Checkbox("Select Agent", &isEnabled))
|
||||
m_mode = TOOLMODE_SELECT;
|
||||
if (imguiCheck("Toggle Polys", m_mode == TOOLMODE_TOGGLE_POLYS))
|
||||
|
||||
isEnabled = m_mode == TOOLMODE_TOGGLE_POLYS;
|
||||
|
||||
if (ImGui::Checkbox("Toggle Polys", &isEnabled))
|
||||
m_mode = TOOLMODE_TOGGLE_POLYS;
|
||||
|
||||
imguiSeparatorLine();
|
||||
|
||||
if (imguiCollapse("Options", 0, params->m_expandOptions))
|
||||
params->m_expandOptions = !params->m_expandOptions;
|
||||
ImGui::Separator(); // was imguiSeperatorLine
|
||||
|
||||
if (params->m_expandOptions)
|
||||
if (ImGui::CollapsingHeader("Options"))
|
||||
{
|
||||
imguiIndent();
|
||||
if (imguiCheck("Optimize Visibility", params->m_optimizeVis))
|
||||
{
|
||||
params->m_optimizeVis = !params->m_optimizeVis;
|
||||
ImGui::Indent();
|
||||
if (ImGui::Checkbox("Optimize Visibility", ¶ms->m_optimizeVis))
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiCheck("Optimize Topology", params->m_optimizeTopo))
|
||||
{
|
||||
params->m_optimizeTopo = !params->m_optimizeTopo;
|
||||
|
||||
if (ImGui::Checkbox("Optimize Topology", ¶ms->m_optimizeTopo))
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiCheck("Anticipate Turns", params->m_anticipateTurns))
|
||||
{
|
||||
params->m_anticipateTurns = !params->m_anticipateTurns;
|
||||
|
||||
if (ImGui::Checkbox("Anticipate Turns", ¶ms->m_anticipateTurns))
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiCheck("Obstacle Avoidance", params->m_obstacleAvoidance))
|
||||
{
|
||||
params->m_obstacleAvoidance = !params->m_obstacleAvoidance;
|
||||
|
||||
if (ImGui::Checkbox("Obstacle Avoidance", ¶ms->m_obstacleAvoidance))
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiSlider("Avoidance Quality", ¶ms->m_obstacleAvoidanceType, 0.0f, 3.0f, 1.0f))
|
||||
|
||||
if (ImGui::SliderInt("Avoidance Quality", ¶ms->m_obstacleAvoidanceType, 0, 3))
|
||||
{
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiCheck("Separation", params->m_separation))
|
||||
{
|
||||
params->m_separation = !params->m_separation;
|
||||
if (ImGui::Checkbox("Separation", ¶ms->m_separation))
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiSlider("Separation Weight", ¶ms->m_separationWeight, 0.0f, 200.0f, 0.01f))
|
||||
|
||||
if (ImGui::SliderFloat("Separation Weight", ¶ms->m_separationWeight, 0.0f, 200.0f))
|
||||
{
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiSlider("Max Acceleration", ¶ms->m_maxAcceleration, 0.0f, 2000.0f, 0.01f))
|
||||
if (ImGui::SliderFloat("Max Acceleration", ¶ms->m_maxAcceleration, 0.0f, 2000.0f))
|
||||
{
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
if (imguiSlider("Max Speed", ¶ms->m_maxSpeed, 0.0f, 2000.0f, 0.01f))
|
||||
if (ImGui::SliderFloat("Max Speed", ¶ms->m_maxSpeed, 0.0f, 2000.0f))
|
||||
{
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
if (imguiCollapse("Traverse Animation Type", 0, params->m_expandTraversalOptions))
|
||||
params->m_expandTraversalOptions = !params->m_expandTraversalOptions;
|
||||
|
||||
const NavMeshType_e loadedNavMeshType = m_editor->getLoadedNavMeshType();
|
||||
|
||||
// TODO: perhaps clamp with m_nav->m_params.traversalTableCount? Technically a navmesh should
|
||||
// contain all the traversal tables it supports, so if we crash the navmesh is technically corrupt.
|
||||
const int traverseTableCount = NavMesh_GetTraversalTableCountForNavMeshType(loadedNavMeshType);
|
||||
const TraverseAnimType_e baseType = NavMesh_GetFirstTraverseAnimTypeForType(loadedNavMeshType);
|
||||
|
||||
if (params->m_expandTraversalOptions)
|
||||
if (ImGui::CollapsingHeader("Traverse Animation Type"))
|
||||
{
|
||||
imguiIndent();
|
||||
const NavMeshType_e loadedNavMeshType = m_editor->getLoadedNavMeshType();
|
||||
|
||||
for (int i = ANIMTYPE_NONE; i < traverseTableCount; i++)
|
||||
// TODO: perhaps clamp with m_nav->m_params.traversalTableCount? Technically a navmesh should
|
||||
// contain all the traversal tables it supports, so if we crash the navmesh is technically corrupt.
|
||||
const int traverseTableCount = NavMesh_GetTraversalTableCountForNavMeshType(loadedNavMeshType);
|
||||
const TraverseAnimType_e baseType = NavMesh_GetFirstTraverseAnimTypeForType(loadedNavMeshType);
|
||||
|
||||
if (params->m_expandTraversalOptions)
|
||||
{
|
||||
const bool noAnimtype = i == ANIMTYPE_NONE;
|
||||
ImGui::Indent();
|
||||
|
||||
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
|
||||
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
|
||||
|
||||
if (imguiCheck(animtypeName, params->m_traverseAnimType == animTypeIndex))
|
||||
for (int i = ANIMTYPE_NONE; i < traverseTableCount; i++)
|
||||
{
|
||||
params->m_traverseAnimType = animTypeIndex;
|
||||
m_state->updateAgentParams();
|
||||
const bool noAnimtype = i == ANIMTYPE_NONE;
|
||||
|
||||
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
|
||||
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
|
||||
|
||||
bool isAnimTypeEnabled = params->m_traverseAnimType == animTypeIndex;
|
||||
|
||||
if (ImGui::Checkbox(animtypeName, &isAnimTypeEnabled))
|
||||
{
|
||||
params->m_traverseAnimType = animTypeIndex;
|
||||
m_state->updateAgentParams();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
}
|
||||
|
||||
if (imguiCollapse("Selected Debug Draw", 0, params->m_expandSelectedDebugDraw))
|
||||
params->m_expandSelectedDebugDraw = !params->m_expandSelectedDebugDraw;
|
||||
|
||||
if (params->m_expandSelectedDebugDraw)
|
||||
if (ImGui::CollapsingHeader("Selected Debug Draw", 0, params->m_expandSelectedDebugDraw))
|
||||
{
|
||||
imguiIndent();
|
||||
if (imguiCheck("Show Corners", params->m_showCorners))
|
||||
params->m_showCorners = !params->m_showCorners;
|
||||
if (imguiCheck("Show Collision Segs", params->m_showCollisionSegments))
|
||||
params->m_showCollisionSegments = !params->m_showCollisionSegments;
|
||||
if (imguiCheck("Show Path", params->m_showPath))
|
||||
params->m_showPath = !params->m_showPath;
|
||||
if (imguiCheck("Show VO", params->m_showVO))
|
||||
params->m_showVO = !params->m_showVO;
|
||||
if (imguiCheck("Show Path Optimization", params->m_showOpt))
|
||||
params->m_showOpt = !params->m_showOpt;
|
||||
if (imguiCheck("Show Neighbours", params->m_showNeis))
|
||||
params->m_showNeis = !params->m_showNeis;
|
||||
imguiUnindent();
|
||||
ImGui::Indent();
|
||||
ImGui::Checkbox("Show Corners", ¶ms->m_showCorners);
|
||||
ImGui::Checkbox("Show Collision Segs", ¶ms->m_showCollisionSegments);
|
||||
ImGui::Checkbox("Show Path", ¶ms->m_showPath);
|
||||
ImGui::Checkbox("Show VO", ¶ms->m_showVO);
|
||||
ImGui::Checkbox("Show Path Optimization", ¶ms->m_showOpt);
|
||||
ImGui::Checkbox("Show Neighbours", ¶ms->m_showNeis);
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
if (imguiCollapse("Debug Draw", 0, params->m_expandDebugDraw))
|
||||
params->m_expandDebugDraw = !params->m_expandDebugDraw;
|
||||
|
||||
if (params->m_expandDebugDraw)
|
||||
if (ImGui::CollapsingHeader("Debug Draw", 0, params->m_expandDebugDraw))
|
||||
{
|
||||
imguiIndent();
|
||||
if (imguiCheck("Show Labels", params->m_showLabels))
|
||||
params->m_showLabels = !params->m_showLabels;
|
||||
if (imguiCheck("Show Prox Grid", params->m_showGrid))
|
||||
params->m_showGrid = !params->m_showGrid;
|
||||
if (imguiCheck("Show Nodes", params->m_showNodes))
|
||||
params->m_showNodes = !params->m_showNodes;
|
||||
if (imguiCheck("Show Perf Graph", params->m_showPerfGraph))
|
||||
params->m_showPerfGraph = !params->m_showPerfGraph;
|
||||
if (imguiCheck("Show Detail All", params->m_showDetailAll))
|
||||
params->m_showDetailAll = !params->m_showDetailAll;
|
||||
imguiUnindent();
|
||||
ImGui::Indent();
|
||||
ImGui::Checkbox("Show Labels", ¶ms->m_showLabels);
|
||||
ImGui::Checkbox("Show Prox Grid", ¶ms->m_showGrid);
|
||||
ImGui::Checkbox("Show Nodes", ¶ms->m_showNodes);
|
||||
ImGui::Checkbox("Show Perf Graph", ¶ms->m_showPerfGraph);
|
||||
ImGui::Checkbox("Show Detail All", ¶ms->m_showDetailAll);
|
||||
ImGui::Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1116,28 +1107,41 @@ void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
|
||||
// Tool help
|
||||
const int h = view[3];
|
||||
int ty = h-40;
|
||||
float ty = (float)h-40;
|
||||
|
||||
if (m_mode == TOOLMODE_CREATE)
|
||||
{
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: add agent. Shift+LMB: remove agent.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: add agent. Shift+LMB: remove agent.");
|
||||
}
|
||||
else if (m_mode == TOOLMODE_MOVE_TARGET)
|
||||
{
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: set move target. Shift+LMB: adjust set velocity.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: set move target. Shift+LMB: adjust set velocity.");
|
||||
|
||||
ty -= 20;
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "Setting velocity will move the agents without pathfinder.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "Setting velocity will move the agents without pathfinder.");
|
||||
}
|
||||
else if (m_mode == TOOLMODE_SELECT)
|
||||
{
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: select agent.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: select agent.");
|
||||
}
|
||||
ty -= 20;
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "SPACE: Run/Pause simulation. 1: Step simulation.", imguiRGBA(255,255,255,192));
|
||||
ty -= 20;
|
||||
|
||||
ty -= 20.f;
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "SPACE: Run/Pause simulation. 1: Step simulation.");
|
||||
|
||||
ty -= 20.f;
|
||||
if (m_state && m_state->isRunning())
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- RUNNING -", imguiRGBA(255,32,16,255));
|
||||
else
|
||||
imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- PAUSED -", imguiRGBA(255,255,255,128));
|
||||
{
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,32,16,255), "- RUNNING -");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::SetCursorPos(ImVec2(280, ty));
|
||||
ImGui::TextColored(ImVec4(255,255,255,128), "- PAUSED -");
|
||||
}
|
||||
}
|
||||
|
@ -176,18 +176,18 @@ void Editor::resetCommonSettings()
|
||||
m_agentMaxSlope = 45.0f;
|
||||
m_regionMinSize = 8;
|
||||
m_regionMergeSize = 20;
|
||||
m_edgeMaxLen = 12.0f;
|
||||
m_edgeMaxLen = 12;
|
||||
m_edgeMaxError = 1.3f;
|
||||
m_vertsPerPoly = 6.0f;
|
||||
m_vertsPerPoly = 6;
|
||||
m_detailSampleDist = 6.0f;
|
||||
m_detailSampleMaxError = 1.0f;
|
||||
m_partitionType = EDITOR_PARTITION_WATERSHED;
|
||||
}
|
||||
void Editor::handleCommonSettings()
|
||||
{
|
||||
imguiLabel("Rasterization");
|
||||
imguiSlider("Cell Size", &m_cellSize, 0.1f, 100.0f, 0.01f);
|
||||
imguiSlider("Cell Height", &m_cellHeight, 0.1f, 100.0f, 0.01f);
|
||||
ImGui::Text("Rasterization");
|
||||
ImGui::SliderFloat("Cell Size", &m_cellSize, 0.1f, 100.0f);
|
||||
ImGui::SliderFloat("Cell Height", &m_cellHeight, 0.1f, 100.0f);
|
||||
|
||||
if (m_geom)
|
||||
{
|
||||
@ -197,51 +197,57 @@ void Editor::handleCommonSettings()
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
char text[64];
|
||||
snprintf(text, 64, "Voxels %d x %d", gw, gh);
|
||||
imguiValue(text);
|
||||
ImGui::Text(text);
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Agent");
|
||||
imguiSlider("Height", &m_agentHeight, 0.1f, 500.0f, 0.1f);
|
||||
imguiSlider("Radius", &m_agentRadius, 0.0f, 500.0f, 0.1f);
|
||||
imguiSlider("Max Climb", &m_agentMaxClimb, 0.1f, 120.0f, 0.1f);
|
||||
imguiSlider("Max Slope", &m_agentMaxSlope, 0.0f, 90.0f, 1.0f);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Agent");
|
||||
ImGui::SliderFloat("Height", &m_agentHeight, 0.1f, 500.0f);
|
||||
ImGui::SliderFloat("Radius", &m_agentRadius, 0.0f, 500.0f);
|
||||
ImGui::SliderFloat("Max Climb", &m_agentMaxClimb, 0.1f, 120.0f);
|
||||
ImGui::SliderFloat("Max Slope", &m_agentMaxSlope, 0.0f, 90.0f); // ImGui_Upgrade: Slider step was 1.0f
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Region");
|
||||
imguiSlider("Min Region Size", &m_regionMinSize, 0.0f, 750.0f, 1.0f);
|
||||
imguiSlider("Merged Region Size", &m_regionMergeSize, 0.0f, 750.0f, 1.0f);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Region");
|
||||
ImGui::SliderInt("Min Region Size", &m_regionMinSize, 0, 750); // todo(amos): increase because of larger map scale?
|
||||
ImGui::SliderInt("Merged Region Size", &m_regionMergeSize, 0, 750); // todo(amos): increase because of larger map scale?
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Partitioning");
|
||||
if (imguiCheck("Watershed", m_partitionType == EDITOR_PARTITION_WATERSHED))
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Partitioning");
|
||||
|
||||
bool isEnabled = m_partitionType == EDITOR_PARTITION_WATERSHED;
|
||||
|
||||
if (ImGui::Checkbox("Watershed", &isEnabled))
|
||||
m_partitionType = EDITOR_PARTITION_WATERSHED;
|
||||
if (imguiCheck("Monotone", m_partitionType == EDITOR_PARTITION_MONOTONE))
|
||||
|
||||
isEnabled = m_partitionType == EDITOR_PARTITION_MONOTONE;
|
||||
|
||||
if (ImGui::Checkbox("Monotone", &isEnabled))
|
||||
m_partitionType = EDITOR_PARTITION_MONOTONE;
|
||||
if (imguiCheck("Layers", m_partitionType == EDITOR_PARTITION_LAYERS))
|
||||
|
||||
isEnabled = m_partitionType == EDITOR_PARTITION_LAYERS;
|
||||
|
||||
if (ImGui::Checkbox("Layers", &isEnabled))
|
||||
m_partitionType = EDITOR_PARTITION_LAYERS;
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Filtering");
|
||||
if (imguiCheck("Low Hanging Obstacles", m_filterLowHangingObstacles))
|
||||
m_filterLowHangingObstacles = !m_filterLowHangingObstacles;
|
||||
if (imguiCheck("Ledge Spans", m_filterLedgeSpans))
|
||||
m_filterLedgeSpans= !m_filterLedgeSpans;
|
||||
if (imguiCheck("Walkable Low Height Spans", m_filterWalkableLowHeightSpans))
|
||||
m_filterWalkableLowHeightSpans = !m_filterWalkableLowHeightSpans;
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Filtering");
|
||||
ImGui::Checkbox("Low Hanging Obstacles", &m_filterLowHangingObstacles);
|
||||
ImGui::Checkbox("Ledge Spans", &m_filterLedgeSpans);
|
||||
ImGui::Checkbox("Walkable Low Height Spans", &m_filterWalkableLowHeightSpans);
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Polygonization");
|
||||
imguiSlider("Max Edge Length", &m_edgeMaxLen, 0.0f, 50.0f, 1.0f);
|
||||
imguiSlider("Max Edge Error", &m_edgeMaxError, 0.1f, 3.0f, 0.1f);
|
||||
imguiSlider("Verts Per Poly", &m_vertsPerPoly, 3.0f, 6.0f, 1.0f);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Polygonization");
|
||||
ImGui::SliderInt("Max Edge Length", &m_edgeMaxLen, 0, 50); // todo(amos): increase due to larger scale maps?
|
||||
ImGui::SliderFloat("Max Edge Error", &m_edgeMaxError, 0.1f, 3.0f);
|
||||
ImGui::SliderInt("Verts Per Poly", &m_vertsPerPoly, 3, 6);
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Detail Mesh");
|
||||
imguiSlider("Sample Distance", &m_detailSampleDist, 1.0f, 16.0f, 1.0f);
|
||||
imguiSlider("Max Sample Error", &m_detailSampleMaxError, 0.0f, 16.0f, 1.0f);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Detail Mesh");
|
||||
ImGui::SliderFloat("Sample Distance", &m_detailSampleDist, 1.0f, 16.0f);
|
||||
ImGui::SliderFloat("Max Sample Error", &m_detailSampleMaxError, 0.0f, 16.0f);
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
void Editor::handleClick(const float* s, const float* p, bool shift)
|
||||
|
@ -91,13 +91,13 @@ public:
|
||||
|
||||
virtual void handleMenu()
|
||||
{
|
||||
imguiLabel("Create Tiles");
|
||||
if (imguiButton("Create All"))
|
||||
ImGui::Text("Create Tiles");
|
||||
if (ImGui::Button("Create All"))
|
||||
{
|
||||
if (m_editor)
|
||||
m_editor->buildAllTiles();
|
||||
}
|
||||
if (imguiButton("Remove All"))
|
||||
if (ImGui::Button("Remove All"))
|
||||
{
|
||||
if (m_editor)
|
||||
m_editor->removeAllTiles();
|
||||
@ -150,14 +150,16 @@ public:
|
||||
{
|
||||
int tx=0, ty=0;
|
||||
m_editor->getTilePos(m_hitPos, tx, ty);
|
||||
char text[32];
|
||||
snprintf(text,32,"(%d,%d)", tx,ty);
|
||||
imguiDrawText((int)x, (int)y-25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,220));
|
||||
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "(%d,%d)", tx,ty);
|
||||
}
|
||||
|
||||
// Tool help
|
||||
const int h = view[3];
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.", imguiRGBA(255,255,255,192));
|
||||
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Rebuild hit tile. Shift+LMB: Clear hit tile.");
|
||||
}
|
||||
};
|
||||
|
||||
@ -215,11 +217,11 @@ void Editor_TileMesh::cleanup()
|
||||
m_dmesh = 0;
|
||||
}
|
||||
const hulldef hulls[NAVMESH_COUNT] = {
|
||||
{ g_navMeshNames[NAVMESH_SMALL] , NAI_Hull::Width(HULL_HUMAN) , NAI_Hull::Height(HULL_HUMAN) * NAI_Hull::Scale(HULL_HUMAN) , 45, 32.0f },
|
||||
{ g_navMeshNames[NAVMESH_MED_SHORT] , NAI_Hull::Width(HULL_PROWLER), NAI_Hull::Height(HULL_PROWLER) * NAI_Hull::Scale(HULL_PROWLER), 50, 32.0f },
|
||||
{ g_navMeshNames[NAVMESH_MEDIUM] , NAI_Hull::Width(HULL_MEDIUM) , NAI_Hull::Height(HULL_MEDIUM) * NAI_Hull::Scale(HULL_MEDIUM) , 55, 32.0f },
|
||||
{ g_navMeshNames[NAVMESH_LARGE] , NAI_Hull::Width(HULL_TITAN) , NAI_Hull::Height(HULL_TITAN) * NAI_Hull::Scale(HULL_TITAN) , 60, 64.0f },
|
||||
{ g_navMeshNames[NAVMESH_EXTRA_LARGE], NAI_Hull::Width(HULL_GOLIATH), NAI_Hull::Height(HULL_GOLIATH) * NAI_Hull::Scale(HULL_GOLIATH), 65, 64.0f },
|
||||
{ g_navMeshNames[NAVMESH_SMALL] , NAI_Hull::Width(HULL_HUMAN) , NAI_Hull::Height(HULL_HUMAN) * NAI_Hull::Scale(HULL_HUMAN) , 45, 32 },
|
||||
{ g_navMeshNames[NAVMESH_MED_SHORT] , NAI_Hull::Width(HULL_PROWLER), NAI_Hull::Height(HULL_PROWLER) * NAI_Hull::Scale(HULL_PROWLER), 50, 32 },
|
||||
{ g_navMeshNames[NAVMESH_MEDIUM] , NAI_Hull::Width(HULL_MEDIUM) , NAI_Hull::Height(HULL_MEDIUM) * NAI_Hull::Scale(HULL_MEDIUM) , 55, 32 },
|
||||
{ g_navMeshNames[NAVMESH_LARGE] , NAI_Hull::Width(HULL_TITAN) , NAI_Hull::Height(HULL_TITAN) * NAI_Hull::Scale(HULL_TITAN) , 60, 64 },
|
||||
{ g_navMeshNames[NAVMESH_EXTRA_LARGE], NAI_Hull::Width(HULL_GOLIATH), NAI_Hull::Height(HULL_GOLIATH) * NAI_Hull::Scale(HULL_GOLIATH), 65, 64 },
|
||||
};
|
||||
|
||||
void Editor_TileMesh::selectNavMeshType(const NavMeshType_e navMeshType)
|
||||
@ -241,7 +243,7 @@ void Editor_TileMesh::handleSettings()
|
||||
{
|
||||
const NavMeshType_e navMeshType = NavMeshType_e(i);
|
||||
|
||||
if (imguiButton(NavMesh_GetNameForType(navMeshType)))
|
||||
if (ImGui::Button(NavMesh_GetNameForType(navMeshType)))
|
||||
{
|
||||
selectNavMeshType(navMeshType);
|
||||
}
|
||||
@ -249,14 +251,11 @@ void Editor_TileMesh::handleSettings()
|
||||
|
||||
Editor::handleCommonSettings();
|
||||
|
||||
if (imguiCheck("Keep Intermediate Results", m_keepInterResults))
|
||||
m_keepInterResults = !m_keepInterResults;
|
||||
|
||||
if (imguiCheck("Build All Tiles", m_buildAll))
|
||||
m_buildAll = !m_buildAll;
|
||||
ImGui::Checkbox("Keep Intermediate Results", &m_keepInterResults);
|
||||
ImGui::Checkbox("Build All Tiles", &m_buildAll);
|
||||
|
||||
imguiLabel("Tiling");
|
||||
imguiSlider("TileSize", &m_tileSize, 8.0f, 1024.0f, 8.0f);
|
||||
ImGui::Text("Tiling");
|
||||
ImGui::SliderInt("TileSize", &m_tileSize, 8, 1024);
|
||||
|
||||
if (m_geom)
|
||||
{
|
||||
@ -265,13 +264,13 @@ void Editor_TileMesh::handleSettings()
|
||||
const float* bmin = m_geom->getNavMeshBoundsMin();
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int ts = (int)m_tileSize;
|
||||
const int ts = m_tileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
snprintf(text, sizeof(text), "Tiles %d x %d", tw, th);
|
||||
imguiValue(text);
|
||||
ImGui::Text(text);
|
||||
snprintf(text, sizeof(text), "Tile Sizes %g x %g (%g)", tw*m_cellSize, th*m_cellSize, m_tileSize*m_cellSize);
|
||||
imguiValue(text);
|
||||
ImGui::Text(text);
|
||||
// Max tiles and max polys affect how the tile IDs are calculated.
|
||||
// There are 28 bits available for identifying a tile and a polygon.
|
||||
int tileBits = rcMin((int)ilog2(nextPow2(tw*th)), 16);
|
||||
@ -279,9 +278,9 @@ void Editor_TileMesh::handleSettings()
|
||||
m_maxTiles = 1 << tileBits;
|
||||
m_maxPolysPerTile = 1 << polyBits;
|
||||
snprintf(text, sizeof(text), "Max Tiles %d", m_maxTiles);
|
||||
imguiValue(text);
|
||||
ImGui::Text(text);
|
||||
snprintf(text, sizeof(text), "Max Polys %d", m_maxPolysPerTile);
|
||||
imguiValue(text);
|
||||
ImGui::Text(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -289,12 +288,12 @@ void Editor_TileMesh::handleSettings()
|
||||
m_maxPolysPerTile = 0;
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiIndent();
|
||||
imguiIndent();
|
||||
ImGui::Indent();
|
||||
ImGui::Indent();
|
||||
|
||||
if (imguiButton("Load"))
|
||||
if (ImGui::Button("Load"))
|
||||
{
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = Editor::loadAll(m_modelName.c_str());
|
||||
@ -304,83 +303,84 @@ void Editor_TileMesh::handleSettings()
|
||||
initToolStates(this);
|
||||
}
|
||||
|
||||
if (imguiButton("Save"))
|
||||
if (ImGui::Button("Save"))
|
||||
{
|
||||
Editor::saveAll(m_modelName.c_str(), m_navMesh);
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
char msg[128];
|
||||
snprintf(msg, sizeof(msg), "Build Time: %.1fms", m_totalBuildTimeMs);
|
||||
imguiLabel(msg);
|
||||
ImGui::Text("Build Time: %.1fms", m_totalBuildTimeMs);
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
if (m_navMesh)
|
||||
{
|
||||
const dtNavMeshParams& params = m_navMesh->m_params;
|
||||
const float* origin = m_navMesh->m_orig;
|
||||
|
||||
char result[256];
|
||||
snprintf(result, sizeof(result), "Mesh Origin: <%g, %g, %g>", origin[0], origin[1], origin[2]);
|
||||
imguiLabel(result);
|
||||
snprintf(result, sizeof(result), "Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
|
||||
imguiLabel(result);
|
||||
snprintf(result, sizeof(result), "Poly Group Count: %d", params.polyGroupCount);
|
||||
imguiLabel(result);
|
||||
snprintf(result, sizeof(result), "Traversal Table Size: %d", params.traversalTableSize);
|
||||
imguiLabel(result);
|
||||
snprintf(result, sizeof(result), "Traversal Table Count: %d", params.traversalTableCount);
|
||||
imguiLabel(result);
|
||||
snprintf(result, sizeof(result), "Max Tiles: %d", params.maxTiles);
|
||||
imguiLabel(result);
|
||||
snprintf(result, sizeof(result), "Max Polys: %d", params.maxPolys);
|
||||
imguiLabel(result);
|
||||
ImGui::Text("Mesh Origin: <%g, %g, %g>", origin[0], origin[1], origin[2]);
|
||||
ImGui::Text("Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
|
||||
ImGui::Text("Poly Group Count: %d", params.polyGroupCount);
|
||||
ImGui::Text("Traversal Table Size: %d", params.traversalTableSize);
|
||||
ImGui::Text("Traversal Table Count: %d", params.traversalTableCount);
|
||||
ImGui::Text("Max Tiles: %d", params.maxTiles);
|
||||
ImGui::Text("Max Polys: %d", params.maxPolys);
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
}
|
||||
|
||||
void Editor_TileMesh::handleTools()
|
||||
{
|
||||
int type = !m_tool ? TOOL_NONE : m_tool->type();
|
||||
bool isEnabled = type == TOOL_NAVMESH_TESTER;
|
||||
|
||||
if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
|
||||
if (ImGui::Checkbox("Test Navmesh", &isEnabled))
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
if (imguiCheck("Prune Navmesh", type == TOOL_NAVMESH_PRUNE))
|
||||
|
||||
isEnabled = type == TOOL_NAVMESH_PRUNE;
|
||||
if (ImGui::Checkbox("Prune Navmesh", &isEnabled))
|
||||
{
|
||||
setTool(new NavMeshPruneTool);
|
||||
}
|
||||
if (imguiCheck("Create Tiles", type == TOOL_TILE_EDIT))
|
||||
|
||||
isEnabled = type == TOOL_TILE_EDIT;
|
||||
if (ImGui::Checkbox("Create Tiles", &isEnabled))
|
||||
{
|
||||
setTool(new NavMeshTileTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
|
||||
|
||||
isEnabled = type == TOOL_OFFMESH_CONNECTION;
|
||||
if (ImGui::Checkbox("Create Off-Mesh Links", &isEnabled))
|
||||
{
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
|
||||
|
||||
isEnabled = type == TOOL_CONVEX_VOLUME;
|
||||
if (ImGui::Checkbox("Create Convex Volumes", &isEnabled))
|
||||
{
|
||||
setTool(new ConvexVolumeTool);
|
||||
}
|
||||
if (imguiCheck("Create Crowds", type == TOOL_CROWD))
|
||||
|
||||
isEnabled = type == TOOL_CROWD;
|
||||
if (ImGui::Checkbox("Create Crowds", &isEnabled))
|
||||
{
|
||||
setTool(new CrowdTool);
|
||||
}
|
||||
|
||||
imguiSeparatorLine();
|
||||
ImGui::Separator(); // was imguiSeperatorLine
|
||||
|
||||
imguiIndent();
|
||||
ImGui::Indent();
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleMenu();
|
||||
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
void Editor_TileMesh::handleDebugMode()
|
||||
@ -419,81 +419,209 @@ void Editor_TileMesh::handleDebugMode()
|
||||
if (unavail == MAX_DRAWMODE)
|
||||
return;
|
||||
|
||||
imguiLabel("Render Options");
|
||||
ImGui::Text("Render Options");
|
||||
|
||||
if (imguiCheck("Draw Off-Mesh Connections", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OFFMESHCONS)))
|
||||
bool isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (ImGui::Checkbox("Draw Off-Mesh Connections", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (imguiCheck("Draw Closed List", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_CLOSEDLIST)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
if (ImGui::Checkbox("Draw Closed List", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
if (imguiCheck("Draw Tile ID Colors", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_COLOR_TILES)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_COLOR_TILES);
|
||||
|
||||
if (ImGui::Checkbox("Draw Tile ID Colors", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_COLOR_TILES);
|
||||
|
||||
if (imguiCheck("Draw Vertex Points", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_VERTS)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_VERTS);
|
||||
|
||||
if (ImGui::Checkbox("Draw Vertex Points", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_VERTS);
|
||||
|
||||
if (imguiCheck("Draw Inner Poly Boundaries", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_INNERBOUND)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_INNERBOUND);
|
||||
|
||||
if (ImGui::Checkbox("Draw Inner Poly Boundaries", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_INNERBOUND);
|
||||
|
||||
if (imguiCheck("Draw Outer Poly Boundaries", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OUTERBOUND)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OUTERBOUND);
|
||||
|
||||
if (ImGui::Checkbox("Draw Outer Poly Boundaries", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OUTERBOUND);
|
||||
|
||||
if (imguiCheck("Draw Poly Centers", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYCENTERS)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYCENTERS);
|
||||
|
||||
if (ImGui::Checkbox("Draw Poly Centers", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYCENTERS);
|
||||
|
||||
if (imguiCheck("Draw Poly Groups", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYGROUPS)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYGROUPS);
|
||||
|
||||
if (ImGui::Checkbox("Draw Poly Groups", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYGROUPS);
|
||||
|
||||
if (imguiCheck("Disable NavMesh Depth Mask", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_DEPTH_MASK)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_DEPTH_MASK);
|
||||
|
||||
if (ImGui::Checkbox("Disable NavMesh Depth Mask", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_NO_DEPTH_MASK);
|
||||
|
||||
if (imguiCheck("Disable NavMesh Transparency", (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_ALPHA)))
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NO_ALPHA);
|
||||
|
||||
if (ImGui::Checkbox("Disable NavMesh Transparency", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_NO_ALPHA);
|
||||
|
||||
imguiLabel("Draw");
|
||||
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
|
||||
ImGui::Text("Draw");
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_MESH;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_MESH]);
|
||||
|
||||
if (ImGui::Checkbox("Input Mesh", &isEnabled))
|
||||
m_drawMode = DRAWMODE_MESH;
|
||||
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_NAVMESH;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH]);
|
||||
|
||||
if (ImGui::Checkbox("Navmesh", &isEnabled))
|
||||
m_drawMode = DRAWMODE_NAVMESH;
|
||||
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_NAVMESH_INVIS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_INVIS]);
|
||||
|
||||
if (ImGui::Checkbox("Navmesh Invis", &isEnabled))
|
||||
m_drawMode = DRAWMODE_NAVMESH_INVIS;
|
||||
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_NAVMESH_TRANS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_TRANS]);
|
||||
|
||||
if (ImGui::Checkbox("Navmesh Trans", &isEnabled))
|
||||
m_drawMode = DRAWMODE_NAVMESH_TRANS;
|
||||
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_NAVMESH_BVTREE;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_BVTREE]);
|
||||
|
||||
if (ImGui::Checkbox("Navmesh BVTree", &isEnabled))
|
||||
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
|
||||
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_NAVMESH_NODES;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_NODES]);
|
||||
|
||||
if (ImGui::Checkbox("Navmesh Nodes", &isEnabled))
|
||||
m_drawMode = DRAWMODE_NAVMESH_NODES;
|
||||
if (imguiCheck("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS, valid[DRAWMODE_NAVMESH_PORTALS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_NAVMESH_PORTALS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_NAVMESH_PORTALS]);
|
||||
|
||||
if (ImGui::Checkbox("Navmesh Portals", &isEnabled))
|
||||
m_drawMode = DRAWMODE_NAVMESH_PORTALS;
|
||||
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_VOXELS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_VOXELS]);
|
||||
|
||||
if (ImGui::Checkbox("Voxels", &isEnabled))
|
||||
m_drawMode = DRAWMODE_VOXELS;
|
||||
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_VOXELS_WALKABLE;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_VOXELS_WALKABLE]);
|
||||
|
||||
if (ImGui::Checkbox("Walkable Voxels", &isEnabled))
|
||||
m_drawMode = DRAWMODE_VOXELS_WALKABLE;
|
||||
if (imguiCheck("Compact", m_drawMode == DRAWMODE_COMPACT, valid[DRAWMODE_COMPACT]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_COMPACT;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_COMPACT]);
|
||||
|
||||
if (ImGui::Checkbox("Compact", &isEnabled))
|
||||
m_drawMode = DRAWMODE_COMPACT;
|
||||
if (imguiCheck("Compact Distance", m_drawMode == DRAWMODE_COMPACT_DISTANCE, valid[DRAWMODE_COMPACT_DISTANCE]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_COMPACT_DISTANCE;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_COMPACT_DISTANCE]);
|
||||
|
||||
if (ImGui::Checkbox("Compact Distance", &isEnabled))
|
||||
m_drawMode = DRAWMODE_COMPACT_DISTANCE;
|
||||
if (imguiCheck("Compact Regions", m_drawMode == DRAWMODE_COMPACT_REGIONS, valid[DRAWMODE_COMPACT_REGIONS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_COMPACT_REGIONS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_COMPACT_REGIONS]);
|
||||
|
||||
if (ImGui::Checkbox("Compact Regions", &isEnabled))
|
||||
m_drawMode = DRAWMODE_COMPACT_REGIONS;
|
||||
if (imguiCheck("Region Connections", m_drawMode == DRAWMODE_REGION_CONNECTIONS, valid[DRAWMODE_REGION_CONNECTIONS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_REGION_CONNECTIONS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_REGION_CONNECTIONS]);
|
||||
|
||||
if (ImGui::Checkbox("Region Connections", &isEnabled))
|
||||
m_drawMode = DRAWMODE_REGION_CONNECTIONS;
|
||||
if (imguiCheck("Raw Contours", m_drawMode == DRAWMODE_RAW_CONTOURS, valid[DRAWMODE_RAW_CONTOURS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_RAW_CONTOURS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_RAW_CONTOURS]);
|
||||
|
||||
if (ImGui::Checkbox("Raw Contours", &isEnabled))
|
||||
m_drawMode = DRAWMODE_RAW_CONTOURS;
|
||||
if (imguiCheck("Both Contours", m_drawMode == DRAWMODE_BOTH_CONTOURS, valid[DRAWMODE_BOTH_CONTOURS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_BOTH_CONTOURS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_BOTH_CONTOURS]);
|
||||
|
||||
if (ImGui::Checkbox("Both Contours", &isEnabled))
|
||||
m_drawMode = DRAWMODE_BOTH_CONTOURS;
|
||||
if (imguiCheck("Contours", m_drawMode == DRAWMODE_CONTOURS, valid[DRAWMODE_CONTOURS]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_CONTOURS;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_CONTOURS]);
|
||||
|
||||
if (ImGui::Checkbox("Contours", &isEnabled))
|
||||
m_drawMode = DRAWMODE_CONTOURS;
|
||||
if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_POLYMESH;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_POLYMESH]);
|
||||
|
||||
if (ImGui::Checkbox("Poly Mesh", &isEnabled))
|
||||
m_drawMode = DRAWMODE_POLYMESH;
|
||||
if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL]))
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_drawMode == DRAWMODE_POLYMESH_DETAIL;
|
||||
ImGui::BeginDisabled(!valid[DRAWMODE_POLYMESH_DETAIL]);
|
||||
|
||||
if (ImGui::Checkbox("Poly Mesh Detail", &isEnabled))
|
||||
m_drawMode = DRAWMODE_POLYMESH_DETAIL;
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (unavail)
|
||||
{
|
||||
imguiValue("Tick 'Keep Intermediate Results'");
|
||||
imguiValue("rebuild some tiles to see");
|
||||
imguiValue("more debug mode options.");
|
||||
ImGui::Text("Tick 'Keep Intermediate Results'");
|
||||
ImGui::Text("rebuild some tiles to see");
|
||||
ImGui::Text("more debug mode options.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,8 +652,8 @@ void Editor_TileMesh::handleRender()
|
||||
// Tiling grid.
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int tw = (gw + (int)m_tileSize-1) / (int)m_tileSize;
|
||||
const int th = (gh + (int)m_tileSize-1) / (int)m_tileSize;
|
||||
const int tw = (gw + m_tileSize-1) / m_tileSize;
|
||||
const int th = (gh + m_tileSize-1) / m_tileSize;
|
||||
const float s = m_tileSize*m_cellSize;
|
||||
duDebugDrawGridXY(&m_dd, bmax[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
|
||||
|
||||
@ -633,9 +761,8 @@ void Editor_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
|
||||
if (m_tileBuildTime > 0.0f && gluProject((GLdouble)(m_lastBuiltTileBmin[0]+m_lastBuiltTileBmax[0])/2, (GLdouble)(m_lastBuiltTileBmin[1]+m_lastBuiltTileBmax[1])/2, (GLdouble)(m_lastBuiltTileBmin[2]+m_lastBuiltTileBmax[2])/2,
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
char text[32];
|
||||
snprintf(text,32,"%.3fms / %dTris / %.1fkB", m_tileBuildTime, m_tileTriCount, m_tileMemUsage);
|
||||
imguiDrawText((int)x, (int)y-25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "%.3fms / %dTris / %.1fkB", m_tileBuildTime, m_tileTriCount, m_tileMemUsage);
|
||||
}
|
||||
|
||||
if (m_tool)
|
||||
@ -810,7 +937,7 @@ void Editor_TileMesh::buildAllTiles()
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int ts = (int)m_tileSize;
|
||||
const int ts = m_tileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
|
||||
@ -865,7 +992,7 @@ void Editor_TileMesh::removeAllTiles()
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int ts = (int)m_tileSize;
|
||||
const int ts = m_tileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
|
||||
@ -922,10 +1049,10 @@ unsigned char* Editor_TileMesh::buildTileMesh(const int tx, const int ty, const
|
||||
m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs);
|
||||
m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
|
||||
m_cfg.maxSimplificationError = m_edgeMaxError;
|
||||
m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
m_cfg.minRegionArea = rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
m_cfg.mergeRegionArea = rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
|
||||
m_cfg.tileSize = (int)m_tileSize;
|
||||
m_cfg.tileSize = m_tileSize;
|
||||
m_cfg.borderSize = m_cfg.walkableRadius + 3; // Reserve enough padding.
|
||||
m_cfg.width = m_cfg.tileSize + m_cfg.borderSize*2;
|
||||
m_cfg.height = m_cfg.tileSize + m_cfg.borderSize*2;
|
||||
|
@ -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,
|
||||
|
@ -211,12 +211,12 @@ void NavMeshPruneTool::handleMenu()
|
||||
if (!nav) return;
|
||||
if (!m_flags) return;
|
||||
|
||||
if (imguiButton("Clear Selection"))
|
||||
if (ImGui::Button("Clear Selection"))
|
||||
{
|
||||
m_flags->clearAllFlags();
|
||||
}
|
||||
|
||||
if (imguiButton("Prune Unselected"))
|
||||
if (ImGui::Button("Prune Unselected"))
|
||||
{
|
||||
disableUnvisitedPolys(nav, m_flags);
|
||||
delete m_flags;
|
||||
@ -312,5 +312,6 @@ void NavMeshPruneTool::handleRenderOverlay(double* proj, double* model, int* vie
|
||||
// Tool help
|
||||
const int h = view[3];
|
||||
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Click fill area.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Click fill area.");
|
||||
}
|
||||
|
@ -212,80 +212,109 @@ void NavMeshTesterTool::init(Editor* editor)
|
||||
|
||||
void NavMeshTesterTool::handleMenu()
|
||||
{
|
||||
if (imguiCheck("Pathfind Follow", m_toolMode == TOOLMODE_PATHFIND_FOLLOW))
|
||||
bool isEnabled = m_toolMode == TOOLMODE_PATHFIND_FOLLOW;
|
||||
|
||||
if (ImGui::Checkbox("Pathfind Follow", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_PATHFIND_FOLLOW;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Pathfind Straight", m_toolMode == TOOLMODE_PATHFIND_STRAIGHT))
|
||||
|
||||
isEnabled = m_toolMode == TOOLMODE_PATHFIND_STRAIGHT;
|
||||
|
||||
if (ImGui::Checkbox("Pathfind Straight", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_PATHFIND_STRAIGHT;
|
||||
recalc();
|
||||
}
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
|
||||
{
|
||||
imguiIndent();
|
||||
imguiLabel("Vertices at crossings");
|
||||
if (imguiCheck("None", m_straightPathOptions == 0))
|
||||
ImGui::Indent();
|
||||
ImGui::Text("Vertices at crossings");
|
||||
|
||||
isEnabled = m_straightPathOptions == 0;
|
||||
|
||||
if (ImGui::Checkbox("None", &isEnabled))
|
||||
{
|
||||
m_straightPathOptions = 0;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Area", m_straightPathOptions == DT_STRAIGHTPATH_AREA_CROSSINGS))
|
||||
|
||||
isEnabled = m_straightPathOptions == DT_STRAIGHTPATH_AREA_CROSSINGS;
|
||||
|
||||
if (ImGui::Checkbox("Area", &isEnabled))
|
||||
{
|
||||
m_straightPathOptions = DT_STRAIGHTPATH_AREA_CROSSINGS;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("All", m_straightPathOptions == DT_STRAIGHTPATH_ALL_CROSSINGS))
|
||||
|
||||
isEnabled = m_straightPathOptions == DT_STRAIGHTPATH_ALL_CROSSINGS;
|
||||
|
||||
if (ImGui::Checkbox("All", &isEnabled))
|
||||
{
|
||||
m_straightPathOptions = DT_STRAIGHTPATH_ALL_CROSSINGS;
|
||||
recalc();
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
}
|
||||
if (imguiCheck("Pathfind Sliced", m_toolMode == TOOLMODE_PATHFIND_SLICED))
|
||||
|
||||
isEnabled = m_straightPathOptions == TOOLMODE_PATHFIND_SLICED;
|
||||
|
||||
if (ImGui::Checkbox("Pathfind Sliced", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_PATHFIND_SLICED;
|
||||
recalc();
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
if (imguiCheck("Distance to Wall", m_toolMode == TOOLMODE_DISTANCE_TO_WALL))
|
||||
isEnabled = m_toolMode == TOOLMODE_DISTANCE_TO_WALL;
|
||||
|
||||
if (ImGui::Checkbox("Distance to Wall", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_DISTANCE_TO_WALL;
|
||||
recalc();
|
||||
}
|
||||
|
||||
if (imguiCheck("Raycast", m_toolMode == TOOLMODE_RAYCAST))
|
||||
isEnabled = m_toolMode == TOOLMODE_RAYCAST;
|
||||
|
||||
if (ImGui::Checkbox("Raycast", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_RAYCAST;
|
||||
recalc();
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
if (imguiCheck("Find Polys in Circle", m_toolMode == TOOLMODE_FIND_POLYS_IN_CIRCLE))
|
||||
isEnabled = m_toolMode == TOOLMODE_FIND_POLYS_IN_CIRCLE;
|
||||
|
||||
if (ImGui::Checkbox("Find Polys in Circle", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_FIND_POLYS_IN_CIRCLE;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Find Polys in Shape", m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE))
|
||||
|
||||
isEnabled = m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE;
|
||||
|
||||
if (ImGui::Checkbox("Find Polys in Shape", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_FIND_POLYS_IN_SHAPE;
|
||||
recalc();
|
||||
}
|
||||
|
||||
if (imguiCheck("Find Local Neighbourhood", m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD))
|
||||
isEnabled = m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD;
|
||||
|
||||
if (ImGui::Checkbox("Find Local Neighbourhood", &isEnabled))
|
||||
{
|
||||
m_toolMode = TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD;
|
||||
recalc();
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
if (imguiButton("Set Random Start"))
|
||||
if (ImGui::Button("Set Random Start"))
|
||||
{
|
||||
dtStatus status = m_navQuery->findRandomPoint(&m_filter, frand, &m_startRef, m_spos);
|
||||
if (dtStatusSucceed(status))
|
||||
@ -294,7 +323,10 @@ void NavMeshTesterTool::handleMenu()
|
||||
recalc();
|
||||
}
|
||||
}
|
||||
if (imguiButton("Set Random End", m_sposSet))
|
||||
|
||||
ImGui::BeginDisabled(m_sposSet);
|
||||
|
||||
if (ImGui::Button("Set Random End"))
|
||||
{
|
||||
if (m_sposSet)
|
||||
{
|
||||
@ -307,9 +339,11 @@ void NavMeshTesterTool::handleMenu()
|
||||
}
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (imguiButton("Make Random Points"))
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button("Make Random Points"))
|
||||
{
|
||||
m_randPointsInCircle = false;
|
||||
m_nrandPoints = 0;
|
||||
@ -325,7 +359,10 @@ void NavMeshTesterTool::handleMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (imguiButton("Make Random Points Around", m_sposSet))
|
||||
|
||||
ImGui::BeginDisabled(m_sposSet);
|
||||
|
||||
if (ImGui::Button("Make Random Points Around"))
|
||||
{
|
||||
if (m_sposSet)
|
||||
{
|
||||
@ -345,64 +382,89 @@ void NavMeshTesterTool::handleMenu()
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiLabel("Include Flags");
|
||||
ImGui::Text("Include Flags");
|
||||
|
||||
imguiIndent();
|
||||
if (imguiCheck("Walk", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_WALK) != 0))
|
||||
ImGui::Indent();
|
||||
|
||||
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_WALK) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Walk", &isEnabled))
|
||||
{
|
||||
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_WALK);
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Swim", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0))
|
||||
|
||||
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Swim", &isEnabled))
|
||||
{
|
||||
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_SWIM);
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Door", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0))
|
||||
|
||||
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Door", &isEnabled))
|
||||
{
|
||||
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_DOOR);
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Jump", (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0))
|
||||
|
||||
isEnabled = (m_filter.getIncludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Jump", &isEnabled))
|
||||
{
|
||||
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ EDITOR_POLYFLAGS_JUMP);
|
||||
recalc();
|
||||
}
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Exclude Flags");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Exclude Flags");
|
||||
|
||||
imguiIndent();
|
||||
if (imguiCheck("Walk", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_WALK) != 0))
|
||||
ImGui::Indent();
|
||||
|
||||
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_WALK) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Walk", &isEnabled))
|
||||
{
|
||||
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_WALK);
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Swim", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0))
|
||||
|
||||
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_SWIM) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Swim", &isEnabled))
|
||||
{
|
||||
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_SWIM);
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Door", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0))
|
||||
|
||||
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_DOOR) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Door", &isEnabled))
|
||||
{
|
||||
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_DOOR);
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Jump", (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0))
|
||||
|
||||
isEnabled = (m_filter.getExcludeFlags() & EDITOR_POLYFLAGS_JUMP) != 0;
|
||||
|
||||
if (ImGui::Checkbox("Jump", &isEnabled))
|
||||
{
|
||||
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ EDITOR_POLYFLAGS_JUMP);
|
||||
recalc();
|
||||
}
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Traverse Anim Type");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Traverse Anim Type");
|
||||
|
||||
imguiIndent();
|
||||
ImGui::Indent();
|
||||
|
||||
const NavMeshType_e loadedNavMeshType = m_editor->getLoadedNavMeshType();
|
||||
|
||||
@ -416,16 +478,18 @@ void NavMeshTesterTool::handleMenu()
|
||||
const bool noAnimtype = i == ANIMTYPE_NONE;
|
||||
|
||||
const TraverseAnimType_e animTypeIndex = noAnimtype ? ANIMTYPE_NONE : TraverseAnimType_e((int)baseType + i);
|
||||
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex];
|
||||
const char* animtypeName = noAnimtype ? "none" : g_traverseAnimTypeNames[animTypeIndex]; // todo(amos): crashes sometimes when animTypeIndex = ANIMTYPE_NONE
|
||||
|
||||
if (imguiCheck(animtypeName, m_traverseAnimType == animTypeIndex))
|
||||
isEnabled = m_traverseAnimType == animTypeIndex;
|
||||
|
||||
if (ImGui::Checkbox(animtypeName, &isEnabled))
|
||||
{
|
||||
m_traverseAnimType = animTypeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
imguiSeparator();
|
||||
ImGui::Unindent();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
void NavMeshTesterTool::handleClick(const float* /*s*/, const float* p, bool shift)
|
||||
@ -1358,12 +1422,14 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
|
||||
if (m_sposSet && gluProject((GLdouble)m_spos[0], (GLdouble)m_spos[1], (GLdouble)m_spos[2],
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "Start");
|
||||
}
|
||||
if (m_eposSet && gluProject((GLdouble)m_epos[0], (GLdouble)m_epos[1], (GLdouble)m_epos[2],
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "End", imguiRGBA(0,0,0,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "End");
|
||||
}
|
||||
|
||||
// Useful utility to draw all polygroup id's at the center of the polygons.
|
||||
@ -1393,7 +1459,7 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
|
||||
// {
|
||||
// char label[6];
|
||||
// snprintf(label, sizeof(label), "%hu", poly->groupId);
|
||||
// imguiDrawText((int)x, (int)y, IMGUI_ALIGN_CENTER, label, imguiRGBA(0, 0, 0, 220));
|
||||
// ImGui::TextColored((int)x, (int)y, IMGUI_ALIGN_CENTER, label, ImVec4(0, 0, 0, 220));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@ -1401,7 +1467,9 @@ void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* vi
|
||||
|
||||
// Tool help
|
||||
const int h = view[3];
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB+SHIFT: Set start location LMB: Set end location", imguiRGBA(255,255,255,192));
|
||||
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB+SHIFT: Set start location LMB: Set end location");
|
||||
}
|
||||
|
||||
void NavMeshTesterTool::drawAgent(const float* pos, float r, float h, float c, const unsigned int col)
|
||||
|
@ -61,9 +61,14 @@ void OffMeshConnectionTool::reset()
|
||||
|
||||
void OffMeshConnectionTool::handleMenu()
|
||||
{
|
||||
if (imguiCheck("One Way", !m_bidir))
|
||||
bool isOneWay = !m_bidir;
|
||||
|
||||
if (ImGui::Checkbox("One Way", &isOneWay))
|
||||
m_bidir = false;
|
||||
if (imguiCheck("Bidirectional", m_bidir))
|
||||
|
||||
bool isBiDirectional = m_bidir;
|
||||
|
||||
if (ImGui::Checkbox("Bidirectional", &isBiDirectional))
|
||||
m_bidir = true;
|
||||
}
|
||||
|
||||
@ -148,17 +153,20 @@ void OffMeshConnectionTool::handleRenderOverlay(double* proj, double* model, int
|
||||
if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220));
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
|
||||
ImGui::TextColored(ImVec4(0,0,0,220), "Start");
|
||||
}
|
||||
|
||||
// Tool help
|
||||
const int h = view[3];
|
||||
if (!m_hitPosSet)
|
||||
{
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Create new connection. SHIFT+LMB: Delete existing connection, click close to start or end point.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Create new connection. SHIFT+LMB: Delete existing connection, click close to start or end point.");
|
||||
}
|
||||
else
|
||||
{
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Set connection end point and finish.", imguiRGBA(255,255,255,192));
|
||||
ImGui::SetCursorPos(ImVec2(280, (float)h-40));
|
||||
ImGui::TextColored(ImVec4(255,255,255,192), "LMB: Set connection end point and finish.");
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ void TestCase::handleRender()
|
||||
bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
{
|
||||
GLdouble x, y, z;
|
||||
char text[64], subtext[64];
|
||||
char text[256];
|
||||
int n = 0;
|
||||
|
||||
static const float LABEL_DIST = 1.0f;
|
||||
@ -406,46 +406,46 @@ bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
if (gluProject((GLdouble)pt[0], (GLdouble)pt[1], (GLdouble)pt[2],
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
snprintf(text, 64, "Path %d\n", n);
|
||||
unsigned int col = imguiRGBA(0,0,0,128);
|
||||
ImVec4 col = ImVec4(0,0,0,128);
|
||||
if (iter->expand)
|
||||
col = imguiRGBA(255,192,0,220);
|
||||
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, text, col);
|
||||
col = ImVec4(255,192,0,220);
|
||||
|
||||
ImGui::SetCursorPos(ImVec2((float)x, (float)y-25));
|
||||
ImGui::TextColored(col, "Path %d\n", n);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
static int resScroll = 0;
|
||||
bool mouseOverMenu = imguiBeginScrollArea("Test Results", 10, view[3] - 10 - 350, 200, 350, &resScroll);
|
||||
// mouseOverMenu = true;
|
||||
|
||||
n = 0;
|
||||
for (Test* iter = m_tests; iter; iter = iter->next)
|
||||
if (ImGui::BeginChild("Test Results", ImVec2(200, 350)))
|
||||
{
|
||||
const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
|
||||
snprintf(subtext, 64, "%.4f ms", (float)total/1000.0f);
|
||||
snprintf(text, 64, "Path %d", n);
|
||||
|
||||
if (imguiCollapse(text, subtext, iter->expand))
|
||||
iter->expand = !iter->expand;
|
||||
if (iter->expand)
|
||||
n = 0;
|
||||
for (Test* iter = m_tests; iter; iter = iter->next)
|
||||
{
|
||||
snprintf(text, 64, "Poly: %.4f ms", (float)iter->findNearestPolyTime/1000.0f);
|
||||
imguiValue(text);
|
||||
const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
|
||||
snprintf(text, sizeof(text), "Path %d %.4f ms", n, (float)total / 1000.0f);
|
||||
|
||||
snprintf(text, 64, "Path: %.4f ms", (float)iter->findPathTime/1000.0f);
|
||||
imguiValue(text);
|
||||
if (ImGui::CollapsingHeader(text))
|
||||
{
|
||||
iter->expand = true;
|
||||
|
||||
snprintf(text, 64, "Straight: %.4f ms", (float)iter->findStraightPathTime/1000.0f);
|
||||
imguiValue(text);
|
||||
|
||||
imguiSeparator();
|
||||
snprintf(text, sizeof(text), "Poly: %.4f ms", (float)iter->findNearestPolyTime / 1000.0f);
|
||||
ImGui::Text(text);
|
||||
|
||||
snprintf(text, sizeof(text), "Path: %.4f ms", (float)iter->findPathTime / 1000.0f);
|
||||
ImGui::Text(text);
|
||||
|
||||
snprintf(text, sizeof(text), "Straight: %.4f ms", (float)iter->findStraightPathTime / 1000.0f);
|
||||
ImGui::Text(text);
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
else
|
||||
iter->expand = false;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
|
||||
return mouseOverMenu;
|
||||
ImGui::EndChild();
|
||||
return true;
|
||||
}
|
||||
|
@ -55,58 +55,85 @@ void GraphParams::setValueRange(float ivmin, float ivmax, int indiv, const char*
|
||||
strcpy(units, iunits);
|
||||
}
|
||||
|
||||
const static ImGuiWindowFlags s_graphWindowFlags = ImGuiWindowFlags_NoBackground|ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove;
|
||||
|
||||
void drawGraphBackground(const GraphParams* p)
|
||||
{
|
||||
ImGui::Begin("GraphBackGround", nullptr, s_graphWindowFlags);
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
|
||||
// BG
|
||||
imguiDrawRoundedRect((float)p->x, (float)p->y, (float)p->w, (float)p->h, (float)p->pad, imguiRGBA(64,64,64,128));
|
||||
|
||||
const float sy = (p->h-p->pad*2) / (p->vmax-p->vmin);
|
||||
const float oy = p->y+p->pad-p->vmin*sy;
|
||||
|
||||
drawList->AddRectFilled(
|
||||
ImVec2(static_cast<float>(p->x), static_cast<float>(p->y)),
|
||||
ImVec2(static_cast<float>(p->x + p->w), static_cast<float>(p->y + p->h)),
|
||||
IM_COL32(64, 64, 64, 128), 0.0f);
|
||||
|
||||
const float sy = (p->h - p->pad * 2) / (p->vmax - p->vmin);
|
||||
const float oy = p->y + p->pad - p->vmin * sy;
|
||||
|
||||
char text[64];
|
||||
|
||||
|
||||
// Divider Lines
|
||||
for (int i = 0; i <= p->ndiv; ++i)
|
||||
{
|
||||
const float u = (float)i/(float)p->ndiv;
|
||||
const float v = p->vmin + (p->vmax-p->vmin)*u;
|
||||
const float u = static_cast<float>(i) / static_cast<float>(p->ndiv);
|
||||
const float v = p->vmin + (p->vmax - p->vmin) * u;
|
||||
snprintf(text, 64, "%.2f %s", v, p->units);
|
||||
const float fy = oy + v*sy;
|
||||
imguiDrawText(p->x + p->w - p->pad, (int)fy-4, IMGUI_ALIGN_RIGHT, text, imguiRGBA(0,0,0,255));
|
||||
imguiDrawLine((float)p->x + (float)p->pad, fy, (float)p->x + (float)p->w - (float)p->pad - 50, fy, 1.0f, imguiRGBA(0,0,0,64));
|
||||
float fy = oy + v * sy;
|
||||
drawList->AddText(
|
||||
ImVec2(static_cast<float>(p->x + p->w - p->pad), fy - 4),
|
||||
IM_COL32(0, 0, 0, 255), text);
|
||||
drawList->AddLine(
|
||||
ImVec2(static_cast<float>(p->x + p->pad), fy),
|
||||
ImVec2(static_cast<float>(p->x + p->w - p->pad - 50), fy),
|
||||
IM_COL32(0, 0, 0, 64), 1.0f);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void drawGraph(const GraphParams* p, const ValueHistory* graph,
|
||||
int idx, const char* label, const unsigned int col)
|
||||
int idx, const char* label, const unsigned int col)
|
||||
{
|
||||
const float sx = (p->w - p->pad*2) / (float)graph->getSampleCount();
|
||||
const float sy = (p->h - p->pad*2) / (p->vmax - p->vmin);
|
||||
const float ox = (float)p->x + (float)p->pad;
|
||||
const float oy = (float)p->y + (float)p->pad - p->vmin*sy;
|
||||
|
||||
ImGui::Begin("Graph", nullptr, s_graphWindowFlags);
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
|
||||
const float sx = (p->w - p->pad * 2) / static_cast<float>(graph->getSampleCount());
|
||||
const float sy = (p->h - p->pad * 2) / (p->vmax - p->vmin);
|
||||
const float ox = static_cast<float>(p->x) + static_cast<float>(p->pad);
|
||||
const float oy = static_cast<float>(p->y) + static_cast<float>(p->pad) - p->vmin * sy;
|
||||
|
||||
// Values
|
||||
float px=0, py=0;
|
||||
for (int i = 0; i < graph->getSampleCount()-1; ++i)
|
||||
{
|
||||
const float x = ox + i*sx;
|
||||
const float y = oy + graph->getSample(i)*sy;
|
||||
float px = 0, py = 0;
|
||||
for (int i = 0; i < graph->getSampleCount() - 1; ++i) {
|
||||
const float x = ox + i * sx;
|
||||
const float y = oy + graph->getSample(i) * sy;
|
||||
if (i > 0)
|
||||
imguiDrawLine(px,py, x,y, 2.0f, col);
|
||||
drawList->AddLine(
|
||||
ImVec2(px, py), ImVec2(x, y), col, 2.0f);
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
|
||||
|
||||
// Label
|
||||
const int size = 15;
|
||||
const int spacing = 10;
|
||||
int ix = p->x + p->w + 5;
|
||||
int iy = p->y + p->h - (idx+1)*(size+spacing);
|
||||
|
||||
imguiDrawRoundedRect((float)ix, (float)iy, (float)size, (float)size, 2.0f, col);
|
||||
|
||||
int iy = p->y + p->h - (idx + 1) * (size + spacing);
|
||||
|
||||
drawList->AddRectFilled(
|
||||
ImVec2(static_cast<float>(ix), static_cast<float>(iy)),
|
||||
ImVec2(static_cast<float>(ix + size), static_cast<float>(iy + size)),
|
||||
col);
|
||||
|
||||
char text[64];
|
||||
snprintf(text, 64, "%.2f %s", graph->getAverage(), p->units);
|
||||
imguiDrawText(ix+size+5, iy+3, IMGUI_ALIGN_LEFT, label, imguiRGBA(255,255,255,192));
|
||||
imguiDrawText(ix+size+150, iy+3, IMGUI_ALIGN_RIGHT, text, imguiRGBA(255,255,255,128));
|
||||
drawList->AddText(
|
||||
ImVec2(static_cast<float>(ix + size + 5), static_cast<float>(iy + 3)),
|
||||
IM_COL32(255, 255, 255, 192), label);
|
||||
drawList->AddText(
|
||||
ImVec2(static_cast<float>(ix + size + 150), static_cast<float>(iy + 3)),
|
||||
IM_COL32(255, 255, 255, 128), text);
|
||||
|
||||
ImGui::End(); // Zijn toch die enge dinge mannn
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -31,7 +31,7 @@
|
||||
|
||||
struct CrowdToolParams
|
||||
{
|
||||
bool m_expandSelectedDebugDraw;
|
||||
bool m_expandSelectedDebugDraw; // todo(amos): imgui upgrade; needed?
|
||||
bool m_showCorners;
|
||||
bool m_showCollisionSegments;
|
||||
bool m_showPath;
|
||||
@ -39,20 +39,20 @@ struct CrowdToolParams
|
||||
bool m_showOpt;
|
||||
bool m_showNeis;
|
||||
|
||||
bool m_expandDebugDraw;
|
||||
bool m_expandDebugDraw; // todo(amos): imgui upgrade; needed?
|
||||
bool m_showLabels;
|
||||
bool m_showGrid;
|
||||
bool m_showNodes;
|
||||
bool m_showPerfGraph;
|
||||
bool m_showDetailAll;
|
||||
|
||||
bool m_expandOptions;
|
||||
bool m_expandTraversalOptions;
|
||||
bool m_expandOptions; // todo(amos): imgui upgrade; needed?
|
||||
bool m_expandTraversalOptions; // todo(amos): imgui upgrade; needed?
|
||||
bool m_anticipateTurns;
|
||||
bool m_optimizeVis;
|
||||
bool m_optimizeTopo;
|
||||
bool m_obstacleAvoidance;
|
||||
float m_obstacleAvoidanceType;
|
||||
int m_obstacleAvoidanceType;
|
||||
bool m_separation;
|
||||
float m_separationWeight;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -172,6 +172,45 @@ void update_camera(const float* bmin, const float* bmax,float* cameraPos,float*
|
||||
glFogf(GL_FOG_END, camr * 1.25f);
|
||||
}
|
||||
|
||||
bool imgui_init(SDL_Window* window, SDL_Renderer* /*renderer*/, SDL_GLContext context)
|
||||
{
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGuiContext* const imguiContext = ImGui::CreateContext();
|
||||
|
||||
if (!imguiContext)
|
||||
return false;
|
||||
|
||||
// todo(amos): check if this is required.
|
||||
//imguiContext->ConfigNavWindowingKeyNext = 0;
|
||||
//imguiContext->ConfigNavWindowingKeyPrev = 0;
|
||||
|
||||
// todo(amos): check if this is required.
|
||||
//ImGuiIO& io = ImGui::GetIO();
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_IsSRGB;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
if (!ImGui_ImplSDL2_InitForOpenGL(window, context))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ImGui_ImplOpenGL2_Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void imgui_shutdown()
|
||||
{
|
||||
ImGui_ImplOpenGL2_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &height, bool presentationMode)
|
||||
{
|
||||
// Init SDL
|
||||
@ -224,9 +263,9 @@ bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &hei
|
||||
}
|
||||
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_GL_CreateContext(window);
|
||||
SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||
|
||||
if (!imguiRenderGLInit(droidsans_data))
|
||||
if (!imgui_init(window, renderer, context))
|
||||
{
|
||||
printf("Could not initialise GUI renderer.\n");
|
||||
SDL_Quit();
|
||||
@ -470,9 +509,7 @@ int not_main(int argc, char** argv)
|
||||
bool showTestCases = false;
|
||||
|
||||
// Window scroll positions.
|
||||
int propScroll = 0;
|
||||
int logScroll = 0;
|
||||
int toolsScroll = 0;
|
||||
//int propScroll = 0;
|
||||
|
||||
float t = 0.0f;
|
||||
float timeAcc = 0.0f;
|
||||
@ -492,6 +529,8 @@ int not_main(int argc, char** argv)
|
||||
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
@ -630,12 +669,6 @@ int not_main(int argc, char** argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char mouseButtonMask = 0;
|
||||
if (SDL_GetMouseState(0, 0) & SDL_BUTTON_LMASK)
|
||||
mouseButtonMask |= IMGUI_MBUT_LEFT;
|
||||
if (SDL_GetMouseState(0, 0) & SDL_BUTTON_RMASK)
|
||||
mouseButtonMask |= IMGUI_MBUT_RIGHT;
|
||||
|
||||
Uint32 time = SDL_GetTicks();
|
||||
float dt = (time - prevFrameTime) / 1000.0f;
|
||||
@ -796,9 +829,15 @@ int not_main(int argc, char** argv)
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
mouseOverMenu = false;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
mouseOverMenu = io.WantCaptureMouse;
|
||||
|
||||
imguiBeginFrame(mousePos[0], mousePos[1], mouseButtonMask, mouseScroll);
|
||||
ImGui_ImplOpenGL2_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
//imguiBeginFrame(mousePos[0], mousePos[1], mouseButtonMask, mouseScroll);
|
||||
|
||||
if (editor)
|
||||
{
|
||||
@ -807,117 +846,119 @@ int not_main(int argc, char** argv)
|
||||
}
|
||||
if (test)
|
||||
{
|
||||
if (test->handleRenderOverlay(reinterpret_cast<double*>(projectionMatrix), reinterpret_cast<double*>(modelviewMatrix), reinterpret_cast<int*>(viewport)))
|
||||
mouseOverMenu = true;
|
||||
test->handleRenderOverlay(reinterpret_cast<double*>(projectionMatrix), reinterpret_cast<double*>(modelviewMatrix), reinterpret_cast<int*>(viewport));
|
||||
}
|
||||
|
||||
// Help text.
|
||||
if (showMenu)
|
||||
{
|
||||
const char msg[] = "W/S/A/D: Move RMB: Rotate";
|
||||
imguiDrawText(280, height-20, IMGUI_ALIGN_LEFT, msg, imguiRGBA(255,255,255,128));
|
||||
// todo(amos): imgui
|
||||
//ImGui::SetCursorPos(ImVec2(280, (float)height-20));
|
||||
ImGui::TextColored(ImVec4(255,255,255,128), "W/S/A/D: Move RMB: Rotate", ImVec4(255,255,255,128));
|
||||
}
|
||||
string geom_path;
|
||||
|
||||
const ImGuiWindowFlags baseWindowFlags = ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
||||
|
||||
if (showMenu)
|
||||
{
|
||||
if (imguiBeginScrollArea("Properties", width-250-10, 10, 250, height-20, &propScroll))
|
||||
mouseOverMenu = true;
|
||||
ImGui::SetNextWindowPos(ImVec2((float)width-250-10, 10.f));
|
||||
ImGui::SetNextWindowSize(ImVec2(250, (float)height-20));
|
||||
|
||||
if (imguiCheck("Show Log", showLog))
|
||||
showLog = !showLog;
|
||||
if (imguiCheck("Show Tools", showTools))
|
||||
showTools = !showTools;
|
||||
|
||||
imguiSeparator();
|
||||
imguiLabel("Input Level");
|
||||
|
||||
if (imguiButton("Load Level..."))
|
||||
if (ImGui::Begin("Properties", nullptr, baseWindowFlags))
|
||||
{
|
||||
char szFile[260];
|
||||
OPENFILENAMEA diag = { 0 };
|
||||
diag.lStructSize = sizeof(diag);
|
||||
ImGui::Checkbox("Show Log", &showLog);
|
||||
ImGui::Checkbox("Show Tools", &showTools);
|
||||
|
||||
SDL_SysWMinfo sdlinfo;
|
||||
SDL_version sdlver;
|
||||
SDL_VERSION(&sdlver);
|
||||
sdlinfo.version = sdlver;
|
||||
SDL_GetWindowWMInfo(window, &sdlinfo);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Input Level");
|
||||
|
||||
diag.hwndOwner = sdlinfo.info.win.window;
|
||||
|
||||
diag.lpstrFile = szFile;
|
||||
diag.lpstrFile[0] = 0;
|
||||
diag.nMaxFile = sizeof(szFile);
|
||||
diag.lpstrFilter = "OBJ\0*.obj\0Ply\0*.ply\0All\0*.*\0"; //TODO: BSP\0*.bsp\0
|
||||
diag.nFilterIndex = 1;
|
||||
diag.lpstrFileTitle = NULL;
|
||||
diag.nMaxFileTitle = 0;
|
||||
diag.lpstrInitialDir = NULL;
|
||||
diag.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
if (GetOpenFileNameA(&diag))
|
||||
if (ImGui::Button("Load Level..."))
|
||||
{
|
||||
geom_path = std::string(szFile);
|
||||
meshName = geom_path.substr(geom_path.rfind("\\")+1);
|
||||
}
|
||||
}
|
||||
if (imguiButton(meshName.c_str()))
|
||||
{
|
||||
if (showLevels)
|
||||
{
|
||||
showLevels = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
showEditor = false;
|
||||
showTestCases = false;
|
||||
showLevels = true;
|
||||
scanDirectory(meshesFolder, ".obj", files);
|
||||
scanDirectoryAppend(meshesFolder, ".gset", files);
|
||||
scanDirectoryAppend(meshesFolder, ".ply", files);
|
||||
}
|
||||
}
|
||||
if (geom)
|
||||
{
|
||||
char text[64];
|
||||
snprintf(text, 64, "Verts: %.1fk Tris: %.1fk",
|
||||
geom->getMesh()->getVertCount()/1000.0f,
|
||||
geom->getMesh()->getTriCount()/1000.0f);
|
||||
imguiValue(text);
|
||||
}
|
||||
imguiSeparator();
|
||||
char szFile[260];
|
||||
OPENFILENAMEA diag = { 0 };
|
||||
diag.lStructSize = sizeof(diag);
|
||||
|
||||
if (geom && editor)
|
||||
{
|
||||
imguiSeparatorLine();
|
||||
|
||||
editor->handleSettings();
|
||||
SDL_SysWMinfo sdlinfo;
|
||||
SDL_version sdlver;
|
||||
SDL_VERSION(&sdlver);
|
||||
sdlinfo.version = sdlver;
|
||||
SDL_GetWindowWMInfo(window, &sdlinfo);
|
||||
|
||||
if (imguiButton("Build"))
|
||||
{
|
||||
ctx.resetLog();
|
||||
if (!editor->handleBuild())
|
||||
diag.hwndOwner = sdlinfo.info.win.window;
|
||||
|
||||
diag.lpstrFile = szFile;
|
||||
diag.lpstrFile[0] = 0;
|
||||
diag.nMaxFile = sizeof(szFile);
|
||||
diag.lpstrFilter = "OBJ\0*.obj\0Ply\0*.ply\0All\0*.*\0"; //TODO: BSP\0*.bsp\0
|
||||
diag.nFilterIndex = 1;
|
||||
diag.lpstrFileTitle = NULL;
|
||||
diag.nMaxFileTitle = 0;
|
||||
diag.lpstrInitialDir = NULL;
|
||||
diag.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
if (GetOpenFileNameA(&diag))
|
||||
{
|
||||
showLog = true;
|
||||
logScroll = 0;
|
||||
geom_path = std::string(szFile);
|
||||
meshName = geom_path.substr(geom_path.rfind("\\") + 1);
|
||||
}
|
||||
ctx.dumpLog("Build log %s:", meshName.c_str());
|
||||
|
||||
// Clear test.
|
||||
delete test;
|
||||
test = 0;
|
||||
}
|
||||
if (ImGui::Button(meshName.c_str()))
|
||||
{
|
||||
if (showLevels)
|
||||
{
|
||||
showLevels = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
showEditor = false;
|
||||
showTestCases = false;
|
||||
showLevels = true;
|
||||
scanDirectory(meshesFolder, ".obj", files);
|
||||
scanDirectoryAppend(meshesFolder, ".gset", files);
|
||||
scanDirectoryAppend(meshesFolder, ".ply", files);
|
||||
}
|
||||
}
|
||||
if (geom)
|
||||
{
|
||||
char text[64];
|
||||
snprintf(text, 64, "Verts: %.1fk Tris: %.1fk",
|
||||
geom->getMesh()->getVertCount() / 1000.0f,
|
||||
geom->getMesh()->getTriCount() / 1000.0f);
|
||||
ImGui::Text(text);
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (geom && editor)
|
||||
{
|
||||
ImGui::Separator(); // was imguiSeperatorLine
|
||||
|
||||
editor->handleSettings();
|
||||
|
||||
if (ImGui::Button("Build"))
|
||||
{
|
||||
ctx.resetLog();
|
||||
if (!editor->handleBuild())
|
||||
{
|
||||
showLog = true;
|
||||
}
|
||||
ctx.dumpLog("Build log %s:", meshName.c_str());
|
||||
|
||||
// Clear test.
|
||||
delete test;
|
||||
test = 0;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
if (editor)
|
||||
{
|
||||
ImGui::Separator(); // was imguiSeperatorLine
|
||||
editor->handleDebugMode();
|
||||
}
|
||||
}
|
||||
|
||||
if (editor)
|
||||
{
|
||||
imguiSeparatorLine();
|
||||
editor->handleDebugMode();
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Editor selection dialog.
|
||||
@ -937,40 +978,41 @@ int not_main(int argc, char** argv)
|
||||
update_camera(bmin, bmax, cameraPos, cameraEulers, camr);
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
//ImGui::EndChild();
|
||||
}
|
||||
|
||||
// Level selection dialog.
|
||||
if (showLevels)
|
||||
{
|
||||
static int levelScroll = 0;
|
||||
if (imguiBeginScrollArea("Choose Level", width - 10 - 250 - 10 - 200, height - 10 - 450, 200, 450, &levelScroll))
|
||||
mouseOverMenu = true;
|
||||
|
||||
vector<string>::const_iterator fileIter = files.begin();
|
||||
vector<string>::const_iterator filesEnd = files.end();
|
||||
vector<string>::const_iterator levelToLoad = filesEnd;
|
||||
for (; fileIter != filesEnd; ++fileIter)
|
||||
ImGui::SetNextWindowPos(ImVec2((float)width-10-250-10-200, (float)height-10-900));
|
||||
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f));
|
||||
if (ImGui::Begin("Choose Level", nullptr, baseWindowFlags))
|
||||
{
|
||||
if (imguiItem(fileIter->c_str()))
|
||||
vector<string>::const_iterator fileIter = files.begin();
|
||||
vector<string>::const_iterator filesEnd = files.end();
|
||||
vector<string>::const_iterator levelToLoad = filesEnd;
|
||||
for (; fileIter != filesEnd; ++fileIter)
|
||||
{
|
||||
levelToLoad = fileIter;
|
||||
// was imguiItem
|
||||
if (ImGui::MenuItem(fileIter->c_str()))
|
||||
{
|
||||
levelToLoad = fileIter;
|
||||
}
|
||||
}
|
||||
|
||||
if (levelToLoad != filesEnd)
|
||||
{
|
||||
meshName = *levelToLoad;
|
||||
showLevels = false;
|
||||
|
||||
delete geom;
|
||||
geom = 0;
|
||||
|
||||
geom_path = meshesFolder + "/" + meshName;
|
||||
}
|
||||
}
|
||||
|
||||
if (levelToLoad != filesEnd)
|
||||
{
|
||||
meshName = *levelToLoad;
|
||||
showLevels = false;
|
||||
|
||||
delete geom;
|
||||
geom = 0;
|
||||
|
||||
geom_path= meshesFolder + "/" + meshName;
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
if (!geom_path.empty())
|
||||
{
|
||||
@ -988,7 +1030,6 @@ int not_main(int argc, char** argv)
|
||||
}
|
||||
|
||||
showLog = true;
|
||||
logScroll = 0;
|
||||
ctx.dumpLog("Geom load log %s:", meshName.c_str());
|
||||
}
|
||||
if (editor && geom)
|
||||
@ -1013,117 +1054,126 @@ int not_main(int argc, char** argv)
|
||||
// Test cases
|
||||
if (showTestCases)
|
||||
{
|
||||
static int testScroll = 0;
|
||||
if (imguiBeginScrollArea("Choose Test To Run", width-10-250-10-200, height-10-450, 200, 450, &testScroll))
|
||||
mouseOverMenu = true;
|
||||
ImGui::SetNextWindowPos(ImVec2((float)width-10-250-10-200, (float)height-10-900));
|
||||
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f));
|
||||
|
||||
vector<string>::const_iterator fileIter = files.begin();
|
||||
vector<string>::const_iterator filesEnd = files.end();
|
||||
vector<string>::const_iterator testToLoad = filesEnd;
|
||||
for (; fileIter != filesEnd; ++fileIter)
|
||||
if (ImGui::Begin("Choose Test To Run", nullptr, baseWindowFlags))
|
||||
{
|
||||
if (imguiItem(fileIter->c_str()))
|
||||
vector<string>::const_iterator fileIter = files.begin();
|
||||
vector<string>::const_iterator filesEnd = files.end();
|
||||
vector<string>::const_iterator testToLoad = filesEnd;
|
||||
for (; fileIter != filesEnd; ++fileIter)
|
||||
{
|
||||
testToLoad = fileIter;
|
||||
if (ImGui::MenuItem(fileIter->c_str()))
|
||||
{
|
||||
testToLoad = fileIter;
|
||||
}
|
||||
}
|
||||
|
||||
if (testToLoad != filesEnd)
|
||||
{
|
||||
string path = testCasesFolder + "/" + *testToLoad;
|
||||
test = new TestCase;
|
||||
if (test)
|
||||
{
|
||||
// Load the test.
|
||||
if (!test->load(path))
|
||||
{
|
||||
delete test;
|
||||
test = 0;
|
||||
}
|
||||
|
||||
if (editor)
|
||||
{
|
||||
editor->setContext(&ctx);
|
||||
showEditor = false;
|
||||
}
|
||||
|
||||
// Load geom.
|
||||
meshName = test->getGeomFileName();
|
||||
|
||||
|
||||
path = meshesFolder + "/" + meshName;
|
||||
|
||||
delete geom;
|
||||
geom = new InputGeom;
|
||||
if (!geom || !geom->load(&ctx, path))
|
||||
{
|
||||
delete geom;
|
||||
geom = 0;
|
||||
delete editor;
|
||||
editor = 0;
|
||||
showLog = true;
|
||||
ctx.dumpLog("Geom load log %s:", meshName.c_str());
|
||||
}
|
||||
if (editor && geom)
|
||||
{
|
||||
editor->handleMeshChanged(geom);
|
||||
get_model_name(meshName, editor->m_modelName);
|
||||
}
|
||||
|
||||
// This will ensure that tile & poly bits are updated in tiled editor.
|
||||
if (editor)
|
||||
editor->handleSettings();
|
||||
|
||||
ctx.resetLog();
|
||||
if (editor && !editor->handleBuild())
|
||||
{
|
||||
ctx.dumpLog("Build log %s:", meshName.c_str());
|
||||
}
|
||||
|
||||
if (geom || editor)
|
||||
{
|
||||
const float* bmin = 0;
|
||||
const float* bmax = 0;
|
||||
if (geom)
|
||||
{
|
||||
bmin = geom->getNavMeshBoundsMin();
|
||||
bmax = geom->getNavMeshBoundsMax();
|
||||
}
|
||||
// Reset camera and fog to match the mesh bounds.
|
||||
update_camera(bmin, bmax, cameraPos, cameraEulers, camr);
|
||||
}
|
||||
|
||||
// Do the tests.
|
||||
if (editor)
|
||||
test->doTests(editor->getNavMesh(), editor->getNavMeshQuery());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (testToLoad != filesEnd)
|
||||
{
|
||||
string path = testCasesFolder + "/" + *testToLoad;
|
||||
test = new TestCase;
|
||||
if (test)
|
||||
{
|
||||
// Load the test.
|
||||
if (!test->load(path))
|
||||
{
|
||||
delete test;
|
||||
test = 0;
|
||||
}
|
||||
|
||||
if (editor)
|
||||
{
|
||||
editor->setContext(&ctx);
|
||||
showEditor = false;
|
||||
}
|
||||
|
||||
// Load geom.
|
||||
meshName = test->getGeomFileName();
|
||||
|
||||
|
||||
path = meshesFolder + "/" + meshName;
|
||||
|
||||
delete geom;
|
||||
geom = new InputGeom;
|
||||
if (!geom || !geom->load(&ctx, path))
|
||||
{
|
||||
delete geom;
|
||||
geom = 0;
|
||||
delete editor;
|
||||
editor = 0;
|
||||
showLog = true;
|
||||
logScroll = 0;
|
||||
ctx.dumpLog("Geom load log %s:", meshName.c_str());
|
||||
}
|
||||
if (editor && geom)
|
||||
{
|
||||
editor->handleMeshChanged(geom);
|
||||
get_model_name(meshName, editor->m_modelName);
|
||||
}
|
||||
|
||||
// This will ensure that tile & poly bits are updated in tiled editor.
|
||||
if (editor)
|
||||
editor->handleSettings();
|
||||
|
||||
ctx.resetLog();
|
||||
if (editor && !editor->handleBuild())
|
||||
{
|
||||
ctx.dumpLog("Build log %s:", meshName.c_str());
|
||||
}
|
||||
|
||||
if (geom || editor)
|
||||
{
|
||||
const float* bmin = 0;
|
||||
const float* bmax = 0;
|
||||
if (geom)
|
||||
{
|
||||
bmin = geom->getNavMeshBoundsMin();
|
||||
bmax = geom->getNavMeshBoundsMax();
|
||||
}
|
||||
// Reset camera and fog to match the mesh bounds.
|
||||
update_camera(bmin, bmax, cameraPos, cameraEulers, camr);
|
||||
}
|
||||
|
||||
// Do the tests.
|
||||
if (editor)
|
||||
test->doTests(editor->getNavMesh(), editor->getNavMeshQuery());
|
||||
}
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
// Log
|
||||
if (showLog && showMenu)
|
||||
{
|
||||
if (imguiBeginScrollArea("Log", 250 + 20, 10, width - 300 - 250, 200, &logScroll))
|
||||
mouseOverMenu = true;
|
||||
for (int i = 0; i < ctx.getLogCount(); ++i)
|
||||
imguiLabel(ctx.getLogText(i));
|
||||
imguiEndScrollArea();
|
||||
ImGui::SetNextWindowPos(ImVec2((float)250+20, 10.f));
|
||||
ImGui::SetNextWindowSize(ImVec2(200.f, 450.f));
|
||||
|
||||
if (ImGui::Begin("Log"))
|
||||
{
|
||||
for (int i = 0; i < ctx.getLogCount(); ++i)
|
||||
ImGui::Text(ctx.getLogText(i));
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Left column tools menu
|
||||
if (!showTestCases && showTools && showMenu) // && geom && editor)
|
||||
{
|
||||
if (imguiBeginScrollArea("Tools", 10, 10, 250, height - 20, &toolsScroll))
|
||||
mouseOverMenu = true;
|
||||
ImGui::SetNextWindowPos(ImVec2(10.f, 10.f));
|
||||
ImGui::SetNextWindowSize(ImVec2(250, (float)height-20));
|
||||
|
||||
if (editor)
|
||||
editor->handleTools();
|
||||
if (ImGui::Begin("Tools", nullptr, baseWindowFlags))
|
||||
{
|
||||
if (editor)
|
||||
editor->handleTools();
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Marker
|
||||
@ -1147,16 +1197,16 @@ int not_main(int argc, char** argv)
|
||||
glLineWidth(1.0f);
|
||||
}
|
||||
|
||||
imguiEndFrame();
|
||||
imguiRenderGLDraw();
|
||||
|
||||
ImGui::EndFrame();
|
||||
|
||||
ImGui::Render();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_GL_SwapWindow(window);
|
||||
|
||||
}
|
||||
|
||||
imguiRenderGLDestroy();
|
||||
|
||||
imgui_shutdown();
|
||||
SDL_Quit();
|
||||
|
||||
delete editor;
|
||||
|
9
src/thirdparty/recast/Pch.h
vendored
9
src/thirdparty/recast/Pch.h
vendored
@ -51,8 +51,13 @@
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#include "NavEditor/Include/imgui.h"
|
||||
#include "NavEditor/Include/imguiRenderGL.h"
|
||||
// todo(amos): we need to make a new PCH dedicated for the recast editor and
|
||||
// move the SDL2 and ImGui includes there!
|
||||
#include "thirdparty/imgui/imgui.h"
|
||||
#include "thirdparty/imgui/imgui_internal.h"
|
||||
#include "thirdparty/imgui/misc/imgui_plotter.h"
|
||||
#include "thirdparty/imgui/backends/imgui_impl_sdl2.h"
|
||||
#include "thirdparty/imgui/backends/imgui_impl_opengl2.h"
|
||||
|
||||
// SDK types
|
||||
#include "tier0/basetypes.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user