|
@@ -82,28 +82,32 @@
|
|
|
#define MAX_FOV 179
|
|
|
|
|
|
void ViewportRotationControl::_notification(int p_what) {
|
|
|
- if (p_what == NOTIFICATION_ENTER_TREE) {
|
|
|
- axis_menu_options.clear();
|
|
|
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_RIGHT);
|
|
|
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_TOP);
|
|
|
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR);
|
|
|
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_LEFT);
|
|
|
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_BOTTOM);
|
|
|
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_FRONT);
|
|
|
-
|
|
|
- axis_colors.clear();
|
|
|
- axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
|
|
|
- axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
|
|
|
- axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), SNAME("Editor")));
|
|
|
- update();
|
|
|
+ switch (p_what) {
|
|
|
+ case NOTIFICATION_ENTER_TREE: {
|
|
|
+ axis_menu_options.clear();
|
|
|
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_RIGHT);
|
|
|
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_TOP);
|
|
|
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR);
|
|
|
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_LEFT);
|
|
|
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_BOTTOM);
|
|
|
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_FRONT);
|
|
|
+
|
|
|
+ axis_colors.clear();
|
|
|
+ axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
|
|
|
+ axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
|
|
|
+ axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), SNAME("Editor")));
|
|
|
+ update();
|
|
|
|
|
|
- if (!is_connected("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited))) {
|
|
|
- connect("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited));
|
|
|
- }
|
|
|
- }
|
|
|
+ if (!is_connected("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited))) {
|
|
|
+ connect("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited));
|
|
|
+ }
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_DRAW && viewport != nullptr) {
|
|
|
- _draw();
|
|
|
+ case NOTIFICATION_DRAW: {
|
|
|
+ if (viewport != nullptr) {
|
|
|
+ _draw();
|
|
|
+ }
|
|
|
+ } break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2422,279 +2426,281 @@ void Node3DEditorViewport::_project_settings_changed() {
|
|
|
}
|
|
|
|
|
|
void Node3DEditorViewport::_notification(int p_what) {
|
|
|
- if (p_what == NOTIFICATION_READY) {
|
|
|
- EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed));
|
|
|
- }
|
|
|
+ switch (p_what) {
|
|
|
+ case NOTIFICATION_READY: {
|
|
|
+ EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed));
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
|
|
- bool visible = is_visible_in_tree();
|
|
|
+ case NOTIFICATION_VISIBILITY_CHANGED: {
|
|
|
+ bool visible = is_visible_in_tree();
|
|
|
|
|
|
- set_process(visible);
|
|
|
+ set_process(visible);
|
|
|
|
|
|
- if (visible) {
|
|
|
- orthogonal = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL));
|
|
|
- _update_name();
|
|
|
- _update_camera(0);
|
|
|
- } else {
|
|
|
- set_freelook_active(false);
|
|
|
- }
|
|
|
- call_deferred(SNAME("update_transform_gizmo_view"));
|
|
|
- rotation_control->set_visible(EditorSettings::get_singleton()->get("editors/3d/navigation/show_viewport_rotation_gizmo"));
|
|
|
- }
|
|
|
+ if (visible) {
|
|
|
+ orthogonal = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL));
|
|
|
+ _update_name();
|
|
|
+ _update_camera(0);
|
|
|
+ } else {
|
|
|
+ set_freelook_active(false);
|
|
|
+ }
|
|
|
+ call_deferred(SNAME("update_transform_gizmo_view"));
|
|
|
+ rotation_control->set_visible(EditorSettings::get_singleton()->get("editors/3d/navigation/show_viewport_rotation_gizmo"));
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_RESIZED) {
|
|
|
- call_deferred(SNAME("update_transform_gizmo_view"));
|
|
|
- }
|
|
|
+ case NOTIFICATION_RESIZED: {
|
|
|
+ call_deferred(SNAME("update_transform_gizmo_view"));
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_PROCESS) {
|
|
|
- real_t delta = get_process_delta_time();
|
|
|
+ case NOTIFICATION_PROCESS: {
|
|
|
+ real_t delta = get_process_delta_time();
|
|
|
|
|
|
- if (zoom_indicator_delay > 0) {
|
|
|
- zoom_indicator_delay -= delta;
|
|
|
- if (zoom_indicator_delay <= 0) {
|
|
|
- surface->update();
|
|
|
- zoom_limit_label->hide();
|
|
|
+ if (zoom_indicator_delay > 0) {
|
|
|
+ zoom_indicator_delay -= delta;
|
|
|
+ if (zoom_indicator_delay <= 0) {
|
|
|
+ surface->update();
|
|
|
+ zoom_limit_label->hide();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- _update_freelook(delta);
|
|
|
+ _update_freelook(delta);
|
|
|
|
|
|
- Node *scene_root = SceneTreeDock::get_singleton()->get_editor_data()->get_edited_scene_root();
|
|
|
- if (previewing_cinema && scene_root != nullptr) {
|
|
|
- Camera3D *cam = scene_root->get_viewport()->get_camera_3d();
|
|
|
- if (cam != nullptr && cam != previewing) {
|
|
|
- //then switch the viewport's camera to the scene's viewport camera
|
|
|
- if (previewing != nullptr) {
|
|
|
- previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
|
|
|
+ Node *scene_root = SceneTreeDock::get_singleton()->get_editor_data()->get_edited_scene_root();
|
|
|
+ if (previewing_cinema && scene_root != nullptr) {
|
|
|
+ Camera3D *cam = scene_root->get_viewport()->get_camera_3d();
|
|
|
+ if (cam != nullptr && cam != previewing) {
|
|
|
+ //then switch the viewport's camera to the scene's viewport camera
|
|
|
+ if (previewing != nullptr) {
|
|
|
+ previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
|
|
|
+ }
|
|
|
+ previewing = cam;
|
|
|
+ previewing->connect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
|
|
|
+ RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera());
|
|
|
+ surface->update();
|
|
|
}
|
|
|
- previewing = cam;
|
|
|
- previewing->connect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
|
|
|
- RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera());
|
|
|
- surface->update();
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- _update_camera(delta);
|
|
|
+ _update_camera(delta);
|
|
|
|
|
|
- Map<Node *, Object *> &selection = editor_selection->get_selection();
|
|
|
+ Map<Node *, Object *> &selection = editor_selection->get_selection();
|
|
|
|
|
|
- bool changed = false;
|
|
|
- bool exist = false;
|
|
|
+ bool changed = false;
|
|
|
+ bool exist = false;
|
|
|
|
|
|
- for (const KeyValue<Node *, Object *> &E : selection) {
|
|
|
- Node3D *sp = Object::cast_to<Node3D>(E.key);
|
|
|
- if (!sp) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ for (const KeyValue<Node *, Object *> &E : selection) {
|
|
|
+ Node3D *sp = Object::cast_to<Node3D>(E.key);
|
|
|
+ if (!sp) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
|
|
|
- if (!se) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
|
|
|
+ if (!se) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- Transform3D t = sp->get_global_gizmo_transform();
|
|
|
- VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sp);
|
|
|
- AABB new_aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp);
|
|
|
+ Transform3D t = sp->get_global_gizmo_transform();
|
|
|
+ VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sp);
|
|
|
+ AABB new_aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp);
|
|
|
|
|
|
- exist = true;
|
|
|
- if (se->last_xform == t && se->aabb == new_aabb && !se->last_xform_dirty) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- changed = true;
|
|
|
- se->last_xform_dirty = false;
|
|
|
- se->last_xform = t;
|
|
|
+ exist = true;
|
|
|
+ if (se->last_xform == t && se->aabb == new_aabb && !se->last_xform_dirty) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ changed = true;
|
|
|
+ se->last_xform_dirty = false;
|
|
|
+ se->last_xform = t;
|
|
|
|
|
|
- se->aabb = new_aabb;
|
|
|
+ se->aabb = new_aabb;
|
|
|
|
|
|
- Transform3D t_offset = t;
|
|
|
+ Transform3D t_offset = t;
|
|
|
|
|
|
- // apply AABB scaling before item's global transform
|
|
|
- {
|
|
|
- const Vector3 offset(0.005, 0.005, 0.005);
|
|
|
- Basis aabb_s;
|
|
|
- aabb_s.scale(se->aabb.size + offset);
|
|
|
- t.translate(se->aabb.position - offset / 2);
|
|
|
- t.basis = t.basis * aabb_s;
|
|
|
- }
|
|
|
- {
|
|
|
- const Vector3 offset(0.01, 0.01, 0.01);
|
|
|
- Basis aabb_s;
|
|
|
- aabb_s.scale(se->aabb.size + offset);
|
|
|
- t_offset.translate(se->aabb.position - offset / 2);
|
|
|
- t_offset.basis = t_offset.basis * aabb_s;
|
|
|
+ // apply AABB scaling before item's global transform
|
|
|
+ {
|
|
|
+ const Vector3 offset(0.005, 0.005, 0.005);
|
|
|
+ Basis aabb_s;
|
|
|
+ aabb_s.scale(se->aabb.size + offset);
|
|
|
+ t.translate(se->aabb.position - offset / 2);
|
|
|
+ t.basis = t.basis * aabb_s;
|
|
|
+ }
|
|
|
+ {
|
|
|
+ const Vector3 offset(0.01, 0.01, 0.01);
|
|
|
+ Basis aabb_s;
|
|
|
+ aabb_s.scale(se->aabb.size + offset);
|
|
|
+ t_offset.translate(se->aabb.position - offset / 2);
|
|
|
+ t_offset.basis = t_offset.basis * aabb_s;
|
|
|
+ }
|
|
|
+
|
|
|
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t);
|
|
|
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_offset, t_offset);
|
|
|
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t);
|
|
|
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray_offset, t_offset);
|
|
|
}
|
|
|
|
|
|
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t);
|
|
|
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_offset, t_offset);
|
|
|
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t);
|
|
|
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray_offset, t_offset);
|
|
|
- }
|
|
|
+ if (changed || (spatial_editor->is_gizmo_visible() && !exist)) {
|
|
|
+ spatial_editor->update_transform_gizmo();
|
|
|
+ }
|
|
|
|
|
|
- if (changed || (spatial_editor->is_gizmo_visible() && !exist)) {
|
|
|
- spatial_editor->update_transform_gizmo();
|
|
|
- }
|
|
|
+ if (message_time > 0) {
|
|
|
+ if (message != last_message) {
|
|
|
+ surface->update();
|
|
|
+ last_message = message;
|
|
|
+ }
|
|
|
|
|
|
- if (message_time > 0) {
|
|
|
- if (message != last_message) {
|
|
|
- surface->update();
|
|
|
- last_message = message;
|
|
|
+ message_time -= get_physics_process_delta_time();
|
|
|
+ if (message_time < 0) {
|
|
|
+ surface->update();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- message_time -= get_physics_process_delta_time();
|
|
|
- if (message_time < 0) {
|
|
|
- surface->update();
|
|
|
+ bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
|
|
|
+ if (show_info != info_label->is_visible()) {
|
|
|
+ info_label->set_visible(show_info);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
|
|
|
- if (show_info != info_label->is_visible()) {
|
|
|
- info_label->set_visible(show_info);
|
|
|
- }
|
|
|
+ Camera3D *current_camera;
|
|
|
|
|
|
- Camera3D *current_camera;
|
|
|
+ if (previewing) {
|
|
|
+ current_camera = previewing;
|
|
|
+ } else {
|
|
|
+ current_camera = camera;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (show_info) {
|
|
|
+ const String viewport_size = vformat(String::utf8("%d × %d"), viewport->get_size().x, viewport->get_size().y);
|
|
|
+ String text;
|
|
|
+ text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1));
|
|
|
+ text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1));
|
|
|
+ text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1));
|
|
|
+ text += "\n";
|
|
|
+ text += vformat(
|
|
|
+ TTR("Size: %s (%.1fMP)\n"),
|
|
|
+ viewport_size,
|
|
|
+ viewport->get_size().x * viewport->get_size().y * 0.000001);
|
|
|
+
|
|
|
+ text += "\n";
|
|
|
+ text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME));
|
|
|
+ text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
|
|
|
+ text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME));
|
|
|
+
|
|
|
+ info_label->set_text(text);
|
|
|
+ }
|
|
|
+
|
|
|
+ // FPS Counter.
|
|
|
+ bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
|
|
|
+
|
|
|
+ if (show_fps != fps_label->is_visible()) {
|
|
|
+ cpu_time_label->set_visible(show_fps);
|
|
|
+ gpu_time_label->set_visible(show_fps);
|
|
|
+ fps_label->set_visible(show_fps);
|
|
|
+ RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps);
|
|
|
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
|
|
|
+ cpu_time_history[i] = 0;
|
|
|
+ gpu_time_history[i] = 0;
|
|
|
+ }
|
|
|
+ cpu_time_history_index = 0;
|
|
|
+ gpu_time_history_index = 0;
|
|
|
+ }
|
|
|
+ if (show_fps) {
|
|
|
+ cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid());
|
|
|
+ cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY;
|
|
|
+ double cpu_time = 0.0;
|
|
|
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
|
|
|
+ cpu_time += cpu_time_history[i];
|
|
|
+ }
|
|
|
+ cpu_time /= FRAME_TIME_HISTORY;
|
|
|
+ // Prevent unrealistically low values.
|
|
|
+ cpu_time = MAX(0.01, cpu_time);
|
|
|
+
|
|
|
+ gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
|
|
|
+ gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
|
|
|
+ double gpu_time = 0.0;
|
|
|
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
|
|
|
+ gpu_time += gpu_time_history[i];
|
|
|
+ }
|
|
|
+ gpu_time /= FRAME_TIME_HISTORY;
|
|
|
+ // Prevent division by zero for the FPS counter (and unrealistically low values).
|
|
|
+ // This limits the reported FPS to 100000.
|
|
|
+ gpu_time = MAX(0.01, gpu_time);
|
|
|
+
|
|
|
+ // Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
|
|
|
+ // Middle point is at 15 ms.
|
|
|
+ cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), rtos(cpu_time).pad_decimals(2)));
|
|
|
+ cpu_time_label->add_theme_color_override(
|
|
|
+ "font_color",
|
|
|
+ frame_time_gradient->get_color_at_offset(
|
|
|
+ Math::range_lerp(cpu_time, 0, 30, 0, 1)));
|
|
|
+
|
|
|
+ gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), rtos(gpu_time).pad_decimals(2)));
|
|
|
+ // Middle point is at 15 ms.
|
|
|
+ gpu_time_label->add_theme_color_override(
|
|
|
+ "font_color",
|
|
|
+ frame_time_gradient->get_color_at_offset(
|
|
|
+ Math::range_lerp(gpu_time, 0, 30, 0, 1)));
|
|
|
+
|
|
|
+ const double fps = 1000.0 / gpu_time;
|
|
|
+ fps_label->set_text(vformat(TTR("FPS: %d"), fps));
|
|
|
+ // Middle point is at 60 FPS.
|
|
|
+ fps_label->add_theme_color_override(
|
|
|
+ "font_color",
|
|
|
+ frame_time_gradient->get_color_at_offset(
|
|
|
+ Math::range_lerp(fps, 110, 10, 0, 1)));
|
|
|
+ }
|
|
|
+
|
|
|
+ bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
|
|
|
+ cinema_label->set_visible(show_cinema);
|
|
|
+ if (show_cinema) {
|
|
|
+ float cinema_half_width = cinema_label->get_size().width / 2.0f;
|
|
|
+ cinema_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -cinema_half_width);
|
|
|
+ }
|
|
|
|
|
|
- if (previewing) {
|
|
|
- current_camera = previewing;
|
|
|
- } else {
|
|
|
- current_camera = camera;
|
|
|
- }
|
|
|
-
|
|
|
- if (show_info) {
|
|
|
- const String viewport_size = vformat(String::utf8("%d × %d"), viewport->get_size().x, viewport->get_size().y);
|
|
|
- String text;
|
|
|
- text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1));
|
|
|
- text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1));
|
|
|
- text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1));
|
|
|
- text += "\n";
|
|
|
- text += vformat(
|
|
|
- TTR("Size: %s (%.1fMP)\n"),
|
|
|
- viewport_size,
|
|
|
- viewport->get_size().x * viewport->get_size().y * 0.000001);
|
|
|
-
|
|
|
- text += "\n";
|
|
|
- text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME));
|
|
|
- text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
|
|
|
- text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME));
|
|
|
-
|
|
|
- info_label->set_text(text);
|
|
|
- }
|
|
|
-
|
|
|
- // FPS Counter.
|
|
|
- bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
|
|
|
-
|
|
|
- if (show_fps != fps_label->is_visible()) {
|
|
|
- cpu_time_label->set_visible(show_fps);
|
|
|
- gpu_time_label->set_visible(show_fps);
|
|
|
- fps_label->set_visible(show_fps);
|
|
|
- RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps);
|
|
|
- for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
|
|
|
- cpu_time_history[i] = 0;
|
|
|
- gpu_time_history[i] = 0;
|
|
|
- }
|
|
|
- cpu_time_history_index = 0;
|
|
|
- gpu_time_history_index = 0;
|
|
|
- }
|
|
|
- if (show_fps) {
|
|
|
- cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid());
|
|
|
- cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY;
|
|
|
- double cpu_time = 0.0;
|
|
|
- for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
|
|
|
- cpu_time += cpu_time_history[i];
|
|
|
- }
|
|
|
- cpu_time /= FRAME_TIME_HISTORY;
|
|
|
- // Prevent unrealistically low values.
|
|
|
- cpu_time = MAX(0.01, cpu_time);
|
|
|
-
|
|
|
- gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
|
|
|
- gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
|
|
|
- double gpu_time = 0.0;
|
|
|
- for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
|
|
|
- gpu_time += gpu_time_history[i];
|
|
|
- }
|
|
|
- gpu_time /= FRAME_TIME_HISTORY;
|
|
|
- // Prevent division by zero for the FPS counter (and unrealistically low values).
|
|
|
- // This limits the reported FPS to 100000.
|
|
|
- gpu_time = MAX(0.01, gpu_time);
|
|
|
-
|
|
|
- // Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
|
|
|
- // Middle point is at 15 ms.
|
|
|
- cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), rtos(cpu_time).pad_decimals(2)));
|
|
|
- cpu_time_label->add_theme_color_override(
|
|
|
- "font_color",
|
|
|
- frame_time_gradient->get_color_at_offset(
|
|
|
- Math::range_lerp(cpu_time, 0, 30, 0, 1)));
|
|
|
-
|
|
|
- gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), rtos(gpu_time).pad_decimals(2)));
|
|
|
- // Middle point is at 15 ms.
|
|
|
- gpu_time_label->add_theme_color_override(
|
|
|
- "font_color",
|
|
|
- frame_time_gradient->get_color_at_offset(
|
|
|
- Math::range_lerp(gpu_time, 0, 30, 0, 1)));
|
|
|
-
|
|
|
- const double fps = 1000.0 / gpu_time;
|
|
|
- fps_label->set_text(vformat(TTR("FPS: %d"), fps));
|
|
|
- // Middle point is at 60 FPS.
|
|
|
- fps_label->add_theme_color_override(
|
|
|
- "font_color",
|
|
|
- frame_time_gradient->get_color_at_offset(
|
|
|
- Math::range_lerp(fps, 110, 10, 0, 1)));
|
|
|
- }
|
|
|
-
|
|
|
- bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
|
|
|
- cinema_label->set_visible(show_cinema);
|
|
|
- if (show_cinema) {
|
|
|
- float cinema_half_width = cinema_label->get_size().width / 2.0f;
|
|
|
- cinema_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -cinema_half_width);
|
|
|
- }
|
|
|
-
|
|
|
- if (lock_rotation) {
|
|
|
- float locked_half_width = locked_label->get_size().width / 2.0f;
|
|
|
- locked_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -locked_half_width);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (p_what == NOTIFICATION_ENTER_TREE) {
|
|
|
- surface->connect("draw", callable_mp(this, &Node3DEditorViewport::_draw));
|
|
|
- surface->connect("gui_input", callable_mp(this, &Node3DEditorViewport::_sinput));
|
|
|
- surface->connect("mouse_entered", callable_mp(this, &Node3DEditorViewport::_surface_mouse_enter));
|
|
|
- surface->connect("mouse_exited", callable_mp(this, &Node3DEditorViewport::_surface_mouse_exit));
|
|
|
- surface->connect("focus_entered", callable_mp(this, &Node3DEditorViewport::_surface_focus_enter));
|
|
|
- surface->connect("focus_exited", callable_mp(this, &Node3DEditorViewport::_surface_focus_exit));
|
|
|
-
|
|
|
- _init_gizmo_instance(index);
|
|
|
- }
|
|
|
-
|
|
|
- if (p_what == NOTIFICATION_EXIT_TREE) {
|
|
|
- _finish_gizmo_instances();
|
|
|
- }
|
|
|
+ if (lock_rotation) {
|
|
|
+ float locked_half_width = locked_label->get_size().width / 2.0f;
|
|
|
+ locked_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -locked_half_width);
|
|
|
+ }
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_THEME_CHANGED) {
|
|
|
- view_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
|
|
|
- preview_camera->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
|
|
|
- Control *gui_base = EditorNode::get_singleton()->get_gui_base();
|
|
|
+ case NOTIFICATION_ENTER_TREE: {
|
|
|
+ surface->connect("draw", callable_mp(this, &Node3DEditorViewport::_draw));
|
|
|
+ surface->connect("gui_input", callable_mp(this, &Node3DEditorViewport::_sinput));
|
|
|
+ surface->connect("mouse_entered", callable_mp(this, &Node3DEditorViewport::_surface_mouse_enter));
|
|
|
+ surface->connect("mouse_exited", callable_mp(this, &Node3DEditorViewport::_surface_mouse_exit));
|
|
|
+ surface->connect("focus_entered", callable_mp(this, &Node3DEditorViewport::_surface_focus_enter));
|
|
|
+ surface->connect("focus_exited", callable_mp(this, &Node3DEditorViewport::_surface_focus_exit));
|
|
|
+
|
|
|
+ _init_gizmo_instance(index);
|
|
|
+ } break;
|
|
|
|
|
|
- view_menu->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- view_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- view_menu->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- view_menu->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- view_menu->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
-
|
|
|
- preview_camera->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- preview_camera->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- preview_camera->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- preview_camera->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- preview_camera->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
-
|
|
|
- frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), SNAME("Editor")));
|
|
|
- frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
|
|
|
- frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), SNAME("Editor")));
|
|
|
+ case NOTIFICATION_EXIT_TREE: {
|
|
|
+ _finish_gizmo_instances();
|
|
|
+ } break;
|
|
|
|
|
|
- info_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- cpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- gpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- fps_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
- locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ case NOTIFICATION_THEME_CHANGED: {
|
|
|
+ view_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
|
|
|
+ preview_camera->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
|
|
|
+ Control *gui_base = EditorNode::get_singleton()->get_gui_base();
|
|
|
+
|
|
|
+ view_menu->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ view_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ view_menu->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ view_menu->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ view_menu->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+
|
|
|
+ preview_camera->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ preview_camera->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ preview_camera->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ preview_camera->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ preview_camera->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+
|
|
|
+ frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), SNAME("Editor")));
|
|
|
+ frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
|
|
|
+ frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), SNAME("Editor")));
|
|
|
+
|
|
|
+ info_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ cpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ gpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ fps_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
|
|
|
+ } break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -4799,197 +4805,202 @@ void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
|
|
|
}
|
|
|
|
|
|
void Node3DEditorViewportContainer::_notification(int p_what) {
|
|
|
- if (p_what == NOTIFICATION_MOUSE_ENTER || p_what == NOTIFICATION_MOUSE_EXIT) {
|
|
|
- mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
|
|
|
- update();
|
|
|
- }
|
|
|
+ switch (p_what) {
|
|
|
+ case NOTIFICATION_MOUSE_ENTER:
|
|
|
+ case NOTIFICATION_MOUSE_EXIT: {
|
|
|
+ mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
|
|
|
+ update();
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_DRAW && mouseover) {
|
|
|
- Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
|
|
|
- Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
|
|
|
+ case NOTIFICATION_DRAW: {
|
|
|
+ if (mouseover) {
|
|
|
+ Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
|
|
|
+ Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
|
|
|
|
|
|
- Ref<Texture2D> hdiag_grabber = get_theme_icon(SNAME("GuiViewportHdiagsplitter"), SNAME("EditorIcons"));
|
|
|
- Ref<Texture2D> vdiag_grabber = get_theme_icon(SNAME("GuiViewportVdiagsplitter"), SNAME("EditorIcons"));
|
|
|
- Ref<Texture2D> vh_grabber = get_theme_icon(SNAME("GuiViewportVhsplitter"), SNAME("EditorIcons"));
|
|
|
+ Ref<Texture2D> hdiag_grabber = get_theme_icon(SNAME("GuiViewportHdiagsplitter"), SNAME("EditorIcons"));
|
|
|
+ Ref<Texture2D> vdiag_grabber = get_theme_icon(SNAME("GuiViewportVdiagsplitter"), SNAME("EditorIcons"));
|
|
|
+ Ref<Texture2D> vh_grabber = get_theme_icon(SNAME("GuiViewportVhsplitter"), SNAME("EditorIcons"));
|
|
|
|
|
|
- Vector2 size = get_size();
|
|
|
+ Vector2 size = get_size();
|
|
|
|
|
|
- int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
|
|
|
+ int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
|
|
|
|
|
|
- int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
|
|
|
+ int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
|
|
|
|
|
|
- int mid_w = size.width * ratio_h;
|
|
|
- int mid_h = size.height * ratio_v;
|
|
|
+ int mid_w = size.width * ratio_h;
|
|
|
+ int mid_h = size.height * ratio_v;
|
|
|
|
|
|
- int size_left = mid_w - h_sep / 2;
|
|
|
- int size_bottom = size.height - mid_h - v_sep / 2;
|
|
|
+ int size_left = mid_w - h_sep / 2;
|
|
|
+ int size_bottom = size.height - mid_h - v_sep / 2;
|
|
|
|
|
|
- switch (view) {
|
|
|
- case VIEW_USE_1_VIEWPORT: {
|
|
|
- // Nothing to show.
|
|
|
+ switch (view) {
|
|
|
+ case VIEW_USE_1_VIEWPORT: {
|
|
|
+ // Nothing to show.
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_2_VIEWPORTS: {
|
|
|
- draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
|
|
|
- set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_2_VIEWPORTS: {
|
|
|
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_2_VIEWPORTS_ALT: {
|
|
|
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
|
|
|
- set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_2_VIEWPORTS_ALT: {
|
|
|
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_3_VIEWPORTS: {
|
|
|
- if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
|
|
|
- draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4));
|
|
|
- set_default_cursor_shape(CURSOR_DRAG);
|
|
|
- } else if ((hovering_v && !dragging_h) || dragging_v) {
|
|
|
- draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
|
|
|
- set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
- } else if (hovering_h || dragging_h) {
|
|
|
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
|
|
|
- set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_3_VIEWPORTS: {
|
|
|
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
|
|
|
+ draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4));
|
|
|
+ set_default_cursor_shape(CURSOR_DRAG);
|
|
|
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
|
|
|
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
+ } else if (hovering_h || dragging_h) {
|
|
|
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
+ }
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_3_VIEWPORTS_ALT: {
|
|
|
- if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
|
|
|
- draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2));
|
|
|
- set_default_cursor_shape(CURSOR_DRAG);
|
|
|
- } else if ((hovering_v && !dragging_h) || dragging_v) {
|
|
|
- draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
|
|
|
- set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
- } else if (hovering_h || dragging_h) {
|
|
|
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
|
|
|
- set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_3_VIEWPORTS_ALT: {
|
|
|
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
|
|
|
+ draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_DRAG);
|
|
|
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
|
|
|
+ draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
+ } else if (hovering_h || dragging_h) {
|
|
|
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
|
|
|
+ set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
+ }
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_4_VIEWPORTS: {
|
|
|
- Vector2 half(mid_w, mid_h);
|
|
|
- if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
|
|
|
- draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0);
|
|
|
- set_default_cursor_shape(CURSOR_DRAG);
|
|
|
- } else if ((hovering_v && !dragging_h) || dragging_v) {
|
|
|
- draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
|
|
|
- set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
- } else if (hovering_h || dragging_h) {
|
|
|
- draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
|
|
|
- set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_4_VIEWPORTS: {
|
|
|
+ Vector2 half(mid_w, mid_h);
|
|
|
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
|
|
|
+ draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0);
|
|
|
+ set_default_cursor_shape(CURSOR_DRAG);
|
|
|
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
|
|
|
+ draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
|
|
|
+ set_default_cursor_shape(CURSOR_VSPLIT);
|
|
|
+ } else if (hovering_h || dragging_h) {
|
|
|
+ draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
|
|
|
+ set_default_cursor_shape(CURSOR_HSPLIT);
|
|
|
+ }
|
|
|
|
|
|
- } break;
|
|
|
- }
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } break;
|
|
|
|
|
|
- if (p_what == NOTIFICATION_SORT_CHILDREN) {
|
|
|
- Node3DEditorViewport *viewports[4];
|
|
|
- int vc = 0;
|
|
|
- for (int i = 0; i < get_child_count(); i++) {
|
|
|
- viewports[vc] = Object::cast_to<Node3DEditorViewport>(get_child(i));
|
|
|
- if (viewports[vc]) {
|
|
|
- vc++;
|
|
|
+ case NOTIFICATION_SORT_CHILDREN: {
|
|
|
+ Node3DEditorViewport *viewports[4];
|
|
|
+ int vc = 0;
|
|
|
+ for (int i = 0; i < get_child_count(); i++) {
|
|
|
+ viewports[vc] = Object::cast_to<Node3DEditorViewport>(get_child(i));
|
|
|
+ if (viewports[vc]) {
|
|
|
+ vc++;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- ERR_FAIL_COND(vc != 4);
|
|
|
+ ERR_FAIL_COND(vc != 4);
|
|
|
|
|
|
- Size2 size = get_size();
|
|
|
+ Size2 size = get_size();
|
|
|
|
|
|
- if (size.x < 10 || size.y < 10) {
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- viewports[i]->hide();
|
|
|
+ if (size.x < 10 || size.y < 10) {
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ viewports[i]->hide();
|
|
|
+ }
|
|
|
+ return;
|
|
|
}
|
|
|
- return;
|
|
|
- }
|
|
|
- int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
|
|
|
+ int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
|
|
|
|
|
|
- int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
|
|
|
+ int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
|
|
|
|
|
|
- int mid_w = size.width * ratio_h;
|
|
|
- int mid_h = size.height * ratio_v;
|
|
|
+ int mid_w = size.width * ratio_h;
|
|
|
+ int mid_h = size.height * ratio_v;
|
|
|
|
|
|
- int size_left = mid_w - h_sep / 2;
|
|
|
- int size_right = size.width - mid_w - h_sep / 2;
|
|
|
+ int size_left = mid_w - h_sep / 2;
|
|
|
+ int size_right = size.width - mid_w - h_sep / 2;
|
|
|
|
|
|
- int size_top = mid_h - v_sep / 2;
|
|
|
- int size_bottom = size.height - mid_h - v_sep / 2;
|
|
|
+ int size_top = mid_h - v_sep / 2;
|
|
|
+ int size_bottom = size.height - mid_h - v_sep / 2;
|
|
|
|
|
|
- switch (view) {
|
|
|
- case VIEW_USE_1_VIEWPORT: {
|
|
|
- viewports[0]->show();
|
|
|
- for (int i = 1; i < 4; i++) {
|
|
|
- viewports[i]->hide();
|
|
|
- }
|
|
|
+ switch (view) {
|
|
|
+ case VIEW_USE_1_VIEWPORT: {
|
|
|
+ viewports[0]->show();
|
|
|
+ for (int i = 1; i < 4; i++) {
|
|
|
+ viewports[i]->hide();
|
|
|
+ }
|
|
|
|
|
|
- fit_child_in_rect(viewports[0], Rect2(Vector2(), size));
|
|
|
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), size));
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_2_VIEWPORTS: {
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- if (i == 1 || i == 3) {
|
|
|
- viewports[i]->hide();
|
|
|
- } else {
|
|
|
- viewports[i]->show();
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_2_VIEWPORTS: {
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ if (i == 1 || i == 3) {
|
|
|
+ viewports[i]->hide();
|
|
|
+ } else {
|
|
|
+ viewports[i]->show();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
|
|
|
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size.width, size_bottom)));
|
|
|
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
|
|
|
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size.width, size_bottom)));
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_2_VIEWPORTS_ALT: {
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- if (i == 1 || i == 3) {
|
|
|
- viewports[i]->hide();
|
|
|
- } else {
|
|
|
- viewports[i]->show();
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_2_VIEWPORTS_ALT: {
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ if (i == 1 || i == 3) {
|
|
|
+ viewports[i]->hide();
|
|
|
+ } else {
|
|
|
+ viewports[i]->show();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size.height)));
|
|
|
- fit_child_in_rect(viewports[2], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
|
|
|
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size.height)));
|
|
|
+ fit_child_in_rect(viewports[2], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_3_VIEWPORTS: {
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- if (i == 1) {
|
|
|
- viewports[i]->hide();
|
|
|
- } else {
|
|
|
- viewports[i]->show();
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_3_VIEWPORTS: {
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ if (i == 1) {
|
|
|
+ viewports[i]->hide();
|
|
|
+ } else {
|
|
|
+ viewports[i]->show();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
|
|
|
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
|
|
|
- fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
|
|
|
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
|
|
|
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
|
|
|
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_3_VIEWPORTS_ALT: {
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- if (i == 1) {
|
|
|
- viewports[i]->hide();
|
|
|
- } else {
|
|
|
- viewports[i]->show();
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_3_VIEWPORTS_ALT: {
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ if (i == 1) {
|
|
|
+ viewports[i]->hide();
|
|
|
+ } else {
|
|
|
+ viewports[i]->show();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
|
|
|
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
|
|
|
- fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
|
|
|
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
|
|
|
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
|
|
|
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
|
|
|
|
|
|
- } break;
|
|
|
- case VIEW_USE_4_VIEWPORTS: {
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- viewports[i]->show();
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ case VIEW_USE_4_VIEWPORTS: {
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ viewports[i]->show();
|
|
|
+ }
|
|
|
|
|
|
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
|
|
|
- fit_child_in_rect(viewports[1], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size_top)));
|
|
|
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
|
|
|
- fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
|
|
|
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
|
|
|
+ fit_child_in_rect(viewports[1], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size_top)));
|
|
|
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
|
|
|
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
|
|
|
|
|
|
- } break;
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ }
|
|
|
+ } break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -6951,6 +6962,7 @@ void Node3DEditor::_notification(int p_what) {
|
|
|
sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size());
|
|
|
environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size());
|
|
|
} break;
|
|
|
+
|
|
|
case NOTIFICATION_ENTER_TREE: {
|
|
|
_update_theme();
|
|
|
_register_all_gizmos();
|
|
@@ -6958,9 +6970,11 @@ void Node3DEditor::_notification(int p_what) {
|
|
|
_init_indicators();
|
|
|
update_all_gizmos();
|
|
|
} break;
|
|
|
+
|
|
|
case NOTIFICATION_EXIT_TREE: {
|
|
|
_finish_indicators();
|
|
|
} break;
|
|
|
+
|
|
|
case NOTIFICATION_THEME_CHANGED: {
|
|
|
_update_theme();
|
|
|
_update_gizmos_menu_theme();
|
|
@@ -6968,11 +6982,13 @@ void Node3DEditor::_notification(int p_what) {
|
|
|
sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
|
|
|
environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
|
|
|
} break;
|
|
|
+
|
|
|
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
|
|
|
// Update grid color by rebuilding grid.
|
|
|
_finish_grid();
|
|
|
_init_grid();
|
|
|
} break;
|
|
|
+
|
|
|
case NOTIFICATION_VISIBILITY_CHANGED: {
|
|
|
if (!is_visible() && tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->is_pressed()) {
|
|
|
EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
|