more debug changes
[physics.git] / src / collisionManager.cpp
CommitLineData
54fe85c5
PG
1/*
2 * Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
0ac1dc80 18#include "collisionManager.h"
54fe85c5
PG
19#include "debug.h"
20
21#include "Vector2.h"
22
23#include "Entities/Ball.h"
24#include "Entities/PhysicsEntity.h"
25
26#include "CollisionInfo.h"
27
28/// ***** Private Class Header *****
29
30/// ***** Private Method Headers *****
31
2869e2e8
PG
32void applyCollisionAt(PhysicsEntity* p1, PhysicsEntity* p2);
33void applyCollisionAt(Ball* b1, Ball* b2);
54fe85c5 34
2869e2e8 35CollisionInfo* getInfoAt(Ball* b1, Ball* b2);
54fe85c5
PG
36
37/// ***** Private Variables *****
38
39/// ***** Initializers/Cleaners *****
40
41void collision::init()
42{
43
44}
45void collision::clean()
46{
47
48}
49
50/// ***** Public Methods *****
51
2869e2e8 52void collision::update(setPhys& sp)
54fe85c5
PG
53{
54 for( setPhys::iterator it1 = sp.begin();
55 it1 != sp.end();
56 it1++ )
57 {
58 for( setPhys::iterator it2 = sp.begin();
59 it2 != sp.end();
60 it2++ )
61 {
62 if( *it1 != *it2 )
63 {
2869e2e8 64 applyCollisionAt(*it1, *it2);
54fe85c5
PG
65 }
66 }
67 }
68
69}
70
71/// ***** Private Methods *****
72
2869e2e8 73void applyCollisionAt(PhysicsEntity* p1, PhysicsEntity* p2)
54fe85c5
PG
74{
75 Ball* b1 = dynamic_cast<Ball*>(p1);
76 Ball* b2 = dynamic_cast<Ball*>(p2);
77
78 if( b1 != NULL && b2 != NULL )
79 {
2869e2e8 80 applyCollisionAt(b1, b2);
54fe85c5
PG
81 return;
82 }
83
ca2d526e 84 DPF(0, "ENTITY TYPE NOT SUPPORTED BY applyCollisionAt()!!");
54fe85c5
PG
85}
86
2869e2e8 87void applyCollisionAt(Ball* b1, Ball* b2)
54fe85c5
PG
88{
89 // /*
2869e2e8 90 CollisionInfo* info = getInfoAt(b1, b2);
54fe85c5
PG
91
92 if(info == NULL)
93 return;
94
95 // a few values to simplify the equations
96 Vector2 normal = info->normal;
97 Vector2 point = info->point;
98
99 delete info;
100
101 float m1 = b1->mass;
102 float m2 = b2->mass;
103
104 float e = (b1->CoR + b2->CoR) / 2;
105
2869e2e8
PG
106 Vector2 v1 = b1->velocityRaw();
107 Vector2 v2 = b2->velocityRaw();
54fe85c5
PG
108
109
110 float iTop = -(e + 1) * (v1 - v2).dot(normal);
111
112 // otherwise the collision happened and we do the math the below assumes
113 // collisions have no friction
114
115 float impulse = iTop / (normal.dot(normal) * (1 / m1 + 1 / m2));
116
117 b1->applyImpulse(impulse / m1 * normal, point);
118 b2->applyImpulse(-impulse / m2 * normal, point);
119 // */
120}
121
2869e2e8 122CollisionInfo* getInfoAt(Ball* b1, Ball* b2)
54fe85c5
PG
123{
124 // a few values to simplify the equations
125 float r1 = b1->radius;
126 float r2 = b2->radius;
127
2869e2e8
PG
128 Vector2 p1 = b1->positionRaw();
129 Vector2 p2 = b2->positionRaw();
130 Vector2 v1 = b1->velocityRaw();
131 Vector2 v2 = b2->velocityRaw();
54fe85c5
PG
132
133 // quick binding box check
134 if (p1.x - r1 > p2.x + r2
135 || p1.x + r1 < p2.x - r2
136 || p1.y - r1 > p2.y + r2
137 || p1.y + r1 < p2.y - r2)
138 return NULL;
139
140 // test if not touching
141 if ((p1 - p2).sqrLength() >= (r1 + r2)*(r1 + r2))
142 return NULL;
143
144 // test if they are moving apart in some way if they aren't it's likely
145 // that they collided last frame and are still overlapping
146
147 if ((v1 - v2).dot(p1 - p2) >= 0)
148 return NULL;
149
150 return new CollisionInfo(p1 - (p1 - p2) * r1 / (r1 + r2), p1 - p2);
151}