Advertisement
Guest User

b2World.cpp v2

a guest
Jun 22nd, 2018
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.66 KB | None | 0 0
  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.         int32 contactCount = 0;
  627.         int32 contactProcessedCount = 0;
  628.  
  629.         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  630.         {
  631.             contactCount++;
  632.             // Is this contact disabled?
  633.             if (c->IsEnabled() == false)
  634.             {
  635.                 continue;
  636.             }
  637.  
  638.             // Prevent excessive sub-stepping.
  639.             if (c->m_toiCount > b2_maxSubSteps)
  640.             {
  641.                 continue;
  642.             }
  643.  
  644.             float32 alpha = 1.0f;
  645.             if (c->m_flags & b2Contact::e_toiFlag)
  646.             {
  647.                 // This contact has a valid cached TOI.
  648.                 alpha = c->m_toi;
  649.             }
  650.             else
  651.             {
  652.                 b2Fixture* fA = c->GetFixtureA();
  653.                 b2Fixture* fB = c->GetFixtureB();
  654.  
  655.                 // Is there a sensor?
  656.                 if (fA->IsSensor() || fB->IsSensor())
  657.                 {
  658.                     continue;
  659.                 }
  660.  
  661.                 b2Body* bA = fA->GetBody();
  662.                 b2Body* bB = fB->GetBody();
  663.  
  664.                 b2BodyType typeA = bA->m_type;
  665.                 b2BodyType typeB = bB->m_type;
  666.                 b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody);
  667.  
  668.                 bool activeA = bA->IsAwake() && typeA != b2_staticBody;
  669.                 bool activeB = bB->IsAwake() && typeB != b2_staticBody;
  670.  
  671.                 // Is at least one body active (awake and dynamic or kinematic)?
  672.                 if (activeA == false && activeB == false)
  673.                 {
  674.                     continue;
  675.                 }
  676.  
  677.                 bool collideA = bA->IsBullet() || typeA != b2_dynamicBody;
  678.                 bool collideB = bB->IsBullet() || typeB != b2_dynamicBody;
  679.  
  680.                 // Are these two non-bullet dynamic bodies?
  681.                 if (collideA == false && collideB == false)
  682.                 {
  683.                     continue;
  684.                 }
  685.  
  686.                 // Compute the TOI for this contact.
  687.                 // Put the sweeps onto the same time interval.
  688.                 float32 alpha0 = bA->m_sweep.alpha0;
  689.  
  690.                 if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0)
  691.                 {
  692.                     alpha0 = bB->m_sweep.alpha0;
  693.                     bA->m_sweep.Advance(alpha0);
  694.                 }
  695.                 else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0)
  696.                 {
  697.                     alpha0 = bA->m_sweep.alpha0;
  698.                     bB->m_sweep.Advance(alpha0);
  699.                 }
  700.  
  701.                 b2Assert(alpha0 < 1.0f);
  702.  
  703.                 int32 indexA = c->GetChildIndexA();
  704.                 int32 indexB = c->GetChildIndexB();
  705.  
  706.                 // Compute the time of impact in interval [0, minTOI]
  707.                 b2TOIInput input;
  708.                 input.proxyA.Set(fA->GetShape(), indexA);
  709.                 input.proxyB.Set(fB->GetShape(), indexB);
  710.                 input.sweepA = bA->m_sweep;
  711.                 input.sweepB = bB->m_sweep;
  712.                 input.tMax = 1.0f;
  713.  
  714.                 b2TOIOutput output;
  715.                 b2TimeOfImpact(&output, &input);
  716.  
  717.                 // Beta is the fraction of the remaining portion of the .
  718.                 float32 beta = output.t;
  719.                 if (output.state == b2TOIOutput::e_touching)
  720.                 {
  721.                     alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
  722.                 }
  723.                 else
  724.                 {
  725.                     alpha = 1.0f;
  726.                 }
  727.  
  728.                 c->m_toi = alpha;
  729.                 c->m_flags |= b2Contact::e_toiFlag;
  730.                 contactProcessedCount++;
  731.             }
  732.  
  733.             if (alpha < minAlpha)
  734.             {
  735.                 // This is the minimum TOI found so far.
  736.                 minContact = c;
  737.                 minAlpha = alpha;
  738.             }
  739.         }
  740.         printf("{c");
  741.         printf("%d",contactProcessedCount);
  742.         printf("/");
  743.         printf("%d",contactCount);
  744.         printf("}");
  745.         fflush(stdout);
  746.  
  747.         if (minContact == NULL || 1.0f - 10.0f * b2_epsilon < minAlpha)
  748.         {
  749.             printf("{E2}");
  750.             fflush(stdout);
  751.             // No more TOI events. Done!
  752.             m_stepComplete = true;
  753.             break;
  754.         }else{
  755.             printf("{E1}");
  756.             fflush(stdout);
  757.         }
  758.  
  759.         // Advance the bodies to the TOI.
  760.         b2Fixture* fA = minContact->GetFixtureA();
  761.         b2Fixture* fB = minContact->GetFixtureB();
  762.         b2Body* bA = fA->GetBody();
  763.         b2Body* bB = fB->GetBody();
  764.  
  765.         b2Sweep backup1 = bA->m_sweep;
  766.         b2Sweep backup2 = bB->m_sweep;
  767.  
  768.         bA->Advance(minAlpha);
  769.         bB->Advance(minAlpha);
  770.         printf("{F}");
  771.         fflush(stdout);
  772.  
  773.         // The TOI contact likely has some new contact points.
  774.         minContact->Update(m_contactManager.m_contactListener);
  775.         minContact->m_flags &= ~b2Contact::e_toiFlag;
  776.         ++minContact->m_toiCount;
  777.  
  778.         printf("{G}");
  779.         fflush(stdout);
  780.         // Is the contact solid?
  781.         if (minContact->IsEnabled() == false || minContact->IsTouching() == false)
  782.         {
  783.             // Restore the sweeps.
  784.             minContact->SetEnabled(false);
  785.             bA->m_sweep = backup1;
  786.             bB->m_sweep = backup2;
  787.             bA->SynchronizeTransform();
  788.             bB->SynchronizeTransform();
  789.             continue;
  790.         }
  791.  
  792.         bA->SetAwake(true);
  793.         bB->SetAwake(true);
  794.  
  795.         // Build the island
  796.         island.Clear();
  797.         island.Add(bA);
  798.         island.Add(bB);
  799.         island.Add(minContact);
  800.  
  801.         bA->m_flags |= b2Body::e_islandFlag;
  802.         bB->m_flags |= b2Body::e_islandFlag;
  803.         minContact->m_flags |= b2Contact::e_islandFlag;
  804.  
  805.         // Get contacts on bodyA and bodyB.
  806.         b2Body* bodies[2] = {bA, bB};
  807.         for (int32 i = 0; i < 2; ++i)
  808.         {
  809.             b2Body* body = bodies[i];
  810.             if (body->m_type == b2_dynamicBody)
  811.             {
  812.                 for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
  813.                 {
  814.                     if (island.m_bodyCount == island.m_bodyCapacity)
  815.                     {
  816.                         break;
  817.                     }
  818.  
  819.                     if (island.m_contactCount == island.m_contactCapacity)
  820.                     {
  821.                         break;
  822.                     }
  823.  
  824.                     b2Contact* contact = ce->contact;
  825.  
  826.                     // Has this contact already been added to the island?
  827.                     if (contact->m_flags & b2Contact::e_islandFlag)
  828.                     {
  829.                         continue;
  830.                     }
  831.  
  832.                     // Only add static, kinematic, or bullet bodies.
  833.                     b2Body* other = ce->other;
  834.                     if (other->m_type == b2_dynamicBody &&
  835.                         body->IsBullet() == false && other->IsBullet() == false)
  836.                     {
  837.                         continue;
  838.                     }
  839.  
  840.                     // Skip sensors.
  841.                     bool sensorA = contact->m_fixtureA->m_isSensor;
  842.                     bool sensorB = contact->m_fixtureB->m_isSensor;
  843.                     if (sensorA || sensorB)
  844.                     {
  845.                         continue;
  846.                     }
  847.  
  848.                     // Tentatively advance the body to the TOI.
  849.                     b2Sweep backup = other->m_sweep;
  850.                     if ((other->m_flags & b2Body::e_islandFlag) == 0)
  851.                     {
  852.                         other->Advance(minAlpha);
  853.                     }
  854.  
  855.                     // Update the contact points
  856.                     contact->Update(m_contactManager.m_contactListener);
  857.  
  858.                     // Was the contact disabled by the user?
  859.                     if (contact->IsEnabled() == false)
  860.                     {
  861.                         other->m_sweep = backup;
  862.                         other->SynchronizeTransform();
  863.                         continue;
  864.                     }
  865.  
  866.                     // Are there contact points?
  867.                     if (contact->IsTouching() == false)
  868.                     {
  869.                         other->m_sweep = backup;
  870.                         other->SynchronizeTransform();
  871.                         continue;
  872.                     }
  873.  
  874.                     // Add the contact to the island
  875.                     contact->m_flags |= b2Contact::e_islandFlag;
  876.                     island.Add(contact);
  877.  
  878.                     // Has the other body already been added to the island?
  879.                     if (other->m_flags & b2Body::e_islandFlag)
  880.                     {
  881.                         continue;
  882.                     }
  883.                    
  884.                     // Add the other body to the island.
  885.                     other->m_flags |= b2Body::e_islandFlag;
  886.  
  887.                     if (other->m_type != b2_staticBody)
  888.                     {
  889.                         other->SetAwake(true);
  890.                     }
  891.  
  892.                     island.Add(other);
  893.                 }
  894.             }
  895.         }
  896.         printf("{H}");
  897.         fflush(stdout);
  898.  
  899.         b2TimeStep subStep;
  900.         subStep.dt = (1.0f - minAlpha) * step.dt;
  901.         subStep.inv_dt = 1.0f / subStep.dt;
  902.         subStep.dtRatio = 1.0f;
  903.         subStep.positionIterations = 20;
  904.         subStep.velocityIterations = step.velocityIterations;
  905.         subStep.warmStarting = false;
  906.         island.SolveTOI(subStep, bA->m_islandIndex, bB->m_islandIndex);
  907.         printf("{I}");
  908.         fflush(stdout);
  909.  
  910.         // Reset island flags and synchronize broad-phase proxies.
  911.         for (int32 i = 0; i < island.m_bodyCount; ++i)
  912.         {
  913.             b2Body* body = island.m_bodies[i];
  914.             body->m_flags &= ~b2Body::e_islandFlag;
  915.  
  916.             if (body->m_type != b2_dynamicBody)
  917.             {
  918.                 continue;
  919.             }
  920.  
  921.             body->SynchronizeFixtures();
  922.  
  923.             // Invalidate all contact TOIs on this displaced body.
  924.             for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
  925.             {
  926.                 ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
  927.             }
  928.         }
  929.         printf("{J}");
  930.         fflush(stdout);
  931.  
  932.         // Commit fixture proxy movements to the broad-phase so that new contacts are created.
  933.         // Also, some contacts can be destroyed.
  934.         m_contactManager.FindNewContacts();
  935.         printf("{K}");
  936.         fflush(stdout);
  937.  
  938.         if (m_subStepping)
  939.         {
  940.             m_stepComplete = false;
  941.             break;
  942.         }
  943.     }
  944. }
  945.  
  946. void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations)
  947. {
  948.     b2Timer stepTimer;
  949.  
  950.     // If new fixtures were added, we need to find the new contacts.
  951.     if (m_flags & e_newFixture)
  952.     {
  953.         m_contactManager.FindNewContacts();
  954.         m_flags &= ~e_newFixture;
  955.     }
  956.  
  957.     m_flags |= e_locked;
  958.  
  959.     b2TimeStep step;
  960.     step.dt = dt;
  961.     step.velocityIterations = velocityIterations;
  962.     step.positionIterations = positionIterations;
  963.     if (dt > 0.0f)
  964.     {
  965.         step.inv_dt = 1.0f / dt;
  966.     }
  967.     else
  968.     {
  969.         step.inv_dt = 0.0f;
  970.     }
  971.  
  972.     step.dtRatio = m_inv_dt0 * dt;
  973.  
  974.     step.warmStarting = m_warmStarting;
  975.    
  976.     // Update contacts. This is where some contacts are destroyed.
  977.     {
  978.         b2Timer timer;
  979.         m_contactManager.Collide();
  980.         m_profile.collide = timer.GetMilliseconds();
  981.     }
  982.  
  983.     // Integrate velocities, solve velocity constraints, and integrate positions.
  984.     if (m_stepComplete && step.dt > 0.0f)
  985.     {
  986.         b2Timer timer;
  987.         Solve(step);
  988.         m_profile.solve = timer.GetMilliseconds();
  989.     }
  990.  
  991.     // Handle TOI events.
  992.     if (m_continuousPhysics && step.dt > 0.0f)
  993.     {
  994.         b2Timer timer;
  995.         SolveTOI(step);
  996.         m_profile.solveTOI = timer.GetMilliseconds();
  997.     }
  998.  
  999.     if (step.dt > 0.0f)
  1000.     {
  1001.         m_inv_dt0 = step.inv_dt;
  1002.     }
  1003.  
  1004.     if (m_flags & e_clearForces)
  1005.     {
  1006.         ClearForces();
  1007.     }
  1008.  
  1009.     m_flags &= ~e_locked;
  1010.  
  1011.     m_profile.step = stepTimer.GetMilliseconds();
  1012.  
  1013.     printf("\n");
  1014.     printf("{PR|");
  1015.     printf("%.2f", m_profile.step);
  1016.     printf("|");
  1017.     printf("%.2f", m_profile.collide);
  1018.     printf("|");
  1019.     printf("%.2f", m_profile.solve);
  1020.     printf("|");
  1021.     printf("%.2f", m_profile.solveInit);
  1022.     printf("|");
  1023.     printf("%.2f", m_profile.solveVelocity);
  1024.     printf("|");
  1025.     printf("%.2f", m_profile.solvePosition);
  1026.     printf("|");
  1027.     printf("%.2f", m_profile.solveTOI);
  1028.     printf("|");
  1029.     printf("%.2f", m_profile.broadphase);
  1030.     printf("}");
  1031.     fflush(stdout);
  1032.  
  1033. }
  1034.  
  1035. void b2World::ClearForces()
  1036. {
  1037.     for (b2Body* body = m_bodyList; body; body = body->GetNext())
  1038.     {
  1039.         body->m_force.SetZero();
  1040.         body->m_torque = 0.0f;
  1041.     }
  1042. }
  1043.  
  1044. struct b2WorldQueryWrapper
  1045. {
  1046.     bool QueryCallback(int32 proxyId)
  1047.     {
  1048.         b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId);
  1049.         return callback->ReportFixture(proxy->fixture);
  1050.     }
  1051.  
  1052.     const b2BroadPhase* broadPhase;
  1053.     b2QueryCallback* callback;
  1054. };
  1055.  
  1056. void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const
  1057. {
  1058.     b2WorldQueryWrapper wrapper;
  1059.     wrapper.broadPhase = &m_contactManager.m_broadPhase;
  1060.     wrapper.callback = callback;
  1061.     m_contactManager.m_broadPhase.Query(&wrapper, aabb);
  1062. }
  1063.  
  1064. struct b2WorldRayCastWrapper
  1065. {
  1066.     float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
  1067.     {
  1068.         void* userData = broadPhase->GetUserData(proxyId);
  1069.         b2FixtureProxy* proxy = (b2FixtureProxy*)userData;
  1070.         b2Fixture* fixture = proxy->fixture;
  1071.         int32 index = proxy->childIndex;
  1072.         b2RayCastOutput output;
  1073.         bool hit = fixture->RayCast(&output, input, index);
  1074.  
  1075.         if (hit)
  1076.         {
  1077.             float32 fraction = output.fraction;
  1078.             b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
  1079.             return callback->ReportFixture(fixture, point, output.normal, fraction);
  1080.         }
  1081.  
  1082.         return input.maxFraction;
  1083.     }
  1084.  
  1085.     const b2BroadPhase* broadPhase;
  1086.     b2RayCastCallback* callback;
  1087. };
  1088.  
  1089. void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
  1090. {
  1091.     b2WorldRayCastWrapper wrapper;
  1092.     wrapper.broadPhase = &m_contactManager.m_broadPhase;
  1093.     wrapper.callback = callback;
  1094.     b2RayCastInput input;
  1095.     input.maxFraction = 1.0f;
  1096.     input.p1 = point1;
  1097.     input.p2 = point2;
  1098.     m_contactManager.m_broadPhase.RayCast(&wrapper, input);
  1099. }
  1100.  
  1101. void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color)
  1102. {
  1103.     switch (fixture->GetType())
  1104.     {
  1105.     case b2Shape::e_circle:
  1106.         {
  1107.             b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
  1108.  
  1109.             b2Vec2 center = b2Mul(xf, circle->m_p);
  1110.             float32 radius = circle->m_radius;
  1111.             b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f));
  1112.  
  1113.             g_debugDraw->DrawSolidCircle(center, radius, axis, color);
  1114.         }
  1115.         break;
  1116.  
  1117.     case b2Shape::e_edge:
  1118.         {
  1119.             b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
  1120.             b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
  1121.             b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
  1122.             g_debugDraw->DrawSegment(v1, v2, color);
  1123.         }
  1124.         break;
  1125.  
  1126.     case b2Shape::e_chain:
  1127.         {
  1128.             b2ChainShape* chain = (b2ChainShape*)fixture->GetShape();
  1129.             int32 count = chain->m_count;
  1130.             const b2Vec2* vertices = chain->m_vertices;
  1131.  
  1132.             b2Vec2 v1 = b2Mul(xf, vertices[0]);
  1133.             for (int32 i = 1; i < count; ++i)
  1134.             {
  1135.                 b2Vec2 v2 = b2Mul(xf, vertices[i]);
  1136.                 g_debugDraw->DrawSegment(v1, v2, color);
  1137.                 g_debugDraw->DrawCircle(v1, 0.05f, color);
  1138.                 v1 = v2;
  1139.             }
  1140.         }
  1141.         break;
  1142.  
  1143.     case b2Shape::e_polygon:
  1144.         {
  1145.             b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
  1146.             int32 vertexCount = poly->m_count;
  1147.             b2Assert(vertexCount <= b2_maxPolygonVertices);
  1148.             b2Vec2 vertices[b2_maxPolygonVertices];
  1149.  
  1150.             for (int32 i = 0; i < vertexCount; ++i)
  1151.             {
  1152.                 vertices[i] = b2Mul(xf, poly->m_vertices[i]);
  1153.             }
  1154.  
  1155.             g_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
  1156.         }
  1157.         break;
  1158.            
  1159.     default:
  1160.         break;
  1161.     }
  1162. }
  1163.  
  1164. void b2World::DrawJoint(b2Joint* joint)
  1165. {
  1166.     b2Body* bodyA = joint->GetBodyA();
  1167.     b2Body* bodyB = joint->GetBodyB();
  1168.     const b2Transform& xf1 = bodyA->GetTransform();
  1169.     const b2Transform& xf2 = bodyB->GetTransform();
  1170.     b2Vec2 x1 = xf1.p;
  1171.     b2Vec2 x2 = xf2.p;
  1172.     b2Vec2 p1 = joint->GetAnchorA();
  1173.     b2Vec2 p2 = joint->GetAnchorB();
  1174.  
  1175.     b2Color color(0.5f, 0.8f, 0.8f);
  1176.  
  1177.     switch (joint->GetType())
  1178.     {
  1179.     case e_distanceJoint:
  1180.         g_debugDraw->DrawSegment(p1, p2, color);
  1181.         break;
  1182.  
  1183.     case e_pulleyJoint:
  1184.         {
  1185.             b2PulleyJoint* pulley = (b2PulleyJoint*)joint;
  1186.             b2Vec2 s1 = pulley->GetGroundAnchorA();
  1187.             b2Vec2 s2 = pulley->GetGroundAnchorB();
  1188.             g_debugDraw->DrawSegment(s1, p1, color);
  1189.             g_debugDraw->DrawSegment(s2, p2, color);
  1190.             g_debugDraw->DrawSegment(s1, s2, color);
  1191.         }
  1192.         break;
  1193.  
  1194.     case e_mouseJoint:
  1195.         // don't draw this
  1196.         break;
  1197.  
  1198.     default:
  1199.         g_debugDraw->DrawSegment(x1, p1, color);
  1200.         g_debugDraw->DrawSegment(p1, p2, color);
  1201.         g_debugDraw->DrawSegment(x2, p2, color);
  1202.     }
  1203. }
  1204.  
  1205. void b2World::DrawDebugData()
  1206. {
  1207.     if (g_debugDraw == NULL)
  1208.     {
  1209.         return;
  1210.     }
  1211.  
  1212.     uint32 flags = g_debugDraw->GetFlags();
  1213.  
  1214.     if (flags & b2Draw::e_shapeBit)
  1215.     {
  1216.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1217.         {
  1218.             const b2Transform& xf = b->GetTransform();
  1219.             for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
  1220.             {
  1221.                 if (b->IsActive() == false)
  1222.                 {
  1223.                     DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f));
  1224.                 }
  1225.                 else if (b->GetType() == b2_staticBody)
  1226.                 {
  1227.                     DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f));
  1228.                 }
  1229.                 else if (b->GetType() == b2_kinematicBody)
  1230.                 {
  1231.                     DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f));
  1232.                 }
  1233.                 else if (b->IsAwake() == false)
  1234.                 {
  1235.                     DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f));
  1236.                 }
  1237.                 else
  1238.                 {
  1239.                     DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f));
  1240.                 }
  1241.             }
  1242.         }
  1243.     }
  1244.  
  1245.     if (flags & b2Draw::e_jointBit)
  1246.     {
  1247.         for (b2Joint* j = m_jointList; j; j = j->GetNext())
  1248.         {
  1249.             DrawJoint(j);
  1250.         }
  1251.     }
  1252.  
  1253.     if (flags & b2Draw::e_pairBit)
  1254.     {
  1255.         b2Color color(0.3f, 0.9f, 0.9f);
  1256.         for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext())
  1257.         {
  1258.             //b2Fixture* fixtureA = c->GetFixtureA();
  1259.             //b2Fixture* fixtureB = c->GetFixtureB();
  1260.  
  1261.             //b2Vec2 cA = fixtureA->GetAABB().GetCenter();
  1262.             //b2Vec2 cB = fixtureB->GetAABB().GetCenter();
  1263.  
  1264.             //g_debugDraw->DrawSegment(cA, cB, color);
  1265.         }
  1266.     }
  1267.  
  1268.     if (flags & b2Draw::e_aabbBit)
  1269.     {
  1270.         b2Color color(0.9f, 0.3f, 0.9f);
  1271.         b2BroadPhase* bp = &m_contactManager.m_broadPhase;
  1272.  
  1273.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1274.         {
  1275.             if (b->IsActive() == false)
  1276.             {
  1277.                 continue;
  1278.             }
  1279.  
  1280.             for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
  1281.             {
  1282.                 for (int32 i = 0; i < f->m_proxyCount; ++i)
  1283.                 {
  1284.                     b2FixtureProxy* proxy = f->m_proxies + i;
  1285.                     b2AABB aabb = bp->GetFatAABB(proxy->proxyId);
  1286.                     b2Vec2 vs[4];
  1287.                     vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
  1288.                     vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
  1289.                     vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
  1290.                     vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
  1291.  
  1292.                     g_debugDraw->DrawPolygon(vs, 4, color);
  1293.                 }
  1294.             }
  1295.         }
  1296.     }
  1297.  
  1298.     if (flags & b2Draw::e_centerOfMassBit)
  1299.     {
  1300.         for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1301.         {
  1302.             b2Transform xf = b->GetTransform();
  1303.             xf.p = b->GetWorldCenter();
  1304.             g_debugDraw->DrawTransform(xf);
  1305.         }
  1306.     }
  1307. }
  1308.  
  1309. int32 b2World::GetProxyCount() const
  1310. {
  1311.     return m_contactManager.m_broadPhase.GetProxyCount();
  1312. }
  1313.  
  1314. int32 b2World::GetTreeHeight() const
  1315. {
  1316.     return m_contactManager.m_broadPhase.GetTreeHeight();
  1317. }
  1318.  
  1319. int32 b2World::GetTreeBalance() const
  1320. {
  1321.     return m_contactManager.m_broadPhase.GetTreeBalance();
  1322. }
  1323.  
  1324. float32 b2World::GetTreeQuality() const
  1325. {
  1326.     return m_contactManager.m_broadPhase.GetTreeQuality();
  1327. }
  1328.  
  1329. void b2World::ShiftOrigin(const b2Vec2& newOrigin)
  1330. {
  1331.     b2Assert((m_flags & e_locked) == 0);
  1332.     if ((m_flags & e_locked) == e_locked)
  1333.     {
  1334.         return;
  1335.     }
  1336.  
  1337.     for (b2Body* b = m_bodyList; b; b = b->m_next)
  1338.     {
  1339.         b->m_xf.p -= newOrigin;
  1340.         b->m_sweep.c0 -= newOrigin;
  1341.         b->m_sweep.c -= newOrigin;
  1342.     }
  1343.  
  1344.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1345.     {
  1346.         j->ShiftOrigin(newOrigin);
  1347.     }
  1348.  
  1349.     m_contactManager.m_broadPhase.ShiftOrigin(newOrigin);
  1350. }
  1351.  
  1352. void b2World::Dump()
  1353. {
  1354.     if ((m_flags & e_locked) == e_locked)
  1355.     {
  1356.         return;
  1357.     }
  1358.  
  1359.     b2Log("b2Vec2 g(%.15lef, %.15lef);\n", m_gravity.x, m_gravity.y);
  1360.     b2Log("m_world->SetGravity(g);\n");
  1361.  
  1362.     b2Log("b2Body** bodies = (b2Body**)b2Alloc(%d * sizeof(b2Body*));\n", m_bodyCount);
  1363.     b2Log("b2Joint** joints = (b2Joint**)b2Alloc(%d * sizeof(b2Joint*));\n", m_jointCount);
  1364.     int32 i = 0;
  1365.     for (b2Body* b = m_bodyList; b; b = b->m_next)
  1366.     {
  1367.         b->m_islandIndex = i;
  1368.         b->Dump();
  1369.         ++i;
  1370.     }
  1371.  
  1372.     i = 0;
  1373.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1374.     {
  1375.         j->m_index = i;
  1376.         ++i;
  1377.     }
  1378.  
  1379.     // First pass on joints, skip gear joints.
  1380.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1381.     {
  1382.         if (j->m_type == e_gearJoint)
  1383.         {
  1384.             continue;
  1385.         }
  1386.  
  1387.         b2Log("{\n");
  1388.         j->Dump();
  1389.         b2Log("}\n");
  1390.     }
  1391.  
  1392.     // Second pass on joints, only gear joints.
  1393.     for (b2Joint* j = m_jointList; j; j = j->m_next)
  1394.     {
  1395.         if (j->m_type != e_gearJoint)
  1396.         {
  1397.             continue;
  1398.         }
  1399.  
  1400.         b2Log("{\n");
  1401.         j->Dump();
  1402.         b2Log("}\n");
  1403.     }
  1404.  
  1405.     b2Log("b2Free(joints);\n");
  1406.     b2Log("b2Free(bodies);\n");
  1407.     b2Log("joints = NULL;\n");
  1408.     b2Log("bodies = NULL;\n");
  1409. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement