some collisions on PhysicsWorld::tick
authornireco
Mon, 08 Dec 2008 16:01:49 +0000
changeset 288 47a5d7896aec
parent 287 f59c8dee7f91
child 289 2130e9f4aab4
some collisions on PhysicsWorld::tick
src/Config.hh
src/PhysicsObject.cc
src/PhysicsObject.hh
src/PhysicsWorld.cc
--- a/src/Config.hh	Mon Dec 08 15:59:33 2008 +0000
+++ b/src/Config.hh	Mon Dec 08 16:01:49 2008 +0000
@@ -47,6 +47,7 @@
 const float PLAYER_COLLISION_ELASTICITY = 0.25; // TODO: This could be
                                         // different for different
                                         // objects
+const float PLAYER_RADIUS = 10;
 
 /*
  * Projectiles
--- a/src/PhysicsObject.cc	Mon Dec 08 15:59:33 2008 +0000
+++ b/src/PhysicsObject.cc	Mon Dec 08 16:01:49 2008 +0000
@@ -247,7 +247,7 @@
         setPosition (newPosition);
 
         // the following may delete this object, so it must be the last thing called
-        onCollision(collisionPoint, NULL);
+        onCollision(collisionPoint);
 
         return;
     }
--- a/src/PhysicsObject.hh	Mon Dec 08 15:59:33 2008 +0000
+++ b/src/PhysicsObject.hh	Mon Dec 08 16:01:49 2008 +0000
@@ -156,14 +156,14 @@
     void walk(TimeMS, bool right);
     Vector walk_one_step(float, bool);
 
+public:
     /**
      * Define object behaviour on collisions.
      *
      * XXX: make this pure-virtual
      */
-    virtual void onCollision (Vector collisionPoint, PhysicsObject *other);
+    virtual void onCollision (Vector collisionPoint, PhysicsObject *other = NULL);
 
-public:
     /**
      * Return the type of the physics object (player, projectile...)
      */
--- a/src/PhysicsWorld.cc	Mon Dec 08 15:59:33 2008 +0000
+++ b/src/PhysicsWorld.cc	Mon Dec 08 16:01:49 2008 +0000
@@ -23,11 +23,65 @@
     objects.remove(po);
 }
 
+
+float distancePointToLine(Vector l1, Vector l2, Vector p) {
+    Vector v(l2.y - l1.y, -(l2.x - l1.x));
+    Vector r(l1.x-p.x, l1.y-p.y);
+    v = v/v.length();
+    float dist = v*r/v.sqrLength();
+    return dist;
+}
+
 void PhysicsWorld::tick (TimeMS tick_length) {
     // tick each object in turn
     for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
         (*i)->tick(tick_length); 
     }
+    for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
+        for (std::list<PhysicsObject*>::iterator j = i; j != objects.end(); j++) {
+            if(i == j)
+                continue;
+            float range_sum_sqr = 2;
+            if((*i)->getType() == PLAYER) {
+                range_sum_sqr += PLAYER_RADIUS-1;
+            }
+            if((*j)->getType() == PLAYER) {
+                range_sum_sqr += PLAYER_RADIUS-1;
+            }
+            range_sum_sqr *= range_sum_sqr;
+            bool collision = false;
+            Vector a1 = (*i)->getPreviousPosition();
+            Vector a2 = (*i)->getPosition();
+            Vector b1 = (*j)->getPreviousPosition();
+            Vector b2 = (*j)->getPosition();
+/*            if(a1 == a2) {
+                float d = abs(distancePointToLine(b1, b2, a1));
+                if(d*d < range_sum_sqr)
+                    collision = true;
+            } else if(b1 == b2) {
+                float d = abs(distancePointToLine(a1, a2, b1));
+                if(d*d < range_sum_sqr)
+                    collision = true;
+            } else {*/
+                float db1 = distancePointToLine(a1, a2, b1);
+                float db2 = distancePointToLine(a1, a2, b2);
+                float da1 = distancePointToLine(b1, b2, a1);
+                float da2 = distancePointToLine(b1, b2, a2);
+                if(db1*db2 < 0 && da1*da2 < 0) {
+                    // lines intersected
+//                    collision = true;
+                }
+                float dab = (a2-b2).sqrLength();
+                if(dab < range_sum_sqr) {
+                    collision = true;
+                }
+//            }
+            if(collision) {
+                (*i)->onCollision(a2, *j);
+                (*j)->onCollision(b2, *i);
+            }
+        }
+    }
 
     // Delete destroyed objects
     objects.remove_if(std::mem_fun(&PhysicsObject::removeIfDestroyed));