b2_world.cpp
Go to the documentation of this file.
1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #include "b2_contact_solver.h"
24 #include "b2_island.h"
25 
26 #include "box2d/b2_body.h"
27 #include "box2d/b2_broad_phase.h"
28 #include "box2d/b2_chain_shape.h"
29 #include "box2d/b2_circle_shape.h"
30 #include "box2d/b2_collision.h"
31 #include "box2d/b2_contact.h"
32 #include "box2d/b2_draw.h"
33 #include "box2d/b2_edge_shape.h"
34 #include "box2d/b2_fixture.h"
35 #include "box2d/b2_polygon_shape.h"
36 #include "box2d/b2_pulley_joint.h"
38 #include "box2d/b2_timer.h"
39 #include "box2d/b2_world.h"
40 
41 #include <new>
42 
43 b2World::b2World(const b2Vec2& gravity)
44 {
45  m_destructionListener = nullptr;
46  m_debugDraw = nullptr;
47 
48  m_bodyList = nullptr;
49  m_jointList = nullptr;
50 
51  m_bodyCount = 0;
52  m_jointCount = 0;
53 
54  m_warmStarting = true;
55  m_continuousPhysics = true;
56  m_subStepping = false;
57 
58  m_stepComplete = true;
59 
60  m_allowSleep = true;
61  m_gravity = gravity;
62 
63  m_newContacts = false;
64  m_locked = false;
65  m_clearForces = true;
66 
67  m_inv_dt0 = 0.0f;
68 
70 
71  memset(&m_profile, 0, sizeof(b2Profile));
72 }
73 
75 {
76  // Some shapes allocate using b2Alloc.
77  b2Body* b = m_bodyList;
78  while (b)
79  {
80  b2Body* bNext = b->m_next;
81 
83  while (f)
84  {
85  b2Fixture* fNext = f->m_next;
86  f->m_proxyCount = 0;
88  f = fNext;
89  }
90 
91  b = bNext;
92  }
93 }
94 
96 {
97  m_destructionListener = listener;
98 }
99 
101 {
103 }
104 
106 {
108 }
109 
111 {
112  m_debugDraw = debugDraw;
113 }
114 
116 {
117  b2Assert(IsLocked() == false);
118  if (IsLocked())
119  {
120  return nullptr;
121  }
122 
123  void* mem = m_blockAllocator.Allocate(sizeof(b2Body));
124  b2Body* b = new (mem) b2Body(def, this);
125 
126  // Add to world doubly linked list.
127  b->m_prev = nullptr;
128  b->m_next = m_bodyList;
129  if (m_bodyList)
130  {
131  m_bodyList->m_prev = b;
132  }
133  m_bodyList = b;
134  ++m_bodyCount;
135 
136  return b;
137 }
138 
140 {
141  b2Assert(m_bodyCount > 0);
142  b2Assert(IsLocked() == false);
143  if (IsLocked())
144  {
145  return;
146  }
147 
148  // Delete the attached joints.
149  b2JointEdge* je = b->m_jointList;
150  while (je)
151  {
152  b2JointEdge* je0 = je;
153  je = je->next;
154 
156  {
158  }
159 
160  DestroyJoint(je0->joint);
161 
162  b->m_jointList = je;
163  }
164  b->m_jointList = nullptr;
165 
166  // Delete the attached contacts.
167  b2ContactEdge* ce = b->m_contactList;
168  while (ce)
169  {
170  b2ContactEdge* ce0 = ce;
171  ce = ce->next;
173  }
174  b->m_contactList = nullptr;
175 
176  // Delete the attached fixtures. This destroys broad-phase proxies.
177  b2Fixture* f = b->m_fixtureList;
178  while (f)
179  {
180  b2Fixture* f0 = f;
181  f = f->m_next;
182 
184  {
186  }
187 
190  f0->~b2Fixture();
191  m_blockAllocator.Free(f0, sizeof(b2Fixture));
192 
193  b->m_fixtureList = f;
194  b->m_fixtureCount -= 1;
195  }
196  b->m_fixtureList = nullptr;
197  b->m_fixtureCount = 0;
198 
199  // Remove world body list.
200  if (b->m_prev)
201  {
202  b->m_prev->m_next = b->m_next;
203  }
204 
205  if (b->m_next)
206  {
207  b->m_next->m_prev = b->m_prev;
208  }
209 
210  if (b == m_bodyList)
211  {
212  m_bodyList = b->m_next;
213  }
214 
215  --m_bodyCount;
216  b->~b2Body();
217  m_blockAllocator.Free(b, sizeof(b2Body));
218 }
219 
221 {
222  b2Assert(IsLocked() == false);
223  if (IsLocked())
224  {
225  return nullptr;
226  }
227 
229 
230  // Connect to the world list.
231  j->m_prev = nullptr;
232  j->m_next = m_jointList;
233  if (m_jointList)
234  {
235  m_jointList->m_prev = j;
236  }
237  m_jointList = j;
238  ++m_jointCount;
239 
240  // Connect to the bodies' doubly linked lists.
241  j->m_edgeA.joint = j;
242  j->m_edgeA.other = j->m_bodyB;
243  j->m_edgeA.prev = nullptr;
244  j->m_edgeA.next = j->m_bodyA->m_jointList;
245  if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA;
246  j->m_bodyA->m_jointList = &j->m_edgeA;
247 
248  j->m_edgeB.joint = j;
249  j->m_edgeB.other = j->m_bodyA;
250  j->m_edgeB.prev = nullptr;
251  j->m_edgeB.next = j->m_bodyB->m_jointList;
252  if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB;
253  j->m_bodyB->m_jointList = &j->m_edgeB;
254 
255  b2Body* bodyA = def->bodyA;
256  b2Body* bodyB = def->bodyB;
257 
258  // If the joint prevents collisions, then flag any contacts for filtering.
259  if (def->collideConnected == false)
260  {
261  b2ContactEdge* edge = bodyB->GetContactList();
262  while (edge)
263  {
264  if (edge->other == bodyA)
265  {
266  // Flag the contact for filtering at the next time step (where either
267  // body is awake).
268  edge->contact->FlagForFiltering();
269  }
270 
271  edge = edge->next;
272  }
273  }
274 
275  // Note: creating a joint doesn't wake the bodies.
276 
277  return j;
278 }
279 
281 {
282  b2Assert(IsLocked() == false);
283  if (IsLocked())
284  {
285  return;
286  }
287 
288  bool collideConnected = j->m_collideConnected;
289 
290  // Remove from the doubly linked list.
291  if (j->m_prev)
292  {
293  j->m_prev->m_next = j->m_next;
294  }
295 
296  if (j->m_next)
297  {
298  j->m_next->m_prev = j->m_prev;
299  }
300 
301  if (j == m_jointList)
302  {
303  m_jointList = j->m_next;
304  }
305 
306  // Disconnect from island graph.
307  b2Body* bodyA = j->m_bodyA;
308  b2Body* bodyB = j->m_bodyB;
309 
310  // Wake up connected bodies.
311  bodyA->SetAwake(true);
312  bodyB->SetAwake(true);
313 
314  // Remove from body 1.
315  if (j->m_edgeA.prev)
316  {
317  j->m_edgeA.prev->next = j->m_edgeA.next;
318  }
319 
320  if (j->m_edgeA.next)
321  {
322  j->m_edgeA.next->prev = j->m_edgeA.prev;
323  }
324 
325  if (&j->m_edgeA == bodyA->m_jointList)
326  {
327  bodyA->m_jointList = j->m_edgeA.next;
328  }
329 
330  j->m_edgeA.prev = nullptr;
331  j->m_edgeA.next = nullptr;
332 
333  // Remove from body 2
334  if (j->m_edgeB.prev)
335  {
336  j->m_edgeB.prev->next = j->m_edgeB.next;
337  }
338 
339  if (j->m_edgeB.next)
340  {
341  j->m_edgeB.next->prev = j->m_edgeB.prev;
342  }
343 
344  if (&j->m_edgeB == bodyB->m_jointList)
345  {
346  bodyB->m_jointList = j->m_edgeB.next;
347  }
348 
349  j->m_edgeB.prev = nullptr;
350  j->m_edgeB.next = nullptr;
351 
353 
354  b2Assert(m_jointCount > 0);
355  --m_jointCount;
356 
357  // If the joint prevents collisions, then flag any contacts for filtering.
358  if (collideConnected == false)
359  {
360  b2ContactEdge* edge = bodyB->GetContactList();
361  while (edge)
362  {
363  if (edge->other == bodyA)
364  {
365  // Flag the contact for filtering at the next time step (where either
366  // body is awake).
367  edge->contact->FlagForFiltering();
368  }
369 
370  edge = edge->next;
371  }
372  }
373 }
374 
375 //
377 {
378  if (flag == m_allowSleep)
379  {
380  return;
381  }
382 
383  m_allowSleep = flag;
384  if (m_allowSleep == false)
385  {
386  for (b2Body* b = m_bodyList; b; b = b->m_next)
387  {
388  b->SetAwake(true);
389  }
390  }
391 }
392 
393 // Find islands, integrate and solve constraints, solve position constraints
394 void b2World::Solve(const b2TimeStep& step)
395 {
396  m_profile.solveInit = 0.0f;
397  m_profile.solveVelocity = 0.0f;
398  m_profile.solvePosition = 0.0f;
399 
400  // Size the island for the worst case.
401  b2Island island(m_bodyCount,
403  m_jointCount,
406 
407  // Clear all the island flags.
408  for (b2Body* b = m_bodyList; b; b = b->m_next)
409  {
410  b->m_flags &= ~b2Body::e_islandFlag;
411  }
412  for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
413  {
414  c->m_flags &= ~b2Contact::e_islandFlag;
415  }
416  for (b2Joint* j = m_jointList; j; j = j->m_next)
417  {
418  j->m_islandFlag = false;
419  }
420 
421  // Build and simulate all awake islands.
422  int32 stackSize = m_bodyCount;
423  b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*));
424  for (b2Body* seed = m_bodyList; seed; seed = seed->m_next)
425  {
426  if (seed->m_flags & b2Body::e_islandFlag)
427  {
428  continue;
429  }
430 
431  if (seed->IsAwake() == false || seed->IsEnabled() == false)
432  {
433  continue;
434  }
435 
436  // The seed can be dynamic or kinematic.
437  if (seed->GetType() == b2_staticBody)
438  {
439  continue;
440  }
441 
442  // Reset island and stack.
443  island.Clear();
444  int32 stackCount = 0;
445  stack[stackCount++] = seed;
446  seed->m_flags |= b2Body::e_islandFlag;
447 
448  // Perform a depth first search (DFS) on the constraint graph.
449  while (stackCount > 0)
450  {
451  // Grab the next body off the stack and add it to the island.
452  b2Body* b = stack[--stackCount];
453  b2Assert(b->IsEnabled() == true);
454  island.Add(b);
455 
456  // To keep islands as small as possible, we don't
457  // propagate islands across static bodies.
458  if (b->GetType() == b2_staticBody)
459  {
460  continue;
461  }
462 
463  // Make sure the body is awake (without resetting sleep timer).
465 
466  // Search all contacts connected to this body.
467  for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next)
468  {
469  b2Contact* contact = ce->contact;
470 
471  // Has this contact already been added to an island?
472  if (contact->m_flags & b2Contact::e_islandFlag)
473  {
474  continue;
475  }
476 
477  // Is this contact solid and touching?
478  if (contact->IsEnabled() == false ||
479  contact->IsTouching() == false)
480  {
481  continue;
482  }
483 
484  // Skip sensors.
485  bool sensorA = contact->m_fixtureA->m_isSensor;
486  bool sensorB = contact->m_fixtureB->m_isSensor;
487  if (sensorA || sensorB)
488  {
489  continue;
490  }
491 
492  island.Add(contact);
493  contact->m_flags |= b2Contact::e_islandFlag;
494 
495  b2Body* other = ce->other;
496 
497  // Was the other body already added to this island?
498  if (other->m_flags & b2Body::e_islandFlag)
499  {
500  continue;
501  }
502 
503  b2Assert(stackCount < stackSize);
504  stack[stackCount++] = other;
505  other->m_flags |= b2Body::e_islandFlag;
506  }
507 
508  // Search all joints connect to this body.
509  for (b2JointEdge* je = b->m_jointList; je; je = je->next)
510  {
511  if (je->joint->m_islandFlag == true)
512  {
513  continue;
514  }
515 
516  b2Body* other = je->other;
517 
518  // Don't simulate joints connected to diabled bodies.
519  if (other->IsEnabled() == false)
520  {
521  continue;
522  }
523 
524  island.Add(je->joint);
525  je->joint->m_islandFlag = true;
526 
527  if (other->m_flags & b2Body::e_islandFlag)
528  {
529  continue;
530  }
531 
532  b2Assert(stackCount < stackSize);
533  stack[stackCount++] = other;
534  other->m_flags |= b2Body::e_islandFlag;
535  }
536  }
537 
538  b2Profile profile;
539  island.Solve(&profile, step, m_gravity, m_allowSleep);
540  m_profile.solveInit += profile.solveInit;
543 
544  // Post solve cleanup.
545  for (int32 i = 0; i < island.m_bodyCount; ++i)
546  {
547  // Allow static bodies to participate in other islands.
548  b2Body* b = island.m_bodies[i];
549  if (b->GetType() == b2_staticBody)
550  {
551  b->m_flags &= ~b2Body::e_islandFlag;
552  }
553  }
554  }
555 
556  m_stackAllocator.Free(stack);
557 
558  {
559  b2Timer timer;
560  // Synchronize fixtures, check for out of range bodies.
561  for (b2Body* b = m_bodyList; b; b = b->GetNext())
562  {
563  // If a body was not in an island then it did not move.
564  if ((b->m_flags & b2Body::e_islandFlag) == 0)
565  {
566  continue;
567  }
568 
569  if (b->GetType() == b2_staticBody)
570  {
571  continue;
572  }
573 
574  // Update fixtures (for broad-phase).
575  b->SynchronizeFixtures();
576  }
577 
578  // Look for new contacts.
581  }
582 }
583 
584 // Find TOI contacts and solve them.
585 void b2World::SolveTOI(const b2TimeStep& step)
586 {
588 
589  if (m_stepComplete)
590  {
591  for (b2Body* b = m_bodyList; b; b = b->m_next)
592  {
593  b->m_flags &= ~b2Body::e_islandFlag;
594  b->m_sweep.alpha0 = 0.0f;
595  }
596 
597  for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
598  {
599  // Invalidate TOI
601  c->m_toiCount = 0;
602  c->m_toi = 1.0f;
603  }
604  }
605 
606  // Find TOI events and solve them.
607  for (;;)
608  {
609  // Find the first TOI.
610  b2Contact* minContact = nullptr;
611  float minAlpha = 1.0f;
612 
613  for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
614  {
615  // Is this contact disabled?
616  if (c->IsEnabled() == false)
617  {
618  continue;
619  }
620 
621  // Prevent excessive sub-stepping.
622  if (c->m_toiCount > b2_maxSubSteps)
623  {
624  continue;
625  }
626 
627  float alpha = 1.0f;
628  if (c->m_flags & b2Contact::e_toiFlag)
629  {
630  // This contact has a valid cached TOI.
631  alpha = c->m_toi;
632  }
633  else
634  {
635  b2Fixture* fA = c->GetFixtureA();
636  b2Fixture* fB = c->GetFixtureB();
637 
638  // Is there a sensor?
639  if (fA->IsSensor() || fB->IsSensor())
640  {
641  continue;
642  }
643 
644  b2Body* bA = fA->GetBody();
645  b2Body* bB = fB->GetBody();
646 
647  b2BodyType typeA = bA->m_type;
648  b2BodyType typeB = bB->m_type;
649  b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody);
650 
651  bool activeA = bA->IsAwake() && typeA != b2_staticBody;
652  bool activeB = bB->IsAwake() && typeB != b2_staticBody;
653 
654  // Is at least one body active (awake and dynamic or kinematic)?
655  if (activeA == false && activeB == false)
656  {
657  continue;
658  }
659 
660  bool collideA = bA->IsBullet() || typeA != b2_dynamicBody;
661  bool collideB = bB->IsBullet() || typeB != b2_dynamicBody;
662 
663  // Are these two non-bullet dynamic bodies?
664  if (collideA == false && collideB == false)
665  {
666  continue;
667  }
668 
669  // Compute the TOI for this contact.
670  // Put the sweeps onto the same time interval.
671  float alpha0 = bA->m_sweep.alpha0;
672 
673  if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0)
674  {
675  alpha0 = bB->m_sweep.alpha0;
676  bA->m_sweep.Advance(alpha0);
677  }
678  else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0)
679  {
680  alpha0 = bA->m_sweep.alpha0;
681  bB->m_sweep.Advance(alpha0);
682  }
683 
684  b2Assert(alpha0 < 1.0f);
685 
686  int32 indexA = c->GetChildIndexA();
687  int32 indexB = c->GetChildIndexB();
688 
689  // Compute the time of impact in interval [0, minTOI]
690  b2TOIInput input;
691  input.proxyA.Set(fA->GetShape(), indexA);
692  input.proxyB.Set(fB->GetShape(), indexB);
693  input.sweepA = bA->m_sweep;
694  input.sweepB = bB->m_sweep;
695  input.tMax = 1.0f;
696 
697  b2TOIOutput output;
698  b2TimeOfImpact(&output, &input);
699 
700  // Beta is the fraction of the remaining portion of the .
701  float beta = output.t;
702  if (output.state == b2TOIOutput::e_touching)
703  {
704  alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
705  }
706  else
707  {
708  alpha = 1.0f;
709  }
710 
711  c->m_toi = alpha;
712  c->m_flags |= b2Contact::e_toiFlag;
713  }
714 
715  if (alpha < minAlpha)
716  {
717  // This is the minimum TOI found so far.
718  minContact = c;
719  minAlpha = alpha;
720  }
721  }
722 
723  if (minContact == nullptr || 1.0f - 10.0f * b2_epsilon < minAlpha)
724  {
725  // No more TOI events. Done!
726  m_stepComplete = true;
727  break;
728  }
729 
730  // Advance the bodies to the TOI.
731  b2Fixture* fA = minContact->GetFixtureA();
732  b2Fixture* fB = minContact->GetFixtureB();
733  b2Body* bA = fA->GetBody();
734  b2Body* bB = fB->GetBody();
735 
736  b2Sweep backup1 = bA->m_sweep;
737  b2Sweep backup2 = bB->m_sweep;
738 
739  bA->Advance(minAlpha);
740  bB->Advance(minAlpha);
741 
742  // The TOI contact likely has some new contact points.
744  minContact->m_flags &= ~b2Contact::e_toiFlag;
745  ++minContact->m_toiCount;
746 
747  // Is the contact solid?
748  if (minContact->IsEnabled() == false || minContact->IsTouching() == false)
749  {
750  // Restore the sweeps.
751  minContact->SetEnabled(false);
752  bA->m_sweep = backup1;
753  bB->m_sweep = backup2;
754  bA->SynchronizeTransform();
755  bB->SynchronizeTransform();
756  continue;
757  }
758 
759  bA->SetAwake(true);
760  bB->SetAwake(true);
761 
762  // Build the island
763  island.Clear();
764  island.Add(bA);
765  island.Add(bB);
766  island.Add(minContact);
767 
770  minContact->m_flags |= b2Contact::e_islandFlag;
771 
772  // Get contacts on bodyA and bodyB.
773  b2Body* bodies[2] = {bA, bB};
774  for (int32 i = 0; i < 2; ++i)
775  {
776  b2Body* body = bodies[i];
777  if (body->m_type == b2_dynamicBody)
778  {
779  for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
780  {
781  if (island.m_bodyCount == island.m_bodyCapacity)
782  {
783  break;
784  }
785 
786  if (island.m_contactCount == island.m_contactCapacity)
787  {
788  break;
789  }
790 
791  b2Contact* contact = ce->contact;
792 
793  // Has this contact already been added to the island?
794  if (contact->m_flags & b2Contact::e_islandFlag)
795  {
796  continue;
797  }
798 
799  // Only add static, kinematic, or bullet bodies.
800  b2Body* other = ce->other;
801  if (other->m_type == b2_dynamicBody &&
802  body->IsBullet() == false && other->IsBullet() == false)
803  {
804  continue;
805  }
806 
807  // Skip sensors.
808  bool sensorA = contact->m_fixtureA->m_isSensor;
809  bool sensorB = contact->m_fixtureB->m_isSensor;
810  if (sensorA || sensorB)
811  {
812  continue;
813  }
814 
815  // Tentatively advance the body to the TOI.
816  b2Sweep backup = other->m_sweep;
817  if ((other->m_flags & b2Body::e_islandFlag) == 0)
818  {
819  other->Advance(minAlpha);
820  }
821 
822  // Update the contact points
824 
825  // Was the contact disabled by the user?
826  if (contact->IsEnabled() == false)
827  {
828  other->m_sweep = backup;
829  other->SynchronizeTransform();
830  continue;
831  }
832 
833  // Are there contact points?
834  if (contact->IsTouching() == false)
835  {
836  other->m_sweep = backup;
837  other->SynchronizeTransform();
838  continue;
839  }
840 
841  // Add the contact to the island
842  contact->m_flags |= b2Contact::e_islandFlag;
843  island.Add(contact);
844 
845  // Has the other body already been added to the island?
846  if (other->m_flags & b2Body::e_islandFlag)
847  {
848  continue;
849  }
850 
851  // Add the other body to the island.
852  other->m_flags |= b2Body::e_islandFlag;
853 
854  if (other->m_type != b2_staticBody)
855  {
856  other->SetAwake(true);
857  }
858 
859  island.Add(other);
860  }
861  }
862  }
863 
864  b2TimeStep subStep;
865  subStep.dt = (1.0f - minAlpha) * step.dt;
866  subStep.inv_dt = 1.0f / subStep.dt;
867  subStep.dtRatio = 1.0f;
868  subStep.positionIterations = 20;
869  subStep.velocityIterations = step.velocityIterations;
870  subStep.warmStarting = false;
871  island.SolveTOI(subStep, bA->m_islandIndex, bB->m_islandIndex);
872 
873  // Reset island flags and synchronize broad-phase proxies.
874  for (int32 i = 0; i < island.m_bodyCount; ++i)
875  {
876  b2Body* body = island.m_bodies[i];
877  body->m_flags &= ~b2Body::e_islandFlag;
878 
879  if (body->m_type != b2_dynamicBody)
880  {
881  continue;
882  }
883 
884  body->SynchronizeFixtures();
885 
886  // Invalidate all contact TOIs on this displaced body.
887  for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
888  {
889  ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
890  }
891  }
892 
893  // Commit fixture proxy movements to the broad-phase so that new contacts are created.
894  // Also, some contacts can be destroyed.
896 
897  if (m_subStepping)
898  {
899  m_stepComplete = false;
900  break;
901  }
902  }
903 }
904 
905 void b2World::Step(float dt, int32 velocityIterations, int32 positionIterations)
906 {
907  b2Timer stepTimer;
908 
909  // If new fixtures were added, we need to find the new contacts.
910  if (m_newContacts)
911  {
913  m_newContacts = false;
914  }
915 
916  m_locked = true;
917 
919  step.dt = dt;
920  step.velocityIterations = velocityIterations;
921  step.positionIterations = positionIterations;
922  if (dt > 0.0f)
923  {
924  step.inv_dt = 1.0f / dt;
925  }
926  else
927  {
928  step.inv_dt = 0.0f;
929  }
930 
931  step.dtRatio = m_inv_dt0 * dt;
932 
934 
935  // Update contacts. This is where some contacts are destroyed.
936  {
937  b2Timer timer;
940  }
941 
942  // Integrate velocities, solve velocity constraints, and integrate positions.
943  if (m_stepComplete && step.dt > 0.0f)
944  {
945  b2Timer timer;
946  Solve(step);
947  m_profile.solve = timer.GetMilliseconds();
948  }
949 
950  // Handle TOI events.
951  if (m_continuousPhysics && step.dt > 0.0f)
952  {
953  b2Timer timer;
954  SolveTOI(step);
956  }
957 
958  if (step.dt > 0.0f)
959  {
960  m_inv_dt0 = step.inv_dt;
961  }
962 
963  if (m_clearForces)
964  {
965  ClearForces();
966  }
967 
968  m_locked = false;
969 
970  m_profile.step = stepTimer.GetMilliseconds();
971 }
972 
974 {
975  for (b2Body* body = m_bodyList; body; body = body->GetNext())
976  {
977  body->m_force.SetZero();
978  body->m_torque = 0.0f;
979  }
980 }
981 
983 {
984  bool QueryCallback(int32 proxyId)
985  {
986  b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId);
987  return callback->ReportFixture(proxy->fixture);
988  }
989 
992 };
993 
994 void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const
995 {
996  b2WorldQueryWrapper wrapper;
998  wrapper.callback = callback;
999  m_contactManager.m_broadPhase.Query(&wrapper, aabb);
1000 }
1001 
1003 {
1004  float RayCastCallback(const b2RayCastInput& input, int32 proxyId)
1005  {
1006  void* userData = broadPhase->GetUserData(proxyId);
1007  b2FixtureProxy* proxy = (b2FixtureProxy*)userData;
1008  b2Fixture* fixture = proxy->fixture;
1009  int32 index = proxy->childIndex;
1010  b2RayCastOutput output;
1011  bool hit = fixture->RayCast(&output, input, index);
1012 
1013  if (hit)
1014  {
1015  float fraction = output.fraction;
1016  b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
1017  return callback->ReportFixture(fixture, point, output.normal, fraction);
1018  }
1019 
1020  return input.maxFraction;
1021  }
1022 
1025 };
1026 
1027 void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
1028 {
1029  b2WorldRayCastWrapper wrapper;
1031  wrapper.callback = callback;
1032  b2RayCastInput input;
1033  input.maxFraction = 1.0f;
1034  input.p1 = point1;
1035  input.p2 = point2;
1036  m_contactManager.m_broadPhase.RayCast(&wrapper, input);
1037 }
1038 
1039 void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color)
1040 {
1041  switch (fixture->GetType())
1042  {
1043  case b2Shape::e_circle:
1044  {
1045  b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
1046 
1047  b2Vec2 center = b2Mul(xf, circle->m_p);
1048  float radius = circle->m_radius;
1049  b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f));
1050 
1051  m_debugDraw->DrawSolidCircle(center, radius, axis, color);
1052  }
1053  break;
1054 
1055  case b2Shape::e_edge:
1056  {
1057  b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
1058  b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
1059  b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
1060  m_debugDraw->DrawSegment(v1, v2, color);
1061 
1062  if (edge->m_oneSided == false)
1063  {
1064  m_debugDraw->DrawPoint(v1, 4.0f, color);
1065  m_debugDraw->DrawPoint(v2, 4.0f, color);
1066  }
1067  }
1068  break;
1069 
1070  case b2Shape::e_chain:
1071  {
1072  b2ChainShape* chain = (b2ChainShape*)fixture->GetShape();
1073  int32 count = chain->m_count;
1074  const b2Vec2* vertices = chain->m_vertices;
1075 
1076  b2Vec2 v1 = b2Mul(xf, vertices[0]);
1077  for (int32 i = 1; i < count; ++i)
1078  {
1079  b2Vec2 v2 = b2Mul(xf, vertices[i]);
1080  m_debugDraw->DrawSegment(v1, v2, color);
1081  v1 = v2;
1082  }
1083  }
1084  break;
1085 
1086  case b2Shape::e_polygon:
1087  {
1088  b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
1089  int32 vertexCount = poly->m_count;
1090  b2Assert(vertexCount <= b2_maxPolygonVertices);
1091  b2Vec2 vertices[b2_maxPolygonVertices];
1092 
1093  for (int32 i = 0; i < vertexCount; ++i)
1094  {
1095  vertices[i] = b2Mul(xf, poly->m_vertices[i]);
1096  }
1097 
1098  m_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
1099  }
1100  break;
1101 
1102  default:
1103  break;
1104  }
1105 }
1106 
1108 {
1109  if (m_debugDraw == nullptr)
1110  {
1111  return;
1112  }
1113 
1114  uint32 flags = m_debugDraw->GetFlags();
1115 
1116  if (flags & b2Draw::e_shapeBit)
1117  {
1118  for (b2Body* b = m_bodyList; b; b = b->GetNext())
1119  {
1120  const b2Transform& xf = b->GetTransform();
1121  for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
1122  {
1123  if (b->GetType() == b2_dynamicBody && b->m_mass == 0.0f)
1124  {
1125  // Bad body
1126  DrawShape(f, xf, b2Color(1.0f, 0.0f, 0.0f));
1127  }
1128  else if (b->IsEnabled() == false)
1129  {
1130  DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f));
1131  }
1132  else if (b->GetType() == b2_staticBody)
1133  {
1134  DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f));
1135  }
1136  else if (b->GetType() == b2_kinematicBody)
1137  {
1138  DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f));
1139  }
1140  else if (b->IsAwake() == false)
1141  {
1142  DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f));
1143  }
1144  else
1145  {
1146  DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f));
1147  }
1148  }
1149  }
1150  }
1151 
1152  if (flags & b2Draw::e_jointBit)
1153  {
1154  for (b2Joint* j = m_jointList; j; j = j->GetNext())
1155  {
1156  j->Draw(m_debugDraw);
1157  }
1158  }
1159 
1160  if (flags & b2Draw::e_pairBit)
1161  {
1162  b2Color color(0.3f, 0.9f, 0.9f);
1163  for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext())
1164  {
1165  b2Fixture* fixtureA = c->GetFixtureA();
1166  b2Fixture* fixtureB = c->GetFixtureB();
1167  int32 indexA = c->GetChildIndexA();
1168  int32 indexB = c->GetChildIndexB();
1169  b2Vec2 cA = fixtureA->GetAABB(indexA).GetCenter();
1170  b2Vec2 cB = fixtureB->GetAABB(indexB).GetCenter();
1171 
1172  m_debugDraw->DrawSegment(cA, cB, color);
1173  }
1174  }
1175 
1176  if (flags & b2Draw::e_aabbBit)
1177  {
1178  b2Color color(0.9f, 0.3f, 0.9f);
1180 
1181  for (b2Body* b = m_bodyList; b; b = b->GetNext())
1182  {
1183  if (b->IsEnabled() == false)
1184  {
1185  continue;
1186  }
1187 
1188  for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
1189  {
1190  for (int32 i = 0; i < f->m_proxyCount; ++i)
1191  {
1192  b2FixtureProxy* proxy = f->m_proxies + i;
1193  b2AABB aabb = bp->GetFatAABB(proxy->proxyId);
1194  b2Vec2 vs[4];
1195  vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
1196  vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
1197  vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
1198  vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
1199 
1200  m_debugDraw->DrawPolygon(vs, 4, color);
1201  }
1202  }
1203  }
1204  }
1205 
1206  if (flags & b2Draw::e_centerOfMassBit)
1207  {
1208  for (b2Body* b = m_bodyList; b; b = b->GetNext())
1209  {
1210  b2Transform xf = b->GetTransform();
1211  xf.p = b->GetWorldCenter();
1213  }
1214  }
1215 }
1216 
1218 {
1220 }
1221 
1223 {
1225 }
1226 
1228 {
1230 }
1231 
1233 {
1235 }
1236 
1237 void b2World::ShiftOrigin(const b2Vec2& newOrigin)
1238 {
1239  b2Assert(m_locked == false);
1240  if (m_locked)
1241  {
1242  return;
1243  }
1244 
1245  for (b2Body* b = m_bodyList; b; b = b->m_next)
1246  {
1247  b->m_xf.p -= newOrigin;
1248  b->m_sweep.c0 -= newOrigin;
1249  b->m_sweep.c -= newOrigin;
1250  }
1251 
1252  for (b2Joint* j = m_jointList; j; j = j->m_next)
1253  {
1254  j->ShiftOrigin(newOrigin);
1255  }
1256 
1258 }
1259 
1261 {
1262  if (m_locked)
1263  {
1264  return;
1265  }
1266 
1267  b2OpenDump("box2d_dump.inl");
1268 
1269  b2Dump("b2Vec2 g(%.9g, %.9g);\n", m_gravity.x, m_gravity.y);
1270  b2Dump("m_world->SetGravity(g);\n");
1271 
1272  b2Dump("b2Body** bodies = (b2Body**)b2Alloc(%d * sizeof(b2Body*));\n", m_bodyCount);
1273  b2Dump("b2Joint** joints = (b2Joint**)b2Alloc(%d * sizeof(b2Joint*));\n", m_jointCount);
1274 
1275  int32 i = 0;
1276  for (b2Body* b = m_bodyList; b; b = b->m_next)
1277  {
1278  b->m_islandIndex = i;
1279  b->Dump();
1280  ++i;
1281  }
1282 
1283  i = 0;
1284  for (b2Joint* j = m_jointList; j; j = j->m_next)
1285  {
1286  j->m_index = i;
1287  ++i;
1288  }
1289 
1290  // First pass on joints, skip gear joints.
1291  for (b2Joint* j = m_jointList; j; j = j->m_next)
1292  {
1293  if (j->m_type == e_gearJoint)
1294  {
1295  continue;
1296  }
1297 
1298  b2Dump("{\n");
1299  j->Dump();
1300  b2Dump("}\n");
1301  }
1302 
1303  // Second pass on joints, only gear joints.
1304  for (b2Joint* j = m_jointList; j; j = j->m_next)
1305  {
1306  if (j->m_type != e_gearJoint)
1307  {
1308  continue;
1309  }
1310 
1311  b2Dump("{\n");
1312  j->Dump();
1313  b2Dump("}\n");
1314  }
1315 
1316  b2Dump("b2Free(joints);\n");
1317  b2Dump("b2Free(bodies);\n");
1318  b2Dump("joints = nullptr;\n");
1319  b2Dump("bodies = nullptr;\n");
1320 
1321  b2CloseDump();
1322 }
b2ContactListener * m_contactListener
float collide
Definition: b2_time_step.h:32
This is an internal class.
Definition: b2_island.h:38
virtual void DrawSegment(const b2Vec2 &p1, const b2Vec2 &p2, const b2Color &color)=0
Draw a line segment.
int32 m_bodyCount
Definition: b2_world.h:237
b2Fixture * m_fixtureB
Definition: b2_contact.h:227
void b2OpenDump(const char *fileName)
Dump to a file. Only one dump file allowed at a time.
Definition: b2_settings.cpp:51
void Update(b2ContactListener *listener)
Definition: b2_contact.cpp:166
void RayCast(b2RayCastCallback *callback, const b2Vec2 &point1, const b2Vec2 &point2) const
Definition: b2_world.cpp:1027
virtual void DrawTransform(const b2Transform &xf)=0
int32 m_islandIndex
Definition: b2_body.h:439
T b2Min(T a, T b)
Definition: b2_math.h:626
void ClearForces()
Definition: b2_world.cpp:973
b2Vec2 * m_vertices
The vertices. Owned by this class.
void SynchronizeFixtures()
Definition: b2_body.cpp:442
void Set(const b2Shape *shape, int32 index)
Definition: b2_distance.cpp:32
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2_math.h:422
static void Destroy(b2Joint *joint, b2BlockAllocator *allocator)
Definition: b2_joint.cpp:174
b2Vec2 p
Definition: b2_math.h:360
draw center of mass frame
Definition: b2_draw.h:61
bool m_newContacts
Definition: b2_world.h:250
b2ContactManager m_contactManager
Definition: b2_world.h:232
float GetTreeQuality() const
Get the quality metric of the embedded tree.
uint32 GetFlags() const
Get the drawing flags.
Definition: b2_draw.cpp:34
void Destroy(b2Contact *c)
b2Vec2 lowerBound
the lower vertex
Definition: b2_collision.h:220
b2Rot q
Definition: b2_math.h:361
int32 GetTreeBalance() const
Get the balance of the dynamic tree.
Definition: b2_world.cpp:1227
void SetAllowSleeping(bool flag)
Enable/disable sleep.
Definition: b2_world.cpp:376
b2ContactFilter * m_contactFilter
f
Joint definitions are used to construct joints.
Definition: b2_joint.h:72
void DrawShape(b2Fixture *shape, const b2Transform &xf, const b2Color &color)
Definition: b2_world.cpp:1039
b2BodyType
Definition: b2_body.h:43
b2Fixture * m_fixtureA
Definition: b2_contact.h:226
bool IsBullet() const
Is this body treated like a bullet for continuous collision detection?
Definition: b2_body.h:633
float solve
Definition: b2_time_step.h:33
float x
Definition: b2_math.h:128
float y
Definition: b2_math.h:128
b2Fixture * fixture
Definition: b2_fixture.h:106
b2Contact * GetNext()
Get the next contact in the world&#39;s contact list.
Definition: b2_contact.h:286
void SetEnabled(bool flag)
Definition: b2_contact.h:264
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2_contact.h:306
bool m_locked
Definition: b2_world.h:251
virtual void DrawSolidCircle(const b2Vec2 &center, float radius, const b2Vec2 &axis, const b2Color &color)=0
Draw a solid circle.
B2_API void b2TimeOfImpact(b2TOIOutput *output, const b2TOIInput *input)
b2Fixture * m_next
Definition: b2_fixture.h:234
b2ContactEdge * GetContactList()
Definition: b2_body.h:714
Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
Definition: b2_collision.h:153
bool m_continuousPhysics
Definition: b2_world.h:256
b2JointEdge * prev
the previous joint edge in the body&#39;s joint list
Definition: b2_joint.h:67
b2ContactEdge * m_contactList
Definition: b2_body.h:458
virtual void DrawPoint(const b2Vec2 &p, float size, const b2Color &color)=0
Draw a point.
bool m_collideConnected
Definition: b2_joint.h:188
const b2BroadPhase * broadPhase
Definition: b2_world.cpp:990
b2Body * m_bodyList
Definition: b2_world.h:234
int32 m_jointCount
Definition: b2_world.h:238
float solveVelocity
Definition: b2_time_step.h:35
void RayCast(T *callback, const b2RayCastInput &input) const
friend class b2Body
Definition: b2_world.h:219
b2World(const b2Vec2 &gravity)
Definition: b2_world.cpp:43
void Free(void *p, int32 size)
Free memory. This will use b2Free if the size is larger than b2_maxBlockSize.
int32 m_proxyCount
Definition: b2_fixture.h:244
const b2AABB & GetAABB(int32 childIndex) const
Definition: b2_fixture.h:359
b2Joint * GetNext()
Get the next joint the world joint list.
Definition: b2_joint.h:208
This is an internal structure.
Definition: b2_time_step.h:42
Input parameters for b2TimeOfImpact.
This proxy is used internally to connect fixtures to the broad-phase.
Definition: b2_fixture.h:103
void b2CloseDump()
Definition: b2_settings.cpp:70
void SetDebugDraw(b2Draw *debugDraw)
Definition: b2_world.cpp:110
void QueryAABB(b2QueryCallback *callback, const b2AABB &aabb) const
Definition: b2_world.cpp:994
void DestroyJoint(b2Joint *joint)
Definition: b2_world.cpp:280
bool m_subStepping
Definition: b2_world.h:257
b2ContactEdge * next
the next contact edge in the body&#39;s contact list
Definition: b2_contact.h:82
const b2BroadPhase * broadPhase
Definition: b2_world.cpp:1023
void FlagForFiltering()
Flag this contact for filtering. Filtering will occur the next time step.
Definition: b2_contact.h:326
int32 m_contactCapacity
Definition: b2_island.h:93
A solid circle shape.
A 2D column vector.
Definition: b2_math.h:41
b2Joint * m_prev
Definition: b2_joint.h:178
b2Body * other
provides quick access to the other body attached.
Definition: b2_joint.h:65
void ShiftOrigin(const b2Vec2 &newOrigin)
Definition: b2_world.cpp:1237
b2Contact * contact
the contact
Definition: b2_contact.h:80
void SolveTOI(const b2TimeStep &subStep, int32 toiIndexA, int32 toiIndexB)
Definition: b2_island.cpp:389
b2DistanceProxy proxyA
b2Vec2 GetCenter() const
Get the center of the AABB.
Definition: b2_collision.h:174
signed int int32
Definition: b2_types.h:28
virtual void SayGoodbye(b2Joint *joint)=0
bool IsEnabled() const
Has this contact been disabled?
Definition: b2_contact.h:276
b2Vec2 m_p
Position.
Color for debug drawing. Each value has the range [0,1].
Definition: b2_draw.h:30
b2JointEdge m_edgeB
Definition: b2_joint.h:181
b2Joint * joint
the joint
Definition: b2_joint.h:66
void Advance(float t)
Definition: b2_body.h:861
b2DistanceProxy proxyB
virtual void DrawPolygon(const b2Vec2 *vertices, int32 vertexCount, const b2Color &color)=0
Draw a closed polygon provided in CCW order.
int32 GetProxyCount() const
Get the number of proxies.
void Solve(const b2TimeStep &step)
Definition: b2_world.cpp:394
b2JointEdge * m_jointList
Definition: b2_body.h:457
int32 m_bodyCount
Definition: b2_island.h:88
void SolveTOI(const b2TimeStep &step)
Definition: b2_world.cpp:585
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2Body ** m_bodies
Definition: b2_island.h:81
float solvePosition
Definition: b2_time_step.h:36
float GetTreeQuality() const
Definition: b2_world.cpp:1232
b2Body * m_prev
Definition: b2_body.h:451
Definition: b2_draw.h:48
bool IsLocked() const
Is the world locked (in the middle of a time step).
Definition: b2_world.h:319
float m_radius
Definition: b2_shape.h:102
void * Allocate(int32 size)
Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize.
int32 GetTreeHeight() const
Get the height of the embedded tree.
b2Joint * m_next
Definition: b2_joint.h:179
Profiling data. Times are in milliseconds.
Definition: b2_time_step.h:29
b2Joint * m_jointList
Definition: b2_world.h:235
b2Contact * m_contactList
draw axis aligned bounding boxes
Definition: b2_draw.h:59
virtual void DrawSolidPolygon(const b2Vec2 *vertices, int32 vertexCount, const b2Color &color)=0
Draw a solid closed polygon provided in CCW order.
b2Joint * CreateJoint(const b2JointDef *def)
Definition: b2_world.cpp:220
bool RayCast(b2RayCastOutput *output, const b2RayCastInput &input, int32 childIndex) const
Definition: b2_fixture.h:349
float m_toi
Definition: b2_contact.h:235
b2QueryCallback * callback
Definition: b2_world.cpp:991
unsigned int uint32
Definition: b2_types.h:31
void * Allocate(int32 size)
bool collideConnected
Set this flag to true if the attached bodies should collide.
Definition: b2_joint.h:95
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2Profile m_profile
Definition: b2_world.h:261
int32 m_fixtureCount
Definition: b2_body.h:455
bool IsAwake() const
Definition: b2_body.h:661
int32 velocityIterations
Definition: b2_time_step.h:47
~b2World()
Destruct the world. All physics entities are destroyed and all heap memory is released.
Definition: b2_world.cpp:74
int32 GetProxyCount() const
Get the number of broad-phase proxies.
Definition: b2_world.cpp:1217
b2Body * GetNext()
Get the next body in the world&#39;s body list.
Definition: b2_body.h:724
b2Vec2 m_vertices[b2_maxPolygonVertices]
void Destroy(b2BlockAllocator *allocator)
Definition: b2_fixture.cpp:73
~b2Body()
Definition: b2_body.cpp:106
int32 GetTreeBalance() const
Get the balance of the embedded tree.
b2BodyType GetType() const
Get the type of this body.
Definition: b2_body.h:474
bool m_warmStarting
Definition: b2_world.h:255
b2RayCastCallback * callback
Definition: b2_world.cpp:1024
b2Body * m_bodyA
Definition: b2_joint.h:182
int32 m_toiCount
Definition: b2_contact.h:234
void ShiftOrigin(const b2Vec2 &newOrigin)
float RayCastCallback(const b2RayCastInput &input, int32 proxyId)
Definition: b2_world.cpp:1004
void SynchronizeTransform()
Definition: b2_body.h:855
void SetContactListener(b2ContactListener *listener)
Definition: b2_world.cpp:105
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2_contact.h:296
void Dump()
Definition: b2_world.cpp:1260
float solveTOI
Definition: b2_time_step.h:38
b2StackAllocator m_stackAllocator
Definition: b2_world.h:230
bool IsSensor() const
Definition: b2_fixture.h:268
float solveInit
Definition: b2_time_step.h:34
b2Body * other
provides quick access to the other body attached.
Definition: b2_contact.h:79
b2BlockAllocator * m_allocator
#define b2_maxSubSteps
Maximum number of sub-steps per contact in continuous physics simulation.
Definition: b2_common.h:77
b2BroadPhase m_broadPhase
const b2AABB & GetFatAABB(int32 proxyId) const
Get the fat AABB for a proxy.
unsigned int step
An axis aligned bounding box.
Definition: b2_collision.h:168
void Clear()
Definition: b2_island.h:45
int32 positionIterations
Definition: b2_time_step.h:48
float m_inv_dt0
Definition: b2_world.h:248
Output parameters for b2TimeOfImpact.
bool m_allowSleep
Definition: b2_world.h:241
float inv_dt
Definition: b2_time_step.h:45
b2DestructionListener * m_destructionListener
Definition: b2_world.h:243
void SetDestructionListener(b2DestructionListener *listener)
Definition: b2_world.cpp:95
int32 childIndex
Definition: b2_fixture.h:107
void Solve(b2Profile *profile, const b2TimeStep &step, const b2Vec2 &gravity, bool allowSleep)
Definition: b2_island.cpp:188
int32 m_bodyCapacity
Definition: b2_island.h:92
void b2Dump(const char *string,...)
Definition: b2_settings.cpp:57
float step
Definition: b2_time_step.h:31
b2Vec2 m_vertex1
These are the edge vertices.
Definition: b2_edge_shape.h:66
void DestroyBody(b2Body *body)
Definition: b2_world.cpp:139
draw broad-phase pairs
Definition: b2_draw.h:60
void DestroyProxies(b2BroadPhase *broadPhase)
Definition: b2_fixture.cpp:143
bool m_clearForces
Definition: b2_world.h:252
b2Vec2 m_vertex2
Definition: b2_edge_shape.h:66
uint16 m_flags
Definition: b2_body.h:437
#define b2_maxPolygonVertices
Definition: b2_settings.h:53
bool m_oneSided
Uses m_vertex0 and m_vertex3 to create smooth collision.
Definition: b2_edge_shape.h:72
bool warmStarting
Definition: b2_time_step.h:49
b2BlockAllocator m_blockAllocator
Definition: b2_world.h:229
int32 m_contactCount
Definition: b2_island.h:90
float dtRatio
Definition: b2_time_step.h:46
int32 m_count
The vertex count.
bool m_isSensor
Definition: b2_fixture.h:248
b2Vec2 m_gravity
Definition: b2_world.h:240
bool IsEnabled() const
Get the active state of the body.
Definition: b2_body.h:666
void Step(float timeStep, int32 velocityIterations, int32 positionIterations)
Definition: b2_world.cpp:905
float broadphase
Definition: b2_time_step.h:37
bool QueryCallback(int32 proxyId)
Definition: b2_world.cpp:984
b2BodyType m_type
Definition: b2_body.h:435
draw joint connections
Definition: b2_draw.h:58
b2Body * bodyA
The first attached body.
Definition: b2_joint.h:89
b2Shape * GetShape()
Definition: b2_fixture.h:258
void DebugDraw()
Call this to draw shapes and other debug draw data. This is intentionally non-const.
Definition: b2_world.cpp:1107
static b2Joint * Create(const b2JointDef *def, b2BlockAllocator *allocator)
Definition: b2_joint.cpp:90
#define b2_epsilon
Definition: b2_common.h:40
#define b2_maxTOIContacts
Maximum number of contacts to be handled to solve a TOI impact.
Definition: b2_common.h:83
uint32 m_flags
Definition: b2_contact.h:216
bool IsTouching() const
Is this contact touching?
Definition: b2_contact.h:281
void Add(b2Body *body)
Definition: b2_island.h:56
#define b2Assert(A)
Definition: b2_common.h:37
int32 GetTreeHeight() const
Get the height of the dynamic tree.
Definition: b2_world.cpp:1222
void SetContactFilter(b2ContactFilter *filter)
Definition: b2_world.cpp:100
b2Contact * m_next
Definition: b2_contact.h:220
void Query(T *callback, const b2AABB &aabb) const
b2JointEdge m_edgeA
Definition: b2_joint.h:180
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
void SetAwake(bool flag)
Definition: b2_body.h:638
b2Body * GetBody()
Definition: b2_fixture.h:283
b2Body * bodyB
The second attached body.
Definition: b2_joint.h:92
b2JointEdge * next
the next joint edge in the body&#39;s joint list
Definition: b2_joint.h:68
b2Body * m_bodyB
Definition: b2_joint.h:183
b2Shape::Type GetType() const
Definition: b2_fixture.h:253
draw shapes
Definition: b2_draw.h:57
b2Sweep m_sweep
Definition: b2_body.h:442
float alpha0
Definition: b2_math.h:388
bool m_stepComplete
Definition: b2_world.h:259
void Advance(float alpha)
Definition: b2_math.h:697
b2Vec2 upperBound
the upper vertex
Definition: b2_collision.h:221
float GetMilliseconds() const
Get the time since construction or the last reset.
Definition: b2_timer.cpp:120
b2Fixture * m_fixtureList
Definition: b2_body.h:454
b2Body * m_next
Definition: b2_body.h:452
b2Draw * m_debugDraw
Definition: b2_world.h:244


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:19