# 画面設計書 6-Sidebar - Material

## 概要

three.js EditorのSidebar - Materialパネルの設計書。本ドキュメントでは、選択オブジェクトのマテリアル（色、テクスチャ、シェーダー設定）を編集する機能について詳細に記述する。

### 本画面の処理概要

Sidebar - Materialパネルは、現在選択されているオブジェクトのマテリアル情報を表示・編集するための画面である。マテリアルタイプの変更、色・テクスチャの設定、PBRパラメータ（roughness、metalness等）の調整、シェーダープログラムの編集など、包括的なマテリアル編集機能を提供する。複数マテリアルを持つオブジェクトではスロット選択にも対応する。

**業務上の目的・背景**：3Dオブジェクトの見た目を決定するマテリアルの編集は、ビジュアル品質に直結する重要な作業である。本パネルにより、ユーザーはBasicからPhysicalまで様々なマテリアルタイプを切り替え、テクスチャマップやPBRパラメータを細かく調整できる。

**画面へのアクセス方法**：Viewportまたは Outlinerでマテリアルを持つオブジェクト（Mesh、Line、Points、Sprite等）を選択すると自動的に表示される。マテリアルを持たないオブジェクト選択時は非表示。

**主要な操作・処理内容**：
1. マテリアルスロット選択（複数マテリアル対応）
2. マテリアルタイプ変更（MeshBasic、MeshStandard、MeshPhysical等）
3. UUID、名前の表示・編集
4. 基本色（Color）、発光色（Emissive）、反射色（Specular）の編集
5. PBRパラメータ（Roughness、Metalness、Clearcoat等）の編集
6. 各種テクスチャマップ（Map、NormalMap、RoughnessMap等）の設定
7. 透明度、ブレンディング、深度テスト等の設定
8. シェーダープログラムの編集（ShaderMaterial用）
9. UserDataのJSON編集
10. マテリアルのJSONエクスポート

**画面遷移**：選択オブジェクトの変更により内容が更新される。マテリアルなしオブジェクト選択時はパネルが非表示になる。

**権限による表示制御**：権限による制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | Material | 主機能 | 選択オブジェクトのマテリアル編集 |
| 49 | MeshBasicMaterial | 補助機能 | 基本マテリアルタイプの設定 |
| 50 | MeshLambertMaterial | 補助機能 | Lambertマテリアルの設定 |
| 51 | MeshPhongMaterial | 補助機能 | Phongマテリアルの設定 |
| 52 | MeshStandardMaterial | 補助機能 | PBRマテリアルの設定 |
| 53 | MeshPhysicalMaterial | 補助機能 | 高度なPBRマテリアルの設定 |
| 88 | Texture | 補助機能 | テクスチャマップの設定 |
| 130 | Color | 補助機能 | マテリアルカラーの設定 |

## 画面種別

プロパティエディタ / 詳細パネル

## URL/ルーティング

URLルーティングなし（エディタ内コンポーネント）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|----------|------|
| Slot | 入力 | Number | マテリアルスロットインデックス |
| Type | 入力 | String | マテリアルタイプ |
| UUID | 入出力 | String | 一意識別子 |
| Name | 入力 | String | マテリアル名 |
| Color | 入力 | Hex Color | 基本色 |
| Specular | 入力 | Hex Color | 反射色（Phong） |
| Shininess | 入力 | Number | 光沢度（Phong） |
| Emissive | 入力 | Hex Color | 発光色 |
| Roughness | 入力 | Number (0-1) | 粗さ（PBR） |
| Metalness | 入力 | Number (0-1) | 金属度（PBR） |
| Clearcoat | 入力 | Number (0-1) | クリアコート |
| IOR | 入力 | Number | 屈折率 |
| Transmission | 入力 | Number (0-1) | 透過率 |
| 各種Map | 入力 | Texture | テクスチャマップ |
| Side | 入力 | Enum | 描画面（Front/Back/Double） |
| Opacity | 入力 | Number (0-1) | 不透明度 |
| Transparent | 入力 | Boolean | 透明フラグ |
| Wireframe | 入力 | Boolean | ワイヤーフレーム表示 |
| User Data | 入力 | JSON | カスタムデータ |

## 表示項目

