# 機能設計書 106-BufferGeometryLoader

## 概要

本ドキュメントは、Three.jsライブラリにおけるジオメトリデータ読み込み機能「BufferGeometryLoader」の設計について記述する。BufferGeometryLoaderは、JSON形式でシリアライズされたBufferGeometryを読み込み、復元するローダークラスである。

### 本機能の処理概要

**業務上の目的・背景**：3Dグラフィックスにおいて、ジオメトリ（頂点データ、法線、UV座標等）はオブジェクトの形状を定義する核心的なデータである。BufferGeometryLoaderは、事前に生成されたジオメトリデータをJSON形式から復元することで、ジオメトリの再利用や動的読み込みを可能にする。

**機能の利用シーン**：
- 事前計算済みジオメトリの読み込み
- ObjectLoaderによるシーン復元時のジオメトリ生成
- ジオメトリのインポート/エクスポート
- カスタムジオメトリの動的読み込み

**主要な処理内容**：
1. FileLoaderを使用してJSONファイルを読み込み
2. parse()メソッドでBufferGeometry/InstancedBufferGeometryの生成
3. indexの復元
4. attributesの復元（position, normal, uv等）
5. morphAttributesの復元
6. groupsの復元
7. boundingSphereの復元

**関連システム・外部連携**：
- FileLoader: JSONファイルの読み込み
- BufferGeometry: 出力されるジオメトリクラス
- InstancedBufferGeometry: インスタンス描画用ジオメトリ
- ObjectLoader: ジオメトリ復元時に使用

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面なし |

## 機能種別

データ読み込み / ジオメトリローダー / オブジェクト復元

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| url | string | Yes | 読み込むJSONファイルのパス/URL | なし |
| onLoad | function(BufferGeometry) | No | 読み込み完了時のコールバック | なし |
| onProgress | function | No | 進捗コールバック | なし |
| onError | function | No | エラー発生時のコールバック | なし |
| manager | LoadingManager | No | ローディングマネージャー | なし |

### 入力データソース

**BufferGeometry JSON形式**
```json
{
  "isInstancedBufferGeometry": false,
  "data": {
    "index": { "type": "Uint16Array", "array": [...] },
    "attributes": {
      "position": { "type": "Float32Array", "array": [...], "itemSize": 3 },
      "normal": { "type": "Float32Array", "array": [...], "itemSize": 3 },
      "uv": { "type": "Float32Array", "array": [...], "itemSize": 2 }
    },
    "morphAttributes": {...},
    "groups": [...],
    "boundingSphere": { "center": [0,0,0], "radius": 1.0 }
  }
}
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| geometry | BufferGeometry | パースされたジオメトリインスタンス |

### 出力先

- onLoadコールバック関数への引数として渡される
- parse()メソッドの戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. load()メソッド呼び出し
2. FileLoader.load()でJSONファイル取得
3. JSON.parse()でオブジェクトに変換
4. parse()メソッド呼び出し
   ├─ isInstancedBufferGeometry判定
   ├─ index復元（BufferAttribute作成）
   ├─ attributes復元
   │    ├─ InterleavedBufferAttribute判定
   │    ├─ InstancedBufferAttribute判定
   │    └─ 通常BufferAttribute作成
   ├─ morphAttributes復元
   ├─ morphTargetsRelative設定
   ├─ groups復元（addGroup呼び出し）
   ├─ boundingSphere復元
   └─ name/userData復元
5. onLoadコールバック実行
```

### フローチャート

