1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#ifndef LOVE_PHYSICS_BOX2D_BODY_H
22#define LOVE_PHYSICS_BOX2D_BODY_H
23
24// LOVE
25#include "common/math.h"
26#include "common/runtime.h"
27#include "common/Object.h"
28#include "physics/Body.h"
29
30// Box2D
31#include <Box2D/Box2D.h>
32
33namespace love
34{
35namespace physics
36{
37namespace box2d
38{
39// Forward declarations.
40class World;
41class Shape;
42class Fixture;
43
44/**
45 * This struct is stored in a void pointer in the Box2D Body class. For now, all
46 * we need is a Lua reference to arbitrary data, but we might need more later.
47 **/
48struct bodyudata
49{
50 // Reference to arbitrary data.
51 Reference *ref = nullptr;
52};
53
54/**
55 * A Body is an entity which has position and orientation
56 * in world space. A Body does have collision geometry
57 * by itself, but depend on an arbitrary number of child Shape objects
58 * which together constitute the final geometry for the Body.
59 **/
60class Body : public love::physics::Body
61{
62public:
63 // Friends.
64 friend class Joint;
65 friend class DistanceJoint;
66 friend class MouseJoint;
67 friend class CircleShape;
68 friend class PolygonShape;
69 friend class Shape;
70 friend class Fixture;
71
72 // Public because joints et al ask for b2body
73 b2Body *body;
74
75 /**
76 * Create a Body at position p.
77 **/
78 Body(World *world, b2Vec2 p, Type type);
79
80 virtual ~Body();
81
82 /**
83 * Gets the current x-position of the Body.
84 **/
85 float getX();
86
87 /**
88 * Gets the current y-position of the Body.
89 **/
90 float getY();
91
92 /**
93 * Gets the current angle (deg) of the Body.
94 **/
95 float getAngle();
96
97 /**
98 * Gets the current position of the Body.
99 * @param[out] x_o The x-component of the position.
100 * @param[out] y_o The y-component of the position.
101 **/
102 void getPosition(float &x_o, float &y_o);
103
104 /**
105 * Gets the velocity in the current center of mass.
106 * @param[out] x_o The x-component of the velocity.
107 * @param[out] y_o The y-component of the velocity.
108 **/
109 void getLinearVelocity(float &x_o, float &y_o);
110
111 /**
112 * The current center of mass for the Body in world
113 * coordinates.
114 * @param[out] x_o The x-component of the center of mass.
115 * @param[out] y_o The y-component of the center of mass.
116 **/
117 void getWorldCenter(float &x_o, float &y_o);
118
119 /**
120 * The current center of mass for the Body in local
121 * coordinates.
122 * @param[out] x_o The x-component of the center of mass.
123 * @param[out] y_o The y-component of the center of mass.
124 **/
125 void getLocalCenter(float &x_o, float &y_o);
126
127 /**
128 * Get the current Body spin. (Angular velocity).
129 **/
130 float getAngularVelocity() const;
131
132 /**
133 * Gets the Body's mass.
134 **/
135 float getMass() const;
136
137 /**
138 * Gets the Body's intertia.
139 **/
140 float getInertia() const;
141
142 /**
143 * Gets mass properties.
144 **/
145 int getMassData(lua_State *L);
146
147 /**
148 * Gets the Body's angular damping.
149 **/
150 float getAngularDamping() const;
151
152 /**
153 * Gets the Body's linear damping.
154 **/
155 float getLinearDamping() const;
156
157 /**
158 * Gets the Body's gravity scale.
159 **/
160 float getGravityScale() const;
161
162 /**
163 * Gets the type of body this is.
164 **/
165 Type getType() const;
166
167 /**
168 * Apply an impulse (jx, jy) with offset (0, 0).
169 **/
170 void applyLinearImpulse(float jx, float jy, bool wake);
171
172 /**
173 * Apply an impulse (jx, jy) with offset (rx, ry).
174 **/
175 void applyLinearImpulse(float jx, float jy, float rx, float ry, bool wake);
176
177 /**
178 * Apply an angular impulse to the body.
179 **/
180 void applyAngularImpulse(float impulse, bool wake);
181
182 /**
183 * Apply torque (t).
184 **/
185 void applyTorque(float t, bool wake);
186
187 /**
188 * Apply force (fx, fy) with offset (0, 0).
189 **/
190 void applyForce(float fx, float fy, bool wake);
191
192 /**
193 * Apply force (fx, fy) with offset (rx, ry).
194 **/
195 void applyForce(float fx, float fy, float rx, float ry, bool wake);
196
197 /**
198 * Sets the x-position of the Body.
199 **/
200 void setX(float x);
201
202 /**
203 * Sets the Y-position of the Body.
204 **/
205 void setY(float y);
206
207 /**
208 * Sets the current velocity of the Body.
209 **/
210 void setLinearVelocity(float x, float y);
211
212 /**
213 * Sets the angle of the Body.
214 **/
215 void setAngle(float d);
216
217 /**
218 * Sets the current spin of the Body.
219 **/
220 void setAngularVelocity(float r);
221
222 /**
223 * Sets the current position of the Body.
224 **/
225 void setPosition(float x, float y);
226
227 /**
228 * Sets the mass from the currently attatched shapes.
229 **/
230 void resetMassData();
231
232 /**
233 * Sets mass properties.
234 * @param x The x-coordinate for the local center of mass.
235 * @param y The y-coordinate for the local center of mass.
236 * @param m The mass.
237 * @param i The inertia.
238 **/
239 void setMassData(float x, float y, float m, float i);
240
241 /**
242 * Sets just the mass. This is provided as a LOVE bonus. Lovely!
243 * @param m The mass.
244 **/
245 void setMass(float m);
246
247 /**
248 * Sets the inertia while keeping the other properties
249 * (mass and local center).
250 * @param i The inertia.
251 **/
252 void setInertia(float i);
253
254 /**
255 * Sets the Body's angular damping.
256 **/
257 void setAngularDamping(float d);
258
259 /**
260 * Sets the Body's linear damping.
261 **/
262 void setLinearDamping(float d);
263
264 /**
265 * Sets the Body's gravity scale.
266 **/
267 void setGravityScale(float scale);
268
269 /**
270 * Sets the type of body this is.
271 **/
272 void setType(Type type);
273
274 /**
275 * Transforms a point (x, y) from local coordinates
276 * to world coordinates.
277 * @param x The x-coordinate of the local point.
278 * @param y The y-coordinate of the local point.
279 * @param[out] x_o The x-coordinate of the point in world coordinates.
280 * @param[out] y_o The y-coordinate of the point in world coordinates.
281 **/
282 void getWorldPoint(float x, float y, float &x_o, float &y_o);
283
284 /**
285 * Transforms a vector (x, y) from local coordinates
286 * to world coordinates.
287 * @param x The x-coordinate of the local vector.
288 * @param y The y-coordinate of the local vector.
289 * @param[out] x_o The x-coordinate of the vector in world coordinates.
290 * @param[out] y_o The y-coordinate of the vector in world coordinates.
291 **/
292 void getWorldVector(float x, float y, float &x_o, float &y_o);
293
294 /**
295 * Transforms a series of points (x, y) from local coordinates
296 * to world coordinates.
297 **/
298 int getWorldPoints(lua_State *L);
299
300 /**
301 * Transforms a point (x, y) from world coordinates
302 * to local coordinates.
303 * @param x The x-coordinate of the world point.
304 * @param y The y-coordinate of the world point.
305 * @param[out] x_o The x-coordinate of the point in local coordinates.
306 * @param[out] y_o The y-coordinate of the point in local coordinates.
307 **/
308 void getLocalPoint(float x, float y, float &x_o, float &y_o);
309
310 /**
311 * Transforms a vector (x, y) from world coordinates
312 * to local coordinates.
313 * @param x The x-coordinate of the world vector.
314 * @param y The y-coordinate of the world vector.
315 * @param[out] x_o The x-coordinate of the vector in local coordinates.
316 * @param[out] y_o The y-coordinate of the vector in local coordinates.
317 **/
318 void getLocalVector(float x, float y, float &x_o, float &y_o);
319
320 /**
321 * Transforms a series of points (x, y) from world coordinates
322 * to local coordinates.
323 **/
324 int getLocalPoints(lua_State *L);
325
326 /**
327 * Gets the velocity on the Body for the given world point.
328 * @param x The x-coordinate of the world point.
329 * @param y The y-coordinate of the world point.
330 * @param[out] x_o The x-component of the velocity vector.
331 * @param[out] y_o The y-component of the velocity vector.
332 **/
333 void getLinearVelocityFromWorldPoint(float x, float y, float &x_o, float &y_o);
334
335 /**
336 * Gets the velocity on the Body for the given local point.
337 * @param x The x-coordinate of the local point.
338 * @param y The y-coordinate of the local point.
339 * @param[out] x_o The x-component of the velocity vector.
340 * @param[out] y_o The y-component of the velocity vector.
341 **/
342 void getLinearVelocityFromLocalPoint(float x, float y, float &x_o, float &y_o);
343
344 /**
345 * Returns true if the Body is a bullet, false otherwise.
346 **/
347 bool isBullet() const;
348
349 /**
350 * Set whether this Body should be treated as a bullet.
351 * Bullets require more processing power than normal shapes.
352 **/
353 void setBullet(bool bullet);
354
355 /**
356 * Checks whether a Body is active or not. An inactive body
357 * cannot be interacted with.
358 **/
359 bool isActive() const;
360
361 /**
362 * Checks whether a Body is awake or not. A Body
363 * will fall to sleep if nothing happens to it for while.
364 **/
365 bool isAwake() const;
366
367 /**
368 * Controls whether this Body should be allowed to sleep.
369 **/
370 void setSleepingAllowed(bool allow);
371 bool isSleepingAllowed() const;
372
373 /**
374 * Changes the body's active state.
375 **/
376 void setActive(bool active);
377
378 /**
379 * Changes the body's sleep state.
380 **/
381 void setAwake(bool awake);
382
383 void setFixedRotation(bool fixed);
384 bool isFixedRotation() const;
385
386 bool isTouching(Body *other) const;
387
388 /**
389 * Get the World this Body resides in.
390 */
391 World *getWorld() const;
392
393 /**
394 * Get an array of all the Fixtures attached to this Body.
395 * @return An array of Fixtures.
396 **/
397 int getFixtures(lua_State *L) const;
398
399 /**
400 * Get an array of all Joints attached to this Body.
401 **/
402 int getJoints(lua_State *L) const;
403
404 /**
405 * Get an array of all active Contacts attached to this Body.
406 * This list changes during World:update and you may miss some collisions
407 * if you don't use the collision callbacks.
408 **/
409 int getContacts(lua_State *L) const;
410
411 /**
412 * Destroy this body.
413 **/
414 void destroy();
415
416 /**
417 * This function stores an in-C reference to
418 * arbitrary Lua data in the Box2D Body object.
419 **/
420 int setUserData(lua_State *L);
421
422 /**
423 * Gets the data set with setData. If no
424 * data is set, nil is returned.
425 **/
426 int getUserData(lua_State *L);
427
428private:
429
430 // FIXME: This should be a weak reference, rather than being completely
431 // unowned?
432 World *world;
433
434 bodyudata *udata;
435
436}; // Body
437
438} // box2d
439} // physics
440} // love
441
442#endif // LOVE_PHYSICS_BOX2D_BODY_H
443