--- /dev/null
+/*
+ * 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()
+{
+
+}
--- /dev/null
+/*
+ * 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
+
float getRadius() const;
- protected:
+ //protected:
float radius;
const float* color;
};
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;
}
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;
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
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
}
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;
}
float angle() const;
float length() const;
+ float sqrLength() const;
+
+ float dot(const Vector2&) const;
Vector2 add(const Vector2&) const;
Vector2 subtract(const Vector2&) const;
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
// comment out when not debugging
#define DEBUGGING
+// comment out to supress warnings
+#define WARNINGS
+
// comment out to prevent FPS and UPS printing
#define FPSUPS
#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);
void manager::init()
{
-
+ collision::init();
}
void manager::clean()
{
-
+ collision::clean();
}
/// ***** Public Methods *****
}
}
- 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)
{
}
}
- 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()
}
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();