12.1 게임에서 물리가 필요한가?

밧줄, 머리카락, 의복 등에 물리적인 동작을 더하면 독특한 게임 효과를 낼 수 있다.

 

12.1.1 물리 시스템으로 할 수 있는 일

ㄴ 동적 객체와 정적 게임 월드 간의 충돌을 검출

ㄴ 중력이나 기타 힘들의 영향을 받아 자유롭게 움직이는 강체 시뮬레이션 스프링 질량계 (spring-mass-system)

ㄴ 부서지는 빌딩과 구조물

ㄴ 레이 캐스트(ray cast) 와 형상 캐스트(shape cast)

ㄴ 트리거 볼륨(Trigger Volume : 게임 월드의 지정된 지역에 물체가 진입하거나 떠나는 순간을 비롯해 그 안에 자리하고 있는지 등을 판별)

ㄴ 캐릭터가 단단한 물건을 집어 드는 기능

ㄴ 복잡한 기계류 (크레인, 움직이는 플랫폼 퍼즐 등)

ㄴ 래그 돌

ㄴ 움직일 수 있는 소품들과 사실에 근접한 머리카락 및 의복의 움직임

ㄴ 물 표면 시뮬레이션과 부력

ㄴ 오디오 전달

 

게임에서 런타임에 물리 시뮬레이션을 수행하는 방법 외에도 오프라인 전처리를 통해 애니메이션 클립을 만드는 과정에서도 물리 시뮬레이션을 응용할 수 있다.

 

12.1.2.1 시뮬레이션 게임

시뮬레이션 게임의 주 목적은 가능한 한 실제와 가까운 경험을 재현하는 것이기 때문에 강체 역학 시스템을 이용해 얻을 수 있는 사실감은 게임에 큰 도움이 된다.

 

12.1.2.2 물리 퍼즐 게임

물리 퍼즐 게임의 핵심은 게이머가 역학적으로 시뮬레이션되는 장난감들을 이리저리 갖고 놀게 하는 것이다. 물리가 꼭 필요하다.

 

12.1.2.3 샌드박스 게임

샌드박스 게임에서 플레이어의 주 목적은 이리저리 돌아다니면서 게임 월드의 물건들로 무엇을 할 수 있는지 탐험하는 것이다. 재미를 위해 사실성을 다소 희생하는 경우도 많다. (실제보다 과하게 묘사)

 

12.1.2.4 목적 중심 게임과 스토리 중심 게임

물리 시스템과는 잘 맞지 않는 편이다.

 

12.1.3 물리가 게임에 미치는 영향

12.1.3.1 디자인에 미치는 영향

ㄴ 예측 가능성을 저해한다.

ㄴ 튜닝과 컨트롤이 어렵다. 

 

원칙적으로는 게임 디자인을 먼저 고르고 물리 시뮬레이션을 넣을지 말지 정해야 한다.

 

12.1.3.2 엔지니어링에 미치는 영향

툴 파이프라인

ㄴ 품질이 뛰어난 충돌/물리 파이프라인을 만들고 관리하는데 적잖은 시간이 걸린다.

 

유저 인터페이스

ㄴ 플레이어가 게임 월드의 물리 객체를 어떻게 컨트롤 할 것인지를 정해야 한다.

 

충돌 검출 역학

ㄴ 시뮬레이션에 사용될 충돌 모델은 그렇지 않은 모델보다 정교하고 조심해서 만들어야 한다.

 

AI

ㄴ 물리적으로 시뮬레이션되는 물체들이 섞여 있으면 길 찾기 결과를 정확히 예측하기 힘들 수 있다.

 

오동작하는 물체

ㄴ 물체들끼리 서로 살짝 뚫고 나갔을 때 의도치 않게 튕겨 나가거나 심하게 요동칠 수 있다.

 

래그 돌 물리

ㄴ애니메이션에 의해 캐릭터 신체의 일부가 다른 충돌 볼륨을 뚫고 들어갈 수 있는데, 이 상태에서 래그 돌이 되면 매우 불안정한 상태를 야기할 수 있다.

 

그래픽

ㄴ 물리에 의해 발생하는 움직임은 화면에 그려지는 물체의 경계 볼륨을 변화시킬 수 있다.

ㄴ 미리 계산된 조명이나 그림자를 쓰기 어려울 수 있다.

 

네트워크와 멀티 플레이어

ㄴ 게임 플레이에 전혀 영향이 없는 물리 효과라면 각 게임 클라이언트에서 따로 계산해도 되지만, 게임 플레이에 영향을 미치는 물리, 예를 들면 수류탄의 궤적 같은 경우는 서버에서 계산한 후, 각 클라이언트에서 정확히 재현해야 한다.

 

녹화와 재생

ㄴ 역학 시뮬레이션과 녹화 재생 기능을 함께 구현하는 것은 어렵다. 시뮬레이션의 무질서한 특성과 물리 계산의 업데이트 타이밍이 달라질 경우 다시 재생한 장면이 원래 녹화된 것과 달라질 수 있기 때문이다.

 

12.1.3.3 아트에 미치는 영향

추가적인 도구와 작업 과정에 의한 복잡도 증가

ㄴ 역학 시뮬레이션에 사용될 물체의 질량, 마찰 계수, 제약조건 및 기타 속성들은 아트 팀의 작업을 복잡하게 만든다.

 

더 복잡한 컨텐츠

ㄴ 외형은 똑같지만 충돌 및 역학 설정이 다른 물체를 여러 개 만들어 다른 목적으로 써야할 수 있다.

ㄴ 예를 들어 원래 형태와 파괴할 수 있는 형태 두 가지를 만들어야 할 수도 있다.

ㄴ 물체 주도 물체는 예측 불가능할 수 있기 때문에 장면의 미적인 구성을 유지하도록 통제하기 힘들 수 있다.

 

12.1.3.4 기타 영향

ㄴ 엔진지어링, 아트, 기획 부서의 긴밀한 협업이 필요하다. (= 프로젝트의 개발 비용이 증가한다.)

 

12.2 충돌/물리 미들웨어

12.2.1 I-Collide, SWIFT, V-Collide, RAPID

I-Collide (SWIFT로 대체됨)

ㄴ 노스 캐롤라이나 대학에서 개발한 오픈소스 충돌 검출 라이브러리

ㄴ 볼록 다면체들 간의 교차를 검출할 수 있다.

 

V-Collide, RAPID

ㄴ 복잡하지만 볼록하지 않은 다면체들도 처리할 수 있는 라이브러리

 

라이브러리들을 바로 게임 엔진에서 사용할 수는 없지만 게임에 사용할 수 있는 완전한 충돌 시스템을 구현하는데 훌륭한 기반이 될 수 있다.

12.2.2 ODE (Open Dynamics Engine)

오픈소스 충돌 및 강체 역학 SDK (공짜)

모든 소스 코드가 공개되어 있다.

 

12.2.3 불릿

게임 산업과 영화 산업에서 모두 쓰이는 오픈소스 충돌 검출 및 물리 라이브러리

충돌 엔진과 역학 시뮬레이션은 통합되어 있지만 충돌 시스템만 따로 사용하거나 다른 물리 엔진과 같이 사용할 수 있는 기능을 제공한다.

연속 충돌 검출 방식(Continuous collision detection)을 지원한다.

12.2.4 Vi TrueAxis

비상업적인 용도로는 무료로 쓸 수 있는 충돌/물리 SDK

 

12.2.5 Physx

비용을 지불하면 모든 소스코드와 라이브러리를 필요에 의해 수정할 수 있다.

 

12.2.6 하복

오늘날 상용 물리 SDK 중 가장 확고한 위치를 점하고 있으며, 가장 다양한 기능들을 지원하고 모든 플랫폼에서 훌륭한 성능을 자랑한다. (가장 비싸다)

충돌/ 물리 엔진, 차량 물리 시스템, 파괴 가능 환경 모델링 시스템, 래그 돌 물리 시스템과 통합되면서 독립적인 애니메이션 SDK 등을 지원한다.

 

12.2.7 Physics Abstraction Layer

한 프로젝트 내에서 여러 개의 물리 SDK를 사용할 수 있는 오픈 소스 라이브러리다.

 

12.2.8 Digital Molecular Matter(DMM)

