5#include "imgui_widgets/utils.h"
34#include <imgui/imgui.h>
35#include <imgui/imgui_internal.h>
36#include <imgui_widgets/gizmo.h>
37#include <imgui_widgets/imcoolbar.h>
54 const std::string& material_path,
58void manipulation_gizmos(
bool& gizmo_at_center,
59 bool& was_using_gizmo,
61 entt::handle editor_camera,
63void handle_camera_movement(entt::handle camera, math::vec3& move_dir,
float&
acceleration,
bool& is_dragging);
66struct material_preview_state
75static material_preview_state g_preview_state;
78auto check_material_drag(std::string& out_material_path) ->
bool
82 auto payload = ImGui::GetDragDropPayload();
83 if(payload && payload->IsDataType(
type.c_str()))
88 std::string(
reinterpret_cast<const char*
>(payload->Data), std::size_t(payload->DataSize));
98void handle_material_preview(
rtti::context& ctx,
const camera_component& camera_comp,
const std::string& material_path)
100 auto& pick_manager = ctx.
get_cached<picking_manager>();
103 if(g_preview_state.current_drag_material != material_path)
106 if(g_preview_state.is_previewing && g_preview_state.last_preview_entity)
108 restore_original_materials(g_preview_state.last_preview_entity, g_preview_state.original_materials);
112 g_preview_state.current_drag_material = material_path;
113 g_preview_state.is_previewing =
false;
118 auto cursor_pos = ImGui::GetMousePos();
119 pick_manager.query_pick(math::vec2{cursor_pos.x, cursor_pos.y},
120 camera_comp.get_camera(),
121 [&ctx, material_path](entt::handle
entity,
const math::vec2& screen_pos)
123 apply_material_preview(ctx,
126 g_preview_state.last_preview_entity,
127 g_preview_state.original_materials,
128 g_preview_state.is_previewing);
133void handle_material_drop(
rtti::context& ctx,
const camera_component& camera_comp,
const std::string& material_path)
135 auto cursor_pos = ImGui::GetMousePos();
136 auto& pick_manager = ctx.
get_cached<picking_manager>();
141 auto material_asset = am.get_asset<
material>(material_path);
145 pick_manager.query_pick(
146 math::vec2{cursor_pos.x, cursor_pos.y},
147 camera_comp.get_camera(),
148 [material_asset, &em](entt::handle
entity,
const math::vec2& screen_pos)
154 auto& model_comp =
entity.get<model_component>();
155 const auto& current_model = model_comp.get_model();
156 auto old_materials = current_model.get_materials();
158 em.push_undo_stack_enabled(
true);
161 em.queue_action<entity_set_materials_action_t>({},
entity, old_materials, material_asset);
163 em.pop_undo_stack_enabled();
167 APPLOG_WARNING(
"Cannot apply material to entity without model_component");
177 const camera_component& camera_comp,
178 const std::string& action_name,
179 std::function<entt::handle(
rtti::context&,
scene&,
const camera&,
const math::vec2&)> producer)
181 auto cursor_pos = ImGui::GetMousePos();
184 em.push_undo_stack_enabled(
true);
185 em.queue_action<create_entities_action_t>(
187 [&ctx, camera = camera_comp.get_camera(), cursor_pos, producer = std::move(producer)]() -> entt::handle
189 auto& em = ctx.get_cached<editing_manager>();
190 auto* target_scene = em.get_active_scene(ctx);
196 auto object = producer(ctx, *target_scene, camera, math::vec2{cursor_pos.x, cursor_pos.y});
204 em.pop_undo_stack_enabled();
208void handle_mesh_drop(
rtti::context& ctx,
const camera_component& camera_comp,
const std::string& mesh_path)
212 queue_create_at_cursor(ctx, camera_comp,
"Drop Mesh",
213 [mesh_path, align_to_surface](
rtti::context& ctx,
scene& scn,
const camera& cam,
const math::vec2& cursor) -> entt::handle
220void handle_prefab_drop(
rtti::context& ctx,
const camera_component& camera_comp,
const std::string& prefab_path)
224 queue_create_at_cursor(ctx, camera_comp,
"Drop Prefab",
225 [prefab_path, align_to_surface](
rtti::context& ctx,
scene& scn,
const camera& cam,
const math::vec2& cursor) -> entt::handle
232void reset_preview_state()
234 if(g_preview_state.is_previewing && g_preview_state.last_preview_entity)
236 restore_original_materials(g_preview_state.last_preview_entity, g_preview_state.original_materials);
237 g_preview_state.is_previewing =
false;
238 g_preview_state.last_preview_entity = {};
239 g_preview_state.original_materials.clear();
240 g_preview_state.current_drag_material.clear();
248auto calculate_movement_speed(
float base_speed,
bool speed_boost_active,
float multiplier) ->
float
250 float movement_speed = base_speed;
251 if(speed_boost_active)
253 movement_speed *= multiplier;
255 return movement_speed;
258void handle_middle_mouse_panning(entt::handle camera,
float movement_speed,
float dt)
260 if(!ImGui::IsMouseDown(ImGuiMouseButton_Middle))
265 auto delta_move = ImGui::GetIO().MouseDelta;
266 auto&
transform = camera.get<transform_component>();
268 if(delta_move.x != 0)
270 transform.move_by_local({-1 * delta_move.x * movement_speed * dt, 0.0f, 0.0f});
272 if(delta_move.y != 0)
274 transform.move_by_local({0.0f, delta_move.y * movement_speed * dt, 0.0f});
278auto collect_movement_input(
float& max_hold,
bool& is_dragging) -> math::vec3
280 math::vec3 movement_input{0.0f, 0.0f, 0.0f};
282 auto is_key_down = [&](ImGuiKey
k) ->
bool
284 bool down = ImGui::IsKeyDown(k);
287 auto data = ImGui::GetKeyData(ImGui::GetCurrentContext(), k);
288 max_hold = std::max(max_hold, data->DownDuration);
295 float move_speed = 4.0f;
298 movement_input.z += move_speed;
302 movement_input.z -= move_speed;
306 movement_input.x += move_speed;
310 movement_input.x -= move_speed;
314 auto delta_wheel = ImGui::GetIO().MouseWheel;
317 movement_input.z += 15.0f * delta_wheel;
320 return movement_input;
323auto handle_mouse_rotation(entt::handle camera,
float rotation_speed,
bool is_dragging) ->
bool
330 auto delta_move = ImGui::GetIO().MouseDelta;
331 auto&
transform = camera.get<transform_component>();
333 if(delta_move.x != 0.0f || delta_move.y != 0.0f)
335 float dx = delta_move.x * rotation_speed;
336 float dy = delta_move.y * rotation_speed;
338 transform.rotate_by_euler_global({0.0f, dx, 0.0f});
339 transform.rotate_by_euler_local({dy, 0.0f, 0.0f});
345void update_movement_acceleration(math::vec3& move_dir,
float&
acceleration,
const math::vec3&
input,
bool any_input)
355 move_dir.x =
input.x;
356 move_dir.z =
input.z;
364void apply_movement(entt::handle camera,
365 const math::vec3& move_dir,
366 float movement_speed,
377 auto&
transform = camera.get<transform_component>();
379 if(!math::any(math::epsilonNotEqual(move_dir, math::vec3(0.0f, 0.0f, 0.0f), math::epsilon<float>())))
384 float adjusted_dt = dt;
385 if(math::epsilonNotEqual(move_dir.x, 0.0f, math::epsilon<float>()) ||
386 math::epsilonNotEqual(move_dir.z, 0.0f, math::epsilon<float>()))
388 adjusted_dt += max_hold * hold_speed;
391 auto length = math::length(move_dir);
392 transform.move_by_local(math::normalize(move_dir) * length * movement_speed * adjusted_dt *
acceleration);
395void handle_camera_movement(entt::handle camera, math::vec3& move_dir,
float&
acceleration,
bool& is_dragging)
397 if(!ImGui::IsWindowFocused())
402 if(!ImGui::IsWindowHovered() && !is_dragging)
408 constexpr float base_movement_speed = 2.0f;
409 constexpr float rotation_speed = 0.1f;
410 constexpr float speed_multiplier = 5.0f;
411 constexpr float hold_speed = 0.1f;
412 float fixed_dt = ImMin(0.0333f, ImGui::GetIO().DeltaTime);
415 float movement_speed = calculate_movement_speed(base_movement_speed, speed_boost_active, speed_multiplier);
418 handle_middle_mouse_panning(camera, movement_speed, fixed_dt);
421 is_dragging = ImGui::IsMouseDown(ImGuiMouseButton_Right);
425 ImGui::WrapMousePos();
426 if(ImGui::IsWindowHovered())
428 ImGui::SetMouseCursor(ImGuiMouseCursor_Cross);
433 float max_hold = 0.0f;
434 math::vec3 movement_input = collect_movement_input(max_hold, is_dragging);
435 bool any_input = math::any(math::epsilonNotEqual(movement_input, math::vec3(0.0f), math::epsilon<float>()));
438 bool any_rotation = handle_mouse_rotation(camera, rotation_speed, is_dragging);
441 update_movement_acceleration(move_dir,
acceleration, movement_input, any_input);
443 if(any_input || any_rotation)
451 apply_movement(camera, move_dir, movement_speed,
acceleration, 0.0f, hold_speed, fixed_dt);
459void setup_gizmo_context(
const camera_component& camera_comp)
461 auto p = ImGui::GetItemRectMin();
462 auto s = ImGui::GetItemRectSize();
463 const auto& camera = camera_comp.get_camera();
465 ImGuizmo::SetDrawlist(ImGui::GetWindowDrawList());
466 ImGuizmo::SetRect(
p.x,
p.y,
s.x,
s.y);
470void handle_view_manipulator(entt::handle editor_camera,
const camera_component& camera_comp)
472 auto p = ImGui::GetItemRectMin();
473 auto s = ImGui::GetItemRectSize();
474 const auto& camera = camera_comp.get_camera();
475 auto& camera_trans = editor_camera.get<transform_component>();
477 auto view = camera.get_view().get_matrix();
478 static const ImVec2 view_gizmo_sz(100.0f, 100.0f);
480 ImGuizmo::ViewManipulate(value_ptr(
view),
482 p + ImVec2(
s.x - view_gizmo_sz.x, 0.0f),
484 ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)));
490void handle_gizmo_shortcuts(editing_manager& em)
492 if(!ImGui::IsWindowFocused())
496 if(ImGui::IsMouseDown(ImGuiMouseButton_Right) || ImGui::IsAnyItemActive() || ImGuizmo::IsUsing())
503 em.operation = ImGuizmo::OPERATION::UNIVERSAL;
507 em.operation = ImGuizmo::OPERATION::TRANSLATE;
511 em.operation = ImGuizmo::OPERATION::ROTATE;
515 em.operation = ImGuizmo::OPERATION::SCALE;
519 em.operation = ImGuizmo::OPERATION::BOUNDS;
523void setup_snap_data(editing_manager& em,
float*& snap,
float*& bounds_snap,
float bounds_snap_data[3])
526 bounds_snap =
nullptr;
533 bounds_snap = bounds_snap_data;
535 if(em.operation == ImGuizmo::OPERATION::TRANSLATE)
537 snap = &em.snap_data.translation_snap[0];
539 else if(em.operation == ImGuizmo::OPERATION::ROTATE)
541 snap = &em.snap_data.rotation_degree_snap;
543 else if(em.operation == ImGuizmo::OPERATION::SCALE)
545 snap = &em.snap_data.scale_snap;
549auto calculate_center_pivot(
const std::vector<entt::handle*>& selections) -> math::vec3
551 math::vec3 pivot{0.0f, 0.0f, 0.0f};
554 for(
const auto& sel : selections)
558 auto& sel_transform_comp = sel->get<transform_component>();
559 pivot += sel_transform_comp.get_position_global();
566 pivot /=
static_cast<float>(points);
572void setup_gizmo_pivot(
bool gizmo_at_center,
574 const std::vector<entt::handle*>& selections,
575 entt::handle active_selection)
577 auto& center_transform_comp =
center.get<transform_component>();
578 auto& transform_comp = active_selection.get<transform_component>();
580 auto trans_global = transform_comp.get_transform_global();
581 center_transform_comp.set_transform_global(trans_global);
585 math::vec3 pivot = calculate_center_pivot(selections);
586 center_transform_comp.set_position_global(pivot);
590struct bounds_manipulation_result_t
599auto handle_component_bounds_manipulation(entt::handle active_selection,
601 const camera_component& camera_comp,
604 float bounds_snap_data[3],
605 float* bounds_snap) -> hpp::optional<bounds_manipulation_result_t>
607 auto& transform_comp = active_selection.get<transform_component>();
608 const auto& camera = camera_comp.get_camera();
625 model_tr.
set_position(transform_comp.get_position_global());
626 model_tr.
set_rotation(transform_comp.get_rotation_global());
627 model_tr.
set_scale(math::vec3(area.width, area.height, 1.0f));
629 math::mat4 output = model_tr;
631 int movetype = ImGuizmo::Manipulate(camera.get_view(),
632 camera.get_projection(),
635 math::value_ptr(output),
641 if(movetype != ImGuizmo::MT_NONE)
650 bounds_manipulation_result_t result;
661auto handle_text_component_bounds_manipulation(entt::handle active_selection,
662 const camera_component& camera_comp,
665 float bounds_snap_data[3],
666 float* bounds_snap) ->
bool
668 auto text_comp = active_selection.try_get<text_component>();
674 auto area = text_comp->get_area();
680 auto result = handle_component_bounds_manipulation(active_selection,
694 const auto&
new_area = result->new_area;
698 auto composite_action = std::make_shared<composite_action_t>();
701 composite_action->add_sub_action(
705 composite_action->add_sub_action(
709 em.push_undo_stack_enabled(
true);
710 em.do_action(
"Text Bounds Manipulation", composite_action);
711 em.pop_undo_stack_enabled();
716auto handle_ui_document_component_bounds_manipulation(entt::handle active_selection,
717 const camera_component& camera_comp,
720 float bounds_snap_data[3],
721 float* bounds_snap) ->
bool
723 auto ui_document_comp = active_selection.try_get<ui_document_component>();
724 if(!ui_document_comp)
729 if(!ui_document_comp->size.is_valid())
733 auto area = ui_document_comp->get_world_space_scale();
735 auto result = handle_component_bounds_manipulation(active_selection,
747 const auto&
initial_area =
fsize_t(result->initial_area.width * ui_document_comp->pixels_per_world_unit,
748 result->initial_area.height * ui_document_comp->pixels_per_world_unit);
750 const auto&
new_area =
fsize_t(result->new_area.width * ui_document_comp->pixels_per_world_unit,
751 result->new_area.height * ui_document_comp->pixels_per_world_unit);
755 auto composite_action = std::make_shared<composite_action_t>();
760 composite_action->add_sub_action(
761 std::make_shared<entity_set_ui_document_component_bounds_action_t>(active_selection,
766 composite_action->add_sub_action(
770 em.push_undo_stack_enabled(
true);
771 em.do_action(
"UI Document Size Manipulation", composite_action);
772 em.pop_undo_stack_enabled();
777auto handle_inverse_kinematics(entt::handle selection, entt::handle
center, editing_manager& em) ->
bool
780 bool is_gizmo_active = ImGuizmo::IsUsing();
781 bool is_other_item_active = ImGui::IsAnyItemActive() && !is_gizmo_active;
783 if(is_other_item_active)
788 auto& center_transform_comp =
center.get<transform_component>();
793 center_transform_comp.get_position_global(),
795 em.ik_data.num_nodes,
801 center_transform_comp.get_position_global(),
803 em.ik_data.num_nodes,
809 center_transform_comp.get_position_global(),
810 center_transform_comp.get_z_axis_global(),
817void apply_transform_delta_to_selections(
const std::vector<entt::handle>& top_level_selections,
818 const std::vector<entt::handle>& original_parents,
819 const math::mat4& center_delta)
821 for(
size_t i = 0;
i < top_level_selections.size(); ++
i)
823 auto& sel = top_level_selections[
i];
829 auto& sel_transform_comp = sel.get<transform_component>();
832 math::mat4 old_global = sel_transform_comp.get_transform_global();
835 math::mat4 new_global = center_delta * old_global;
839 entt::handle original_parent = original_parents[
i];
842 const auto& parent_transform = original_parent.get<transform_component>();
843 math::mat4 parent_global = parent_transform.get_transform_global();
844 math::mat4 parent_global_inv = glm::inverse(parent_global);
846 math::mat4 new_local = parent_global_inv * new_global;
857auto handle_standard_gizmo_manipulation(entt::handle active_selection,
859 const camera_component& camera_comp,
863 auto& center_transform_comp =
center.get<transform_component>();
864 const auto& camera = camera_comp.get_camera();
866 math::mat4 output = center_transform_comp.get_transform_global();
867 math::mat4 output_delta;
869 ImGuizmo::AllowAxisFlip(
false);
871 int movetype = ImGuizmo::Manipulate(camera.get_view(),
872 camera.get_projection(),
875 math::value_ptr(output),
876 math::value_ptr(output_delta),
881 if(movetype != ImGuizmo::MT_NONE)
885 auto perspective = center_transform_comp.get_perspective_local();
886 auto skew = center_transform_comp.get_skew_local();
888 if(ImGuizmo::IsScaleType(movetype))
890 center_transform_comp.scale_by_local(delta.
get_scale());
892 if(ImGuizmo::IsRotateType(movetype))
894 center_transform_comp.rotate_by_global(delta.
get_rotation());
896 if(ImGuizmo::IsTranslateType(movetype))
901 center_transform_comp.set_skew_local(skew);
902 center_transform_comp.set_perspective_local(perspective);
908void manipulation_gizmos(
bool& gizmo_at_center,
909 bool& was_using_gizmo,
911 entt::handle editor_camera,
914 auto& camera_trans = editor_camera.get<transform_component>();
915 auto& camera_comp = editor_camera.get<camera_component>();
917 setup_gizmo_context(camera_comp);
918 handle_view_manipulator(editor_camera, camera_comp);
919 handle_gizmo_shortcuts(em);
921 auto active_sel = em.try_get_active_selection_as<entt::handle>();
922 if(!active_sel || !active_sel->valid() || !active_sel->all_of<transform_component>())
927 float bounds_snap_data[3] = {0.1f, 0.1f, 0.0f};
928 float* snap =
nullptr;
929 float* bounds_snap =
nullptr;
931 setup_snap_data(em, snap, bounds_snap, bounds_snap_data);
933 auto selections = em.try_get_selections_as<entt::handle>();
934 setup_gizmo_pivot(gizmo_at_center,
center, selections, *active_sel);
937 auto& center_transform_comp =
center.get<transform_component>();
938 math::mat4 center_initial_global = center_transform_comp.get_transform_global();
941 std::vector<entt::handle> selection_values;
942 selection_values.reserve(selections.size());
943 for(
const auto& sel : selections)
947 selection_values.emplace_back(*sel);
953 std::vector<entt::handle> original_parents;
954 std::vector<math::transform> original_transforms;
955 original_parents.reserve(top_level_selections.size());
956 original_transforms.reserve(top_level_selections.size());
959 for(
const auto& sel : top_level_selections)
963 auto& sel_transform_comp = sel.get<transform_component>();
964 original_parents.emplace_back(sel_transform_comp.get_parent());
965 original_transforms.emplace_back(sel_transform_comp.get_transform_local());
969 bool bounds_changed =
false;
971 if(em.operation != ImGuizmo::ROTATE && em.operation != ImGuizmo::SCALE && top_level_selections.size() == 1)
973 bounds_changed = handle_text_component_bounds_manipulation(*active_sel,
980 bounds_changed = handle_ui_document_component_bounds_manipulation(*active_sel,
988 int movetype = ImGuizmo::MT_NONE;
990 if(em.operation != ImGuizmo::BOUNDS)
992 movetype = handle_standard_gizmo_manipulation(*active_sel,
center, camera_comp, em, snap);
996 math::mat4 center_final_global = center_transform_comp.get_transform_global();
997 math::mat4 center_delta = center_final_global * glm::inverse(center_initial_global);
999 auto batch_action = std::make_shared<composite_action_t>();
1001 for(
size_t i = 0;
i < top_level_selections.size(); ++
i)
1003 auto& sel = top_level_selections[
i];
1014 handle_inverse_kinematics(sel,
center, em);
1019 auto& sel_transform_comp = sel.get<transform_component>();
1020 math::mat4 old_global = sel_transform_comp.get_transform_global();
1021 math::mat4 new_global = center_delta * old_global;
1024 entt::handle original_parent = original_parents[
i];
1029 const auto& parent_transform = original_parent.get<transform_component>();
1030 math::mat4 parent_global = parent_transform.get_transform_global();
1031 math::mat4 parent_global_inv = glm::inverse(parent_global);
1032 math::mat4 new_local = parent_global_inv * new_global;
1042 sel_transform_comp.set_transform_local(new_local_transform);
1044 if(movetype != ImGuizmo::MT_NONE)
1048 bool position = ImGuizmo::IsTranslateType(movetype);
1049 bool rotation = ImGuizmo::IsRotateType(movetype);
1050 bool scale = ImGuizmo::IsScaleType(movetype);
1053 if(top_level_selections.size() > 1)
1064 auto composite_action = std::make_shared<composite_action_t>();
1068 composite_action->add_sub_action(
1069 std::make_shared<transform_move_action_t>(sel,
1070 original_transforms[i].get_position(),
1075 composite_action->add_sub_action(
1076 std::make_shared<transform_rotate_action_t>(sel,
1077 original_transforms[i].get_rotation(),
1082 composite_action->add_sub_action(
1083 std::make_shared<transform_scale_action_t>(sel,
1084 original_transforms[i].get_scale(),
1089 composite_action->add_sub_action(
1090 std::make_shared<transform_skew_action_t>(sel,
1091 original_transforms[i].get_skew(),
1095 batch_action->add_sub_action(composite_action);
1101 if(batch_action->sub_actions.size() > 0)
1103 em.push_undo_stack_enabled(
true);
1104 em.do_action(
"Transform Manipulation", batch_action);
1105 em.pop_undo_stack_enabled();
1110void process_drag_drop_target(
rtti::context& ctx,
const camera_component& camera_comp)
1112 if(!ImGui::BeginDragDropTarget())
1115 reset_preview_state();
1120 if(ImGui::IsDragDropPayloadBeingAccepted())
1122 ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
1125 std::string material_path;
1126 if(check_material_drag(material_path))
1128 handle_material_preview(ctx, camera_comp, material_path);
1133 ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed);
1134 reset_preview_state();
1140 auto payload = ImGui::AcceptDragDropPayload(
type.c_str());
1141 if(payload !=
nullptr)
1143 std::string absolute_path(
reinterpret_cast<const char*
>(payload->Data), std::size_t(payload->DataSize));
1147 reset_preview_state();
1149 handle_material_drop(ctx, camera_comp, key);
1156 auto payload = ImGui::AcceptDragDropPayload(
type.c_str());
1157 if(payload !=
nullptr)
1160 reset_preview_state();
1162 std::string absolute_path(
reinterpret_cast<const char*
>(payload->Data), std::size_t(payload->DataSize));
1165 handle_mesh_drop(ctx, camera_comp, key);
1172 auto payload = ImGui::AcceptDragDropPayload(
type.c_str());
1173 if(payload !=
nullptr)
1176 reset_preview_state();
1178 std::string absolute_path(
reinterpret_cast<const char*
>(payload->Data), std::size_t(payload->DataSize));
1181 handle_prefab_drop(ctx, camera_comp, key);
1185 ImGui::EndDragDropTarget();
1194 auto& model_comp =
entity.get<model_component>();
1195 class model model_copy = model_comp.get_model();
1198 for(
size_t i = 0;
i <
original_materials.size() && i < model_copy.get_materials().size(); ++i)
1204 model_comp.set_model(model_copy);
1210 const std::string& material_path,
1241 auto material_asset = am.get_asset<
material>(material_path);
1244 auto& model_comp =
entity.get<model_component>();
1245 auto& model = model_comp.get_model();
1251 for(
const auto& mat : model.get_materials())
1258 class model model_copy = model;
1259 for(
size_t i = 0;
i < model_copy.get_materials().
size(); ++
i)
1261 model_copy.set_material(material_asset, i);
1263 model_comp.set_model(model_copy);
1279 , fullscreen_name_(get_name() +
" (Fullscreen)")
1312 if(!ImGui::IsAnyItemHovered() && !ImGuizmo::IsOver() && ImGui::IsWindowHovered())
1314 if(ImGui::IsMouseClicked(ImGuiMouseButton_Left))
1316 drag_start_pos_ = ImGui::GetMousePos();
1319 if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
1322 if(!is_drag_selecting_)
1324 is_drag_selecting_ =
true;
1330 if(is_drag_selecting_)
1332 drag_current_pos_ = ImGui::GetMousePos();
1335 if(ImGui::IsMouseReleased(ImGuiMouseButton_Left))
1337 auto& pick_manager = ctx.
get_cached<picking_manager>();
1338 pick_manager.cancel_pick();
1339 is_drag_selecting_ =
false;
1344void scene_panel::draw_drag_selection_rect(
const ImVec2& start_pos,
const ImVec2& current_pos)
1346 if(start_pos.x == current_pos.x && start_pos.y == current_pos.y)
1351 ImDrawList* draw_list = ImGui::GetWindowDrawList();
1354 ImVec2 min_pos(std::min(start_pos.x, current_pos.x), std::min(start_pos.y, current_pos.y));
1355 ImVec2 max_pos(std::max(start_pos.x, current_pos.x), std::max(start_pos.y, current_pos.y));
1358 ImU32 rect_color = ImGui::GetColorU32(ImVec4(0.2f, 0.6f, 1.0f, 0.3f));
1359 ImU32 border_color = ImGui::GetColorU32(ImVec4(0.2f, 0.6f, 1.0f, 0.8f));
1362 draw_list->AddRectFilled(min_pos, max_pos, rect_color);
1365 draw_list->AddRect(min_pos, max_pos, border_color, 0.0f, 0, 2.0f);
1368void scene_panel::handle_prefab_mode_changes(
rtti::context& ctx)
1370 auto& em = ctx.
get_cached<editing_manager>();
1374 if(is_prefab_mode && !was_prefab_mode_)
1380 else if(!is_prefab_mode && was_prefab_mode_)
1389 was_prefab_mode_ = is_prefab_mode;
1394 handle_prefab_mode_changes(ctx);
1423auto scene_panel::begin_panel(
const char*
name, ImGuiWindowFlags flags) ->
bool
1425 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
1427 ImGui::PopStyleVar();
1433 auto& em = ctx.
get_cached<editing_manager>();
1434 auto& path = ctx.
get_cached<rendering_system>();
1442 auto& camera_comp =
handle.get<camera_component>();
1449 path.render_scene(
handle, camera_comp, *target_scene, dt,
false);
1456 if(m_skip_frames_ > 0)
1472 draw_scene(ctx, dt);
1482 ImGuiWindowFlags flags = ImGuiWindowFlags_MenuBar;
1485 flags |= ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
1486 ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus;
1493 entt::handle camera_entity;
1495 [&](
auto e,
auto&& camera_comp)
1497 camera_entity = panel_scene_.create_handle(e);
1499 return camera_entity;
1514 entt::handle center_entity;
1516 auto view = panel_scene_.registry->view<
root_component>(entt::exclude<camera_component>);
1518 [&](
auto e,
auto&& comp)
1520 center_entity = panel_scene_.create_handle(e);
1522 return center_entity;
1527 return auto_save_prefab_;
1534void scene_panel::draw_prefab_mode_header(
rtti::context& ctx)
1543 ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonActive));
1550 ImGui::PopStyleColor();
1555 ImGui::Text(
"Editing Prefab: %s", fs::path(em.
edited_prefab.id()).filename().string().c_str());
1558 if(ImGui::Button(
"Save"))
1564 ImGui::Checkbox(
"Auto Save", &auto_save_prefab_);
1565 ImGui::SetItemTooltipEx(
"%s",
"Automatically save changes when exiting prefab mode");
1571void scene_panel::draw_transform_tools(editing_manager& em)
1573 ImGui::SetNextWindowViewportToCurrent();
1575 if(ImGui::MenuItem(
ICON_MDI_CURSOR_MOVE,
nullptr, em.operation == ImGuizmo::OPERATION::TRANSLATE))
1577 em.operation = ImGuizmo::OPERATION::TRANSLATE;
1579 ImGui::SetItemTooltipEx(
"%s",
"Translate Tool");
1580 ImGui::SetNextWindowViewportToCurrent();
1584 em.operation = ImGuizmo::OPERATION::ROTATE;
1586 ImGui::SetItemTooltipEx(
"%s",
"Rotate Tool");
1587 ImGui::SetNextWindowViewportToCurrent();
1591 em.operation = ImGuizmo::OPERATION::SCALE;
1592 em.mode = ImGuizmo::MODE::LOCAL;
1594 ImGui::SetItemTooltipEx(
"%s",
"Scale Tool");
1595 ImGui::SetNextWindowViewportToCurrent();
1597 if(ImGui::MenuItem(
ICON_MDI_MOVE_RESIZE,
nullptr, em.operation == ImGuizmo::OPERATION::UNIVERSAL))
1599 em.operation = ImGuizmo::OPERATION::UNIVERSAL;
1600 em.mode = ImGuizmo::MODE::LOCAL;
1602 ImGui::SetItemTooltipEx(
"%s",
"Transform Tool");
1605void scene_panel::draw_gizmo_pivot_mode_menu(
bool& gizmo_at_center)
1609 ImGui::SetNextWindowViewportToCurrent();
1611 if(ImGui::BeginMenu(
icon))
1615 gizmo_at_center =
true;
1617 ImGui::SetItemTooltipEx(
"%s",
1618 "The tool handle is placed at the center\n"
1619 "of the selections' pivots.");
1623 gizmo_at_center =
false;
1625 ImGui::SetItemTooltipEx(
"%s",
1626 "The tool handle is placed at the\n"
1627 "active object's pivot point.");
1631 ImGui::SetItemTooltipEx(
"%s",
"Tool's Handle Position");
1634void scene_panel::draw_coordinate_system_menu(editing_manager& em)
1638 ImGui::SetNextWindowViewportToCurrent();
1640 if(ImGui::BeginMenu(
icon))
1644 em.mode == ImGuizmo::MODE::LOCAL))
1646 em.mode = ImGuizmo::MODE::LOCAL;
1648 ImGui::SetItemTooltipEx(
"%s",
"Local Coordinate System");
1650 if(ImGui::MenuItem(
ICON_MDI_WEB "Global",
nullptr, em.mode == ImGuizmo::MODE::WORLD))
1652 em.mode = ImGuizmo::MODE::WORLD;
1654 ImGui::SetItemTooltipEx(
"%s",
"Global Coordinate System");
1658 ImGui::SetItemTooltipEx(
"%s",
"Tool's Coordinate System");
1661void scene_panel::draw_grid_settings_menu(editing_manager& em)
1663 ImGui::SetNextWindowViewportToCurrent();
1667 em.show_grid = !em.show_grid;
1669 ImGui::SetItemTooltipEx(
"%s",
"Show/Hide Grid");
1670 ImGui::SetNextWindowViewportToCurrent();
1674 ImGui::PushItemWidth(100.0f);
1676 ImGui::TextUnformatted(
"Grid Visual");
1677 ImGui::LabelText(
"Plane",
"%s",
"X Z");
1678 ImGui::KnobSliderScalarT(
"Opacity", &em.grid_data.opacity, 0.0f, 1.0f);
1679 ImGui::Checkbox(
"Depth Aware", &em.grid_data.depth_aware);
1680 ImGui::SetItemTooltipEx(
"%s",
"Grid is depth aware.");
1682 ImGui::PopItemWidth();
1686 ImGui::SetItemTooltipEx(
"%s",
"Grid Properties");
1689void scene_panel::draw_gizmos_settings_menu(editing_manager& em)
1691 ImGui::SetNextWindowViewportToCurrent();
1695 em.show_icon_gizmos = !em.show_icon_gizmos;
1697 ImGui::SetItemTooltipEx(
"%s",
"Show/Hide Gizmos");
1698 ImGui::PushID(
"Billboard Gizmos");
1699 ImGui::SetNextWindowViewportToCurrent();
1703 ImGui::PushItemWidth(100.0f);
1705 ImGui::TextUnformatted(
"Gizmos Visual");
1706 ImGui::KnobSliderScalarT(
"Opacity", &em.billboard_data.opacity, 0.0f, 1.0f);
1707 ImGui::KnobSliderScalarT(
"Size", &em.billboard_data.size, 0.1f, 1.0f);
1709 ImGui::Checkbox(
"Depth Aware", &em.billboard_data.depth_aware);
1710 ImGui::SetItemTooltipEx(
"%s",
"Gizmos are depth aware.");
1713 ImGui::TextUnformatted(
"Billboard Filters");
1714 ImGui::Checkbox(
"Camera", &em.billboard_data.show_camera);
1715 ImGui::Checkbox(
"Light", &em.billboard_data.show_light);
1716 ImGui::Checkbox(
"Reflection Probe", &em.billboard_data.show_reflection_probe);
1717 ImGui::Checkbox(
"Audio Source", &em.billboard_data.show_audio_source);
1718 ImGui::Checkbox(
"Particle Emitter", &em.billboard_data.show_particle_emitter);
1721 ImGui::TextUnformatted(
"Selection Gizmos");
1722 ImGui::Checkbox(
"Selection Outline", &em.gizmos.show_selection_outline);
1723 ImGui::Checkbox(
"Selection Wireframe", &em.gizmos.show_selection_wireframe);
1724 ImGui::SetItemTooltipEx(
"%s",
"Draw a vertex-pulling wireframe overlay on top of the selected entity's mesh.");
1725 if(em.gizmos.show_selection_wireframe)
1727 ImGui::ColorEdit4(
"Wireframe Color",
1728 math::value_ptr(em.gizmos.selection_wireframe_color),
1729 ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoInputs);
1730 ImGui::KnobSliderScalarT(
"Wireframe Thickness",
1731 &em.gizmos.selection_wireframe_thickness,
1736 ImGui::Checkbox(
"Camera Gizmos", &em.gizmos.show_camera);
1737 ImGui::Checkbox(
"Model Gizmos", &em.gizmos.show_model);
1738 ImGui::Checkbox(
"Light Gizmos", &em.gizmos.show_light);
1739 ImGui::Checkbox(
"Reflection Probe Gizmos", &em.gizmos.show_reflection_probe);
1740 ImGui::Checkbox(
"Volume Gizmos", &em.gizmos.show_volume);
1741 ImGui::Checkbox(
"Text Gizmos", &em.gizmos.show_text);
1742 ImGui::Checkbox(
"Particle Emitter Gizmos", &em.gizmos.show_particle_emitter);
1743 ImGui::Checkbox(
"Component Gizmos", &em.gizmos.show_component_gizmos);
1746 ImGui::TextUnformatted(
"Model Details");
1747 ImGui::Checkbox(
"World Bounds & LOD", &em.gizmos.show_model_bounds);
1748 ImGui::Checkbox(
"World Submesh Bounds & LOD", &em.gizmos.show_model_submesh_bounds);
1751 ImGui::TextUnformatted(
"Particle Emitter Details");
1752 ImGui::Checkbox(
"Bounds", &em.gizmos.show_particle_emitter_bounds);
1753 ImGui::Checkbox(
"Shape", &em.gizmos.show_particle_emitter_shape);
1754 ImGui::Checkbox(
"Direction", &em.gizmos.show_particle_emitter_direction);
1756 ImGui::PopItemWidth();
1760 ImGui::SetItemTooltipEx(
"%s",
"Gizmos Properties");
1764void scene_panel::draw_visualization_menu()
1766 ImGui::SetNextWindowViewportToCurrent();
1770 ImGui::RadioButton(
"Full", &visualize_passes_, -1);
1771 ImGui::RadioButton(
"Base Color", &visualize_passes_, 0);
1772 ImGui::RadioButton(
"Diffuse Color", &visualize_passes_, 1);
1773 ImGui::RadioButton(
"Specular Color", &visualize_passes_, 2);
1774 ImGui::RadioButton(
"Radiance", &visualize_passes_, 3);
1775 ImGui::RadioButton(
"Irradiance", &visualize_passes_, 4);
1776 ImGui::RadioButton(
"Ambient Occlusion", &visualize_passes_, 5);
1777 ImGui::RadioButton(
"Normals (World Space)", &visualize_passes_, 6);
1778 ImGui::RadioButton(
"Roughness", &visualize_passes_, 7);
1779 ImGui::RadioButton(
"Metalness", &visualize_passes_, 8);
1780 ImGui::RadioButton(
"Emissive Color", &visualize_passes_, 9);
1781 ImGui::RadioButton(
"Subsurface Color", &visualize_passes_, 10);
1782 ImGui::RadioButton(
"Depth", &visualize_passes_, 11);
1783 ImGui::RadioButton(
"SSIL", &visualize_passes_, 12);
1784 ImGui::RadioButton(
"Radiance Alpha", &visualize_passes_, 13);
1785 ImGui::RadioButton(
"Specular Occlusion", &visualize_passes_, 14);
1789 ImGui::SetItemTooltipEx(
"%s",
"Visualize Render Passes");
1792void scene_panel::draw_snapping_menu(editing_manager& em)
1794 ImGui::SetNextWindowViewportToCurrent();
1798 ImGui::PushItemWidth(200.0f);
1799 ImGui::DragVecN(
"Translation Snap",
1800 ImGuiDataType_Float,
1801 math::value_ptr(em.snap_data.translation_snap),
1802 em.snap_data.translation_snap.length(),
1808 ImGui::DragFloat(
"Rotation Degree Snap", &em.snap_data.rotation_degree_snap);
1809 ImGui::DragFloat(
"Scale Snap", &em.snap_data.scale_snap);
1810 ImGui::PopItemWidth();
1813 ImGui::SetItemTooltipEx(
"%s",
"Snapping Properties");
1816void scene_panel::draw_inverse_kinematics_menu(editing_manager& em)
1818 ImGui::SetNextWindowViewportToCurrent();
1822 ImGui::PushItemWidth(200.0f);
1823 ImGui::InputInt(
"Inverse Kinematic Nodes", &em.ik_data.num_nodes);
1826 ImGui::TextUnformatted(
"Inverse Kinematic Shortcuts");
1830 ImGui::PopItemWidth();
1833 ImGui::SetItemTooltipEx(
"%s",
"Inverse Kinematic Properties");
1836void scene_panel::draw_camera_settings_menu(
rtti::context& ctx)
1838 ImGui::SetNextWindowSizeConstraints({}, {400.0f, ImGui::GetContentRegionAvail().y});
1839 ImGui::SetNextWindowViewportToCurrent();
1843 if(ImGui::Button(
"Reset Camera"))
1848 ImGui::SetItemTooltipEx(
"%s",
"Reset the Scene camera.");
1855 ImGui::SetItemTooltipEx(
"%s",
"Settings for the Scene view camera.");
1858void scene_panel::handle_viewport_interaction(
rtti::context& ctx,
const camera& camera, editing_manager& em)
1860 bool is_using = ImGuizmo::IsUsing();
1861 bool is_over = ImGuizmo::IsOver();
1862 bool is_entity = em.is_selected_type<entt::handle>();
1865 handle_drag_selection(ctx, camera, em);
1869 auto& pick_manager = ctx.
get_cached<picking_manager>();
1872 math::vec2 area = {bounds.second.x - bounds.first.x, bounds.second.y - bounds.first.y};
1874 math::vec2
center = {bounds.first.x + area.x * 0.5f, bounds.first.y + area.y * 0.5f};
1876 pick_manager.request_pick(camera, em.get_select_mode(),
center, area);
1880 if(ImGui::IsItemClicked(ImGuiMouseButton_Left) && !is_using && !is_drag_selecting_)
1882 bool is_over_active_gizmo = is_over && is_entity;
1883 if(!is_over_active_gizmo)
1885 ImGui::SetWindowFocus();
1886 auto& pick_manager = ctx.
get_cached<picking_manager>();
1887 auto pos = ImGui::GetMousePos();
1889 pick_manager.request_pick(camera, em.get_select_mode(), {pos.x, pos.y});
1893 if(ImGui::IsItemClicked(ImGuiMouseButton_Middle) || ImGui::IsItemClicked(ImGuiMouseButton_Right))
1895 ImGui::SetWindowFocus();
1896 ImGui::SetMouseCursor(ImGuiMouseCursor_None);
1899 if(ImGui::IsItemReleased(ImGuiMouseButton_Middle) || ImGui::IsItemReleased(ImGuiMouseButton_Right))
1901 ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
1905void scene_panel::handle_keyboard_shortcuts(editing_manager& em)
1911 auto selections = em.try_get_selections_as_copy<entt::handle>();
1913 if(is_delete_pressed)
1918 if(is_focus_pressed)
1923 if(is_duplicate_pressed)
1929void scene_panel::setup_camera_viewport(camera_component& camera_comp,
const ImVec2&
size,
const ImVec2& pos)
1933 camera_comp.get_camera().set_viewport_pos({
static_cast<int32_t
>(pos.x),
static_cast<int32_t
>(pos.y)});
1934 camera_comp.set_viewport_size({
static_cast<std::uint32_t
>(
size.x),
static_cast<std::uint32_t
>(
size.y)});
1938void scene_panel::draw_scene_viewport(
rtti::context& ctx,
const ImVec2&
size,
const ImVec2& pos)
1940 auto& em = ctx.
get_cached<editing_manager>();
1947 auto& camera_comp = camera_entity.get<camera_component>();
1948 const auto& camera = camera_comp.get_camera();
1949 const auto& rview = camera_comp.get_render_view();
1950 const auto& obuffer = rview.fbo_safe_get(
"OBUFFER");
1952 ImGui::SetCursorScreenPos(pos);
1953 if(obuffer && obuffer->get_attachment_count() > 0)
1955 const auto& tex = obuffer->get_texture(0);
1963 if(em.is_prefab_mode())
1965 ImVec2 padding(2.0f, 2.0f);
1966 auto color = ImGui::GetColorU32(ImGuiCol_ButtonActive);
1967 auto min = ImGui::GetItemRectMin() - padding;
1968 auto max = ImGui::GetItemRectMax() + padding;
1969 ImGui::RenderFocusFrame(min, max,
color, 4.0f);
1972 handle_viewport_interaction(ctx, camera, em);
1973 handle_keyboard_shortcuts(em);
1975 manipulation_gizmos(gizmo_at_center_, was_using_gizmo_,
get_center(), camera_entity, em);
1976 handle_camera_movement(camera_entity, move_dir_, acceleration_, is_dragging_);
1977 draw_selected_camera(ctx, camera_entity,
size);
2018 if(is_drag_selecting_)
2020 draw_drag_selection_rect(drag_start_pos_, drag_current_pos_);
2023 camera_comp.get_pipeline_data().get_pipeline()->set_debug_pass(visualize_passes_);
2025 auto window = ImGui::GetCurrentWindow();
2026 auto draw_list = window->DrawList;
2027 auto clip_rect = window->ClipRect;
2028 clip_rect.Expand(-ImGui::GetStyle().FramePadding);
2029 draw_list->PushClipRect(clip_rect.Min, clip_rect.Max);
2031 auto callbacks = std::move(dd_2d_.
callbacks);
2032 for(
const auto& callback : callbacks)
2037 draw_list->PopClipRect();
2044 if(m_skip_frames_ > 0)
2046 auto spinner_size = ImGui::GetContentRegionAvail().y * 0.2f;
2048 ImGui::SetCursorPosY(ImGui::GetContentRegionAvail().
y * 0.5f - spinner_size * 0.5f);
2049 ImGui::AlignedItem(0.5f,
2050 ImGui::GetContentRegionAvail().
x,
2054 ImSpinner::Spinner<ImSpinner::SpinnerTypeT::e_st_eclipse>(
"spinner",
2055 ImSpinner::Radius{spinner_size * 0.5f},
2056 ImSpinner::Thickness{6.0f},
2057 ImSpinner::Color{ImSpinner::white},
2058 ImSpinner::Speed{6.0f});
2067 bool has_edit_camera = camera_entity && camera_entity.all_of<transform_component, camera_component>();
2069 if(!has_edit_camera)
2074 auto avail = ImGui::GetContentRegionAvail();
2075 if(avail.x <= 0 || avail.y <= 0)
2085 ImVec2 view_size = avail;
2091 const auto avail_origin = ImGui::GetCursorScreenPos();
2092 const ImVec2 view_pos(avail_origin.x + (avail.x - view_size.x) * 0.5f,
2093 avail_origin.y + (avail.y - view_size.y) * 0.5f);
2095 auto& camera_comp = camera_entity.get<camera_component>();
2097 setup_camera_viewport(camera_comp, view_size, view_pos);
2098 draw_scene_viewport(ctx, view_size, view_pos);
2099 process_drag_drop_target(ctx, camera_comp);
2101 const auto& pstats = camera_comp.get_pipeline_data().get_pipeline()->get_stats();
2113 auto& em = ctx.
get_cached<editing_manager>();
2115 if(ImGui::BeginMenuBar())
2118 ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyleColorVec4(ImGuiCol_TabSelected));
2119 ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetStyleColorVec4(ImGuiCol_TabSelected));
2120 ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImGui::GetStyleColorVec4(ImGuiCol_TabSelectedOverline));
2122 draw_prefab_mode_header(ctx);
2124 draw_transform_tools(em);
2125 draw_gizmo_pivot_mode_menu(gizmo_at_center_);
2126 draw_coordinate_system_menu(em);
2127 draw_grid_settings_menu(em);
2128 draw_gizmos_settings_menu(em);
2129 draw_visualization_menu();
2130 draw_snapping_menu(em);
2131 draw_inverse_kinematics_menu(em);
2132 draw_camera_settings_menu(ctx);
2135 ImGui::PopStyleColor(3);
2137 ImGui::EndMenuBar();
2141void scene_panel::draw_selected_camera(
rtti::context& ctx, entt::handle editor_camera,
const ImVec2&
size)
2143 auto& em = ctx.
get_cached<editing_manager>();
2145 if(
auto sel = em.try_get_active_selection_as<entt::handle>())
2147 if(sel && sel->valid() && sel->all_of<camera_component>())
2149 const auto& selected_camera = sel->get<camera_component>();
2152 game_panel.set_visible_force(
true);
2154 const auto& camera = selected_camera.get_camera();
2155 const auto& render_view = selected_camera.get_render_view();
2156 const auto& viewport_size = camera.get_viewport_size();
2157 const auto& obuffer = render_view.fbo_safe_get(
"OBUFFER");
2163 float factor = std::min(
size.x /
float(viewport_size.width),
size.y /
float(viewport_size.height)) / 4.0f;
2164 ImVec2 bounds(viewport_size.width * factor, viewport_size.height * factor);
2167 ImVec2(ImGui::GetWindowSize().
x - 20 - bounds.x, ImGui::GetWindowSize().y - 20 - bounds.y);
2170 ImGui::SetCursorPos(image_pos);
2172 const auto& tex = obuffer->get_texture(0);
2177 auto&
transform = editor_camera.get<transform_component>();
2178 auto& transform_selected = sel->get<transform_component>();
2179 transform_selected.set_transform_global(
transform.get_transform_global());
const btCollisionObject * object
Class that contains core camera data, used for rendering and other purposes.
auto get_render_view() -> gfx::render_view &
Gets the render view.
Class representing a camera. Contains functionality for manipulating and updating a camera....
void focus_entities(entt::handle camera, const std::vector< entt::handle > &entities)
void duplicate_entities(const std::vector< entt::handle > &entities)
void delete_entities(const std::vector< entt::handle > &entities)
void on_frame_render(rtti::context &ctx, scene &scn, entt::handle camera_entity, dd_2d_raii &dd_2d)
auto init(rtti::context &ctx) -> bool
auto deinit(rtti::context &ctx) -> bool
auto get_profiler_timeline_panel() -> profiler_timeline_panel &
auto get_game_panel() -> game_panel &
virtual auto get_window_name() const -> const char *
virtual bool begin_panel(const char *name, ImGuiWindowFlags flags)
auto is_fullscreen() const -> bool
auto is_visible() const -> bool
Base class for different rendering paths in the ACE framework.
void on_frame_update(scene &scn, delta_t dt)
Prepares the scene for rendering.
void on_frame_before_render(scene &scn, delta_t dt)
void on_frame_render(rtti::context &ctx, delta_t dt)
void on_frame_update(rtti::context &ctx, delta_t dt)
void init(rtti::context &ctx)
auto get_auto_save_prefab() const -> bool
auto is_drag_selection_active() const -> bool
auto get_drag_selection_bounds() const -> std::pair< ImVec2, ImVec2 >
auto get_window_flags() const -> ImGuiWindowFlags override
scene_panel(imgui_panels *parent, const char *name)
void on_frame_before_render(rtti::context &ctx, delta_t dt)
auto get_center() -> entt::handle
void reset_camera(rtti::context &ctx)
Recreate the Scene panel editor camera at the default pose (UI "Reset Camera").
auto get_window_name() const -> const char *override
void deinit(rtti::context &ctx)
auto get_camera() -> entt::handle
size< std::uint32_t > usize32_t
std::chrono::duration< float > delta_t
#define ICON_MDI_ROTATE_3D
#define ICON_MDI_ARROW_DOWN_BOLD
#define ICON_MDI_SELECTION_MARKER
#define ICON_MDI_GRID_LARGE
#define ICON_MDI_ROTATE_3D_VARIANT
#define ICON_MDI_DRAWING_BOX
#define ICON_MDI_CURSOR_MOVE
#define ICON_MDI_SET_CENTER
#define ICON_MDI_KEYBOARD_RETURN
#define ICON_MDI_RELATIVE_SCALE
#define ICON_MDI_MOVE_RESIZE
#define APPLOG_WARNING(...)
void Image(gfx::texture_handle _handle, uint8_t _mip, uint8_t _flags, const ImVec2 &_size, const ImVec2 &_uv0=ImVec2(0.0f, 0.0f), const ImVec2 &_uv1=ImVec2(1.0f, 1.0f))
ImTextureID ToId(gfx::texture_handle _handle, uint8_t _mip=0, uint8_t _flags=IMGUI_FLAGS_ALPHA_BLEND)
auto get_suported_formats() -> const std::vector< std::string > &
path convert_to_protocol(const path &_path)
Oposite of the resolve_protocol this function tries to convert to protocol path from an absolute one.
bgfx::Transform transform
transform_t< float > transform
void stop_all(const std::string &scope)
Stops all actions within the specified scope.
constexpr ImGuiKey camera_forward
constexpr ImGuiKey camera_left
constexpr ImGuiKey modifier_camera_speed_boost
constexpr ImGuiKey delete_item
const ImGuiKeyCombination duplicate_item
constexpr ImGuiKey camera_right
constexpr ImGuiKey modifier_drop_align_to_surface
constexpr ImGuiKeyChord snap_scene_camera_to_selected_camera
constexpr ImGuiKey ik_ccd
constexpr ImGuiKey camera_backward
auto get_shortcut_name(const ImGuiKeyCombination &shortcut) -> std::string
constexpr ImGuiKey ik_two_bone
constexpr ImGuiKey ik_fabrik
constexpr ImGuiKey toggle_local_global
constexpr ImGuiKey focus_selected
constexpr ImGuiKey bounds_tool
constexpr ImGuiKey rotate_tool
constexpr ImGuiKey modifier_snapping
constexpr ImGuiKey universal_tool
constexpr ImGuiKey scale_tool
constexpr ImGuiKey move_tool
auto get_resolution(rtti::context &ctx, int index) -> const settings::resolution_settings::resolution *
Get the resolution preset at the given index (clamped against the configured presets)....
auto compute_fitted_size(const settings::resolution_settings::resolution &res, ImVec2 avail_size) -> ImVec2
Compute a viewport size that always fits within avail_size by aspect ratio (ignoring any fixed pixel ...
auto draw_menu(rtti::context &ctx, int ¤t_index) -> bool
Draw the resolution selection drop-down for the current menu bar. The selection is read and written t...
void draw(const rendering::pipeline_stats &pstats, state &overlay_state, const char *id)
Draw a statistics overlay child window at the top-right corner of the current ImGui window....
void draw_stats_toggle(state &overlay_state)
Draw a right-aligned "Stats" toggle button for the menu bar. Toggles the overlay visibility on click.
auto ik_set_position_two_bone(entt::handle end_effector, const math::vec3 &target, const math::vec3 &pole, float weight, float soften) -> bool
auto ik_set_position_fabrik(entt::handle end_effector, const math::vec3 &target, const math::vec3 &pole, size_t num_bones_in_chain, int max_iterations, float threshold) -> bool
auto ik_set_position_ccd(entt::handle end_effector, const math::vec3 &target, const math::vec3 &pole, size_t num_bones_in_chain, int max_iterations, float threshold) -> bool
auto make_proxy(entt::meta_any &var, const std::string &name) -> meta_any_proxy
Creates a simple proxy for direct variable access.
auto inspect_var(rtti::context &ctx, entt::meta_any &var, const meta_any_proxy &var_proxy, const var_info &info, const entt::meta_custom &custom) -> inspect_result
Main entry point for inspecting any variable with automatic type resolution.
std::vector< math::color > color
std::vector< float > scale
std::vector< math::quat > rotation
std::vector< asset_handle< material > > original_materials
std::string current_drag_material
math::vec3 initial_position
entt::handle last_preview_entity
Thread-safe handle to an asset.
auto add(Args &&... args) -> T &
std::vector< std::function< void()> > callbacks
static auto create_mesh_entity_at(rtti::context &ctx, scene &scn, const std::string &key, const camera &cam, math::vec2 pos, bool align_to_surface=false) -> entt::handle
Creates a mesh entity at a specified position.
static void focus_camera_on_entities(entt::handle camera, hpp::span< const entt::handle > entities, float duration=0.0f)
Focuses a camera on a specified entity with a timed transition.
static auto create_camera_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a camera entity.
static auto create_prefab_at(rtti::context &ctx, scene &scn, const std::string &key, const camera &cam, math::vec2 pos, bool align_to_surface=false) -> entt::handle
Creates a prefab entity at a specified position.
auto is_prefab_mode() const -> bool
auto get_active_scene(rtti::context &ctx) -> scene *
entt::handle prefab_entity
void exit_prefab_mode(rtti::context &ctx, save_option save_changes=save_option::prompt)
void save_prefab_changes(rtti::context &ctx)
asset_handle< prefab > edited_prefab
Root component structure for the ACE framework, serves as the base component.
auto create_entity(const std::string &tag={}, entt::handle parent={}) -> entt::handle
Creates an entity in the scene with an optional tag and parent.
bool open_profiler_requested