Fixed quite a few issues with the prop instance merger's logic.

This commit is contained in:
Relintai 2021-08-10 12:23:53 +02:00
parent 6a4c4ad1aa
commit 924b32e70a
5 changed files with 81 additions and 40 deletions

View File

@ -81,16 +81,11 @@ void PropInstanceJob::_reset() {
} }
void PropInstanceJob::_execute() { void PropInstanceJob::_execute() {
ActiveBuildPhaseType origpt = _build_phase_type; ActiveBuildPhaseType origpt = _build_phase_type;
while (!get_cancelled() && _in_tree && !_build_done && origpt == _build_phase_type && !should_return()) { while (!get_cancelled() && _in_tree && !_build_done && origpt == _build_phase_type && !should_return()) {
execute_phase(); execute_phase();
} }
if (!_in_tree) {
_prop.unref();
}
} }
void PropInstanceJob::execute_phase() { void PropInstanceJob::execute_phase() {
@ -110,8 +105,11 @@ void PropInstanceJob::physics_process(const float delta) {
call("_physics_process", delta); call("_physics_process", delta);
} }
void PropInstanceJob::prop_instance_exit_tree() { void PropInstanceJob::prop_instance_enter_tree() {
_in_tree = true;
}
void PropInstanceJob::prop_instance_exit_tree() {
_in_tree = false; _in_tree = false;
if (get_complete()) { if (get_complete()) {

View File

@ -88,6 +88,7 @@ public:
void process(const float delta); void process(const float delta);
void physics_process(const float delta); void physics_process(const float delta);
void prop_instance_enter_tree();
void prop_instance_exit_tree(); void prop_instance_exit_tree();
PropInstanceJob(); PropInstanceJob();

View File

@ -59,6 +59,16 @@ typedef class RenderingServer VS;
#include "../thread_pool/thread_pool.h" #include "../thread_pool/thread_pool.h"
#endif #endif
bool PropInstanceMerger::get_building() {
return _building;
}
void PropInstanceMerger::set_building(const bool value) {
_building = value;
set_physics_process_internal(_building);
set_process_internal(_building);
}
Ref<PropInstanceJob> PropInstanceMerger::get_job() { Ref<PropInstanceJob> PropInstanceMerger::get_job() {
return _job; return _job;
} }
@ -383,7 +393,7 @@ void PropInstanceMerger::_init_materials() {
} }
void PropInstanceMerger::_build() { void PropInstanceMerger::_build() {
_building = true; set_building(true);
_build_queued = false; _build_queued = false;
if (_job.is_valid()) { if (_job.is_valid()) {
@ -400,36 +410,18 @@ void PropInstanceMerger::_build() {
} }
if (!_prop_data.is_valid()) { if (!_prop_data.is_valid()) {
_building = false; set_building(false);
return; return;
} }
if (!_job.is_valid()) {
//todo this should probably be in a virtual method, lik in Terraman or Voxelman
_job = Ref<PropInstancePropJob>(memnew(PropInstancePropJob()));
_job->set_prop_instace(this);
Ref<PropMesherJobStep> js;
js.instance();
js->set_job_type(PropMesherJobStep::TYPE_NORMAL);
_job->add_jobs_step(js);
js.instance();
js->set_job_type(PropMesherJobStep::TYPE_MERGE_VERTS);
_job->add_jobs_step(js);
js.instance();
js->set_job_type(PropMesherJobStep::TYPE_BAKE_TEXTURE);
_job->add_jobs_step(js);
}
if (!is_inside_tree()) { if (!is_inside_tree()) {
_building = false; set_building(false);
_build_queued = true; _build_queued = true;
return; return;
} }
_job->reset();
Ref<PropMaterialCache> cache = PropCache::get_singleton()->material_cache_get(_prop_data); Ref<PropMaterialCache> cache = PropCache::get_singleton()->material_cache_get(_prop_data);
if (!cache->get_initialized()) { if (!cache->get_initialized()) {
@ -460,6 +452,7 @@ void PropInstanceMerger::_build() {
} }
void PropInstanceMerger::_build_finished() { void PropInstanceMerger::_build_finished() {
set_building(false);
} }
void PropInstanceMerger::_prop_preprocess(Transform transform, const Ref<PropData> &prop) { void PropInstanceMerger::_prop_preprocess(Transform transform, const Ref<PropData> &prop) {
@ -546,10 +539,28 @@ void PropInstanceMerger::_prop_preprocess(Transform transform, const Ref<PropDat
PropInstanceMerger::PropInstanceMerger() { PropInstanceMerger::PropInstanceMerger() {
_build_queued = false; _build_queued = false;
_building = false; set_building(false);
_first_lod_distance_squared = 20; _first_lod_distance_squared = 20;
_lod_reduction_distance_squared = 10; _lod_reduction_distance_squared = 10;
//todo this should probably be in a virtual method, lik in Terraman or Voxelman
_job = Ref<PropInstancePropJob>(memnew(PropInstancePropJob()));
_job->set_prop_instace(this);
Ref<PropMesherJobStep> js;
js.instance();
js->set_job_type(PropMesherJobStep::TYPE_NORMAL);
_job->add_jobs_step(js);
js.instance();
js->set_job_type(PropMesherJobStep::TYPE_MERGE_VERTS);
_job->add_jobs_step(js);
js.instance();
js->set_job_type(PropMesherJobStep::TYPE_BAKE_TEXTURE);
_job->add_jobs_step(js);
} }
PropInstanceMerger::~PropInstanceMerger() { PropInstanceMerger::~PropInstanceMerger() {
@ -564,16 +575,15 @@ void PropInstanceMerger::_notification(int p_what) {
switch (p_what) { switch (p_what) {
case NOTIFICATION_ENTER_TREE: { case NOTIFICATION_ENTER_TREE: {
if (_prop_data.is_valid()) { if (_prop_data.is_valid()) {
_job->prop_instance_enter_tree();
build(); build();
} }
set_physics_process_internal(true);
set_process_internal(true);
break; break;
} }
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
if (_job.is_valid()) { if (_job.is_valid()) {
_job->prop_instance_exit_tree();
_job->set_cancelled(true); _job->set_cancelled(true);
} }
@ -585,8 +595,20 @@ void PropInstanceMerger::_notification(int p_what) {
//todo turn this on and off properly //todo turn this on and off properly
if (_building) { if (_building) {
if (!_job.is_valid()) {
return;
}
if (_job->get_build_phase_type() == PropInstanceJob::BUILD_PHASE_TYPE_PHYSICS_PROCESS) { if (_job->get_build_phase_type() == PropInstanceJob::BUILD_PHASE_TYPE_PHYSICS_PROCESS) {
_job->physics_process(get_physics_process_delta_time()); _job->physics_process(get_physics_process_delta_time());
if (_job->get_build_phase_type() == PropInstanceJob::BUILD_PHASE_TYPE_NORMAL) {
#if THREAD_POOL_PRESENT
ThreadPool::get_singleton()->add_job(_job);
#else
job->execute();
#endif
}
} }
} }
@ -596,8 +618,20 @@ void PropInstanceMerger::_notification(int p_what) {
//todo turn this on and off properly //todo turn this on and off properly
if (_building) { if (_building) {
if (!_job.is_valid()) {
return;
}
if (_job->get_build_phase_type() == PropInstanceJob::BUILD_PHASE_TYPE_PROCESS) { if (_job->get_build_phase_type() == PropInstanceJob::BUILD_PHASE_TYPE_PROCESS) {
_job->process(get_process_delta_time()); _job->process(get_process_delta_time());
if (_job->get_build_phase_type() == PropInstanceJob::BUILD_PHASE_TYPE_NORMAL) {
#if THREAD_POOL_PRESENT
ThreadPool::get_singleton()->add_job(_job);
#else
job->execute();
#endif
}
} }
} }

View File

@ -47,6 +47,9 @@ class PropInstanceMerger : public PropInstance {
GDCLASS(PropInstanceMerger, PropInstance); GDCLASS(PropInstanceMerger, PropInstance);
public: public:
bool get_building();
void set_building(const bool value);
Ref<PropInstanceJob> get_job(); Ref<PropInstanceJob> get_job();
void set_job(const Ref<PropInstanceJob> &job); void set_job(const Ref<PropInstanceJob> &job);

View File

@ -313,7 +313,6 @@ void PropInstancePropJob::_execute_phase() {
#ifdef MESH_DATA_RESOURCE_PRESENT #ifdef MESH_DATA_RESOURCE_PRESENT
if (_prop_mesh_datas.size() == 0) { if (_prop_mesh_datas.size() == 0) {
//reset_meshes(); //reset_meshes();
set_complete(true); set_complete(true);
finished(); finished();
return; return;
@ -329,9 +328,6 @@ void PropInstancePropJob::_execute_phase() {
finished(); finished();
ERR_FAIL_MSG("PropInstancePropJob: _phase is too high!"); ERR_FAIL_MSG("PropInstancePropJob: _phase is too high!");
} }
//set_complete(true); //So threadpool knows it's done
//finished();
} }
void PropInstancePropJob::_reset() { void PropInstancePropJob::_reset() {
@ -340,6 +336,8 @@ void PropInstancePropJob::_reset() {
_build_done = false; _build_done = false;
_phase = 0; _phase = 0;
reset_stages();
if (get_prop_mesher().is_valid()) { if (get_prop_mesher().is_valid()) {
get_prop_mesher()->reset(); get_prop_mesher()->reset();
} }
@ -358,6 +356,7 @@ void PropInstancePropJob::phase_steps() {
reset_stages(); reset_stages();
//next_phase(); //next_phase();
set_complete(true); //So threadpool knows it's done set_complete(true); //So threadpool knows it's done
finished();
return; return;
} }
@ -458,7 +457,9 @@ void PropInstancePropJob::phase_steps() {
} }
reset_stages(); reset_stages();
next_phase(); //next_phase();
set_complete(true); //So threadpool knows it's done
finished();
} }
void PropInstancePropJob::step_type_normal() { void PropInstancePropJob::step_type_normal() {
@ -519,8 +520,8 @@ void PropInstancePropJob::step_type_merge_verts() {
} }
void PropInstancePropJob::step_type_bake_texture() { void PropInstancePropJob::step_type_bake_texture() {
Ref<ShaderMaterial> mat; // = chunk->get_library()->material_lod_get(0); Ref<ShaderMaterial> mat = _material_cache->material_lod_get(0);
Ref<SpatialMaterial> spmat; // = chunk->get_library()->material_lod_get(0); Ref<SpatialMaterial> spmat = _material_cache->material_lod_get(0);
Ref<Texture> tex; Ref<Texture> tex;
if (mat.is_valid()) { if (mat.is_valid()) {
@ -708,6 +709,10 @@ PropInstancePropJob::PropInstancePropJob() {
set_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); set_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS);
_prop_instace = NULL; _prop_instace = NULL;
//todo allocate this in a virtual method
_prop_mesher.instance();
_prop_mesher->set_build_flags(PropMesher::BUILD_FLAG_USE_LIGHTING | PropMesher::BUILD_FLAG_USE_AO | PropMesher::BUILD_FLAG_USE_RAO | PropMesher::BUILD_FLAG_GENERATE_AO | PropMesher::BUILD_FLAG_AUTO_GENERATE_RAO | PropMesher::BUILD_FLAG_BAKE_LIGHTS);
} }
PropInstancePropJob::~PropInstancePropJob() { PropInstancePropJob::~PropInstancePropJob() {