summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/script_language.h27
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp44
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h4
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp72
-rw-r--r--editor/plugins/spatial_editor_plugin.h12
-rw-r--r--editor/script_editor_debugger.cpp78
-rw-r--r--editor/script_editor_debugger.h17
-rw-r--r--main/main.cpp8
-rw-r--r--scene/SCsub1
-rw-r--r--scene/debugger/SCsub5
-rw-r--r--scene/debugger/script_debugger_remote.cpp (renamed from core/script_debugger_remote.cpp)172
-rw-r--r--scene/debugger/script_debugger_remote.h (renamed from core/script_debugger_remote.h)12
-rw-r--r--scene/main/scene_tree.cpp70
-rw-r--r--scene/main/scene_tree.h23
-rw-r--r--scene/main/viewport.cpp122
-rw-r--r--scene/main/viewport.h36
-rw-r--r--servers/register_server_types.cpp2
17 files changed, 536 insertions, 169 deletions
diff --git a/core/script_language.h b/core/script_language.h
index 116918fdc0..f90bb4b6c3 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -427,31 +427,6 @@ class ScriptDebugger {
ScriptLanguage *break_lang;
public:
- typedef void (*RequestSceneTreeMessageFunc)(void *);
-
- struct LiveEditFuncs {
-
- void *udata;
- void (*node_path_func)(void *, const NodePath &p_path, int p_id);
- void (*res_path_func)(void *, const String &p_path, int p_id);
-
- void (*node_set_func)(void *, int p_id, const StringName &p_prop, const Variant &p_value);
- void (*node_set_res_func)(void *, int p_id, const StringName &p_prop, const String &p_value);
- void (*node_call_func)(void *, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE);
- void (*res_set_func)(void *, int p_id, const StringName &p_prop, const Variant &p_value);
- void (*res_set_res_func)(void *, int p_id, const StringName &p_prop, const String &p_value);
- void (*res_call_func)(void *, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE);
- void (*root_func)(void *, const NodePath &p_scene_path, const String &p_scene_from);
-
- void (*tree_create_node_func)(void *, const NodePath &p_parent, const String &p_type, const String &p_name);
- void (*tree_instance_node_func)(void *, const NodePath &p_parent, const String &p_path, const String &p_name);
- void (*tree_remove_node_func)(void *, const NodePath &p_at);
- void (*tree_remove_and_keep_node_func)(void *, const NodePath &p_at, ObjectID p_keep_id);
- void (*tree_restore_node_func)(void *, ObjectID p_id, const NodePath &p_at, int p_at_pos);
- void (*tree_duplicate_node_func)(void *, const NodePath &p_at, const String &p_new_name);
- void (*tree_reparent_node_func)(void *, const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
- };
-
_FORCE_INLINE_ static ScriptDebugger *get_singleton() { return singleton; }
void set_lines_left(int p_left);
int get_lines_left() const;
@@ -480,8 +455,6 @@ public:
virtual bool is_remote() const { return false; }
virtual void request_quit() {}
- virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
- virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {}
virtual bool is_profiling() const = 0;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index f9a7b7caf1..7db05ab270 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -3730,6 +3730,7 @@ void CanvasItemEditor::_notification(int p_what) {
grid_snap_button->set_icon(get_icon("SnapGrid", "EditorIcons"));
snap_config_menu->set_icon(get_icon("GuiTabMenu", "EditorIcons"));
skeleton_menu->set_icon(get_icon("Bone", "EditorIcons"));
+ override_camera_button->set_icon(get_icon("Camera2D", "EditorIcons"));
pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
ruler_button->set_icon(get_icon("Ruler", "EditorIcons"));
pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
@@ -3799,6 +3800,15 @@ void CanvasItemEditor::_notification(int p_what) {
anchor_mode_button->set_icon(get_icon("Anchor", "EditorIcons"));
}
+
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (!is_visible() && override_camera_button->is_pressed()) {
+ ScriptEditorDebugger *debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ override_camera_button->set_pressed(false);
+ }
+ }
}
void CanvasItemEditor::_selection_changed() {
@@ -4140,6 +4150,15 @@ void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) {
grid_snap_active = p_status;
viewport->update();
}
+void CanvasItemEditor::_button_override_camera(bool p_pressed) {
+ ScriptEditorDebugger *debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ if (p_pressed) {
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_2D);
+ } else {
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ }
+}
void CanvasItemEditor::_button_tool_select(int p_index) {
@@ -4237,6 +4256,17 @@ void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) {
viewport->update();
}
+void CanvasItemEditor::_update_override_camera_button(bool p_game_running) {
+ if (p_game_running) {
+ override_camera_button->set_disabled(false);
+ override_camera_button->set_tooltip(TTR("Game camera override\nOverrides game camera with editor viewport camera."));
+ } else {
+ override_camera_button->set_disabled(true);
+ override_camera_button->set_pressed(false);
+ override_camera_button->set_tooltip(TTR("Game camera override\nNo game instance running."));
+ }
+}
+
void CanvasItemEditor::_popup_callback(int p_op) {
last_option = MenuOption(p_op);
@@ -4829,6 +4859,8 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_button_zoom_plus", &CanvasItemEditor::_button_zoom_plus);
ClassDB::bind_method("_button_toggle_smart_snap", &CanvasItemEditor::_button_toggle_smart_snap);
ClassDB::bind_method("_button_toggle_grid_snap", &CanvasItemEditor::_button_toggle_grid_snap);
+ ClassDB::bind_method(D_METHOD("_button_override_camera", "pressed"), &CanvasItemEditor::_button_override_camera);
+ ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button);
ClassDB::bind_method("_button_toggle_anchor_mode", &CanvasItemEditor::_button_toggle_anchor_mode);
ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll);
ClassDB::bind_method("_update_scrollbars", &CanvasItemEditor::_update_scrollbars);
@@ -5141,6 +5173,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
editor_selection->connect("selection_changed", this, "update");
editor_selection->connect("selection_changed", this, "_selection_changed");
+ editor->call_deferred("connect", "play_pressed", this, "_update_override_camera_button", make_binds(true));
+ editor->call_deferred("connect", "stop_pressed", this, "_update_override_camera_button", make_binds(false));
+
hb = memnew(HBoxContainer);
add_child(hb);
hb->set_anchors_and_margins_preset(Control::PRESET_WIDE);
@@ -5385,6 +5420,15 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->add_child(memnew(VSeparator));
+ override_camera_button = memnew(ToolButton);
+ hb->add_child(override_camera_button);
+ override_camera_button->connect("toggled", this, "_button_override_camera");
+ override_camera_button->set_toggle_mode(true);
+ override_camera_button->set_disabled(true);
+ _update_override_camera_button(false);
+
+ hb->add_child(memnew(VSeparator));
+
view_menu = memnew(MenuButton);
view_menu->set_text(TTR("View"));
hb->add_child(view_menu);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 480fb89621..4b419ffcce 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -360,6 +360,7 @@ private:
ToolButton *ungroup_button;
MenuButton *skeleton_menu;
+ ToolButton *override_camera_button;
MenuButton *view_menu;
HBoxContainer *animation_hb;
MenuButton *animation_menu;
@@ -533,8 +534,11 @@ private:
void _button_zoom_plus();
void _button_toggle_smart_snap(bool p_status);
void _button_toggle_grid_snap(bool p_status);
+ void _button_override_camera(bool p_pressed);
void _button_tool_select(int p_index);
+ void _update_override_camera_button(bool p_game_running);
+
HSplitContainer *palette_split;
VSplitContainer *bottom_split;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 1d8fd38858..29ae57af18 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -901,6 +901,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
+ emit_signal("clicked", this);
+
float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor();
switch (b->get_button_index()) {
@@ -3096,6 +3098,7 @@ void SpatialEditorViewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw);
ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")));
+ ADD_SIGNAL(MethodInfo("clicked", PropertyInfo(Variant::OBJECT, "viewport")));
}
void SpatialEditorViewport::reset() {
@@ -4369,6 +4372,19 @@ void SpatialEditor::_menu_item_toggled(bool pressed, int p_option) {
tool_option_button[TOOL_OPT_USE_SNAP]->set_pressed(pressed);
snap_enabled = pressed;
} break;
+
+ case MENU_TOOL_OVERRIDE_CAMERA: {
+ ScriptEditorDebugger *const debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ if (pressed) {
+ using Override = ScriptEditorDebugger::CameraOverride;
+
+ debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
+ } else {
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ }
+
+ } break;
}
}
@@ -4396,6 +4412,35 @@ void SpatialEditor::_menu_gizmo_toggled(int p_option) {
update_all_gizmos();
}
+void SpatialEditor::_update_camera_override_button(bool p_game_running) {
+ Button *const button = tool_option_button[TOOL_OPT_OVERRIDE_CAMERA];
+
+ if (p_game_running) {
+ button->set_disabled(false);
+ button->set_tooltip(TTR("Game camera override\nNo game instance running."));
+ } else {
+ button->set_disabled(true);
+ button->set_pressed(false);
+ button->set_tooltip(TTR("Game camera override\nOverrides game camera with editor viewport camera."));
+ }
+}
+
+void SpatialEditor::_update_camera_override_viewport(Object *p_viewport) {
+ SpatialEditorViewport *current_viewport = Object::cast_to<SpatialEditorViewport>(p_viewport);
+
+ if (!current_viewport)
+ return;
+
+ ScriptEditorDebugger *const debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ camera_override_viewport_id = current_viewport->index;
+ if (debugger->get_camera_override() >= ScriptEditorDebugger::OVERRIDE_3D_1) {
+ using Override = ScriptEditorDebugger::CameraOverride;
+
+ debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
+ }
+}
+
void SpatialEditor::_menu_item_pressed(int p_option) {
switch (p_option) {
@@ -5290,6 +5335,7 @@ void SpatialEditor::_notification(int p_what) {
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"));
+ tool_option_button[SpatialEditor::TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_icon("Camera", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
@@ -5305,6 +5351,9 @@ void SpatialEditor::_notification(int p_what) {
get_tree()->connect("node_removed", this, "_node_removed");
EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", this, "_refresh_menu_icons");
editor_selection->connect("selection_changed", this, "_refresh_menu_icons");
+
+ editor->connect("stop_pressed", this, "_update_camera_override_button", make_binds(false));
+ editor->connect("play_pressed", this, "_update_camera_override_button", make_binds(true));
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_register_all_gizmos();
@@ -5339,6 +5388,13 @@ void SpatialEditor::_notification(int p_what) {
// Update grid color by rebuilding grid.
_finish_grid();
_init_grid();
+ } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (!is_visible() && tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->is_pressed()) {
+ ScriptEditorDebugger *debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_pressed(false);
+ }
}
}
@@ -5483,6 +5539,8 @@ void SpatialEditor::_bind_methods() {
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
ClassDB::bind_method("_refresh_menu_icons", &SpatialEditor::_refresh_menu_icons);
+ ClassDB::bind_method("_update_camera_override_button", &SpatialEditor::_update_camera_override_button);
+ ClassDB::bind_method("_update_camera_override_viewport", &SpatialEditor::_update_camera_override_viewport);
ADD_SIGNAL(MethodInfo("transform_key_request"));
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
@@ -5536,6 +5594,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
snap_key_enabled = false;
tool_mode = TOOL_MODE_SELECT;
+ camera_override_viewport_id = 0;
+
hbc_menu = memnew(HBoxContainer);
vbc->add_child(hbc_menu);
@@ -5633,6 +5693,17 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(memnew(VSeparator));
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA] = memnew(ToolButton);
+ hbc_menu->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_toggle_mode(true);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_flat(true);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_disabled(true);
+ button_binds.write[0] = MENU_TOOL_OVERRIDE_CAMERA;
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", this, "_menu_item_toggled", button_binds);
+ _update_camera_override_button(false);
+
+ hbc_menu->add_child(memnew(VSeparator));
+
// Drag and drop support;
preview_node = memnew(Spatial);
preview_bounds = AABB();
@@ -5721,6 +5792,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
viewports[i] = memnew(SpatialEditorViewport(this, editor, i));
viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view");
+ viewports[i]->connect("clicked", this, "_update_camera_override_viewport");
viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept);
viewport_base->add_child(viewports[i]);
}
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index fe91c33642..65e3c32ca8 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -494,6 +494,7 @@ public:
TOOL_OPT_LOCAL_COORDS,
TOOL_OPT_USE_SNAP,
+ TOOL_OPT_OVERRIDE_CAMERA,
TOOL_OPT_MAX
};
@@ -559,6 +560,7 @@ private:
MENU_TOOL_LIST_SELECT,
MENU_TOOL_LOCAL_COORDS,
MENU_TOOL_USE_SNAP,
+ MENU_TOOL_OVERRIDE_CAMERA,
MENU_TRANSFORM_CONFIGURE_SNAP,
MENU_TRANSFORM_DIALOG,
MENU_VIEW_USE_1_VIEWPORT,
@@ -585,9 +587,6 @@ private:
PopupMenu *gizmos_menu;
MenuButton *view_menu;
- ToolButton *lock_button;
- ToolButton *unlock_button;
-
AcceptDialog *accept;
ConfirmationDialog *snap_dialog;
@@ -615,13 +614,16 @@ private:
void _menu_item_pressed(int p_option);
void _menu_item_toggled(bool pressed, int p_option);
void _menu_gizmo_toggled(int p_option);
+ void _update_camera_override_button(bool p_game_running);
+ void _update_camera_override_viewport(Object *p_viewport);
HBoxContainer *hbc_menu;
void _generate_selection_box();
UndoRedo *undo_redo;
- void _instance_scene();
+ int camera_override_viewport_id;
+
void _init_indicators();
void _update_gizmos_menu();
void _update_gizmos_menu_theme();
@@ -716,7 +718,7 @@ public:
void set_can_preview(Camera *p_preview);
SpatialEditorViewport *get_editor_viewport(int p_idx) {
- ERR_FAIL_INDEX_V(p_idx, 4, NULL);
+ ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), NULL);
return viewports[p_idx];
}
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 89d275a90b..738ada99f7 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -33,6 +33,8 @@
#include "core/io/marshalls.h"
#include "core/project_settings.h"
#include "core/ustring.h"
+#include "editor/plugins/canvas_item_editor_plugin.h"
+#include "editor/plugins/spatial_editor_plugin.h"
#include "editor_network_profiler.h"
#include "editor_node.h"
#include "editor_profiler.h"
@@ -1212,6 +1214,42 @@ void ScriptEditorDebugger::_notification(int p_what) {
}
}
}
+
+ if (camera_override == OVERRIDE_2D) {
+ CanvasItemEditor *editor = CanvasItemEditor::get_singleton();
+
+ Dictionary state = editor->get_state();
+ float zoom = state["zoom"];
+ Point2 offset = state["ofs"];
+ Transform2D transform;
+
+ transform.scale_basis(Size2(zoom, zoom));
+ transform.elements[2] = -offset * zoom;
+
+ Array msg;
+ msg.push_back("override_camera_2D:transform");
+ msg.push_back(transform);
+ ppeer->put_var(msg);
+
+ } else if (camera_override >= OVERRIDE_3D_1) {
+ int viewport_idx = camera_override - OVERRIDE_3D_1;
+ SpatialEditorViewport *viewport = SpatialEditor::get_singleton()->get_editor_viewport(viewport_idx);
+ Camera *const cam = viewport->get_camera();
+
+ Array msg;
+ msg.push_back("override_camera_3D:transform");
+ msg.push_back(cam->get_camera_transform());
+ if (cam->get_projection() == Camera::PROJECTION_ORTHOGONAL) {
+ msg.push_back(false);
+ msg.push_back(cam->get_size());
+ } else {
+ msg.push_back(true);
+ msg.push_back(cam->get_fov());
+ }
+ msg.push_back(cam->get_znear());
+ msg.push_back(cam->get_zfar());
+ ppeer->put_var(msg);
+ }
}
if (error_count != last_error_count || warning_count != last_warning_count) {
@@ -1426,6 +1464,7 @@ void ScriptEditorDebugger::start() {
set_process(true);
breaked = false;
+ camera_override = OVERRIDE_NONE;
}
void ScriptEditorDebugger::pause() {
@@ -1870,6 +1909,45 @@ void ScriptEditorDebugger::live_debug_reparent_node(const NodePath &p_at, const
}
}
+ScriptEditorDebugger::CameraOverride ScriptEditorDebugger::get_camera_override() const {
+ return camera_override;
+}
+
+void ScriptEditorDebugger::set_camera_override(CameraOverride p_override) {
+
+ if (p_override == OVERRIDE_2D && camera_override != OVERRIDE_2D) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_2D:set");
+ msg.push_back(true);
+ ppeer->put_var(msg);
+ }
+ } else if (p_override != OVERRIDE_2D && camera_override == OVERRIDE_2D) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_2D:set");
+ msg.push_back(false);
+ ppeer->put_var(msg);
+ }
+ } else if (p_override >= OVERRIDE_3D_1 && camera_override < OVERRIDE_3D_1) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_3D:set");
+ msg.push_back(true);
+ ppeer->put_var(msg);
+ }
+ } else if (p_override < OVERRIDE_3D_1 && camera_override >= OVERRIDE_3D_1) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_3D:set");
+ msg.push_back(false);
+ ppeer->put_var(msg);
+ }
+ }
+
+ camera_override = p_override;
+}
+
void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool p_enabled) {
if (connection.is_valid()) {
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index cc284476c0..14b024d066 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -35,6 +35,7 @@
#include "core/io/tcp_server.h"
#include "editor/editor_inspector.h"
#include "editor/property_editor.h"
+#include "scene/3d/camera.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
@@ -58,6 +59,17 @@ class ScriptEditorDebugger : public Control {
GDCLASS(ScriptEditorDebugger, Control);
+public:
+ enum CameraOverride {
+ OVERRIDE_NONE,
+ OVERRIDE_2D,
+ OVERRIDE_3D_1, // 3D Viewport 1
+ OVERRIDE_3D_2, // 3D Viewport 2
+ OVERRIDE_3D_3, // 3D Viewport 3
+ OVERRIDE_3D_4 // 3D Viewport 4
+ };
+
+private:
enum MessageType {
MESSAGE_ERROR,
MESSAGE_WARNING,
@@ -165,6 +177,8 @@ class ScriptEditorDebugger : public Control {
bool live_debug;
+ CameraOverride camera_override;
+
void _performance_draw();
void _performance_select();
void _stack_dump_frame_selected();
@@ -250,6 +264,9 @@ public:
void live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name);
void live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
+ CameraOverride get_camera_override() const;
+ void set_camera_override(CameraOverride p_override);
+
void set_breakpoint(const String &p_path, int p_line, bool p_enabled);
void update_live_edit_root();
diff --git a/main/main.cpp b/main/main.cpp
index fe0f5a0215..120db33600 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -44,7 +44,6 @@
#include "core/project_settings.h"
#include "core/register_core_types.h"
#include "core/script_debugger_local.h"
-#include "core/script_debugger_remote.h"
#include "core/script_language.h"
#include "core/translation.h"
#include "core/version.h"
@@ -59,6 +58,7 @@
#include "main/tests/test_main.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
+#include "scene/debugger/script_debugger_remote.h"
#include "scene/main/scene_tree.h"
#include "scene/main/viewport.h"
#include "scene/register_scene_types.h"
@@ -1583,6 +1583,12 @@ bool Main::start() {
if (!project_manager && !editor) { // game
if (game_path != "" || script != "") {
+ if (script_debugger && script_debugger->is_remote()) {
+ ScriptDebuggerRemote *remote_debugger = static_cast<ScriptDebuggerRemote *>(script_debugger);
+
+ remote_debugger->set_scene_tree(sml);
+ }
+
//autoload
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
diff --git a/scene/SCsub b/scene/SCsub
index d8839ce3a8..1c5b87b87a 100644
--- a/scene/SCsub
+++ b/scene/SCsub
@@ -30,6 +30,7 @@ SConscript('2d/SCsub')
SConscript('animation/SCsub')
SConscript('audio/SCsub')
SConscript('resources/SCsub')
+SConscript('debugger/SCsub')
# Build it all as a library
diff --git a/scene/debugger/SCsub b/scene/debugger/SCsub
new file mode 100644
index 0000000000..b01e2fd54d
--- /dev/null
+++ b/scene/debugger/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/core/script_debugger_remote.cpp b/scene/debugger/script_debugger_remote.cpp
index 65ef2a0978..c3c6a088cb 100644
--- a/core/script_debugger_remote.cpp
+++ b/scene/debugger/script_debugger_remote.cpp
@@ -37,7 +37,10 @@
#include "core/os/os.h"
#include "core/project_settings.h"
#include "scene/main/node.h"
+#include "scene/main/scene_tree.h"
+#include "scene/main/viewport.h"
#include "scene/resources/packed_scene.h"
+#include "servers/visual_server.h"
void ScriptDebuggerRemote::_send_video_memory() {
@@ -150,7 +153,10 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ uint64_t loop_begin_usec = 0;
+ uint64_t loop_time_sec = 0;
while (true) {
+ loop_begin_usec = OS::get_singleton()->get_ticks_usec();
_get_output();
@@ -279,9 +285,10 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
break;
} else if (command == "request_scene_tree") {
- if (request_scene_tree)
- request_scene_tree(request_scene_tree_ud);
-
+#ifdef DEBUG_ENABLED
+ if (scene_tree)
+ scene_tree->_debugger_request_tree();
+#endif
} else if (command == "request_video_mem") {
_send_video_memory();
@@ -293,6 +300,40 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
_set_object_property(cmd[1], cmd[2], cmd[3]);
+ } else if (command == "override_camera_2D:set") {
+ bool enforce = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_canvas_transform_override(enforce);
+ }
+ } else if (command == "override_camera_2D:transform") {
+ Transform2D transform = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->set_canvas_transform_override(transform);
+ }
+ } else if (command == "override_camera_3D:set") {
+ bool enable = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_camera_override(enable);
+ }
+ } else if (command == "override_camera_3D:transform") {
+ Transform transform = cmd[1];
+ bool is_perspective = cmd[2];
+ float size_or_fov = cmd[3];
+ float near = cmd[4];
+ float far = cmd[5];
+
+ if (scene_tree) {
+ if (is_perspective) {
+ scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far);
+ } else {
+ scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far);
+ }
+ scene_tree->get_root()->set_camera_override_transform(transform);
+ }
+
} else if (command == "reload_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
@@ -315,6 +356,13 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
OS::get_singleton()->delay_usec(10000);
OS::get_singleton()->process_and_drop_events();
}
+
+ // This is for the camera override to stay live even when the game is paused from the editor
+ loop_time_sec = (OS::get_singleton()->get_ticks_usec() - loop_begin_usec) / 1000000.0f;
+ VisualServer::get_singleton()->sync();
+ if (VisualServer::get_singleton()->has_changed()) {
+ VisualServer::get_singleton()->draw(true, loop_time_sec * Engine::get_singleton()->get_time_scale());
+ }
}
packet_peer_stream->put_var("debug_exit");
@@ -446,93 +494,75 @@ void ScriptDebuggerRemote::_err_handler(void *ud, const char *p_func, const char
bool ScriptDebuggerRemote::_parse_live_edit(const Array &p_command) {
+#ifdef DEBUG_ENABLED
+
String cmdstr = p_command[0];
- if (!live_edit_funcs || !cmdstr.begins_with("live_"))
+ if (!scene_tree || !cmdstr.begins_with("live_"))
return false;
- //print_line(Variant(cmd).get_construct_string());
if (cmdstr == "live_set_root") {
- if (!live_edit_funcs->root_func)
- return true;
- //print_line("root: "+Variant(cmd).get_construct_string());
- live_edit_funcs->root_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_root_func(p_command[1], p_command[2]);
} else if (cmdstr == "live_node_path") {
- if (!live_edit_funcs->node_path_func)
- return true;
- //print_line("path: "+Variant(cmd).get_construct_string());
-
- live_edit_funcs->node_path_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_node_path_func(p_command[1], p_command[2]);
} else if (cmdstr == "live_res_path") {
- if (!live_edit_funcs->res_path_func)
- return true;
- live_edit_funcs->res_path_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_res_path_func(p_command[1], p_command[2]);
} else if (cmdstr == "live_node_prop_res") {
- if (!live_edit_funcs->node_set_res_func)
- return true;
- live_edit_funcs->node_set_res_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_node_set_res_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_node_prop") {
- if (!live_edit_funcs->node_set_func)
- return true;
- live_edit_funcs->node_set_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_node_set_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_res_prop_res") {
- if (!live_edit_funcs->res_set_res_func)
- return true;
- live_edit_funcs->res_set_res_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_res_set_res_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_res_prop") {
- if (!live_edit_funcs->res_set_func)
- return true;
- live_edit_funcs->res_set_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_res_set_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_node_call") {
- if (!live_edit_funcs->node_call_func)
- return true;
- live_edit_funcs->node_call_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
+ scene_tree->_live_edit_node_call_func(p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
} else if (cmdstr == "live_res_call") {
- if (!live_edit_funcs->res_call_func)
- return true;
- live_edit_funcs->res_call_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
+ scene_tree->_live_edit_res_call_func(p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
} else if (cmdstr == "live_create_node") {
- live_edit_funcs->tree_create_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_create_node_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_instance_node") {
- live_edit_funcs->tree_instance_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_instance_node_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_remove_node") {
- live_edit_funcs->tree_remove_node_func(live_edit_funcs->udata, p_command[1]);
+ scene_tree->_live_edit_remove_node_func(p_command[1]);
} else if (cmdstr == "live_remove_and_keep_node") {
- live_edit_funcs->tree_remove_and_keep_node_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_remove_and_keep_node_func(p_command[1], p_command[2]);
+
} else if (cmdstr == "live_restore_node") {
- live_edit_funcs->tree_restore_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_restore_node_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_duplicate_node") {
- live_edit_funcs->tree_duplicate_node_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_duplicate_node_func(p_command[1], p_command[2]);
+
} else if (cmdstr == "live_reparent_node") {
- live_edit_funcs->tree_reparent_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3], p_command[4]);
+ scene_tree->_live_edit_reparent_node_func(p_command[1], p_command[2], p_command[3], p_command[4]);
} else {
@@ -540,6 +570,10 @@ bool ScriptDebuggerRemote::_parse_live_edit(const Array &p_command) {
}
return true;
+#else
+
+ return false;
+#endif
}
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
@@ -732,8 +766,10 @@ void ScriptDebuggerRemote::_poll_events() {
debug(get_break_language());
} else if (command == "request_scene_tree") {
- if (request_scene_tree)
- request_scene_tree(request_scene_tree_ud);
+#ifdef DEBUG_ENABLED
+ if (scene_tree)
+ scene_tree->_debugger_request_tree();
+#endif
} else if (command == "request_video_mem") {
_send_video_memory();
@@ -777,6 +813,40 @@ void ScriptDebuggerRemote::_poll_events() {
multiplayer->profiling_end();
profiling_network = false;
+ } else if (command == "override_camera_2D:set") {
+ bool enforce = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_canvas_transform_override(enforce);
+ }
+ } else if (command == "override_camera_2D:transform") {
+ Transform2D transform = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->set_canvas_transform_override(transform);
+ }
+ } else if (command == "override_camera_3D:set") {
+ bool enable = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_camera_override(enable);
+ }
+ } else if (command == "override_camera_3D:transform") {
+ Transform transform = cmd[1];
+ bool is_perspective = cmd[2];
+ float size_or_fov = cmd[3];
+ float near = cmd[4];
+ float far = cmd[5];
+
+ if (scene_tree) {
+ if (is_perspective) {
+ scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far);
+ } else {
+ scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far);
+ }
+ scene_tree->get_root()->set_camera_override_transform(transform);
+ }
+
} else if (command == "reload_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
@@ -1106,17 +1176,6 @@ void ScriptDebuggerRemote::request_quit() {
requested_quit = true;
}
-void ScriptDebuggerRemote::set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {
-
- request_scene_tree = p_func;
- request_scene_tree_ud = p_udata;
-}
-
-void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
-
- live_edit_funcs = p_funcs;
-}
-
void ScriptDebuggerRemote::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
multiplayer = p_multiplayer;
}
@@ -1195,8 +1254,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
msec_count(0),
locking(false),
poll_every(0),
- request_scene_tree(NULL),
- live_edit_funcs(NULL) {
+ scene_tree(NULL) {
packet_peer_stream->set_stream_peer(tcp_client);
packet_peer_stream->set_output_buffer_max_size(1024 * 1024 * 8); //8mb should be way more than enough
diff --git a/core/script_debugger_remote.h b/scene/debugger/script_debugger_remote.h
index b6dd925181..13ad7ddbe3 100644
--- a/core/script_debugger_remote.h
+++ b/scene/debugger/script_debugger_remote.h
@@ -37,6 +37,8 @@
#include "core/os/os.h"
#include "core/script_language.h"
+class SceneTree;
+
class ScriptDebuggerRemote : public ScriptDebugger {
struct Message {
@@ -116,16 +118,14 @@ class ScriptDebuggerRemote : public ScriptDebugger {
void _poll_events();
uint32_t poll_every;
- bool _parse_live_edit(const Array &p_command);
+ SceneTree *scene_tree;
- RequestSceneTreeMessageFunc request_scene_tree;
- void *request_scene_tree_ud;
+ bool _parse_live_edit(const Array &p_command);
void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value);
void _send_object_id(ObjectID p_id);
void _send_video_memory();
- LiveEditFuncs *live_edit_funcs;
Ref<MultiplayerAPI> multiplayer;
@@ -176,8 +176,6 @@ public:
virtual void send_message(const String &p_message, const Array &p_args);
virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info);
- virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
- virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
virtual bool is_profiling() const;
@@ -189,6 +187,8 @@ public:
virtual void set_skip_breakpoints(bool p_skip_breakpoints);
+ void set_scene_tree(SceneTree *p_scene_tree) { scene_tree = p_scene_tree; };
+
ScriptDebuggerRemote();
~ScriptDebuggerRemote();
};
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 38ad6886b1..5653049060 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -40,6 +40,7 @@
#include "core/project_settings.h"
#include "main/input_default.h"
#include "node.h"
+#include "scene/debugger/script_debugger_remote.h"
#include "scene/resources/dynamic_font.h"
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
@@ -1094,27 +1095,6 @@ void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_li
}
}
-static void _fill_array(Node *p_node, Array &array, int p_level) {
-
- array.push_back(p_node->get_child_count());
- array.push_back(p_node->get_name());
- array.push_back(p_node->get_class());
- array.push_back(p_node->get_instance_id());
- for (int i = 0; i < p_node->get_child_count(); i++) {
-
- _fill_array(p_node->get_child(i), array, p_level + 1);
- }
-}
-
-void SceneTree::_debugger_request_tree(void *self) {
-
- SceneTree *sml = (SceneTree *)self;
-
- Array arr;
- _fill_array(sml->root, arr, 0);
- ScriptDebugger::get_singleton()->send_message("scene_tree", arr);
-}
-
void SceneTree::_flush_delete_queue() {
_THREAD_SAFE_METHOD_
@@ -1337,6 +1317,25 @@ void SceneTree::add_current_scene(Node *p_current) {
}
#ifdef DEBUG_ENABLED
+static void _fill_array(Node *p_node, Array &array, int p_level) {
+
+ array.push_back(p_node->get_child_count());
+ array.push_back(p_node->get_name());
+ array.push_back(p_node->get_class());
+ array.push_back(p_node->get_instance_id());
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+
+ _fill_array(p_node->get_child(i), array, p_level + 1);
+ }
+}
+
+void SceneTree::_debugger_request_tree() {
+
+ Array arr;
+ _fill_array(root, arr, 0);
+ ScriptDebugger::get_singleton()->send_message("scene_tree", arr);
+}
+
void SceneTree::_live_edit_node_path_func(const NodePath &p_path, int p_id) {
live_edit_node_path_cache[p_id] = p_path;
@@ -2117,7 +2116,11 @@ SceneTree::SceneTree() {
_update_root_rect();
if (ScriptDebugger::get_singleton()) {
- ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree, this);
+ if (ScriptDebugger::get_singleton()->is_remote()) {
+ ScriptDebuggerRemote *remote_debugger = static_cast<ScriptDebuggerRemote *>(ScriptDebugger::get_singleton());
+
+ remote_debugger->set_scene_tree(this);
+ }
ScriptDebugger::get_singleton()->set_multiplayer(multiplayer);
}
@@ -2129,29 +2132,6 @@ SceneTree::SceneTree() {
#ifdef DEBUG_ENABLED
- live_edit_funcs.udata = this;
- live_edit_funcs.node_path_func = _live_edit_node_path_funcs;
- live_edit_funcs.res_path_func = _live_edit_res_path_funcs;
- live_edit_funcs.node_set_func = _live_edit_node_set_funcs;
- live_edit_funcs.node_set_res_func = _live_edit_node_set_res_funcs;
- live_edit_funcs.node_call_func = _live_edit_node_call_funcs;
- live_edit_funcs.res_set_func = _live_edit_res_set_funcs;
- live_edit_funcs.res_set_res_func = _live_edit_res_set_res_funcs;
- live_edit_funcs.res_call_func = _live_edit_res_call_funcs;
- live_edit_funcs.root_func = _live_edit_root_funcs;
-
- live_edit_funcs.tree_create_node_func = _live_edit_create_node_funcs;
- live_edit_funcs.tree_instance_node_func = _live_edit_instance_node_funcs;
- live_edit_funcs.tree_remove_node_func = _live_edit_remove_node_funcs;
- live_edit_funcs.tree_remove_and_keep_node_func = _live_edit_remove_and_keep_node_funcs;
- live_edit_funcs.tree_restore_node_func = _live_edit_restore_node_funcs;
- live_edit_funcs.tree_duplicate_node_func = _live_edit_duplicate_node_funcs;
- live_edit_funcs.tree_reparent_node_func = _live_edit_reparent_node_funcs;
-
- if (ScriptDebugger::get_singleton()) {
- ScriptDebugger::get_singleton()->set_live_edit_funcs(&live_edit_funcs);
- }
-
live_edit_root = NodePath("/root");
#endif
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index ef847ebb5b..2cf6a117e7 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -211,7 +211,6 @@ private:
Variant _call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
Variant _call_group(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
- static void _debugger_request_tree(void *self);
void _flush_delete_queue();
//optimization
friend class CanvasItem;
@@ -220,6 +219,7 @@ private:
SelfList<Node>::List xform_change_list;
+ friend class ScriptDebuggerRemote;
#ifdef DEBUG_ENABLED
Map<int, NodePath> live_edit_node_path_cache;
@@ -231,7 +231,7 @@ private:
Map<String, Set<Node *> > live_scene_edit_cache;
Map<Node *, Map<ObjectID, Node *> > live_edit_remove_list;
- ScriptDebugger::LiveEditFuncs live_edit_funcs;
+ void _debugger_request_tree();
void _live_edit_node_path_func(const NodePath &p_path, int p_id);
void _live_edit_res_path_func(const String &p_path, int p_id);
@@ -252,25 +252,6 @@ private:
void _live_edit_duplicate_node_func(const NodePath &p_at, const String &p_new_name);
void _live_edit_reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
- static void _live_edit_node_path_funcs(void *self, const NodePath &p_path, int p_id) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_path_func(p_path, p_id); }
- static void _live_edit_res_path_funcs(void *self, const String &p_path, int p_id) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_path_func(p_path, p_id); }
-
- static void _live_edit_node_set_funcs(void *self, int p_id, const StringName &p_prop, const Variant &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_set_func(p_id, p_prop, p_value); }
- static void _live_edit_node_set_res_funcs(void *self, int p_id, const StringName &p_prop, const String &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_set_res_func(p_id, p_prop, p_value); }
- static void _live_edit_node_call_funcs(void *self, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_call_func(p_id, p_method, VARIANT_ARG_PASS); }
- static void _live_edit_res_set_funcs(void *self, int p_id, const StringName &p_prop, const Variant &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_set_func(p_id, p_prop, p_value); }
- static void _live_edit_res_set_res_funcs(void *self, int p_id, const StringName &p_prop, const String &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_set_res_func(p_id, p_prop, p_value); }
- static void _live_edit_res_call_funcs(void *self, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_call_func(p_id, p_method, VARIANT_ARG_PASS); }
- static void _live_edit_root_funcs(void *self, const NodePath &p_scene_path, const String &p_scene_from) { reinterpret_cast<SceneTree *>(self)->_live_edit_root_func(p_scene_path, p_scene_from); }
-
- static void _live_edit_create_node_funcs(void *self, const NodePath &p_parent, const String &p_type, const String &p_name) { reinterpret_cast<SceneTree *>(self)->_live_edit_create_node_func(p_parent, p_type, p_name); }
- static void _live_edit_instance_node_funcs(void *self, const NodePath &p_parent, const String &p_path, const String &p_name) { reinterpret_cast<SceneTree *>(self)->_live_edit_instance_node_func(p_parent, p_path, p_name); }
- static void _live_edit_remove_node_funcs(void *self, const NodePath &p_at) { reinterpret_cast<SceneTree *>(self)->_live_edit_remove_node_func(p_at); }
- static void _live_edit_remove_and_keep_node_funcs(void *self, const NodePath &p_at, ObjectID p_keep_id) { reinterpret_cast<SceneTree *>(self)->_live_edit_remove_and_keep_node_func(p_at, p_keep_id); }
- static void _live_edit_restore_node_funcs(void *self, ObjectID p_id, const NodePath &p_at, int p_at_pos) { reinterpret_cast<SceneTree *>(self)->_live_edit_restore_node_func(p_id, p_at, p_at_pos); }
- static void _live_edit_duplicate_node_funcs(void *self, const NodePath &p_at, const String &p_new_name) { reinterpret_cast<SceneTree *>(self)->_live_edit_duplicate_node_func(p_at, p_new_name); }
- static void _live_edit_reparent_node_funcs(void *self, const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) { reinterpret_cast<SceneTree *>(self)->_live_edit_reparent_node_func(p_at, p_new_place, p_new_name, p_at_pos); }
-
#endif
enum {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 95536bbb23..86ff99a19a 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -779,10 +779,45 @@ bool Viewport::is_audio_listener_2d() const {
return audio_listener_2d;
}
+void Viewport::enable_canvas_transform_override(bool p_enable) {
+ if (override_canvas_transform == p_enable) {
+ return;
+ }
+
+ override_canvas_transform = p_enable;
+ if (p_enable) {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform_override);
+ } else {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
+ }
+}
+
+bool Viewport::is_canvas_transform_override_enbled() const {
+ return override_canvas_transform;
+}
+
+void Viewport::set_canvas_transform_override(const Transform2D &p_transform) {
+ if (canvas_transform_override == p_transform) {
+ return;
+ }
+
+ canvas_transform_override = p_transform;
+ if (override_canvas_transform) {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform_override);
+ }
+}
+
+Transform2D Viewport::get_canvas_transform_override() const {
+ return canvas_transform_override;
+}
+
void Viewport::set_canvas_transform(const Transform2D &p_transform) {
canvas_transform = p_transform;
- VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
+
+ if (!override_canvas_transform) {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
+ }
}
Transform2D Viewport::get_canvas_transform() const {
@@ -890,10 +925,12 @@ void Viewport::_camera_set(Camera *p_camera) {
camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
}
camera = p_camera;
- if (camera)
- VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
- else
- VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ if (!camera_override) {
+ if (camera)
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
+ else
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ }
if (camera) {
camera->notification(Camera::NOTIFICATION_BECAME_CURRENT);
@@ -1108,10 +1145,82 @@ Listener *Viewport::get_listener() const {
}
Camera *Viewport::get_camera() const {
-
return camera;
}
+void Viewport::enable_camera_override(bool p_enable) {
+
+#ifndef _3D_DISABLED
+ if (p_enable == camera_override) {
+ return;
+ }
+
+ if (p_enable) {
+ camera_override.rid = VisualServer::get_singleton()->camera_create();
+ } else {
+ VisualServer::get_singleton()->free(camera_override.rid);
+ camera_override.rid = RID();
+ }
+
+ if (p_enable) {
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, camera_override.rid);
+ } else if (camera) {
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
+ } else {
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ }
+#endif
+}
+
+bool Viewport::is_camera_override_enabled() const {
+ return camera_override;
+}
+
+void Viewport::set_camera_override_transform(const Transform &p_transform) {
+ if (camera_override) {
+ camera_override.transform = p_transform;
+ VisualServer::get_singleton()->camera_set_transform(camera_override.rid, p_transform);
+ }
+}
+
+Transform Viewport::get_camera_override_transform() const {
+ if (camera_override) {
+ return camera_override.transform;
+ }
+
+ return Transform();
+}
+
+void Viewport::set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
+ if (camera_override) {
+ if (camera_override.fov == p_fovy_degrees && camera_override.z_near == p_z_near &&
+ camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_PERSPECTIVE)
+ return;
+
+ camera_override.fov = p_fovy_degrees;
+ camera_override.z_near = p_z_near;
+ camera_override.z_far = p_z_far;
+ camera_override.projection = CameraOverrideData::PROJECTION_PERSPECTIVE;
+
+ VisualServer::get_singleton()->camera_set_perspective(camera_override.rid, camera_override.fov, camera_override.z_near, camera_override.z_far);
+ }
+}
+
+void Viewport::set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far) {
+ if (camera_override) {
+ if (camera_override.size == p_size && camera_override.z_near == p_z_near &&
+ camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_ORTHOGONAL)
+ return;
+
+ camera_override.size = p_size;
+ camera_override.z_near = p_z_near;
+ camera_override.z_far = p_z_far;
+ camera_override.projection = CameraOverrideData::PROJECTION_ORTHOGONAL;
+
+ VisualServer::get_singleton()->camera_set_orthogonal(camera_override.rid, camera_override.size, camera_override.z_near, camera_override.z_far);
+ }
+}
+
Transform2D Viewport::get_final_transform() const {
return stretch_transform * global_canvas_transform;
@@ -3180,6 +3289,7 @@ Viewport::Viewport() {
parent = NULL;
listener = NULL;
camera = NULL;
+ override_canvas_transform = false;
canvas_layers.insert(NULL); // This eases picking code (interpreted as the canvas of the Viewport)
arvr = false;
size_override = false;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 6393785b22..3c3b436ca1 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -160,6 +160,24 @@ private:
bool arvr;
+ struct CameraOverrideData {
+ Transform transform;
+ enum Projection {
+ PROJECTION_PERSPECTIVE,
+ PROJECTION_ORTHOGONAL
+ };
+ Projection projection;
+ float fov;
+ float size;
+ float z_near;
+ float z_far;
+ RID rid;
+
+ operator bool() const {
+ return rid != RID();
+ }
+ } camera_override;
+
Camera *camera;
Set<Camera *> cameras;
Set<CanvasLayer *> canvas_layers;
@@ -173,6 +191,9 @@ private:
bool audio_listener_2d;
RID internal_listener_2d;
+ bool override_canvas_transform;
+
+ Transform2D canvas_transform_override;
Transform2D canvas_transform;
Transform2D global_canvas_transform;
Transform2D stretch_transform;
@@ -394,6 +415,15 @@ public:
Listener *get_listener() const;
Camera *get_camera() const;
+ void enable_camera_override(bool p_enable);
+ bool is_camera_override_enabled() const;
+
+ void set_camera_override_transform(const Transform &p_transform);
+ Transform get_camera_override_transform() const;
+
+ void set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far);
+ void set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far);
+
void set_use_arvr(bool p_use_arvr);
bool use_arvr();
@@ -418,6 +448,12 @@ public:
Ref<World2D> get_world_2d() const;
Ref<World2D> find_world_2d() const;
+ void enable_canvas_transform_override(bool p_enable);
+ bool is_canvas_transform_override_enbled() const;
+
+ void set_canvas_transform_override(const Transform2D &p_transform);
+ Transform2D get_canvas_transform_override() const;
+
void set_canvas_transform(const Transform2D &p_transform);
Transform2D get_canvas_transform() const;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index f7cec6a378..c944e7016e 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -56,12 +56,12 @@
#include "audio_server.h"
#include "camera/camera_feed.h"
#include "camera_server.h"
-#include "core/script_debugger_remote.h"
#include "physics/physics_server_sw.h"
#include "physics_2d/physics_2d_server_sw.h"
#include "physics_2d/physics_2d_server_wrap_mt.h"
#include "physics_2d_server.h"
#include "physics_server.h"
+#include "scene/debugger/script_debugger_remote.h"
#include "visual/shader_types.h"
#include "visual_server.h"