Implemented VertexLight2D management support to LayeredTileMapLayers.

This commit is contained in:
Relintai 2024-05-11 22:59:41 +02:00
parent 7a4271104d
commit 7476c8608c
4 changed files with 189 additions and 18 deletions

View File

@ -1543,6 +1543,154 @@ void LayeredTileMapLayer::_scenes_draw_cell_debug(const RID &p_canvas_item, cons
}
#endif // DEBUG_ENABLED
////////////////////////// VertexLights2D ///////////////////////////////////////////
//VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
void LayeredTileMapLayer::_vertex_light_update(bool p_force_cleanup) {
// Check if we should cleanup everything.
bool forced_cleanup = p_force_cleanup || !enabled || !_use_vertex_lights || !is_inside_tree() || !tile_set.is_valid();
// ----------- regions processing -----------
if (forced_cleanup) {
// Clean everything.
for (HashMap<Vector2i, CellData>::Element *kv = tile_map_layer_data.front(); kv; kv = kv->next) {
_vertex_light_clear_cell(kv->value());
}
} else {
if (_vertex_lights_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_SET]) {
// Update all cells.
for (HashMap<Vector2i, CellData>::Element *kv = tile_map_layer_data.front(); kv; kv = kv->next) {
_vertex_light_update_cell(kv->value());
}
} else {
// Update dirty cells.
for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
CellData &cell_data = *cell_data_list_element->self();
_vertex_light_update_cell(cell_data);
}
}
}
// -----------
// Mark the navigation state as up to date.
_vertex_lights_was_cleaned_up = forced_cleanup;
}
void LayeredTileMapLayer::_vertex_light_notification(int p_what) {
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
VertexLights2DServer *vls = VertexLights2DServer::get_singleton();
if (tile_set.is_valid()) {
Transform2D tilemap_xform = get_global_transform();
for (HashMap<Vector2i, CellData>::Element *kv = tile_map_layer_data.front(); kv; kv = kv->next) {
const CellData &cell_data = kv->value();
Transform2D tile_transform;
tile_transform.set_origin(tile_set->map_to_local(kv->key()));
Transform2D ctf = tilemap_xform * tile_transform;
Vector2 pos = ctf.xform(Vector2());
// Update navigation regions transform.
const RID &light = cell_data.vertex_light;
if (light.is_valid()) {
vls->light_set_position(light, pos);
}
}
}
}
}
void LayeredTileMapLayer::_vertex_light_clear_cell(CellData &r_cell_data) {
VertexLights2DServer *vls = VertexLights2DServer::get_singleton();
// Clear
const RID &light = r_cell_data.vertex_light;
if (light.is_valid()) {
vls->light_set_map(light, RID());
vls->free(light);
}
r_cell_data.vertex_light = RID();
}
void LayeredTileMapLayer::_vertex_light_update_cell(CellData &r_cell_data) {
VertexLights2DServer *vls = VertexLights2DServer::get_singleton();
RID light_map = get_world_2d()->get_vertex_lights_2d_map();
ERR_FAIL_COND(!light_map.is_valid());
// Get the navigation polygons and create regions.
LayeredTileMapCell &c = r_cell_data.cell;
LayeredTileSetSource *source;
if (tile_set->has_source(c.source_id)) {
source = *tile_set->get_source(c.source_id);
if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
LayeredTileSetAtlasSource *atlas_source = Object::cast_to<LayeredTileSetAtlasSource>(source);
if (atlas_source) {
const LayeredTileData *tile_data;
if (r_cell_data.runtime_tile_data_cache) {
tile_data = r_cell_data.runtime_tile_data_cache;
} else {
tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
RID &light = r_cell_data.vertex_light;
bool enabled = tile_data->get_vertex_light_is_enabled();
if (enabled) {
// Create or update regions.
if (!light.is_valid()) {
light = vls->light_create();
}
vls->light_set_map(light, light_map);
vls->light_set_range(light, tile_data->get_vertex_light_range());
vls->light_set_attenuation(light, tile_data->get_vertex_light_attenuation());
vls->light_set_color(light, tile_data->get_vertex_light_color());
vls->light_set_mode(light, (VertexLights2DServer::VertexLight2DMode)tile_data->get_vertex_light_mode());
vls->light_set_z_range(light, tile_data->get_vertex_light_z_range());
vls->light_set_layer_range(light, tile_data->get_vertex_light_layer_range());
vls->light_set_item_cull_mask(light, tile_data->get_vertex_light_item_cull_mask());
const Vector2 local_tile_pos = tile_set->map_to_local(r_cell_data.coords);
vls->light_set_position(light, to_global(local_tile_pos));
} else {
// Clear region.
if (light.is_valid()) {
vls->light_set_map(light, RID());
vls->free(light);
light = RID();
}
}
return;
}
}
}
// If we did not return earlier, clear the cell.
_vertex_light_clear_cell(r_cell_data);
}
#ifdef DEBUG_ENABLED
void LayeredTileMapLayer::_vertex_light_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data) {
//TODO
}
#endif // DEBUG_ENABLED
#endif
/////////////////////////////////////////////////////////////////////
void LayeredTileMapLayer::_build_runtime_update_tile_data(bool p_force_cleanup) {
@ -1863,6 +2011,11 @@ void LayeredTileMapLayer::_internal_update(bool p_force_cleanup) {
// This may add cells to the dirty list if a runtime modification has been notified.
_build_runtime_update_tile_data(p_force_cleanup);
//VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
_vertex_light_update(p_force_cleanup);
#endif
// Update all subsystems.
_rendering_update(p_force_cleanup);
_physics_update(p_force_cleanup);
@ -1944,6 +2097,11 @@ void LayeredTileMapLayer::_notification(int p_what) {
} break;
}
//VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
_vertex_light_notification(p_what);
#endif
_rendering_notification(p_what);
_physics_notification(p_what);
_navigation_notification(p_what);

View File

@ -118,6 +118,7 @@ struct CellData {
//VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
Color vertex_light_color;
RID vertex_light;
#endif
// Debug.
@ -425,6 +426,18 @@ private:
void _scenes_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data);
#endif // DEBUG_ENABLED
//VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
bool _vertex_lights_was_cleaned_up = false;
void _vertex_light_update(bool p_force_cleanup);
void _vertex_light_notification(int p_what);
void _vertex_light_clear_cell(CellData &r_cell_data);
void _vertex_light_update_cell(CellData &r_cell_data);
#ifdef DEBUG_ENABLED
void _vertex_light_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data);
#endif // DEBUG_ENABLED
#endif
// Terrains.
LayeredTileSet::TerrainsPattern _get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, const RBSet<TerrainConstraint> &p_constraints, LayeredTileSet::TerrainsPattern p_current_pattern) const;
RBSet<TerrainConstraint> _get_terrain_constraints_from_added_pattern(const Vector2i &p_position, int p_terrain_set, LayeredTileSet::TerrainsPattern p_terrains_pattern) const;