한정된 방법을 사용해 모양이 변하고 파괴 가능한 물체를 시뮬레이션하는 물리 엔진이다. 오프라인 기능과 런타임 기능을 모두 지원한다.

 

12.3 충돌 검출 시스템

게임 엔진이 물리 검출 시스템을 사용하는 주된 목적은 게임 월드의 물체들이 서로 접촉을 했느냐를 알아내는 것이다.

이를 위해 검출이 필요한 모든 물체를 하나 이상의 기하적인 형태로 표현해야 한다. 충돌 시스템은 주어진 시간에 이런 형태들이 교차하는지 판별한다.

 

충돌 시스템은 단순히 교차 여부만 판별하는 것이 아니라 의미 있는 정보도 제공한다. 접촉 정보는 물체가 서로 뚫고 들어가는 부자연스러운 시각 효과를 방지하는데 쓰인다. 보통 다음 프레임을 그리기 전에 뚫고 들어간 물체들을 서로 떨어지게 만드는 방식을 이용한다.

 

충돌 시스템이 가장 중요하게 사용되는 분야는 강체 역학 시뮬레이션인데, 물체가 튕겨 나가거나 미끄러지거나 멈추는 등 사실적인 물리 현상을 재현하는 용도로 사용된다.

 

12.3.1 충돌 단위

교차 검사에서는 대개 기하학적으로나 수학적으로 단순한 형상을 선호한다. 

바위를 구로 나타낼 수도 있고 자동차의 후드는 사각 박스 형태로 나타낼 수도 있다.

 

이런 단순한 표현으로 원하는 효과를 얻을 수 없을 때만 더 복잡한 형상을 사용해야 한다.

 

하복에서 충돌 검출에 사용하는 독립된 강체를 충돌체라고 부른다. (C++ 클래스 khpCollidable의 인스턴스)

PhysX에서는 강체를 액터라고 부른다. (C++ 클래스 NxActor의 인스턴스)

 

충돌체는 두 가지 중요한 정보를 포함한다. (형상과 변환)

형상은 충돌체의 기하학적인 형태(캡슐, 구, 직육면체)를 나타내고

변환은 게임 월드 안에서의 위치와 방향을 나타낸다.

 

충돌체에 변환 정보가 필요한 이유

ㄴ 형상은 객체의 생긴 모양을 뜻할 뿐이기 때문에 제대로 쓰이려면 월드 공간에서 제 위치와 방향을 갖게 변환해야한다.

ㄴ 복잡한 형상을 구성하는 요소(여러 개의 점과 평면으로 구성된)을 일일이 움직이려면 느리기 때문

ㄴ 어느 정도 복잡한 형상을 나타내는 데 필요한 정보는 적잖은 메모리를 차지할 수 있는데, 하나 이상의 충돌체가 동일한 형상 정보를 공유할 수 있다면 변환 정보만 다르게 하여 여러 개의 충돌체를 정의 할 수 있다. 

 

게임 객체 중에는 충돌체가 전혀 없는 것도 있고 한 개를 갖고 있는 경우도 있고 여러 충돌체로 이루어진 경우도 있다.

 

12.3.2 충돌/물리 월드

일반적으로 충돌 시스템은 모든 충돌체를 관리하기 위해 충돌 월드라 불리는 싱글턴 자료 구조를 이용한다.

하복에서 충돌 월드는 hkpWorld 클래스의 인스턴스, PhysX의 충돌 월드는 NxScene의 인스턴스

충돌 월드는 게임의 모든 충돌체를 나타내는 기하학적 입체의 계층 구조에서 루트가 된다.

 

각 게임 객체 안에 충돌 정보를 넣어 관리하기보다 충돌 정보를 별도의 자료 구조로 유지하면 얻을 수 있는 장점

ㄴ 다른 객체와 충돌할 가능성이 있는 객체의 충돌체만 충돌 월드에 갖고 있으면 된다.

ㄴ 충돌체를 최대한 효율적인 방식으로 조작할 수 있는 여지가 생긴다. (캐시 미스를 최소화)

ㄴ 효과적인 캡슐화 방식으로써 동작한다.

 

12.3.2.1 물리 월드

게임에 강체 역학 시스템이 있다면 물리 시뮬레이션의 움직이는 강체는 충돌 시스템의 충돌체 하나와 연결된다. 

하복에서 강체가 없는 충돌체는 존재할 수 있지만 강체는 충돌체 하나와 대응(참조)되어야 한다.

두 SDK에서 강체의 위치와 방향을 고정시킬 수 있는데 이렇게 하면 강체는 역학 시뮬레이션에는 참여하지 않고 충돌체 역할만 한다는 뜻이다.

 

대부분의 SDK에서는 충돌 라이브러리와 강체 역학 시뮬레이션을 분리하는데 이렇게 하면 물리를 사용하지는 않지만 충돌 검출 기능은 사용하는 게임에서 이점을 얻기 때문이다.

 

12.3.3 형상의 개념

형상은 경계에 의해 둘러싸이고 분명히 안과 밖이 있는 공간이다. 게임 객체 중 많은 것들이 면으로 표현된다. (지형, 강, 얇은 벽 등) 하지만 면으로는 안과 밖을 표현할 수 없기 때문에 대부분의 충돌 SDK는 면을 기본 단위로 지원하고 형상 개념을 확장해 닫힌 공간과 열린 면을 모두 다룰 수 있게 한다.

 

일반적으로 충돌 라이브러리는 옵션으로 밀어내기 값을 주어 면이 부피를 갖게 한다. 이 값은 면이 얼마나 두꺼운지를 지정한다. 이렇게 하면 작고 빠르게 움직이는 물체가 극히 얇은 면을 지날 때 충돌을 검출하지 못하는 문제를 줄일 수 있다.

 

12.3.3.1 교차

기하학적으로 두 형상의 교차는 두 형상 안에 공통으로 들어가는 모든 점(무수히 많은) 이라 할 수 있다.

 

12.3.3.2 접촉

게임에서는 교차를 찾을 때 엄격한 정의대로 점들의 집합이 필요한 것은 아니다. 단순히 두 물체가 서로 교차하는지 아닌지만 알면 된다.

 

일반적으로 충돌 시스템은 접촉 정보를 사용하기 편한 자료 구조에 모아 놓고, 접촉이 검출될 때마다 이 자료 구조를 생성한다. 접촉 정보는 다음과 같은 것들을 포함할 수 있다.

ㄴ 분리 벡터 (물체들을 움직여 충돌 상태에서 벗어나게 만들 수 있는 벡터)

ㄴ 접촉이 발생한 두 충돌체에 관한 정보

ㄴ 분리 벡터 방향으로 물체를 움직일 속도

 

12.3.3.3 볼록함

볼록한 형상은 형상 안에서 시작한 모든 반직선이 표면을 오직 한 번만 통과하는 성질이 있기 때문에 볼록 형상끼리 교차 검사하는 것이 오목 형상이 포함될 때보다 단순하면서 계산도 쉽다.

 

12.3.4 충돌 기본 단위

12.3.4.1 구

구의 정보는 중심과 반지름으로 이루어져 부동소수 4개로 이루어진 벡터에 넣어 SIMD 수학 라이브러리에 응용할 수 있다.

 

12.3.4.2 캡슐

원기둥 하나의 양쪽에 반구가 더해진 형태, 구가 지점 A에서 지점 B로 이동하는 동안의 흔적을 나타내는 입체인 스윕구라고 볼 수도 있다.

보통 두 점과 반지름 하나를 사용한다.

원기둥이나 박스보다 교차 검사가 쉽기 때문에 사람의 팔다리와 같이 원기둥과 유사한 형태의 물체를 모델링할 때 캡슐을 많이 사용한다.

 

12.3.4.3 축 정렬 경계 박스 AABB (axis-aligned bounding box)

AABB는 위치한 좌표계에 상대적인 개념으로만 설명할 수 있다.

AABB는 두 점으로 나타낼 수 있다. (좌표축을 기준으로 박스의 가장 최소 좌표, 최대 좌표)

물체가 박스 모양이고, 물체가 좌표계의 축과 대략적으로 평행일 때에만 잘 동작할 수 있다.

 

12.3.4.4 유향 경계 박스 (OBB, Oriented Bounding Box)

축 정렬 경계 박스에 좌표축을 기준으로 회전할 수 있게 한 것

