From 1a7c404a1711e6141e39626e19981235e4a61770 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 31 Jul 2022 14:47:23 +0200 Subject: [PATCH] Implemented texture scale for TiledWalls. --- modules/props/prop_mesher.cpp | 111 +++++++++++-------- modules/props/prop_mesher.h | 3 +- modules/props/tiled_wall/tiled_wall_data.cpp | 11 ++ modules/props/tiled_wall/tiled_wall_data.h | 44 ++++---- 4 files changed, 101 insertions(+), 68 deletions(-) diff --git a/modules/props/prop_mesher.cpp b/modules/props/prop_mesher.cpp index b9b249a9a..62e66d6d0 100644 --- a/modules/props/prop_mesher.cpp +++ b/modules/props/prop_mesher.cpp @@ -376,7 +376,7 @@ void PropMesher::remove_doubles() { void PropMesher::remove_doubles_hashed() { if (_vertices.size() == 0) { return; - } + } //print_error("before " + String::num(_vertices.size())); @@ -454,18 +454,15 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const //collect rects LocalVector normal_rects; LocalVector flavour_rects; - LocalVector normal_y_sizes; - LocalVector flavour_y_sizes; - LocalVector normal_z_offsets; - LocalVector flavour_z_offsets; + LocalVector normal_data; + LocalVector flavour_data; for (int i = 0; i < tiled_wall_data->get_tile_count(); ++i) { const Ref &t = tiled_wall_data->get_tile_texture(i); if (t.is_valid()) { normal_rects.push_back(cache->texture_get_uv_rect(t)); - normal_y_sizes.push_back(tiled_wall_data->get_tile_y_size(i)); - normal_z_offsets.push_back(tiled_wall_data->get_tile_z_offset(i)); + normal_data.push_back(tiled_wall_data->get_tile(i)); } } @@ -474,8 +471,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const if (t.is_valid()) { flavour_rects.push_back(cache->texture_get_uv_rect(t)); - flavour_y_sizes.push_back(tiled_wall_data->get_flavour_tile_y_size(i)); - flavour_z_offsets.push_back(tiled_wall_data->get_flavour_tile_z_offset(i)); + flavour_data.push_back(tiled_wall_data->get_flavour_tile(i)); } } @@ -488,7 +484,8 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const if (tiling_type == TiledWallData::TILED_WALL_TILING_TYPE_NONE) { Rect2 r = normal_rects[0]; - float yh = normal_y_sizes[0]; + float yh = normal_data[0].y_size; + int texture_scale = normal_data[0].texture_scale; if (flavour_rects.size() == 0) { //no flavours @@ -496,7 +493,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const float ych = 0; for (int y = 0; y < height; ++y) { - add_tiled_wall_mesh_rect_simple(x, ych, yh, 0, 0, transform, r); + add_tiled_wall_mesh_rect_simple(x, ych, yh, 0, 0, transform, r, texture_scale); ych += yh; } @@ -508,14 +505,14 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const 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); + add_tiled_wall_mesh_rect_simple(x, ych, yh, 0, 0, transform, r, texture_scale); ych += yh; } else { int indx = Math::rand() % flavour_rects.size(); - float fyh = flavour_y_sizes[indx]; - add_tiled_wall_mesh_rect_simple(x, ych, fyh, 0, 0, transform, flavour_rects[indx]); + 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); ych += fyh; } @@ -531,13 +528,14 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const int indx = x % normal_rects.size(); r = normal_rects[indx]; - float ysize = normal_y_sizes[indx]; - float z_offset = normal_z_offsets[indx]; + float ysize = normal_data[indx].y_size; + float z_offset = normal_data[indx].z_offset; + int texture_scale = normal_data[indx].texture_scale; float cys = 0; for (int y = 0; y < height; ++y) { - add_tiled_wall_mesh_rect_simple(x, cys, ysize, z_offset, z_offset, transform, r); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, z_offset, z_offset, transform, r, texture_scale); cys += ysize; } @@ -548,20 +546,21 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const int indx = x % normal_rects.size(); r = normal_rects[indx]; - float ysize = normal_y_sizes[indx]; + float ysize = normal_data[indx].y_size; + int texture_scale = normal_data[indx].texture_scale; float cys = 0; for (int y = 0; y < height; ++y) { if (Math::randf() > flavour_chance) { - add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, r); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, r, texture_scale); cys += ysize; } else { int findx = Math::rand() % flavour_rects.size(); - float yh = flavour_y_sizes[findx]; + float yh = flavour_data[findx].y_size; - add_tiled_wall_mesh_rect_simple(x, cys, yh, 0, 0, transform, flavour_rects[findx]); + add_tiled_wall_mesh_rect_simple(x, cys, yh, 0, 0, transform, flavour_rects[findx], flavour_data[indx].texture_scale); cys += yh; } @@ -583,14 +582,14 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const int indx = y % normal_rects.size(); r = normal_rects[indx]; - float ysize = normal_y_sizes[indx]; - float current_z_offset = normal_z_offsets[indx]; + float ysize = normal_data[indx].y_size; + float current_z_offset = normal_data[indx].z_offset; if (y == 0) { prev_z_offset = current_z_offset; } - add_tiled_wall_mesh_rect_simple(x, cys, ysize, prev_z_offset, current_z_offset, transform, r); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, prev_z_offset, current_z_offset, transform, r, normal_data[indx].texture_scale); cys += ysize; @@ -608,7 +607,7 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const int indx = y % normal_rects.size(); r = normal_rects[indx]; - float ysize = normal_y_sizes[indx]; + float ysize = normal_data[indx].y_size; float current_z_offset = 0; if (y == 0) { @@ -616,15 +615,15 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const } if (Math::randf() > flavour_chance) { - current_z_offset = normal_z_offsets[indx]; + current_z_offset = normal_data[indx].z_offset; - add_tiled_wall_mesh_rect_simple(x, cys, ysize, prev_z_offset, current_z_offset, transform, r); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, prev_z_offset, current_z_offset, transform, r, normal_data[indx].texture_scale); cys += ysize; } else { int findx = Math::rand() % flavour_rects.size(); - current_z_offset = flavour_z_offsets[findx]; + current_z_offset = flavour_data[findx].z_offset; - add_tiled_wall_mesh_rect_simple(x, cys, ysize, prev_z_offset, current_z_offset, transform, flavour_rects[findx]); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, prev_z_offset, current_z_offset, transform, flavour_rects[findx], flavour_data[findx].texture_scale); cys += ysize; } @@ -644,9 +643,9 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const int indx = (x + y) % normal_rects.size(); r = normal_rects[indx]; - float ysize = normal_y_sizes[indx]; + float ysize = normal_data[indx].y_size; - add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, r); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, r, normal_data[indx].texture_scale); cys += ysize; } @@ -660,16 +659,16 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const int indx = (x + y) % normal_rects.size(); r = normal_rects[indx]; - float ysize = normal_y_sizes[indx]; + float ysize = normal_data[indx].y_size; if (Math::randf() > flavour_chance) { - add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, r); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, r, normal_data[indx].texture_scale); cys += ysize; } else { int findx = Math::rand() % flavour_rects.size(); - float yh = flavour_y_sizes[findx]; + float yh = flavour_data[findx].y_size; - add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, flavour_rects[findx]); + add_tiled_wall_mesh_rect_simple(x, cys, ysize, 0, 0, transform, flavour_rects[findx], flavour_data[findx].texture_scale); cys += yh; } @@ -679,27 +678,27 @@ void PropMesher::add_tiled_wall_simple(const int width, const int height, const } } -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) { +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(); //x + 1, y add_normal(transform.basis.xform(Vector3(0, 0, -1))); - add_uv(transform_uv(Vector2(1, 1), texture_rect)); + add_uv(transform_uv_scaled(Vector2(1, 1), texture_rect, x, y, texture_scale)); add_vertex(transform.xform(Vector3(x + 1, y, prev_z_offset))); //x, y add_normal(transform.basis.xform(Vector3(0, 0, -1))); - add_uv(transform_uv(Vector2(0, 1), texture_rect)); + add_uv(transform_uv_scaled(Vector2(0, 1), texture_rect, x, y, texture_scale)); add_vertex(transform.xform(Vector3(x, y, prev_z_offset))); //x, y + 1 add_normal(transform.basis.xform(Vector3(0, 0, -1))); - add_uv(transform_uv(Vector2(0, 0), texture_rect)); + add_uv(transform_uv_scaled(Vector2(0, 0), texture_rect, x, y, texture_scale)); add_vertex(transform.xform(Vector3(x, y + y_size, current_z_offset))); //x + 1, y + 1 add_normal(transform.basis.xform(Vector3(0, 0, -1))); - add_uv(transform_uv(Vector2(1, 0), texture_rect)); + add_uv(transform_uv_scaled(Vector2(1, 0), texture_rect, x, y, texture_scale)); add_vertex(transform.xform(Vector3(x + 1, y + y_size, current_z_offset))); add_indices(vc + 2); @@ -721,6 +720,25 @@ _FORCE_INLINE_ Vector2 PropMesher::transform_uv(const Vector2 &uv, const Rect2 & return ruv; } +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; + + float sizex = rect.size.x / static_cast(texture_scale); + float sizey = rect.size.y / static_cast(texture_scale); + + ruv.x *= sizex; + ruv.y *= sizey; + + ruv.x += rect.position.x + sizex * lx; + ruv.y += rect.position.y + sizey * ly; + + return ruv; +} + + #ifdef MESH_DATA_RESOURCE_PRESENT void PropMesher::add_mesh_data_resource(Ref mesh, const Vector3 position, const Vector3 rotation, const Vector3 scale, const Rect2 uv_rect) { Transform transform = Transform(Basis(rotation).scaled(scale), position); @@ -750,7 +768,7 @@ void PropMesher::add_mesh_data_resource_transform(Ref mesh, co for (int i = 0; i < vertices.size(); ++i) { if (normals.size() > 0) { add_normal(transform.basis.xform(normals[i])); - } + } if (normals.size() > 0) { Vector2 uv = uvs[i]; @@ -763,7 +781,7 @@ void PropMesher::add_mesh_data_resource_transform(Ref mesh, co if (colors.size() > 0) { add_color(colors[i]); - } + } add_vertex(transform.xform(vertices[i])); } @@ -871,11 +889,11 @@ float PropMesher::get_random_ao(const Vector3 &position) { if (val > 1) { val = 1; - } + } if (val < 0) { val = -val; - } + } return val; } @@ -1462,9 +1480,10 @@ void PropMesher::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "build_flags", PROPERTY_HINT_FLAGS, PropMesher::BINDING_STRING_BUILD_FLAGS), "set_build_flags", "get_build_flags"); ClassDB::bind_method(D_METHOD("add_tiled_wall_simple", "width", "height", "transform", "tiled_wall_data", "cache"), &PropMesher::add_tiled_wall_simple); - //ClassDB::bind_method(D_METHOD("add_tiled_wall_mesh_rect_simple", "x", "y", "y_size", "transform", "texture_rect"), &PropMesher::add_tiled_wall_mesh_rect_simple); + //ClassDB::bind_method(D_METHOD("add_tiled_wall_mesh_rect_simple", "x", "y", "y_size", "transform", "texture_rect", "texture_scale"), &PropMesher::add_tiled_wall_mesh_rect_simple); ClassDB::bind_method(D_METHOD("transform_uv", "uv", "rect"), &PropMesher::transform_uv); - + ClassDB::bind_method(D_METHOD("transform_uv_scaled", "uv", "rect", "x", "y", "texture_scale"), &PropMesher::transform_uv_scaled); + #ifdef MESH_DATA_RESOURCE_PRESENT ClassDB::bind_method(D_METHOD("add_mesh_data_resource", "mesh", "position", "rotation", "scale", "uv_rect"), &PropMesher::add_mesh_data_resource, DEFVAL(Rect2(0, 0, 1, 1)), DEFVAL(Vector3(1.0, 1.0, 1.0)), DEFVAL(Vector3()), DEFVAL(Vector3())); ClassDB::bind_method(D_METHOD("add_mesh_data_resource_transform", "mesh", "transform", "uv_rect"), &PropMesher::add_mesh_data_resource_transform, DEFVAL(Rect2(0, 0, 1, 1))); diff --git a/modules/props/prop_mesher.h b/modules/props/prop_mesher.h index 99c8efe5a..3f399aa4f 100644 --- a/modules/props/prop_mesher.h +++ b/modules/props/prop_mesher.h @@ -129,9 +129,10 @@ public: void reset(); void add_tiled_wall_simple(const int width, const int height, const Transform &transform, const Ref &tiled_wall_data, Ref cache); - void 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); + void 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); Vector2 transform_uv(const Vector2 &uv, const Rect2 &rect) const; + Vector2 transform_uv_scaled(const Vector2 &uv, const Rect2 &rect, const int x, const int y, const int texture_scale) const; #ifdef MESH_DATA_RESOURCE_PRESENT void add_mesh_data_resource(Ref mesh, const Vector3 position = Vector3(0, 0, 0), const Vector3 rotation = Vector3(0, 0, 0), const Vector3 scale = Vector3(1.0, 1.0, 1.0), const Rect2 uv_rect = Rect2(0, 0, 1, 1)); diff --git a/modules/props/tiled_wall/tiled_wall_data.cpp b/modules/props/tiled_wall/tiled_wall_data.cpp index 8aabe8cdf..8732f6ea5 100644 --- a/modules/props/tiled_wall/tiled_wall_data.cpp +++ b/modules/props/tiled_wall/tiled_wall_data.cpp @@ -79,6 +79,12 @@ void TiledWallData::remove_tile(const int index) { emit_changed(); } +TiledWallData::TextureEntry TiledWallData::get_tile(const int index) const { + ERR_FAIL_INDEX_V(index, _tiles.size(), TextureEntry()); + + return _tiles[index]; +} + Ref TiledWallData::get_tile_texture(const int index) const { ERR_FAIL_INDEX_V(index, _tiles.size(), Ref()); @@ -150,6 +156,11 @@ void TiledWallData::remove_flavour_tile(const int index) { emit_changed(); } +TiledWallData::TextureEntry TiledWallData::get_flavour_tile(const int index) const { + ERR_FAIL_INDEX_V(index, _flavour_tiles.size(), TextureEntry()); + + return _flavour_tiles[index]; +} Ref TiledWallData::get_flavour_tile_texture(const int index) const { ERR_FAIL_INDEX_V(index, _flavour_tiles.size(), Ref()); diff --git a/modules/props/tiled_wall/tiled_wall_data.h b/modules/props/tiled_wall/tiled_wall_data.h index 31204e02d..160516227 100644 --- a/modules/props/tiled_wall/tiled_wall_data.h +++ b/modules/props/tiled_wall/tiled_wall_data.h @@ -59,6 +59,26 @@ public: TILED_WALL_COLLIDER_TYPE_CONCAVE_MESH }; + struct TextureEntry { + Ref texture; + float y_size; + float z_offset; + int texture_scale; + + TextureEntry() { + y_size = 1; + z_offset = 0; + texture_scale = 1; + } + + TextureEntry(const Ref &p_texture, const float p_y_size = 1, const float p_z_offset = 0, const float p_texture_scale = 0) { + texture = p_texture; + y_size = p_y_size; + z_offset = p_z_offset; + texture_scale = p_texture_scale; + } + }; + static const String BINDING_STRING_TILED_WALL_TILING_TYPE; static const String BINDING_STRING_TILED_WALL_COLLIDER_TYPE; @@ -75,6 +95,7 @@ public: //textures void add_tile(const Ref &texture, const float y_size = 1, const float z_offset = 0, const int texture_scale = 1); void remove_tile(const int index); + TextureEntry get_tile(const int index) const; Ref get_tile_texture(const int index) const; void set_tile_texture(const int index, const Ref &texture); @@ -92,8 +113,9 @@ public: void set_tile_count(const int count); //flavour_textures - void add_flavour_tile(const Ref &texture, const float y_size =1, const float z_offset = 0, const int texture_scale = 1); + void add_flavour_tile(const Ref &texture, const float y_size = 1, const float z_offset = 0, const int texture_scale = 1); void remove_flavour_tile(const int index); + TextureEntry get_flavour_tile(const int index) const; Ref get_flavour_tile_texture(const int index) const; void set_flavour_tile_texture(const int index, const Ref &texture); @@ -145,26 +167,6 @@ protected: static void _bind_methods(); private: - struct TextureEntry { - Ref texture; - float y_size; - float z_offset; - int texture_scale; - - TextureEntry() { - y_size = 1; - z_offset = 0; - texture_scale = 1; - } - - TextureEntry(const Ref &p_texture, const float p_y_size = 1, const float p_z_offset = 0, const float p_texture_scale = 0) { - texture = p_texture; - y_size = p_y_size; - z_offset = p_z_offset; - texture_scale = p_texture_scale; - } - }; - TiledWallTilingType _tiling_type; TiledWallColliderType _collider_type; float _colldier_z_offset;