# 画面設計書 53-メッシュエディタ

## 概要

本ドキュメントは、Godot Engineエディターにおける「メッシュエディタ」の画面設計を定義するものである。メッシュエディタは、Meshリソースを選択した際にインスペクタードックの上部に表示される3Dプレビューウィジェットを提供し、メッシュの形状を視覚的に確認できるエディタープラグインである。

### 本画面の処理概要

メッシュエディタは、3Dメッシュリソースのプレビュー表示に特化したシンプルなビューワーを提供する。専用のサブビューポート内でメッシュをレンダリングし、ユーザーはマウスドラッグで回転させてあらゆる角度からメッシュを確認できる。ライトの切り替え機能により、異なる照明条件下でのメッシュの見え方を確認することも可能。

**業務上の目的・背景**：3Dゲーム開発において、インポートされたメッシュや手動で作成したメッシュリソースの形状を素早く確認する必要がある。メッシュエディタは、シーンにメッシュを配置することなく、インスペクター上で直接メッシュの外観を確認できるため、アセット管理やデバッグの効率を向上させる。特に大量のメッシュアセットを扱うプロジェクトにおいて、目的のメッシュを素早く特定する際に有用である。

**画面へのアクセス方法**：ファイルシステムドックでメッシュリソースファイル（.mesh、.res、.tres等）を選択するか、インスペクタードックでMeshリソースプロパティをクリックしてリソースを展開すると、インスペクター上部に3Dプレビューが自動的に表示される。

**主要な操作・処理内容**：
1. メッシュの3Dプレビュー表示：選択されたメッシュをリアルタイムでレンダリング
2. 回転操作：マウスの左ボタンドラッグでメッシュを回転させて確認
3. ライト1切り替え：メインのディレクショナルライトのオン/オフを切り替え
4. ライト2切り替え：サブのディレクショナルライトのオン/オフを切り替え

**画面遷移**：エディタメイン画面のインスペクタードック内に統合されて表示される。Meshリソースの選択解除によりプレビューは非表示となる。この画面から他の画面への遷移は発生しない。

**権限による表示制御**：特にロールベースの制御はない。エディター環境での利用が前提であり、すべてのユーザーが同等の機能にアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | 3Dレンダリング | 主機能 | メッシュリソースの詳細表示・プレビュー |

## 画面種別

プレビュー/ビューワー（リソースプレビュー）

## URL/ルーティング

デスクトップアプリケーションのため、URLベースのルーティングは存在しない。Meshリソース選択時に自動的にアクティブ化される。

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|------|----------|------|
| mesh | Ref<Mesh> | 入力 | プレビュー対象のメッシュリソース |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|------|------|
| 3Dプレビュー領域 | SubViewportContainer | メッシュを表示するビューポート |
| ライト1ボタン | Button | メインライトの切り替えトグルボタン |
| ライト2ボタン | Button | サブライトの切り替えトグルボタン |
| メッシュインスタンス | MeshInstance3D | プレビュー用のメッシュ表示ノード |

## イベント仕様

### 1-メッシュプレビュー表示

Meshリソースが選択されると、edit()メソッドが呼び出され、以下の処理が実行される：
- メッシュがMeshInstance3Dに設定される
- メッシュのAABB（軸平行バウンディングボックス）から適切なスケールとオフセットが計算される
- 初期回転（X軸-15度、Y軸30度）が設定される

### 2-回転操作

プレビュー領域上でマウス左ボタンをドラッグすると、gui_input()メソッドにより回転が更新される：
- X軸回転（rot_x）：マウスのY方向移動 × 0.01
- Y軸回転（rot_y）：マウスのX方向移動 × 0.01
- X軸回転は -π/2 から π/2 の範囲にクランプされる

### 3-ライト1切り替え

ライト1ボタンをトグルすると、メインのDirectionalLight3D（斜め上からの白色光）の表示/非表示が切り替わる。

### 4-ライト2切り替え

ライト2ボタンをトグルすると、サブのDirectionalLight3D（上からの灰色光、Color(0.7, 0.7, 0.7)）の表示/非表示が切り替わる。

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

本機能はデータベースを使用しない。また、プレビュー操作はリソースデータを変更しない読み取り専用の機能である。

### 操作別データ影響一覧

| 操作（イベント） | 対象リソース | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| メッシュプレビュー | なし | SELECT（読み取りのみ） | メッシュデータを読み取ってレンダリング |
| 回転操作 | なし | なし | UIステートのみ変更、リソース影響なし |
| ライト切り替え | なし | なし | UIステートのみ変更、リソース影響なし |

## メッセージ仕様

本機能では特にユーザー向けメッセージは表示されない。

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| メッシュがnull | プレビューが空の状態で表示される |
| AABBの最長軸が0 | スケーリング計算がスキップされる |

## 備考

- プレビュービューポートはMSAA 4X設定でレンダリングされる
- 物理ライトユニット使用時（プロジェクト設定）は、CameraAttributesPracticalがカメラに設定される
- 最小サイズは 1 × 150 ピクセル（EDSCALE適用後）
- メッシュはAABBの中心がビューポート中央に来るようにオフセットされる
- 最長軸が0.5の相対サイズになるようにスケーリングされる