너비, 깊이, 높이와 변환(회전, 위치) 정보가 필요하다.

 

12.3.4.5 DOP (AABB와 OBB를 일반화 한 개념 : Discrete Oriented Polytope)

DOP는 여러 개의 평면을 무한대에 위치시키고, 근사하려는 물체와 만날 때 까지 법선 방향으로 움직여 만든다.

AAOB는 각 평면의 법선이 좌표축에 평행한 성질을 가진 6-DOP

OBB는 각 평면의 법선이 물체의 고유 좌표축에 평행한 성질을 가진 6-DOP

 

12.3.4.6 임의의 형상을 한 볼록 입체

대부분의 충돌 엔진들은 임의의 형상을 한 볼록 입체도 지원한다. 이런 블록 입체들은 3D 아티스트가 마야 등의 도구를 이용해 만든다. 형상의 삼각형들은 평면의 집합으로 변환되는데, (K-DOP) 이는 평면식 k개로 나타낸다.

 

 

12.3.4.7 다각형(폴리곤) 수프

임의의 형태이고 볼록하지 않은 형상을 지원하는 충돌 시스템도 있다. 이 형상들은 대개 삼각형이나 다른 단순한 다각형으로 만든다. 그래서 다각형 혹은 폴리곤 soup라고 불린다.

 

다각형 수프는 보통 지형이나 빌딩과 같이 복잡하면서 정적인 형상을 모델링할 때 쓰인다.

 

형상들의 충돌 검출 중 다각형 수프에 대한 충돌 검출이 가장 오래 걸리기 때문에 대부분의 게임에서는 역학 시뮬레이션에 참여하지 않는 물체에만 다각형 수프를 사용하게 된다.

 

볼록한 다각형이나 단순한 형상들과는 달리 다각형 수프는 닫힌 공간 뿐만 아니라 열린 표면을 나타낼 수 있다.

 

다각형 수프와 어떤 물체가 충돌 상태에 있을 때 물체를 어느 방향으로 밀어낼지 정하기 위해서 다각형 수프를 이루는 삼각형의 정점 감김 정보를 사용할 수 있다.

 

12.3.4.8 복합 형상

볼록하지 않은 물체를 모델링할 때 다각형 수프보다 복합 형상이 효율적이 경우가 많다.

 

어떤 물리 엔진(하복) 에서는 복합 형상 전체의 볼륨 경계 볼륨(하위 형상들을 포함하는 상위 형상) 을 충돌 검사에 이용해 겹치지 않는다면 하위 형상들에 대한 검사를 하지 않는 방법을 사용한다. 이 과정을 중간 단계 층돌 검사라고 부른다.

 

12.3.5 충돌 검사와 해석 기하학

12.3.5.1 점과 구

점의 중심과 구의 중심의 차이 벡터의 크기를 구의 반지름과 비교

 

12.3.5.2 구와 구

두 구의 중심의 차이 벡터의 크기와 두 반지름의 합과 비교

 

12.3.5.3 분할 축 정리

두 볼록 형상을 한 축에 투영했을 때 투영한 이미지들이 겹치지 않는 축이 존재하면, 두 형상은 교차하지 않는다.

 

어떤 형상은 분할 축이 될만한 후보를 쉽게 찾을 수 있는 특성이 있다

구와 구의 경우

ㄴ 두 구의 중심을 이은 선분과 평행한 축

 

12.3.5.4 AABB와 AABB

두 AABB가 서로 교차하는지 알기 위해서는 마찬가지로 분할 축 정리를 이용한다.

AABB의 면들은 모두 동일한 좌표축에 평행하다는 성질이 있기 때문에 분할 축이 존재한다면 3 좌표축 중 하나라는 것을 알 수 있다.

각 AABB의 각 좌표축마다 최대 최소 좌표가 모두 겹치는 경우에만 두 AABB가 교차한다고 말할 수 있다.

 

12.3.5.5 볼록 형상들 간의 충돌 검출: GJK 알고리즘

교차하는 두 블록 형상의 민코프스키 차이는 원점을 포함하지만 교차하지 않는 형상은 그렇지 않다.

GJK 알고리즘은 반복적인 알고리즘으로 처음에는 민코프스키 차이의 껍데기 위에 있는 임의의 점 하나의 단체로 시작하여 점차 차수가 높은 단체를 만들어가면서 그 중에 원점을 포함할 수 있는 것을 찾으려 한다. 지금의 단체보다 원점에 더 가까운 받침 정점 (볼록한 껍데기 위 한 점)을 단체에 더한다. 이렇게 만든 단체가 원점을 둘러싸게 되면 끝난다. (교차함)

 

12.3.5.6 기타 형상 간의 교차 검사

형상과 형상의 교차를 말할 때 형상 종류가 N개 있으면 교차 검사의 수는 N의 제곱이 되기 때문에 충돌 엔진은 기본 단위 종류의 수를 제한한다. 

하지만 GJK는 모든 종류의 블록 형상들 간의 충돌 검출을 한 번에 처리할 수 있다. (알고리즘에서 사용하는 받침 함수만 형상에 따라 다르다.)

 

하복에서는 충돌 에이전트(hkCollisionAgent 클래스를 상속받는 클래스들)라는 객체들을 이용해 교차 테스트 종류를 결정한다.

충돌 에이전트 클래스에는 (hkpSphereSphereAgent, hkpSphereCapsuleAgent, hkpGskConvexConvexAgent) 등이 있다.

hkpCollisionDispatcher 클래스의 역할은 2차원 디스패치 테이블로 에이전트의 종류를 찾아 충돌체 둘을 에이전트의 인자를 넘겨 호출하는 것이다.

 

12.3.5.7 움직이는 물체 간의 충돌 검출

작고 빠른 물체는 프레임 사이에 다른 물체를 통과할 수 있는 문제가 있다. (터널링 문제)

 

해결 방법

1. 스윕 형상

ㄴ 궤적 형상을 이용하는 것 (구 -> 캡슐)

ㄴ 충돌체가 곡선을 그리며 움직이는 경우는 문제가 생긴다.

ㄴ 충돌체가 회전하는 경우에 스윕 형상을 만들면 볼록하지 않을 수 있어 선형 보외법을 사용하여 볼록하게 만들 수 있는데 이는 부정확하다.

 

2. 연속 충돌 검출 (CCD, Coutinuous Collision Detection)

ㄴ 주어진 시간 구간 내에서 움지깅는 두 물체 간의 가장 이른 충돌 시각을 찾는 것

ㄴ 두 충돌체의 이전 시간 단계(프레임 단위)와 현재 시간 단계의 위치와 방향을 선형 보간해서, 이전 시간 단계와 현재 시간 단계 사이에 있는 임의의 시각에서 충돌체의 변환을 대략적으로 계산할 수 있다.

그런 후 이 움직임 경로에서 가장 이른 TOI (time of impact) 를 검색한다.

 

12.3.6 성능 최적화

충돌 검출은 CPU를 많이 쓰는 작업이다.

ㄴ 두 형상이 교차하는지 알아내는데 필요한 계산 자체가 매우 복잡하다.

ㄴ 게임 월드에는 수많은 물체들이 있는 것이 보통인데, 교차 검사 횟수는 물체 수가 많아질수록 급격히 증가한다.

 

물체 n개가 있으면 단순한 방식에서는 모든 쌍을 검사하기 떄문에 알고리즘은 n의 제곱 복잡도를 갖는다. 

그렇기 때문에, 공간 해시, 공간 분할, 계층적 경계 볼륨 기법 등이 교차 검사 횟수를 줄이는데 사용된다.

 

12.3.6.1 시간적 일관성

시간적 일관성 (프레임 간 일관성) 기법은 충돌체가 완만한 속도로 움직이고 있다면 다음 프레임에서 충돌체의 위치와 방향을 예측할 수 있다는 점에서 사용한다. 

매 프레임마다 위치와 방향을 다시 계산하는 수고를 덜 수 있다.

하복의 충돌 에이전트(hkpCollisionAgent)는 여러 프레임에 걸쳐 지속적으로 쓰인다.

 

12.3.6.2 공간 분할

옥트리, 이진 공간 분할 트리, kd-트리 등의 다양한 계층 분할 방식들이 충돌 검출 최적화 과정에서 공간을 분할하는데 쓰이다.

 

