# 機能設計書 132-Box3

## 概要

本ドキュメントは、Three.jsの数学ライブラリにおける3D軸平行境界ボックス（AABB: Axis-Aligned Bounding Box）を表現するBox3クラスの機能設計書である。

### 本機能の処理概要

Box3クラスは、3D空間における軸平行境界ボックスを表現するためのクラスである。最小点（min）と最大点（max）の2つのVector3によってボックスの範囲を定義し、3Dオブジェクトの境界判定、視錐台カリング、衝突検出などに使用される。Three.jsにおいて最も重要な幾何学プリミティブの一つである。

**業務上の目的・背景**：3Dグラフィックスにおいて、オブジェクトの境界を効率的に管理することは、レンダリングパフォーマンスの最適化に不可欠である。Box3は視錐台カリング（カメラの視野外のオブジェクトを除外）、マウスピッキング（3Dオブジェクトの選択）、物理シミュレーションでの衝突検出など、多くの高度な処理の基盤となる。

**機能の利用シーン**：
- 3Dオブジェクトの境界計算（BufferGeometryのboundingBox）
- 視錐台カリングによるレンダリング最適化
- Raycasterによるオブジェクト選択の高速化
- 物理シミュレーションでの衝突検出
- オブジェクトの中心配置や自動カメラ調整
- シーン全体のサイズ計算

**主要な処理内容**：
1. 3D境界ボックスの生成と初期化（min/max座標の設定）
2. 点群、配列、BufferAttribute、Object3Dからの境界ボックス設定
3. 点・ボックス・球・平面・三角形との包含・交差判定
4. ボックスの拡張・縮小・移動・変換（Matrix4適用）
5. 境界球への変換
6. 複数ボックスの合成・交差領域計算
7. JSONシリアライズ/デシリアライズ

**関連システム・外部連携**：BufferGeometry、Object3D、Raycaster、Frustumなど、Three.jsの主要コンポーネントと連携。

**権限による制御**：なし（純粋な数学ユーティリティクラス）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | Menubar - Edit | 補助機能 | オブジェクトの中央配置計算 |

## 機能種別

計算処理 / ジオメトリ演算

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| min | Vector3 | No | ボックスの下限座標 | デフォルト: (+Infinity, +Infinity, +Infinity) |
| max | Vector3 | No | ボックスの上限座標 | デフォルト: (-Infinity, -Infinity, -Infinity) |

### 入力データソース

コンストラクタ引数、メソッド呼び出し、BufferAttribute、Object3Dからの自動計算

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isBox3 | boolean | Box3インスタンス識別フラグ（常にtrue） |
| min | Vector3 | ボックスの下限座標 |
| max | Vector3 | ボックスの上限座標 |

### 出力先

メモリ上のオブジェクトとして保持、またはJSONへのシリアライズ

## 処理フロー

### 処理シーケンス

```
1. 境界ボックスの初期化
   └─ min/maxをInfinityで初期化（空のボックス状態）
2. データソースからの境界設定
   ├─ setFromArray: 数値配列から設定
   ├─ setFromBufferAttribute: 頂点属性から設定
   ├─ setFromPoints: Vector3配列から設定
   ├─ setFromCenterAndSize: 中心とサイズから設定
   └─ setFromObject: Object3D階層から設定
3. 包含・交差判定
   ├─ containsPoint/containsBox
   ├─ intersectsBox/intersectsSphere/intersectsPlane/intersectsTriangle
   └─ 分離軸定理（SAT）による判定
4. ボックス変換
   ├─ applyMatrix4: 4x4行列による変換
   ├─ translate: 平行移動
   └─ expand系: 拡張操作
5. シリアライズ
   └─ toJSON/fromJSON
```

### フローチャート

```mermaid
flowchart TD
    A[Box3インスタンス生成] --> B{初期化方法}
    B -->|setFromArray| C[数値配列から計算]
    B -->|setFromBufferAttribute| D[頂点属性から計算]
    B -->|setFromObject| E[Object3D階層を再帰走査]
    B -->|setFromPoints| F[Vector3配列から計算]
    C --> G[境界ボックス確定]
    D --> G
    E --> G
    F --> G
    G --> H{操作種別}
    H -->|包含判定| I[containsPoint/Box]
    H -->|交差判定| J[intersects系メソッド]
    H -->|変換| K[applyMatrix4/translate]
    H -->|合成| L[union/intersect]
    H -->|シリアライズ| M[toJSON/fromJSON]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 空ボックス表現 | min > maxの場合、ボックスは空とみなされる | isEmpty()判定時 |
| BR-002 | 等価境界 | min == maxの場合、1点を含むボックスとみなされる | containsPoint判定時 |
| BR-003 | 8頂点変換 | applyMatrix4は8頂点を変換後、新しいAABBを計算 | 行列変換時 |
| BR-004 | 三角形交差 | SAT（分離軸定理）で9+3+1=13軸をテスト | intersectsTriangle時 |

### 計算ロジック

**中心点の計算**:
```javascript
center = (min + max) * 0.5
```

**サイズの計算**:
```javascript
size = max - min
```

**8頂点変換**:
```javascript
// 2^3 = 8通りの頂点組み合わせを変換
for each (x in [min.x, max.x])
  for each (y in [min.y, max.y])
    for each (z in [min.z, max.z])
      transform(x, y, z) by matrix
