1 /**
2 Kinematic body 3D node.
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.kinematicbody;
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.physicsbody;
25 import godot.kinematiccollision;
26 /**
27 Kinematic body 3D node.
28 
29 Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses:
30 $(B Simulated motion:) When these bodies are moved manually, either from code or from an $(D AnimationPlayer) (with $(D AnimationPlayer.playbackProcessMode) set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
31 $(B Kinematic characters:) KinematicBody also has an API for moving objects (the $(D moveAndCollide) and $(D moveAndSlide) methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but don't require advanced physics.
32 */
33 @GodotBaseClass struct KinematicBody
34 {
35 	package(godot) enum string _GODOT_internal_name = "KinematicBody";
36 public:
37 @nogc nothrow:
38 	union { /** */ godot_object _godot_object; /** */ PhysicsBody _GODOT_base; }
39 	alias _GODOT_base this;
40 	alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses);
41 	package(godot) __gshared bool _classBindingInitialized = false;
42 	package(godot) static struct GDNativeClassBinding
43 	{
44 		__gshared:
45 		@GodotName("get_axis_lock") GodotMethod!(bool, long) getAxisLock;
46 		@GodotName("get_floor_normal") GodotMethod!(Vector3) getFloorNormal;
47 		@GodotName("get_floor_velocity") GodotMethod!(Vector3) getFloorVelocity;
48 		@GodotName("get_safe_margin") GodotMethod!(double) getSafeMargin;
49 		@GodotName("get_slide_collision") GodotMethod!(KinematicCollision, long) getSlideCollision;
50 		@GodotName("get_slide_count") GodotMethod!(long) getSlideCount;
51 		@GodotName("is_on_ceiling") GodotMethod!(bool) isOnCeiling;
52 		@GodotName("is_on_floor") GodotMethod!(bool) isOnFloor;
53 		@GodotName("is_on_wall") GodotMethod!(bool) isOnWall;
54 		@GodotName("move_and_collide") GodotMethod!(KinematicCollision, Vector3, bool, bool, bool) moveAndCollide;
55 		@GodotName("move_and_slide") GodotMethod!(Vector3, Vector3, Vector3, bool, long, double, bool) moveAndSlide;
56 		@GodotName("move_and_slide_with_snap") GodotMethod!(Vector3, Vector3, Vector3, Vector3, bool, long, double, bool) moveAndSlideWithSnap;
57 		@GodotName("set_axis_lock") GodotMethod!(void, long, bool) setAxisLock;
58 		@GodotName("set_safe_margin") GodotMethod!(void, double) setSafeMargin;
59 		@GodotName("test_move") GodotMethod!(bool, Transform, Vector3, bool) testMove;
60 	}
61 	/// 
62 	pragma(inline, true) bool opEquals(in KinematicBody other) const
63 	{ return _godot_object.ptr is other._godot_object.ptr; }
64 	/// 
65 	pragma(inline, true) typeof(null) opAssign(typeof(null) n)
66 	{ _godot_object.ptr = n; return null; }
67 	/// 
68 	pragma(inline, true) bool opEquals(typeof(null) n) const
69 	{ return _godot_object.ptr is n; }
70 	/// 
71 	size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; }
72 	mixin baseCasts;
73 	/// Construct a new instance of KinematicBody.
74 	/// Note: use `memnew!KinematicBody` instead.
75 	static KinematicBody _new()
76 	{
77 		static godot_class_constructor constructor;
78 		if(constructor is null) constructor = _godot_api.godot_get_class_constructor("KinematicBody");
79 		if(constructor is null) return typeof(this).init;
80 		return cast(KinematicBody)(constructor());
81 	}
82 	@disable new(size_t s);
83 	/**
84 	Returns `true` if the specified `axis` is locked. See also $(D moveLockX), $(D moveLockY) and $(D moveLockZ).
85 	*/
86 	bool getAxisLock(in long axis) const
87 	{
88 		checkClassBinding!(typeof(this))();
89 		return ptrcall!(bool)(GDNativeClassBinding.getAxisLock, _godot_object, axis);
90 	}
91 	/**
92 	Returns the surface normal of the floor at the last collision point. Only valid after calling $(D moveAndSlide) or $(D moveAndSlideWithSnap) and when $(D isOnFloor) returns `true`.
93 	*/
94 	Vector3 getFloorNormal() const
95 	{
96 		checkClassBinding!(typeof(this))();
97 		return ptrcall!(Vector3)(GDNativeClassBinding.getFloorNormal, _godot_object);
98 	}
99 	/**
100 	Returns the linear velocity of the floor at the last collision point. Only valid after calling $(D moveAndSlide) or $(D moveAndSlideWithSnap) and when $(D isOnFloor) returns `true`.
101 	*/
102 	Vector3 getFloorVelocity() const
103 	{
104 		checkClassBinding!(typeof(this))();
105 		return ptrcall!(Vector3)(GDNativeClassBinding.getFloorVelocity, _godot_object);
106 	}
107 	/**
108 	
109 	*/
110 	double getSafeMargin() const
111 	{
112 		checkClassBinding!(typeof(this))();
113 		return ptrcall!(double)(GDNativeClassBinding.getSafeMargin, _godot_object);
114 	}
115 	/**
116 	Returns a $(D KinematicCollision), which contains information about a collision that occurred during the last call to $(D moveAndSlide) or $(D moveAndSlideWithSnap). Since the body can collide several times in a single call to $(D moveAndSlide), you must specify the index of the collision in the range 0 to ($(D getSlideCount) - 1).
117 	*/
118 	Ref!KinematicCollision getSlideCollision(in long slide_idx)
119 	{
120 		checkClassBinding!(typeof(this))();
121 		return ptrcall!(KinematicCollision)(GDNativeClassBinding.getSlideCollision, _godot_object, slide_idx);
122 	}
123 	/**
124 	Returns the number of times the body collided and changed direction during the last call to $(D moveAndSlide) or $(D moveAndSlideWithSnap).
125 	*/
126 	long getSlideCount() const
127 	{
128 		checkClassBinding!(typeof(this))();
129 		return ptrcall!(long)(GDNativeClassBinding.getSlideCount, _godot_object);
130 	}
131 	/**
132 	Returns `true` if the body collided with the ceiling on the last call of $(D moveAndSlide) or $(D moveAndSlideWithSnap). Otherwise, returns `false`.
133 	*/
134 	bool isOnCeiling() const
135 	{
136 		checkClassBinding!(typeof(this))();
137 		return ptrcall!(bool)(GDNativeClassBinding.isOnCeiling, _godot_object);
138 	}
139 	/**
140 	Returns `true` if the body collided with the floor on the last call of $(D moveAndSlide) or $(D moveAndSlideWithSnap). Otherwise, returns `false`.
141 	*/
142 	bool isOnFloor() const
143 	{
144 		checkClassBinding!(typeof(this))();
145 		return ptrcall!(bool)(GDNativeClassBinding.isOnFloor, _godot_object);
146 	}
147 	/**
148 	Returns `true` if the body collided with a wall on the last call of $(D moveAndSlide) or $(D moveAndSlideWithSnap). Otherwise, returns `false`.
149 	*/
150 	bool isOnWall() const
151 	{
152 		checkClassBinding!(typeof(this))();
153 		return ptrcall!(bool)(GDNativeClassBinding.isOnWall, _godot_object);
154 	}
155 	/**
156 	Moves the body along the vector `rel_vec`. The body will stop if it collides. Returns a $(D KinematicCollision), which contains information about the collision.
157 	If `test_only` is `true`, the body does not move but the would-be collision information is given.
158 	*/
159 	Ref!KinematicCollision moveAndCollide(in Vector3 rel_vec, in bool infinite_inertia = true, in bool exclude_raycast_shapes = true, in bool test_only = false)
160 	{
161 		checkClassBinding!(typeof(this))();
162 		return ptrcall!(KinematicCollision)(GDNativeClassBinding.moveAndCollide, _godot_object, rel_vec, infinite_inertia, exclude_raycast_shapes, test_only);
163 	}
164 	/**
165 	Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a $(D KinematicBody) or $(D RigidBody), it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes.
166 	This method should be used in $(D Node._physicsProcess) (or in a method called by $(D Node._physicsProcess)), as it uses the physics step's `delta` value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
167 	`linear_velocity` is the velocity vector (typically meters per second). Unlike in $(D moveAndCollide), you should $(I not) multiply it by `delta` — the physics engine handles applying the velocity.
168 	`up_direction` is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of `Vector3(0, 0, 0)`, everything is considered a wall.
169 	If `stop_on_slope` is `true`, body will not slide on slopes when you include gravity in `linear_velocity` and the body is standing still.
170 	If the body collides, it will change direction a maximum of `max_slides` times before it stops.
171 	`floor_max_angle` is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees.
172 	If `infinite_inertia` is `true`, body will be able to push $(D RigidBody) nodes, but it won't also detect any collisions with them. If `false`, it will interact with $(D RigidBody) nodes like with $(D StaticBody).
173 	Returns the `linear_velocity` vector, rotated and/or scaled if a slide collision occurred. To get detailed information about collisions that occurred, use $(D getSlideCollision).
174 	*/
175 	Vector3 moveAndSlide(in Vector3 linear_velocity, in Vector3 up_direction = Vector3(0, 0, 0), in bool stop_on_slope = false, in long max_slides = 4, in double floor_max_angle = 0.785398, in bool infinite_inertia = true)
176 	{
177 		checkClassBinding!(typeof(this))();
178 		return ptrcall!(Vector3)(GDNativeClassBinding.moveAndSlide, _godot_object, linear_velocity, up_direction, stop_on_slope, max_slides, floor_max_angle, infinite_inertia);
179 	}
180 	/**
181 	Moves the body while keeping it attached to slopes. Similar to $(D moveAndSlide).
182 	As long as the `snap` vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting `snap` to `(0, 0, 0)` or by using $(D moveAndSlide) instead.
183 	*/
184 	Vector3 moveAndSlideWithSnap(in Vector3 linear_velocity, in Vector3 snap, in Vector3 up_direction = Vector3(0, 0, 0), in bool stop_on_slope = false, in long max_slides = 4, in double floor_max_angle = 0.785398, in bool infinite_inertia = true)
185 	{
186 		checkClassBinding!(typeof(this))();
187 		return ptrcall!(Vector3)(GDNativeClassBinding.moveAndSlideWithSnap, _godot_object, linear_velocity, snap, up_direction, stop_on_slope, max_slides, floor_max_angle, infinite_inertia);
188 	}
189 	/**
190 	Locks or unlocks the specified `axis` depending on the value of `lock`. See also $(D moveLockX), $(D moveLockY) and $(D moveLockZ).
191 	*/
192 	void setAxisLock(in long axis, in bool lock)
193 	{
194 		checkClassBinding!(typeof(this))();
195 		ptrcall!(void)(GDNativeClassBinding.setAxisLock, _godot_object, axis, lock);
196 	}
197 	/**
198 	
199 	*/
200 	void setSafeMargin(in double pixels)
201 	{
202 		checkClassBinding!(typeof(this))();
203 		ptrcall!(void)(GDNativeClassBinding.setSafeMargin, _godot_object, pixels);
204 	}
205 	/**
206 	Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given $(D Transform), then tries to move the body along the vector `rel_vec`. Returns `true` if a collision would occur.
207 	*/
208 	bool testMove(in Transform from, in Vector3 rel_vec, in bool infinite_inertia = true)
209 	{
210 		checkClassBinding!(typeof(this))();
211 		return ptrcall!(bool)(GDNativeClassBinding.testMove, _godot_object, from, rel_vec, infinite_inertia);
212 	}
213 	/**
214 	Extra margin used for collision recovery in motion functions (see $(D moveAndCollide), $(D moveAndSlide), $(D moveAndSlideWithSnap)).
215 	If the body is at least this close to another body, it will consider them to be colliding and will be pushed away before performing the actual motion.
216 	A higher value means it's more flexible for detecting collision, which helps with consistently detecting walls and floors.
217 	A lower value forces the collision algorithm to use more exact detection, so it can be used in cases that specifically require precision, e.g at very low scale to avoid visible jittering, or for stability with a stack of kinematic bodies.
218 	*/
219 	@property double collisionSafeMargin()
220 	{
221 		return getSafeMargin();
222 	}
223 	/// ditto
224 	@property void collisionSafeMargin(double v)
225 	{
226 		setSafeMargin(v);
227 	}
228 	/**
229 	Lock the body's X axis movement.
230 	*/
231 	@property bool moveLockX()
232 	{
233 		return getAxisLock(1);
234 	}
235 	/// ditto
236 	@property void moveLockX(bool v)
237 	{
238 		setAxisLock(1, v);
239 	}
240 	/**
241 	Lock the body's Y axis movement.
242 	*/
243 	@property bool moveLockY()
244 	{
245 		return getAxisLock(2);
246 	}
247 	/// ditto
248 	@property void moveLockY(bool v)
249 	{
250 		setAxisLock(2, v);
251 	}
252 	/**
253 	Lock the body's Z axis movement.
254 	*/
255 	@property bool moveLockZ()
256 	{
257 		return getAxisLock(4);
258 	}
259 	/// ditto
260 	@property void moveLockZ(bool v)
261 	{
262 		setAxisLock(4, v);
263 	}
264 }