# 機能設計書 29-PlaneGeometry

## 概要

本ドキュメントは、Three.jsにおけるPlaneGeometry（平面ジオメトリ）機能の詳細設計を記述する。PlaneGeometryは2D平面の3Dジオメトリを生成するクラスである。

### 本機能の処理概要

PlaneGeometryは、指定された幅と高さに基づいてXY平面上に平面のジオメトリ（頂点、法線、UV座標、インデックス）を生成するクラスである。セグメント数を指定することで分割数を制御でき、地形やディスプレースメントマッピングの基礎として使用できる。

**業務上の目的・背景**：平面は3Dグラフィックスにおいて最も基本的な形状であり、地面、壁、スクリーン、ポスター、水面など多くの用途に使用される。PlaneGeometryを使用することで、プログラム的に平面メッシュを生成でき、テクスチャマッピングやシェーダーエフェクトの土台として活用できる。

**機能の利用シーン**：
- 地面や床の表現
- 壁やスクリーンの表現
- ビルボードやポスター
- 水面の表現（波のシェーダーと組み合わせ）
- 地形生成（ディスプレースメントマッピング）
- UIパネルの表示

**主要な処理内容**：
1. グリッド状の頂点座標の計算
2. 一定の法線ベクトル（+Z方向）の設定
3. テクスチャマッピング用UV座標の計算
4. 三角形メッシュ用のインデックス生成

**関連システム・外部連携**：BufferGeometry、BufferAttribute、Mesh、マテリアルシステムと連携して動作する。

**権限による制御**：特になし（ライブラリ機能として権限制御は行わない）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | Sidebar - Geometry | 補助機能 | 平面パラメータの編集 |

## 機能種別

データ生成 / ジオメトリ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| width | number | No | X軸方向の幅 | デフォルト: 1 |
| height | number | No | Y軸方向の高さ | デフォルト: 1 |
| widthSegments | number | No | X方向のセグメント数 | デフォルト: 1、floor()で整数化 |
| heightSegments | number | No | Y方向のセグメント数 | デフォルト: 1、floor()で整数化 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| type | string | 'PlaneGeometry' |
| parameters | Object | コンストラクタパラメータのコピー |
| index | BufferAttribute | 三角形インデックス |
| attributes.position | Float32BufferAttribute | 頂点座標（3成分） |
| attributes.normal | Float32BufferAttribute | 法線ベクトル（3成分、全て[0,0,1]） |
| attributes.uv | Float32BufferAttribute | UV座標（2成分） |

### 出力先

- Meshオブジェクトのgeometryプロパティ
- JSON形式でのシリアライズ出力

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ実行
   └─ super()でBufferGeometryを初期化
   └─ type = 'PlaneGeometry' を設定
   └─ parametersオブジェクトを保存
   └─ セグメント数を整数化

2. 頂点生成ループ
   └─ Y方向（gridY1）でループ
   └─ X方向（gridX1）でループ
      └─ 頂点座標を計算（x, -y, 0）
      └─ 法線を追加（0, 0, 1）
      └─ UV座標を計算

3. インデックス生成ループ
   └─ 各セグメントについて2つの三角形を生成