12.3.6.3 넓은 단계, 중간 단계, 좁은 단계

하복에서는 매 시간 단계에서 검사해야 하는 충돌체들을 선별하는 데 세 가지 단계를 사용한다.

 

1. 대강의 AABB 테스트

2. 복합 형상들을 대강의 경계 볼륨으로 검사

3. 개별적인 충돌 단위들로 테스트

 

Sweep And Prune 알고리즘

ㄴ 주요 엔진(하복 Physx)들이 모두 넓은 단계 충돌 검출에서 사용하는 알고리즘이다.

ㄴ 충돌체들의 AABB에서 세 좌표축 방향으로 최댓값과 최솟값을 구한 후 정렬된 리스트를 탐색해 교차하는 AABB를 찾는 방식이다. Sweep And Prune 알고리즘은 프레임 간 일관성 기법을 이용해 정렬에 걸리는 복잡도를 O(n log n)에서 O(n)으로 줄일 수 있다.

 

12.3.7 충돌 질의

캐스트란 임의의 물체를 충돌 월드에 위치시킨 후 반직선 혹은 선분만큼 움직이는 동안 어떤 물체와 충돌하는지, 혹은 충돌하지 않았는지를 판별하는 것이다.

캐스트는 대상이 실제로 충돌 월드에 존재하지 않는다는 점에서 일반적인 충돌 검출 과정과는 다르다.

 

12.3.7.1 레이 캐스트

시작점과 끝점이 있는 선분을 충돌 월드의 충돌체들과 테스트한다.

선분은 점 하나와 델타 벡터 하나로 표현한다.

 

충돌 검출 시스템은 시작점에서 가장 가까운 접촉 정보를 리턴하는 경우도 있고 어떤 충돌 검출 시스템은 모든 충돌체들을 알려주기도 한다

 

12.3.7.2 형상 캐스트

구 캐스트 캡슐 캐스트 등 여러 종류를 사용할 수 있다.

시작점 + 델타 벡터 + 형상의 종류 + 크기 + 방향의 정보를 사용한다.

 

블록 형상을 캐스트할 때는 다음의 두 경우를 따져봐야 한다.

1. 캐스트할 형상이 다른 충돌체를 관통하거나 아니면 접촉하고 있어 시작점에서 움직일 수 없는 경우

ㄴ 시작 지점에서 충돌이 일어났는지 아닌지 충돌 시스템이 정보를 알려준다. 접촉 지점은 캐스트 형상의 안에 있을 수도 있고, 표면에 있을 수도 있다.

 

2. 캐스트할 형상이 시작점에서 다른 어떠한 충돌체와 교차하거나 만나지 않아서 움직일 수 있는 경우

ㄴ 다른 물체와 부딪힐 때까지 선분을 따라 이동할 수 있다. 

 

레이 캐스트와 마찬가지로 캐스트 형상의 최초의 접촉들(형상은 한번에 여러 충돌체와 교차할 수 있다) 만 알려주는 API 있는 반면, 가상의 경로를 계속 진행해 그동아느이 모든 접촉을 알려주는 API도 있다.

 

응용

ㄴ 가상 카메라가 게임 월드의 물체와 충돌하는 지를 알아낼 때 사용한다.

ㄴ 캐릭터의 움직임을 구현할 때, 캡슐 캐스트를 흔히 사용한다. 예를 들면 캐릭터를 평평하지 않은 지형에서 앞으로 밀 떄 구나 캡슐을 캐릭터 발 사이에 놓고 움직이는 방향으로 캐스트하고, 두 번째 캐스트에서 아래위로 움직여보고 지면에 항상 닿아 있게 보정한다.

 

12.3.7.3 팬텀

게임 월드 안의 특정한 공간(예를 들어 캐릭터의 일정한 반경)에 있는 모든 충돌체를 탐지하고 싶은 경우 사용한다.

이동거리 벡터 D가 0인 구 캐스트와 비슷하다. 

 

구 캐스트와는 달리 팬텀은 충돌 월드에 지속적으로 존재한다. 팬텀은 보이지 않고, 역학 시뮬레이션에 관여하지 않는 충돌체와 같은 의미이다.

 

12.3.7.4 기타 충돌 질의

하복에는 Closed Point 질의가 있는데, 해당 충돌체에서 가장 가까운 다른 충돌체 위의 점을 찾는데 쓰인다.

 

12.3.8 충돌 필터링

게임에는 종종 특정한 종류의 물체 사이에 충돌을 켜고 끌 수 있는 기능이 필요하다. 예를 들면 대부분의 물체는 물 표면을 뚫고 지나갈 수 있다. 부력을 시뮬레이션해서 물에 뜨게 만들거나 바닥에 가라앉게 할 수도 있지만 어쨌건 수면이 단단해서는 안 된다. 거의 모든 충돌 엔진에서는 게임 나름의 기준에 따라 충돌체 간의 접촉을 허용하거나 허용하지 않을 수 있는 기능이 있다. 이를 충돌 필터링이라고 한다.

 

12.3.8.1 충돌 마스킹과 계층

게임 월드의 물체들을 범주로 나눈 후 테이블을 이용해 특정 범주의 물체가 다른 물체와 충돌할 수 있는지 없는지를 찾는 방법이다.

 

12.3.8.2 충돌 콜백

충돌이 검출될 때마다 콜백 함수를 호출하는 방법

하복 기준

접촉 지점이 처음 월드에 더해지면 contactPointAdded() 콜백을 호출

접촉 지점이 이후에 올바른 것으로 판별되면(이보다 이른 TOI가 발견되지 않으면) contactPointConfirmed() 콜백을 호출

이 콜백 함수들 안에서 충돌하는 대상에 따라 접촉 지점을 거부할 수 있다(필터링 할 수 있다).

 

12.3.8.3 충돌 머터리얼

충돌 했을 때 나는 소리나 효과 등의 부가적인 효과를 제어하기 위해 게임 월드의 충돌체들을 분류해야 할 필요가 있다.

충돌 기본 단위와 충돌 머터리얼을 연결하는데 흔히 쓰이는 방법은 8, 16, 32 비트 정수를 사용하는 것인데, 이 값으로 상세한 충돌 속성이 저장된 자료구조 배열에 접근한다.

 

12.4 강체 역학

게임 물리 엔진에서는 게임 월드 안에 있는 강체들의 움직임에 대해 여러 가지 제약 조건을 줄 수 있다.

가장 널리 쓰이는 제약 조건은 통과할 수 없는 조건이다.

대부분의 물리 시스템들은 시뮬레이션 하는 강체 간에 사실적인 상호작용 구현을 위해 개발자가 별도의 제약조건을 설정할 수 있게 지원하기도 한다.

경첩, 직선축 관절, 볼 관절, 바퀴, 래그 돌 등이 있다.

 

역학 시뮬레이션의 강체와 충돌 엔진의 충돌체 간에는 대개 일대일 관계가 있다. 하복의 hkpRigidBody 객체는 오직 한 개의 hkpCollidable 참조만 갖고 있다.

12.4.1 기본 지식

12.4.1.1 단위

강체 역학 시뮬레이션은 대부분 MKS 단위계를 이용한다. 미터(m), 킬로그램(kg), 초(s)를 사용한다.

 

12.4.1.2 선 동역학과 각 동역학의 구분

제약 없는 강체는 직교 좌표계의 세 축 방향으로 평행 이동하면서 마찬가지로 세 축에 대해 자유롭게 회전할 수 있는 물체다. 이런 경우 물체는 6자유도를 갖는다고 한다.

 

제약 없는 강체의 운동은 다음과 같이 서로 완전히 독립된 두 부분으로 나눌 수 있다.

 

선 동역학

ㄴ 회전 성분을 무시할 때 물체의 운동

 

각 동역학

ㄴ 물체의 회전 운동을 나타낸다.

 

질량 중심

ㄴ 선 동역학의 관점에서 제약 없는 강체는 모든 질량이 질량 중심이라 불리는 한 점에 있는 것처럼 행동한다.

ㄴ 강체의 질량은 질량 중심에서 모든 방향으로 균등하게 배분된다.

ㄴ 밀도가 균일한 물체의 경우 질량 중심은 입체의 기하 중심과 같다.

 

12.4.2 선 동역학

