42 ImGui::SetNextWindowPosCenter(ImGuiCond_FirstUseEver);
43 ImGuiWindowFlags win_flags = ImGuiWindowFlags_NoCollapse;
44 bool keep_open =
true;
45 ImGui::Begin(
_LC(
"FlexbodyDebug",
"Flexbody/Prop debug"), &keep_open, win_flags);
50 ImGui::Text(
"%s",
_LC(
"FlexbodyDebug",
"You are on foot."));
58 ImGui::Text(
"%s",
_LC(
"FlexbodyDebug",
"This vehicle has no flexbodies or props."));
81 Ogre::MaterialPtr mat;
83 std::string mesh_name;
103 mat = flexbody->
getEntity()->getSubEntity(0)->getMaterial();
111 ImGui::AlignTextToFramePadding();
112 ImGui::Text(
"Mesh: '%s'", mesh_name.c_str());
119 if (mat->getTechniques().size() > 0 && mat->getTechniques()[0]->getPasses().size() > 0)
121 Ogre::PolygonMode mode = (this->
draw_mesh_wireframe) ? Ogre::PM_WIREFRAME : Ogre::PM_SOLID;
122 mat->getTechniques()[0]->getPasses()[0]->setPolygonMode(mode);
127 ImGui::AlignTextToFramePadding();
128 ImGui::Text(
"Base nodes: Ref=%d, X=%d, Y=%d", (
int)node_ref, (
int)node_x, (
int)node_y);
132 bool flexbody_locators_visible =
false;
135 ImGui::AlignTextToFramePadding();
136 ImGui::Text(
"Forset nodes: (total %d)", (
int)flexbody->
getForsetNodes().size());
140 ImGui::AlignTextToFramePadding();
141 ImGui::Text(
"Vertices: (total %d)", (
int)flexbody->
getVertexCount());
143 ImGui::Checkbox(
"Show all (pick with mouse)##verts", &this->
show_vertices);
150 if (ImGui::CollapsingHeader(
"Vertex locators table"))
155 if (ImGui::CollapsingHeader(
"Vertex locators memory (experimental!)"))
161 if (ImGui::CollapsingHeader(
"Mesh info"))
169 m_is_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
180 this->
DrawDebugView(flexbody, prop, node_ref, node_x, node_y);
192 int num_combo_items = 0;
203 fb->getOrigMeshName(), fb->getVertexCount(), fb->getForsetNodes().size()));
227 if (p.pp_beacon_type ==
'L' || p.pp_beacon_type ==
'R' || p.pp_beacon_type ==
'w')
229 caption =
fmt::format(
"(special prop - aerial nav light '{}')", p.pp_beacon_type);
231 else if (p.pp_wheel_mesh_obj)
233 if (p.pp_mesh_obj->getLoadedMesh() && p.pp_wheel_mesh_obj->getLoadedMesh())
235 caption =
fmt::format(
"(special prop: dashboard '{}' + dirwheel '{}')", p.pp_mesh_obj->getLoadedMesh()->getName(), p.pp_wheel_mesh_obj->getLoadedMesh()->getName());
237 else if (!p.pp_mesh_obj->getLoadedMesh() && p.pp_wheel_mesh_obj->getLoadedMesh())
239 caption =
fmt::format(
"(special prop: no dashboard + dirwheel '{}')", p.pp_wheel_mesh_obj->getLoadedMesh()->getName());
243 caption =
"(corrupted dashboard prop - no meshes loaded)";
246 else if (p.pp_mesh_obj && p.pp_mesh_obj->getLoadedMesh())
248 caption =
fmt::format(
"{} (prop)", p.pp_mesh_obj->getLoadedMesh()->getName());
252 caption =
"(corrupted prop - mesh not loaded)";
296 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
302 const int LAYER_BEAMS = 0;
303 const int LAYER_NODES = 1;
304 const int LAYER_TEXT = 2;
305 drawlist->ChannelsSplit(3);
309 drawlist->ChannelsSetCurrent(LAYER_NODES);
310 Ogre::Vector3 refnode_pos = world2screen.
Convert(
nodes[node_ref].AbsPosition);
311 Ogre::Vector3 xnode_pos = world2screen.
Convert(
nodes[node_x].AbsPosition);
312 Ogre::Vector3 ynode_pos = world2screen.
Convert(
nodes[node_y].AbsPosition);
318 drawlist->ChannelsSetCurrent(LAYER_BEAMS);
319 if (refnode_pos.z < 0)
325 drawlist->ChannelsSetCurrent(LAYER_TEXT);
335 drawlist->ChannelsSetCurrent(LAYER_NODES);
336 Ogre::Vector3 pos = world2screen.
Convert(
nodes[node].AbsPosition);
339 drawlist->ChannelsSetCurrent(LAYER_TEXT);
344 float hovered_vert_dist_squared = FLT_MAX;
345 ImVec2 mouse_pos = ImGui::GetMousePos();
346 ImVec2 dbg_cursor_dist(0, 0);
352 if (vert_pos.z < 0.f)
355 drawlist->ChannelsSetCurrent(LAYER_NODES);
359 ImVec2 cursor_dist((vert_pos.x - mouse_pos.x), (vert_pos.y - mouse_pos.y));
360 float dist_squared = (cursor_dist.x * cursor_dist.x) + (cursor_dist.y * cursor_dist.y);
361 if (dist_squared < hovered_vert_dist_squared)
364 hovered_vert_dist_squared = dist_squared;
365 dbg_cursor_dist = cursor_dist;
387 if (vert_pos.z < 0.f)
391 drawlist->ChannelsSetCurrent(LAYER_NODES);
395 ImVec2 cursor_dist((vert_pos.x - mouse_pos.x), (vert_pos.y - mouse_pos.y));
396 float dist_squared = (cursor_dist.x * cursor_dist.x) + (cursor_dist.y * cursor_dist.y);
397 if (dist_squared < hovered_vert_dist_squared)
400 hovered_vert_dist_squared = dist_squared;
401 dbg_cursor_dist = cursor_dist;
405 drawlist->ChannelsSetCurrent(LAYER_TEXT);
411 Ogre::Vector3 refnode_pos = world2screen.
Convert(
nodes[loc.
ref].AbsPosition);
412 Ogre::Vector3 xnode_pos = world2screen.
Convert(
nodes[loc.
nx].AbsPosition);
413 Ogre::Vector3 ynode_pos = world2screen.
Convert(
nodes[loc.
ny].AbsPosition);
422 drawlist->ChannelsSetCurrent(LAYER_BEAMS);
423 if (refnode_pos.z < 0)
445 drawlist->ChannelsMerge();
478 if (combo_flexbody_selection >= 0 && combo_flexbody_selection < (
int)flexbody_vec.size())
485 if (combo_prop_selection >= 0 && combo_prop_selection < (
int)prop_vec.size())
488 if (prop_vec[combo_prop_selection].pp_wheel_mesh_obj)
491 prop_vec[combo_prop_selection].pp_wheel_mesh_obj->setVisible(
true);
502 prop.pp_camera_mode_active = prop.pp_camera_mode_orig;
507 flexbody->fb_camera_mode_active = flexbody->fb_camera_mode_orig;
514 const float content_height =
515 (2.f * ImGui::GetStyle().WindowPadding.y)
516 + (5.f * ImGui::GetItemsLineHeightWithSpacing())
517 + ImGui::GetStyle().ItemSpacing.y * 5;
518 const float child_height = ImGui::GetWindowHeight() - (content_height + 100);
521 ImGui::BeginChild(
"FlexbodyDebug-scroll", ImVec2(0.f, child_height),
false);
525 ImGui::TextDisabled(
"Vert#");
527 ImGui::TextDisabled(
"REF node");
529 ImGui::TextDisabled(
"VX node");
531 ImGui::TextDisabled(
"VY node");
541 ImGui::TextDisabled(
"%d", i);
543 ImGui::Text(
"%d", (
int)loc.
ref);
545 ImGui::Text(
"%d", (
int)loc.
nx);
547 ImGui::Text(
"%d", (
int)loc.
ny);
550 if (ImGui::Checkbox(
"Show", &
show))
557 locators_visible = locators_visible || this->
show_locator[i];
568 NodeNum_t forset_max = std::numeric_limits<NodeNum_t>::min();
569 NodeNum_t forset_min = std::numeric_limits<NodeNum_t>::max();
572 if (n > forset_max) { forset_max = n; }
573 if (n < forset_min) { forset_min = n; }
577 const float SLIDER_WIDTH = 150;
580 if (ImGui::Button(
"Reload vehicle"))
590 if (ImGui::CollapsingHeader(
"Artistic effects (keep all enabled for correct visual)."))
602 ImGui::TextDisabled(
"Sorting: insert-sort by lowest penalty, start: REF=VX=VY=%d", (
int)forset_min);
603 ImGui::TextDisabled(
"Penalty calc: nodes (each x each), smalest nodes, node means");
604 ImGui::SetNextItemWidth(SLIDER_WIDTH);
606 ImGui::SetNextItemWidth(SLIDER_WIDTH);
608 ImGui::SetNextItemWidth(SLIDER_WIDTH);
613 ImGui::TextDisabled(
"For optimal CPU cache usage, all dots should be roughly in ascending order (left->right), gaps are OK");
614 ImGui::TextDisabled(
"X axis (left->right) = verts (total %d)", flexbody->
getVertexCount());
615 ImGui::TextDisabled(
"Y axis (bottom->top) = nodes (lowest %d, higest %d) ", (
int)forset_min, (
int)forset_max);
625 ImVec2 size(ImGui::GetWindowWidth() - 2 * ImGui::GetStyle().WindowPadding.x, 200);
626 ImVec2 top_left_pos = ImGui::GetCursorScreenPos();
629 ImDrawList* drawlist = ImGui::GetWindowDrawList();
631 const float x_step = (size.x / (float)num_verts);
632 const float y_step = (size.y / (float)(forset_max - forset_min));
633 for (
int i = 0; i < num_verts; i++)
635 const int NUM_SEGMENTS = 5;
637 ImVec2 bottom_x_pos = top_left_pos + ImVec2(i * x_step, size.y);
648 ImGui::Text(
"For developers only; modders cannot affect this.");
657 ImGui::Text(
"The prop mesh files as provided by modder.");