Advertisement
Guest User

b2World.cpp

a guest
Jun 21st, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. * Copyright (c) 2006-2011 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/b2World.h>
  20. #include <Box2D/Dynamics/b2Body.h>
  21. #include <Box2D/Dynamics/b2Fixture.h>
  22. #include <Box2D/Dynamics/b2Island.h>
  23. #include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
  24. #include <Box2D/Dynamics/Contacts/b2Contact.h>
  25. #include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
  26. #include <Box2D/Collision/b2Collision.h>
  27. #include <Box2D/Collision/b2BroadPhase.h>
  28. #include <Box2D/Collision/Shapes/b2CircleShape.h>
  29. #include <Box2D/Collision/Shapes/b2EdgeShape.h>
  30. #include <Box2D/Collision/Shapes/b2ChainShape.h>
  31. #include <Box2D/Collision/Shapes/b2PolygonShape.h>
  32. #include <Box2D/Collision/b2TimeOfImpact.h>
  33. #include <Box2D/Common/b2Draw.h>
  34. #include <Box2D/Common/b2Timer.h>
  35. #include <new>
  36.  
  37. #include <string>
  38. #include <stdio.h>
  39.  
  40. b2World::b2World(const b2Vec2& gravity)
  41. {
  42.     m_destructionListener = NULL;
  43.     g_debugDraw = NULL;
  44.  
  45.     m_bodyList = NULL;
  46.     m_jointList = NULL;
  47.  
  48.     m_bodyCount = 0;
  49.     m_jointCount = 0;
  50.  
  51.     m_warmStarting = true;
  52.     m_continuousPhysics = true;
  53.     m_subStepping = false;
  54.  
  55.     m_stepComplete = true;
  56.  
  57.     m_allowSleep = true;
  58.     m_gravity = gravity;
  59.  
  60.     m_flags = e_clearForces;
  61.  
  62.     m_inv_dt0 = 0.0f;
  63.  
  64.     m_contactManager.m_allocator = &m_blockAllocator;
  65.  
  66.     memset(&m_profile, 0, sizeof(b2Profile));
  67. }
  68.  
  69. b2World::~b2World()
  70. {
  71.     // Some shapes allocate using b2Alloc.
  72.     b2Body* b = m_bodyList;
  73.     while (b)
  74.     {
  75.         b2Body* bNext = b->m_next;
  76.  
  77.         b2Fixture* f = b->m_fixtureList;
  78.         while (f)
  79.         {
  80.             b2Fixture* fNext = f->m_next;
  81.             f->m_proxyCount = 0;
  82.             f->Destroy(&m_blockAllocator);
  83.             f = fNext;
  84.         }
  85.  
  86.         b = bNext;
  87.     }
  88. }
  89.  
  90. void b2World::SetDestructionListener(b2DestructionListener* listener)
  91. {
  92.     m_destructionListener = listener;
  93. }
  94.  
  95. void b2World::SetContactFilter(b2ContactFilter* filter)
  96. {
  97.     m_contactManager.m_contactFilter = filter;
  98. }
  99.  
  100. void b2World::SetContactListener(b2ContactListener* listener)
  101. {
  102.     m_contactManager.m_contactListener = listener;
  103. }
  104.  
  105. void b2World::SetDebugDraw(b2Draw* debugDraw)
  106. {
  107.     g_debugDraw = debugDraw;
  108. }
  109.  
  110. b2Body* b2World::CreateBody(const b2BodyDef* def)
  111. {
  112.     b2Assert(IsLocked() == false);
  113.     if (IsLocked())
  114.     {
  115.         return NULL;
  116.     }
  117.  
  118.     void* mem = m_blockAllocator.Allocate(sizeof(b2Body));
  119.     b2Body* b = new (mem) b2Body(def, this);
  120.  
  121.     // Add to world doubly linked list.
  122.     b->m_prev = NULL;
  123.     b->m_next = m_bodyList;
  124.     if (m_bodyList)
  125.     {
  126.         m_bodyList->m_prev = b;
  127.     }
  128.     m_bodyList = b;
  129.     ++m_bodyCount;
  130.  
  131.     return b;
  132. }
  133.  
  134. void b2World::DestroyBody(b2Body* b)
  135. {
  136.     b2Assert(m_bodyCount > 0);
  137.     b2Assert(IsLocked() == false);
  138.     if (IsLocked())
  139.     {
  140.         return;
  141.     }
  142.  
  143.     // Delete the attached joints.
  144.     b2JointEdge* je = b->m_jointList;
  145.     while (je)
  146.     {
  147.         b2JointEdge* je0 = je;
  148.         je = je->next;
  149.  
  150.         if (m_destructionListener)
  151.         {
  152.             m_destructionListener->SayGoodbye(je0->joint);
  153.         }
  154.  
  155.         DestroyJoint(je0->joint);
  156.  
  157.         b->m_jointList = je;
  158.     }
  159.     b->m_jointList = NULL;
  160.  
  161.     // Delete the attached contacts.
  162.     b2ContactEdge* ce = b->m_contactList;
  163.     while (ce)
  164.     {
  165.         b2ContactEdge* ce0 = ce;
  166.         ce = ce->next;
  167.         m_contactManager.Destroy(ce0->contact);
  168.     }
  169.     b->m_contactList = NULL;
  170.  
  171.     // Delete the attached fixtures. This destroys broad-phase proxies.
  172.     b2Fixture* f = b->m_fixtureList;
  173.     while (f)
  174.     {
  175.         b2Fixture* f0 = f;
  176.         f = f->m_next;
  177.  
  178.         if (m_destructionListener)
  179.         {
  180.             m_destructionListener->SayGoodbye(f0);
  181.         }
  182.  
  183.         f0->DestroyProxies(&m_contactManager.m_broadPhase);
  184.         f0->Destroy(&m_blockAllocator);
  185.         f0->~b2Fixture();
  186.         m_blockAllocator.Free(f0, sizeof(b2Fixture));
  187.  
  188.         b->m_fixtureList = f;
  189.         b->m_fixtureCount -= 1;
  190.     }
  191.     b->m_fixtureList = NULL;
  192.     b->m_fixtureCount = 0;
  193.  
  194.     // Remove world body list.
  195.     if (b->m_prev)
  196.     {
  197.         b->m_prev->m_next = b->m_next;
  198.     }
  199.  
  200.     if (b->m_next)
  201.     {
  202.         b->m_next->m_prev = b->m_prev;
  203.     }
  204.  
  205.     if (b == m_bodyList)
  206.     {
  207.         m_bodyList = b->m_next;
  208.     }
  209.  
  210.     --m_bodyCount;
  211.     b->~b2Body();
  212.     m_blockAllocator.Free(b, sizeof(b2Body));
  213. }
  214.  
  215. b2Joint* b2World::CreateJoint(const b2JointDef* def)
  216. {
  217.     b2Assert(IsLocked() == false);
  218.     if (IsLocked())
  219.     {
  220.         return NULL;
  221.     }
  222.  
  223.     b2Joint* j = b2Joint::Create(def, &m_blockAllocator);
  224.  
  225.     // Connect to the world list.
  226.     j->m_prev = NULL;
  227.     j->m_next = m_jointList;
  228.     if (m_jointList)
  229.     {
  230.         m_jointList->m_prev = j;
  231.     }
  232.     m_jointList = j;
  233.     ++m_jointCount;
  234.  
  235.     // Connect to the bodies' doubly linked lists.
  236.     j->m_edgeA.joint = j;
  237.     j->m_edgeA.other = j->m_bodyB;
  238.     j->m_edgeA.prev = NULL;
  239.     j->m_edgeA.next = j->m_bodyA->m_jointList;
  240.     if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA;
  241.     j->m_bodyA->m_jointList = &j->m_edgeA;
  242.  
  243.     j->m_edgeB.joint = j;
  244.     j->m_edgeB.other = j->m_bodyA;
  245.     j->m_edgeB.prev = NULL;
  246.     j->m_edgeB.next = j->m_bodyB->m_jointList;
  247.     if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB;
  248.     j->m_bodyB->m_jointList = &j->m_edgeB;
  249.  
  250.     b2Body* bodyA = def->bodyA;
  251.     b2Body* bodyB = def->bodyB;
  252.  
  253.     // If the joint prevents collisions, then flag any contacts for filtering.
  254.     if (def->collideConnected == false)
  255.     {
  256.         b2ContactEdge* edge = bodyB->GetContactList();
  257.         while (edge)
  258.         {
  259.             if (edge->other == bodyA)
  260.             {
  261.                 // Flag the contact for filtering at the next time step (where either
  262.                 // body is awake).
  263.                 edge->contact->FlagForFiltering();
  264.             }
  265.  
  266.             edge = edge->next;
  267.         }
  268.     }
  269.  
  270.     // Note: creating a joint doesn't wake the bodies.
  271.  
  272.     return j;
  273. }
  274.  
  275. void b2World::DestroyJoint(b2Joint* j)
  276. {
  277.     b2Assert(IsLocked() == false);
  278.     if (IsLocked())
  279.     {
  280.         return;
  281.     }
  282.  
  283.     bool collideConnected = j->m_collideConnected;
  284.  
  285.     // Remove from the doubly linked list.
  286.     if (j->m_prev)
  287.     {
  288.         j->m_prev->m_next = j->m_next;
  289.     }
  290.  
  291.     if (j->m_next)
  292.     {
  293.         j->m_next->m_prev = j->m_prev;
  294.     }
  295.  
  296.     if (j == m_jointList)
  297.     {
  298.         m_jointList = j->m_next;
  299.     }
  300.  
  301.     // Disconnect from island graph.
  302.     b2Body* bodyA = j->m_bodyA;
  303.     b2Body* bodyB = j->m_bodyB;
  304.  
  305.     // Wake up connected bodies.
  306.     bodyA->SetAwake(true);
  307.     bodyB->SetAwake(true);
  308.  
  309.     // Remove from body 1.
  310.     if (j->m_edgeA.prev)
  311.     {
  312.         j->m_edgeA.prev->next = j->m_edgeA.next;
  313.     }
  314.  
  315.     if (j->m_edgeA.next)
  316.     {
  317.         j->m_edgeA.next->prev = j->m_edgeA.prev;
  318.     }
  319.  
  320.     if (&j->m_edgeA == bodyA->m_jointList)
  321.     {
  322.         bodyA->m_jointList = j->m_edgeA.next;
  323.     }
  324.  
  325.     j->m_edgeA.prev = NULL;
  326.     j->m_edgeA.next = NULL;
  327.  
  328.     // Remove from body 2
  329.     if (j->m_edgeB.prev)
  330.     {
  331.         j->m_edgeB.prev->next = j->m_edgeB.next;
  332.     }
  333.  
  334.     if (j->m_edgeB.next)
  335.     {
  336.         j->m_edgeB.next->prev = j->m_edgeB.prev;
  337.     }
  338.  
  339.     if (&j->m_edgeB == bodyB->m_jointList)
  340.     {
  341.         bodyB->m_jointList = j->m_edgeB.next;
  342.     }
  343.  
  344.     j->m_edgeB.prev = NULL;
  345.     j->m_edgeB.next = NULL;
  346.  
  347.     b2Joint::Destroy(j, &m_blockAllocator);
  348.  
  349.     b2Assert(m_jointCount > 0);
  350.     --m_jointCount;
  351.  
  352.     // If the joint prevents collisions, then flag any contacts for filtering.
  353.     if (collideConnected == false)
  354.     {
  355.         b2ContactEdge* edge = bodyB->GetContactList();
  356.         while (edge)
  357.         {
  358.             if (edge->other == bodyA)
  359.             {
  360.                 // Flag the contact for filtering at the next time step (where either
  361.                 // body is awake).
  362.                 edge->contact->FlagForFiltering();
  363.             }
  364.  
  365.             edge = edge->next;
  366.         }
  367.     }
  368. }
  369.  
  370. //
  371. void b2World::SetAllowSleeping(bool flag)
  372. {
  373.     if (flag == m_allowSleep)
  374.     {
  375.         return;
  376.     }
  377.  
  378.     m_allowSleep = flag;
  379.     if (m_allowSleep == false)
  380.     {
  381.         for (b2Body* b = m_bodyList; b; b = b->m_next)
  382.         {
  383.             b->SetAwake(true);
  384.         }
  385.     }
  386. }
  387.  
  388. // Find islands, integrate and solve constraints, solve position constraints
  389. void b2World::Solve(const b2TimeStep& step)
  390. {
  391.     m_profile.solveInit = 0.0f;
  392.     m_profile.solveVelocity = 0.0f;
  393.     m_profile.solvePosition = 0.0f;
  394.  
  395.     // Size the island for the worst case.
  396.     b2Island island(m_bodyCount,
  397.                     m_contactManager.m_contactCount,
  398.                     m_jointCount,
  399.                     &m_stackAllocator,
  400.                     m_contactManager.m_contactListener);
  401.  
  402.     // Clear all the island flags.
  403.     for (b2Body* b = m_bodyList; b; b = b->m_next)
  404.     {
  405.         b->m_flags &= ~b2Body::e_islandFlag;
  406.     }
  407.  
  408.     for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  409.     {
  410.         c->m_flags &= ~b2Contact::e_islandFlag;
  411.     }
  412.  
  413.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  414.     {
  415.         j->m_islandFlag = false;
  416.     }
  417.  
  418.     // Build and simulate all awake islands.
  419.     int32 stackSize = m_bodyCount;
  420.     b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*));
  421.     for (b2Body* seed = m_bodyList; seed; seed = seed->m_next)
  422.     {
  423.         if (seed->m_flags & b2Body::e_islandFlag)
  424.         {
  425.             continue;
  426.         }
  427.  
  428.         if (seed->IsAwake() == false || seed->IsActive() == false)
  429.         {
  430.             continue;
  431.         }
  432.  
  433.         // The seed can be dynamic or kinematic.
  434.         if (seed->GetType() == b2_staticBody)
  435.         {
  436.             continue;
  437.         }
  438.  
  439.         //printf("{N}");
  440.         //fflush(stdout);
  441.         // Reset island and stack.
  442.         island.Clear();
  443.         int32 stackCount = 0;
  444.         stack[stackCount++] = seed;
  445.         seed->m_flags |= b2Body::e_islandFlag;
  446.  
  447.         // Perform a depth first search (DFS) on the constraint graph.
  448.         while (stackCount > 0)
  449.         {
  450.             // Grab the next body off the stack and add it to the island.
  451.             b2Body* b = stack[--stackCount];
  452.             b2Assert(b->IsActive() == true);
  453.             island.Add(b);
  454.  
  455.             // Make sure the body is awake.
  456.             b->SetAwake(true);
  457.  
  458.             // To keep islands as small as possible, we don't
  459.             // propagate islands across static bodies.
  460.             if (b->GetType() == b2_staticBody)
  461.             {
  462.                 continue;
  463.             }
  464.  
  465.             // Search all contacts connected to this body.
  466.             for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next)
  467.             {
  468.                 b2Contact* contact = ce->contact;
  469.  
  470.                 // Has this contact already been added to an island?
  471.                 if (contact->m_flags & b2Contact::e_islandFlag)
  472.                 {
  473.                     continue;
  474.                 }
  475.  
  476.                 // Is this contact solid and touching?
  477.                 if (contact->IsEnabled() == false ||
  478.                     contact->IsTouching() == false)
  479.                 {
  480.                     continue;
  481.                 }
  482.  
  483.                 // Skip sensors.
  484.                 bool sensorA = contact->m_fixtureA->m_isSensor;
  485.                 bool sensorB = contact->m_fixtureB->m_isSensor;
  486.                 if (sensorA || sensorB)
  487.                 {
  488.                     continue;
  489.                 }
  490.  
  491.                 island.Add(contact);
  492.                 contact->m_flags |= b2Contact::e_islandFlag;
  493.  
  494.                 b2Body* other = ce->other;
  495.  
  496.                 // Was the other body already added to this island?
  497.                 if (other->m_flags & b2Body::e_islandFlag)
  498.                 {
  499.                     continue;
  500.                 }
  501.  
  502.                 b2Assert(stackCount < stackSize);
  503.                 stack[stackCount++] = other;
  504.                 other->m_flags |= b2Body::e_islandFlag;
  505.             }
  506.  
  507.             // Search all joints connect to this body.
  508.             for (b2JointEdge* je = b->m_jointList; je; je = je->next)
  509.             {
  510.                 if (je->joint->m_islandFlag == true)
  511.                 {
  512.                     continue;
  513.                 }
  514.  
  515.                 b2Body* other = je->other;
  516.  
  517.                 // Don't simulate joints connected to inactive bodies.
  518.                 if (other->IsActive() == false)
  519.                 {
  520.                     continue;
  521.                 }
  522.  
  523.                 island.Add(je->joint);
  524.                 je->joint->m_islandFlag = true;
  525.  
  526.                 if (other->m_flags & b2Body::e_islandFlag)
  527.                 {
  528.                     continue;
  529.                 }
  530.  
  531.                 b2Assert(stackCount < stackSize);
  532.                 stack[stackCount++] = other;
  533.                 other->m_flags |= b2Body::e_islandFlag;
  534.             }
  535.         }
  536.  
  537.         //printf("{M}");
  538.         //fflush(stdout);
  539.         b2Profile profile;
  540.         island.Solve(&profile, step, m_gravity, m_allowSleep);
  541.         m_profile.solveInit += profile.solveInit;
  542.         m_profile.solveVelocity += profile.solveVelocity;
  543.         m_profile.solvePosition += profile.solvePosition;
  544.  
  545.         //printf("{;}");
  546.         //fflush(stdout);
  547.         // Post solve cleanup.
  548.         for (int32 i = 0; i < island.m_bodyCount; ++i)
  549.         {
  550.             // Allow static bodies to participate in other islands.
  551.             b2Body* b = island.m_bodies[i];
  552.             if (b->GetType() == b2_staticBody)
  553.             {
  554.                 b->m_flags &= ~b2Body::e_islandFlag;
  555.             }
  556.         }
  557.     }
  558.  
  559.     m_stackAllocator.Free(stack);
  560.  
  561.     {
  562.         b2Timer timer;
  563.         // Synchronize fixtures, check for out of range bodies.
  564.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  565.         {
  566.             // If a body was not in an island then it did not move.
  567.             if ((b->m_flags & b2Body::e_islandFlag) == 0)
  568.             {
  569.                 continue;
  570.             }
  571.  
  572.             if (b->GetType() == b2_staticBody)
  573.             {
  574.                 continue;
  575.             }
  576.  
  577.             // Update fixtures (for broad-phase).
  578.             b->SynchronizeFixtures();
  579.         }
  580.  
  581.         // Look for new contacts.
  582.         m_contactManager.FindNewContacts();
  583.         m_profile.broadphase = timer.GetMilliseconds();
  584.     }
  585. }
  586.  
  587. // Find TOI contacts and solve them.
  588. void b2World::SolveTOI(const b2TimeStep& step)
  589. {
  590.  
  591.     printf("\n");
  592.     printf("{A}");
  593.     fflush(stdout);
  594.  
  595.     b2Island island(2 * b2_maxTOIContacts, b2_maxTOIContacts, 0, &m_stackAllocator, m_contactManager.m_contactListener);
  596.     printf("{B}");
  597.     fflush(stdout);
  598.  
  599.     if (m_stepComplete)
  600.     {
  601.         for (b2Body* b = m_bodyList; b; b = b->m_next)
  602.         {
  603.             b->m_flags &= ~b2Body::e_islandFlag;
  604.             b->m_sweep.alpha0 = 0.0f;
  605.         }
  606.         printf("{C}");
  607.         fflush(stdout);
  608.  
  609.         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  610.         {
  611.             // Invalidate TOI
  612.             c->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
  613.             c->m_toiCount = 0;
  614.             c->m_toi = 1.0f;
  615.         }
  616.     }
  617.     printf("{D}");
  618.     fflush(stdout);
  619.  
  620.     // Find TOI events and solve them.
  621.     for (;;)
  622.     {
  623.         // Find the first TOI.
  624.         b2Contact* minContact = NULL;
  625.         float32 minAlpha = 1.0f;
  626.  
  627.         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  628.         {
  629.             // Is this contact disabled?
  630.             if (c->IsEnabled() == false)
  631.             {
  632.                 continue;
  633.             }
  634.  
  635.             // Prevent excessive sub-stepping.
  636.             if (c->m_toiCount > b2_maxSubSteps)
  637.             {
  638.                 continue;
  639.             }
  640.  
  641.             float32 alpha = 1.0f;
  642.             if (c->m_flags & b2Contact::e_toiFlag)
  643.             {
  644.                 // This contact has a valid cached TOI.
  645.                 alpha = c->m_toi;
  646.             }
  647.             else
  648.             {
  649.                 b2Fixture* fA = c->GetFixtureA();
  650.                 b2Fixture* fB = c->GetFixtureB();
  651.  
  652.                 // Is there a sensor?
  653.                 if (fA->IsSensor() || fB->IsSensor())
  654.                 {
  655.                     continue;
  656.                 }
  657.  
  658.                 b2Body* bA = fA->GetBody();
  659.                 b2Body* bB = fB->GetBody();
  660.  
  661.                 b2BodyType typeA = bA->m_type;
  662.                 b2BodyType typeB = bB->m_type;
  663.                 b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody);
  664.  
  665.                 bool activeA = bA->IsAwake() && typeA != b2_staticBody;
  666.                 bool activeB = bB->IsAwake() && typeB != b2_staticBody;
  667.  
  668.                 // Is at least one body active (awake and dynamic or kinematic)?
  669.                 if (activeA == false && activeB == false)
  670.                 {
  671.                     continue;
  672.                 }
  673.  
  674.                 bool collideA = bA->IsBullet() || typeA != b2_dynamicBody;
  675.                 bool collideB = bB->IsBullet() || typeB != b2_dynamicBody;
  676.  
  677.                 // Are these two non-bullet dynamic bodies?
  678.                 if (collideA == false && collideB == false)
  679.                 {
  680.                     continue;
  681.                 }
  682.  
  683.                 // Compute the TOI for this contact.
  684.                 // Put the sweeps onto the same time interval.
  685.                 float32 alpha0 = bA->m_sweep.alpha0;
  686.  
  687.                 if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0)
  688.                 {
  689.                     alpha0 = bB->m_sweep.alpha0;
  690.                     bA->m_sweep.Advance(alpha0);
  691.                 }
  692.                 else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0)
  693.                 {
  694.                     alpha0 = bA->m_sweep.alpha0;
  695.                     bB->m_sweep.Advance(alpha0);
  696.                 }
  697.  
  698.                 b2Assert(alpha0 < 1.0f);
  699.  
  700.                 int32 indexA = c->GetChildIndexA();
  701.                 int32 indexB = c->GetChildIndexB();
  702.  
  703.                 // Compute the time of impact in interval [0, minTOI]
  704.                 b2TOIInput input;
  705.                 input.proxyA.Set(fA->GetShape(), indexA);
  706.                 input.proxyB.Set(fB->GetShape(), indexB);
  707.                 input.sweepA = bA->m_sweep;
  708.                 input.sweepB = bB->m_sweep;
  709.                 input.tMax = 1.0f;
  710.  
  711.                 b2TOIOutput output;
  712.                 b2TimeOfImpact(&output, &input);
  713.  
  714.                 // Beta is the fraction of the remaining portion of the .
  715.                 float32 beta = output.t;
  716.                 if (output.state == b2TOIOutput::e_touching)
  717.                 {
  718.                     alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
  719.                 }
  720.                 else
  721.                 {
  722.                     alpha = 1.0f;
  723.                 }
  724.  
  725.                 c->m_toi = alpha;
  726.                 c->m_flags |= b2Contact::e_toiFlag;
  727.             }
  728.  
  729.             if (alpha < minAlpha)
  730.             {
  731.                 // This is the minimum TOI found so far.
  732.                 minContact = c;
  733.                 minAlpha = alpha;
  734.             }
  735.         }
  736.  
  737.         if (minContact == NULL || 1.0f - 10.0f * b2_epsilon < minAlpha)
  738.         {
  739.             printf("{E2}");
  740.             fflush(stdout);
  741.             // No more TOI events. Done!
  742.             m_stepComplete = true;
  743.             break;
  744.         }else{
  745.             printf("{E1}");
  746.             fflush(stdout);
  747.         }
  748.  
  749.         // Advance the bodies to the TOI.
  750.         b2Fixture* fA = minContact->GetFixtureA();
  751.         b2Fixture* fB = minContact->GetFixtureB();
  752.         b2Body* bA = fA->GetBody();
  753.         b2Body* bB = fB->GetBody();
  754.  
  755.         b2Sweep backup1 = bA->m_sweep;
  756.         b2Sweep backup2 = bB->m_sweep;
  757.  
  758.         bA->Advance(minAlpha);
  759.         bB->Advance(minAlpha);
  760.         printf("{F}");
  761.         fflush(stdout);
  762.  
  763.         // The TOI contact likely has some new contact points.
  764.         minContact->Update(m_contactManager.m_contactListener);
  765.         minContact->m_flags &= ~b2Contact::e_toiFlag;
  766.         ++minContact->m_toiCount;
  767.  
  768.         printf("{G}");
  769.         fflush(stdout);
  770.         // Is the contact solid?
  771.         if (minContact->IsEnabled() == false || minContact->IsTouching() == false)
  772.         {
  773.             // Restore the sweeps.
  774.             minContact->SetEnabled(false);
  775.             bA->m_sweep = backup1;
  776.             bB->m_sweep = backup2;
  777.             bA->SynchronizeTransform();
  778.             bB->SynchronizeTransform();
  779.             continue;
  780.         }
  781.  
  782.         bA->SetAwake(true);
  783.         bB->SetAwake(true);
  784.  
  785.         // Build the island
  786.         island.Clear();
  787.         island.Add(bA);
  788.         island.Add(bB);
  789.         island.Add(minContact);
  790.  
  791.         bA->m_flags |= b2Body::e_islandFlag;
  792.         bB->m_flags |= b2Body::e_islandFlag;
  793.         minContact->m_flags |= b2Contact::e_islandFlag;
  794.  
  795.         // Get contacts on bodyA and bodyB.
  796.         b2Body* bodies[2] = {bA, bB};
  797.         for (int32 i = 0; i < 2; ++i)
  798.         {
  799.             b2Body* body = bodies[i];
  800.             if (body->m_type == b2_dynamicBody)
  801.             {
  802.                 for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
  803.                 {
  804.                     if (island.m_bodyCount == island.m_bodyCapacity)
  805.                     {
  806.                         break;
  807.                     }
  808.  
  809.                     if (island.m_contactCount == island.m_contactCapacity)
  810.                     {
  811.                         break;
  812.                     }
  813.  
  814.                     b2Contact* contact = ce->contact;
  815.  
  816.                     // Has this contact already been added to the island?
  817.                     if (contact->m_flags & b2Contact::e_islandFlag)
  818.                     {
  819.                         continue;
  820.                     }
  821.  
  822.                     // Only add static, kinematic, or bullet bodies.
  823.                     b2Body* other = ce->other;
  824.                     if (other->m_type == b2_dynamicBody &&
  825.                         body->IsBullet() == false && other->IsBullet() == false)
  826.                     {
  827.                         continue;
  828.                     }
  829.  
  830.                     // Skip sensors.
  831.                     bool sensorA = contact->m_fixtureA->m_isSensor;
  832.                     bool sensorB = contact->m_fixtureB->m_isSensor;
  833.                     if (sensorA || sensorB)
  834.                     {
  835.                         continue;
  836.                     }
  837.  
  838.                     // Tentatively advance the body to the TOI.
  839.                     b2Sweep backup = other->m_sweep;
  840.                     if ((other->m_flags & b2Body::e_islandFlag) == 0)
  841.                     {
  842.                         other->Advance(minAlpha);
  843.                     }
  844.  
  845.                     // Update the contact points
  846.                     contact->Update(m_contactManager.m_contactListener);
  847.  
  848.                     // Was the contact disabled by the user?
  849.                     if (contact->IsEnabled() == false)
  850.                     {
  851.                         other->m_sweep = backup;
  852.                         other->SynchronizeTransform();
  853.                         continue;
  854.                     }
  855.  
  856.                     // Are there contact points?
  857.                     if (contact->IsTouching() == false)
  858.                     {
  859.                         other->m_sweep = backup;
  860.                         other->SynchronizeTransform();
  861.                         continue;
  862.                     }
  863.  
  864.                     // Add the contact to the island
  865.                     contact->m_flags |= b2Contact::e_islandFlag;
  866.                     island.Add(contact);
  867.  
  868.                     // Has the other body already been added to the island?
  869.                     if (other->m_flags & b2Body::e_islandFlag)
  870.                     {
  871.                         continue;
  872.                     }
  873.                    
  874.                     // Add the other body to the island.
  875.                     other->m_flags |= b2Body::e_islandFlag;
  876.  
  877.                     if (other->m_type != b2_staticBody)
  878.                     {
  879.                         other->SetAwake(true);
  880.                     }
  881.  
  882.                     island.Add(other);
  883.                 }
  884.             }
  885.         }
  886.         printf("{H}");
  887.         fflush(stdout);
  888.  
  889.         b2TimeStep subStep;
  890.         subStep.dt = (1.0f - minAlpha) * step.dt;
  891.         subStep.inv_dt = 1.0f / subStep.dt;
  892.         subStep.dtRatio = 1.0f;
  893.         subStep.positionIterations = 20;
  894.         subStep.velocityIterations = step.velocityIterations;
  895.         subStep.warmStarting = false;
  896.         island.SolveTOI(subStep, bA->m_islandIndex, bB->m_islandIndex);
  897.         printf("{I}");
  898.         fflush(stdout);
  899.  
  900.         // Reset island flags and synchronize broad-phase proxies.
  901.         for (int32 i = 0; i < island.m_bodyCount; ++i)
  902.         {
  903.             b2Body* body = island.m_bodies[i];
  904.             body->m_flags &= ~b2Body::e_islandFlag;
  905.  
  906.             if (body->m_type != b2_dynamicBody)
  907.             {
  908.                 continue;
  909.             }
  910.  
  911.             body->SynchronizeFixtures();
  912.  
  913.             // Invalidate all contact TOIs on this displaced body.
  914.             for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
  915.             {
  916.                 ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
  917.             }
  918.         }
  919.         printf("{J}");
  920.         fflush(stdout);
  921.  
  922.         // Commit fixture proxy movements to the broad-phase so that new contacts are created.
  923.         // Also, some contacts can be destroyed.
  924.         m_contactManager.FindNewContacts();
  925.         printf("{K}");
  926.         fflush(stdout);
  927.  
  928.         if (m_subStepping)
  929.         {
  930.             m_stepComplete = false;
  931.             break;
  932.         }
  933.     }
  934. }
  935.  
  936. void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations)
  937. {
  938.     b2Timer stepTimer;
  939.  
  940.     // If new fixtures were added, we need to find the new contacts.
  941.     if (m_flags & e_newFixture)
  942.     {
  943.         m_contactManager.FindNewContacts();
  944.         m_flags &= ~e_newFixture;
  945.     }
  946.  
  947.     m_flags |= e_locked;
  948.  
  949.     b2TimeStep step;
  950.     step.dt = dt;
  951.     step.velocityIterations = velocityIterations;
  952.     step.positionIterations = positionIterations;
  953.     if (dt > 0.0f)
  954.     {
  955.         step.inv_dt = 1.0f / dt;
  956.     }
  957.     else
  958.     {
  959.         step.inv_dt = 0.0f;
  960.     }
  961.  
  962.     step.dtRatio = m_inv_dt0 * dt;
  963.  
  964.     step.warmStarting = m_warmStarting;
  965.    
  966.     // Update contacts. This is where some contacts are destroyed.
  967.     {
  968.         b2Timer timer;
  969.         m_contactManager.Collide();
  970.         m_profile.collide = timer.GetMilliseconds();
  971.     }
  972.  
  973.     // Integrate velocities, solve velocity constraints, and integrate positions.
  974.     if (m_stepComplete && step.dt > 0.0f)
  975.     {
  976.         b2Timer timer;
  977.         Solve(step);
  978.         m_profile.solve = timer.GetMilliseconds();
  979.     }
  980.  
  981.     // Handle TOI events.
  982.     if (m_continuousPhysics && step.dt > 0.0f)
  983.     {
  984.         b2Timer timer;
  985.         SolveTOI(step);
  986.         m_profile.solveTOI = timer.GetMilliseconds();
  987.     }
  988.  
  989.     if (step.dt > 0.0f)
  990.     {
  991.         m_inv_dt0 = step.inv_dt;
  992.     }
  993.  
  994.     if (m_flags & e_clearForces)
  995.     {
  996.         ClearForces();
  997.     }
  998.  
  999.     m_flags &= ~e_locked;
  1000.  
  1001.     m_profile.step = stepTimer.GetMilliseconds();
  1002.  
  1003.     printf("\n");
  1004.     printf("{PR|");
  1005.     printf("%.2f", m_profile.step);
  1006.     printf("|");
  1007.     printf("%.2f", m_profile.collide);
  1008.     printf("|");
  1009.     printf("%.2f", m_profile.solve);
  1010.     printf("|");
  1011.     printf("%.2f", m_profile.solveInit);
  1012.     printf("|");
  1013.     printf("%.2f", m_profile.solveVelocity);
  1014.     printf("|");
  1015.     printf("%.2f", m_profile.solvePosition);
  1016.     printf("|");
  1017.     printf("%.2f", m_profile.solveTOI);
  1018.     printf("|");
  1019.     printf("%.2f", m_profile.broadphase);
  1020.     printf("}");
  1021.     fflush(stdout);
  1022.  
  1023. }
  1024.  
  1025. void b2World::ClearForces()
  1026. {
  1027.     for (b2Body* body = m_bodyList; body; body = body->GetNext())
  1028.     {
  1029.         body->m_force.SetZero();
  1030.         body->m_torque = 0.0f;
  1031.     }
  1032. }
  1033.  
  1034. struct b2WorldQueryWrapper
  1035. {
  1036.     bool QueryCallback(int32 proxyId)
  1037.     {
  1038.         b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId);
  1039.         return callback->ReportFixture(proxy->fixture);
  1040.     }
  1041.  
  1042.     const b2BroadPhase* broadPhase;
  1043.     b2QueryCallback* callback;
  1044. };
  1045.  
  1046. void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const
  1047. {
  1048.     b2WorldQueryWrapper wrapper;
  1049.     wrapper.broadPhase = &m_contactManager.m_broadPhase;
  1050.     wrapper.callback = callback;
  1051.     m_contactManager.m_broadPhase.Query(&wrapper, aabb);
  1052. }
  1053.  
  1054. struct b2WorldRayCastWrapper
  1055. {
  1056.     float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
  1057.     {
  1058.         void* userData = broadPhase->GetUserData(proxyId);
  1059.         b2FixtureProxy* proxy = (b2FixtureProxy*)userData;
  1060.         b2Fixture* fixture = proxy->fixture;
  1061.         int32 index = proxy->childIndex;
  1062.         b2RayCastOutput output;
  1063.         bool hit = fixture->RayCast(&output, input, index);
  1064.  
  1065.         if (hit)
  1066.         {
  1067.             float32 fraction = output.fraction;
  1068.             b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
  1069.             return callback->ReportFixture(fixture, point, output.normal, fraction);
  1070.         }
  1071.  
  1072.         return input.maxFraction;
  1073.     }
  1074.  
  1075.     const b2BroadPhase* broadPhase;
  1076.     b2RayCastCallback* callback;
  1077. };
  1078.  
  1079. void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
  1080. {
  1081.     b2WorldRayCastWrapper wrapper;
  1082.     wrapper.broadPhase = &m_contactManager.m_broadPhase;
  1083.     wrapper.callback = callback;
  1084.     b2RayCastInput input;
  1085.     input.maxFraction = 1.0f;
  1086.     input.p1 = point1;
  1087.     input.p2 = point2;
  1088.     m_contactManager.m_broadPhase.RayCast(&wrapper, input);
  1089. }
  1090.  
  1091. void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color)
  1092. {
  1093.     switch (fixture->GetType())
  1094.     {
  1095.     case b2Shape::e_circle:
  1096.         {
  1097.             b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
  1098.  
  1099.             b2Vec2 center = b2Mul(xf, circle->m_p);
  1100.             float32 radius = circle->m_radius;
  1101.             b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f));
  1102.  
  1103.             g_debugDraw->DrawSolidCircle(center, radius, axis, color);
  1104.         }
  1105.         break;
  1106.  
  1107.     case b2Shape::e_edge:
  1108.         {
  1109.             b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
  1110.             b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
  1111.             b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
  1112.             g_debugDraw->DrawSegment(v1, v2, color);
  1113.         }
  1114.         break;
  1115.  
  1116.     case b2Shape::e_chain:
  1117.         {
  1118.             b2ChainShape* chain = (b2ChainShape*)fixture->GetShape();
  1119.             int32 count = chain->m_count;
  1120.             const b2Vec2* vertices = chain->m_vertices;
  1121.  
  1122.             b2Vec2 v1 = b2Mul(xf, vertices[0]);
  1123.             for (int32 i = 1; i < count; ++i)
  1124.             {
  1125.                 b2Vec2 v2 = b2Mul(xf, vertices[i]);
  1126.                 g_debugDraw->DrawSegment(v1, v2, color);
  1127.                 g_debugDraw->DrawCircle(v1, 0.05f, color);
  1128.                 v1 = v2;
  1129.             }
  1130.         }
  1131.         break;
  1132.  
  1133.     case b2Shape::e_polygon:
  1134.         {
  1135.             b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
  1136.             int32 vertexCount = poly->m_count;
  1137.             b2Assert(vertexCount <= b2_maxPolygonVertices);
  1138.             b2Vec2 vertices[b2_maxPolygonVertices];
  1139.  
  1140.             for (int32 i = 0; i < vertexCount; ++i)
  1141.             {
  1142.                 vertices[i] = b2Mul(xf, poly->m_vertices[i]);
  1143.             }
  1144.  
  1145.             g_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
  1146.         }
  1147.         break;
  1148.            
  1149.     default:
  1150.         break;
  1151.     }
  1152. }
  1153.  
  1154. void b2World::DrawJoint(b2Joint* joint)
  1155. {
  1156.     b2Body* bodyA = joint->GetBodyA();
  1157.     b2Body* bodyB = joint->GetBodyB();
  1158.     const b2Transform& xf1 = bodyA->GetTransform();
  1159.     const b2Transform& xf2 = bodyB->GetTransform();
  1160.     b2Vec2 x1 = xf1.p;
  1161.     b2Vec2 x2 = xf2.p;
  1162.     b2Vec2 p1 = joint->GetAnchorA();
  1163.     b2Vec2 p2 = joint->GetAnchorB();
  1164.  
  1165.     b2Color color(0.5f, 0.8f, 0.8f);
  1166.  
  1167.     switch (joint->GetType())
  1168.     {
  1169.     case e_distanceJoint:
  1170.         g_debugDraw->DrawSegment(p1, p2, color);
  1171.         break;
  1172.  
  1173.     case e_pulleyJoint:
  1174.         {
  1175.             b2PulleyJoint* pulley = (b2PulleyJoint*)joint;
  1176.             b2Vec2 s1 = pulley->GetGroundAnchorA();
  1177.             b2Vec2 s2 = pulley->GetGroundAnchorB();
  1178.             g_debugDraw->DrawSegment(s1, p1, color);
  1179.             g_debugDraw->DrawSegment(s2, p2, color);
  1180.             g_debugDraw->DrawSegment(s1, s2, color);
  1181.         }
  1182.         break;
  1183.  
  1184.     case e_mouseJoint:
  1185.         // don't draw this
  1186.         break;
  1187.  
  1188.     default:
  1189.         g_debugDraw->DrawSegment(x1, p1, color);
  1190.         g_debugDraw->DrawSegment(p1, p2, color);
  1191.         g_debugDraw->DrawSegment(x2, p2, color);
  1192.     }
  1193. }
  1194.  
  1195. void b2World::DrawDebugData()
  1196. {
  1197.     if (g_debugDraw == NULL)
  1198.     {
  1199.         return;
  1200.     }
  1201.  
  1202.     uint32 flags = g_debugDraw->GetFlags();
  1203.  
  1204.     if (flags & b2Draw::e_shapeBit)
  1205.     {
  1206.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1207.         {
  1208.             const b2Transform& xf = b->GetTransform();
  1209.             for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
  1210.             {
  1211.                 if (b->IsActive() == false)
  1212.                 {
  1213.                     DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f));
  1214.                 }
  1215.                 else if (b->GetType() == b2_staticBody)
  1216.                 {
  1217.                     DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f));
  1218.                 }
  1219.                 else if (b->GetType() == b2_kinematicBody)
  1220.                 {
  1221.                     DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f));
  1222.                 }
  1223.                 else if (b->IsAwake() == false)
  1224.                 {
  1225.                     DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f));
  1226.                 }
  1227.                 else
  1228.                 {
  1229.                     DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f));
  1230.                 }
  1231.             }
  1232.         }
  1233.     }
  1234.  
  1235.     if (flags & b2Draw::e_jointBit)
  1236.     {
  1237.         for (b2Joint* j = m_jointList; j; j = j->GetNext())
  1238.         {
  1239.             DrawJoint(j);
  1240.         }
  1241.     }
  1242.  
  1243.     if (flags & b2Draw::e_pairBit)
  1244.     {
  1245.         b2Color color(0.3f, 0.9f, 0.9f);
  1246.         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext())
  1247.         {
  1248.             //b2Fixture* fixtureA = c->GetFixtureA();
  1249.             //b2Fixture* fixtureB = c->GetFixtureB();
  1250.  
  1251.             //b2Vec2 cA = fixtureA->GetAABB().GetCenter();
  1252.             //b2Vec2 cB = fixtureB->GetAABB().GetCenter();
  1253.  
  1254.             //g_debugDraw->DrawSegment(cA, cB, color);
  1255.         }
  1256.     }
  1257.  
  1258.     if (flags & b2Draw::e_aabbBit)
  1259.     {
  1260.         b2Color color(0.9f, 0.3f, 0.9f);
  1261.         b2BroadPhase* bp = &m_contactManager.m_broadPhase;
  1262.  
  1263.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1264.         {
  1265.             if (b->IsActive() == false)
  1266.             {
  1267.                 continue;
  1268.             }
  1269.  
  1270.             for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
  1271.             {
  1272.                 for (int32 i = 0; i < f->m_proxyCount; ++i)
  1273.                 {
  1274.                     b2FixtureProxy* proxy = f->m_proxies + i;
  1275.                     b2AABB aabb = bp->GetFatAABB(proxy->proxyId);
  1276.                     b2Vec2 vs[4];
  1277.                     vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
  1278.                     vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
  1279.                     vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
  1280.                     vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
  1281.  
  1282.                     g_debugDraw->DrawPolygon(vs, 4, color);
  1283.                 }
  1284.             }
  1285.         }
  1286.     }
  1287.  
  1288.     if (flags & b2Draw::e_centerOfMassBit)
  1289.     {
  1290.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1291.         {
  1292.             b2Transform xf = b->GetTransform();
  1293.             xf.p = b->GetWorldCenter();
  1294.             g_debugDraw->DrawTransform(xf);
  1295.         }
  1296.     }
  1297. }
  1298.  
  1299. int32 b2World::GetProxyCount() const
  1300. {
  1301.     return m_contactManager.m_broadPhase.GetProxyCount();
  1302. }
  1303.  
  1304. int32 b2World::GetTreeHeight() const
  1305. {
  1306.     return m_contactManager.m_broadPhase.GetTreeHeight();
  1307. }
  1308.  
  1309. int32 b2World::GetTreeBalance() const
  1310. {
  1311.     return m_contactManager.m_broadPhase.GetTreeBalance();
  1312. }
  1313.  
  1314. float32 b2World::GetTreeQuality() const
  1315. {
  1316.     return m_contactManager.m_broadPhase.GetTreeQuality();
  1317. }
  1318.  
  1319. void b2World::ShiftOrigin(const b2Vec2& newOrigin)
  1320. {
  1321.     b2Assert((m_flags & e_locked) == 0);
  1322.     if ((m_flags & e_locked) == e_locked)
  1323.     {
  1324.         return;
  1325.     }
  1326.  
  1327.     for (b2Body* b = m_bodyList; b; b = b->m_next)
  1328.     {
  1329.         b->m_xf.p -= newOrigin;
  1330.         b->m_sweep.c0 -= newOrigin;
  1331.         b->m_sweep.c -= newOrigin;
  1332.     }
  1333.  
  1334.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1335.     {
  1336.         j->ShiftOrigin(newOrigin);
  1337.     }
  1338.  
  1339.     m_contactManager.m_broadPhase.ShiftOrigin(newOrigin);
  1340. }
  1341.  
  1342. void b2World::Dump()
  1343. {
  1344.     if ((m_flags & e_locked) == e_locked)
  1345.     {
  1346.         return;
  1347.     }
  1348.  
  1349.     b2Log("b2Vec2 g(%.15lef, %.15lef);\n", m_gravity.x, m_gravity.y);
  1350.     b2Log("m_world->SetGravity(g);\n");
  1351.  
  1352.     b2Log("b2Body** bodies = (b2Body**)b2Alloc(%d * sizeof(b2Body*));\n", m_bodyCount);
  1353.     b2Log("b2Joint** joints = (b2Joint**)b2Alloc(%d * sizeof(b2Joint*));\n", m_jointCount);
  1354.     int32 i = 0;
  1355.     for (b2Body* b = m_bodyList; b; b = b->m_next)
  1356.     {
  1357.         b->m_islandIndex = i;
  1358.         b->Dump();
  1359.         ++i;
  1360.     }
  1361.  
  1362.     i = 0;
  1363.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1364.     {
  1365.         j->m_index = i;
  1366.         ++i;
  1367.     }
  1368.  
  1369.     // First pass on joints, skip gear joints.
  1370.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1371.     {
  1372.         if (j->m_type == e_gearJoint)
  1373.         {
  1374.             continue;
  1375.         }
  1376.  
  1377.         b2Log("{\n");
  1378.         j->Dump();
  1379.         b2Log("}\n");
  1380.     }
  1381.  
  1382.     // Second pass on joints, only gear joints.
  1383.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1384.     {
  1385.         if (j->m_type != e_gearJoint)
  1386.         {
  1387.             continue;
  1388.         }
  1389.  
  1390.         b2Log("{\n");
  1391.         j->Dump();
  1392.         b2Log("}\n");
  1393.     }
  1394.  
  1395.     b2Log("b2Free(joints);\n");
  1396.     b2Log("b2Free(bodies);\n");
  1397.     b2Log("joints = NULL;\n");
  1398.     b2Log("bodies = NULL;\n");
  1399. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement