From e4e38c0bde1c100ae334a9b596d2c7ec48ecd1f9 Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 17 Jul 2019 02:28:16 +0200 Subject: [PATCH] Work on lights, and cleanups. --- data/voxel_light.cpp | 23 --- data/voxel_light.h | 6 - meshers/cubic_mesher/voxel_cube_points.cpp | 35 +++- meshers/cubic_mesher/voxel_cube_points.h | 4 + meshers/voxel_mesher.cpp | 4 +- world/voxel_buffer.cpp | 141 ++++++++------ world/voxel_buffer.h | 13 +- world/voxel_chunk.cpp | 204 ++++++++++++++++----- world/voxel_chunk.h | 49 ++++- 9 files changed, 328 insertions(+), 151 deletions(-) diff --git a/data/voxel_light.cpp b/data/voxel_light.cpp index 9506b92..6756427 100644 --- a/data/voxel_light.cpp +++ b/data/voxel_light.cpp @@ -1,23 +1,5 @@ #include "voxel_light.h" -int VoxelLight::get_chunk_position_x() { - return _chunk_position.x; -} -int VoxelLight::get_chunk_position_y() { - return _chunk_position.y; -} -int VoxelLight::get_chunk_position_z() { - return _chunk_position.z; -} -Vector3i VoxelLight::get_chunk_position() { - return _chunk_position; -} -void VoxelLight::set_chunk_position(int x, int y, int z) { - _chunk_position.x = x; - _chunk_position.y = y; - _chunk_position.z = z; -} - int VoxelLight::get_world_position_x() { return _world_position.x; } @@ -62,11 +44,6 @@ VoxelLight::~VoxelLight() { } void VoxelLight::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_chunk_position_x"), &VoxelLight::get_chunk_position_x); - ClassDB::bind_method(D_METHOD("get_chunk_position_y"), &VoxelLight::get_chunk_position_y); - ClassDB::bind_method(D_METHOD("get_chunk_position_z"), &VoxelLight::get_chunk_position_z); - ClassDB::bind_method(D_METHOD("set_chunk_position", "x", "y", "z"), &VoxelLight::set_chunk_position); - ClassDB::bind_method(D_METHOD("get_world_position_x"), &VoxelLight::get_world_position_x); ClassDB::bind_method(D_METHOD("get_world_position_y"), &VoxelLight::get_world_position_y); ClassDB::bind_method(D_METHOD("get_world_position_z"), &VoxelLight::get_world_position_z); diff --git a/data/voxel_light.h b/data/voxel_light.h index 6ec4ad8..598d911 100644 --- a/data/voxel_light.h +++ b/data/voxel_light.h @@ -11,12 +11,6 @@ class VoxelLight : public Reference { GDCLASS(VoxelLight, Reference); public: - int get_chunk_position_x(); - int get_chunk_position_y(); - int get_chunk_position_z(); - Vector3i get_chunk_position(); - void set_chunk_position(int x, int y, int z); - int get_world_position_x(); int get_world_position_y(); int get_world_position_z(); diff --git a/meshers/cubic_mesher/voxel_cube_points.cpp b/meshers/cubic_mesher/voxel_cube_points.cpp index ba69d0f..7be5930 100644 --- a/meshers/cubic_mesher/voxel_cube_points.cpp +++ b/meshers/cubic_mesher/voxel_cube_points.cpp @@ -436,6 +436,15 @@ void VoxelCubePoints::setup(const Ref buffer, int x, int y, int z, _point_aos[P011] = buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_AO); _point_aos[P101] = buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_AO); _point_aos[P111] = buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_AO); + + _point_colors[P000] = Color(buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P100] = Color(buffer->get_voxel(x + size, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x + size, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x + size, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P010] = Color(buffer->get_voxel(x, y + size, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x, y + size, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x, y + size, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P001] = Color(buffer->get_voxel(x, y, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x, y, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x, y, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P110] = Color(buffer->get_voxel(x + size, y + size, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x + size, y + size, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x + size, y + size, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P011] = Color(buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P101] = Color(buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P111] = Color(buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); refresh_neighbours(buffer); @@ -585,6 +594,27 @@ int VoxelCubePoints::get_face_point_ao(int face, int index) { return _point_aos[indx]; } +Color VoxelCubePoints::get_face_point_ao_color(int face, int index) { + int indx = get_point_index(face, index); + + float ao_value = (_point_aos[indx] / 255.0) * 0.75; + + return Color(ao_value, ao_value, ao_value); +} + +Color VoxelCubePoints::get_face_point_light_color(int face, int index) { + int indx = get_point_index(face, index); + + return _point_colors[indx]; +} +Color VoxelCubePoints::get_face_point_color_mixed(int face, int index) { + int indx = get_point_index(face, index); + + float ao_value = (_point_aos[indx] / 255.0) * 0.75; + + return _point_colors[indx] - Color(ao_value, ao_value, ao_value); +} + Vector3 VoxelCubePoints::get_point(int index) { ERR_FAIL_INDEX_V(index, POINT_COUNT, Vector3()); @@ -753,7 +783,10 @@ void VoxelCubePoints::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_ao", "index"), &VoxelCubePoints::get_point_ao); ClassDB::bind_method(D_METHOD("get_face_point_ao", "face", "index"), &VoxelCubePoints::get_face_point_ao); - + ClassDB::bind_method(D_METHOD("get_face_point_ao_color", "face", "index"), &VoxelCubePoints::get_face_point_ao_color); + ClassDB::bind_method(D_METHOD("get_face_point_light_color", "face", "index"), &VoxelCubePoints::get_face_point_light_color); + ClassDB::bind_method(D_METHOD("get_face_point_color_mixed", "face", "index"), &VoxelCubePoints::get_face_point_color_mixed); + ClassDB::bind_method(D_METHOD("get_point", "index"), &VoxelCubePoints::get_point); ClassDB::bind_method(D_METHOD("get_top_left_point", "face"), &VoxelCubePoints::get_top_left_point); diff --git a/meshers/cubic_mesher/voxel_cube_points.h b/meshers/cubic_mesher/voxel_cube_points.h index c2bd9e5..89233b4 100644 --- a/meshers/cubic_mesher/voxel_cube_points.h +++ b/meshers/cubic_mesher/voxel_cube_points.h @@ -116,6 +116,9 @@ public: int get_point_ao(int index); int get_face_point_ao(int face, int index); + Color get_face_point_ao_color(int face, int index); + Color get_face_point_light_color(int face, int index); + Color get_face_point_color_mixed(int face, int index); Vector3 get_point(int index); Vector3 get_top_left_point(int face); @@ -144,6 +147,7 @@ private: uint8_t _point_types[POINT_COUNT]; uint8_t _point_fills[POINT_COUNT]; uint8_t _point_aos[POINT_COUNT]; + Color _point_colors[POINT_COUNT]; unsigned int _point_neighbours[POINT_COUNT]; int _size; diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 224ab05..2ba70d4 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -136,7 +136,7 @@ void VoxelMesher::bake_lights(MeshInstance *node, Vector > &ligh for (int i = 0; i < lights.size(); ++i) { Ref light = lights.get(i); - Vector3 lightDir = light->get_world_position() - vertex; + Vector3 lightDir = light->get_world_position().to_vec3() - vertex; float dist2 = lightDir.dot(lightDir); //inverse sqrt @@ -155,7 +155,7 @@ void VoxelMesher::bake_lights(MeshInstance *node, Vector > &ligh Vector3 value = cv * (NdotL / (1.0 + dist2)); - value *= light->get_strength(); + value *= light->get_size(); v_lightDiffuse += value; /* diff --git a/world/voxel_buffer.cpp b/world/voxel_buffer.cpp index a33dd2b..2788d00 100644 --- a/world/voxel_buffer.cpp +++ b/world/voxel_buffer.cpp @@ -25,7 +25,6 @@ const char *VoxelBuffer::CHANNEL_ID_HINT_STRING = "Type,Sdf,Data2,Data3,Data4,Data5,Data6,Data7"; VoxelBuffer::VoxelBuffer() { - _channels[CHANNEL_ISOLEVEL].defval = 255; } VoxelBuffer::~VoxelBuffer() { @@ -285,57 +284,91 @@ uint8_t *VoxelBuffer::get_channel_raw(unsigned int channel_index) const { } void VoxelBuffer::generate_ao() { - unsigned int size_x = _size.x; - unsigned int size_y = _size.y; - unsigned int size_z = _size.z; - - ERR_FAIL_COND(size_x == 0 || size_y == 0 || size_z == 0); - - for (unsigned int y = 1; y < size_y - 1; ++y) { - for (unsigned int z = 1; z < size_z - 1; ++z) { - for (unsigned int x = 1; x < size_x - 1; ++x) { - int current = get_voxel(x, y, z, CHANNEL_ISOLEVEL); - - int sum = get_voxel(x + 1, y, z, CHANNEL_ISOLEVEL); - sum += get_voxel(x - 1, y, z, CHANNEL_ISOLEVEL); - sum += get_voxel(x, y + 1, z, CHANNEL_ISOLEVEL); - sum += get_voxel(x, y - 1, z, CHANNEL_ISOLEVEL); - sum += get_voxel(x, y, z + 1, CHANNEL_ISOLEVEL); - sum += get_voxel(x, y, z - 1, CHANNEL_ISOLEVEL); - - sum /= 6; - - sum -= current; - - if (sum < 0) - sum = 0; - - set_voxel(sum, x, y, z, CHANNEL_AO); - } - } - } + unsigned int size_x = _size.x; + unsigned int size_y = _size.y; + unsigned int size_z = _size.z; + + ERR_FAIL_COND(size_x == 0 || size_y == 0 || size_z == 0); + + for (unsigned int y = 1; y < size_y - 1; ++y) { + for (unsigned int z = 1; z < size_z - 1; ++z) { + for (unsigned int x = 1; x < size_x - 1; ++x) { + int current = get_voxel(x, y, z, CHANNEL_ISOLEVEL); + + int sum = get_voxel(x + 1, y, z, CHANNEL_ISOLEVEL); + sum += get_voxel(x - 1, y, z, CHANNEL_ISOLEVEL); + sum += get_voxel(x, y + 1, z, CHANNEL_ISOLEVEL); + sum += get_voxel(x, y - 1, z, CHANNEL_ISOLEVEL); + sum += get_voxel(x, y, z + 1, CHANNEL_ISOLEVEL); + sum += get_voxel(x, y, z - 1, CHANNEL_ISOLEVEL); + + sum /= 6; + + sum -= current; + + if (sum < 0) + sum = 0; + + set_voxel(sum, x, y, z, CHANNEL_AO); + } + } + } } -void VoxelBuffer::add_light(int local_x, int local_y, int local_z, int size, Color color){ - VoxelBufferLight l; - - l.x = local_x; - l.y = local_y; - l.z = local_z; - l.color = color; - l.size = size; - - _lights.push_back(l); +void VoxelBuffer::add_light(int local_x, int local_y, int local_z, int size, Color color) { + ERR_FAIL_COND(size < 0); + + int size_x = _size.x; + int size_y = _size.y; + int size_z = _size.z; + + float sizef = static_cast(size); + float rf = (color.r / sizef); + float gf = (color.g / sizef); + float bf = (color.b / sizef); + + for (int y = local_y - size; y <= local_y + size; ++y) { + if (y < 0 || y > size_y) + continue; + + for (int z = local_z - size; z <= local_z + size; ++z) { + if (z < 0 || z > size_z) + continue; + + for (int x = local_x - size; x <= local_x + size; ++x) { + if (x < 0 || x > size_x) + continue; + + float len = (Math::sqrt((real_t)x * x + y * y + z * z)) / sizef; + + int r = rf * len * 255.0; + int g = gf * len * 255.0; + int b = bf * len * 255.0; + + r += get_voxel(x, y, z, CHANNEL_LIGHT_COLOR_R); + g += get_voxel(x, y, z, CHANNEL_LIGHT_COLOR_G); + b += get_voxel(x, y, z, CHANNEL_LIGHT_COLOR_B); + + if (r > 255) + r = 255; + + if (g > 255) + g = 255; + + if (b > 255) + b = 255; + + set_voxel(r, x, y, z, CHANNEL_LIGHT_COLOR_R); + set_voxel(g, x, y, z, CHANNEL_LIGHT_COLOR_G); + set_voxel(b, x, y, z, CHANNEL_LIGHT_COLOR_B); + } + } + } } -void VoxelBuffer::remove_light(int local_x, int local_y, int local_z) { - for (int i = 0; i < _lights.size(); ++i) { - VoxelBufferLight l = _lights.get(i); - - if (l.x == local_x && l.y == local_y && l-z == local_z) { - _lights.remove(i); - return; - } - } +void VoxelBuffer::clear_lights() { + fill(0, CHANNEL_LIGHT_COLOR_R); + fill(0, CHANNEL_LIGHT_COLOR_G); + fill(0, CHANNEL_LIGHT_COLOR_B); } void VoxelBuffer::create_channel(int i, Vector3i size, uint8_t defval) { @@ -381,11 +414,11 @@ void VoxelBuffer::_bind_methods() { ClassDB::bind_method(D_METHOD("is_uniform", "channel"), &VoxelBuffer::is_uniform); ClassDB::bind_method(D_METHOD("optimize"), &VoxelBuffer::compress_uniform_channels); - ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelBuffer::generate_ao); - - ClassDB::bind_method(D_METHOD("add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelBuffer::add_light); - ClassDB::bind_method(D_METHOD("remove_light", "local_x", "local_y", "local_z"), &VoxelBuffer::remove_light); - + ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelBuffer::generate_ao); + + ClassDB::bind_method(D_METHOD("add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelBuffer::add_light); + ClassDB::bind_method(D_METHOD("clear_lights"), &VoxelBuffer::clear_lights); + BIND_ENUM_CONSTANT(CHANNEL_TYPE); BIND_ENUM_CONSTANT(CHANNEL_ISOLEVEL); BIND_ENUM_CONSTANT(CHANNEL_LIGHT_COLOR_R); diff --git a/world/voxel_buffer.h b/world/voxel_buffer.h index fdec3ca..96b70c4 100644 --- a/world/voxel_buffer.h +++ b/world/voxel_buffer.h @@ -124,8 +124,9 @@ public: uint8_t *get_channel_raw(unsigned int channel_index) const; void generate_ao(); + void add_light(int local_x, int local_y, int local_z, int size, Color color); - void remove_light(int local_x, int local_y, int local_z); + void clear_lights(); private: void create_channel_noinit(int i, Vector3i size); @@ -147,14 +148,6 @@ protected: _FORCE_INLINE_ void _fill_area_binding(int defval, Vector3 min, Vector3 max, unsigned int channel_index) { fill_area(defval, Vector3i(min), Vector3i(max), channel_index); } _FORCE_INLINE_ void _set_voxel_f_binding(real_t value, int x, int y, int z, unsigned int channel) { set_voxel_f(value, x, y, z, channel); } - struct VoxelBufferLight { - int x; - int y; - int z; - Color _color; - int _size; - }; - private: struct Channel { // Allocated when the channel is populated. @@ -175,8 +168,6 @@ private: // How many voxels are there in the three directions. All populated channels have the same size. Vector3i _size; - - Vector _lights; }; VARIANT_ENUM_CAST(VoxelBuffer::ChannelId) diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index c8b1550..5d2bd98 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -1,13 +1,66 @@ #include "voxel_chunk.h" -NodePath VoxelChunk::get_library_path() { - return _library_path; +int VoxelChunk::get_chunk_position_x() { + return _chunk_position.x; } -void VoxelChunk::set_library_path(NodePath value) { - _library_path = value; +void VoxelChunk::set_chunk_position_x(int value) { + _chunk_position.x = value; } -NodePath VoxelChunk::get_mesh_instance_path() { +int VoxelChunk::get_chunk_position_y() { + return _chunk_position.y; +} +void VoxelChunk::set_chunk_position_y(int value) { + _chunk_position.y = value; +} + +int VoxelChunk::get_chunk_position_z() { + return _chunk_position.z; +} +void VoxelChunk::set_chunk_position_z(int value) { + _chunk_position.z = value; +} + +Vector3i VoxelChunk::get_chunk_position() const { + return _chunk_position; +} +void VoxelChunk::set_chunk_position(int x, int y, int z) { + _chunk_position.x = x; + _chunk_position.y = y; + _chunk_position.z = z; +} + +int VoxelChunk::get_chunk_size_x() { + return _chunk_size.x; +} +void VoxelChunk::set_chunk_size_x(int value) { + _chunk_size.x = value; +} + +int VoxelChunk::get_chunk_size_y() { + return _chunk_size.y; +} +void VoxelChunk::set_chunk_size_y(int value) { + _chunk_size.y = value; +} + +int VoxelChunk::get_chunk_size_z() { + return _chunk_size.z; +} +void VoxelChunk::set_chunk_size_z(int value) { + _chunk_size.z = value; +} + +Vector3i VoxelChunk::get_chunk_size() const { + return _chunk_size; +} +void VoxelChunk::set_chunk_size(int x, int y, int z) { + _chunk_size.x = x; + _chunk_size.y = y; + _chunk_size.z = z; +} + +NodePath VoxelChunk::get_mesh_instance_path() const { return _mesh_instance_path; } void VoxelChunk::set_mesh_instance_path(NodePath value) { @@ -21,7 +74,7 @@ void VoxelChunk::set_library(Ref value) { _library = value; } -float VoxelChunk::get_voxel_scale() { +float VoxelChunk::get_voxel_scale() const { return _voxel_scale; } void VoxelChunk::set_voxel_scale(float value) { @@ -35,21 +88,21 @@ void VoxelChunk::set_mesher(Ref mesher) { _mesher = mesher; } -bool VoxelChunk::get_build_mesh() { +bool VoxelChunk::get_build_mesh() const { return _build_mesh; } void VoxelChunk::set_build_mesh(bool value) { _build_mesh = value; } -bool VoxelChunk::get_create_collider() { +bool VoxelChunk::get_create_collider() const { return _create_collider; } void VoxelChunk::set_create_collider(bool value) { _create_collider = value; } -bool VoxelChunk::get_bake_lights() { +bool VoxelChunk::get_bake_lights() const { return _bake_lights; } void VoxelChunk::set_bake_lights(bool value) { @@ -170,18 +223,62 @@ bool VoxelChunk::is_enabled() const { return _enabled; } -void VoxelChunk::add_voxel_light_bind(Vector3 position, Color color, float strength) { - add_voxel_light(position, color, strength); +void VoxelChunk::add_lights(Array lights) { + for (int i = 0; i < lights.size(); ++i) { + Ref light = Ref(lights.get(i)); + + if (light.is_valid()) { + add_voxel_light(light); + } + } +} +void VoxelChunk::add_voxel_light(Ref light) { + _voxel_lights.push_back(light); +} +void VoxelChunk::remove_voxel_light(Ref light) { + for (int i = 0; i < _voxel_lights.size(); ++i) { + if (_voxel_lights[i] == light) { + _voxel_lights.remove(i); + return; + } + } +} +void VoxelChunk::clear_voxel_lights() { + _voxel_lights.clear(); } -Ref VoxelChunk::add_voxel_light(Vector3i position, Color color, float strength, Vector3 offset) { - Vector3 pos(position.x, position.y, position.z); +void VoxelChunk::get_lights(Array lights) { + for (int i = 0; i < _voxel_lights.size(); ++i) { + lights.append(_voxel_lights[i]); + } +} - Ref light = Ref(memnew(VoxelLight(position, color, strength, to_global(pos + Vector3((float)0.5, (float)0.5, (float)0.5) * _voxel_scale), offset))); +void VoxelChunk::bake_lights() { + clear_baked_lights(); - _voxel_lights.push_back(light); + for (int i = 0; i < _voxel_lights.size(); ++i) { + bake_light(_voxel_lights[i]); + } +} +void VoxelChunk::bake_light(Ref light) { + ERR_FAIL_COND(!light.is_valid()); - return light; + Vector3i wp = light->get_world_position(); + + int wpx = wp.x - (_chunk_position.x * _chunk_size.x); + int wpy = wp.y - (_chunk_position.y * _chunk_size.y); + int wpz = wp.z - (_chunk_position.z * _chunk_size.z); + + + //int wpx = (int)(wp.x / _chunk_size.x) - _chunk_position.x; + //int wpy = (int)(wp.y / _chunk_size.y) - _chunk_position.y; + //int wpz = (int)(wp.z / _chunk_size.z) - _chunk_position.z; + + _buffer->add_light(wpx, wpy, wpz, light->get_size(), light->get_color()); +} + +void VoxelChunk::clear_baked_lights() { + _buffer->clear_lights(); } void VoxelChunk::draw_cross_voxels(Vector3 pos) { @@ -245,7 +342,6 @@ void VoxelChunk::draw_debug_voxels(int max, Color color) { if (a > max) { break; } - } } } @@ -253,8 +349,7 @@ void VoxelChunk::draw_debug_voxels(int max, Color color) { _debug_drawer->end(); } -void VoxelChunk::draw_debug_voxel_lights(int max, bool localPosition) { - /* +void VoxelChunk::draw_debug_voxel_lights() { if (_debug_drawer == NULL) { Node *n = get_node(_debug_drawer_path); @@ -263,37 +358,25 @@ void VoxelChunk::draw_debug_voxel_lights(int max, bool localPosition) { } } - if (_debug_drawer == NULL) { - return; - } + ERR_FAIL_COND(_debug_drawer == NULL); _debug_drawer->clear(); _debug_drawer->begin(Mesh::PrimitiveType::PRIMITIVE_LINES); _debug_drawer->set_color(Color(1, 1, 1)); - const int *k = NULL; + for (int i = 0; i < _voxel_lights.size(); ++i) { + Ref v = _voxel_lights[i]; - Vector3 pos = get_transform().get_origin(); + Vector3i pos = v->get_world_position(); - int a = 0; - while ((k = _voxel_lights->next(k))) { - Ref v = _voxel_lights->get(*k); + int pos_x = pos.x - (_chunk_size.x * _chunk_position.x); + int pos_y = pos.y - (_chunk_size.y * _chunk_position.y); + int pos_z = pos.z - (_chunk_size.z * _chunk_position.z); - if (localPosition) { - Vector3i lp = v->get_local_position(); - draw_cross_voxels(pos + Vector3(lp.x, lp.y, lp.z), (float)v->get_strength() / (float)10); - } else { - Vector3i wp = v->get_world_position(); - draw_cross_voxels(pos + Vector3(wp.x, wp.y, wp.z), (float)v->get_strength() / (float)10); - } - ++a; - - if (a > max) { - break; - } + draw_cross_voxels(Vector3(pos_x, pos_y, pos_z), 1.0); } - _debug_drawer->end();*/ + _debug_drawer->end(); } void VoxelChunk::_bind_methods() { @@ -302,9 +385,33 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("_create_mesher"), &VoxelChunk::_create_mesher); - ClassDB::bind_method(D_METHOD("get_library_path"), &VoxelChunk::get_library_path); - ClassDB::bind_method(D_METHOD("set_library_path", "value"), &VoxelChunk::set_library_path); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "library_path"), "set_library_path", "get_library_path"); + ClassDB::bind_method(D_METHOD("get_chunk_position_x"), &VoxelChunk::get_chunk_position_x); + ClassDB::bind_method(D_METHOD("set_chunk_position_x", "value"), &VoxelChunk::set_chunk_position_x); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_position_x"), "set_chunk_position_x", "get_chunk_position_x"); + + ClassDB::bind_method(D_METHOD("get_chunk_position_y"), &VoxelChunk::get_chunk_position_y); + ClassDB::bind_method(D_METHOD("set_chunk_position_y", "value"), &VoxelChunk::set_chunk_position_y); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_position_y"), "set_chunk_position_y", "get_chunk_position_y"); + + ClassDB::bind_method(D_METHOD("get_chunk_position_z"), &VoxelChunk::get_chunk_position_z); + ClassDB::bind_method(D_METHOD("set_chunk_position_z", "value"), &VoxelChunk::set_chunk_position_z); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_position_z"), "set_chunk_position_x", "get_chunk_position_z"); + + ClassDB::bind_method(D_METHOD("set_chunk_position", "x", "y", "z"), &VoxelChunk::set_chunk_position); + + ClassDB::bind_method(D_METHOD("get_chunk_size_x"), &VoxelChunk::get_chunk_size_x); + ClassDB::bind_method(D_METHOD("set_chunk_size_x", "value"), &VoxelChunk::set_chunk_size_x); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_size_x"), "set_chunk_size_x", "get_chunk_size_x"); + + ClassDB::bind_method(D_METHOD("get_chunk_size_y"), &VoxelChunk::get_chunk_size_y); + ClassDB::bind_method(D_METHOD("set_chunk_size_y", "value"), &VoxelChunk::set_chunk_size_y); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_size_y"), "set_chunk_size_y", "get_chunk_size_y"); + + ClassDB::bind_method(D_METHOD("get_chunk_size_z"), &VoxelChunk::get_chunk_size_z); + ClassDB::bind_method(D_METHOD("set_chunk_size_z", "value"), &VoxelChunk::set_chunk_size_z); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_size_z"), "set_chunk_size_x", "get_chunk_size_z"); + + ClassDB::bind_method(D_METHOD("set_chunk_size", "x", "y", "z"), &VoxelChunk::set_chunk_size); ClassDB::bind_method(D_METHOD("get_mesh_instance_path"), &VoxelChunk::get_mesh_instance_path); ClassDB::bind_method(D_METHOD("set_mesh_instance_path", "value"), &VoxelChunk::set_mesh_instance_path); @@ -344,13 +451,22 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("set_mesher", "Mesher"), &VoxelChunk::set_mesher); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher"), "set_mesher", "get_mesher"); + ClassDB::bind_method(D_METHOD("add_lights", "lights"), &VoxelChunk::add_lights); + ClassDB::bind_method(D_METHOD("add_voxel_light", "light"), &VoxelChunk::add_voxel_light); + ClassDB::bind_method(D_METHOD("remove_voxel_light", "light"), &VoxelChunk::remove_voxel_light); + ClassDB::bind_method(D_METHOD("clear_voxel_lights"), &VoxelChunk::clear_voxel_lights); + ClassDB::bind_method(D_METHOD("get_lights", "lights"), &VoxelChunk::get_lights); + ClassDB::bind_method(D_METHOD("bake_lights"), &VoxelChunk::bake_lights); + ClassDB::bind_method(D_METHOD("bake_light", "light"), &VoxelChunk::bake_light); + ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights); + ClassDB::bind_method(D_METHOD("build"), &VoxelChunk::build); ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh); ClassDB::bind_method(D_METHOD("clear"), &VoxelChunk::clear); ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max"), &VoxelChunk::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights", "max", "localPosition"), &VoxelChunk::draw_debug_voxel_lights); + ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunk::draw_debug_voxel_lights); } VoxelChunk::VoxelChunk() { diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index b0015c2..67f0470 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -9,6 +9,7 @@ #include "scene/3d/collision_shape.h" #include "scene/3d/physics_body.h" #include "scene/resources/concave_polygon_shape.h" +#include "core/array.h" #include "../data/voxel_light.h" @@ -24,28 +25,45 @@ class VoxelChunk : public Spatial { GDCLASS(VoxelChunk, Spatial); public: - NodePath get_library_path(); - void set_library_path(NodePath value); + int get_chunk_position_x(); + void set_chunk_position_x(int value); + int get_chunk_position_y(); + void set_chunk_position_y(int value); + int get_chunk_position_z(); + void set_chunk_position_z(int value); - NodePath get_mesh_instance_path(); + Vector3i get_chunk_position() const; + void set_chunk_position(int x, int y, int z); + + int get_chunk_size_x(); + void set_chunk_size_x(int value); + int get_chunk_size_y(); + void set_chunk_size_y(int value); + int get_chunk_size_z(); + void set_chunk_size_z(int value); + + Vector3i get_chunk_size() const; + void set_chunk_size(int x, int y, int z); + + NodePath get_mesh_instance_path() const; void set_mesh_instance_path(NodePath value); Ref get_library(); void set_library(Ref value); - float get_voxel_scale(); + float get_voxel_scale() const; void set_voxel_scale(float value); Ref get_mesher() const; void set_mesher(Ref mesher); - bool get_build_mesh(); + bool get_build_mesh() const; void set_build_mesh(bool value); - bool get_create_collider(); + bool get_create_collider() const; void set_create_collider(bool value); - bool get_bake_lights(); + bool get_bake_lights() const; void set_bake_lights(bool value); NodePath get_debug_drawer_path(); @@ -65,8 +83,16 @@ public: void set_enabled(bool p_enabled); bool is_enabled() const; - Ref add_voxel_light(Vector3i position, Color color, float strength, Vector3 offset = Vector3()); - void add_voxel_light_bind(Vector3 position, Color color, float strength); + void add_lights(Array lights); + void add_voxel_light(Ref light); + void remove_voxel_light(Ref light); + void clear_voxel_lights(); + + void get_lights(Array lights); + + void bake_lights(); + void bake_light(Ref light); + void clear_baked_lights(); StaticBody *create_trimesh_collision_node(); @@ -74,7 +100,7 @@ public: virtual ~VoxelChunk(); void draw_debug_voxels(int max, Color color = Color(1, 1, 1)); - void draw_debug_voxel_lights(int max, bool localPosition = false); + void draw_debug_voxel_lights(); void draw_cross_voxels(Vector3 pos); void draw_cross_voxels(Vector3 pos, float fill); @@ -83,6 +109,9 @@ protected: bool _enabled; + Vector3i _chunk_position; + Vector3i _chunk_size; + Ref _buffer; Vector > _voxel_lights; float _voxel_scale;