선 동역학의 관점에서는 어떤 강체의 위치를 위치 벡터로 표현할 수 있는데, 이 벡터는 월드 공간 원점에서 그 강체의 질량 중심을 가리킨다.

 

 

12.4.2.1 선속도와 선 가속도

강체의 선속도란 이 물체의 질량 중심이 움직이는 속도와 방향으로 결정된다. 벡터로 표현한다.

벡터 값으로 일반적으로 초당 미터 (m/s) 단위로 나타낸다.

시간에 대한 위치의 일차 도함수는 속도, 이차 도함수는 가속도이다.

 

12.4.2.2 힘과 운동량

질량이 있는 물체를 가속하거나 감속하는 모든 것을 힘이라고 한다.

크기와 뱡향이 있기 때문에 벡터 값(F)으로 표현한다.

 

F = ma 이므로 힘은 kg-m/s² 단위(뉴턴)이다.

 

12.4.3 운동 방정식 풀기

강체 역학의 핵심 문제는 작용하는 힘이 주어졌을 때 물체의 움직임을 구하는 것이다.

선 동역학의 경우 순수 힘 F(t)나 이전 시간의 물체 위치와 속도 등의 정보를 가지고  v(t)와 r(t)를 찾는 것을 의미한다.

 

12.4.3.1 함수로서의 힘

힘은 상수인 경우도 있지만 시간에 대한 함수인 경우도 있다.

또 힘은 물체의 위치나 속도 등 다른 값에 대한 함수가 될 수도 있다.

 

12.4.3.2 상 미분 방정식 (ODE, Ordinary Differential Equation)

상 미분 방정식이란 하나의 독립 변수 (t)에 대한 함수 하나와 그 도함수들로 이루어진 방정식을 일컨는 말이다.

12.4.3.3 분석적 해법

중력과 같이 가속도가 고정인 경우(힘이 일정한 경우) 에는 가능하지만 게임 물리에서는 분석적인 해법을 쓸 수 있는 경우가 드물다. 게임은 상호적인 시뮬레이션이기 때문에 힘이 어떻게 변할지 예측할 수 없다.

 

12.4.4 수치 적분

현재 시각에서 물체의 위치와 속도를 알고, 힘이 시간, 위치, 속도의 함수라면 이걸들을 이용해 다음 시각에서의 물체의 위치와 속도를 찾는 것이 목표이다.

 

12.4.4.1 명시적 오일러 법

모든 시간 단계마다 물체의 속도가 상수라는 가정을 하여 현재의 속도를 사용하여 다음 프레임에서 물체의 위치를 예측한다.

시간에 따라 속도가 일정할 때만 정확하다.

 

12.4.4.2 수치 해석적 방법의 특성

상 미분 방정식(ODE)에 대한 수치 해석적인 방법은 다음과 같은 속성이 있다.

 

수렴성

ㄴ 시간 단계 t가 0으로 수렴함에 따라 근사적인 해법은 점점 진짜 해법에 가까워지는가?

 

차수

ㄴ 오차는 대새 시간 단계 Δt의 몇 제곱에 비례하는가? 오차가 O(Δt²)라면 차수 1 이라고 한다.

ㄴ 명시적 오일러 법은 차수가 1인 방식이다. (테일러 급수에서 Δt의 1 제곱인 항까지 정확하기 때문)

ㄴ 차수가 클수록 오차가 작아진다.

ㄴ 오차는 대개 ODE를 테일러 급수 전개한 것과 ODE를 빼서 남아있는 항들의 차수를 이용해 구한다.

테일러 급수

 

안정성

ㄴ수치 해석적인 해법이 시간이 지남에 따라 안정화되는가?  

 

12.4.4.3 명시적 오일러 법 이외의 방식

명시적 오일러 법은 단순한 구현에 많이 쓰이며, 속도가 일정한 경우에는 잘 적용될 수 있다.

범용 역학 시뮬레이션에서는 오차가 크고 안정성이 낮기 때문에 쓰지 못한다.

 

여러 수치 해석적인 방법들이 ODE를 푸는데 쓰인다.

ㄴ 후향 오일러 법 (차수가 1인 방식)

ㄴ 중점 오일러 법 (차수가 2인 방식)

ㄴ 여러 종류의 Runge-Jutta 방식 

 

12.4.4.4 베를레 적분

오늘날 상호적인 게임에서 가장 많이 쓰이는 수치 해석적 ODE 해법이다.

 

일반 베를레 방식과 속도 베를레 방식이 있다.

 

일반 베를레 방식

ㄴ 오류 차수가 높다.(오차가 작음)

ㄴ 계산하기 복잡하지 않다.

ㄴ 가속도가 주어졌을 때 한 번에 위치를 바로 구할 수 있다.

 

테일러 급수 전개를 두 개 더한다. 시간을 앞으로 보내는 식과 뒤로 보내는 식이다.

 

다음 시간 단계에서의 위치는 가속도와 이전 위치들( 현재 t1, 과거 t1-Δt )로 표현된다.

일계 도함수 항(속도)이 사라짐을 알 수 있다.

순수 힘에 관한 식으로 베를레 방식을 표현하면 다음과 같다.

속도는 여러가지 방법으로 근사치를 얻을 수는 있다.

 

12.4.4.5 속도 베를레 방식

속도 베를레 방식은 일반 베를레 방식보다 널리 쓰인다. 네 단계로 이루어져 있고 편의를 위해 시간 단계를 두 부분으로 나눈다.

ODE를 알고 있을 때 아래의 4단계를 거친다.

 

12.4.5 2차원 각 동역학

제약 없는 강체는 질량의 중심을 중심으로 회전 운동을 한다.

이 말은 물체 질량 중심의 선운동에 각운동을 더하면 물체의 모든 운동을 완전히 나타낼 수 있다는 뜻이다.

이처럼 물체에 힘이 가해졌을 때 회전 운동을 연구하는 분야를 각동역학(angular dynamics) 이라고 한다.

 

2차원에서는 각 동역학은 선 동역학과 완전히 똑같은 식으로 동작한다.

 

12.4.5.1 방향과 각속력

2차원에서는 모든 선 운동이 xy 평면에서만 일어나고 모든 회전 운동은 z축을 기준으로 발생한다.

2차원 강체의 방향은 각 θ만 갖고도 나타낼 수 있다. x축 양의 방향을 바라보고 있을 때를 θ = 0으로 정할 수 있다.

 

12.4.5.2 각속력과 가속도

각속도란 물체의 회전각이 시간에 따라 얼마나 빠르게 변하는지를 나타내는 값이다 

각속도는 스칼라 함수 ω(t)로 나타내고, 단위는 초당 라디안 (rad / s)이다.

각속도 (좌) / 선속도 (우)

각가속도 α(t)는 각속도의 변화율이며, 초의 제곱당 라디안 (rad / s²)이다.

각가속도 (좌) / 선가속도 (우)

 

12.4.5.3 관성 모멘트

점 질량의 선 속도를 바꾸기 힘든 정도를 나타내는 개념이 질량이라면, 어떤 강체를 특정한 축 기준으로 회전할 때 각속도를 바꾸기 힘든 정도를 나타내는 개념이 관성 모멘트이다.

 

물체의 질량이 회전축에 모여있는 경우에는 상대적으로 회전하기 쉽기 때문에 회전축에서 멀리 떨어져 있는 경우보다 관성 모멘트가 작다.

 

지금은 2차원 각운동만을 다루기 때문에 회전축은 항상 z축이며, 물체의 관성 모멘트는 그냥 스칼라 값이다. 관성 모멘트는 흔히 기호 I로 나타낸다.

 

12.4.5.4 토크

힘이 작용하는 경로가 물체의 질량 중심을 통과하는 경우는 지금까지 봐 왔던 선 운동만 일어난다. 그렇지 않은 경우 선 운동 외에도 토크라 불리는 회전하는 힘이 생긴다.

 

물체의 질량 중심에서 힘이 작용하는 지점까지의 벡터 r과 힘 F를 외적 연산 한 값이 토크 N이다

N = r X F

N = r X F

2차원에서 r과 F는 모두 xy 평면에 놓여있기 때문에 N은 언제나 z축 방향이다. 

 

토크 (좌) / 힘 (우)

 

12.4.6 3차원의 각 동역학

12.4.6.1 관성 텐서