recalculate min/max from transformed points
```

**SAT（分離軸定理）による三角形交差判定**:
```javascript
// 9軸: AABBの3辺 x 三角形の3辺
// 3軸: AABBの面法線（= x, y, z軸）
// 1軸: 三角形の面法線
if any axis separates -> no intersection
```

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

該当なし（純粋な計算処理クラス）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 空ボックス | min > maxの状態で演算 | isEmpty()で事前チェック |
| - | ゼロ除算 | サイズ0のボックスでgetParameter | 呼び出し側で事前チェック必要 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 基本メソッドはO(1)の計算量
- setFromArray/setFromBufferAttributeはO(n)（nは頂点数）
- setFromObject/expandByObjectはO(n)（nはObject3D階層のノード数）
- メモリ使用量: Vector3 x 2 = 48バイト程度

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

該当なし（純粋な数学計算）

## 備考

- BufferGeometry.computeBoundingBox()で自動計算されboundingBoxプロパティに格納
- Frustum.intersectsObject()で視錐台カリングに使用
- Raycasterの事前判定で高速化に貢献
- Box2クラスは2D版の対応クラス

---

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

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

### 推奨読解順序

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

Box3クラスは2つのVector3（min, max）で直方体領域を表現する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Vector3.js | `src/math/Vector3.js` | Box3が依存する3Dベクトルクラスの基本操作 |
| 1-2 | Box3.js | `src/math/Box3.js` | クラスのプロパティ定義（min, max, isBox3） |

**読解のコツ**: Infinityを使った「空のボックス」表現がキーポイント。expandByPoint時にmin/maxが自然に更新される仕組みを理解する。

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

Box3クラスのコンストラクタと主要なsetterを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Box3.js | `src/math/Box3.js` | コンストラクタとset系メソッド群 |

**主要処理フロー**:
1. **14-39行目**: コンストラクタでmin/maxを初期化
2. **65-77行目**: setFromArray() - 数値配列からの設定
3. **86-98行目**: setFromBufferAttribute() - 頂点属性からの設定
4. **107-119行目**: setFromPoints() - Vector3配列からの設定
5. **150-156行目**: setFromObject() - Object3D階層からの設定

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

Object3D階層からの境界ボックス計算は最も複雑な処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Box3.js | `src/math/Box3.js` | expandByObject()の実装（298-380行目） |

**主要処理フロー**:
- **303行目**: updateWorldMatrix()でワールド変換を更新
- **305-367行目**: ジオメトリがある場合の処理
  - **314-331行目**: precise=trueの場合、各頂点をワールド座標に変換
  - **333-366行目**: precise=falseの場合、バウンディングボックス自体を変換
- **370-376行目**: 子オブジェクトを再帰的に処理

#### Step 4: 交差判定を理解する

各種オブジェクトとの交差判定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Box3.js | `src/math/Box3.js` | intersects系メソッド群 |

**主要処理フロー**:
- **437-444行目**: intersectsBox() - 6分離面による判定
- **452-460行目**: intersectsSphere() - 最近点との距離判定
- **468-513行目**: intersectsPlane() - 最小/最大ドット積による判定
- **521-572行目**: intersectsTriangle() - SAT（分離軸定理）による13軸判定

#### Step 5: SAT（分離軸定理）を理解する

三角形との交差判定で使用される分離軸定理の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Box3.js | `src/math/Box3.js` | satForAxes()関数（779-803行目） |

**主要処理フロー**:
- **546-555行目**: 9軸のテスト（AABB辺 x 三角形辺）
- **558-563行目**: 3軸のテスト（AABB面法線）
- **567-570行目**: 1軸のテスト（三角形面法線）

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

```
Box3
    │
    ├─ setFromObject(object, precise)
    │      ├─ makeEmpty()
    │      └─ expandByObject(object, precise)
    │             ├─ object.updateWorldMatrix()
    │             ├─ geometry.getAttribute('position')
    │             │      └─ expandByPoint() [precise=true]
    │             ├─ geometry.computeBoundingBox() [precise=false]
    │             │      └─ _box.copy().applyMatrix4()
    │             │             └─ union()
    │             └─ expandByObject(child) [recursive]
    │
    ├─ intersectsTriangle(triangle)
    │      ├─ getCenter()
    │      ├─ _extents.subVectors()
    │      └─ satForAxes() [3回呼び出し]
    │
    ├─ applyMatrix4(matrix)
    │      └─ _points[0-7].applyMatrix4()
    │             └─ setFromPoints(_points)
    │
    └─ getBoundingSphere(target)
           ├─ getCenter()
           └─ getSize() -> length() * 0.5
```

### データフロー図

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

Object3D ─────────▶ setFromObject() ─────▶ Box3 {min, max}
(3Dオブジェクト階層)    expandByObject()
                        (再帰処理)

BufferAttribute ──▶ setFromBufferAttribute() ──▶ Box3 {min, max}
(頂点データ)

Triangle ─────────▶ intersectsTriangle() ──▶ boolean
                    (SAT判定)

Matrix4 ──────────▶ applyMatrix4() ────────▶ Box3 {min, max}
(変換行列)           (8頂点変換)               (変換後)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Box3.js | `src/math/Box3.js` | ソース | 3D境界ボックスクラス本体 |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトルクラス（依存） |
| Sphere.js | `src/math/Sphere.js` | ソース | 境界球クラス（相互参照） |
| Plane.js | `src/math/Plane.js` | ソース | 平面クラス（交差判定で使用） |
| Triangle.js | `src/math/Triangle.js` | ソース | 三角形クラス（交差判定で使用） |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | boundingBox計算で使用 |
| Frustum.js | `src/math/Frustum.js` | ソース | 視錐台カリングで使用 |
| Box2.js | `src/math/Box2.js` | ソース | 2D版の対応クラス（参考） |
