diff --git a/modules/navigation/3d/nav_mesh_generator_3d.cpp b/modules/navigation/3d/nav_mesh_generator_3d.cpp index e92a9d304b0a..f1dd3876b2d8 100644 --- a/modules/navigation/3d/nav_mesh_generator_3d.cpp +++ b/modules/navigation/3d/nav_mesh_generator_3d.cpp @@ -34,6 +34,7 @@ #include "core/config/project_settings.h" #include "core/math/convex_hull.h" +#include "core/math/vector3.h" #include "core/os/thread.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" @@ -595,7 +596,12 @@ void NavMeshGenerator3D::generator_parse_navigationobstacle_node(const Refroot_node_transform * Transform3D(Basis(), obstacle->get_global_position()); + // Obstacles are projected to the xz-plane, so only rotation around the y-axis can be taken into account. + Transform3D node_xform; + node_xform.origin = obstacle->get_global_position(); + node_xform.scale_basis(obstacle->get_global_basis().get_scale()); + node_xform.rotate_basis(Vector3(0.0, 1.0, 0.0), obstacle->get_global_rotation().y); + node_xform = p_source_geometry_data->root_node_transform * node_xform; const float obstacle_radius = obstacle->get_radius(); @@ -635,7 +641,7 @@ void NavMeshGenerator3D::generator_parse_navigationobstacle_node(const Refadd_projected_obstruction(obstruction_shape_vertices, obstacle->get_global_position().y + p_source_geometry_data->root_node_transform.origin.y, obstacle->get_height(), obstacle->get_carve_navigation_mesh()); + p_source_geometry_data->add_projected_obstruction(obstruction_shape_vertices, obstacle->get_global_position().y + p_source_geometry_data->root_node_transform.origin.y, obstacle->get_global_basis().get_scale().y * obstacle->get_height(), obstacle->get_carve_navigation_mesh()); } void NavMeshGenerator3D::generator_parse_source_geometry_data(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_root_node) { diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index f2ac8f789c9c..a5076c1e31c6 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -31,6 +31,8 @@ #include "navigation_obstacle_3d.h" #include "core/math/geometry_2d.h" +#include "core/math/transform_3d.h" +#include "core/math/vector3.h" #include "servers/navigation_server_3d.h" void NavigationObstacle3D::_bind_methods() { @@ -173,8 +175,11 @@ void NavigationObstacle3D::_notification(int p_what) { RS::get_singleton()->instance_set_transform(fake_agent_radius_debug_instance, debug_transform); } if (static_obstacle_debug_instance.is_valid() && get_vertices().size() > 0) { + // Obstacles are projected to the xz-plane, so only rotation around the y-axis can be taken into account. Transform3D debug_transform; debug_transform.origin = get_global_position(); + debug_transform.scale_basis(get_global_basis().get_scale()); + debug_transform.rotate_basis(Vector3(0.0, 1.0, 0.0), get_global_rotation().y); RS::get_singleton()->instance_set_transform(static_obstacle_debug_instance, debug_transform); } #endif // DEBUG_ENABLED @@ -346,6 +351,15 @@ bool NavigationObstacle3D::get_carve_navigation_mesh() const { return carve_navigation_mesh; } +PackedStringArray NavigationObstacle3D::get_configuration_warnings() const { + PackedStringArray warnings = Node::get_configuration_warnings(); + + if (get_global_rotation().x != 0.0 || get_global_rotation().z != 0.0) { + warnings.push_back(RTR("NavigationObstacle3D only takes global rotation around the y-axis into account. Rotations around the x-axis or z-axis might lead to unexpected results.")); + } + return warnings; +} + void NavigationObstacle3D::_update_map(RID p_map) { NavigationServer3D::get_singleton()->obstacle_set_map(obstacle, p_map); map_current = p_map; diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index e9a4669fa270..3cb9a4d280fb 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -117,6 +117,8 @@ class NavigationObstacle3D : public Node3D { void set_carve_navigation_mesh(bool p_enabled); bool get_carve_navigation_mesh() const; + PackedStringArray get_configuration_warnings() const override; + private: void _update_map(RID p_map); void _update_position(const Vector3 p_position);