# Backdrop (배경막)

6면 박스 (4 벽 + 바닥 + 천정) 형태의 *환경 / 분위기* 컴포넌트. 3D 전용.
**장면의 시각적 setting** 을 만든다 — 창고, 클린룸, 쇼룸 등 — 카메라를 둘러
싸는 6면 표면으로 분위기를 형성한다.

Backdrop 은 *구조 컨테이너가 아니다*. 자식 관리도 하지 않는다. 순수하게
시각적/장식 목적. 실제 컴포넌트는 backdrop 의 부피 *안에* 자유롭게 배치하면
된다 — backdrop 은 단지 벽지일 뿐.

## 가시성

Backdrop 은 **3D 전용**이다. 2D 캔버스에서는 의도적으로 보이지도 선택되지도
않는다. 작업하려면 모델러를 3D 모드로 전환한다.

- 2D 캔버스 — 그리기 없음, 클릭 대상 없음
- 3D 모드 — 안에서 본 6면 envelope. 작은 *편집용 선택 핸들* 구체가 유일한
  클릭 대상. envelope 의 면 자체는 raycast 대상이 아니라 안에 놓인 컴포넌트
  들이 가려지지 않는다.

## 면별 상태 — `state.faces`

6 면 각각 독립적으로 설정한다.

```
state.faces = {
  east:    { fillStyle, visible, alpha, rotation, mirror },
  west:    { fillStyle, visible, alpha, rotation, mirror },
  north:   { ... },
  south:   { ... },
  floor:   { ... },
  ceiling: { ... },
}
```

| 필드         | 의미                                                                                                                  |
| ------------ | --------------------------------------------------------------------------------------------------------------------- |
| `fillStyle`  | 면 색상 또는 텍스처 (`#RGB` / `rgba(...)` / 패턴 / 이미지 URL). rgba 알파는 material opacity 에 반영.                 |
| `visible`    | 면을 켜고 끈다 (설정값은 보존).                                                                                       |
| `alpha`      | 면별 투명도 곱셈자 (0–1). `fillStyle.alpha` 와 결합.                                                                  |
| `rotation`   | 텍스처 회전 (0 / 90 / 180 / 270). 기본 `0`.                                                                           |
| `mirror`     | 좌우 거울상 (boolean). `rotation` 과 결합해 dihedral 8가지 방향 모두 표현.                                            |

엔진은 모든 면에 *안쪽 시점 U-flip* 보정을 자동 적용한다 — Three.js
BoxGeometry 의 기본 UV 는 바깥 시점 기준이라 backdrop 안에서 보면 좌우 반전돼
나타나는데, 이 보정으로 `rotation=0, mirror=false` 가 진짜 정방향이 된다.

### 방위 매핑 (things-scene 2D → 3D)

```
2D left → 3D +x   ⇒  east  = +X
2D top  → 3D +z   ⇒  south = +Z   (= 화면 아래 = 남쪽)
                      north = −Z
```

지도 컨벤션과 일치 — 2D 평면도의 "위쪽" 이 북쪽.

## 컴포넌트 수준 속성

| 속성          | 의미                                                                                                                  |
| ------------- | --------------------------------------------------------------------------------------------------------------------- |
| `fitToBoard`  | `true` 면 envelope 가 rootModel 의 `width / height` 를 자동 추종, 평면 위치는 world origin 에 고정. board 리사이즈 시 자동 재빌드. |
| `seeThrough`  | `true` (기본) 면 뒷면 culling — 카메라가 backdrop *외부에서 안을 들여다 보는* 일반 케이스. 360° 가상 환경처럼 막아야 할 땐 `false`. |
| `alpha`       | 면별 alpha 위에 곱해지는 전역 투명도.                                                                                 |
| `width / height / depth` | `fitToBoard` off 일 때의 envelope 크기.                                                                    |

수직 위치는 scene 수준의 `state.placement` (`'floor'` / `'space'` /
`'inverted'`) 를 따른다 — 같은 placement 의 다른 컴포넌트들과 일관되게
배치된다.

## fit-to-board

`fitToBoard = true` 가 일반적인 사용 — backdrop 이 *board 전체를 감싸는
벽지 envelope* 가 된다. board 크기를 단일 source of truth 로 두고 backdrop
은 따라가게 한다.

- `OFF → ON` 전환 시 초기 depth: `min(width, height)`.
- 이후 depth 는 자동 동기화 대상이 아니다 (property panel 에서 수동 편집한
  값이 유지됨).

## 가이드 외곽선

`app.isEditMode === true` 동안만 envelope 의 가장자리 outline 이 표시된다.
런타임에는 outline 없이 면 채움만으로 envelope 가 인지된다.

## 팁

- 면 텍스처가 좌우 반전돼 보이면 그 면의 `mirror` 를 토글하거나 `rotation`
  을 180 으로.
- 은은한 분위기 tint (예: 창고 ambient) 가 필요하면 전역 `alpha` 대신
  `fillStyle` 에 `rgba(...)` 를 직접 — 색과 투명도를 한 곳에서 관리.
- `seeThrough = false` 는 *진짜로 막아야 하는* 환경 (예: 가상 룸 내부)
  에서만 사용.
- 한 scene 에 backdrop 1 개를 권장. 스택 가능하지만 서로를 가린다.