3차원에서 강체의 회전 질량은 관성 텐서라 불리는 3x3 행렬로 나타낸다. 이것은 보통 기호 I로 표기한다.

이 행렬의 대각선 성분들은 좌표계의 세 축에 대한 관성 모멘트를 나타낸다. 대각선이 아닌 성분들은 관성 곱이라고 부른다. 이 값들은 물체가 세 좌표축에 모두 대칭일 때는 0이 된다.(육면체 박스처럼) 이 값들이 0이 아닐 경우 물리적으로는 사실적이지만 다소 직관적이지 않아 보이는 운동을 하게 되는데, 보통 게이머들은 이것을 사실적이지 않은 운동이라고 생각하기 쉽다. 그렇기 때문에 게임 엔진에서 쓰이는 관성 텐서는 종종 성분이 세 개인 벡터로 단순화하는 경우가 많다.

 

12.4.6.2 3차원에서의 방향

사원수를 물체의 방향을 나타내는 데 사용하고, 물체의 방향은 시간에 대한 함수이므로 q(t)로 써야 한다.

회전각이 0인 임의의 방향을 정해야 한다.

 

12.4.6.3 3차원에서의 각속도와 운동량

3차원에서 각속도는 벡터 값이고 ω(t)로 표기한다.

각속도 벡터는 회전축을 나타내는 단위 벡터 u에 그 축에 대한 물체의 2차원 각속도를 곱한 것으로 생각하면 된다.

3차원에서는 회전하는 강체에 작용하는 힘이 없더라도 각속도 벡터 ω(t)는 일정하지 않을 수 있는데, 이것은 회전축이 계속 변할 수 있기 때문이다.

 

각 속도는 보존되는 값이 아니기 때문에 역학 시뮬레이션에는 각 운동량 L을 주요 물리량으로 다룬다.

각 운동량 L(t) = Iω(t)

 

12.4.6.4 3차원에서의 토크

3차원에서도 토크를 구하는 방법은 힘의 작용점 벡터와 힘 벡터의 외적을 사용한다.

각속도는 보존되는 값이 아니기 때문에 각운동량을 기준으로 표현해야 한다.

 

운동량 = 질량 x 속도

각운동량 = 관성 모멘트 x 각속도

 

12.4.6.5 3차원 각운동 방정식 풀기

어려우니까 결론만

명시적 오일러 법을 사용했을 때 3차원 각운동 ODE의 근사 해

 

12.4.7 충돌 응답

물체가 서로 충돌하는 경우 역학 시뮬레이션에서는 물체드링 사실적으로 충돌에 반응하면서 시뮬레이션 단계가 끝나는 시점에서는 서로 뚫고 들어간 상태로 남아 있지 않게 조치를 취해야 한다. 이를 충돌 응답이라고 한다.

 

12.4.7.1 에너지

힘은 강체들의 계(system) 에 에너지를 더하거나 (폭발) 에너지를 감소시킨다. (마찰)

에너지는 위치 에너지와 운동 에너지로 구성된다.

운동 에너지

선 운동에서 발생하는 운동 에너지(선운동량 p와 속도 벡터 v)
회전 운동에서 발생하는 운동 에너지 (각운동량 L과 각속도 ω)

 

12.4.7.2 충격적 충돌 응답

대부분의 실시간 시뮬레이션들은 뉴턴의 법칙에 기반을 두고 운동량과 운동에너지를 분석한다.

 

이 법칙은 충돌의 속성을 단순화하는 다음과 같은 가정에 바탕을 둔다.

 

1. 충돌 힘은 무한히 짧은 시간에 작용하고, 따라서 이상적인 충격이라고 할 수 있다. 그렇기 때문에 물체의 속력은 충돌 결과 즉시 변한다.

 

2. 물체들이 접촉하는 지점의 표면에는 마찰이 없다. 이 말은 충돌 과정에서 두 물체를 떨어뜨리려는 충격은 접촉 표면에 수직으로 작용한다는 뜻이다. 즉 충돌 충격에는 비스듬한 성분이 없다.

 

3. 충돌 과정에서 일어나는 물체들의 분자 단위 반응들은 반발 계수(보통 ε로 표현한다.)라는 수 하나로 흉내 낼 수 있다. 이 수는 충돌로 인해 얼마만큼의 에너지를 잃는가를 나타낸다. ε = 1일 경우 완전 탄성 충돌이고 에너지를 잃지 않는다. ε = 0일 경우에는 비탄성 충돌이며 두 물체는 운동에너지를 완전히 잃는다.

 

완전 탄성 충돌의 경우 에너지 손실(T lost) = 0이고 완전 비탄성 충돌의 경우 첨자가 붙은 운동에너지의 합은 0이 된다.

 

12.4.7.3 페널티 힘

충돌 응답을 구현하는 또 다른 방식에는 실제로는 존재하지 않는 페널티 힘이라는 개념을 시뮬레이션에 도입하는 방법이 있다.

스프링 상수 K는 교차해 있는 시간을 효율적으로 조정하는 역할을 하고, 감쇠 계수 b는 반발 계수와 다소 비슷한 역할을 한다.

b = 0인 경우 감쇠 효과는 없다. (완전 탄성 충돌이다)

 

12.4.7.4 제약조건을 통한 충돌 해결

대부분의 물리 엔진에서 물체의 운동에 여러 제약 조건을 넣어 시뮬레이션 할 수 있다.

제약조건으로 충돌을 처리한다면 그냥 시뮬레이션의 제약조건 해결사(constraint solver)를 실행해 해결하면 된다. 제약조건 해결사가 빠르고 품질 높은 시각적 결과를 뽑아낸다면 이 또한 효율적인 충돌 처리법이 된다.

 

12.4.7.5 마찰

12.4.7.6 용접 (WELDING)

물체가 다각형 수프를 따라 미끄러지고 있는 경우 추가적으로 문제가 발생한다.

물체가 한 삼각형에서 같은 다각형 수프의 다른 삼각형으로 미끄러지는 경우 충돌 검출 시스템은 이 물체가 다음 삼각형의 모서리에 닿을 것을 예측해 불필요한 충돌을 감지하게 된다.

 

하복 4.5에서는 메시에 삼각형 인접 정보를 첨가하는 방식을 사용한다.

이 방식을 사용하면 충돌 검출 시스템은 어떤 모서리가 어느 모서리가 다각형 수프 내에 있는 모서리인지 알수 있기 때문에 가짜 충돌 정보를 정확하고 빠르게 버릴 수 있다. 하복은 이것을 용접이라고 부르는데, 사실상 다각형 수프의 삼각형들의 모서리를 용접한 것과 마찬가지이기 때문이다.

 

12.4.7.7 점차 멈춰 서기, 섬, 잠재우기

운동하던 물체가 마찰, 감쇠 등을 통해 에너지를 잃으면 움직이던 물체들은 점차 멈춰야 한다. 하지만 컴퓨터 시뮬레이션을 통해 점차 멈춰서는 일은 부동소수 오차나 반발력 계산 오류, 수치적인 불안정성 등의 여러 요인 때문에 물체들이 자연스럽게 멈춰 서지 못하고 계속 불안정하게 떨리게 된다.

 

시스템에서 물체의 에너지를 제거할 수도 있고, 물체의 속도가 일정한 기준 아래로 내려가면 그냥 속도를 0으로 만들 수도 있다.

 

물체가 움직이지 않게 되면 더 이상 매 프레임 물체의 운동 방정식을 계산할 필요가 없기 때문에 매 프레임 계산 대상에서 제외할 수 있다. (잠재우기) 잠자는 물체들은 시뮬레이션에서는 잠시 제외되지만 충돌에서는 여전히 유효하며, 잠자는 물체에 힘이나 충격이 작용하거나 물체를 평행 상태로 지탱하고 있던 접촉 지점을 잃게 되면 깨어나게 되고 다시 동적 시뮬레이션을 시작한다.

 

잠재우는 기준(평행 상태 판단 기준)

ㄴ 물체가 3개 이상의 점촉 지점(한 개 이상의 접촉 평면)을 통해 중력 등 기타 작용하는 힘과 평형을 이루고 있는 상태

ㄴ 물체의 선 운동량과 각 운동량이 미리 정해진 기준보다 낮을 때

