# 機能設計書 158-DirectionalLightHelper

## 概要

本ドキュメントは、Three.jsライブラリにおけるDirectionalLightHelper機能の設計仕様を記載する。DirectionalLightHelperは平行光源（DirectionalLight）の位置と方向を可視化するためのヘルパーオブジェクトである。

### 本機能の処理概要

DirectionalLightHelperは、平行光源の位置を正方形のワイヤーフレームで、光の方向をターゲットへの線分で表現する。光源の変形や色の変更に追従してupdate()メソッドで動的に更新できるデバッグ・開発支援機能である。

**業務上の目的・背景**：平行光源は無限遠からの平行な光線をシミュレートするため、その位置と方向を直感的に把握することが難しい。DirectionalLightHelperは、光源の位置を平面で、照射方向をターゲットへの線分で可視化することで、ライティング設定のデバッグを支援する。

**機能の利用シーン**：
- 平行光源（太陽光等）の配置確認
- シャドウマップの方向確認
- 複数光源環境でのライト識別
- ライティングデバッグ

**主要な処理内容**：
1. 光源位置に正方形のワイヤーフレーム（lightPlane）を描画
2. 光源からターゲットへの線分（targetLine）を描画
3. update()による位置・方向・色の動的更新
4. 光源のmatrixWorldを共有して位置同期

**関連システム・外部連携**：DirectionalLightと連携。WebGLRenderer/WebGPURendererによるレンダリングパイプラインと連携。

**権限による制御**：本機能に権限制御はない。全てのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | Menubar - View | 補助機能 | ライトヘルパー表示切替 |

## 機能種別

可視化処理 / デバッグ支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| light | DirectionalLight | Yes | 可視化する平行光源 | DirectionalLightインスタンス |
| size | number | No | 光源表示平面のサイズ（デフォルト: 1） | 正の数値 |
| color | number\|Color\|string | No | ヘルパーの色（未指定時はライトの色を使用） | 有効なカラー値 |

### 入力データソース

コンストラクタ引数として直接指定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DirectionalLightHelper | Object3D | 光源を表す平面+線分オブジェクト |

### 出力先

シーングラフへの追加（scene.add()）によりレンダリング対象となる。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ light, size, colorパラメータの受け取り
2. lightプロパティ設定
3. 光源のmatrixWorldを共有
   └─ matrixAutoUpdate = false
4. colorプロパティ設定
5. lightPlane（正方形）の生成
   └─ 5頂点の閉じた正方形ライン
   └─ LineBasicMaterial (fog: false, toneMapped: false)
6. targetLine（方向線）の生成
   └─ 2頂点の線分
   └─ 同じマテリアルを共有
