mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-22 17:17:17 +01:00
More cleanups.
This commit is contained in:
parent
57153f4a33
commit
d35db3a25a
@ -69,6 +69,35 @@
|
||||
|
||||
// todo port p_navigation_polygon->get_source_geometry_mode()
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask2D::_execute() {
|
||||
Ref<NavigationPolygon> navigation_polygon = navigation_polygon;
|
||||
Ref<NavigationMeshSourceGeometryData3D> source_geometry_data = source_geometry_data;
|
||||
|
||||
if (navigation_polygon.is_null() || source_geometry_data.is_null() || !source_geometry_data->has_data()) {
|
||||
status = NavigationGeneratorTask2D::TaskStatus::BAKING_FAILED;
|
||||
set_complete(true);
|
||||
return;
|
||||
}
|
||||
_static_bake_2d_from_source_geometry_data(navigation_polygon, source_geometry_data);
|
||||
status = NavigationGeneratorTask2D::TaskStatus::BAKING_FINISHED;
|
||||
|
||||
set_complete(true);
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_execute"), &NavigationGeneratorTask2D::_execute);
|
||||
}
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask3D::_execute() {
|
||||
set_complete(true);
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_execute"), &NavigationGeneratorTask3D::_execute);
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::process() {
|
||||
generator_mutex.lock();
|
||||
|
||||
@ -81,100 +110,77 @@ void PandemoniumNavigationMeshGenerator::process() {
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::cleanup() {
|
||||
baking_navpolys.clear();
|
||||
geometry_2d_parsers.clear();
|
||||
_baking_navpolys.clear();
|
||||
_geometry_2d_parsers.clear();
|
||||
#ifndef _3D_DISABLED
|
||||
baking_navmeshes.clear();
|
||||
geometry_3d_parsers.clear();
|
||||
_baking_navmeshes.clear();
|
||||
_geometry_3d_parsers.clear();
|
||||
#endif // _3D_DISABLED
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_tasks() {
|
||||
if (navigation_generator_2d_task_to_threadpool_task_id.size() == 0) {
|
||||
if (_2d_parse_jobs.size() == 0 && _2d_running_jobs.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_process_2d_parse_tasks();
|
||||
_process_2d_bake_tasks();
|
||||
_process_2d_callbacks();
|
||||
_process_2d_cleanup_tasks();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_parse_tasks() {
|
||||
// add parse tasks to a different vector from the get go instead of collecting them ?
|
||||
|
||||
// _parse_tasks
|
||||
// _submitted_jobs -> jobs submitted to threadpoool
|
||||
// _process mutex, goes over _submitted_jobs if finished calls callback with results as param, and removes is
|
||||
|
||||
LocalVector<NavigationGeneratorTask2D *> _open_parse_tasks;
|
||||
|
||||
for (const KeyValue<NavigationGeneratorTask2D *, WorkerThreadPool::TaskID> &E : navigation_generator_2d_task_to_threadpool_task_id) {
|
||||
NavigationGeneratorTask2D *navigation_generator_task = E.key;
|
||||
if (navigation_generator_task->status == NavigationGeneratorTask2D::TaskStatus::PARSING_REQUIRED) {
|
||||
_open_parse_tasks.push_back(navigation_generator_task);
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that this cannot be parallelized in a simple way, because we need mainloop to not delete nodes under it while processing.
|
||||
// If parallelization is implemented, it needs to wait for the tasks to complete. (Like in the original pr.)
|
||||
// Also the RenderingServer has locks that need the main thread to be active, so it can deadlock.
|
||||
|
||||
// TODO implement ThreadPool like max processing per frame support
|
||||
|
||||
if (_open_parse_tasks.size() > 0) {
|
||||
for (uint32_t i(0); i < _open_parse_tasks.size(); i++) {
|
||||
// Add logic from _parse_2d_scenetree_task to here
|
||||
if (_2d_parse_jobs.size() > 0) {
|
||||
while (_2d_parse_jobs.size() > 0) {
|
||||
Ref<NavigationGeneratorTask2D> navigation_generator_task = _2d_parse_jobs[0];
|
||||
|
||||
_parse_2d_scenetree_task(i, _open_parse_tasks.ptr());
|
||||
}
|
||||
_2d_parse_jobs.remove(0);
|
||||
|
||||
_open_parse_tasks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_bake_tasks() {
|
||||
// Just merge this into the task and use ThreadPool
|
||||
|
||||
for (KeyValue<NavigationGeneratorTask2D *, WorkerThreadPool::TaskID> &E : navigation_generator_2d_task_to_threadpool_task_id) {
|
||||
NavigationGeneratorTask2D *navigation_generator_task = E.key;
|
||||
|
||||
if (navigation_generator_task->status == NavigationGeneratorTask2D::TaskStatus::PARSING_FINISHED) {
|
||||
if (use_threads && baking_use_multiple_threads) {
|
||||
WorkerThreadPool::TaskID threadpool_task_id = WorkerThreadPool::get_singleton()->add_native_task(
|
||||
PandemoniumNavigationMeshGenerator::_navigation_mesh_generator_2d_thread_bake,
|
||||
navigation_generator_task,
|
||||
baking_use_high_priority_threads,
|
||||
"NavigationMeshGeneratorBake2D");
|
||||
|
||||
navigation_generator_2d_task_to_threadpool_task_id[navigation_generator_task] = threadpool_task_id;
|
||||
if (navigation_generator_task.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::BAKING_STARTED;
|
||||
Ref<NavigationPolygon> navigation_polygon = navigation_generator_task->navigation_polygon;
|
||||
Ref<NavigationMeshSourceGeometryData3D> source_geometry_data = navigation_generator_task->source_geometry_data;
|
||||
ObjectID parse_root_object_id = navigation_generator_task->parse_root_object_id;
|
||||
|
||||
} else if (navigation_generator_task->status == NavigationGeneratorTask2D::TaskStatus::BAKING_STARTED) {
|
||||
if (use_threads && baking_use_multiple_threads) {
|
||||
WorkerThreadPool::TaskID threadpool_task_id = E.value;
|
||||
|
||||
if (WorkerThreadPool::get_singleton()->is_task_completed(threadpool_task_id)) {
|
||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(threadpool_task_id);
|
||||
|
||||
navigation_generator_2d_task_to_threadpool_task_id[navigation_generator_task] = WorkerThreadPool::TaskID();
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::BAKING_FINISHED;
|
||||
}
|
||||
} else {
|
||||
_navigation_mesh_generator_2d_thread_bake(navigation_generator_task);
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::BAKING_FINISHED;
|
||||
if (navigation_polygon.is_null() || parse_root_object_id == ObjectID()) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
continue;
|
||||
}
|
||||
Object *parse_root_obj = ObjectDB::get_instance(parse_root_object_id);
|
||||
if (parse_root_obj == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
Node *parse_root_node = Object::cast_to<Node>(parse_root_obj);
|
||||
if (parse_root_node == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
_static_parse_2d_source_geometry_data(navigation_polygon, parse_root_node, source_geometry_data, navigation_generator_task->geometry_parsers);
|
||||
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FINISHED;
|
||||
|
||||
// Submit resulting class To threadpool
|
||||
navigation_generator_task->set_complete(false);
|
||||
ThreadPool::get_singleton()->add_job(navigation_generator_task);
|
||||
_2d_running_jobs.push_back(navigation_generator_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_callbacks() {
|
||||
// Do this at the end when a job is finished on the main thread
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_cleanup_tasks() {
|
||||
LocalVector<NavigationGeneratorTask2D *> tasks_to_remove;
|
||||
|
||||
for (const KeyValue<NavigationGeneratorTask2D *, WorkerThreadPool::TaskID> &E : navigation_generator_2d_task_to_threadpool_task_id) {
|
||||
// only chech if completed is true
|
||||
|
||||
if (E.key->status == NavigationGeneratorTask2D::TaskStatus::BAKING_FINISHED) {
|
||||
if (E.key->callback.is_valid()) {
|
||||
Callable::CallError ce;
|
||||
@ -189,13 +195,7 @@ void PandemoniumNavigationMeshGenerator::_process_2d_callbacks() {
|
||||
E.key->status = NavigationGeneratorTask2D::TaskStatus::CALLBACK_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_cleanup_tasks() {
|
||||
LocalVector<NavigationGeneratorTask2D *> tasks_to_remove;
|
||||
|
||||
for (const KeyValue<NavigationGeneratorTask2D *, WorkerThreadPool::TaskID> &E : navigation_generator_2d_task_to_threadpool_task_id) {
|
||||
// every finished bake should have its callback by now, so remove everything that has bake/callback finished or that failed
|
||||
if (E.key->status == NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED ||
|
||||
E.key->status == NavigationGeneratorTask2D::TaskStatus::BAKING_FAILED ||
|
||||
@ -215,73 +215,17 @@ void PandemoniumNavigationMeshGenerator::_process_2d_cleanup_tasks() {
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_parse_2d_scenetree_task(uint32_t index, NavigationGeneratorTask2D **parse_task) {
|
||||
// nott needed, control method
|
||||
|
||||
NavigationGeneratorTask2D *navigation_generator_task = (*(parse_task + index));
|
||||
if (navigation_generator_task == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<NavigationPolygon> navigation_polygon = navigation_generator_task->navigation_polygon;
|
||||
Ref<NavigationMeshSourceGeometryData3D> source_geometry_data = navigation_generator_task->source_geometry_data;
|
||||
ObjectID parse_root_object_id = navigation_generator_task->parse_root_object_id;
|
||||
|
||||
if (navigation_polygon.is_null() || parse_root_object_id == ObjectID()) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
Object *parse_root_obj = ObjectDB::get_instance(parse_root_object_id);
|
||||
if (parse_root_obj == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
Node *parse_root_node = Object::cast_to<Node>(parse_root_obj);
|
||||
if (parse_root_node == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
_static_parse_2d_source_geometry_data(navigation_polygon, parse_root_node, source_geometry_data, navigation_generator_task->geometry_parsers);
|
||||
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FINISHED;
|
||||
|
||||
// Submit resulting class To threadpool
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_navigation_mesh_generator_2d_thread_bake(void *p_arg) {
|
||||
// Not needed control method
|
||||
|
||||
NavigationGeneratorTask2D *navigation_generator_task = static_cast<NavigationGeneratorTask2D *>(p_arg);
|
||||
|
||||
if (navigation_generator_task == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<NavigationPolygon> navigation_polygon = navigation_generator_task->navigation_polygon;
|
||||
Ref<NavigationMeshSourceGeometryData3D> source_geometry_data = navigation_generator_task->source_geometry_data;
|
||||
|
||||
if (navigation_polygon.is_null() || source_geometry_data.is_null() || !source_geometry_data->has_data()) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::BAKING_FAILED;
|
||||
return;
|
||||
}
|
||||
_static_bake_2d_from_source_geometry_data(navigation_polygon, source_geometry_data);
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::BAKING_FINISHED;
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) {
|
||||
generator_mutex.lock();
|
||||
if (geometry_2d_parsers.find(p_geometry_parser) < 0) {
|
||||
geometry_2d_parsers.push_back(p_geometry_parser);
|
||||
if (_geometry_2d_parsers.find(p_geometry_parser) < 0) {
|
||||
_geometry_2d_parsers.push_back(p_geometry_parser);
|
||||
}
|
||||
generator_mutex.unlock();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) {
|
||||
generator_mutex.lock();
|
||||
geometry_2d_parsers.erase(p_geometry_parser);
|
||||
_geometry_2d_parsers.erase(p_geometry_parser);
|
||||
generator_mutex.unlock();
|
||||
}
|
||||
|
||||
@ -294,7 +238,7 @@ Ref<NavigationMeshSourceGeometryData2D> PandemoniumNavigationMeshGenerator::pars
|
||||
|
||||
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data = Ref<NavigationMeshSourceGeometryData2D>(memnew(NavigationMeshSourceGeometryData2D));
|
||||
|
||||
_static_parse_2d_source_geometry_data(p_navigation_polygon, p_root_node, source_geometry_data, geometry_2d_parsers);
|
||||
_static_parse_2d_source_geometry_data(p_navigation_polygon, p_root_node, source_geometry_data, _geometry_2d_parsers);
|
||||
|
||||
return source_geometry_data;
|
||||
};
|
||||
@ -303,18 +247,18 @@ void PandemoniumNavigationMeshGenerator::bake_2d_from_source_geometry_data(Ref<N
|
||||
ERR_FAIL_COND_MSG(!p_navigation_polygon.is_valid(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid NavigationMeshSourceGeometryData2D.");
|
||||
ERR_FAIL_COND_MSG(p_navigation_polygon->get_outline_count() == 0 && !p_source_geometry_data->has_data(), "NavigationMeshSourceGeometryData2D is empty. Parse source geometry first.");
|
||||
ERR_FAIL_COND_MSG(baking_navpolys.find(p_navigation_polygon) >= 0, "NavigationPolygon is already baking. Wait for current bake task to finish.");
|
||||
ERR_FAIL_COND_MSG(_baking_navpolys.find(p_navigation_polygon) >= 0, "NavigationPolygon is already baking. Wait for current bake task to finish.");
|
||||
|
||||
generator_mutex.lock();
|
||||
baking_navpolys.push_back(p_navigation_polygon);
|
||||
_baking_navpolys.push_back(p_navigation_polygon);
|
||||
generator_mutex.unlock();
|
||||
|
||||
_static_bake_2d_from_source_geometry_data(p_navigation_polygon, p_source_geometry_data);
|
||||
|
||||
generator_mutex.lock();
|
||||
int64_t navigation_polygon_index = baking_navpolys.find(p_navigation_polygon);
|
||||
int64_t navigation_polygon_index = _baking_navpolys.find(p_navigation_polygon);
|
||||
if (navigation_polygon_index >= 0) {
|
||||
baking_navpolys.remove_unordered(navigation_polygon_index);
|
||||
_baking_navpolys.remove_unordered(navigation_polygon_index);
|
||||
}
|
||||
generator_mutex.unlock();
|
||||
}
|
||||
@ -572,11 +516,11 @@ void PandemoniumNavigationMeshGenerator::_static_bake_2d_from_source_geometry_da
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback) {
|
||||
ERR_FAIL_COND_MSG(baking_navpolys.find(p_navigation_polygon) >= 0, "NavigationPolygon was already added to baking queue. Wait for current bake task to finish.");
|
||||
ERR_FAIL_COND_MSG(_baking_navpolys.find(p_navigation_polygon) >= 0, "NavigationPolygon was already added to baking queue. Wait for current bake task to finish.");
|
||||
ERR_FAIL_COND_MSG(p_root_node == nullptr, "NavigationPolygon requires a valid root node.");
|
||||
|
||||
generator_mutex.lock();
|
||||
baking_navpolys.push_back(p_navigation_polygon);
|
||||
_baking_navpolys.push_back(p_navigation_polygon);
|
||||
generator_mutex.unlock();
|
||||
|
||||
NavigationGeneratorTask2D *navigation_generator_task = memnew(NavigationGeneratorTask2D);
|
||||
@ -585,7 +529,7 @@ void PandemoniumNavigationMeshGenerator::parse_and_bake_2d(Ref<NavigationPolygon
|
||||
navigation_generator_task->source_geometry_data = Ref<NavigationMeshSourceGeometryData2D>(memnew(NavigationMeshSourceGeometryData2D));
|
||||
navigation_generator_task->callback = p_callback;
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_REQUIRED;
|
||||
navigation_generator_task->geometry_parsers = geometry_2d_parsers;
|
||||
navigation_generator_task->geometry_parsers = _geometry_2d_parsers;
|
||||
|
||||
generator_mutex.lock();
|
||||
navigation_generator_2d_task_to_threadpool_task_id[navigation_generator_task] = WorkerThreadPool::TaskID();
|
||||
@ -594,12 +538,12 @@ void PandemoniumNavigationMeshGenerator::parse_and_bake_2d(Ref<NavigationPolygon
|
||||
|
||||
bool PandemoniumNavigationMeshGenerator::is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const {
|
||||
ERR_FAIL_COND_V(!p_navigation_polygon.is_valid(), false);
|
||||
return baking_navpolys.find(p_navigation_polygon) >= 0;
|
||||
return _baking_navpolys.find(p_navigation_polygon) >= 0;
|
||||
}
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
void PandemoniumNavigationMeshGenerator::_process_3d_tasks() {
|
||||
if (navigation_generator_3d_task_to_threadpool_task_id.size() == 0) {
|
||||
if (_3d_parse_jobs.size() == 0 && _3d_running_jobs.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -610,28 +554,28 @@ void PandemoniumNavigationMeshGenerator::_process_3d_tasks() {
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_3d_parse_tasks() {
|
||||
LocalVector<NavigationGeneratorTask3D *> _open_parse_tasks;
|
||||
LocalVector<NavigationGeneratorTask3D *> _2d_parse_jobs;
|
||||
|
||||
for (const KeyValue<NavigationGeneratorTask3D *, WorkerThreadPool::TaskID> &E : navigation_generator_3d_task_to_threadpool_task_id) {
|
||||
NavigationGeneratorTask3D *navigation_generator_task = E.key;
|
||||
if (navigation_generator_task->status == NavigationGeneratorTask3D::TaskStatus::PARSING_REQUIRED) {
|
||||
_open_parse_tasks.push_back(navigation_generator_task);
|
||||
_2d_parse_jobs.push_back(navigation_generator_task);
|
||||
navigation_generator_task->status = NavigationGeneratorTask3D::TaskStatus::PARSING_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (_open_parse_tasks.size() > 0) {
|
||||
if (_2d_parse_jobs.size() > 0) {
|
||||
// Use threads to parse the SceneTree only when RenderingServer is set to multi-threaded.
|
||||
// When RenderingServer is set to single-threaded process gets stuck on receiving Mesh data arrays.
|
||||
if (use_threads && parsing_use_multiple_threads && OS::get_singleton()->get_render_thread_mode() == OS::RenderThreadMode::RENDER_SEPARATE_THREAD) {
|
||||
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &PandemoniumNavigationMeshGenerator::_parse_3d_scenetree_task, _open_parse_tasks.ptr(), _open_parse_tasks.size(), -1, parsing_use_high_priority_threads, SNAME("NavigationMeshGeneratorParsing3D"));
|
||||
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &PandemoniumNavigationMeshGenerator::_parse_3d_scenetree_task, _2d_parse_jobs.ptr(), _2d_parse_jobs.size(), -1, parsing_use_high_priority_threads, SNAME("NavigationMeshGeneratorParsing3D"));
|
||||
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
|
||||
} else {
|
||||
for (uint32_t i(0); i < _open_parse_tasks.size(); i++) {
|
||||
_parse_3d_scenetree_task(i, _open_parse_tasks.ptr());
|
||||
for (uint32_t i(0); i < _2d_parse_jobs.size(); i++) {
|
||||
_parse_3d_scenetree_task(i, _2d_parse_jobs.ptr());
|
||||
}
|
||||
}
|
||||
_open_parse_tasks.clear();
|
||||
_2d_parse_jobs.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1031,7 +975,7 @@ void PandemoniumNavigationMeshGenerator::bake_3d_from_source_geometry_data(Ref<N
|
||||
ERR_FAIL_COND_MSG(!p_navigation_mesh.is_valid(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid NavigationMeshSourceGeometryData3D.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data->has_data(), "NavigationMeshSourceGeometryData3D is empty. Parse source geometry first.");
|
||||
ERR_FAIL_COND_MSG(baking_navmeshes.find(p_navigation_mesh) >= 0, "NavigationMesh is already baking. Wait for current bake task to finish.");
|
||||
ERR_FAIL_COND_MSG(_baking_navmeshes.find(p_navigation_mesh) >= 0, "NavigationMesh is already baking. Wait for current bake task to finish.");
|
||||
|
||||
generator_mutex.lock();
|
||||
baking_navmeshes.push_back(p_navigation_mesh);
|
||||
|
@ -47,6 +47,8 @@ class NavigationGeometryParser3D;
|
||||
class PandemoniumNavigationMeshGenerator : public NavigationMeshGenerator {
|
||||
public:
|
||||
class NavigationGeneratorTask2D : public ThreadPoolJob {
|
||||
GDCLASS(NavigationGeneratorTask2D, ThreadPoolJob);
|
||||
|
||||
public:
|
||||
enum TaskStatus {
|
||||
PARSING_REQUIRED,
|
||||
@ -66,17 +68,14 @@ public:
|
||||
Ref<FuncRef> callback;
|
||||
NavigationGeneratorTask2D::TaskStatus status = NavigationGeneratorTask2D::TaskStatus::PARSING_REQUIRED;
|
||||
LocalVector<Ref<NavigationGeometryParser2D>> geometry_parsers;
|
||||
|
||||
void _execute();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
static void _navigation_mesh_generator_2d_thread_bake(void *p_arg);
|
||||
|
||||
private:
|
||||
LocalVector<Ref<NavigationPolygon>> baking_navpolys;
|
||||
LocalVector<Ref<NavigationGeometryParser2D>> geometry_2d_parsers;
|
||||
HashMap<NavigationGeneratorTask2D *, WorkerThreadPool::TaskID> navigation_generator_2d_task_to_threadpool_task_id;
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
public:
|
||||
class NavigationGeneratorTask3D : public ThreadPoolJob {
|
||||
public:
|
||||
enum TaskStatus {
|
||||
@ -97,16 +96,17 @@ public:
|
||||
Ref<FuncRef> callback;
|
||||
NavigationGeneratorTask3D::TaskStatus status = NavigationGeneratorTask3D::TaskStatus::PARSING_REQUIRED;
|
||||
LocalVector<Ref<NavigationGeometryParser3D>> geometry_parsers;
|
||||
|
||||
void _execute();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
static void _navigation_mesh_generator_3d_thread_bake(void *p_arg);
|
||||
|
||||
private:
|
||||
LocalVector<Ref<NavigationMesh>> baking_navmeshes;
|
||||
LocalVector<Ref<NavigationGeometryParser3D>> geometry_3d_parsers;
|
||||
HashMap<NavigationGeneratorTask3D *, WorkerThreadPool::TaskID> navigation_generator_3d_task_to_threadpool_task_id;
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
//Remove
|
||||
static void _navigation_mesh_generator_3d_thread_bake(void *p_arg);
|
||||
|
||||
public:
|
||||
virtual void process();
|
||||
virtual void cleanup();
|
||||
@ -145,10 +145,7 @@ public:
|
||||
private:
|
||||
void _process_2d_tasks();
|
||||
void _process_2d_parse_tasks();
|
||||
void _process_2d_bake_tasks();
|
||||
void _process_2d_callbacks();
|
||||
void _process_2d_cleanup_tasks();
|
||||
void _parse_2d_scenetree_task(uint32_t index, NavigationGeneratorTask2D **parse_task);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
void _process_3d_tasks();
|
||||
@ -171,6 +168,18 @@ private:
|
||||
bool parsing_use_high_priority_threads = true;
|
||||
bool baking_use_multiple_threads = true;
|
||||
bool baking_use_high_priority_threads = true;
|
||||
|
||||
LocalVector<Ref<NavigationPolygon>> _baking_navpolys;
|
||||
LocalVector<Ref<NavigationGeometryParser2D>> _geometry_2d_parsers;
|
||||
LocalVector<Ref<NavigationGeneratorTask2D>> _2d_parse_jobs;
|
||||
LocalVector<Ref<NavigationGeneratorTask2D>> _2d_running_jobs;
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
LocalVector<Ref<NavigationMesh>> _baking_navmeshes;
|
||||
LocalVector<Ref<NavigationGeometryParser3D>> _geometry_3d_parsers;
|
||||
LocalVector<Ref<NavigationGeneratorTask3D>> _3d_parse_jobs;
|
||||
LocalVector<Ref<NavigationGeneratorTask3D>> _3d_running_jobs;
|
||||
#endif // _3D_DISABLED
|
||||
};
|
||||
|
||||
#endif // GODOT_NAVIGATION_MESH_GENERATOR_H
|
||||
|
Loading…
Reference in New Issue
Block a user