Ability to make CanvasLayers have pseudo 3D depth.

This commit is contained in:
Juan Linietsky 2019-04-05 10:24:54 -03:00
parent 4141703b1a
commit 19a6a6286a
11 changed files with 133 additions and 5 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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