| 要素 | 表示内容 | 説明 |
|------|----------|------|
| Slot | スロット選択ドロップダウン | 複数マテリアル時のみ表示 |
| Type | マテリアルタイプ選択 | Mesh/Line/Points/Sprite別のオプション |
| UUID | UUID + 再生成ボタン | 一意識別子 |
| Name | 名前入力フィールド | マテリアル名 |
| Program | シェーダープログラム表示 | ShaderMaterial時のみ |
| Color | カラーピッカー | 基本色 |
| Specular/Shininess | カラー/数値 | Phong系のみ |
| Emissive | カラーピッカー | 発光色 |
| Roughness/Metalness | スライダー | PBR系のみ |
| Clearcoat関連 | 数値/マップ | Physical系のみ |
| IOR/Transmission | 数値 | Physical系のみ |
| Maps | テクスチャ選択UI群 | 各種マップ |
| Side | ドロップダウン | 描画面選択 |
| Opacity/Transparent | 数値/チェックボックス | 透明度設定 |
| Wireframe | チェックボックス | ワイヤー表示 |
| User Data | テキストエリア | JSON |
| Export | ボタン | JSONエクスポート |

## イベント仕様

### 1-マテリアルタイプ変更

マテリアルタイプを変更した際の処理。

1. materialClass UISelectを変更（行477-539）
2. 新しいマテリアルクラスをインスタンス化（line479）
3. RawShaderMaterialの場合はvertexShaderVariablesを追加
4. MeshPhysicalMaterial切替時は既存プロパティをコピー
5. `SetMaterialCommand`を実行
6. `editor.addMaterial()`で管理に追加

### 2-プロパティ変更

各種マテリアルプロパティを変更した際の処理。

1. 各プロパティUI（SidebarMaterialColorProperty、SidebarMaterialNumberProperty等）のonChangeイベント発火
2. プロパティコンポーネント内で`SetMaterialValueCommand`を実行
3. `signals.materialChanged`が発火
4. Viewportが再描画

### 3-マテリアルスロット選択

複数マテリアルオブジェクトでスロットを変更した際の処理。

1. materialSlotSelectを変更（行455-465）
2. `currentMaterialSlot`を更新
3. `signals.materialChanged.dispatch()`を発火
4. `refreshUI()`で選択スロットのマテリアル情報を表示

### 4-UUID再生成

UUIDの再生成ボタン押下処理。

1. 「New」ボタンをクリック（行57-62）
2. `THREE.MathUtils.generateUUID()`で新UUIDを生成
3. `update()`関数内で`SetMaterialValueCommand`を実行（行471-475）

### 5-UserData編集

カスタムデータのJSON編集処理。

1. テキストエリアを編集（行401-423）
2. `onKeyUp`でJSON構文を検証
3. `update()`関数内でJSON.parseを実行（行541-554）
4. パース成功時に`SetMaterialValueCommand`で`userData`を更新

### 6-オブジェクト選択変更時の表示更新

選択オブジェクト変更時のUI更新処理。

1. `signals.objectSelected`を受信（行655-684）
2. マテリアルの有無を判定
3. マテリアルがあれば`currentObject`を設定し`refreshUI()`を呼び出し
4. なければパネルを非表示

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

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

Sidebar - Material単体でのデータベース操作はない。マテリアル変更はCommandパターンでHistoryに記録され、自動保存機能によりIndexedDBに永続化される。

## メッセージ仕様

メッセージ表示はない。UserDataのJSON構文エラーはCSSクラスによる視覚フィードバックで表示。

## 例外処理

| 状況 | 処理 |
|------|------|
| UserData JSONパースエラー | console.warnでログ出力、変更を適用しない |
| JSONエクスポート失敗 | JSON.stringifyのフォールバック処理 |

## 備考

- マテリアルタイプはオブジェクトタイプ（Mesh/Line/Points/Sprite）によって選択肢が異なる
- MeshPhysicalMaterialへの変更時はMeshStandardMaterialのプロパティを引き継ぐ
- プロパティUIは専用コンポーネント（SidebarMaterialColorProperty等）として分離されている
- ShaderMaterial/RawShaderMaterialではシェーダープログラム編集UIが表示される
- 複数マテリアル対応時のスロット行は、単一マテリアル時は非表示

---

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

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

### 推奨読解順序

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

マテリアルの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Sidebar.Material.js | `editor/js/Sidebar.Material.js` | 行21-24のcurrentObject、currentMaterialSlot |
| 1-2 | three.js Materials | `src/materials/*.js` | 各マテリアルクラスのプロパティ |

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

SidebarMaterialの初期化を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Sidebar.Material.js | `editor/js/Sidebar.Material.js` | 行16のSidebarMaterial関数開始 |

