From f62b605d9a3e2a66cb4c9ec057c91d56bb926b79 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 7 Aug 2021 13:47:55 +0200 Subject: [PATCH] now PropJob will actually use JobSteps. --- world/blocky/terra_world_blocky.cpp | 33 ++- world/jobs/terra_prop_job.cpp | 302 ++++++++++++---------------- world/jobs/terra_prop_job.h | 2 + 3 files changed, 158 insertions(+), 179 deletions(-) diff --git a/world/blocky/terra_world_blocky.cpp b/world/blocky/terra_world_blocky.cpp index 877fec9..28f1169 100644 --- a/world/blocky/terra_world_blocky.cpp +++ b/world/blocky/terra_world_blocky.cpp @@ -31,7 +31,6 @@ SOFTWARE. #include "../jobs/terra_terrarin_job.h" Ref TerraWorldBlocky::_create_chunk(int x, int z, Ref chunk) { - if (!chunk.is_valid()) { chunk = Ref(memnew(TerraChunkBlocky)); } @@ -43,15 +42,11 @@ Ref TerraWorldBlocky::_create_chunk(int x, int z, Ref ch Ref lj; lj.instance(); - Ref pj; - pj.instance(); - pj->set_prop_mesher(Ref(memnew(TerraMesherBlocky))); - Ref s; s.instance(); s->set_job_type(TerraMesherJobStep::TYPE_NORMAL); tj->add_jobs_step(s); - + s.instance(); s->set_job_type(TerraMesherJobStep::TYPE_NORMAL_LOD); s->set_lod_index(1); @@ -73,6 +68,32 @@ Ref TerraWorldBlocky::_create_chunk(int x, int z, Ref ch tj->set_mesher(Ref(memnew(TerraMesherBlocky()))); tj->set_liquid_mesher(Ref(memnew(TerraMesherLiquidBlocky()))); + Ref pj; + pj.instance(); + pj->set_prop_mesher(Ref(memnew(TerraMesherBlocky))); + + s.instance(); + s->set_job_type(TerraMesherJobStep::TYPE_NORMAL); + pj->add_jobs_step(s); + + s.instance(); + s->set_job_type(TerraMesherJobStep::TYPE_MERGE_VERTS); + pj->add_jobs_step(s); + + s.instance(); + s->set_job_type(TerraMesherJobStep::TYPE_BAKE_TEXTURE); + pj->add_jobs_step(s); + + s.instance(); + s->set_job_type(TerraMesherJobStep::TYPE_SIMPLIFY_MESH); +#ifdef MESH_UTILS_PRESENT + Ref fqms; + fqms.instance(); + s->set_fqms(fqms); + s->set_simplification_steps(2); +#endif + pj->add_jobs_step(s); + chunk->job_add(lj); chunk->job_add(tj); chunk->job_add(pj); diff --git a/world/jobs/terra_prop_job.cpp b/world/jobs/terra_prop_job.cpp index a5dbc6c..0d94928 100644 --- a/world/jobs/terra_prop_job.cpp +++ b/world/jobs/terra_prop_job.cpp @@ -24,15 +24,14 @@ SOFTWARE. #include "../../defines.h" +#include "../../library/terra_material_cache.h" #include "../../library/terra_surface.h" #include "../../library/terraman_library.h" -#include "../../library/terra_material_cache.h" -#include "../../meshers/terra_mesher.h" #include "../../meshers/default/terra_mesher_default.h" +#include "../../meshers/terra_mesher.h" #include "../default/terra_chunk_default.h" - #ifdef MESH_DATA_RESOURCE_PRESENT #include "../../../mesh_data_resource/mesh_data_resource.h" #endif @@ -214,140 +213,9 @@ void TerraPropJob::phase_prop() { } } - if (get_prop_mesher()->get_vertex_count() != 0) { - if (should_do()) { - temp_mesh_arr = get_prop_mesher()->build_mesh(); - - if (should_return()) { - return; - } - } - - RID mesh_rid = chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 0); - - if (should_do()) { - if (mesh_rid == RID()) { - if ((chunk->get_build_flags() & TerraChunkDefault::BUILD_FLAG_CREATE_LODS) != 0) - chunk->meshes_create(TerraChunkDefault::MESH_INDEX_PROP, chunk->get_lod_num() + 1); - else - chunk->meshes_create(TerraChunkDefault::MESH_INDEX_PROP, 1); - - mesh_rid = chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 0); - } - - if (VS::get_singleton()->mesh_get_surface_count(mesh_rid) > 0) -#if !GODOT4 - VS::get_singleton()->mesh_remove_surface(mesh_rid, 0); -#else - VS::get_singleton()->mesh_clear(mesh_rid); #endif - if (should_return()) { - return; - } - } - - if (should_do()) { - VS::get_singleton()->mesh_add_surface_from_arrays(mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - - if (chunk->get_library()->prop_material_lod_get(0).is_valid()) - VS::get_singleton()->mesh_surface_set_material(mesh_rid, 0, chunk->get_library()->prop_material_lod_get(0)->get_rid()); - - if (should_return()) { - return; - } - } - - if ((chunk->get_build_flags() & TerraChunkDefault::BUILD_FLAG_CREATE_LODS) != 0) { - if (should_do()) { - if (chunk->get_lod_num() >= 1) { - //for lod 1 just remove uv2 - temp_mesh_arr[VisualServer::ARRAY_TEX_UV2] = Variant(); - - VisualServer::get_singleton()->mesh_add_surface_from_arrays(chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 1), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - - if (chunk->get_library()->prop_material_lod_get(1).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 1), 0, chunk->get_library()->prop_material_lod_get(1)->get_rid()); - } - - if (should_return()) { - return; - } - } - - if (should_do()) { - if (chunk->get_lod_num() >= 2) { - 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->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 2), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr2); - - if (chunk->get_library()->prop_material_lod_get(2).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 2), 0, chunk->get_library()->prop_material_lod_get(2)->get_rid()); - } - if (should_return()) { - return; - } - } - - // if (should_do()) { - if (chunk->get_lod_num() >= 3) { - Ref mat = chunk->get_library()->prop_material_lod_get(0); - Ref spmat = chunk->get_library()->prop_material_lod_get(0); - Ref tex; - - if (mat.is_valid()) { - tex = mat->get_shader_param("texture_albedo"); - } else if (spmat.is_valid()) { - tex = spmat->get_texture(SpatialMaterial::TEXTURE_ALBEDO); - } - - if (tex.is_valid()) { - 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->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 3), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - - if (chunk->get_library()->prop_material_lod_get(3).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 3), 0, chunk->get_library()->prop_material_lod_get(3)->get_rid()); - } - } - -#ifdef MESH_UTILS_PRESENT - if (should_do()) { - if (chunk->get_lod_num() > 4) { - Ref fqms; - fqms.instance(); - fqms->set_preserve_border_edges(true); - fqms->initialize(temp_mesh_arr); - - for (int i = 4; i < chunk->get_lod_num(); ++i) { - fqms->simplify_mesh(temp_mesh_arr.size() * 0.8, 7); - temp_mesh_arr = fqms->get_arrays(); - - VisualServer::get_singleton()->mesh_add_surface_from_arrays( - chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, i), - VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - - if (chunk->get_library()->prop_material_lod_get(i).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material( - chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, i), 0, - chunk->get_library()->prop_material_lod_get(i)->get_rid()); - } - } - - if (should_return()) { - return; - } - } -#endif - } - } - -#endif - - set_complete(true); //So threadpool knows it's done - next_job(); + next_phase(); } void TerraPropJob::_physics_process(float delta) { @@ -376,7 +244,9 @@ void TerraPropJob::_execute_phase() { if (_phase == 1) { phase_prop(); - } else if (_phase > 1) { + } else if (_phase == 2) { + phase_steps(); + } else if (_phase > 2) { set_complete(true); //So threadpool knows it's done next_job(); ERR_FAIL_MSG("TerraPropJob: _phase is too high!"); @@ -400,14 +270,131 @@ void TerraPropJob::_reset() { set_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); } -void TerraPropJob::step_type_normal() { +void TerraPropJob::phase_steps() { Ref chunk = _chunk; - //TODO make this automatic in build_mesh - if ((chunk->get_build_flags() & TerraChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) { - _prop_mesher->bake_colors(_chunk); + ERR_FAIL_COND(!_prop_mesher.is_valid()); + + if (should_return()) { + return; } + if (_prop_mesher->get_vertex_count() == 0) { + reset_stages(); + next_phase(); + + return; + } + + //set up the meshes + if (should_do()) { + RID mesh_rid = chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, 0); + + if (mesh_rid == RID()) { + //need to allocate the meshes + + //first count how many we need + int count = 0; + for (int i = 0; i < _job_steps.size(); ++i) { + Ref step = _job_steps[i]; + + ERR_FAIL_COND(!step.is_valid()); + + switch (step->get_job_type()) { + case TerraMesherJobStep::TYPE_NORMAL: + ++count; + break; + case TerraMesherJobStep::TYPE_NORMAL_LOD: + ++count; + break; + case TerraMesherJobStep::TYPE_DROP_UV2: + ++count; + break; + case TerraMesherJobStep::TYPE_MERGE_VERTS: + ++count; + break; + case TerraMesherJobStep::TYPE_BAKE_TEXTURE: + ++count; + break; + case TerraMesherJobStep::TYPE_SIMPLIFY_MESH: +#ifdef MESH_UTILS_PRESENT + count += step->get_simplification_steps(); +#endif + break; + default: + break; + } + } + + //allocate + if (count > 0) + chunk->meshes_create(TerraChunkDefault::MESH_INDEX_PROP, count); + + } else { + //we have the meshes, just clear + int count = chunk->mesh_rid_get_count(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH); + + for (int i = 0; i < count; ++i) { + mesh_rid = chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, i); + + if (VS::get_singleton()->mesh_get_surface_count(mesh_rid) > 0) +#if !GODOT4 + VS::get_singleton()->mesh_remove_surface(mesh_rid, 0); +#else + VS::get_singleton()->mesh_clear(mesh_rid); +#endif + } + } + } + + for (; _current_job_step < _job_steps.size();) { + Ref step = _job_steps[_current_job_step]; + + ERR_FAIL_COND(!step.is_valid()); + + switch (step->get_job_type()) { + case TerraMesherJobStep::TYPE_NORMAL: + step_type_normal(); + break; + case TerraMesherJobStep::TYPE_NORMAL_LOD: + step_type_normal_lod(); + break; + case TerraMesherJobStep::TYPE_DROP_UV2: + step_type_drop_uv2(); + break; + case TerraMesherJobStep::TYPE_MERGE_VERTS: + step_type_merge_verts(); + break; + case TerraMesherJobStep::TYPE_BAKE_TEXTURE: + step_type_bake_texture(); + break; + case TerraMesherJobStep::TYPE_SIMPLIFY_MESH: + step_type_simplify_mesh(); + break; + case TerraMesherJobStep::TYPE_OTHER: + //do nothing + break; + } + + ++_current_job_step; + + if (should_return()) { + return; + } + } + + reset_stages(); + //next_phase(); + + set_complete(true); //So threadpool knows it's done + next_job(); +} + +void TerraPropJob::step_type_normal() { + //TODO add a lighting generation step + + Ref chunk = _chunk; + temp_mesh_arr = _prop_mesher->build_mesh(); RID mesh_rid = chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, _current_mesh); @@ -425,43 +412,13 @@ void TerraPropJob::step_type_normal() { if (lmat.is_valid()) { VisualServer::get_singleton()->mesh_surface_set_material(mesh_rid, 0, lmat->get_rid()); } + ++_current_mesh; } void TerraPropJob::step_type_normal_lod() { - Ref step = _job_steps[_current_job_step]; - - ERR_FAIL_COND(!step.is_valid()); - - Ref chunk = _chunk; - - _prop_mesher->set_lod_index(step->get_lod_index()); - _prop_mesher->reset(); - _prop_mesher->add_chunk(_chunk); - - //TODO make this automatic in build_mesh - if ((chunk->get_build_flags() & TerraChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) { - _prop_mesher->bake_colors(_chunk); - } - - temp_mesh_arr = _prop_mesher->build_mesh(); - - RID mesh_rid = chunk->mesh_rid_get_index(TerraChunkDefault::MESH_INDEX_PROP, TerraChunkDefault::MESH_TYPE_INDEX_MESH, _current_mesh); - - VS::get_singleton()->mesh_add_surface_from_arrays(mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - - Ref lmat; - - if (chunk->prop_material_cache_key_has()) { - lmat = chunk->get_library()->prop_material_cache_get(_chunk->prop_material_cache_key_get())->material_lod_get(_current_mesh); - } else { - lmat = chunk->get_library()->prop_material_lod_get(_current_mesh); - } - - if (lmat.is_valid()) { - VisualServer::get_singleton()->mesh_surface_set_material(mesh_rid, 0, lmat->get_rid()); - } + print_error("Error: step_type_normal_lod doesn't work for TerraPropJobs!"); ++_current_mesh; } @@ -588,7 +545,6 @@ void TerraPropJob::step_type_simplify_mesh() { #endif } - TerraPropJob::TerraPropJob() { set_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); diff --git a/world/jobs/terra_prop_job.h b/world/jobs/terra_prop_job.h index bbb4725..debaf03 100644 --- a/world/jobs/terra_prop_job.h +++ b/world/jobs/terra_prop_job.h @@ -49,6 +49,8 @@ public: void _execute_phase(); void _reset(); + void phase_steps(); + void step_type_normal(); void step_type_normal_lod(); void step_type_drop_uv2();