summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2019-11-08 10:02:18 +0100
committerGitHub <noreply@github.com>2019-11-08 10:02:18 +0100
commit621dc7022f9b9e09790481d8915858fa4d007ba4 (patch)
tree29d880f2c81f6081df2dcd01a2d0f30a4819ec42 /scene/main
parent31f327a4a9c2637a8d2ada01b293ed138c3e6f99 (diff)
parent8b0546d93b7487476e8ec290399d95fd172d9f50 (diff)
Merge pull request #27742 from rxlecky/camera-replication
Game camera override
Diffstat (limited to 'scene/main')
-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
4 files changed, 179 insertions, 72 deletions
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 d060ac273d..1af88171f6 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;