# 画面設計書 12-Menubar - Add

## 概要

本ドキュメントは、three.js エディタにおけるオブジェクト追加メニュー（Menubar - Add）の画面設計書である。このメニューは、3Dシーンに各種ジオメトリ（メッシュ）、ライト、カメラなどのオブジェクトを追加する機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：3Dシーンを構築する際、ユーザーは基本的な3Dプリミティブ（Box、Sphere、Cylinderなど）やライト、カメラを素早く追加できる必要がある。このメニューは、コード記述なしでGUI操作のみで多様なオブジェクトをシーンに配置することを可能にし、3Dコンテンツ制作の効率を大幅に向上させる。

**画面へのアクセス方法**：エディタメイン画面（editor/index.html）のメニューバー領域に常時表示される。「Add」メニュータイトルをクリックすると、ドロップダウン形式でカテゴリ別のオプションが展開される。サブメニュー（Mesh、Light、Camera）はマウスオーバーでさらに展開される。

**主要な操作・処理内容**：
1. **Group追加**：空のGroupオブジェクトをシーンに追加
2. **Mesh追加**（サブメニュー）：Box、Capsule、Circle、Cylinder、Dodecahedron、Icosahedron、Lathe、Octahedron、Plane、Ring、Sphere、Sprite、Tetrahedron、Torus、TorusKnot、Tubeの16種類
3. **Light追加**（サブメニュー）：Ambient、Directional、Hemisphere、Point、Spotの5種類
4. **Camera追加**（サブメニュー）：Orthographic、Perspectiveの2種類

**画面遷移**：メニュー操作によりオブジェクトがViewportのシーンに追加される。追加されたオブジェクトは自動的に選択され、Sidebar - Object/Geometry/Materialパネルの表示が更新される。

**権限による表示制御**：特別な権限制御は存在しない。すべてのユーザーがすべてのオブジェクト追加機能を使用できる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 75 | Mesh | 主機能 | メッシュオブジェクトの追加 |
| 27 | BoxGeometry | 補助機能 | Boxメッシュの追加 |
| 28 | SphereGeometry | 補助機能 | Sphereメッシュの追加 |
| 30 | CylinderGeometry | 補助機能 | Cylinderメッシュの追加 |
| 32 | TorusGeometry | 補助機能 | Torusメッシュの追加 |
| 33 | TorusKnotGeometry | 補助機能 | TorusKnotメッシュの追加 |
| 67 | AmbientLight | 補助機能 | 環境光の追加 |
| 68 | DirectionalLight | 補助機能 | 平行光源の追加 |
| 69 | PointLight | 補助機能 | 点光源の追加 |
| 70 | SpotLight | 補助機能 | スポットライトの追加 |
| 71 | HemisphereLight | 補助機能 | 半球光の追加 |
| 19 | PerspectiveCamera | 補助機能 | 透視投影カメラの追加 |
| 20 | OrthographicCamera | 補助機能 | 正射影カメラの追加 |
| 83 | Group | 補助機能 | グループオブジェクトの追加 |
| 82 | Sprite | 補助機能 | スプライトの追加 |

## 画面種別

メニュー（ドロップダウン + サブメニュー）

## URL/ルーティング

エディタメイン画面の一部として `editor/index.html` に含まれる。独立したルーティングは持たない。

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| カメラアスペクト比 | 入力 | Number | OrthographicCamera作成時に使用（editor.camera.aspect） |
| 作成オブジェクト | 出力 | Object3D | シーンに追加されるオブジェクト |

## 表示項目

### メインメニュー

| 項目 | 表示内容 |
|------|---------|
| Group | グループオブジェクト追加 |
| Mesh | メッシュサブメニュー展開（ホバーで表示） |
| Light | ライトサブメニュー展開（ホバーで表示） |
| Camera | カメラサブメニュー展開（ホバーで表示） |

### Meshサブメニュー（16項目）

