1 /**
2 AStar class representation that uses vectors as edges.
3 
4 Copyright:
5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.  
6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)  
7 Copyright (c) 2017-2018 Godot-D contributors  
8 
9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License)
10 
11 
12 */
13 module godot.astar;
14 import std.meta : AliasSeq, staticIndexOf;
15 import std.traits : Unqual;
16 import godot.d.meta;
17 import godot.core;
18 import godot.c;
19 import godot.d.bind;
20 import godot.d.reference;
21 import godot.object;
22 import godot.classdb;
23 import godot.reference;
24 /**
25 AStar class representation that uses vectors as edges.
26 
27 A* (A star) is a computer algorithm that is widely used in pathfinding and graph traversal, the process of plotting an efficiently directed path between multiple points. It enjoys widespread use due to its performance and accuracy. Godot's A* implementation make use of vectors as points.
28 You must add points manually with $(D AStar.addPoint) and create segments manually with $(D AStar.connectPoints). So you can test if there is a path between two points with the $(D AStar.arePointsConnected) function, get the list of existing ids in the found path with $(D AStar.getIdPath), or the points list with $(D AStar.getPointPath).
29 */
30 @GodotBaseClass struct AStar
31 {
32 	enum string _GODOT_internal_name = "AStar";
33 public:
34 @nogc nothrow:
35 	union { godot_object _godot_object; Reference _GODOT_base; }
36 	alias _GODOT_base this;
37 	alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses);
38 	package(godot) __gshared bool _classBindingInitialized = false;
39 	package(godot) static struct _classBinding
40 	{
41 		__gshared:
42 		@GodotName("_estimate_cost") GodotMethod!(double, long, long) _estimateCost;
43 		@GodotName("_compute_cost") GodotMethod!(double, long, long) _computeCost;
44 		@GodotName("get_available_point_id") GodotMethod!(long) getAvailablePointId;
45 		@GodotName("add_point") GodotMethod!(void, long, Vector3, double) addPoint;
46 		@GodotName("get_point_position") GodotMethod!(Vector3, long) getPointPosition;
47 		@GodotName("set_point_position") GodotMethod!(void, long, Vector3) setPointPosition;
48 		@GodotName("get_point_weight_scale") GodotMethod!(double, long) getPointWeightScale;
49 		@GodotName("set_point_weight_scale") GodotMethod!(void, long, double) setPointWeightScale;
50 		@GodotName("remove_point") GodotMethod!(void, long) removePoint;
51 		@GodotName("has_point") GodotMethod!(bool, long) hasPoint;
52 		@GodotName("get_points") GodotMethod!(Array) getPoints;
53 		@GodotName("get_point_connections") GodotMethod!(PoolIntArray, long) getPointConnections;
54 		@GodotName("connect_points") GodotMethod!(void, long, long, bool) connectPoints;
55 		@GodotName("disconnect_points") GodotMethod!(void, long, long) disconnectPoints;
56 		@GodotName("are_points_connected") GodotMethod!(bool, long, long) arePointsConnected;
57 		@GodotName("clear") GodotMethod!(void) clear;
58 		@GodotName("get_closest_point") GodotMethod!(long, Vector3) getClosestPoint;
59 		@GodotName("get_closest_position_in_segment") GodotMethod!(Vector3, Vector3) getClosestPositionInSegment;
60 		@GodotName("get_point_path") GodotMethod!(PoolVector3Array, long, long) getPointPath;
61 		@GodotName("get_id_path") GodotMethod!(PoolIntArray, long, long) getIdPath;
62 	}
63 	bool opEquals(in AStar other) const { return _godot_object.ptr is other._godot_object.ptr; }
64 	AStar opAssign(T : typeof(null))(T n) { _godot_object.ptr = null; }
65 	bool opEquals(typeof(null) n) const { return _godot_object.ptr is null; }
66 	mixin baseCasts;
67 	static AStar _new()
68 	{
69 		static godot_class_constructor constructor;
70 		if(constructor is null) constructor = _godot_api.godot_get_class_constructor("AStar");
71 		if(constructor is null) return typeof(this).init;
72 		return cast(AStar)(constructor());
73 	}
74 	@disable new(size_t s);
75 	/**
76 	Called when estimating the cost between a point and the path's ending point.
77 	*/
78 	double _estimateCost(in long from_id, in long to_id)
79 	{
80 		Array _GODOT_args = Array.empty_array;
81 		_GODOT_args.append(from_id);
82 		_GODOT_args.append(to_id);
83 		String _GODOT_method_name = String("_estimate_cost");
84 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!double);
85 	}
86 	/**
87 	Called when computing the cost between two connected points.
88 	*/
89 	double _computeCost(in long from_id, in long to_id)
90 	{
91 		Array _GODOT_args = Array.empty_array;
92 		_GODOT_args.append(from_id);
93 		_GODOT_args.append(to_id);
94 		String _GODOT_method_name = String("_compute_cost");
95 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!double);
96 	}
97 	/**
98 	Returns the next available point id with no point associated to it.
99 	*/
100 	long getAvailablePointId() const
101 	{
102 		checkClassBinding!(typeof(this))();
103 		return ptrcall!(long)(_classBinding.getAvailablePointId, _godot_object);
104 	}
105 	/**
106 	Adds a new point at the given position with the given identifier. The algorithm prefers points with lower `weight_scale` to form a path. The `id` must be 0 or larger, and the `weight_scale` must be 1 or larger.
107 	
108 	
109 	var as = AStar.new()
110 	
111 	as.add_point(1, Vector3(1,0,0), 4) # Adds the point (1,0,0) with weight_scale=4 and id=1
112 	
113 	
114 	If there already exists a point for the given id, its position and weight scale are updated to the given values.
115 	*/
116 	void addPoint(in long id, in Vector3 position, in double weight_scale = 1)
117 	{
118 		checkClassBinding!(typeof(this))();
119 		ptrcall!(void)(_classBinding.addPoint, _godot_object, id, position, weight_scale);
120 	}
121 	/**
122 	Returns the position of the point associated with the given id.
123 	*/
124 	Vector3 getPointPosition(in long id) const
125 	{
126 		checkClassBinding!(typeof(this))();
127 		return ptrcall!(Vector3)(_classBinding.getPointPosition, _godot_object, id);
128 	}
129 	/**
130 	Sets the position for the point with the given id.
131 	*/
132 	void setPointPosition(in long id, in Vector3 position)
133 	{
134 		checkClassBinding!(typeof(this))();
135 		ptrcall!(void)(_classBinding.setPointPosition, _godot_object, id, position);
136 	}
137 	/**
138 	Returns the weight scale of the point associated with the given id.
139 	*/
140 	double getPointWeightScale(in long id) const
141 	{
142 		checkClassBinding!(typeof(this))();
143 		return ptrcall!(double)(_classBinding.getPointWeightScale, _godot_object, id);
144 	}
145 	/**
146 	Sets the `weight_scale` for the point with the given id.
147 	*/
148 	void setPointWeightScale(in long id, in double weight_scale)
149 	{
150 		checkClassBinding!(typeof(this))();
151 		ptrcall!(void)(_classBinding.setPointWeightScale, _godot_object, id, weight_scale);
152 	}
153 	/**
154 	Removes the point associated with the given id from the points pool.
155 	*/
156 	void removePoint(in long id)
157 	{
158 		checkClassBinding!(typeof(this))();
159 		ptrcall!(void)(_classBinding.removePoint, _godot_object, id);
160 	}
161 	/**
162 	Returns whether a point associated with the given id exists.
163 	*/
164 	bool hasPoint(in long id) const
165 	{
166 		checkClassBinding!(typeof(this))();
167 		return ptrcall!(bool)(_classBinding.hasPoint, _godot_object, id);
168 	}
169 	/**
170 	Returns an array of all points.
171 	*/
172 	Array getPoints()
173 	{
174 		checkClassBinding!(typeof(this))();
175 		return ptrcall!(Array)(_classBinding.getPoints, _godot_object);
176 	}
177 	/**
178 	Returns an array with the ids of the points that form the connect with the given point.
179 	
180 	
181 	var as = AStar.new()
182 	
183 	as.add_point(1, Vector3(0,0,0))
184 	as.add_point(2, Vector3(0,1,0))
185 	as.add_point(3, Vector3(1,1,0))
186 	as.add_point(4, Vector3(2,0,0))
187 	
188 	as.connect_points(1, 2, true)
189 	as.connect_points(1, 3, true)
190 	
191 	var neighbors = as.get_point_connections(1) # returns $(D 2, 3)
192 	
193 	
194 	*/
195 	PoolIntArray getPointConnections(in long id)
196 	{
197 		checkClassBinding!(typeof(this))();
198 		return ptrcall!(PoolIntArray)(_classBinding.getPointConnections, _godot_object, id);
199 	}
200 	/**
201 	Creates a segment between the given points.
202 	
203 	
204 	var as = AStar.new()
205 	
206 	as.add_point(1, Vector3(1,1,0))
207 	as.add_point(2, Vector3(0,5,0))
208 	
209 	as.connect_points(1, 2, false) # If bidirectional=false it's only possible to go from point 1 to point 2
210 	                               # and not from point 2 to point 1.
211 	
212 	
213 	*/
214 	void connectPoints(in long id, in long to_id, in bool bidirectional = true)
215 	{
216 		checkClassBinding!(typeof(this))();
217 		ptrcall!(void)(_classBinding.connectPoints, _godot_object, id, to_id, bidirectional);
218 	}
219 	/**
220 	Deletes the segment between the given points.
221 	*/
222 	void disconnectPoints(in long id, in long to_id)
223 	{
224 		checkClassBinding!(typeof(this))();
225 		ptrcall!(void)(_classBinding.disconnectPoints, _godot_object, id, to_id);
226 	}
227 	/**
228 	Returns whether there is a connection/segment between the given points.
229 	*/
230 	bool arePointsConnected(in long id, in long to_id) const
231 	{
232 		checkClassBinding!(typeof(this))();
233 		return ptrcall!(bool)(_classBinding.arePointsConnected, _godot_object, id, to_id);
234 	}
235 	/**
236 	Clears all the points and segments.
237 	*/
238 	void clear()
239 	{
240 		checkClassBinding!(typeof(this))();
241 		ptrcall!(void)(_classBinding.clear, _godot_object);
242 	}
243 	/**
244 	Returns the id of the closest point to `to_position`. Returns -1 if there are no points in the points pool.
245 	*/
246 	long getClosestPoint(in Vector3 to_position) const
247 	{
248 		checkClassBinding!(typeof(this))();
249 		return ptrcall!(long)(_classBinding.getClosestPoint, _godot_object, to_position);
250 	}
251 	/**
252 	Returns the closest position to `to_position` that resides inside a segment between two connected points.
253 	
254 	
255 	var as = AStar.new()
256 	
257 	as.add_point(1, Vector3(0,0,0))
258 	as.add_point(2, Vector3(0,5,0))
259 	
260 	as.connect_points(1, 2)
261 	
262 	var res = as.get_closest_position_in_segment(Vector3(3,3,0)) # returns (0, 3, 0)
263 	
264 	
265 	The result is in the segment that goes from `y=0` to `y=5`. It's the closest position in the segment to the given point.
266 	*/
267 	Vector3 getClosestPositionInSegment(in Vector3 to_position) const
268 	{
269 		checkClassBinding!(typeof(this))();
270 		return ptrcall!(Vector3)(_classBinding.getClosestPositionInSegment, _godot_object, to_position);
271 	}
272 	/**
273 	Returns an array with the points that are in the path found by AStar between the given points. The array is ordered from the starting point to the ending point of the path.
274 	*/
275 	PoolVector3Array getPointPath(in long from_id, in long to_id)
276 	{
277 		checkClassBinding!(typeof(this))();
278 		return ptrcall!(PoolVector3Array)(_classBinding.getPointPath, _godot_object, from_id, to_id);
279 	}
280 	/**
281 	Returns an array with the ids of the points that form the path found by AStar between the given points. The array is ordered from the starting point to the ending point of the path.
282 	
283 	
284 	var as = AStar.new()
285 	
286 	as.add_point(1, Vector3(0,0,0))
287 	as.add_point(2, Vector3(0,1,0), 1) # default weight is 1
288 	as.add_point(3, Vector3(1,1,0))
289 	as.add_point(4, Vector3(2,0,0))
290 	
291 	as.connect_points(1, 2, false)
292 	as.connect_points(2, 3, false)
293 	as.connect_points(4, 3, false)
294 	as.connect_points(1, 4, false)
295 	as.connect_points(5, 4, false)
296 	
297 	var res = as.get_id_path(1, 3) # returns $(D 1, 2, 3)
298 	
299 	
300 	If you change the 2nd point's weight to 3, then the result will be `$(D 1, 4, 3)` instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
301 	*/
302 	PoolIntArray getIdPath(in long from_id, in long to_id)
303 	{
304 		checkClassBinding!(typeof(this))();
305 		return ptrcall!(PoolIntArray)(_classBinding.getIdPath, _godot_object, from_id, to_id);
306 	}
307 }