# 帳票設計書 1-GLTFExporter

## 概要

本ドキュメントは、Three.jsライブラリにおけるGLTFExporterの帳票設計書である。GLTFExporterは3DシーンをglTF 2.0形式でエクスポートするためのモジュールであり、JSON(.gltf)またはバイナリ(.glb)形式での出力に対応する。

### 本帳票の処理概要

GLTFExporterは、Three.jsのシーン、メッシュ、マテリアル、テクスチャ、アニメーション等を含む3Dコンテンツを、Web標準のglTF 2.0形式に変換してエクスポートする機能を提供する。

**業務上の目的・背景**：glTF（GL Transmission Format）は、3Dコンテンツのウェブ配信における事実上の標準フォーマットであり、Three.jsで作成・編集した3Dモデルを他のアプリケーションやプラットフォームで利用可能にするために不可欠な機能である。AR/VRアプリケーション、ゲームエンジン、3Dビューワーとの相互運用性を確保するために本エクスポーターが必要となる。

**帳票の利用シーン**：ウェブ上の3Dエディタでユーザーが作成したモデルを保存する場合、3Dアセット管理システムでの標準フォーマット出力、AR/VRプレビュー用のモデル生成、他のDCCツール（Blender、Maya等）へのデータ受け渡し時に利用される。

**主要な出力内容**：
1. メッシュジオメトリ（頂点位置、法線、UV座標、頂点カラー）
2. マテリアル情報（PBRマテリアル、テクスチャ参照）
3. テクスチャ画像データ（埋め込みまたは外部参照）
4. スケルトン・スキニング情報（ボーン階層、ウェイト）
5. モーフターゲット（ブレンドシェイプ）
6. アニメーションデータ（キーフレーム、補間方式）
7. ライト・カメラ情報（KHR_lights_punctual拡張）
8. シーン階層構造（ノードツリー）

**帳票の出力タイミング**：ユーザーがエクスポート操作を実行した時点、または自動保存機能によるバックグラウンド保存時に出力される。parseまたはparseAsyncメソッドを呼び出すことで処理が開始される。

**帳票の利用者**：3Dコンテンツ制作者、ウェブ開発者、ゲーム開発者、AR/VRアプリケーション開発者が主な利用者である。

## 帳票種別

3Dモデルデータ出力（バイナリ/JSONファイル）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Three.js アプリケーション | N/A（ライブラリ使用） | GLTFExporter.parse() または parseAsync() メソッド呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | glTF 2.0 JSON (.gltf) / glTF 2.0 Binary (.glb) |
| 用紙サイズ | N/A（バイナリファイル） |
| 向き | N/A |
| ファイル名 | 任意（アプリケーション側で指定） |
| 出力方法 | ArrayBuffer（.glb）またはJSONオブジェクト（.gltf）として返却 |
| 文字コード | UTF-8 |

### glTF固有設定

| 項目 | 内容 |
|-----|------|
| binary | true: .glb形式、false: .gltf形式（デフォルト: false） |
| trs | true: TRS分解形式、false: 行列形式（デフォルト: false） |
| onlyVisible | true: 可視オブジェクトのみ出力（デフォルト: true） |
| maxTextureSize | テクスチャの最大サイズ（デフォルト: Infinity） |
| animations | エクスポートするAnimationClipの配列 |
| includeCustomExtensions | カスタム拡張の含有（デフォルト: false） |

## 帳票レイアウト

### レイアウト概要

glTFファイルはJSON構造で、アセット情報、シーン定義、ノード階層、メッシュ、マテリアル、テクスチャ、アニメーション等のセクションで構成される。

