Merge pull request #51152 from lawnjelly/portals_improve_ui

This commit is contained in:
Rémi Verschelde 2021-08-02 14:40:18 +02:00 committed by GitHub
commit 73c6ab0215
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 162 additions and 33 deletions

View File

@ -32,12 +32,6 @@
#include "editor/spatial_editor_gizmos.h"
void RoomManagerEditorPlugin::_rooms_convert() {
if (_room_manager) {
_room_manager->rooms_convert();
}
}
void RoomManagerEditorPlugin::_flip_portals() {
if (_room_manager) {
_room_manager->rooms_flip_portals();
@ -59,16 +53,15 @@ bool RoomManagerEditorPlugin::handles(Object *p_object) const {
void RoomManagerEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button_rooms_convert->show();
button_flip_portals->show();
} else {
button_rooms_convert->hide();
button_flip_portals->hide();
}
SpatialEditor::get_singleton()->show_advanced_portal_tools(p_visible);
}
void RoomManagerEditorPlugin::_bind_methods() {
ClassDB::bind_method("_rooms_convert", &RoomManagerEditorPlugin::_rooms_convert);
ClassDB::bind_method("_flip_portals", &RoomManagerEditorPlugin::_flip_portals);
}
@ -82,13 +75,6 @@ RoomManagerEditorPlugin::RoomManagerEditorPlugin(EditorNode *p_node) {
button_flip_portals->connect("pressed", this, "_flip_portals");
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, button_flip_portals);
button_rooms_convert = memnew(ToolButton);
button_rooms_convert->set_icon(editor->get_gui_base()->get_icon("RoomGroup", "EditorIcons"));
button_rooms_convert->set_text(TTR("Convert Rooms"));
button_rooms_convert->hide();
button_rooms_convert->connect("pressed", this, "_rooms_convert");
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, button_rooms_convert);
_room_manager = nullptr;
Ref<RoomGizmoPlugin> room_gizmo_plugin = Ref<RoomGizmoPlugin>(memnew(RoomGizmoPlugin));

View File

@ -43,11 +43,9 @@ class RoomManagerEditorPlugin : public EditorPlugin {
RoomManager *_room_manager;
ToolButton *button_rooms_convert;
ToolButton *button_flip_portals;
EditorNode *editor;
void _rooms_convert();
void _flip_portals();
protected:

View File

@ -47,6 +47,7 @@
#include "scene/3d/collision_shape.h"
#include "scene/3d/mesh_instance.h"
#include "scene/3d/physics_body.h"
#include "scene/3d/room_manager.h"
#include "scene/3d/visual_instance.h"
#include "scene/gui/viewport_container.h"
#include "scene/resources/packed_scene.h"
@ -733,6 +734,10 @@ void SpatialEditorViewport::_update_name() {
view_mode += " [auto]";
}
if (RoomManager::static_rooms_get_active_and_loaded()) {
view_mode += " [portals active]";
}
if (name != "") {
view_menu->set_text(name + " " + view_mode);
} else {
@ -4303,6 +4308,42 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
}
}
void SpatialEditor::show_advanced_portal_tools(bool p_show) {
// toolbar button
Button *const button = tool_button[TOOL_CONVERT_ROOMS];
if (p_show) {
button->set_text(TTR("Convert Rooms"));
} else {
button->set_text("");
}
}
void SpatialEditor::update_portal_tools() {
// the view portal culling toggle
int view_portal_item_index = view_menu->get_popup()->get_item_index(MENU_VIEW_PORTAL_CULLING);
if (RoomManager::active_room_manager) {
view_menu->get_popup()->set_item_disabled(view_portal_item_index, false);
bool active = RoomManager::static_rooms_get_active();
view_menu->get_popup()->set_item_checked(view_portal_item_index, active);
} else {
view_menu->get_popup()->set_item_disabled(view_portal_item_index, true);
}
// toolbar button
Button *const button = tool_button[TOOL_CONVERT_ROOMS];
if (RoomManager::active_room_manager) {
button->show();
} else {
button->hide();
}
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->_update_name();
}
}
void SpatialEditor::update_transform_gizmo() {
List<Node *> &selection = editor_selection->get_selected_node_list();
AABB center;
@ -4791,6 +4832,10 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
update_transform_gizmo();
} break;
case MENU_TOOL_CONVERT_ROOMS: {
RoomManager::static_rooms_convert();
update_portal_tools();
} break;
case MENU_TRANSFORM_CONFIGURE_SNAP: {
snap_dialog->popup_centered(Size2(200, 180));
} break;
@ -4897,6 +4942,11 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), grid_enabled);
} break;
case MENU_VIEW_PORTAL_CULLING: {
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
RoomManager::static_rooms_set_active(!is_checked);
update_portal_tools();
} break;
case MENU_VIEW_CAMERA_SETTINGS: {
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
} break;
@ -5916,6 +5966,7 @@ void SpatialEditor::_notification(int p_what) {
tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons"));
tool_button[SpatialEditor::TOOL_GROUP_SELECTED]->set_icon(get_icon("Group", "EditorIcons"));
tool_button[SpatialEditor::TOOL_UNGROUP_SELECTED]->set_icon(get_icon("Ungroup", "EditorIcons"));
tool_button[SpatialEditor::TOOL_CONVERT_ROOMS]->set_icon(get_icon("RoomGroup", "EditorIcons"));
tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons"));
tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons"));
@ -6293,6 +6344,15 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", this, "_menu_item_toggled", button_binds);
_update_camera_override_button(false);
tool_button[TOOL_CONVERT_ROOMS] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_CONVERT_ROOMS]);
tool_button[TOOL_CONVERT_ROOMS]->set_toggle_mode(false);
tool_button[TOOL_CONVERT_ROOMS]->set_flat(true);
button_binds.write[0] = MENU_TOOL_CONVERT_ROOMS;
tool_button[TOOL_CONVERT_ROOMS]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_CONVERT_ROOMS]->set_shortcut(ED_SHORTCUT("spatial_editor/convert_rooms", TTR("Convert Rooms"), KEY_MASK_ALT | KEY_C));
tool_button[TOOL_CONVERT_ROOMS]->set_tooltip(TTR("Converts rooms for portal culling."));
hbc_menu->add_child(memnew(VSeparator));
// Drag and drop support;
@ -6363,6 +6423,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid"), KEY_MASK_CMD + KEY_G), MENU_VIEW_GRID);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_portal_culling", TTR("View Portal Culling"), KEY_MASK_ALT | KEY_P), MENU_VIEW_PORTAL_CULLING);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings...")), MENU_VIEW_CAMERA_SETTINGS);

