summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp38
-rw-r--r--scene/resources/animation.h7
-rw-r--r--scene/resources/bit_mask.cpp6
-rw-r--r--scene/resources/box_shape.cpp4
-rw-r--r--scene/resources/capsule_shape.cpp4
-rw-r--r--scene/resources/capsule_shape_2d.cpp4
-rw-r--r--scene/resources/circle_shape_2d.cpp4
-rw-r--r--scene/resources/concave_polygon_shape.cpp4
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp4
-rw-r--r--scene/resources/convex_polygon_shape.cpp4
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp4
-rw-r--r--scene/resources/default_theme/default_theme.cpp11
-rw-r--r--scene/resources/default_theme/icon_parent_folder.pngbin0 -> 329 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h8
-rw-r--r--scene/resources/default_theme/tree_bg_disabled.pngbin0 -> 406 bytes
-rw-r--r--scene/resources/dynamic_font.cpp2
-rw-r--r--scene/resources/material.cpp28
-rw-r--r--scene/resources/material.h9
-rw-r--r--scene/resources/mesh.cpp211
-rw-r--r--scene/resources/mesh.h7
-rw-r--r--scene/resources/packed_scene.cpp8
-rw-r--r--scene/resources/plane_shape.cpp4
-rw-r--r--scene/resources/primitive_meshes.cpp2
-rw-r--r--scene/resources/ray_shape.cpp4
-rw-r--r--scene/resources/rectangle_shape_2d.cpp4
-rw-r--r--scene/resources/segment_shape_2d.cpp8
-rw-r--r--scene/resources/shape_line_2d.cpp4
-rw-r--r--scene/resources/sphere_shape.cpp4
-rw-r--r--scene/resources/surface_tool.cpp114
-rw-r--r--scene/resources/surface_tool.h3
-rw-r--r--scene/resources/texture.cpp69
-rw-r--r--scene/resources/texture.h27
-rw-r--r--scene/resources/tile_set.cpp399
-rw-r--r--scene/resources/tile_set.h84
-rw-r--r--scene/resources/world.cpp4
35 files changed, 1034 insertions, 63 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 8192074c17..4544549f94 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -77,6 +77,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
track_set_interpolation_loop_wrap(track, p_value);
else if (what == "imported")
track_set_imported(track, p_value);
+ else if (what == "enabled")
+ track_set_enabled(track, p_value);
else if (what == "keys" || what == "key_values") {
if (track_get_type(track) == TYPE_TRANSFORM) {
@@ -247,6 +249,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = track_get_interpolation_loop_wrap(track);
else if (what == "imported")
r_ret = track_is_imported(track);
+ else if (what == "enabled")
+ r_ret = track_is_enabled(track);
else if (what == "keys") {
if (track_get_type(track) == TYPE_TRANSFORM) {
@@ -391,6 +395,7 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/imported", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -1575,6 +1580,19 @@ bool Animation::track_is_imported(int p_track) const {
return tracks[p_track]->imported;
}
+void Animation::track_set_enabled(int p_track, bool p_enabled) {
+
+ ERR_FAIL_INDEX(p_track, tracks.size());
+ tracks[p_track]->enabled = p_enabled;
+ emit_changed();
+}
+
+bool Animation::track_is_enabled(int p_track) const {
+
+ ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
+ return tracks[p_track]->enabled;
+}
+
void Animation::track_move_down(int p_track) {
if (p_track > 0 && p_track < tracks.size()) {
@@ -1595,6 +1613,22 @@ float Animation::get_step() const {
return step;
}
+void Animation::copy_track(int src_track, Ref<Animation> p_to_animation) {
+ ERR_FAIL_COND(p_to_animation.is_null());
+ ERR_FAIL_INDEX(src_track, get_track_count());
+ int dst_track = p_to_animation->get_track_count();
+ p_to_animation->add_track(track_get_type(src_track));
+
+ p_to_animation->track_set_path(dst_track, track_get_path(src_track));
+ p_to_animation->track_set_imported(dst_track, track_is_imported(src_track));
+ p_to_animation->track_set_enabled(dst_track, track_is_enabled(src_track));
+ p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(src_track));
+ p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(src_track));
+ for (int i = 0; i < track_get_key_count(src_track); i++) {
+ p_to_animation->track_insert_key(dst_track, track_get_key_time(src_track, i), track_get_key_value(src_track, i), track_get_key_transition(src_track, i));
+ }
+}
+
void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
@@ -1611,6 +1645,9 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("track_set_imported", "idx", "imported"), &Animation::track_set_imported);
ClassDB::bind_method(D_METHOD("track_is_imported", "idx"), &Animation::track_is_imported);
+ ClassDB::bind_method(D_METHOD("track_set_enabled", "idx", "enabled"), &Animation::track_set_enabled);
+ ClassDB::bind_method(D_METHOD("track_is_enabled", "idx"), &Animation::track_is_enabled);
+
ClassDB::bind_method(D_METHOD("transform_track_insert_key", "idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key);
ClassDB::bind_method(D_METHOD("track_insert_key", "idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1));
ClassDB::bind_method(D_METHOD("track_remove_key", "idx", "key_idx"), &Animation::track_remove_key);
@@ -1650,6 +1687,7 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step);
ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
+ ClassDB::bind_method(D_METHOD("copy_track", "track", "to_animation"), &Animation::copy_track);
BIND_ENUM_CONSTANT(TYPE_VALUE);
BIND_ENUM_CONSTANT(TYPE_TRANSFORM);
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 6235e161a3..1f468b29b5 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -67,10 +67,12 @@ private:
bool loop_wrap;
NodePath path; // path to something
bool imported;
+ bool enabled;
Track() {
interpolation = INTERPOLATION_LINEAR;
imported = false;
loop_wrap = true;
+ enabled = true;
}
virtual ~Track() {}
};
@@ -239,6 +241,9 @@ public:
void track_set_imported(int p_track, bool p_imported);
bool track_is_imported(int p_track) const;
+ void track_set_enabled(int p_track, bool p_enabled);
+ bool track_is_enabled(int p_track) const;
+
int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3());
void track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition = 1);
void track_set_key_transition(int p_track, int p_key_idx, float p_transition);
@@ -269,6 +274,8 @@ public:
Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const;
StringName method_track_get_name(int p_track, int p_key_idx) const;
+ void copy_track(int p_track, Ref<Animation> p_to_animation);
+
void set_length(float p_length);
float get_length() const;
diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp
index 029a9ef0e8..eebc872dfb 100644
--- a/scene/resources/bit_mask.cpp
+++ b/scene/resources/bit_mask.cpp
@@ -38,7 +38,7 @@ void BitMap::create(const Size2 &p_size) {
width = p_size.width;
height = p_size.height;
bitmask.resize(((width * height) / 8) + 1);
- zeromem(bitmask.ptr(), bitmask.size());
+ zeromem(bitmask.ptrw(), bitmask.size());
}
void BitMap::create_from_image_alpha(const Ref<Image> &p_image) {
@@ -51,7 +51,7 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image) {
create(Size2(img->get_width(), img->get_height()));
PoolVector<uint8_t>::Read r = img->get_data().read();
- uint8_t *w = bitmask.ptr();
+ uint8_t *w = bitmask.ptrw();
for (int i = 0; i < width * height; i++) {
@@ -65,7 +65,7 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image) {
void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
Rect2i current = Rect2i(0, 0, width, height).clip(p_rect);
- uint8_t *data = bitmask.ptr();
+ uint8_t *data = bitmask.ptrw();
for (int i = current.position.x; i < current.position.x + current.size.x; i++) {
diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp
index 4b9843f3f5..858e19c9a6 100644
--- a/scene/resources/box_shape.cpp
+++ b/scene/resources/box_shape.cpp
@@ -73,8 +73,8 @@ void BoxShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
}
-BoxShape::BoxShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) {
+BoxShape::BoxShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) {
set_extents(Vector3(1, 1, 1));
}
diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp
index e11b98f82e..f0eb8232e5 100644
--- a/scene/resources/capsule_shape.cpp
+++ b/scene/resources/capsule_shape.cpp
@@ -113,8 +113,8 @@ void CapsuleShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
}
-CapsuleShape::CapsuleShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) {
+CapsuleShape::CapsuleShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) {
radius = 1.0;
height = 1.0;
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 912150b939..3caf12feb8 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -97,8 +97,8 @@ void CapsuleShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height");
}
-CapsuleShape2D::CapsuleShape2D()
- : Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {
+CapsuleShape2D::CapsuleShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {
radius = 10;
height = 20;
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index 287bde4bfb..bff3ed4d67 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -76,8 +76,8 @@ void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}
-CircleShape2D::CircleShape2D()
- : Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) {
+CircleShape2D::CircleShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) {
radius = 10;
_update_shape();
diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp
index 6ae4fde85e..1c48f0c30b 100644
--- a/scene/resources/concave_polygon_shape.cpp
+++ b/scene/resources/concave_polygon_shape.cpp
@@ -106,8 +106,8 @@ void ConcavePolygonShape::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape::get_faces);
}
-ConcavePolygonShape::ConcavePolygonShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) {
+ConcavePolygonShape::ConcavePolygonShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) {
//set_planes(Vector3(1,1,1));
}
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index bb91e33ec2..e90046fd28 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -84,6 +84,6 @@ void ConcavePolygonShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments");
}
-ConcavePolygonShape2D::ConcavePolygonShape2D()
- : Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) {
+ConcavePolygonShape2D::ConcavePolygonShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) {
}
diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp
index bba52bd5ff..31c4ea55e9 100644
--- a/scene/resources/convex_polygon_shape.cpp
+++ b/scene/resources/convex_polygon_shape.cpp
@@ -81,8 +81,8 @@ void ConvexPolygonShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "points"), "set_points", "get_points");
}
-ConvexPolygonShape::ConvexPolygonShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) {
+ConvexPolygonShape::ConvexPolygonShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) {
//set_points(Vector3(1,1,1));
}
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index a76b6a7cf4..9c25b6b467 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -86,8 +86,8 @@ Rect2 ConvexPolygonShape2D::get_rect() const {
return rect;
}
-ConvexPolygonShape2D::ConvexPolygonShape2D()
- : Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) {
+ConvexPolygonShape2D::ConvexPolygonShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) {
int pcount = 3;
for (int i = 0; i < pcount; i++)
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index cd28c9d203..bb2c8750e3 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -257,6 +257,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// LinkButton
+ theme->set_stylebox("focus", "LinkButton", focus);
+
theme->set_font("font", "LinkButton", default_font);
theme->set_color("font_color", "LinkButton", control_font_color);
@@ -310,7 +312,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("pressed", "OptionButton", sb_optbutton_pressed);
theme->set_stylebox("hover", "OptionButton", sb_optbutton_hover);
theme->set_stylebox("disabled", "OptionButton", sb_optbutton_disabled);
- theme->set_stylebox("focus", "OptionButton", sb_button_focus);
+ theme->set_stylebox("focus", "OptionButton", sb_optbutton_focus);
theme->set_icon("arrow", "OptionButton", make_icon(option_arrow_png));
@@ -328,8 +330,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("normal", "MenuButton", sb_button_normal);
theme->set_stylebox("pressed", "MenuButton", sb_button_pressed);
- theme->set_stylebox("hover", "MenuButton", sb_button_pressed);
- theme->set_stylebox("disabled", "MenuButton", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_stylebox("hover", "MenuButton", sb_button_hover);
+ theme->set_stylebox("disabled", "MenuButton", sb_button_disabled);
theme->set_stylebox("focus", "MenuButton", sb_button_focus);
theme->set_font("font", "MenuButton", default_font);
@@ -448,6 +450,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("normal", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3));
theme->set_stylebox("focus", "TextEdit", focus);
+ theme->set_stylebox("read_only", "TextEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4));
theme->set_stylebox("completion", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3));
theme->set_icon("tab", "TextEdit", make_icon(tab_png));
@@ -465,6 +468,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("selection_color", "TextEdit", font_color_selection);
theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4));
theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2));
+ theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
theme->set_color("caret_color", "TextEdit", control_font_color);
theme->set_color("caret_background_color", "TextEdit", Color::html("000000"));
@@ -556,6 +560,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// File Dialog
theme->set_icon("reload", "FileDialog", make_icon(icon_reload_png));
+ theme->set_icon("parent_folder", "FileDialog", make_icon(icon_parent_folder_png));
// Popup
diff --git a/scene/resources/default_theme/icon_parent_folder.png b/scene/resources/default_theme/icon_parent_folder.png
new file mode 100644
index 0000000000..47fee1ad81
--- /dev/null
+++ b/scene/resources/default_theme/icon_parent_folder.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 38e5f58b0d..c6b37cad5a 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -174,6 +174,10 @@ static const unsigned char icon_folder_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x8f, 0xc1, 0xd, 0x80, 0x30, 0x8, 0x45, 0x9f, 0x9d, 0x84, 0x39, 0x4c, 0x3b, 0xbd, 0x75, 0x8f, 0x32, 0x9, 0x5e, 0xec, 0xa5, 0x9, 0xa4, 0xc6, 0x26, 0x5e, 0x7c, 0x17, 0xe, 0xc0, 0xe3, 0x3, 0x5f, 0xb3, 0x1, 0xb4, 0xd6, 0x4e, 0x60, 0x77, 0x66, 0xaa, 0x88, 0x14, 0x4f, 0x90, 0xee, 0xea, 0x2d, 0x3, 0xe4, 0x28, 0x41, 0x8a, 0x9a, 0x1d, 0x55, 0x75, 0x25, 0xfd, 0x5, 0x9b, 0x11, 0xd, 0x54, 0x11, 0x29, 0x53, 0x9, 0x1c, 0x32, 0x4c, 0xbe, 0x10, 0xf1, 0xb, 0x16, 0xa, 0xea, 0xd3, 0x45, 0x33, 0x3b, 0xde, 0x1e, 0x5f, 0xc3, 0x5, 0x1f, 0xc5, 0x12, 0x2c, 0xc5, 0x88, 0xe1, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char icon_parent_folder_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x90, 0xbd, 0x6a, 0x2, 0x51, 0x10, 0x46, 0xcf, 0x8c, 0xbb, 0xaf, 0x10, 0xdb, 0xcb, 0x2e, 0x4b, 0x40, 0xf2, 0x14, 0x51, 0x8b, 0x3c, 0x70, 0x44, 0x48, 0x48, 0x15, 0x4c, 0x61, 0x67, 0xd2, 0x4, 0x96, 0xb, 0x5b, 0x89, 0x58, 0x59, 0xee, 0x8f, 0x3b, 0x36, 0xbb, 0x8d, 0x78, 0xa3, 0x92, 0x4a, 0x4f, 0xf9, 0xcd, 0xcc, 0x99, 0x61, 0xe0, 0xe6, 0x91, 0x50, 0xc1, 0x7b, 0x3f, 0x54, 0xd5, 0x39, 0x60, 0x6d, 0xdb, 0xbe, 0x24, 0x49, 0xb2, 0xb9, 0x58, 0x90, 0xe7, 0xf9, 0x43, 0x1c, 0xc7, 0xef, 0x66, 0xf6, 0xd4, 0x45, 0xbf, 0xc0, 0xb3, 0x73, 0x6e, 0x7d, 0x56, 0x70, 0x62, 0xb8, 0xe7, 0xa4, 0x44, 0x8f, 0xcf, 0x8e, 0xa2, 0xe8, 0xa3, 0x1b, 0xfe, 0xee, 0x62, 0x13, 0x91, 0x1f, 0xe0, 0x11, 0x78, 0xf3, 0xde, 0xf, 0x83, 0x2, 0x55, 0x9d, 0x1, 0x23, 0x60, 0xd5, 0x34, 0xcd, 0xb4, 0xcf, 0xab, 0xaa, 0x1a, 0x77, 0xc2, 0x91, 0xaa, 0xbe, 0x6, 0x5, 0xc0, 0xe, 0xf8, 0x2a, 0xcb, 0x72, 0x92, 0xa6, 0xe9, 0xb6, 0xf, 0xb3, 0x2c, 0xdb, 0xd6, 0x75, 0x3d, 0x11, 0x91, 0x25, 0x50, 0xfe, 0xf9, 0x83, 0x1e, 0x33, 0x93, 0xa2, 0x28, 0xf6, 0x80, 0x39, 0xe7, 0x6, 0xa1, 0xbe, 0xe3, 0xb, 0xae, 0x26, 0x28, 0x10, 0x11, 0x3, 0x16, 0x22, 0xf2, 0xf9, 0xdf, 0x25, 0xf7, 0xce, 0x1, 0x9e, 0x13, 0x48, 0xe9, 0x87, 0xc5, 0x3a, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char icon_play_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0xf2, 0x80, 0x11, 0x99, 0xf3, 0xe0, 0xc1, 0x83, 0xc3, 0xc, 0xc, 0xc, 0xc2, 0xc, 0xc, 0xc, 0xa5, 0xa, 0xa, 0xa, 0x5b, 0xc9, 0x31, 0xe0, 0x3f, 0x5c, 0x82, 0x91, 0x71, 0x27, 0x3, 0x3, 0x43, 0x91, 0xbc, 0xbc, 0xfc, 0x35, 0x7c, 0x6, 0x30, 0xe1, 0x92, 0xf8, 0xff, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xff, 0x2f, 0x3e, 0x78, 0xf0, 0x60, 0xca, 0x93, 0x27, 0x4f, 0x84, 0x49, 0x76, 0x1, 0x1a, 0xf8, 0xc0, 0xc8, 0xc8, 0xd8, 0xf1, 0xeb, 0xd7, 0xaf, 0x9, 0xaa, 0xaa, 0xaa, 0x3f, 0x89, 0x72, 0x1, 0x1a, 0x10, 0xf8, 0xff, 0xff, 0x7f, 0x7, 0x2b, 0x2b, 0xeb, 0x1e, 0x74, 0x9, 0x62, 0xd, 0xc0, 0x9, 0x88, 0x35, 0xe0, 0x3d, 0x23, 0x23, 0x63, 0xc5, 0xef, 0xdf, 0xbf, 0x5d, 0xd0, 0x25, 0x58, 0x8, 0x68, 0xfc, 0xc3, 0xc0, 0xc0, 0x30, 0x93, 0x85, 0x85, 0xa5, 0x5e, 0x46, 0x46, 0xe6, 0x2d, 0x36, 0x5, 0x38, 0xd, 0x20, 0x36, 0x1a, 0xd1, 0xd, 0x38, 0xc2, 0x0, 0x4d, 0x48, 0xf2, 0xf2, 0xf2, 0x44, 0x25, 0xa4, 0x61, 0x0, 0x0, 0x1e, 0x57, 0x33, 0x3c, 0xcc, 0xe7, 0x34, 0x69, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
@@ -406,6 +410,10 @@ static const unsigned char tree_bg_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xd, 0xf6, 0xb4, 0x61, 0xf5, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char tree_bg_disabled_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x95, 0xce, 0x31, 0x12, 0x2, 0x21, 0x10, 0x44, 0xd1, 0x3f, 0x40, 0xa1, 0x44, 0xa6, 0x46, 0xde, 0x63, 0x4f, 0xe5, 0x15, 0x38, 0xb2, 0xd6, 0x6, 0xb0, 0xc8, 0x30, 0x6, 0x96, 0xac, 0x56, 0x99, 0xf8, 0xb3, 0x7e, 0x51, 0xcb, 0xf9, 0x1a, 0xb3, 0x3f, 0xa, 0xaf, 0xc, 0xad, 0x2d, 0xcb, 0xe5, 0x76, 0x38, 0x5, 0x76, 0xec, 0x6c, 0xf7, 0xe0, 0x53, 0xe0, 0x13, 0xa1, 0x27, 0x27, 0x43, 0x26, 0x81, 0x20, 0xc8, 0x70, 0xfc, 0xe8, 0xf, 0x34, 0x67, 0xd8, 0x9c, 0x86, 0x61, 0x2e, 0x68, 0xe9, 0x91, 0xaf, 0x4b, 0x5a, 0x7d, 0x2a, 0x2c, 0x3, 0xed, 0xef, 0x1e, 0x6b, 0xcb, 0x4f, 0xa6, 0x66, 0x2b, 0x25, 0x6, 0x1, 0x37, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char tree_bg_focus_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xdb, 0xb, 0x4, 0x12, 0x2d, 0x3a, 0xb5, 0x1b, 0x14, 0x49, 0x0, 0x0, 0x2, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xc5, 0x57, 0x31, 0x8e, 0x14, 0x31, 0x10, 0xac, 0xea, 0x3d, 0x11, 0x91, 0xdf, 0x49, 0xf7, 0xf, 0x78, 0x1, 0xf, 0x40, 0x84, 0x44, 0x10, 0xf2, 0x20, 0x42, 0x62, 0x12, 0xc4, 0x3, 0x78, 0x1, 0xff, 0x21, 0x42, 0xb8, 0x8a, 0xc0, 0x1e, 0x4f, 0xdb, 0xe3, 0xb9, 0xbb, 0x45, 0x20, 0x7c, 0x1a, 0xdd, 0x8c, 0xec, 0xed, 0xae, 0xae, 0xea, 0xee, 0xe9, 0xe1, 0xfd, 0xed, 0xdd, 0xb, 0x0, 0xdf, 0xf1, 0x7f, 0xd6, 0x4b, 0xde, 0xdf, 0xde, 0xf9, 0xcb, 0xeb, 0x9f, 0xff, 0xc5, 0xfb, 0x9b, 0xaf, 0xcf, 0x70, 0xb3, 0x3d, 0x3c, 0xff, 0xf0, 0xd, 0x24, 0x11, 0x71, 0x1, 0x49, 0x90, 0x4, 0x0, 0x4, 0xd3, 0x2f, 0xb6, 0x7b, 0xf, 0xff, 0x86, 0x2d, 0x8c, 0x47, 0x60, 0x1b, 0x0, 0x61, 0x1b, 0xb6, 0x21, 0x15, 0xd8, 0xc6, 0x8f, 0x8f, 0xaf, 0x0, 0x60, 0x7, 0x0, 0xa2, 0x2, 0x20, 0x11, 0x41, 0x30, 0xa2, 0x2, 0xc1, 0xb5, 0x0, 0x8c, 0x79, 0xd9, 0x80, 0x24, 0x48, 0x0, 0x48, 0x28, 0x9d, 0xb9, 0xd9, 0xd, 0xb0, 0x31, 0x40, 0x5c, 0x2e, 0x1, 0x46, 0x0, 0xd, 0xd0, 0xb6, 0xef, 0x35, 0x8e, 0x13, 0x6, 0xbc, 0x33, 0x60, 0xa3, 0x9a, 0x11, 0x6c, 0x82, 0xe6, 0xa, 0x0, 0x86, 0xe8, 0x2f, 0x71, 0xa9, 0xf7, 0x9c, 0x4d, 0x1f, 0x69, 0x5e, 0x1, 0xd8, 0xa3, 0x37, 0xa4, 0xa, 0x27, 0x1a, 0x13, 0x79, 0x25, 0x9, 0xaa, 0xe3, 0xd8, 0x9c, 0x5f, 0xea, 0x7d, 0x67, 0x80, 0xd7, 0x31, 0x20, 0xab, 0x3, 0x20, 0x5, 0x20, 0x2a, 0x13, 0x41, 0x40, 0x2b, 0x0, 0x76, 0x22, 0xb9, 0xb1, 0xd1, 0x92, 0x91, 0x5d, 0x86, 0xf3, 0x35, 0xef, 0x5, 0xa3, 0x25, 0x60, 0xd, 0x6e, 0x66, 0xe5, 0x0, 0xc0, 0xa8, 0x54, 0x1, 0x6, 0xe9, 0x16, 0x9f, 0x4f, 0xdc, 0x1c, 0x13, 0xed, 0xb1, 0x55, 0x31, 0x78, 0x70, 0x8e, 0xca, 0xcb, 0x8e, 0x6a, 0xbe, 0x56, 0x88, 0x67, 0x38, 0xdb, 0x75, 0x58, 0x76, 0xdf, 0x1b, 0x6c, 0x7a, 0xc, 0x6c, 0x90, 0x0, 0xfd, 0xe0, 0xe8, 0x98, 0xe4, 0x4, 0xe2, 0x69, 0xc, 0xe4, 0x40, 0xaa, 0xf9, 0x63, 0x70, 0xbb, 0x4, 0x16, 0x9c, 0x12, 0xa7, 0x3e, 0xe7, 0x38, 0xb3, 0x4, 0x2b, 0x6f, 0xc7, 0x23, 0xbb, 0xc3, 0x66, 0xdb, 0x38, 0x7, 0x0, 0xcf, 0x32, 0x34, 0xb6, 0x52, 0xb4, 0x3c, 0xf7, 0x35, 0x10, 0xd9, 0xf7, 0x6, 0x56, 0x93, 0x4, 0x4b, 0x0, 0x43, 0x28, 0xf9, 0x4a, 0x3d, 0x6e, 0xb0, 0x3e, 0x9, 0x31, 0xa9, 0x62, 0xd6, 0xc4, 0x36, 0x9c, 0xf2, 0xd9, 0xbd, 0x41, 0x2d, 0x24, 0x68, 0xc7, 0x1f, 0x62, 0x60, 0x6a, 0xc1, 0x7f, 0x95, 0x81, 0xaa, 0x13, 0x61, 0x9, 0xa6, 0xf6, 0x1c, 0x30, 0x17, 0x11, 0x6f, 0x48, 0x12, 0x3b, 0xf3, 0x7b, 0xc2, 0xeb, 0xca, 0x92, 0xb7, 0x72, 0x5f, 0x31, 0x90, 0x11, 0x4e, 0x48, 0xb3, 0x13, 0xa6, 0xcc, 0x3e, 0x51, 0x60, 0x91, 0x53, 0x55, 0x87, 0xf3, 0x2a, 0x98, 0xff, 0x7c, 0x6c, 0x1a, 0xf9, 0xec, 0xda, 0xeb, 0x94, 0x13, 0x43, 0xdd, 0x3f, 0x2a, 0x41, 0xd2, 0xb, 0x27, 0x65, 0xe8, 0x13, 0x20, 0x29, 0x3f, 0xc6, 0x7c, 0x48, 0x65, 0x8, 0x41, 0xda, 0xa4, 0xd5, 0x11, 0xc0, 0x2a, 0x61, 0xce, 0x18, 0x58, 0xd2, 0xbe, 0x98, 0x48, 0x96, 0xdd, 0xf5, 0xbc, 0x11, 0x65, 0xb6, 0x12, 0x55, 0xcb, 0xde, 0xb3, 0x78, 0x27, 0x78, 0xdc, 0xcb, 0x72, 0xe6, 0xd7, 0x8a, 0x27, 0xe6, 0x52, 0x1f, 0x10, 0xe0, 0xb8, 0x92, 0x81, 0xb4, 0x3f, 0x1, 0x1d, 0xed, 0x6c, 0xd4, 0xef, 0x12, 0x2f, 0x73, 0xa0, 0xe, 0xf, 0x42, 0x24, 0x20, 0xf, 0x91, 0xbf, 0x6e, 0x44, 0xfb, 0xde, 0xa1, 0x4, 0xa5, 0x7, 0xaa, 0xa0, 0x23, 0xad, 0xd4, 0x4b, 0xaa, 0x73, 0x0, 0xb7, 0xa1, 0x82, 0x87, 0x46, 0x74, 0x9a, 0xf, 0x48, 0x5d, 0xb3, 0xd, 0xa2, 0xb0, 0x96, 0xe5, 0x7d, 0xc8, 0x81, 0x19, 0xf1, 0x36, 0x2b, 0xba, 0xbd, 0x5e, 0xb3, 0xb7, 0x55, 0x12, 0x76, 0x90, 0xc4, 0x3a, 0x1, 0xa7, 0x66, 0xbc, 0x3, 0x90, 0xe0, 0x8, 0xc8, 0x42, 0x29, 0xa5, 0x7b, 0xa2, 0x63, 0x9f, 0x88, 0x26, 0xa, 0x9c, 0x85, 0x6f, 0x7b, 0x2b, 0x0, 0x92, 0x51, 0x4a, 0x81, 0x5c, 0x2a, 0xcb, 0x2a, 0x47, 0x0, 0xb0, 0x2b, 0x8, 0x11, 0x62, 0x20, 0x58, 0x20, 0x47, 0x77, 0x5a, 0xe5, 0x98, 0x43, 0x3f, 0x2, 0xd8, 0xc1, 0xa5, 0x39, 0x40, 0x82, 0xb5, 0xd9, 0xd7, 0x5a, 0x2, 0x59, 0x80, 0x9, 0x8a, 0x0, 0x7f, 0x1, 0x8, 0x44, 0x8, 0x64, 0xe0, 0xe8, 0x6e, 0x4b, 0xb4, 0x87, 0xa6, 0xc4, 0x3d, 0x17, 0x24, 0xa3, 0xa8, 0xc0, 0x32, 0x8a, 0xea, 0x33, 0x67, 0x0, 0x6e, 0xc, 0x94, 0x5e, 0xe2, 0x46, 0x11, 0x3a, 0x0, 0x82, 0x57, 0x1, 0x98, 0xbf, 0xb, 0xa4, 0xf6, 0x55, 0xd4, 0x2a, 0xe1, 0x0, 0x40, 0xf5, 0xf3, 0xa5, 0xd3, 0x16, 0x6a, 0xb4, 0xa7, 0x19, 0xfa, 0x4f, 0x18, 0xe8, 0x2c, 0x34, 0xfb, 0x92, 0x20, 0xbb, 0xf, 0xa3, 0x1d, 0xc0, 0xcd, 0xe7, 0xb7, 0x83, 0xf9, 0xf2, 0x24, 0xd3, 0xd7, 0xaf, 0x40, 0x9a, 0x84, 0x1, 0xf0, 0xfe, 0xf6, 0xee, 0x1d, 0x80, 0x4f, 0xff, 0xc8, 0xdf, 0x63, 0xeb, 0xfd, 0x6f, 0x3, 0x74, 0x35, 0xa7, 0x2a, 0xf0, 0x17, 0xed, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/default_theme/tree_bg_disabled.png b/scene/resources/default_theme/tree_bg_disabled.png
new file mode 100644
index 0000000000..a0fa505e4c
--- /dev/null
+++ b/scene/resources/default_theme/tree_bg_disabled.png
Binary files differ
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 48c6add586..a40417f24d 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -125,7 +125,7 @@ Error DynamicFontAtSize::_load() {
_fontdata[font->font_path] = Vector<uint8_t>();
Vector<uint8_t> &fontdata = _fontdata[font->font_path];
fontdata.resize(len);
- f->get_buffer(fontdata.ptr(), len);
+ f->get_buffer(fontdata.ptrw(), len);
font->set_font_ptr(fontdata.ptr(), len);
f->close();
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 286840656b..c8ab7c2a04 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -215,6 +215,13 @@ bool ShaderMaterial::_can_do_next_pass() const {
return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL;
}
+Shader::Mode ShaderMaterial::get_shader_mode() const {
+ if (shader.is_valid())
+ return shader->get_mode();
+ else
+ return Shader::MODE_SPATIAL;
+}
+
ShaderMaterial::ShaderMaterial() {
}
@@ -653,16 +660,16 @@ void SpatialMaterial::_update_shader() {
code += "\t\tvec2 P = view_dir.xy * depth_scale;\n";
code += "\t\tvec2 delta = P / num_layers;\n";
code += "\t\tvec2 ofs = base_uv;\n";
- code += "\t\tfloat depth = texture(texture_depth, ofs).r;\n";
+ code += "\t\tfloat depth = textureLod(texture_depth, ofs,0.0).r;\n";
code += "\t\tfloat current_depth = 0.0;\n";
code += "\t\twhile(current_depth < depth) {\n";
code += "\t\t\tofs -= delta;\n";
- code += "\t\t\tdepth = texture(texture_depth, ofs).r;\n";
+ code += "\t\t\tdepth = textureLod(texture_depth, ofs,0.0).r;\n";
code += "\t\t\tcurrent_depth += layer_depth;\n";
code += "\t\t}\n";
code += "\t\tvec2 prev_ofs = ofs + delta;\n";
code += "\t\tfloat after_depth = depth - current_depth;\n";
- code += "\t\tfloat before_depth = texture(texture_depth, prev_ofs).r - current_depth + layer_depth;\n";
+ code += "\t\tfloat before_depth = textureLod(texture_depth, prev_ofs, 0.0).r - current_depth + layer_depth;\n";
code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n";
code += "\t\tofs = mix(ofs,prev_ofs,weight);\n";
@@ -689,6 +696,10 @@ void SpatialMaterial::_update_shader() {
}
}
+ if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
+ code += "\talbedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
+ }
+
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
code += "\talbedo_tex *= COLOR;\n";
}
@@ -1658,6 +1669,11 @@ RID SpatialMaterial::get_shader_rid() const {
return shader_map[current_key].shader;
}
+Shader::Mode SpatialMaterial::get_shader_mode() const {
+
+ return Shader::MODE_SPATIAL;
+}
+
void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
@@ -1833,6 +1849,7 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR);
@@ -2019,6 +2036,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2);
BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR);
BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
+ BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
@@ -2048,8 +2066,8 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY);
}
-SpatialMaterial::SpatialMaterial()
- : element(this) {
+SpatialMaterial::SpatialMaterial() :
+ element(this) {
//initialize to right values
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 877d4dfd41..7cfa38fce4 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -69,6 +69,8 @@ public:
int get_render_priority() const;
virtual RID get_rid() const;
+
+ virtual Shader::Mode get_shader_mode() const = 0;
Material();
virtual ~Material();
};
@@ -96,6 +98,8 @@ public:
void set_shader_param(const StringName &p_param, const Variant &p_value);
Variant get_shader_param(const StringName &p_param) const;
+ virtual Shader::Mode get_shader_mode() const;
+
ShaderMaterial();
~ShaderMaterial();
};
@@ -181,6 +185,7 @@ public:
FLAG_TRIPLANAR_USE_WORLD,
FLAG_AO_ON_UV2,
FLAG_USE_ALPHA_SCISSOR,
+ FLAG_ALBEDO_TEXTURE_FORCE_SRGB,
FLAG_MAX
};
@@ -229,7 +234,7 @@ private:
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 12;
+ uint64_t flags : 13;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 2;
@@ -599,6 +604,8 @@ public:
RID get_shader_rid() const;
+ virtual Shader::Mode get_shader_mode() const;
+
SpatialMaterial();
virtual ~SpatialMaterial();
};
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 0a886c25b1..0b352efca2 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -28,10 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "mesh.h"
+
+#include "pair.h"
#include "scene/resources/concave_polygon_shape.h"
#include "scene/resources/convex_polygon_shape.h"
#include "surface_tool.h"
+#include <stdlib.h>
+
void Mesh::_clear_triangle_mesh() const {
triangle_mesh.unref();
@@ -413,8 +417,21 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
return newmesh;
}
+void Mesh::set_lightmap_size_hint(const Vector2 &p_size) {
+ lightmap_size_hint = p_size;
+}
+
+Size2 Mesh::get_lightmap_size_hint() const {
+ return lightmap_size_hint;
+}
+
void Mesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint);
+ ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint);
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
+
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
@@ -1035,6 +1052,200 @@ void ArrayMesh::regen_normalmaps() {
}
}
+//dirty hack
+bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = NULL;
+
+struct ArrayMeshLightmapSurface {
+
+ Ref<Material> material;
+ Vector<SurfaceTool::Vertex> vertices;
+ Mesh::PrimitiveType primitive;
+ uint32_t format;
+};
+
+Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {
+
+ ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
+ ERR_EXPLAIN("Can't unwrap mesh with blend shapes");
+ ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE);
+
+ Vector<float> vertices;
+ Vector<float> normals;
+ Vector<int> indices;
+ Vector<int> face_materials;
+ Vector<float> uv;
+ Vector<Pair<int, int> > uv_index;
+
+ Vector<ArrayMeshLightmapSurface> surfaces;
+ for (int i = 0; i < get_surface_count(); i++) {
+ ArrayMeshLightmapSurface s;
+ s.primitive = surface_get_primitive_type(i);
+
+ if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) {
+ ERR_EXPLAIN("Only triangles are supported for lightmap unwrap");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+ s.format = surface_get_format(i);
+ if (!(s.format & ARRAY_FORMAT_NORMAL)) {
+ ERR_EXPLAIN("Normals are required for lightmap unwrap");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+
+ Array arrays = surface_get_arrays(i);
+ s.material = surface_get_material(i);
+ s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays);
+
+ PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX];
+ int vc = rvertices.size();
+ PoolVector<Vector3>::Read r = rvertices.read();
+
+ PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL];
+ PoolVector<Vector3>::Read rn = rnormals.read();
+
+ int vertex_ofs = vertices.size() / 3;
+
+ vertices.resize((vertex_ofs + vc) * 3);
+ normals.resize((vertex_ofs + vc) * 3);
+ uv_index.resize(vertex_ofs + vc);
+
+ for (int j = 0; j < vc; j++) {
+
+ Vector3 v = p_base_transform.xform(r[j]);
+
+ vertices[(j + vertex_ofs) * 3 + 0] = v.x;
+ vertices[(j + vertex_ofs) * 3 + 1] = v.y;
+ vertices[(j + vertex_ofs) * 3 + 2] = v.z;
+ normals[(j + vertex_ofs) * 3 + 0] = rn[j].x;
+ normals[(j + vertex_ofs) * 3 + 1] = rn[j].y;
+ normals[(j + vertex_ofs) * 3 + 2] = rn[j].z;
+ uv_index[j + vertex_ofs] = Pair<int, int>(i, j);
+ }
+
+ PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX];
+ int ic = rindices.size();
+ int index_ofs = indices.size();
+
+ if (ic == 0) {
+ indices.resize(index_ofs + vc);
+ face_materials.resize((index_ofs + vc) / 3);
+ for (int j = 0; j < vc; j++) {
+ indices[index_ofs + j] = vertex_ofs + j;
+ }
+ for (int j = 0; j < vc / 3; j++) {
+ face_materials[(index_ofs / 3) + j] = i;
+ }
+
+ } else {
+ PoolVector<int>::Read ri = rindices.read();
+ indices.resize(index_ofs + ic);
+ face_materials.resize((index_ofs + ic) / 3);
+ for (int j = 0; j < ic; j++) {
+ indices[index_ofs + j] = vertex_ofs + ri[j];
+ }
+ for (int j = 0; j < ic / 3; j++) {
+ face_materials[(index_ofs / 3) + j] = i;
+ }
+ }
+
+ surfaces.push_back(s);
+ }
+
+ //unwrap
+
+ float *gen_uvs;
+ int *gen_vertices;
+ int *gen_indices;
+ int gen_vertex_count;
+ int gen_index_count;
+ int size_x;
+ int size_y;
+
+ bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);
+
+ if (!ok) {
+ return ERR_CANT_CREATE;
+ }
+
+ //remove surfaces
+ while (get_surface_count()) {
+ surface_remove(0);
+ }
+
+ //create surfacetools for each surface..
+ Vector<Ref<SurfaceTool> > surfaces_tools;
+
+ for (int i = 0; i < surfaces.size(); i++) {
+ Ref<SurfaceTool> st;
+ st.instance();
+ st->begin(Mesh::PRIMITIVE_TRIANGLES);
+ st->set_material(surfaces[i].material);
+ surfaces_tools.push_back(st); //stay there
+ }
+
+ print_line("gen indices: " + itos(gen_index_count));
+ //go through all indices
+ for (int i = 0; i < gen_index_count; i += 3) {
+
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG);
+
+ ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
+
+ int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first;
+
+ for (int j = 0; j < 3; j++) {
+
+ int vertex_idx = gen_vertices[gen_indices[i + j]];
+
+ SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];
+
+ if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
+ surfaces_tools[surface]->add_color(v.color);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
+ surfaces_tools[surface]->add_uv(v.uv);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
+ surfaces_tools[surface]->add_normal(v.normal);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
+ Plane t;
+ t.normal = v.tangent;
+ t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
+ surfaces_tools[surface]->add_tangent(t);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
+ surfaces_tools[surface]->add_bones(v.bones);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
+ surfaces_tools[surface]->add_weights(v.weights);
+ }
+
+ Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
+ surfaces_tools[surface]->add_uv2(uv2);
+
+ surfaces_tools[surface]->add_vertex(v.vertex);
+ }
+ }
+
+ //free stuff
+ ::free(gen_vertices);
+ ::free(gen_indices);
+ ::free(gen_uvs);
+
+ //generate surfaces
+
+ for (int i = 0; i < surfaces_tools.size(); i++) {
+ surfaces_tools[i]->index();
+ surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
+ }
+
+ set_lightmap_size_hint(Size2(size_x, size_y));
+
+ return OK;
+}
+
void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index b85a6a84af..ea38ebf2ff 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -43,6 +43,8 @@ class Mesh : public Resource {
GDCLASS(Mesh, Resource);
mutable Ref<TriangleMesh> triangle_mesh; //cached
+ Size2 lightmap_size_hint;
+
protected:
void _clear_triangle_mesh() const;
@@ -138,6 +140,9 @@ public:
virtual AABB get_aabb() const = 0;
+ void set_lightmap_size_hint(const Vector2 &p_size);
+ Size2 get_lightmap_size_hint() const;
+
Mesh();
};
@@ -216,6 +221,8 @@ public:
void center_geometry();
void regen_normalmaps();
+ Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
+
virtual void reload_from_file();
ArrayMesh();
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 5d6f44dfef..3a5cb7da2e 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -177,7 +177,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node = Object::cast_to<Node>(obj);
} else {
- print_line("wtf class is disabled for: " + itos(n.type));
+ print_line("Class is disabled for: " + itos(n.type));
print_line("name: " + String(snames[n.type]));
}
@@ -232,11 +232,11 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
Node *base = i == 0 ? node : ret_nodes[0];
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
-
- res->local_scene = base;
- resources_local_to_scene[res] = res;
+ //for the main scene, use the resource as is
+ res->configure_for_local_scene(base, resources_local_to_scene);
} else {
+ //for instances, a copy must be made
Node *base = i == 0 ? node : ret_nodes[0];
Ref<Resource> local_dupe = res->duplicate_for_local_scene(base, resources_local_to_scene);
resources_local_to_scene[res] = local_dupe;
diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp
index 2b1e890a5d..2eb2ceff24 100644
--- a/scene/resources/plane_shape.cpp
+++ b/scene/resources/plane_shape.cpp
@@ -86,8 +86,8 @@ void PlaneShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane");
}
-PlaneShape::PlaneShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {
+PlaneShape::PlaneShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {
set_plane(Plane(0, 1, 0, 0));
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 3b80db291c..2e8f9cbb33 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -164,7 +164,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh_arrays"), &PrimitiveMesh::get_mesh_arrays);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
}
void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp
index ccce7660c6..b03a81b6bd 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape.cpp
@@ -66,8 +66,8 @@ void RayShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length");
}
-RayShape::RayShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
+RayShape::RayShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
set_length(1.0);
}
diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 69dbb76744..202024aa96 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -66,8 +66,8 @@ void RectangleShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "extents"), "set_extents", "get_extents");
}
-RectangleShape2D::RectangleShape2D()
- : Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) {
+RectangleShape2D::RectangleShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) {
extents = Vector2(10, 10);
_update_shape();
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 7c7ec0d112..e8ef448e23 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -86,8 +86,8 @@ void SegmentShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "b"), "set_b", "get_b");
}
-SegmentShape2D::SegmentShape2D()
- : Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) {
+SegmentShape2D::SegmentShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) {
a = Vector2();
b = Vector2(0, 10);
@@ -145,8 +145,8 @@ real_t RayShape2D::get_length() const {
return length;
}
-RayShape2D::RayShape2D()
- : Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) {
+RayShape2D::RayShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) {
length = 20;
_update_shape();
diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/shape_line_2d.cpp
index d046ce876c..512ff3bc56 100644
--- a/scene/resources/shape_line_2d.cpp
+++ b/scene/resources/shape_line_2d.cpp
@@ -95,8 +95,8 @@ void LineShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "d"), "set_d", "get_d");
}
-LineShape2D::LineShape2D()
- : Shape2D(Physics2DServer::get_singleton()->line_shape_create()) {
+LineShape2D::LineShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->line_shape_create()) {
normal = Vector2(0, -1);
d = 0;
diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp
index 00203c2b4b..042988dcd3 100644
--- a/scene/resources/sphere_shape.cpp
+++ b/scene/resources/sphere_shape.cpp
@@ -80,8 +80,8 @@ void SphereShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius");
}
-SphereShape::SphereShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) {
+SphereShape::SphereShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) {
set_radius(1.0);
}
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index bf89e704bc..d8600e041d 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -101,6 +101,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
vtx.color = last_color;
vtx.normal = last_normal;
vtx.uv = last_uv;
+ vtx.uv2 = last_uv2;
vtx.weights = last_weights;
vtx.bones = last_bones;
vtx.tangent = last_tangent.normal;
@@ -401,7 +402,7 @@ Array SurfaceTool::commit_to_arrays() {
return a;
}
-Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
+Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_flags) {
Ref<ArrayMesh> mesh;
if (p_existing.is_valid())
@@ -418,7 +419,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
Array a = commit_to_arrays();
- mesh->add_surface_from_arrays(primitive, a);
+ mesh->add_surface_from_arrays(primitive, a, Array(), p_flags);
if (material.is_valid())
mesh->surface_set_material(surface, material);
@@ -482,6 +483,113 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
+Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) {
+
+ Vector<SurfaceTool::Vertex> ret;
+
+ PoolVector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX];
+ PoolVector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL];
+ PoolVector<float> tarr = p_arrays[VS::ARRAY_TANGENT];
+ PoolVector<Color> carr = p_arrays[VS::ARRAY_COLOR];
+ PoolVector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV];
+ PoolVector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2];
+ PoolVector<int> barr = p_arrays[VS::ARRAY_BONES];
+ PoolVector<float> warr = p_arrays[VS::ARRAY_WEIGHTS];
+
+ int vc = varr.size();
+
+ if (vc == 0)
+ return ret;
+ int lformat = 0;
+
+ PoolVector<Vector3>::Read rv;
+ if (varr.size()) {
+ lformat |= VS::ARRAY_FORMAT_VERTEX;
+ rv = varr.read();
+ }
+ PoolVector<Vector3>::Read rn;
+ if (narr.size()) {
+ lformat |= VS::ARRAY_FORMAT_NORMAL;
+ rn = narr.read();
+ }
+ PoolVector<float>::Read rt;
+ if (tarr.size()) {
+ lformat |= VS::ARRAY_FORMAT_TANGENT;
+ rt = tarr.read();
+ }
+ PoolVector<Color>::Read rc;
+ if (carr.size()) {
+ lformat |= VS::ARRAY_FORMAT_COLOR;
+ rc = carr.read();
+ }
+
+ PoolVector<Vector2>::Read ruv;
+ if (uvarr.size()) {
+ lformat |= VS::ARRAY_FORMAT_TEX_UV;
+ ruv = uvarr.read();
+ }
+
+ PoolVector<Vector2>::Read ruv2;
+ if (uv2arr.size()) {
+ lformat |= VS::ARRAY_FORMAT_TEX_UV2;
+ ruv2 = uv2arr.read();
+ }
+
+ PoolVector<int>::Read rb;
+ if (barr.size()) {
+ lformat |= VS::ARRAY_FORMAT_BONES;
+ rb = barr.read();
+ }
+
+ PoolVector<float>::Read rw;
+ if (warr.size()) {
+ lformat |= VS::ARRAY_FORMAT_WEIGHTS;
+ rw = warr.read();
+ }
+
+ for (int i = 0; i < vc; i++) {
+
+ Vertex v;
+ if (lformat & VS::ARRAY_FORMAT_VERTEX)
+ v.vertex = varr[i];
+ if (lformat & VS::ARRAY_FORMAT_NORMAL)
+ v.normal = narr[i];
+ if (lformat & VS::ARRAY_FORMAT_TANGENT) {
+ Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
+ v.tangent = p.normal;
+ v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
+ }
+ if (lformat & VS::ARRAY_FORMAT_COLOR)
+ v.color = carr[i];
+ if (lformat & VS::ARRAY_FORMAT_TEX_UV)
+ v.uv = uvarr[i];
+ if (lformat & VS::ARRAY_FORMAT_TEX_UV2)
+ v.uv2 = uv2arr[i];
+ if (lformat & VS::ARRAY_FORMAT_BONES) {
+ Vector<int> b;
+ b.resize(4);
+ b[0] = barr[i * 4 + 0];
+ b[1] = barr[i * 4 + 1];
+ b[2] = barr[i * 4 + 2];
+ b[3] = barr[i * 4 + 3];
+ v.bones = b;
+ }
+ if (lformat & VS::ARRAY_FORMAT_WEIGHTS) {
+ Vector<float> w;
+ w.resize(4);
+ w[0] = warr[i * 4 + 0];
+ w[1] = warr[i * 4 + 1];
+ w[2] = warr[i * 4 + 2];
+ w[3] = warr[i * 4 + 3];
+ v.weights = w;
+ }
+
+ ret.push_back(v);
+ }
+
+ return ret;
+}
+
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX];
@@ -882,7 +990,7 @@ void SurfaceTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from);
ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from);
- ClassDB::bind_method(D_METHOD("commit", "existing"), &SurfaceTool::commit, DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT));
}
SurfaceTool::SurfaceTool() {
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index cdaac643de..b180ffe260 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -127,10 +127,11 @@ public:
List<Vertex> &get_vertex_array() { return vertex_array; }
void create_from_triangle_arrays(const Array &p_arrays);
+ static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays);
Array commit_to_arrays();
void create_from(const Ref<Mesh> &p_existing, int p_surface);
void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform);
- Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>());
+ Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT);
SurfaceTool();
};
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 162edd0d1c..987d6c5f6a 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1601,3 +1601,72 @@ int GradientTexture::get_width() const {
Ref<Image> GradientTexture::get_data() const {
return VisualServer::get_singleton()->texture_get_data(texture);
}
+
+//////////////////////////////////////
+
+void ProxyTexture::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base);
+ ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base", "get_base");
+}
+
+void ProxyTexture::set_base(const Ref<Texture> &p_texture) {
+
+ base = p_texture;
+ if (base.is_valid()) {
+ VS::get_singleton()->texture_set_proxy(proxy, base->get_rid());
+ } else {
+ VS::get_singleton()->texture_set_proxy(proxy, RID());
+ }
+}
+
+Ref<Texture> ProxyTexture::get_base() const {
+
+ return base;
+}
+
+int ProxyTexture::get_width() const {
+
+ if (base.is_valid())
+ return base->get_width();
+ return 1;
+}
+int ProxyTexture::get_height() const {
+
+ if (base.is_valid())
+ return base->get_height();
+ return 1;
+}
+RID ProxyTexture::get_rid() const {
+
+ return proxy;
+}
+
+bool ProxyTexture::has_alpha() const {
+
+ if (base.is_valid())
+ return base->has_alpha();
+ return false;
+}
+
+void ProxyTexture::set_flags(uint32_t p_flags) {
+}
+
+uint32_t ProxyTexture::get_flags() const {
+
+ if (base.is_valid())
+ return base->get_flags();
+ return 0;
+}
+
+ProxyTexture::ProxyTexture() {
+
+ proxy = VS::get_singleton()->texture_create();
+}
+
+ProxyTexture::~ProxyTexture() {
+
+ VS::get_singleton()->free(proxy);
+}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index ee54156647..76c0195ef9 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -493,4 +493,31 @@ public:
virtual ~GradientTexture();
};
+class ProxyTexture : public Texture {
+ GDCLASS(ProxyTexture, Texture)
+
+private:
+ RID proxy;
+ Ref<Texture> base;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_base(const Ref<Texture> &p_texture);
+ Ref<Texture> get_base() const;
+
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual RID get_rid() const;
+
+ virtual bool has_alpha() const;
+
+ virtual void set_flags(uint32_t p_flags);
+ virtual uint32_t get_flags() const;
+
+ ProxyTexture();
+ ~ProxyTexture();
+};
+
#endif
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 29ac7852bf..1a46353fe3 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "tile_set.h"
+#include "array.h"
bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
@@ -55,7 +56,74 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
tile_set_modulate(id, p_value);
else if (what == "region")
tile_set_region(id, p_value);
- else if (what == "shape")
+ else if (what == "is_autotile")
+ tile_set_is_autotile(id, p_value);
+ else if (what.left(9) == "autotile/") {
+ what = what.right(9);
+ if (what == "bitmask_mode")
+ autotile_set_bitmask_mode(id, (BitmaskMode)((int)p_value));
+ else if (what == "icon_coordinate")
+ autotile_set_icon_coordinate(id, p_value);
+ else if (what == "tile_size")
+ autotile_set_size(id, p_value);
+ else if (what == "spacing")
+ autotile_set_spacing(id, p_value);
+ else if (what == "bitmask_flags") {
+ tile_map[id].autotile_data.flags.clear();
+ if (p_value.is_array()) {
+ Array p = p_value;
+ Vector2 last_coord;
+ while (p.size() > 0) {
+ if (p[0].get_type() == Variant::VECTOR2) {
+ last_coord = p[0];
+ } else if (p[0].get_type() == Variant::INT) {
+ autotile_set_bitmask(id, last_coord, p[0]);
+ }
+ p.pop_front();
+ }
+ }
+ } else if (what == "occluder_map") {
+ tile_map[id].autotile_data.occluder_map.clear();
+ Array p = p_value;
+ Vector2 last_coord;
+ while (p.size() > 0) {
+ if (p[0].get_type() == Variant::VECTOR2) {
+ last_coord = p[0];
+ } else if (p[0].get_type() == Variant::OBJECT) {
+ autotile_set_light_occluder(id, p[0], last_coord);
+ }
+ p.pop_front();
+ }
+ } else if (what == "navpoly_map") {
+ tile_map[id].autotile_data.navpoly_map.clear();
+ Array p = p_value;
+ Vector2 last_coord;
+ while (p.size() > 0) {
+ if (p[0].get_type() == Variant::VECTOR2) {
+ last_coord = p[0];
+ } else if (p[0].get_type() == Variant::OBJECT) {
+ autotile_set_navigation_polygon(id, p[0], last_coord);
+ }
+ p.pop_front();
+ }
+ } else if (what == "priority_map") {
+ tile_map[id].autotile_data.priority_map.clear();
+ Array p = p_value;
+ Vector3 val;
+ Vector2 v;
+ int priority;
+ while (p.size() > 0) {
+ val = p[0];
+ if (val.z > 1) {
+ v.x = val.x;
+ v.y = val.y;
+ priority = (int)val.z;
+ tile_map[id].autotile_data.priority_map[v] = priority;
+ }
+ p.pop_front();
+ }
+ }
+ } else if (what == "shape")
tile_set_shape(id, 0, p_value);
else if (what == "shape_offset")
tile_set_shape_offset(id, 0, p_value);
@@ -105,7 +173,54 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = tile_get_modulate(id);
else if (what == "region")
r_ret = tile_get_region(id);
- else if (what == "shape")
+ else if (what == "is_autotile")
+ r_ret = tile_get_is_autotile(id);
+ else if (what.left(9) == "autotile/") {
+ what = what.right(9);
+ if (what == "bitmask_mode")
+ r_ret = autotile_get_bitmask_mode(id);
+ else if (what == "icon_coordinate")
+ r_ret = autotile_get_icon_coordinate(id);
+ else if (what == "tile_size")
+ r_ret = autotile_get_size(id);
+ else if (what == "spacing")
+ r_ret = autotile_get_spacing(id);
+ else if (what == "bitmask_flags") {
+ Array p;
+ for (Map<Vector2, uint16_t>::Element *E = tile_map[id].autotile_data.flags.front(); E; E = E->next()) {
+ p.push_back(E->key());
+ p.push_back(E->value());
+ }
+ r_ret = p;
+ } else if (what == "occluder_map") {
+ Array p;
+ for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) {
+ p.push_back(E->key());
+ p.push_back(E->value());
+ }
+ r_ret = p;
+ } else if (what == "navpoly_map") {
+ Array p;
+ for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = tile_map[id].autotile_data.navpoly_map.front(); E; E = E->next()) {
+ p.push_back(E->key());
+ p.push_back(E->value());
+ }
+ r_ret = p;
+ } else if (what == "priority_map") {
+ Array p;
+ Vector3 v;
+ for (Map<Vector2, int>::Element *E = tile_map[id].autotile_data.priority_map.front(); E; E = E->next()) {
+ if (E->value() > 1) {
+ //Dont save default value
+ v.x = E->key().x;
+ v.y = E->key().y;
+ v.z = E->value();
+ p.push_back(v);
+ }
+ }
+ r_ret = p;
+ }
+ } else if (what == "shape")
r_ret = tile_get_shape(id, 0);
else if (what == "shape_offset")
r_ret = tile_get_shape_offset(id, 0);
@@ -142,6 +257,17 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"));
p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate"));
p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region"));
+ p_list->push_back(PropertyInfo(Variant::BOOL, pre + "is_autotile", PROPERTY_HINT_NONE, ""));
+ if (tile_get_is_autotile(id)) {
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/icon_coordinate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/spacing", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ }
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset"));
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "navigation_offset"));
@@ -158,10 +284,25 @@ void TileSet::create_tile(int p_id) {
ERR_FAIL_COND(tile_map.has(p_id));
tile_map[p_id] = TileData();
+ tile_map[p_id].autotile_data = AutotileData();
+ _change_notify("");
+ emit_changed();
+}
+
+void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ tile_map[p_id].autotile_data.bitmask_mode = p_mode;
_change_notify("");
emit_changed();
}
+TileSet::BitmaskMode TileSet::autotile_get_bitmask_mode(int p_id) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), BITMASK_2X2);
+ return tile_map[p_id].autotile_data.bitmask_mode;
+}
+
void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -240,6 +381,152 @@ Rect2 TileSet::tile_get_region(int p_id) const {
return tile_map[p_id].region;
}
+void TileSet::tile_set_is_autotile(int p_id, bool p_is_autotile) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ tile_map[p_id].is_autotile = p_is_autotile;
+ _change_notify("");
+ emit_changed();
+}
+
+bool TileSet::tile_get_is_autotile(int p_id) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), false);
+ return tile_map[p_id].is_autotile;
+}
+
+void TileSet::autotile_set_icon_coordinate(int p_id, Vector2 coord) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ tile_map[p_id].autotile_data.icon_coord = coord;
+ emit_changed();
+}
+
+Vector2 TileSet::autotile_get_icon_coordinate(int p_id) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
+ return tile_map[p_id].autotile_data.icon_coord;
+}
+
+void TileSet::autotile_set_spacing(int p_id, int p_spacing) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ ERR_FAIL_COND(p_spacing < 0);
+ tile_map[p_id].autotile_data.spacing = p_spacing;
+ emit_changed();
+}
+
+int TileSet::autotile_get_spacing(int p_id) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
+ return tile_map[p_id].autotile_data.spacing;
+}
+
+void TileSet::autotile_set_size(int p_id, Size2 p_size) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ ERR_FAIL_COND(p_size.x <= 0 || p_size.y <= 0);
+ tile_map[p_id].autotile_data.size = p_size;
+}
+
+Size2 TileSet::autotile_get_size(int p_id) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Size2());
+ return tile_map[p_id].autotile_data.size;
+}
+
+void TileSet::autotile_clear_bitmask_map(int p_id) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ tile_map[p_id].autotile_data.flags.clear();
+}
+
+void TileSet::autotile_set_subtile_priority(int p_id, const Vector2 &p_coord, int p_priority) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ ERR_FAIL_COND(p_priority <= 0);
+ tile_map[p_id].autotile_data.priority_map[p_coord] = p_priority;
+}
+
+int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), 1);
+ if (tile_map[p_id].autotile_data.priority_map.has(p_coord)) {
+ return tile_map[p_id].autotile_data.priority_map[p_coord];
+ }
+ //When not custom priority set return the default value
+ return 1;
+}
+
+const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
+
+ static Map<Vector2, int> dummy;
+ ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
+ return tile_map[p_id].autotile_data.priority_map;
+}
+
+void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ if (p_flag == 0) {
+ if (tile_map[p_id].autotile_data.flags.has(p_coord))
+ tile_map[p_id].autotile_data.flags.erase(p_coord);
+ } else {
+ tile_map[p_id].autotile_data.flags[p_coord] = p_flag;
+ }
+}
+
+uint16_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
+ if (!tile_map[p_id].autotile_data.flags.has(p_coord)) {
+ return 0;
+ }
+ return tile_map[p_id].autotile_data.flags[p_coord];
+}
+
+const Map<Vector2, uint16_t> &TileSet::autotile_get_bitmask_map(int p_id) {
+
+ static Map<Vector2, uint16_t> dummy;
+ ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
+ return tile_map[p_id].autotile_data.flags;
+}
+
+Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node, const Vector2 &p_tile_location) {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
+ //First try to forward selection to script
+ if (p_tilemap_node->get_class_name() == "TileMap") {
+ if (get_script_instance() != NULL) {
+ if (get_script_instance()->has_method("_forward_subtile_selection")) {
+ Variant ret = get_script_instance()->call("_forward_subtile_selection", p_id, p_bitmask, p_tilemap_node, p_tile_location);
+ if (ret.get_type() == Variant::VECTOR2) {
+ return ret;
+ }
+ }
+ }
+ }
+
+ List<Vector2> coords;
+ uint16_t mask;
+ for (Map<Vector2, uint16_t>::Element *E = tile_map[p_id].autotile_data.flags.front(); E; E = E->next()) {
+ mask = E->get();
+ if (tile_map[p_id].autotile_data.bitmask_mode == BITMASK_2X2) {
+ mask &= (BIND_BOTTOMLEFT | BIND_BOTTOMRIGHT | BIND_TOPLEFT | BIND_TOPRIGHT);
+ }
+ if (mask == p_bitmask) {
+ for (int i = 0; i < autotile_get_subtile_priority(p_id, E->key()); i++) {
+ coords.push_back(E->key());
+ }
+ }
+ }
+ if (coords.size() == 0) {
+ return autotile_get_icon_coordinate(p_id);
+ } else {
+ return coords[Math::random(0, (int)coords.size())];
+ }
+}
+
void TileSet::tile_set_name(int p_id, const String &p_name) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -257,7 +544,7 @@ void TileSet::tile_clear_shapes(int p_id) {
tile_map[p_id].shapes_data.clear();
}
-void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way) {
+void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way, const Vector2 &p_autotile_coord) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -265,15 +552,17 @@ void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transf
new_data.shape = p_shape;
new_data.shape_transform = p_transform;
new_data.one_way_collision = p_one_way;
+ new_data.autotile_coord = p_autotile_coord;
tile_map[p_id].shapes_data.push_back(new_data);
-};
+}
+
int TileSet::tile_get_shape_count(int p_id) const {
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].shapes_data.size();
-};
+}
void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape) {
@@ -351,6 +640,26 @@ Ref<OccluderPolygon2D> TileSet::tile_get_light_occluder(int p_id) const {
return tile_map[p_id].occluder;
}
+void TileSet::autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord) {
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ if (p_light_occluder.is_null()) {
+ if (tile_map[p_id].autotile_data.occluder_map.has(p_coord)) {
+ tile_map[p_id].autotile_data.occluder_map.erase(p_coord);
+ }
+ } else {
+ tile_map[p_id].autotile_data.occluder_map[p_coord] = p_light_occluder;
+ }
+}
+
+Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const {
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>());
+ if (!tile_map[p_id].autotile_data.occluder_map.has(p_coord)) {
+ return Ref<OccluderPolygon2D>();
+ } else {
+ return tile_map[p_id].autotile_data.occluder_map[p_coord];
+ }
+}
+
void TileSet::tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -358,6 +667,7 @@ void TileSet::tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offs
}
Vector2 TileSet::tile_get_navigation_polygon_offset(int p_id) const {
+
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].navigation_polygon_offset;
}
@@ -374,6 +684,42 @@ Ref<NavigationPolygon> TileSet::tile_get_navigation_polygon(int p_id) const {
return tile_map[p_id].navigation_polygon;
}
+const Map<Vector2, Ref<OccluderPolygon2D> > &TileSet::autotile_get_light_oclusion_map(int p_id) const {
+
+ static Map<Vector2, Ref<OccluderPolygon2D> > dummy;
+ ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
+ return tile_map[p_id].autotile_data.occluder_map;
+}
+
+void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ if (p_navigation_polygon.is_null()) {
+ if (tile_map[p_id].autotile_data.navpoly_map.has(p_coord)) {
+ tile_map[p_id].autotile_data.navpoly_map.erase(p_coord);
+ }
+ } else {
+ tile_map[p_id].autotile_data.navpoly_map[p_coord] = p_navigation_polygon;
+ }
+}
+
+Ref<NavigationPolygon> TileSet::autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<NavigationPolygon>());
+ if (!tile_map[p_id].autotile_data.navpoly_map.has(p_coord)) {
+ return Ref<NavigationPolygon>();
+ } else {
+ return tile_map[p_id].autotile_data.navpoly_map[p_coord];
+ }
+}
+
+const Map<Vector2, Ref<NavigationPolygon> > &TileSet::autotile_get_navigation_map(int p_id) const {
+
+ static Map<Vector2, Ref<NavigationPolygon> > dummy;
+ ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
+ return tile_map[p_id].autotile_data.navpoly_map;
+}
+
void TileSet::tile_set_occluder_offset(int p_id, const Vector2 &p_offset) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -381,6 +727,7 @@ void TileSet::tile_set_occluder_offset(int p_id, const Vector2 &p_offset) {
}
Vector2 TileSet::tile_get_occluder_offset(int p_id) const {
+
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].occluder_offset;
}
@@ -405,6 +752,7 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
Vector<ShapeData> shapes_data;
Transform2D default_transform = tile_get_shape_transform(p_id, 0);
bool default_one_way = tile_get_shape_one_way(p_id, 0);
+ Vector2 default_autotile_coord = Vector2();
for (int i = 0; i < p_shapes.size(); i++) {
ShapeData s = ShapeData();
@@ -415,6 +763,7 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
s.shape = shape;
s.shape_transform = default_transform;
s.one_way_collision = default_one_way;
+ s.autotile_coord = default_autotile_coord;
} else if (p_shapes[i].get_type() == Variant::DICTIONARY) {
Dictionary d = p_shapes[i];
@@ -435,6 +784,11 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
else
s.one_way_collision = default_one_way;
+ if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2)
+ s.autotile_coord = d["autotile_coord"];
+ else
+ s.autotile_coord = default_autotile_coord;
+
} else {
ERR_EXPLAIN("Expected an array of objects or dictionaries for tile_set_shapes");
ERR_CONTINUE(true);
@@ -457,6 +811,7 @@ Array TileSet::_tile_get_shapes(int p_id) const {
shape_data["shape"] = data[i].shape;
shape_data["shape_transform"] = data[i].shape_transform;
shape_data["one_way"] = data[i].one_way_collision;
+ shape_data["autotile_coord"] = data[i].autotile_coord;
arr.push_back(shape_data);
}
@@ -487,6 +842,21 @@ bool TileSet::has_tile(int p_id) const {
return tile_map.has(p_id);
}
+bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) {
+
+ if (p_drawn_id == p_neighbor_id) {
+ return true;
+ } else if (get_script_instance() != NULL) {
+ if (get_script_instance()->has_method("_is_tile_bound")) {
+ Variant ret = get_script_instance()->call("_is_tile_bound", p_drawn_id, p_neighbor_id);
+ if (ret.get_type() == Variant::BOOL) {
+ return ret;
+ }
+ }
+ }
+ return false;
+}
+
void TileSet::remove_tile(int p_id) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -523,6 +893,8 @@ void TileSet::clear() {
void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile);
+ ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "mode"), &TileSet::autotile_set_bitmask_mode);
+ ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode"), &TileSet::autotile_get_bitmask_mode);
ClassDB::bind_method(D_METHOD("tile_set_name", "id", "name"), &TileSet::tile_set_name);
ClassDB::bind_method(D_METHOD("tile_get_name", "id"), &TileSet::tile_get_name);
ClassDB::bind_method(D_METHOD("tile_set_texture", "id", "texture"), &TileSet::tile_set_texture);
@@ -541,7 +913,7 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("tile_get_shape_transform", "id", "shape_id"), &TileSet::tile_get_shape_transform);
ClassDB::bind_method(D_METHOD("tile_set_shape_one_way", "id", "shape_id", "one_way"), &TileSet::tile_set_shape_one_way);
ClassDB::bind_method(D_METHOD("tile_get_shape_one_way", "id", "shape_id"), &TileSet::tile_get_shape_one_way);
- ClassDB::bind_method(D_METHOD("tile_add_shape", "id", "shape", "shape_transform", "one_way"), &TileSet::tile_add_shape, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("tile_add_shape", "id", "shape", "shape_transform", "one_way", "autotile_coord"), &TileSet::tile_add_shape, DEFVAL(false), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("tile_get_shape_count", "id"), &TileSet::tile_get_shape_count);
ClassDB::bind_method(D_METHOD("tile_set_shapes", "id", "shapes"), &TileSet::_tile_set_shapes);
ClassDB::bind_method(D_METHOD("tile_get_shapes", "id"), &TileSet::_tile_get_shapes);
@@ -559,6 +931,21 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_last_unused_tile_id"), &TileSet::get_last_unused_tile_id);
ClassDB::bind_method(D_METHOD("find_tile_by_name", "name"), &TileSet::find_tile_by_name);
ClassDB::bind_method(D_METHOD("get_tiles_ids"), &TileSet::_get_tiles_ids);
+
+ BIND_VMETHOD(MethodInfo("_is_tile_bound", PropertyInfo(Variant::INT, "drawn_id"), PropertyInfo(Variant::INT, "neighbor_id")));
+ BIND_VMETHOD(MethodInfo("_forward_subtile_selection", PropertyInfo(Variant::INT, "autotile_id"), PropertyInfo(Variant::INT, "bitmask"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location")));
+
+ BIND_ENUM_CONSTANT(BITMASK_2X2);
+ BIND_ENUM_CONSTANT(BITMASK_3X3);
+
+ BIND_ENUM_CONSTANT(BIND_TOPLEFT);
+ BIND_ENUM_CONSTANT(BIND_TOP);
+ BIND_ENUM_CONSTANT(BIND_TOPRIGHT);
+ BIND_ENUM_CONSTANT(BIND_LEFT);
+ BIND_ENUM_CONSTANT(BIND_RIGHT);
+ BIND_ENUM_CONSTANT(BIND_BOTTOMLEFT);
+ BIND_ENUM_CONSTANT(BIND_BOTTOM);
+ BIND_ENUM_CONSTANT(BIND_BOTTOMRIGHT);
}
TileSet::TileSet() {
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 3ef3f00cef..deac583f62 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -30,6 +30,7 @@
#ifndef TILE_SET_H
#define TILE_SET_H
+#include "core/array.h"
#include "resource.h"
#include "scene/2d/light_occluder_2d.h"
#include "scene/2d/navigation_polygon.h"
@@ -44,6 +45,7 @@ public:
struct ShapeData {
Ref<Shape2D> shape;
Transform2D shape_transform;
+ Vector2 autotile_coord;
bool one_way_collision;
ShapeData() {
@@ -51,6 +53,41 @@ public:
}
};
+ enum BitmaskMode {
+ BITMASK_2X2,
+ BITMASK_3X3
+ };
+
+ enum AutotileBindings {
+ BIND_TOPLEFT = 1,
+ BIND_TOP = 2,
+ BIND_TOPRIGHT = 4,
+ BIND_LEFT = 8,
+ BIND_CENTER = 16,
+ BIND_RIGHT = 32,
+ BIND_BOTTOMLEFT = 64,
+ BIND_BOTTOM = 128,
+ BIND_BOTTOMRIGHT = 256
+ };
+
+ struct AutotileData {
+ BitmaskMode bitmask_mode;
+ int spacing;
+ Size2 size;
+ Vector2 icon_coord;
+ Map<Vector2, uint16_t> flags;
+ Map<Vector2, Ref<OccluderPolygon2D> > occluder_map;
+ Map<Vector2, Ref<NavigationPolygon> > navpoly_map;
+ Map<Vector2, int> priority_map;
+
+ // Default size to prevent invalid value
+ explicit AutotileData() :
+ size(64, 64),
+ icon_coord(0, 0) {
+ bitmask_mode = BITMASK_2X2;
+ }
+ };
+
private:
struct TileData {
@@ -66,10 +103,13 @@ private:
Ref<NavigationPolygon> navigation_polygon;
Ref<ShaderMaterial> material;
Color modulate;
+ bool is_autotile;
+ AutotileData autotile_data;
// Default modulate for back-compat
- explicit TileData()
- : modulate(1, 1, 1) {}
+ explicit TileData() :
+ modulate(1, 1, 1),
+ is_autotile(false) {}
};
Map<int, TileData> tile_map;
@@ -87,6 +127,9 @@ protected:
public:
void create_tile(int p_id);
+ void autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode);
+ BitmaskMode autotile_get_bitmask_mode(int p_id) const;
+
void tile_set_name(int p_id, const String &p_name);
String tile_get_name(int p_id) const;
@@ -102,6 +145,28 @@ public:
void tile_set_region(int p_id, const Rect2 &p_region);
Rect2 tile_get_region(int p_id) const;
+ void tile_set_is_autotile(int p_id, bool p_is_autotile);
+ bool tile_get_is_autotile(int p_id) const;
+
+ void autotile_set_icon_coordinate(int p_id, Vector2 coord);
+ Vector2 autotile_get_icon_coordinate(int p_id) const;
+
+ void autotile_set_spacing(int p_id, int p_spacing);
+ int autotile_get_spacing(int p_id) const;
+
+ void autotile_set_size(int p_id, Size2 p_size);
+ Size2 autotile_get_size(int p_id) const;
+
+ void autotile_clear_bitmask_map(int p_id);
+ void autotile_set_subtile_priority(int p_id, const Vector2 &p_coord, int p_priority);
+ int autotile_get_subtile_priority(int p_id, const Vector2 &p_coord);
+ const Map<Vector2, int> &autotile_get_priority_map(int p_id) const;
+
+ void autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag);
+ uint16_t autotile_get_bitmask(int p_id, Vector2 p_coord);
+ const Map<Vector2, uint16_t> &autotile_get_bitmask_map(int p_id);
+ Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2());
+
void tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape);
Ref<Shape2D> tile_get_shape(int p_id, int p_shape_id) const;
@@ -115,7 +180,7 @@ public:
bool tile_get_shape_one_way(int p_id, int p_shape_id) const;
void tile_clear_shapes(int p_id);
- void tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way = false);
+ void tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way = false, const Vector2 &p_autotile_coord = Vector2());
int tile_get_shape_count(int p_id) const;
void tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes);
@@ -133,16 +198,26 @@ public:
void tile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder);
Ref<OccluderPolygon2D> tile_get_light_occluder(int p_id) const;
+ void autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord);
+ Ref<OccluderPolygon2D> autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const;
+ const Map<Vector2, Ref<OccluderPolygon2D> > &autotile_get_light_oclusion_map(int p_id) const;
+
void tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_navigation_polygon_offset(int p_id) const;
void tile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon);
Ref<NavigationPolygon> tile_get_navigation_polygon(int p_id) const;
+ void autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord);
+ Ref<NavigationPolygon> autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const;
+ const Map<Vector2, Ref<NavigationPolygon> > &autotile_get_navigation_map(int p_id) const;
+
void remove_tile(int p_id);
bool has_tile(int p_id) const;
+ bool is_tile_bound(int p_drawn_id, int p_neighbor_id);
+
int find_tile_by_name(const String &p_name) const;
void get_tile_list(List<int> *p_tiles) const;
@@ -153,4 +228,7 @@ public:
TileSet();
};
+VARIANT_ENUM_CAST(TileSet::AutotileBindings);
+VARIANT_ENUM_CAST(TileSet::BitmaskMode);
+
#endif // TILE_SET_H
diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp
index 86b32a5cdd..c63ba24cbd 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world.cpp
@@ -159,9 +159,9 @@ struct SpatialIndexer {
Vector<Plane> planes = c->get_frustum();
- int culled = octree.cull_convex(planes, cull.ptr(), cull.size());
+ int culled = octree.cull_convex(planes, cull.ptrw(), cull.size());
- VisibilityNotifier **ptr = cull.ptr();
+ VisibilityNotifier **ptr = cull.ptrw();
List<VisibilityNotifier *> added;
List<VisibilityNotifier *> removed;