Skip to content

Commit 116c49b

Browse files
committed
refactoring continues
1 parent a1b3cc8 commit 116c49b

3 files changed

Lines changed: 144 additions & 119 deletions

File tree

src/Box2D_Helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace box2d
3131
}
3232
};
3333

34-
34+
// vectors
3535
static const vec2 NullVector { 0.0f, 0.0f };
3636
static const vec2 ForwardVector (1.0f, 0.0f);
3737
static const vec2 LateralVector (0.0f, 1.0f);

src/PhysicsManager.cpp

Lines changed: 135 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@ static_assert(sizeof(b2FixtureData_map) <= sizeof(void*), "Cannot pack data into
2828

2929
//////////////////////////////////////////////////////////////////////////
3030

31+
// choose fixture by category bits (any of it)
32+
inline b2Fixture* FilterFixture(b2Fixture* fixtureA, b2Fixture* fixtureB, unsigned short categoryBits)
33+
{
34+
if ((fixtureA->GetFilterData().categoryBits & categoryBits) > 0)
35+
return fixtureA;
36+
37+
if ((fixtureB->GetFilterData().categoryBits & categoryBits) > 0)
38+
return fixtureB;
39+
40+
return nullptr;
41+
}
42+
43+
template<typename TUserDataClass>
44+
inline TUserDataClass* CastBodyData(b2Body* physicsBody)
45+
{
46+
debug_assert(physicsBody);
47+
48+
void* userdata = physicsBody->GetUserData();
49+
debug_assert(userdata);
50+
51+
return (TUserDataClass*) userdata;
52+
}
53+
54+
//////////////////////////////////////////////////////////////////////////
55+
3156
PhysicsManager gPhysics;
3257

3358
PhysicsManager::PhysicsManager()
@@ -271,89 +296,107 @@ void PhysicsManager::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
271296
b2Fixture* fixtureA = contact->GetFixtureA();
272297
b2Fixture* fixtureB = contact->GetFixtureB();
273298

274-
b2Fixture* fixtureMapSolidBlock = nullptr;
275-
b2Fixture* fixturePed = nullptr;
276-
b2Fixture* fixtureCar = nullptr;
277-
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_MAP_SOLID_BLOCK)
278-
{
279-
fixtureMapSolidBlock = fixtureA;
280-
}
281-
if (fixtureB->GetFilterData().categoryBits == PHYSICS_OBJCAT_MAP_SOLID_BLOCK)
282-
{
283-
fixtureMapSolidBlock = fixtureB;
284-
}
285-
286-
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_PED)
287-
{
288-
fixturePed = fixtureA;
289-
}
290-
if (fixtureB->GetFilterData().categoryBits == PHYSICS_OBJCAT_PED)
291-
{
292-
fixturePed = fixtureB;
293-
}
294-
295-
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_CAR)
296-
{
297-
fixtureCar = fixtureA;
298-
}
299-
if (fixtureB->GetFilterData().categoryBits == PHYSICS_OBJCAT_CAR)
300-
{
301-
fixtureCar = fixtureB;
302-
}
303-
304299
bool hasCollision = true;
305-
for (;;)
300+
if (fixtureA->GetFilterData().categoryBits ==
301+
fixtureB->GetFilterData().categoryBits)
306302
{
307-
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_PED &&
308-
fixtureB->GetFilterData().categoryBits == PHYSICS_OBJCAT_PED)
303+
// ped vs ped
304+
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_PED)
309305
{
310-
PedPhysicsComponent* physicsComponentA = (PedPhysicsComponent*) fixtureA->GetBody()->GetUserData();
311-
PedPhysicsComponent* physicsComponentB = (PedPhysicsComponent*) fixtureB->GetBody()->GetUserData();
312-
hasCollision = CollidePedVsPed(contact, physicsComponentA, physicsComponentB);
306+
PedPhysicsComponent* physicsComponentA = CastBodyData<PedPhysicsComponent>(fixtureA->GetBody());
307+
PedPhysicsComponent* physicsComponentB = CastBodyData<PedPhysicsComponent>(fixtureB->GetBody());
308+
hasCollision = HasCollisionPedVsPed(contact, physicsComponentA, physicsComponentB);
313309
}
314-
315-
if (hasCollision && fixturePed)
310+
// car vs car
311+
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_CAR)
316312
{
317-
PedPhysicsComponent* physicsComponent = (PedPhysicsComponent*) fixturePed->GetBody()->GetUserData();
318-
debug_assert(physicsComponent);
319-
320-
hasCollision = physicsComponent->ShouldCollideWith((fixtureA != fixturePed ? fixtureA : fixtureB)->GetFilterData().categoryBits);
313+
CarPhysicsComponent* physicsComponentA = CastBodyData<CarPhysicsComponent>(fixtureA->GetBody());
314+
CarPhysicsComponent* physicsComponentB = CastBodyData<CarPhysicsComponent>(fixtureB->GetBody());
315+
hasCollision = HasCollisionCarVsCar(contact, physicsComponentA, physicsComponentB);
321316
}
322-
323-
if (hasCollision && fixtureMapSolidBlock && fixturePed)
317+
}
318+
else
319+
{
320+
b2Fixture* fixtureMapSolidBlock = FilterFixture(fixtureA, fixtureB, PHYSICS_OBJCAT_MAP_SOLID_BLOCK);
321+
b2Fixture* fixturePed = FilterFixture(fixtureA, fixtureB, PHYSICS_OBJCAT_PED);
322+
b2Fixture* fixtureCar = FilterFixture(fixtureA, fixtureB, PHYSICS_OBJCAT_CAR);
323+
324+
if (fixturePed)
324325
{
325-
b2FixtureData_map fxdata = fixtureMapSolidBlock->GetUserData();
326-
PhysicsComponent* physicsObject = (PhysicsComponent*) fixturePed->GetBody()->GetUserData();
327-
debug_assert(physicsObject);
326+
PedPhysicsComponent* pedPhysicsObject = CastBodyData<PedPhysicsComponent>(fixturePed->GetBody());
327+
debug_assert(pedPhysicsObject);
328328

329-
// detect height
330-
float height = gGameMap.GetHeightAtPosition(physicsObject->GetPosition());
331-
hasCollision = HasCollisionPedestrianVsMap(fxdata.mX, fxdata.mZ, height);
329+
// ped vs map solid block
330+
if (fixtureMapSolidBlock)
331+
{
332+
b2FixtureData_map fxdata = fixtureMapSolidBlock->GetUserData();
333+
334+
float height = gGameMap.GetHeightAtPosition(pedPhysicsObject->GetPosition());
335+
hasCollision = pedPhysicsObject->ShouldCollideWith(PHYSICS_OBJCAT_MAP_SOLID_BLOCK) &&
336+
HasCollisionPedVsMap(fxdata.mX, fxdata.mZ, height);
337+
}
338+
// ped vs car
339+
else if (fixtureCar)
340+
{
341+
CarPhysicsComponent* carPhysicsObject = CastBodyData<CarPhysicsComponent>(fixtureCar->GetBody());
342+
hasCollision = pedPhysicsObject->ShouldCollideWith(PHYSICS_OBJCAT_CAR) &&
343+
HasCollisionPedVsCar(contact, pedPhysicsObject, carPhysicsObject);
344+
}
332345
}
333-
334-
if (hasCollision && fixtureMapSolidBlock && fixtureCar)
346+
// car vs map solid block
347+
else if (fixtureCar && fixtureMapSolidBlock)
335348
{
336349
b2FixtureData_map fxdata = fixtureMapSolidBlock->GetUserData();
337350
hasCollision = HasCollisionCarVsMap(contact, fixtureCar, fxdata.mX, fxdata.mZ);
338351
}
339-
340-
if (hasCollision && fixtureCar && fixturePed)
341-
{
342-
hasCollision = HasCollisionPedestrianVsCar(contact, fixturePed, fixtureCar);
343-
}
344-
345-
break;
346352
}
347353

