1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
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#ifndef HEADER_SUPERTUX_COLLISION_COLLISION_HPP
18#define HEADER_SUPERTUX_COLLISION_COLLISION_HPP
19
20#include <limits>
21#include <algorithm>
22
23#include "collision/collision_hit.hpp"
24
25class Vector;
26class Rectf;
27class AATriangle;
28
29namespace collision {
30
31class Constraints final
32{
33public:
34 Constraints() :
35 ground_movement(),
36 hit(),
37 position_left(),
38 position_right(),
39 position_top(),
40 position_bottom(),
41 speed_left(),
42 speed_right(),
43 speed_top(),
44 speed_bottom()
45 {
46 float infinity = (std::numeric_limits<float>::has_infinity ?
47 std::numeric_limits<float>::infinity() :
48 std::numeric_limits<float>::max());
49 position_left = -infinity;
50 position_right = infinity;
51 position_top = -infinity;
52 position_bottom = infinity;
53
54 speed_left = -infinity;
55 speed_right = infinity;
56 speed_top = -infinity;
57 speed_bottom = infinity;
58 }
59
60 bool has_constraints() const
61 {
62 float infinity = (std::numeric_limits<float>::has_infinity ?
63 std::numeric_limits<float>::infinity() :
64 std::numeric_limits<float>::max());
65 return
66 position_left > -infinity ||
67 position_right < infinity ||
68 position_top > -infinity ||
69 position_bottom < infinity;
70 }
71
72public:
73
74 void constrain_left (float position, float velocity)
75 {
76 position_left = std::max (position_left, position);
77 speed_left = std::max (speed_left, velocity);
78 }
79
80 void constrain_right (float position, float velocity)
81 {
82 position_right = std::min (position_right, position);
83 speed_right = std::min (speed_right, velocity);
84 }
85
86 void constrain_top (float position, float velocity)
87 {
88 position_top = std::max (position_top, position);
89 speed_top = std::max (speed_top, velocity);
90 }
91
92 void constrain_bottom (float position, float velocity)
93 {
94 position_bottom = std::min (position_bottom, position);
95 speed_bottom = std::min (speed_bottom, velocity);
96 }
97
98 float get_position_left () const { return position_left; }
99 float get_position_right () const { return position_right; }
100 float get_position_top () const { return position_top; }
101 float get_position_bottom () const { return position_bottom; }
102
103 float get_height () const { return (position_bottom - position_top); }
104 float get_width () const { return (position_right - position_left); }
105
106 float get_x_midpoint () const { return (.5f * (position_left + position_right)); }
107
108 Vector ground_movement;
109 CollisionHit hit;
110
111private:
112 float position_left;
113 float position_right;
114 float position_top;
115 float position_bottom;
116
117 float speed_left;
118 float speed_right;
119 float speed_top;
120 float speed_bottom;
121};
122
123/** checks if 2 rectangle intersect each other */
124bool intersects(const Rectf& r1, const Rectf& r2);
125
126/** does collision detection between a rectangle and an axis aligned triangle
127 * Returns true in case of a collision and fills in the hit structure then.
128 */
129bool rectangle_aatriangle(Constraints* constraints, const Rectf& rect,
130 const AATriangle& triangle, const Vector& addl_ground_movement = Vector(0,0));
131
132void set_rectangle_rectangle_constraints(Constraints* constraints,
133 const Rectf& r1, const Rectf& r2, const Vector& addl_ground_movement = Vector(0,0));
134
135bool line_intersects_line(const Vector& line1_start, const Vector& line1_end, const Vector& line2_start, const Vector& line2_end);
136bool intersects_line(const Rectf& r, const Vector& line_start, const Vector& line_end);
137
138} // namespace collision
139
140#endif
141
142/* EOF */
143