3D Physics Engine
프로젝트 개요
- 본 프로젝트는 DirectX 12를 사용하여 C++로 처음부터 구축한 포괄적인 3D 물리 엔진입니다.
- 현대 게임 개발에서 흔히 사용되는 강체 동역학(rigid body dynamics), 충돌 감지(collision detection), 그리고 구속 조건 해법(constraint resolution)의 핵심 원리를 깊이 있게 탐구하기 위해 개발되었습니다.
- 이 엔진은 견고한 물리 파이프라인, 유연한 구속 조건 솔버, 그리고 복잡한 물리적 상호작용을 분석하고 검증하도록 설계된 강력한 시각적 디버깅 도구 모음을 특징으로 합니다.

핵심 엔진 아키텍처 및 기능
- 엔진은 코어 물리 시뮬레이션을 렌더링 및 디버깅 레이어와 분리하는 모듈형 아키텍처를 기반으로 구축되었습니다.
- 주요 기술적 특징은 다음과 같습니다:
1. 물리 파이프라인 및 충돌
- 엔진의 시뮬레이션 루프는 감지(detection)와 해상(resolution)을 명확하게 분리하고 런타임 성능 비교를 가능하게 하는 견고하고 유연한 파이프라인을 특징으로 합니다.
이중 모드 충돌 감지
- 기본 경로 (N-Squared): 모든 쌍을 확인하는 기본적인 $O(N^2)$ 검사도 구현되었습니다.
- 이 “무차별 대입(brute force)” 방식은 디버깅 및 광역 단계 최적화의 현저한 성능 향상을 명확하게 입증하기 위해 토글(toggle)할 수 있습니다.
- 최적화 경로 (광역/협역 단계 - Broad/Narrow Phase): 주된 감지 경로는 고성능의 2단계 프로세스입니다.
- 광역 단계 (Broad Phase): 각 축을 따라 객체의 AABB를 정렬하여 잠재적인 충돌 쌍을 효율적으로 걸러내는 Sweep and Prune (SAP) 알고리즘을 활용합니다.
- 이는 $O(N^2)$ 문제 공간을 획기적으로 줄여줍니다.
- 협역 단계 (Narrow Phase): 남은 쌍에 대해 GJK 알고리즘을 사용하여 구 대 구(sphere-to-sphere) 및 볼록체 대 볼록체(convex-to-convex) 형태에 대한 정확한 교차 테스트를 수행합니다.
- 광역 단계 (Broad Phase): 각 축을 따라 객체의 AABB를 정렬하여 잠재적인 충돌 쌍을 효율적으로 걸러내는 Sweep and Prune (SAP) 알고리즘을 활용합니다.
하이브리드 충돌 해상
- 엔진은 감지된 접촉을 그 성격에 따라 두 가지 다른 솔버로 지능적으로 분배합니다:
- 1. 동적 접촉 (충돌 시간 해상기 - Time-of-Impact Resolver): 접촉이 발생하기 전에 감지된($TimeOfImpact > 0$) 접촉에 대해서는 예측적인 충격 기반(predictive impulse-based) 솔버를 사용합니다.
- 엔진은 모든 동적 접촉을 충돌 시간(TOI) 순서로 정렬한 후, 가장 빠른 충돌 시간으로 시뮬레이션을 진행하고, “정상(normal)” 충격으로 이를 해상한 다음, 프레임의 시간 단계(time step)가 완료될 때까지 이 과정을 반복합니다.
- 2. 정적 및 정지 접촉 (구속 조건 솔버 - Constraint Solver): 이미 관통되었거나 정지 중인($TimeOfImpact = 0$) 접촉에 대해서는 더욱 견고한 반복적 구속 조건(iterative constraint) 솔버를 사용합니다.
- 이러한 접촉은 매니폴드(manifolds)에 추가되고, 안정적이고 물리적으로 그럴듯한 쌓기, 정지 및 기타 복잡한 다중 바디 상호작용을 보장하기 위해 여러 번의 반복을 거쳐 해상됩니다.
2. 강력한 디버깅 도구 모음
- 프로젝트의 중요한 초점은 물리 프로그래밍에 필수적인 런타임 디버깅 도구를 개발하는 것이었습니다.

