# 機能設計書 156-PlaneHelper

## 概要

本ドキュメントは、Three.jsライブラリにおけるPlaneHelper機能の設計仕様を記載する。PlaneHelperはPlaneインスタンス（数学的な無限平面）を可視化するためのヘルパーオブジェクトである。

### 本機能の処理概要

PlaneHelperは、指定されたPlaneオブジェクトの位置と向きを、ワイヤーフレームの正方形と半透明のメッシュで表現する。平面の法線方向と原点からの距離（定数）に基づいて自動的に配置される、デバッグ・開発支援機能である。

**業務上の目的・背景**：クリッピングプレーンや衝突判定で使用するPlaneインスタンスは、目に見えない数学的概念である。PlaneHelperは、これらの平面を視覚化することで、正しい位置と向きの確認を可能にし、デバッグ作業を効率化する。

**機能の利用シーン**：
- クリッピングプレーンの位置確認
- レイキャスト用平面のデバッグ
- 物理シミュレーションの境界面表示
- 空間分割アルゴリズムの可視化

**主要な処理内容**：
1. 正方形のワイヤーフレームライン生成
2. 半透明メッシュの追加（平面の面を表現）
3. updateMatrixWorld()による自動位置・向き更新
4. Plane.normalとPlane.constantに基づく配置

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接的な関連なし。デバッグ用途で利用 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| plane | Plane | Yes | 可視化するPlaneインスタンス | Planeインスタンス |
| size | number | No | ヘルパーの一辺サイズ（デフォルト: 1） | 正の数値 |
| hex | number\|Color\|string | No | ヘルパーの色（デフォルト: 0xffff00 黄色） | 有効なカラー値 |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PlaneHelper | Line | 平面を表すライン+メッシュオブジェクト |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ plane, size, hexパラメータの受け取り
2. ワイヤーフレーム頂点の定義
   └─ 正方形の4辺を表す8頂点
3. BufferGeometryの構築
   └─ position属性を設定
4. LineBasicMaterialの生成
   └─ 指定色、toneMapped: false
5. Lineとして初期化
6. planeとsizeプロパティの保存
7. 半透明メッシュの追加
   └─ 三角形2枚で正方形面を構成
   └─ MeshBasicMaterial (opacity: 0.2, transparent: true)
```

### フローチャート

```mermaid
flowchart TD
    A[開始: new PlaneHelper] --> B[plane, size, hex引数受け取り]
    B --> C[ワイヤーフレーム頂点定義]
    C --> D[BufferGeometry作成]
    D --> E[LineBasicMaterial作成]
    E --> F[Line初期化]
    F --> G[plane, sizeプロパティ保存]
    G --> H[半透明メッシュ用頂点定義]
    H --> I[メッシュ用BufferGeometry作成]
    I --> J[MeshBasicMaterial作成]
    J --> K[Meshを子として追加]
    K --> L[終了]

    M[updateMatrixWorld呼び出し] --> N[position = 0,0,0]
    N --> O[scale = size/2, size/2, 1]
    O --> P[lookAt: plane.normal]
    P --> Q[translateZ: -plane.constant]
    Q --> R[親クラスupdateMatrixWorld]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-156-01 | デフォルトサイズ | size未指定時は1を使用 | size未指定時 |
| BR-156-02 | デフォルトカラー | hex未指定時は黄色(0xffff00)を使用 | hex未指定時 |
| BR-156-03 | 半透明面 | メッシュはopacity: 0.2で描画 | 常時 |
| BR-156-04 | 深度書込無効 | 半透明面はdepthWrite: falseで描画 | 常時 |
| BR-156-05 | 自動追従 | updateMatrixWorldでPlaneの変化に自動追従 | レンダリング毎 |

### 計算ロジック

位置・向きの計算（updateMatrixWorld）:
```javascript
this.position.set(0, 0, 0)           // 一旦原点に
this.scale.set(0.5 * size, 0.5 * size, 1)  // スケール設定
this.lookAt(this.plane.normal)       // 法線方向を向く
this.translateZ(-this.plane.constant) // 定数分だけ移動
```

Planeの定義:
- normal: 平面の法線ベクトル（単位ベクトル）
- constant: 原点から平面までの符号付き距離

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 暗黙的エラー | planeがnull/undefined | エラー発生 |
| - | 暗黙的エラー | plane.normalがゼロベクトル | lookAtが失敗 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ワイヤーフレーム頂点数: 8
- メッシュ頂点数: 6（三角形2枚）
- ドローコール: 2（ライン + メッシュ）
- updateMatrixWorld()はレンダリングループで自動呼び出し

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

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