```
┌─────────────────────────────────────┐
│            GLBヘッダー部             │
│  (Magic, Version, TotalLength)      │
├─────────────────────────────────────┤
│          JSONチャンク               │
│  (asset, scenes, nodes, meshes,     │
│   materials, textures, animations)  │
├─────────────────────────────────────┤
│         バイナリチャンク             │
│  (頂点データ、インデックス、         │
│   テクスチャ画像データ)             │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | magic | glTFマジックナンバー | 固定値 0x46546C67 | Uint32 |
| 2 | version | glTFバージョン | 固定値 2 | Uint32 |
| 3 | length | ファイル全体のバイト長 | 計算値 | Uint32 |

### 明細部（JSONチャンク）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | asset | アセットメタ情報 | GLTFWriter.json.asset | JSON Object | 可変 |
| 2 | scenes | シーン定義配列 | Scene オブジェクト | JSON Array | 可変 |
| 3 | nodes | ノード定義配列 | Object3D 階層 | JSON Array | 可変 |
| 4 | meshes | メッシュ定義配列 | Mesh オブジェクト | JSON Array | 可変 |
| 5 | materials | マテリアル定義配列 | Material オブジェクト | JSON Array | 可変 |
| 6 | textures | テクスチャ定義配列 | Texture オブジェクト | JSON Array | 可変 |
| 7 | images | 画像定義配列 | 画像データ | JSON Array | 可変 |
| 8 | accessors | データアクセサ配列 | BufferAttribute | JSON Array | 可変 |
| 9 | bufferViews | バッファビュー配列 | 計算値 | JSON Array | 可変 |
| 10 | buffers | バッファ定義配列 | バイナリデータ | JSON Array | 可変 |
| 11 | animations | アニメーション定義 | AnimationClip | JSON Array | 可変 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | extensionsUsed | 使用拡張リスト | 検出された拡張機能 | JSON Array |
| 2 | extensionsRequired | 必須拡張リスト | 必須の拡張機能 | JSON Array |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| input | エクスポート対象のSceneまたはScene配列 | Yes |
| onlyVisible | 可視オブジェクトのみ出力するかどうか | No |
| binary | バイナリ形式(.glb)で出力するかどうか | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | シーン階層順 | 深さ優先 |
| 2 | 子オブジェクト順 | 配列インデックス順 |

### 改ページ条件

N/A（単一ファイル出力）

## データベース参照仕様

### 参照テーブル一覧

本エクスポーターはデータベースを使用せず、Three.jsオブジェクトのメモリ上のデータを直接参照する。

| データソース | 用途 | 参照方法 |
|-------------|------|---------|
| Scene | シーン構造 | input パラメータ |
| Object3D | ノード階層 | traverse メソッド |
| Mesh | ジオメトリ・マテリアル | isMesh プロパティで判定 |
| BufferGeometry | 頂点データ | geometry プロパティ |
| Material | マテリアル情報 | material プロパティ |
| Texture | テクスチャデータ | map 等のテクスチャプロパティ |

### テーブル別参照項目詳細

#### BufferGeometry

| 参照項目（属性名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| position | accessors.POSITION | 必須 | 頂点位置 |
| normal | accessors.NORMAL | 存在時 | 法線ベクトル |
| uv | accessors.TEXCOORD_0 | 存在時 | テクスチャ座標 |
| color | accessors.COLOR_0 | 存在時 | 頂点カラー |
| skinIndex | accessors.JOINTS_0 | スキニング時 | ボーンインデックス |
| skinWeight | accessors.WEIGHTS_0 | スキニング時 | ボーンウェイト |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| バッファサイズ | ceil(byteLength / 4) * 4 | 切り上げ | 4バイト境界アライメント |
| GLBファイルサイズ | header(12) + jsonChunk + binChunk | - | 各チャンクにプレフィックス8バイト含む |
| min/max | 属性値の最小/最大 | なし | アクセサのbounds |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[parseAsync呼び出し] --> B[オプション設定]
    B --> C[processInputAsync]
    C --> D[シーン走査]
    D --> E{オブジェクト種別}
    E -->|Mesh| F[processMesh]
    E -->|Light| G[processLight]
    E -->|Camera| H[processCamera]
    E -->|その他| I[processNode]
    F --> J[マテリアル処理]
    J --> K[テクスチャ処理]
    K --> L[バッファ生成]
    G --> L
    H --> L
    I --> L
    L --> M[アニメーション処理]
    M --> N[JSON構築]
    N --> O{binary?}
    O -->|true| P[GLB生成]
    O -->|false| Q[gltf JSON返却]
    P --> R[ArrayBuffer返却]
    Q --> S[終了]
    R --> S
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 入力エラー | input が null または未定義 | - | 有効なSceneを渡す |
| テクスチャエラー | 圧縮テクスチャで textureUtils 未設定 | "THREE.GLTFExporter: setTextureUtils() must be called" | setTextureUtils() を呼び出す |
| シリアライズエラー | userData のJSON変換失敗 | "userData won't be serialized" | userData の内容を修正 |
| 正規化エラー | 法線ベクトルが非正規化 | - | 自動正規化が実行される |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | メッシュ数: 1〜1000、頂点数: 〜数百万 |
| 目標出力時間 | 10万頂点で1秒以内 |
| 同時出力数上限 | 1（非同期処理だが同時実行は非推奨） |

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

- ユーザーデータ（userData）はJSON.stringifyでシリアライズされるため、循環参照やシリアライズ不可能なデータは除外される
- テクスチャ画像はBase64エンコードされて埋め込まれるか、外部参照として出力される
- 出力ファイルへのアクセス制御はアプリケーション側の責務

## 備考

- 対応するglTF 2.0拡張: KHR_lights_punctual, KHR_materials_clearcoat, KHR_materials_dispersion, KHR_materials_emissive_strength, KHR_materials_ior, KHR_materials_iridescence, KHR_materials_specular, KHR_materials_sheen, KHR_materials_transmission, KHR_materials_unlit, KHR_materials_volume, KHR_mesh_quantization, KHR_texture_transform, EXT_materials_bump, EXT_mesh_gpu_instancing
- サードパーティプラグインによりKHR_materials_variantsも対応可能

---

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

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

### 推奨読解順序

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

glTF 2.0の出力構造とThree.jsオブジェクトとの対応関係を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GLTFExporter.js | `examples/jsm/exporters/GLTFExporter.js` | 311-376行目: WEBGL定数とglTFとの対応マッピングを確認 |

**読解のコツ**: glTF仕様書と照らし合わせながら、Three.jsの定数がどのglTF定数にマップされるかを確認する。

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

GLTFExporterクラスとそのメソッドの関係を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GLTFExporter.js | `examples/jsm/exporters/GLTFExporter.js` | 103-305行目: GLTFExporterクラスの定義とプラグイン登録機構 |

**主要処理フロー**:
1. **103-108行**: コンストラクタでtextureUtilsとpluginCallbacksを初期化
2. **120-203行**: デフォルトプラグイン（マテリアル拡張）を登録
3. **269-284行**: parseメソッドでGLTFWriterを生成し、プラグインを設定して書き込み開始
4. **293-303行**: parseAsyncメソッドでPromiseベースのAPI提供

#### Step 3: GLTFWriterクラスを理解する

実際のエクスポート処理を担うGLTFWriterの内部構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | GLTFExporter.js | `examples/jsm/exporters/GLTFExporter.js` | 584-623行目: GLTFWriterの初期状態とキャッシュ構造 |

**主要処理フロー**:
- **605-610行**: json.assetにバージョン情報とジェネレータ情報を設定
- **612-619行**: メッシュ、属性、マテリアル、テクスチャ、画像のキャッシュを初期化

#### Step 4: 書き込み処理を理解する

writeAsyncメソッドの処理フローを追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | GLTFExporter.js | `examples/jsm/exporters/GLTFExporter.js` | 644-759行目: 書き込み処理のメインフロー |

**主要処理フロー**:
- **646-654行**: デフォルトオプションのマージ
- **663行**: processInputAsyncでシーン処理を開始
- **688-734行**: バイナリ形式(GLB)の生成処理
- **736-756行**: JSON形式(gltf)の生成処理

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

```
GLTFExporter.parseAsync()
    │
    ├─ GLTFWriter.writeAsync()
    │      │
    │      ├─ processInputAsync()
    │      │      │
    │      │      ├─ processScene()
    │      │      │      └─ processNode()
    │      │      │             ├─ processMesh()
    │      │      │             │      ├─ processMaterial()
    │      │      │             │      │      └─ processTexture()
    │      │      │             │      └─ processAccessor()
    │      │      │             ├─ processLight()
    │      │      │             └─ processCamera()
    │      │      │
    │      │      └─ processAnimations()
    │      │
    │      └─ GLB/JSON生成
    │
    └─ プラグイン処理
           ├─ GLTFLightExtension
           ├─ GLTFMaterialsUnlitExtension
           ├─ GLTFMaterialsTransmissionExtension
           └─ ... その他マテリアル拡張
