From a4156f1f0a69bcf4d7c1f43550a39a76cc389e0a Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 14 Sep 2016 15:55:14 -0300 Subject: [PATCH] Added a few functions to make 2D split screen easier. --- scene/2d/camera_2d.cpp | 59 +++++++++++++++++++++++++++++------- scene/2d/camera_2d.h | 5 ++++ scene/main/canvas_layer.cpp | 60 +++++++++++++++++++++++++++++-------- scene/main/canvas_layer.h | 8 +++++ 4 files changed, 110 insertions(+), 22 deletions(-) diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index e576aa10e0..17352705c7 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -44,6 +44,9 @@ void Camera2D::_update_scroll() { } if (current) { + + ERR_FAIL_COND( custom_viewport && !ObjectDB::get_instance(custom_viewport_id) ); + Matrix32 xform = get_camera_transform(); if (viewport) { @@ -240,14 +243,10 @@ void Camera2D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { - viewport = NULL; - Node *n=this; - while(n){ - - viewport = n->cast_to(); - if (viewport) - break; - n=n->get_parent(); + if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) { + viewport=custom_viewport; + } else { + viewport=get_viewport(); } canvas = get_canvas(); @@ -270,8 +269,8 @@ void Camera2D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - if (is_current()) { - if (viewport) { + if (is_current()) { + if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { viewport->set_canvas_transform( Matrix32() ); } } @@ -549,6 +548,42 @@ bool Camera2D::is_follow_smoothing_enabled() const { return smoothing_enabled; } +void Camera2D::set_custom_viewport(Node *p_viewport) { + ERR_FAIL_NULL(p_viewport); + if (is_inside_tree()) { + remove_from_group(group_name); + remove_from_group(canvas_group_name); + } + + custom_viewport=p_viewport->cast_to(); + + if (custom_viewport) { + custom_viewport_id=custom_viewport->get_instance_ID(); + } else { + custom_viewport_id=0; + } + + if (is_inside_tree()) { + + if (custom_viewport) + viewport=custom_viewport; + else + viewport=get_viewport(); + + RID vp = viewport->get_viewport(); + group_name = "__cameras_"+itos(vp.get_id()); + canvas_group_name ="__cameras_c"+itos(canvas.get_id()); + add_to_group(group_name); + add_to_group(canvas_group_name); + } + +} + +Node* Camera2D::get_custom_viewport() const { + + return custom_viewport; +} + void Camera2D::_bind_methods() { @@ -597,6 +632,8 @@ void Camera2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_zoom","zoom"),&Camera2D::set_zoom); ObjectTypeDB::bind_method(_MD("get_zoom"),&Camera2D::get_zoom); + ObjectTypeDB::bind_method(_MD("set_custom_viewport","viewport:Viewport"),&Camera2D::set_custom_viewport); + ObjectTypeDB::bind_method(_MD("get_custom_viewport:Viewport"),&Camera2D::get_custom_viewport); ObjectTypeDB::bind_method(_MD("set_follow_smoothing","follow_smoothing"),&Camera2D::set_follow_smoothing); ObjectTypeDB::bind_method(_MD("get_follow_smoothing"),&Camera2D::get_follow_smoothing); @@ -662,6 +699,8 @@ Camera2D::Camera2D() { first=true; smoothing_enabled=false; limit_smoothing_enabled=false; + custom_viewport=NULL; + custom_viewport_id=0; smoothing=5.0; zoom = Vector2(1, 1); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 9f3e4254bb..a4d6dc5b96 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -48,6 +48,8 @@ protected: Point2 smoothed_camera_pos; bool first; + ObjectID custom_viewport_id; // to check validity + Viewport *custom_viewport; Viewport *viewport; StringName group_name; @@ -128,6 +130,9 @@ public: Point2 get_camera_screen_center() const; + void set_custom_viewport(Node *p_viewport); + Node* get_custom_viewport() const; + Vector2 get_camera_pos() const; void force_update_scroll(); void reset_smoothing(); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index c31a57f819..8e238c7d77 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -168,20 +168,13 @@ void CanvasLayer::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { - Node *n = this; - vp=NULL; + if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) { - while(n) { + vp=custom_viewport; + } else { + vp=Node::get_viewport(); - if (n->cast_to()) { - - vp = n->cast_to(); - break; - } - n=n->get_parent(); } - - ERR_FAIL_COND(!vp); viewport=vp->get_viewport(); @@ -205,6 +198,7 @@ Size2 CanvasLayer::get_viewport_size() const { if (!is_inside_tree()) return Size2(1,1); + Rect2 r = vp->get_visible_rect(); return r.size; } @@ -215,6 +209,43 @@ RID CanvasLayer::get_viewport() const { return viewport; } +void CanvasLayer::set_custom_viewport(Node *p_viewport) { + ERR_FAIL_NULL(p_viewport); + if (is_inside_tree()) { + VisualServer::get_singleton()->viewport_remove_canvas(viewport,canvas->get_canvas()); + viewport=RID(); + } + + custom_viewport=p_viewport->cast_to(); + + if (custom_viewport) { + custom_viewport_id=custom_viewport->get_instance_ID(); + } else { + custom_viewport_id=0; + } + + if (is_inside_tree()) { + + + if (custom_viewport) + vp=custom_viewport; + else + vp=Node::get_viewport(); + + viewport = vp->get_viewport(); + + VisualServer::get_singleton()->viewport_attach_canvas(viewport,canvas->get_canvas()); + VisualServer::get_singleton()->viewport_set_canvas_layer(viewport,canvas->get_canvas(),layer); + VisualServer::get_singleton()->viewport_set_canvas_transform(viewport,canvas->get_canvas(),transform); + } + +} + +Node* CanvasLayer::get_custom_viewport() const { + + return custom_viewport; +} + void CanvasLayer::_bind_methods() { @@ -241,8 +272,11 @@ void CanvasLayer::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_scale","scale"),&CanvasLayer::set_scale); ObjectTypeDB::bind_method(_MD("get_scale"),&CanvasLayer::get_scale); + ObjectTypeDB::bind_method(_MD("set_custom_viewport","viewport:Viewport"),&CanvasLayer::set_custom_viewport); + ObjectTypeDB::bind_method(_MD("get_custom_viewport:Viewport"),&CanvasLayer::get_custom_viewport); + ObjectTypeDB::bind_method(_MD("get_world_2d:World2D"),&CanvasLayer::get_world_2d); - ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasLayer::get_viewport); +// ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasLayer::get_viewport); ADD_PROPERTY( PropertyInfo(Variant::INT,"layer",PROPERTY_HINT_RANGE,"-128,128,1"),_SCS("set_layer"),_SCS("get_layer") ); //ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"transform",PROPERTY_HINT_RANGE),_SCS("set_transform"),_SCS("get_transform") ); @@ -260,4 +294,6 @@ CanvasLayer::CanvasLayer() { locrotscale_dirty=false; layer=1; canvas = Ref( memnew(World2D) ); + custom_viewport=NULL; + custom_viewport_id=0; } diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index a3e8211a43..6aad90a09d 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -45,6 +45,10 @@ class CanvasLayer : public Node { int layer; Matrix32 transform; Ref canvas; + + ObjectID custom_viewport_id; // to check validity + Viewport *custom_viewport; + RID viewport; Viewport *vp; @@ -55,6 +59,7 @@ class CanvasLayer : public Node { void _update_xform(); void _update_locrotscale(); + protected: void _notification(int p_what); @@ -85,6 +90,9 @@ public: RID get_viewport() const; + void set_custom_viewport(Node *p_viewport); + Node* get_custom_viewport() const; + CanvasLayer(); };