You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Implement multiple occlusion polygons within each TileSet occlusion layer
This commit is contained in:
@@ -443,13 +443,15 @@ void TileMapLayer::_rendering_notification(int p_what) {
|
||||
Transform2D tilemap_xform = get_global_transform();
|
||||
for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) {
|
||||
const CellData &cell_data = kv.value;
|
||||
for (const RID &occluder : cell_data.occluders) {
|
||||
if (occluder.is_null()) {
|
||||
continue;
|
||||
for (const LocalVector<RID> &polygons : cell_data.occluders) {
|
||||
for (const RID &rid : polygons) {
|
||||
if (rid.is_null()) {
|
||||
continue;
|
||||
}
|
||||
Transform2D xform(0, tile_set->map_to_local(kv.key));
|
||||
rs->canvas_light_occluder_attach_to_canvas(rid, get_canvas());
|
||||
rs->canvas_light_occluder_set_transform(rid, tilemap_xform * xform);
|
||||
}
|
||||
Transform2D xform(0, tile_set->map_to_local(kv.key));
|
||||
rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
|
||||
rs->canvas_light_occluder_set_transform(occluder, tilemap_xform * xform);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -557,8 +559,10 @@ void TileMapLayer::_rendering_occluders_clear_cell(CellData &r_cell_data) {
|
||||
RenderingServer *rs = RenderingServer::get_singleton();
|
||||
|
||||
// Free the occluders.
|
||||
for (const RID &rid : r_cell_data.occluders) {
|
||||
rs->free(rid);
|
||||
for (const LocalVector<RID> &polygons : r_cell_data.occluders) {
|
||||
for (const RID &rid : polygons) {
|
||||
rs->free(rid);
|
||||
}
|
||||
}
|
||||
r_cell_data.occluders.clear();
|
||||
}
|
||||
@@ -566,11 +570,12 @@ void TileMapLayer::_rendering_occluders_clear_cell(CellData &r_cell_data) {
|
||||
void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) {
|
||||
RenderingServer *rs = RenderingServer::get_singleton();
|
||||
|
||||
// Free unused occluders then resize the occluders array.
|
||||
// Free unused occluders then resize the occluder array.
|
||||
for (uint32_t i = tile_set->get_occlusion_layers_count(); i < r_cell_data.occluders.size(); i++) {
|
||||
RID occluder_id = r_cell_data.occluders[i];
|
||||
if (occluder_id.is_valid()) {
|
||||
rs->free(occluder_id);
|
||||
for (const RID &occluder_id : r_cell_data.occluders[i]) {
|
||||
if (occluder_id.is_valid()) {
|
||||
rs->free(occluder_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
r_cell_data.occluders.resize(tile_set->get_occlusion_layers_count());
|
||||
@@ -598,30 +603,42 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) {
|
||||
// Create, update or clear occluders.
|
||||
bool needs_set_not_interpolated = is_inside_tree() && get_tree()->is_physics_interpolation_enabled() && !is_physics_interpolated();
|
||||
for (uint32_t occlusion_layer_index = 0; occlusion_layer_index < r_cell_data.occluders.size(); occlusion_layer_index++) {
|
||||
Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder(occlusion_layer_index);
|
||||
LocalVector<RID> &occluders = r_cell_data.occluders[occlusion_layer_index];
|
||||
|
||||
RID &occluder = r_cell_data.occluders[occlusion_layer_index];
|
||||
|
||||
if (occluder_polygon.is_valid()) {
|
||||
// Create or update occluder.
|
||||
Transform2D xform;
|
||||
xform.set_origin(tile_set->map_to_local(r_cell_data.coords));
|
||||
if (!occluder.is_valid()) {
|
||||
occluder = rs->canvas_light_occluder_create();
|
||||
if (needs_set_not_interpolated) {
|
||||
rs->canvas_light_occluder_set_interpolated(occluder, false);
|
||||
}
|
||||
// Free unused occluders then resize the occluders array.
|
||||
for (uint32_t i = tile_data->get_occluder_polygons_count(occlusion_layer_index); i < r_cell_data.occluders[occlusion_layer_index].size(); i++) {
|
||||
RID occluder_id = occluders[i];
|
||||
if (occluder_id.is_valid()) {
|
||||
rs->free(occluder_id);
|
||||
}
|
||||
rs->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform);
|
||||
rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder(occlusion_layer_index, flip_h, flip_v, transpose)->get_rid());
|
||||
rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
|
||||
rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index));
|
||||
rs->canvas_light_occluder_set_as_sdf_collision(occluder, tile_set->get_occlusion_layer_sdf_collision(occlusion_layer_index));
|
||||
} else {
|
||||
// Clear occluder.
|
||||
if (occluder.is_valid()) {
|
||||
rs->free(occluder);
|
||||
occluder = RID();
|
||||
}
|
||||
occluders.resize(tile_data->get_occluder_polygons_count(occlusion_layer_index));
|
||||
|
||||
for (uint32_t occlusion_polygon_index = 0; occlusion_polygon_index < occluders.size(); occlusion_polygon_index++) {
|
||||
RID &occluder = occluders[occlusion_polygon_index];
|
||||
Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder_polygon(occlusion_layer_index, occlusion_polygon_index);
|
||||
if (occluder_polygon.is_valid()) {
|
||||
// Create or update occluder.
|
||||
|
||||
Transform2D xform;
|
||||
xform.set_origin(tile_set->map_to_local(r_cell_data.coords));
|
||||
if (!occluder.is_valid()) {
|
||||
occluder = rs->canvas_light_occluder_create();
|
||||
if (needs_set_not_interpolated) {
|
||||
rs->canvas_light_occluder_set_interpolated(occluder, false);
|
||||
}
|
||||
}
|
||||
rs->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform);
|
||||
rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder_polygon(occlusion_layer_index, occlusion_polygon_index, flip_h, flip_v, transpose)->get_rid());
|
||||
rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
|
||||
rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index));
|
||||
rs->canvas_light_occluder_set_as_sdf_collision(occluder, tile_set->get_occlusion_layer_sdf_collision(occlusion_layer_index));
|
||||
} else {
|
||||
// Clear occluder.
|
||||
if (occluder.is_valid()) {
|
||||
rs->free(occluder);
|
||||
occluder = RID();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1709,11 +1726,13 @@ void TileMapLayer::_physics_interpolated_changed() {
|
||||
}
|
||||
|
||||
for (const KeyValue<Vector2i, CellData> &E : tile_map_layer_data) {
|
||||
for (const RID &occluder : E.value.occluders) {
|
||||
if (occluder.is_valid()) {
|
||||
rs->canvas_light_occluder_set_interpolated(occluder, interpolated);
|
||||
if (needs_reset) {
|
||||
rs->canvas_light_occluder_reset_physics_interpolation(occluder);
|
||||
for (const LocalVector<RID> &polygons : E.value.occluders) {
|
||||
for (const RID &occluder_id : polygons) {
|
||||
if (occluder_id.is_valid()) {
|
||||
rs->canvas_light_occluder_set_interpolated(occluder_id, interpolated);
|
||||
if (needs_reset) {
|
||||
rs->canvas_light_occluder_reset_physics_interpolation(occluder_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user