b2Body.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org
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 * 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.
17 */
18 
19 #include <Box2D/Dynamics/b2Body.h>
21 #include <Box2D/Dynamics/b2World.h>
24 
25 b2Body::b2Body(const b2BodyDef* bd, b2World* world)
26 {
27  b2Assert(bd->position.IsValid());
29  b2Assert(b2IsValid(bd->angle));
31  b2Assert(b2IsValid(bd->angularDamping) && bd->angularDamping >= 0.0f);
32  b2Assert(b2IsValid(bd->linearDamping) && bd->linearDamping >= 0.0f);
33 
34  m_flags = 0;
35 
36  if (bd->bullet)
37  {
39  }
40  if (bd->fixedRotation)
41  {
43  }
44  if (bd->allowSleep)
45  {
47  }
48  if (bd->awake)
49  {
51  }
52  if (bd->active)
53  {
55  }
56 
57  m_world = world;
58 
59  m_xf.p = bd->position;
60  m_xf.q.Set(bd->angle);
61 
63  m_sweep.c0 = m_xf.p;
64  m_sweep.c = m_xf.p;
65  m_sweep.a0 = bd->angle;
66  m_sweep.a = bd->angle;
67  m_sweep.alpha0 = 0.0f;
68 
69  m_jointList = NULL;
70  m_contactList = NULL;
71  m_prev = NULL;
72  m_next = NULL;
73 
76 
80 
81  m_force.SetZero();
82  m_torque = 0.0f;
83 
84  m_sleepTime = 0.0f;
85 
86  m_type = bd->type;
87 
88  if (m_type == b2_dynamicBody)
89  {
90  m_mass = 1.0f;
91  m_invMass = 1.0f;
92  }
93  else
94  {
95  m_mass = 0.0f;
96  m_invMass = 0.0f;
97  }
98 
99  m_I = 0.0f;
100  m_invI = 0.0f;
101 
102  m_userData = bd->userData;
103 
104  m_fixtureList = NULL;
105  m_fixtureCount = 0;
106 }
107 
109 {
110  // shapes and joints are destroyed in b2World::Destroy
111 }
112 
114 {
115  b2Assert(m_world->IsLocked() == false);
116  if (m_world->IsLocked() == true)
117  {
118  return;
119  }
120 
121  if (m_type == type)
122  {
123  return;
124  }
125 
126  m_type = type;
127 
128  ResetMassData();
129 
130  if (m_type == b2_staticBody)
131  {
133  m_angularVelocity = 0.0f;
134  m_sweep.a0 = m_sweep.a;
135  m_sweep.c0 = m_sweep.c;
137  }
138 
139  SetAwake(true);
140 
141  m_force.SetZero();
142  m_torque = 0.0f;
143 
144  // Delete the attached contacts.
146  while (ce)
147  {
148  b2ContactEdge* ce0 = ce;
149  ce = ce->next;
151  }
152  m_contactList = NULL;
153 
154  // Touch the proxies so that new contacts will be created (when appropriate)
156  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
157  {
158  int32 proxyCount = f->m_proxyCount;
159  for (int32 i = 0; i < proxyCount; ++i)
160  {
161  broadPhase->TouchProxy(f->m_proxies[i].proxyId);
162  }
163  }
164 }
165 
167 {
168  b2Assert(m_world->IsLocked() == false);
169  if (m_world->IsLocked() == true)
170  {
171  return NULL;
172  }
173 
175 
176  void* memory = allocator->Allocate(sizeof(b2Fixture));
177  b2Fixture* fixture = new (memory) b2Fixture;
178  fixture->Create(allocator, this, def);
179 
180  if (m_flags & e_activeFlag)
181  {
183  fixture->CreateProxies(broadPhase, m_xf);
184  }
185 
186  fixture->m_next = m_fixtureList;
187  m_fixtureList = fixture;
188  ++m_fixtureCount;
189 
190  fixture->m_body = this;
191 
192  // Adjust mass properties if needed.
193  if (fixture->m_density > 0.0f)
194  {
195  ResetMassData();
196  }
197 
198  // Let the world know we have a new fixture. This will cause new contacts
199  // to be created at the beginning of the next time step.
201 
202  return fixture;
203 }
204 
206 {
207  b2FixtureDef def;
208  def.shape = shape;
209  def.density = density;
210 
211  return CreateFixture(&def);
212 }
213 
215 {
216  b2Assert(m_world->IsLocked() == false);
217  if (m_world->IsLocked() == true)
218  {
219  return;
220  }
221 
222  b2Assert(fixture->m_body == this);
223 
224  // Remove the fixture from this body's singly linked list.
226  b2Fixture** node = &m_fixtureList;
227  bool found = false;
228  while (*node != NULL)
229  {
230  if (*node == fixture)
231  {
232  *node = fixture->m_next;
233  found = true;
234  break;
235  }
236 
237  node = &(*node)->m_next;
238  }
239 
240  // You tried to remove a shape that is not attached to this body.
241  b2Assert(found);
242 
243  // Destroy any contacts associated with the fixture.
245  while (edge)
246  {
247  b2Contact* c = edge->contact;
248  edge = edge->next;
249 
250  b2Fixture* fixtureA = c->GetFixtureA();
251  b2Fixture* fixtureB = c->GetFixtureB();
252 
253  if (fixture == fixtureA || fixture == fixtureB)
254  {
255  // This destroys the contact and removes it from
256  // this body's contact list.
258  }
259  }
260 
262 
263  if (m_flags & e_activeFlag)
264  {
266  fixture->DestroyProxies(broadPhase);
267  }
268 
269  fixture->Destroy(allocator);
270  fixture->m_body = NULL;
271  fixture->m_next = NULL;
272  fixture->~b2Fixture();
273  allocator->Free(fixture, sizeof(b2Fixture));
274 
275  --m_fixtureCount;
276 
277  // Reset the mass data.
278  ResetMassData();
279 }
280 
282 {
283  // Compute mass data from shapes. Each shape has its own density.
284  m_mass = 0.0f;
285  m_invMass = 0.0f;
286  m_I = 0.0f;
287  m_invI = 0.0f;
289 
290  // Static and kinematic bodies have zero mass.
292  {
293  m_sweep.c0 = m_xf.p;
294  m_sweep.c = m_xf.p;
295  m_sweep.a0 = m_sweep.a;
296  return;
297  }
298 
300 
301  // Accumulate mass over all fixtures.
302  b2Vec2 localCenter = b2Vec2_zero;
303  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
304  {
305  if (f->m_density == 0.0f)
306  {
307  continue;
308  }
309 
310  b2MassData massData;
311  f->GetMassData(&massData);
312  m_mass += massData.mass;
313  localCenter += massData.mass * massData.center;
314  m_I += massData.I;
315  }
316 
317  // Compute center of mass.
318  if (m_mass > 0.0f)
319  {
320  m_invMass = 1.0f / m_mass;
321  localCenter *= m_invMass;
322  }
323  else
324  {
325  // Force all dynamic bodies to have a positive mass.
326  m_mass = 1.0f;
327  m_invMass = 1.0f;
328  }
329 
330  if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0)
331  {
332  // Center the inertia about the center of mass.
333  m_I -= m_mass * b2Dot(localCenter, localCenter);
334  b2Assert(m_I > 0.0f);
335  m_invI = 1.0f / m_I;
336 
337  }
338  else
339  {
340  m_I = 0.0f;
341  m_invI = 0.0f;
342  }
343 
344  // Move center of mass.
345  b2Vec2 oldCenter = m_sweep.c;
346  m_sweep.localCenter = localCenter;
348 
349  // Update center of mass velocity.
351 }
352 
353 void b2Body::SetMassData(const b2MassData* massData)
354 {
355  b2Assert(m_world->IsLocked() == false);
356  if (m_world->IsLocked() == true)
357  {
358  return;
359  }
360 
361  if (m_type != b2_dynamicBody)
362  {
363  return;
364  }
365 
366  m_invMass = 0.0f;
367  m_I = 0.0f;
368  m_invI = 0.0f;
369 
370  m_mass = massData->mass;
371  if (m_mass <= 0.0f)
372  {
373  m_mass = 1.0f;
374  }
375 
376  m_invMass = 1.0f / m_mass;
377 
378  if (massData->I > 0.0f && (m_flags & b2Body::e_fixedRotationFlag) == 0)
379  {
380  m_I = massData->I - m_mass * b2Dot(massData->center, massData->center);
381  b2Assert(m_I > 0.0f);
382  m_invI = 1.0f / m_I;
383  }
384 
385  // Move center of mass.
386  b2Vec2 oldCenter = m_sweep.c;
387  m_sweep.localCenter = massData->center;
389 
390  // Update center of mass velocity.
392 }
393 
394 bool b2Body::ShouldCollide(const b2Body* other) const
395 {
396  // At least one body should be dynamic.
397  if (m_type != b2_dynamicBody && other->m_type != b2_dynamicBody)
398  {
399  return false;
400  }
401 
402  // Does a joint prevent collision?
403  for (b2JointEdge* jn = m_jointList; jn; jn = jn->next)
404  {
405  if (jn->other == other)
406  {
407  if (jn->joint->m_collideConnected == false)
408  {
409  return false;
410  }
411  }
412  }
413 
414  return true;
415 }
416 
417 void b2Body::SetTransform(const b2Vec2& position, float32 angle)
418 {
419  b2Assert(m_world->IsLocked() == false);
420  if (m_world->IsLocked() == true)
421  {
422  return;
423  }
424 
425  m_xf.q.Set(angle);
426  m_xf.p = position;
427 
429  m_sweep.a = angle;
430 
431  m_sweep.c0 = m_sweep.c;
432  m_sweep.a0 = angle;
433 
435  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
436  {
437  f->Synchronize(broadPhase, m_xf, m_xf);
438  }
439 }
440 
442 {
443  b2Transform xf1;
444  xf1.q.Set(m_sweep.a0);
445  xf1.p = m_sweep.c0 - b2Mul(xf1.q, m_sweep.localCenter);
446 
448  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
449  {
450  f->Synchronize(broadPhase, xf1, m_xf);
451  }
452 }
453 
454 void b2Body::SetActive(bool flag)
455 {
456  b2Assert(m_world->IsLocked() == false);
457 
458  if (flag == IsActive())
459  {
460  return;
461  }
462 
463  if (flag)
464  {
466 
467  // Create all proxies.
469  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
470  {
471  f->CreateProxies(broadPhase, m_xf);
472  }
473 
474  // Contacts are created the next time step.
475  }
476  else
477  {
478  m_flags &= ~e_activeFlag;
479 
480  // Destroy all proxies.
482  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
483  {
484  f->DestroyProxies(broadPhase);
485  }
486 
487  // Destroy the attached contacts.
489  while (ce)
490  {
491  b2ContactEdge* ce0 = ce;
492  ce = ce->next;
494  }
495  m_contactList = NULL;
496  }
497 }
498 
500 {
501  bool status = (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag;
502  if (status == flag)
503  {
504  return;
505  }
506 
507  if (flag)
508  {
510  }
511  else
512  {
514  }
515 
516  m_angularVelocity = 0.0f;
517 
518  ResetMassData();
519 }
520 
522 {
523  int32 bodyIndex = m_islandIndex;
524 
525  b2Log("{\n");
526  b2Log(" b2BodyDef bd;\n");
527  b2Log(" bd.type = b2BodyType(%d);\n", m_type);
528  b2Log(" bd.position.Set(%.15lef, %.15lef);\n", m_xf.p.x, m_xf.p.y);
529  b2Log(" bd.angle = %.15lef;\n", m_sweep.a);
530  b2Log(" bd.linearVelocity.Set(%.15lef, %.15lef);\n", m_linearVelocity.x, m_linearVelocity.y);
531  b2Log(" bd.angularVelocity = %.15lef;\n", m_angularVelocity);
532  b2Log(" bd.linearDamping = %.15lef;\n", m_linearDamping);
533  b2Log(" bd.angularDamping = %.15lef;\n", m_angularDamping);
534  b2Log(" bd.allowSleep = bool(%d);\n", m_flags & e_autoSleepFlag);
535  b2Log(" bd.awake = bool(%d);\n", m_flags & e_awakeFlag);
536  b2Log(" bd.fixedRotation = bool(%d);\n", m_flags & e_fixedRotationFlag);
537  b2Log(" bd.bullet = bool(%d);\n", m_flags & e_bulletFlag);
538  b2Log(" bd.active = bool(%d);\n", m_flags & e_activeFlag);
539  b2Log(" bd.gravityScale = %.15lef;\n", m_gravityScale);
540  b2Log(" bodies[%d] = m_world->CreateBody(&bd);\n", m_islandIndex);
541  b2Log("\n");
542  for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
543  {
544  b2Log(" {\n");
545  f->Dump(bodyIndex);
546  b2Log(" }\n");
547  }
548  b2Log("}\n");
549 }
const b2Shape * shape
Definition: b2Fixture.h:71
float32 b2Dot(const b2Vec2 &a, const b2Vec2 &b)
Perform the dot product on two vectors.
Definition: b2Math.h:406
const b2Vec2 b2Vec2_zero(0.0f, 0.0f)
Useful constant.
float32 m_invMass
Definition: b2Body.h:455
int32 m_islandIndex
Definition: b2Body.h:434
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2Math.h:433
float32 m_gravityScale
Definition: b2Body.h:462
float32 linearDamping
Definition: b2Body.h:92
void SynchronizeFixtures()
Definition: b2Body.cpp:441
float32 angularVelocity
The angular velocity of the body.
Definition: b2Body.h:87
bool fixedRotation
Should this body be prevented from rotating? Useful for characters.
Definition: b2Body.h:107
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2Body.cpp:166
void b2Log(const char *string,...)
Logging function.
Definition: b2Settings.cpp:38
void Create(b2BlockAllocator *allocator, b2Body *body, const b2FixtureDef *def)
Definition: b2Fixture.cpp:41
b2Vec2 p
Definition: b2Math.h:372
b2ContactManager m_contactManager
Definition: b2World.h:238
b2Vec2 c0
Definition: b2Math.h:394
void SetType(b2BodyType type)
Set the type of this body. This may alter the mass and velocity.
Definition: b2Body.cpp:113
void Destroy(b2Contact *c)
b2Rot q
Definition: b2Math.h:373
void ResetMassData()
Definition: b2Body.cpp:281
f
b2Vec2 m_linearVelocity
Definition: b2Body.h:439
float32 I
The rotational inertia of the shape about the local origin.
Definition: b2Shape.h:36
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2Contact.h:284
b2Vec2 m_force
Definition: b2Body.h:442
b2Fixture * m_next
Definition: b2Fixture.h:220
b2ContactEdge * m_contactList
Definition: b2Body.h:453
float32 angularDamping
Definition: b2Body.h:97
void Free(void *p, int32 size)
Free memory. This will use b2Free if the size is larger than b2_maxBlockSize.
float32 alpha0
Definition: b2Math.h:399
bool bullet
Definition: b2Body.h:113
b2Vec2 center
The position of the shape&#39;s centroid relative to the shape&#39;s origin.
Definition: b2Shape.h:33
b2ContactEdge * next
the next contact edge in the body&#39;s contact list
Definition: b2Contact.h:71
void SetZero()
Set this vector to all zeros.
Definition: b2Math.h:62
A 2D column vector.
Definition: b2Math.h:53
void SetTransform(const b2Vec2 &position, float32 angle)
Definition: b2Body.cpp:417
float32 m_angularDamping
Definition: b2Body.h:461
b2Contact * contact
the contact
Definition: b2Contact.h:69
b2Vec2 c
center world positions
Definition: b2Math.h:394
void SetFixedRotation(bool flag)
Definition: b2Body.cpp:499
signed int int32
Definition: b2Settings.h:31
bool IsValid() const
Does this vector contain finite coordinates?
Definition: b2Math.h:129
b2Vec2 localCenter
local center of mass position
Definition: b2Math.h:393
float32 b2Cross(const b2Vec2 &a, const b2Vec2 &b)
Perform the cross product on two vectors. In 2D this produces a scalar.
Definition: b2Math.h:412
b2Body(const b2BodyDef *bd, b2World *world)
Definition: b2Body.cpp:25
b2Vec2 linearVelocity
The linear velocity of the body&#39;s origin in world co-ordinates.
Definition: b2Body.h:84
b2JointEdge * m_jointList
Definition: b2Body.h:452
b2BodyType type
Definition: b2Body.h:74
float32 angle
The world angle of the body in radians.
Definition: b2Body.h:81
bool active
Does this body start out active?
Definition: b2Body.h:116
float32 m_linearDamping
Definition: b2Body.h:460
A rigid body. These are created via b2World::CreateBody.
Definition: b2Body.h:126
b2Body * m_prev
Definition: b2Body.h:446
float32 mass
The mass of the shape, usually in kilograms.
Definition: b2Shape.h:30
void * Allocate(int32 size)
Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize.
void DestroyFixture(b2Fixture *fixture)
Definition: b2Body.cpp:214
bool b2IsValid(float32 x)
This function is used to ensure that a floating point number is not a NaN or infinity.
Definition: b2Math.h:26
float32 m_density
Definition: b2Fixture.h:218
b2World * m_world
Definition: b2Body.h:445
float32 m_mass
Definition: b2Body.h:455
float32 m_invI
Definition: b2Body.h:458
int32 m_fixtureCount
Definition: b2Body.h:450
float32 gravityScale
Scale the gravity applied to this body.
Definition: b2Body.h:122
float32 a0
Definition: b2Math.h:395
void Destroy(b2BlockAllocator *allocator)
Definition: b2Fixture.cpp:69
~b2Body()
Definition: b2Body.cpp:108
void SetActive(bool flag)
Definition: b2Body.cpp:454
bool awake
Is this body initially awake or sleeping?
Definition: b2Body.h:104
float32 density
The density, usually in kg/m^2.
Definition: b2Fixture.h:83
void SetMassData(const b2MassData *data)
Definition: b2Body.cpp:353
bool IsActive() const
Get the active state of the body.
Definition: b2Body.h:659
float32 m_I
Definition: b2Body.h:458
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2Contact.h:274
void Dump()
Dump this body to a log file.
Definition: b2Body.cpp:521
float32 y
Definition: b2Math.h:140
int32 m_flags
Definition: b2World.h:236
float32 m_torque
Definition: b2Body.h:443
b2Vec2 position
Definition: b2Body.h:78
b2BroadPhase m_broadPhase
#define b2Assert(A)
Definition: b2Settings.h:27
void Set(float32 angle)
Set using an angle in radians.
Definition: b2Math.h:312
b2Body * m_body
Definition: b2Fixture.h:221
void TouchProxy(int32 proxyId)
Call to trigger a re-processing of it&#39;s pairs on the next call to UpdatePairs.
float32 m_sleepTime
Definition: b2Body.h:464
void DestroyProxies(b2BroadPhase *broadPhase)
Definition: b2Fixture.cpp:139
void CreateProxies(b2BroadPhase *broadPhase, const b2Transform &xf)
Definition: b2Fixture.cpp:122
uint16 m_flags
Definition: b2Body.h:432
b2Transform m_xf
Definition: b2Body.h:436
void * m_userData
Definition: b2Body.h:466
float32 m_angularVelocity
Definition: b2Body.h:440
b2BlockAllocator m_blockAllocator
Definition: b2World.h:233
bool allowSleep
Definition: b2Body.h:101
bool ShouldCollide(const b2Body *other) const
Definition: b2Body.cpp:394
float32 x
Definition: b2Math.h:140
b2BodyType m_type
Definition: b2Body.h:430
float32 a
world angles
Definition: b2Math.h:395
This holds the mass data computed for a shape.
Definition: b2Shape.h:27
void SetAwake(bool flag)
Definition: b2Body.h:633
b2JointEdge * next
the next joint edge in the body&#39;s joint list
Definition: b2Joint.h:70
void * userData
Use this to store application specific body data.
Definition: b2Body.h:119
b2BodyType
Definition: b2Body.h:39
b2Sweep m_sweep
Definition: b2Body.h:437
float float32
Definition: b2Settings.h:35
b2Fixture * m_fixtureList
Definition: b2Body.h:449
bool IsLocked() const
Is the world locked (in the middle of a time step).
Definition: b2World.h:321
b2Body * m_next
Definition: b2Body.h:447


mvsim
Author(s):
autogenerated on Thu Jun 6 2019 19:36:39