From 8b0546d93b7487476e8ec290399d95fd172d9f50 Mon Sep 17 00:00:00 2001 From: Erik <35656626+SeleckyErik@users.noreply.github.com> Date: Sat, 6 Apr 2019 22:55:01 +0200 Subject: Implement game camera override Implemented uniform API in Viewport class to override 2D and/or 3D camera. Added buttons in 2D and 3D editor viewport toolbars that override the running game camera transform with the editor viewport camera transform. Implemented via remote debugger protocol and camera override API. Removed LiveEditFuncs function pointers from ScriptDebugger class. Since the debugger got access to the SceneTree instance (if one exists), there is no need to store the function pointers. The live edit functions in SceneTree are used directly instead. Also removed the static version of live edit functions in SceneTree for the same reason. This reduced the SceneTree -> Debugger coupling too since the function pointers don't need to be set from SceneTree anymore. Moved script_debugger_remote.h/cpp from 'core/' to 'scene/debugger/'. This is because the remote debugger is now using SceneTree directly and 'core/' classes should not depend on 'scene/' classes. --- scene/main/scene_tree.cpp | 70 ++++++++++---------------- scene/main/scene_tree.h | 23 +-------- scene/main/viewport.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++--- scene/main/viewport.h | 36 ++++++++++++++ 4 files changed, 179 insertions(+), 72 deletions(-) (limited to 'scene/main') 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 *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(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::List xform_change_list; + friend class ScriptDebuggerRemote; #ifdef DEBUG_ENABLED Map live_edit_node_path_cache; @@ -231,7 +231,7 @@ private: Map > live_scene_edit_cache; Map > 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 cameras; Set 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 get_world_2d() const; Ref 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; -- cgit v1.2.3