View File

@ -207,7 +207,8 @@ class SpatialEditorViewport : public Control {
VIEW_DISPLAY_SHADELESS,
VIEW_LOCK_ROTATION,
VIEW_CINEMATIC_PREVIEW,
VIEW_AUTO_ORTHOGONAL
VIEW_AUTO_ORTHOGONAL,
VIEW_PORTAL_CULLING,
};
public:
@ -545,6 +546,7 @@ public:
TOOL_UNLOCK_SELECTED,
TOOL_GROUP_SELECTED,
TOOL_UNGROUP_SELECTED,
TOOL_CONVERT_ROOMS,
TOOL_MAX
};
@ -624,6 +626,7 @@ private:
MENU_TOOL_LOCAL_COORDS,
MENU_TOOL_USE_SNAP,
MENU_TOOL_OVERRIDE_CAMERA,
MENU_TOOL_CONVERT_ROOMS,
MENU_TRANSFORM_CONFIGURE_SNAP,
MENU_TRANSFORM_DIALOG,
MENU_VIEW_USE_1_VIEWPORT,
@ -634,6 +637,7 @@ private:
MENU_VIEW_USE_4_VIEWPORTS,
MENU_VIEW_ORIGIN,
MENU_VIEW_GRID,
MENU_VIEW_PORTAL_CULLING,
MENU_VIEW_GIZMOS_3D_ICONS,
MENU_VIEW_CAMERA_SETTINGS,
MENU_LOCK_SELECTED,
@ -762,6 +766,8 @@ public:
void update_grid();
void update_transform_gizmo();
void update_portal_tools();
void show_advanced_portal_tools(bool p_show);
void update_all_gizmos(Node *p_node = nullptr);
void snap_selected_nodes_to_floor();
void select_gizmo_highlight_axis(int p_axis);

View File

