From 3b64ecbc4b2dcc1fe254406aa5b3272b2d7d4876 Mon Sep 17 00:00:00 2001 From: Andrea Catania Date: Thu, 20 Feb 2020 17:56:30 +0100 Subject: Renamed NavigationMeshInstance to NavigationRegion --- doc/classes/Navigation.xml | 2 +- doc/classes/NavigationMeshInstance.xml | 42 ---- doc/classes/NavigationRegion.xml | 42 ++++ editor/icons/NavigationMeshInstance.svg | 1 - editor/icons/NavigationRegion.svg | 58 +++++ editor/import/resource_importer_scene.cpp | 2 +- editor/plugins/mesh_instance_editor_plugin.cpp | 4 +- editor/plugins/mesh_library_editor_plugin.cpp | 6 +- editor/spatial_editor_gizmos.cpp | 8 +- .../gdnavigation/navigation_mesh_editor_plugin.cpp | 6 +- .../gdnavigation/navigation_mesh_editor_plugin.h | 6 +- modules/gdnavigation/navigation_mesh_generator.h | 2 +- scene/3d/navigation.h | 2 +- scene/3d/navigation_mesh_instance.cpp | 258 --------------------- scene/3d/navigation_mesh_instance.h | 75 ------ scene/3d/navigation_region.cpp | 258 +++++++++++++++++++++ scene/3d/navigation_region.h | 75 ++++++ scene/register_scene_types.cpp | 4 +- scene/resources/mesh_library.h | 2 +- servers/navigation_server.h | 2 +- 20 files changed, 456 insertions(+), 399 deletions(-) delete mode 100644 doc/classes/NavigationMeshInstance.xml create mode 100644 doc/classes/NavigationRegion.xml delete mode 100644 editor/icons/NavigationMeshInstance.svg create mode 100644 editor/icons/NavigationRegion.svg delete mode 100644 scene/3d/navigation_mesh_instance.cpp delete mode 100644 scene/3d/navigation_mesh_instance.h create mode 100644 scene/3d/navigation_region.cpp create mode 100644 scene/3d/navigation_region.h diff --git a/doc/classes/Navigation.xml b/doc/classes/Navigation.xml index 0000ca6bd5..93170bca4a 100644 --- a/doc/classes/Navigation.xml +++ b/doc/classes/Navigation.xml @@ -4,7 +4,7 @@ Mesh-based navigation and pathfinding node. - Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on. + Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationRegion] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on. diff --git a/doc/classes/NavigationMeshInstance.xml b/doc/classes/NavigationMeshInstance.xml deleted file mode 100644 index 75bd62e278..0000000000 --- a/doc/classes/NavigationMeshInstance.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - An instance of a [NavigationMesh]. - - - An instance of a [NavigationMesh]. It tells the [Navigation] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation] node. - - - - - - - - - Bakes the [NavigationMesh]. The baking is done in a seperate 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]. - - - - - - Determines if the [NavigationMeshInstance] is enabled or disabled. - - - The [NavigationMesh] resource to use. - - - - - - Notifies when the navigation mesh bake operation is completed. - - - - - Notifies when the [NavigationMesh] has changed. - - - - - - diff --git a/doc/classes/NavigationRegion.xml b/doc/classes/NavigationRegion.xml new file mode 100644 index 0000000000..41fac70654 --- /dev/null +++ b/doc/classes/NavigationRegion.xml @@ -0,0 +1,42 @@ + + + + A region of the navigation map. + + + A region of the navigation map. It tells the [Navigation] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation] node (even not a direct child). + + + + + + + + + Bakes the [NavigationMesh]. The baking is done in a seperate 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]. + + + + + + Determines if the [NavigationRegion] is enabled or disabled. + + + The [NavigationMesh] resource to use. + + + + + + Notifies when the navigation mesh bake operation is completed. + + + + + Notifies when the [NavigationMesh] has changed. + + + + + + diff --git a/editor/icons/NavigationMeshInstance.svg b/editor/icons/NavigationMeshInstance.svg deleted file mode 100644 index 737d9c319d..0000000000 --- a/editor/icons/NavigationMeshInstance.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/editor/icons/NavigationRegion.svg b/editor/icons/NavigationRegion.svg new file mode 100644 index 0000000000..92cc9afd91 --- /dev/null +++ b/editor/icons/NavigationRegion.svg @@ -0,0 +1,58 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 9fb6be50d9..dbd67d1e22 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -559,7 +559,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map Ref mesh = mi->get_mesh(); ERR_FAIL_COND_V(mesh.is_null(), NULL); - NavigationMeshInstance *nmi = memnew(NavigationMeshInstance); + NavigationRegion *nmi = memnew(NavigationRegion); nmi->set_name(_fixstr(name, "navmesh")); Ref nmesh = memnew(NavigationMesh); diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 37cf16de58..c285bb4e1a 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -32,7 +32,7 @@ #include "editor/editor_scale.h" #include "scene/3d/collision_shape.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/physics_body.h" #include "scene/gui/box_container.h" #include "spatial_editor_plugin.h" @@ -233,7 +233,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { return; nmesh->create_from_mesh(mesh); - NavigationMeshInstance *nmi = memnew(NavigationMeshInstance); + NavigationRegion *nmi = memnew(NavigationRegion); nmi->set_navigation_mesh(nmesh); Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index ea8842a56f..863ea451b5 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -34,7 +34,7 @@ #include "editor/editor_settings.h" #include "main/main.h" #include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/physics_body.h" #include "scene/main/viewport.h" #include "scene/resources/packed_scene.h" @@ -152,9 +152,9 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref p_library, Transform navmesh_transform; for (int j = 0; j < mi->get_child_count(); j++) { Node *child2 = mi->get_child(j); - if (!Object::cast_to(child2)) + if (!Object::cast_to(child2)) continue; - NavigationMeshInstance *sb = Object::cast_to(child2); + NavigationRegion *sb = Object::cast_to(child2); navmesh = sb->get_navigation_mesh(); navmesh_transform = sb->get_transform(); if (!navmesh.is_null()) diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 40e1be665c..f240654487 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -41,7 +41,7 @@ #include "scene/3d/light.h" #include "scene/3d/listener.h" #include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/particles.h" #include "scene/3d/physics_joint.h" #include "scene/3d/position_3d.h" @@ -3720,11 +3720,11 @@ NavigationMeshSpatialGizmoPlugin::NavigationMeshSpatialGizmoPlugin() { } bool NavigationMeshSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { - return Object::cast_to(p_spatial) != NULL; + return Object::cast_to(p_spatial) != NULL; } String NavigationMeshSpatialGizmoPlugin::get_name() const { - return "NavigationMeshInstance"; + return "NavigationRegion"; } int NavigationMeshSpatialGizmoPlugin::get_priority() const { @@ -3733,7 +3733,7 @@ int NavigationMeshSpatialGizmoPlugin::get_priority() const { void NavigationMeshSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - NavigationMeshInstance *navmesh = Object::cast_to(p_gizmo->get_spatial_node()); + NavigationRegion *navmesh = Object::cast_to(p_gizmo->get_spatial_node()); Ref edge_material = get_material("navigation_edge_material", p_gizmo); Ref edge_material_disabled = get_material("navigation_edge_material_disabled", p_gizmo); diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp index 28fe0bfd06..4ab90ac7eb 100644 --- a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp +++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp @@ -84,7 +84,7 @@ void NavigationMeshEditor::_clear_pressed() { } } -void NavigationMeshEditor::edit(NavigationMeshInstance *p_nav_mesh_instance) { +void NavigationMeshEditor::edit(NavigationRegion *p_nav_mesh_instance) { if (p_nav_mesh_instance == NULL || node == p_nav_mesh_instance) { return; @@ -128,12 +128,12 @@ NavigationMeshEditor::~NavigationMeshEditor() { void NavigationMeshEditorPlugin::edit(Object *p_object) { - navigation_mesh_editor->edit(Object::cast_to(p_object)); + navigation_mesh_editor->edit(Object::cast_to(p_object)); } bool NavigationMeshEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("NavigationMeshInstance"); + return p_object->is_class("NavigationRegion"); } void NavigationMeshEditorPlugin::make_visible(bool p_visible) { diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h index f5833f3d7f..7c3faebf57 100644 --- a/modules/gdnavigation/navigation_mesh_editor_plugin.h +++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h @@ -36,7 +36,7 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" -class NavigationMeshInstance; +class NavigationRegion; class NavigationMeshEditor : public Control { friend class NavigationMeshEditorPlugin; @@ -50,7 +50,7 @@ class NavigationMeshEditor : public Control { ToolButton *button_reset; Label *bake_info; - NavigationMeshInstance *node; + NavigationRegion *node; void _bake_pressed(); void _clear_pressed(); @@ -61,7 +61,7 @@ protected: void _notification(int p_option); public: - void edit(NavigationMeshInstance *p_nav_mesh_instance); + void edit(NavigationRegion *p_nav_mesh_instance); NavigationMeshEditor(); ~NavigationMeshEditor(); }; diff --git a/modules/gdnavigation/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h index 27a56e1d7a..d1f2e4b56f 100644 --- a/modules/gdnavigation/navigation_mesh_generator.h +++ b/modules/gdnavigation/navigation_mesh_generator.h @@ -33,7 +33,7 @@ #ifndef _3D_DISABLED -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index 85887651ff..08f306611f 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -31,7 +31,7 @@ #ifndef NAVIGATION_H #define NAVIGATION_H -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/spatial.h" class Navigation : public Spatial { diff --git a/scene/3d/navigation_mesh_instance.cpp b/scene/3d/navigation_mesh_instance.cpp deleted file mode 100644 index 8f8574ba2d..0000000000 --- a/scene/3d/navigation_mesh_instance.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/*************************************************************************/ -/* navigation_mesh_instance.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "navigation_mesh_instance.h" -#include "core/os/thread.h" -#include "mesh_instance.h" -#include "navigation.h" -#include "servers/navigation_server.h" - -void NavigationMeshInstance::set_enabled(bool p_enabled) { - - if (enabled == p_enabled) - return; - enabled = p_enabled; - - if (!is_inside_tree()) - return; - - if (!enabled) { - - NavigationServer::get_singleton()->region_set_map(region, RID()); - } else { - - if (navigation) { - - NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); - } - } - - if (debug_view) { - MeshInstance *dm = Object::cast_to(debug_view); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); - } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); - } - } - - update_gizmo(); -} - -bool NavigationMeshInstance::is_enabled() const { - - return enabled; -} - -///////////////////////////// - -void NavigationMeshInstance::_notification(int p_what) { - - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - - Spatial *c = this; - while (c) { - - navigation = Object::cast_to(c); - if (navigation) { - - if (enabled) { - - NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); - } - break; - } - - c = c->get_parent_spatial(); - } - - if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { - - MeshInstance *dm = memnew(MeshInstance); - dm->set_mesh(navmesh->get_debug_mesh()); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); - } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); - } - add_child(dm); - debug_view = dm; - } - - } break; - case NOTIFICATION_TRANSFORM_CHANGED: { - - NavigationServer::get_singleton()->region_set_transform(region, get_global_transform()); - - } break; - case NOTIFICATION_EXIT_TREE: { - - if (navigation) { - - NavigationServer::get_singleton()->region_set_map(region, RID()); - } - - if (debug_view) { - debug_view->queue_delete(); - debug_view = NULL; - } - navigation = NULL; - } break; - } -} - -void NavigationMeshInstance::set_navigation_mesh(const Ref &p_navmesh) { - - if (p_navmesh == navmesh) - return; - - if (navmesh.is_valid()) { - navmesh->remove_change_receptor(this); - } - - navmesh = p_navmesh; - - if (navmesh.is_valid()) { - navmesh->add_change_receptor(this); - } - - NavigationServer::get_singleton()->region_set_navmesh(region, p_navmesh); - - if (debug_view && navmesh.is_valid()) { - Object::cast_to(debug_view)->set_mesh(navmesh->get_debug_mesh()); - } - - emit_signal("navigation_mesh_changed"); - - update_gizmo(); - update_configuration_warning(); -} - -Ref NavigationMeshInstance::get_navigation_mesh() const { - - return navmesh; -} - -struct BakeThreadsArgs { - NavigationMeshInstance *nav_mesh_instance; -}; - -void _bake_navigation_mesh(void *p_user_data) { - BakeThreadsArgs *args = static_cast(p_user_data); - - if (args->nav_mesh_instance->get_navigation_mesh().is_valid()) { - Ref nav_mesh = args->nav_mesh_instance->get_navigation_mesh()->duplicate(); - - NavigationServer::get_singleton()->region_bake_navmesh(nav_mesh, args->nav_mesh_instance); - args->nav_mesh_instance->call_deferred("_bake_finished", nav_mesh); - memdelete(args); - } else { - - ERR_PRINT("Can't bake the navigation mesh if the `NavigationMesh` resource doesn't exist"); - args->nav_mesh_instance->call_deferred("_bake_finished", Ref()); - memdelete(args); - } -} - -void NavigationMeshInstance::bake_navigation_mesh() { - ERR_FAIL_COND(bake_thread != NULL); - - BakeThreadsArgs *args = memnew(BakeThreadsArgs); - args->nav_mesh_instance = this; - - bake_thread = Thread::create(_bake_navigation_mesh, args); - ERR_FAIL_COND(bake_thread == NULL); -} - -void NavigationMeshInstance::_bake_finished(Ref p_nav_mesh) { - set_navigation_mesh(p_nav_mesh); - bake_thread = NULL; -} - -String NavigationMeshInstance::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) - return String(); - - if (!navmesh.is_valid()) { - return TTR("A NavigationMesh resource must be set or created for this node to work."); - } - const Spatial *c = this; - while (c) { - - if (Object::cast_to(c)) - return String(); - - c = Object::cast_to(c->get_parent()); - } - - return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data."); -} - -void NavigationMeshInstance::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationMeshInstance::set_navigation_mesh); - ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationMeshInstance::get_navigation_mesh); - - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationMeshInstance::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationMeshInstance::is_enabled); - - ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationMeshInstance::bake_navigation_mesh); - 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::BOOL, "enabled"), "set_enabled", "is_enabled"); - - ADD_SIGNAL(MethodInfo("navigation_mesh_changed")); - ADD_SIGNAL(MethodInfo("bake_finished")); -} - -void NavigationMeshInstance::_changed_callback(Object *p_changed, const char *p_prop) { - update_gizmo(); - update_configuration_warning(); -} - -NavigationMeshInstance::NavigationMeshInstance() { - - enabled = true; - set_notify_transform(true); - region = NavigationServer::get_singleton()->region_create(); - - navigation = NULL; - debug_view = NULL; - bake_thread = NULL; -} - -NavigationMeshInstance::~NavigationMeshInstance() { - if (navmesh.is_valid()) - navmesh->remove_change_receptor(this); - NavigationServer::get_singleton()->free(region); -} diff --git a/scene/3d/navigation_mesh_instance.h b/scene/3d/navigation_mesh_instance.h deleted file mode 100644 index 1135bf47d2..0000000000 --- a/scene/3d/navigation_mesh_instance.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************/ -/* navigation_mesh_instance.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef NAVIGATION_MESH_INSTANCE_H -#define NAVIGATION_MESH_INSTANCE_H - -#include "scene/3d/spatial.h" -#include "scene/resources/mesh.h" -#include "scene/resources/navigation_mesh.h" - -class Navigation; - -class NavigationMeshInstance : public Spatial { - - GDCLASS(NavigationMeshInstance, Spatial); - - bool enabled; - RID region; - Ref navmesh; - - Navigation *navigation; - Node *debug_view; - Thread *bake_thread; - -protected: - void _notification(int p_what); - static void _bind_methods(); - void _changed_callback(Object *p_changed, const char *p_prop); - -public: - void set_enabled(bool p_enabled); - bool is_enabled() const; - - void set_navigation_mesh(const Ref &p_navmesh); - Ref get_navigation_mesh() const; - - /// Bakes the navigation mesh in a dedicated thread; once done, automatically - /// sets the new navigation mesh and emits a signal - void bake_navigation_mesh(); - void _bake_finished(Ref p_nav_mesh); - - String get_configuration_warning() const; - - NavigationMeshInstance(); - ~NavigationMeshInstance(); -}; - -#endif // NAVIGATION_MESH_INSTANCE_H diff --git a/scene/3d/navigation_region.cpp b/scene/3d/navigation_region.cpp new file mode 100644 index 0000000000..d96d095797 --- /dev/null +++ b/scene/3d/navigation_region.cpp @@ -0,0 +1,258 @@ +/*************************************************************************/ +/* navigation_region.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_region.h" +#include "core/os/thread.h" +#include "mesh_instance.h" +#include "navigation.h" +#include "servers/navigation_server.h" + +void NavigationRegion::set_enabled(bool p_enabled) { + + if (enabled == p_enabled) + return; + enabled = p_enabled; + + if (!is_inside_tree()) + return; + + if (!enabled) { + + NavigationServer::get_singleton()->region_set_map(region, RID()); + } else { + + if (navigation) { + + NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); + } + } + + if (debug_view) { + MeshInstance *dm = Object::cast_to(debug_view); + if (is_enabled()) { + dm->set_material_override(get_tree()->get_debug_navigation_material()); + } else { + dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); + } + } + + update_gizmo(); +} + +bool NavigationRegion::is_enabled() const { + + return enabled; +} + +///////////////////////////// + +void NavigationRegion::_notification(int p_what) { + + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + + Spatial *c = this; + while (c) { + + navigation = Object::cast_to(c); + if (navigation) { + + if (enabled) { + + NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); + } + break; + } + + c = c->get_parent_spatial(); + } + + if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { + + MeshInstance *dm = memnew(MeshInstance); + dm->set_mesh(navmesh->get_debug_mesh()); + if (is_enabled()) { + dm->set_material_override(get_tree()->get_debug_navigation_material()); + } else { + dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); + } + add_child(dm); + debug_view = dm; + } + + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + + NavigationServer::get_singleton()->region_set_transform(region, get_global_transform()); + + } break; + case NOTIFICATION_EXIT_TREE: { + + if (navigation) { + + NavigationServer::get_singleton()->region_set_map(region, RID()); + } + + if (debug_view) { + debug_view->queue_delete(); + debug_view = NULL; + } + navigation = NULL; + } break; + } +} + +void NavigationRegion::set_navigation_mesh(const Ref &p_navmesh) { + + if (p_navmesh == navmesh) + return; + + if (navmesh.is_valid()) { + navmesh->remove_change_receptor(this); + } + + navmesh = p_navmesh; + + if (navmesh.is_valid()) { + navmesh->add_change_receptor(this); + } + + NavigationServer::get_singleton()->region_set_navmesh(region, p_navmesh); + + if (debug_view && navmesh.is_valid()) { + Object::cast_to(debug_view)->set_mesh(navmesh->get_debug_mesh()); + } + + emit_signal("navigation_mesh_changed"); + + update_gizmo(); + update_configuration_warning(); +} + +Ref NavigationRegion::get_navigation_mesh() const { + + return navmesh; +} + +struct BakeThreadsArgs { + NavigationRegion *nav_mesh_instance; +}; + +void _bake_navigation_mesh(void *p_user_data) { + BakeThreadsArgs *args = static_cast(p_user_data); + + if (args->nav_mesh_instance->get_navigation_mesh().is_valid()) { + Ref nav_mesh = args->nav_mesh_instance->get_navigation_mesh()->duplicate(); + + NavigationServer::get_singleton()->region_bake_navmesh(nav_mesh, args->nav_mesh_instance); + args->nav_mesh_instance->call_deferred("_bake_finished", nav_mesh); + memdelete(args); + } else { + + ERR_PRINT("Can't bake the navigation mesh if the `NavigationMesh` resource doesn't exist"); + args->nav_mesh_instance->call_deferred("_bake_finished", Ref()); + memdelete(args); + } +} + +void NavigationRegion::bake_navigation_mesh() { + ERR_FAIL_COND(bake_thread != NULL); + + BakeThreadsArgs *args = memnew(BakeThreadsArgs); + args->nav_mesh_instance = this; + + bake_thread = Thread::create(_bake_navigation_mesh, args); + ERR_FAIL_COND(bake_thread == NULL); +} + +void NavigationRegion::_bake_finished(Ref p_nav_mesh) { + set_navigation_mesh(p_nav_mesh); + bake_thread = NULL; +} + +String NavigationRegion::get_configuration_warning() const { + + if (!is_visible_in_tree() || !is_inside_tree()) + return String(); + + if (!navmesh.is_valid()) { + return TTR("A NavigationMesh resource must be set or created for this node to work."); + } + const Spatial *c = this; + while (c) { + + if (Object::cast_to(c)) + return String(); + + c = Object::cast_to(c->get_parent()); + } + + return TTR("NavigationRegion must be a child or grandchild to a Navigation node. It only provides navigation data."); +} + +void NavigationRegion::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationRegion::set_navigation_mesh); + ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationRegion::get_navigation_mesh); + + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion::is_enabled); + + ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion::bake_navigation_mesh); + ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion::_bake_finished); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); + + ADD_SIGNAL(MethodInfo("navigation_mesh_changed")); + ADD_SIGNAL(MethodInfo("bake_finished")); +} + +void NavigationRegion::_changed_callback(Object *p_changed, const char *p_prop) { + update_gizmo(); + update_configuration_warning(); +} + +NavigationRegion::NavigationRegion() { + + enabled = true; + set_notify_transform(true); + region = NavigationServer::get_singleton()->region_create(); + + navigation = NULL; + debug_view = NULL; + bake_thread = NULL; +} + +NavigationRegion::~NavigationRegion() { + if (navmesh.is_valid()) + navmesh->remove_change_receptor(this); + NavigationServer::get_singleton()->free(region); +} diff --git a/scene/3d/navigation_region.h b/scene/3d/navigation_region.h new file mode 100644 index 0000000000..c6b2ea350f --- /dev/null +++ b/scene/3d/navigation_region.h @@ -0,0 +1,75 @@ +/*************************************************************************/ +/* navigation_region.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef navigation_region_H +#define navigation_region_H + +#include "scene/3d/spatial.h" +#include "scene/resources/mesh.h" +#include "scene/resources/navigation_mesh.h" + +class Navigation; + +class NavigationRegion : public Spatial { + + GDCLASS(NavigationRegion, Spatial); + + bool enabled; + RID region; + Ref navmesh; + + Navigation *navigation; + Node *debug_view; + Thread *bake_thread; + +protected: + void _notification(int p_what); + static void _bind_methods(); + void _changed_callback(Object *p_changed, const char *p_prop); + +public: + void set_enabled(bool p_enabled); + bool is_enabled() const; + + void set_navigation_mesh(const Ref &p_navmesh); + Ref get_navigation_mesh() const; + + /// Bakes the navigation mesh in a dedicated thread; once done, automatically + /// sets the new navigation mesh and emits a signal + void bake_navigation_mesh(); + void _bake_finished(Ref p_nav_mesh); + + String get_configuration_warning() const; + + NavigationRegion(); + ~NavigationRegion(); +}; + +#endif // navigation_region_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 6288598ce2..f11d0a21d4 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -190,7 +190,7 @@ #include "scene/3d/multimesh_instance.h" #include "scene/3d/navigation.h" #include "scene/3d/navigation_agent.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/navigation_obstacle.h" #include "scene/3d/particles.h" #include "scene/3d/path.h" @@ -470,7 +470,7 @@ void register_scene_types() { ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 9155975f47..b256e86b96 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -34,7 +34,7 @@ #include "core/map.h" #include "core/resource.h" #include "mesh.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "shape.h" class MeshLibrary : public Resource { diff --git a/servers/navigation_server.h b/servers/navigation_server.h index 2587e53ab2..7c9b6ba595 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -37,7 +37,7 @@ #include "core/object.h" #include "core/rid.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" /// This server uses the concept of internal mutability. /// All the constant functions can be called in multithread because internally -- cgit v1.2.3