# Drone Flight Studio

Windows용 3D 쿼드콥터 비행 시뮬레이터입니다. 기체, 프로펠러 애니메이션, 해안 도시 연습장은 자체 제작했습니다. CesiumJS로 렌더링하고 Google Maps Photorealistic 3D Tiles를 선택적으로 연결합니다.

## 실행

`Drone-Flight-Studio.exe`를 더블클릭하세요. Node.js 설치 없이 실행됩니다. 첫 실행 시 압축 해제로 잠시 기다릴 수 있습니다. `시작.cmd`도 같은 프로그램을 엽니다. 설치·코드 서명되지 않은 로컬 빌드입니다.

연습장은 인터넷/API 키 없이 실행됩니다. 시작 위치에서 **T**를 누르면 약 8m까지 자동 이륙합니다. 키를 놓으면 감속하고 호버링합니다. 실제 항공역학 인증이나 실제 드론 제어를 위한 소프트웨어는 아닙니다.

| 키 | 기능 |
|---|---|
| W / S | 전진 / 후진, 피치 자동 표현 |
| A / D | 좌 / 우 이동, 롤 자동 표현 |
| ↑ / ↓ | 상승 / 하강 |
| ← / → | 기수 왼쪽 / 오른쪽 회전 (yaw) |
| T / L | 자동 이륙 / 현재 위치 자동 착륙 |
| Shift | 고속 이동 (최대 22 m/s, 기본 11 m/s) |
| Space | 제동·호버링, 자동 착륙 취소 |
| C | 추적 → 드론 카메라 → 궤도 시점 |
| I / K | 카메라 틸트 위 / 아래 (-90~30도) |
| J / U | 카메라 팬 왼쪽 / 오른쪽 (-180~180도) |
| O | 짐벌·화각 초기화 |
| 마우스 휠 | 화각 조절 (25~100도) |
| F | 드론 카메라 시점 PNG 사진 저장 |
| P | 일시정지 / 계속 |
| R | 출발 지점으로 초기화 |
| H | 조종 UI 숨김 / 표시 |

카메라 패널 슬라이더로도 틸트·팬·화각을 조절할 수 있습니다. 짐벌 각도는 드론 카메라 시점과 촬영에 적용됩니다. 외부 추적 시점은 기체를 바라봅니다. 입력 칸이나 슬라이더에 초점이 있는 동안 비행 단축키는 무시됩니다. 장면을 클릭하면 비행 키를 다시 사용할 수 있습니다. 다른 창으로 전환하면 비행을 자동 일시정지합니다.

## Google 지도 연결

1. Google Cloud 프로젝트에서 결제 계정을 연결하고 **Map Tiles API**를 활성화한 뒤 API 키를 발급합니다.
2. 앱 우측 상단 **지도 설정** → **Google Maps**를 선택합니다.
3. API 키를 입력하고 위치 프리셋 또는 위도·경도를 설정합니다.
4. **출발면 해발 높이**를 실제 출발 지면 또는 옥상 높이에 맞춘 뒤 시작합니다.

API 키는 메모리에서만 사용하며 디스크에 저장하지 않습니다. 앱을 재실행하면 다시 입력해야 합니다. Google 연결을 선택할 때부터 API 요청 및 과금이 발생할 수 있습니다. Cloud 콘솔에서 Map Tiles API로 키 사용 범위를 제한하고 할당량을 관리하세요. 앱은 보통 `http://127.0.0.1:4173`에서 실행되며 해당 포트가 점유되면 임시 포트를 사용합니다. HTTP 리퍼러 제한을 설정하는 경우 이 주소를 고려해야 합니다. 클라이언트 렌더링 특성상 API 키는 실행 중 네트워크 요청에서 보일 수 있습니다.

Google 모드는 지원 지역의 실제 3D 타일을 스트리밍합니다. 서울 등 일부 위치에서는 고해상도 3D 데이터가 제공되지 않을 수 있습니다. 연결 실패 시 연습장/기존 환경이 유지됩니다. 유효한 개인 API 키가 제공되지 않아 실제 Google 계정으로 지도 로딩은 검증하지 못했습니다.

**지형 높이를 자동 측정하지 않습니다.** Google 모드의 고도는 입력한 출발면 기준이고 지형·건물 충돌은 지원하지 않습니다. 연습장은 건물 주변의 단순 수평 충돌 방지를 제공합니다. 충돌 박스는 건물의 근사치이며 정밀한 충돌·옥상 착륙 시뮬레이션은 아닙니다. 최대 상대 높이는 600m입니다.

Google Maps 및 데이터 제공자 출처는 화면 하단에 표시하며 촬영 이미지 하단에도 포함합니다. 사진의 Google 출처 표기를 유지하고 공유·재사용 시 Google 이용약관을 확인하세요. 앱은 지도를 별도로 다운로드하거나 오프라인 지도 DB를 만들지 않습니다.

- [Google Map Tiles API 설정](https://developers.google.com/maps/documentation/tile/get-api-key)
- [Google 3D 렌더러 연동](https://developers.google.com/maps/documentation/tile/use-renderer)
- [Google Map Tiles 이용 정책](https://developers.google.com/maps/documentation/tile/policies)
- [Google Maps Platform 약관](https://cloud.google.com/maps-platform/terms)
- [Google 개인정보처리방침](https://policies.google.com/privacy)

## 소스 코드

`source/`에 소스, 원본 glTF 기체, 빌드 설정과 잠금 파일이 있습니다. Node.js 22.12 이상이 필요합니다.

```powershell
cd source
npm ci
npm start
# 웹 브라우저에서 실행: http://127.0.0.1:4173
npm run dev
# 물리 테스트
npm test
# Edge가 설치된 Windows에서 통합 테스트
node tests/ui-smoke.mjs
# Windows 실행 파일 생성
npm run dist
```

`scripts/model.mjs`는 기체를 원본 glTF로 생성합니다. `app/physics.mjs`는 비행 상태/물리, `app/main.mjs`는 지도·렌더링·입력·촬영을 담당합니다. 개발용 서버는 로컬 루프백 인터페이스에만 바인딩합니다.

## 검증

- 비행 물리 단위 테스트 5개: 자동 이착륙, 기체 상대 이동, 감속, 일시정지, 대각 속도 제한, 바닥/장애물, 제동.
- 실제 Edge WebGL 통합 테스트: 3D 렌더링, 키보드 비행, 카메라 전환/짐벌, PNG 다운로드, 초기화/착륙, API 키 누락 처리, UI 표시.
- Google 실서버 연동은 유효한 API 키 입력 후 별도 확인이 필요합니다.

## 개인정보

연습장에서는 외부 서비스에 위치나 비행 데이터를 전송하지 않습니다. Google 모드에서는 Google로 API 키와 현재 뷰의 지도 타일 요청을 전송합니다. 사진은 사용자가 선택한 로컬 위치에 저장합니다. 앱 자체 분석/추적 서비스는 없습니다.