4. バッファ属性の設定
```

### フローチャート

```mermaid
flowchart TD
    A[PlaneGeometry生成] --> B[パラメータ保存]
    B --> C[セグメント数整数化]
    C --> D[サイズ計算]
    D --> E[頂点生成ループ]
    E --> F{iy < gridY1?}
    F -->|Yes| G{ix < gridX1?}
    G -->|Yes| H[頂点座標計算]
    H --> I[法線追加 0,0,1]
    I --> J[UV座標計算]
    J --> G
    G -->|No| F
    F -->|No| K[インデックス生成ループ]
    K --> L[2三角形/セグメント生成]
    L --> M[バッファ属性設定]
    M --> N[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 原点中心 | ジオメトリは原点を中心に生成される | 常時 |
| BR-02 | XY平面 | 平面はXY平面に配置され、Z=0 | 常時 |
| BR-03 | 法線固定 | 全ての頂点の法線は+Z方向（0,0,1） | 常時 |
| BR-04 | Y軸反転 | 頂点のY座標は反転される（-y）、UVは通常方向 | 常時 |

### 計算ロジック

頂点とUVの計算:

```javascript
// サイズ計算
width_half = width / 2
height_half = height / 2
segment_width = width / gridX
segment_height = height / gridY

// 各頂点について
for (iy = 0 to gridY) {
  y = iy * segment_height - height_half

  for (ix = 0 to gridX) {
    x = ix * segment_width - width_half

    // 頂点座標（Y軸反転に注意）
    vertices.push(x, -y, 0)

    // 法線（常に+Z方向）
    normals.push(0, 0, 1)

    // UV座標
    u = ix / gridX
    v = 1 - (iy / gridY)
    uvs.push(u, v)
  }
}
```

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

該当なし（クライアントサイドのみの処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 明示的なエラー処理なし | 負のサイズ値でも動作 |

### リトライ仕様

リトライ処理は不要

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

該当なし（クライアントサイドのみの処理）

## パフォーマンス要件

- 頂点数 = (widthSegs + 1) * (heightSegs + 1)
- デフォルト設定で4頂点、6インデックス

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

特になし（ブラウザのセキュリティモデルに依存）

## 備考

- 両面表示が必要な場合はマテリアルでside: THREE.DoubleSideを設定
- 地形生成時はセグメント数を増やしてディスプレースメントマップを適用
- fromJSON()静的メソッドでJSONからインスタンス化可能

---

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

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

### 推奨読解順序

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

PlaneGeometryはBufferGeometryを継承したシンプルなジオメトリクラス。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PlaneGeometry.js | `src/geometries/PlaneGeometry.js` | クラスの全体構造（134行） |
| 1-2 | BufferGeometry.js | `src/core/BufferGeometry.js` | 親クラスの構造 |

**読解のコツ**: PlaneGeometryは最もシンプルなジオメトリの一つで、グリッド構造の基本を理解するのに最適。

#### Step 2: コンストラクタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PlaneGeometry.js | `src/geometries/PlaneGeometry.js` | 27-106行目 |

**主要処理フロー**:
1. **29行目**: super()でBufferGeometryを初期化
2. **31行目**: type = 'PlaneGeometry' を設定
3. **40-45行目**: parametersオブジェクトを保存
4. **47-48行目**: 幅と高さの半分を計算
5. **50-51行目**: セグメント数をfloor()で整数化
6. **56-57行目**: セグメントあたりの幅と高さを計算
7. **66-83行目**: 頂点生成ループ
8. **85-99行目**: インデックス生成ループ
9. **101-104行目**: バッファ属性を設定

#### Step 3: 頂点生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PlaneGeometry.js | `src/geometries/PlaneGeometry.js` | 66-83行目 |

**主要処理フロー**:
- **68行目**: y = iy * segment_height - height_half
- **72行目**: x = ix * segment_width - width_half
- **74行目**: vertices.push( x, - y, 0 ) - Y軸反転に注意
- **76行目**: normals.push( 0, 0, 1 ) - 全て+Z方向
- **78-79行目**: UV座標の計算

#### Step 4: インデックス生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | PlaneGeometry.js | `src/geometries/PlaneGeometry.js` | 85-99行目 |

**主要処理フロー**:
- **89-92行目**: 四角形の4頂点インデックスを計算
- **94-95行目**: 2つの三角形を追加

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

```
PlaneGeometry
    |
    +-- extends BufferGeometry
    |
    +-- constructor(width, height, widthSegs, heightSegs)
    |       |
    |       +-- super()
    |       +-- Math.floor() でセグメント数を整数化
    |       +-- 頂点生成ループ
    |       |       +-- 頂点座標計算 (x, -y, 0)
    |       |       +-- 法線設定 (0, 0, 1)
    |       |       +-- UV計算
    |       +-- インデックス生成ループ
    |       |       +-- 四角形を2三角形に分割
    |       +-- setIndex()
    |       +-- setAttribute('position')
    |       +-- setAttribute('normal')
    |       +-- setAttribute('uv')
    |
    +-- copy(source)
    |
    +-- static fromJSON(data)
```

### データフロー図

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

width, height ──────> PlaneGeometry構築 ────────> PlaneGeometryインスタンス
widthSegs, heightSegs       |                           |
                            v                           v
                      グリッド頂点計算          position: Float32BufferAttribute
                            |                   normal: Float32BufferAttribute
                            v                   uv: Float32BufferAttribute
                      x = ix * segW - w/2       index: BufferAttribute
                      y = iy * segH - h/2
                      z = 0
                            |
                            v
                      Mesh.geometryとして使用 ───> レンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PlaneGeometry.js | `src/geometries/PlaneGeometry.js` | ソース | PlaneGeometryクラスの実装 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 親クラス |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 頂点属性の格納 |
| Mesh.js | `src/objects/Mesh.js` | ソース | ジオメトリを使用するオブジェクト |
