Make 2d tiled walls pixel perfect, just like the engine expects.

This commit is contained in:
Relintai 2022-02-23 08:59:52 +01:00
parent b9b151414a
commit 5e12fc6525
4 changed files with 67 additions and 30 deletions

View File

@ -129,6 +129,15 @@ Ref<AtlasTexture> Prop2DMaterialCache::texture_get_atlas(const int index) {
Ref<AtlasTexture> Prop2DMaterialCache::texture_get_atlas_tex(const Ref<Texture> &texture) { Ref<AtlasTexture> Prop2DMaterialCache::texture_get_atlas_tex(const Ref<Texture> &texture) {
return Ref<AtlasTexture>(); return Ref<AtlasTexture>();
} }
Rect2 Prop2DMaterialCache::texture_get_rect(const Ref<Texture> &texture) {
Ref<AtlasTexture> at = texture_get_atlas_tex(texture);
if (!at.is_valid()) {
return Rect2();
}
return at->get_region();
}
Rect2 Prop2DMaterialCache::texture_get_uv_rect(const Ref<Texture> &texture) { Rect2 Prop2DMaterialCache::texture_get_uv_rect(const Ref<Texture> &texture) {
return Rect2(0, 0, 1, 1); return Rect2(0, 0, 1, 1);
} }

View File

@ -68,6 +68,7 @@ public:
virtual Ref<Texture> texture_get(const int index); virtual Ref<Texture> texture_get(const int index);
virtual Ref<AtlasTexture> texture_get_atlas(const int index); virtual Ref<AtlasTexture> texture_get_atlas(const int index);
virtual Ref<AtlasTexture> texture_get_atlas_tex(const Ref<Texture> &texture); virtual Ref<AtlasTexture> texture_get_atlas_tex(const Ref<Texture> &texture);
virtual Rect2 texture_get_rect(const Ref<Texture> &texture);
virtual Rect2 texture_get_uv_rect(const Ref<Texture> &texture); virtual Rect2 texture_get_uv_rect(const Ref<Texture> &texture);
virtual Ref<Texture> texture_get_merged(); virtual Ref<Texture> texture_get_merged();

View File

@ -358,12 +358,15 @@ void Prop2DMesher::add_tiled_wall_simple(const int width, const int height, cons
//collect rects //collect rects
Vector<Rect2> normal_rects; Vector<Rect2> normal_rects;
Vector<Rect2> flavour_rects; Vector<Rect2> flavour_rects;
Vector<Vector2> normal_sizes;
Vector<Vector2> flavour_sizes;
for (int i = 0; i < tiled_wall_data->get_texture_count(); ++i) { for (int i = 0; i < tiled_wall_data->get_texture_count(); ++i) {
const Ref<Texture> &t = tiled_wall_data->get_texture(i); const Ref<Texture> &t = tiled_wall_data->get_texture(i);
if (t.is_valid()) { if (t.is_valid()) {
normal_rects.push_back(cache->texture_get_uv_rect(t)); normal_rects.push_back(cache->texture_get_uv_rect(t));
normal_sizes.push_back(cache->texture_get_rect(t).size);
} }
} }
@ -372,26 +375,27 @@ void Prop2DMesher::add_tiled_wall_simple(const int width, const int height, cons
if (t.is_valid()) { if (t.is_valid()) {
flavour_rects.push_back(cache->texture_get_uv_rect(t)); flavour_rects.push_back(cache->texture_get_uv_rect(t));
flavour_sizes.push_back(cache->texture_get_rect(t).size);
} }
} }
//fallback //fallback
if (normal_rects.size() == 0) { if (normal_rects.size() == 0) {
normal_rects.push_back(Rect2(0, 0, 1, 1)); normal_rects.push_back(Rect2(0, 0, 1, 1));
normal_sizes.push_back(Vector2(1, 1));
} }
TiledWall2DData::TiledWall2DTilingType tiling_type = tiled_wall_data->get_tiling_type(); TiledWall2DData::TiledWall2DTilingType tiling_type = tiled_wall_data->get_tiling_type();
//todo implement flavour!
if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_NONE) { if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_NONE) {
Rect2 r = normal_rects[0]; Rect2 r = normal_rects[0];
Vector2 rs = normal_sizes[0];
if (flavour_rects.size() == 0) { if (flavour_rects.size() == 0) {
//no flavours //no flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} }
} }
} else { } else {
@ -399,87 +403,107 @@ void Prop2DMesher::add_tiled_wall_simple(const int width, const int height, cons
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
if (Math::randf() > flavour_chance) { if (Math::randf() > flavour_chance) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} else { } else {
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[Math::rand() % flavour_rects.size()]); int ind = Math::rand() % flavour_rects.size();
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[ind], flavour_sizes[ind]);
} }
} }
} }
} }
} else if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_HORIZONTAL) { } else if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_HORIZONTAL) {
Rect2 r; Rect2 r;
Vector2 rs;
if (flavour_rects.size() == 0) { if (flavour_rects.size() == 0) {
//no flavours //no flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
r = normal_rects[x % normal_rects.size()]; int ind = x % normal_rects.size();
r = normal_rects[ind];
rs = normal_sizes[ind];
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} }
} }
} else { } else {
//has flavours //has flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
r = normal_rects[x % normal_rects.size()]; int ind = x % normal_rects.size();
r = normal_rects[ind];
rs = normal_sizes[ind];
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
if (Math::randf() > flavour_chance) { if (Math::randf() > flavour_chance) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} else { } else {
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[Math::rand() % flavour_rects.size()]); int find = Math::rand() % flavour_rects.size();
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[find], flavour_sizes[find]);
} }
} }
} }
} }
} else if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_VERTICAL) { } else if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_VERTICAL) {
Rect2 r; Rect2 r;
Vector2 rs;
if (flavour_rects.size() == 0) { if (flavour_rects.size() == 0) {
//no flavours //no flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
r = normal_rects[y % normal_rects.size()]; int ind = y % normal_rects.size();
r = normal_rects[ind];
rs = normal_sizes[ind];
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} }
} }
} else { } else {
//has flavours //has flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
r = normal_rects[y % normal_rects.size()]; int ind = y % normal_rects.size();
r = normal_rects[ind];
rs = normal_sizes[ind];
if (Math::randf() > flavour_chance) { if (Math::randf() > flavour_chance) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} else { } else {
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[Math::rand() % flavour_rects.size()]); int find = Math::rand() % flavour_rects.size();
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[find], flavour_sizes[find]);
} }
} }
} }
} }
} else if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_BOTH) { } else if (tiling_type == TiledWall2DData::TILED_WALL_TILING_TYPE_BOTH) {
Rect2 r; Rect2 r;
Vector2 rs;
if (flavour_rects.size() == 0) { if (flavour_rects.size() == 0) {
//no flavours //no flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
r = normal_rects[(x + y) % normal_rects.size()]; int ind = (x + y) % normal_rects.size();
r = normal_rects[ind];
rs = normal_sizes[ind];
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} }
} }
} else { } else {
//has flavours //has flavours
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
r = normal_rects[(x + y) % normal_rects.size()]; int ind = (x + y) % normal_rects.size();
r = normal_rects[ind];
rs = normal_sizes[ind];
if (Math::randf() > flavour_chance) { if (Math::randf() > flavour_chance) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r); add_tiled_wall_mesh_rect_simple(x, y, transform, r, rs);
} else { } else {
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[Math::rand() % flavour_rects.size()]); int find = Math::rand() % flavour_rects.size();
add_tiled_wall_mesh_rect_simple(x, y, transform, flavour_rects[find], flavour_sizes[find]);
} }
} }
} }
@ -487,24 +511,27 @@ void Prop2DMesher::add_tiled_wall_simple(const int width, const int height, cons
} }
} }
void Prop2DMesher::add_tiled_wall_mesh_rect_simple(const int x, const int y, const Transform2D &transform, const Rect2 &texture_rect) { void Prop2DMesher::add_tiled_wall_mesh_rect_simple(const int x, const int y, const Transform2D &transform, const Rect2 &texture_uv_rect, const Vector2 &size) {
int vc = get_vertex_count(); int vc = get_vertex_count();
int sx = x * size.x;
int sy = y * size.y;
//x + 1, y //x + 1, y
add_uv(transform_uv(Vector2(1, 0), texture_rect)); add_uv(transform_uv(Vector2(1, 0), texture_uv_rect));
add_vertex(transform.xform(Vector2(x + 1, y))); add_vertex(transform.xform(Vector2(sx + size.x, sy)));
//x, y //x, y
add_uv(transform_uv(Vector2(0, 0), texture_rect)); add_uv(transform_uv(Vector2(0, 0), texture_uv_rect));
add_vertex(transform.xform(Vector2(x, y))); add_vertex(transform.xform(Vector2(sx, sy)));
//x, y + 1 //x, y + 1
add_uv(transform_uv(Vector2(0, 1), texture_rect)); add_uv(transform_uv(Vector2(0, 1), texture_uv_rect));
add_vertex(transform.xform(Vector2(x, y + 1))); add_vertex(transform.xform(Vector2(sx, sy + size.y)));
//x + 1, y + 1 //x + 1, y + 1
add_uv(transform_uv(Vector2(1, 1), texture_rect)); add_uv(transform_uv(Vector2(1, 1), texture_uv_rect));
add_vertex(transform.xform(Vector2(x + 1, y + 1))); add_vertex(transform.xform(Vector2(sx + size.x, sy + size.y)));
add_indices(vc + 2); add_indices(vc + 2);
add_indices(vc + 1); add_indices(vc + 1);

View File

@ -133,7 +133,7 @@ public:
void reset(); void reset();
void add_tiled_wall_simple(const int width, const int height, const Transform2D &transform, const Ref<TiledWall2DData> &tiled_wall_data, Ref<Prop2DMaterialCache> cache); void add_tiled_wall_simple(const int width, const int height, const Transform2D &transform, const Ref<TiledWall2DData> &tiled_wall_data, Ref<Prop2DMaterialCache> cache);
void add_tiled_wall_mesh_rect_simple(const int x, const int y, const Transform2D &transform, const Rect2 &texture_rect); void add_tiled_wall_mesh_rect_simple(const int x, const int y, const Transform2D &transform, const Rect2 &texture_uv_rect, const Vector2 &size);
Vector2 transform_uv(const Vector2 &uv, const Rect2 &rect) const; Vector2 transform_uv(const Vector2 &uv, const Rect2 &rect) const;
#ifdef MESH_DATA_RESOURCE_PRESENT #ifdef MESH_DATA_RESOURCE_PRESENT