diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/navigation_server_2d.cpp | 15 | ||||
-rw-r--r-- | servers/navigation_server_2d.h | 9 | ||||
-rw-r--r-- | servers/navigation_server_3d.cpp | 7 | ||||
-rw-r--r-- | servers/navigation_server_3d.h | 9 | ||||
-rw-r--r-- | servers/physics_3d/collision_solver_3d_sat.cpp | 45 | ||||
-rw-r--r-- | servers/rendering/rendering_server_default.h | 2 |
6 files changed, 82 insertions, 5 deletions
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index fee74f3dbc..7e579c36f4 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -156,6 +156,10 @@ static Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) { } } +void NavigationServer2D::_emit_map_changed(RID p_map) { + emit_signal("map_changed", p_map); +} + void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_create"), &NavigationServer2D::map_create); ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &NavigationServer2D::map_set_active); @@ -174,6 +178,9 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer2D::region_get_layers); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer2D::region_set_transform); ClassDB::bind_method(D_METHOD("region_set_navpoly", "region", "nav_poly"), &NavigationServer2D::region_set_navpoly); + ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &NavigationServer2D::region_get_connections_count); + ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_start); + ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_end); ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer2D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer2D::agent_set_map); @@ -189,10 +196,14 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "receiver", "method", "userdata"), &NavigationServer2D::agent_set_callback, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("free", "object"), &NavigationServer2D::free); + + ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); } NavigationServer2D::NavigationServer2D() { singleton = this; + ERR_FAIL_COND_MSG(!NavigationServer3D::get_singleton(), "The Navigation3D singleton should be initialized before the 2D one."); + NavigationServer3D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationServer2D::_emit_map_changed)); } NavigationServer2D::~NavigationServer2D() { @@ -226,6 +237,10 @@ void NavigationServer2D::region_set_navpoly(RID p_region, Ref<NavigationPolygon> NavigationServer3D::get_singleton()->region_set_navmesh(p_region, poly_to_mesh(p_nav_mesh)); } +int FORWARD_1_C(region_get_connections_count, RID, p_region, rid_to_rid); +Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_start, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int); +Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_end, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int); + RID NavigationServer2D::agent_create() const { RID agent = NavigationServer3D::get_singleton()->agent_create(); NavigationServer3D::get_singleton()->agent_set_ignore_y(agent, true); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 46c8f6a71d..d56c719839 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -45,12 +45,14 @@ class NavigationServer2D : public Object { static NavigationServer2D *singleton; + void _emit_map_changed(RID p_map); + protected: static void _bind_methods(); public: /// Thread safe, can be used across many threads. - static const NavigationServer2D *get_singleton() { return singleton; } + static NavigationServer2D *get_singleton() { return singleton; } /// MUST be used in single thread! static NavigationServer2D *get_singleton_mut() { return singleton; } @@ -98,6 +100,11 @@ public: /// Set the navigation poly of this region. virtual void region_set_navpoly(RID p_region, Ref<NavigationPolygon> p_nav_mesh) const; + /// Get a list of a region's connection to other regions. + virtual int region_get_connections_count(RID p_region) const; + virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const; + virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const; + /// Creates the agent. virtual RID agent_create() const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index d81ce70af6..b0047a250a 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -59,6 +59,9 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer3D::region_set_transform); ClassDB::bind_method(D_METHOD("region_set_navmesh", "region", "nav_mesh"), &NavigationServer3D::region_set_navmesh); ClassDB::bind_method(D_METHOD("region_bake_navmesh", "mesh", "node"), &NavigationServer3D::region_bake_navmesh); + ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &NavigationServer3D::region_get_connections_count); + ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer3D::region_get_connection_pathway_start); + ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer3D::region_get_connection_pathway_end); ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer3D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer3D::agent_set_map); @@ -77,9 +80,11 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer3D::set_active); ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer3D::process); + + ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); } -const NavigationServer3D *NavigationServer3D::get_singleton() { +NavigationServer3D *NavigationServer3D::get_singleton() { return singleton; } diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index beed19d563..420f9c9c18 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -55,7 +55,7 @@ protected: public: /// Thread safe, can be used across many threads. - static const NavigationServer3D *get_singleton(); + static NavigationServer3D *get_singleton(); /// MUST be used in single thread! static NavigationServer3D *get_singleton_mut(); @@ -111,9 +111,14 @@ public: /// Set the navigation mesh of this region. virtual void region_set_navmesh(RID p_region, Ref<NavigationMesh> p_nav_mesh) const = 0; - /// Bake the navigation mesh + /// Bake the navigation mesh. virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const = 0; + /// Get a list of a region's connection to other regions. + virtual int region_get_connections_count(RID p_region) const = 0; + virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0; + virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0; + /// Creates the agent. virtual RID agent_create() const = 0; diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index 5c77fa2847..33075a38be 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -1627,6 +1627,51 @@ static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin> separator(capsule_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + if (!separator.test_previous_axis()) { + return; + } + + // Cylinder B end caps. + Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1).normalized(); + if (!separator.test_axis(cylinder_B_axis)) { + return; + } + + // Cylinder edge against capsule balls. + + Vector3 capsule_A_axis = p_transform_a.basis.get_axis(1); + + Vector3 capsule_A_ball_1 = p_transform_a.origin + capsule_A_axis * (capsule_A->get_height() * 0.5); + Vector3 capsule_A_ball_2 = p_transform_a.origin - capsule_A_axis * (capsule_A->get_height() * 0.5); + + if (!separator.test_axis((p_transform_b.origin - capsule_A_ball_1).cross(cylinder_B_axis).cross(cylinder_B_axis).normalized())) { + return; + } + + if (!separator.test_axis((p_transform_b.origin - capsule_A_ball_2).cross(cylinder_B_axis).cross(cylinder_B_axis).normalized())) { + return; + } + + // Cylinder edge against capsule edge. + + Vector3 center_diff = p_transform_b.origin - p_transform_a.origin; + + if (!separator.test_axis(capsule_A_axis.cross(center_diff).cross(capsule_A_axis).normalized())) { + return; + } + + if (!separator.test_axis(cylinder_B_axis.cross(center_diff).cross(cylinder_B_axis).normalized())) { + return; + } + + real_t proj = capsule_A_axis.cross(cylinder_B_axis).cross(cylinder_B_axis).dot(capsule_A_axis); + if (Math::is_zero_approx(proj)) { + // Parallel capsule and cylinder axes, handle with specific axes only. + // Note: GJKEPA with no margin can lead to degenerate cases in this situation. + separator.generate_contacts(); + return; + } + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; // Fallback to generic algorithm to find the best separating axis. diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index c6be07a3de..e82d5cc3f8 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -233,7 +233,7 @@ public: FUNC2(shader_set_code, RID, const String &) FUNC1RC(String, shader_get_code, RID) - FUNC2C(shader_get_param_list, RID, List<PropertyInfo> *) + FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *) FUNC3(shader_set_default_texture_param, RID, const StringName &, RID) FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &) |