mirror of
https://github.com/godotengine/godot.git
synced 2025-04-19 01:27:45 +08:00
Merge pull request #101505 from smix8/region_bounds
Add functions to get axis-aligned bounds of navigation regions
This commit is contained in:
commit
a69ccee151
@ -23,6 +23,12 @@
|
||||
Bakes the [NavigationPolygon]. If [param on_thread] is set to [code]true[/code] (default), the baking is done on a separate thread.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_bounds" qualifiers="const">
|
||||
<return type="Rect2" />
|
||||
<description>
|
||||
Returns the axis-aligned rectangle for the region's transformed navigation mesh.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_navigation_layer_value" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="layer_number" type="int" />
|
||||
|
@ -23,6 +23,12 @@
|
||||
Bakes the [NavigationMesh]. If [param on_thread] is set to [code]true[/code] (default), the baking is done on a separate thread. Baking on separate thread is useful because navigation baking is not a cheap operation. When it is completed, it automatically sets the new [NavigationMesh]. Please note that baking on separate thread may be very slow if geometry is parsed from meshes as async access to each mesh involves heavy synchronization. Also, please note that baking on a separate thread is automatically disabled on operating systems that cannot use threads (such as Web with threads disabled).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_bounds" qualifiers="const">
|
||||
<return type="AABB" />
|
||||
<description>
|
||||
Returns the axis-aligned bounding box for the region's transformed navigation mesh.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_navigation_layer_value" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="layer_number" type="int" />
|
||||
|
@ -784,6 +784,13 @@
|
||||
Creates a new region.
|
||||
</description>
|
||||
</method>
|
||||
<method name="region_get_bounds" qualifiers="const">
|
||||
<return type="Rect2" />
|
||||
<param index="0" name="region" type="RID" />
|
||||
<description>
|
||||
Returns the axis-aligned rectangle for the [param region]'s transformed navigation mesh.
|
||||
</description>
|
||||
</method>
|
||||
<method name="region_get_closest_point" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<param index="0" name="region" type="RID" />
|
||||
|
@ -925,6 +925,13 @@
|
||||
Creates a new region.
|
||||
</description>
|
||||
</method>
|
||||
<method name="region_get_bounds" qualifiers="const">
|
||||
<return type="AABB" />
|
||||
<param index="0" name="region" type="RID" />
|
||||
<description>
|
||||
Returns the axis-aligned bounding box for the [param region]'s transformed navigation mesh.
|
||||
</description>
|
||||
</method>
|
||||
<method name="region_get_closest_point" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<param index="0" name="region" type="RID" />
|
||||
|
@ -158,6 +158,13 @@ static Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) {
|
||||
}
|
||||
}
|
||||
|
||||
static Rect2 aabb_to_rect2(AABB aabb) {
|
||||
Rect2 rect2;
|
||||
rect2.position = Vector2(aabb.position.x, aabb.position.z);
|
||||
rect2.size = Vector2(aabb.size.x, aabb.size.z);
|
||||
return rect2;
|
||||
}
|
||||
|
||||
void GodotNavigationServer2D::init() {
|
||||
#ifdef CLIPPER2_ENABLED
|
||||
navmesh_generator_2d = memnew(NavMeshGenerator2D);
|
||||
@ -332,6 +339,11 @@ Vector2 GodotNavigationServer2D::region_get_random_point(RID p_region, uint32_t
|
||||
return v3_to_v2(result);
|
||||
}
|
||||
|
||||
Rect2 GodotNavigationServer2D::region_get_bounds(RID p_region) const {
|
||||
AABB bounds = NavigationServer3D::get_singleton()->region_get_bounds(p_region);
|
||||
return aabb_to_rect2(bounds);
|
||||
}
|
||||
|
||||
RID FORWARD_0(link_create);
|
||||
|
||||
void FORWARD_2(link_set_map, RID, p_link, RID, p_map, rid_to_rid, rid_to_rid);
|
||||
|
@ -105,6 +105,7 @@ public:
|
||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const override;
|
||||
virtual Vector2 region_get_closest_point(RID p_region, const Vector2 &p_point) const override;
|
||||
virtual Vector2 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const override;
|
||||
virtual Rect2 region_get_bounds(RID p_region) const override;
|
||||
|
||||
virtual RID link_create() override;
|
||||
|
||||
|
@ -595,6 +595,13 @@ Vector3 GodotNavigationServer3D::region_get_random_point(RID p_region, uint32_t
|
||||
return region->get_random_point(p_navigation_layers, p_uniformly);
|
||||
}
|
||||
|
||||
AABB GodotNavigationServer3D::region_get_bounds(RID p_region) const {
|
||||
const NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, AABB());
|
||||
|
||||
return region->get_bounds();
|
||||
}
|
||||
|
||||
RID GodotNavigationServer3D::link_create() {
|
||||
MutexLock lock(operations_mutex);
|
||||
|
||||
|
@ -187,6 +187,7 @@ public:
|
||||
virtual Vector3 region_get_closest_point(RID p_region, const Vector3 &p_point) const override;
|
||||
virtual Vector3 region_get_closest_point_normal(RID p_region, const Vector3 &p_point) const override;
|
||||
virtual Vector3 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const override;
|
||||
virtual AABB region_get_bounds(RID p_region) const override;
|
||||
|
||||
virtual RID link_create() override;
|
||||
COMMAND_2(link_set_map, RID, p_link, RID, p_map);
|
||||
|
@ -200,6 +200,9 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_
|
||||
#ifdef DEBUG_ENABLED
|
||||
debug_mesh_dirty = true;
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
_update_bounds();
|
||||
|
||||
NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon);
|
||||
|
||||
if (navigation_polygon.is_valid()) {
|
||||
@ -341,6 +344,8 @@ void NavigationRegion2D::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_navigation_polygon_changed"), &NavigationRegion2D::_navigation_polygon_changed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_bounds"), &NavigationRegion2D::get_bounds);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navigation_polygon", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_edge_connections"), "set_use_edge_connections", "get_use_edge_connections");
|
||||
@ -648,3 +653,26 @@ void NavigationRegion2D::_set_debug_visible(bool p_visible) {
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
void NavigationRegion2D::_update_bounds() {
|
||||
if (navigation_polygon.is_null()) {
|
||||
bounds = Rect2();
|
||||
return;
|
||||
}
|
||||
|
||||
const Vector<Vector2> &vertices = navigation_polygon->get_vertices();
|
||||
if (vertices.is_empty()) {
|
||||
bounds = Rect2();
|
||||
return;
|
||||
}
|
||||
|
||||
const Transform2D gt = is_inside_tree() ? get_global_transform() : get_transform();
|
||||
|
||||
Rect2 new_bounds;
|
||||
new_bounds.position = gt.xform(vertices[0]);
|
||||
|
||||
for (const Vector2 &vertex : vertices) {
|
||||
new_bounds.expand_to(gt.xform(vertex));
|
||||
}
|
||||
bounds = new_bounds;
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ class NavigationRegion2D : public Node2D {
|
||||
|
||||
void _navigation_polygon_changed();
|
||||
|
||||
Rect2 bounds;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
private:
|
||||
RID debug_mesh_rid;
|
||||
@ -113,10 +115,13 @@ public:
|
||||
void _bake_finished(Ref<NavigationPolygon> p_navigation_polygon);
|
||||
bool is_baking() const;
|
||||
|
||||
Rect2 get_bounds() const { return bounds; }
|
||||
|
||||
NavigationRegion2D();
|
||||
~NavigationRegion2D();
|
||||
|
||||
private:
|
||||
void _update_bounds();
|
||||
void _region_enter_navigation_map();
|
||||
void _region_exit_navigation_map();
|
||||
void _region_update_transform();
|
||||
|
@ -193,6 +193,8 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_naviga
|
||||
navigation_mesh->connect_changed(callable_mp(this, &NavigationRegion3D::_navigation_mesh_changed));
|
||||
}
|
||||
|
||||
_update_bounds();
|
||||
|
||||
NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, p_navigation_mesh);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
@ -314,6 +316,8 @@ void NavigationRegion3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("bake_navigation_mesh", "on_thread"), &NavigationRegion3D::bake_navigation_mesh, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("is_baking"), &NavigationRegion3D::is_baking);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_bounds"), &NavigationRegion3D::get_bounds);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navigation_mesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_edge_connections"), "set_use_edge_connections", "get_use_edge_connections");
|
||||
@ -740,3 +744,26 @@ void NavigationRegion3D::_update_debug_edge_connections_mesh() {
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
void NavigationRegion3D::_update_bounds() {
|
||||
if (navigation_mesh.is_null()) {
|
||||
bounds = AABB();
|
||||
return;
|
||||
}
|
||||
|
||||
const Vector<Vector3> &vertices = navigation_mesh->get_vertices();
|
||||
if (vertices.is_empty()) {
|
||||
bounds = AABB();
|
||||
return;
|
||||
}
|
||||
|
||||
const Transform3D gt = is_inside_tree() ? get_global_transform() : get_transform();
|
||||
|
||||
AABB new_bounds;
|
||||
new_bounds.position = gt.xform(vertices[0]);
|
||||
|
||||
for (const Vector3 &vertex : vertices) {
|
||||
new_bounds.expand_to(gt.xform(vertex));
|
||||
}
|
||||
bounds = new_bounds;
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ class NavigationRegion3D : public Node3D {
|
||||
|
||||
void _navigation_mesh_changed();
|
||||
|
||||
AABB bounds;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
RID debug_instance;
|
||||
RID debug_edge_connections_instance;
|
||||
@ -110,10 +112,13 @@ public:
|
||||
|
||||
PackedStringArray get_configuration_warnings() const override;
|
||||
|
||||
AABB get_bounds() const { return bounds; }
|
||||
|
||||
NavigationRegion3D();
|
||||
~NavigationRegion3D();
|
||||
|
||||
private:
|
||||
void _update_bounds();
|
||||
void _region_enter_navigation_map();
|
||||
void _region_exit_navigation_map();
|
||||
void _region_update_transform();
|
||||
|
@ -91,6 +91,7 @@ void NavigationServer2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_end);
|
||||
ClassDB::bind_method(D_METHOD("region_get_closest_point", "region", "to_point"), &NavigationServer2D::region_get_closest_point);
|
||||
ClassDB::bind_method(D_METHOD("region_get_random_point", "region", "navigation_layers", "uniformly"), &NavigationServer2D::region_get_random_point);
|
||||
ClassDB::bind_method(D_METHOD("region_get_bounds", "region"), &NavigationServer2D::region_get_bounds);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer2D::link_create);
|
||||
ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer2D::link_set_map);
|
||||
|
@ -154,6 +154,7 @@ public:
|
||||
|
||||
virtual Vector2 region_get_closest_point(RID p_region, const Vector2 &p_point) const = 0;
|
||||
virtual Vector2 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const = 0;
|
||||
virtual Rect2 region_get_bounds(RID p_region) const = 0;
|
||||
|
||||
/// Creates a new link between positions in the nav map.
|
||||
virtual RID link_create() = 0;
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const override { return Vector2(); }
|
||||
Vector2 region_get_closest_point(RID p_region, const Vector2 &p_point) const override { return Vector2(); }
|
||||
Vector2 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const override { return Vector2(); }
|
||||
Rect2 region_get_bounds(RID p_region) const override { return Rect2(); }
|
||||
|
||||
RID link_create() override { return RID(); }
|
||||
void link_set_map(RID p_link, RID p_map) override {}
|
||||
|
@ -106,6 +106,7 @@ void NavigationServer3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("region_get_closest_point", "region", "to_point"), &NavigationServer3D::region_get_closest_point);
|
||||
ClassDB::bind_method(D_METHOD("region_get_closest_point_normal", "region", "to_point"), &NavigationServer3D::region_get_closest_point_normal);
|
||||
ClassDB::bind_method(D_METHOD("region_get_random_point", "region", "navigation_layers", "uniformly"), &NavigationServer3D::region_get_random_point);
|
||||
ClassDB::bind_method(D_METHOD("region_get_bounds", "region"), &NavigationServer3D::region_get_bounds);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer3D::link_create);
|
||||
ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer3D::link_set_map);
|
||||
|
@ -176,6 +176,8 @@ public:
|
||||
virtual Vector3 region_get_closest_point_normal(RID p_region, const Vector3 &p_point) const = 0;
|
||||
virtual Vector3 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const = 0;
|
||||
|
||||
virtual AABB region_get_bounds(RID p_region) const = 0;
|
||||
|
||||
/// Creates a new link between positions in the nav map.
|
||||
virtual RID link_create() = 0;
|
||||
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
Vector3 region_get_closest_point(RID p_region, const Vector3 &p_point) const override { return Vector3(); }
|
||||
Vector3 region_get_closest_point_normal(RID p_region, const Vector3 &p_point) const override { return Vector3(); }
|
||||
Vector3 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const override { return Vector3(); }
|
||||
AABB region_get_bounds(RID p_region) const override { return AABB(); }
|
||||
|
||||
RID link_create() override { return RID(); }
|
||||
void link_set_map(RID p_link, RID p_map) override {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user