# 機能設計書 12-InterleavedBuffer

## 概要

本ドキュメントは、Three.jsライブラリにおけるInterleavedBuffer機能の設計を詳細に記述するものである。InterleavedBufferは、複数の頂点属性（位置、法線、UV、色など）を単一の配列バッファにパッキングし、メモリ効率とキャッシュヒット率を向上させるためのクラスである。

### 本機能の処理概要

InterleavedBufferクラスは、異なる種類の頂点属性データを「インターリーブ」形式で格納するためのバッファを管理する。インターリーブとは、各頂点のデータを属性ごとにまとめるのではなく、頂点単位でまとめて格納する方式である。

**業務上の目的・背景**：3Dグラフィックスにおいて、頂点データのメモリレイアウトはレンダリングパフォーマンスに大きく影響する。従来の分離型配置（位置配列、法線配列、UV配列を別々に保持）では、GPU上でのキャッシュ効率が低下する場合がある。InterleavedBufferは同一頂点の全属性を連続したメモリ領域に配置することで、GPUのメモリアクセスパターンを最適化し、特に頂点シェーダでの処理効率を向上させる。

**機能の利用シーン**：大量の頂点データを持つモデルのレンダリング、パーティクルシステム、モーフターゲットアニメーション、複数の頂点属性を効率的に管理したい場合に使用される。glTFファイルからインポートしたモデルデータがインターリーブ形式で格納されている場合にも活用される。

**主要な処理内容**：
1. TypedArrayをベースとしたインターリーブバッファの管理
2. ストライド（頂点あたりの要素数）の設定と管理
3. 部分更新のための更新範囲管理
4. バッファのコピー・クローン機能
5. JSON形式でのシリアライズ
6. GPUアップロード完了時のコールバック機能

**関連システム・外部連携**：InterleavedBufferAttributeと組み合わせて使用され、BufferGeometryの頂点属性として設定される。WebGLRendererのWebGLAttributesモジュールによって実際のGPUバッファ操作が行われる。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | InterleavedBufferは内部APIであり、直接的な画面関連はない |

## 機能種別

データ管理 / メモリ最適化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| array | TypedArray | Yes | 頂点属性データを格納した型付き配列 | Float32Array, Uint8Array等 |
| stride | number | Yes | 頂点あたりの要素数 | 正の整数 |

### 入力データソース

- プログラムから直接渡されるTypedArray
- glTFローダーなどから変換されたバッファデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| uuid | string | バッファの一意識別子 |
| array | TypedArray | 頂点データを格納した配列 |
| stride | number | 頂点あたりの要素数 |
| count | number | 頂点数（array.length / stride） |
| usage | number | バッファ使用パターン定数 |
| version | number | 更新バージョン番号 |
| updateRanges | Array | 部分更新が必要な範囲のリスト |

### 出力先

- WebGLレンダラーのWebGLAttributesモジュール（GPU転送用）
- JSON形式でのシリアライズ出力

## 処理フロー

### 処理シーケンス

```
1. InterleavedBufferインスタンスの生成
   └─ UUID生成、配列・ストライド設定、count計算

2. 使用パターンの設定（オプション）
   └─ setUsage()でStaticDraw/DynamicDraw等を指定

3. データ更新時
   └─ set()で配列データ更新
   └─ addUpdateRange()で更新範囲を追加
   └─ needsUpdate = trueでバージョンインクリメント

4. レンダリング時のバッファ処理
   └─ WebGLAttributesによるGPUバッファへの転送
   └─ onUploadCallback()の呼び出し

5. 更新範囲のクリア
   └─ clearUpdateRanges()でupdateRanges配列をクリア

6. シリアライズ時
   └─ toJSON()でオブジェクトをJSON形式に変換
```

### フローチャート

