42 ImGuiWindowFlags win_flags = ImGuiWindowFlags_NoCollapse;
43 bool keep_open =
true;
44 ImGui::Begin(
_LC(
"FlexbodyDebug",
"Flexbody/Prop debug"), &keep_open, win_flags);
49 ImGui::Text(
"%s",
_LC(
"FlexbodyDebug",
"You are on foot."));
57 ImGui::Text(
"%s",
_LC(
"FlexbodyDebug",
"This vehicle has no flexbodies or props."));
80 Ogre::MaterialPtr mat;
82 std::string mesh_name;
102 mat = flexbody->
getEntity()->getSubEntity(0)->getMaterial();
110 ImGui::Text(
"Mesh: '%s'", mesh_name.c_str());
117 if (mat->getTechniques().size() > 0 && mat->getTechniques()[0]->getPasses().size() > 0)
119 Ogre::PolygonMode mode = (this->
draw_mesh_wireframe) ? Ogre::PM_WIREFRAME : Ogre::PM_SOLID;
120 mat->getTechniques()[0]->getPasses()[0]->setPolygonMode(mode);
125 ImGui::Text(
"Base nodes: Ref=%d, X=%d, Y=%d", (
int)node_ref, (
int)node_x, (
int)node_y);
129 bool flexbody_locators_visible =
false;
132 ImGui::Text(
"Forset nodes: (total %d)", (
int)flexbody->
getForsetNodes().size());
136 ImGui::Text(
"Vertices: (total %d)", (
int)flexbody->
getVertexCount());
138 ImGui::Checkbox(
"Show all (pick with mouse)##verts", &this->
show_vertices);
140 if (ImGui::CollapsingHeader(
"Vertex locators table"))
145 if (ImGui::CollapsingHeader(
"Vertex locators memory (experimental!)"))
151 if (ImGui::CollapsingHeader(
"Mesh info"))
159 m_is_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
170 this->
DrawDebugView(flexbody, prop, node_ref, node_x, node_y);
182 int num_combo_items = 0;
193 fb->getOrigMeshName(), fb->getVertexCount(), fb->getForsetNodes().size()));
217 if (p.pp_beacon_type ==
'L' || p.pp_beacon_type ==
'R' || p.pp_beacon_type ==
'w')
219 caption =
fmt::format(
"(special prop - aerial nav light '{}')", p.pp_beacon_type);
221 else if (p.pp_wheel_mesh_obj)
223 if (p.pp_mesh_obj->getLoadedMesh() && p.pp_wheel_mesh_obj->getLoadedMesh())
225 caption =
fmt::format(
"(special prop: dashboard '{}' + dirwheel '{}')", p.pp_mesh_obj->getLoadedMesh()->getName(), p.pp_wheel_mesh_obj->getLoadedMesh()->getName());
227 else if (!p.pp_mesh_obj->getLoadedMesh() && p.pp_wheel_mesh_obj->getLoadedMesh())
229 caption =
fmt::format(
"(special prop: no dashboard + dirwheel '{}')", p.pp_wheel_mesh_obj->getLoadedMesh()->getName());
233 caption =
"(corrupted dashboard prop - no meshes loaded)";
236 else if (p.pp_mesh_obj && p.pp_mesh_obj->getLoadedMesh())
238 caption =
fmt::format(
"{} (prop)", p.pp_mesh_obj->getLoadedMesh()->getName());
242 caption =
"(corrupted prop - mesh not loaded)";
286 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
292 const int LAYER_BEAMS = 0;
293 const int LAYER_NODES = 1;
294 const int LAYER_TEXT = 2;
295 drawlist->ChannelsSplit(3);
299 drawlist->ChannelsSetCurrent(LAYER_NODES);
300 Ogre::Vector3 refnode_pos = world2screen.
Convert(
nodes[node_ref].AbsPosition);
301 Ogre::Vector3 xnode_pos = world2screen.
Convert(
nodes[node_x].AbsPosition);
302 Ogre::Vector3 ynode_pos = world2screen.
Convert(
nodes[node_y].AbsPosition);
308 drawlist->ChannelsSetCurrent(LAYER_BEAMS);
309 if (refnode_pos.z < 0)
315 drawlist->ChannelsSetCurrent(LAYER_TEXT);
325 drawlist->ChannelsSetCurrent(LAYER_NODES);
326 Ogre::Vector3 pos = world2screen.
Convert(
nodes[node].AbsPosition);
329 drawlist->ChannelsSetCurrent(LAYER_TEXT);
334 int hovered_vert = -1;
335 float hovered_vert_dist_squared = FLT_MAX;
336 ImVec2 mouse_pos = ImGui::GetMousePos();
337 ImVec2 dbg_cursor_dist(0, 0);
343 if (vert_pos.z < 0.f)
346 drawlist->ChannelsSetCurrent(LAYER_NODES);
350 ImVec2 cursor_dist((vert_pos.x - mouse_pos.x), (vert_pos.y - mouse_pos.y));
351 float dist_squared = (cursor_dist.x * cursor_dist.x) + (cursor_dist.y * cursor_dist.y);
352 if (dist_squared < hovered_vert_dist_squared)
355 hovered_vert_dist_squared = dist_squared;
356 dbg_cursor_dist = cursor_dist;
363 if (hovered_vert != -1
378 if (vert_pos.z < 0.f)
382 drawlist->ChannelsSetCurrent(LAYER_NODES);
386 ImVec2 cursor_dist((vert_pos.x - mouse_pos.x), (vert_pos.y - mouse_pos.y));
387 float dist_squared = (cursor_dist.x * cursor_dist.x) + (cursor_dist.y * cursor_dist.y);
388 if (dist_squared < hovered_vert_dist_squared)
391 hovered_vert_dist_squared = dist_squared;
392 dbg_cursor_dist = cursor_dist;
396 drawlist->ChannelsSetCurrent(LAYER_TEXT);
402 Ogre::Vector3 refnode_pos = world2screen.
Convert(
nodes[loc.
ref].AbsPosition);
403 Ogre::Vector3 xnode_pos = world2screen.
Convert(
nodes[loc.
nx].AbsPosition);
404 Ogre::Vector3 ynode_pos = world2screen.
Convert(
nodes[loc.
ny].AbsPosition);
413 drawlist->ChannelsSetCurrent(LAYER_BEAMS);
414 if (refnode_pos.z < 0)
428 if (i == hovered_vert && ImGui::IsMouseClicked(0))
436 drawlist->ChannelsMerge();
469 if (combo_flexbody_selection >= 0 && combo_flexbody_selection < (
int)flexbody_vec.size())
476 if (combo_prop_selection >= 0 && combo_prop_selection < (
int)prop_vec.size())
479 if (prop_vec[combo_prop_selection].pp_wheel_mesh_obj)
482 prop_vec[combo_prop_selection].pp_wheel_mesh_obj->setVisible(
true);
493 prop.pp_camera_mode_active = prop.pp_camera_mode_orig;
498 flexbody->fb_camera_mode_active = flexbody->fb_camera_mode_orig;
505 const float content_height =
506 (2.f * ImGui::GetStyle().WindowPadding.y)
507 + (5.f * ImGui::GetItemsLineHeightWithSpacing())
508 + ImGui::GetStyle().ItemSpacing.y * 5;
509 const float child_height = ImGui::GetWindowHeight() - (content_height + 100);
512 ImGui::BeginChild(
"FlexbodyDebug-scroll", ImVec2(0.f, child_height),
false);
516 ImGui::TextDisabled(
"Vert#");
518 ImGui::TextDisabled(
"REF node");
520 ImGui::TextDisabled(
"VX node");
522 ImGui::TextDisabled(
"VY node");
532 ImGui::TextDisabled(
"%d", i);
534 ImGui::Text(
"%d", (
int)loc.
ref);
536 ImGui::Text(
"%d", (
int)loc.
nx);
538 ImGui::Text(
"%d", (
int)loc.
ny);
541 if (ImGui::Checkbox(
"Show", &show))
548 locators_visible = locators_visible || this->
show_locator[i];
559 NodeNum_t forset_max = std::numeric_limits<NodeNum_t>::min();
560 NodeNum_t forset_min = std::numeric_limits<NodeNum_t>::max();
563 if (n > forset_max) { forset_max = n; }
564 if (n < forset_min) { forset_min = n; }
568 const float SLIDER_WIDTH = 150;
571 if (ImGui::Button(
"Reload vehicle"))
581 if (ImGui::CollapsingHeader(
"Artistic effects (keep all enabled for correct visual)."))
593 ImGui::TextDisabled(
"Sorting: insert-sort by lowest penalty, start: REF=VX=VY=%d", (
int)forset_min);
594 ImGui::TextDisabled(
"Penalty calc: nodes (each x each), smalest nodes, node means");
595 ImGui::SetNextItemWidth(SLIDER_WIDTH);
597 ImGui::SetNextItemWidth(SLIDER_WIDTH);
599 ImGui::SetNextItemWidth(SLIDER_WIDTH);
604 ImGui::TextDisabled(
"For optimal CPU cache usage, all dots should be roughly in ascending order (left->right), gaps are OK");
605 ImGui::TextDisabled(
"X axis (left->right) = verts (total %d)", flexbody->
getVertexCount());
606 ImGui::TextDisabled(
"Y axis (bottom->top) = nodes (lowest %d, higest %d) ", (
int)forset_min, (
int)forset_max);
616 ImVec2 size(ImGui::GetWindowWidth() - 2 * ImGui::GetStyle().WindowPadding.x, 200);
617 ImVec2 top_left_pos = ImGui::GetCursorScreenPos();
620 ImDrawList* drawlist = ImGui::GetWindowDrawList();
622 const float x_step = (size.x / (float)num_verts);
623 const float y_step = (size.y / (float)(forset_max - forset_min));
624 for (
int i = 0; i < num_verts; i++)
626 const int NUM_SEGMENTS = 5;
628 ImVec2 bottom_x_pos = top_left_pos + ImVec2(i * x_step, size.y);
639 ImGui::Text(
"For developers only; modders cannot affect this.");
648 ImGui::Text(
"The prop mesh files as provided by modder.");