2
* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
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
* Permission is granted to anyone to use this software for any purpose,
8
* including commercial applications, and to alter it and redistribute it
9
* freely, subject to the following restrictions:
10
* 1. The origin of this software must not be misrepresented; you must not
11
* claim that you wrote the original software. If you use this software
12
* in a product, an acknowledgment in the product documentation would be
13
* appreciated but is not required.
14
* 2. Altered source versions must be plainly marked as such, and must not be
15
* misrepresented as being the original software.
16
* 3. This notice may not be removed or altered from any source distribution.
22
#include <Box2D/Common/b2Math.h>
23
#include <Box2D/Collision/Shapes/b2Shape.h>
38
/// static: zero mass, zero velocity, may be manually moved
39
/// kinematic: zero mass, non-zero velocity set by user, moved by solver
40
/// dynamic: positive mass, non-zero velocity determined by forces, moved by solver
51
/// A body definition holds all the data needed to construct a rigid body.
52
/// You can safely re-use body definitions. Shapes are added to a body after construction.
55
/// This constructor sets the body definition default values.
59
position.Set(0.0f, 0.0f);
61
linearVelocity.Set(0.0f, 0.0f);
62
angularVelocity = 0.0f;
64
angularDamping = 0.0f;
67
fixedRotation = false;
74
/// The body type: static, kinematic, or dynamic.
75
/// Note: if a dynamic body would have zero mass, the mass is set to one.
78
/// The world position of the body. Avoid creating bodies at the origin
79
/// since this can lead to many overlapping shapes.
82
/// The world angle of the body in radians.
85
/// The linear velocity of the body's origin in world co-ordinates.
86
b2Vec2 linearVelocity;
88
/// The angular velocity of the body.
89
float32 angularVelocity;
91
/// Linear damping is use to reduce the linear velocity. The damping parameter
92
/// can be larger than 1.0f but the damping effect becomes sensitive to the
93
/// time step when the damping parameter is large.
94
float32 linearDamping;
96
/// Angular damping is use to reduce the angular velocity. The damping parameter
97
/// can be larger than 1.0f but the damping effect becomes sensitive to the
98
/// time step when the damping parameter is large.
99
float32 angularDamping;
101
/// Set this flag to false if this body should never fall asleep. Note that
102
/// this increases CPU usage.
105
/// Is this body initially awake or sleeping?
108
/// Should this body be prevented from rotating? Useful for characters.
111
/// Is this a fast moving body that should be prevented from tunneling through
112
/// other moving bodies? Note that all bodies are prevented from tunneling through
113
/// kinematic and static bodies. This setting is only considered on dynamic bodies.
114
/// @warning You should use this flag sparingly since it increases processing time.
117
/// Does this body start out active?
120
/// Use this to store application specific body data.
123
/// Scale the gravity applied to this body.
124
float32 gravityScale;
127
/// A rigid body. These are created via b2World::CreateBody.
131
/// Creates a fixture and attach it to this body. Use this function if you need
132
/// to set some fixture parameters, like friction. Otherwise you can create the
133
/// fixture directly from a shape.
134
/// If the density is non-zero, this function automatically updates the mass of the body.
135
/// Contacts are not created until the next time step.
136
/// @param def the fixture definition.
137
/// @warning This function is locked during callbacks.
138
b2Fixture* CreateFixture(const b2FixtureDef* def);
140
/// Creates a fixture from a shape and attach it to this body.
141
/// This is a convenience function. Use b2FixtureDef if you need to set parameters
142
/// like friction, restitution, user data, or filtering.
143
/// If the density is non-zero, this function automatically updates the mass of the body.
144
/// @param shape the shape to be cloned.
145
/// @param density the shape density (set to zero for static bodies).
146
/// @warning This function is locked during callbacks.
147
b2Fixture* CreateFixture(const b2Shape* shape, float32 density);
149
/// Destroy a fixture. This removes the fixture from the broad-phase and
150
/// destroys all contacts associated with this fixture. This will
151
/// automatically adjust the mass of the body if the body is dynamic and the
152
/// fixture has positive density.
153
/// All fixtures attached to a body are implicitly destroyed when the body is destroyed.
154
/// @param fixture the fixture to be removed.
155
/// @warning This function is locked during callbacks.
156
void DestroyFixture(b2Fixture* fixture);
158
/// Set the position of the body's origin and rotation.
159
/// This breaks any contacts and wakes the other bodies.
160
/// Manipulating a body's transform may cause non-physical behavior.
161
/// @param position the world position of the body's local origin.
162
/// @param angle the world rotation in radians.
163
void SetTransform(const b2Vec2& position, float32 angle);
165
/// Get the body transform for the body's origin.
166
/// @return the world transform of the body's origin.
167
const b2Transform& GetTransform() const;
169
/// Get the world body origin position.
170
/// @return the world position of the body's origin.
171
const b2Vec2& GetPosition() const;
173
/// Get the angle in radians.
174
/// @return the current world rotation angle in radians.
175
float32 GetAngle() const;
177
/// Get the world position of the center of mass.
178
const b2Vec2& GetWorldCenter() const;
180
/// Get the local position of the center of mass.
181
const b2Vec2& GetLocalCenter() const;
183
/// Set the linear velocity of the center of mass.
184
/// @param v the new linear velocity of the center of mass.
185
void SetLinearVelocity(const b2Vec2& v);
187
/// Get the linear velocity of the center of mass.
188
/// @return the linear velocity of the center of mass.
189
b2Vec2 GetLinearVelocity() const;
191
/// Set the angular velocity.
192
/// @param omega the new angular velocity in radians/second.
193
void SetAngularVelocity(float32 omega);
195
/// Get the angular velocity.
196
/// @return the angular velocity in radians/second.
197
float32 GetAngularVelocity() const;
199
/// Apply a force at a world point. If the force is not
200
/// applied at the center of mass, it will generate a torque and
201
/// affect the angular velocity. This wakes up the body.
202
/// @param force the world force vector, usually in Newtons (N).
203
/// @param point the world position of the point of application.
204
void ApplyForce(const b2Vec2& force, const b2Vec2& point);
206
/// Apply a force to the center of mass. This wakes up the body.
207
/// @param force the world force vector, usually in Newtons (N).
208
void ApplyForceToCenter(const b2Vec2& force);
210
/// Apply a torque. This affects the angular velocity
211
/// without affecting the linear velocity of the center of mass.
212
/// This wakes up the body.
213
/// @param torque about the z-axis (out of the screen), usually in N-m.
214
void ApplyTorque(float32 torque);
216
/// Apply an impulse at a point. This immediately modifies the velocity.
217
/// It also modifies the angular velocity if the point of application
218
/// is not at the center of mass. This wakes up the body.
219
/// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
220
/// @param point the world position of the point of application.
221
void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point);
223
/// Apply an angular impulse.
224
/// @param impulse the angular impulse in units of kg*m*m/s
225
void ApplyAngularImpulse(float32 impulse);
227
/// Get the total mass of the body.
228
/// @return the mass, usually in kilograms (kg).
229
float32 GetMass() const;
231
/// Get the rotational inertia of the body about the local origin.
232
/// @return the rotational inertia, usually in kg-m^2.
233
float32 GetInertia() const;
235
/// Get the mass data of the body.
236
/// @return a struct containing the mass, inertia and center of the body.
237
void GetMassData(b2MassData* data) const;
239
/// Set the mass properties to override the mass properties of the fixtures.
240
/// Note that this changes the center of mass position.
241
/// Note that creating or destroying fixtures can also alter the mass.
242
/// This function has no effect if the body isn't dynamic.
243
/// @param massData the mass properties.
244
void SetMassData(const b2MassData* data);
246
/// This resets the mass properties to the sum of the mass properties of the fixtures.
247
/// This normally does not need to be called unless you called SetMassData to override
248
/// the mass and you later want to reset the mass.
249
void ResetMassData();
251
/// Get the world coordinates of a point given the local coordinates.
252
/// @param localPoint a point on the body measured relative the the body's origin.
253
/// @return the same point expressed in world coordinates.
254
b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const;
256
/// Get the world coordinates of a vector given the local coordinates.
257
/// @param localVector a vector fixed in the body.
258
/// @return the same vector expressed in world coordinates.
259
b2Vec2 GetWorldVector(const b2Vec2& localVector) const;
261
/// Gets a local point relative to the body's origin given a world point.
262
/// @param a point in world coordinates.
263
/// @return the corresponding local point relative to the body's origin.
264
b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const;
266
/// Gets a local vector given a world vector.
267
/// @param a vector in world coordinates.
268
/// @return the corresponding local vector.
269
b2Vec2 GetLocalVector(const b2Vec2& worldVector) const;
271
/// Get the world linear velocity of a world point attached to this body.
272
/// @param a point in world coordinates.
273
/// @return the world velocity of a point.
274
b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;
276
/// Get the world velocity of a local point.
277
/// @param a point in local coordinates.
278
/// @return the world velocity of a point.
279
b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const;
281
/// Get the linear damping of the body.
282
float32 GetLinearDamping() const;
284
/// Set the linear damping of the body.
285
void SetLinearDamping(float32 linearDamping);
287
/// Get the angular damping of the body.
288
float32 GetAngularDamping() const;
290
/// Set the angular damping of the body.
291
void SetAngularDamping(float32 angularDamping);
293
/// Get the gravity scale of the body.
294
float32 GetGravityScale() const;
296
/// Set the gravity scale of the body.
297
void SetGravityScale(float32 scale);
299
/// Set the type of this body. This may alter the mass and velocity.
300
void SetType(b2BodyType type);
302
/// Get the type of this body.
303
b2BodyType GetType() const;
305
/// Should this body be treated like a bullet for continuous collision detection?
306
void SetBullet(bool flag);
308
/// Is this body treated like a bullet for continuous collision detection?
309
bool IsBullet() const;
311
/// You can disable sleeping on this body. If you disable sleeping, the
312
/// body will be woken.
313
void SetSleepingAllowed(bool flag);
315
/// Is this body allowed to sleep
316
bool IsSleepingAllowed() const;
318
/// Set the sleep state of the body. A sleeping body has very
320
/// @param flag set to true to put body to sleep, false to wake it.
321
void SetAwake(bool flag);
323
/// Get the sleeping state of this body.
324
/// @return true if the body is sleeping.
325
bool IsAwake() const;
327
/// Set the active state of the body. An inactive body is not
328
/// simulated and cannot be collided with or woken up.
329
/// If you pass a flag of true, all fixtures will be added to the
331
/// If you pass a flag of false, all fixtures will be removed from
332
/// the broad-phase and all contacts will be destroyed.
333
/// Fixtures and joints are otherwise unaffected. You may continue
334
/// to create/destroy fixtures and joints on inactive bodies.
335
/// Fixtures on an inactive body are implicitly inactive and will
336
/// not participate in collisions, ray-casts, or queries.
337
/// Joints connected to an inactive body are implicitly inactive.
338
/// An inactive body is still owned by a b2World object and remains
339
/// in the body list.
340
void SetActive(bool flag);
342
/// Get the active state of the body.
343
bool IsActive() const;
345
/// Set this body to have fixed rotation. This causes the mass
347
void SetFixedRotation(bool flag);
349
/// Does this body have fixed rotation?
350
bool IsFixedRotation() const;
352
/// Get the list of all fixtures attached to this body.
353
b2Fixture* GetFixtureList();
354
const b2Fixture* GetFixtureList() const;
356
/// Get the list of all joints attached to this body.
357
b2JointEdge* GetJointList();
358
const b2JointEdge* GetJointList() const;
360
/// Get the list of all contacts attached to this body.
361
/// @warning this list changes during the time step and you may
362
/// miss some collisions if you don't use b2ContactListener.
363
b2ContactEdge* GetContactList();
364
const b2ContactEdge* GetContactList() const;
366
/// Get the next body in the world's body list.
368
const b2Body* GetNext() const;
370
/// Get the user data pointer that was provided in the body definition.
371
void* GetUserData() const;
373
/// Set the user data. Use this to store your application specific data.
374
void SetUserData(void* data);
376
/// Get the parent world of this body.
378
const b2World* GetWorld() const;
380
/// Dump this body to a log file
385
friend class b2World;
386
friend class b2Island;
387
friend class b2ContactManager;
388
friend class b2ContactSolver;
389
friend class b2Contact;
391
friend class b2DistanceJoint;
392
friend class b2GearJoint;
393
friend class b2WheelJoint;
394
friend class b2MouseJoint;
395
friend class b2PrismaticJoint;
396
friend class b2PulleyJoint;
397
friend class b2RevoluteJoint;
398
friend class b2WeldJoint;
399
friend class b2FrictionJoint;
400
friend class b2RopeJoint;
405
e_islandFlag = 0x0001,
406
e_awakeFlag = 0x0002,
407
e_autoSleepFlag = 0x0004,
408
e_bulletFlag = 0x0008,
409
e_fixedRotationFlag = 0x0010,
410
e_activeFlag = 0x0020,
414
b2Body(const b2BodyDef* bd, b2World* world);
417
void SynchronizeFixtures();
418
void SynchronizeTransform();
420
// This is used to prevent connected bodies from colliding.
421
// It may lie, depending on the collideConnected flag.
422
bool ShouldCollide(const b2Body* other) const;
424
void Advance(float32 t);
432
b2Transform m_xf; // the body origin transform
433
b2Sweep m_sweep; // the swept motion for CCD
435
b2Vec2 m_linearVelocity;
436
float32 m_angularVelocity;
445
b2Fixture* m_fixtureList;
446
int32 m_fixtureCount;
448
b2JointEdge* m_jointList;
449
b2ContactEdge* m_contactList;
451
float32 m_mass, m_invMass;
453
// Rotational inertia about the center of mass.
456
float32 m_linearDamping;
457
float32 m_angularDamping;
458
float32 m_gravityScale;
465
inline b2BodyType b2Body::GetType() const
470
inline const b2Transform& b2Body::GetTransform() const
475
inline const b2Vec2& b2Body::GetPosition() const
480
inline float32 b2Body::GetAngle() const
485
inline const b2Vec2& b2Body::GetWorldCenter() const
490
inline const b2Vec2& b2Body::GetLocalCenter() const
492
return m_sweep.localCenter;
495
inline void b2Body::SetLinearVelocity(const b2Vec2& v)
497
if (m_type == b2_staticBody)
502
if (b2Dot(v,v) > 0.0f)
507
m_linearVelocity = v;
510
inline b2Vec2 b2Body::GetLinearVelocity() const
512
return m_linearVelocity;
515
inline void b2Body::SetAngularVelocity(float32 w)
517
if (m_type == b2_staticBody)
527
m_angularVelocity = w;
530
inline float32 b2Body::GetAngularVelocity() const
532
return m_angularVelocity;
535
inline float32 b2Body::GetMass() const
540
inline float32 b2Body::GetInertia() const
542
return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
545
inline void b2Body::GetMassData(b2MassData* data) const
548
data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
549
data->center = m_sweep.localCenter;
552
inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const
554
return b2Mul(m_xf, localPoint);
557
inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const
559
return b2Mul(m_xf.q, localVector);
562
inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const
564
return b2MulT(m_xf, worldPoint);
567
inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const
569
return b2MulT(m_xf.q, worldVector);
572
inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const
574
return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
577
inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const
579
return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
582
inline float32 b2Body::GetLinearDamping() const
584
return m_linearDamping;
587
inline void b2Body::SetLinearDamping(float32 linearDamping)
589
m_linearDamping = linearDamping;
592
inline float32 b2Body::GetAngularDamping() const
594
return m_angularDamping;
597
inline void b2Body::SetAngularDamping(float32 angularDamping)
599
m_angularDamping = angularDamping;
602
inline float32 b2Body::GetGravityScale() const
604
return m_gravityScale;
607
inline void b2Body::SetGravityScale(float32 scale)
609
m_gravityScale = scale;
612
inline void b2Body::SetBullet(bool flag)
616
m_flags |= e_bulletFlag;
620
m_flags &= ~e_bulletFlag;
624
inline bool b2Body::IsBullet() const
626
return (m_flags & e_bulletFlag) == e_bulletFlag;
629
inline void b2Body::SetAwake(bool flag)
633
if ((m_flags & e_awakeFlag) == 0)
635
m_flags |= e_awakeFlag;
641
m_flags &= ~e_awakeFlag;
643
m_linearVelocity.SetZero();
644
m_angularVelocity = 0.0f;
650
inline bool b2Body::IsAwake() const
652
return (m_flags & e_awakeFlag) == e_awakeFlag;
655
inline bool b2Body::IsActive() const
657
return (m_flags & e_activeFlag) == e_activeFlag;
660
inline void b2Body::SetFixedRotation(bool flag)
664
m_flags |= e_fixedRotationFlag;
668
m_flags &= ~e_fixedRotationFlag;
674
inline bool b2Body::IsFixedRotation() const
676
return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag;
679
inline void b2Body::SetSleepingAllowed(bool flag)
683
m_flags |= e_autoSleepFlag;
687
m_flags &= ~e_autoSleepFlag;
692
inline bool b2Body::IsSleepingAllowed() const
694
return (m_flags & e_autoSleepFlag) == e_autoSleepFlag;
697
inline b2Fixture* b2Body::GetFixtureList()
699
return m_fixtureList;
702
inline const b2Fixture* b2Body::GetFixtureList() const
704
return m_fixtureList;
707
inline b2JointEdge* b2Body::GetJointList()
712
inline const b2JointEdge* b2Body::GetJointList() const
717
inline b2ContactEdge* b2Body::GetContactList()
719
return m_contactList;
722
inline const b2ContactEdge* b2Body::GetContactList() const
724
return m_contactList;
727
inline b2Body* b2Body::GetNext()
732
inline const b2Body* b2Body::GetNext() const
737
inline void b2Body::SetUserData(void* data)
742
inline void* b2Body::GetUserData() const
747
inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point)
749
if (m_type != b2_dynamicBody)
754
if (IsAwake() == false)
760
m_torque += b2Cross(point - m_sweep.c, force);
763
inline void b2Body::ApplyForceToCenter(const b2Vec2& force)
765
if (m_type != b2_dynamicBody)
770
if (IsAwake() == false)
778
inline void b2Body::ApplyTorque(float32 torque)
780
if (m_type != b2_dynamicBody)
785
if (IsAwake() == false)
793
inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point)
795
if (m_type != b2_dynamicBody)
800
if (IsAwake() == false)
804
m_linearVelocity += m_invMass * impulse;
805
m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse);
808
inline void b2Body::ApplyAngularImpulse(float32 impulse)
810
if (m_type != b2_dynamicBody)
815
if (IsAwake() == false)
819
m_angularVelocity += m_invI * impulse;
822
inline void b2Body::SynchronizeTransform()
824
m_xf.q.Set(m_sweep.a);
825
m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter);
828
inline void b2Body::Advance(float32 alpha)
830
// Advance to the new safe time. This doesn't sync the broad-phase.
831
m_sweep.Advance(alpha);
832
m_sweep.c = m_sweep.c0;
833
m_sweep.a = m_sweep.a0;
834
m_xf.q.Set(m_sweep.a);
835
m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter);
838
inline b2World* b2Body::GetWorld()
843
inline const b2World* b2Body::GetWorld() const