Split _create_chunk() to _create_chunk() and _setup_chunk() in TerrainWorld.

Unfortunately this is a breaking change. (Very slight though.)
Now _create_chunk() should be used to initialize serialized properties
in chunks. The new _setup_chunk() virtual should be used to initialize
other non/serialized properties (like meshers).
Fortunately the only thing that needs to be done is to split old
_create_chunk() into two.
Note that when using procedural generation, the old way should just work
without any updates necessary. This change is only needed when loading
of chunks is desired.
This commit is contained in:
Relintai 2025-04-07 22:06:04 +02:00
parent 32487af081
commit bd476c1d66
8 changed files with 82 additions and 33 deletions

View File

@ -45,7 +45,11 @@ Ref<TerrainChunk> TerrainWorldBlocky::_create_chunk(int x, int z, Ref<TerrainChu
chunk = Ref<TerrainChunk>(memnew(TerrainChunkBlocky));
}
if (chunk->job_get_count() == 0) {
return TerrainWorld::_create_chunk(x, z, chunk);
}
void TerrainWorldBlocky::_setup_chunk(Ref<TerrainChunk> p_chunk) {
if (p_chunk->job_get_count() == 0) {
Ref<TerrainTerrainJob> tj;
tj.instance();
@ -109,12 +113,12 @@ Ref<TerrainChunk> TerrainWorldBlocky::_create_chunk(int x, int z, Ref<TerrainChu
#endif
pj->add_jobs_step(s);
chunk->job_add(lj);
chunk->job_add(tj);
chunk->job_add(pj);
p_chunk->job_add(lj);
p_chunk->job_add(tj);
p_chunk->job_add(pj);
}
return TerrainWorld::_create_chunk(x, z, chunk);
TerrainWorld::_setup_chunk(p_chunk);
}
TerrainWorldBlocky::TerrainWorldBlocky() {

View File

@ -43,6 +43,7 @@ public:
protected:
Ref<TerrainChunk> _create_chunk(int x, int z, Ref<TerrainChunk> p_chunk);
virtual void _setup_chunk(Ref<TerrainChunk> p_chunk);
static void _bind_methods();
};

View File

@ -190,7 +190,18 @@ Ref<TerrainChunk> TerrainWorldDefault::_create_chunk(int x, int z, Ref<TerrainCh
chunk = Ref<TerrainChunk>(memnew(TerrainChunkDefault));
}
if (chunk->job_get_count() == 0) {
Ref<TerrainChunkDefault> vcd = chunk;
if (vcd.is_valid()) {
vcd->set_build_flags(_build_flags);
vcd->set_lod_num(_num_lods);
}
return TerrainWorld::_create_chunk(x, z, chunk);
}
void TerrainWorldDefault::_setup_chunk(Ref<TerrainChunk> p_chunk) {
if (p_chunk->job_get_count() == 0) {
Ref<TerrainTerrainJob> tj;
tj.instance();
@ -224,19 +235,12 @@ Ref<TerrainChunk> TerrainWorldDefault::_create_chunk(int x, int z, Ref<TerrainCh
s->set_job_type(TerrainMesherJobStep::TYPE_BAKE_TEXTURE);
tj->add_jobs_step(s);
chunk->job_add(lj);
chunk->job_add(tj);
chunk->job_add(pj);
p_chunk->job_add(lj);
p_chunk->job_add(tj);
p_chunk->job_add(pj);
}
Ref<TerrainChunkDefault> vcd = chunk;
if (vcd.is_valid()) {
vcd->set_build_flags(_build_flags);
vcd->set_lod_num(_num_lods);
}
return TerrainWorld::_create_chunk(x, z, chunk);
TerrainWorld::_setup_chunk(p_chunk);
}
void TerrainWorldDefault::_chunk_added(Ref<TerrainChunk> chunk) {

View File

@ -64,6 +64,7 @@ protected:
void _notification(int p_what);
void _update_lods();
Ref<TerrainChunk> _create_chunk(int x, int z, Ref<TerrainChunk> p_chunk);
virtual void _setup_chunk(Ref<TerrainChunk> p_chunk);
virtual void _chunk_added(Ref<TerrainChunk> chunk);
int _get_channel_index_info(const ChannelTypeInfo channel_type);

View File

@ -99,6 +99,13 @@ void TerrainChunk::set_is_terrain_generated(const bool value) {
_is_terrain_generated = value;
}
bool TerrainChunk::get_is_setup() const {
return _is_setup;
}
void TerrainChunk::set_is_setup(const bool value) {
_is_setup = value;
}
bool TerrainChunk::is_build_aborted() const {
return _abort_build;
}
@ -1917,6 +1924,7 @@ bool TerrainChunk::is_safe_to_delete() {
}
TerrainChunk::TerrainChunk() {
_is_setup = false;
_is_processing = false;
_is_phisics_processing = false;
_is_in_tree = false;
@ -2267,6 +2275,10 @@ void TerrainChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_is_terrain_generated", "value"), &TerrainChunk::set_is_terrain_generated);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_terrain_generated"), "set_is_terrain_generated", "get_is_terrain_generated");
ClassDB::bind_method(D_METHOD("get_is_setup"), &TerrainChunk::get_is_setup);
ClassDB::bind_method(D_METHOD("set_is_setup", "value"), &TerrainChunk::set_is_setup);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_setup", PROPERTY_HINT_NONE, "", 0), "set_is_setup", "get_is_setup");
ClassDB::bind_method(D_METHOD("is_build_aborted"), &TerrainChunk::is_build_aborted);
ClassDB::bind_method(D_METHOD("get_dirty"), &TerrainChunk::get_dirty);

View File

@ -95,6 +95,9 @@ public:
bool get_is_terrain_generated() const;
void set_is_terrain_generated(const bool value);
bool get_is_setup() const;
void set_is_setup(const bool value);
bool is_build_aborted() const;
bool is_in_tree() const;
@ -522,6 +525,8 @@ protected:
bool _abort_build;
bool _queued_generation;
bool _is_setup;
};
#endif

View File

@ -349,7 +349,11 @@ void TerrainWorld::chunk_add(Ref<TerrainChunk> chunk, const int x, const int z)
emit_signal("chunk_added", chunk);
generation_queue_add_to(chunk);
if (!chunk->get_is_terrain_generated()) {
generation_queue_add_to(chunk);
} else {
chunk->build();
}
}
bool TerrainWorld::chunk_has(const int x, const int z) const {
return _chunks.has(IntPos(x, z));
@ -494,6 +498,7 @@ Ref<TerrainChunk> TerrainWorld::chunk_get_or_create(int x, int z) {
chunk = _world_chunk_data_manager->load_chunk(Vector2i(x, z));
if (chunk.is_valid()) {
chunk_setup(chunk);
chunk_add(chunk, x, z);
return chunk;
}
@ -516,6 +521,7 @@ Ref<TerrainChunk> TerrainWorld::chunk_get_or_load(const int x, const int z) {
chunk = _world_chunk_data_manager->load_chunk(Vector2i(x, z));
if (chunk.is_valid()) {
chunk_setup(chunk);
chunk_add(chunk, x, z);
return chunk;
}
@ -531,6 +537,7 @@ Ref<TerrainChunk> TerrainWorld::chunk_load(const int x, const int z) {
chunk = _world_chunk_data_manager->load_chunk(Vector2i(x, z));
if (chunk.is_valid()) {
chunk_setup(chunk);
chunk_add(chunk, x, z);
return chunk;
}
@ -541,7 +548,10 @@ Ref<TerrainChunk> TerrainWorld::chunk_load(const int x, const int z) {
Ref<TerrainChunk> TerrainWorld::chunk_create(const int x, const int z) {
Ref<TerrainChunk> c;
c = call("_create_chunk", x, z, Ref<TerrainChunk>());
c = call("_create_chunk", x, z, Ref<TerrainChunk>(), true);
chunk_setup(c);
chunk_add(c, x, z);
if (_world_chunk_data_manager.is_valid()) {
_world_chunk_data_manager->on_world_chunk_created(c);
@ -552,25 +562,15 @@ Ref<TerrainChunk> TerrainWorld::chunk_create(const int x, const int z) {
return c;
}
void TerrainWorld::chunk_setup(Ref<TerrainChunk> chunk) {
ERR_FAIL_COND(!chunk.is_valid());
call("_create_chunk", chunk->get_position_x(), chunk->get_position_z(), chunk);
}
Ref<TerrainChunk> TerrainWorld::_create_chunk(const int x, const int z, Ref<TerrainChunk> chunk) {
if (!chunk.is_valid()) {
chunk.instance();
}
//no meshers here
ERR_FAIL_COND_V(!chunk.is_valid(), NULL);
chunk->set_name("Chunk[" + String::num(x) + "," + String::num(z) + "]");
chunk->set_voxel_world(this);
chunk->set_name("Chunk[" + String::num(x) + "," + String::num(z) + "]");
chunk->set_position(x, z);
chunk->set_world_height(_world_height);
chunk->set_library(_library);
@ -582,11 +582,29 @@ Ref<TerrainChunk> TerrainWorld::_create_chunk(const int x, const int z, Ref<Terr
chunk->set_visible(false);
}
chunk_add(chunk, x, z);
return chunk;
}
void TerrainWorld::chunk_setup(Ref<TerrainChunk> chunk) {
ERR_FAIL_COND(!chunk.is_valid());
if (chunk->get_is_setup()) {
return;
}
call("_setup_chunk", chunk);
chunk->set_is_setup(true);
}
void TerrainWorld::_setup_chunk(Ref<TerrainChunk> p_chunk) {
p_chunk->set_voxel_world(this);
if (!get_active()) {
p_chunk->set_visible(false);
}
}
void TerrainWorld::chunk_generate(Ref<TerrainChunk> chunk) {
ERR_FAIL_COND(!chunk.is_valid());
@ -1827,8 +1845,10 @@ void TerrainWorld::_bind_methods() {
BIND_VMETHOD(MethodInfo("_generation_finished"));
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "ret", PROPERTY_HINT_RESOURCE_TYPE, "TerrainChunk"), "_create_chunk", PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "z"), PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerrainChunk")));
BIND_VMETHOD(MethodInfo("_prepare_chunk_for_generation", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerrainChunk")));
BIND_VMETHOD(MethodInfo("_generate_chunk", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerrainChunk")));
BIND_VMETHOD(MethodInfo("_setup_chunk", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerrainChunk")));
ClassDB::bind_method(D_METHOD("chunk_get_or_create", "x", "z"), &TerrainWorld::chunk_get_or_create);
ClassDB::bind_method(D_METHOD("chunk_get_or_load", "x", "z"), &TerrainWorld::chunk_get_or_load);
@ -1836,8 +1856,9 @@ void TerrainWorld::_bind_methods() {
ClassDB::bind_method(D_METHOD("chunk_create", "x", "z"), &TerrainWorld::chunk_create);
ClassDB::bind_method(D_METHOD("chunk_setup", "chunk"), &TerrainWorld::chunk_setup);
ClassDB::bind_method(D_METHOD("_create_chunk", "x", "z", "chunk"), &TerrainWorld::_create_chunk);
ClassDB::bind_method(D_METHOD("_create_chunk", "x", "z", "chunk", "is_new"), &TerrainWorld::_create_chunk);
ClassDB::bind_method(D_METHOD("_generate_chunk", "chunk"), &TerrainWorld::_generate_chunk);
ClassDB::bind_method(D_METHOD("_setup_chunk", "chunk"), &TerrainWorld::_setup_chunk);
ClassDB::bind_method(D_METHOD("can_chunk_do_build_step"), &TerrainWorld::can_chunk_do_build_step);
ClassDB::bind_method(D_METHOD("is_position_walkable", "position"), &TerrainWorld::is_position_walkable);

View File

@ -238,6 +238,7 @@ public:
protected:
virtual void _generate_chunk(Ref<TerrainChunk> chunk);
virtual Ref<TerrainChunk> _create_chunk(int x, int z, Ref<TerrainChunk> p_chunk);
virtual void _setup_chunk(Ref<TerrainChunk> p_chunk);
virtual int _get_channel_index_info(const ChannelTypeInfo channel_type);
void _editor_button_property_pressed(const StringName &p_property);