From: Patrik Gornicz Date: Sat, 6 Dec 2008 19:40:38 +0000 (-0500) Subject: wip: advanced collisions X-Git-Tag: physics-premerge~80 X-Git-Url: http://gitweb.pgornicz.com/gitweb.cgi?a=commitdiff_plain;h=14597cf61ffc968977a2a8571b6f0fe4a89bf6b5;p=libbear.git wip: advanced collisions --- diff --git a/src/collisionManager.cpp b/src/collisionManager.cpp index e03135a..df83319 100644 --- a/src/collisionManager.cpp +++ b/src/collisionManager.cpp @@ -29,13 +29,22 @@ /// ***** Private Method Headers ***** -void applyCollisionAt(PhysicsEntity* p1, PhysicsEntity* p2); -void applyCollisionAt(Ball* b1, Ball* b2); +void clearEntities(); +void placeEntity(PhysicsEntity* p); +void updateEntities(); -bool getInfoAt(Ball* b1, Ball* b2, CollisionInfo* cInfo); +void applyCollision(PhysicsEntity* p1, PhysicsEntity* p2); +void applyCollision(Ball* b1, Ball* b2); + +bool getInfo(Ball* b1, Ball* b2, CollisionInfo* cInfo); /// ***** Private Variables ***** +const int xDivisions = 20; +const int yDivisions = 16; + +setPhys divisions[xDivisions][yDivisions]; + /// ***** Initializers/Cleaners ***** void collision::init() @@ -51,44 +60,115 @@ void collision::clean() void collision::update(setPhys& sp) { - for( setPhys::iterator it1 = sp.begin(); - it1 != sp.end(); - it1++ ) + clearEntities(); + + for( setPhys::iterator it = sp.begin(); + it != sp.end(); + it++ ) { - for( setPhys::iterator it2 = sp.begin(); - it2 != sp.end(); - it2++ ) + placeEntity(*it); + } + + updateEntities(); +} + +/// ***** Private Methods ***** + +void clearEntities() +{ + for( int x = 0; + x < xDivisions; + x++ ) + { + for( int y = 0; + y < yDivisions; + y++ ) { - if( *it1 != *it2 ) - { - applyCollisionAt(*it1, *it2); - } + divisions[x][y].clear(); } } +} +void placeEntity(PhysicsEntity* p) +{ + Ball* b = dynamic_cast(p); + + if( b == NULL ) + { + DPF(0, "ENTITY TYPE NOT SUPPORTED BY placeEntity()!!"); + return; + } + + const float& xb = b->positionRaw().x; + const float& yb = b->positionRaw().y; + const float& rad = b->radius; + + for( int x = (int)(xb - rad); + x < (int)(xb + rad); + x++ ) + { + if(x < 0 || xDivisions <= x) + break; + + for( int y = (int)(yb - rad); + y < (int)(yb + rad); + y++ ) + { + if(y < 0 || yDivisions <= y) + break; + + divisions[x][y].insert(p); + } + } } -/// ***** Private Methods ***** +void updateEntities() +{ + for( int x = 0; + x < xDivisions; + x++ ) + { + for( int y = 0; + y < yDivisions; + y++ ) + { + for( setPhys::iterator it1 = divisions[x][y].begin(); + it1 != divisions[x][y].end(); + it1++ ) + { + for( setPhys::iterator it2 = divisions[x][y].begin(); + it2 != divisions[x][y].end(); + it2++ ) + { + if( *it1 != *it2 ) + { + applyCollision(*it1, *it2); + } + } + } + } + } +} -void applyCollisionAt(PhysicsEntity* p1, PhysicsEntity* p2) +void applyCollision(PhysicsEntity* p1, PhysicsEntity* p2) { Ball* b1 = dynamic_cast(p1); Ball* b2 = dynamic_cast(p2); if( b1 != NULL && b2 != NULL ) { - applyCollisionAt(b1, b2); + applyCollision(b1, b2); return; } - DPF(0, "ENTITY TYPE NOT SUPPORTED BY applyCollisionAt()!!"); + DPF(0, "ENTITY TYPE NOT SUPPORTED BY applyCollision()!!"); } -void applyCollisionAt(Ball* b1, Ball* b2) +void applyCollision(Ball* b1, Ball* b2) { CollisionInfo cInfo; - if(!getInfoAt(b1, b2, &cInfo)) + if(!getInfo(b1, b2, &cInfo)) return; // a few values to simplify the equations @@ -115,7 +195,7 @@ void applyCollisionAt(Ball* b1, Ball* b2) b2->applyImpulse(-impulse / m2 * normal, point); } -bool getInfoAt(Ball* b1, Ball* b2, CollisionInfo* pcInfo) +bool getInfo(Ball* b1, Ball* b2, CollisionInfo* pcInfo) { // a few values to simplify the equations float r1 = b1->radius;