**主要処理フロー**:
1. **行25-28**: UIPanel作成、初期非表示設定
2. **行32-40**: マテリアルスロット選択UI
3. **行44-50**: マテリアルタイプ選択UI
4. **行54-68**: UUID行
5. **行72-82**: Name行
6. **行86-87**: SidebarMaterialProgram（シェーダー）
7. **行91-397**: 各種プロパティUI（Color、Roughness、Maps等）
8. **行401-451**: UserData、Export
9. **行455-560**: update関数（変更処理）
10. **行580-651**: refreshUI関数（表示更新）
11. **行655-686**: シグナルハンドラ

#### Step 3: プロパティコンポーネントを理解する

専用プロパティUIの構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Sidebar.Material.ColorProperty.js | `editor/js/Sidebar.Material.ColorProperty.js` | 色プロパティの実装 |
| 3-2 | Sidebar.Material.NumberProperty.js | `editor/js/Sidebar.Material.NumberProperty.js` | 数値プロパティの実装 |
| 3-3 | Sidebar.Material.MapProperty.js | `editor/js/Sidebar.Material.MapProperty.js` | テクスチャマップの実装 |

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

```
Sidebar.Material.js
    │
    ├─ UIPanel (container)
    │
    ├─ Slot Selection
    │      └─ UISelect (materialSlotSelect)
    │
    ├─ Type Selection
    │      └─ UISelect (materialClass)
    │
    ├─ Basic Info
    │      ├─ UIInput (materialUUID) + UIButton (renew)
    │      └─ UIInput (materialName)
    │
    ├─ Shader Program
    │      └─ SidebarMaterialProgram
    │
    ├─ Property Components
    │      ├─ SidebarMaterialColorProperty (color, specular, emissive, etc.)
    │      ├─ SidebarMaterialNumberProperty (roughness, metalness, etc.)
    │      ├─ SidebarMaterialRangeValueProperty
    │      ├─ SidebarMaterialBooleanProperty (vertexColors, transparent, etc.)
    │      ├─ SidebarMaterialConstantProperty (side, blending, depthPacking)
    │      └─ SidebarMaterialMapProperty (map, normalMap, etc.)
    │
    ├─ UITextArea (materialUserData)
    │
    └─ UIButton (exportJson)

Commands:
    ├─ SetMaterialCommand
    └─ SetMaterialValueCommand
```

### データフロー図

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

マテリアルタイプ変更 ▶ new Material() ────────▶ SetMaterialCommand
                                                  │
                                                  ▼
                                            editor.addMaterial()
                                                  │
                                                  ▼
                                            signals.materialChanged

プロパティ変更 ─────▶ Property Component ────▶ SetMaterialValueCommand
                                                  │
                                                  ▼
                                            signals.materialChanged
                                                  │
                                                  ▼
                                            Viewport再描画

スロット変更 ───────▶ update() ──────────────▶ signals.materialChanged
                                                  │
                                                  ▼
                                            refreshUI()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Sidebar.Material.js | `editor/js/Sidebar.Material.js` | ソース | Materialパネルメインコンポーネント |
| Sidebar.Material.BooleanProperty.js | `editor/js/Sidebar.Material.BooleanProperty.js` | ソース | ブールプロパティUI |
| Sidebar.Material.ColorProperty.js | `editor/js/Sidebar.Material.ColorProperty.js` | ソース | 色プロパティUI |
| Sidebar.Material.ConstantProperty.js | `editor/js/Sidebar.Material.ConstantProperty.js` | ソース | 定数プロパティUI |
| Sidebar.Material.MapProperty.js | `editor/js/Sidebar.Material.MapProperty.js` | ソース | テクスチャマップUI |
| Sidebar.Material.NumberProperty.js | `editor/js/Sidebar.Material.NumberProperty.js` | ソース | 数値プロパティUI |
| Sidebar.Material.RangeValueProperty.js | `editor/js/Sidebar.Material.RangeValueProperty.js` | ソース | 範囲値プロパティUI |
| Sidebar.Material.Program.js | `editor/js/Sidebar.Material.Program.js` | ソース | シェーダープログラムUI |
| SetMaterialCommand.js | `editor/js/commands/SetMaterialCommand.js` | ソース | マテリアル設定コマンド |
| SetMaterialValueCommand.js | `editor/js/commands/SetMaterialValueCommand.js` | ソース | マテリアル値変更コマンド |
