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
Kuras
[Figure1. ํ‰๋ฉด์„ ํ†ต๊ณผํ•˜๋Š” ๊ตฌ]


 ์œ„์˜ ๊ทธ๋ฆผ์€, ํ‰๋ฉด์„ ๋น ๋ฅด๊ฒŒ ๊ฐ€๋กœ์ง€๋ฅด๋Š” ๊ตฌ์˜ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
์ด๋Š” ์  C0๊ฐ€ ํ‰๋ฉด์˜ positive side์—, ์  C1๊ฐ€ negative side์— ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
 ์ผ๋ฐ˜์ ์œผ๋กœ, ๊ตฌ๊ฐ€ (Frame์˜ ์–ด๋Š ์‹œ์ ์—) ํ‰๋ฉด์„ ๊ฐ€๋กœ์ง€๋ฅผ ๋•Œ, d0 > r ์ด๊ณ  d1 < r ์ž…๋‹ˆ๋‹ค.
 (r์€ ๊ตฌ์˜ ๋ฐ˜์ง€๋ฆ„, d0๊ณผ d1์€ ์  c0, c1์—์„œ ํ‰๋ฉด๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ)


์ด์ œ, ์  C์—์„œ ํ‰๋ฉด๊นŒ์ง€์˜ (signed)distance๋Š” ํ•ด๋‹น ๊ณต์‹์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.







๊ทธ๋ฆฌ๊ณ  ์ข€ ๋” ํšจ์œจ์ ์œผ๋กœ, ์šฐ๋ฆฌ๋Š” ํ‰๋ฉด์„ {n, D}์ด๋ผ๋Š” ํ˜•ํƒœ๋กœ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€์š”.

 


๊ทธ๋Ÿผ, ๊ฑฐ๋ฆฌ d๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

 



 ํ•œํŽธ, ์  C0 -> C1 ๊นŒ์ง€์˜ ๊ถค์ ์€ u๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ํŒŒ๋ผ๋ฉ”ํ„ฐํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 
์ด ๋ณ€์ˆ˜๋Š” ์  C0์—์„œ์˜ ๊ฐ’์ด 0, ์  C1์—์„œ์˜ ๊ฐ’์ด 1์ด๊ธฐ ๋•Œ๋ฌธ์—, 
์ •๊ทœํ™”๋œ ์‹œ๊ฐ„(๋ณ€์ˆ˜)๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 (์ •๊ทœํ™”๋œ ์‹œ๊ฐ„์—์„œ) ๊ตฌ๊ฐ€ ์ฒ˜์Œ ํ‰๋ฉด๊ณผ ๊ต์ฐจํ•˜๋Š” ์‹œ์ ์€, ์ด๋ ‡๊ฒŒ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


 ์ด ์‹œ์ (ui)์—์„œ ๊ตฌ์˜ ์ค‘์‹ฌ์€, ์  C0์™€ C1์˜ ์•„ํ•€๊ฒฐํ•ฉ์œผ๋กœ ๋ณด๊ฐ„(interpolation)๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
(์ฐธ๊ณ  ๋งํฌ - https://blog.naver.com/jspark_/220405026284)



์œ„์˜ ๊ณต์‹์€ 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
















๋Œ“๊ธ€

์ด ๋ธ”๋กœ๊ทธ์˜ ์ธ๊ธฐ ๊ฒŒ์‹œ๋ฌผ

(์˜์—ญ) Separating Axis Theorem(SAT) ์„ค๋ช…

Visual Studio์—์„œ Cocos2d-x ์ฝ˜์†”์ฐฝ ๋กœ๊ทธ ๋„์šฐ๊ธฐ

์‚ฌ์šฉ์ž ์ •์˜ ํด๋ž˜์Šค์˜ ๋‚ด์šฉ์„ ์œ ๋‹ˆํ‹ฐ Inspector์— ๋ณด์ด๊ฒŒ ํ•˜๊ธฐ