View File

@ -6847,7 +6847,7 @@ Vector<Vector2> LayeredTileData::get_transformed_avoidance_polygon(int p_layer_i
// VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
bool LayeredTileData::get_vertex_light_is_enabled() {
bool LayeredTileData::get_vertex_light_is_enabled() const {
return _vertex_light.enabled;
}
void LayeredTileData::set_vertex_light_enabled(const bool p_enabled) {
@ -6855,7 +6855,7 @@ void LayeredTileData::set_vertex_light_enabled(const bool p_enabled) {
emit_signal("changed");
}
Vector2i LayeredTileData::get_vertex_light_position() {
Vector2i LayeredTileData::get_vertex_light_position() const {
return _vertex_light.position;
}
void LayeredTileData::set_vertex_light_position(const Vector2i &p_position) {
@ -6863,7 +6863,7 @@ void LayeredTileData::set_vertex_light_position(const Vector2i &p_position) {
emit_signal("changed");
}
Vector2i LayeredTileData::get_vertex_light_range() {
Vector2i LayeredTileData::get_vertex_light_range() const {
return _vertex_light.range;
}
void LayeredTileData::set_vertex_light_range(const Vector2i &p_range) {
@ -6871,7 +6871,7 @@ void LayeredTileData::set_vertex_light_range(const Vector2i &p_range) {
emit_signal("changed");
}
real_t LayeredTileData::get_vertex_light_attenuation() {
real_t LayeredTileData::get_vertex_light_attenuation() const {
return _vertex_light.attenuation;
}
void LayeredTileData::set_vertex_light_attenuation(const real_t p_attenuation) {
@ -6879,7 +6879,7 @@ void LayeredTileData::set_vertex_light_attenuation(const real_t p_attenuation) {
emit_signal("changed");
}
Color LayeredTileData::get_vertex_light_color() {
Color LayeredTileData::get_vertex_light_color() const {
return _vertex_light.color;
}
void LayeredTileData::set_vertex_light_color(const Color &p_color) {
@ -6887,7 +6887,7 @@ void LayeredTileData::set_vertex_light_color(const Color &p_color) {
emit_signal("changed");
}
LayeredTileData::VertexLight2DMode LayeredTileData::get_vertex_light_mode() {
LayeredTileData::VertexLight2DMode LayeredTileData::get_vertex_light_mode() const {
return _vertex_light.mode;
}
void LayeredTileData::set_vertex_light_mode(const LayeredTileData::VertexLight2DMode p_mode) {
@ -6895,7 +6895,7 @@ void LayeredTileData::set_vertex_light_mode(const LayeredTileData::VertexLight2D
emit_signal("changed");
}
Vector2i LayeredTileData::get_vertex_light_z_range() {
Vector2i LayeredTileData::get_vertex_light_z_range() const {
return _vertex_light.z_range;
}
void LayeredTileData::set_vertex_light_z_range(const Vector2i &p_z_range) {
@ -6903,7 +6903,7 @@ void LayeredTileData::set_vertex_light_z_range(const Vector2i &p_z_range) {
emit_signal("changed");
}
Vector2i LayeredTileData::get_vertex_light_layer_range() {
Vector2i LayeredTileData::get_vertex_light_layer_range() const {
return _vertex_light.layer_range;
}
void LayeredTileData::set_vertex_light_layer_range(const Vector2i &p_layer_range) {
@ -6911,7 +6911,7 @@ void LayeredTileData::set_vertex_light_layer_range(const Vector2i &p_layer_range
emit_signal("changed");
}
int LayeredTileData::get_vertex_light_item_cull_mask() {
int LayeredTileData::get_vertex_light_item_cull_mask() const {
return _vertex_light.item_cull_mask;
}
void LayeredTileData::set_vertex_light_item_cull_mask(const int p_item_cull_mask) {

View File

@ -1066,31 +1066,31 @@ public:
// VertexLights2D
#ifdef MODULE_VERTEX_LIGHTS_2D_ENABLED
bool get_vertex_light_is_enabled();
bool get_vertex_light_is_enabled() const;
void set_vertex_light_enabled(const bool p_enabled);
Vector2i get_vertex_light_position();
Vector2i get_vertex_light_position() const;
void set_vertex_light_position(const Vector2i &p_position);
Vector2i get_vertex_light_range();
Vector2i get_vertex_light_range() const;
void set_vertex_light_range(const Vector2i &p_range);
real_t get_vertex_light_attenuation();
real_t get_vertex_light_attenuation() const;
void set_vertex_light_attenuation(const real_t p_attenuation);
Color get_vertex_light_color();
Color get_vertex_light_color() const;
void set_vertex_light_color(const Color &p_color);
VertexLight2DMode get_vertex_light_mode();
VertexLight2DMode get_vertex_light_mode() const;
void set_vertex_light_mode(const VertexLight2DMode p_mode);
Vector2i get_vertex_light_z_range();
Vector2i get_vertex_light_z_range() const;
void set_vertex_light_z_range(const Vector2i &p_z_range);
Vector2i get_vertex_light_layer_range();
Vector2i get_vertex_light_layer_range() const;
void set_vertex_light_layer_range(const Vector2i &p_layer_range);
int get_vertex_light_item_cull_mask();
int get_vertex_light_item_cull_mask() const;
void set_vertex_light_item_cull_mask(const int p_item_cull_mask);
#endif