diff options
Diffstat (limited to 'modules/navigation')
4 files changed, 102 insertions, 13 deletions
diff --git a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp index c243e3e6e3..5cdff7b52a 100644 --- a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp +++ b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp @@ -110,7 +110,7 @@ NavigationMeshEditor::NavigationMeshEditor() { button_reset->set_flat(true); bake_hbox->add_child(button_reset); // No button text, we only use a revert icon which is set when entering the tree. - button_reset->set_tooltip(TTR("Clear the navigation mesh.")); + button_reset->set_tooltip_text(TTR("Clear the navigation mesh.")); button_reset->connect("pressed", callable_mp(this, &NavigationMeshEditor::_clear_pressed)); bake_info = memnew(Label); diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index 2cdb5b7cb4..4191e46f62 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -123,8 +123,8 @@ void GodotNavigationServer::add_command(SetCommand *command) const { } } -Array GodotNavigationServer::get_maps() const { - Array all_map_rids; +TypedArray<RID> GodotNavigationServer::get_maps() const { + TypedArray<RID> all_map_rids; List<RID> maps_owned; map_owner.get_owned_list(&maps_owned); if (maps_owned.size()) { @@ -245,8 +245,8 @@ RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 return map->get_closest_point_owner(p_point); } -Array GodotNavigationServer::map_get_regions(RID p_map) const { - Array regions_rids; +TypedArray<RID> GodotNavigationServer::map_get_regions(RID p_map) const { + TypedArray<RID> regions_rids; const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, regions_rids); const LocalVector<NavRegion *> regions = map->get_regions(); @@ -257,8 +257,8 @@ Array GodotNavigationServer::map_get_regions(RID p_map) const { return regions_rids; } -Array GodotNavigationServer::map_get_agents(RID p_map) const { - Array agents_rids; +TypedArray<RID> GodotNavigationServer::map_get_agents(RID p_map) const { + TypedArray<RID> agents_rids; const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, agents_rids); const LocalVector<RvoAgent *> agents = map->get_agents(); @@ -453,11 +453,11 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { } } -COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist) { +COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance) { RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); - agent->get_agent()->neighborDist_ = p_dist; + agent->get_agent()->neighborDist_ = p_distance; } COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index da1f8cba0b..05ba46ede1 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -85,7 +85,7 @@ public: void add_command(SetCommand *command) const; - virtual Array get_maps() const override; + virtual TypedArray<RID> get_maps() const override; virtual RID map_create() const override; COMMAND_2(map_set_active, RID, p_map, bool, p_active); @@ -107,8 +107,8 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const override; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const override; - virtual Array map_get_regions(RID p_map) const override; - virtual Array map_get_agents(RID p_map) const override; + virtual TypedArray<RID> map_get_regions(RID p_map) const override; + virtual TypedArray<RID> map_get_agents(RID p_map) const override; virtual void map_force_update(RID p_map) override; @@ -135,7 +135,7 @@ public: virtual RID agent_create() const override; COMMAND_2(agent_set_map, RID, p_agent, RID, p_map); virtual RID agent_get_map(RID p_agent) const override; - COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist); + COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance); COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count); COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time); COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius); diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 6e8ac77f79..848e554fb0 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -42,6 +42,7 @@ #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" #include "scene/resources/cylinder_shape_3d.h" +#include "scene/resources/height_map_shape_3d.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/shape_3d.h" #include "scene/resources/sphere_shape_3d.h" @@ -275,6 +276,50 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans _add_faces(faces, transform, p_vertices, p_indices); } } + + HeightMapShape3D *heightmap_shape = Object::cast_to<HeightMapShape3D>(*s); + if (heightmap_shape) { + int heightmap_depth = heightmap_shape->get_map_depth(); + int heightmap_width = heightmap_shape->get_map_width(); + + if (heightmap_depth >= 2 && heightmap_width >= 2) { + const Vector<real_t> &map_data = heightmap_shape->get_map_data(); + + Vector2 heightmap_gridsize(heightmap_width - 1, heightmap_depth - 1); + Vector2 start = heightmap_gridsize * -0.5; + + Vector<Vector3> vertex_array; + vertex_array.resize((heightmap_depth - 1) * (heightmap_width - 1) * 6); + int map_data_current_index = 0; + + for (int d = 0; d < heightmap_depth - 1; d++) { + for (int w = 0; w < heightmap_width - 1; w++) { + if (map_data_current_index + 1 + heightmap_depth < map_data.size()) { + float top_left_height = map_data[map_data_current_index]; + float top_right_height = map_data[map_data_current_index + 1]; + float bottom_left_height = map_data[map_data_current_index + heightmap_depth]; + float bottom_right_height = map_data[map_data_current_index + 1 + heightmap_depth]; + + Vector3 top_left = Vector3(start.x + w, top_left_height, start.y + d); + Vector3 top_right = Vector3(start.x + w + 1.0, top_right_height, start.y + d); + Vector3 bottom_left = Vector3(start.x + w, bottom_left_height, start.y + d + 1.0); + Vector3 bottom_right = Vector3(start.x + w + 1.0, bottom_right_height, start.y + d + 1.0); + + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_left); + vertex_array.push_back(top_left); + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_right); + vertex_array.push_back(bottom_left); + } + map_data_current_index += 1; + } + } + if (vertex_array.size() > 0) { + _add_faces(vertex_array, transform, p_vertices, p_indices); + } + } + } } } } @@ -362,6 +407,50 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans PackedVector3Array faces = Variant(dict["faces"]); _add_faces(faces, shapes[i], p_vertices, p_indices); } break; + case PhysicsServer3D::SHAPE_HEIGHTMAP: { + Dictionary dict = data; + ///< dict( int:"width", int:"depth",float:"cell_size", float_array:"heights" + int heightmap_depth = dict["depth"]; + int heightmap_width = dict["width"]; + + if (heightmap_depth >= 2 && heightmap_width >= 2) { + const Vector<real_t> &map_data = dict["heights"]; + + Vector2 heightmap_gridsize(heightmap_width - 1, heightmap_depth - 1); + Vector2 start = heightmap_gridsize * -0.5; + + Vector<Vector3> vertex_array; + vertex_array.resize((heightmap_depth - 1) * (heightmap_width - 1) * 6); + int map_data_current_index = 0; + + for (int d = 0; d < heightmap_depth - 1; d++) { + for (int w = 0; w < heightmap_width - 1; w++) { + if (map_data_current_index + 1 + heightmap_depth < map_data.size()) { + float top_left_height = map_data[map_data_current_index]; + float top_right_height = map_data[map_data_current_index + 1]; + float bottom_left_height = map_data[map_data_current_index + heightmap_depth]; + float bottom_right_height = map_data[map_data_current_index + 1 + heightmap_depth]; + + Vector3 top_left = Vector3(start.x + w, top_left_height, start.y + d); + Vector3 top_right = Vector3(start.x + w + 1.0, top_right_height, start.y + d); + Vector3 bottom_left = Vector3(start.x + w, bottom_left_height, start.y + d + 1.0); + Vector3 bottom_right = Vector3(start.x + w + 1.0, bottom_right_height, start.y + d + 1.0); + + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_left); + vertex_array.push_back(top_left); + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_right); + vertex_array.push_back(bottom_left); + } + map_data_current_index += 1; + } + } + if (vertex_array.size() > 0) { + _add_faces(vertex_array, shapes[i], p_vertices, p_indices); + } + } + } break; default: { WARN_PRINT("Unsupported collision shape type."); } break; |