Add ability to `bake_navigation_mesh` off thread.
This feature makes it possible to workaround problems such as: - long baking time due to heavy synchronization when parsing geometry from mesh instances - crash when freeing `NavigationMeshInstance` while baking - errors when actively baking node tree is being detached from the scene tree
This commit is contained in:
parent
912e22821d
commit
505ace250d
|
@ -11,8 +11,9 @@
|
||||||
<methods>
|
<methods>
|
||||||
<method name="bake_navigation_mesh">
|
<method name="bake_navigation_mesh">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
|
<argument index="0" name="on_thread" type="bool" default="true" />
|
||||||
<description>
|
<description>
|
||||||
Bakes the [NavigationMesh]. The baking is done in a separate thread because navigation baking is not a cheap operation. This can be done at runtime. When it is completed, it automatically sets the new [NavigationMesh].
|
Bakes the [NavigationMesh]. If [code]on_thread[/code] is set to [code]true[/code] (default), the baking is done on a separate thread. Baking on separate thread is useful because navigation baking is not a cheap operation. When it is completed, it automatically sets the new [NavigationMesh]. Please note that baking on separate thread may be very slow if geometry is parsed from meshes as async access to each mesh involves heavy synchronization.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_region_rid" qualifiers="const">
|
<method name="get_region_rid" qualifiers="const">
|
||||||
|
|
|
@ -172,13 +172,17 @@ void _bake_navigation_mesh(void *p_user_data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationMeshInstance::bake_navigation_mesh() {
|
void NavigationMeshInstance::bake_navigation_mesh(bool p_on_thread) {
|
||||||
ERR_FAIL_COND_MSG(bake_thread.is_started(), "Navigation Mesh Bake thread is already baking a Navigation Mesh. Unable to start another bake request.");
|
ERR_FAIL_COND_MSG(bake_thread.is_started(), "Navigation Mesh Bake thread is already baking a Navigation Mesh. Unable to start another bake request.");
|
||||||
|
|
||||||
BakeThreadsArgs *args = memnew(BakeThreadsArgs);
|
BakeThreadsArgs *args = memnew(BakeThreadsArgs);
|
||||||
args->nav_region = this;
|
args->nav_region = this;
|
||||||
|
|
||||||
|
if (p_on_thread) {
|
||||||
bake_thread.start(_bake_navigation_mesh, args);
|
bake_thread.start(_bake_navigation_mesh, args);
|
||||||
|
} else {
|
||||||
|
_bake_navigation_mesh(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationMeshInstance::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
|
void NavigationMeshInstance::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
|
||||||
|
@ -216,7 +220,7 @@ void NavigationMeshInstance::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationMeshInstance::get_region_rid);
|
ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationMeshInstance::get_region_rid);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationMeshInstance::bake_navigation_mesh);
|
ClassDB::bind_method(D_METHOD("bake_navigation_mesh", "on_thread"), &NavigationMeshInstance::bake_navigation_mesh, DEFVAL(true));
|
||||||
ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationMeshInstance::_bake_finished);
|
ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationMeshInstance::_bake_finished);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
|
||||||
|
|
|
@ -62,9 +62,9 @@ public:
|
||||||
void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
|
void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
|
||||||
Ref<NavigationMesh> get_navigation_mesh() const;
|
Ref<NavigationMesh> get_navigation_mesh() const;
|
||||||
|
|
||||||
/// Bakes the navigation mesh in a dedicated thread; once done, automatically
|
/// Bakes the navigation mesh; once done, automatically
|
||||||
/// sets the new navigation mesh and emits a signal
|
/// sets the new navigation mesh and emits a signal
|
||||||
void bake_navigation_mesh();
|
void bake_navigation_mesh(bool p_on_thread);
|
||||||
void _bake_finished(Ref<NavigationMesh> p_nav_mesh);
|
void _bake_finished(Ref<NavigationMesh> p_nav_mesh);
|
||||||
|
|
||||||
String get_configuration_warning() const;
|
String get_configuration_warning() const;
|
||||||
|
|
Loading…
Reference in New Issue