hwi's laboratory  
Front Page
Tag | Location | Media | Guestbook | Admin   
 
강체 시뮬레이션(Rigid Body Simulation)

공개물리엔진과 책들을 참고해서 강체 시뮬레이션을 구현했다.

충돌 검출 부분은 ODE, 물리 시뮬레이션 부분은 JigLib를 참고했다. 

박스와 박스, 박스와 삼각형 충돌의 경우 SAT 알고리즘을 사용하는 것이 효율적이다. 
박스와 구, 삼각형 이외 더 복잡한  Convex 객체들끼리의 충돌을 구하는 효율적인 알고리즘은 GJK + EPA 알고리즘이 있다.  Bullet이 GJK, EPA 부분에 대해 잘 나와있다.

서적은 국내에서 나온 게임 물리관련 여러 서적이 있지만, 그런 게임 물리 서적 보다는 '게임 인터렉티브 애플리케이션을 위한 수학' 책 뒷부분에 나오는 강체 처리 부분이 더 정리가 잘 되어 있다고 생각한다. 

전체적으로 설명과 소스까지 한번 쉽게 살펴보려면 Game Physics Engine Development(millington, morgan kaufmann) 이 책을 추천한다. 

사원수로 방위를 표현할 때 각속도로 방위를 갱신하는 식은 
q' = q +  dt  *1/2 wq
인데, 이 식의 증명은 Game Physics(David H. Eberly)에 나와있다. 

간단히 강체 시뮬레이션에서 몇가지 중요한 점만 살펴보자.

1. Collision Detection
충돌을 검출하는 부분으로, 단순히 충돌의 유무 뿐만 아니라
충돌점, 충돌법선, 투과깊이를 구해야한다. 이 3가지 정보로 충돌 처리를 수행할 수 있다.

2. Collision Resolve
충돌 해소에서 가장 직관적이고 간단한 방법은 impulse를 도입하는 것이다.
impulse는 아주 짧은 시간에 적용되는 큰 힘이라고 생각하면 된다. 시간에 상관없이 곧바로 강체의 속도를 바꾼다. 

impulse로 충돌을 처리하는 방법은 여러 방법이 있는데 충돌을 하나 하나씩 처리하는 방법이 가장 간단한다. 

충돌한 두 객체의 충돌정보(충돌점, 충돌법선, 투과깊이)를 이용해서 두 객체에 적용해야할 impulse 크기를 계산하고 impulse를 적용시키면 된다. 

impulse 크기 구하기.
1. unit impulse가 적용되었을 때 강체의 속도가 얼마나 변화하는 지를 계산한다.
2. 반발계수를 이용하면 충돌점에서의 상대 속도가 얼마나 변화해야하는 지를 알 수 있다.
u_rel' = -e * u_rel (u_rel : 충돌점에서의 상대속도)

3. [ u_rel' - u_rel ] 이 식은 우리가 구하고자하는 속도 변화량의 크기이다. 그러므로 impulse의 크기는 [(u_rel' - u_rel) / unit impulse당 속도변화량]이 된다. 

3. Contact Resolve
물리 시뮬레이션에서 제일 중요한 부분이 이 부분이다. 
강체를 계속 움직이게 하는건 쉬우나 가만히 있어야 하는 강체를 가만히 있게 하는 것이 더 어렵다. 
Contact는 반발이 되지 않는 Collision 이다. 즉 반발계수가 0이 되어야 한다. 
이 부분에서 강체가 서로 투과하지 않도록 하는 처리를 해주어야 한다. 

처리하는 알고리즘 자체는 Collision Resolve와 크게 다르지 않다.
impulse로 반발계수가 0인 충돌을 처리해야 한다. 

impulse는 속도변화와 관련되어 있으므로 투과깊이를 속도로 표현해야 한다. 시뮬레이션의 시간 변화량이 dt라고 할 때,

minSeparateVelocity = contact.penetrationDepth / dt

minSeparateVelocity가 투과 깊이를 속도로 표현한 양이다. 
즉, 강체가 서로 곂치지 않게 하려면 충돌점에서의 상대 속도가 최소한 저 속도의 크기 보다는 커야한다. 

그리고 Contact를 처리해야 하므로 두 점의 상대 속도가 minSeparateVelocity의 크기가 되도록 해야한다.

따라서 impulse의 크기는 (minSeparateVelocity - u_rel)  / unit impulse당 속도변화량) 가 된다. 

주의할 점은 이렇게만 처리하면 작은 떨림이 지속적으로 발생한다. 

예를들면, 박스와 평면의 충돌시 박스 하단의 4점이 충돌점이 되는데, 충돌점 하나를 처리하면 나머지 3개의 충돌점의 상대 속도가 바뀌고, 원래 적용해야할 impuse보다 더 큰 impulse가 필요해진다. 이러한 현상이 계속되어 떨림이 멈추지가 않는다.

위 현상을 최소화 하기위해서는 적용시킬 impulse를 작게해서 한번에 밀어내지 말고 여러번에 걸쳐 조금씩 밀어내는 방법이 있다.(JigLib 참고) 

참고 : 
4. Game Physics Engine Development(millington, morgan kaufmann)



BLOG main image
 Notice
 Category
분류 전체보기 (27)
life (0)
project (0)
works (24)
misc (0)
study (1)
scrap (1)
review (0)
... (0)
study_cg (0)
 TAGS
CEDEC
 Calendar
«   2024/05   »
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
 Recent Entries
 Recent Comments
 Recent Trackbacks
 Archive
 Link Site
바보가 아닌 Mr
V i n t e r s o r g
 Visitor Statistics
Total :
Today :
Yesterday :
rss