From: Patrik Gornicz Date: Wed, 21 Jan 2009 23:50:34 +0000 (-0500) Subject: refactored collisionManager X-Git-Tag: physics-premerge~56 X-Git-Url: http://gitweb.pgornicz.com/gitweb.cgi?a=commitdiff_plain;h=7d8eb69997a3000979f0b4cd73c9fbf9d1f10988;p=libbear.git refactored collisionManager --- diff --git a/TODO b/TODO index 7f2feba..54b6269 100644 --- a/TODO +++ b/TODO @@ -21,6 +21,12 @@ and a * entry is something to remember when working in this area of the project. - bind keys - load / save state +- remove (at least direct) uses of stl and the std libs + - create my own set + - replace the setPhys in collisionHandler + - create my own list -- LInKS !! + +******************************************************************************* +LINKS !! http://www.gimp.org/tutorials/ diff --git a/src/collisionManager.cpp b/src/collisionManager.cpp index 81d5e05..dc5a785 100644 --- a/src/collisionManager.cpp +++ b/src/collisionManager.cpp @@ -28,29 +28,27 @@ #include "mathw.h" -/// ***** Private Class Header ***** - /// ***** Private Method Headers ***** -void clearEntities(); -void placeEntity(PhysicsEntity* p); -void updateEntities(); +static void clearEntities(); +static void placeEntity(PhysicsEntity*); +static void updateEntities(); -void applyCollision(PhysicsEntity* p1, PhysicsEntity* p2); -void applyCollision(Ball* b1, Ball* b2); -void applyCollision(Polygon* pPoly, Ball* pBall); +static void applyCollision(PhysicsEntity*, PhysicsEntity*); +static void applyCollision(Ball*, Ball*); +static void applyCollision(Polygon*, Ball*); -bool getInfo(const Ball* b1, const Ball* b2, CollisionInfo* cInfo); -bool getInfo(const Polygon* pPoly, const Ball* pBall, CollisionInfo* cInfo); +static bool getInfo(const Ball*, const Ball*, CollisionInfo*); +static bool getInfo(const Polygon*, const Ball*, CollisionInfo*); /// ***** Private Variables ***** -const int xDivisions = 20; -const int yDivisions = 16; -const int screenX = 800; -const int screenY = 600; +static const int sc_ixDivisions = 20; +static const int sc_iyDivisions = 16; +static const int sc_ixScreenSize = 800; +static const int sc_iyScreenSize = 600; -setPhys divisions[xDivisions][yDivisions]; +setPhys divisions[sc_ixDivisions][sc_iyDivisions]; /// ***** Initializers/Cleaners ***** @@ -84,11 +82,11 @@ void collision::update(setPhys& sp) void clearEntities() { for( int x = 0; - x < xDivisions; + x < sc_ixDivisions; x++ ) { for( int y = 0; - y < yDivisions; + y < sc_iyDivisions; y++ ) { divisions[x][y].clear(); @@ -96,36 +94,38 @@ void clearEntities() } } -void placeEntity(PhysicsEntity* p) +void placeEntity(PhysicsEntity* ppe) { - Vector2 minP; - Vector2 maxP; + DASSERT(ppe != NULL); + + Vector2 vecMin; + Vector2 vecMax; { // Ball case - Ball* b = dynamic_cast(p); + Ball* pBall = dynamic_cast(ppe); - if( b != NULL ) + if( pBall != NULL ) { - const float& xb = b->positionRaw().m_fX; - const float& yb = b->positionRaw().m_fY; - const float& rad = b->radius; + const float& xb = pBall->positionRaw().m_fX; + const float& yb = pBall->positionRaw().m_fY; + const float& rad = pBall->radius; - minP.m_fX = xb - rad; - minP.m_fY = yb - rad; - maxP.m_fX = xb + rad; - maxP.m_fY = yb + rad; + vecMin.m_fX = xb - rad; + vecMin.m_fY = yb - rad; + vecMax.m_fX = xb + rad; + vecMax.m_fY = yb + rad; goto start; } } { // Polygon case - Polygon* pPoly = dynamic_cast(p); + Polygon* pPoly = dynamic_cast(ppe); if( pPoly != NULL ) { - minP = pPoly->minP; - maxP = pPoly->maxP; + vecMin = pPoly->minP; + vecMax = pPoly->maxP; goto start; } @@ -135,21 +135,21 @@ void placeEntity(PhysicsEntity* p) return; start: - for( int x = static_cast( minP.m_fX / (screenX / xDivisions) ); - x <= static_cast( maxP.m_fX / (screenX / xDivisions) ); + for( int x = static_cast( vecMin.m_fX / (sc_ixScreenSize / sc_ixDivisions) ); + x <= static_cast( vecMax.m_fX / (sc_ixScreenSize / sc_ixDivisions) ); x++ ) { - if(x < 0 || xDivisions <= x) + if(x < 0 || sc_ixDivisions <= x) break; - for( int y = static_cast( minP.m_fY / (screenY / yDivisions) ); - y <= static_cast( maxP.m_fY / (screenY / yDivisions) ); + for( int y = static_cast( vecMin.m_fY / (sc_iyScreenSize / sc_iyDivisions) ); + y <= static_cast( vecMax.m_fY / (sc_iyScreenSize / sc_iyDivisions) ); y++ ) { - if(y < 0 || yDivisions <= y) + if(y < 0 || sc_iyDivisions <= y) break; - divisions[x][y].insert(p); + divisions[x][y].insert(ppe); } } } @@ -157,11 +157,11 @@ start: void updateEntities() { for( int x = 0; - x < xDivisions; + x < sc_ixDivisions; x++ ) { for( int y = 0; - y < yDivisions; + y < sc_iyDivisions; y++ ) { for( setPhys::iterator it1 = divisions[x][y].begin(); @@ -182,22 +182,24 @@ void updateEntities() } } -void applyCollision(PhysicsEntity* p1, PhysicsEntity* p2) +void applyCollision(PhysicsEntity* ppe1, PhysicsEntity* ppe2) { - { - Ball* b1 = dynamic_cast(p1); - Ball* b2 = dynamic_cast(p2); + DASSERT(ppe1 != NULL && ppe2 != NULL); - if( b1 != NULL && b2 != NULL ) + {// Ball vs Ball + Ball* pb1 = dynamic_cast(ppe1); + Ball* pb2 = dynamic_cast(ppe2); + + if( pb1 != NULL && pb2 != NULL ) { - applyCollision(b1, b2); + applyCollision(pb1, pb2); return; } } - { - Polygon* pPoly = dynamic_cast(p1); - Ball* pBall = dynamic_cast(p2); + {// Polygon vs Ball + Polygon* pPoly = dynamic_cast(ppe1); + Ball* pBall = dynamic_cast(ppe2); if( pPoly != NULL && pBall != NULL ) { @@ -206,9 +208,9 @@ void applyCollision(PhysicsEntity* p1, PhysicsEntity* p2) } } - { - Polygon* pPoly = dynamic_cast(p2); - Ball* pBall = dynamic_cast(p1); + {// Ball vs Polygon + Polygon* pPoly = dynamic_cast(ppe2); + Ball* pBall = dynamic_cast(ppe1); if( pPoly != NULL && pBall != NULL ) { @@ -220,47 +222,52 @@ void applyCollision(PhysicsEntity* p1, PhysicsEntity* p2) DPF(0, "ENTITY TYPE NOT SUPPORTED BY applyCollision()!!"); } -void applyCollision(Ball* b1, Ball* b2) +void applyCollision(Ball* pb1, Ball* pb2) { + DASSERT(pb1 != NULL && pb2 != NULL); + CollisionInfo cInfo; - if(!getInfo(b1, b2, &cInfo)) + if(!getInfo(pb1, pb2, &cInfo)) return; // a few values to simplify the equations - const Vector2& normal = cInfo.m_vecNormal; - const Vector2& point = cInfo.m_vecPoint; + const Vector2& vecNormal = cInfo.m_vecNormal; + const Vector2& vecPoint = cInfo.m_vecPoint; - float m1 = b1->mass; - float m2 = b2->mass; + float m1 = pb1->mass; + float m2 = pb2->mass; - float e = (b1->CoR + b2->CoR) / 2; + float e = (pb1->CoR + pb2->CoR) / 2; - Vector2 v1 = b1->velocityRaw(); - Vector2 v2 = b2->velocityRaw(); + Vector2 v1 = pb1->velocityRaw(); + Vector2 v2 = pb2->velocityRaw(); - float iTop = -(e + 1) * (v1 - v2).dot(normal); + float iTop = -(e + 1) * (v1 - v2).dot(vecNormal); // otherwise the collision happened and we do the math the below assumes // collisions have no friction - float impulse = iTop / (normal.dot(normal) * (1 / m1 + 1 / m2)); + float impulse = iTop / (vecNormal.dot(vecNormal) * (1 / m1 + 1 / m2)); - b1->applyImpulse(impulse / m1 * normal, point); - b2->applyImpulse(-impulse / m2 * normal, point); + pb1->applyImpulse(impulse / m1 * vecNormal, vecPoint); + pb2->applyImpulse(-impulse / m2 * vecNormal, vecPoint); } void applyCollision(Polygon* pPoly, Ball* pBall) { + DASSERT(pPoly != NULL && pBall != NULL); + CollisionInfo cInfo; if(!getInfo(pPoly, pBall, &cInfo)) return; - float fCoR = pBall->CoR; - Vector2 vecNorm = cInfo.m_vecNormal; + // a few values to simplify the equations + const Vector2& vecNorm = cInfo.m_vecNormal; + float fCoR = pBall->CoR; Vector2 vecVelo = pBall->velocityRaw(); // impulse divided by mass @@ -270,23 +277,23 @@ void applyCollision(Polygon* pPoly, Ball* pBall) pBall->applyImpulse(idm * vecNorm); // HACK - // CoR penetration fix, adds the jitters + // CoR penetration fix, adds the polygon-ball jitters // from center to point Vector2 vecCollP = vecNorm / vecNorm.length() * pBall->radius; pBall->applyNudge(cInfo.m_vecPoint + vecCollP - pBall->positionRaw()); } -bool getInfo(const Ball* b1, const Ball* b2, CollisionInfo* pcInfo) +bool getInfo(const Ball* pb1, const Ball* pb2, CollisionInfo* pcInfo) { // a few values to simplify the equations - float r1 = b1->radius; - float r2 = b2->radius; + float r1 = pb1->radius; + float r2 = pb2->radius; - Vector2 p1 = b1->positionRaw(); - Vector2 p2 = b2->positionRaw(); - Vector2 v1 = b1->velocityRaw(); - Vector2 v2 = b2->velocityRaw(); + Vector2 p1 = pb1->positionRaw(); + Vector2 p2 = pb2->positionRaw(); + Vector2 v1 = pb1->velocityRaw(); + Vector2 v2 = pb2->velocityRaw(); // quick binding box check if (p1.m_fX - r1 > p2.m_fX + r2 @@ -299,7 +306,7 @@ bool getInfo(const Ball* b1, const Ball* b2, CollisionInfo* pcInfo) if ((p1 - p2).sqrLength() >= (r1 + r2)*(r1 + r2)) return false; - // test if they are moving apart in some way if they aren't it's likely + // test if they are moving apart in some way if they are it's likely // that they collided last frame and are still overlapping if ((v1 - v2).dot(p1 - p2) >= 0)