mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Add a way to filter neighbor points to AStar2D/3D
This commit is contained in:
parent
8b2739ee55
commit
610712a269
4 changed files with 79 additions and 0 deletions
|
@ -349,6 +349,13 @@ bool AStar3D::_solve(Point *begin_point, Point *end_point, bool p_allow_partial_
|
|||
continue;
|
||||
}
|
||||
|
||||
if (neighbor_filter_enabled) {
|
||||
bool filtered;
|
||||
if (GDVIRTUAL_CALL(_filter_neighbor, p->id, e->id, filtered) && filtered) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
real_t tentative_g_score = p->g_score + _compute_cost(p->id, e->id) * e->weight_scale;
|
||||
|
||||
bool new_point = false;
|
||||
|
@ -524,6 +531,14 @@ Vector<int64_t> AStar3D::get_id_path(int64_t p_from_id, int64_t p_to_id, bool p_
|
|||
return path;
|
||||
}
|
||||
|
||||
bool AStar3D::is_neighbor_filter_enabled() const {
|
||||
return neighbor_filter_enabled;
|
||||
}
|
||||
|
||||
void AStar3D::set_neighbor_filter_enabled(bool p_enabled) {
|
||||
neighbor_filter_enabled = p_enabled;
|
||||
}
|
||||
|
||||
void AStar3D::set_point_disabled(int64_t p_id, bool p_disabled) {
|
||||
Point **p_entry = points.getptr(p_id);
|
||||
ERR_FAIL_COND_MSG(!p_entry, vformat("Can't set if point is disabled. Point with id: %d doesn't exist.", p_id));
|
||||
|
@ -555,6 +570,9 @@ void AStar3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar3D::set_point_disabled, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar3D::is_point_disabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_neighbor_filter_enabled", "enabled"), &AStar3D::set_neighbor_filter_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_neighbor_filter_enabled"), &AStar3D::is_neighbor_filter_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar3D::connect_points, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id", "bidirectional"), &AStar3D::disconnect_points, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id", "bidirectional"), &AStar3D::are_points_connected, DEFVAL(true));
|
||||
|
@ -570,8 +588,11 @@ void AStar3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id", "allow_partial_path"), &AStar3D::get_point_path, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id", "allow_partial_path"), &AStar3D::get_id_path, DEFVAL(false));
|
||||
|
||||
GDVIRTUAL_BIND(_filter_neighbor, "from_id", "neighbor_id")
|
||||
GDVIRTUAL_BIND(_estimate_cost, "from_id", "end_id")
|
||||
GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id")
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "neighbor_filter_enabled"), "set_neighbor_filter_enabled", "is_neighbor_filter_enabled");
|
||||
}
|
||||
|
||||
AStar3D::~AStar3D() {
|
||||
|
@ -621,6 +642,14 @@ PackedInt64Array AStar2D::get_point_ids() {
|
|||
return astar.get_point_ids();
|
||||
}
|
||||
|
||||
bool AStar2D::is_neighbor_filter_enabled() const {
|
||||
return astar.neighbor_filter_enabled;
|
||||
}
|
||||
|
||||
void AStar2D::set_neighbor_filter_enabled(bool p_enabled) {
|
||||
astar.neighbor_filter_enabled = p_enabled;
|
||||
}
|
||||
|
||||
void AStar2D::set_point_disabled(int64_t p_id, bool p_disabled) {
|
||||
astar.set_point_disabled(p_id, p_disabled);
|
||||
}
|
||||
|
@ -854,6 +883,13 @@ bool AStar2D::_solve(AStar3D::Point *begin_point, AStar3D::Point *end_point, boo
|
|||
continue;
|
||||
}
|
||||
|
||||
if (astar.neighbor_filter_enabled) {
|
||||
bool filtered;
|
||||
if (GDVIRTUAL_CALL(_filter_neighbor, p->id, e->id, filtered) && filtered) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
real_t tentative_g_score = p->g_score + _compute_cost(p->id, e->id) * e->weight_scale;
|
||||
|
||||
bool new_point = false;
|
||||
|
@ -895,6 +931,9 @@ void AStar2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar2D::get_point_connections);
|
||||
ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar2D::get_point_ids);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_neighbor_filter_enabled", "enabled"), &AStar2D::set_neighbor_filter_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_neighbor_filter_enabled"), &AStar2D::is_neighbor_filter_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar2D::set_point_disabled, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar2D::is_point_disabled);
|
||||
|
||||
|
@ -913,6 +952,9 @@ void AStar2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id", "allow_partial_path"), &AStar2D::get_point_path, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id", "allow_partial_path"), &AStar2D::get_id_path, DEFVAL(false));
|
||||
|
||||
GDVIRTUAL_BIND(_filter_neighbor, "from_id", "neighbor_id")
|
||||
GDVIRTUAL_BIND(_estimate_cost, "from_id", "end_id")
|
||||
GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id")
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "neighbor_filter_enabled"), "set_neighbor_filter_enabled", "is_neighbor_filter_enabled");
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ class AStar3D : public RefCounted {
|
|||
AHashMap<int64_t, Point *> points;
|
||||
HashSet<Segment, Segment> segments;
|
||||
Point *last_closest_point = nullptr;
|
||||
bool neighbor_filter_enabled = false;
|
||||
|
||||
bool _solve(Point *begin_point, Point *end_point, bool p_allow_partial_path);
|
||||
|
||||
|
@ -122,6 +123,7 @@ protected:
|
|||
virtual real_t _estimate_cost(int64_t p_from_id, int64_t p_end_id);
|
||||
virtual real_t _compute_cost(int64_t p_from_id, int64_t p_to_id);
|
||||
|
||||
GDVIRTUAL2RC(bool, _filter_neighbor, int64_t, int64_t)
|
||||
GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
|
||||
GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
|
||||
|
||||
|
@ -144,6 +146,9 @@ public:
|
|||
Vector<int64_t> get_point_connections(int64_t p_id);
|
||||
PackedInt64Array get_point_ids();
|
||||
|
||||
bool is_neighbor_filter_enabled() const;
|
||||
void set_neighbor_filter_enabled(bool p_enabled);
|
||||
|
||||
void set_point_disabled(int64_t p_id, bool p_disabled = true);
|
||||
bool is_point_disabled(int64_t p_id) const;
|
||||
|
||||
|
@ -178,6 +183,7 @@ protected:
|
|||
virtual real_t _estimate_cost(int64_t p_from_id, int64_t p_end_id);
|
||||
virtual real_t _compute_cost(int64_t p_from_id, int64_t p_to_id);
|
||||
|
||||
GDVIRTUAL2RC(bool, _filter_neighbor, int64_t, int64_t)
|
||||
GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
|
||||
GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
|
||||
|
||||
|
@ -200,6 +206,9 @@ public:
|
|||
Vector<int64_t> get_point_connections(int64_t p_id);
|
||||
PackedInt64Array get_point_ids();
|
||||
|
||||
bool is_neighbor_filter_enabled() const;
|
||||
void set_neighbor_filter_enabled(bool p_enabled);
|
||||
|
||||
void set_point_disabled(int64_t p_id, bool p_disabled = true);
|
||||
bool is_point_disabled(int64_t p_id) const;
|
||||
|
||||
|
|
|
@ -29,6 +29,15 @@
|
|||
Note that this function is hidden in the default [AStar2D] class.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_filter_neighbor" qualifiers="virtual const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="from_id" type="int" />
|
||||
<param index="1" name="neighbor_id" type="int" />
|
||||
<description>
|
||||
Called when neighboring enters processing and if [member neighbor_filter_enabled] is [code]true[/code]. If [code]true[/code] is returned the point will not be processed.
|
||||
Note that this function is hidden in the default [AStar2D] class.
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_point">
|
||||
<return type="void" />
|
||||
<param index="0" name="id" type="int" />
|
||||
|
@ -307,4 +316,9 @@
|
|||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="neighbor_filter_enabled" type="bool" setter="set_neighbor_filter_enabled" getter="is_neighbor_filter_enabled" default="false">
|
||||
If [code]true[/code] enables the filtering of neighbors via [method _filter_neighbor].
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
|
@ -70,6 +70,15 @@
|
|||
Note that this function is hidden in the default [AStar3D] class.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_filter_neighbor" qualifiers="virtual const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="from_id" type="int" />
|
||||
<param index="1" name="neighbor_id" type="int" />
|
||||
<description>
|
||||
Called when neighboring point enters processing and if [member neighbor_filter_enabled] is [code]true[/code]. If [code]true[/code] is returned the point will not be processed.
|
||||
Note that this function is hidden in the default [AStar3D] class.
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_point">
|
||||
<return type="void" />
|
||||
<param index="0" name="id" type="int" />
|
||||
|
@ -346,4 +355,9 @@
|
|||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="neighbor_filter_enabled" type="bool" setter="set_neighbor_filter_enabled" getter="is_neighbor_filter_enabled" default="false">
|
||||
If [code]true[/code] enables the filtering of neighbors via [method _filter_neighbor].
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue