Browse Source

Make AStar to use 64-bit logic

Yuri Rubinsky 3 years ago
parent
commit
7da2a21425
5 changed files with 148 additions and 153 deletions
  1. 81 81
      core/math/a_star.cpp
  2. 59 64
      core/math/a_star.h
  3. 2 2
      doc/classes/AStar2D.xml
  4. 2 2
      doc/classes/AStar3D.xml
  5. 4 4
      tests/core/math/test_astar.h

+ 81 - 81
core/math/a_star.cpp

@@ -33,19 +33,19 @@
 #include "core/math/geometry_3d.h"
 #include "core/math/geometry_3d.h"
 #include "core/object/script_language.h"
 #include "core/object/script_language.h"
 
 
-int AStar3D::get_available_point_id() const {
+int64_t AStar3D::get_available_point_id() const {
 	if (points.has(last_free_id)) {
 	if (points.has(last_free_id)) {
-		int cur_new_id = last_free_id + 1;
+		int64_t cur_new_id = last_free_id + 1;
 		while (points.has(cur_new_id)) {
 		while (points.has(cur_new_id)) {
 			cur_new_id++;
 			cur_new_id++;
 		}
 		}
-		const_cast<int &>(last_free_id) = cur_new_id;
+		const_cast<int64_t &>(last_free_id) = cur_new_id;
 	}
 	}
 
 
 	return last_free_id;
 	return last_free_id;
 }
 }
 
 
-void AStar3D::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
+void AStar3D::add_point(int64_t p_id, const Vector3 &p_pos, real_t p_weight_scale) {
 	ERR_FAIL_COND_MSG(p_id < 0, vformat("Can't add a point with negative id: %d.", p_id));
 	ERR_FAIL_COND_MSG(p_id < 0, vformat("Can't add a point with negative id: %d.", p_id));
 	ERR_FAIL_COND_MSG(p_weight_scale < 0.0, vformat("Can't add a point with weight scale less than 0.0: %f.", p_weight_scale));
 	ERR_FAIL_COND_MSG(p_weight_scale < 0.0, vformat("Can't add a point with weight scale less than 0.0: %f.", p_weight_scale));
 
 
@@ -68,7 +68,7 @@ void AStar3D::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
 	}
 	}
 }
 }
 
 
