# RoomForge 이동 메타데이터 1.0 GLB를 읽을 때 장면 루트 노드의 `extras.roomforge_navigation`을 확인합니다. Three.js GLTFLoader에서는 해당 루트 Object3D의 `userData.roomforge_navigation`으로 읽힙니다. 별도 `navigation.json`에도 동일한 값을 저장합니다. `extras`는 glTF의 사용자 정의 JSON 저장 공간입니다: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-extras ## 좌표와 방향 `schema`는 `roomforge.navigation`, `version`은 `1.0`입니다. 좌표는 **장면 루트 로컬 좌표**, 단위는 **미터**, 순서는 `[x, y, z]`입니다. 오른손 좌표계, +Y 위, 기본 정면 -Z입니다. 위치는 카메라 높이가 아닌 **발바닥이 지지면에 닿는 위치**입니다. GLB 루트를 이동/회전/스케일했다면 좌표에도 같은 루트 변환을 적용하세요. `yaw_deg`는 +Y축 회전 각도입니다. 0°는 -Z, +90°는 -X, -90°는 +X입니다. Three.js에서는 `rotation.y = yaw_deg * Math.PI / 180`으로 사용합니다. ## 필드 규격 | 필드 | 의미 | |---|---| | `status` | `ready`: AI 선택 및 지형 검사 완료. `unavailable`: 적합한 지점 없음. 이 경우 좌표를 임의로 만들지 않음 | | `recommended_start` | 시작 위치 `position_m`, 바라볼 방향 `yaw_deg`, 선정 이유 `reason`, AI 적합도 `confidence` | | `stage_center` | 주 무대의 중심에 가까운 이동 가능 지점. 콘서트가 아닌 장소에서는 주요 탐험/상호작용 지점 | | `walkable_points` | 시작점과 연결된 영역의 추천 이동 지점 목록 | | `movement_bounds_m` | 시작점에서 도달 가능한 표본 영역을 감싸는 `{min:[x,y,z], max:[x,y,z]}`. 내부 전체가 이동 가능하다는 뜻은 아님 | | `walkable_area` | `representation: sampled_grid`, `cell_size_m`, 시작 영역 `region_id`, 연결된 이동 가능 표본 `cells` | | `walkable_area.cells[]` | 각 셀의 지지면 중심 `center_m`, 지지 메시 `support_mesh`, 경사 `slope_deg` | | `agent` | 검사에 사용한 사람 크기: 높이 1.8m, 반지름 0.55m, 최대 경사 35°, 최대 단차 0.45m | | `scene_bounds_m` | 하늘을 제외한 전체 장면 메시의 경계 | | `generated_at` | 생성 시각 ISO 8601 UTC | | `notes` | 검사 범위 및 제한 설명 | 각 추천 지점에는 `support_mesh`, `region_id`, `slope_deg`, `clearance_radius_m`, `geometry_validated:true`도 포함합니다. `confidence`는 0~1 AI 적합도 판단값이며 측정된 안전 확률이 아닙니다. 무대 중심이 시작점과 다른 영역에 있으면 걸어서 연결되어 있다고 간주하지 마세요. ## 이동 영역 사용 각 셀은 X/Z 평면에서 `center_m`을 중심으로 한 변 길이 `cell_size_m`의 정사각형입니다. Y는 **중심점의 지지면 높이**이며 셀 전체의 일정한 높이를 뜻하지 않습니다. 셀 중심, 모서리 지지면, 머리 공간, 주변 반지름, 연결 경로의 0.25m 간격 표본을 검사합니다. 연결된 영역만 `walkable_area.cells`에 저장합니다. 이 데이터는 표본 격자이며 완전한 내비메시가 아닙니다. 이동 후보를 셀 영역으로 제한한 뒤 실제 런타임 캡슐 충돌/바닥 레이캐스트로 이동을 확인하세요. 셀 사이의 작은 장애물이나 동적 물체는 런타임 검사가 필요합니다. `collision:false` 장식·군중은 검사에서 제외됩니다. 형상이 수정되면 좌표를 다시 판정하며 재판정되지 않은 오래된 값은 GLB에 넣지 않습니다. `collision:true` 군중 구역은 사람이 밀집한 경계 상자를 장애물로 취급합니다. 군중 머리 위를 바닥 후보로 선택하지 않습니다. 관객 사이의 개별 틈새는 이동 가능 범위에 포함하지 않는 보수적인 검사입니다. ## Three.js 읽기 예 ```js let navigation, navigationRoot; gltf.scene.traverse(object => { if (object.userData.roomforge_navigation) { navigation = object.userData.roomforge_navigation; navigationRoot = object; } }); if (navigation?.status === 'ready') { const local = new THREE.Vector3(...navigation.recommended_start.position_m); const worldFeet = navigationRoot.localToWorld(local); // 캐릭터 발 위치를 worldFeet에 배치합니다. // 루트 회전이 있으면 yaw에도 루트 월드 회전을 합성합니다. } ``` 기계 검증 규격은 `shared/navigation.schema.json`입니다. 이동 가능 지점을 AI가 새로 상상하는 대신 실제 지형 검사에서 얻은 후보 중 선택합니다.