mirror of
https://github.com/Relintai/voxelman.git
synced 2024-11-12 10:15:12 +01:00
Removed the old meshing implementation, and replaced most logic to the new one. The code compiles, but it won't work for now. Also other cleanups.
This commit is contained in:
parent
0db9475db1
commit
235943f7ca
@ -36,9 +36,9 @@ void VoxelMesherBlocky::_add_chunk(Ref<VoxelChunk> p_chunk) {
|
||||
|
||||
ERR_FAIL_COND(!chunk.is_valid());
|
||||
|
||||
if ((get_build_flags() & VoxelChunkDefault::BUILD_FLAG_GENERATE_AO) != 0)
|
||||
if (!chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_AO))
|
||||
chunk->generate_ao();
|
||||
//if ((get_build_flags() & VoxelChunkDefault::BUILD_FLAG_GENERATE_AO) != 0)
|
||||
// if (!chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_AO))
|
||||
// chunk->generate_ao();
|
||||
|
||||
int x_size = chunk->get_size_x();
|
||||
int y_size = chunk->get_size_y();
|
||||
|
@ -29,8 +29,8 @@ void VoxelMesherLiquidBlocky::_add_chunk(Ref<VoxelChunk> p_chunk) {
|
||||
|
||||
ERR_FAIL_COND(!chunk.is_valid());
|
||||
|
||||
if ((get_build_flags() & VoxelChunkDefault::BUILD_FLAG_GENERATE_AO) != 0)
|
||||
chunk->generate_ao();
|
||||
//if ((get_build_flags() & VoxelChunkDefault::BUILD_FLAG_GENERATE_AO) != 0)
|
||||
// chunk->generate_ao();
|
||||
|
||||
int x_size = chunk->get_size_x();
|
||||
int y_size = chunk->get_size_y();
|
||||
|
@ -37,15 +37,15 @@ void VoxelMesherCubic::_add_chunk(Ref<VoxelChunk> p_chunk) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_RANDOM_AO)) {
|
||||
chunk->generate_ao();
|
||||
}
|
||||
//if (chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_RANDOM_AO)) {
|
||||
// chunk->generate_ao();
|
||||
//}
|
||||
|
||||
int x_size = chunk->get_size_x();
|
||||
int y_size = chunk->get_size_y();
|
||||
int z_size = chunk->get_size_z();
|
||||
|
||||
float voxel_size = get_lod_size();
|
||||
float voxel_size = 1;
|
||||
float voxel_scale = get_voxel_scale();
|
||||
|
||||
Ref<VoxelCubePoints> cube_points;
|
||||
|
@ -182,14 +182,14 @@ void VoxelMesherMarchingCubes::_add_chunk(Ref<VoxelChunk> p_chunk) {
|
||||
|
||||
ERR_FAIL_COND(!chunk.is_valid());
|
||||
|
||||
Ref<VoxelJob> job = chunk->get_job();
|
||||
Ref<VoxelJob> job = chunk->get_current_job();
|
||||
|
||||
if (!job->has_meta("ao_done")) {
|
||||
job->set_meta("ao_done", true);
|
||||
chunk->generate_ao();
|
||||
}
|
||||
//if (!job->has_meta("ao_done")) {
|
||||
// job->set_meta("ao_done", true);
|
||||
// chunk->generate_ao();
|
||||
//}
|
||||
|
||||
job->remove_meta("ao_done");
|
||||
//job->remove_meta("ao_done");
|
||||
|
||||
if (job->should_return()) {
|
||||
return;
|
||||
@ -201,7 +201,7 @@ void VoxelMesherMarchingCubes::_add_chunk(Ref<VoxelChunk> p_chunk) {
|
||||
int y_size = chunk->get_size_y();
|
||||
int z_size = chunk->get_size_z();
|
||||
|
||||
int lod_size = get_lod_size();
|
||||
int lod_size = 1;
|
||||
|
||||
int start_y = 0;
|
||||
|
||||
|
@ -149,13 +149,6 @@ void VoxelMesher::set_voxel_scale(const float voxel_scale) {
|
||||
_voxel_scale = voxel_scale;
|
||||
}
|
||||
|
||||
int VoxelMesher::get_lod_size() const {
|
||||
return _lod_size;
|
||||
}
|
||||
void VoxelMesher::set_lod_size(const int lod_size) {
|
||||
_lod_size = lod_size;
|
||||
}
|
||||
|
||||
Rect2 VoxelMesher::get_uv_margin() const {
|
||||
return _uv_margin;
|
||||
}
|
||||
@ -905,7 +898,6 @@ VoxelMesher::VoxelMesher(const Ref<VoxelmanLibrary> &library) {
|
||||
|
||||
_mesher_index = 0;
|
||||
_voxel_scale = 1;
|
||||
_lod_size = 1;
|
||||
_ao_strength = 0.25;
|
||||
_base_light_value = 0.5;
|
||||
_uv_margin = Rect2(0, 0, 1, 1);
|
||||
@ -919,7 +911,6 @@ VoxelMesher::VoxelMesher(const Ref<VoxelmanLibrary> &library) {
|
||||
VoxelMesher::VoxelMesher() {
|
||||
_mesher_index = 0;
|
||||
_voxel_scale = 1;
|
||||
_lod_size = 1;
|
||||
_ao_strength = 0.25;
|
||||
_base_light_value = 0.5;
|
||||
_uv_margin = Rect2(0, 0, 1, 1);
|
||||
@ -972,10 +963,6 @@ void VoxelMesher::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelMesher::set_voxel_scale);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_lod_size"), &VoxelMesher::get_lod_size);
|
||||
ClassDB::bind_method(D_METHOD("set_lod_size", "value"), &VoxelMesher::set_lod_size);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_size"), "set_lod_size", "get_lod_size");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_ao_strength"), &VoxelMesher::get_ao_strength);
|
||||
ClassDB::bind_method(D_METHOD("set_ao_strength", "value"), &VoxelMesher::set_ao_strength);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao_strength"), "set_ao_strength", "get_ao_strength");
|
||||
|
@ -117,9 +117,6 @@ public:
|
||||
float get_voxel_scale() const;
|
||||
void set_voxel_scale(const float voxel_scale);
|
||||
|
||||
int get_lod_size() const;
|
||||
void set_lod_size(const int lod_size);
|
||||
|
||||
Rect2 get_uv_margin() const;
|
||||
void set_uv_margin(const Rect2 margin);
|
||||
|
||||
@ -215,7 +212,6 @@ protected:
|
||||
Ref<Material> _material;
|
||||
|
||||
float _voxel_scale;
|
||||
int _lod_size;
|
||||
|
||||
float _ao_strength;
|
||||
float _base_light_value;
|
||||
|
@ -27,6 +27,10 @@ SOFTWARE.
|
||||
|
||||
#include "../../defines.h"
|
||||
|
||||
#include "../jobs/voxel_light_job.h"
|
||||
#include "../jobs/voxel_prop_job.h"
|
||||
#include "../jobs/voxel_terrarin_job.h"
|
||||
|
||||
VoxelChunkBlocky::VoxelChunkBlocky() {
|
||||
}
|
||||
|
||||
@ -38,39 +42,22 @@ void VoxelChunkBlocky::_setup_channels() {
|
||||
}
|
||||
|
||||
void VoxelChunkBlocky::_create_meshers() {
|
||||
set_prop_mesher(Ref<VoxelMesher>(memnew(VoxelMesherBlocky)));
|
||||
add_mesher(Ref<VoxelMesher>(memnew(VoxelMesherBlocky())));
|
||||
add_liquid_mesher(Ref<VoxelMesher>(memnew(VoxelMesherLiquidBlocky())));
|
||||
Ref<VoxelTerrarinJob> tj;
|
||||
tj.instance();
|
||||
|
||||
for (int i = 0; i < _meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _meshers.get(i);
|
||||
Ref<VoxelLightJob> lj;
|
||||
lj.instance();
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
Ref<VoxelPropJob> pj;
|
||||
pj.instance();
|
||||
pj->set_prop_mesher(Ref<VoxelMesher>(memnew(VoxelMesherBlocky)));
|
||||
|
||||
mesher->set_lod_size(get_lod_size());
|
||||
mesher->set_voxel_scale(get_voxel_scale());
|
||||
tj->add_mesher(Ref<VoxelMesher>(memnew(VoxelMesherBlocky())));
|
||||
tj->add_liquid_mesher(Ref<VoxelMesher>(memnew(VoxelMesherLiquidBlocky())));
|
||||
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (md.is_valid()) {
|
||||
md->set_build_flags(get_build_flags());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _liquid_meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _liquid_meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_lod_size(get_lod_size());
|
||||
mesher->set_voxel_scale(get_voxel_scale());
|
||||
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (md.is_valid()) {
|
||||
md->set_build_flags(get_build_flags());
|
||||
}
|
||||
}
|
||||
add_job(lj);
|
||||
add_job(tj);
|
||||
add_job(pj);
|
||||
}
|
||||
|
||||
void VoxelChunkBlocky::_bind_methods() {
|
||||
|
@ -26,6 +26,10 @@ SOFTWARE.
|
||||
|
||||
#include "../../defines.h"
|
||||
|
||||
#include "../jobs/voxel_light_job.h"
|
||||
#include "../jobs/voxel_prop_job.h"
|
||||
#include "../jobs/voxel_terrarin_job.h"
|
||||
|
||||
VoxelChunkCubic::VoxelChunkCubic() {
|
||||
}
|
||||
|
||||
@ -37,45 +41,26 @@ void VoxelChunkCubic::_setup_channels() {
|
||||
}
|
||||
|
||||
void VoxelChunkCubic::_create_meshers() {
|
||||
set_prop_mesher(Ref<VoxelMesher>(memnew(VoxelMesherCubic)));
|
||||
Ref<VoxelTerrarinJob> tj;
|
||||
tj.instance();
|
||||
|
||||
Ref<VoxelLightJob> lj;
|
||||
lj.instance();
|
||||
|
||||
Ref<VoxelPropJob> pj;
|
||||
pj.instance();
|
||||
pj->set_prop_mesher(Ref<VoxelMesher>(memnew(VoxelMesherCubic)));
|
||||
|
||||
Ref<VoxelMesher> m = Ref<VoxelMesher>(memnew(VoxelMesherCubic()));
|
||||
m->set_channel_index_type(VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
|
||||
m->set_channel_index_isolevel(VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL);
|
||||
add_mesher(m);
|
||||
|
||||
//add_liquid_mesher(Ref<VoxelMesher>(memnew(VoxelMesherLiquiCubic())));
|
||||
tj->add_mesher(m);
|
||||
//add_liquid_mesher(Ref<VoxelMesher>(memnew(VoxelMesherLiquidMarchingCubes())));
|
||||
|
||||
for (int i = 0; i < _meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_lod_size(get_lod_size());
|
||||
mesher->set_voxel_scale(get_voxel_scale());
|
||||
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (md.is_valid()) {
|
||||
md->set_build_flags(get_build_flags());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i = 0; i < _liquid_meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _liquid_meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_lod_size(get_lod_size());
|
||||
mesher->set_voxel_scale(get_voxel_scale());
|
||||
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (md.is_valid()) {
|
||||
md->set_build_flags(get_build_flags());
|
||||
}
|
||||
}*/
|
||||
add_job(lj);
|
||||
add_job(tj);
|
||||
add_job(pj);
|
||||
}
|
||||
|
||||
void VoxelChunkCubic::_bind_methods() {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -55,31 +55,8 @@ class VoxelChunkDefault : public VoxelChunk {
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
static const String BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE;
|
||||
static const String BINDING_STRING_BUILD_FLAGS;
|
||||
|
||||
enum {
|
||||
VOXEL_CHUNK_STATE_GENERATION_QUEUED = 1,
|
||||
VOXEL_CHUNK_STATE_GENERATION,
|
||||
VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED,
|
||||
VOXEL_CHUNK_STATE_MESH_GENERATION,
|
||||
VOXEL_CHUNK_STATE_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
BUILD_PHASE_DONE = 0,
|
||||
BUILD_PHASE_SETUP,
|
||||
BUILD_PHASE_TERRARIN_MESH_SETUP,
|
||||
BUILD_PHASE_COLLIDER,
|
||||
BUILD_PHASE_LIGHTS,
|
||||
BUILD_PHASE_TERRARIN_MESH,
|
||||
#ifdef MESH_DATA_RESOURCE_PRESENT
|
||||
BUILD_PHASE_MESH_DATA_RESOURCES,
|
||||
#endif
|
||||
BUILD_PHASE_FINALIZE,
|
||||
BUILD_PHASE_MAX
|
||||
};
|
||||
|
||||
enum DefaultChannels {
|
||||
DEFAULT_CHANNEL_TYPE = 0,
|
||||
DEFAULT_CHANNEL_ISOLEVEL,
|
||||
@ -94,12 +71,6 @@ public:
|
||||
MAX_DEFAULT_CHANNELS
|
||||
};
|
||||
|
||||
enum ActiveBuildPhaseType {
|
||||
BUILD_PHASE_TYPE_NORMAL = 0,
|
||||
BUILD_PHASE_TYPE_PROCESS,
|
||||
BUILD_PHASE_TYPE_PHYSICS_PROCESS,
|
||||
};
|
||||
|
||||
enum {
|
||||
MESH_INDEX_TERRARIN = 0,
|
||||
MESH_INDEX_PROP,
|
||||
@ -131,21 +102,7 @@ public:
|
||||
int get_build_flags() const;
|
||||
void set_build_flags(const int flags);
|
||||
|
||||
ActiveBuildPhaseType get_active_build_phase_type() const;
|
||||
void set_active_build_phase_type(const ActiveBuildPhaseType value);
|
||||
|
||||
bool get_build_phase_done() const;
|
||||
void set_build_phase_done(const bool value);
|
||||
|
||||
int get_lod_size() const;
|
||||
void set_lod_size(const int lod_size);
|
||||
|
||||
int get_current_build_phase() const;
|
||||
void set_current_build_phase(const int value);
|
||||
|
||||
int get_max_build_phase() const;
|
||||
void set_max_build_phase(const int value);
|
||||
|
||||
//add dirty flags
|
||||
bool get_lights_dirty() const;
|
||||
void set_lights_dirty(const bool value);
|
||||
|
||||
@ -156,18 +113,6 @@ public:
|
||||
int get_current_lod_level() const;
|
||||
void set_current_lod_level(const int value);
|
||||
|
||||
//Data Management functions
|
||||
void generate_ao();
|
||||
|
||||
void build_step();
|
||||
|
||||
void build_phase();
|
||||
void build_phase_process();
|
||||
void build_phase_physics_process();
|
||||
|
||||
bool has_next_phase();
|
||||
void next_phase();
|
||||
|
||||
//Meshes
|
||||
Dictionary get_mesh_rids();
|
||||
void set_mesh_rids(const Dictionary &rids);
|
||||
@ -229,25 +174,19 @@ public:
|
||||
bool get_build_step_in_progress() const;
|
||||
void set_build_step_in_progress(const bool value);
|
||||
|
||||
Ref<VoxelJob> get_job();
|
||||
void build();
|
||||
void finalize_build();
|
||||
|
||||
VoxelChunkDefault();
|
||||
~VoxelChunkDefault();
|
||||
|
||||
protected:
|
||||
virtual void _setup_channels();
|
||||
virtual void _build_phase(int phase);
|
||||
virtual void _build_phase_process(int phase);
|
||||
virtual void _build_phase_physics_process(int phase);
|
||||
|
||||
virtual void _create_meshers();
|
||||
virtual void _build(bool immediate);
|
||||
virtual void _visibility_changed(bool visible);
|
||||
|
||||
virtual void _enter_tree();
|
||||
virtual void _exit_tree();
|
||||
virtual void _process(float delta);
|
||||
virtual void _physics_process(float delta);
|
||||
virtual void _world_transform_changed();
|
||||
|
||||
//lights
|
||||
@ -257,23 +196,16 @@ protected:
|
||||
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();
|
||||
|
||||
int _build_flags;
|
||||
|
||||
bool _abort_build;
|
||||
bool _queued_generation;
|
||||
|
||||
int _current_build_phase;
|
||||
int _max_build_phases;
|
||||
bool _enabled;
|
||||
|
||||
bool _lights_dirty;
|
||||
|
||||
int _lod_size;
|
||||
|
||||
//lod
|
||||
int _lod_num;
|
||||
int _current_lod_level;
|
||||
@ -286,24 +218,10 @@ protected:
|
||||
RID _debug_mesh_instance;
|
||||
PoolVector3Array _debug_mesh_array;
|
||||
|
||||
bool _build_prioritized;
|
||||
bool _build_phase_done;
|
||||
bool _build_step_in_progress;
|
||||
|
||||
PoolVector<Vector3> temp_arr_collider;
|
||||
PoolVector<Vector3> temp_arr_collider_liquid;
|
||||
|
||||
ActiveBuildPhaseType _active_build_phase_type;
|
||||
|
||||
Vector<Ref<VoxelLight> > _lights;
|
||||
|
||||
Ref<VoxelJob> _job;
|
||||
|
||||
Array temp_mesh_arr;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelChunkDefault::DefaultChannels);
|
||||
VARIANT_ENUM_CAST(VoxelChunkDefault::ActiveBuildPhaseType);
|
||||
VARIANT_ENUM_CAST(VoxelChunkDefault::BuildFlags);
|
||||
|
||||
#endif
|
||||
|
@ -71,10 +71,6 @@ void VoxelJob::_reset() {
|
||||
_phase = 0;
|
||||
}
|
||||
|
||||
#define NEW 0
|
||||
|
||||
#if NEW
|
||||
|
||||
void VoxelJob::_execute() {
|
||||
|
||||
ActiveBuildPhaseType origpt = _build_phase_type;
|
||||
@ -84,43 +80,6 @@ void VoxelJob::_execute() {
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void VoxelJob::_execute() {
|
||||
ERR_FAIL_COND(!_chunk.is_valid());
|
||||
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
|
||||
ERR_FAIL_COND(!chunk.is_valid());
|
||||
|
||||
if (!chunk->has_next_phase()) {
|
||||
set_complete(true);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(!chunk->has_next_phase());
|
||||
|
||||
while (!get_cancelled() && _in_tree && chunk->has_next_phase() && chunk->get_active_build_phase_type() == VoxelChunkDefault::BUILD_PHASE_TYPE_NORMAL) {
|
||||
|
||||
chunk->build_phase();
|
||||
|
||||
if (chunk->get_active_build_phase_type() == VoxelChunkDefault::BUILD_PHASE_TYPE_NORMAL && should_return())
|
||||
return;
|
||||
|
||||
if (!chunk->get_build_phase_done())
|
||||
break;
|
||||
}
|
||||
|
||||
chunk->set_build_step_in_progress(false);
|
||||
|
||||
if (!_in_tree) {
|
||||
chunk.unref();
|
||||
}
|
||||
|
||||
set_complete(true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void VoxelJob::execute_phase() {
|
||||
call("_execute_phase");
|
||||
}
|
||||
@ -225,6 +184,111 @@ void VoxelJob::generate_random_ao(int seed, int octaves, int period, float persi
|
||||
}
|
||||
}
|
||||
|
||||
Array VoxelJob::merge_mesh_array(Array arr) const {
|
||||
ERR_FAIL_COND_V(arr.size() != VisualServer::ARRAY_MAX, arr);
|
||||
|
||||
PoolVector3Array verts = arr[VisualServer::ARRAY_VERTEX];
|
||||
PoolVector3Array normals = arr[VisualServer::ARRAY_NORMAL];
|
||||
PoolVector2Array uvs = arr[VisualServer::ARRAY_TEX_UV];
|
||||
PoolColorArray colors = arr[VisualServer::ARRAY_COLOR];
|
||||
PoolIntArray indices = arr[VisualServer::ARRAY_INDEX];
|
||||
|
||||
bool has_normals = normals.size() > 0;
|
||||
bool has_uvs = uvs.size() > 0;
|
||||
bool has_colors = colors.size() > 0;
|
||||
|
||||
int i = 0;
|
||||
while (i < verts.size()) {
|
||||
Vector3 v = verts[i];
|
||||
|
||||
Array equals;
|
||||
for (int j = i + 1; j < verts.size(); ++j) {
|
||||
Vector3 vc = verts[j];
|
||||
|
||||
if (Math::is_equal_approx(v.x, vc.x) && Math::is_equal_approx(v.y, vc.y) && Math::is_equal_approx(v.z, vc.z))
|
||||
equals.push_back(j);
|
||||
}
|
||||
|
||||
for (int k = 0; k < equals.size(); ++k) {
|
||||
int rem = equals[k];
|
||||
int remk = rem - k;
|
||||
|
||||
verts.remove(remk);
|
||||
|
||||
if (has_normals)
|
||||
normals.remove(remk);
|
||||
if (has_uvs)
|
||||
uvs.remove(remk);
|
||||
if (has_colors)
|
||||
colors.remove(remk);
|
||||
|
||||
for (int j = 0; j < indices.size(); ++j) {
|
||||
int indx = indices[j];
|
||||
|
||||
if (indx == remk)
|
||||
indices.set(j, i);
|
||||
else if (indx > remk)
|
||||
indices.set(j, indx - 1);
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
arr[VisualServer::ARRAY_VERTEX] = verts;
|
||||
|
||||
if (has_normals)
|
||||
arr[VisualServer::ARRAY_NORMAL] = normals;
|
||||
if (has_uvs)
|
||||
arr[VisualServer::ARRAY_TEX_UV] = uvs;
|
||||
if (has_colors)
|
||||
arr[VisualServer::ARRAY_COLOR] = colors;
|
||||
|
||||
arr[VisualServer::ARRAY_INDEX] = indices;
|
||||
|
||||
return arr;
|
||||
}
|
||||
Array VoxelJob::bake_mesh_array_uv(Array arr, Ref<Texture> tex, const float mul_color) const {
|
||||
ERR_FAIL_COND_V(arr.size() != VisualServer::ARRAY_MAX, arr);
|
||||
ERR_FAIL_COND_V(!tex.is_valid(), arr);
|
||||
|
||||
Ref<Image> img = tex->get_data();
|
||||
|
||||
ERR_FAIL_COND_V(!img.is_valid(), arr);
|
||||
|
||||
Vector2 imgsize = img->get_size();
|
||||
|
||||
PoolVector2Array uvs = arr[VisualServer::ARRAY_TEX_UV];
|
||||
PoolColorArray colors = arr[VisualServer::ARRAY_COLOR];
|
||||
|
||||
if (colors.size() < uvs.size())
|
||||
colors.resize(uvs.size());
|
||||
|
||||
#if !GODOT4
|
||||
img->lock();
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < uvs.size(); ++i) {
|
||||
Vector2 uv = uvs[i];
|
||||
uv *= imgsize;
|
||||
|
||||
int ux = static_cast<int>(CLAMP(uv.x, 0, imgsize.x - 1));
|
||||
int uy = static_cast<int>(CLAMP(uv.y, 0, imgsize.y - 1));
|
||||
|
||||
Color c = img->get_pixel(ux, uy);
|
||||
|
||||
colors.set(i, colors[i] * c * mul_color);
|
||||
}
|
||||
|
||||
#if !GODOT4
|
||||
img->unlock();
|
||||
#endif
|
||||
|
||||
arr[VisualServer::ARRAY_COLOR] = colors;
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
void VoxelJob::chunk_exit_tree() {
|
||||
|
||||
_in_tree = false;
|
||||
@ -290,7 +354,7 @@ void VoxelJob::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("execute_phase"), &VoxelJob::execute_phase);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelJob::generate_ao);
|
||||
ClassDB::bind_method(D_METHOD("generate_random_ao", "seed", "octaves", "period", "persistence", "scale_factor"), &VoxelJob::generate_random_ao);
|
||||
ClassDB::bind_method(D_METHOD("generate_random_ao", "seed", "octaves", "period", "persistence", "scale_factor"), &VoxelJob::generate_random_ao, DEFVAL(4), DEFVAL(30), DEFVAL(0.3), DEFVAL(0.6));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("chunk_exit_tree"), &VoxelJob::chunk_exit_tree);
|
||||
|
||||
|
@ -23,6 +23,8 @@ SOFTWARE.
|
||||
#ifndef VOXEL_JOB_H
|
||||
#define VOXEL_JOB_H
|
||||
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
#if THREAD_POOL_PRESENT
|
||||
#include "../../../thread_pool/thread_pool_job.h"
|
||||
#else
|
||||
@ -75,7 +77,9 @@ public:
|
||||
void physics_process(const float delta);
|
||||
|
||||
void generate_ao();
|
||||
void generate_random_ao(int seed, int octaves, int period, float persistence, float scale_factor);
|
||||
void generate_random_ao(int seed, int octaves = 4, int period = 30, float persistence = 0.3, float scale_factor = 0.6);
|
||||
Array merge_mesh_array(Array arr) const;
|
||||
Array bake_mesh_array_uv(Array arr, Ref<Texture> tex, float mul_color = 0.7) const;
|
||||
|
||||
void chunk_exit_tree();
|
||||
|
||||
|
@ -33,6 +33,10 @@ SOFTWARE.
|
||||
void VoxelLightJob::phase_light() {
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
|
||||
if ((chunk->get_build_flags() & VoxelChunkDefault::BUILD_FLAG_GENERATE_AO) != 0)
|
||||
if (!chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_AO))
|
||||
generate_ao();
|
||||
|
||||
bool gr = (chunk->get_build_flags() & VoxelChunkDefault::BUILD_FLAG_AUTO_GENERATE_RAO) != 0;
|
||||
|
||||
if (!gr && (chunk->get_build_flags() & VoxelChunkDefault::BUILD_FLAG_USE_LIGHTING) == 0) {
|
||||
@ -50,7 +54,7 @@ void VoxelLightJob::phase_light() {
|
||||
}
|
||||
|
||||
if (gr && should_do()) {
|
||||
chunk->generate_random_ao(chunk->get_voxel_world()->get_current_seed());
|
||||
generate_random_ao(chunk->get_voxel_world()->get_current_seed());
|
||||
|
||||
if (should_return())
|
||||
return;
|
||||
|
@ -50,6 +50,64 @@ void VoxelPropJob::phase_reset() {
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelPropJob::phase_physics_process() {
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
|
||||
//TODO this should only update the differences
|
||||
for (int i = 0; i < chunk->get_collider_count(); ++i) {
|
||||
PhysicsServer::get_singleton()->free(chunk->get_collider_body(i));
|
||||
}
|
||||
|
||||
chunk->clear_colliders();
|
||||
|
||||
#ifdef MESH_DATA_RESOURCE_PRESENT
|
||||
for (int i = 0; i < chunk->get_mesh_data_resource_count(); ++i) {
|
||||
Ref<MeshDataResource> mdr = chunk->get_mesh_data_resource(i);
|
||||
|
||||
for (int j = 0; j < mdr->get_collision_shape_count(); ++j) {
|
||||
Ref<Shape> shape = mdr->get_collision_shape(j);
|
||||
Transform offset = mdr->get_collision_shape_offset(j);
|
||||
|
||||
if (!shape.is_valid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RID body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
|
||||
|
||||
Transform transform = chunk->get_mesh_data_resource_transform(i);
|
||||
transform *= offset;
|
||||
|
||||
PhysicsServer::get_singleton()->body_add_shape(body, shape->get_rid());
|
||||
|
||||
//TODO store the layer mask somewhere
|
||||
PhysicsServer::get_singleton()->body_set_collision_layer(body, 1);
|
||||
PhysicsServer::get_singleton()->body_set_collision_mask(body, 1);
|
||||
|
||||
if (chunk->get_voxel_world()->is_inside_tree() && chunk->get_voxel_world()->is_inside_world()) {
|
||||
Ref<World> world = chunk->get_voxel_world()->GET_WORLD();
|
||||
|
||||
if (world.is_valid() && world->get_space() != RID()) {
|
||||
PhysicsServer::get_singleton()->body_set_space(body, world->get_space());
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, chunk->get_transform() * transform);
|
||||
|
||||
chunk->add_collider(transform, shape, shape->get_rid(), body);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TOOLS_ENABLED
|
||||
if (SceneTree::get_singleton()->is_debugging_collisions_hint() && chunk->get_collider_count() > 0) {
|
||||
chunk->draw_debug_mdr_colliders();
|
||||
}
|
||||
#endif
|
||||
|
||||
set_build_phase_type(BUILD_PHASE_TYPE_NORMAL);
|
||||
next_phase();
|
||||
}
|
||||
|
||||
void VoxelPropJob::phase_prop() {
|
||||
#ifdef MESH_DATA_RESOURCE_PRESENT
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
@ -196,7 +254,7 @@ void VoxelPropJob::phase_prop() {
|
||||
|
||||
if (should_do()) {
|
||||
if (chunk->get_lod_num() >= 2) {
|
||||
Array temp_mesh_arr2 = chunk->merge_mesh_array(temp_mesh_arr);
|
||||
Array temp_mesh_arr2 = merge_mesh_array(temp_mesh_arr);
|
||||
temp_mesh_arr = temp_mesh_arr2;
|
||||
|
||||
VisualServer::get_singleton()->mesh_add_surface_from_arrays(chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_PROP, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 2), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr2);
|
||||
@ -222,7 +280,7 @@ void VoxelPropJob::phase_prop() {
|
||||
}
|
||||
|
||||
if (tex.is_valid()) {
|
||||
temp_mesh_arr = chunk->bake_mesh_array_uv(temp_mesh_arr, tex);
|
||||
temp_mesh_arr = bake_mesh_array_uv(temp_mesh_arr, tex);
|
||||
temp_mesh_arr[VisualServer::ARRAY_TEX_UV] = Variant();
|
||||
|
||||
VisualServer::get_singleton()->mesh_add_surface_from_arrays(chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_PROP, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 3), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr);
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
void set_prop_mesher(const Ref<VoxelMesher> &mesher);
|
||||
|
||||
void phase_reset();
|
||||
void phase_physics_process();
|
||||
void phase_prop();
|
||||
|
||||
void _execute();
|
||||
|
@ -27,7 +27,9 @@ SOFTWARE.
|
||||
#include "../../library/voxel_surface.h"
|
||||
#include "../../library/voxelman_library.h"
|
||||
|
||||
#include "../../meshers/default/voxel_mesher_default.h"
|
||||
#include "../../meshers/voxel_mesher.h"
|
||||
|
||||
#include "../default/voxel_chunk_default.h"
|
||||
|
||||
Ref<VoxelMesher> VoxelTerrarinJob::get_mesher(int index) const {
|
||||
@ -209,6 +211,49 @@ void VoxelTerrarinJob::phase_collider() {
|
||||
}
|
||||
|
||||
set_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS);
|
||||
next_phase();
|
||||
}
|
||||
|
||||
void VoxelTerrarinJob::phase_physics_process() {
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
|
||||
if (temp_arr_collider.size() != 0) {
|
||||
if (!chunk->has_meshes(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_BODY)) {
|
||||
chunk->create_colliders(VoxelChunkDefault::MESH_INDEX_TERRARIN);
|
||||
}
|
||||
|
||||
PhysicsServer::get_singleton()->shape_set_data(chunk->get_mesh_rid(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_SHAPE), temp_arr_collider);
|
||||
|
||||
temp_arr_collider.resize(0);
|
||||
}
|
||||
|
||||
if (temp_arr_collider_liquid.size() != 0) {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
if (!chunk->has_meshes(VoxelChunkDefault::MESH_INDEX_LIQUID, VoxelChunkDefault::MESH_TYPE_INDEX_BODY)) {
|
||||
chunk->create_colliders(VoxelChunkDefault::MESH_INDEX_LIQUID);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else {
|
||||
if (!has_meshes(MESH_INDEX_LIQUID, MESH_TYPE_INDEX_AREA)) {
|
||||
create_colliders_area(MESH_INDEX_LIQUID);
|
||||
}
|
||||
}*/
|
||||
|
||||
PhysicsServer::get_singleton()->shape_set_data(chunk->get_mesh_rid(VoxelChunkDefault::MESH_INDEX_LIQUID, VoxelChunkDefault::MESH_TYPE_INDEX_SHAPE), temp_arr_collider_liquid);
|
||||
|
||||
temp_arr_collider_liquid.resize(0);
|
||||
}
|
||||
|
||||
//TODO this should only update the differences
|
||||
for (int i = 0; i < chunk->get_collider_count(); ++i) {
|
||||
PhysicsServer::get_singleton()->free(chunk->get_collider_body(i));
|
||||
}
|
||||
|
||||
chunk->clear_colliders();
|
||||
|
||||
set_build_phase_type(BUILD_PHASE_TYPE_NORMAL);
|
||||
next_phase();
|
||||
}
|
||||
|
||||
void VoxelTerrarinJob::phase_terrarin_mesh() {
|
||||
@ -414,7 +459,7 @@ void VoxelTerrarinJob::phase_terrarin_mesh() {
|
||||
|
||||
if (should_do()) {
|
||||
if (chunk->get_lod_num() >= 2) {
|
||||
Array temp_mesh_arr2 = chunk->merge_mesh_array(temp_mesh_arr);
|
||||
Array temp_mesh_arr2 = merge_mesh_array(temp_mesh_arr);
|
||||
temp_mesh_arr = temp_mesh_arr2;
|
||||
|
||||
VisualServer::get_singleton()->mesh_add_surface_from_arrays(chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 2), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr2);
|
||||
@ -441,7 +486,7 @@ void VoxelTerrarinJob::phase_terrarin_mesh() {
|
||||
}
|
||||
|
||||
if (tex.is_valid()) {
|
||||
temp_mesh_arr = chunk->bake_mesh_array_uv(temp_mesh_arr, tex);
|
||||
temp_mesh_arr = bake_mesh_array_uv(temp_mesh_arr, tex);
|
||||
temp_mesh_arr[VisualServer::ARRAY_TEX_UV] = Variant();
|
||||
|
||||
VisualServer::get_singleton()->mesh_add_surface_from_arrays(chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 3), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr);
|
||||
@ -583,6 +628,43 @@ void VoxelTerrarinJob::_execute_phase() {
|
||||
phase_finalize_physics_process();
|
||||
}
|
||||
|
||||
void VoxelTerrarinJob::_reset() {
|
||||
VoxelJob::_reset();
|
||||
|
||||
_build_done = false;
|
||||
_phase = 0;
|
||||
|
||||
for (int i = 0; i < _meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_voxel_scale(_chunk->get_voxel_scale());
|
||||
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (chunk.is_valid() && md.is_valid()) {
|
||||
md->set_build_flags(chunk->get_build_flags());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _liquid_meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _liquid_meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_voxel_scale(_chunk->get_voxel_scale());
|
||||
|
||||
Ref<VoxelChunkDefault> chunk = _chunk;
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (chunk.is_valid() && md.is_valid()) {
|
||||
md->set_build_flags(chunk->get_build_flags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VoxelTerrarinJob::VoxelTerrarinJob() {
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,14 @@ public:
|
||||
void phase_setup();
|
||||
void phase_terrarin_mesh_setup();
|
||||
void phase_collider();
|
||||
void phase_physics_proces();
|
||||
void phase_terrarin_mesh();
|
||||
void phase_finalize();
|
||||
void phase_finalize_physics_process();
|
||||
void phase_physics_process();
|
||||
|
||||
void _execute_phase();
|
||||
void _reset();
|
||||
|
||||
VoxelTerrarinJob();
|
||||
~VoxelTerrarinJob();
|
||||
|
@ -26,6 +26,10 @@ SOFTWARE.
|
||||
|
||||
#include "../../defines.h"
|
||||
|
||||
#include "../jobs/voxel_light_job.h"
|
||||
#include "../jobs/voxel_prop_job.h"
|
||||
#include "../jobs/voxel_terrarin_job.h"
|
||||
|
||||
VoxelChunkMarchingCubes::VoxelChunkMarchingCubes() {
|
||||
}
|
||||
|
||||
@ -37,45 +41,26 @@ void VoxelChunkMarchingCubes::_setup_channels() {
|
||||
}
|
||||
|
||||
void VoxelChunkMarchingCubes::_create_meshers() {
|
||||
set_prop_mesher(Ref<VoxelMesher>(memnew(VoxelMesherMarchingCubes)));
|
||||
Ref<VoxelTerrarinJob> tj;
|
||||
tj.instance();
|
||||
|
||||
Ref<VoxelLightJob> lj;
|
||||
lj.instance();
|
||||
|
||||
Ref<VoxelPropJob> pj;
|
||||
pj.instance();
|
||||
pj->set_prop_mesher(Ref<VoxelMesher>(memnew(VoxelMesherMarchingCubes)));
|
||||
|
||||
Ref<VoxelMesher> m = Ref<VoxelMesher>(memnew(VoxelMesherMarchingCubes()));
|
||||
m->set_channel_index_type(VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
|
||||
m->set_channel_index_isolevel(VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL);
|
||||
add_mesher(m);
|
||||
|
||||
tj->add_mesher(m);
|
||||
//add_liquid_mesher(Ref<VoxelMesher>(memnew(VoxelMesherLiquidMarchingCubes())));
|
||||
|
||||
for (int i = 0; i < _meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_lod_size(get_lod_size());
|
||||
mesher->set_voxel_scale(get_voxel_scale());
|
||||
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (md.is_valid()) {
|
||||
md->set_build_flags(get_build_flags());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i = 0; i < _liquid_meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _liquid_meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_lod_size(get_lod_size());
|
||||
mesher->set_voxel_scale(get_voxel_scale());
|
||||
|
||||
Ref<VoxelMesherDefault> md = mesher;
|
||||
|
||||
if (md.is_valid()) {
|
||||
md->set_build_flags(get_build_flags());
|
||||
}
|
||||
}*/
|
||||
add_job(lj);
|
||||
add_job(tj);
|
||||
add_job(pj);
|
||||
}
|
||||
|
||||
void VoxelChunkMarchingCubes::_bind_methods() {
|
||||
|
@ -30,6 +30,10 @@ SOFTWARE.
|
||||
|
||||
#include "jobs/voxel_job.h"
|
||||
|
||||
#if THREAD_POOL_PRESENT
|
||||
#include "../../thread_pool/thread_pool.h"
|
||||
#endif
|
||||
|
||||
_FORCE_INLINE_ bool VoxelChunk::get_is_build_threaded() const {
|
||||
return _is_build_threaded;
|
||||
}
|
||||
@ -195,14 +199,6 @@ float VoxelChunk::get_voxel_scale() const {
|
||||
}
|
||||
void VoxelChunk::set_voxel_scale(const float value) {
|
||||
_voxel_scale = value;
|
||||
|
||||
for (int i = 0; i < _meshers.size(); ++i) {
|
||||
Ref<VoxelMesher> mesher = _meshers.get(i);
|
||||
|
||||
ERR_CONTINUE(!mesher.is_valid());
|
||||
|
||||
mesher->set_voxel_scale(_voxel_scale);
|
||||
}
|
||||
}
|
||||
|
||||
VoxelWorld *VoxelChunk::get_voxel_world() const {
|
||||
@ -249,60 +245,34 @@ void VoxelChunk::next_job() {
|
||||
++_current_job;
|
||||
|
||||
if (_current_job >= _jobs.size()) {
|
||||
_current_job = 0;
|
||||
_current_job = -1;
|
||||
set_is_generating(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<VoxelJob> j = _jobs[_current_job];
|
||||
|
||||
if (!j.is_valid()) {
|
||||
//skip if invalid
|
||||
next_job();
|
||||
}
|
||||
|
||||
if (j->get_build_phase_type() == VoxelJob::BUILD_PHASE_TYPE_NORMAL) {
|
||||
j->set_complete(false);
|
||||
|
||||
#if THREAD_POOL_PRESENT
|
||||
ThreadPool::get_singleton()->add_job(j);
|
||||
#else
|
||||
j->execute();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Ref<VoxelJob> VoxelChunk::get_current_job() {
|
||||
if (_current_job < 0 || _current_job >= _jobs.size()) {
|
||||
return Ref<VoxelJob>();
|
||||
}
|
||||
|
||||
Ref<VoxelMesher> VoxelChunk::get_mesher(int index) const {
|
||||
ERR_FAIL_INDEX_V(index, _meshers.size(), Ref<VoxelMesher>());
|
||||
|
||||
return _meshers.get(index);
|
||||
}
|
||||
void VoxelChunk::set_mesher(int index, const Ref<VoxelMesher> &mesher) {
|
||||
ERR_FAIL_INDEX(index, _meshers.size());
|
||||
|
||||
_meshers.set(index, mesher);
|
||||
}
|
||||
void VoxelChunk::remove_mesher(const int index) {
|
||||
ERR_FAIL_INDEX(index, _meshers.size());
|
||||
|
||||
_meshers.remove(index);
|
||||
}
|
||||
void VoxelChunk::add_mesher(const Ref<VoxelMesher> &mesher) {
|
||||
_meshers.push_back(mesher);
|
||||
}
|
||||
int VoxelChunk::get_mesher_count() const {
|
||||
return _meshers.size();
|
||||
}
|
||||
|
||||
Ref<VoxelMesher> VoxelChunk::get_liquid_mesher(int index) const {
|
||||
ERR_FAIL_INDEX_V(index, _liquid_meshers.size(), Ref<VoxelMesher>());
|
||||
|
||||
return _liquid_meshers.get(index);
|
||||
}
|
||||
void VoxelChunk::set_liquid_mesher(int index, const Ref<VoxelMesher> &mesher) {
|
||||
ERR_FAIL_INDEX(index, _liquid_meshers.size());
|
||||
|
||||
_liquid_meshers.set(index, mesher);
|
||||
}
|
||||
void VoxelChunk::remove_liquid_mesher(const int index) {
|
||||
ERR_FAIL_INDEX(index, _liquid_meshers.size());
|
||||
|
||||
_liquid_meshers.remove(index);
|
||||
}
|
||||
void VoxelChunk::add_liquid_mesher(const Ref<VoxelMesher> &mesher) {
|
||||
_liquid_meshers.push_back(mesher);
|
||||
}
|
||||
int VoxelChunk::get_liquid_mesher_count() const {
|
||||
return _liquid_meshers.size();
|
||||
}
|
||||
|
||||
Ref<VoxelMesher> VoxelChunk::get_prop_mesher() const {
|
||||
return _prop_mesher;
|
||||
}
|
||||
void VoxelChunk::set_prop_mesher(const Ref<VoxelMesher> &mesher) {
|
||||
_prop_mesher = mesher;
|
||||
return _jobs[_current_job];
|
||||
}
|
||||
|
||||
//Voxel Data
|
||||
@ -611,111 +581,6 @@ void VoxelChunk::clear() {
|
||||
call("_clear");
|
||||
}
|
||||
|
||||
Array VoxelChunk::merge_mesh_array(Array arr) const {
|
||||
ERR_FAIL_COND_V(arr.size() != VisualServer::ARRAY_MAX, arr);
|
||||
|
||||
PoolVector3Array verts = arr[VisualServer::ARRAY_VERTEX];
|
||||
PoolVector3Array normals = arr[VisualServer::ARRAY_NORMAL];
|
||||
PoolVector2Array uvs = arr[VisualServer::ARRAY_TEX_UV];
|
||||
PoolColorArray colors = arr[VisualServer::ARRAY_COLOR];
|
||||
PoolIntArray indices = arr[VisualServer::ARRAY_INDEX];
|
||||
|
||||
bool has_normals = normals.size() > 0;
|
||||
bool has_uvs = uvs.size() > 0;
|
||||
bool has_colors = colors.size() > 0;
|
||||
|
||||
int i = 0;
|
||||
while (i < verts.size()) {
|
||||
Vector3 v = verts[i];
|
||||
|
||||
Array equals;
|
||||
for (int j = i + 1; j < verts.size(); ++j) {
|
||||
Vector3 vc = verts[j];
|
||||
|
||||
if (Math::is_equal_approx(v.x, vc.x) && Math::is_equal_approx(v.y, vc.y) && Math::is_equal_approx(v.z, vc.z))
|
||||
equals.push_back(j);
|
||||
}
|
||||
|
||||
for (int k = 0; k < equals.size(); ++k) {
|
||||
int rem = equals[k];
|
||||
int remk = rem - k;
|
||||
|
||||
verts.remove(remk);
|
||||
|
||||
if (has_normals)
|
||||
normals.remove(remk);
|
||||
if (has_uvs)
|
||||
uvs.remove(remk);
|
||||
if (has_colors)
|
||||
colors.remove(remk);
|
||||
|
||||
for (int j = 0; j < indices.size(); ++j) {
|
||||
int indx = indices[j];
|
||||
|
||||
if (indx == remk)
|
||||
indices.set(j, i);
|
||||
else if (indx > remk)
|
||||
indices.set(j, indx - 1);
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
arr[VisualServer::ARRAY_VERTEX] = verts;
|
||||
|
||||
if (has_normals)
|
||||
arr[VisualServer::ARRAY_NORMAL] = normals;
|
||||
if (has_uvs)
|
||||
arr[VisualServer::ARRAY_TEX_UV] = uvs;
|
||||
if (has_colors)
|
||||
arr[VisualServer::ARRAY_COLOR] = colors;
|
||||
|
||||
arr[VisualServer::ARRAY_INDEX] = indices;
|
||||
|
||||
return arr;
|
||||
}
|
||||
Array VoxelChunk::bake_mesh_array_uv(Array arr, Ref<Texture> tex, const float mul_color) const {
|
||||
ERR_FAIL_COND_V(arr.size() != VisualServer::ARRAY_MAX, arr);
|
||||
ERR_FAIL_COND_V(!tex.is_valid(), arr);
|
||||
|
||||
Ref<Image> img = tex->get_data();
|
||||
|
||||
ERR_FAIL_COND_V(!img.is_valid(), arr);
|
||||
|
||||
Vector2 imgsize = img->get_size();
|
||||
|
||||
PoolVector2Array uvs = arr[VisualServer::ARRAY_TEX_UV];
|
||||
PoolColorArray colors = arr[VisualServer::ARRAY_COLOR];
|
||||
|
||||
if (colors.size() < uvs.size())
|
||||
colors.resize(uvs.size());
|
||||
|
||||
#if !GODOT4
|
||||
img->lock();
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < uvs.size(); ++i) {
|
||||
Vector2 uv = uvs[i];
|
||||
uv *= imgsize;
|
||||
|
||||
int ux = static_cast<int>(CLAMP(uv.x, 0, imgsize.x - 1));
|
||||
int uy = static_cast<int>(CLAMP(uv.y, 0, imgsize.y - 1));
|
||||
|
||||
Color c = img->get_pixel(ux, uy);
|
||||
|
||||
colors.set(i, colors[i] * c * mul_color);
|
||||
}
|
||||
|
||||
#if !GODOT4
|
||||
img->unlock();
|
||||
#endif
|
||||
|
||||
arr[VisualServer::ARRAY_COLOR] = colors;
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
void VoxelChunk::bake_lights() {
|
||||
if (has_method("_bake_lights"))
|
||||
call("_bake_lights");
|
||||
@ -883,7 +748,7 @@ void VoxelChunk::set_mesh_data_resource_uv_rect(const int index, const Rect2 &uv
|
||||
Transform VoxelChunk::get_mesh_data_resource_transform(const int index) {
|
||||
ERR_FAIL_INDEX_V(index, _mesh_data_resources.size(), Transform());
|
||||
|
||||
return _mesh_data_resources[index].transform;
|
||||
return _mesh_data_resources.write[index].transform;
|
||||
}
|
||||
void VoxelChunk::set_mesh_data_resource_transform(const int index, const Transform &transform) {
|
||||
ERR_FAIL_INDEX(index, _mesh_data_resources.size());
|
||||
@ -1030,28 +895,6 @@ void VoxelChunk::generation_process(const float delta) {
|
||||
void VoxelChunk::generation_physics_process(const float delta) {
|
||||
call("_generation_physics_process", delta);
|
||||
}
|
||||
void VoxelChunk::_generation_process(const float delta) {
|
||||
ERR_FAIL_INDEX(_current_job, _jobs.size());
|
||||
|
||||
Ref<VoxelJob> job = _jobs[_current_job];
|
||||
|
||||
ERR_FAIL_COND(!job.is_valid());
|
||||
|
||||
if (job->get_build_phase_type() == VoxelJob::BUILD_PHASE_TYPE_PROCESS) {
|
||||
job->process(delta);
|
||||
}
|
||||
}
|
||||
void VoxelChunk::_generation_physics_process(const float delta) {
|
||||
ERR_FAIL_INDEX(_current_job, _jobs.size());
|
||||
|
||||
Ref<VoxelJob> job = _jobs[_current_job];
|
||||
|
||||
ERR_FAIL_COND(!job.is_valid());
|
||||
|
||||
if (job->get_build_phase_type() == VoxelJob::BUILD_PHASE_TYPE_PHYSICS_PROCESS) {
|
||||
job->physics_process(delta);
|
||||
}
|
||||
}
|
||||
|
||||
Transform VoxelChunk::get_transform() const {
|
||||
return _transform;
|
||||
@ -1112,8 +955,6 @@ VoxelChunk::VoxelChunk() {
|
||||
}
|
||||
|
||||
VoxelChunk::~VoxelChunk() {
|
||||
_meshers.clear();
|
||||
|
||||
if (_library.is_valid()) {
|
||||
_library.unref();
|
||||
}
|
||||
@ -1140,6 +981,57 @@ VoxelChunk::~VoxelChunk() {
|
||||
_jobs.clear();
|
||||
}
|
||||
|
||||
void VoxelChunk::_enter_tree() {
|
||||
for (int i = 0; i < _jobs.size(); ++i) {
|
||||
Ref<VoxelJob> j = _jobs[i];
|
||||
|
||||
if (j.is_valid()) {
|
||||
j->set_chunk(Ref<VoxelChunk>(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::_exit_tree() {
|
||||
_abort_build = true;
|
||||
|
||||
for (int i = 0; i < _jobs.size(); ++i) {
|
||||
Ref<VoxelJob> j = _jobs[i];
|
||||
|
||||
if (j.is_valid()) {
|
||||
j->chunk_exit_tree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::_generation_process(const float delta) {
|
||||
ERR_FAIL_INDEX(_current_job, _jobs.size());
|
||||
|
||||
Ref<VoxelJob> job = _jobs[_current_job];
|
||||
|
||||
ERR_FAIL_COND(!job.is_valid());
|
||||
|
||||
if (job->get_build_phase_type() == VoxelJob::BUILD_PHASE_TYPE_PROCESS) {
|
||||
if (!_voxel_world->can_chunk_do_build_step())
|
||||
return;
|
||||
|
||||
job->process(delta);
|
||||
}
|
||||
}
|
||||
void VoxelChunk::_generation_physics_process(const float delta) {
|
||||
ERR_FAIL_INDEX(_current_job, _jobs.size());
|
||||
|
||||
Ref<VoxelJob> job = _jobs[_current_job];
|
||||
|
||||
ERR_FAIL_COND(!job.is_valid());
|
||||
|
||||
if (job->get_build_phase_type() == VoxelJob::BUILD_PHASE_TYPE_PHYSICS_PROCESS) {
|
||||
if (!_voxel_world->can_chunk_do_build_step())
|
||||
return;
|
||||
|
||||
job->physics_process(delta);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::_world_transform_changed() {
|
||||
Transform wt;
|
||||
|
||||
@ -1334,22 +1226,7 @@ void VoxelChunk::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_current_job_index"), &VoxelChunk::get_current_job_index);
|
||||
ClassDB::bind_method(D_METHOD("next_job"), &VoxelChunk::next_job);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_mesher", "index"), &VoxelChunk::get_mesher);
|
||||
ClassDB::bind_method(D_METHOD("set_mesher", "index", "mesher"), &VoxelChunk::set_mesher);
|
||||
ClassDB::bind_method(D_METHOD("remove_mesher", "index"), &VoxelChunk::remove_mesher);
|
||||
ClassDB::bind_method(D_METHOD("add_mesher", "mesher"), &VoxelChunk::add_mesher);
|
||||
ClassDB::bind_method(D_METHOD("get_mesher_count"), &VoxelChunk::get_mesher_count);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_liquid_mesher", "index"), &VoxelChunk::get_liquid_mesher);
|
||||
ClassDB::bind_method(D_METHOD("set_liquid_mesher", "index", "mesher"), &VoxelChunk::set_liquid_mesher);
|
||||
ClassDB::bind_method(D_METHOD("remove_liquid_mesher", "index"), &VoxelChunk::remove_liquid_mesher);
|
||||
ClassDB::bind_method(D_METHOD("add_liquid_mesher", "mesher"), &VoxelChunk::add_liquid_mesher);
|
||||
ClassDB::bind_method(D_METHOD("get_liquid_mesher_count"), &VoxelChunk::get_liquid_mesher_count);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_prop_mesher"), &VoxelChunk::get_prop_mesher);
|
||||
ClassDB::bind_method(D_METHOD("set_prop_mesher", "mesher"), &VoxelChunk::set_prop_mesher);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop_mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher", 0), "set_prop_mesher", "get_prop_mesher");
|
||||
ClassDB::bind_method(D_METHOD("get_current_job"), &VoxelChunk::get_current_job);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_voxel_world"), &VoxelChunk::get_voxel_world);
|
||||
ClassDB::bind_method(D_METHOD("set_voxel_world", "world"), &VoxelChunk::set_voxel_world_bind);
|
||||
@ -1385,9 +1262,6 @@ void VoxelChunk::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_data_index", "x", "y", "z"), &VoxelChunk::get_data_index);
|
||||
ClassDB::bind_method(D_METHOD("get_data_size"), &VoxelChunk::get_data_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("merge_mesh_array", "arr"), &VoxelChunk::merge_mesh_array);
|
||||
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_prop", "prop"), &VoxelChunk::add_prop);
|
||||
@ -1448,4 +1322,9 @@ void VoxelChunk::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("to_global", "local"), &VoxelChunk::to_global);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_world_transform_changed"), &VoxelChunk::_world_transform_changed);
|
||||
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("_generation_process"), &VoxelChunk::_generation_process);
|
||||
ClassDB::bind_method(D_METHOD("_generation_physics_process"), &VoxelChunk::_generation_physics_process);
|
||||
}
|
||||
|
@ -149,24 +149,7 @@ public:
|
||||
|
||||
int get_current_job_index();
|
||||
void next_job();
|
||||
|
||||
//Meshers
|
||||
Ref<VoxelMesher> get_mesher(const int index) const;
|
||||
void set_mesher(const int index, const Ref<VoxelMesher> &mesher);
|
||||
void remove_mesher(const int index);
|
||||
void add_mesher(const Ref<VoxelMesher> &mesher);
|
||||
int get_mesher_count() const;
|
||||
|
||||
//Liquid Meshers
|
||||
Ref<VoxelMesher> get_liquid_mesher(const int index) const;
|
||||
void set_liquid_mesher(const int index, const Ref<VoxelMesher> &mesher);
|
||||
void remove_liquid_mesher(const int index);
|
||||
void add_liquid_mesher(const Ref<VoxelMesher> &mesher);
|
||||
int get_liquid_mesher_count() const;
|
||||
|
||||
//Prop Meshers
|
||||
Ref<VoxelMesher> get_prop_mesher() const;
|
||||
void set_prop_mesher(const Ref<VoxelMesher> &mesher);
|
||||
Ref<VoxelJob> get_current_job();
|
||||
|
||||
//Channels
|
||||
void setup_channels();
|
||||
@ -205,9 +188,6 @@ public:
|
||||
void build(const bool immediate = false);
|
||||
void clear();
|
||||
|
||||
Array merge_mesh_array(Array arr) const;
|
||||
Array bake_mesh_array_uv(Array arr, Ref<Texture> tex, float mul_color = 0.7) const;
|
||||
|
||||
//light Baking
|
||||
void bake_lights();
|
||||
void bake_light(Ref<VoxelLight> light);
|
||||
@ -279,8 +259,6 @@ public:
|
||||
void world_light_removed(const Ref<VoxelLight> &light);
|
||||
void generation_process(const float delta);
|
||||
void generation_physics_process(const float delta);
|
||||
void _generation_process(const float delta);
|
||||
void _generation_physics_process(const float delta);
|
||||
|
||||
Transform get_transform() const;
|
||||
void set_transform(const Transform &transform);
|
||||
@ -292,6 +270,12 @@ public:
|
||||
VoxelChunk();
|
||||
~VoxelChunk();
|
||||
|
||||
protected:
|
||||
virtual void _enter_tree();
|
||||
virtual void _exit_tree();
|
||||
virtual void _generation_process(const float delta);
|
||||
virtual void _generation_physics_process(const float delta);
|
||||
|
||||
protected:
|
||||
#if PROPS_PRESENT
|
||||
struct PropDataStore {
|
||||
@ -366,9 +350,6 @@ protected:
|
||||
Vector<Ref<VoxelJob> > _jobs;
|
||||
|
||||
Ref<VoxelmanLibrary> _library;
|
||||
Vector<Ref<VoxelMesher> > _meshers;
|
||||
Vector<Ref<VoxelMesher> > _liquid_meshers;
|
||||
Ref<VoxelMesher> _prop_mesher;
|
||||
|
||||
#if PROPS_PRESENT
|
||||
Vector<PropDataStore> _props;
|
||||
@ -381,6 +362,8 @@ protected:
|
||||
Vector<ColliderBody> _colliders;
|
||||
|
||||
Transform _transform;
|
||||
|
||||
bool _abort_build;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user