```mermaid
flowchart TD
    A[load開始] --> B[FileLoader.load]
    B --> C[JSON.parse]
    C --> D{isInstancedBufferGeometry?}
    D -->|Yes| E[new InstancedBufferGeometry]
    D -->|No| F[new BufferGeometry]
    E --> G[index復元]
    F --> G
    G --> H[attributes復元]
    H --> I[morphAttributes復元]
    I --> J[groups復元]
    J --> K[boundingSphere復元]
    K --> L[geometry返却]
    L --> M[onLoad実行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-106-1 | タイプ別配列変換 | getTypedArray()で型文字列からTypedArrayを生成 | 常時 |
| BR-106-2 | InterleavedBuffer対応 | isInterleavedBufferAttribute時は専用処理 | attribute.isInterleavedBufferAttribute === true |
| BR-106-3 | InstancedBuffer対応 | isInstancedBufferAttribute時は専用クラス使用 | attribute.isInstancedBufferAttribute === true |

### 計算ロジック

特になし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | JSON解析エラー | 不正なJSONファイル | onErrorコールバック実行 |
| - | パースエラー | parse()内でエラー発生 | onErrorコールバック実行、manager.itemError() |

### リトライ仕様

自動リトライ機能なし

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

該当なし

## パフォーマンス要件

- InterleavedBufferのキャッシュによる重複生成防止
- ArrayBufferのキャッシュによるメモリ効率化

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

特になし

## 備考

- InterleavedBuffer: 複数の属性が1つのバッファを共有する最適化形式
- InstancedBufferAttribute: インスタンス描画用の属性
- groupsはdrawcallsまたはoffsetsとしても互換性あり（レガシー対応）

---

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

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

### 推奨読解順序

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

BufferGeometryとBufferAttributeの関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BufferGeometry.js | `src/core/BufferGeometry.js` | index, attributes, morphAttributesの構造 |
| 1-2 | BufferAttribute.js | `src/core/BufferAttribute.js` | TypedArray格納とitemSize |

#### Step 2: ファイル読み込みフローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BufferGeometryLoader.js | `src/loaders/BufferGeometryLoader.js` | 48-80行目: load()メソッド |

**主要処理フロー**:
- **52-55行目**: FileLoaderの設定
- **56-78行目**: 読み込みとparse()呼び出し

#### Step 3: パース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BufferGeometryLoader.js | `src/loaders/BufferGeometryLoader.js` | 88-238行目: parse()メソッド |

**主要処理フロー**:
- **93-110行目**: getInterleavedBuffer()関数
- **112-125行目**: getArrayBuffer()関数
- **127行目**: ジオメトリタイプ判定
- **129-136行目**: index復元
- **138-163行目**: attributes復元
- **165-201行目**: morphAttributes復元
- **211-223行目**: groups復元
- **225-231行目**: boundingSphere復元

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

```
BufferGeometryLoader.load(url, onLoad, onProgress, onError)
    │
    ├─ FileLoader.load(url)
    │      └─ JSON.parse(text)
    │
    └─ parse(json)
           │
           ├─ new BufferGeometry() / InstancedBufferGeometry()
           │
           ├─ index復元
           │      └─ geometry.setIndex(new BufferAttribute(...))
           │
           ├─ attributes復元
           │      ├─ getInterleavedBuffer() [InterleavedBuffer復元]
           │      ├─ new InterleavedBufferAttribute()
           │      ├─ new InstancedBufferAttribute()
           │      └─ new BufferAttribute()
           │
           ├─ morphAttributes復元
           │      └─ geometry.morphAttributes[key] = [...]
           │
           ├─ groups復元
           │      └─ geometry.addGroup(start, count, materialIndex)
           │
           └─ boundingSphere復元
                  └─ geometry.boundingSphere = new Sphere().fromJSON()
```

### データフロー図

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

JSON File ──▶ FileLoader ──▶ JSON Object
                                   │
                                   ▼
               ┌──────────────────────────────────┐
               │           parse(json)             │
               │                                   │
               │   index ──▶ BufferAttribute      │
               │                                   │
               │   attributes ──▶ BufferAttribute │──▶ BufferGeometry
               │                      or           │
               │             InterleavedBufferAttr │
               │                                   │
               │   morphAttributes ──▶ [Array]     │
               │                                   │
               │   groups ──▶ addGroup()           │
               │                                   │
               │   boundingSphere ──▶ Sphere       │
               └──────────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BufferGeometryLoader.js | `src/loaders/BufferGeometryLoader.js` | ソース | ジオメトリローダー本体（243行） |
| FileLoader.js | `src/loaders/FileLoader.js` | ソース | JSONファイル取得 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 出力ジオメトリクラス |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 頂点属性クラス |
| InstancedBufferGeometry.js | `src/core/InstancedBufferGeometry.js` | ソース | インスタンス用ジオメトリ |
| InterleavedBuffer.js | `src/core/InterleavedBuffer.js` | ソース | インターリーブバッファ |
| InterleavedBufferAttribute.js | `src/core/InterleavedBufferAttribute.js` | ソース | インターリーブ属性 |
| utils.js | `src/utils.js` | ソース | getTypedArray関数提供 |