ㄴ 물체의 선 운동량과 각 운동량의 이동 평균이 정해진 기준보다 낮을 때

ㄴ 물체의 총 운동 에너지 ( T = 1/2p v + 1/2L ω)가 정해진 기준보다 낮을 때

 

시뮬레이션 섬

하복과 PhysX에서는 한층 더 성능을 최적화하기 위해 서로 영향을 주거나 곧 영향 줄 가능성이 있는 물체들을 자동으로 한데 묶어 시뮬레이션 섬이라고 지칭한다.

각 시뮬레이션 섬들은 서로 독립적으로 시뮬레이션되기 때문에 캐시 일관성이나 병렬 처리에 유리한 방식이다.

잠재우기를 시뮬레이션 섬 단위로 한다.

 

12.4.8 제약조건

제약 없는 강체는 세 방향으로 평행 이동할 수 있고, 세 직교 좌표축을 기준으로 회전할 수 있어서 자유도가 6이다.

제약 조건은 강체의 자유도를 부분적으로 감소시키거나 없앨 수 있다.

물리 SDK에서는 다양한 제약조건을 지원한다.

 

12.4.8.1 점과 점 제약조건

물체 A의 한 점이 물체 B의 한 점에 항상 붙어 있어야 한다.

 

12.4.8.2 단단한 스프링

물체 A의 한 점은 물체 B의 한 점과 일정한 거리만큼 떨어져 있어야 한다.

 

12.4.8.3 경첩 제약조건

회전 운동의 자유도를 1로 제약해 경첩의 축 방향으로만 회전할 수 있도록 한다.

 

12.4.8.4 각기둥 제약조건

평행 운동의 자유도를 1로 제약해 축 방향으로만 평행이동 할 수 있도록 한다.

 

12.4.8.5 흔히 쓰이는 다른 제약조건

평면, 바퀴, 도르래

 

12.4.8.6 제약조건 체인

여러 물체가 제약조건들로 인해 체인 형태로 연결된 경우 시뮬레이션하기 어려울 때가 있는데, 제약 조건 체인이라는 제약조건들의 특수한 그룹을 사용하여 제약 조건 해결사에 물체들이 어떻게 연결되어 있는지에 대한 정보를 제공해야 한다.

 

12.4.8.7 래그 돌

제약조건 체인을 이용한다.

래그 돌은 물리 시스템에 의해 좌우되는 (물리월드의 강체들의 위치와 회전으로 애니메이션 뼈대의 위치와 방향을 정한다.) 절차적 애니메이션 (실행 시간에 생성하는 애니메이션)이다.

 

12.4.9 강체의 움직임 제어

대부분의 게임에서는 디자인적 요소로 중력의 영향을 받아 움직이거나 여러 물체들 사이의 충돌에 의해 자연스럽게 운동하는 강체들의 움직임을 어느 정도 통제할 수 있어야 한다.

 

12.4.9.1 중력

중력은 힘이 아니라 가속도이기 때문에 질량에 관계없이 모든 물체에 똑같은 영향을 미친다.

모든 곳에서 쓰이면서 특수한 성질이 있기 때문에 SDK의 전역 설정으로 지정하는 경우가 많다.

 

12.4.9.2 힘 가하기

게임에서 물리 시뮬레이션을 하는 동안 물체들에는 수많은 힘이 가해질 수 있다. 힘은 한정된 시간에 걸쳐 작용한다.(즉시 작용하는 경우 충격이라고 한다.)

게임 안에서 힘은 특성상 대개 동적이다.(프레임마다 바뀐다.) 그렇기 때문에 거의 모든 물리 SDK에서는 힘을 적용하는 함수들을 프레임마다 한 번씩, 힘이 유효한 동안(여러 프레임) 계속 호출하도록 설계한다.

 

12.4.9.3 토크 가하기

질량 중심에서 등거리인 두 지점에 크기가 같고 방향이 정반대인 힘을 가하면 순수하게 토크만 생긴다.

이처럼 쌍으로 작용해 토크를 만드는 두 힘을 짝힘이라고 한다.

 

12.4.9.4 충격 가하기

충격은 즉각적인 운동량의 변화다.

엄밀한 의미에서 충격은 무한히 짧은 시간동안 작용하는 힘이다. 시간 간격을 통해 역학 시뮬레이션을 구현하는 경우 가장 짧은 힘 적용 시간은 Δt인데 충격을 제대로 흉내내기에는 너무 긴 시간이다. 대개의 물리 엔진은 applyImpulse 같은 함수로 물체에 충격을 가하게 된다.

 

12.4.10 충돌/물리 단계

충돌/물리 엔진의 업데이트 단계에서 일어나는 일

1. 물리 월드의 물체들에 힘과 토크를 Δt 만큼 앞선 시각으로 계산하여 다음 프레임에서의 위치와 방향을 시험적으로 결정한다.

 

2. 시험적인 이동으로 인해 물체들 간에 새로운 접촉 정보가 생겼는지를 알아내기 위해 충돌 검출 라이브러리를 호출한다.(시간적 일관성을 활용하기 위해 물체들은 각각의 접촉 정보를 유지한다. 따라서 시뮬레이션하는 매 단계 충돌 엔진은 기존의 접촉 정보가 유효하지 않게 바뀌었느지와 새로운 접촉 정보가 더해졌는지만 알아내면 된다)

 

3. 충돌을 해결한다. 충격을 가하거나 페널티 포스를 가하는 방법, 또는 제약조건 해결 과정에서 처리하는 방법 등이 쓰인다. SDK에 따라서는 이 단계에 충돌 검출을 수행할 수도 있다.

 

4. 제약조건 해결사에 의해 제약조건을 충족시키게 한다.

 

 

12.4.10.1 제약조건 해결사

제약조건 해결사는 반복적 알고리즘이다.

물체의 실제 위치 및 회전을 제약조건이 충족될 떄의 이상적인 위치 및 회전과 최대한 근접하게 함으로써 다수의 제약조건을 동시에 만족시키는 것이 목적이다. 따라서 제약 조건 해결사는 반복적인 오차 최소화 알고리즘이라 할 수 있다.

 

물리 시뮬레이션의 매 단계에서는 수치 적분을 이용해 물체들의 변환을 예측한다. 그런 후 제약조건 해결사는 물체들의 상대적인 위치를 가지고 두 물체가 공유하는 회전축이 얼마나 틀어졌는지를 계산한다. 오차가 발견되면 해결사는 물체들을 움직여 오차를 최소화하거나 아니면 없애려 시도한다.

오차가 없다면 더 이상 반복할 필요가 없다.

 

여러 개의 제약조건을 동시에 충족해야 하는 경우에는 여러 번 반복해야 할 수도 있다.

오차를 최소화할 수 있게 잘 설계된 제약조건 해결사가 있지만 그렇지 않은 경우에는 물체들이 엉뚱하게 움직이는 것을 볼 수도 있다.

 

12.4.10.2 엔진 간의 구현 차이

엔진마다 여러 계산 단계를 수행하는 방법이나 상대적인 수행 순서는 물리 SDK마다 차이가 있을 수 있다.

 

12.5 물리 엔진과 게임 통합

12.5.1 게임 객체와 강체간의 연결

게임 객체는 충돌/물리 월드에 여러 개의 강체로 표현되기도 하고 강체가 아예 없을 수도 있다.

 

1. 강체가 없는 경우

ㄴ 장식으로 쓰이는 물체들이나, 볼 수는 있지만 근처에 갈 수 없는 물체로 쓰인다.

 

2. 강체가 하나인 경우

ㄴ 대부분의 단순한 게임 객체는 강체 하나로 표현할 수 있다. 이 경우 강체의 충돌체는 가능한 한 게임 객체의 모양과 비슷한 것을 고른다.

 

3. 강체가 여러 개인 경우

ㄴ 캐릭터, 탈것 등 여러 견고한 부분들로 구성된 물체들. 이런 게임 객체들은 대개 뼈대를 이용해 각 부분의 위치를 관리한다.

 

게임 객체와 강체 간의 연결은 엔진에서 관리하며, 보통 각 게임 객체가 자신의 강체들을 관리하는 경우가 많다.

 

12.5.1.1 물리 주도 물체

게임에 강체 역학 시스템을 사용하는 경우 완전히 시뮬레이션에 의해서만 움직이는 물체들을 물리 주도 물체들이라고 한다.

 

