wip: advanced collisions
authorPatrik Gornicz <Gornicz.P@gmail.com>
Sat, 6 Dec 2008 19:40:38 +0000 (14:40 -0500)
committerPatrik Gornicz <Gornicz.P@gmail.com>
Sat, 6 Dec 2008 19:40:38 +0000 (14:40 -0500)
src/collisionManager.cpp

index e03135a..df83319 100644 (file)
 
 /// ***** 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<Ball*>(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<Ball*>(p1);
     Ball* b2 = dynamic_cast<Ball*>(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;