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:
Relintai 2020-10-02 23:47:39 +02:00
parent 0db9475db1
commit 235943f7ca
20 changed files with 463 additions and 1768 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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() {

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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() {
}

View File

@ -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();

View File

@ -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() {

View File

@ -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);
}

View File

@ -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