| 項目 | ジオメトリクラス | デフォルトパラメータ |
|------|-----------------|---------------------|
| Box | BoxGeometry | (1, 1, 1, 1, 1, 1) |
| Capsule | CapsuleGeometry | (1, 1, 4, 8, 1) |
| Circle | CircleGeometry | (1, 32, 0, Math.PI * 2) |
| Cylinder | CylinderGeometry | (1, 1, 1, 32, 1, false, 0, Math.PI * 2) |
| Dodecahedron | DodecahedronGeometry | (1, 0) |
| Icosahedron | IcosahedronGeometry | (1, 0) |
| Lathe | LatheGeometry | デフォルト |
| Octahedron | OctahedronGeometry | (1, 0) |
| Plane | PlaneGeometry | (1, 1, 1, 1) |
| Ring | RingGeometry | (0.5, 1, 32, 1, 0, Math.PI * 2) |
| Sphere | SphereGeometry | (1, 32, 16, 0, Math.PI * 2, 0, Math.PI) |
| Sprite | SpriteMaterial | なし |
| Tetrahedron | TetrahedronGeometry | (1, 0) |
| Torus | TorusGeometry | (1, 0.4, 12, 48, Math.PI * 2) |
| TorusKnot | TorusKnotGeometry | (1, 0.4, 64, 8, 2, 3) |
| Tube | TubeGeometry | CatmullRomCurve3ベース、(path, 64, 1, 8, false) |

### Lightサブメニュー（5項目）

| 項目 | ライトクラス | デフォルトパラメータ |
|------|-------------|---------------------|
| Ambient | AmbientLight | color: 0x222222 |
| Directional | DirectionalLight | color: 0xffffff, intensity: 1, position: (5, 10, 7.5) |
| Hemisphere | HemisphereLight | skyColor: 0x00aaff, groundColor: 0xffaa00, intensity: 1, position: (0, 10, 0) |
| Point | PointLight | color: 0xffffff, intensity: 1, distance: 0 |
| Spot | SpotLight | color: 0xffffff, intensity: 1, angle: Math.PI * 0.1, position: (5, 10, 7.5) |

### Cameraサブメニュー（2項目）

| 項目 | カメラクラス | デフォルトパラメータ |
|------|-------------|---------------------|
| Orthographic | OrthographicCamera | left: -aspect, right: aspect |
| Perspective | PerspectiveCamera | デフォルト |

## イベント仕様

### 1-Group追加

- **トリガー**：Groupメニュー項目クリック
- **処理内容**：
  1. `new THREE.Group()` でGroupオブジェクトを作成
  2. nameを'Group'に設定
  3. `AddObjectCommand` を実行してシーンに追加
- **画面更新**：Viewportにオブジェクトが追加され、自動選択される

### 2-Mesh追加（例：Box）

- **トリガー**：Mesh > Boxメニュー項目クリック
- **処理内容**：
  1. `new THREE.BoxGeometry(1, 1, 1, 1, 1, 1)` でジオメトリ作成
  2. `new THREE.MeshStandardMaterial()` でマテリアル作成
  3. `new THREE.Mesh(geometry, material)` でメッシュ作成
  4. nameを'Box'に設定
  5. `AddObjectCommand` を実行してシーンに追加
- **画面更新**：Viewportにメッシュが追加され、自動選択される

### 3-Light追加（例：DirectionalLight）

- **トリガー**：Light > Directionalメニュー項目クリック
- **処理内容**：
  1. `new THREE.DirectionalLight(0xffffff, 1)` でライト作成
  2. nameを'DirectionalLight'、target.nameを'DirectionalLight Target'に設定
  3. position.set(5, 10, 7.5) で初期位置設定
  4. `AddObjectCommand` を実行してシーンに追加
- **画面更新**：Viewportにライト（とヘルパー）が追加され、自動選択される

### 4-Camera追加（例：PerspectiveCamera）

- **トリガー**：Camera > Perspectiveメニュー項目クリック
- **処理内容**：
  1. `new THREE.PerspectiveCamera()` でカメラ作成
  2. nameを'PerspectiveCamera'に設定
  3. `AddObjectCommand` を実行してシーンに追加
