# 機能設計書 27-BoxGeometry

## 概要

本ドキュメントは、Three.jsにおけるBoxGeometry（ボックスジオメトリ）機能の詳細設計を記述する。BoxGeometryは直方体（立方体を含む）の3Dジオメトリを生成するクラスである。

### 本機能の処理概要

BoxGeometryは、指定された幅、高さ、奥行きに基づいて直方体のジオメトリ（頂点、法線、UV座標、インデックス）を生成するクラスである。各辺に沿ったセグメント数を指定することで、分割数を制御できる。

**業務上の目的・背景**：直方体は3Dグラフィックスにおいて最も基本的かつ頻繁に使用される形状の一つである。建物、家具、パッケージ、UI要素など、多くのオブジェクトの基礎として使用される。BoxGeometryを使用することで、プログラム的に直方体メッシュを生成でき、手動でのモデリングなしに3Dコンテンツを構築できる。

**機能の利用シーン**：
- 建築ビジュアライゼーションでの建物や部屋の表現
- ゲームにおけるプロトタイピング（グレーボックス）
- 製品のパッケージ表示
- UIやダッシュボードの3D要素
- 物理シミュレーションのコリジョンボックス

**主要な処理内容**：
1. 6面それぞれの頂点座標の計算
2. 各面の法線ベクトルの設定
3. テクスチャマッピング用UV座標の計算
4. 三角形メッシュ用のインデックス生成
5. マルチマテリアル用のグループ設定

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | Sidebar - Geometry | 補助機能 | 直方体パラメータの編集 |
| 12 | Menubar - Add | 補助機能 | Boxメッシュの追加 |
| 35 | Geometry Browser | 主機能 | 直方体ジオメトリのプレビュー |

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| type | string | 'BoxGeometry' |
| parameters | Object | コンストラクタパラメータのコピー |
| index | BufferAttribute | 三角形インデックス |
| attributes.position | Float32BufferAttribute | 頂点座標（3成分） |
| attributes.normal | Float32BufferAttribute | 法線ベクトル（3成分） |
| attributes.uv | Float32BufferAttribute | UV座標（2成分） |
| groups | Array | マルチマテリアル用グループ（6面分） |

### 出力先

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

## 処理フロー

### 処理シーケンス

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

2. 6面の構築（buildPlane関数を6回呼び出し）
   └─ +X面（右）: z-y平面
   └─ -X面（左）: z-y平面
   └─ +Y面（上）: x-z平面
   └─ -Y面（下）: x-z平面
   └─ +Z面（前）: x-y平面
   └─ -Z面（後）: x-y平面

3. バッファ属性の設定
   └─ setIndex(indices)
   └─ setAttribute('position', ...)
   └─ setAttribute('normal', ...)
   └─ setAttribute('uv', ...)
