Implemented TiledWall meshing.

This commit is contained in:
Relintai 2021-08-18 16:07:03 +02:00
parent 78f049e8c9
commit 4d7d66e969
3 changed files with 119 additions and 0 deletions

View File

@ -25,6 +25,9 @@ SOFTWARE.
#include "lights/prop_light.h"
#include "modules/opensimplex/open_simplex_noise.h"
#include "material_cache/prop_material_cache.h"
#include "tiled_wall/tiled_wall_data.h"
const String PropMesher::BINDING_STRING_BUILD_FLAGS = "Use Lighting,Use AO,Use RAO,Bake Lights";
bool PropMesher::Vertex::operator==(const Vertex &p_vertex) const {
@ -463,6 +466,111 @@ void PropMesher::reset() {
_last_tangent = Plane();
}
void PropMesher::add_tiled_wall_simple(const int width, const int height, const Transform &transform, const Ref<TiledWallData> &tiled_wall_data, const Ref<PropMaterialCache> &cache) {
ERR_FAIL_COND(!tiled_wall_data.is_valid());
ERR_FAIL_COND(!cache.is_valid());
ERR_FAIL_COND(width < 0);
ERR_FAIL_COND(height < 0);
if (tiled_wall_data->get_texture_count() == 0) {
return;
}
//collect rects
Vector<Rect2> normal_rects;
Vector<Rect2> flavour_rects;
//fallback
if (normal_rects.size() == 0) {
normal_rects.push_back(Rect2(0, 0, 1, 1));
}
TiledWallData::TiledWallTilingType tiling_type = tiled_wall_data->get_tiling_type();
//todo implement flavour!
if (tiling_type == TiledWallData::TILED_WALL_TILING_TYPE_NONE) {
Rect2 r = normal_rects[0];
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r);
}
}
} else if (tiling_type == TiledWallData::TILED_WALL_TILING_TYPE_HORIZONTAL) {
Rect2 r;
for (int x = 0; x < width; ++x) {
r = normal_rects[x % normal_rects.size()];
for (int y = 0; y < height; ++y) {
add_tiled_wall_mesh_rect_simple(x, y, transform, r);
}
}
} else if (tiling_type == TiledWallData::TILED_WALL_TILING_TYPE_VERTICAL) {
Rect2 r;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
r = normal_rects[y % normal_rects.size()];
add_tiled_wall_mesh_rect_simple(x, y, transform, r);
}
}
} else if (tiling_type == TiledWallData::TILED_WALL_TILING_TYPE_BOTH) {
Rect2 r;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
r = normal_rects[(x + y) % normal_rects.size()];
add_tiled_wall_mesh_rect_simple(x, y, transform, r);
}
}
}
}
void PropMesher::add_tiled_wall_mesh_rect_simple(const int x, const int y, const Transform &transform, const Rect2 &texture_rect) {
//x + 1, y
add_normal(transform.xform(Vector3(0, 0, 1)));
add_uv(transform_uv(Vector2(1, 1), texture_rect));
add_vertex(transform.xform(Vector3(x + 1, y, 0)));
//x, y
add_normal(transform.xform(Vector3(0, 0, 1)));
add_uv(transform_uv(Vector2(0, 1), texture_rect));
add_vertex(transform.xform(Vector3(x, y, 0)));
//x, y + 1
add_normal(transform.xform(Vector3(0, 0, 1)));
add_uv(transform_uv(Vector2(0, 0), texture_rect));
add_vertex(transform.xform(Vector3(x, y + 1, 0)));
//x + 1, y + 1
add_normal(transform.xform(Vector3(0, 0, 1)));
add_uv(transform_uv(Vector2(1, 0), texture_rect));
add_vertex(transform.xform(Vector3(x + 1, y + 1, 0)));
int vc = get_vertex_count();
add_indices(vc + 2);
add_indices(vc + 1);
add_indices(vc + 0);
add_indices(vc + 3);
add_indices(vc + 2);
add_indices(vc + 0);
}
_FORCE_INLINE_ Vector2 PropMesher::transform_uv(const Vector2 &uv, const Rect2 &rect) const {
Vector2 ruv = uv;
ruv.x *= rect.size.x;
ruv.y *= rect.size.y;
ruv.x += rect.position.x;
ruv.y += rect.position.y;
return ruv;
}
#ifdef MESH_DATA_RESOURCE_PRESENT
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);
@ -1172,6 +1280,10 @@ void PropMesher::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_build_flags", "value"), &PropMesher::set_build_flags);
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", "transform", "texture_rect"), &PropMesher::add_tiled_wall_mesh_rect_simple);
ClassDB::bind_method(D_METHOD("transform_uv", "uv", "rect"), &PropMesher::transform_uv);
#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)));

View File

@ -62,6 +62,8 @@ using PoolVector = Vector<N>;
class OpenSimplexNoise;
class PropLight;
class PropMaterialCache;
class TiledWallData;
class PropMesher : public Reference {
GDCLASS(PropMesher, Reference);
@ -143,6 +145,10 @@ public:
void reset();
void add_tiled_wall_simple(const int width, const int height, const Transform &transform, const Ref<TiledWallData> &tiled_wall_data, const Ref<PropMaterialCache> &cache);
void add_tiled_wall_mesh_rect_simple(const int x, const int y, const Transform &transform, const Rect2 &texture_rect);
Vector2 transform_uv(const Vector2 &uv, const Rect2 &rect) const;
#ifdef MESH_DATA_RESOURCE_PRESENT
void add_mesh_data_resource(Ref<MeshDataResource> 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));
void add_mesh_data_resource_transform(Ref<MeshDataResource> mesh, const Transform transform, const Rect2 uv_rect = Rect2(0, 0, 1, 1));

View File

@ -155,6 +155,7 @@ void TiledWall::generate_mesh() {
}
//_mesher->tiled wall mesh_wimple(w, h, TWD, cache)
_mesher->add_tiled_wall_simple(_width, _height, Transform(), _data, _cache);
_mesh_array = _mesher->build_mesh();