대화형 객체 조사기
- 런타임에 시뮬레이션을 일시 중지할 수 있습니다.
- 마우스 클릭을 통해 씬 내의 객체를 선택할 수 있습니다.
- 선택 시, UI 패널에 핵심 상태 정보가 표시됩니다:
- 객체 ID
- 위치 및 방향(Position and Orientation)
- 선형 속도 및 각속도(Linear Velocity and Angular Velocity).
런타임 기즈모
- 선택된 객체는 3D 기즈모를 사용하여 직접 조작(이동 및 회전)할 수 있습니다.
- 이 조작에는 특수화된 물리 구현이 적용됩니다: 이동된 객체는 다른 동적 객체를 밀어내지만, 중력의 영향을 받지 않습니다.
- 디버깅을 위한 안정적인 상태를 유지하기 위해 접촉 해상 시 속도는 0으로 재설정됩니다.
- 일시 중지될 때 엔진은 모든 객체의 속도 상태를 저장하며, 시뮬레이션 재개 시 이 상태가 복원됩니다.
- 조사기 패널은 일시 중지 전의 상태를 명확하게 분석할 수 있도록 선택된 항목의 저장된 속도를 계속 표시합니다.
접촉점 시각화
- 객체가 선택되면, 현재 모든 접촉점은 작고 선택 가능한 (노란색) 구체로 렌더링됩니다.
- 접촉점 구체를 선택하면 충돌에 대한 자세한 정보가 표시됩니다:
- 관련된 두 바디의 ID, 충돌 법선(normal)
- 충돌 시간(Time of Impact, TOI)
- 각 바디에 대한 국소 및 월드 공간에서의 접촉 위치.

프레임별 기록
- 엔진은 지난 60 프레임 동안의 모든 객체의 상태(위치, 회전 등)를 기록합니다.
- UI 슬라이더를 통해 사용자는 이 기록을 앞뒤로 스크러빙(scrubbing)할 수 있으며, 이는 고속 이벤트를 분석하거나 시뮬레이션 버그가 발생하는 정확한 순간을 찾는 강력한 도구를 제공합니다.

시연
- 시연은 계산 효율성, 수치적 안정성, 그리고 구속 조건 해상 정확도를 고강도 및 구성적으로 복잡한 시나리오를 통해 체계적으로 평가하도록 구성되었습니다.
- 시연을 통해 입증된 주요 측면은 다음과 같습니다:
1. 성능 및 스트레스 테스트
- 이 시연은 과부하 상태에서 엔진의 안정성과 성능을 테스트합니다.
- 씬은 다수의 동적 객체(구체 및 볼록체)를 생성하고 이를 컨테이너에 떨어뜨립니다.
시연된 주요 기능:
- todo!! : 이 부분 수정하기
- 대용량 객체 처리: 다수의 활성 강체를 처리하는 동안에도 시뮬레이션은 안정적으로 유지됩니다.
- 동적 UI 제어: 이 씬을 위한 전용 UI 패널은 런타임 구성을 가능하게 합니다:
- 알고리즘 토글링: 광역 및 협역 충돌 단계를 활성화하거나 비활성화하여 성능 영향을 명확하게 시연하는 버튼입니다.
- 모양 선택: 구체 또는 더 복잡한 볼록체(예: 다이아몬드)를 생성하기 위한 토글입니다.
- 스트레스 수준: 생성되는 객체의 수를 제어하는 슬라이더(1-10)입니다.
- 초기 높이: 모든 객체의 시작 낙하 높이를 조정하는 슬라이더입니다.
2. 샌드박스 및 구속 조건 시나리오
- 이 시연은 게임에서 흔히 사용되는 복잡한 구속 조건 기반 상호작용을 처리하는 물리 솔버의 견고함을 보여줍니다.
시연된 주요 시나리오:
- 이 씬의 UI에는 각 사전 정의된 시나리오를 즉시 로드할 수 있는 버튼이 있습니다.
- 박스 쌓기: 솔버의 정지 접촉 처리 능력과 안정성을 테스트하기 위해 객체들을 쌓습니다.

- 움직이는 플랫폼: 동적 객체는 운동학적으로 구동되는 플랫폼과 정확하게 상호작용합니다.

- 사슬: 최상단 상자는 고정되고, 다섯 개의 상자가 거리 구속 조건으로 연결된 전형적인 물리 시나리오입니다.

- 스피너: 고정된 상자를 기반으로 동적 객체가 계속 회전하도록 시연합니다.

- 래그돌: 간단한 래그돌을 통해 관절 구속 조건 및 복잡한 복합 강체 상호작용을 시연합니다.

- 추가: 더 추가하기!
도전 과제 및 향후 개발
- 이 프로젝트는 안정적이고 효율적인 구속 조건 솔버를 구현하고 디버깅 도구를 위한 엔진 상태를 관리하는 데 있어 상당한 기술적 도전 과제를 제공했습니다.
- 향후 개발에는 다음이 포함될 수 있습니다:
- 볼록체의 모양 확장 (예: 원통, 피라미드).
- 고접촉 시나리오에서 더 나은 성능을 위한 솔버 최적화.
Leave a comment