348354
contact->SetEnabled(hasCollision);
349355
}
350356

351357
void PhysicsManager::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
352358
{
359+
b2Fixture* fixtureA = contact->GetFixtureA();
360+
b2Fixture* fixtureB = contact->GetFixtureB();
361+
362+
// check car vs car
363+
if (fixtureA->GetFilterData().categoryBits ==
364+
fixtureB->GetFilterData().categoryBits)
365+
{
366+
if (fixtureA->GetFilterData().categoryBits == PHYSICS_OBJCAT_CAR)
367+
{
368+
// todo
369+
}
370+
371+
return;
372+
}
373+
374+
// find impulse
375+
float maxImpulse = 0.0f;
376+
for (int icurr = 0; icurr < impulse->count; ++icurr)
377+
{
378+
maxImpulse = glm::max(maxImpulse, fabs(impulse->normalImpulses[icurr]));
379+
}
380+
381+
if (maxImpulse < 0.01f) // impact is too small, ignore
382+
return;
383+
384+
b2Fixture* fixtureMapSolidBlock = FilterFixture(fixtureA, fixtureB, PHYSICS_OBJCAT_MAP_SOLID_BLOCK);
385+
b2Fixture* fixturePed = FilterFixture(fixtureA, fixtureB, PHYSICS_OBJCAT_PED);
386+
b2Fixture* fixtureCar = FilterFixture(fixtureA, fixtureB, PHYSICS_OBJCAT_CAR);
387+
388+
if (fixtureCar && fixturePed)
389+
{
390+
CarPhysicsComponent* physicsComponentCar = CastBodyData<CarPhysicsComponent>(fixtureCar->GetBody());
391+
PedPhysicsComponent* physicsComponentPed = CastBodyData<PedPhysicsComponent>(fixturePed->GetBody());
392+
HandleContactPedVsCar(contact, maxImpulse, physicsComponentPed, physicsComponentCar);
393+
}
353394
}
354395

