1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE a_modes.inc}
17 // some geometry utilities
20 interface
23 // do line clipping; returns `false` if line is outside of the box
26 // returns `true` if there is an intersection (if starting point is inside the box, it counts as intersection)
29 // you are not supposed to understand this
30 // returns `true` if there is an intersection, and enter coords
31 // enter coords will be equal to (x0, y0) if starting point is inside the box
32 // if result is `false`, `inx` and `iny` are undefined
33 function lineAABBIntersects (x0, y0, x1, y1: Integer; bx, by, bw, bh: Integer; out inx, iny: Integer): Boolean;
35 type
39 // sweep two AABB's to see if and when they are overlapping
40 // returns `true` if collision was detected (but boxes aren't overlap)
41 // `u1` and `u1` has no sense if no collision was detected (`hitx` and `hity` either)
42 // u0 = normalized time of first collision (i.e. collision starts at myMove*u0)
43 // u1 = normalized time of second collision (i.e. collision stops after myMove*u1)
44 // hitedge for `it`: it will probably be `None` if no collision was detected, but it is not guaranteed
45 // enter/exit coords will form non-intersecting configuration (i.e. will be before/after the actual collision)
46 // but beware of floating point inexactness; `sweepAABB()` will try to (crudely) compensate for it
47 // while calculating `hitx` and `hity`.
48 function sweepAABB (mex0, mey0, mew, meh: Integer; medx, medy: Integer; itx0, ity0, itw, ith: Integer;
55 implementation
58 // ////////////////////////////////////////////////////////////////////////// //
59 function distanceSq (x0, y0, x1, y1: Integer): Integer; inline; begin result := (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0); end;
62 // ////////////////////////////////////////////////////////////////////////// //
64 const
72 begin
78 var
82 begin
87 begin
93 begin
96 end
98 begin
101 end
103 begin
106 end
108 begin
113 begin
117 end
118 else
119 begin
128 // returns `true` if there is an intersection (if starting point is inside the box, it counts as intersection)
130 var
132 begin
135 if (x0 >= bx) and (y0 >= by) and (x0 < bx+bw) and (y0 < by+bh) then begin result := true; exit; end;
142 // returns `true` if there is an intersection, and enter coords
143 // enter coords will be equal to (x0, y0) if starting point is inside the box
144 // if result is `false`, `inx` and `iny` are undefined
145 function lineAABBIntersects (x0, y0, x1, y1: Integer; bx, by, bw, bh: Integer; out inx, iny: Integer): Boolean;
146 var
148 begin
153 if (x0 >= bx) and (y0 >= by) and (x0 < bx+bw) and (y0 < by+bh) then begin result := true; exit; end;
158 begin
161 // hack!
164 end
165 else
166 begin
173 // ////////////////////////////////////////////////////////////////////////// //
174 function sweepAABB (mex0, mey0, mew, meh: Integer; medx, medy: Integer; itx0, ity0, itw, ith: Integer;
177 var
181 var
183 begin
187 begin
191 end
193 begin
200 begin
203 end
205 begin
213 var
216 begin
231 // check if they are overlapping right now (SAT)
232 //if (mex1 >= itx0) and (mex0 <= itx1) and (mey1 >= ity0) and (mey0 <= ity1) then begin result := true; exit; end;
236 // treat b as stationary, so invert v to get relative velocity
250 begin
253 begin
256 // just in case, compensate for floating point inexactness
258 begin