added ball to ball collisions
authorPatrik Gornicz <Gornicz.P@gmail.com>
Sat, 9 Aug 2008 16:52:30 +0000 (12:52 -0400)
committerPatrik Gornicz <Gornicz.P@gmail.com>
Sat, 9 Aug 2008 16:52:30 +0000 (12:52 -0400)
12 files changed:
src/CollisionInfo.cpp [new file with mode: 0644]
src/CollisionInfo.h [new file with mode: 0644]
src/Entities/Ball.h
src/Entities/PhysicsEntity.cpp
src/Entities/PhysicsEntity.h
src/Makefile
src/Vector2.cpp
src/Vector2.h
src/collisionHandler.cpp [new file with mode: 0644]
src/collisionHandler.h [new file with mode: 0644]
src/debug.h
src/entityManager.cpp

diff --git a/src/CollisionInfo.cpp b/src/CollisionInfo.cpp
new file mode 100644 (file)
index 0000000..09e9083
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CollisionInfo.h"
+
+/// ***** Constructors/Destructors *****
+
+CollisionInfo::CollisionInfo(const Vector2& point, const Vector2& normal)
+    : point(point), normal(normal)
+{
+
+}
+
+CollisionInfo::~CollisionInfo()
+{
+
+}
diff --git a/src/CollisionInfo.h b/src/CollisionInfo.h
new file mode 100644 (file)
index 0000000..1c0cb19
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef COLLISIONINFO_H
+#define COLLISIONINFO_H
+
+#include "Vector2.h"
+
+/// ***** Header Class *****
+
+class CollisionInfo
+{
+    public:
+        CollisionInfo(const Vector2& point, const Vector2& normal);
+        ~CollisionInfo();
+
+
+        Vector2 point;
+        Vector2 normal;
+};
+
+#endif // COLLISIONINFO_H
+
index a42d725..d4d43a7 100644 (file)
@@ -34,7 +34,7 @@ class Ball: public PhysicsEntity
 
     float getRadius() const;
 
-  protected:
+  //protected:
     float radius;
     const float* color;
 };
index 285236e..3354fe2 100644 (file)
@@ -70,10 +70,18 @@ Vector2 PhysicsEntity::velocityAt(float time_step) const
 
 void PhysicsEntity::applyForce(const Vector2& force)
 {
+    applyForce(force, position);
+}
+void PhysicsEntity::applyForce(const Vector2& force, const Vector2& at)
+{
     this->force += force;
 }
 
-void PhysicsEntity::applyImpulse(const Vector2& impluse)
+void PhysicsEntity::applyImpulse(const Vector2& impulse)
+{
+    applyImpulse(impulse, position);
+}
+void PhysicsEntity::applyImpulse(const Vector2& impulse, const Vector2& at)
 {
-    velocity += impluse;
+    velocity += impulse;
 }
index 47971a5..a682c9f 100644 (file)
@@ -37,10 +37,13 @@ class PhysicsEntity: public Entity
     virtual Vector2 positionAt(float) const;
     virtual Vector2 velocityAt(float) const;
 
-    virtual void applyForce(const Vector2&);
-    virtual void applyImpulse(const Vector2&);
+    virtual void applyForce(const Vector2& force);
+    virtual void applyForce(const Vector2& force, const Vector2& at);
 
-  protected:
+    virtual void applyImpulse(const Vector2& impulse);
+    virtual void applyImpulse(const Vector2& impulse, const Vector2& at);
+
+  //protected:
     Vector2 force;
 
     float mass;
index 7964286..1e3e3f5 100644 (file)
@@ -13,9 +13,6 @@ CXXFLAGS := -Wall -pedantic -ansi ${DBGFLAGS}
 TARGET := ../run_physics
 
 SRCS := # simply to keep every line below the same
-SRCS += entityManager.cpp
-SRCS += effectManager.cpp
-SRCS += entityCreator.cpp
 SRCS += game.cpp
 SRCS += main.cpp
 SRCS += mathw.cpp
