From 07afd06c2a805bf994fa756f44328527de08e217 Mon Sep 17 00:00:00 2001 From: Relintai Date: Fri, 14 Feb 2020 19:02:31 +0100 Subject: [PATCH] Now chunks can properly use multiple meshers at the same time. --- meshers/cubic_mesher/voxel_mesher_cubic.cpp | 1 + meshers/voxel_mesher.cpp | 31 ++++++++++++++++ meshers/voxel_mesher.h | 3 ++ world/voxel_chunk.cpp | 41 +++++++++++++++------ world/voxel_chunk.h | 2 +- 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/meshers/cubic_mesher/voxel_mesher_cubic.cpp b/meshers/cubic_mesher/voxel_mesher_cubic.cpp index af2aa5d..906b8d0 100644 --- a/meshers/cubic_mesher/voxel_mesher_cubic.cpp +++ b/meshers/cubic_mesher/voxel_mesher_cubic.cpp @@ -97,6 +97,7 @@ void VoxelMesherCubic::_add_chunk(Node *p_chunk) { add_color(light); add_uv((cube_points->get_point_uv_direction(face, i) + Vector2(0.5, 0.5)) * Vector2(tile_uv_size, tile_uv_size)); + add_uv2((cube_points->get_point_uv_direction(face, i) + Vector2(0.5, 0.5)) * Vector2(tile_uv_size, tile_uv_size)); add_vertex((vertices[i] * voxel_size + Vector3(x, y, z)) * voxel_scale); } diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 29b1da0..20d5b87 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -104,6 +104,7 @@ void VoxelMesher::build_mesh(RID mesh) { int len = _vertices.size(); for (int i = 0; i < len; ++i) { + if (_normals.size() > 0) { _surface_tool->add_normal(_normals.get(i)); } @@ -304,6 +305,32 @@ void VoxelMesher::add_mesh_data_resource_transform(Ref mesh, c } } +void VoxelMesher::add_mesher(const Ref &mesher) { + call("_add_mesher", mesher); +} +void VoxelMesher::_add_mesher(const Ref &mesher) { + int orig_size = _vertices.size(); + + _vertices.append_array(mesher->_vertices); + _normals.append_array(mesher->_normals); + _colors.append_array(mesher->_colors); + _uvs.append_array(mesher->_uvs); + _uv2s.append_array(mesher->_uv2s); + _bones.append_array(mesher->_bones); + + int s = mesher->_indices.size(); + + if (s == 0) + return; + + int orig_indices_size = _indices.size(); + + _indices.resize(_indices.size() + s); + for (int i = 0; i < s; ++i) { + _indices.set(i + orig_indices_size, mesher->_indices[i] + orig_size); + } +} + void VoxelMesher::bake_colors_bind(Node *chunk) { VoxelChunk *vchunk = Object::cast_to(chunk); @@ -790,6 +817,10 @@ void VoxelMesher::_bind_methods() { ClassDB::bind_method(D_METHOD("add_mesh_data_resource", "mesh", "position", "rotation", "scale", "uv_rect"), &VoxelMesher::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"), &VoxelMesher::add_mesh_data_resource_transform, DEFVAL(Rect2(0, 0, 1, 1))); + BIND_VMETHOD(MethodInfo("_add_mesher", PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher"))); + ClassDB::bind_method(D_METHOD("add_mesher", "mesher"), &VoxelMesher::add_mesher); + ClassDB::bind_method(D_METHOD("_add_mesher", "mesher"), &VoxelMesher::_add_mesher); + ClassDB::bind_method(D_METHOD("bake_colors", "chunk"), &VoxelMesher::bake_colors_bind); ClassDB::bind_method(D_METHOD("_bake_colors", "chunk"), &VoxelMesher::_bake_colors); diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h index 0c25661..cdbf9ce 100644 --- a/meshers/voxel_mesher.h +++ b/meshers/voxel_mesher.h @@ -87,6 +87,9 @@ public: 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)); void add_mesh_data_resource_transform(Ref mesh, const Transform transform, const Rect2 uv_rect = Rect2(0, 0, 1, 1)); + void add_mesher(const Ref &mesher); + void _add_mesher(const Ref &mesher); + void bake_colors_bind(Node *chunk); void bake_colors(VoxelChunk *chunk); void _bake_colors(Node *p_chunk); diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index 89d4b30..00fca44 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -275,7 +275,7 @@ void VoxelChunk::_setup_channels() { set_channel_count(MAX_DEFAULT_CHANNELS); } -void VoxelChunk::set_size(int size_x, int size_y, int size_z, int margin_start, int margin_end) { +void VoxelChunk::set_size(uint32_t size_x, uint32_t size_y, uint32_t size_z, uint32_t margin_start, uint32_t margin_end) { if (_size_x == size_x && _size_y == size_y && _size_z == size_z && _margin_start == margin_start && _margin_end == margin_end) { return; } @@ -383,7 +383,7 @@ void VoxelChunk::fill_channel(uint8_t value, int channel_index) { uint32_t size = get_data_size(); - for (int i = 0; i < size; ++i) { + for (uint32_t i = 0; i < size; ++i) { ch[i] = value; } } @@ -467,16 +467,20 @@ void VoxelChunk::add_light(int local_x, int local_y, int local_z, int size, Colo //float gf = (color.g / sizef); //float bf = (color.b / sizef); + int64_t dsx = static_cast(_data_size_x); + int64_t dsy = static_cast(_data_size_y); + int64_t dsz = static_cast(_data_size_z); + for (int y = local_y - size; y <= local_y + size; ++y) { - if (y < 0 || y >= _data_size_y) + if (y < 0 || y >= dsy) continue; for (int z = local_z - size; z <= local_z + size; ++z) { - if (z < 0 || z >= _data_size_z) + if (z < 0 || z >= dsz) continue; for (int x = local_x - size; x <= local_x + size; ++x) { - if (x < 0 || x >= _data_size_x) + if (x < 0 || x >= dsx) continue; int lx = x - local_x; @@ -549,14 +553,25 @@ void VoxelChunk::finalize_mesh() { allocate_main_mesh(); } + Ref mesher; for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); + Ref m = _meshers.get(i); - ERR_CONTINUE(!mesher.is_valid()); + ERR_CONTINUE(!m.is_valid()); + + if (!mesher.is_valid()) { + mesher = m; + mesher->set_material(get_library()->get_material()); + continue; + } mesher->set_material(get_library()->get_material()); - mesher->build_mesh(_mesh_rid); + mesher->add_mesher(m); } + + ERR_FAIL_COND(!mesher.is_valid()); + + mesher->build_mesh(_mesh_rid); } void VoxelChunk::build_deferred() { @@ -1186,9 +1201,13 @@ void VoxelChunk::draw_debug_voxels(int max, Color color) { int a = 0; - for (int y = 0; y < _size_y; ++y) { - for (int z = 0; z < _size_z; ++z) { - for (int x = 0; x < _size_x; ++x) { + int64_t sx = static_cast(_size_x); + int64_t sy = static_cast(_size_y); + int64_t sz = static_cast(_size_y); + + for (int y = 0; y < sy; ++y) { + for (int z = 0; z < sz; ++z) { + for (int x = 0; x < sx; ++x) { int type = get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index d365b9b..75e88a7 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -192,7 +192,7 @@ public: void setup_channels(); void _setup_channels(); - void set_size(int size_x, int size_y, int size_z, int margin_start = 0, int margin_end = 0); + void set_size(uint32_t size_x, uint32_t size_y, uint32_t size_z, uint32_t margin_start = 0, uint32_t margin_end = 0); bool validate_channel_data_position(uint32_t x, uint32_t y, uint32_t z) const;