diff options
Diffstat (limited to 'modules/gridmap')
-rw-r--r-- | modules/gridmap/SCsub | 2 | ||||
-rw-r--r-- | modules/gridmap/doc_classes/GridMap.xml | 38 | ||||
-rw-r--r-- | modules/gridmap/editor/grid_map_editor_plugin.cpp | 25 | ||||
-rw-r--r-- | modules/gridmap/editor/grid_map_editor_plugin.h | 7 | ||||
-rw-r--r-- | modules/gridmap/grid_map.cpp | 151 | ||||
-rw-r--r-- | modules/gridmap/grid_map.h | 20 |
6 files changed, 163 insertions, 80 deletions
diff --git a/modules/gridmap/SCsub b/modules/gridmap/SCsub index da3f7d4dd9..282d772592 100644 --- a/modules/gridmap/SCsub +++ b/modules/gridmap/SCsub @@ -7,5 +7,5 @@ env_gridmap = env_modules.Clone() # Godot source files env_gridmap.add_source_files(env.modules_sources, "*.cpp") -if env["tools"]: +if env.editor_build: env_gridmap.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 6717f23057..686ba4dad6 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -25,12 +25,14 @@ <method name="clear_baked_meshes"> <return type="void" /> <description> + Clears all baked meshes. See [method make_baked_meshes]. </description> </method> <method name="get_bake_mesh_instance"> <return type="RID" /> <param index="0" name="idx" type="int" /> <description> + Returns [RID] of a baked mesh with the given [param idx]. </description> </method> <method name="get_bake_meshes"> @@ -57,7 +59,7 @@ <return type="Basis" /> <param index="0" name="position" type="Vector3i" /> <description> - Returns the basis that gives the specificed cell its orientation. + Returns the basis that gives the specified cell its orientation. </description> </method> <method name="get_cell_item_orientation" qualifiers="const"> @@ -84,7 +86,7 @@ <method name="get_meshes" qualifiers="const"> <return type="Array" /> <description> - Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space. + Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in local space. </description> </method> <method name="get_navigation_layer_value" qualifiers="const"> @@ -94,6 +96,13 @@ Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32. </description> </method> + <method name="get_navigation_map" qualifiers="const"> + <return type="RID" /> + <description> + Returns the [RID] of the navigation map this GridMap node uses for its cell baked navigation meshes. + This function returns always the map set on the GridMap node and not the map on the NavigationServer. If the map is changed directly with the NavigationServer API the GridMap node will not be aware of the map change. + </description> + </method> <method name="get_orthogonal_index_from_basis" qualifiers="const"> <return type="int" /> <param index="0" name="basis" type="Basis" /> @@ -114,24 +123,33 @@ Returns an array of all cells with the given item index specified in [code]item[/code]. </description> </method> + <method name="local_to_map" qualifiers="const"> + <return type="Vector3i" /> + <param index="0" name="local_position" type="Vector3" /> + <description> + Returns the map coordinates of the cell containing the given [param local_position]. If [param local_position] is in global coordinates, consider using [method Node3D.to_local] before passing it to this method. See also [method map_to_local]. + </description> + </method> <method name="make_baked_meshes"> <return type="void" /> <param index="0" name="gen_lightmap_uv" type="bool" default="false" /> <param index="1" name="lightmap_uv_texel_size" type="float" default="0.1" /> <description> + Bakes lightmap data for all meshes in the assigned [MeshLibrary]. </description> </method> - <method name="map_to_world" qualifiers="const"> + <method name="map_to_local" qualifiers="const"> <return type="Vector3" /> <param index="0" name="map_position" type="Vector3i" /> <description> - Returns the position of a grid cell in the GridMap's local coordinate space. + Returns the position of a grid cell in the GridMap's local coordinate space. To convert the returned value into global coordinates, use [method Node3D.to_global]. See also [method map_to_local]. </description> </method> <method name="resource_changed"> <return type="void" /> <param index="0" name="resource" type="Resource" /> <description> + Notifies the [GridMap] about changed resource and recreates octant data. </description> </method> <method name="set_cell_item"> @@ -169,12 +187,11 @@ Based on [code]value[/code], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [code]layer_number[/code] between 1 and 32. </description> </method> - <method name="world_to_map" qualifiers="const"> - <return type="Vector3i" /> - <param index="0" name="world_position" type="Vector3" /> + <method name="set_navigation_map"> + <return type="void" /> + <param index="0" name="navigation_map" type="RID" /> <description> - Returns the coordinates of the grid cell containing the given point. - [code]pos[/code] should be in the GridMap's local coordinate space. + Sets the [RID] of the navigation map this GridMap node should use for its cell baked navigation meshes. </description> </method> </methods> @@ -209,6 +226,9 @@ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> The physics layers this GridMap detects collisions in. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> + <member name="collision_priority" type="float" setter="set_collision_priority" getter="get_collision_priority" default="1.0"> + The priority used to solve colliding when occurring penetration. The higher the priority is, the lower the penetration into the object will be. This can for example be used to prevent the player from breaking through the boundaries of a level. + </member> <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library"> The assigned [MeshLibrary]. </member> diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 17f9832096..89ef9ddd90 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -40,6 +40,8 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/camera_3d.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/separator.h" #include "scene/main/window.h" void GridMapEditor::_node_removed(Node *p_node) { @@ -459,6 +461,7 @@ void GridMapEditor::_delete_selection() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("GridMap Delete Selection")); for (int i = selection.begin.x; i <= selection.end.x; i++) { for (int j = selection.begin.y; j <= selection.end.y; j++) { @@ -479,6 +482,7 @@ void GridMapEditor::_fill_selection() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("GridMap Fill Selection")); for (int i = selection.begin.x; i <= selection.end.x; i++) { for (int j = selection.begin.y; j <= selection.end.y; j++) { @@ -572,6 +576,7 @@ void GridMapEditor::_do_paste() { rot = node->get_basis_with_orthogonal_index(paste_indicator.orientation); Vector3 ofs = paste_indicator.current - paste_indicator.click; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("GridMap Paste Selection")); for (const ClipboardItem &item : clipboard_items) { @@ -603,13 +608,13 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::WHEEL_UP && (mb->is_command_pressed() || mb->is_shift_pressed())) { + if (mb->get_button_index() == MouseButton::WHEEL_UP && (mb->is_command_or_control_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() + mb->get_factor()); } return EditorPlugin::AFTER_GUI_INPUT_STOP; // Eaten. - } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) { + } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN && (mb->is_command_or_control_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() - mb->get_factor()); } @@ -617,7 +622,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } if (mb->is_pressed()) { - Node3DEditorViewport::NavigationScheme nav_scheme = (Node3DEditorViewport::NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + Node3DEditorViewport::NavigationScheme nav_scheme = (Node3DEditorViewport::NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->is_alt_pressed()) { input_action = INPUT_NONE; } else if (mb->get_button_index() == MouseButton::LEFT) { @@ -629,7 +634,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } else if (mb->is_shift_pressed() && can_edit) { input_action = INPUT_SELECT; last_selection = selection; - } else if (mb->is_command_pressed() && can_edit) { + } else if (mb->is_command_or_control_pressed() && can_edit) { input_action = INPUT_PICK; } else { input_action = INPUT_PAINT; @@ -659,6 +664,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } else { if ((mb->get_button_index() == MouseButton::RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_PAINT)) { if (set_items.size()) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("GridMap Paint")); for (const SetItem &si : set_items) { undo_redo->add_do_method(node, "set_cell_item", si.position, si.new_value, si.new_orientation); @@ -680,6 +686,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } if (mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_SELECT) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("GridMap Selection")); undo_redo->add_do_method(this, "_set_selection", selection.active, selection.begin, selection.end); undo_redo->add_undo_method(this, "_set_selection", last_selection.active, last_selection.begin, last_selection.end); @@ -746,7 +753,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { - if (pan_gesture->is_alt_pressed() && (pan_gesture->is_command_pressed() || pan_gesture->is_shift_pressed())) { + if (pan_gesture->is_alt_pressed() && (pan_gesture->is_command_or_control_pressed() || pan_gesture->is_shift_pressed())) { const real_t delta = pan_gesture->get_delta().y * 0.5; accumulated_floor_delta += delta; int step = 0; @@ -807,7 +814,7 @@ void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) { const Ref<InputEventMouseButton> mb = p_ie; // Zoom in/out using Ctrl + mouse wheel - if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed()) { + if (mb.is_valid() && mb->is_pressed() && mb->is_command_or_control_pressed()) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { size_slider->set_value(size_slider->get_value() + 0.2); } @@ -1142,8 +1149,6 @@ void GridMapEditor::_bind_methods() { } GridMapEditor::GridMapEditor() { - undo_redo = EditorNode::get_singleton()->get_undo_redo(); - int mw = EDITOR_DEF("editors/grid_map/palette_min_width", 230); Control *ec = memnew(Control); ec->set_custom_minimum_size(Size2(mw, 0) * EDSCALE); @@ -1434,7 +1439,7 @@ GridMapEditor::~GridMapEditor() { void GridMapEditorPlugin::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - switch ((int)EditorSettings::get_singleton()->get("editors/grid_map/editor_side")) { + switch ((int)EDITOR_GET("editors/grid_map/editor_side")) { case 0: { // Left. Node3DEditor::get_singleton()->move_control_to_left_panel(grid_map_editor); } break; @@ -1472,7 +1477,7 @@ GridMapEditorPlugin::GridMapEditorPlugin() { EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/grid_map/editor_side", PROPERTY_HINT_ENUM, "Left,Right")); grid_map_editor = memnew(GridMapEditor); - switch ((int)EditorSettings::get_singleton()->get("editors/grid_map/editor_side")) { + switch ((int)EDITOR_GET("editors/grid_map/editor_side")) { case 0: { // Left. Node3DEditor::get_singleton()->add_control_to_left_panel(grid_map_editor); } break; diff --git a/modules/gridmap/editor/grid_map_editor_plugin.h b/modules/gridmap/editor/grid_map_editor_plugin.h index a64dc4a80b..1cf2e4cb89 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.h +++ b/modules/gridmap/editor/grid_map_editor_plugin.h @@ -35,11 +35,13 @@ #include "../grid_map.h" #include "editor/editor_plugin.h" +#include "scene/gui/box_container.h" #include "scene/gui/item_list.h" #include "scene/gui/slider.h" #include "scene/gui/spin_box.h" -class EditorUndoRedoManager; +class ConfirmationDialog; +class MenuButton; class Node3DEditorPlugin; class GridMapEditor : public VBoxContainer { @@ -63,7 +65,6 @@ class GridMapEditor : public VBoxContainer { DISPLAY_LIST }; - Ref<EditorUndoRedoManager> undo_redo; InputAction input_action = INPUT_NONE; Panel *panel = nullptr; MenuButton *options = nullptr; @@ -241,7 +242,7 @@ protected: void _notification(int p_what); public: - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } virtual String get_name() const override { return "GridMap"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 8486e2c58b..e594153058 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -138,7 +138,7 @@ void GridMap::_get_property_list(List<PropertyInfo> *p_list) const { void GridMap::set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; - _reset_physic_bodies_collision_filters(); + _update_physics_bodies_collision_properties(); } uint32_t GridMap::get_collision_layer() const { @@ -147,7 +147,7 @@ uint32_t GridMap::get_collision_layer() const { void GridMap::set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; - _reset_physic_bodies_collision_filters(); + _update_physics_bodies_collision_properties(); } uint32_t GridMap::get_collision_mask() const { @@ -157,13 +157,13 @@ uint32_t GridMap::get_collision_mask() const { void GridMap::set_collision_layer_value(int p_layer_number, bool p_value) { ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); - uint32_t collision_layer = get_collision_layer(); + uint32_t collision_layer_new = get_collision_layer(); if (p_value) { - collision_layer |= 1 << (p_layer_number - 1); + collision_layer_new |= 1 << (p_layer_number - 1); } else { - collision_layer &= ~(1 << (p_layer_number - 1)); + collision_layer_new &= ~(1 << (p_layer_number - 1)); } - set_collision_layer(collision_layer); + set_collision_layer(collision_layer_new); } bool GridMap::get_collision_layer_value(int p_layer_number) const { @@ -184,6 +184,15 @@ void GridMap::set_collision_mask_value(int p_layer_number, bool p_value) { set_collision_mask(mask); } +void GridMap::set_collision_priority(real_t p_priority) { + collision_priority = p_priority; + _update_physics_bodies_collision_properties(); +} + +real_t GridMap::get_collision_priority() const { + return collision_priority; +} + void GridMap::set_physics_material(Ref<PhysicsMaterial> p_material) { physics_material = p_material; _recreate_octant_data(); @@ -226,6 +235,27 @@ bool GridMap::is_baking_navigation() { return bake_navigation; } +void GridMap::set_navigation_map(RID p_navigation_map) { + map_override = p_navigation_map; + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + Octant &g = *octant_map[E.key]; + for (KeyValue<IndexKey, Octant::NavigationCell> &F : g.navigation_cell_ids) { + if (F.value.region.is_valid()) { + NavigationServer3D::get_singleton()->region_set_map(F.value.region, map_override); + } + } + } +} + +RID GridMap::get_navigation_map() const { + if (map_override.is_valid()) { + return map_override; + } else if (is_inside_tree()) { + return get_world_3d()->get_navigation_map(); + } + return RID(); +} + void GridMap::set_navigation_layers(uint32_t p_navigation_layers) { navigation_layers = p_navigation_layers; _recreate_octant_data(); @@ -364,6 +394,7 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) { PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id()); PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer); PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask); + PhysicsServer3D::get_singleton()->body_set_collision_priority(g->static_body, collision_priority); if (physics_material.is_valid()) { PhysicsServer3D::get_singleton()->body_set_param(g->static_body, PhysicsServer3D::BODY_PARAM_FRICTION, physics_material->get_friction()); PhysicsServer3D::get_singleton()->body_set_param(g->static_body, PhysicsServer3D::BODY_PARAM_BOUNCE, physics_material->get_bounce()); @@ -497,18 +528,18 @@ int GridMap::get_orthogonal_index_from_basis(const Basis &p_basis) const { return 0; } -Vector3i GridMap::world_to_map(const Vector3 &p_world_position) const { +Vector3i GridMap::local_to_map(const Vector3 &p_world_position) const { Vector3 map_position = (p_world_position / cell_size).floor(); return Vector3i(map_position); } -Vector3 GridMap::map_to_world(const Vector3i &p_map_position) const { +Vector3 GridMap::map_to_local(const Vector3i &p_map_position) const { Vector3 offset = _get_offset(); - Vector3 world_pos( + Vector3 local_position( p_map_position.x * cell_size.x + offset.x, p_map_position.y * cell_size.y + offset.y, p_map_position.z * cell_size.z + offset.z); - return world_pos; + return local_position; } void GridMap::_octant_transform(const OctantKey &p_key) { @@ -521,13 +552,13 @@ void GridMap::_octant_transform(const OctantKey &p_key) { } // update transform for NavigationServer regions and navigation debugmesh instances - for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { + for (const KeyValue<IndexKey, Octant::NavigationCell> &E : g.navigation_cell_ids) { if (bake_navigation) { if (E.value.region.is_valid()) { NavigationServer3D::get_singleton()->region_set_transform(E.value.region, get_global_transform() * E.value.xform); } - if (E.value.navmesh_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_transform(E.value.navmesh_debug_instance, get_global_transform() * E.value.xform); + if (E.value.navigation_mesh_debug_instance.is_valid()) { + RS::get_singleton()->instance_set_transform(E.value.navigation_mesh_debug_instance, get_global_transform() * E.value.xform); } } } @@ -553,13 +584,13 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } //erase navigation - for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { + for (const KeyValue<IndexKey, Octant::NavigationCell> &E : g.navigation_cell_ids) { NavigationServer3D::get_singleton()->free(E.value.region); - if (E.value.navmesh_debug_instance.is_valid()) { - RS::get_singleton()->free(E.value.navmesh_debug_instance); + if (E.value.navigation_mesh_debug_instance.is_valid()) { + RS::get_singleton()->free(E.value.navigation_mesh_debug_instance); } } - g.navmesh_ids.clear(); + g.navigation_cell_ids.clear(); //erase multimeshes @@ -627,39 +658,44 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } } - // add the item's navmesh at given xform to GridMap's Navigation ancestor - Ref<NavigationMesh> navmesh = mesh_library->get_item_navmesh(c.item); - if (navmesh.is_valid()) { - Octant::NavMesh nm; - nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item); + // add the item's navigation_mesh at given xform to GridMap's Navigation ancestor + Ref<NavigationMesh> navigation_mesh = mesh_library->get_item_navigation_mesh(c.item); + if (navigation_mesh.is_valid()) { + Octant::NavigationCell nm; + nm.xform = xform * mesh_library->get_item_navigation_mesh_transform(c.item); if (bake_navigation) { RID region = NavigationServer3D::get_singleton()->region_create(); + NavigationServer3D::get_singleton()->region_set_owner_id(region, get_instance_id()); NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers); - NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh); + NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, navigation_mesh); NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * nm.xform); if (is_inside_tree()) { - NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + if (map_override.is_valid()) { + NavigationServer3D::get_singleton()->region_set_map(region, map_override); + } else { + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + } } nm.region = region; +#ifdef DEBUG_ENABLED // add navigation debugmesh visual instances if debug is enabled SceneTree *st = SceneTree::get_singleton(); if (st && st->is_debugging_navigation_hint()) { - if (!nm.navmesh_debug_instance.is_valid()) { - RID navmesh_debug_rid = navmesh->get_debug_mesh()->get_rid(); - nm.navmesh_debug_instance = RS::get_singleton()->instance_create(); - RS::get_singleton()->instance_set_base(nm.navmesh_debug_instance, navmesh_debug_rid); - RS::get_singleton()->mesh_surface_set_material(navmesh_debug_rid, 0, st->get_debug_navigation_material()->get_rid()); + if (!nm.navigation_mesh_debug_instance.is_valid()) { + RID navigation_mesh_debug_rid = navigation_mesh->get_debug_mesh()->get_rid(); + nm.navigation_mesh_debug_instance = RS::get_singleton()->instance_create(); + RS::get_singleton()->instance_set_base(nm.navigation_mesh_debug_instance, navigation_mesh_debug_rid); } if (is_inside_tree()) { - RS::get_singleton()->instance_set_scenario(nm.navmesh_debug_instance, get_world_3d()->get_scenario()); - RS::get_singleton()->instance_set_transform(nm.navmesh_debug_instance, get_global_transform() * nm.xform); + RS::get_singleton()->instance_set_scenario(nm.navigation_mesh_debug_instance, get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_transform(nm.navigation_mesh_debug_instance, get_global_transform() * nm.xform); } } +#endif // DEBUG_ENABLED } - - g.navmesh_ids[E] = nm; + g.navigation_cell_ids[E] = nm; } } @@ -725,10 +761,11 @@ bool GridMap::_octant_update(const OctantKey &p_key) { return false; } -void GridMap::_reset_physic_bodies_collision_filters() { +void GridMap::_update_physics_bodies_collision_properties() { for (const KeyValue<OctantKey, Octant *> &E : octant_map) { PhysicsServer3D::get_singleton()->body_set_collision_layer(E.value->static_body, collision_layer); PhysicsServer3D::get_singleton()->body_set_collision_mask(E.value->static_body, collision_mask); + PhysicsServer3D::get_singleton()->body_set_collision_priority(E.value->static_body, collision_priority); } } @@ -749,15 +786,20 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { } if (bake_navigation && mesh_library.is_valid()) { - for (KeyValue<IndexKey, Octant::NavMesh> &F : g.navmesh_ids) { + for (KeyValue<IndexKey, Octant::NavigationCell> &F : g.navigation_cell_ids) { if (cell_map.has(F.key) && F.value.region.is_valid() == false) { - Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F.key].item); - if (nm.is_valid()) { + Ref<NavigationMesh> navigation_mesh = mesh_library->get_item_navigation_mesh(cell_map[F.key].item); + if (navigation_mesh.is_valid()) { RID region = NavigationServer3D::get_singleton()->region_create(); + NavigationServer3D::get_singleton()->region_set_owner_id(region, get_instance_id()); NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers); - NavigationServer3D::get_singleton()->region_set_navmesh(region, nm); + NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, navigation_mesh); NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F.value.xform); - NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + if (map_override.is_valid()) { + NavigationServer3D::get_singleton()->region_set_map(region, map_override); + } else { + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + } F.value.region = region; } @@ -793,14 +835,14 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID()); } - for (KeyValue<IndexKey, Octant::NavMesh> &F : g.navmesh_ids) { + for (KeyValue<IndexKey, Octant::NavigationCell> &F : g.navigation_cell_ids) { if (F.value.region.is_valid()) { NavigationServer3D::get_singleton()->free(F.value.region); F.value.region = RID(); } - if (F.value.navmesh_debug_instance.is_valid()) { - RS::get_singleton()->free(F.value.navmesh_debug_instance); - F.value.navmesh_debug_instance = RID(); + if (F.value.navigation_mesh_debug_instance.is_valid()) { + RS::get_singleton()->free(F.value.navigation_mesh_debug_instance); + F.value.navigation_mesh_debug_instance = RID(); } } @@ -831,15 +873,15 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { PhysicsServer3D::get_singleton()->free(g.static_body); // Erase navigation - for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { + for (const KeyValue<IndexKey, Octant::NavigationCell> &E : g.navigation_cell_ids) { if (E.value.region.is_valid()) { NavigationServer3D::get_singleton()->free(E.value.region); } - if (E.value.navmesh_debug_instance.is_valid()) { - RS::get_singleton()->free(E.value.navmesh_debug_instance); + if (E.value.navigation_mesh_debug_instance.is_valid()) { + RS::get_singleton()->free(E.value.navigation_mesh_debug_instance); } } - g.navmesh_ids.clear(); + g.navigation_cell_ids.clear(); #ifdef DEBUG_ENABLED if (bake_navigation) { @@ -1016,12 +1058,18 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &GridMap::set_collision_layer_value); ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &GridMap::get_collision_layer_value); + ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &GridMap::set_collision_priority); + ClassDB::bind_method(D_METHOD("get_collision_priority"), &GridMap::get_collision_priority); + ClassDB::bind_method(D_METHOD("set_physics_material", "material"), &GridMap::set_physics_material); ClassDB::bind_method(D_METHOD("get_physics_material"), &GridMap::get_physics_material); ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation); ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation); + ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &GridMap::set_navigation_map); + ClassDB::bind_method(D_METHOD("get_navigation_map"), &GridMap::get_navigation_map); + ClassDB::bind_method(D_METHOD("set_navigation_layers", "layers"), &GridMap::set_navigation_layers); ClassDB::bind_method(D_METHOD("get_navigation_layers"), &GridMap::get_navigation_layers); @@ -1047,8 +1095,8 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("get_basis_with_orthogonal_index", "index"), &GridMap::get_basis_with_orthogonal_index); ClassDB::bind_method(D_METHOD("get_orthogonal_index_from_basis", "basis"), &GridMap::get_orthogonal_index_from_basis); - ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &GridMap::world_to_map); - ClassDB::bind_method(D_METHOD("map_to_world", "map_position"), &GridMap::map_to_world); + ClassDB::bind_method(D_METHOD("local_to_map", "local_position"), &GridMap::local_to_map); + ClassDB::bind_method(D_METHOD("map_to_local", "map_position"), &GridMap::map_to_local); ClassDB::bind_method(D_METHOD("_update_octants_callback"), &GridMap::_update_octants_callback); ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &GridMap::resource_changed); @@ -1084,6 +1132,7 @@ void GridMap::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority"); ADD_GROUP("Navigation", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); @@ -1117,7 +1166,7 @@ TypedArray<Vector3i> GridMap::get_used_cells() const { TypedArray<Vector3i> GridMap::get_used_cells_by_item(int p_item) const { TypedArray<Vector3i> a; for (const KeyValue<IndexKey, Cell> &E : cell_map) { - if (E.value.item == p_item) { + if ((int)E.value.item == p_item) { Vector3i p(E.key.x, E.key.y, E.key.z); a.push_back(p); } @@ -1356,7 +1405,7 @@ void GridMap::_update_octant_navigation_debug_edge_connections_mesh(const Octant Vector<Vector3> vertex_array; - for (KeyValue<IndexKey, Octant::NavMesh> &F : g.navmesh_ids) { + for (KeyValue<IndexKey, Octant::NavigationCell> &F : g.navigation_cell_ids) { if (cell_map.has(F.key) && F.value.region.is_valid()) { int connections_count = NavigationServer3D::get_singleton()->region_get_connections_count(F.value.region); if (connections_count == 0) { diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index f83ce68b09..59d2936f2c 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -95,10 +95,10 @@ class GridMap : public Node3D { * A GridMap can have multiple Octants. */ struct Octant { - struct NavMesh { + struct NavigationCell { RID region; Transform3D xform; - RID navmesh_debug_instance; + RID navigation_mesh_debug_instance; }; struct MultimeshInstance { @@ -124,7 +124,7 @@ class GridMap : public Node3D { bool dirty = false; RID static_body; - HashMap<IndexKey, NavMesh> navmesh_ids; + HashMap<IndexKey, NavigationCell> navigation_cell_ids; }; union OctantKey { @@ -150,8 +150,10 @@ class GridMap : public Node3D { uint32_t collision_layer = 1; uint32_t collision_mask = 1; + real_t collision_priority = 1.0; Ref<PhysicsMaterial> physics_material; bool bake_navigation = false; + RID map_override; uint32_t navigation_layers = 1; Transform3D last_transform; @@ -184,7 +186,7 @@ class GridMap : public Node3D { return Vector3(p_key.x, p_key.y, p_key.z) * cell_size * octant_size; } - void _reset_physic_bodies_collision_filters(); + void _update_physics_bodies_collision_properties(); void _octant_enter_world(const OctantKey &p_key); void _octant_exit_world(const OctantKey &p_key); bool _octant_update(const OctantKey &p_key); @@ -239,6 +241,9 @@ public: void set_collision_mask_value(int p_layer_number, bool p_value); bool get_collision_mask_value(int p_layer_number) const; + void set_collision_priority(real_t p_priority); + real_t get_collision_priority() const; + void set_physics_material(Ref<PhysicsMaterial> p_material); Ref<PhysicsMaterial> get_physics_material() const; @@ -247,6 +252,9 @@ public: void set_bake_navigation(bool p_bake_navigation); bool is_baking_navigation(); + void set_navigation_map(RID p_navigation_map); + RID get_navigation_map() const; + void set_navigation_layers(uint32_t p_navigation_layers); uint32_t get_navigation_layers() const; @@ -276,8 +284,8 @@ public: Basis get_basis_with_orthogonal_index(int p_index) const; int get_orthogonal_index_from_basis(const Basis &p_basis) const; - Vector3i world_to_map(const Vector3 &p_world_position) const; - Vector3 map_to_world(const Vector3i &p_map_position) const; + Vector3i local_to_map(const Vector3 &p_local_position) const; + Vector3 map_to_local(const Vector3i &p_map_position) const; void set_cell_scale(float p_scale); float get_cell_scale() const; |