36 #include "imgui_internal.h"
46 ImGuiWindowFlags win_flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize;
47 bool keep_open =
true;
48 ImGui::Begin(
_LC(
"About",
"Static collision debug"), &keep_open, win_flags);
50 ImGui::Text(
"Terrain name: %s",
App::GetGameContext()->GetTerrain()->getTerrainName().c_str());
52 ImGui::Checkbox(
"Draw labels", &m_draw_labels);
53 ImGui::Checkbox(
"Draw label types", &m_labels_draw_types);
54 ImGui::Checkbox(
"Sources on labels", &m_labels_draw_sources);
58 ImGui::PushID(
"EVENTBOX");
59 ImGui::TextColored(COLOR_EVENTBOX,
"EVENTBOX");
60 ImGui::Text(
"Num event boxes: %d", (
int)
App::GetGameContext()->GetTerrain()->GetCollisions()->getCollisionBoxes().size());
61 if (ImGui::Checkbox(
"Show event boxes", &m_draw_collision_boxes))
63 this->SetDrawEventBoxes(m_draw_collision_boxes);
65 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
66 if (ImGui::InputFloat(
"Draw distance (meters, 0=unlimited)", &m_collision_box_draw_distance))
68 for (Ogre::SceneNode* snode : m_collision_boxes)
70 snode->getAttachedObject(0)->setRenderingDistance(m_collision_box_draw_distance);
73 if (m_collision_boxes.size() > 0)
75 if (ImGui::Button(
"Dump debug meshes (performance)."))
77 this->ClearEventBoxVisuals();
84 ImGui::PushID(
"COLLMESH");
85 ImGui::TextColored(COLOR_COLLMESH,
"COLLMESH");
86 ImGui::Text(
"Num collision meshes: %d (%d tris)",
89 if (ImGui::Checkbox(
"Show collision meshes", &m_draw_collision_meshes))
91 this->SetDrawCollisionMeshes(m_draw_collision_meshes);
93 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
94 if (ImGui::InputFloat(
"Draw distance (meters, 0=unlimited)", &m_collision_mesh_draw_distance))
96 for (Ogre::SceneNode* snode : m_collision_meshes)
98 snode->getAttachedObject(0)->setRenderingDistance(m_collision_mesh_draw_distance);
101 if (m_collision_meshes.size() > 0)
103 if (ImGui::Button(
"Dump debug meshes (performance)."))
105 this->ClearCollisionMeshVisuals();
112 ImGui::PushID(
"CELL");
114 ImGui::Text(
"Occupancy: ");
115 for (
int i = 0; i <= 10; i+=1)
119 ImVec4 color(f * 2.0, 2.0 * (1.0 - f), 0.2, 0.7);
121 ImGui::TextColored(color,
"%d ", tris);
123 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
124 if (ImGui::InputInt(
"Debug area extent (around character)", &m_cell_generator_distance_limit));
126 ImGui::TextDisabled(
"(?)");
127 if (ImGui::IsItemHovered())
129 ImGui::BeginTooltip();
130 ImGui::Text(
"To save memory and FPS, only cells around the characters will be visualized");
133 if (ImGui::Checkbox(
"Show lookup cells (warning: slow!)", &m_draw_collision_cells))
135 this->SetDrawCollisionCells(m_draw_collision_cells);
137 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
138 if (ImGui::InputFloat(
"Draw distance (meters, 0=unlimited)", &m_collision_cell_draw_distance))
140 for (Ogre::SceneNode* snode : m_collision_cells)
142 snode->getAttachedObject(0)->setRenderingDistance(m_collision_cell_draw_distance);
145 if (m_collision_grid_root)
147 if (ImGui::Button(
"Dump debug meshes (performance)."))
149 this->ClearCollisionCellVisuals();
154 m_is_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
161 this->SetVisible(
false);
167 if (m_draw_labels && m_draw_collision_boxes)
171 if (
IsDistanceWithin(cam_pos, this->GetCollBoxWorldPos(cbox), m_collision_box_draw_distance))
173 this->DrawCollisionBoxDebugText(cbox);
178 if (m_draw_labels && m_draw_collision_meshes)
182 if (
IsDistanceWithin(cam_pos, cmesh.position, m_collision_mesh_draw_distance))
184 this->DrawCollisionMeshDebugText(cmesh);
197 debugmo->begin(
"tracks/debug/collision/triangle", RenderOperation::OT_TRIANGLE_LIST);
202 debugmo->position(ctri.
a - coll_mesh.
position);
203 debugmo->position(ctri.
b - coll_mesh.
position);
204 debugmo->position(ctri.
c - coll_mesh.
position);
207 debugmo->setRenderingDistance(m_collision_mesh_draw_distance);
208 debugmo->setBoundingBox(AxisAlignedBox::BOX_INFINITE);
212 debugsn->setPosition(coll_mesh.
position);
214 debugsn->attachObject(debugmo);
217 m_collision_meshes.push_back(debugsn);
222 int scripthandler = -1;
228 debugsn->setPosition(coll_box.
center);
231 String matName =
"tracks/debug/collision/box";
232 if (coll_box.
virt && scripthandler == -1)
233 matName =
"tracks/debug/eventbox/unused";
234 else if (coll_box.
virt)
235 matName =
"tracks/debug/eventbox/used";
237 for (
int i = 0; i < 8; i++)
241 mo->begin(matName, Ogre::RenderOperation::OT_TRIANGLE_LIST);
252 mo->triangle(0, 1, 2);
253 mo->triangle(1, 3, 2);
255 mo->triangle(3, 1, 5);
256 mo->triangle(5, 7, 3);
258 mo->triangle(6, 4, 0);
259 mo->triangle(0, 2, 6);
261 mo->triangle(7, 5, 4);
262 mo->triangle(4, 6, 7);
264 mo->triangle(5, 4, 1);
265 mo->triangle(4, 0, 1);
267 mo->triangle(2, 3, 6);
268 mo->triangle(3, 7, 6);
271 mo->setBoundingBox(aa);
272 mo->setRenderingDistance(200);
273 debugsn->attachObject(mo);
277 mo->begin(matName, Ogre::RenderOperation::OT_LINE_LIST);
287 mo->index(0); mo->index(1); mo->index(1); mo->index(3); mo->index(3); mo->index(2); mo->index(2); mo->index(0);
289 mo->index(1); mo->index(5); mo->index(5); mo->index(7); mo->index(7); mo->index(3); mo->index(3); mo->index(1);
291 mo->index(0); mo->index(2); mo->index(2); mo->index(6); mo->index(6); mo->index(4); mo->index(4); mo->index(0);
293 mo->index(5); mo->index(4); mo->index(4); mo->index(6); mo->index(6); mo->index(7); mo->index(7); mo->index(5);
296 mo->setBoundingBox(aa);
297 debugsn->attachObject(mo);
298 mo->setRenderingDistance(200);
300 m_collision_boxes.push_back(debugsn);
305 return Vector3(coll_box.
lo + (coll_box.
hi - coll_box.
lo) * 0.5f);
310 const char* label_type_str = (m_labels_draw_types) ?
"COLLMESH\n" :
"";
313 std::string caption =
fmt::format(
"{}meshname:{}\ngroundmodel:{}",
314 label_type_str, coll_mesh.
mesh_name, ground_model_str);
315 if (m_labels_draw_sources)
320 this->DrawLabelAtWorldPos(caption, coll_mesh.
position, COLOR_COLLMESH);
329 const char* type_str = (m_labels_draw_types) ?
"EVENTBOX\n" :
"";
331 this->DrawLabelAtWorldPos(
332 fmt::format(
"{}event:{}\ninstance:{}\nhandler:{}", type_str,
334 this->GetCollBoxWorldPos(coll_box), COLOR_EVENTBOX);
341 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
345 Ogre::Vector3 pos_xyz = world2screen.
Convert(world_pos);
351 ImVec2 pos((
int)pos_xyz.x + 0.5, (
int)pos_xyz.y + 0.5);
353 ImVec2 text_size = ImGui::CalcTextSize(caption.c_str());
357 ImGuiContext* g = ImGui::GetCurrentContext();
359 ImVec2 text_pos(pos.x - ((text_size.x / 2)), pos.y - ((text_size.y / 2)));
362 const float PADDING = 4.f;
363 drawlist->AddRectFilled(
364 text_pos - ImVec2(PADDING, PADDING),
365 text_pos + text_size + ImVec2(PADDING, PADDING),
367 ImGui::GetStyle().WindowRounding);
370 drawlist->AddText(g->Font, g->FontSize, text_pos, ImColor(text_color), caption.c_str());
378 this->ClearEventBoxVisuals();
381 this->ClearCollisionMeshVisuals();
384 this->ClearCollisionCellVisuals();
389 if (MaterialManager::getSingleton().getByName(
"mat-coll-dbg-0", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME))
397 for (i = 0; i <= 100; i++)
400 sprintf(bname,
"mat-coll-dbg-%d", i);
401 MaterialPtr mat = (MaterialPtr)(MaterialManager::getSingleton().create(bname, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));
402 float f = fabs(((
float)i) / 100);
403 Pass* p = mat->getTechnique(0)->getPass(0);
404 p->createTextureUnitState()->setColourOperationEx(LBX_MODULATE, LBS_MANUAL, LBS_CURRENT, ColourValue(f * 2.0, 2.0 * (1.0 - f), 0.2, 0.7));
405 p->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
406 p->setLightingEnabled(
false);
407 p->setDepthWriteEnabled(
false);
408 p->setDepthBias(3, 3);
409 p->setCullingMode(Ogre::CULL_NONE);
411 Pass* p2 = mat->getTechnique(0)->createPass();
412 p2->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
413 p2->setLightingEnabled(
false);
414 p2->setDepthWriteEnabled(
false);
415 p2->setDepthBias(3, 3);
416 p2->setCullingMode(Ogre::CULL_NONE);
417 p2->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
418 TextureUnitState* tus2 = p2->createTextureUnitState();
419 tus2->setTextureName(
"tile.png");
422 mat->setLightingEnabled(
false);
423 mat->setReceiveShadows(
false);
429 m_draw_collision_boxes = val;
432 if (m_draw_collision_boxes && m_collision_boxes.size() == 0)
436 this->AddCollisionBoxDebugMesh(cbox);
440 for (Ogre::SceneNode* snode : m_collision_boxes)
442 snode->setVisible(m_draw_collision_boxes);
448 m_draw_collision_meshes = val;
451 if (m_draw_collision_meshes && m_collision_meshes.size() == 0)
455 this->AddCollisionMeshDebugMesh(cmesh);
459 for (Ogre::SceneNode* snode : m_collision_meshes)
461 snode->setVisible(m_draw_collision_meshes);
467 m_draw_collision_cells = val;
470 if (m_draw_collision_cells && !m_collision_grid_root)
472 this->GenerateCellDebugMaterials();
476 aabb.setMinimum(
App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(-m_cell_generator_distance_limit, 0, -m_cell_generator_distance_limit));
477 aabb.getMinimum().y = -FLT_MAX;
478 aabb.setMaximum(
App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(m_cell_generator_distance_limit, 0, m_cell_generator_distance_limit));
479 aabb.getMaximum().y = FLT_MAX;
484 catch (std::bad_alloc
const& allocex)
487 fmt::format(
"Could not create debug view, error: {}", allocex.what()));
488 this->ClearCollisionCellVisuals();
492 if (m_collision_grid_root)
494 m_collision_grid_root->setVisible(m_draw_collision_cells);
500 for (Ogre::SceneNode* snode : m_collision_meshes)
502 Entity* ent =
static_cast<Entity*
>(snode->getAttachedObject(0));
506 m_collision_meshes.clear();
507 m_draw_collision_meshes =
false;
508 m_collision_mesh_draw_distance = DEFAULT_DRAWDIST;
513 for (Ogre::SceneNode* snode : m_collision_boxes)
515 Entity* ent =
static_cast<Entity*
>(snode->getAttachedObject(0));
519 m_collision_boxes.clear();
520 m_draw_collision_boxes =
false;
521 m_collision_box_draw_distance = DEFAULT_DRAWDIST;
526 for (Ogre::SceneNode* snode : m_collision_cells)
528 ManualObject* mo =
static_cast<ManualObject*
>(snode->getAttachedObject(0));
531 m_collision_cells.clear();
532 m_draw_collision_cells =
false;
533 m_collision_cell_draw_distance = DEFAULT_DRAWDIST;
535 if (m_collision_grid_root)
537 m_collision_grid_root->removeAndDestroyAllChildren();
539 m_collision_grid_root =
nullptr;
547 this->SetDrawEventBoxes(
false);
548 this->SetDrawCollisionMeshes(
false);
549 this->SetDrawCollisionCells(
false);