Files
game_engine/docs/superpowers/specs/2026-03-25-phase5-1-collision-detection.md
2026-03-25 11:37:16 +09:00

5.2 KiB

Phase 5-1: Collision Detection — Design Spec

Overview

voltex_physics crate에 충돌 감지 시스템을 구현한다. Broad phase (BVH) + Narrow phase (전용 함수) 구조로, Sphere와 Box 콜라이더를 지원한다.

Dependencies

  • voltex_math — Vec3, Mat4, AABB(신규)
  • voltex_ecs — World, Entity, Transform, SparseSet

Module Structure

crates/voltex_physics/
├── Cargo.toml
└── src/
    ├── lib.rs          — public exports
    ├── aabb.rs         — AABB type (voltex_math에 추가)
    ├── collider.rs     — Collider enum
    ├── contact.rs      — ContactPoint
    ├── bvh.rs          — BvhTree (broad phase)
    ├── narrow.rs       — sphere_vs_sphere, sphere_vs_box, box_vs_box
    └── collision.rs    — detect_collisions (ECS 통합)

참고: AABB는 voltex_math에 추가한다 (스펙에 명시된 기본 수학 타입).

Types

AABB (voltex_math에 추가)

#[derive(Debug, Clone, Copy)]
pub struct AABB {
    pub min: Vec3,
    pub max: Vec3,
}

Methods:

  • new(min, max) -> Self
  • from_center_half_extents(center, half_extents) -> Self
  • center() -> Vec3
  • half_extents() -> Vec3
  • contains_point(point: Vec3) -> bool
  • intersects(other: &AABB) -> bool
  • merged(other: &AABB) -> AABB — 두 AABB를 감싸는 최소 AABB
  • surface_area() -> f32 — BVH SAH 비용 계산용

Collider (voltex_physics)

#[derive(Debug, Clone, Copy)]
pub enum Collider {
    Sphere { radius: f32 },
    Box { half_extents: Vec3 },
}
  • ECS 컴포넌트로 사용. 형상(shape)만 저장.
  • 위치는 같은 entity의 Transform.position에서 가져온다.
  • aabb(&self, position: Vec3) -> AABB — broad phase용 바운딩 박스 생성

ContactPoint (voltex_physics)

#[derive(Debug, Clone, Copy)]
pub struct ContactPoint {
    pub entity_a: Entity,
    pub entity_b: Entity,
    pub normal: Vec3,      // A에서 B 방향 단위 법선
    pub depth: f32,        // 침투 깊이 (양수 = 겹침)
    pub point_on_a: Vec3,  // A 표면의 접촉점
    pub point_on_b: Vec3,  // B 표면의 접촉점
}

BvhTree (voltex_physics)

바이너리 트리. 각 리프는 하나의 Entity + AABB.

pub struct BvhTree {
    nodes: Vec<BvhNode>,
}

enum BvhNode {
    Leaf { entity: Entity, aabb: AABB },
    Internal { aabb: AABB, left: usize, right: usize },
}

Methods:

  • build(entries: &[(Entity, AABB)]) -> Self — 중앙값 분할(median split)로 구축. 가장 긴 축 기준 정렬 후 이분.
  • query_pairs(&self) -> Vec<(Entity, Entity)> — 트리 순회로 AABB가 겹치는 리프 쌍 반환.

매 프레임 rebuild한다 (동적 씬 대응). 최적화(incremental update)는 성능 문제 발생 시 추후 적용.

Narrow Phase Functions (voltex_physics::narrow)

모든 함수는 위치(Vec3)와 형상 파라미터를 받아 Option<ContactPoint>를 반환한다. Entity 정보는 호출부에서 채운다.

pub fn sphere_vs_sphere(
    pos_a: Vec3, radius_a: f32,
    pos_b: Vec3, radius_b: f32,
) -> Option<(Vec3, f32, Vec3, Vec3)>  // (normal, depth, point_a, point_b)

pub fn sphere_vs_box(
    sphere_pos: Vec3, radius: f32,
    box_pos: Vec3, half_extents: Vec3,
) -> Option<(Vec3, f32, Vec3, Vec3)>

pub fn box_vs_box(
    pos_a: Vec3, half_a: Vec3,
    pos_b: Vec3, half_b: Vec3,
) -> Option<(Vec3, f32, Vec3, Vec3)>

box_vs_box: SAT (Separating Axis Theorem) 기반. 축 정렬(AABB vs AABB)만 지원한다. 회전된 OBB는 Convex Hull 추가 시 GJK/EPA로 대체.

ECS Integration (voltex_physics::collision)

pub fn detect_collisions(world: &World) -> Vec<ContactPoint>
  1. Transform + Collider를 가진 entity를 query2로 수집
  2. 각 entity의 AABB 계산 (collider.aabb(transform.position))
  3. BvhTree::build()query_pairs()로 broad phase 후보 추출
  4. 각 후보 쌍에 대해 collider 타입 조합에 맞는 narrow phase 함수 호출
  5. 접촉이 있으면 ContactPoint에 entity 정보를 채워 결과에 추가

Conventions

  • 법선(normal): entity_a에서 entity_b 방향
  • 침투 깊이(depth): 양수 = 겹침, 0 이하 = 접촉 없음
  • 좌표계: 기존 voltex_math 규약 (오른손 좌표계)
  • WGSL vec3 alignment 규칙은 AABB에 해당 없음 (GPU에 올리지 않음)

Test Plan

voltex_math (AABB)

  • new, from_center_half_extents 생성
  • center, half_extents 계산
  • contains_point: 내부/외부/경계
  • intersects: 겹침/분리/접선
  • merged: 두 AABB 합집합
  • surface_area: 정확도

voltex_physics

  • narrow::sphere_vs_sphere: 겹침, 분리, 접선, 완전 포함
  • narrow::sphere_vs_box: 면/모서리/꼭짓점 접촉, 분리, 내부 포함
  • narrow::box_vs_box: 각 축 겹침, 분리, 접선
  • collider::aabb: Sphere/Box의 AABB 생성
  • bvh::build: 빈 입력, 단일, 다수 엔트리
  • bvh::query_pairs: 겹치는 쌍 정확성, 분리된 쌍 미포함
  • collision::detect_collisions: ECS 통합 E2E

Out of Scope (Phase 5-1)

  • Capsule, Convex Hull 콜라이더
  • GJK/EPA 알고리즘
  • 회전된 박스(OBB) 충돌
  • 리지드바디 시뮬레이션 (Phase 5-2)
  • 레이캐스팅 (Phase 5-3)
  • 연속 충돌 감지 (CCD)