36 #include "imgui_internal.h"
46 ImGui::SetNextWindowPosCenter(ImGuiCond_FirstUseEver);
47 ImGuiWindowFlags win_flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize;
48 bool keep_open =
true;
49 ImGui::Begin(
_LC(
"About",
"Static collision debug"), &keep_open, win_flags);
51 ImGui::Text(
"Terrain name: %s",
App::GetGameContext()->GetTerrain()->getTerrainName().c_str());
53 ImGui::Checkbox(
"Draw labels", &m_draw_labels);
54 ImGui::Checkbox(
"Draw label types", &m_labels_draw_types);
55 ImGui::Checkbox(
"Sources on labels", &m_labels_draw_sources);
59 ImGui::PushID(
"EVENTBOX");
60 ImGui::TextColored(COLOR_EVENTBOX,
"EVENTBOX");
61 ImGui::Text(
"Num event boxes: %d", (
int)
App::GetGameContext()->GetTerrain()->GetCollisions()->getCollisionBoxes().size());
62 if (ImGui::Checkbox(
"Show event boxes", &m_draw_collision_boxes))
64 this->SetDrawEventBoxes(m_draw_collision_boxes);
66 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
67 if (ImGui::InputFloat(
"Draw distance (meters, 0=unlimited)", &m_collision_box_draw_distance))
69 for (Ogre::SceneNode* snode : m_collision_boxes)
71 snode->getAttachedObject(0)->setRenderingDistance(m_collision_box_draw_distance);
74 if (m_collision_boxes.size() > 0)
76 if (ImGui::Button(
"Dump debug meshes (performance)."))
78 this->ClearEventBoxVisuals();
85 ImGui::PushID(
"COLLMESH");
86 ImGui::TextColored(COLOR_COLLMESH,
"COLLMESH");
87 ImGui::Text(
"Num collision meshes: %d (%d tris)",
90 if (ImGui::Checkbox(
"Show collision meshes", &m_draw_collision_meshes))
92 this->SetDrawCollisionMeshes(m_draw_collision_meshes);
94 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
95 if (ImGui::InputFloat(
"Draw distance (meters, 0=unlimited)", &m_collision_mesh_draw_distance))
97 for (Ogre::SceneNode* snode : m_collision_meshes)
99 snode->getAttachedObject(0)->setRenderingDistance(m_collision_mesh_draw_distance);
102 if (m_collision_meshes.size() > 0)
104 if (ImGui::Button(
"Dump debug meshes (performance)."))
106 this->ClearCollisionMeshVisuals();
113 ImGui::PushID(
"CELL");
115 ImGui::Text(
"Occupancy: ");
116 for (
int i = 0; i <= 10; i+=1)
120 ImVec4 color(f * 2.0, 2.0 * (1.0 - f), 0.2, 0.7);
122 ImGui::TextColored(color,
"%d ", tris);
124 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
125 if (ImGui::InputInt(
"Debug area extent (around character)", &m_cell_generator_distance_limit));
127 ImGui::TextDisabled(
"(?)");
128 if (ImGui::IsItemHovered())
130 ImGui::BeginTooltip();
131 ImGui::Text(
"To save memory and FPS, only cells around the characters will be visualized");
134 if (ImGui::Checkbox(
"Show lookup cells (warning: slow!)", &m_draw_collision_cells))
136 this->SetDrawCollisionCells(m_draw_collision_cells);
138 ImGui::SetNextItemWidth(WIDTH_DRAWDIST);
139 if (ImGui::InputFloat(
"Draw distance (meters, 0=unlimited)", &m_collision_cell_draw_distance))
141 for (Ogre::SceneNode* snode : m_collision_cells)
143 snode->getAttachedObject(0)->setRenderingDistance(m_collision_cell_draw_distance);
146 if (m_collision_grid_root)
148 if (ImGui::Button(
"Dump debug meshes (performance)."))
150 this->ClearCollisionCellVisuals();
155 m_is_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
162 this->SetVisible(
false);
168 if (m_draw_labels && m_draw_collision_boxes)
172 if (
IsDistanceWithin(cam_pos, this->GetCollBoxWorldPos(cbox), m_collision_box_draw_distance))
174 this->DrawCollisionBoxDebugText(cbox);
179 if (m_draw_labels && m_draw_collision_meshes)
183 if (
IsDistanceWithin(cam_pos, cmesh.position, m_collision_mesh_draw_distance))
185 this->DrawCollisionMeshDebugText(cmesh);
198 debugmo->begin(
"tracks/debug/collision/triangle", RenderOperation::OT_TRIANGLE_LIST);
203 debugmo->position(ctri.
a - coll_mesh.
position);
204 debugmo->position(ctri.
b - coll_mesh.
position);
205 debugmo->position(ctri.
c - coll_mesh.
position);
208 debugmo->setRenderingDistance(m_collision_mesh_draw_distance);
209 debugmo->setBoundingBox(AxisAlignedBox::BOX_INFINITE);
213 debugsn->setPosition(coll_mesh.
position);
215 debugsn->attachObject(debugmo);
218 m_collision_meshes.push_back(debugsn);
223 int scripthandler = -1;
229 debugsn->setPosition(coll_box.
center);
232 String matName =
"tracks/debug/collision/box";
233 if (coll_box.
virt && scripthandler == -1)
234 matName =
"tracks/debug/eventbox/unused";
235 else if (coll_box.
virt)
236 matName =
"tracks/debug/eventbox/used";
238 for (
int i = 0; i < 8; i++)
242 mo->begin(matName, Ogre::RenderOperation::OT_TRIANGLE_LIST);
253 mo->triangle(0, 1, 2);
254 mo->triangle(1, 3, 2);
256 mo->triangle(3, 1, 5);
257 mo->triangle(5, 7, 3);
259 mo->triangle(6, 4, 0);
260 mo->triangle(0, 2, 6);
262 mo->triangle(7, 5, 4);
263 mo->triangle(4, 6, 7);
265 mo->triangle(5, 4, 1);
266 mo->triangle(4, 0, 1);
268 mo->triangle(2, 3, 6);
269 mo->triangle(3, 7, 6);
272 mo->setBoundingBox(aa);
273 mo->setRenderingDistance(200);
274 debugsn->attachObject(mo);
278 mo->begin(matName, Ogre::RenderOperation::OT_LINE_LIST);
288 mo->index(0); mo->index(1); mo->index(1); mo->index(3); mo->index(3); mo->index(2); mo->index(2); mo->index(0);
290 mo->index(1); mo->index(5); mo->index(5); mo->index(7); mo->index(7); mo->index(3); mo->index(3); mo->index(1);
292 mo->index(0); mo->index(2); mo->index(2); mo->index(6); mo->index(6); mo->index(4); mo->index(4); mo->index(0);
294 mo->index(5); mo->index(4); mo->index(4); mo->index(6); mo->index(6); mo->index(7); mo->index(7); mo->index(5);
297 mo->setBoundingBox(aa);
298 debugsn->attachObject(mo);
299 mo->setRenderingDistance(200);
301 m_collision_boxes.push_back(debugsn);
306 return Vector3(coll_box.
lo + (coll_box.
hi - coll_box.
lo) * 0.5f);
311 const char* label_type_str = (m_labels_draw_types) ?
"COLLMESH\n" :
"";
314 std::string caption =
fmt::format(
"{}meshname:{}\ngroundmodel:{}",
315 label_type_str, coll_mesh.
mesh_name, ground_model_str);
316 if (m_labels_draw_sources)
321 this->DrawLabelAtWorldPos(caption, coll_mesh.
position, COLOR_COLLMESH);
330 const char* type_str = (m_labels_draw_types) ?
"EVENTBOX\n" :
"";
332 std::string label =
fmt::format(
"{}event: {}\ninstance: {}\nhandler: {}", type_str,
338 label +=
"\nfilter: avatar";
341 label +=
"\nfilter: truck";
344 label +=
"\nfilter: truck_wheels";
347 label +=
"\nfilter: airplane";
350 label +=
"\nfilter: boat";
355 this->DrawLabelAtWorldPos(label, this->GetCollBoxWorldPos(coll_box), COLOR_EVENTBOX);
362 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
366 Ogre::Vector3 pos_xyz = world2screen.
Convert(world_pos);
372 ImVec2 pos((
int)pos_xyz.x + 0.5, (
int)pos_xyz.y + 0.5);
374 ImVec2 text_size = ImGui::CalcTextSize(caption.c_str());
378 ImGuiContext* g = ImGui::GetCurrentContext();
380 ImVec2 text_pos(pos.x - ((text_size.x / 2)), pos.y - ((text_size.y / 2)));
383 const float PADDING = 4.f;
384 drawlist->AddRectFilled(
385 text_pos - ImVec2(PADDING, PADDING),
386 text_pos + text_size + ImVec2(PADDING, PADDING),
388 ImGui::GetStyle().WindowRounding);
391 drawlist->AddText(g->Font, g->FontSize, text_pos, ImColor(text_color), caption.c_str());
399 this->ClearEventBoxVisuals();
402 this->ClearCollisionMeshVisuals();
405 this->ClearCollisionCellVisuals();
410 if (MaterialManager::getSingleton().getByName(
"mat-coll-dbg-0", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME))
418 for (i = 0; i <= 100; i++)
421 sprintf(bname,
"mat-coll-dbg-%d", i);
422 MaterialPtr mat = (MaterialPtr)(MaterialManager::getSingleton().create(bname, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));
423 float f = fabs(((
float)i) / 100);
424 Pass* p = mat->getTechnique(0)->getPass(0);
425 p->createTextureUnitState()->setColourOperationEx(LBX_MODULATE, LBS_MANUAL, LBS_CURRENT, ColourValue(f * 2.0, 2.0 * (1.0 - f), 0.2, 0.7));
426 p->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
427 p->setLightingEnabled(
false);
428 p->setDepthWriteEnabled(
false);
429 p->setDepthBias(3, 3);
430 p->setCullingMode(Ogre::CULL_NONE);
432 Pass* p2 = mat->getTechnique(0)->createPass();
433 p2->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
434 p2->setLightingEnabled(
false);
435 p2->setDepthWriteEnabled(
false);
436 p2->setDepthBias(3, 3);
437 p2->setCullingMode(Ogre::CULL_NONE);
438 p2->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
439 TextureUnitState* tus2 = p2->createTextureUnitState();
440 tus2->setTextureName(
"tile.png");
443 mat->setLightingEnabled(
false);
444 mat->setReceiveShadows(
false);
450 m_draw_collision_boxes = val;
453 if (m_draw_collision_boxes && m_collision_boxes.size() == 0)
457 this->AddCollisionBoxDebugMesh(cbox);
461 for (Ogre::SceneNode* snode : m_collision_boxes)
463 snode->setVisible(m_draw_collision_boxes);
469 m_draw_collision_meshes = val;
472 if (m_draw_collision_meshes && m_collision_meshes.size() == 0)
476 this->AddCollisionMeshDebugMesh(cmesh);
480 for (Ogre::SceneNode* snode : m_collision_meshes)
482 snode->setVisible(m_draw_collision_meshes);
488 m_draw_collision_cells = val;
491 if (m_draw_collision_cells && !m_collision_grid_root)
493 this->GenerateCellDebugMaterials();
497 aabb.setMinimum(
App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(-m_cell_generator_distance_limit, 0, -m_cell_generator_distance_limit));
498 aabb.getMinimum().y = -FLT_MAX;
499 aabb.setMaximum(
App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(m_cell_generator_distance_limit, 0, m_cell_generator_distance_limit));
500 aabb.getMaximum().y = FLT_MAX;
505 catch (std::bad_alloc
const& allocex)
508 fmt::format(
"Could not create debug view, error: {}", allocex.what()));
509 this->ClearCollisionCellVisuals();
513 if (m_collision_grid_root)
515 m_collision_grid_root->setVisible(m_draw_collision_cells);
521 for (Ogre::SceneNode* snode : m_collision_meshes)
523 Entity* ent =
static_cast<Entity*
>(snode->getAttachedObject(0));
527 m_collision_meshes.clear();
528 m_draw_collision_meshes =
false;
529 m_collision_mesh_draw_distance = DEFAULT_DRAWDIST;
534 for (Ogre::SceneNode* snode : m_collision_boxes)
536 Entity* ent =
static_cast<Entity*
>(snode->getAttachedObject(0));
540 m_collision_boxes.clear();
541 m_draw_collision_boxes =
false;
542 m_collision_box_draw_distance = DEFAULT_DRAWDIST;
547 for (Ogre::SceneNode* snode : m_collision_cells)
549 ManualObject* mo =
static_cast<ManualObject*
>(snode->getAttachedObject(0));
552 m_collision_cells.clear();
553 m_draw_collision_cells =
false;
554 m_collision_cell_draw_distance = DEFAULT_DRAWDIST;
556 if (m_collision_grid_root)
558 m_collision_grid_root->removeAndDestroyAllChildren();
560 m_collision_grid_root =
nullptr;
568 this->SetDrawEventBoxes(
false);
569 this->SetDrawCollisionMeshes(
false);
570 this->SetDrawCollisionCells(
false);