@ -43,6 +43,10 @@
#include "scene/3d/light.h"
#include "visibility_notifier.h"
#ifdef TOOLS_ENABLED
#include "editor/plugins/spatial_editor_plugin.h"
#endif
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
@ -54,31 +58,55 @@
#include "core/math/convex_hull.h"
#endif
#ifdef TOOLS_ENABLED
RoomManager *RoomManager::active_room_manager = nullptr;
#endif
// This needs to be static because it cannot easily be propagated to portals
// during load (as the RoomManager may be loaded before Portals enter the scene tree)
real_t RoomManager::_default_portal_margin = 1.0;
#ifdef TOOLS_ENABLED
RoomManager *RoomManager::active_room_manager = nullptr;
// static versions of functions for use from editor toolbars
void RoomManager::static_rooms_set_active(bool p_active) {
if (active_room_manager) {
active_room_manager->rooms_set_active(p_active);
active_room_manager->property_list_changed_notify();
}
}
bool RoomManager::static_rooms_get_active() {
if (active_room_manager) {
return active_room_manager->rooms_get_active();
}
return false;
}
bool RoomManager::static_rooms_get_active_and_loaded() {
if (active_room_manager) {
if (active_room_manager->rooms_get_active()) {
Ref<World> world = active_room_manager->get_world();
RID scenario = world->get_scenario();
return active_room_manager->rooms_get_active() && VisualServer::get_singleton()->rooms_is_loaded(scenario);
}
}
return false;
}
void RoomManager::static_rooms_convert() {
if (active_room_manager) {
return active_room_manager->rooms_convert();
}
}
#endif
RoomManager::RoomManager() {
// some high value, we want room manager to be processed after other
// nodes because the camera should be moved first
set_process_priority(10000);
#ifdef TOOLS_ENABLED
// note this mechanism may fail to work correctly if the user creates two room managers,
// but should not create major problems as it is just used to auto update when portals etc
// are changed in the editor, and there is a check for nullptr.
active_room_manager = this;
#endif
}
RoomManager::~RoomManager() {
#ifdef TOOLS_ENABLED
active_room_manager = nullptr;
#endif
}
String RoomManager::get_configuration_warning() const {
@ -173,12 +201,33 @@ void RoomManager::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
if (Engine::get_singleton()->is_editor_hint()) {
set_process_internal(_godot_preview_camera_ID != (ObjectID)-1);
#ifdef TOOLS_ENABLED
// note this mechanism may fail to work correctly if the user creates two room managers,
// but should not create major problems as it is just used to auto update when portals etc
// are changed in the editor, and there is a check for nullptr.
active_room_manager = this;
SpatialEditor *spatial_editor = SpatialEditor::get_singleton();
if (spatial_editor) {
spatial_editor->update_portal_tools();
}
#endif
} else {
if (_settings_gameplay_monitor_enabled) {
set_process_internal(true);
}
}
} break;
case NOTIFICATION_EXIT_TREE: {
#ifdef TOOLS_ENABLED
active_room_manager = nullptr;
if (Engine::get_singleton()->is_editor_hint()) {
SpatialEditor *spatial_editor = SpatialEditor::get_singleton();
if (spatial_editor) {
spatial_editor->update_portal_tools();
}
}
#endif
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
// can't call visual server if not inside world
if (!is_inside_world()) {
@ -459,6 +508,10 @@ void RoomManager::rooms_set_active(bool p_active) {
if (is_inside_world() && get_world().is_valid()) {
VisualServer::get_singleton()->rooms_set_active(get_world()->get_scenario(), p_active);
_active = p_active;
#ifdef TOOLS_ENABLED
SpatialEditor::get_singleton()->update_portal_tools();
#endif
}
}

View File

@ -134,6 +134,12 @@ public:
// an easy way of grabbing the active room manager for tools purposes
#ifdef TOOLS_ENABLED
static RoomManager *active_room_manager;
// static versions of functions for use from editor toolbars
static void static_rooms_set_active(bool p_active);
static bool static_rooms_get_active();
static bool static_rooms_get_active_and_loaded();
static void static_rooms_convert();
#endif
private:

View File

@ -159,6 +159,7 @@ public:
// for use in the editor only, to allow a cheap way of turning off portals
// if there has been a change, e.g. moving a room etc.
void rooms_unload() { _ensure_unloaded(); }
bool rooms_is_loaded() const { return _loaded; }
// debugging
void set_debug_sprawl(bool p_active) { _debug_sprawl = p_active; }

View File

@ -593,6 +593,9 @@ public:
BIND3(rooms_set_debug_feature, RID, RoomsDebugFeature, bool)
BIND2(rooms_update_gameplay_monitor, RID, const Vector<Vector3> &)
// don't use this in a game
BIND1RC(bool, rooms_is_loaded, RID)
// Callbacks
BIND1(callbacks_register, VisualServerCallbacks *)

View File

@ -1308,6 +1308,12 @@ void VisualServerScene::rooms_update_gameplay_monitor(RID p_scenario, const Vect
scenario->_portal_renderer.rooms_update_gameplay_monitor(p_camera_positions);
}
bool VisualServerScene::rooms_is_loaded(RID p_scenario) const {
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND_V(!scenario, false);
return scenario->_portal_renderer.rooms_is_loaded();
}
Vector<ObjectID> VisualServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const {
Vector<ObjectID> instances;
Scenario *scenario = scenario_owner.get(p_scenario);

View File

@ -647,6 +647,9 @@ public:
virtual void rooms_set_debug_feature(RID p_scenario, VisualServer::RoomsDebugFeature p_feature, bool p_active);
virtual void rooms_update_gameplay_monitor(RID p_scenario, const Vector<Vector3> &p_camera_positions);
// don't use this in a game
virtual bool rooms_is_loaded(RID p_scenario) const;
virtual void callbacks_register(VisualServerCallbacks *p_callbacks);
VisualServerCallbacks *get_callbacks() const { return _visual_server_callbacks; }

View File

@ -516,6 +516,9 @@ public:
FUNC3(rooms_set_debug_feature, RID, RoomsDebugFeature, bool)
FUNC2(rooms_update_gameplay_monitor, RID, const Vector<Vector3> &)
// don't use this in a game
FUNC1RC(bool, rooms_is_loaded, RID)
// Callbacks
FUNC1(callbacks_register, VisualServerCallbacks *)

View File

@ -909,6 +909,9 @@ public:
virtual void rooms_set_debug_feature(RID p_scenario, RoomsDebugFeature p_feature, bool p_active) = 0;
virtual void rooms_update_gameplay_monitor(RID p_scenario, const Vector<Vector3> &p_camera_positions) = 0;
// don't use this in a game!
virtual bool rooms_is_loaded(RID p_scenario) const = 0;
// callbacks are used to send messages back from the visual server to scene tree in thread friendly manner
virtual void callbacks_register(VisualServerCallbacks *p_callbacks) = 0;