b2World.cpp 33 KB

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