b2World.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  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. #include <Box2D/Dynamics/b2World.h>
  19. #include <Box2D/Dynamics/b2Body.h>
  20. #include <Box2D/Dynamics/b2Fixture.h>
  21. #include <Box2D/Dynamics/b2Island.h>
  22. #include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
  23. #include <Box2D/Dynamics/Contacts/b2Contact.h>
  24. #include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
  25. #include <Box2D/Collision/b2Collision.h>
  26. #include <Box2D/Collision/b2BroadPhase.h>
  27. #include <Box2D/Collision/Shapes/b2CircleShape.h>
  28. #include <Box2D/Collision/Shapes/b2EdgeShape.h>
  29. #include <Box2D/Collision/Shapes/b2LoopShape.h>
  30. #include <Box2D/Collision/Shapes/b2PolygonShape.h>
  31. #include <Box2D/Collision/b2TimeOfImpact.h>
  32. #include <Box2D/Common/b2Draw.h>
  33. #include <Box2D/Common/b2Timer.h>
  34. #include <new>
  35. b2World::b2World(const b2Vec2& gravity, bool doSleep)
  36. {
  37. m_destructionListener = NULL;
  38. m_debugDraw = NULL;
  39. m_bodyList = NULL;
  40. m_jointList = NULL;
  41. m_bodyCount = 0;
  42. m_jointCount = 0;
  43. m_warmStarting = true;
  44. m_continuousPhysics = true;
  45. m_subStepping = false;
  46. m_stepComplete = true;
  47. m_allowSleep = doSleep;
  48. m_gravity = gravity;
  49. m_flags = e_clearForces;
  50. m_inv_dt0 = 0.0f;
  51. m_contactManager.m_allocator = &m_blockAllocator;
  52. memset(&m_profile, 0, sizeof(b2Profile));
  53. }
  54. b2World::~b2World()
  55. {
  56. // Some shapes allocate using b2Alloc.
  57. b2Body* b = m_bodyList;
  58. while (b)
  59. {
  60. b2Body* bNext = b->m_next;
  61. b2Fixture* f = b->m_fixtureList;
  62. while (f)
  63. {
  64. b2Fixture* fNext = f->m_next;
  65. f->m_proxyCount = 0;
  66. f->Destroy(&m_blockAllocator);
  67. f = fNext;
  68. }
  69. b = bNext;
  70. }
  71. }
  72. void b2World::SetDestructionListener(b2DestructionListener* listener)
  73. {
  74. m_destructionListener = listener;
  75. }
  76. void b2World::SetContactFilter(b2ContactFilter* filter)
  77. {
  78. m_contactManager.m_contactFilter = filter;
  79. }
  80. void b2World::SetContactListener(b2ContactListener* listener)
  81. {
  82. m_contactManager.m_contactListener = listener;
  83. }
  84. void b2World::SetDebugDraw(b2Draw* debugDraw)
  85. {
  86. m_debugDraw = debugDraw;
  87. }
  88. b2Body* b2World::CreateBody(const b2BodyDef* def)
  89. {
  90. b2Assert(IsLocked() == false);
  91. if (IsLocked())
  92. {
  93. return NULL;
  94. }
  95. void* mem = m_blockAllocator.Allocate(sizeof(b2Body));
  96. b2Body* b = new (mem) b2Body(def, this);
  97. // Add to world doubly linked list.
  98. b->m_prev = NULL;
  99. b->m_next = m_bodyList;
  100. if (m_bodyList)
  101. {
  102. m_bodyList->m_prev = b;
  103. }
  104. m_bodyList = b;
  105. ++m_bodyCount;
  106. return b;
  107. }
  108. void b2World::DestroyBody(b2Body* b)
  109. {
  110. b2Assert(m_bodyCount > 0);
  111. b2Assert(IsLocked() == false);
  112. if (IsLocked())
  113. {
  114. return;
  115. }
  116. // Delete the attached joints.
  117. b2JointEdge* je = b->m_jointList;
  118. while (je)
  119. {
  120. b2JointEdge* je0 = je;
  121. je = je->next;
  122. if (m_destructionListener)
  123. {
  124. m_destructionListener->SayGoodbye(je0->joint);
  125. }
  126. DestroyJoint(je0->joint);
  127. b->m_jointList = je;
  128. }
  129. b->m_jointList = NULL;
  130. // Delete the attached contacts.
  131. b2ContactEdge* ce = b->m_contactList;
  132. while (ce)
  133. {
  134. b2ContactEdge* ce0 = ce;
  135. ce = ce->next;
  136. m_contactManager.Destroy(ce0->contact);
  137. }
  138. b->m_contactList = NULL;
  139. // Delete the attached fixtures. This destroys broad-phase proxies.
  140. b2Fixture* f = b->m_fixtureList;
  141. while (f)
  142. {
  143. b2Fixture* f0 = f;
  144. f = f->m_next;
  145. if (m_destructionListener)
  146. {
  147. m_destructionListener->SayGoodbye(f0);
  148. }
  149. f0->DestroyProxies(&m_contactManager.m_broadPhase);
  150. f0->Destroy(&m_blockAllocator);
  151. f0->~b2Fixture();
  152. m_blockAllocator.Free(f0, sizeof(b2Fixture));
  153. b->m_fixtureList = f;
  154. b->m_fixtureCount -= 1;
  155. }
  156. b->m_fixtureList = NULL;
  157. b->m_fixtureCount = 0;
  158. // Remove world body list.
  159. if (b->m_prev)
  160. {
  161. b->m_prev->m_next = b->m_next;
  162. }
  163. if (b->m_next)
  164. {
  165. b->m_next->m_prev = b->m_prev;
  166. }
  167. if (b == m_bodyList)
  168. {
  169. m_bodyList = b->m_next;
  170. }
  171. --m_bodyCount;
  172. b->~b2Body();
  173. m_blockAllocator.Free(b, sizeof(b2Body));
  174. }
  175. b2Joint* b2World::CreateJoint(const b2JointDef* def)
  176. {
  177. b2Assert(IsLocked() == false);
  178. if (IsLocked())
  179. {
  180. return NULL;
  181. }
  182. b2Joint* j = b2Joint::Create(def, &m_blockAllocator);
  183. // Connect to the world list.
  184. j->m_prev = NULL;
  185. j->m_next = m_jointList;
  186. if (m_jointList)
  187. {
  188. m_jointList->m_prev = j;
  189. }
  190. m_jointList = j;
  191. ++m_jointCount;
  192. // Connect to the bodies' doubly linked lists.
  193. j->m_edgeA.joint = j;
  194. j->m_edgeA.other = j->m_bodyB;
  195. j->m_edgeA.prev = NULL;
  196. j->m_edgeA.next = j->m_bodyA->m_jointList;
  197. if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA;
  198. j->m_bodyA->m_jointList = &j->m_edgeA;
  199. j->m_edgeB.joint = j;
  200. j->m_edgeB.other = j->m_bodyA;
  201. j->m_edgeB.prev = NULL;
  202. j->m_edgeB.next = j->m_bodyB->m_jointList;
  203. if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB;
  204. j->m_bodyB->m_jointList = &j->m_edgeB;
  205. b2Body* bodyA = def->bodyA;
  206. b2Body* bodyB = def->bodyB;
  207. // If the joint prevents collisions, then flag any contacts for filtering.
  208. if (def->collideConnected == false)
  209. {
  210. b2ContactEdge* edge = bodyB->GetContactList();
  211. while (edge)
  212. {
  213. if (edge->other == bodyA)
  214. {
  215. // Flag the contact for filtering at the next time step (where either
  216. // body is awake).
  217. edge->contact->FlagForFiltering();
  218. }
  219. edge = edge->next;
  220. }
  221. }
  222. // Note: creating a joint doesn't wake the bodies.
  223. return j;
  224. }
  225. void b2World::DestroyJoint(b2Joint* j)
  226. {
  227. b2Assert(IsLocked() == false);
  228. if (IsLocked())
  229. {
  230. return;
  231. }
  232. bool collideConnected = j->m_collideConnected;
  233. // Remove from the doubly linked list.
  234. if (j->m_prev)
  235. {
  236. j->m_prev->m_next = j->m_next;
  237. }
  238. if (j->m_next)
  239. {
  240. j->m_next->m_prev = j->m_prev;
  241. }
  242. if (j == m_jointList)
  243. {
  244. m_jointList = j->m_next;
  245. }
  246. // Disconnect from island graph.
  247. b2Body* bodyA = j->m_bodyA;
  248. b2Body* bodyB = j->m_bodyB;
  249. // Wake up connected bodies.
  250. bodyA->SetAwake(true);
  251. bodyB->SetAwake(true);
  252. // Remove from body 1.
  253. if (j->m_edgeA.prev)
  254. {
  255. j->m_edgeA.prev->next = j->m_edgeA.next;
  256. }
  257. if (j->m_edgeA.next)
  258. {
  259. j->m_edgeA.next->prev = j->m_edgeA.prev;
  260. }
  261. if (&j->m_edgeA == bodyA->m_jointList)
  262. {
  263. bodyA->m_jointList = j->m_edgeA.next;
  264. }
  265. j->m_edgeA.prev = NULL;
  266. j->m_edgeA.next = NULL;
  267. // Remove from body 2
  268. if (j->m_edgeB.prev)
  269. {
  270. j->m_edgeB.prev->next = j->m_edgeB.next;
  271. }
  272. if (j->m_edgeB.next)
  273. {
  274. j->m_edgeB.next->prev = j->m_edgeB.prev;
  275. }
  276. if (&j->m_edgeB == bodyB->m_jointList)
  277. {
  278. bodyB->m_jointList = j->m_edgeB.next;
  279. }
  280. j->m_edgeB.prev = NULL;
  281. j->m_edgeB.next = NULL;
  282. b2Joint::Destroy(j, &m_blockAllocator);
  283. b2Assert(m_jointCount > 0);
  284. --m_jointCount;
  285. // If the joint prevents collisions, then flag any contacts for filtering.
  286. if (collideConnected == false)
  287. {
  288. b2ContactEdge* edge = bodyB->GetContactList();
  289. while (edge)
  290. {
  291. if (edge->other == bodyA)
  292. {
  293. // Flag the contact for filtering at the next time step (where either
  294. // body is awake).
  295. edge->contact->FlagForFiltering();
  296. }
  297. edge = edge->next;
  298. }
  299. }
  300. }
  301. // Find islands, integrate and solve constraints, solve position constraints
  302. void b2World::Solve(const b2TimeStep& step)
  303. {
  304. m_profile.solveInit = 0.0f;
  305. m_profile.solveVelocity = 0.0f;
  306. m_profile.solvePosition = 0.0f;
  307. // Size the island for the worst case.
  308. b2Island island(m_bodyCount,
  309. m_contactManager.m_contactCount,
  310. m_jointCount,
  311. &m_stackAllocator,
  312. m_contactManager.m_contactListener);
  313. // Clear all the island flags.
  314. for (b2Body* b = m_bodyList; b; b = b->m_next)
  315. {
  316. b->m_flags &= ~b2Body::e_islandFlag;
  317. }
  318. for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  319. {
  320. c->m_flags &= ~b2Contact::e_islandFlag;
  321. }
  322. for (b2Joint* j = m_jointList; j; j = j->m_next)
  323. {
  324. j->m_islandFlag = false;
  325. }
  326. // Build and simulate all awake islands.
  327. int32 stackSize = m_bodyCount;
  328. b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*));
  329. for (b2Body* seed = m_bodyList; seed; seed = seed->m_next)
  330. {
  331. if (seed->m_flags & b2Body::e_islandFlag)
  332. {
  333. continue;
  334. }
  335. if (seed->IsAwake() == false || seed->IsActive() == false)
  336. {
  337. continue;
  338. }
  339. // The seed can be dynamic or kinematic.
  340. if (seed->GetType() == b2_staticBody)
  341. {
  342. continue;
  343. }
  344. // Reset island and stack.
  345. island.Clear();
  346. int32 stackCount = 0;
  347. stack[stackCount++] = seed;
  348. seed->m_flags |= b2Body::e_islandFlag;
  349. // Perform a depth first search (DFS) on the constraint graph.
  350. while (stackCount > 0)
  351. {
  352. // Grab the next body off the stack and add it to the island.
  353. b2Body* b = stack[--stackCount];
  354. b2Assert(b->IsActive() == true);
  355. island.Add(b);
  356. // Make sure the body is awake.
  357. b->SetAwake(true);
  358. // To keep islands as small as possible, we don't
  359. // propagate islands across static bodies.
  360. if (b->GetType() == b2_staticBody)
  361. {
  362. continue;
  363. }
  364. // Search all contacts connected to this body.
  365. for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next)
  366. {
  367. b2Contact* contact = ce->contact;
  368. // Has this contact already been added to an island?
  369. if (contact->m_flags & b2Contact::e_islandFlag)
  370. {
  371. continue;
  372. }
  373. // Is this contact solid and touching?
  374. if (contact->IsEnabled() == false ||
  375. contact->IsTouching() == false)
  376. {
  377. continue;
  378. }
  379. // Skip sensors.
  380. bool sensorA = contact->m_fixtureA->m_isSensor;
  381. bool sensorB = contact->m_fixtureB->m_isSensor;
  382. if (sensorA || sensorB)
  383. {
  384. continue;
  385. }
  386. island.Add(contact);
  387. contact->m_flags |= b2Contact::e_islandFlag;
  388. b2Body* other = ce->other;
  389. // Was the other body already added to this island?
  390. if (other->m_flags & b2Body::e_islandFlag)
  391. {
  392. continue;
  393. }
  394. b2Assert(stackCount < stackSize);
  395. stack[stackCount++] = other;
  396. other->m_flags |= b2Body::e_islandFlag;
  397. }
  398. // Search all joints connect to this body.
  399. for (b2JointEdge* je = b->m_jointList; je; je = je->next)
  400. {
  401. if (je->joint->m_islandFlag == true)
  402. {
  403. continue;
  404. }
  405. b2Body* other = je->other;
  406. // Don't simulate joints connected to inactive bodies.
  407. if (other->IsActive() == false)
  408. {
  409. continue;
  410. }
  411. island.Add(je->joint);
  412. je->joint->m_islandFlag = true;
  413. if (other->m_flags & b2Body::e_islandFlag)
  414. {
  415. continue;
  416. }
  417. b2Assert(stackCount < stackSize);
  418. stack[stackCount++] = other;
  419. other->m_flags |= b2Body::e_islandFlag;
  420. }
  421. }
  422. b2Profile profile;
  423. island.Solve(&profile, step, m_gravity, m_allowSleep);
  424. m_profile.solveInit += profile.solveInit;
  425. m_profile.solveVelocity += profile.solveVelocity;
  426. m_profile.solvePosition += profile.solvePosition;
  427. // Post solve cleanup.
  428. for (int32 i = 0; i < island.m_bodyCount; ++i)
  429. {
  430. // Allow static bodies to participate in other islands.
  431. b2Body* b = island.m_bodies[i];
  432. if (b->GetType() == b2_staticBody)
  433. {
  434. b->m_flags &= ~b2Body::e_islandFlag;
  435. }
  436. }
  437. }
  438. m_stackAllocator.Free(stack);
  439. {
  440. b2Timer timer;
  441. // Synchronize fixtures, check for out of range bodies.
  442. for (b2Body* b = m_bodyList; b; b = b->GetNext())
  443. {
  444. // If a body was not in an island then it did not move.
  445. if ((b->m_flags & b2Body::e_islandFlag) == 0)
  446. {
  447. continue;
  448. }
  449. if (b->GetType() == b2_staticBody)
  450. {
  451. continue;
  452. }
  453. // Update fixtures (for broad-phase).
  454. b->SynchronizeFixtures();
  455. }
  456. // Look for new contacts.
  457. m_contactManager.FindNewContacts();
  458. m_profile.broadphase = timer.GetMilliseconds();
  459. }
  460. }
  461. // Find TOI contacts and solve them.
  462. void b2World::SolveTOI(const b2TimeStep& step)
  463. {
  464. b2Island island(2 * b2_maxTOIContacts, b2_maxTOIContacts, 0, &m_stackAllocator, m_contactManager.m_contactListener);
  465. if (m_stepComplete)
  466. {
  467. for (b2Body* b = m_bodyList; b; b = b->m_next)
  468. {
  469. b->m_flags &= ~b2Body::e_islandFlag;
  470. b->m_sweep.alpha0 = 0.0f;
  471. }
  472. for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  473. {
  474. // Invalidate TOI
  475. c->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
  476. c->m_toiCount = 0;
  477. c->m_toi = 1.0f;
  478. }
  479. }
  480. // Find TOI events and solve them.
  481. for (;;)
  482. {
  483. // Find the first TOI.
  484. b2Contact* minContact = NULL;
  485. float32 minAlpha = 1.0f;
  486. for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
  487. {
  488. // Is this contact disabled?
  489. if (c->IsEnabled() == false)
  490. {
  491. continue;
  492. }
  493. // Prevent excessive sub-stepping.
  494. if (c->m_toiCount > b2_maxSubSteps)
  495. {
  496. continue;
  497. }
  498. float32 alpha = 1.0f;
  499. if (c->m_flags & b2Contact::e_toiFlag)
  500. {
  501. // This contact has a valid cached TOI.
  502. alpha = c->m_toi;
  503. }
  504. else
  505. {
  506. b2Fixture* fA = c->GetFixtureA();
  507. b2Fixture* fB = c->GetFixtureB();
  508. // Is there a sensor?
  509. if (fA->IsSensor() || fB->IsSensor())
  510. {
  511. continue;
  512. }
  513. b2Body* bA = fA->GetBody();
  514. b2Body* bB = fB->GetBody();
  515. b2BodyType typeA = bA->m_type;
  516. b2BodyType typeB = bB->m_type;
  517. b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody);
  518. bool activeA = bA->IsAwake() && typeA != b2_staticBody;
  519. bool activeB = bB->IsAwake() && typeB != b2_staticBody;
  520. // Is at least one body active (awake and dynamic or kinematic)?
  521. if (activeA == false && activeB == false)
  522. {
  523. continue;
  524. }
  525. bool collideA = bA->IsBullet() || typeA != b2_dynamicBody;
  526. bool collideB = bB->IsBullet() || typeB != b2_dynamicBody;
  527. // Are these two non-bullet dynamic bodies?
  528. if (collideA == false && collideB == false)
  529. {
  530. continue;
  531. }
  532. // Compute the TOI for this contact.
  533. // Put the sweeps onto the same time interval.
  534. float32 alpha0 = bA->m_sweep.alpha0;
  535. if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0)
  536. {
  537. alpha0 = bB->m_sweep.alpha0;
  538. bA->m_sweep.Advance(alpha0);
  539. }
  540. else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0)
  541. {
  542. alpha0 = bA->m_sweep.alpha0;
  543. bB->m_sweep.Advance(alpha0);
  544. }
  545. b2Assert(alpha0 < 1.0f);
  546. int32 indexA = c->GetChildIndexA();
  547. int32 indexB = c->GetChildIndexB();
  548. // Compute the time of impact in interval [0, minTOI]
  549. b2TOIInput input;
  550. input.proxyA.Set(fA->GetShape(), indexA);
  551. input.proxyB.Set(fB->GetShape(), indexB);
  552. input.sweepA = bA->m_sweep;
  553. input.sweepB = bB->m_sweep;
  554. input.tMax = 1.0f;
  555. b2TOIOutput output;
  556. b2TimeOfImpact(&output, &input);
  557. // Beta is the fraction of the remaining portion of the .
  558. float32 beta = output.t;
  559. if (output.state == b2TOIOutput::e_touching)
  560. {
  561. alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
  562. }
  563. else
  564. {
  565. alpha = 1.0f;
  566. }
  567. c->m_toi = alpha;
  568. c->m_flags |= b2Contact::e_toiFlag;
  569. }
  570. if (alpha < minAlpha)
  571. {
  572. // This is the minimum TOI found so far.
  573. minContact = c;
  574. minAlpha = alpha;
  575. }
  576. }
  577. if (minContact == NULL || 1.0f - 10.0f * b2_epsilon < minAlpha)
  578. {
  579. // No more TOI events. Done!
  580. m_stepComplete = true;
  581. break;
  582. }
  583. // Advance the bodies to the TOI.
  584. b2Fixture* fA = minContact->GetFixtureA();
  585. b2Fixture* fB = minContact->GetFixtureB();
  586. b2Body* bA = fA->GetBody();
  587. b2Body* bB = fB->GetBody();
  588. b2Sweep backup1 = bA->m_sweep;
  589. b2Sweep backup2 = bB->m_sweep;
  590. bA->Advance(minAlpha);
  591. bB->Advance(minAlpha);
  592. // The TOI contact likely has some new contact points.
  593. minContact->Update(m_contactManager.m_contactListener);
  594. minContact->m_flags &= ~b2Contact::e_toiFlag;
  595. ++minContact->m_toiCount;
  596. // Is the contact solid?
  597. if (minContact->IsEnabled() == false || minContact->IsTouching() == false)
  598. {
  599. // Restore the sweeps.
  600. minContact->SetEnabled(false);
  601. bA->m_sweep = backup1;
  602. bB->m_sweep = backup2;
  603. bA->SynchronizeTransform();
  604. bB->SynchronizeTransform();
  605. continue;
  606. }
  607. bA->SetAwake(true);
  608. bB->SetAwake(true);
  609. // Build the island
  610. island.Clear();
  611. island.Add(bA);
  612. island.Add(bB);
  613. island.Add(minContact);
  614. bA->m_flags |= b2Body::e_islandFlag;
  615. bB->m_flags |= b2Body::e_islandFlag;
  616. minContact->m_flags |= b2Contact::e_islandFlag;
  617. // Get contacts on bodyA and bodyB.
  618. b2Body* bodies[2] = {bA, bB};
  619. for (int32 i = 0; i < 2; ++i)
  620. {
  621. b2Body* body = bodies[i];
  622. if (body->m_type == b2_dynamicBody)
  623. {
  624. for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
  625. {
  626. if (island.m_bodyCount == island.m_bodyCapacity)
  627. {
  628. break;
  629. }
  630. if (island.m_contactCount == island.m_contactCapacity)
  631. {
  632. break;
  633. }
  634. b2Contact* contact = ce->contact;
  635. // Has this contact already been added to the island?
  636. if (contact->m_flags & b2Contact::e_islandFlag)
  637. {
  638. continue;
  639. }
  640. // Only add static, kinematic, or bullet bodies.
  641. b2Body* other = ce->other;
  642. if (other->m_type == b2_dynamicBody &&
  643. body->IsBullet() == false && other->IsBullet() == false)
  644. {
  645. continue;
  646. }
  647. // Skip sensors.
  648. bool sensorA = contact->m_fixtureA->m_isSensor;
  649. bool sensorB = contact->m_fixtureB->m_isSensor;
  650. if (sensorA || sensorB)
  651. {
  652. continue;
  653. }
  654. // Tentatively advance the body to the TOI.
  655. b2Sweep backup = other->m_sweep;
  656. if ((other->m_flags & b2Body::e_islandFlag) == 0)
  657. {
  658. other->Advance(minAlpha);
  659. }
  660. // Update the contact points
  661. contact->Update(m_contactManager.m_contactListener);
  662. // Was the contact disabled by the user?
  663. if (contact->IsEnabled() == false)
  664. {
  665. other->m_sweep = backup;
  666. other->SynchronizeTransform();
  667. continue;
  668. }
  669. // Are there contact points?
  670. if (contact->IsTouching() == false)
  671. {
  672. other->m_sweep = backup;
  673. other->SynchronizeTransform();
  674. continue;
  675. }
  676. // Add the contact to the island
  677. contact->m_flags |= b2Contact::e_islandFlag;
  678. island.Add(contact);
  679. // Has the other body already been added to the island?
  680. if (other->m_flags & b2Body::e_islandFlag)
  681. {
  682. continue;
  683. }
  684. // Add the other body to the island.
  685. other->m_flags |= b2Body::e_islandFlag;
  686. if (other->m_type != b2_staticBody)
  687. {
  688. other->SetAwake(true);
  689. }
  690. island.Add(other);
  691. }
  692. }
  693. }
  694. b2TimeStep subStep;
  695. subStep.dt = (1.0f - minAlpha) * step.dt;
  696. subStep.inv_dt = 1.0f / subStep.dt;
  697. subStep.dtRatio = 1.0f;
  698. subStep.positionIterations = 20;
  699. subStep.velocityIterations = step.velocityIterations;
  700. subStep.warmStarting = false;
  701. island.SolveTOI(subStep, bA->m_islandIndex, bB->m_islandIndex);
  702. // Reset island flags and synchronize broad-phase proxies.
  703. for (int32 i = 0; i < island.m_bodyCount; ++i)
  704. {
  705. b2Body* body = island.m_bodies[i];
  706. body->m_flags &= ~b2Body::e_islandFlag;
  707. if (body->m_type != b2_dynamicBody)
  708. {
  709. continue;
  710. }
  711. body->SynchronizeFixtures();
  712. // Invalidate all contact TOIs on this displaced body.
  713. for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
  714. {
  715. ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
  716. }
  717. }
  718. // Commit fixture proxy movements to the broad-phase so that new contacts are created.
  719. // Also, some contacts can be destroyed.
  720. m_contactManager.FindNewContacts();
  721. if (m_subStepping)
  722. {
  723. m_stepComplete = false;
  724. break;
  725. }
  726. }
  727. }
  728. void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations)
  729. {
  730. b2Timer stepTimer;
  731. // If new fixtures were added, we need to find the new contacts.
  732. if (m_flags & e_newFixture)
  733. {
  734. m_contactManager.FindNewContacts();
  735. m_flags &= ~e_newFixture;
  736. }
  737. m_flags |= e_locked;
  738. b2TimeStep step;
  739. step.dt = dt;
  740. step.velocityIterations = velocityIterations;
  741. step.positionIterations = positionIterations;
  742. if (dt > 0.0f)
  743. {
  744. step.inv_dt = 1.0f / dt;
  745. }
  746. else
  747. {
  748. step.inv_dt = 0.0f;
  749. }
  750. step.dtRatio = m_inv_dt0 * dt;
  751. step.warmStarting = m_warmStarting;
  752. // Update contacts. This is where some contacts are destroyed.
  753. {
  754. b2Timer timer;
  755. m_contactManager.Collide();
  756. m_profile.collide = timer.GetMilliseconds();
  757. }
  758. // Integrate velocities, solve velocity constraints, and integrate positions.
  759. if (m_stepComplete && step.dt > 0.0f)
  760. {
  761. b2Timer timer;
  762. Solve(step);
  763. m_profile.solve = timer.GetMilliseconds();
  764. }
  765. // Handle TOI events.
  766. if (m_continuousPhysics && step.dt > 0.0f)
  767. {
  768. b2Timer timer;
  769. SolveTOI(step);
  770. m_profile.solveTOI = timer.GetMilliseconds();
  771. }
  772. if (step.dt > 0.0f)
  773. {
  774. m_inv_dt0 = step.inv_dt;
  775. }
  776. if (m_flags & e_clearForces)
  777. {
  778. ClearForces();
  779. }
  780. m_flags &= ~e_locked;
  781. m_profile.step = stepTimer.GetMilliseconds();
  782. }
  783. void b2World::ClearForces()
  784. {
  785. for (b2Body* body = m_bodyList; body; body = body->GetNext())
  786. {
  787. body->m_force.SetZero();
  788. body->m_torque = 0.0f;
  789. }
  790. }
  791. struct b2WorldQueryWrapper
  792. {
  793. bool QueryCallback(int32 proxyId)
  794. {
  795. b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId);
  796. return callback->ReportFixture(proxy->fixture);
  797. }
  798. const b2BroadPhase* broadPhase;
  799. b2QueryCallback* callback;
  800. };
  801. void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const
  802. {
  803. b2WorldQueryWrapper wrapper;
  804. wrapper.broadPhase = &m_contactManager.m_broadPhase;
  805. wrapper.callback = callback;
  806. m_contactManager.m_broadPhase.Query(&wrapper, aabb);
  807. }
  808. struct b2WorldRayCastWrapper
  809. {
  810. float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
  811. {
  812. void* userData = broadPhase->GetUserData(proxyId);
  813. b2FixtureProxy* proxy = (b2FixtureProxy*)userData;
  814. b2Fixture* fixture = proxy->fixture;
  815. int32 index = proxy->childIndex;
  816. b2RayCastOutput output;
  817. bool hit = fixture->RayCast(&output, input, index);
  818. if (hit)
  819. {
  820. float32 fraction = output.fraction;
  821. b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
  822. return callback->ReportFixture(fixture, point, output.normal, fraction);
  823. }
  824. return input.maxFraction;
  825. }
  826. const b2BroadPhase* broadPhase;
  827. b2RayCastCallback* callback;
  828. };
  829. void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
  830. {
  831. b2WorldRayCastWrapper wrapper;
  832. wrapper.broadPhase = &m_contactManager.m_broadPhase;
  833. wrapper.callback = callback;
  834. b2RayCastInput input;
  835. input.maxFraction = 1.0f;
  836. input.p1 = point1;
  837. input.p2 = point2;
  838. m_contactManager.m_broadPhase.RayCast(&wrapper, input);
  839. }
  840. void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color)
  841. {
  842. switch (fixture->GetType())
  843. {
  844. case b2Shape::e_circle:
  845. {
  846. b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
  847. b2Vec2 center = b2Mul(xf, circle->m_p);
  848. float32 radius = circle->m_radius;
  849. b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f));
  850. m_debugDraw->DrawSolidCircle(center, radius, axis, color);
  851. }
  852. break;
  853. case b2Shape::e_edge:
  854. {
  855. b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
  856. b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
  857. b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
  858. m_debugDraw->DrawSegment(v1, v2, color);
  859. }
  860. break;
  861. case b2Shape::e_loop:
  862. {
  863. b2LoopShape* loop = (b2LoopShape*)fixture->GetShape();
  864. int32 count = loop->GetCount();
  865. const b2Vec2* vertices = loop->GetVertices();
  866. b2Vec2 v1 = b2Mul(xf, vertices[count - 1]);
  867. for (int32 i = 0; i < count; ++i)
  868. {
  869. b2Vec2 v2 = b2Mul(xf, vertices[i]);
  870. m_debugDraw->DrawSegment(v1, v2, color);
  871. m_debugDraw->DrawCircle(v1, 0.05f, color);
  872. v1 = v2;
  873. }
  874. }
  875. break;
  876. case b2Shape::e_polygon:
  877. {
  878. b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
  879. int32 vertexCount = poly->m_vertexCount;
  880. b2Assert(vertexCount <= b2_maxPolygonVertices);
  881. b2Vec2 vertices[b2_maxPolygonVertices];
  882. for (int32 i = 0; i < vertexCount; ++i)
  883. {
  884. vertices[i] = b2Mul(xf, poly->m_vertices[i]);
  885. }
  886. m_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
  887. }
  888. break;
  889. }
  890. }
  891. void b2World::DrawJoint(b2Joint* joint)
  892. {
  893. b2Body* bodyA = joint->GetBodyA();
  894. b2Body* bodyB = joint->GetBodyB();
  895. const b2Transform& xf1 = bodyA->GetTransform();
  896. const b2Transform& xf2 = bodyB->GetTransform();
  897. b2Vec2 x1 = xf1.p;
  898. b2Vec2 x2 = xf2.p;
  899. b2Vec2 p1 = joint->GetAnchorA();
  900. b2Vec2 p2 = joint->GetAnchorB();
  901. b2Color color(0.5f, 0.8f, 0.8f);
  902. switch (joint->GetType())
  903. {
  904. case e_distanceJoint:
  905. m_debugDraw->DrawSegment(p1, p2, color);
  906. break;
  907. case e_pulleyJoint:
  908. {
  909. b2PulleyJoint* pulley = (b2PulleyJoint*)joint;
  910. b2Vec2 s1 = pulley->GetGroundAnchorA();
  911. b2Vec2 s2 = pulley->GetGroundAnchorB();
  912. m_debugDraw->DrawSegment(s1, p1, color);
  913. m_debugDraw->DrawSegment(s2, p2, color);
  914. m_debugDraw->DrawSegment(s1, s2, color);
  915. }
  916. break;
  917. case e_mouseJoint:
  918. // don't draw this
  919. break;
  920. default:
  921. m_debugDraw->DrawSegment(x1, p1, color);
  922. m_debugDraw->DrawSegment(p1, p2, color);
  923. m_debugDraw->DrawSegment(x2, p2, color);
  924. }
  925. }
  926. void b2World::DrawDebugData()
  927. {
  928. if (m_debugDraw == NULL)
  929. {
  930. return;
  931. }
  932. uint32 flags = m_debugDraw->GetFlags();
  933. if (flags & b2Draw::e_shapeBit)
  934. {
  935. for (b2Body* b = m_bodyList; b; b = b->GetNext())
  936. {
  937. const b2Transform& xf = b->GetTransform();
  938. for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
  939. {
  940. if (b->IsActive() == false)
  941. {
  942. DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f));
  943. }
  944. else if (b->GetType() == b2_staticBody)
  945. {
  946. DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f));
  947. }
  948. else if (b->GetType() == b2_kinematicBody)
  949. {
  950. DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f));
  951. }
  952. else if (b->IsAwake() == false)
  953. {
  954. DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f));
  955. }
  956. else
  957. {
  958. DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f));
  959. }
  960. }
  961. }
  962. }
  963. if (flags & b2Draw::e_jointBit)
  964. {
  965. for (b2Joint* j = m_jointList; j; j = j->GetNext())
  966. {
  967. DrawJoint(j);
  968. }
  969. }
  970. if (flags & b2Draw::e_pairBit)
  971. {
  972. b2Color color(0.3f, 0.9f, 0.9f);
  973. for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext())
  974. {
  975. //b2Fixture* fixtureA = c->GetFixtureA();
  976. //b2Fixture* fixtureB = c->GetFixtureB();
  977. //b2Vec2 cA = fixtureA->GetAABB().GetCenter();
  978. //b2Vec2 cB = fixtureB->GetAABB().GetCenter();
  979. //m_debugDraw->DrawSegment(cA, cB, color);
  980. }
  981. }
  982. if (flags & b2Draw::e_aabbBit)
  983. {
  984. b2Color color(0.9f, 0.3f, 0.9f);
  985. b2BroadPhase* bp = &m_contactManager.m_broadPhase;
  986. for (b2Body* b = m_bodyList; b; b = b->GetNext())
  987. {
  988. if (b->IsActive() == false)
  989. {
  990. continue;
  991. }
  992. for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
  993. {
  994. for (int32 i = 0; i < f->m_proxyCount; ++i)
  995. {
  996. b2FixtureProxy* proxy = f->m_proxies + i;
  997. b2AABB aabb = bp->GetFatAABB(proxy->proxyId);
  998. b2Vec2 vs[4];
  999. vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
  1000. vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
  1001. vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
  1002. vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
  1003. m_debugDraw->DrawPolygon(vs, 4, color);
  1004. }
  1005. }
  1006. }
  1007. }
  1008. if (flags & b2Draw::e_centerOfMassBit)
  1009. {
  1010. for (b2Body* b = m_bodyList; b; b = b->GetNext())
  1011. {
  1012. b2Transform xf = b->GetTransform();
  1013. xf.p = b->GetWorldCenter();
  1014. m_debugDraw->DrawTransform(xf);
  1015. }
  1016. }
  1017. }
  1018. int32 b2World::GetProxyCount() const
  1019. {
  1020. return m_contactManager.m_broadPhase.GetProxyCount();
  1021. }
  1022. int32 b2World::GetTreeHeight() const
  1023. {
  1024. return m_contactManager.m_broadPhase.GetTreeHeight();
  1025. }
  1026. int32 b2World::GetTreeBalance() const
  1027. {
  1028. return m_contactManager.m_broadPhase.GetTreeBalance();
  1029. }
  1030. float32 b2World::GetTreeQuality() const
  1031. {
  1032. return m_contactManager.m_broadPhase.GetTreeQuality();
  1033. }