summaryrefslogtreecommitdiffstats
path: root/scene/resources/2d/tile_set.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/2d/tile_set.cpp')
-rw-r--r--scene/resources/2d/tile_set.cpp168
1 files changed, 144 insertions, 24 deletions
diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp
index dd6ae5096a..49d84bfb1b 100644
--- a/scene/resources/2d/tile_set.cpp
+++ b/scene/resources/2d/tile_set.cpp
@@ -3444,7 +3444,8 @@ void TileSet::_compatibility_conversion() {
polygon.write[index] = xform.xform(polygon[index] - ctd->region.get_size() / 2.0);
}
occluder->set_polygon(polygon);
- tile_data->set_occluder(0, occluder);
+ tile_data->add_occluder_polygon(0);
+ tile_data->set_occluder_polygon(0, 0, occluder);
}
if (ctd->navigation.is_valid()) {
if (get_navigation_layers_count() < 1) {
@@ -3558,7 +3559,8 @@ void TileSet::_compatibility_conversion() {
polygon.write[index] = xform.xform(polygon[index] - ctd->region.get_size() / 2.0);
}
occluder->set_polygon(polygon);
- tile_data->set_occluder(0, occluder);
+ tile_data->add_occluder_polygon(0);
+ tile_data->set_occluder_polygon(0, 0, occluder);
}
if (ctd->autotile_navpoly_map.has(coords)) {
if (get_navigation_layers_count() < 1) {
@@ -6220,33 +6222,86 @@ int TileData::get_y_sort_origin() const {
return y_sort_origin;
}
+#ifndef DISABLE_DEPRECATED
void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon) {
ERR_FAIL_INDEX(p_layer_id, occluders.size());
- occluders.write[p_layer_id].occluder = p_occluder_polygon;
- occluders.write[p_layer_id].transformed_occluders.clear();
+ if (get_occluder_polygons_count(p_layer_id) == 0) {
+ add_occluder_polygon(p_layer_id);
+ }
+ set_occluder_polygon(p_layer_id, 0, p_occluder_polygon);
emit_signal(CoreStringName(changed));
}
Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
ERR_FAIL_INDEX_V(p_layer_id, occluders.size(), Ref<OccluderPolygon2D>());
+ if (get_occluder_polygons_count(p_layer_id) == 0) {
+ return Ref<OccluderPolygon2D>();
+ }
+ return get_occluder_polygon(p_layer_id, 0, p_flip_h, p_flip_v, p_transpose);
+}
+#endif // DISABLE_DEPRECATED
+
+void TileData::set_occluder_polygons_count(int p_layer_id, int p_polygons_count) {
+ ERR_FAIL_INDEX(p_layer_id, occluders.size());
+ ERR_FAIL_COND(p_polygons_count < 0);
+ if (p_polygons_count == occluders.write[p_layer_id].polygons.size()) {
+ return;
+ }
+ occluders.write[p_layer_id].polygons.resize(p_polygons_count);
+ notify_property_list_changed();
+ emit_signal(CoreStringName(changed));
+}
+
+int TileData::get_occluder_polygons_count(int p_layer_id) const {
+ ERR_FAIL_INDEX_V(p_layer_id, occluders.size(), 0);
+ return occluders[p_layer_id].polygons.size();
+}
+
+void TileData::add_occluder_polygon(int p_layer_id) {
+ ERR_FAIL_INDEX(p_layer_id, occluders.size());
+ occluders.write[p_layer_id].polygons.push_back(OcclusionLayerTileData::PolygonOccluderTileData());
+ emit_signal(CoreStringName(changed));
+}
+
+void TileData::remove_occluder_polygon(int p_layer_id, int p_polygon_index) {
+ ERR_FAIL_INDEX(p_layer_id, occluders.size());
+ ERR_FAIL_INDEX(p_polygon_index, occluders[p_layer_id].polygons.size());
+ occluders.write[p_layer_id].polygons.remove_at(p_polygon_index);
+ emit_signal(CoreStringName(changed));
+}
+
+void TileData::set_occluder_polygon(int p_layer_id, int p_polygon_index, const Ref<OccluderPolygon2D> &p_occluder_polygon) {
+ ERR_FAIL_INDEX(p_layer_id, occluders.size());
+ ERR_FAIL_INDEX(p_polygon_index, occluders[p_layer_id].polygons.size());
+
+ OcclusionLayerTileData::PolygonOccluderTileData &polygon_occluder_tile_data = occluders.write[p_layer_id].polygons.write[p_polygon_index];
+ polygon_occluder_tile_data.occluder_polygon = p_occluder_polygon;
+ polygon_occluder_tile_data.transformed_polygon_occluders.clear();
+ emit_signal(CoreStringName(changed));
+}
+
+Ref<OccluderPolygon2D> TileData::get_occluder_polygon(int p_layer_id, int p_polygon_index, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
+ ERR_FAIL_INDEX_V(p_layer_id, occluders.size(), Ref<OccluderPolygon2D>());
+ ERR_FAIL_INDEX_V(p_polygon_index, occluders[p_layer_id].polygons.size(), Ref<OccluderPolygon2D>());
const OcclusionLayerTileData &layer_tile_data = occluders[p_layer_id];
+ const Ref<OccluderPolygon2D> &occluder_polygon = layer_tile_data.polygons[p_polygon_index].occluder_polygon;
int key = int(p_flip_h) | int(p_flip_v) << 1 | int(p_transpose) << 2;
if (key == 0) {
- return layer_tile_data.occluder;
+ return occluder_polygon;
}
- if (layer_tile_data.occluder.is_null()) {
+ if (occluder_polygon.is_null()) {
return Ref<OccluderPolygon2D>();
}
- HashMap<int, Ref<OccluderPolygon2D>>::Iterator I = layer_tile_data.transformed_occluders.find(key);
+ HashMap<int, Ref<OccluderPolygon2D>>::Iterator I = layer_tile_data.polygons[p_polygon_index].transformed_polygon_occluders.find(key);
if (!I) {
Ref<OccluderPolygon2D> transformed_polygon;
transformed_polygon.instantiate();
- transformed_polygon->set_polygon(get_transformed_vertices(layer_tile_data.occluder->get_polygon(), p_flip_h, p_flip_v, p_transpose));
- layer_tile_data.transformed_occluders[key] = transformed_polygon;
+ transformed_polygon->set_polygon(get_transformed_vertices(occluder_polygon->get_polygon(), p_flip_h, p_flip_v, p_transpose));
+ layer_tile_data.polygons[p_polygon_index].transformed_polygon_occluders[key] = transformed_polygon;
return transformed_polygon;
} else {
return I->value;
@@ -6594,13 +6649,37 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) {
#endif
Vector<String> components = String(p_name).split("/", true, 2);
-
- if (components.size() == 2 && components[0].begins_with("occlusion_layer_") && components[0].trim_prefix("occlusion_layer_").is_valid_int()) {
+ if (components.size() >= 2 && components[0].begins_with("occlusion_layer_") && components[0].trim_prefix("occlusion_layer_").is_valid_int()) {
// Occlusion layers.
int layer_index = components[0].trim_prefix("occlusion_layer_").to_int();
ERR_FAIL_COND_V(layer_index < 0, false);
- if (components[1] == "polygon") {
- Ref<OccluderPolygon2D> polygon = p_value;
+ if (components.size() == 2) {
+ if (components[1] == "polygon") {
+ // Kept for compatibility.
+ Ref<OccluderPolygon2D> polygon = p_value;
+ if (layer_index >= occluders.size()) {
+ if (tile_set) {
+ return false;
+ } else {
+ occluders.resize(layer_index + 1);
+ }
+ }
+ if (get_occluder_polygons_count(layer_index) == 0) {
+ add_occluder_polygon(layer_index);
+ }
+ set_occluder_polygon(layer_index, 0, polygon);
+ return true;
+ } else if (components[1] == "polygons_count") {
+ if (p_value.get_type() != Variant::INT) {
+ return false;
+ }
+ set_occluder_polygons_count(layer_index, p_value);
+ return true;
+ }
+ } else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) {
+ // Polygons.
+ int polygon_index = components[1].trim_prefix("polygon_").to_int();
+ ERR_FAIL_COND_V(polygon_index < 0, false);
if (layer_index >= occluders.size()) {
if (tile_set) {
@@ -6609,8 +6688,16 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) {
occluders.resize(layer_index + 1);
}
}
- set_occluder(layer_index, polygon);
- return true;
+
+ if (polygon_index >= occluders[layer_index].polygons.size()) {
+ occluders.write[layer_index].polygons.resize(polygon_index + 1);
+ }
+
+ if (components[2] == "polygon") {
+ Ref<OccluderPolygon2D> polygon = p_value;
+ set_occluder_polygon(layer_index, polygon_index, polygon);
+ return true;
+ }
}
} else if (components.size() >= 2 && components[0].begins_with("physics_layer_") && components[0].trim_prefix("physics_layer_").is_valid_int()) {
// Physics layers.
@@ -6638,6 +6725,7 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
} else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) {
+ // Polygons.
int polygon_index = components[1].trim_prefix("polygon_").to_int();
ERR_FAIL_COND_V(polygon_index < 0, false);
@@ -6724,16 +6812,36 @@ bool TileData::_get(const StringName &p_name, Variant &r_ret) const {
Vector<String> components = String(p_name).split("/", true, 2);
if (tile_set) {
- if (components.size() == 2 && components[0].begins_with("occlusion_layer") && components[0].trim_prefix("occlusion_layer_").is_valid_int()) {
+ if (components.size() >= 2 && components[0].begins_with("occlusion_layer") && components[0].trim_prefix("occlusion_layer_").is_valid_int()) {
// Occlusion layers.
int layer_index = components[0].trim_prefix("occlusion_layer_").to_int();
ERR_FAIL_COND_V(layer_index < 0, false);
if (layer_index >= occluders.size()) {
return false;
}
- if (components[1] == "polygon") {
- r_ret = get_occluder(layer_index);
- return true;
+ if (components.size() == 2) {
+ if (components[1] == "polygon") {
+ // Kept for compatibility.
+ if (occluders[layer_index].polygons.is_empty()) {
+ return false;
+ }
+ r_ret = get_occluder_polygon(layer_index, 0);
+ return true;
+ } else if (components[1] == "polygons_count") {
+ r_ret = get_occluder_polygons_count(layer_index);
+ return true;
+ }
+ } else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) {
+ // Polygons.
+ int polygon_index = components[1].trim_prefix("polygon_").to_int();
+ ERR_FAIL_COND_V(polygon_index < 0, false);
+ if (polygon_index >= occluders[layer_index].polygons.size()) {
+ return false;
+ }
+ if (components[2] == "polygon") {
+ r_ret = get_occluder_polygon(layer_index, polygon_index);
+ return true;
+ }
}
} else if (components.size() >= 2 && components[0].begins_with("physics_layer_") && components[0].trim_prefix("physics_layer_").is_valid_int()) {
// Physics layers.
@@ -6813,12 +6921,15 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
// Occlusion layers.
p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Rendering", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < occluders.size(); i++) {
- // occlusion_layer_%d/polygon
- property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT);
- if (occluders[i].occluder.is_null()) {
- property_info.usage ^= PROPERTY_USAGE_STORAGE;
+ p_list->push_back(PropertyInfo(Variant::INT, vformat("occlusion_layer_%d/%s", i, PNAME("polygons_count")), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
+ for (int j = 0; j < occluders[i].polygons.size(); j++) {
+ // occlusion_layer_%d/polygon_%d/polygon
+ property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/polygon_%d/%s", i, j, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT);
+ if (occluders[i].polygons[j].occluder_polygon.is_null()) {
+ property_info.usage ^= PROPERTY_USAGE_STORAGE;
+ }
+ p_list->push_back(property_info);
}
- p_list->push_back(property_info);
}
// Physics layers.
@@ -6923,8 +7034,17 @@ void TileData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_y_sort_origin", "y_sort_origin"), &TileData::set_y_sort_origin);
ClassDB::bind_method(D_METHOD("get_y_sort_origin"), &TileData::get_y_sort_origin);
+ ClassDB::bind_method(D_METHOD("set_occluder_polygons_count", "layer_id", "polygons_count"), &TileData::set_occluder_polygons_count);
+ ClassDB::bind_method(D_METHOD("get_occluder_polygons_count", "layer_id"), &TileData::get_occluder_polygons_count);
+ ClassDB::bind_method(D_METHOD("add_occluder_polygon", "layer_id"), &TileData::add_occluder_polygon);
+ ClassDB::bind_method(D_METHOD("remove_occluder_polygon", "layer_id", "polygon_index"), &TileData::remove_occluder_polygon);
+ ClassDB::bind_method(D_METHOD("set_occluder_polygon", "layer_id", "polygon_index", "polygon"), &TileData::set_occluder_polygon);
+ ClassDB::bind_method(D_METHOD("get_occluder_polygon", "layer_id", "polygon_index", "flip_h", "flip_v", "transpose"), &TileData::get_occluder_polygon, DEFVAL(false), DEFVAL(false), DEFVAL(false));
+
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_occluder", "layer_id", "occluder_polygon"), &TileData::set_occluder);
ClassDB::bind_method(D_METHOD("get_occluder", "layer_id", "flip_h", "flip_v", "transpose"), &TileData::get_occluder, DEFVAL(false), DEFVAL(false), DEFVAL(false));
+#endif // DISABLE_DEPRECATED
// Physics.
ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "layer_id", "velocity"), &TileData::set_constant_linear_velocity);