- **画面更新**：Viewportにカメラ（とヘルパー）が追加され、自動選択される

## データベース更新仕様

本画面はブラウザ上で動作する3Dエディタであり、データベースへの直接的な更新は行わない。すべての操作はメモリ上のシーングラフに対して行われる。

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|---------------|---------------|---------|
| なし | - | 本メニューでは特別なメッセージ表示はない |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| なし | 本メニューでは特別な例外処理はない。オブジェクト作成は常に成功する |

## 備考

- すべてのメッシュは `MeshStandardMaterial` がデフォルトで適用される（PBR対応）
- Latheジオメトリは `DoubleSide` マテリアルが使用される
- DirectionalLightとSpotLightはtargetオブジェクトも自動的に作成される
- サブメニューはマウスオーバーで表示され、マウスアウトで非表示になる
- サブメニューの位置は親メニュー項目の右端に合わせて動的に計算される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

THREE.jsの基本オブジェクト構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | three.module.js | `build/three.module.js` | Mesh、Light、Cameraの基底クラス構造 |

**読解のコツ**: THREE.jsのオブジェクトはすべてObject3Dを継承している。Meshはgeometryとmaterialを持つ。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Menubar.Add.js | `editor/js/Menubar.Add.js` | メニューUI構築とサブメニュー展開ロジック |

**主要処理フロー**:
1. **7-21行目**: UIPanel/UIRowを使用したメニュー構造の構築
2. **23-36行目**: Groupオブジェクト追加処理
3. **38-59行目**: Meshサブメニューのホバー表示制御
4. **61-323行目**: 各種Meshの追加処理（16種類）
5. **325-449行目**: 各種Lightの追加処理（5種類）
6. **451-504行目**: 各種Cameraの追加処理（2種類）

#### Step 3: サブメニュー表示ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Menubar.Add.js | `editor/js/Menubar.Add.js` | onMouseOver/onMouseOut処理 |

**主要処理フロー**:
- **40-55行目**: `meshSubmenuTitle.onMouseOver()` でサブメニュー位置を計算し表示
- **43-47行目**: getBoundingClientRect()で親要素の位置取得、setLeft/setTopで配置

### プログラム呼び出し階層図

```
MenubarAdd (Menubar.Add.js)
    │
    ├─ group.onClick()
    │      ├─ new THREE.Group()
    │      └─ editor.execute(AddObjectCommand)
    │
    ├─ meshSubmenu
    │      ├─ box.onClick()
    │      │      ├─ new THREE.BoxGeometry()
    │      │      ├─ new THREE.MeshStandardMaterial()
    │      │      ├─ new THREE.Mesh()
    │      │      └─ editor.execute(AddObjectCommand)
    │      ├─ sphere.onClick() ... (同様)
    │      └─ ... (他14種類)
    │
    ├─ lightSubmenu
    │      ├─ ambient.onClick()
    │      │      ├─ new THREE.AmbientLight()
    │      │      └─ editor.execute(AddObjectCommand)
    │      └─ ... (他4種類)
    │
    └─ cameraSubmenu
           ├─ orthographic.onClick()
           │      ├─ new THREE.OrthographicCamera()
           │      └─ editor.execute(AddObjectCommand)
           └─ perspective.onClick()
                  ├─ new THREE.PerspectiveCamera()
                  └─ editor.execute(AddObjectCommand)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

メニュークリック ───────▶ Menubar.Add.js ──────────▶ シーングラフ更新
                              │
editor.camera.aspect ──────────┘                    ▶ Sidebar更新
(Orthographic用)
                                                    ▶ Viewport再描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Menubar.Add.js | `editor/js/Menubar.Add.js` | ソース | Addメニューの主要実装 |
| AddObjectCommand.js | `editor/js/commands/AddObjectCommand.js` | ソース | オブジェクト追加コマンド |
| ui.js | `editor/js/libs/ui.js` | ソース | UIコンポーネント（UIPanel, UIRow等） |
| Editor.js | `editor/js/Editor.js` | ソース | editor.execute()の実装 |