@@ -23,6 +20,12 @@ SRCS += ticks.cpp
 SRCS += Vector2.cpp
 SRCS += handleSignal.cpp
 
+SRCS += entityManager.cpp
+SRCS += effectManager.cpp
+SRCS += entityCreator.cpp
+SRCS += collisionHandler.cpp
+SRCS += CollisionInfo.cpp
+
 SRCS += Entities/Ball.cpp
 SRCS += Entities/Entity.cpp
 SRCS += Entities/Line.cpp
index 2c25375..d13ea95 100644 (file)
@@ -63,7 +63,16 @@ float Vector2::angle() const
 }
 float Vector2::length() const
 {
-    return sqrt(x*x + y*y);
+    return sqrt(sqrLength());
+}
+float Vector2::sqrLength() const
+{
+    return x*x + y*y;
+}
+
+float Vector2::dot(const Vector2& v) const
+{
+    return x*v.x + y*v.y;
 }
 
 
index 00b921b..13ffd88 100644 (file)
@@ -39,6 +39,9 @@ class Vector2
 
     float angle() const;
     float length() const;
+    float sqrLength() const;
+
+    float dot(const Vector2&) const;
 
     Vector2 add(const Vector2&) const;
     Vector2 subtract(const Vector2&) const;
diff --git a/src/collisionHandler.cpp b/src/collisionHandler.cpp
new file mode 100644 (file)
index 0000000..08dc904
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "collisionHandler.h"
+#include "debug.h"
+
+#include "Vector2.h"
+
+#include "Entities/Ball.h"
+#include "Entities/PhysicsEntity.h"
+
+#include "CollisionInfo.h"
+
+/// ***** Private Class Header *****
+
+/// ***** Private Method Headers *****
+
+void applyCollisionAt(PhysicsEntity* p1, PhysicsEntity* p2, float time_step);
+void applyCollisionAt(Ball* b1, Ball* b2, float time_step);
+
+CollisionInfo* getInfoAt(Ball* b1, Ball* b2, float time_step);
+
+/// ***** Private Variables *****
+
+/// ***** Initializers/Cleaners *****
+
+void collision::init()
+{
+
+}
+void collision::clean()
+{
+
+}
+
+/// ***** Public Methods *****
+
+void collision::update(setPhys sp, float time_step)
+{
+    for( setPhys::iterator it1 = sp.begin();
+         it1 != sp.end();
+         it1++ )
+    {
+        for( setPhys::iterator it2 = sp.begin();
+                it2 != sp.end();
+                it2++ )
+        {
+            if( *it1 != *it2 )
+            {
+                applyCollisionAt(*it1, *it2, time_step);
+            }
+        }
+    }
+
+}
+
+/// ***** Private Methods *****
+
+void applyCollisionAt(PhysicsEntity* p1, PhysicsEntity* p2, float time_step)
+{
+    Ball* b1 = dynamic_cast<Ball*>(p1);
+    Ball* b2 = dynamic_cast<Ball*>(p2);
+
+    if( b1 != NULL && b2 != NULL )
+    {
+        applyCollisionAt(b1, b2, time_step);
+        return;
+    }
+
+#ifdef WARNINGS
+    cerr << "ENTITY TYPE NOT SUPPORTED BY applyCollisionAt()!!" << endl;
+#endif
+}
+
+void applyCollisionAt(Ball* b1, Ball* b2, float time_step)
+{
+    // /*
+    CollisionInfo* info = getInfoAt(b1, b2, time_step);
+
+    if(info == NULL)
+        return;
+
+    // a few values to simplify the equations
+    Vector2 normal = info->normal;
+    Vector2 point = info->point;
+
+    delete info;
+
+    float m1 = b1->mass;
+    float m2 = b2->mass;
+
+    float e = (b1->CoR + b2->CoR) / 2;
+
+    Vector2 v1 = b1->velocityAt(time_step);
+    Vector2 v2 = b2->velocityAt(time_step);
+
+
+    float iTop = -(e + 1) * (v1 - v2).dot(normal);
+
+    // 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));
+
+    b1->applyImpulse(impulse / m1 * normal, point);
+    b2->applyImpulse(-impulse / m2 * normal, point);
+    // */
+}
+
+CollisionInfo* getInfoAt(Ball* b1, Ball* b2, float time_step)
+{
+    // a few values to simplify the equations
+    float r1 = b1->radius;
+    float r2 = b2->radius;
+
+    Vector2 p1 = b1->positionAt(time_step);
+    Vector2 p2 = b2->positionAt(time_step);
+    Vector2 v1 = b1->velocityAt(time_step);
+    Vector2 v2 = b2->velocityAt(time_step);
+
+    // quick binding box check
+    if (p1.x - r1 > p2.x + r2
+     || p1.x + r1 < p2.x - r2
+     || p1.y - r1 > p2.y + r2
+     || p1.y + r1 < p2.y - r2)
+        return NULL;
+
+    // test if not touching
+    if ((p1 - p2).sqrLength() >= (r1 + r2)*(r1 + r2))
+        return NULL;
+
+    // test if they are moving apart in some way if they aren't it's likely
+    // that they collided last frame and are still overlapping
+
+    if ((v1 - v2).dot(p1 - p2) >= 0)
+        return NULL;
+
+    return new CollisionInfo(p1 - (p1 - p2) * r1 / (r1 + r2), p1 - p2);
+}
diff --git a/src/collisionHandler.h b/src/collisionHandler.h
new file mode 100644 (file)
index 0000000..27940c2
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COLLISIONHANDLER_H
+#define COLLISIONHANDLER_H
+
+#include "Entities/PhysicsEntity.h"
+
+#include <set>
+typedef std::set<PhysicsEntity*> setPhys;
+
+/// ***** Header Methods *****
+namespace collision
+{
+    void init();
+    void clean();
+
+    void update(setPhys, float);
+}
+
+#endif // COLLISIONHANDLER_H
index 5fc114b..9460055 100644 (file)
@@ -27,6 +27,9 @@ using std::endl;
 // comment out when not debugging
 #define DEBUGGING
 