---

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

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

### 推奨読解順序

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

まず、Meshリソースの基本構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mesh.h | `scene/resources/mesh.h` | Meshクラスの基本定義、get_aabb()メソッド |

**読解のコツ**: Meshは3Dジオメトリデータを保持し、get_aabb()でバウンディングボックスを取得できることを理解する。

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

プラグインの登録とインスペクターへの統合方法を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mesh_editor_plugin.h | `editor/scene/3d/mesh_editor_plugin.h` | クラス定義、MeshEditor、EditorInspectorPluginMesh |
| 2-2 | mesh_editor_plugin.cpp | `editor/scene/3d/mesh_editor_plugin.cpp` | can_handle(), parse_begin() |

**主要処理フロー**:
1. **170-172行**: can_handle()でMeshオブジェクト判定
2. **174-184行**: parse_begin()でMeshEditorをインスペクターに追加

#### Step 3: プレビューUI構築を理解する

プレビュービューポートとコントロールの構築を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mesh_editor_plugin.cpp | `editor/scene/3d/mesh_editor_plugin.cpp` | MeshEditor()コンストラクタ（104-166行） |

**主要処理フロー**:
- **105-116行**: SubViewport、Camera3D、World3Dの設定
- **118-130行**: ライトの設定（2つのDirectionalLight3D）
- **132-135行**: MeshInstance3Dとrotation Nodeの設定
- **139-163行**: ライト切り替えボタンのUI構築

#### Step 4: メッシュ編集（プレビュー設定）を理解する

メッシュがセットされた際の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mesh_editor_plugin.cpp | `editor/scene/3d/mesh_editor_plugin.cpp` | edit()メソッド（74-94行） |

**主要処理フロー**:
- **74-76行**: メッシュ参照とMeshInstance3Dへの設定
- **78-80行**: 初期回転角度の設定（-15度、30度）
- **82-93行**: AABBからスケールとオフセットの計算

#### Step 5: 入力処理を理解する

マウス操作による回転処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | mesh_editor_plugin.cpp | `editor/scene/3d/mesh_editor_plugin.cpp` | gui_input()（38-49行）、_update_rotation()（67-72行） |

**主要処理フロー**:
- **38-48行**: マウスドラッグ検出と回転値更新
- **67-72行**: Transform3D生成と適用

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

```
MeshEditorPlugin (エディタープラグイン)
    │
    └─ EditorInspectorPluginMesh (インスペクタープラグイン)
           ├─ can_handle() → Mesh判定
           │
           └─ parse_begin()
                  │
                  └─ MeshEditor (プレビューウィジェット)
                         ├─ コンストラクタ → UI構築
                         │      ├─ SubViewport作成
                         │      ├─ Camera3D設定
                         │      ├─ DirectionalLight3D × 2
                         │      ├─ MeshInstance3D
                         │      └─ ライトボタン × 2
                         │
                         ├─ edit() → メッシュ設定
                         │      ├─ mesh_instance->set_mesh()
                         │      └─ スケール/オフセット計算
                         │
                         ├─ gui_input() → 回転操作
                         │      └─ _update_rotation()
                         │
                         ├─ _on_light_1_switch_pressed()
                         └─ _on_light_2_switch_pressed()
```

### データフロー図

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

Meshリソース選択
        │
        ▼
EditorInspectorPluginMesh::can_handle()
        │
        ▼
parse_begin()
        │
        ▼
MeshEditor::edit()
        │
        ├─ mesh_instance->set_mesh(mesh)
        │
        ├─ AABB取得 → get_center(), get_longest_axis_size()
        │
        └─ Transform計算 → スケール・オフセット適用
              │
              ▼
        SubViewport レンダリング ───▶ 3Dプレビュー表示

マウスドラッグ
        │
        ▼
gui_input()
        │
        ├─ rot_x, rot_y 更新
        │
        └─ _update_rotation()
              │
              ▼
        rotation->set_transform() ───▶ プレビュー回転更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mesh_editor_plugin.cpp | `editor/scene/3d/mesh_editor_plugin.cpp` | ソース | メッシュエディター本体実装 |
| mesh_editor_plugin.h | `editor/scene/3d/mesh_editor_plugin.h` | ヘッダー | クラス定義 |
| mesh.cpp | `scene/resources/mesh.cpp` | ソース | Meshリソース基底クラス |
| mesh.h | `scene/resources/mesh.h` | ヘッダー | Meshリソース定義 |
| mesh_instance_3d.cpp | `scene/3d/mesh_instance_3d.cpp` | ソース | メッシュ表示ノード |
| subviewport.cpp | `scene/main/subviewport.cpp` | ソース | サブビューポート実装 |
| light_3d.cpp | `scene/3d/light_3d.cpp` | ソース | ライトノード実装 |
| camera_3d.cpp | `scene/3d/camera_3d.cpp` | ソース | カメラノード実装 |
| editor_inspector.cpp | `editor/inspector/editor_inspector.cpp` | ソース | インスペクタープラグイン基盤 |
