fix: 카메라 타겟이 항상 지반 아래를 가리키던 버그

[원인]
scene_extents 가 반환하는 BB 는 지반·교대 푸팅까지 포함 →
  top_y = girder_h + slab + 200
  bot_y = -(girder_h + 4000)
center Y = (top_y + bot_y)/2 = (slab - 3800)/2 ≈ -1790mm (지반 아래 1.8m)

더 큰 문제: top/bot 이 girder_h 에 따라 같은 비율로 변해서 center Y 는 고정.
→ girder_h 가 바뀌어도 카메라 타겟은 거더 중심을 추적하지 않음.
→ 거더가 실제론 커졌어도 카메라가 항상 지반 아래를 보기 때문에, 슬래브만
   화면 위쪽으로 멀어지고 거더는 그대로 있는 것처럼 인식됨.

[수정]
- rebuild_mesh(): zoom_extents 에 전달할 Y 범위를 [0, girder_h+slab] 로 제한
  → target Y = (girder_h + slab)/2, 거더·데크 중심으로 카메라가 추적.
- 초기 카메라: cy 를 scene_extents 중심 대신 (girder_h+slab)/2 로 설정.

결과: 거더 높이를 올리면 카메라 target 도 비례해 위로 이동 → 거더가 화면
중앙에서 자라는 것이 보이고, 슬래브는 그 위쪽에 붙어 함께 올라감.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-15 10:01:35 +09:00
parent 24b15f15ec
commit e986604f49

View File

@@ -260,10 +260,12 @@ impl RenderState {
let num_indices = mesh.indices.len() as u32;
// ── Camera ────────────────────────────────────────────────────────────
// Camera for full bridge scene
// Camera for full bridge scene.
// 주의: scene_extents 는 지반·교대까지 포함해서 center Y ≈ -1790mm (지반 아래).
// 초기부터 카메라가 교량 중심을 향하도록 Y 타겟은 거더+데크 중심으로 계산.
let (mn, mx) = scene_extents(&params);
let cx = (mn[0] + mx[0]) * 0.5;
let cy = (mn[1] + mx[1]) * 0.5;
let cy = (params.girder_height + params.slab_thickness) * 0.5;
let cz = (mn[2] + mx[2]) * 0.5;
let span = (mx[2] - mn[2]).max(mx[0] - mn[0]);
let mut camera = Camera {
@@ -492,8 +494,15 @@ impl RenderState {
let (mn, mx) = scene_extents(&self.params);
self.scene_mn = mn;
self.scene_mx = mx;
// Apply 후 씬 범위에 맞게 카메라 자동 피트 (거더 높이 변경 등이 즉시 보이도록).
self.camera.zoom_extents(mn, mx);
// Apply 후 교량 상부구조 (거더+데크) 로 제한한 BB로 카메라 자동 피트.
// scene_extents 는 지반·교대 푸팅까지 포함되어 center Y ≈ -1790mm(지반 아래) 가 되고,
// girder_h 가 바뀌어도 top/bot 이 같은 비율로 이동해 center 가 고정 → 카메라가
// 거더 중심을 추적하지 않아 "거더는 그대로"처럼 보이는 착시.
// → Y 범위를 [0, girder_h + slab] 로만 잡아 target Y = 거더+데크 중심이 되게 함.
let focus_top = self.params.girder_height + self.params.slab_thickness;
let focus_mn = [mn[0], 0.0_f32, mn[2]];
let focus_mx = [mx[0], focus_top, mx[2]];
self.camera.zoom_extents(focus_mn, focus_mx);
self.update_camera();
self.dirty = false;
}