-Vector3 AStar3D::get_point_position(int p_id) const {
+Vector3 AStar3D::get_point_position(int64_t p_id) const {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_V_MSG(!p_exists, Vector3(), vformat("Can't get point's position. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_V_MSG(!p_exists, Vector3(), vformat("Can't get point's position. Point with id: %d doesn't exist.", p_id));
@@ -76,7 +76,7 @@ Vector3 AStar3D::get_point_position(int p_id) const {
 	return p->pos;
 	return p->pos;
 }
 }
 
 
-void AStar3D::set_point_position(int p_id, const Vector3 &p_pos) {
+void AStar3D::set_point_position(int64_t p_id, const Vector3 &p_pos) {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set point's position. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set point's position. Point with id: %d doesn't exist.", p_id));
@@ -84,7 +84,7 @@ void AStar3D::set_point_position(int p_id, const Vector3 &p_pos) {
 	p->pos = p_pos;
 	p->pos = p_pos;
 }
 }
 
 
-real_t AStar3D::get_point_weight_scale(int p_id) const {
+real_t AStar3D::get_point_weight_scale(int64_t p_id) const {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_V_MSG(!p_exists, 0, vformat("Can't get point's weight scale. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_V_MSG(!p_exists, 0, vformat("Can't get point's weight scale. Point with id: %d doesn't exist.", p_id));
@@ -92,7 +92,7 @@ real_t AStar3D::get_point_weight_scale(int p_id) const {
 	return p->weight_scale;
 	return p->weight_scale;
 }
 }
 
 
-void AStar3D::set_point_weight_scale(int p_id, real_t p_weight_scale) {
+void AStar3D::set_point_weight_scale(int64_t p_id, real_t p_weight_scale) {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set point's weight scale. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set point's weight scale. Point with id: %d doesn't exist.", p_id));
@@ -101,12 +101,12 @@ void AStar3D::set_point_weight_scale(int p_id, real_t p_weight_scale) {
 	p->weight_scale = p_weight_scale;
 	p->weight_scale = p_weight_scale;
 }
 }
 
 
-void AStar3D::remove_point(int p_id) {
+void AStar3D::remove_point(int64_t p_id) {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't remove point. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't remove point. Point with id: %d doesn't exist.", p_id));
 
 
-	for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+	for (OAHashMap<int64_t, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
 		Segment s(p_id, (*it.key));
 		Segment s(p_id, (*it.key));
 		segments.erase(s);
 		segments.erase(s);
 
 
@@ -114,7 +114,7 @@ void AStar3D::remove_point(int p_id) {
 		(*it.value)->unlinked_neighbours.remove(p->id);
 		(*it.value)->unlinked_neighbours.remove(p->id);
 	}
 	}
 
 
-	for (OAHashMap<int, Point *>::Iterator it = p->unlinked_neighbours.iter(); it.valid; it = p->unlinked_neighbours.next_iter(it)) {
+	for (OAHashMap<int64_t, Point *>::Iterator it = p->unlinked_neighbours.iter(); it.valid; it = p->unlinked_neighbours.next_iter(it)) {
 		Segment s(p_id, (*it.key));
 		Segment s(p_id, (*it.key));
 		segments.erase(s);
 		segments.erase(s);
 
 
@@ -127,7 +127,7 @@ void AStar3D::remove_point(int p_id) {
 	last_free_id = p_id;
 	last_free_id = p_id;
 }
 }
 
 
-void AStar3D::connect_points(int p_id, int p_with_id, bool bidirectional) {
+void AStar3D::connect_points(int64_t p_id, int64_t p_with_id, bool bidirectional) {
 	ERR_FAIL_COND_MSG(p_id == p_with_id, vformat("Can't connect point with id: %d to itself.", p_id));
 	ERR_FAIL_COND_MSG(p_id == p_with_id, vformat("Can't connect point with id: %d to itself.", p_id));
 
 
 	Point *a;
 	Point *a;
@@ -165,7 +165,7 @@ void AStar3D::connect_points(int p_id, int p_with_id, bool bidirectional) {
 	segments.insert(s);
 	segments.insert(s);
 }
 }
 
 
-void AStar3D::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
+void AStar3D::disconnect_points(int64_t p_id, int64_t p_with_id, bool bidirectional) {
 	Point *a;
 	Point *a;
 	bool a_exists = points.lookup(p_id, a);
 	bool a_exists = points.lookup(p_id, a);
 	ERR_FAIL_COND_MSG(!a_exists, vformat("Can't disconnect points. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_MSG(!a_exists, vformat("Can't disconnect points. Point with id: %d doesn't exist.", p_id));
@@ -175,7 +175,7 @@ void AStar3D::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
 	ERR_FAIL_COND_MSG(!b_exists, vformat("Can't disconnect points. Point with id: %d doesn't exist.", p_with_id));
 	ERR_FAIL_COND_MSG(!b_exists, vformat("Can't disconnect points. Point with id: %d doesn't exist.", p_with_id));
 
 
 	Segment s(p_id, p_with_id);
 	Segment s(p_id, p_with_id);
-	int remove_direction = bidirectional ? (int)Segment::BIDIRECTIONAL : s.direction;
+	int remove_direction = bidirectional ? (int)Segment::BIDIRECTIONAL : (int)s.direction;
 
 
 	HashSet<Segment, Segment>::Iterator element = segments.find(s);
 	HashSet<Segment, Segment>::Iterator element = segments.find(s);
 	if (element) {
 	if (element) {
@@ -205,35 +205,35 @@ void AStar3D::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
 	}
 	}
 }
 }
 
 
-bool AStar3D::has_point(int p_id) const {
+bool AStar3D::has_point(int64_t p_id) const {
 	return points.has(p_id);
 	return points.has(p_id);
 }
 }
 
 
 Array AStar3D::get_point_ids() {
 Array AStar3D::get_point_ids() {
 	Array point_list;
 	Array point_list;
 
 
-	for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+	for (OAHashMap<int64_t, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
 		point_list.push_back(*(it.key));
 		point_list.push_back(*(it.key));
 	}
 	}
 
 
 	return point_list;
 	return point_list;
 }
 }
 
 
-Vector<int> AStar3D::get_point_connections(int p_id) {
+Vector<int64_t> AStar3D::get_point_connections(int64_t p_id) {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
-	ERR_FAIL_COND_V_MSG(!p_exists, Vector<int>(), vformat("Can't get point's connections. Point with id: %d doesn't exist.", p_id));
+	ERR_FAIL_COND_V_MSG(!p_exists, Vector<int64_t>(), vformat("Can't get point's connections. Point with id: %d doesn't exist.", p_id));
 
 
-	Vector<int> point_list;
+	Vector<int64_t> point_list;
 
 
-	for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+	for (OAHashMap<int64_t, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
 		point_list.push_back((*it.key));
 		point_list.push_back((*it.key));
 	}
 	}
 
 
 	return point_list;
 	return point_list;
 }
 }
 
 
-bool AStar3D::are_points_connected(int p_id, int p_with_id, bool bidirectional) const {
+bool AStar3D::are_points_connected(int64_t p_id, int64_t p_with_id, bool bidirectional) const {
 	Segment s(p_id, p_with_id);
 	Segment s(p_id, p_with_id);
 	const HashSet<Segment, Segment>::Iterator element = segments.find(s);
 	const HashSet<Segment, Segment>::Iterator element = segments.find(s);
 
 
@@ -243,32 +243,32 @@ bool AStar3D::are_points_connected(int p_id, int p_with_id, bool bidirectional)
 
 
 void AStar3D::clear() {
 void AStar3D::clear() {
 	last_free_id = 0;
 	last_free_id = 0;
-	for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+	for (OAHashMap<int64_t, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
 		memdelete(*(it.value));
 		memdelete(*(it.value));
 	}
 	}
 	segments.clear();
 	segments.clear();
 	points.clear();
 	points.clear();
 }
 }
 
 
-int AStar3D::get_point_count() const {
+int64_t AStar3D::get_point_count() const {
 	return points.get_num_elements();
 	return points.get_num_elements();
 }
 }
 
 
-int AStar3D::get_point_capacity() const {
+int64_t AStar3D::get_point_capacity() const {
 	return points.get_capacity();
 	return points.get_capacity();
 }
 }
 
 
-void AStar3D::reserve_space(int p_num_nodes) {
+void AStar3D::reserve_space(int64_t p_num_nodes) {
 	ERR_FAIL_COND_MSG(p_num_nodes <= 0, vformat("New capacity must be greater than 0, new was: %d.", p_num_nodes));
 	ERR_FAIL_COND_MSG(p_num_nodes <= 0, vformat("New capacity must be greater than 0, new was: %d.", p_num_nodes));
 	ERR_FAIL_COND_MSG((uint32_t)p_num_nodes < points.get_capacity(), vformat("New capacity must be greater than current capacity: %d, new was: %d.", points.get_capacity(), p_num_nodes));
 	ERR_FAIL_COND_MSG((uint32_t)p_num_nodes < points.get_capacity(), vformat("New capacity must be greater than current capacity: %d, new was: %d.", points.get_capacity(), p_num_nodes));
 	points.reserve(p_num_nodes);
 	points.reserve(p_num_nodes);
 }
 }
 
 
-int AStar3D::get_closest_point(const Vector3 &p_point, bool p_include_disabled) const {
-	int closest_id = -1;
+int64_t AStar3D::get_closest_point(const Vector3 &p_point, bool p_include_disabled) const {
+	int64_t closest_id = -1;
 	real_t closest_dist = 1e20;
 	real_t closest_dist = 1e20;
 
 
-	for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+	for (OAHashMap<int64_t, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
 		if (!p_include_disabled && !(*it.value)->enabled) {
 		if (!p_include_disabled && !(*it.value)->enabled) {
 			continue; // Disabled points should not be considered.
 			continue; // Disabled points should not be considered.
 		}
 		}
@@ -276,7 +276,7 @@ int AStar3D::get_closest_point(const Vector3 &p_point, bool p_include_disabled)
 		// Keep the closest point's ID, and in case of multiple closest IDs,
 		// Keep the closest point's ID, and in case of multiple closest IDs,
 		// the smallest one (makes it deterministic).
 		// the smallest one (makes it deterministic).
 		real_t d = p_point.distance_squared_to((*it.value)->pos);
 		real_t d = p_point.distance_squared_to((*it.value)->pos);
-		int id = *(it.key);
+		int64_t id = *(it.key);
 		if (d <= closest_dist) {
 		if (d <= closest_dist) {
 			if (d == closest_dist && id > closest_id) { // Keep lowest ID.
 			if (d == closest_dist && id > closest_id) { // Keep lowest ID.
 				continue;
 				continue;
@@ -295,8 +295,8 @@ Vector3 AStar3D::get_closest_position_in_segment(const Vector3 &p_point) const {
 
 
 	for (const Segment &E : segments) {
 	for (const Segment &E : segments) {
 		Point *from_point = nullptr, *to_point = nullptr;
 		Point *from_point = nullptr, *to_point = nullptr;
-		points.lookup(E.u, from_point);
-		points.lookup(E.v, to_point);
+		points.lookup(E.key.first, from_point);
+		points.lookup(E.key.second, to_point);
 
 
 		if (!(from_point->enabled && to_point->enabled)) {
 		if (!(from_point->enabled && to_point->enabled)) {
 			continue;
 			continue;
@@ -346,7 +346,7 @@ bool AStar3D::_solve(Point *begin_point, Point *end_point) {
 		open_list.remove_at(open_list.size() - 1);
 		open_list.remove_at(open_list.size() - 1);
 		p->closed_pass = pass; // Mark the point as closed
 		p->closed_pass = pass; // Mark the point as closed
 
 
-		for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+		for (OAHashMap<int64_t, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
 			Point *e = *(it.value); // The neighbour point
 			Point *e = *(it.value); // The neighbour point
 
 
 			if (!e->enabled || e->closed_pass == pass) {
 			if (!e->enabled || e->closed_pass == pass) {
@@ -380,7 +380,7 @@ bool AStar3D::_solve(Point *begin_point, Point *end_point) {
 	return found_route;
 	return found_route;
 }
 }
 
 
-real_t AStar3D::_estimate_cost(int p_from_id, int p_to_id) {
+real_t AStar3D::_estimate_cost(int64_t p_from_id, int64_t p_to_id) {
 	real_t scost;
 	real_t scost;
 	if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
 	if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
 		return scost;
 		return scost;
@@ -397,7 +397,7 @@ real_t AStar3D::_estimate_cost(int p_from_id, int p_to_id) {
 	return from_point->pos.distance_to(to_point->pos);
 	return from_point->pos.distance_to(to_point->pos);
 }
 }
 
 
-real_t AStar3D::_compute_cost(int p_from_id, int p_to_id) {
+real_t AStar3D::_compute_cost(int64_t p_from_id, int64_t p_to_id) {
 	real_t scost;
 	real_t scost;
 	if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
 	if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
 		return scost;
 		return scost;
@@ -414,7 +414,7 @@ real_t AStar3D::_compute_cost(int p_from_id, int p_to_id) {
 	return from_point->pos.distance_to(to_point->pos);
 	return from_point->pos.distance_to(to_point->pos);
 }
 }
 
 
-Vector<Vector3> AStar3D::get_point_path(int p_from_id, int p_to_id) {
+Vector<Vector3> AStar3D::get_point_path(int64_t p_from_id, int64_t p_to_id) {
 	Point *a;
 	Point *a;
 	bool from_exists = points.lookup(p_from_id, a);
 	bool from_exists = points.lookup(p_from_id, a);
 	ERR_FAIL_COND_V_MSG(!from_exists, Vector<Vector3>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_from_id));
 	ERR_FAIL_COND_V_MSG(!from_exists, Vector<Vector3>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_from_id));
@@ -438,7 +438,7 @@ Vector<Vector3> AStar3D::get_point_path(int p_from_id, int p_to_id) {
 	}
 	}
 
 
 	Point *p = end_point;
 	Point *p = end_point;
-	int pc = 1; // Begin point
+	int64_t pc = 1; // Begin point
 	while (p != begin_point) {
 	while (p != begin_point) {
 		pc++;
 		pc++;
 		p = p->prev_point;
 		p = p->prev_point;
@@ -451,7 +451,7 @@ Vector<Vector3> AStar3D::get_point_path(int p_from_id, int p_to_id) {
 		Vector3 *w = path.ptrw();
 		Vector3 *w = path.ptrw();
 
 
 		Point *p2 = end_point;
 		Point *p2 = end_point;
-		int idx = pc - 1;
+		int64_t idx = pc - 1;
 		while (p2 != begin_point) {
 		while (p2 != begin_point) {
 			w[idx--] = p2->pos;
 			w[idx--] = p2->pos;
 			p2 = p2->prev_point;
 			p2 = p2->prev_point;
@@ -463,17 +463,17 @@ Vector<Vector3> AStar3D::get_point_path(int p_from_id, int p_to_id) {
 	return path;
 	return path;
 }
 }
 
 
-Vector<int> AStar3D::get_id_path(int p_from_id, int p_to_id) {
+Vector<int64_t> AStar3D::get_id_path(int64_t p_from_id, int64_t p_to_id) {
 	Point *a;
 	Point *a;
 	bool from_exists = points.lookup(p_from_id, a);
 	bool from_exists = points.lookup(p_from_id, a);
-	ERR_FAIL_COND_V_MSG(!from_exists, Vector<int>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_from_id));
+	ERR_FAIL_COND_V_MSG(!from_exists, Vector<int64_t>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_from_id));
 
 
 	Point *b;
 	Point *b;
 	bool to_exists = points.lookup(p_to_id, b);
 	bool to_exists = points.lookup(p_to_id, b);
-	ERR_FAIL_COND_V_MSG(!to_exists, Vector<int>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_to_id));
+	ERR_FAIL_COND_V_MSG(!to_exists, Vector<int64_t>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_to_id));
 
 
 	if (a == b) {
 	if (a == b) {
-		Vector<int> ret;
+		Vector<int64_t> ret;
 		ret.push_back(a->id);
 		ret.push_back(a->id);
 		return ret;
 		return ret;
 	}
 	}
@@ -483,24 +483,24 @@ Vector<int> AStar3D::get_id_path(int p_from_id, int p_to_id) {
 
 
 	bool found_route = _solve(begin_point, end_point);
 	bool found_route = _solve(begin_point, end_point);
 	if (!found_route) {
 	if (!found_route) {
-		return Vector<int>();
+		return Vector<int64_t>();
 	}
 	}
 
 
 	Point *p = end_point;
 	Point *p = end_point;
-	int pc = 1; // Begin point
+	int64_t pc = 1; // Begin point
 	while (p != begin_point) {
 	while (p != begin_point) {
 		pc++;
 		pc++;
 		p = p->prev_point;
 		p = p->prev_point;
 	}
 	}
 
 
-	Vector<int> path;
+	Vector<int64_t> path;
 	path.resize(pc);
 	path.resize(pc);
 
 
 	{
 	{
-		int *w = path.ptrw();
+		int64_t *w = path.ptrw();
 
 
 		p = end_point;
 		p = end_point;
-		int idx = pc - 1;
+		int64_t idx = pc - 1;
 		while (p != begin_point) {
 		while (p != begin_point) {
 			w[idx--] = p->id;
 			w[idx--] = p->id;
 			p = p->prev_point;
 			p = p->prev_point;
@@ -512,7 +512,7 @@ Vector<int> AStar3D::get_id_path(int p_from_id, int p_to_id) {
 	return path;
 	return path;
 }
 }
 
 
-void AStar3D::set_point_disabled(int p_id, bool p_disabled) {
+void AStar3D::set_point_disabled(int64_t p_id, bool p_disabled) {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set if point is disabled. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set if point is disabled. Point with id: %d doesn't exist.", p_id));
@@ -520,7 +520,7 @@ void AStar3D::set_point_disabled(int p_id, bool p_disabled) {
 	p->enabled = !p_disabled;
 	p->enabled = !p_disabled;
 }
 }
 
 
-bool AStar3D::is_point_disabled(int p_id) const {
+bool AStar3D::is_point_disabled(int64_t p_id) const {
 	Point *p;
 	Point *p;
 	bool p_exists = points.lookup(p_id, p);
 	bool p_exists = points.lookup(p_id, p);
 	ERR_FAIL_COND_V_MSG(!p_exists, false, vformat("Can't get if point is disabled. Point with id: %d doesn't exist.", p_id));
 	ERR_FAIL_COND_V_MSG(!p_exists, false, vformat("Can't get if point is disabled. Point with id: %d doesn't exist.", p_id));
@@ -568,40 +568,40 @@ AStar3D::~AStar3D() {
 
 
 /////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////
 
 
-int AStar2D::get_available_point_id() const {
+int64_t AStar2D::get_available_point_id() const {
 	return astar.get_available_point_id();
 	return astar.get_available_point_id();
 }
 }
 
 
-void AStar2D::add_point(int p_id, const Vector2 &p_pos, real_t p_weight_scale) {
+void AStar2D::add_point(int64_t p_id, const Vector2 &p_pos, real_t p_weight_scale) {
 	astar.add_point(p_id, Vector3(p_pos.x, p_pos.y, 0), p_weight_scale);
 	astar.add_point(p_id, Vector3(p_pos.x, p_pos.y, 0), p_weight_scale);
 }
 }
 
 
-Vector2 AStar2D::get_point_position(int p_id) const {
+Vector2 AStar2D::get_point_position(int64_t p_id) const {
 	Vector3 p = astar.get_point_position(p_id);
 	Vector3 p = astar.get_point_position(p_id);
 	return Vector2(p.x, p.y);
 	return Vector2(p.x, p.y);
 }
 }
 
 
-void AStar2D::set_point_position(int p_id, const Vector2 &p_pos) {
+void AStar2D::set_point_position(int64_t p_id, const Vector2 &p_pos) {
 	astar.set_point_position(p_id, Vector3(p_pos.x, p_pos.y, 0));
 	astar.set_point_position(p_id, Vector3(p_pos.x, p_pos.y, 0));
 }
 }
 
 
-real_t AStar2D::get_point_weight_scale(int p_id) const {
+real_t AStar2D::get_point_weight_scale(int64_t p_id) const {
 	return astar.get_point_weight_scale(p_id);
 	return astar.get_point_weight_scale(p_id);
 }
 }
 
 
-void AStar2D::set_point_weight_scale(int p_id, real_t p_weight_scale) {
+void AStar2D::set_point_weight_scale(int64_t p_id, real_t p_weight_scale) {
 	astar.set_point_weight_scale(p_id, p_weight_scale);
 	astar.set_point_weight_scale(p_id, p_weight_scale);
 }
 }
 
 
-void AStar2D::remove_point(int p_id) {
+void AStar2D::remove_point(int64_t p_id) {
 	astar.remove_point(p_id);
 	astar.remove_point(p_id);
 }
 }
 
 
-bool AStar2D::has_point(int p_id) const {
+bool AStar2D::has_point(int64_t p_id) const {
 	return astar.has_point(p_id);
 	return astar.has_point(p_id);
 }
 }
 
 
-Vector<int> AStar2D::get_point_connections(int p_id) {
+Vector<int64_t> AStar2D::get_point_connections(int64_t p_id) {
 	return astar.get_point_connections(p_id);
 	return astar.get_point_connections(p_id);
 }
 }
 
 
@@ -609,31 +609,31 @@ Array AStar2D::get_point_ids() {
 	return astar.get_point_ids();
 	return astar.get_point_ids();
 }
 }
 
 
-void AStar2D::set_point_disabled(int p_id, bool p_disabled) {
+void AStar2D::set_point_disabled(int64_t p_id, bool p_disabled) {
 	astar.set_point_disabled(p_id, p_disabled);
 	astar.set_point_disabled(p_id, p_disabled);
 }
 }
 
 
-bool AStar2D::is_point_disabled(int p_id) const {
+bool AStar2D::is_point_disabled(int64_t p_id) const {
 	return astar.is_point_disabled(p_id);
 	return astar.is_point_disabled(p_id);
 }
 }
 
 
-void AStar2D::connect_points(int p_id, int p_with_id, bool p_bidirectional) {
+void AStar2D::connect_points(int64_t p_id, int64_t p_with_id, bool p_bidirectional) {
 	astar.connect_points(p_id, p_with_id, p_bidirectional);
 	astar.connect_points(p_id, p_with_id, p_bidirectional);
 }
 }
 
 
-void AStar2D::disconnect_points(int p_id, int p_with_id, bool p_bidirectional) {
+void AStar2D::disconnect_points(int64_t p_id, int64_t p_with_id, bool p_bidirectional) {
 	astar.disconnect_points(p_id, p_with_id, p_bidirectional);
 	astar.disconnect_points(p_id, p_with_id, p_bidirectional);
 }
 }
 
 
-bool AStar2D::are_points_connected(int p_id, int p_with_id, bool p_bidirectional) const {
+bool AStar2D::are_points_connected(int64_t p_id, int64_t p_with_id, bool p_bidirectional) const {
 	return astar.are_points_connected(p_id, p_with_id, p_bidirectional);
 	return astar.are_points_connected(p_id, p_with_id, p_bidirectional);
 }
 }
 
 
-int AStar2D::get_point_count() const {
+int64_t AStar2D::get_point_count() const {
 	return astar.get_point_count();
 	return astar.get_point_count();
 }
 }
 
 
-int AStar2D::get_point_capacity() const {
+int64_t AStar2D::get_point_capacity() const {
 	return astar.get_point_capacity();
 	return astar.get_point_capacity();
 }
 }
 
 
@@ -641,11 +641,11 @@ void AStar2D::clear() {
 	astar.clear();
 	astar.clear();
 }
 }
 
 
-void AStar2D::reserve_space(int p_num_nodes) {
+void AStar2D::reserve_space(int64_t p_num_nodes) {
 	astar.reserve_space(p_num_nodes);
 	astar.reserve_space(p_num_nodes);
 }
 }
 
 
-int AStar2D::get_closest_point(const Vector2 &p_point, bool p_include_disabled) const {
+int64_t AStar2D::get_closest_point(const Vector2 &p_point, bool p_include_disabled) const {
 	return astar.get_closest_point(Vector3(p_point.x, p_point.y, 0), p_include_disabled);
 	return astar.get_closest_point(Vector3(p_point.x, p_point.y, 0), p_include_disabled);
 }
 }
 
 
@@ -654,7 +654,7 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
 	return Vector2(p.x, p.y);
 	return Vector2(p.x, p.y);
 }
 }
 
 
-real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
+real_t AStar2D::_estimate_cost(int64_t p_from_id, int64_t p_to_id) {
 	real_t scost;
 	real_t scost;
 	if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
 	if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
 		return scost;
 		return scost;
@@ -671,7 +671,7 @@ real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
 	return from_point->pos.distance_to(to_point->pos);
 	return from_point->pos.distance_to(to_point->pos);
 }
 }
 
 
-real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
+real_t AStar2D::_compute_cost(int64_t p_from_id, int64_t p_to_id) {
 	real_t scost;
 	real_t scost;
 	if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
 	if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
 		return scost;
 		return scost;
@@ -688,7 +688,7 @@ real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
 	return from_point->pos.distance_to(to_point->pos);
 	return from_point->pos.distance_to(to_point->pos);
 }
 }
 
 
-Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
+Vector<Vector2> AStar2D::get_point_path(int64_t p_from_id, int64_t p_to_id) {
 	AStar3D::Point *a;
 	AStar3D::Point *a;
 	bool from_exists = astar.points.lookup(p_from_id, a);
 	bool from_exists = astar.points.lookup(p_from_id, a);
 	ERR_FAIL_COND_V_MSG(!from_exists, Vector<Vector2>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_from_id));
 	ERR_FAIL_COND_V_MSG(!from_exists, Vector<Vector2>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_from_id));
@@ -711,7 +711,7 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
 	}
 	}
 
 
 	AStar3D::Point *p = end_point;
 	AStar3D::Point *p = end_point;
-	int pc = 1; // Begin point
+	int64_t pc = 1; // Begin point
 	while (p != begin_point) {
 	while (p != begin_point) {
 		pc++;
 		pc++;
 		p = p->prev_point;
 		p = p->prev_point;
@@ -724,7 +724,7 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
 		Vector2 *w = path.ptrw();
 		Vector2 *w = path.ptrw();
 
 
 		AStar3D::Point *p2 = end_point;
 		AStar3D::Point *p2 = end_point;
-		int idx = pc - 1;
+		int64_t idx = pc - 1;
 		while (p2 != begin_point) {
 		while (p2 != begin_point) {
 			w[idx--] = Vector2(p2->pos.x, p2->pos.y);
 			w[idx--] = Vector2(p2->pos.x, p2->pos.y);
 			p2 = p2->prev_point;
 			p2 = p2->prev_point;
@@ -736,17 +736,17 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
 	return path;
 	return path;
 }
 }
 
 
-Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
+Vector<int64_t> AStar2D::get_id_path(int64_t p_from_id, int64_t p_to_id) {
 	AStar3D::Point *a;
 	AStar3D::Point *a;
 	bool from_exists = astar.points.lookup(p_from_id, a);
 	bool from_exists = astar.points.lookup(p_from_id, a);
-	ERR_FAIL_COND_V_MSG(!from_exists, Vector<int>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_from_id));
+	ERR_FAIL_COND_V_MSG(!from_exists, Vector<int64_t>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_from_id));
 
 
 	AStar3D::Point *b;
 	AStar3D::Point *b;
 	bool to_exists = astar.points.lookup(p_to_id, b);
 	bool to_exists = astar.points.lookup(p_to_id, b);
-	ERR_FAIL_COND_V_MSG(!to_exists, Vector<int>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_to_id));
+	ERR_FAIL_COND_V_MSG(!to_exists, Vector<int64_t>(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_to_id));
 
 
 	if (a == b) {
 	if (a == b) {
-		Vector<int> ret;
+		Vector<int64_t> ret;
 		ret.push_back(a->id);
 		ret.push_back(a->id);
 		return ret;
 		return ret;
 	}
 	}
@@ -756,24 +756,24 @@ Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
 
 
 	bool found_route = _solve(begin_point, end_point);
 	bool found_route = _solve(begin_point, end_point);
 	if (!found_route) {
 	if (!found_route) {
-		return Vector<int>();
+		return Vector<int64_t>();
 	}
 	}
 
 
 	AStar3D::Point *p = end_point;
 	AStar3D::Point *p = end_point;
-	int pc = 1; // Begin point
+	int64_t pc = 1; // Begin point
 	while (p != begin_point) {
 	while (p != begin_point) {
 		pc++;
 		pc++;
 		p = p->prev_point;
 		p = p->prev_point;
 	}
 	}
 
 
-	Vector<int> path;
+	Vector<int64_t> path;
 	path.resize(pc);
 	path.resize(pc);
 
 
 	{
 	{
-		int *w = path.ptrw();
+		int64_t *w = path.ptrw();
 
 
 		p = end_point;
 		p = end_point;
-		int idx = pc - 1;
+		int64_t idx = pc - 1;
 		while (p != begin_point) {
 		while (p != begin_point) {
 			w[idx--] = p->id;
 			w[idx--] = p->id;
 			p = p->prev_point;
 			p = p->prev_point;
@@ -813,7 +813,7 @@ bool AStar2D::_solve(AStar3D::Point *begin_point, AStar3D::Point *end_point) {
 		open_list.remove_at(open_list.size() - 1);
 		open_list.remove_at(open_list.size() - 1);
 		p->closed_pass = astar.pass; // Mark the point as closed
 		p->closed_pass = astar.pass; // Mark the point as closed
 
 
-		for (OAHashMap<int, AStar3D::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+		for (OAHashMap<int64_t, AStar3D::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
 			AStar3D::Point *e = *(it.value); // The neighbour point
 			AStar3D::Point *e = *(it.value); // The neighbour point
 
 
 			if (!e->enabled || e->closed_pass == astar.pass) {
 			if (!e->enabled || e->closed_pass == astar.pass) {

+ 59 - 64
core/math/a_star.h

@@ -35,6 +35,7 @@
 #include "core/object/ref_counted.h"
 #include "core/object/ref_counted.h"
 #include "core/object/script_language.h"
 #include "core/object/script_language.h"
 #include "core/templates/oa_hash_map.h"
 #include "core/templates/oa_hash_map.h"
+#include "core/templates/pair.h"
 
 
 /**
 /**
 	A* pathfinding algorithm.
 	A* pathfinding algorithm.
@@ -47,13 +48,13 @@ class AStar3D : public RefCounted {
 	struct Point {
 	struct Point {
 		Point() {}
 		Point() {}
 
 
-		int id = 0;
+		int64_t id = 0;
 		Vector3 pos;
 		Vector3 pos;
 		real_t weight_scale = 0;
 		real_t weight_scale = 0;
 		bool enabled = false;
 		bool enabled = false;
 
 
-		OAHashMap<int, Point *> neighbours = 4u;
-		OAHashMap<int, Point *> unlinked_neighbours = 4u;
+		OAHashMap<int64_t, Point *> neighbours = 4u;
+		OAHashMap<int64_t, Point *> unlinked_neighbours = 4u;
 
 
 		// Used for pathfinding.
 		// Used for pathfinding.
 		Point *prev_point = nullptr;
 		Point *prev_point = nullptr;
@@ -76,13 +77,7 @@ class AStar3D : public RefCounted {
 	};
 	};
 
 
 	struct Segment {
 	struct Segment {
-		union {
-			struct {
-				int32_t u;
-				int32_t v;
-			};
-			uint64_t key = 0;
-		};
+		Pair<int64_t, int64_t> key;
 
 
 		enum {
 		enum {
 			NONE = 0,
 			NONE = 0,
@@ -93,28 +88,28 @@ class AStar3D : public RefCounted {
 		unsigned char direction = NONE;
 		unsigned char direction = NONE;
 
 
 		static uint32_t hash(const Segment &p_seg) {
 		static uint32_t hash(const Segment &p_seg) {
-			return hash_one_uint64(p_seg.key);
+			return PairHash<int64_t, int64_t>().hash(p_seg.key);
 		}
 		}
 		bool operator==(const Segment &p_s) const { return key == p_s.key; }
 		bool operator==(const Segment &p_s) const { return key == p_s.key; }
 
 
 		Segment() {}
 		Segment() {}
-		Segment(int p_from, int p_to) {
+		Segment(int64_t p_from, int64_t p_to) {
 			if (p_from < p_to) {
 			if (p_from < p_to) {
-				u = p_from;
-				v = p_to;
+				key.first = p_from;
+				key.second = p_to;
 				direction = FORWARD;
 				direction = FORWARD;
 			} else {
 			} else {
-				u = p_to;
-				v = p_from;
+				key.first = p_to;
+				key.second = p_from;
 				direction = BACKWARD;
 				direction = BACKWARD;
 			}
 			}
 		}
 		}
 	};
 	};
 
 
-	int last_free_id = 0;
+	int64_t last_free_id = 0;
 	uint64_t pass = 1;
 	uint64_t pass = 1;
 
 
-	OAHashMap<int, Point *> points;
+	OAHashMap<int64_t, Point *> points;
 	HashSet<Segment, Segment> segments;
 	HashSet<Segment, Segment> segments;
 
 
 	bool _solve(Point *begin_point, Point *end_point);
 	bool _solve(Point *begin_point, Point *end_point);
@@ -122,42 +117,42 @@ class AStar3D : public RefCounted {
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
 
 
-	virtual real_t _estimate_cost(int p_from_id, int p_to_id);
-	virtual real_t _compute_cost(int p_from_id, int p_to_id);
+	virtual real_t _estimate_cost(int64_t p_from_id, int64_t p_to_id);
+	virtual real_t _compute_cost(int64_t p_from_id, int64_t p_to_id);
 
 
 	GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
 	GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
 	GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
 	GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
 
 
 public:
 public:
-	int get_available_point_id() const;
-
-	void add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale = 1);
-	Vector3 get_point_position(int p_id) const;
-	void set_point_position(int p_id, const Vector3 &p_pos);
-	real_t get_point_weight_scale(int p_id) const;
-	void set_point_weight_scale(int p_id, real_t p_weight_scale);
-	void remove_point(int p_id);
-	bool has_point(int p_id) const;
-	Vector<int> get_point_connections(int p_id);
+	int64_t get_available_point_id() const;
+
+	void add_point(int64_t p_id, const Vector3 &p_pos, real_t p_weight_scale = 1);
+	Vector3 get_point_position(int64_t p_id) const;
+	void set_point_position(int64_t p_id, const Vector3 &p_pos);
+	real_t get_point_weight_scale(int64_t p_id) const;
+	void set_point_weight_scale(int64_t p_id, real_t p_weight_scale);
+	void remove_point(int64_t p_id);
+	bool has_point(int64_t p_id) const;
+	Vector<int64_t> get_point_connections(int64_t p_id);
 	Array get_point_ids();
 	Array get_point_ids();
 
 
-	void set_point_disabled(int p_id, bool p_disabled = true);
-	bool is_point_disabled(int p_id) const;
+	void set_point_disabled(int64_t p_id, bool p_disabled = true);
+	bool is_point_disabled(int64_t p_id) const;
 
 
-	void connect_points(int p_id, int p_with_id, bool bidirectional = true);
-	void disconnect_points(int p_id, int p_with_id, bool bidirectional = true);
-	bool are_points_connected(int p_id, int p_with_id, bool bidirectional = true) const;
+	void connect_points(int64_t p_id, int64_t p_with_id, bool bidirectional = true);
+	void disconnect_points(int64_t p_id, int64_t p_with_id, bool bidirectional = true);
+	bool are_points_connected(int64_t p_id, int64_t p_with_id, bool bidirectional = true) const;
 
 
-	int get_point_count() const;
-	int get_point_capacity() const;
-	void reserve_space(int p_num_nodes);
+	int64_t get_point_count() const;
+	int64_t get_point_capacity() const;
+	void reserve_space(int64_t p_num_nodes);
 	void clear();
 	void clear();
 
 
-	int get_closest_point(const Vector3 &p_point, bool p_include_disabled = false) const;
+	int64_t get_closest_point(const Vector3 &p_point, bool p_include_disabled = false) const;
 	Vector3 get_closest_position_in_segment(const Vector3 &p_point) const;
 	Vector3 get_closest_position_in_segment(const Vector3 &p_point) const;
 
 
-	Vector<Vector3> get_point_path(int p_from_id, int p_to_id);
-	Vector<int> get_id_path(int p_from_id, int p_to_id);
+	Vector<Vector3> get_point_path(int64_t p_from_id, int64_t p_to_id);
+	Vector<int64_t> get_id_path(int64_t p_from_id, int64_t p_to_id);
 
 
 	AStar3D() {}
 	AStar3D() {}
 	~AStar3D();
 	~AStar3D();
@@ -172,42 +167,42 @@ class AStar2D : public RefCounted {
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
 
 
-	virtual real_t _estimate_cost(int p_from_id, int p_to_id);
-	virtual real_t _compute_cost(int p_from_id, int p_to_id);
+	virtual real_t _estimate_cost(int64_t p_from_id, int64_t p_to_id);
+	virtual real_t _compute_cost(int64_t p_from_id, int64_t p_to_id);
 
 
 	GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
 	GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
 	GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
 	GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
 
 
 public:
 public:
-	int get_available_point_id() const;
-
-	void add_point(int p_id, const Vector2 &p_pos, real_t p_weight_scale = 1);
-	Vector2 get_point_position(int p_id) const;
-	void set_point_position(int p_id, const Vector2 &p_pos);
-	real_t get_point_weight_scale(int p_id) const;
-	void set_point_weight_scale(int p_id, real_t p_weight_scale);
-	void remove_point(int p_id);
-	bool has_point(int p_id) const;
-	Vector<int> get_point_connections(int p_id);
+	int64_t get_available_point_id() const;
+
+	void add_point(int64_t p_id, const Vector2 &p_pos, real_t p_weight_scale = 1);
+	Vector2 get_point_position(int64_t p_id) const;
+	void set_point_position(int64_t p_id, const Vector2 &p_pos);
+	real_t get_point_weight_scale(int64_t p_id) const;
+	void set_point_weight_scale(int64_t p_id, real_t p_weight_scale);
+	void remove_point(int64_t p_id);
+	bool has_point(int64_t p_id) const;
+	Vector<int64_t> get_point_connections(int64_t p_id);
 	Array get_point_ids();
 	Array get_point_ids();
 
 
-	void set_point_disabled(int p_id, bool p_disabled = true);
-	bool is_point_disabled(int p_id) const;
+	void set_point_disabled(int64_t p_id, bool p_disabled = true);
+	bool is_point_disabled(int64_t p_id) const;
 
 
-	void connect_points(int p_id, int p_with_id, bool p_bidirectional = true);
-	void disconnect_points(int p_id, int p_with_id, bool p_bidirectional = true);
-	bool are_points_connected(int p_id, int p_with_id, bool p_bidirectional = true) const;
+	void connect_points(int64_t p_id, int64_t p_with_id, bool p_bidirectional = true);
+	void disconnect_points(int64_t p_id, int64_t p_with_id, bool p_bidirectional = true);
+	bool are_points_connected(int64_t p_id, int64_t p_with_id, bool p_bidirectional = true) const;
 
 
-	int get_point_count() const;
-	int get_point_capacity() const;
-	void reserve_space(int p_num_nodes);
+	int64_t get_point_count() const;
+	int64_t get_point_capacity() const;
+	void reserve_space(int64_t p_num_nodes);
 	void clear();
 	void clear();
 
 
-	int get_closest_point(const Vector2 &p_point, bool p_include_disabled = false) const;
+	int64_t get_closest_point(const Vector2 &p_point, bool p_include_disabled = false) const;
 	Vector2 get_closest_position_in_segment(const Vector2 &p_point) const;
 	Vector2 get_closest_position_in_segment(const Vector2 &p_point) const;
 
 
-	Vector<Vector2> get_point_path(int p_from_id, int p_to_id);
-	Vector<int> get_id_path(int p_from_id, int p_to_id);
+	Vector<Vector2> get_point_path(int64_t p_from_id, int64_t p_to_id);
+	Vector<int64_t> get_id_path(int64_t p_from_id, int64_t p_to_id);
 
 
 	AStar2D() {}
 	AStar2D() {}
 	~AStar2D() {}
 	~AStar2D() {}

+ 2 - 2
doc/classes/AStar2D.xml

@@ -135,7 +135,7 @@
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_id_path">
 		<method name="get_id_path">
-			<return type="PackedInt32Array" />
+			<return type="PackedInt64Array" />
 			<argument index="0" name="from_id" type="int" />
 			<argument index="0" name="from_id" type="int" />
 			<argument index="1" name="to_id" type="int" />
 			<argument index="1" name="to_id" type="int" />
 			<description>
 			<description>
@@ -179,7 +179,7 @@
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_point_connections">
 		<method name="get_point_connections">
-			<return type="PackedInt32Array" />
+			<return type="PackedInt64Array" />
 			<argument index="0" name="id" type="int" />
 			<argument index="0" name="id" type="int" />
 			<description>
 			<description>
 				Returns an array with the IDs of the points that form the connection with the given point.
 				Returns an array with the IDs of the points that form the connection with the given point.

+ 2 - 2
doc/classes/AStar3D.xml

@@ -164,7 +164,7 @@
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_id_path">
 		<method name="get_id_path">
-			<return type="PackedInt32Array" />
+			<return type="PackedInt64Array" />
 			<argument index="0" name="from_id" type="int" />
 			<argument index="0" name="from_id" type="int" />
 			<argument index="1" name="to_id" type="int" />
 			<argument index="1" name="to_id" type="int" />
 			<description>
 			<description>
@@ -207,7 +207,7 @@
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_point_connections">
 		<method name="get_point_connections">
-			<return type="PackedInt32Array" />
+			<return type="PackedInt64Array" />
 			<argument index="0" name="id" type="int" />
 			<argument index="0" name="id" type="int" />
 			<description>
 			<description>
 				Returns an array with the IDs of the points that form the connection with the given point.
 				Returns an array with the IDs of the points that form the connection with the given point.

+ 4 - 4
tests/core/math/test_astar.h

@@ -58,7 +58,7 @@ public:
 	}
 	}
 
 
 	// Disable heuristic completely.
 	// Disable heuristic completely.
-	real_t _compute_cost(int p_from, int p_to) {
+	real_t _compute_cost(int64_t p_from, int64_t p_to) {
 		if (p_from == A && p_to == C) {
 		if (p_from == A && p_to == C) {
 			return 1000;
 			return 1000;
 		}
 		}
@@ -68,7 +68,7 @@ public:
 
 
 TEST_CASE("[AStar3D] ABC path") {
 TEST_CASE("[AStar3D] ABC path") {
 	ABCX abcx;
 	ABCX abcx;
-	Vector<int> path = abcx.get_id_path(ABCX::A, ABCX::C);
+	Vector<int64_t> path = abcx.get_id_path(ABCX::A, ABCX::C);
 	REQUIRE(path.size() == 3);
 	REQUIRE(path.size() == 3);
 	CHECK(path[0] == ABCX::A);
 	CHECK(path[0] == ABCX::A);
 	CHECK(path[1] == ABCX::B);
 	CHECK(path[1] == ABCX::B);
@@ -77,7 +77,7 @@ TEST_CASE("[AStar3D] ABC path") {
 
 
 TEST_CASE("[AStar3D] ABCX path") {
 TEST_CASE("[AStar3D] ABCX path") {
 	ABCX abcx;
 	ABCX abcx;
-	Vector<int> path = abcx.get_id_path(ABCX::X, ABCX::C);
+	Vector<int64_t> path = abcx.get_id_path(ABCX::X, ABCX::C);
 	REQUIRE(path.size() == 4);
 	REQUIRE(path.size() == 4);
 	CHECK(path[0] == ABCX::X);
 	CHECK(path[0] == ABCX::X);
 	CHECK(path[1] == ABCX::A);
 	CHECK(path[1] == ABCX::A);
@@ -318,7 +318,7 @@ TEST_CASE("[Stress][AStar3D] Find paths") {
 		for (int u = 0; u < N; u++) {
 		for (int u = 0; u < N; u++) {
 			for (int v = 0; v < N; v++) {
 			for (int v = 0; v < N; v++) {
 				if (u != v) {
 				if (u != v) {
-					Vector<int> route = a.get_id_path(u, v);
+					Vector<int64_t> route = a.get_id_path(u, v);
 					if (!Math::is_inf(d[u][v])) {
 					if (!Math::is_inf(d[u][v])) {
 						// Reachable.
 						// Reachable.
 						if (route.size() == 0) {
 						if (route.size() == 0) {