Browse Source

Ability to make CanvasLayers have pseudo 3D depth.

Juan Linietsky 6 years ago
parent
commit
19a6a6286a

+ 11 - 0
editor/plugins/canvas_item_editor_plugin.cpp

@@ -4150,6 +4150,14 @@ void CanvasItemEditor::_popup_callback(int p_op) {
 
 			_focus_selection(p_op);
 
+		} break;
+		case PREVIEW_CANVAS_SCALE: {
+
+			bool preview = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(PREVIEW_CANVAS_SCALE));
+			preview = !preview;
+			VS::get_singleton()->canvas_set_disable_scale(!preview);
+			view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(PREVIEW_CANVAS_SCALE), preview);
+
 		} break;
 		case SKELETON_MAKE_BONES: {
 
@@ -4824,6 +4832,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	p->add_separator();
 	p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION);
 	p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION);
+	p->add_separator();
+	p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_P), PREVIEW_CANVAS_SCALE);
 
 	presets_menu = memnew(MenuButton);
 	presets_menu->set_text(TTR("Layout"));
@@ -5421,6 +5431,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
 	label_desc->add_constant_override("line_spacing", 0);
 	label_desc->hide();
 	editor->get_gui_base()->add_child(label_desc);
+	VS::get_singleton()->canvas_set_disable_scale(true);
 }
 
 CanvasItemEditorViewport::~CanvasItemEditorViewport() {

+ 1 - 0
editor/plugins/canvas_item_editor_plugin.h

@@ -171,6 +171,7 @@ private:
 		ANIM_CLEAR_POSE,
 		VIEW_CENTER_TO_SELECTION,
 		VIEW_FRAME_TO_SELECTION,
+		PREVIEW_CANVAS_SCALE,
 		SKELETON_MAKE_BONES,
 		SKELETON_CLEAR_BONES,
 		SKELETON_SHOW_BONES,

+ 1 - 1
scene/2d/parallax_background.cpp

@@ -207,7 +207,7 @@ void ParallaxBackground::_bind_methods() {
 ParallaxBackground::ParallaxBackground() {
 
 	scale = 1.0;
-	set_layer(-1); //behind all by default
+	set_layer(-100); //behind all by default
 
 	base_scale = Vector2(1, 1);
 	ignore_camera_zoom = false;

+ 51 - 0
scene/main/canvas_layer.cpp

@@ -153,6 +153,7 @@ void CanvasLayer::_notification(int p_what) {
 			VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
 			VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
 			VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
+			_update_follow_viewport();
 
 		} break;
 		case NOTIFICATION_EXIT_TREE: {
@@ -160,6 +161,7 @@ void CanvasLayer::_notification(int p_what) {
 			vp->_canvas_layer_remove(this);
 			VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
 			viewport = RID();
+			_update_follow_viewport(false);
 
 		} break;
 		case NOTIFICATION_MOVED_IN_PARENT: {
@@ -235,6 +237,41 @@ RID CanvasLayer::get_canvas() const {
 
 	return canvas;
 }
+
+void CanvasLayer::set_follow_viewport(bool p_enable) {
+	if (follow_viewport == p_enable) {
+		return;
+	}
+
+	follow_viewport = p_enable;
+	_update_follow_viewport();
+}
+
+bool CanvasLayer::is_following_viewport() const {
+	return follow_viewport;
+}
+
+void CanvasLayer::set_follow_viewport_scale(float p_ratio) {
+	follow_viewport_scale = p_ratio;
+	_update_follow_viewport();
+}
+
+float CanvasLayer::get_follow_viewport_scale() const {
+	return follow_viewport_scale;
+}
+
+void CanvasLayer::_update_follow_viewport(bool p_force_exit) {
+
+	if (!is_inside_tree()) {
+		return;
+	}
+	if (p_force_exit || !follow_viewport) {
+		VS::get_singleton()->canvas_set_parent(canvas, RID(), 1.0);
+	} else {
+		VS::get_singleton()->canvas_set_parent(canvas, vp->get_world_2d()->get_canvas(), follow_viewport_scale);
+	}
+}
+
 void CanvasLayer::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
@@ -255,18 +292,30 @@ void CanvasLayer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_scale", "scale"), &CanvasLayer::set_scale);
 	ClassDB::bind_method(D_METHOD("get_scale"), &CanvasLayer::get_scale);
 
+	ClassDB::bind_method(D_METHOD("set_follow_viewport", "enable"), &CanvasLayer::set_follow_viewport);
+	ClassDB::bind_method(D_METHOD("is_following_viewport"), &CanvasLayer::is_following_viewport);
+
+	ClassDB::bind_method(D_METHOD("set_follow_viewport_scale", "scale"), &CanvasLayer::set_follow_viewport_scale);
+	ClassDB::bind_method(D_METHOD("get_follow_viewport_scale"), &CanvasLayer::get_follow_viewport_scale);
+
 	ClassDB::bind_method(D_METHOD("set_custom_viewport", "viewport"), &CanvasLayer::set_custom_viewport);
 	ClassDB::bind_method(D_METHOD("get_custom_viewport"), &CanvasLayer::get_custom_viewport);
 
 	ClassDB::bind_method(D_METHOD("get_canvas"), &CanvasLayer::get_canvas);
 
+	ADD_GROUP("Layer", "");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer");
+	ADD_GROUP("Transform", "");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
 	ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
+	ADD_GROUP("", "");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport");
+	ADD_GROUP("Follow Viewport", "follow_viewport");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enable"), "set_follow_viewport", "is_following_viewport");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale");
 }
 
 CanvasLayer::CanvasLayer() {
@@ -280,6 +329,8 @@ CanvasLayer::CanvasLayer() {
 	custom_viewport = NULL;
 	custom_viewport_id = 0;
 	sort_index = 0;
+	follow_viewport = false;
+	follow_viewport_scale = 1.0;
 }
 
 CanvasLayer::~CanvasLayer() {

+ 10 - 0
scene/main/canvas_layer.h

@@ -55,8 +55,12 @@ class CanvasLayer : public Node {
 
 	int sort_index;
 
+	bool follow_viewport;
+	float follow_viewport_scale;
+
 	void _update_xform();
 	void _update_locrotscale();
+	void _update_follow_viewport(bool p_force_exit = false);
 
 protected:
 	void _notification(int p_what);
@@ -91,6 +95,12 @@ public:
 	void reset_sort_index();
 	int get_sort_index();
 
+	void set_follow_viewport(bool p_enable);
+	bool is_following_viewport() const;
+
+	void set_follow_viewport_scale(float p_ratio);
+	float get_follow_viewport_scale() const;
+
 	RID get_canvas() const;
 
 	CanvasLayer();

+ 14 - 0
servers/visual/visual_server_canvas.cpp

@@ -319,6 +319,19 @@ void VisualServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color)
 	canvas->modulate = p_color;
 }
 
+void VisualServerCanvas::canvas_set_disable_scale(bool p_disable) {
+	disable_scale = p_disable;
+}
+
+void VisualServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) {
+
+	Canvas *canvas = canvas_owner.get(p_canvas);
+	ERR_FAIL_COND(!canvas);
+
+	canvas->parent = p_parent;
+	canvas->parent_scale = p_scale;
+}
+
 RID VisualServerCanvas::canvas_item_create() {
 
 	Item *canvas_item = memnew(Item);
@@ -1434,4 +1447,5 @@ bool VisualServerCanvas::free(RID p_rid) {
 }
 
 VisualServerCanvas::VisualServerCanvas() {
+	disable_scale = false;
 }

+ 8 - 1
servers/visual/visual_server_canvas.h

@@ -126,6 +126,8 @@ public:
 		bool children_order_dirty;
 		Vector<ChildItem> child_items;
 		Color modulate;
+		RID parent;
+		float parent_scale;
 
 		int find_item(Item *p_item) {
 			for (int i = 0; i < child_items.size(); i++) {
@@ -143,13 +145,16 @@ public:
 		Canvas() {
 			modulate = Color(1, 1, 1, 1);
 			children_order_dirty = true;
+			parent_scale = 1.0;
 		}
 	};
 
-	RID_Owner<Canvas> canvas_owner;
+	mutable RID_Owner<Canvas> canvas_owner;
 	RID_Owner<Item> canvas_item_owner;
 	RID_Owner<RasterizerCanvas::Light> canvas_light_owner;
 
+	bool disable_scale;
+
 private:
 	void _render_canvas_item_tree(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights);
 	void _render_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
@@ -161,6 +166,8 @@ public:
 	RID canvas_create();
 	void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring);
 	void canvas_set_modulate(RID p_canvas, const Color &p_color);
+	void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale);
+	void canvas_set_disable_scale(bool p_disable);
 
 	RID canvas_item_create();
 	void canvas_item_set_parent(RID p_item, RID p_parent);

+ 2 - 0
servers/visual/visual_server_raster.h

@@ -569,6 +569,8 @@ public:
 	BIND0R(RID, canvas_create)
 	BIND3(canvas_set_item_mirroring, RID, RID, const Point2 &)
 	BIND2(canvas_set_modulate, RID, const Color &)
+	BIND3(canvas_set_parent, RID, RID, float)
+	BIND1(canvas_set_disable_scale, bool)
 
 	BIND0R(RID, canvas_item_create)
 	BIND2(canvas_item_set_parent, RID, RID)

+ 30 - 3
servers/visual/visual_server_viewport.cpp

@@ -35,6 +35,33 @@
 #include "visual_server_globals.h"
 #include "visual_server_scene.h"
 
+static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewport, VisualServerCanvas::Canvas *p_canvas, VisualServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
+
+	Transform2D xf = p_viewport->global_transform;
+
+	float scale = 1.0;
+	if (p_viewport->canvas_map.has(p_canvas->parent)) {
+		xf = xf * p_viewport->canvas_map[p_canvas->parent].transform;
+		scale = p_canvas->parent_scale;
+	}
+
+	xf = xf * p_canvas_data->transform;
+
+	if (scale != 1.0 && !VSG::canvas->disable_scale) {
+		Vector2 pivot = p_vp_size * 0.5;
+		Transform2D xfpivot;
+		xfpivot.set_origin(pivot);
+		Transform2D xfscale;
+		xfscale.scale(Vector2(scale, scale));
+
+		xf = xfpivot.affine_inverse() * xf;
+		xf = xfscale * xf;
+		xf = xfpivot * xf;
+	}
+
+	return xf;
+}
+
 void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
 
 	/* Camera should always be BEFORE any other 3D */
@@ -86,10 +113,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
 
 		for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
 
-			Transform2D xf = p_viewport->global_transform * E->get().transform;
-
 			VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas);
 
+			Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
+
 			//find lights in canvas
 
 			for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) {
@@ -193,7 +220,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
 
 			VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas);
 
-			Transform2D xform = p_viewport->global_transform * E->get()->transform;
+			Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size);
 
 			RasterizerCanvas::Light *canvas_lights = NULL;
 

+ 2 - 0
servers/visual/visual_server_wrap_mt.h

@@ -487,6 +487,8 @@ public:
 	FUNCRID(canvas)
 	FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &)
 	FUNC2(canvas_set_modulate, RID, const Color &)
+	FUNC3(canvas_set_parent, RID, RID, float)
+	FUNC1(canvas_set_disable_scale, bool)
 
 	FUNCRID(canvas_item)
 	FUNC2(canvas_item_set_parent, RID, RID)

+ 3 - 0
servers/visual_server.h

@@ -860,6 +860,9 @@ public:
 	virtual RID canvas_create() = 0;
 	virtual void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) = 0;
 	virtual void canvas_set_modulate(RID p_canvas, const Color &p_color) = 0;
+	virtual void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) = 0;
+
+	virtual void canvas_set_disable_scale(bool p_disable) = 0;
 
 	virtual RID canvas_item_create() = 0;
 	virtual void canvas_item_set_parent(RID p_item, RID p_parent) = 0;