Added noise offset support to TiledWalls.

This commit is contained in:
Relintai 2023-02-25 12:08:49 +01:00
parent 0cbe3b29f6
commit 47525f401b
3 changed files with 200 additions and 20 deletions

View File

@ -30,6 +30,11 @@ SOFTWARE.
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_FASTNOISE_ENABLED
#include "../fastnoise/fastnoise_noise_params.h"
#include "../fastnoise/noise.h"
#endif
const String PropMesher::BINDING_STRING_BUILD_FLAGS = "Use Lighting,Use AO,Use RAO,Bake Lights";
bool PropMesher::Vertex::operator==(const Vertex &p_vertex) const {
@ -451,6 +456,10 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
return;
}
#ifdef MODULE_FASTNOISE_ENABLED
int tiled_wall_vertex_start_index = _vertices.size();
#endif
float flavour_chance = tiled_wall_data->get_flavour_tile_chance();
//collect rects
@ -483,6 +492,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
}
TiledWallData::TiledWallTilingType tiling_type = tiled_wall_data->get_tiling_type();
float cys = 0;
if (tiling_type == TiledWallData::TILED_WALL_TILING_TYPE_NONE) {
Rect2 r = normal_rects[0];
@ -492,31 +502,31 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
if (flavour_rects.size() == 0) {
//no flavours
for (int x = 0; x < width; ++x) {
float ych = 0;
cys = 0;
for (int y = 0; y < height; ++y) {
add_tiled_wall_mesh_rect_simple(x, ych, yh, 0, 0, transform, r, texture_scale);
add_tiled_wall_mesh_rect_simple(x, cys, yh, 0, 0, transform, r, texture_scale);
ych += yh;
cys += yh;
}
}
} else {
//has flavours
for (int x = 0; x < width; ++x) {
float ych = 0;
cys = 0;
for (int y = 0; y < height; ++y) {
if (Math::randf() > flavour_chance) {
add_tiled_wall_mesh_rect_simple(x, ych, yh, 0, 0, transform, r, texture_scale);
add_tiled_wall_mesh_rect_simple(x, cys, yh, 0, 0, transform, r, texture_scale);
ych += yh;
cys += yh;
} else {
int indx = Math::rand() % flavour_rects.size();
float fyh = flavour_data[indx].y_size;
add_tiled_wall_mesh_rect_simple(x, ych, fyh, 0, 0, transform, flavour_rects[indx], flavour_data[indx].texture_scale);
add_tiled_wall_mesh_rect_simple(x, cys, fyh, 0, 0, transform, flavour_rects[indx], flavour_data[indx].texture_scale);
ych += fyh;
cys += fyh;
}
}
}
@ -534,7 +544,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
float z_offset = normal_data[indx].z_offset;
int texture_scale = normal_data[indx].texture_scale;
float cys = 0;
cys = 0;
for (int y = 0; y < height; ++y) {
add_tiled_wall_mesh_rect_simple(x, cys, ysize, z_offset, z_offset, transform, r, texture_scale);
@ -551,7 +561,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
float ysize = normal_data[indx].y_size;
int texture_scale = normal_data[indx].texture_scale;
float cys = 0;
cys = 0;
for (int y = 0; y < height; ++y) {
if (Math::randf() > flavour_chance) {
@ -576,7 +586,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
//no flavours
for (int x = 0; x < width; ++x) {
float cys = 0;
cys = 0;
float prev_z_offset = 0;
@ -601,7 +611,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
} else {
//has flavours
for (int x = 0; x < width; ++x) {
float cys = 0;
cys = 0;
float prev_z_offset = 0;
@ -639,7 +649,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
if (flavour_rects.size() == 0) {
//no flavours
for (int x = 0; x < width; ++x) {
float cys = 0;
cys = 0;
for (int y = 0; y < height; ++y) {
int indx = (x + y) % normal_rects.size();
@ -655,7 +665,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
} else {
//has flavours
for (int x = 0; x < width; ++x) {
float cys = 0;
cys = 0;
for (int y = 0; y < height; ++y) {
int indx = (x + y) % normal_rects.size();
@ -678,12 +688,94 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const
}
}
}
#ifdef MODULE_FASTNOISE_ENABLED
Ref<TiledWallData> twd = tiled_wall_data;
Ref<FastnoiseNoiseParams> offset_noise = twd->get_offset_noise();
if (offset_noise.is_null()) {
return;
}
float offset_noise_strength = tiled_wall_data->get_offset_noise_strength();
Ref<FastNoise> noise;
noise.instance();
offset_noise->setup_noise(noise);
if (twd->get_offset_noise_randomize_seed()) {
noise->set_seed(Math::rand());
}
if (twd->get_offset_noise_skip_edges()) {
//Vector3 vert_min = Vector3(Math_INF, Math_INF, Math_INF);
//Vector3 vert_max = Vector3(-Math_INF, -Math_INF, -Math_INF);
Vector3 vert_min = transform.xform(Vector3(0, 0, 0));
Vector3 vert_max = transform.xform(Vector3(width, cys, 0));
int vs = _vertices.size();
PoolVector<Vertex>::Write w = _vertices.write();
Vertex *wptr = w.ptr();
/*
for (int i = tiled_wall_vertex_start_index; i < vs; ++i) {
Vertex v = wptr[i];
if (v.vertex < vert_min) {
vert_min = v.vertex;
}
if (v.vertex > vert_max) {
vert_max = v.vertex;
}
}
*/
for (int i = tiled_wall_vertex_start_index; i < vs; ++i) {
Vertex v = wptr[i];
int sim_count = 0;
if (Math::is_equal_approx(v.vertex.x, vert_min.x) || Math::is_equal_approx(v.vertex.x, vert_max.x)) {
++sim_count;
}
if (Math::is_equal_approx(v.vertex.y, vert_min.y) || Math::is_equal_approx(v.vertex.y, vert_max.y)) {
++sim_count;
}
if (sim_count == 1 && (Math::is_equal_approx(v.vertex.z, vert_min.z) || Math::is_equal_approx(v.vertex.z, vert_max.z))) {
++sim_count;
}
if (sim_count > 1) {
continue;
}
float n = noise->get_noise_2d(v.vertex.x, v.vertex.z) * offset_noise_strength;
v.vertex += transform.basis.xform(Vector3(0, 0, n));
wptr[i] = v;
}
} else {
int vs = _vertices.size();
PoolVector<Vertex>::Write w = _vertices.write();
Vertex *wptr = w.ptr();
for (int i = tiled_wall_vertex_start_index; i < vs; ++i) {
Vertex v = wptr[i];
float n = noise->get_noise_2d(v.vertex.x, v.vertex.z) * offset_noise_strength;
v.vertex += transform.basis.xform(Vector3(0, 0, n));
wptr[i] = v;
}
}
#endif
}
void PropMesher::add_tiled_wall_mesh_rect_simple(const float x, const float y, const float y_size, const float prev_z_offset, const float current_z_offset, const Transform &transform, const Rect2 &texture_rect, const int texture_scale) {
int vc = get_vertex_count();
float cy = CLAMP(0.0, 1.0, y_size);
float cy = CLAMP(0.0, 1.0, y_size);
//x + 1, y
add_normal(transform.basis.xform(Vector3(0, 0, -1)));
@ -727,8 +819,8 @@ _FORCE_INLINE_ Vector2 PropMesher::transform_uv(const Vector2 &uv, const Rect2 &
Vector2 PropMesher::transform_uv_scaled(const Vector2 &uv, const Rect2 &rect, const int x, const int y, const int texture_scale) const {
Vector2 ruv = uv;
int lx = x % texture_scale;
int ly = y % texture_scale;
int lx = x % texture_scale;
int ly = y % texture_scale;
float sizex = rect.size.x / static_cast<float>(texture_scale);
float sizey = rect.size.y / static_cast<float>(texture_scale);
@ -742,7 +834,6 @@ Vector2 PropMesher::transform_uv_scaled(const Vector2 &uv, const Rect2 &rect, co
return ruv;
}
#ifdef MODULE_MESH_DATA_RESOURCE_ENABLED
void PropMesher::add_mesh_data_resource(Ref<MeshDataResource> mesh, const Vector3 position, const Vector3 rotation, const Vector3 scale, const Rect2 uv_rect) {
Transform transform = Transform(Basis(rotation).scaled(scale), position);

View File

@ -42,6 +42,10 @@ SOFTWARE.
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_FASTNOISE_ENABLED
#include "../../fastnoise/fastnoise_noise_params.h"
#endif
#ifdef MODULE_ENTITY_SPELL_SYSTEM_ENABLED
#include "modules/entity_spell_system/material_cache/ess_material_cache.h"
#endif
@ -235,6 +239,44 @@ void TiledWallData::set_flavour_tile_chance(const float value) {
_flavour_chance = value;
}
#ifdef MODULE_FASTNOISE_ENABLED
Ref<FastnoiseNoiseParams> TiledWallData::get_offset_noise() {
return _offset_noise;
}
void TiledWallData::set_offset_noise(const Ref<FastnoiseNoiseParams> &val) {
_offset_noise = val;
emit_changed();
}
float TiledWallData::get_offset_noise_strength() const {
return _offset_noise_strength;
}
void TiledWallData::set_offset_noise_strength(const float val) {
_offset_noise_strength = val;
emit_changed();
}
bool TiledWallData::get_offset_noise_randomize_seed() const {
return _offset_noise_randomize_seed;
}
void TiledWallData::set_offset_noise_randomize_seed(const bool val) {
_offset_noise_randomize_seed = val;
emit_changed();
}
bool TiledWallData::get_offset_noise_skip_edges() const {
return _offset_noise_skip_edges;
}
void TiledWallData::set_offset_noise_skip_edges(const bool val) {
_offset_noise_skip_edges = val;
emit_changed();
}
#endif
//materials
void TiledWallData::material_add(const Ref<Material> &value) {
ERR_FAIL_COND(!value.is_valid());
@ -399,6 +441,11 @@ TiledWallData::TiledWallData() {
_collider_type = TILED_WALL_COLLIDER_TYPE_PLANE;
_flavour_chance = 0.15;
_collider_z_offset = 0;
#ifdef MODULE_FASTNOISE_ENABLED
_offset_noise_strength = 0;
_offset_noise_randomize_seed = true;
_offset_noise_skip_edges = true;
#endif
}
TiledWallData::~TiledWallData() {
_tiles.clear();
@ -599,6 +646,24 @@ void TiledWallData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flavour_tile_chance", "texture"), &TiledWallData::set_flavour_tile_chance);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "flavour_tile_chance"), "set_flavour_tile_chance", "get_flavour_tile_chance");
#ifdef MODULE_FASTNOISE_ENABLED
ClassDB::bind_method(D_METHOD("get_offset_noise"), &TiledWallData::get_offset_noise);
ClassDB::bind_method(D_METHOD("set_offset_noise", "texture"), &TiledWallData::set_offset_noise);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "offset_noise", PROPERTY_HINT_RESOURCE_TYPE, "FastnoiseNoiseParams"), "set_offset_noise", "get_offset_noise");
ClassDB::bind_method(D_METHOD("get_offset_noise_strength"), &TiledWallData::get_offset_noise_strength);
ClassDB::bind_method(D_METHOD("set_offset_noise_strength", "texture"), &TiledWallData::set_offset_noise_strength);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_noise_strength"), "set_offset_noise_strength", "get_offset_noise_strength");
ClassDB::bind_method(D_METHOD("get_offset_noise_randomize_seed"), &TiledWallData::get_offset_noise_randomize_seed);
ClassDB::bind_method(D_METHOD("set_offset_noise_randomize_seed", "texture"), &TiledWallData::set_offset_noise_randomize_seed);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "offset_noise_randomize_seed"), "set_offset_noise_randomize_seed", "get_offset_noise_randomize_seed");
ClassDB::bind_method(D_METHOD("get_offset_noise_skip_edges"), &TiledWallData::get_offset_noise_skip_edges);
ClassDB::bind_method(D_METHOD("set_offset_noise_skip_edges", "texture"), &TiledWallData::set_offset_noise_skip_edges);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "offset_noise_skip_edges"), "set_offset_noise_skip_edges", "get_offset_noise_skip_edges");
#endif
//materials
ClassDB::bind_method(D_METHOD("material_add", "value"), &TiledWallData::material_add);
ClassDB::bind_method(D_METHOD("material_set", "index", "value"), &TiledWallData::material_set);

View File

@ -44,6 +44,9 @@ class PropMesher;
#ifdef MODULE_ENTITY_SPELL_SYSTEM_ENABLED
class ESSMaterialCache;
#endif
#ifdef MODULE_FASTNOISE_ENABLED
class FastnoiseNoiseParams;
#endif
class TiledWallData : public Resource {
GDCLASS(TiledWallData, Resource);
@ -140,6 +143,20 @@ public:
float get_flavour_tile_chance() const;
void set_flavour_tile_chance(const float value);
#ifdef MODULE_FASTNOISE_ENABLED
Ref<FastnoiseNoiseParams> get_offset_noise();
void set_offset_noise(const Ref<FastnoiseNoiseParams> &val);
float get_offset_noise_strength() const;
void set_offset_noise_strength(const float val);
bool get_offset_noise_randomize_seed() const;
void set_offset_noise_randomize_seed(const bool val);
bool get_offset_noise_skip_edges() const;
void set_offset_noise_skip_edges(const bool val);
#endif
//materials
void material_add(const Ref<Material> &value);
void material_set(const int index, const Ref<Material> &value);
@ -185,6 +202,13 @@ private:
Vector<TextureEntry> _flavour_tiles;
float _flavour_chance;
#ifdef MODULE_FASTNOISE_ENABLED
Ref<FastnoiseNoiseParams> _offset_noise;
float _offset_noise_strength;
bool _offset_noise_randomize_seed;
bool _offset_noise_skip_edges;
#endif
Vector<Ref<Material>> _materials;
};