```

### データフロー図

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

Scene/Object3D ─────▶ processInputAsync() ─────▶ json.scenes
      │                                                  │
      ▼                                                  ▼
   Mesh ────────────▶ processMesh() ───────────▶ json.meshes
      │                     │                            │
      ▼                     ▼                            ▼
BufferGeometry ────▶ processAccessor() ────────▶ json.accessors
      │                     │                            │
      ▼                     ▼                            ▼
  Material ─────────▶ processMaterial() ───────▶ json.materials
      │                     │                            │
      ▼                     ▼                            ▼
  Texture ──────────▶ processTexture() ────────▶ json.textures
      │                     │                            │
      ▼                     ▼                            ▼
   Image ───────────▶ processImage() ──────────▶ json.images
                            │                            │
                            ▼                            ▼
                      バッファ統合 ─────────────▶ json.buffers
                            │
                            ▼
                    GLB/gltf出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GLTFExporter.js | `examples/jsm/exporters/GLTFExporter.js` | ソース | メインエクスポーター実装 |
| three.module.js | `build/three.module.js` | ソース | Three.jsコアライブラリ（Scene, Mesh, Material等） |
| WebGLTextureUtils.js | `examples/jsm/utils/WebGLTextureUtils.js` | ソース | WebGL用テクスチャユーティリティ |
| WebGPUTextureUtils.js | `examples/jsm/utils/WebGPUTextureUtils.js` | ソース | WebGPU用テクスチャユーティリティ |
