1 /**
2 SkeletonIK is used to place the end bone of a $(D Skeleton) bone chain at a certain point in 3D by rotating all bones in the chain accordingly.
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.skeletonik;
14 import std.meta : AliasSeq, staticIndexOf;
15 import std.traits : Unqual;
16 import godot.d.traits;
17 import godot.core;
18 import godot.c;
19 import godot.d.bind;
20 import godot.d.reference;
21 import godot.globalenums;
22 import godot.object;
23 import godot.classdb;
24 import godot.node;
25 import godot.skeleton;
26 /**
27 SkeletonIK is used to place the end bone of a $(D Skeleton) bone chain at a certain point in 3D by rotating all bones in the chain accordingly.
28 
29 A typical scenario for IK in games is to place a characters feet on the ground or a characters hands on a currently hold object. SkeletonIK uses FabrikInverseKinematic internally to solve the bone chain and applies the results to the $(D Skeleton) `bones_global_pose_override` property for all affected bones in the chain. If fully applied this overwrites any bone transform from $(D Animation)s or bone custom poses set by users. The applied amount can be controlled with the `interpolation` property.
30 
31 
32 # Apply IK effect automatically on every new frame (not the current)
33 skeleton_ik_node.start()
34 
35 # Apply IK effect only on the current frame
36 skeleton_ik_node.start(true)
37 
38 # Stop IK effect and reset bones_global_pose_override on Skeleton
39 skeleton_ik_node.stop()
40 
41 # Apply full IK effect
42 skeleton_ik_node.set_interpolation(1.0)
43 
44 # Apply half IK effect
45 skeleton_ik_node.set_interpolation(0.5)
46 
47 # Apply zero IK effect (a value at or below 0.01 also removes bones_global_pose_override on Skeleton)
48 skeleton_ik_node.set_interpolation(0.0)
49 
50 
51 */
52 @GodotBaseClass struct SkeletonIK
53 {
54 	package(godot) enum string _GODOT_internal_name = "SkeletonIK";
55 public:
56 @nogc nothrow:
57 	union { /** */ godot_object _godot_object; /** */ Node _GODOT_base; }
58 	alias _GODOT_base this;
59 	alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses);
60 	package(godot) __gshared bool _classBindingInitialized = false;
61 	package(godot) static struct GDNativeClassBinding
62 	{
63 		__gshared:
64 		@GodotName("get_interpolation") GodotMethod!(double) getInterpolation;
65 		@GodotName("get_magnet_position") GodotMethod!(Vector3) getMagnetPosition;
66 		@GodotName("get_max_iterations") GodotMethod!(long) getMaxIterations;
67 		@GodotName("get_min_distance") GodotMethod!(double) getMinDistance;
68 		@GodotName("get_parent_skeleton") GodotMethod!(Skeleton) getParentSkeleton;
69 		@GodotName("get_root_bone") GodotMethod!(String) getRootBone;
70 		@GodotName("get_target_node") GodotMethod!(NodePath) getTargetNode;
71 		@GodotName("get_target_transform") GodotMethod!(Transform) getTargetTransform;
72 		@GodotName("get_tip_bone") GodotMethod!(String) getTipBone;
73 		@GodotName("is_override_tip_basis") GodotMethod!(bool) isOverrideTipBasis;
74 		@GodotName("is_running") GodotMethod!(bool) isRunning;
75 		@GodotName("is_using_magnet") GodotMethod!(bool) isUsingMagnet;
76 		@GodotName("set_interpolation") GodotMethod!(void, double) setInterpolation;
77 		@GodotName("set_magnet_position") GodotMethod!(void, Vector3) setMagnetPosition;
78 		@GodotName("set_max_iterations") GodotMethod!(void, long) setMaxIterations;
79 		@GodotName("set_min_distance") GodotMethod!(void, double) setMinDistance;
80 		@GodotName("set_override_tip_basis") GodotMethod!(void, bool) setOverrideTipBasis;
81 		@GodotName("set_root_bone") GodotMethod!(void, String) setRootBone;
82 		@GodotName("set_target_node") GodotMethod!(void, NodePath) setTargetNode;
83 		@GodotName("set_target_transform") GodotMethod!(void, Transform) setTargetTransform;
84 		@GodotName("set_tip_bone") GodotMethod!(void, String) setTipBone;
85 		@GodotName("set_use_magnet") GodotMethod!(void, bool) setUseMagnet;
86 		@GodotName("start") GodotMethod!(void, bool) start;
87 		@GodotName("stop") GodotMethod!(void) stop;
88 	}
89 	/// 
90 	pragma(inline, true) bool opEquals(in SkeletonIK other) const
91 	{ return _godot_object.ptr is other._godot_object.ptr; }
92 	/// 
93 	pragma(inline, true) typeof(null) opAssign(typeof(null) n)
94 	{ _godot_object.ptr = n; return null; }
95 	/// 
96 	pragma(inline, true) bool opEquals(typeof(null) n) const
97 	{ return _godot_object.ptr is n; }
98 	/// 
99 	size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; }
100 	mixin baseCasts;
101 	/// Construct a new instance of SkeletonIK.
102 	/// Note: use `memnew!SkeletonIK` instead.
103 	static SkeletonIK _new()
104 	{
105 		static godot_class_constructor constructor;
106 		if(constructor is null) constructor = _godot_api.godot_get_class_constructor("SkeletonIK");
107 		if(constructor is null) return typeof(this).init;
108 		return cast(SkeletonIK)(constructor());
109 	}
110 	@disable new(size_t s);
111 	/**
112 	
113 	*/
114 	double getInterpolation() const
115 	{
116 		checkClassBinding!(typeof(this))();
117 		return ptrcall!(double)(GDNativeClassBinding.getInterpolation, _godot_object);
118 	}
119 	/**
120 	
121 	*/
122 	Vector3 getMagnetPosition() const
123 	{
124 		checkClassBinding!(typeof(this))();
125 		return ptrcall!(Vector3)(GDNativeClassBinding.getMagnetPosition, _godot_object);
126 	}
127 	/**
128 	
129 	*/
130 	long getMaxIterations() const
131 	{
132 		checkClassBinding!(typeof(this))();
133 		return ptrcall!(long)(GDNativeClassBinding.getMaxIterations, _godot_object);
134 	}
135 	/**
136 	
137 	*/
138 	double getMinDistance() const
139 	{
140 		checkClassBinding!(typeof(this))();
141 		return ptrcall!(double)(GDNativeClassBinding.getMinDistance, _godot_object);
142 	}
143 	/**
144 	Returns the parent $(D Skeleton) Node that was present when SkeletonIK entered the $(D SceneTree). Returns null if the parent node was not a $(D Skeleton) Node when SkeletonIK entered the $(D SceneTree).
145 	*/
146 	Skeleton getParentSkeleton() const
147 	{
148 		checkClassBinding!(typeof(this))();
149 		return ptrcall!(Skeleton)(GDNativeClassBinding.getParentSkeleton, _godot_object);
150 	}
151 	/**
152 	
153 	*/
154 	String getRootBone() const
155 	{
156 		checkClassBinding!(typeof(this))();
157 		return ptrcall!(String)(GDNativeClassBinding.getRootBone, _godot_object);
158 	}
159 	/**
160 	
161 	*/
162 	NodePath getTargetNode()
163 	{
164 		checkClassBinding!(typeof(this))();
165 		return ptrcall!(NodePath)(GDNativeClassBinding.getTargetNode, _godot_object);
166 	}
167 	/**
168 	
169 	*/
170 	Transform getTargetTransform() const
171 	{
172 		checkClassBinding!(typeof(this))();
173 		return ptrcall!(Transform)(GDNativeClassBinding.getTargetTransform, _godot_object);
174 	}
175 	/**
176 	
177 	*/
178 	String getTipBone() const
179 	{
180 		checkClassBinding!(typeof(this))();
181 		return ptrcall!(String)(GDNativeClassBinding.getTipBone, _godot_object);
182 	}
183 	/**
184 	
185 	*/
186 	bool isOverrideTipBasis() const
187 	{
188 		checkClassBinding!(typeof(this))();
189 		return ptrcall!(bool)(GDNativeClassBinding.isOverrideTipBasis, _godot_object);
190 	}
191 	/**
192 	Returns `true` if SkeletonIK is applying IK effects on continues frames to the $(D Skeleton) bones. Returns `false` if SkeletonIK is stopped or $(D start) was used with the `one_time` parameter set to `true`.
193 	*/
194 	bool isRunning()
195 	{
196 		checkClassBinding!(typeof(this))();
197 		return ptrcall!(bool)(GDNativeClassBinding.isRunning, _godot_object);
198 	}
199 	/**
200 	
201 	*/
202 	bool isUsingMagnet() const
203 	{
204 		checkClassBinding!(typeof(this))();
205 		return ptrcall!(bool)(GDNativeClassBinding.isUsingMagnet, _godot_object);
206 	}
207 	/**
208 	
209 	*/
210 	void setInterpolation(in double interpolation)
211 	{
212 		checkClassBinding!(typeof(this))();
213 		ptrcall!(void)(GDNativeClassBinding.setInterpolation, _godot_object, interpolation);
214 	}
215 	/**
216 	
217 	*/
218 	void setMagnetPosition(in Vector3 local_position)
219 	{
220 		checkClassBinding!(typeof(this))();
221 		ptrcall!(void)(GDNativeClassBinding.setMagnetPosition, _godot_object, local_position);
222 	}
223 	/**
224 	
225 	*/
226 	void setMaxIterations(in long iterations)
227 	{
228 		checkClassBinding!(typeof(this))();
229 		ptrcall!(void)(GDNativeClassBinding.setMaxIterations, _godot_object, iterations);
230 	}
231 	/**
232 	
233 	*/
234 	void setMinDistance(in double min_distance)
235 	{
236 		checkClassBinding!(typeof(this))();
237 		ptrcall!(void)(GDNativeClassBinding.setMinDistance, _godot_object, min_distance);
238 	}
239 	/**
240 	
241 	*/
242 	void setOverrideTipBasis(in bool _override)
243 	{
244 		checkClassBinding!(typeof(this))();
245 		ptrcall!(void)(GDNativeClassBinding.setOverrideTipBasis, _godot_object, _override);
246 	}
247 	/**
248 	
249 	*/
250 	void setRootBone(in String root_bone)
251 	{
252 		checkClassBinding!(typeof(this))();
253 		ptrcall!(void)(GDNativeClassBinding.setRootBone, _godot_object, root_bone);
254 	}
255 	/**
256 	
257 	*/
258 	void setTargetNode(NodePathArg0)(in NodePathArg0 node)
259 	{
260 		checkClassBinding!(typeof(this))();
261 		ptrcall!(void)(GDNativeClassBinding.setTargetNode, _godot_object, node);
262 	}
263 	/**
264 	
265 	*/
266 	void setTargetTransform(in Transform target)
267 	{
268 		checkClassBinding!(typeof(this))();
269 		ptrcall!(void)(GDNativeClassBinding.setTargetTransform, _godot_object, target);
270 	}
271 	/**
272 	
273 	*/
274 	void setTipBone(in String tip_bone)
275 	{
276 		checkClassBinding!(typeof(this))();
277 		ptrcall!(void)(GDNativeClassBinding.setTipBone, _godot_object, tip_bone);
278 	}
279 	/**
280 	
281 	*/
282 	void setUseMagnet(in bool use)
283 	{
284 		checkClassBinding!(typeof(this))();
285 		ptrcall!(void)(GDNativeClassBinding.setUseMagnet, _godot_object, use);
286 	}
287 	/**
288 	Starts applying IK effects on each frame to the $(D Skeleton) bones but will only take effect starting on the next frame. If `one_time` is `true`, this will take effect immediately but also reset on the next frame.
289 	*/
290 	void start(in bool one_time = false)
291 	{
292 		checkClassBinding!(typeof(this))();
293 		ptrcall!(void)(GDNativeClassBinding.start, _godot_object, one_time);
294 	}
295 	/**
296 	Stops applying IK effects on each frame to the $(D Skeleton) bones and also calls $(D Skeleton.clearBonesGlobalPoseOverride) to remove existing overrides on all bones.
297 	*/
298 	void stop()
299 	{
300 		checkClassBinding!(typeof(this))();
301 		ptrcall!(void)(GDNativeClassBinding.stop, _godot_object);
302 	}
303 	/**
304 	Interpolation value for how much the IK results are applied to the current skeleton bone chain. A value of `1.0` will overwrite all skeleton bone transforms completely while a value of `0.0` will visually disable the SkeletonIK. A value at or below `0.01` also calls $(D Skeleton.clearBonesGlobalPoseOverride).
305 	*/
306 	@property double interpolation()
307 	{
308 		return getInterpolation();
309 	}
310 	/// ditto
311 	@property void interpolation(double v)
312 	{
313 		setInterpolation(v);
314 	}
315 	/**
316 	Secondary target position (first is $(D target) property or $(D targetNode)) for the IK chain. Use magnet position (pole target) to control the bending of the IK chain. Only works if the bone chain has more than 2 bones. The middle chain bone position will be linearly interpolated with the magnet position.
317 	*/
318 	@property Vector3 magnet()
319 	{
320 		return getMagnetPosition();
321 	}
322 	/// ditto
323 	@property void magnet(Vector3 v)
324 	{
325 		setMagnetPosition(v);
326 	}
327 	/**
328 	Number of iteration loops used by the IK solver to produce more accurate (and elegant) bone chain results.
329 	*/
330 	@property long maxIterations()
331 	{
332 		return getMaxIterations();
333 	}
334 	/// ditto
335 	@property void maxIterations(long v)
336 	{
337 		setMaxIterations(v);
338 	}
339 	/**
340 	The minimum distance between bone and goal target. If the distance is below this value, the IK solver stops further iterations.
341 	*/
342 	@property double minDistance()
343 	{
344 		return getMinDistance();
345 	}
346 	/// ditto
347 	@property void minDistance(double v)
348 	{
349 		setMinDistance(v);
350 	}
351 	/**
352 	If `true` overwrites the rotation of the tip bone with the rotation of the $(D target) (or $(D targetNode) if defined).
353 	*/
354 	@property bool overrideTipBasis()
355 	{
356 		return isOverrideTipBasis();
357 	}
358 	/// ditto
359 	@property void overrideTipBasis(bool v)
360 	{
361 		setOverrideTipBasis(v);
362 	}
363 	/**
364 	The name of the current root bone, the first bone in the IK chain.
365 	*/
366 	@property String rootBone()
367 	{
368 		return getRootBone();
369 	}
370 	/// ditto
371 	@property void rootBone(String v)
372 	{
373 		setRootBone(v);
374 	}
375 	/**
376 	First target of the IK chain where the tip bone is placed and, if $(D overrideTipBasis) is `true`, how the tip bone is rotated. If a $(D targetNode) path is available the nodes transform is used instead and this property is ignored.
377 	*/
378 	@property Transform target()
379 	{
380 		return getTargetTransform();
381 	}
382 	/// ditto
383 	@property void target(Transform v)
384 	{
385 		setTargetTransform(v);
386 	}
387 	/**
388 	Target node $(D NodePath) for the IK chain. If available, the node's current $(D Transform) is used instead of the $(D target) property.
389 	*/
390 	@property NodePath targetNode()
391 	{
392 		return getTargetNode();
393 	}
394 	/// ditto
395 	@property void targetNode(NodePath v)
396 	{
397 		setTargetNode(v);
398 	}
399 	/**
400 	The name of the current tip bone, the last bone in the IK chain placed at the $(D target) transform (or $(D targetNode) if defined).
401 	*/
402 	@property String tipBone()
403 	{
404 		return getTipBone();
405 	}
406 	/// ditto
407 	@property void tipBone(String v)
408 	{
409 		setTipBone(v);
410 	}
411 	/**
412 	If `true`, instructs the IK solver to consider the secondary magnet target (pole target) when calculating the bone chain. Use the magnet position (pole target) to control the bending of the IK chain.
413 	*/
414 	@property bool useMagnet()
415 	{
416 		return isUsingMagnet();
417 	}
418 	/// ditto
419 	@property void useMagnet(bool v)
420 	{
421 		setUseMagnet(v);
422 	}
423 }