이번 글에서는 팀원이 구현한 부분인 Initialization, Integrate, 그리고 Broad Phase 단계를 간단히 살펴보려 한다. 물리 엔진의 큰 틀에서 이 단계들은 초기화와 첫 번째 물리 연산 루프에 해당한다.
물리 엔진의 초기화 단계는 물리 연산이 이루어질 환경을 설정하는 과정이다. 이 중에서도 가장 중요한 World 클래스 설계부터 살펴보자.
class World
{
public:
World(uint32_t size, App &app);
~World();
void startFrame();
void runPhysics();
// ...
ContactManager contactManager;
App &app;
private:
std::vector<Rigidbody *> rigidbodies;
};
Rigidbody는 물리 엔진에서 모델을 대표하는 객체로, 아래와 같이 설계되어 있다.
class Rigidbody
{
public:
// ...
protected:
static int32_t BODY_COUNT;
World *world;
Transform xf;
glm::vec3 linearVelocity;
glm::vec3 angularVelocity;
glm::mat3 inverseInertiaTensorWorld;
glm::mat3 inverseInertiaTensor;
glm::mat4 transformMatrix;
glm::vec3 forceAccum;
glm::vec3 torqueAccum;
glm::vec3 acceleration;
glm::vec3 lastFrameAcceleration;
std::vector<Fixture *> fixtures;
std::queue<glm::vec3> forceRegistry;
Sweep sweep;
BodyType type;
float inverseMass;
float linearDamping;
float angularDamping;
float gravityScale;
int32_t xfId;
int32_t m_flags;
int32_t m_islandIndex;
int32_t m_bodyID;
ContactLink *m_contactLinks;
};
속도, 질량, 댐핑, 중력 등 물리 엔진에서 필요한 속성들이 모두 포함되어 있다. 여기서 특히 주목할 부분은 xf(Transform)와 Fixture이다.
class Fixture
{
public:
// ...
protected:
Rigidbody *body;
Shape *shape;
float density;
float friction;
float restitution;
std::vector<FixtureProxy *> proxies;
};
Integrate는 world에서 runPhysics()를 통해 실행되는 첫 단계로, world 내부의 rigidbody를 순회하며 다음 과정을 수행한다.
AABB (Axis-Aligned Bounding Box): 물체의 범위를 x, y, z 축을 따라 정렬된 박스로 표현하는 방식.
Broad Phase는 1차적으로 충돌 가능성을 감지하는 단계다. 다음 과정을 통해 진행된다.
이로써 Broad Phase에서 충돌 쌍을 Narrow Phase로 넘기게 되며, 이후 Solve 단계에서 처리된다.
다음 글에서는 이 과정을 기반으로 내가 맡은 Narrow Phase와 Solve 단계를 어떻게 구현했는지에 대해 자세히 다뤄볼 예정이다.
FT_Newton: Narrow Phase / SAT vs GJK - (5) (0) | 2025.01.15 |
---|---|
FT_Newton: 『게임 물리 엔진 개발』 vs Box2D - (4) (0) | 2025.01.15 |
FT_Newton: 물리 엔진 개요 - (2) (1) | 2025.01.10 |
FT_Newton: Vulkan 공부 및 리팩토링 - (1) (0) | 2025.01.06 |
FT_Newton: 나만의 물리 엔진 제작 - (0) (0) | 2025.01.06 |