Skip to content

Commit

Permalink
Implemented RAO for LayeredTileMaps.
Browse files Browse the repository at this point in the history
  • Loading branch information
Relintai committed Mar 11, 2024
1 parent 765a8de commit 16699e7
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 11 deletions.
140 changes: 131 additions & 9 deletions modules/layered_tile_map/layered_tile_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,21 @@ void LayeredTileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, con
real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);

Array anim_data;

for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
real_t frame_duration_scaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame) * speed;

RID tex_rid = tex.is_valid() ? tex->get_rid() : RID();
//RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID normal_rid = RID();

Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);

//tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, Ref<Texture>(), p_tile_set->is_uv_clipping());

Array d;
d.resize(8);

//real_t frame_time = d[0];
//Rect2 tex_rect = d[1]; //const Rect2 &p_rect
//rect->texture = d[2]; //RID p_texture
Expand All @@ -207,7 +207,7 @@ void LayeredTileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, con
//bool transpose = d[5]; //bool p_transpose = false
//rect->normal_map = d[6]; //RID p_normal_map = RID()
//bool clip_uv = d[7]; //bool p_clip_uv = false

d[0] = frame_duration_scaled;
d[1] = dest_rect;
d[2] = tex_rid;
Expand All @@ -219,9 +219,9 @@ void LayeredTileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, con

anim_data.push_back(d);
}

bool random_start_time = atlas_source->get_tile_animation_mode(p_atlas_coords) == LayeredTileSetAtlasSource::TILE_ANIMATION_MODE_RANDOM_START_TIMES;

RenderingServer::get_singleton()->canvas_item_add_texture_rect_animation(p_canvas_item, anim_data, random_start_time);
}
}
Expand Down Expand Up @@ -496,6 +496,106 @@ void LayeredTileMap::set_cells_terrain_path(int p_layer, PoolVector2iArray p_pat
TILEMAP_CALL_FOR_LAYER(p_layer, set_cells_terrain_path, p_path, p_terrain_set, p_terrain, p_ignore_empty_terrains);
}

//RAO
#ifdef MODULE_FASTNOISE_ENABLED
void LayeredTileMap::rao_set_use(bool p_rao) {
if (_use_rao == p_rao) {
return;
}

_use_rao = p_rao;

if (!_use_rao) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];

layer->set_rao_noise(Ref<FastNoise>());
}

} else {
if (_noise_params.is_valid()) {
if (!_rao_noise.is_valid()) {
_rao_noise.instance();
}

rao_setup_noise(_rao_noise);
} else {
_rao_noise.unref();
}

for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];

layer->set_rao_noise(_rao_noise);
}
}

_emit_changed();
}
bool LayeredTileMap::rao_get_use() const {
return _use_rao;
}

void LayeredTileMap::rao_set_noise_params(const Ref<FastnoiseNoiseParams> &noise) {
if (_noise_params == noise) {
return;
}

_noise_params = noise;

if (!_use_rao) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];

layer->set_rao_noise(Ref<FastNoise>());
}
} else {
if (_noise_params.is_valid()) {
if (!_rao_noise.is_valid()) {
_rao_noise.instance();
}

rao_setup_noise(_rao_noise);
} else {
_rao_noise.unref();
}

for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];

layer->set_rao_noise(_rao_noise);
}
}

_emit_changed();
}

void LayeredTileMap::rao_set_strength(const real_t p_strength) {
_rao_strength = p_strength;

for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];

layer->set_rao_strength(p_strength);
}

_emit_changed();
}
real_t LayeredTileMap::rao_get_strength() const {
return _rao_strength;
}

Ref<FastnoiseNoiseParams> LayeredTileMap::rao_get_noise_params() {
return _noise_params;
}

void LayeredTileMap::rao_setup_noise(Ref<FastNoise> noise) {
if (_noise_params.is_valid()) {
_noise_params->setup_noise(noise);
}
}
#endif