```mermaid
flowchart TD
    A[InterleavedBuffer生成] --> B[array, stride設定]
    B --> C[count計算: array.length / stride]
    C --> D{データ更新?}
    D -->|Yes| E[set: 配列データ更新]
    E --> F[addUpdateRange: 更新範囲追加]
    F --> G[needsUpdate = true]
    G --> H[version++]
    D -->|No| I[レンダリング待機]
    H --> I
    I --> J[WebGLAttributes処理]
    J --> K[onUploadCallback呼び出し]
    K --> L[clearUpdateRanges]
    L --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 一意識別子 | 各InterleavedBufferはUUIDを持つ | インスタンス生成時 |
| BR-02 | デフォルト使用パターン | usage初期値はStaticDrawUsage | インスタンス生成時 |
| BR-03 | countの自動計算 | count = array.length / stride | 配列設定時 |
| BR-04 | バージョン管理 | needsUpdate=true時にversionがインクリメント | 更新通知時 |
| BR-05 | バッファ共有 | clone時にarrayBufferが共有される場合がある | clone実行時 |

### 計算ロジック

- count = array.length / stride（頂点数の計算）
- UUIDはMathUtils.generateUUID()で生成

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

該当なし（GPU側のメモリ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データ不整合 | array.lengthがstrideで割り切れない | 正しいストライド値を設定 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- インターリーブ配置によりGPUキャッシュヒット率の向上
- addUpdateRange()による部分更新でデータ転送量を最小化
- onUpload()コールバックでCPU側データの解放が可能

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

- GPUメモリへの直接アクセスはWebGL APIを介して行われ、サンドボックス内で安全に動作
- TypedArrayのバッファ境界チェックはJavaScriptエンジンが実施

## 備考

- InterleavedBufferAttributeと組み合わせて各属性へのビューを作成
- updateRangesを使用することで、大きなバッファの一部のみを更新可能
- toJSON()でシリアライズ時にarrayBufferが共有される仕組みを持つ

---

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

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

### 推奨読解順序

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

InterleavedBufferの構造とその依存関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | InterleavedBuffer.js | `src/core/InterleavedBuffer.js` | クラス定義と全プロパティの把握 |
| 1-2 | MathUtils.js | `src/math/MathUtils.js` | UUID生成関数 |
| 1-3 | constants.js | `src/constants.js` | StaticDrawUsage等の定数定義 |

**読解のコツ**: InterleavedBufferは単独では使用されず、InterleavedBufferAttributeを通じて各頂点属性（position, normal, uv等）へのアクセスを提供する。両クラスの関係を理解することが重要。

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

InterleavedBufferのインスタンス化と基本操作を理解する。

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

**主要処理フロー**:
1. **18-85行目**: コンストラクタでisInterleavedBufferフラグ、array、stride、count、usage、updateRanges、version、uuidを初期化
2. **101-105行目**: needsUpdateセッター - trueが設定されるとversionをインクリメント
3. **113-119行目**: setUsage()でバッファ使用パターンを設定
4. **127-131行目**: addUpdateRange()で部分更新範囲を追加
5. **136-140行目**: clearUpdateRanges()で更新範囲をクリア
6. **148-157行目**: copy()で別のInterleavedBufferからデータをコピー
7. **169-182行目**: copyAt()で特定頂点のデータをコピー
8. **191-197行目**: set()で配列データを設定
9. **205-232行目**: clone()でインスタンスを複製（arrayBuffer共有の仕組みあり）
10. **256-287行目**: toJSON()でシリアライズ

#### Step 3: 関連クラスとの連携を理解する

InterleavedBufferがどのように使用されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InterleavedBufferAttribute.js | `src/core/InterleavedBufferAttribute.js` | 個別属性へのビュー |
| 3-2 | BufferGeometry.js | `src/core/BufferGeometry.js` | setAttribute()での使用 |
| 3-3 | WebGLAttributes.js | `src/renderers/webgl/WebGLAttributes.js` | GPUバッファへの転送 |

**主要処理フロー**:
- **InterleavedBufferAttribute**: InterleavedBufferの特定のオフセット・サイズにアクセスするビュー
- **BufferGeometry**: position, normal, uv等の属性としてInterleavedBufferAttributeを設定
- **WebGLAttributes**: update()でInterleavedBufferをGPUバッファに転送

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

```
BufferGeometry.setAttribute()
    │
    └─ InterleavedBufferAttribute
           │
           └─ InterleavedBuffer
                  │
                  ├─ setUsage() ────────▶ usage更新
                  │
                  ├─ addUpdateRange() ──▶ updateRanges配列に追加
                  │
                  ├─ needsUpdate ───────▶ version++
                  │
                  └─ [レンダリング時] ───▶ WebGLAttributes.update()
                                                  │
                                                  ▼
                                         gl.bufferData/gl.bufferSubData
                                                  │
                                                  ▼
                                         onUploadCallback()
```

### データフロー図

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

TypedArray (頂点データ)
        │
        ▼
InterleavedBuffer ─────────────────────────────────────────────▶ array, stride, count
        │
        ▼
InterleavedBufferAttribute ─────▶ offset, itemSize ─────▶ 特定属性へのビュー
        │
        ▼
BufferGeometry.setAttribute() ──▶ attributes["position"] 等
        │
        ▼
WebGLAttributes.update() ──────────────────────────────────────▶ WebGLBuffer (GPU)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| InterleavedBuffer.js | `src/core/InterleavedBuffer.js` | ソース | メインクラス定義 |
| InterleavedBufferAttribute.js | `src/core/InterleavedBufferAttribute.js` | ソース | 属性ビュー定義 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | ジオメトリでの使用 |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 比較対象（非インターリーブ） |
| MathUtils.js | `src/math/MathUtils.js` | ソース | UUID生成ユーティリティ |
| constants.js | `src/constants.js` | ソース | StaticDrawUsage等の定数 |
| WebGLAttributes.js | `src/renderers/webgl/WebGLAttributes.js` | ソース | GPUバッファ管理 |
| ObjectLoader.js | `src/loaders/ObjectLoader.js` | ソース | JSONからの復元 |
