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::Text(
"Mesh: '%s'", mesh_name.c_str());
118 if (mat->getTechniques().size() > 0 && mat->getTechniques()[0]->getPasses().size() > 0)
120 Ogre::PolygonMode mode = (this->
draw_mesh_wireframe) ? Ogre::PM_WIREFRAME : Ogre::PM_SOLID;
121 mat->getTechniques()[0]->getPasses()[0]->setPolygonMode(mode);
126 ImGui::Text(
"Base nodes: Ref=%d, X=%d, Y=%d", (
int)node_ref, (
int)node_x, (
int)node_y);
130 bool flexbody_locators_visible =
false;
133 ImGui::Text(
"Forset nodes: (total %d)", (
int)flexbody->
getForsetNodes().size());
137 ImGui::Text(
"Vertices: (total %d)", (
int)flexbody->
getVertexCount());
139 ImGui::Checkbox(
"Show all (pick with mouse)##verts", &this->
show_vertices);
141 if (ImGui::CollapsingHeader(
"Vertex locators table"))
146 if (ImGui::CollapsingHeader(
"Vertex locators memory (experimental!)"))
152 if (ImGui::CollapsingHeader(
"Mesh info"))
160 m_is_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
171 this->
DrawDebugView(flexbody, prop, node_ref, node_x, node_y);
183 int num_combo_items = 0;
194 fb->getOrigMeshName(), fb->getVertexCount(), fb->getForsetNodes().size()));
218 if (p.pp_beacon_type ==
'L' || p.pp_beacon_type ==
'R' || p.pp_beacon_type ==
'w')
220 caption =
fmt::format(
"(special prop - aerial nav light '{}')", p.pp_beacon_type);
222 else if (p.pp_wheel_mesh_obj)
224 if (p.pp_mesh_obj->getLoadedMesh() && p.pp_wheel_mesh_obj->getLoadedMesh())
226 caption =
fmt::format(
"(special prop: dashboard '{}' + dirwheel '{}')", p.pp_mesh_obj->getLoadedMesh()->getName(), p.pp_wheel_mesh_obj->getLoadedMesh()->getName());
228 else if (!p.pp_mesh_obj->getLoadedMesh() && p.pp_wheel_mesh_obj->getLoadedMesh())
230 caption =
fmt::format(
"(special prop: no dashboard + dirwheel '{}')", p.pp_wheel_mesh_obj->getLoadedMesh()->getName());
234 caption =
"(corrupted dashboard prop - no meshes loaded)";
237 else if (p.pp_mesh_obj && p.pp_mesh_obj->getLoadedMesh())
239 caption =
fmt::format(
"{} (prop)", p.pp_mesh_obj->getLoadedMesh()->getName());
243 caption =
"(corrupted prop - mesh not loaded)";
287 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
293 const int LAYER_BEAMS = 0;
294 const int LAYER_NODES = 1;
295 const int LAYER_TEXT = 2;
296 drawlist->ChannelsSplit(3);
300 drawlist->ChannelsSetCurrent(LAYER_NODES);
301 Ogre::Vector3 refnode_pos = world2screen.
Convert(
nodes[node_ref].AbsPosition);
302 Ogre::Vector3 xnode_pos = world2screen.
Convert(
nodes[node_x].AbsPosition);
303 Ogre::Vector3 ynode_pos = world2screen.
Convert(
nodes[node_y].AbsPosition);
309 drawlist->ChannelsSetCurrent(LAYER_BEAMS);
310 if (refnode_pos.z < 0)
316 drawlist->ChannelsSetCurrent(LAYER_TEXT);
326 drawlist->ChannelsSetCurrent(LAYER_NODES);
327 Ogre::Vector3 pos = world2screen.
Convert(
nodes[node].AbsPosition);
330 drawlist->ChannelsSetCurrent(LAYER_TEXT);
335 int hovered_vert = -1;
336 float hovered_vert_dist_squared = FLT_MAX;
337 ImVec2 mouse_pos = ImGui::GetMousePos();
338 ImVec2 dbg_cursor_dist(0, 0);
344 if (vert_pos.z < 0.f)
347 drawlist->ChannelsSetCurrent(LAYER_NODES);
351 ImVec2 cursor_dist((vert_pos.x - mouse_pos.x), (vert_pos.y - mouse_pos.y));
352 float dist_squared = (cursor_dist.x * cursor_dist.x) + (cursor_dist.y * cursor_dist.y);
353 if (dist_squared < hovered_vert_dist_squared)
356 hovered_vert_dist_squared = dist_squared;
357 dbg_cursor_dist = cursor_dist;
364 if (hovered_vert != -1
379 if (vert_pos.z < 0.f)
383 drawlist->ChannelsSetCurrent(LAYER_NODES);
387 ImVec2 cursor_dist((vert_pos.x - mouse_pos.x), (vert_pos.y - mouse_pos.y));
388 float dist_squared = (cursor_dist.x * cursor_dist.x) + (cursor_dist.y * cursor_dist.y);
389 if (dist_squared < hovered_vert_dist_squared)
392 hovered_vert_dist_squared = dist_squared;
393 dbg_cursor_dist = cursor_dist;
397 drawlist->ChannelsSetCurrent(LAYER_TEXT);
403 Ogre::Vector3 refnode_pos = world2screen.
Convert(
nodes[loc.
ref].AbsPosition);
404 Ogre::Vector3 xnode_pos = world2screen.
Convert(
nodes[loc.
nx].AbsPosition);
405 Ogre::Vector3 ynode_pos = world2screen.
Convert(
nodes[loc.
ny].AbsPosition);
414 drawlist->ChannelsSetCurrent(LAYER_BEAMS);
415 if (refnode_pos.z < 0)
429 if (i == hovered_vert && ImGui::IsMouseClicked(0))
437 drawlist->ChannelsMerge();
470 if (combo_flexbody_selection >= 0 && combo_flexbody_selection < (
int)flexbody_vec.size())
477 if (combo_prop_selection >= 0 && combo_prop_selection < (
int)prop_vec.size())
480 if (prop_vec[combo_prop_selection].pp_wheel_mesh_obj)
483 prop_vec[combo_prop_selection].pp_wheel_mesh_obj->setVisible(
true);
494 prop.pp_camera_mode_active = prop.pp_camera_mode_orig;
499 flexbody->fb_camera_mode_active = flexbody->fb_camera_mode_orig;
506 const float content_height =
507 (2.f * ImGui::GetStyle().WindowPadding.y)
508 + (5.f * ImGui::GetItemsLineHeightWithSpacing())
509 + ImGui::GetStyle().ItemSpacing.y * 5;
510 const float child_height = ImGui::GetWindowHeight() - (content_height + 100);
513 ImGui::BeginChild(
"FlexbodyDebug-scroll", ImVec2(0.f, child_height),
false);
517 ImGui::TextDisabled(
"Vert#");
519 ImGui::TextDisabled(
"REF node");
521 ImGui::TextDisabled(
"VX node");
523 ImGui::TextDisabled(
"VY node");
533 ImGui::TextDisabled(
"%d", i);
535 ImGui::Text(
"%d", (
int)loc.
ref);
537 ImGui::Text(
"%d", (
int)loc.
nx);
539 ImGui::Text(
"%d", (
int)loc.
ny);
542 if (ImGui::Checkbox(
"Show", &show))
549 locators_visible = locators_visible || this->
show_locator[i];
560 NodeNum_t forset_max = std::numeric_limits<NodeNum_t>::min();
561 NodeNum_t forset_min = std::numeric_limits<NodeNum_t>::max();
564 if (n > forset_max) { forset_max = n; }
565 if (n < forset_min) { forset_min = n; }
569 const float SLIDER_WIDTH = 150;
572 if (ImGui::Button(
"Reload vehicle"))
582 if (ImGui::CollapsingHeader(
"Artistic effects (keep all enabled for correct visual)."))
594 ImGui::TextDisabled(
"Sorting: insert-sort by lowest penalty, start: REF=VX=VY=%d", (
int)forset_min);
595 ImGui::TextDisabled(
"Penalty calc: nodes (each x each), smalest nodes, node means");
596 ImGui::SetNextItemWidth(SLIDER_WIDTH);
598 ImGui::SetNextItemWidth(SLIDER_WIDTH);
600 ImGui::SetNextItemWidth(SLIDER_WIDTH);
605 ImGui::TextDisabled(
"For optimal CPU cache usage, all dots should be roughly in ascending order (left->right), gaps are OK");
606 ImGui::TextDisabled(
"X axis (left->right) = verts (total %d)", flexbody->
getVertexCount());
607 ImGui::TextDisabled(
"Y axis (bottom->top) = nodes (lowest %d, higest %d) ", (
int)forset_min, (
int)forset_max);
617 ImVec2 size(ImGui::GetWindowWidth() - 2 * ImGui::GetStyle().WindowPadding.x, 200);
618 ImVec2 top_left_pos = ImGui::GetCursorScreenPos();
621 ImDrawList* drawlist = ImGui::GetWindowDrawList();
623 const float x_step = (size.x / (float)num_verts);
624 const float y_step = (size.y / (float)(forset_max - forset_min));
625 for (
int i = 0; i < num_verts; i++)
627 const int NUM_SEGMENTS = 5;
629 ImVec2 bottom_x_pos = top_left_pos + ImVec2(i * x_step, size.y);
640 ImGui::Text(
"For developers only; modders cannot affect this.");
649 ImGui::Text(
"The prop mesh files as provided by modder.");