LayeredTileMapCell LayeredTileMap::get_cell(int p_layer, const Vector2i &p_coords, bool p_use_proxies) const {
TILEMAP_CALL_FOR_LAYER_V(p_layer, LayeredTileMapCell(), get_cell, p_coords, p_use_proxies);
}
Expand Down Expand Up @@ -1046,6 +1146,23 @@ void LayeredTileMap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode");

//RAO
#ifdef MODULE_FASTNOISE_ENABLED
ADD_GROUP("RAO", "rao");

ClassDB::bind_method(D_METHOD("rao_set_use", "value"), &LayeredTileMap::rao_set_use);
ClassDB::bind_method(D_METHOD("rao_get_use"), &LayeredTileMap::rao_get_use);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rao_use"), "rao_set_use", "rao_get_use");

ClassDB::bind_method(D_METHOD("rao_set_strength", "value"), &LayeredTileMap::rao_set_strength);
ClassDB::bind_method(D_METHOD("rao_get_strength"), &LayeredTileMap::rao_get_strength);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rao_strength"), "rao_set_strength", "rao_get_strength");

ClassDB::bind_method(D_METHOD("rao_set_noise_params", "noise"), &LayeredTileMap::rao_set_noise_params);
ClassDB::bind_method(D_METHOD("rao_get_noise_params"), &LayeredTileMap::rao_get_noise_params);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "rao_noise", PROPERTY_HINT_RESOURCE_TYPE, "FastnoiseNoiseParams"), "rao_set_noise_params", "rao_get_noise_params");
#endif

ADD_ARRAY("layers", "layer_");

ADD_PROPERTY_DEFAULT("format", LayeredTileMapDataFormat::FORMAT_1);
Expand All @@ -1066,6 +1183,11 @@ LayeredTileMap::LayeredTileMap() {
new_layer->connect(CoreStringNames::get_singleton()->changed, this, "_emit_changed");
layers.push_back(new_layer);
default_layer = memnew(LayeredTileMapLayer);

#ifdef MODULE_FASTNOISE_ENABLED
_use_rao = true;
_rao_strength = 0.3;
#endif
}

