Merge pull request #27742 from rxlecky/camera-replication

Game camera override
This commit is contained in:
Rémi Verschelde 2019-11-08 10:02:18 +01:00 committed by GitHub
commit 621dc7022f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 536 additions and 169 deletions

View file

@ -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;

View file

@ -3811,6 +3811,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"));
@ -3880,6 +3881,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() {
@ -4221,6 +4231,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) {
@ -4318,6 +4337,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);
@ -4915,6 +4945,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);
@ -5246,6 +5278,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);
@ -5491,6 +5526,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);

View file

@ -364,6 +364,7 @@ private:
ToolButton *ungroup_button;
MenuButton *skeleton_menu;
ToolButton *override_camera_button;
MenuButton *view_menu;
HBoxContainer *animation_hb;
MenuButton *animation_menu;
@ -537,8 +538,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;

View file

@ -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()) {
@ -3101,6 +3103,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() {
@ -4373,6 +4376,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;
}
}
@ -4400,6 +4416,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) {
@ -5294,6 +5339,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"));
@ -5309,6 +5355,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();
@ -5343,6 +5392,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);
}
}
}
@ -5487,6 +5543,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"));
@ -5540,6 +5598,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);
@ -5637,6 +5697,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();
@ -5725,6 +5796,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]);
}

View file

@ -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];
}

View file

@ -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"
@ -1232,6 +1234,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) {
@ -1446,6 +1484,7 @@ void ScriptEditorDebugger::start() {
set_process(true);
breaked = false;
camera_override = OVERRIDE_NONE;
}
void ScriptEditorDebugger::pause() {
@ -1890,6 +1929,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()) {

View file

@ -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();

View file

@ -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"
@ -1581,6 +1581,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);

View file

@ -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

5
scene/debugger/SCsub Normal file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env python
Import('env')
env.add_source_files(env.scene_sources, "*.cpp")

View file

@ -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

View file

@ -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();
};

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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"