355396
void PhysicsManager::FixedStepGravity()
356397
{
398+
// todo: cleanup this mess
399+
357400
// cars
358401
for (Vehicle* currCar: gGameObjectsManager.mCarsList)
359402
{
@@ -444,14 +487,24 @@ void PhysicsManager::FixedStepGravity()
444487
}
445488
}
446489

447-
bool PhysicsManager::CollidePedVsPed(b2Contact* contact, PedPhysicsComponent* pedA, PedPhysicsComponent* pedB)
490+
bool PhysicsManager::HasCollisionPedVsPed(b2Contact* contact, PedPhysicsComponent* pedA, PedPhysicsComponent* pedB) const
448491
{
449492
// todo: temporary implementation
450493

451494
return false;
452495
}
453496

454-
bool PhysicsManager::HasCollisionPedestrianVsMap(int mapx, int mapz, float height) const
497+
bool PhysicsManager::HasCollisionCarVsCar(b2Contact* contact, CarPhysicsComponent* carA, CarPhysicsComponent* carB) const
498+
{
499+
int carLayerA = (int) (Convert::MetersToMapUnits(carA->mHeight) + 0.5f);
500+
int carLayerB = (int) (Convert::MetersToMapUnits(carB->mHeight) + 0.5f);
501+
502+
// todo: handle slopes
503+
504+
return carLayerA == carLayerB;
505+
}
506+
507+
bool PhysicsManager::HasCollisionPedVsMap(int mapx, int mapz, float height) const
455508
{
456509
int mapLayer = (int) (Convert::MetersToMapUnits(height) + 0.5f);
457510

@@ -463,7 +516,7 @@ bool PhysicsManager::HasCollisionPedestrianVsMap(int mapx, int mapz, float heigh
463516

464517
bool PhysicsManager::HasCollisionCarVsMap(b2Contact* contact, b2Fixture* fixtureCar, int mapx, int mapz) const
465518
{
466-
CarPhysicsComponent* carPhysicsComponent = (CarPhysicsComponent*) fixtureCar->GetBody()->GetUserData();
519+
CarPhysicsComponent* carPhysicsComponent = CastBodyData<CarPhysicsComponent>(fixtureCar->GetBody());
467520
debug_assert(carPhysicsComponent);
468521

469522
int mapLayer = (int) (Convert::MetersToMapUnits(carPhysicsComponent->mHeight) + 0.5f);
@@ -474,11 +527,12 @@ bool PhysicsManager::HasCollisionCarVsMap(b2Contact* contact, b2Fixture* fixture
474527
return (blockData->mGroundType == eGroundType_Building);
475528
}
476529

477-
bool PhysicsManager::HasCollisionPedestrianVsCar(b2Contact* contact, b2Fixture* fixturePed, b2Fixture* fixtureCar)
530+
bool PhysicsManager::HasCollisionPedVsCar(b2Contact* contact, PedPhysicsComponent* ped, CarPhysicsComponent* car) const
478531
{
479-
CarPhysicsComponent* carPhysicsObject = (CarPhysicsComponent*) fixtureCar->GetBody()->GetUserData();
480-
PedPhysicsComponent* pedPhysicsObject = (PedPhysicsComponent*) fixturePed->GetBody()->GetUserData();
481-
return true;
532+
// check car bounds height
533+
// todo: get car height!
534+
return ((ped->mHeight >= car->mHeight) &&
535+
(ped->mHeight <= (car->mHeight + 2.0f)));
482536
}
483537

484538
bool PhysicsManager::ProcessSensorContact(b2Contact* contact, bool onBegin)
@@ -492,10 +546,12 @@ bool PhysicsManager::ProcessSensorContact(b2Contact* contact, bool onBegin)
492546
if (!(sensorA ^ sensorB))
493547
return false;
494548

495-
PedPhysicsComponent* pedPhysicsComponent = nullptr;
496-
CarPhysicsComponent* carPhysicsComponent = nullptr;
497-
if (GetContactComponents(contact, pedPhysicsComponent, carPhysicsComponent))
549+
b2Fixture* pedFixture = FilterFixture(contact->GetFixtureA(), contact->GetFixtureB(), PHYSICS_OBJCAT_PED | PHYSICS_OBJCAT_PED_SENSOR);
550+
b2Fixture* carFixture = FilterFixture(contact->GetFixtureA(), contact->GetFixtureB(), PHYSICS_OBJCAT_CAR);
551+
if (pedFixture && carFixture)
498552
{
553+
PedPhysicsComponent* pedPhysicsComponent = CastBodyData<PedPhysicsComponent>(pedFixture->GetBody());
554+
CarPhysicsComponent* carPhysicsComponent = CastBodyData<CarPhysicsComponent>(carFixture->GetBody());
499555
if (onBegin)
500556
{
501557
pedPhysicsComponent->HandleCarContactBegin();
@@ -506,48 +562,9 @@ bool PhysicsManager::ProcessSensorContact(b2Contact* contact, bool onBegin)
506562
}
507563
return true;
508564
}
509-
510565
return false;
511566
}
512567

513-
bool PhysicsManager::GetContactComponents(b2Contact* contact, PedPhysicsComponent*& pedPhysicsObject, CarPhysicsComponent*& carPhysicsObject) const
514-
{
515-
b2Fixture* fixtureA = contact->GetFixtureA();
516-
b2Fixture* fixtureB = contact->GetFixtureB();
517-
518-
b2Fixture* fixturePed = nullptr;
519-
b2Fixture* fixtureCar = nullptr;
520-
521-
const b2Filter& filterA = fixtureA->GetFilterData();
522-
if ((filterA.categoryBits == PHYSICS_OBJCAT_PED) || (filterA.categoryBits == PHYSICS_OBJCAT_PED_SENSOR))
523-
{
524-
fixturePed = fixtureA;
525-
}
526-
else if (filterA.categoryBits == PHYSICS_OBJCAT_CAR)
527-
{
528-
fixtureCar = fixtureA;
529-
}
530-
531-
const b2Filter& filterB = fixtureB->GetFilterData();
532-
if ((filterB.categoryBits == PHYSICS_OBJCAT_PED) || (filterB.categoryBits == PHYSICS_OBJCAT_PED_SENSOR))
533-
{
534-
fixturePed = fixtureB;
535-
}
536-
else if (filterB.categoryBits == PHYSICS_OBJCAT_CAR)
537-
{
538-
fixtureCar = fixtureB;
539-
}
540-
541-
if (fixturePed == nullptr || fixtureCar == nullptr)
542-
return false;
543-
544-
carPhysicsObject = (CarPhysicsComponent*) fixtureCar->GetBody()->GetUserData();
545-
pedPhysicsObject = (PedPhysicsComponent*) fixturePed->GetBody()->GetUserData();
546-
547-
debug_assert(carPhysicsObject && pedPhysicsObject);
548-
return true;
549-
}
550-
551568
void PhysicsManager::QueryObjectsLinecast(const glm::vec2& pointA, const glm::vec2& pointB, PhysicsLinecastResult& outputResult) const
552569
{
553570
outputResult.SetNull();
@@ -570,13 +587,13 @@ void PhysicsManager::QueryObjectsLinecast(const glm::vec2& pointA, const glm::ve
570587
if (filterData.categoryBits == PHYSICS_OBJCAT_CAR)
571588
{
572589
currHit = &mOutput.mHits[mOutput.mHitsCount++];
573-
currHit->mCarComponent = (CarPhysicsComponent*) fixture->GetBody()->GetUserData();
590+
currHit->mCarComponent = CastBodyData<CarPhysicsComponent>(fixture->GetBody());
574591

575592
}
576593
if (filterData.categoryBits == PHYSICS_OBJCAT_PED)
577594
{
578595
currHit = &mOutput.mHits[mOutput.mHitsCount++];
579-
currHit->mPedComponent = (PedPhysicsComponent*) fixture->GetBody()->GetUserData();
596+
currHit->mPedComponent = CastBodyData<PedPhysicsComponent>(fixture->GetBody());
580597
}
581598
if (currHit)
582599
{
@@ -617,13 +634,13 @@ void PhysicsManager::QueryObjectsWithinBox(const glm::vec2& aaboxCenter, const g
617634
if (filterData.categoryBits == PHYSICS_OBJCAT_CAR)
618635
{
619636
PhysicsQueryElement& currElement = mOutput.mElements[mOutput.mElementsCount++];
620-
currElement.mCarComponent = (CarPhysicsComponent*) fixture->GetBody()->GetUserData();
637+
currElement.mCarComponent = CastBodyData<CarPhysicsComponent>(fixture->GetBody());
621638
}
622639

623640
if (filterData.categoryBits == PHYSICS_OBJCAT_PED)
624641
{
625642
PhysicsQueryElement& currElement = mOutput.mElements[mOutput.mElementsCount++];
626-
currElement.mPedComponent = (PedPhysicsComponent*) fixture->GetBody()->GetUserData();
643+
currElement.mPedComponent = CastBodyData<PedPhysicsComponent>(fixture->GetBody());
627644
}
628645
return true;
629646
}
@@ -638,4 +655,9 @@ void PhysicsManager::QueryObjectsWithinBox(const glm::vec2& aaboxCenter, const g
638655
aabb.upperBound.x = (aaboxCenter.x + aabboxExtents.x);
639656
aabb.upperBound.y = (aaboxCenter.y + aabboxExtents.y);
640657
mPhysicsWorld->QueryAABB(&query_callback, aabb);
641-
}
658+
}
659+
660+
void PhysicsManager::HandleContactPedVsCar(b2Contact* contact, float impulse, PedPhysicsComponent* ped, CarPhysicsComponent* car)
661+
{
662+
663+
}

src/PhysicsManager.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,17 @@ class PhysicsManager final: private b2ContactListener
5959
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override;
6060
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override;
6161

62-
bool CollidePedVsPed(b2Contact* contact, PedPhysicsComponent* pedA, PedPhysicsComponent* pedB);
63-
bool HasCollisionPedestrianVsMap(int mapx, int mapz, float height) const;
62+
// pre solve collisions
63+
bool HasCollisionPedVsPed(b2Contact* contact, PedPhysicsComponent* pedA, PedPhysicsComponent* pedB) const;
64+
bool HasCollisionCarVsCar(b2Contact* contact, CarPhysicsComponent* carA, CarPhysicsComponent* carB) const;
65+
bool HasCollisionPedVsMap(int mapx, int mapz, float height) const;
6466
bool HasCollisionCarVsMap(b2Contact* contact, b2Fixture* fixtureCar, int mapx, int mapz) const;
65-
bool HasCollisionPedestrianVsCar(b2Contact* contact, b2Fixture* fixturePed, b2Fixture* fixtureCar);
67+
bool HasCollisionPedVsCar(b2Contact* contact, PedPhysicsComponent* ped, CarPhysicsComponent* car) const;
6668

67-
bool ProcessSensorContact(b2Contact* contact, bool onBegin);
69+
// post solve collisions
70+
void HandleContactPedVsCar(b2Contact* contact, float impulse, PedPhysicsComponent* ped, CarPhysicsComponent* car);
6871

69-
bool GetContactComponents(b2Contact* contact, PedPhysicsComponent*& pedPhysicsObject, CarPhysicsComponent*& carPhysicsObject) const;
72+
bool ProcessSensorContact(b2Contact* contact, bool onBegin);
7073

7174
private:
7275
b2Body* mMapCollisionShape;

0 commit comments

Comments
 (0)