+// comment out to supress warnings
+#define WARNINGS
+
 // comment out to prevent FPS and UPS printing
 #define FPSUPS
 
index 82dc6d8..c7fc78b 100644 (file)
 #include "debug.h"
 
 #include <set>
-#include <iostream>
 
 #include "Entities/Entity.h"
 #include "Entities/Particle.h"
 #include "Entities/PhysicsEntity.h"
 
+#include "collisionHandler.h"
+
 /// ***** Private Method Headers *****
 
 void updateParticles(float);
@@ -46,11 +47,11 @@ setPhys physics_To_Remove;
 
 void manager::init()
 {
-
+    collision::init();
 }
 void manager::clean()
 {
-
+    collision::clean();
 }
 
 /// ***** Public Methods *****
@@ -75,8 +76,9 @@ void manager::add(Entity* e)
         }
     }
 
-    std::cerr << "ENTITY TYPE NOT SUPPORTED BY addEntity()!!";
-    std::cerr << std::endl;
+#ifdef WARNINGS
+    cerr << "ENTITY TYPE NOT SUPPORTED BY addEntity()!!" << endl;
+#endif
 }
 void manager::remove(Entity* e)
 {
@@ -98,8 +100,9 @@ void manager::remove(Entity* e)
         }
     }
 
-    std::cerr << "ENTITY TYPE NOT SUPPORTED BY deleteEntity()!!";
-    std::cerr << std::endl;
+#ifdef WARNINGS
+    cerr << "ENTITY TYPE NOT SUPPORTED BY deleteEntity()!!" << endl;
+#endif
 }
 
 void manager::handleInput()
@@ -180,6 +183,9 @@ void updatePhysics(float time_step)
     }
     physics_To_Remove.clear();
 
+    // apply collision math
+    collision::update(active_Physics, time_step);
+
     // update active PhysicsEntity*s
     for( setPhys::iterator it = active_Physics.begin();
          it != active_Physics.end();