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