LayeredTileMap::~LayeredTileMap() {
Expand Down
30 changes: 30 additions & 0 deletions modules/layered_tile_map/layered_tile_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
#include "layered_tile_map_layer_group.h"
#include "layered_tile_set.h"

#include "modules/modules_enabled.gen.h"

#ifdef MODULE_FASTNOISE_ENABLED
#include "modules/fastnoise/fastnoise_noise_params.h"
#include "modules/fastnoise/noise.h"
#endif

class Control;
class LayeredTileMapLayer;
class TerrainConstraint;
Expand Down Expand Up @@ -79,6 +86,15 @@ class LayeredTileMap : public LayeredTileMapLayerGroup {
Transform2D last_valid_transform;
Transform2D new_transform;

//RAO
#ifdef MODULE_FASTNOISE_ENABLED
bool _use_rao;
real_t _rao_strength;
Ref<FastnoiseNoiseParams> _noise_params;

Ref<FastNoise> _rao_noise;
#endif

void _emit_changed();

protected:
Expand Down Expand Up @@ -162,6 +178,20 @@ class LayeredTileMap : public LayeredTileMapLayerGroup {
void set_cells_terrain_connect(int p_layer, PoolVector2iArray p_cells, int p_terrain_set, int p_terrain, bool p_ignore_empty_terrains = true);
void set_cells_terrain_path(int p_layer, PoolVector2iArray p_path, int p_terrain_set, int p_terrain, bool p_ignore_empty_terrains = true);

//RAO
#ifdef MODULE_FASTNOISE_ENABLED
void rao_set_use(bool p_rao);
bool rao_get_use() const;

void rao_set_strength(const real_t p_strength);
real_t rao_get_strength() const;

void rao_set_noise_params(const Ref<FastnoiseNoiseParams> &noise);
Ref<FastnoiseNoiseParams> rao_get_noise_params();

void rao_setup_noise(Ref<FastNoise> noise);
#endif

// Not exposed to users.
LayeredTileMapCell get_cell(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const;
int get_effective_quadrant_size(int p_layer) const;
Expand Down
63 changes: 63 additions & 0 deletions modules/layered_tile_map/layered_tile_map_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,25 @@ void LayeredTileMapLayer::_rendering_update() {
}

// Drawing the tile in the canvas item.

//RAO
#ifdef MODULE_FASTNOISE_ENABLED
if (_rao_noise.is_valid()) {
float col = (static_cast<float>(cell_data.rao) / 255.0) * _rao_strength;

Color modulate = get_modulate();
Color self_modulate = get_self_modulate();

Color m = Color(modulate.r * self_modulate.r - col, modulate.g * self_modulate.g - col, modulate.b * self_modulate.b - col, modulate.a * self_modulate.a);

LayeredTileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, m, tile_data, random_animation_offset);
} else {
LayeredTileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
}
#else
LayeredTileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);

#endif
}
} else {
// Free the quadrant.
Expand Down Expand Up @@ -407,6 +425,8 @@ void LayeredTileMapLayer::_rendering_update() {

for (List<RID>::Element *ci = rendering_quadrant->canvas_items.front(); ci; ci = ci->next()) {
rs->canvas_item_set_light_mask(ci->get(), get_light_mask());

rs->canvas_item_set_self_modulate(ci->get(), get_self_modulate());
rs->canvas_item_set_self_modulate(ci->get(), get_self_modulate());
}
}
Expand Down Expand Up @@ -503,6 +523,16 @@ void LayeredTileMapLayer::_rendering_quadrants_update_cell(CellData &r_cell_data
canvas_items_position = tile_set->map_to_local(rendering_quadrant_size * quadrant_coords);
}

#ifdef MODULE_FASTNOISE_ENABLED
if (dirty.flags[DIRTY_FLAGS_LAYER_RAO]) {
if (_rao_noise.is_valid()) {
r_cell_data.rao = static_cast<uint8_t>(static_cast<int>(CLAMP(_rao_noise->get_noise_2d(r_cell_data.coords.x, r_cell_data.coords.y), 0, 1) * 255.0) % 255);
} else {
r_cell_data.rao = 0;
}
}
#endif

Ref<RenderingQuadrant> rendering_quadrant;
if (rendering_quadrant_map.has(quadrant_coords)) {
// Reuse existing rendering quadrant.
Expand Down Expand Up @@ -2802,6 +2832,35 @@ LayeredTileMapLayer::VisibilityMode LayeredTileMapLayer::get_navigation_visibili
return navigation_visibility_mode;
}

//RAO
#ifdef MODULE_FASTNOISE_ENABLED
Ref<FastNoise> LayeredTileMapLayer::get_rao_noise() {
return _rao_noise;
}
void LayeredTileMapLayer::set_rao_noise(const Ref<FastNoise> &noise) {
// Don't check if they are the same!
_rao_noise = noise;

dirty.flags[DIRTY_FLAGS_LAYER_RAO] = true;

_queue_internal_update();
emit_signal(CoreStringNames::get_singleton()->changed);
}

void LayeredTileMapLayer::set_rao_strength(const real_t p_strength) {
_rao_strength = p_strength;

dirty.flags[DIRTY_FLAGS_LAYER_RAO] = true;

_queue_internal_update();
emit_signal(CoreStringNames::get_singleton()->changed);
}
real_t LayeredTileMapLayer::get_rao_strength() const {
return _rao_strength;
}

#endif

void LayeredTileMapLayer::fix_invalid_tiles() {
Ref<LayeredTileSet> tileset = get_effective_tile_set();
ERR_FAIL_COND_MSG(tileset.is_null(), "Cannot call fix_invalid_tiles() on a LayeredTileMap without a valid LayeredTileSet.");
Expand Down Expand Up @@ -2845,6 +2904,10 @@ void LayeredTileMapLayer::tile_data_runtime_update(const Vector2i &p_coords, Lay

LayeredTileMapLayer::LayeredTileMapLayer() {
set_notify_transform(true);

#ifdef MODULE_FASTNOISE_ENABLED
_rao_strength = 0.3;
#endif
}

LayeredTileMapLayer::~LayeredTileMapLayer() {
Expand Down
Loading

0 comments on commit 16699e7

Please sign in to comment.