Backport NavigationServer with RVO2 to 3.x

Change the entire navigation system.
Remove editor prefix from nav mesh generator class. It is now used for baking
at runtime as well.
Navigation supports obstacle avoidance now with the RVO2 library.
Nav system will also automatically link all nav meshes together to form one
overall complete nav map.
This commit is contained in:
Jake Young 2021-12-16 00:15:23 -05:00 committed by Rémi Verschelde
parent 571e05d3d3
commit 09bc9eb101
No known key found for this signature in database
GPG key ID: C3336907360768E1
109 changed files with 7910 additions and 2002 deletions

View file

@ -36,6 +36,7 @@
#include "scene/resources/mesh_library.h"
#include "scene/resources/surface_tool.h"
#include "scene/scene_string_names.h"
#include "servers/navigation_server.h"
#include "servers/visual_server.h"
bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
@ -406,12 +407,10 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
}
//erase navigation
if (navigation) {
for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
navigation->navmesh_remove(E->get().id);
}
g.navmesh_ids.clear();
for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
NavigationServer::get_singleton()->free(E->get().region);
}
g.navmesh_ids.clear();
//erase multimeshes
@ -490,9 +489,11 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item);
if (navigation) {
nm.id = navigation->navmesh_add(navmesh, xform, this);
} else {
nm.id = -1;
RID region = NavigationServer::get_singleton()->region_create();
NavigationServer::get_singleton()->region_set_navmesh(region, navmesh);
NavigationServer::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform);
NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid());
nm.region = region;
}
g.navmesh_ids[E->get()] = nm;
}
@ -579,10 +580,14 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) {
if (navigation && mesh_library.is_valid()) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
if (cell_map.has(F->key()) && F->get().id < 0) {
if (cell_map.has(F->key()) && F->get().region.is_valid() == false) {
Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item);
if (nm.is_valid()) {
F->get().id = navigation->navmesh_add(nm, F->get().xform, this);
RID region = NavigationServer::get_singleton()->region_create();
NavigationServer::get_singleton()->region_set_navmesh(region, nm);
NavigationServer::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform);
NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid());
F->get().region = region;
}
}
}
@ -605,9 +610,9 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
if (navigation) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
if (F->get().id >= 0) {
navigation->navmesh_remove(F->get().id);
F->get().id = -1;
if (F->get().region.is_valid()) {
NavigationServer::get_singleton()->free(F->get().region);
F->get().region = RID();
}
}
}
@ -632,13 +637,11 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
g.static_body = RID();
}
//erase navigation
if (navigation) {
for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
navigation->navmesh_remove(E->get().id);
}
g.navmesh_ids.clear();
// Erase navigation
for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
NavigationServer::get_singleton()->free(E->get().region);
}
g.navmesh_ids.clear();
//erase multimeshes

View file

@ -86,7 +86,7 @@ class GridMap : public Spatial {
*/
struct Octant {
struct NavMesh {
int id;
RID region;
Transform xform;
};