diff options
Diffstat (limited to 'scene/resources/2d/tile_set.cpp')
-rw-r--r-- | scene/resources/2d/tile_set.cpp | 168 |
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); |