mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-24 04:46:48 +01:00
Also added the navigation mesh generator module. It's disabled for now, as it needs some reworks.
This commit is contained in:
parent
54ae614941
commit
e55c561075
48
modules/navigation_mesh_generator/SCsub
Normal file
48
modules/navigation_mesh_generator/SCsub
Normal 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)
|
9
modules/navigation_mesh_generator/config.py
Normal file
9
modules/navigation_mesh_generator/config.py
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
def can_build(env, platform):
|
||||
#return True
|
||||
return False
|
||||
|
||||
|
||||
def configure(env):
|
||||
pass
|
@ -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
|
@ -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
|
@ -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") {
|
||||
}
|
@ -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
@ -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
|
64
modules/navigation_mesh_generator/register_types.cpp
Normal file
64
modules/navigation_mesh_generator/register_types.cpp
Normal 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) {
|
||||
}
|
||||
}
|
40
modules/navigation_mesh_generator/register_types.h
Normal file
40
modules/navigation_mesh_generator/register_types.h
Normal 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
|
Loading…
Reference in New Issue
Block a user