File indexing completed on 2025-08-03 03:50:01

0001 /*
0002 * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
0003 *
0004 * This software is provided 'as-is', without any express or implied
0005 * warranty.  In no event will the authors be held liable for any damages
0006 * arising from the use of this software.
0007 * Permission is granted to anyone to use this software for any purpose,
0008 * including commercial applications, and to alter it and redistribute it
0009 * freely, subject to the following restrictions:
0010 * 1. The origin of this software must not be misrepresented; you must not
0011 * claim that you wrote the original software. If you use this software
0012 * in a product, an acknowledgment in the product documentation would be
0013 * appreciated but is not required.
0014 * 2. Altered source versions must be plainly marked as such, and must not be
0015 * misrepresented as being the original software.
0016 * 3. This notice may not be removed or altered from any source distribution.
0017 */
0018 
0019 #include <Box2D/Dynamics/b2World.h>
0020 #include <Box2D/Dynamics/b2Body.h>
0021 #include <Box2D/Dynamics/b2Fixture.h>
0022 #include <Box2D/Dynamics/b2Island.h>
0023 #include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
0024 #include <Box2D/Dynamics/Contacts/b2Contact.h>
0025 #include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
0026 #include <Box2D/Collision/b2Collision.h>
0027 #include <Box2D/Collision/b2BroadPhase.h>
0028 #include <Box2D/Collision/Shapes/b2CircleShape.h>
0029 #include <Box2D/Collision/Shapes/b2EdgeShape.h>
0030 #include <Box2D/Collision/Shapes/b2LoopShape.h>
0031 #include <Box2D/Collision/Shapes/b2PolygonShape.h>
0032 #include <Box2D/Collision/b2TimeOfImpact.h>
0033 #include <new>
0034 
0035 b2World::b2World(const b2Vec2& gravity, bool doSleep)
0036 {
0037     m_destructionListener = NULL;
0038     m_debugDraw = NULL;
0039 
0040     m_bodyList = NULL;
0041     m_jointList = NULL;
0042 
0043     m_bodyCount = 0;
0044     m_jointCount = 0;
0045 
0046     m_warmStarting = true;
0047     m_continuousPhysics = true;
0048     m_subStepping = false;
0049 
0050     m_stepComplete = true;
0051 
0052     m_allowSleep = doSleep;
0053     m_gravity = gravity;
0054 
0055     m_flags = e_clearForces;
0056 
0057     m_inv_dt0 = 0.0f;
0058 
0059     m_contactManager.m_allocator = &m_blockAllocator;
0060 }
0061 
0062 b2World::~b2World()
0063 {
0064     // Some shapes allocate using b2Alloc.
0065     b2Body* b = m_bodyList;
0066     while (b)
0067     {
0068         b2Body* bNext = b->m_next;
0069 
0070         b2Fixture* f = b->m_fixtureList;
0071         while (f)
0072         {
0073             b2Fixture* fNext = f->m_next;
0074             f->m_proxyCount = 0;
0075             f->Destroy(&m_blockAllocator);
0076             f = fNext;
0077         }
0078 
0079         b = bNext;
0080     }
0081 }
0082 
0083 void b2World::SetDestructionListener(b2DestructionListener* listener)
0084 {
0085     m_destructionListener = listener;
0086 }
0087 
0088 void b2World::SetContactFilter(b2ContactFilter* filter)
0089 {
0090     m_contactManager.m_contactFilter = filter;
0091 }
0092 
0093 void b2World::SetContactListener(b2ContactListener* listener)
0094 {
0095     m_contactManager.m_contactListener = listener;
0096 }
0097 
0098 void b2World::SetDebugDraw(b2DebugDraw* debugDraw)
0099 {
0100     m_debugDraw = debugDraw;
0101 }
0102 
0103 b2Body* b2World::CreateBody(const b2BodyDef* def)
0104 {
0105     b2Assert(IsLocked() == false);
0106     if (IsLocked())
0107     {
0108         return NULL;
0109     }
0110 
0111     void* mem = m_blockAllocator.Allocate(sizeof(b2Body));
0112     b2Body* b = new (mem) b2Body(def, this);
0113 
0114     // Add to world doubly linked list.
0115     b->m_prev = NULL;
0116     b->m_next = m_bodyList;
0117     if (m_bodyList)
0118     {
0119         m_bodyList->m_prev = b;
0120     }
0121     m_bodyList = b;
0122     ++m_bodyCount;
0123 
0124     return b;
0125 }
0126 
0127 void b2World::DestroyBody(b2Body* b)
0128 {
0129     b2Assert(m_bodyCount > 0);
0130     b2Assert(IsLocked() == false);
0131     if (IsLocked())
0132     {
0133         return;
0134     }
0135 
0136     // Delete the attached joints.
0137     b2JointEdge* je = b->m_jointList;
0138     while (je)
0139     {
0140         b2JointEdge* je0 = je;
0141         je = je->next;
0142 
0143         if (m_destructionListener)
0144         {
0145             m_destructionListener->SayGoodbye(je0->joint);
0146         }
0147 
0148         DestroyJoint(je0->joint);
0149 
0150         b->m_jointList = je;
0151     }
0152     b->m_jointList = NULL;
0153 
0154     // Delete the attached contacts.
0155     b2ContactEdge* ce = b->m_contactList;
0156     while (ce)
0157     {
0158         b2ContactEdge* ce0 = ce;
0159         ce = ce->next;
0160         m_contactManager.Destroy(ce0->contact);
0161     }
0162     b->m_contactList = NULL;
0163 
0164     // Delete the attached fixtures. This destroys broad-phase proxies.
0165     b2Fixture* f = b->m_fixtureList;
0166     while (f)
0167     {
0168         b2Fixture* f0 = f;
0169         f = f->m_next;
0170 
0171         if (m_destructionListener)
0172         {
0173             m_destructionListener->SayGoodbye(f0);
0174         }
0175 
0176         f0->DestroyProxies(&m_contactManager.m_broadPhase);
0177         f0->Destroy(&m_blockAllocator);
0178         f0->~b2Fixture();
0179         m_blockAllocator.Free(f0, sizeof(b2Fixture));
0180 
0181         b->m_fixtureList = f;
0182         b->m_fixtureCount -= 1;
0183     }
0184     b->m_fixtureList = NULL;
0185     b->m_fixtureCount = 0;
0186 
0187     // Remove world body list.
0188     if (b->m_prev)
0189     {
0190         b->m_prev->m_next = b->m_next;
0191     }
0192 
0193     if (b->m_next)
0194     {
0195         b->m_next->m_prev = b->m_prev;
0196     }
0197 
0198     if (b == m_bodyList)
0199     {
0200         m_bodyList = b->m_next;
0201     }
0202 
0203     --m_bodyCount;
0204     b->~b2Body();
0205     m_blockAllocator.Free(b, sizeof(b2Body));
0206 }
0207 
0208 b2Joint* b2World::CreateJoint(const b2JointDef* def)
0209 {
0210     b2Assert(IsLocked() == false);
0211     if (IsLocked())
0212     {
0213         return NULL;
0214     }
0215 
0216     b2Joint* j = b2Joint::Create(def, &m_blockAllocator);
0217 
0218     // Connect to the world list.
0219     j->m_prev = NULL;
0220     j->m_next = m_jointList;
0221     if (m_jointList)
0222     {
0223         m_jointList->m_prev = j;
0224     }
0225     m_jointList = j;
0226     ++m_jointCount;
0227 
0228     // Connect to the bodies' doubly linked lists.
0229     j->m_edgeA.joint = j;
0230     j->m_edgeA.other = j->m_bodyB;
0231     j->m_edgeA.prev = NULL;
0232     j->m_edgeA.next = j->m_bodyA->m_jointList;
0233     if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA;
0234     j->m_bodyA->m_jointList = &j->m_edgeA;
0235 
0236     j->m_edgeB.joint = j;
0237     j->m_edgeB.other = j->m_bodyA;
0238     j->m_edgeB.prev = NULL;
0239     j->m_edgeB.next = j->m_bodyB->m_jointList;
0240     if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB;
0241     j->m_bodyB->m_jointList = &j->m_edgeB;
0242 
0243     b2Body* bodyA = def->bodyA;
0244     b2Body* bodyB = def->bodyB;
0245 
0246     // If the joint prevents collisions, then flag any contacts for filtering.
0247     if (def->collideConnected == false)
0248     {
0249         b2ContactEdge* edge = bodyB->GetContactList();
0250         while (edge)
0251         {
0252             if (edge->other == bodyA)
0253             {
0254                 // Flag the contact for filtering at the next time step (where either
0255                 // body is awake).
0256                 edge->contact->FlagForFiltering();
0257             }
0258 
0259             edge = edge->next;
0260         }
0261     }
0262 
0263     // Note: creating a joint doesn't wake the bodies.
0264 
0265     return j;
0266 }
0267 
0268 void b2World::DestroyJoint(b2Joint* j)
0269 {
0270     b2Assert(IsLocked() == false);
0271     if (IsLocked())
0272     {
0273         return;
0274     }
0275 
0276     bool collideConnected = j->m_collideConnected;
0277 
0278     // Remove from the doubly linked list.
0279     if (j->m_prev)
0280     {
0281         j->m_prev->m_next = j->m_next;
0282     }
0283 
0284     if (j->m_next)
0285     {
0286         j->m_next->m_prev = j->m_prev;
0287     }
0288 
0289     if (j == m_jointList)
0290     {
0291         m_jointList = j->m_next;
0292     }
0293 
0294     // Disconnect from island graph.
0295     b2Body* bodyA = j->m_bodyA;
0296     b2Body* bodyB = j->m_bodyB;
0297 
0298     // Wake up connected bodies.
0299     bodyA->SetAwake(true);
0300     bodyB->SetAwake(true);
0301 
0302     // Remove from body 1.
0303     if (j->m_edgeA.prev)
0304     {
0305         j->m_edgeA.prev->next = j->m_edgeA.next;
0306     }
0307 
0308     if (j->m_edgeA.next)
0309     {
0310         j->m_edgeA.next->prev = j->m_edgeA.prev;
0311     }
0312 
0313     if (&j->m_edgeA == bodyA->m_jointList)
0314     {
0315         bodyA->m_jointList = j->m_edgeA.next;
0316     }
0317 
0318     j->m_edgeA.prev = NULL;
0319     j->m_edgeA.next = NULL;
0320 
0321     // Remove from body 2
0322     if (j->m_edgeB.prev)
0323     {
0324         j->m_edgeB.prev->next = j->m_edgeB.next;
0325     }
0326 
0327     if (j->m_edgeB.next)
0328     {
0329         j->m_edgeB.next->prev = j->m_edgeB.prev;
0330     }
0331 
0332     if (&j->m_edgeB == bodyB->m_jointList)
0333     {
0334         bodyB->m_jointList = j->m_edgeB.next;
0335     }
0336 
0337     j->m_edgeB.prev = NULL;
0338     j->m_edgeB.next = NULL;
0339 
0340     b2Joint::Destroy(j, &m_blockAllocator);
0341 
0342     b2Assert(m_jointCount > 0);
0343     --m_jointCount;
0344 
0345     // If the joint prevents collisions, then flag any contacts for filtering.
0346     if (collideConnected == false)
0347     {
0348         b2ContactEdge* edge = bodyB->GetContactList();
0349         while (edge)
0350         {
0351             if (edge->other == bodyA)
0352             {
0353                 // Flag the contact for filtering at the next time step (where either
0354                 // body is awake).
0355                 edge->contact->FlagForFiltering();
0356             }
0357 
0358             edge = edge->next;
0359         }
0360     }
0361 }
0362 
0363 // Find islands, integrate and solve constraints, solve position constraints
0364 void b2World::Solve(const b2TimeStep& step)
0365 {
0366     // Size the island for the worst case.
0367     b2Island island(m_bodyCount,
0368                     m_contactManager.m_contactCount,
0369                     m_jointCount,
0370                     &m_stackAllocator,
0371                     m_contactManager.m_contactListener);
0372 
0373     // Clear all the island flags.
0374     for (b2Body* b = m_bodyList; b; b = b->m_next)
0375     {
0376         b->m_flags &= ~b2Body::e_islandFlag;
0377     }
0378     for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
0379     {
0380         c->m_flags &= ~b2Contact::e_islandFlag;
0381     }
0382     for (b2Joint* j = m_jointList; j; j = j->m_next)
0383     {
0384         j->m_islandFlag = false;
0385     }
0386 
0387     // Build and simulate all awake islands.
0388     int32 stackSize = m_bodyCount;
0389     b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*));
0390     for (b2Body* seed = m_bodyList; seed; seed = seed->m_next)
0391     {
0392         if (seed->m_flags & b2Body::e_islandFlag)
0393         {
0394             continue;
0395         }
0396 
0397         if (seed->IsAwake() == false || seed->IsActive() == false)
0398         {
0399             continue;
0400         }
0401 
0402         // The seed can be dynamic or kinematic.
0403         if (seed->GetType() == b2_staticBody)
0404         {
0405             continue;
0406         }
0407 
0408         // Reset island and stack.
0409         island.Clear();
0410         int32 stackCount = 0;
0411         stack[stackCount++] = seed;
0412         seed->m_flags |= b2Body::e_islandFlag;
0413 
0414         // Perform a depth first search (DFS) on the constraint graph.
0415         while (stackCount > 0)
0416         {
0417             // Grab the next body off the stack and add it to the island.
0418             b2Body* b = stack[--stackCount];
0419             b2Assert(b->IsActive() == true);
0420             island.Add(b);
0421 
0422             // Make sure the body is awake.
0423             b->SetAwake(true);
0424 
0425             // To keep islands as small as possible, we don't
0426             // propagate islands across static bodies.
0427             if (b->GetType() == b2_staticBody)
0428             {
0429                 continue;
0430             }
0431 
0432             // Search all contacts connected to this body.
0433             for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next)
0434             {
0435                 b2Contact* contact = ce->contact;
0436 
0437                 // Has this contact already been added to an island?
0438                 if (contact->m_flags & b2Contact::e_islandFlag)
0439                 {
0440                     continue;
0441                 }
0442 
0443                 // Is this contact solid and touching?
0444                 if (contact->IsEnabled() == false ||
0445                     contact->IsTouching() == false)
0446                 {
0447                     continue;
0448                 }
0449 
0450                 // Skip sensors.
0451                 bool sensorA = contact->m_fixtureA->m_isSensor;
0452                 bool sensorB = contact->m_fixtureB->m_isSensor;
0453                 if (sensorA || sensorB)
0454                 {
0455                     continue;
0456                 }
0457 
0458                 island.Add(contact);
0459                 contact->m_flags |= b2Contact::e_islandFlag;
0460 
0461                 b2Body* other = ce->other;
0462 
0463                 // Was the other body already added to this island?
0464                 if (other->m_flags & b2Body::e_islandFlag)
0465                 {
0466                     continue;
0467                 }
0468 
0469                 b2Assert(stackCount < stackSize);
0470                 stack[stackCount++] = other;
0471                 other->m_flags |= b2Body::e_islandFlag;
0472             }
0473 
0474             // Search all joints connect to this body.
0475             for (b2JointEdge* je = b->m_jointList; je; je = je->next)
0476             {
0477                 if (je->joint->m_islandFlag == true)
0478                 {
0479                     continue;
0480                 }
0481 
0482                 b2Body* other = je->other;
0483 
0484                 // Don't simulate joints connected to inactive bodies.
0485                 if (other->IsActive() == false)
0486                 {
0487                     continue;
0488                 }
0489 
0490                 island.Add(je->joint);
0491                 je->joint->m_islandFlag = true;
0492 
0493                 if (other->m_flags & b2Body::e_islandFlag)
0494                 {
0495                     continue;
0496                 }
0497 
0498                 b2Assert(stackCount < stackSize);
0499                 stack[stackCount++] = other;
0500                 other->m_flags |= b2Body::e_islandFlag;
0501             }
0502         }
0503 
0504         island.Solve(step, m_gravity, m_allowSleep);
0505 
0506         // Post solve cleanup.
0507         for (int32 i = 0; i < island.m_bodyCount; ++i)
0508         {
0509             // Allow static bodies to participate in other islands.
0510             b2Body* b = island.m_bodies[i];
0511             if (b->GetType() == b2_staticBody)
0512             {
0513                 b->m_flags &= ~b2Body::e_islandFlag;
0514             }
0515         }
0516     }
0517 
0518     m_stackAllocator.Free(stack);
0519 
0520     // Synchronize fixtures, check for out of range bodies.
0521     for (b2Body* b = m_bodyList; b; b = b->GetNext())
0522     {
0523         // If a body was not in an island then it did not move.
0524         if ((b->m_flags & b2Body::e_islandFlag) == 0)
0525         {
0526             continue;
0527         }
0528 
0529         if (b->GetType() == b2_staticBody)
0530         {
0531             continue;
0532         }
0533 
0534         // Update fixtures (for broad-phase).
0535         b->SynchronizeFixtures();
0536     }
0537 
0538     // Look for new contacts.
0539     m_contactManager.FindNewContacts();
0540 }
0541 
0542 // Find TOI contacts and solve them.
0543 void b2World::SolveTOI(const b2TimeStep& step)
0544 {
0545     b2Island island(2 * b2_maxTOIContacts, b2_maxTOIContacts, 0, &m_stackAllocator, m_contactManager.m_contactListener);
0546 
0547     if (m_stepComplete)
0548     {
0549         for (b2Body* b = m_bodyList; b; b = b->m_next)
0550         {
0551             b->m_flags &= ~b2Body::e_islandFlag;
0552             b->m_sweep.alpha0 = 0.0f;
0553         }
0554 
0555         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
0556         {
0557             // Invalidate TOI
0558             c->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
0559             c->m_toiCount = 0;
0560             c->m_toi = 1.0f;
0561         }
0562     }
0563 
0564     // Find TOI events and solve them.
0565     for (;;)
0566     {
0567         // Find the first TOI.
0568         b2Contact* minContact = NULL;
0569         qreal minAlpha = 1.0f;
0570 
0571         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
0572         {
0573             // Is this contact disabled?
0574             if (c->IsEnabled() == false)
0575             {
0576                 continue;
0577             }
0578 
0579             // Prevent excessive sub-stepping.
0580             if (c->m_toiCount > b2_maxSubSteps)
0581             {
0582                 continue;
0583             }
0584 
0585             qreal alpha = 1.0f;
0586             if (c->m_flags & b2Contact::e_toiFlag)
0587             {
0588                 // This contact has a valid cached TOI.
0589                 alpha = c->m_toi;
0590             }
0591             else
0592             {
0593                 b2Fixture* fA = c->GetFixtureA();
0594                 b2Fixture* fB = c->GetFixtureB();
0595 
0596                 // Is there a sensor?
0597                 if (fA->IsSensor() || fB->IsSensor())
0598                 {
0599                     continue;
0600                 }
0601 
0602                 b2Body* bA = fA->GetBody();
0603                 b2Body* bB = fB->GetBody();
0604 
0605                 b2BodyType typeA = bA->GetType();
0606                 b2BodyType typeB = bB->GetType();
0607                 b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody);
0608 
0609                 bool awakeA = bA->IsAwake() && typeA != b2_staticBody;
0610                 bool awakeB = bB->IsAwake() && typeB != b2_staticBody;
0611 
0612                 // Is at least one body awake?
0613                 if (awakeA == false && awakeB == false)
0614                 {
0615                     continue;
0616                 }
0617 
0618                 bool collideA = bA->IsBullet() || typeA != b2_dynamicBody;
0619                 bool collideB = bB->IsBullet() || typeB != b2_dynamicBody;
0620 
0621                 // Are these two non-bullet dynamic bodies?
0622                 if (collideA == false && collideB == false)
0623                 {
0624                     continue;
0625                 }
0626 
0627                 // Compute the TOI for this contact.
0628                 // Put the sweeps onto the same time interval.
0629                 qreal alpha0 = bA->m_sweep.alpha0;
0630 
0631                 if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0)
0632                 {
0633                     alpha0 = bB->m_sweep.alpha0;
0634                     bA->m_sweep.Advance(alpha0);
0635                 }
0636                 else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0)
0637                 {
0638                     alpha0 = bA->m_sweep.alpha0;
0639                     bB->m_sweep.Advance(alpha0);
0640                 }
0641 
0642                 b2Assert(alpha0 < 1.0f);
0643 
0644                 int32 indexA = c->GetChildIndexA();
0645                 int32 indexB = c->GetChildIndexB();
0646 
0647                 // Compute the time of impact in interval [0, minTOI]
0648                 b2TOIInput input;
0649                 input.proxyA.Set(fA->GetShape(), indexA);
0650                 input.proxyB.Set(fB->GetShape(), indexB);
0651                 input.sweepA = bA->m_sweep;
0652                 input.sweepB = bB->m_sweep;
0653                 input.tMax = 1.0f;
0654 
0655                 b2TOIOutput output;
0656                 b2TimeOfImpact(&output, &input);
0657 
0658                 // Beta is the fraction of the remaining portion of the .
0659                 qreal beta = output.t;
0660                 if (output.state == b2TOIOutput::e_touching)
0661                 {
0662                     alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
0663                 }
0664                 else
0665                 {
0666                     alpha = 1.0f;
0667                 }
0668 
0669                 c->m_toi = alpha;
0670                 c->m_flags |= b2Contact::e_toiFlag;
0671             }
0672 
0673             if (alpha < minAlpha)
0674             {
0675                 // This is the minimum TOI found so far.
0676                 minContact = c;
0677                 minAlpha = alpha;
0678             }
0679         }
0680 
0681         if (minContact == NULL || 1.0f - 10.0f * b2_epsilon < minAlpha)
0682         {
0683             // No more TOI events. Done!
0684             m_stepComplete = true;
0685             break;
0686         }
0687 
0688         // Advance the bodies to the TOI.
0689         b2Fixture* fA = minContact->GetFixtureA();
0690         b2Fixture* fB = minContact->GetFixtureB();
0691         b2Body* bA = fA->GetBody();
0692         b2Body* bB = fB->GetBody();
0693 
0694         b2Sweep backup1 = bA->m_sweep;
0695         b2Sweep backup2 = bB->m_sweep;
0696 
0697         bA->Advance(minAlpha);
0698         bB->Advance(minAlpha);
0699 
0700         // The TOI contact likely has some new contact points.
0701         minContact->Update(m_contactManager.m_contactListener);
0702         minContact->m_flags &= ~b2Contact::e_toiFlag;
0703         ++minContact->m_toiCount;
0704 
0705         // Is the contact solid?
0706         if (minContact->IsEnabled() == false || minContact->IsTouching() == false)
0707         {
0708             // Restore the sweeps.
0709             minContact->SetEnabled(false);
0710             bA->m_sweep = backup1;
0711             bB->m_sweep = backup2;
0712             bA->SynchronizeTransform();
0713             bB->SynchronizeTransform();
0714             continue;
0715         }
0716 
0717         bA->SetAwake(true);
0718         bB->SetAwake(true);
0719 
0720         // Build the island
0721         island.Clear();
0722         island.Add(bA);
0723         island.Add(bB);
0724         island.Add(minContact);
0725 
0726         bA->m_flags |= b2Body::e_islandFlag;
0727         bB->m_flags |= b2Body::e_islandFlag;
0728         minContact->m_flags |= b2Contact::e_islandFlag;
0729 
0730         // Get contacts on bodyA and bodyB.
0731         b2Body* bodies[2] = {bA, bB};
0732         for (int32 i = 0; i < 2; ++i)
0733         {
0734             b2Body* body = bodies[i];
0735             if (body->m_type == b2_dynamicBody)
0736             {
0737                 for (b2ContactEdge* ce = body->m_contactList; ce && island.m_bodyCount < b2_maxTOIContacts; ce = ce->next)
0738                 {
0739                     b2Contact* contact = ce->contact;
0740 
0741                     // Has this contact already been added to the island?
0742                     if (contact->m_flags & b2Contact::e_islandFlag)
0743                     {
0744                         continue;
0745                     }
0746 
0747                     // Only add static, kinematic, or bullet bodies.
0748                     b2Body* other = ce->other;
0749                     if (other->m_type == b2_dynamicBody &&
0750                         body->IsBullet() == false && other->IsBullet() == false)
0751                     {
0752                         continue;
0753                     }
0754 
0755                     // Skip sensors.
0756                     bool sensorA = contact->m_fixtureA->m_isSensor;
0757                     bool sensorB = contact->m_fixtureB->m_isSensor;
0758                     if (sensorA || sensorB)
0759                     {
0760                         continue;
0761                     }
0762 
0763                     // Tentatively advance the body to the TOI.
0764                     b2Sweep backup = other->m_sweep;
0765                     if ((other->m_flags & b2Body::e_islandFlag) == 0)
0766                     {
0767                         other->Advance(minAlpha);
0768                     }
0769 
0770                     // Update the contact points
0771                     contact->Update(m_contactManager.m_contactListener);
0772 
0773                     // Was the contact disabled by the user?
0774                     if (contact->IsEnabled() == false)
0775                     {
0776                         other->m_sweep = backup;
0777                         other->SynchronizeTransform();
0778                         continue;
0779                     }
0780 
0781                     // Are there contact points?
0782                     if (contact->IsTouching() == false)
0783                     {
0784                         other->m_sweep = backup;
0785                         other->SynchronizeTransform();
0786                         continue;
0787                     }
0788 
0789                     // Add the contact to the island
0790                     contact->m_flags |= b2Contact::e_islandFlag;
0791                     island.Add(contact);
0792 
0793                     // Has the other body already been added to the island?
0794                     if (other->m_flags & b2Body::e_islandFlag)
0795                     {
0796                         continue;
0797                     }
0798                     
0799                     // Add the other body to the island.
0800                     other->m_flags |= b2Body::e_islandFlag;
0801 
0802                     if (other->m_type != b2_staticBody)
0803                     {
0804                         other->SetAwake(true);
0805                     }
0806 
0807                     island.Add(other);
0808                 }
0809             }
0810         }
0811 
0812         b2TimeStep subStep;
0813         subStep.dt = (1.0f - minAlpha) * step.dt;
0814         subStep.inv_dt = 1.0f / subStep.dt;
0815         subStep.dtRatio = 1.0f;
0816         subStep.positionIterations = 20;
0817         subStep.velocityIterations = step.velocityIterations;
0818         subStep.warmStarting = false;
0819         island.SolveTOI(subStep, bA, bB);
0820 
0821         // Reset island flags and synchronize broad-phase proxies.
0822         for (int32 i = 0; i < island.m_bodyCount; ++i)
0823         {
0824             b2Body* body = island.m_bodies[i];
0825             body->m_flags &= ~b2Body::e_islandFlag;
0826 
0827             if (body->m_type != b2_dynamicBody)
0828             {
0829                 continue;
0830             }
0831 
0832             body->SynchronizeFixtures();
0833 
0834             // Invalidate all contact TOIs on this displaced body.
0835             for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
0836             {
0837                 ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
0838             }
0839         }
0840 
0841         // Commit fixture proxy movements to the broad-phase so that new contacts are created.
0842         // Also, some contacts can be destroyed.
0843         m_contactManager.FindNewContacts();
0844 
0845         if (m_subStepping)
0846         {
0847             m_stepComplete = false;
0848             break;
0849         }
0850     }
0851 }
0852 
0853 void b2World::Step(qreal dt, int32 velocityIterations, int32 positionIterations)
0854 {
0855     // If new fixtures were added, we need to find the new contacts.
0856     if (m_flags & e_newFixture)
0857     {
0858         m_contactManager.FindNewContacts();
0859         m_flags &= ~e_newFixture;
0860     }
0861 
0862     m_flags |= e_locked;
0863 
0864     b2TimeStep step;
0865     step.dt = dt;
0866     step.velocityIterations = velocityIterations;
0867     step.positionIterations = positionIterations;
0868     if (dt > 0.0f)
0869     {
0870         step.inv_dt = 1.0f / dt;
0871     }
0872     else
0873     {
0874         step.inv_dt = 0.0f;
0875     }
0876 
0877     step.dtRatio = m_inv_dt0 * dt;
0878 
0879     step.warmStarting = m_warmStarting;
0880 
0881     // Update contacts. This is where some contacts are destroyed.
0882     m_contactManager.Collide();
0883 
0884     // Integrate velocities, solve velocity constraints, and integrate positions.
0885     if (m_stepComplete && step.dt > 0.0f)
0886     {
0887         Solve(step);
0888     }
0889 
0890     // Handle TOI events.
0891     if (m_continuousPhysics && step.dt > 0.0f)
0892     {
0893         SolveTOI(step);
0894     }
0895 
0896     if (step.dt > 0.0f)
0897     {
0898         m_inv_dt0 = step.inv_dt;
0899     }
0900 
0901     if (m_flags & e_clearForces)
0902     {
0903         ClearForces();
0904     }
0905 
0906     m_flags &= ~e_locked;
0907 }
0908 
0909 void b2World::ClearForces()
0910 {
0911     for (b2Body* body = m_bodyList; body; body = body->GetNext())
0912     {
0913         body->m_force.SetZero();
0914         body->m_torque = 0.0f;
0915     }
0916 }
0917 
0918 struct b2WorldQueryWrapper
0919 {
0920     bool QueryCallback(int32 proxyId)
0921     {
0922         b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId);
0923         return callback->ReportFixture(proxy->fixture);
0924     }
0925 
0926     const b2BroadPhase* broadPhase;
0927     b2QueryCallback* callback;
0928 };
0929 
0930 void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const
0931 {
0932     b2WorldQueryWrapper wrapper;
0933     wrapper.broadPhase = &m_contactManager.m_broadPhase;
0934     wrapper.callback = callback;
0935     m_contactManager.m_broadPhase.Query(&wrapper, aabb);
0936 }
0937 
0938 struct b2WorldRayCastWrapper
0939 {
0940     qreal RayCastCallback(const b2RayCastInput& input, int32 proxyId)
0941     {
0942         void* userData = broadPhase->GetUserData(proxyId);
0943         b2FixtureProxy* proxy = (b2FixtureProxy*)userData;
0944         b2Fixture* fixture = proxy->fixture;
0945         int32 index = proxy->childIndex;
0946         b2RayCastOutput output;
0947         bool hit = fixture->RayCast(&output, input, index);
0948 
0949         if (hit)
0950         {
0951             qreal fraction = output.fraction;
0952             b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
0953             return callback->ReportFixture(fixture, point, output.normal, fraction);
0954         }
0955 
0956         return input.maxFraction;
0957     }
0958 
0959     const b2BroadPhase* broadPhase;
0960     b2RayCastCallback* callback;
0961 };
0962 
0963 void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
0964 {
0965     b2WorldRayCastWrapper wrapper;
0966     wrapper.broadPhase = &m_contactManager.m_broadPhase;
0967     wrapper.callback = callback;
0968     b2RayCastInput input;
0969     input.maxFraction = 1.0f;
0970     input.p1 = point1;
0971     input.p2 = point2;
0972     m_contactManager.m_broadPhase.RayCast(&wrapper, input);
0973 }
0974 
0975 void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color)
0976 {
0977     switch (fixture->GetType())
0978     {
0979     case b2Shape::e_circle:
0980         {
0981             b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
0982 
0983             b2Vec2 center = b2Mul(xf, circle->m_p);
0984             qreal radius = circle->m_radius;
0985             b2Vec2 axis = xf.R.col1;
0986 
0987             m_debugDraw->DrawSolidCircle(center, radius, axis, color);
0988         }
0989         break;
0990 
0991     case b2Shape::e_edge:
0992         {
0993             b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
0994             b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
0995             b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
0996             m_debugDraw->DrawSegment(v1, v2, color);
0997         }
0998         break;
0999 
1000     case b2Shape::e_loop:
1001         {
1002             b2LoopShape* loop = (b2LoopShape*)fixture->GetShape();
1003             int32 count = loop->GetCount();
1004             const b2Vec2* vertices = loop->GetVertices();
1005 
1006             b2Vec2 v1 = b2Mul(xf, vertices[count - 1]);
1007             for (int32 i = 0; i < count; ++i)
1008             {
1009                 b2Vec2 v2 = b2Mul(xf, vertices[i]);
1010                 m_debugDraw->DrawSegment(v1, v2, color);
1011                 v1 = v2;
1012             }
1013         }
1014         break;
1015 
1016     case b2Shape::e_polygon:
1017         {
1018             b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
1019             int32 vertexCount = poly->m_vertexCount;
1020             b2Assert(vertexCount <= b2_maxPolygonVertices);
1021             b2Vec2 vertices[b2_maxPolygonVertices];
1022 
1023             for (int32 i = 0; i < vertexCount; ++i)
1024             {
1025                 vertices[i] = b2Mul(xf, poly->m_vertices[i]);
1026             }
1027 
1028             m_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
1029         }
1030         break;
1031     default:
1032         break;
1033     }
1034 }
1035 
1036 void b2World::DrawJoint(b2Joint* joint)
1037 {
1038     b2Body* bodyA = joint->GetBodyA();
1039     b2Body* bodyB = joint->GetBodyB();
1040     const b2Transform& xf1 = bodyA->GetTransform();
1041     const b2Transform& xf2 = bodyB->GetTransform();
1042     b2Vec2 x1 = xf1.position;
1043     b2Vec2 x2 = xf2.position;
1044     b2Vec2 p1 = joint->GetAnchorA();
1045     b2Vec2 p2 = joint->GetAnchorB();
1046 
1047     b2Color color(0.5f, 0.8f, 0.8f);
1048 
1049     switch (joint->GetType())
1050     {
1051     case e_distanceJoint:
1052         m_debugDraw->DrawSegment(p1, p2, color);
1053         break;
1054 
1055     case e_pulleyJoint:
1056         {
1057             b2PulleyJoint* pulley = (b2PulleyJoint*)joint;
1058             b2Vec2 s1 = pulley->GetGroundAnchorA();
1059             b2Vec2 s2 = pulley->GetGroundAnchorB();
1060             m_debugDraw->DrawSegment(s1, p1, color);
1061             m_debugDraw->DrawSegment(s2, p2, color);
1062             m_debugDraw->DrawSegment(s1, s2, color);
1063         }
1064         break;
1065 
1066     case e_mouseJoint:
1067         // don't draw this
1068         break;
1069 
1070     default:
1071         m_debugDraw->DrawSegment(x1, p1, color);
1072         m_debugDraw->DrawSegment(p1, p2, color);
1073         m_debugDraw->DrawSegment(x2, p2, color);
1074     }
1075 }
1076 
1077 void b2World::DrawDebugData()
1078 {
1079     if (m_debugDraw == NULL)
1080     {
1081         return;
1082     }
1083 
1084     uint32 flags = m_debugDraw->GetFlags();
1085 
1086     if (flags & b2DebugDraw::e_shapeBit)
1087     {
1088         for (b2Body* b = m_bodyList; b; b = b->GetNext())
1089         {
1090             const b2Transform& xf = b->GetTransform();
1091             for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
1092             {
1093                 if (b->IsActive() == false)
1094                 {
1095                     DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f));
1096                 }
1097                 else if (b->GetType() == b2_staticBody)
1098                 {
1099                     DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f));
1100                 }
1101                 else if (b->GetType() == b2_kinematicBody)
1102                 {
1103                     DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f));
1104                 }
1105                 else if (b->IsAwake() == false)
1106                 {
1107                     DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f));
1108                 }
1109                 else
1110                 {
1111                     DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f));
1112                 }
1113             }
1114         }
1115     }
1116 
1117     if (flags & b2DebugDraw::e_jointBit)
1118     {
1119         for (b2Joint* j = m_jointList; j; j = j->GetNext())
1120         {
1121             DrawJoint(j);
1122         }
1123     }
1124 
1125     if (flags & b2DebugDraw::e_pairBit)
1126     {
1127         b2Color color(0.3f, 0.9f, 0.9f);
1128         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext())
1129         {
1130             //b2Fixture* fixtureA = c->GetFixtureA();
1131             //b2Fixture* fixtureB = c->GetFixtureB();
1132 
1133             //b2Vec2 cA = fixtureA->GetAABB().GetCenter();
1134             //b2Vec2 cB = fixtureB->GetAABB().GetCenter();
1135 
1136             //m_debugDraw->DrawSegment(cA, cB, color);
1137         }
1138     }
1139 
1140     if (flags & b2DebugDraw::e_aabbBit)
1141     {
1142         b2Color color(0.9f, 0.3f, 0.9f);
1143         b2BroadPhase* bp = &m_contactManager.m_broadPhase;
1144 
1145         for (b2Body* b = m_bodyList; b; b = b->GetNext())
1146         {
1147             if (b->IsActive() == false)
1148             {
1149                 continue;
1150             }
1151 
1152             for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
1153             {
1154                 for (int32 i = 0; i < f->m_proxyCount; ++i)
1155                 {
1156                     b2FixtureProxy* proxy = f->m_proxies + i;
1157                     b2AABB aabb = bp->GetFatAABB(proxy->proxyId);
1158                     b2Vec2 vs[4];
1159                     vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
1160                     vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
1161                     vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
1162                     vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
1163 
1164                     m_debugDraw->DrawPolygon(vs, 4, color);
1165                 }
1166             }
1167         }
1168     }
1169 
1170     if (flags & b2DebugDraw::e_centerOfMassBit)
1171     {
1172         for (b2Body* b = m_bodyList; b; b = b->GetNext())
1173         {
1174             b2Transform xf = b->GetTransform();
1175             xf.position = b->GetWorldCenter();
1176             m_debugDraw->DrawTransform(xf);
1177         }
1178     }
1179 }
1180 
1181 int32 b2World::GetProxyCount() const
1182 {
1183     return m_contactManager.m_broadPhase.GetProxyCount();
1184 }