Simple Intersection Tests For Games (์์ญ)
[์๋ฌธ]
http://www.gamasutra.com/view/feature/131790/simple_intersection_tests_for_games.php?page=1
๋น์ ์ ์ฐจ๊ฐ ์์ 180๋ง์ผ๋ก finish line์ ํต๊ณผํ๋ , ์ด์์ด ๋น์ ์ ์น์ ๊ฐ์ด์ ๊ฟฐ๋ซ๋ , ๋ชจ๋ ๊ฒ์์ Object Intersection์์๋ ์ถฉ๋ํ์ง๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด ๊ธฐ์ฌ๋ ๋๋ถ๋ถ์ ํ์(Shape)์ ํ์ฉ๋๋ ๋ช๊ฐ์ง ๊ฐ๋จํ Intersection Test๋ฅผ ์๊ฐํฉ๋๋ค. => [Sphere, Box]
Sweep Tests for Moving Objects
Collision Detection์ ๊ฐ์ฅ ๊ณตํต์ ์ธ ์ ๊ทผ๋ฒ์๋งค Frame์ด ๋๋ ๋, ๋ ๋ฌผ์ฒด๊ฐ Overlap๋๋์ง๋ฅผ ํ ์คํธ ํ๋ ๊ฒ์ ๋๋ค.
๋ฌธ์ ๋ ์ด ๋ฐฉ๋ฒ์ด ๋ ๋์์ด ์๋ก ๋น ๋ฅด๊ฒ ์์ง์ด๋ฉด์ ๊ต์ฐจํ ๋, ํ์งํ์ง ๋ชปํ ์๋ ์๋ค๋ ๊ฒ์ ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํผํ๊ธฐ ์ํด, ๋ฌผ์ฒด๋ค์ ๊ถค์ ์ ์๊ฒ ๋ถํ ํ ๋ค์, ๋งค Point์์ Check ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ ๋ฌผ์ฒด์ (Frame ์ฌ์ด) ์ด๋ ๊ฐ๊ฒฉ์ด ๋์ ๊ฒฝ์ฐ, ๋๋ฌด ๋น์ผ ๋น์ฉ์ ์ง๋ถํด์ผ ํฉ๋๋ค.
๋ฐ๋ฉด์, Sweep Test๋ ํจ์จ์ ์ผ๋ก (๋ฌผ์ฒด๊ฐ) Overlap๋๋ ์๊ฐ ๊ฐ๊ฒฉ์ ๊ฒฐ์ ํ ์ ์๊ณ , ์ด๋ Subdivision ์๊ณ ๋ฆฌ์ฆ์์ ์ต์ ์ ์์์ ์ผ๋ก ์ด์ฉ๋ ์ ์์ต๋๋ค.
A Sphere-Plane Sweep Test
[Figure1. ํ๋ฉด์ ํต๊ณผํ๋ ๊ตฌ]
์์ ๊ทธ๋ฆผ์, ํ๋ฉด์ ๋น ๋ฅด๊ฒ ๊ฐ๋ก์ง๋ฅด๋ ๊ตฌ์ ์๋ฅผ ๋ณด์ฌ์ค๋๋ค.
์ด๋ ์ C0๊ฐ ํ๋ฉด์ positive side์, ์ C1๊ฐ negative side์ ์๋ ๊ฒ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก, ๊ตฌ๊ฐ (Frame์ ์ด๋ ์์ ์) ํ๋ฉด์ ๊ฐ๋ก์ง๋ฅผ ๋, d0 > r ์ด๊ณ d1 < r ์
๋๋ค.
(r์ ๊ตฌ์ ๋ฐ์ง๋ฆ, d0๊ณผ d1์ ์ c0, c1์์ ํ๋ฉด๊น์ง์ ๊ฑฐ๋ฆฌ)
์ด์ , ์ C์์ ํ๋ฉด๊น์ง์ (signed)distance๋ ํด๋น ๊ณต์์ผ๋ก ์ป์ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ข ๋ ํจ์จ์ ์ผ๋ก, ์ฐ๋ฆฌ๋ ํ๋ฉด์ {n, D}์ด๋ผ๋ ํํ๋ก ์ ๋ฆฌํ ์ ์์ง์.
ํํธ, ์ C0 -> C1 ๊น์ง์ ๊ถค์ ์ u๋ผ๋ ๋ณ์๋ฅผ ํตํด ํ๋ผ๋ฉํฐํ ํ ์ ์์ต๋๋ค.
์ด ๋ณ์๋ ์ C0์์์ ๊ฐ์ด 0, ์ C1์์์ ๊ฐ์ด 1์ด๊ธฐ ๋๋ฌธ์,
์ ๊ทํ๋ ์๊ฐ(๋ณ์)๋ก ๊ฐ์ฃผํ ์ ์์ต๋๋ค.
(์ ๊ทํ๋ ์๊ฐ์์) ๊ตฌ๊ฐ ์ฒ์ ํ๋ฉด๊ณผ ๊ต์ฐจํ๋ ์์ ์, ์ด๋ ๊ฒ ํํ ๊ฐ๋ฅํฉ๋๋ค.
์ด ์์ (ui)์์ ๊ตฌ์ ์ค์ฌ์, ์ C0์ C1์ ์ํ๊ฒฐํฉ์ผ๋ก ๋ณด๊ฐ(interpolation)๋ ์ ์์ต๋๋ค.
์์ ๊ณต์์ d0๊ฐ d1๊ณผ ๋ค๋ฅด๋ค๋ ์กฐ๊ฑด ํ์ (displacement(๋ณ์ ์ด๋)๊ฐ ๋ฐ์ํ๋ ์กฐ๊ฑด)
Ci๋ฅผ ์ ํํ ๋ณด๊ฐํฉ๋๋ค. r=0 ์ผ ๋ ์กฐ์ฐจ๋์(line segment์ธ ๊ฒฝ์ฐ)
์ํ๋ค๋ฉด, ํ๋ผ๋ฉํฐ u๋ ๋ํ ํด๋น ์ ์์ ๋ฌผ์ฒด์ ๋ฐฉํฅ์ ์ ํ๋ณด๊ฐ ํ๋๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
ํด๋น ์๋ฅผ ํตํด, ๊ตฌ๋ ํ๋ฉด์ positive side๋ก๋ถํฐ ์ ๊ทผํ๊ณ , C0 ์ง์ ์์ ํ๋ฉด์ ๊ดํตํ์ง ์์๋ค๋ ์ฌ์ค์ ์ ์ ์์ต๋๋ค.
์ด์ frame์์ ์ด๋ฏธ ๊ดํต์ด ์ด๋ค์ก์์ ๊ฐ์ ํ case๋ผ๋ฉด, |d0| <= r ์ด๋ผ๋ ์กฐ๊ฑด์ด ์ฑ๋ฆฝํด์ผ ํฉ๋๋ค.
Listing 1์ ์ด sphere - plane sweep ํ
์คํธ์ ๊ตฌํ๋ถ์
๋๋ค.
[๋ฒ์ญ ์ถ๊ฐ ์ค์ ๋๋ค --]
[๋ฒ์ญ ์ถ๊ฐ ์ค์ ๋๋ค --]
Listing 1. A sphere-plane sweep test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#include "vector.h"
class PLANE
{
public:
VECTOR N;
//unit normal
SCALAR D;
//distance from the plane to the origin from a
//normal and a point
PLANE(const VECTOR& p0, const VECTOR& n) : N(n), D(-N.dot(p0))
{}
//from 3 points
PLANE(const VECTOR& p0, const VECTOR& p1,
const VECTOR& p2) : N((p1 - p0).cross(p2 - p0).unit()),
D(-N.dot(p0))
{}
//signed distance from the plane topoint 'p' along
//the unit normal
const SCALAR distanceToPoint(const VECTOR& p) const
{
return N.dot(p) + D;
}
};
const bool SpherePlaneSweep
(
const SCALAR r, //sphere radius
const VECTOR& C0, //previous position of sphere
const VECTOR& C1, //current position of sphere
const PLANE& plane, //the plane
VECTOR& Ci, //position of sphere when it first touched the plane
SCALAR& u //normalized time of collision
)
{
const SCALAR d0 = plane.distanceToPoint(C0);
const SCALAR d1 = plane.distanceToPoint(C1);
//check if it was touching on previous frame
if (fabs(d0) <= r)
{
Ci = C0;
u = 0;
return true;
}
//check if the sphere penetrated during this frame
if (d0 > r && d1 < r)
{
u = (d0 - r) / (d0 - d1); //normalized time
Ci = (1 - u)*C0 + u*C1; //point of first contact
return true;
}
return false;
}
| cs |
๋๊ธ
๋๊ธ ์ฐ๊ธฐ