Also added the navigation mesh generator module. It's disabled for now, as it needs some reworks.

This commit is contained in:
Relintai 2023-06-03 21:18:18 +02:00
parent 54ae614941
commit e55c561075
10 changed files with 1991 additions and 0 deletions

View File

@ -0,0 +1,48 @@
#!/usr/bin/env python
Import("env")
Import("env_modules")
env_navigation_mesh_generator = env_modules.Clone()
# Thirdparty source files
thirdparty_obj = []
# Recast Thirdparty source files
if env["builtin_recastnavigation"]:
thirdparty_dir = "#thirdparty/recastnavigation/Recast/"
thirdparty_sources = [
"Source/Recast.cpp",
"Source/RecastAlloc.cpp",
"Source/RecastArea.cpp",
"Source/RecastAssert.cpp",
"Source/RecastContour.cpp",
"Source/RecastFilter.cpp",
"Source/RecastLayers.cpp",
"Source/RecastMesh.cpp",
"Source/RecastMeshDetail.cpp",
"Source/RecastRasterization.cpp",
"Source/RecastRegion.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_navigation_mesh_generator.Prepend(CPPPATH=[thirdparty_dir + "Include"])
env_thirdparty = env_navigation_mesh_generator.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj
# Godot source files
module_obj = []
env_navigation_mesh_generator.add_source_files(module_obj, "*.cpp")
if env.editor_build:
env_navigation_mesh_generator.add_source_files(module_obj, "editor/*.cpp")
env.modules_sources += module_obj
# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)

View File

@ -0,0 +1,9 @@
def can_build(env, platform):
#return True
return False
def configure(env):
pass

View File

@ -0,0 +1,191 @@
/**************************************************************************/
/* navigation_mesh_editor_plugin.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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_editor_plugin.h"
#ifdef TOOLS_ENABLED
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/label.h"
#include "servers/navigation/navigation_mesh_generator.h"
void NavigationMeshEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = nullptr;
hide();
}
}
void NavigationMeshEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
button_bake->set_icon(get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
button_reset->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
} break;
}
}
void NavigationMeshEditor::_bake_pressed() {
button_bake->set_pressed(false);
ERR_FAIL_COND(!node);
Ref<NavigationMesh> navigation_mesh = node->get_navigation_mesh();
if (!navigation_mesh.is_valid()) {
err_dialog->set_text(TTR("A NavigationMesh resource must be set or created for this node to work."));
err_dialog->popup_centered();
return;
}
String path = navigation_mesh->get_path();
if (!path.is_resource_file()) {
int srpos = path.find("::");
if (srpos != -1) {
String base = path.substr(0, srpos);
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
err_dialog->set_text(TTR("Cannot generate navigation mesh because it does not belong to the edited scene. Make it unique first."));
err_dialog->popup_centered();
return;
}
} else {
if (FileAccess::exists(base + ".import")) {
err_dialog->set_text(TTR("Cannot generate navigation mesh because it belongs to a resource which was imported."));
err_dialog->popup_centered();
return;
}
}
}
} else {
if (FileAccess::exists(path + ".import")) {
err_dialog->set_text(TTR("Cannot generate navigation mesh because the resource was imported from another type."));
err_dialog->popup_centered();
return;
}
}
node->bake_navigation_mesh(true);
node->update_gizmos();
}
void NavigationMeshEditor::_clear_pressed() {
if (node) {
if (node->get_navigation_mesh().is_valid()) {
node->get_navigation_mesh()->clear();
}
}
button_bake->set_pressed(false);
bake_info->set_text("");
if (node) {
node->update_gizmos();
}
}
void NavigationMeshEditor::edit(NavigationRegion3D *p_nav_region) {
if (p_nav_region == nullptr || node == p_nav_region) {
return;
}
node = p_nav_region;
}
void NavigationMeshEditor::_bind_methods() {
}
NavigationMeshEditor::NavigationMeshEditor() {
bake_hbox = memnew(HBoxContainer);
button_bake = memnew(Button);
button_bake->set_flat(true);
bake_hbox->add_child(button_bake);
button_bake->set_toggle_mode(true);
button_bake->set_text(TTR("Bake NavigationMesh"));
button_bake->set_tooltip_text(TTR("Bakes the NavigationMesh by first parsing the scene for source geometry and then creating the navigation mesh vertices and indices."));
button_bake->connect("pressed", callable_mp(this, &NavigationMeshEditor::_bake_pressed));
button_reset = memnew(Button);
button_reset->set_flat(true);
bake_hbox->add_child(button_reset);
button_reset->set_text(TTR("Clear NavigationMesh"));
button_reset->set_tooltip_text(TTR("Clears the internal NavigationMesh vertices and indices."));
button_reset->connect("pressed", callable_mp(this, &NavigationMeshEditor::_clear_pressed));
bake_info = memnew(Label);
bake_hbox->add_child(bake_info);
err_dialog = memnew(AcceptDialog);
add_child(err_dialog);
node = nullptr;
}
NavigationMeshEditor::~NavigationMeshEditor() {
}
void NavigationMeshEditorPlugin::edit(Object *p_object) {
navigation_mesh_editor->edit(Object::cast_to<NavigationRegion3D>(p_object));
}
bool NavigationMeshEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("NavigationRegion3D");
}
void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
navigation_mesh_editor->show();
navigation_mesh_editor->bake_hbox->show();
} else {
navigation_mesh_editor->hide();
navigation_mesh_editor->bake_hbox->hide();
navigation_mesh_editor->edit(nullptr);
}
}
NavigationMeshEditorPlugin::NavigationMeshEditorPlugin() {
navigation_mesh_editor = memnew(NavigationMeshEditor);
EditorNode::get_singleton()->get_main_screen_control()->add_child(navigation_mesh_editor);
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, navigation_mesh_editor->bake_hbox);
navigation_mesh_editor->hide();
navigation_mesh_editor->bake_hbox->hide();
}
NavigationMeshEditorPlugin::~NavigationMeshEditorPlugin() {
}
#endif // TOOLS_ENABLED

View File

@ -0,0 +1,90 @@
/**************************************************************************/
/* navigation_mesh_editor_plugin.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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_EDITOR_PLUGIN_H
#define NAVIGATION_MESH_EDITOR_PLUGIN_H
#ifdef TOOLS_ENABLED
#include "editor/editor_plugin.h"
class AcceptDialog;
class Button;
class HBoxContainer;
class Label;
class NavigationRegion3D;
class NavigationMeshEditor : public Control {
friend class NavigationMeshEditorPlugin;
GDCLASS(NavigationMeshEditor, Control);
AcceptDialog *err_dialog = nullptr;
HBoxContainer *bake_hbox = nullptr;
Button *button_bake = nullptr;
Button *button_reset = nullptr;
Label *bake_info = nullptr;
NavigationRegion3D *node = nullptr;
void _bake_pressed();
void _clear_pressed();
protected:
void _node_removed(Node *p_node);
static void _bind_methods();
void _notification(int p_what);
public:
void edit(NavigationRegion3D *p_nav_region);
NavigationMeshEditor();
~NavigationMeshEditor();
};
class NavigationMeshEditorPlugin : public EditorPlugin {
GDCLASS(NavigationMeshEditorPlugin, EditorPlugin);
NavigationMeshEditor *navigation_mesh_editor = nullptr;
public:
virtual String get_name() const override { return "NavigationMesh"; }
bool has_main_screen() const override { return false; }
virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
NavigationMeshEditorPlugin();
~NavigationMeshEditorPlugin();
};
#endif // TOOLS_ENABLED
#endif // NAVIGATION_MESH_EDITOR_PLUGIN_H

View File

@ -0,0 +1,210 @@
/**************************************************************************/
/* navigation_polygon_editor_plugin.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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_polygon_editor_plugin.h"
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/mesh_instance_2d.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/label.h"
#include "scene/gui/option_button.h"
#include "servers/navigation/navigation_mesh_generator.h"
Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const {
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
if (!navpoly.is_valid()) {
navpoly = Ref<NavigationPolygon>(memnew(NavigationPolygon));
node->set_navigation_polygon(navpoly);
}
return navpoly;
}
Node2D *NavigationPolygonEditor::_get_node() const {
return node;
}
void NavigationPolygonEditor::_set_node(Node *p_polygon) {
node = Object::cast_to<NavigationRegion2D>(p_polygon);
}
int NavigationPolygonEditor::_get_polygon_count() const {
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
if (navpoly.is_valid()) {
return navpoly->get_outline_count();
} else {
return 0;
}
}
Variant NavigationPolygonEditor::_get_polygon(int p_idx) const {
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
if (navpoly.is_valid()) {
return navpoly->get_outline(p_idx);
} else {
return Variant(Vector<Vector2>());
}
}
void NavigationPolygonEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
navpoly->set_outline(p_idx, p_polygon);
}
void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->add_do_method(navpoly.ptr(), "add_outline", p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "remove_outline", navpoly->get_outline_count());
}
void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->add_do_method(navpoly.ptr(), "remove_outline", p_idx);
undo_redo->add_undo_method(navpoly.ptr(), "add_outline_at_index", navpoly->get_outline(p_idx), p_idx);
}
void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->add_do_method(navpoly.ptr(), "set_outline", p_idx, p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "set_outline", p_idx, p_previous);
}
bool NavigationPolygonEditor::_has_resource() const {
return node && node->get_navigation_polygon().is_valid();
}
void NavigationPolygonEditor::_create_resource() {
if (!node) {
return;
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Create Navigation Polygon"));
undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon)));
undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(Ref<RefCounted>()));
undo_redo->commit_action();
_menu_option(MODE_CREATE);
}
NavigationPolygonEditor::NavigationPolygonEditor() {
bake_hbox = memnew(HBoxContainer);
add_child(bake_hbox);
button_bake = memnew(Button);
button_bake->set_flat(true);
bake_hbox->add_child(button_bake);
button_bake->set_toggle_mode(true);
button_bake->set_text(TTR("Bake NavigationPolygon"));
button_bake->set_tooltip_text(TTR("Bakes the NavigationPolygon by first parsing the scene for source geometry and then creating the navigation polygon vertices and polygons."));
button_bake->connect("pressed", callable_mp(this, &NavigationPolygonEditor::_bake_pressed));
button_reset = memnew(Button);
button_reset->set_flat(true);
bake_hbox->add_child(button_reset);
button_reset->set_text(TTR("Clear NavigationPolygon"));
button_reset->set_tooltip_text(TTR("Clears the internal NavigationPolygon outlines, vertices and polygons."));
button_reset->connect("pressed", callable_mp(this, &NavigationPolygonEditor::_clear_pressed));
bake_info = memnew(Label);
bake_hbox->add_child(bake_info);
err_dialog = memnew(AcceptDialog);
add_child(err_dialog);
node = nullptr;
}
void NavigationPolygonEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
button_bake->set_icon(get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
button_reset->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
} break;
}
}
void NavigationPolygonEditor::_bake_pressed() {
button_bake->set_pressed(false);
ERR_FAIL_COND(!node);
Ref<NavigationPolygon> navigation_polygon = node->get_navigation_polygon();
if (!navigation_polygon.is_valid()) {
err_dialog->set_text(TTR("A NavigationMesh2D resource must be set or created for this node to work."));
err_dialog->popup_centered();
return;
}
navigation_polygon->clear_polygons();
navigation_polygon->set_vertices(Vector<Vector2>());
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data = NavigationMeshGenerator::get_singleton()->parse_2d_source_geometry_data(navigation_polygon, node);
NavigationMeshGenerator::get_singleton()->bake_2d_from_source_geometry_data(navigation_polygon, source_geometry_data);
node->queue_redraw();
}
void NavigationPolygonEditor::_clear_pressed() {
ERR_FAIL_COND(!node);
if (!node->get_navigation_polygon().is_valid()) {
return;
}
node->get_navigation_polygon()->clear();
button_bake->set_pressed(false);
bake_info->set_text("");
if (node) {
node->queue_redraw();
}
}
void NavigationPolygonEditor::_update_polygon_editing_state() {
if (!_get_node()) {
return;
}
if (node != nullptr && node->get_navigation_polygon().is_valid()) {
bake_hbox->show();
} else {
bake_hbox->hide();
}
}
NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin() :
AbstractPolygon2DEditorPlugin(memnew(NavigationPolygonEditor), "NavigationRegion2D") {
}

View File

@ -0,0 +1,94 @@
/**************************************************************************/
/* navigation_polygon_editor_plugin.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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_POLYGON_EDITOR_PLUGIN_H
#define NAVIGATION_POLYGON_EDITOR_PLUGIN_H
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/navigation_region_2d.h"
#include "editor/editor_plugin.h"
class AcceptDialog;
class OptionButton;
class HBoxContainer;
class NavigationPolygonEditor : public AbstractPolygon2DEditor {
friend class NavigationPolygonEditorPlugin;
GDCLASS(NavigationPolygonEditor, AbstractPolygon2DEditor);
NavigationRegion2D *node = nullptr;
Ref<NavigationPolygon> _ensure_navpoly() const;
AcceptDialog *err_dialog = nullptr;
HBoxContainer *bake_hbox = nullptr;
Button *button_bake = nullptr;
Button *button_reset = nullptr;
Label *bake_info = nullptr;
void _bake_pressed();
void _clear_pressed();
void _update_polygon_editing_state();
protected:
void _notification(int p_what);
virtual Node2D *_get_node() const override;
virtual void _set_node(Node *p_polygon) override;
virtual int _get_polygon_count() const override;
virtual Variant _get_polygon(int p_idx) const override;
virtual void _set_polygon(int p_idx, const Variant &p_polygon) const override;
virtual void _action_add_polygon(const Variant &p_polygon) override;
virtual void _action_remove_polygon(int p_idx) override;
virtual void _action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) override;
virtual bool _has_resource() const override;
virtual void _create_resource() override;
public:
NavigationPolygonEditor();
};
class NavigationPolygonEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(NavigationPolygonEditorPlugin, AbstractPolygon2DEditorPlugin);
NavigationPolygonEditor *navigation_polygon_editor = nullptr;
public:
NavigationPolygonEditorPlugin();
};
#endif // NAVIGATION_POLYGON_EDITOR_PLUGIN_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,167 @@
/**************************************************************************/
/* godot_navigation_mesh_generator.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Pandemonium Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 PANDEMONIUM_NAVIGATION_MESH_GENERATOR_H
#define PANDEMONIUM_NAVIGATION_MESH_GENERATOR_H
#include "servers/navigation/navigation_mesh_generator.h"
#include "core/object/worker_thread_pool.h"
#include "scene/2d/navigation_geometry_parser_2d.h"
#include "scene/3d/navigation_geometry_parser_3d.h"
#include "scene/resources/navigation_mesh_source_geometry_data_2d.h"
#include "scene/resources/navigation_mesh_source_geometry_data_3d.h"
class PandemoniumNavigationMeshGenerator : public NavigationMeshGenerator {
Mutex generator_mutex;
bool use_threads = true;
bool parsing_use_multiple_threads = true;
bool parsing_use_high_priority_threads = true;
bool baking_use_multiple_threads = true;
bool baking_use_high_priority_threads = true;
public:
PandemoniumNavigationMeshGenerator();
~PandemoniumNavigationMeshGenerator() override;
struct NavigationGeneratorTask2D {
enum TaskStatus {
PARSING_REQUIRED,
PARSING_STARTED,
PARSING_FINISHED,
PARSING_FAILED,
BAKING_STARTED,
BAKING_FINISHED,
BAKING_FAILED,
CALLBACK_DISPATCHED,
CALLBACK_FAILED,
};
Ref<NavigationPolygon> navigation_polygon;
ObjectID parse_root_object_id;
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data;
Callable callback;
NavigationGeneratorTask2D::TaskStatus status = NavigationGeneratorTask2D::TaskStatus::PARSING_REQUIRED;
LocalVector<Ref<NavigationGeometryParser2D>> geometry_parsers;
};
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:
struct NavigationGeneratorTask3D {
enum TaskStatus {
PARSING_REQUIRED,
PARSING_STARTED,
PARSING_FINISHED,
PARSING_FAILED,
BAKING_STARTED,
BAKING_FINISHED,
BAKING_FAILED,
CALLBACK_DISPATCHED,
CALLBACK_FAILED,
};
Ref<NavigationMesh> navigation_mesh;
ObjectID parse_root_object_id;
Ref<NavigationMeshSourceGeometryData3D> source_geometry_data;
Callable callback;
NavigationGeneratorTask3D::TaskStatus status = NavigationGeneratorTask3D::TaskStatus::PARSING_REQUIRED;
LocalVector<Ref<NavigationGeometryParser3D>> geometry_parsers;
};
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
public:
virtual void process() override;
virtual void cleanup() override;
// 2D ////////////////////////////////////
virtual void register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) override;
virtual void unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) override;
virtual Ref<NavigationMeshSourceGeometryData2D> parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Callable p_callback = Callable()) override;
virtual void bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Callable p_callback = Callable()) override;
virtual void parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Callable p_callback = Callable()) override;
static void _static_parse_2d_geometry_node(Ref<NavigationPolygon> p_navigation_polygon, Node *p_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, bool p_recurse_children, LocalVector<Ref<NavigationGeometryParser2D>> &p_geometry_2d_parsers);
static void _static_parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, LocalVector<Ref<NavigationGeometryParser2D>> &p_geometry_2d_parsers);
static void _static_bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data);
virtual bool is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const override;
#ifndef _3D_DISABLED
virtual void register_geometry_parser_3d(Ref<NavigationGeometryParser3D> p_geometry_parser) override;
virtual void unregister_geometry_parser_3d(Ref<NavigationGeometryParser3D> p_geometry_parser) override;
virtual Ref<NavigationMeshSourceGeometryData3D> parse_3d_source_geometry_data(Ref<NavigationMesh> p_navigation_mesh, Node *p_root_node, Callable p_callback = Callable()) override;
virtual void bake_3d_from_source_geometry_data(Ref<NavigationMesh> p_navigation_mesh, Ref<NavigationMeshSourceGeometryData3D> p_source_geometry_data, Callable p_callback = Callable()) override;
virtual void parse_and_bake_3d(Ref<NavigationMesh> p_navigation_mesh, Node *p_root_node, Callable p_callback = Callable()) override;
static void _static_parse_3d_geometry_node(Ref<NavigationMesh> p_navigation_mesh, Node *p_node, Ref<NavigationMeshSourceGeometryData3D> p_source_geometry_data, bool p_recurse_children, LocalVector<Ref<NavigationGeometryParser3D>> &p_geometry_3d_parsers);
static void _static_parse_3d_source_geometry_data(Ref<NavigationMesh> p_navigation_mesh, Node *p_root_node, Ref<NavigationMeshSourceGeometryData3D> p_source_geometry_data, LocalVector<Ref<NavigationGeometryParser3D>> &p_geometry_3d_parsers);
static void _static_bake_3d_from_source_geometry_data(Ref<NavigationMesh> p_navigation_mesh, Ref<NavigationMeshSourceGeometryData3D> p_source_geometry_data);
virtual bool is_navigation_mesh_baking(Ref<NavigationMesh> p_navigation_mesh) const override;
#endif // _3D_DISABLED
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();
void _process_3d_parse_tasks();
void _process_3d_bake_tasks();
void _process_3d_callbacks();
void _process_3d_cleanup_tasks();
void _parse_3d_scenetree_task(uint32_t index, NavigationGeneratorTask3D **parse_task);
#endif // _3D_DISABLED
};
#endif // GODOT_NAVIGATION_MESH_GENERATOR_H

View File

@ -0,0 +1,64 @@
/**************************************************************************/
/* register_types.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "register_types.h"
#include "core/config/engine.h"
#include "servers/navigation/navigation_mesh_generator.h"
#include "godot_navigation_mesh_generator.h"
#ifdef TOOLS_ENABLED
#include "editor/navigation_mesh_editor_plugin.h"
#include "editor/navigation_polygon_editor_plugin.h"
#endif // TOOLS_ENABLED
NavigationMeshGenerator *new_navigation_mesh_generator_server() {
return memnew(GodotNavigationMeshGenerator);
}
void register_navigation_mesh_generator_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS) {
NavigationMeshGeneratorManager::get_singleton()->register_server("GodotNavigationMeshGenerator", callable_mp_static(new_navigation_mesh_generator_server));
NavigationMeshGeneratorManager::get_singleton()->set_default_server("GodotNavigationMeshGenerator");
}
#ifdef TOOLS_ENABLED
if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
EditorPlugins::add_by_type<NavigationPolygonEditorPlugin>();
}
#endif // TOOLS_ENABLED
}
void unregister_navigation_mesh_generator_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS) {
}
}

View File

@ -0,0 +1,40 @@
#ifndef NAVIGATION_MESH_GENERATOR_REGISTER_TYPES_H
#define NAVIGATION_MESH_GENERATOR_REGISTER_TYPES_H
/**************************************************************************/
/* register_types.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "modules/register_module_types.h"
void register_navigation_mesh_generator_types(ModuleRegistrationLevel p_level);
void unregister_navigation_mesh_generator_types(ModuleRegistrationLevel p_level);
#endif // NAVIGATION_MESH_GENERATOR_REGISTER_TYPES_H