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

126 lines
3.2 KiB
Markdown

# Phase 5-3: Raycasting — Design Spec
## Overview
`voltex_math`에 Ray 타입을 추가하고, `voltex_physics`에 기하 교차 함수와 BVH 가속 레이캐스트를 구현한다.
## Scope
- Ray 타입 (voltex_math)
- ray_vs_aabb, ray_vs_sphere, ray_vs_box 교차 함수
- BVH 가속 ECS 레이캐스트: `raycast(world, ray, max_dist) -> Option<RayHit>`
## Out of Scope
- Ray vs Plane, Triangle, Mesh
- 연속 레이캐스트 (sweep)
- 다중 hit 반환 (raycast_all)
## Module Structure
### voltex_math (수정)
- `crates/voltex_math/src/ray.rs` — Ray 타입 (Create)
- `crates/voltex_math/src/lib.rs` — Ray 모듈 등록 (Modify)
### voltex_physics (추가)
- `crates/voltex_physics/src/ray.rs` — ray_vs_aabb, ray_vs_sphere, ray_vs_box (Create)
- `crates/voltex_physics/src/raycast.rs` — RayHit, raycast ECS 통합 (Create)
- `crates/voltex_physics/src/lib.rs` — 새 모듈 등록 (Modify)
## Types
### Ray (voltex_math)
```rust
#[derive(Debug, Clone, Copy)]
pub struct Ray {
pub origin: Vec3,
pub direction: Vec3,
}
```
- `new(origin, direction) -> Self` — direction을 정규화하여 저장
- `at(t: f32) -> Vec3``origin + direction * t`
### RayHit (voltex_physics)
```rust
#[derive(Debug, Clone, Copy)]
pub struct RayHit {
pub entity: Entity,
pub t: f32,
pub point: Vec3,
pub normal: Vec3,
}
```
## Functions
### ray_vs_aabb (voltex_physics::ray)
```rust
pub fn ray_vs_aabb(ray: &Ray, aabb: &AABB) -> Option<f32>
```
Slab method. t값만 반환 (BVH 순회용, 법선 불필요).
ray가 AABB 내부에서 시작하면 t=0 반환.
### ray_vs_sphere (voltex_physics::ray)
```rust
pub fn ray_vs_sphere(ray: &Ray, center: Vec3, radius: f32) -> Option<(f32, Vec3)>
```
이차방정식 풀이. (t, normal) 반환.
ray가 구 내부에서 시작하면 far intersection 반환.
### ray_vs_box (voltex_physics::ray)
```rust
pub fn ray_vs_box(ray: &Ray, center: Vec3, half_extents: Vec3) -> Option<(f32, Vec3)>
```
Slab method + 진입 면에서 법선 계산. (t, normal) 반환.
ray가 박스 내부에서 시작하면 t=0, 진행 방향 기준 법선 반환.
### raycast (voltex_physics::raycast)
```rust
pub fn raycast(world: &World, ray: &Ray, max_dist: f32) -> Option<RayHit>
```
1. Transform + Collider 가진 entity 수집, AABB 계산
2. BvhTree::build()로 BVH 구축
3. 모든 리프를 순회하며 ray_vs_aabb로 broad phase
4. AABB hit인 경우 콜라이더 타입별 정밀 교차:
- Sphere → ray_vs_sphere
- Box → ray_vs_box
5. t < max_dist인 hit 중 가장 가까운 것 반환
NOTE: BVH 조기 종료 최적화는 추후. 첫 구현은 모든 리프 검사 후 최소 t 선택.
## Conventions
- Ray direction은 항상 단위 벡터
- t >= 0 인 교차만 유효 (ray 뒤쪽 무시)
- normal은 ray가 진입하는 면의 바깥 방향
- max_dist: t의 상한
## Test Plan
### voltex_math (Ray)
- new: direction 정규화 확인
- at: 정확한 점 계산
### voltex_physics (ray.rs)
- ray_vs_aabb: hit, miss, 내부 시작 (t=0)
- ray_vs_sphere: hit (t, normal 정확도), miss, 접선, 내부 시작
- ray_vs_box: 각 면 hit, miss, 내부 시작
### voltex_physics (raycast.rs)
- 빈 world → None
- 단일 entity hit
- 여러 entity 중 가장 가까운 것 반환
- miss (max_dist 초과)
- Sphere + Box 혼합