]> git.localhorst.tv Git - sdl-test8.git/blob - src/game/Entity.cpp
1c3f78527296e859b81e2c597b57285ab1de2245
[sdl-test8.git] / src / game / Entity.cpp
1 /*
2  * Entity.cpp
3  *
4  *  Created on: Apr 25, 2012
5  *      Author: holy
6  */
7
8 #include "Entity.h"
9
10 #include "../app/Timer.h"
11 #include "../geometry/constants.h"
12
13 #include <limits>
14
15 using geometry::PI;
16 using std::numeric_limits;
17
18 namespace game {
19
20
21 void Entity::Update(const app::Timer &timer) {
22         translation += linearVelocity * timer.DeltaT();
23         rotation += angularVelocity * timer.DeltaT();
24         if (rotation > 2.0 * PI) {
25                 rotation -= 2.0 * PI;
26         } else if (rotation < -(2.0 * PI)) {
27                 rotation += 2.0 * PI;
28         }
29         shape->Translate(linearVelocity * timer.DeltaT());
30         shape->Rotate(angularVelocity * timer.DeltaT());
31 }
32
33 bool Entity::CheckCollision(const Entity &other, Ray &ray) {
34         return shape->CheckCollision(*other.shape, ray);
35 }
36
37
38 Entity::Vector Entity::VelocityAt(const Vector &p) const {
39         if (angularVelocity == 0 || p == translation) return linearVelocity;
40
41         Vector v(linearVelocity);
42         Vector pRelative(p - translation);
43         v += pRelative.Rotate90() * angularVelocity;
44         return v;
45 }
46
47
48 void Entity::Rotate(Scalar d) {
49         rotation += d;
50         shape->Rotate(d);
51 }
52
53 void Entity::Translate(const Vector &d) {
54         translation += d;
55         shape->Translate(d);
56 }
57
58 void Entity::Accelerate(const Vector &dvl, Scalar dva) {
59         linearVelocity += dvl;
60         angularVelocity += dva;
61 }
62
63
64 void Entity::CollisionResponse(Entity &a, const Ray &na, Entity &b) {
65         if (a.mass == numeric_limits<Scalar>::infinity()
66                         && b.mass == numeric_limits<Scalar>::infinity()) {
67                 // special case: collision of two infinitely heavy entities
68                 InfInfCollisionResponse(a, na, b);
69                 return;
70         }
71
72         const Scalar e(1);
73
74         const Vector va(a.LinearVelocity());
75         const Vector vb(b.LinearVelocity());
76         const Scalar wa(a.AngularVelocity());
77         const Scalar wb(b.AngularVelocity());
78
79         const Vector vap(a.VelocityAt(na.Origin()));
80         const Vector vbp(b.VelocityAt(na.Origin()));
81         const Vector vab = vap - vbp;
82
83         const Vector rap90((na.Origin() - a.Origin()).Rotate90());
84         const Vector rbp90((na.Origin() - b.Origin()).Rotate90());
85
86         const Scalar ia(a.Mass());
87         const Scalar ib(b.Mass());
88
89         const Scalar rap90dotN(rap90.Dot(na.Direction()));
90         const Scalar rbp90dotN(rbp90.Dot(na.Direction()));
91
92         const Scalar j(
93                         (((-(1 + e)) * vab).Dot(na.Direction()))
94                         / (na.Direction().Dot(na.Direction() * ((1.0 / a.Mass()) + (1.0 / b.Mass())))
95                                         + ((rap90dotN * rap90dotN) / ia)
96                                         + ((rbp90dotN * rbp90dotN) / ib) ));
97
98         const Vector va2(va + ((j / a.Mass()) * na.Direction()));
99         const Vector vb2(vb - ((j / b.Mass()) * na.Direction()));
100         const Scalar wa2(wa + ((rap90.Dot(j * na.Direction())) / ia));
101         const Scalar wb2(wb - ((rbp90.Dot(j * na.Direction())) / ib));
102
103         a.linearVelocity = va2;
104         a.angularVelocity = wa2;
105         b.linearVelocity = vb2;
106         b.angularVelocity = wb2;
107 }
108
109 void Entity::InfInfCollisionResponse(Entity &a, const Ray &na, Entity &b) {
110         // If both elements are standing still or both are moving, move them away
111         // from each other. Otherwise, move the moving one.
112         if ((a.linearVelocity == Vector() && b.linearVelocity == Vector())
113                         || (a.linearVelocity != Vector() && b.linearVelocity != Vector())) {
114                 a.Translate(na.Direction());
115                 b.Translate(-na.Direction());
116                 Ray n;
117                 while (a.shape->CheckCollision(*b.shape, n)) {
118                         a.Translate(n.Direction());
119                         b.Translate(-n.Direction());
120                 }
121         } else if (a.linearVelocity == Vector()) {
122                 b.Translate(-na.Direction());
123                 Ray n;
124                 while (b.shape->CheckCollision(*a.shape, n)) {
125                         b.Translate(n.Direction());
126                 }
127         } else {
128                 a.Translate(na.Direction());
129                 Ray n;
130                 while (a.shape->CheckCollision(*b.shape, n)) {
131                         a.Translate(n.Direction());
132                 }
133         }
134 }
135
136 }