우선 시뮬레이션을 처리하고 그후 물리 시스템에서 물체의 위치와 방향을 얻어 온다. 이 변환 정보는 게임 객체에 그대로 적용되거나 아니면 일부 관절, 혹은 그 안의 자료 구조 등에 적용된다.

 

12.5.1.2 게임 주도 물체

게임 물체들 중 일부는 물리에 영향 받지 않고 움직여야 한다. 이런 물체들은 충돌 검출에는 참여해야 하지만(에를 들면 물리 주도 물체들을 밀쳐내며 이동하는 경우), 물리 엔진에 의해 움직임에 영향을 받아서는 안 된다. 이런 기능을 위해 대부분의 물리 SDK는 게임 주도 물체라 불리는 특수한 강체를 지원한다. (하복에서는 key framed body라고 부른다).

 

게임 주도 물체들은 시뮬레이션 하는 동안 힘과 충돌 충격에 의해서 속도가 바뀌지 않아야(움직이지 않아야) 하기 때문에 무한대의 질량을 가진다고 설정한다.

 

게임 주도 물체들을 물리 월드에서 움직이렴녀 단순히 매 프레임마다 게임 객체의 자리를 따라 위치와 방향을 바꿔서는 안 된다. 이렇게 하면 물리 시뮬레이션에서 해결하기 굉장히 어려운 불연속적인 요소를 집어넣게 된다. 

 

그렇기 때문에 게임 주도 물체들은 대개 충격을 이용해 다음 프레임에 물체가 원하는 위치에 오게 속도에 즉각적인 변화를 준다. 대부분의 물리 SDK는 다음 프레임에서 원하는 위치와 방향에 도달하는데 필요한 충격의 성분과 각 성분을 계산해주는 함수를 제공한다.

 

12.5.1.3 고정된 물체

게임 월드는 대개 정적인 형상과 동적인 객체들이 섞여 이루어진다. 게임 월드의 정적인 부분을 모델링하기 위해 대부분의 물리 SDK에는 고정된 물체라 불리는 특수한 종류의 강체가 있다. 고정된 물체는 게임 주도 물체와 비슷한 면이 있지만 동적인 시뮬레이션에는 전혀 관여하지 않는다. 이것들은 충돌만 하는 물체들이다.

 

12.5.1.4 하복의 모션 타입

하복에서는 hkpRigidBody 클래스의 인스턴스를 이용해 모든 종류의 강체들을 나타낸다. 각 인스턴스에는 모션 타입을 지정하는 부분이 있다. 모션 타입은 물체가 고정돼 있는지, 아니면 게임 주도인지 물리 주도인지를 시스템에 알려주는 역할을 한다.

 

하복은 물체의 종류를 모션타입만을 바꿈으로써 쉽게 바꿀 수 있다.(고정된 물체, 게임 주도 물체, 물리 주도 물체)

 

12.5.2 시뮬레이션 업데이트

물체 시뮬레이션을 완전히 업데이트 하려면 다음과 같은 단계를 거쳐야 한다. 업데이트는 대개 프레임당 한 번씩 한다.

 

게임 주도 강체 업데이트

ㄴ 물리 월드에 있는 게임 주도 강체들의 변환을 업데이트해서 게임 월드에 있는 쌍들의 변환과 일치되게 한다.

 

팬텀 업데이트

ㄴ 팬텀 형상은 게임 주도 충돌체처럼 동작하지만 강체는 없다. 이는 여러 종류의 충돌 질의를 하는 데 쓰인다. 팬텀의 위치는 물리 단계 전에 업데이트해 충돌 검출이 수행될 때 제 위치에 자리하게 한다.

 

힘 업데이트, 충격 적용, 제약조건 조정

ㄴ 게임에서 가해지는 모든 힘들을 적용한다.

ㄴ 해당 프레임에서 게임 이벤트에 의해 발생한 모든 충격을 적용한다.

ㄴ 필요한 경우 제약조건을 조정한다.

 

시뮬레이션 단계 밟기

ㄴ 운동 방정식을 수치 적분하는 과정

ㄴ 충돌 검출

ㄴ 충돌 해결

ㄴ 제약조건 적용하기 

 

물리 주도 게임 객체 업데이트

ㄴ 물리 월드에서 물체들의 변환을 뽑아 낸 후 해당하는 게임 객체나 관절의 변환을 업데이트한다.

 

팬텀 질의

ㄴ 물리 단계가 끝난 후, 각 팬텀 형상의 접촉 정보를 읽어와 다양한 의사 결정에 이용한다.

 

충돌 캐스트 질의 수행

ㄴ 레이 캐스트와 형상 캐스트를 수행하는데, 이 과정은 동기화되는 경우도 있고 비동기화 되는 경우도 있다. 얻은 결과는 게임 엔진에서 다양한 의사 결정에 쓰인다.

 

업데이트 의존 관계

ㄴ 게임 주도 물체 업데이트와 힘/충격 업데이트는 시뮬레이션 단계보다 앞에 수행해야 한다.

ㄴ 물리 주도 게임 객체 업데이트는 시뮬레이션 단계가 끝난 후에 수행되어야 한다.

ㄴ 레이 캐스트와 형상 캐스트는 게임 루프 안에서 아무 때나 할 수 있다.

ㄴ 렌더링은 게임 루프의 마지막에 온다.

 

12.5.2.1 충돌 질의 시점 정하기

충돌 시스템에서 최신 정보를 얻어 오려면 해당 프레임의 물리 단계(시뮬레이션 단계)가 끝난 후 충돌 질의를 던져야 한다. 하지만 물리 단계는 대개 프레임의 맨 마지막에 수행되는데 이때는 이미 게임 로직에서 대부분의 의사 결정이 끝난 상태이고 게임 주도 물체들의 새 위치도 정해진 상태이다. 

 

충돌 질의를 언제 던져야 하는지에 대한 정답은 없지만 2가지 선택 방법이 있다.

1. 이전 프레임의 상태를 바탕으로 정하기

ㄴ 이전 프레임의 충돌 정보를 바탕으로 해도 정확한 의사 결정을 할 수 있는 경우가 많기 때문에 사용 가능하다.

ㄴ 물체가 너무 빠르게 이동하면 오류가 생길 수 있다.

 

2. 물리 단계 이후에 충돌 질의하기

ㄴ 충돌 질의 결과를 바탕으로 한 의사 결정이 맨 마지막까지 미뤄져도 상관 없는 경우 이 방법을 쓸 수 있다. 충돌 질의에 따라 달라지는 렌더링 효과가 그 좋은 예다.

 

12.5.3 게임에서 충돌과 물리를 사용하는 예

나중에 필요할 때 찾아보기

 

12.5.3.1 단순한 강체를 갖는 게임 객체

12.5.3.2 총알 추적

12.5.3.3 수류탄

12.5.3.4 폭발

12.5.3.5 파괴 가능 물체

12.5.3.6 캐릭터 구현

12.5.3.7 카메라 충돌

12.5.3.8 래그 돌 통합

 

12.6 고급 물리 기능

강체 시뮬레이션을 넘어서 물리엔진이 확장되는 분야들

 

가변 형상 물체

ㄴ 하드웨어가 발달하고 고성능 알고리즘이 개발되면서 물리 엔진에서도 가변 형상 물체를 지원하기 시작했다.

 

의복

ㄴ 의복은 스프링으로 연결된 점 질량들이 종이 형태로 배열된 모양으로 모델링할 수 있다. 하자만 의복은 다른 물체와의 충돌이나 시뮬레이션에서 수치적인 안정성 등 많은 부분에서 문제가 발생할 수 있기 때문에 구현하기 까다롭다.

 

머리카락

ㄴ 수많은 가는 섬유 형태로 모델링하거나 밧줄 형태나 가변 형상 물체로 모델링할 수 있다.

 

물 표면 시뮬레이션과 부력

일반 유체 역학 시뮬레이션

 

물리 기반 오디오 합성

ㄴ 물리적으로 시뮬레이션되는 물체가 좀 더 사실적으로 보이게 하기 위해서 적절한 오디오를 동적으로 합성해 생성하는 방법

 

GPGPU

ㄴ GPU의 병렬 처리 능력을 그래픽이 아닌 다른 일에 사용

+ Recent posts