```

### フローチャート

```mermaid
flowchart TD
    A[BoxGeometry生成] --> B[パラメータ保存]
    B --> C[セグメント数整数化]
    C --> D[buildPlane: +X面]
    D --> E[buildPlane: -X面]
    E --> F[buildPlane: +Y面]
    F --> G[buildPlane: -Y面]
    G --> H[buildPlane: +Z面]
    H --> I[buildPlane: -Z面]
    I --> J[インデックス設定]
    J --> K[position属性設定]
    K --> L[normal属性設定]
    L --> M[uv属性設定]
    M --> N[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 原点中心 | ジオメトリは原点を中心に生成される | 常時 |
| BR-02 | 軸平行 | 各辺はXYZ軸に平行 | 常時 |
| BR-03 | マテリアルインデックス | 6面それぞれに異なるマテリアルインデックスを割り当て（0-5） | 常時 |
| BR-04 | セグメント整数化 | セグメント数はfloor()で整数化される | 常時 |

### 計算ロジック

buildPlane関数の処理:

```javascript
// グリッドの各セルについて
for (iy = 0 to gridY) {
  for (ix = 0 to gridX) {
    // 頂点座標
    x = ix * segmentWidth - widthHalf
    y = iy * segmentHeight - heightHalf

    // 法線（面に垂直、深さ方向）
    normal = depth > 0 ? 1 : -1

    // UV座標
    u = ix / gridX
    v = 1 - (iy / gridY)
  }
}

// インデックス（2つの三角形/セグメント）
for each segment {
  indices.push(a, b, d)  // 三角形1
  indices.push(b, c, d)  // 三角形2
}
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 明示的なエラー処理なし | 負のサイズ値でも動作（反転したジオメトリ） |

### リトライ仕様

リトライ処理は不要

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

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

## パフォーマンス要件

- セグメント数を増やすと頂点数が増加（頂点数 ≈ 6 * (widthSegs+1) * (heightSegs+1)）
- 1セグメントで24頂点、36インデックス

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

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

## 備考

- 立方体を生成する場合はwidth = height = depthを指定
- マルチマテリアル使用時は6つのマテリアルを配列で渡す
- fromJSON()静的メソッドでJSONからインスタンス化可能

---

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

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

### 推奨読解順序

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

BoxGeometryはBufferGeometryを継承したジオメトリクラス。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BoxGeometry.js | `src/geometries/BoxGeometry.js` | クラスの全体構造（220行） |
| 1-2 | BufferGeometry.js | `src/core/BufferGeometry.js` | 親クラスの構造 |
| 1-3 | BufferAttribute.js | `src/core/BufferAttribute.js` | 頂点データの格納 |

**読解のコツ**: BoxGeometryはbuildPlane()というヘルパー関数を使用して6面を順番に構築する。

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

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

**主要処理フロー**:
1. **34行目**: super()でBufferGeometryを初期化
2. **36行目**: type = 'BoxGeometry' を設定
3. **45-52行目**: parametersオブジェクトを保存
4. **58-60行目**: セグメント数をfloor()で整数化
5. **64-67行目**: バッファ配列を初期化
6. **76-81行目**: buildPlane()を6回呼び出して各面を構築
7. **85-88行目**: バッファ属性を設定

#### Step 3: buildPlane()関数を理解する

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

**主要処理フロー**:
- **92-97行目**: セグメントサイズと半分のサイズを計算
- **105行目**: Vector3を使って頂点座標を組み立て
- **109-146行目**: 頂点、法線、UVを生成
- **156-176行目**: インデックスを生成
- **180行目**: addGroup()でマテリアルインデックスを設定

#### Step 4: copy()とfromJSON()を理解する

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

**主要処理フロー**:
- **194-202行目**: copy()でパラメータをコピー
- **211-215行目**: fromJSON()でJSONからインスタンス生成

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

```
BoxGeometry
    |
    +-- extends BufferGeometry
    |
    +-- constructor(width, height, depth, widthSegs, heightSegs, depthSegs)
    |       |
    |       +-- super()
    |       +-- buildPlane() x 6
    |               |
    |               +-- 頂点座標計算
    |               +-- 法線設定
    |               +-- UV計算
    |               +-- インデックス生成
    |               +-- addGroup()
    |       +-- setIndex()
    |       +-- setAttribute('position')
    |       +-- setAttribute('normal')
    |       +-- setAttribute('uv')
    |
    +-- copy(source)
    |
    +-- static fromJSON(data)
```

### データフロー図

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

width, height, depth ──> BoxGeometry構築 ────────> BoxGeometryインスタンス
widthSegs, heightSegs,        |                           |
depthSegs                     v                           v
                        buildPlane() x 6           position: Float32BufferAttribute
                              |                    normal: Float32BufferAttribute
                              v                    uv: Float32BufferAttribute
                        頂点・法線・UV計算          index: BufferAttribute
                              |                    groups: [{start, count, materialIndex}]
                              v
                        Mesh.geometryとして使用 ───> レンダリング
```

### 関連ファイル一覧

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