mirror of
https://github.com/Relintai/voxelman.git
synced 2024-11-12 10:15:12 +01:00
Cleaned up the light baking api.
This commit is contained in:
parent
17b033e707
commit
7a3e4ecbe3
@ -118,6 +118,13 @@ void VoxelChunkDefault::set_max_build_phase(const int value) {
|
||||
_max_build_phases = value;
|
||||
}
|
||||
|
||||
bool VoxelChunkDefault::get_lights_dirty() const {
|
||||
return _lights_dirty;
|
||||
}
|
||||
void VoxelChunkDefault::set_lights_dirty(const bool value) {
|
||||
_lights_dirty = value;
|
||||
}
|
||||
|
||||
int VoxelChunkDefault::get_lod_num() const {
|
||||
return _lod_num;
|
||||
}
|
||||
@ -319,10 +326,6 @@ void VoxelChunkDefault::next_phase() {
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::clear() {
|
||||
_voxel_lights.clear();
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::emit_build_finished() {
|
||||
emit_signal("mesh_generation_finished", this);
|
||||
|
||||
@ -705,6 +708,16 @@ void VoxelChunkDefault::update_transforms() {
|
||||
}
|
||||
}
|
||||
|
||||
//Lights
|
||||
Ref<VoxelLight> VoxelChunkDefault::get_light(const int index) {
|
||||
ERR_FAIL_INDEX_V(index, _lights.size(), Ref<VoxelLight>());
|
||||
|
||||
return _lights.get(index);
|
||||
}
|
||||
int VoxelChunkDefault::get_light_count() const {
|
||||
return _lights.size();
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::create_debug_immediate_geometry() {
|
||||
ERR_FAIL_COND(_voxel_world == NULL);
|
||||
ERR_FAIL_COND(_debug_drawer != NULL);
|
||||
@ -806,8 +819,8 @@ void VoxelChunkDefault::draw_debug_voxel_lights() {
|
||||
_debug_drawer->begin(Mesh::PrimitiveType::PRIMITIVE_LINES);
|
||||
_debug_drawer->set_color(Color(1, 1, 1));
|
||||
|
||||
for (int i = 0; i < _voxel_lights.size(); ++i) {
|
||||
Ref<VoxelLight> v = _voxel_lights[i];
|
||||
for (int i = 0; i < _lights.size(); ++i) {
|
||||
Ref<VoxelLight> v = _lights[i];
|
||||
|
||||
int pos_x = v->get_world_position_x() - (_size_x * _position_x);
|
||||
int pos_y = v->get_world_position_y() - (_size_y * _position_y);
|
||||
@ -915,11 +928,106 @@ void VoxelChunkDefault::_world_transform_changed() {
|
||||
update_transforms();
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::_bake_lights() {
|
||||
clear_baked_lights();
|
||||
|
||||
for (int i = 0; i < _lights.size(); ++i) {
|
||||
bake_light(_lights.get(i));
|
||||
}
|
||||
}
|
||||
void VoxelChunkDefault::_bake_light(Ref<VoxelLight> light) {
|
||||
ERR_FAIL_COND(!light.is_valid());
|
||||
|
||||
Color color = light->get_color();
|
||||
int size = light->get_size();
|
||||
|
||||
int local_x = light->get_world_position_x() - (_position_x * _size_x);
|
||||
int local_y = light->get_world_position_y() - (_position_y * _size_y);
|
||||
int local_z = light->get_world_position_z() - (_position_z * _size_z);
|
||||
|
||||
ERR_FAIL_COND(size < 0);
|
||||
|
||||
//float sizef = static_cast<float>(size);
|
||||
//float rf = (color.r / sizef);
|
||||
//float gf = (color.g / sizef);
|
||||
//float bf = (color.b / sizef);
|
||||
|
||||
int64_t dsx = static_cast<int64_t>(_data_size_x);
|
||||
int64_t dsy = static_cast<int64_t>(_data_size_y);
|
||||
int64_t dsz = static_cast<int64_t>(_data_size_z);
|
||||
|
||||
for (int y = local_y - size; y <= local_y + size; ++y) {
|
||||
if (y < 0 || y >= dsy)
|
||||
continue;
|
||||
|
||||
for (int z = local_z - size; z <= local_z + size; ++z) {
|
||||
if (z < 0 || z >= dsz)
|
||||
continue;
|
||||
|
||||
for (int x = local_x - size; x <= local_x + size; ++x) {
|
||||
if (x < 0 || x >= dsx)
|
||||
continue;
|
||||
|
||||
int lx = x - local_x;
|
||||
int ly = y - local_y;
|
||||
int lz = z - local_z;
|
||||
|
||||
float str = size - (((float)lx * lx + ly * ly + lz * lz));
|
||||
str /= size;
|
||||
|
||||
if (str < 0)
|
||||
continue;
|
||||
|
||||
int r = color.r * str * 255.0;
|
||||
int g = color.g * str * 255.0;
|
||||
int b = color.b * str * 255.0;
|
||||
|
||||
r += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_R);
|
||||
g += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G);
|
||||
b += get_voxel(x, y, z, DEFAULT_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, DEFAULT_CHANNEL_LIGHT_COLOR_R);
|
||||
set_voxel(g, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G);
|
||||
set_voxel(b, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void VoxelChunkDefault::_clear_baked_lights() {
|
||||
fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_R);
|
||||
fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_G);
|
||||
fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_B);
|
||||
}
|
||||
void VoxelChunkDefault::_world_light_added(const Ref<VoxelLight> &light) {
|
||||
_lights.push_back(light);
|
||||
|
||||
set_lights_dirty(true);
|
||||
}
|
||||
void VoxelChunkDefault::_world_light_removed(const Ref<VoxelLight> &light) {
|
||||
int index = _lights.find(light);
|
||||
|
||||
if (index != -1) {
|
||||
_lights.remove(index);
|
||||
|
||||
set_lights_dirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::free_chunk() {
|
||||
free_rids();
|
||||
}
|
||||
|
||||
VoxelChunkDefault::VoxelChunkDefault() {
|
||||
_lights_dirty = false;
|
||||
_is_generating = false;
|
||||
_is_build_threaded = false;
|
||||
_abort_build = false;
|
||||
@ -969,6 +1077,8 @@ VoxelChunkDefault::~VoxelChunkDefault() {
|
||||
_abort_build = true;
|
||||
wait_and_finish_thread();
|
||||
}
|
||||
|
||||
_lights.clear();
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::_setup_channels() {
|
||||
@ -1238,70 +1348,6 @@ void VoxelChunkDefault::_build_phase_physics_process(int phase) {
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::_add_light(int local_x, int local_y, int local_z, int size, Color color) {
|
||||
ERR_FAIL_COND(size < 0);
|
||||
|
||||
//float sizef = static_cast<float>(size);
|
||||
//float rf = (color.r / sizef);
|
||||
//float gf = (color.g / sizef);
|
||||
//float bf = (color.b / sizef);
|
||||
|
||||
int64_t dsx = static_cast<int64_t>(_data_size_x);
|
||||
int64_t dsy = static_cast<int64_t>(_data_size_y);
|
||||
int64_t dsz = static_cast<int64_t>(_data_size_z);
|
||||
|
||||
for (int y = local_y - size; y <= local_y + size; ++y) {
|
||||
if (y < 0 || y >= dsy)
|
||||
continue;
|
||||
|
||||
for (int z = local_z - size; z <= local_z + size; ++z) {
|
||||
if (z < 0 || z >= dsz)
|
||||
continue;
|
||||
|
||||
for (int x = local_x - size; x <= local_x + size; ++x) {
|
||||
if (x < 0 || x >= dsx)
|
||||
continue;
|
||||
|
||||
int lx = x - local_x;
|
||||
int ly = y - local_y;
|
||||
int lz = z - local_z;
|
||||
|
||||
float str = size - (((float)lx * lx + ly * ly + lz * lz));
|
||||
str /= size;
|
||||
|
||||
if (str < 0)
|
||||
continue;
|
||||
|
||||
int r = color.r * str * 255.0;
|
||||
int g = color.g * str * 255.0;
|
||||
int b = color.b * str * 255.0;
|
||||
|
||||
r += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_R);
|
||||
g += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G);
|
||||
b += get_voxel(x, y, z, DEFAULT_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, DEFAULT_CHANNEL_LIGHT_COLOR_R);
|
||||
set_voxel(g, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G);
|
||||
set_voxel(b, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void VoxelChunkDefault::_clear_baked_lights() {
|
||||
fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_R);
|
||||
fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_G);
|
||||
fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_B);
|
||||
}
|
||||
|
||||
void VoxelChunkDefault::_create_meshers() {
|
||||
for (int i = 0; i < _meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _meshers.get(i);
|
||||
@ -1356,6 +1402,10 @@ void VoxelChunkDefault::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_max_build_phase", "value"), &VoxelChunkDefault::set_max_build_phase);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_build_phase"), "set_max_build_phase", "get_max_build_phase");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_lights_dirty"), &VoxelChunkDefault::get_lights_dirty);
|
||||
ClassDB::bind_method(D_METHOD("set_lights_dirty", "value"), &VoxelChunkDefault::set_lights_dirty);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "lights_dirty", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_lights_dirty", "get_lights_dirty");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_lod_num"), &VoxelChunkDefault::get_lod_num);
|
||||
ClassDB::bind_method(D_METHOD("set_lod_num"), &VoxelChunkDefault::set_lod_num);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_num"), "set_lod_num", "get_lod_num");
|
||||
@ -1364,14 +1414,10 @@ void VoxelChunkDefault::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_current_lod_level"), &VoxelChunkDefault::set_current_lod_level);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_lod_level"), "set_current_lod_level", "get_current_lod_level");
|
||||
|
||||
//Voxel Data
|
||||
|
||||
//Data Management functions
|
||||
ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelChunkDefault::generate_ao);
|
||||
ClassDB::bind_method(D_METHOD("add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelChunkDefault::add_light);
|
||||
ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunkDefault::clear_baked_lights);
|
||||
|
||||
//Meshes
|
||||
//Meshing
|
||||
BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase")));
|
||||
BIND_VMETHOD(MethodInfo("_build_phase_process", PropertyInfo(Variant::INT, "phase")));
|
||||
BIND_VMETHOD(MethodInfo("_build_phase_physics_process", PropertyInfo(Variant::INT, "phase")));
|
||||
@ -1410,13 +1456,14 @@ void VoxelChunkDefault::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("create_colliders", "mesh_index", "layer_mask"), &VoxelChunkDefault::create_colliders, DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("free_colliders", "mesh_index"), &VoxelChunkDefault::free_colliders);
|
||||
|
||||
//Lights
|
||||
ClassDB::bind_method(D_METHOD("get_light", "index"), &VoxelChunkDefault::get_light);
|
||||
ClassDB::bind_method(D_METHOD("get_light_count"), &VoxelChunkDefault::get_light_count);
|
||||
|
||||
//Debug
|
||||
ClassDB::bind_method(D_METHOD("create_debug_immediate_geometry"), &VoxelChunkDefault::create_debug_immediate_geometry);
|
||||
ClassDB::bind_method(D_METHOD("free_debug_immediate_geometry"), &VoxelChunkDefault::free_debug_immediate_geometry);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunkDefault::free_chunk);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("emit_build_finished"), &VoxelChunkDefault::emit_build_finished);
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_draw_debug_voxel_lights", PropertyInfo(Variant::OBJECT, "debug_drawer", PROPERTY_HINT_RESOURCE_TYPE, "ImmediateGeometry")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("draw_cross_voxels", "max"), &VoxelChunkDefault::draw_cross_voxels);
|
||||
@ -1425,23 +1472,35 @@ void VoxelChunkDefault::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunkDefault::draw_debug_voxel_lights);
|
||||
|
||||
//Free
|
||||
ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunkDefault::free_chunk);
|
||||
|
||||
//etc
|
||||
ClassDB::bind_method(D_METHOD("emit_build_finished"), &VoxelChunkDefault::emit_build_finished);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("generate_random_ao", "seed", "octaves", "period", "persistence", "scale_factor"), &VoxelChunkDefault::generate_random_ao, DEFVAL(4), DEFVAL(30), DEFVAL(0.3), DEFVAL(0.6));
|
||||
|
||||
//virtuals
|
||||
ClassDB::bind_method(D_METHOD("_setup_channels"), &VoxelChunkDefault::_setup_channels);
|
||||
ClassDB::bind_method(D_METHOD("_build_phase", "phase"), &VoxelChunkDefault::_build_phase);
|
||||
ClassDB::bind_method(D_METHOD("_build_phase_process", "phase"), &VoxelChunkDefault::_build_phase_process);
|
||||
ClassDB::bind_method(D_METHOD("_build_phase_physics_process", "phase"), &VoxelChunkDefault::_build_phase_physics_process);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelChunkDefault::_add_light);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_clear_baked_lights"), &VoxelChunkDefault::_clear_baked_lights);
|
||||
ClassDB::bind_method(D_METHOD("_create_meshers"), &VoxelChunkDefault::_create_meshers);
|
||||
ClassDB::bind_method(D_METHOD("_build", "immediate"), &VoxelChunkDefault::_build);
|
||||
ClassDB::bind_method(D_METHOD("_visibility_changed", "visible"), &VoxelChunkDefault::_visibility_changed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_exit_tree"), &VoxelChunkDefault::_exit_tree);
|
||||
ClassDB::bind_method(D_METHOD("_process", "delta"), &VoxelChunkDefault::_process);
|
||||
ClassDB::bind_method(D_METHOD("_physics_process", "delta"), &VoxelChunkDefault::_physics_process);
|
||||
ClassDB::bind_method(D_METHOD("_visibility_changed", "visible"), &VoxelChunkDefault::_visibility_changed);
|
||||
|
||||
//lights
|
||||
ClassDB::bind_method(D_METHOD("_bake_lights"), &VoxelChunkDefault::_bake_lights);
|
||||
ClassDB::bind_method(D_METHOD("_bake_light", "light"), &VoxelChunkDefault::_bake_light);
|
||||
ClassDB::bind_method(D_METHOD("_clear_baked_lights"), &VoxelChunkDefault::_clear_baked_lights);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_world_light_added", "light"), &VoxelChunkDefault::_world_light_added);
|
||||
ClassDB::bind_method(D_METHOD("_world_light_removed", "light"), &VoxelChunkDefault::_world_light_removed);
|
||||
|
||||
BIND_CONSTANT(BUILD_PHASE_DONE);
|
||||
BIND_CONSTANT(BUILD_PHASE_SETUP);
|
||||
|
@ -156,6 +156,9 @@ public:
|
||||
int get_max_build_phase() const;
|
||||
void set_max_build_phase(const int value);
|
||||
|
||||
bool get_lights_dirty() const;
|
||||
void set_lights_dirty(const bool value);
|
||||
|
||||
//Lod
|
||||
int get_lod_num() const;
|
||||
void set_lod_num(const int value);
|
||||
@ -180,8 +183,6 @@ public:
|
||||
bool has_next_phase();
|
||||
void next_phase();
|
||||
|
||||
void clear();
|
||||
|
||||
//Meshes
|
||||
Dictionary get_mesh_rids();
|
||||
void set_mesh_rids(const Dictionary &rids);
|
||||
@ -209,6 +210,10 @@ public:
|
||||
//Transform
|
||||
void update_transforms();
|
||||
|
||||
//Lights
|
||||
Ref<VoxelLight> get_light(const int index);
|
||||
int get_light_count() const;
|
||||
|
||||
//Debug
|
||||
void create_debug_immediate_geometry();
|
||||
void free_debug_immediate_geometry();
|
||||
@ -218,11 +223,13 @@ public:
|
||||
void draw_debug_voxels(int max, Color color = Color(1, 1, 1));
|
||||
void draw_debug_voxel_lights();
|
||||
|
||||
//Visibility
|
||||
void visibility_changed(bool visible);
|
||||
|
||||
//free
|
||||
void free_chunk();
|
||||
|
||||
//etc
|
||||
void emit_build_finished();
|
||||
|
||||
void generate_random_ao(const int seed, const int octaves = 4, const int period = 30, const float persistence = 0.3, const float scale_factor = 0.6);
|
||||
@ -236,8 +243,6 @@ protected:
|
||||
virtual void _build_phase_process(int phase);
|
||||
virtual void _build_phase_physics_process(int phase);
|
||||
|
||||
virtual void _add_light(int local_x, int local_y, int local_z, int size, Color color);
|
||||
virtual void _clear_baked_lights();
|
||||
virtual void _create_meshers();
|
||||
virtual void _build(bool immediate);
|
||||
virtual void _visibility_changed(bool visible);
|
||||
@ -247,6 +252,13 @@ protected:
|
||||
virtual void _physics_process(float delta);
|
||||
virtual void _world_transform_changed();
|
||||
|
||||
//lights
|
||||
virtual void _bake_lights();
|
||||
virtual void _bake_light(Ref<VoxelLight> light);
|
||||
virtual void _clear_baked_lights();
|
||||
virtual void _world_light_added(const Ref<VoxelLight> &light);
|
||||
virtual void _world_light_removed(const Ref<VoxelLight> &light);
|
||||
|
||||
void wait_and_finish_thread();
|
||||
|
||||
static void _bind_methods();
|
||||
@ -260,6 +272,8 @@ protected:
|
||||
int _max_build_phases;
|
||||
bool _enabled;
|
||||
|
||||
bool _lights_dirty;
|
||||
|
||||
int _lod_size;
|
||||
|
||||
//lod
|
||||
@ -281,6 +295,8 @@ protected:
|
||||
PoolVector<Vector3> temp_arr_collider;
|
||||
|
||||
ActiveBuildPhaseType _active_build_phase_type;
|
||||
|
||||
Vector<Ref<VoxelLight> > _lights;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelChunkDefault::DefaultChannels);
|
||||
|
@ -610,111 +610,20 @@ Array VoxelChunk::bake_mesh_array_uv(Array arr, Ref<Texture> tex, float mul_colo
|
||||
return arr;
|
||||
}
|
||||
|
||||
void VoxelChunk::add_lights(Array lights) {
|
||||
for (int i = 0; i < lights.size(); ++i) {
|
||||
Ref<VoxelLight> light = Ref<VoxelLight>(lights.get(i));
|
||||
|
||||
if (light.is_valid()) {
|
||||
add_voxel_light(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
void VoxelChunk::add_voxel_light(Ref<VoxelLight> light) {
|
||||
_voxel_lights.push_back(light);
|
||||
}
|
||||
|
||||
void VoxelChunk::create_voxel_light(const Color color, const int size, const int x, const int y, const int z) {
|
||||
Ref<VoxelLight> light;
|
||||
light.instance();
|
||||
|
||||
light->set_world_position(_position_x * _size_x + x, _position_y * _size_y + y, _position_z * _size_z + z);
|
||||
light->set_color(color);
|
||||
light->set_size(size);
|
||||
|
||||
add_voxel_light(light);
|
||||
}
|
||||
|
||||
void VoxelChunk::remove_voxel_light(Ref<VoxelLight> 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();
|
||||
}
|
||||
|
||||
void VoxelChunk::add_lights_into(Array target) {
|
||||
for (int i = 0; i < _voxel_lights.size(); ++i) {
|
||||
target.append(_voxel_lights[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::add_unique_lights_into(Array target) {
|
||||
for (int i = 0; i < _voxel_lights.size(); ++i) {
|
||||
Ref<VoxelLight> l = _voxel_lights.get(i);
|
||||
|
||||
bool append = true;
|
||||
for (int j = 0; j < target.size(); ++j) {
|
||||
Ref<VoxelLight> l2 = target.get(j);
|
||||
|
||||
if (!l2.is_valid())
|
||||
continue;
|
||||
|
||||
if (l2->get_world_position() == l->get_world_position() && l2->get_size() == l->get_size()) {
|
||||
append = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (append)
|
||||
target.append(l);
|
||||
}
|
||||
}
|
||||
|
||||
Array VoxelChunk::get_lights() {
|
||||
Array target;
|
||||
|
||||
for (int i = 0; i < _voxel_lights.size(); ++i) {
|
||||
target.append(_voxel_lights[i]);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void VoxelChunk::bake_lights() {
|
||||
clear_baked_lights();
|
||||
|
||||
for (int i = 0; i < _voxel_lights.size(); ++i) {
|
||||
bake_light(_voxel_lights[i]);
|
||||
}
|
||||
if (has_method("_bake_lights"))
|
||||
call("_bake_lights");
|
||||
}
|
||||
void VoxelChunk::bake_light(Ref<VoxelLight> light) {
|
||||
ERR_FAIL_COND(!light.is_valid());
|
||||
if (!light.is_valid())
|
||||
return;
|
||||
|
||||
int wpx = light->get_world_position_x() - (_position_x * _size_x);
|
||||
int wpy = light->get_world_position_y() - (_position_y * _size_y);
|
||||
int wpz = light->get_world_position_z() - (_position_z * _size_z);
|
||||
|
||||
add_light(wpx, wpy, wpz, light->get_size(), light->get_color());
|
||||
if (has_method("_bake_lights"))
|
||||
call("_bake_light", light);
|
||||
}
|
||||
|
||||
void VoxelChunk::clear_baked_lights() {
|
||||
ERR_FAIL_COND_MSG(!has_method("_clear_baked_lights"), "VoxelChunk: _clear_baked_lights() is missing! Please implement it!");
|
||||
|
||||
call("_clear_baked_lights");
|
||||
}
|
||||
|
||||
void VoxelChunk::add_light(int local_x, int local_y, int local_z, int size, Color color) {
|
||||
ERR_FAIL_COND_MSG(!has_method("_add_light"), "VoxelChunk: _add_light() is missing! Please implement it!");
|
||||
|
||||
call("_add_light", local_x, local_y, local_z, size, color);
|
||||
}
|
||||
|
||||
void VoxelChunk::add_prop_light(Ref<VoxelLight> light) {
|
||||
bake_light(light);
|
||||
if (has_method("_clear_baked_lights"))
|
||||
call("_clear_baked_lights");
|
||||
}
|
||||
|
||||
void VoxelChunk::add_prop(Ref<VoxelChunkPropData> prop) {
|
||||
@ -767,6 +676,14 @@ void VoxelChunk::visibility_changed(bool visible) {
|
||||
if (has_method("_visibility_changed"))
|
||||
call("_visibility_changed", _is_visible);
|
||||
}
|
||||
void VoxelChunk::world_light_added(const Ref<VoxelLight> &light) {
|
||||
if (has_method("_world_light_added"))
|
||||
call("_world_light_added", light);
|
||||
}
|
||||
void VoxelChunk::world_light_removed(const Ref<VoxelLight> &light) {
|
||||
if (has_method("_world_light_removed"))
|
||||
call("_world_light_removed", light);
|
||||
}
|
||||
|
||||
Transform VoxelChunk::get_transform() const {
|
||||
return _transform;
|
||||
@ -806,8 +723,6 @@ VoxelChunk::VoxelChunk() {
|
||||
}
|
||||
|
||||
VoxelChunk::~VoxelChunk() {
|
||||
_voxel_lights.clear();
|
||||
|
||||
_meshers.clear();
|
||||
|
||||
if (_library.is_valid()) {
|
||||
@ -886,7 +801,14 @@ void VoxelChunk::_bind_methods() {
|
||||
BIND_VMETHOD(MethodInfo("_prop_added", PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunkPropData")));
|
||||
BIND_VMETHOD(MethodInfo("_create_meshers"));
|
||||
BIND_VMETHOD(MethodInfo("_setup_channels"));
|
||||
BIND_VMETHOD(MethodInfo("_add_light", PropertyInfo(Variant::INT, "local_x"), PropertyInfo(Variant::INT, "local_y"), PropertyInfo(Variant::INT, "local_z"), PropertyInfo(Variant::INT, "size"), PropertyInfo(Variant::COLOR, "color")));
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_bake_lights"));
|
||||
BIND_VMETHOD(MethodInfo("_bake_light", PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLight")));
|
||||
BIND_VMETHOD(MethodInfo("_clear_baked_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);
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_enter_tree"));
|
||||
BIND_VMETHOD(MethodInfo("_exit_tree"));
|
||||
@ -894,8 +816,17 @@ void VoxelChunk::_bind_methods() {
|
||||
BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta")));
|
||||
BIND_VMETHOD(MethodInfo("_world_transform_changed"));
|
||||
BIND_VMETHOD(MethodInfo("_visibility_changed", PropertyInfo(Variant::BOOL, "visible")));
|
||||
BIND_VMETHOD(MethodInfo("_world_light_added", PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLight")));
|
||||
BIND_VMETHOD(MethodInfo("_world_light_removed", PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLight")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("enter_tree"), &VoxelChunk::enter_tree);
|
||||
ClassDB::bind_method(D_METHOD("exit_tree"), &VoxelChunk::exit_tree);
|
||||
ClassDB::bind_method(D_METHOD("process", "delta"), &VoxelChunk::process);
|
||||
ClassDB::bind_method(D_METHOD("physics_process", "delta"), &VoxelChunk::physics_process);
|
||||
ClassDB::bind_method(D_METHOD("world_transform_changed"), &VoxelChunk::world_transform_changed);
|
||||
ClassDB::bind_method(D_METHOD("visibility_changed", "visible"), &VoxelChunk::visibility_changed);
|
||||
ClassDB::bind_method(D_METHOD("world_light_added", "light"), &VoxelChunk::world_light_added);
|
||||
ClassDB::bind_method(D_METHOD("world_light_removed", "light"), &VoxelChunk::world_light_removed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_process"), &VoxelChunk::get_process);
|
||||
ClassDB::bind_method(D_METHOD("set_process", "value"), &VoxelChunk::set_process);
|
||||
@ -1020,20 +951,6 @@ void VoxelChunk::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("bake_mesh_array_uv", "arr", "tex", "mul_color"), &VoxelChunk::bake_mesh_array_uv, DEFVAL(0.7));
|
||||
|
||||
//Meshes
|
||||
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("create_voxel_light", "color", "size", "x", "y", "z"), &VoxelChunk::create_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("add_lights_into", "lights"), &VoxelChunk::add_lights_into);
|
||||
ClassDB::bind_method(D_METHOD("add_unique_lights_into", "lights"), &VoxelChunk::add_unique_lights_into);
|
||||
ClassDB::bind_method(D_METHOD("get_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("add_prop_light", "light"), &VoxelChunk::add_prop_light);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelChunk::add_prop);
|
||||
ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelChunk::get_prop);
|
||||
|
@ -177,25 +177,11 @@ public:
|
||||
Array merge_mesh_array(Array arr) const;
|
||||
Array bake_mesh_array_uv(Array arr, Ref<Texture> tex, float mul_color = 0.7) const;
|
||||
|
||||
//lights
|
||||
void add_lights(Array lights);
|
||||
void add_voxel_light(Ref<VoxelLight> light);
|
||||
void create_voxel_light(const Color color, const int size, const int x, const int y, const int z);
|
||||
void remove_voxel_light(Ref<VoxelLight> light);
|
||||
void clear_voxel_lights();
|
||||
|
||||
void add_lights_into(Array target);
|
||||
void add_unique_lights_into(Array target);
|
||||
Array get_lights();
|
||||
|
||||
//light Baking
|
||||
void bake_lights();
|
||||
void bake_light(Ref<VoxelLight> light);
|
||||
void clear_baked_lights();
|
||||
|
||||
void add_light(int local_x, int local_y, int local_z, int size, Color color);
|
||||
|
||||
void add_prop_light(Ref<VoxelLight> light);
|
||||
|
||||
//props
|
||||
void add_prop(Ref<VoxelChunkPropData> prop);
|
||||
Ref<VoxelChunkPropData> get_prop(int index);
|
||||
@ -211,6 +197,8 @@ public:
|
||||
void physics_process(float delta);
|
||||
void world_transform_changed();
|
||||
void visibility_changed(bool visible);
|
||||
void world_light_added(const Ref<VoxelLight> &light);
|
||||
void world_light_removed(const Ref<VoxelLight> &light);
|
||||
|
||||
Transform get_transform() const;
|
||||
void set_transform(const Transform &transform);
|
||||
@ -256,8 +244,6 @@ protected:
|
||||
|
||||
Vector<uint8_t *> _channels;
|
||||
|
||||
Vector<Ref<VoxelLight> > _voxel_lights;
|
||||
|
||||
float _voxel_scale;
|
||||
|
||||
Ref<VoxelmanLibrary> _library;
|
||||
|
@ -279,7 +279,7 @@ int VoxelWorld::get_generation_size() {
|
||||
return _generating.size();
|
||||
}
|
||||
|
||||
void VoxelWorld::clear() {
|
||||
void VoxelWorld::clear_chunks() {
|
||||
for (int i = 0; i < _chunks_vector.size(); ++i) {
|
||||
_chunks_vector.get(i)->exit_tree();
|
||||
}
|
||||
@ -413,6 +413,81 @@ void VoxelWorld::set_chunks(const Vector<Variant> &chunks) {
|
||||
}
|
||||
}
|
||||
|
||||
//Lights
|
||||
|
||||
void VoxelWorld::add_light(const Ref<VoxelLight> &light) {
|
||||
_lights.push_back(light);
|
||||
|
||||
for (int i = 0; i < _chunks_vector.size(); ++i) {
|
||||
Ref<VoxelChunk> chunk = _chunks_vector[i];
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->world_light_added(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ref<VoxelLight> VoxelWorld::get_light(const int index) {
|
||||
ERR_FAIL_INDEX_V(index, _lights.size(), Ref<VoxelLight>());
|
||||
|
||||
return _lights.get(index);
|
||||
}
|
||||
void VoxelWorld::remove_light(const int index) {
|
||||
ERR_FAIL_INDEX(index, _lights.size());
|
||||
|
||||
Ref<VoxelLight> light = _lights[index];
|
||||
|
||||
for (int i = 0; i < _chunks_vector.size(); ++i) {
|
||||
Ref<VoxelChunk> chunk = _chunks_vector[i];
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->world_light_removed(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
int VoxelWorld::get_light_count() const {
|
||||
return _lights.size();
|
||||
}
|
||||
void VoxelWorld::clear_lights() {
|
||||
for (int i = 0; i < _lights.size(); ++i) {
|
||||
|
||||
Ref<VoxelLight> light = _lights[i];
|
||||
|
||||
if (!light.is_valid())
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < _chunks_vector.size(); ++j) {
|
||||
Ref<VoxelChunk> chunk = _chunks_vector[j];
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->world_light_removed(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_lights.clear();
|
||||
}
|
||||
|
||||
Vector<Variant> VoxelWorld::get_lights() {
|
||||
Vector<Variant> r;
|
||||
for (int i = 0; i < _lights.size(); i++) {
|
||||
#if VERSION_MAJOR < 4
|
||||
r.push_back(_lights[i].get_ref_ptr());
|
||||
#else
|
||||
r.push_back(_lights[i]);
|
||||
#endif
|
||||
}
|
||||
return r;
|
||||
}
|
||||
void VoxelWorld::set_lights(const Vector<Variant> &chunks) {
|
||||
clear_lights();
|
||||
|
||||
for (int i = 0; i < chunks.size(); ++i) {
|
||||
Ref<VoxelLight> light = Ref<VoxelLight>(chunks[i]);
|
||||
|
||||
add_light(light);
|
||||
}
|
||||
}
|
||||
|
||||
VoxelWorld::VoxelWorld() {
|
||||
_editable = false;
|
||||
|
||||
@ -448,6 +523,8 @@ VoxelWorld ::~VoxelWorld() {
|
||||
|
||||
_generation_queue.clear();
|
||||
_generating.clear();
|
||||
|
||||
_lights.clear();
|
||||
}
|
||||
|
||||
void VoxelWorld::_generate_chunk(Ref<VoxelChunk> chunk) {
|
||||
@ -667,7 +744,7 @@ void VoxelWorld::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("remove_generation_index", "index"), &VoxelWorld::remove_generation_index);
|
||||
ClassDB::bind_method(D_METHOD("get_generation_size"), &VoxelWorld::get_generation_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("clear"), &VoxelWorld::clear);
|
||||
ClassDB::bind_method(D_METHOD("clear_chunks"), &VoxelWorld::clear_chunks);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("generation_finished"));
|
||||
BIND_VMETHOD(MethodInfo("_generation_finished"));
|
||||
@ -685,4 +762,14 @@ void VoxelWorld::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("can_chunk_do_build_step"), &VoxelWorld::can_chunk_do_build_step);
|
||||
ClassDB::bind_method(D_METHOD("is_position_walkable", "position"), &VoxelWorld::is_position_walkable);
|
||||
ClassDB::bind_method(D_METHOD("on_chunk_mesh_generation_finished", "chunk"), &VoxelWorld::on_chunk_mesh_generation_finished);
|
||||
|
||||
//Lights
|
||||
ClassDB::bind_method(D_METHOD("add_light", "light"), &VoxelWorld::add_light);
|
||||
ClassDB::bind_method(D_METHOD("get_light", "index"), &VoxelWorld::get_light);
|
||||
ClassDB::bind_method(D_METHOD("remove_light", "index"), &VoxelWorld::remove_light);
|
||||
ClassDB::bind_method(D_METHOD("get_light_count"), &VoxelWorld::get_light_count);
|
||||
ClassDB::bind_method(D_METHOD("clear_lights"), &VoxelWorld::clear_lights);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_lights"), &VoxelWorld::get_lights);
|
||||
ClassDB::bind_method(D_METHOD("set_lights", "chunks"), &VoxelWorld::set_lights);
|
||||
}
|
||||
|
@ -100,12 +100,14 @@ public:
|
||||
void set_player(Spatial *player);
|
||||
void set_player_bind(Node *player);
|
||||
|
||||
//World Areas
|
||||
Ref<WorldArea> get_world_area(const int index) const;
|
||||
void add_world_area(Ref<WorldArea> area);
|
||||
void remove_world_area(const int index);
|
||||
void clear_world_areas();
|
||||
int get_world_area_count() const;
|
||||
|
||||
//Chunks
|
||||
void add_chunk(Ref<VoxelChunk> chunk, const int x, const int y, const int z);
|
||||
bool has_chunk(const int x, const int y, const int z) const;
|
||||
Ref<VoxelChunk> get_chunk(const int x, const int y, const int z);
|
||||
@ -125,7 +127,7 @@ public:
|
||||
void remove_generation_index(int index);
|
||||
int get_generation_size();
|
||||
|
||||
void clear();
|
||||
void clear_chunks();
|
||||
|
||||
Ref<VoxelChunk> get_or_create_chunk(int x, int y, int z);
|
||||
Ref<VoxelChunk> create_chunk(int x, int y, int z);
|
||||
@ -140,6 +142,16 @@ public:
|
||||
Vector<Variant> get_chunks();
|
||||
void set_chunks(const Vector<Variant> &chunks);
|
||||
|
||||
//Lights
|
||||
void add_light(const Ref<VoxelLight> &light);
|
||||
Ref<VoxelLight> get_light(const int index);
|
||||
void remove_light(const int index);
|
||||
int get_light_count() const;
|
||||
void clear_lights();
|
||||
|
||||
Vector<Variant> get_lights();
|
||||
void set_lights(const Vector<Variant> &chunks);
|
||||
|
||||
VoxelWorld();
|
||||
~VoxelWorld();
|
||||
|
||||
@ -214,6 +226,8 @@ private:
|
||||
Vector<Ref<VoxelChunk> > _generating;
|
||||
int _max_frame_chunk_build_steps;
|
||||
int _num_frame_chunk_build_steps;
|
||||
|
||||
Vector<Ref<VoxelLight> > _lights;
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const VoxelWorld::IntPos &a, const VoxelWorld::IntPos &b) {
|
||||
|
Loading…
Reference in New Issue
Block a user