## 備考

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

---

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

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

### 推奨読解順序

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

PlaneHelperはLineとMeshの複合オブジェクトである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Plane.js | `src/math/Plane.js` | normal（法線）とconstant（定数）の理解 |
| 1-2 | BufferGeometry.js | `src/core/BufferGeometry.js` | 頂点データの管理方法 |
| 1-3 | Line.js | `src/objects/Line.js` | 線オブジェクトの基本 |
| 1-4 | Mesh.js | `src/objects/Mesh.js` | メッシュオブジェクトの基本 |

**読解のコツ**: Planeは法線ベクトル(normal)と原点からの距離(constant)で定義される。点Pが平面上にある条件は `normal.dot(P) + constant = 0` である。

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

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

**主要処理フロー**:
1. **28行目**: コンストラクタ開始
2. **30行目**: color変数設定
3. **32行目**: ワイヤーフレーム頂点定義（8頂点で正方形4辺）
4. **34-36行目**: BufferGeometry作成、boundingSphere計算
5. **38行目**: LineBasicMaterial生成
6. **40行目**: type = 'PlaneHelper'
7. **47行目**: planeプロパティ設定
8. **55行目**: sizeプロパティ設定
9. **57行目**: 半透明メッシュ用頂点（6頂点、三角形2枚）
10. **59-61行目**: メッシュ用BufferGeometry
11. **63行目**: MeshBasicMaterial（半透明設定）
12. **63行目**: this.add()で子要素追加

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PlaneHelper.js | `src/helpers/PlaneHelper.js` | 67-78行目のupdateMatrixWorld |

**主要処理フロー**:
- **69行目**: position.set(0,0,0) - 原点に配置
- **71行目**: scale設定 - sizeの半分（頂点が-1〜1なので）
- **73行目**: lookAt(plane.normal) - 法線方向を向く
- **75行目**: translateZ(-plane.constant) - 定数分移動
- **77行目**: 親クラスのupdateMatrixWorld呼び出し

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

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

**主要処理フロー**:
- **87行目**: this.geometry.dispose() - ライン用
- **88行目**: this.material.dispose() - ライン用
- **89行目**: this.children[0].geometry.dispose() - メッシュ用
- **90行目**: this.children[0].material.dispose() - メッシュ用

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

```
PlaneHelper (src/helpers/PlaneHelper.js)
    │
    ├─ extends Line (src/objects/Line.js)
    │      └─ extends Object3D (src/core/Object3D.js)
    │
    ├─ child: Mesh (src/objects/Mesh.js)
    │      └─ MeshBasicMaterial (半透明)
    │
    ├─ references Plane (src/math/Plane.js)
    │      └─ normal: Vector3 (法線)
    │      └─ constant: number (原点からの距離)
    │
    ├─ uses BufferGeometry (src/core/BufferGeometry.js)
    │
    ├─ uses LineBasicMaterial (src/materials/LineBasicMaterial.js)
    │
    └─ uses MeshBasicMaterial (src/materials/MeshBasicMaterial.js)
```

### データフロー図

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

Plane             ───▶  PlaneHelper Constructor      ───▶  Line + Mesh複合オブジェクト
    │                        │
    │                        ├─▶ ワイヤーフレーム生成
    │                        │        └─▶ 8頂点の正方形
    │                        │
    │                        └─▶ 半透明メッシュ生成
    │                                 └─▶ 6頂点の正方形面
    │
    └── [レンダリング時] ──▶  updateMatrixWorld
                                    │
                                    ├─▶ lookAt(plane.normal)
                                    └─▶ translateZ(-plane.constant)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PlaneHelper.js | `src/helpers/PlaneHelper.js` | ソース | メイン実装 |
| Plane.js | `src/math/Plane.js` | ソース | 数学的平面（参照対象） |
| Line.js | `src/objects/Line.js` | ソース | 親クラス（線オブジェクト） |
| Mesh.js | `src/objects/Mesh.js` | ソース | 子要素（半透明面） |
| Object3D.js | `src/core/Object3D.js` | ソース | 基底クラス（3Dオブジェクト） |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | ジオメトリデータ管理 |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 頂点属性データ |
| LineBasicMaterial.js | `src/materials/LineBasicMaterial.js` | ソース | ワイヤーフレーム用マテリアル |
| MeshBasicMaterial.js | `src/materials/MeshBasicMaterial.js` | ソース | 半透明面用マテリアル |