7. update()呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始: new DirectionalLightHelper] --> B[light, size, color引数受け取り]
    B --> C[lightプロパティ設定]
    C --> D[matrixWorld共有]
    D --> E[colorプロパティ設定]
    E --> F[size未指定時は1を設定]
    F --> G[lightPlane用頂点定義]
    G --> H[BufferGeometry作成]
    H --> I[LineBasicMaterial作成]
    I --> J[lightPlane Line作成]
    J --> K[this.add lightPlane]
    K --> L[targetLine用頂点定義]
    L --> M[targetLine Line作成]
    M --> N[this.add targetLine]
    N --> O[update呼び出し]
    O --> P[終了]

    Q[update呼び出し] --> R[light.updateWorldMatrix]
    R --> S[target.updateWorldMatrix]
    S --> T[_v1 = light位置取得]
    T --> U[_v2 = target位置取得]
    U --> V[_v3 = 方向ベクトル計算]
    V --> W[lightPlane.lookAt target]
    W --> X{color指定あり?}
    X -->|Yes| Y[指定色を設定]
    X -->|No| Z[lightの色をコピー]
    Y --> AA[targetLine.lookAt target]
    Z --> AA
    AA --> AB[targetLine.scale.z = 距離]
    AB --> AC[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-158-01 | デフォルトサイズ | size未指定時は1を使用 | size未指定時 |
| BR-158-02 | 自動カラー | color未指定時はlightの色を使用 | color未指定時 |
| BR-158-03 | 手動更新 | 光源変形後はupdate()を呼ぶ必要あり | 光源変更時 |
| BR-158-04 | フォグ無効 | fog: falseでフォグの影響を受けない | 常時 |
| BR-158-05 | トーンマッピング無効 | toneMapped: falseでトーンマッピング無効 | 常時 |

### 計算ロジック

方向ベクトルと距離の計算:
```javascript
_v1.setFromMatrixPosition(light.matrixWorld)    // ライト位置
_v2.setFromMatrixPosition(light.target.matrixWorld) // ターゲット位置
_v3.subVectors(_v2, _v1)                        // 方向ベクトル

lightPlane.lookAt(_v2)                          // ターゲット方向を向く
targetLine.scale.z = _v3.length()               // 距離でスケール
```

## データベース操作仕様

該当なし（本機能はデータベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 暗黙的エラー | lightがnull/undefined | エラー発生 |
| - | 暗黙的エラー | light.targetがない | エラー発生 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- lightPlane頂点数: 5（閉じた正方形）
- targetLine頂点数: 2
- ドローコール: 2（lightPlane + targetLine）
- update()は光源変更時に手動呼び出し

## セキュリティ考慮事項

該当なし（クライアントサイドの可視化機能）

## 備考

- dispose()メソッドを呼び出すことでGPUリソースを解放可能
- Object3Dを継承（LineやLineSegmentsではない）
- lightPlaneとtargetLineの2つの子要素を持つ複合オブジェクト

---

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

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

### 推奨読解順序

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

DirectionalLightHelperはObject3Dを継承し、2つのLine子要素を持つ。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DirectionalLight.js | `src/lights/DirectionalLight.js` | target属性、matrixWorld |
| 1-2 | Object3D.js | `src/core/Object3D.js` | matrixWorld, updateWorldMatrix |
| 1-3 | Vector3.js | `src/math/Vector3.js` | setFromMatrixPosition, subVectors |

**読解のコツ**: DirectionalLightはtargetプロパティを持ち、ライト位置からターゲット位置への方向が光の方向となる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DirectionalLightHelper.js | `src/helpers/DirectionalLightHelper.js` | 本体実装 |

**主要処理フロー**:
1. **8-10行目**: _v1, _v2, _v3のキャッシュ
2. **40行目**: コンストラクタ開始
3. **49行目**: lightプロパティ設定
4. **51-52行目**: matrixWorld共有、matrixAutoUpdate=false
5. **60行目**: colorプロパティ設定
6. **62行目**: type = 'DirectionalLightHelper'
7. **64行目**: size未指定時のデフォルト値
8. **66-73行目**: lightPlane用ジオメトリ（5頂点の正方形）
9. **75行目**: LineBasicMaterial生成（fog: false）
10. **82行目**: lightPlane Line作成
11. **83行目**: this.add(lightPlane)
12. **85-86行目**: targetLine用ジオメトリ（2頂点）
13. **93行目**: targetLine Line作成（マテリアル共有）
14. **94行目**: this.add(targetLine)
15. **96行目**: update()呼び出し

#### Step 3: updateを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DirectionalLightHelper.js | `src/helpers/DirectionalLightHelper.js` | 117-143行目のupdate |

**主要処理フロー**:
- **119行目**: light.updateWorldMatrix()
- **120行目**: target.updateWorldMatrix()
- **122行目**: _v1にライト位置
- **123行目**: _v2にターゲット位置
- **124行目**: _v3に方向ベクトル
- **126行目**: lightPlane.lookAt(ターゲット)
- **128-136行目**: 色設定（指定色 or ライト色）
- **140行目**: targetLine.lookAt(ターゲット)
- **141行目**: targetLine.scale.z = 距離

#### Step 4: disposeを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DirectionalLightHelper.js | `src/helpers/DirectionalLightHelper.js` | 104-110行目のdispose |

**主要処理フロー**:
- **106行目**: lightPlane.geometry.dispose()
- **107行目**: lightPlane.material.dispose()
- **108行目**: targetLine.geometry.dispose()
- **109行目**: targetLine.material.dispose()

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

```
DirectionalLightHelper (src/helpers/DirectionalLightHelper.js)
    │
    ├─ extends Object3D (src/core/Object3D.js)
    │
    ├─ child: lightPlane (Line)
    │      ├─ BufferGeometry (5頂点正方形)
    │      └─ LineBasicMaterial
    │
    ├─ child: targetLine (Line)
    │      ├─ BufferGeometry (2頂点)
    │      └─ LineBasicMaterial (共有)
    │
    └─ references DirectionalLight (src/lights/DirectionalLight.js)
           ├─ matrixWorld
           ├─ target.matrixWorld
           └─ color
```

### データフロー図

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

DirectionalLight       ───▶  DirectionalLightHelper      ───▶  Object3D + 2 Lines
    │                        Constructor
    │                              │
    │                              ├─▶ lightPlane生成（正方形）
    │                              │
    │                              └─▶ targetLine生成（方向線）
    │
    └── [ライト変更時] ──▶  update()
                                  │
                                  ├─▶ light/targetの位置取得
                                  ├─▶ lightPlane.lookAt()
                                  ├─▶ 色更新
                                  └─▶ targetLine.scale.z = 距離
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DirectionalLightHelper.js | `src/helpers/DirectionalLightHelper.js` | ソース | メイン実装 |
| DirectionalLight.js | `src/lights/DirectionalLight.js` | ソース | 対象光源クラス |
| Object3D.js | `src/core/Object3D.js` | ソース | 親クラス（3Dオブジェクト） |
| Line.js | `src/objects/Line.js` | ソース | 子要素（線オブジェクト） |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | ジオメトリデータ管理 |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 頂点属性データ |
| LineBasicMaterial.js | `src/materials/LineBasicMaterial.js` | ソース | 線描画マテリアル |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトル演算 |
