# 機能設計書 170-DataUtils

## 概要

本ドキュメントは、Three.jsライブラリにおけるDataUtils機能の設計仕様を記述する。DataUtilsは、データ変換のためのユーティリティ関数を提供するクラスであり、特にHalf Float（FP16）と Single Float（FP32）の相互変換機能を実装している。

### 本機能の処理概要

DataUtilsクラスは、半精度浮動小数点数（Float16/Half Float）と単精度浮動小数点数（Float32）の高速変換機能を提供する。ルックアップテーブルを使用した最適化された変換アルゴリズムにより、HDRテクスチャやGPU処理で使用されるHalf Floatデータの効率的な処理を可能にする。

**業務上の目的・背景**：WebGLやWebGPUでは、メモリ効率とパフォーマンスのためにHalf Float形式がよく使用される。HDRテクスチャ、頂点属性、計算シェーダーのデータなど、様々な場面でFP16データの読み書きが必要となる。DataUtilsは、JavaScript環境でこれらの変換を効率的に行うための機能を提供する。

**機能の利用シーン**：
- HDRテクスチャデータの読み込み/書き出し
- HalfFloatType頂点属性の処理
- GPU計算結果の読み取り
- テクスチャ圧縮処理

**主要な処理内容**：
1. toHalfFloat() - FP32からFP16への変換
2. fromHalfFloat() - FP16からFP32への変換
3. ルックアップテーブルによる高速変換

**関連システム・外部連携**：DataTexture、BufferAttribute、テクスチャローダーと連携。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接的な画面関連なし（ユーティリティクラス） |

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| val | number | Yes | 変換対象の数値 | toHalfFloat: -65504〜65504、fromHalfFloat: 有効なFP16値 |

### 入力データソース

JavaScript number型の値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| halfFloat | number | FP16値（16ビット整数として表現） |
| float32 | number | FP32値 |

### 出力先

JavaScript number型として返却。

## 処理フロー

### 処理シーケンス

```
1. モジュール読み込み時
   └─ _generateTables()でルックアップテーブルを生成
2. toHalfFloat(val)呼び出し
   └─ 範囲チェック（警告）
   └─ クランプ処理
   └─ ビット操作でFP16に変換
3. fromHalfFloat(val)呼び出し
   └─ ルックアップテーブルから変換
```

### フローチャート

```mermaid
flowchart TD
    A[モジュール読み込み] --> B[_generateTables]
    B --> C[baseTable, shiftTable生成]
    B --> D[mantissaTable, exponentTable, offsetTable生成]

    E[toHalfFloat呼び出し] --> F{val > 65504?}
    F -->|Yes| G[警告出力]
    F -->|No| H[クランプ処理]
    G --> H
    H --> I[Float32をUint32として取得]
    I --> J[指数部を抽出]
    J --> K[baseTable + シフト演算]
    K --> L[FP16値を返却]

    M[fromHalfFloat呼び出し] --> N[上位5ビット抽出]
    N --> O[mantissaTable + exponentTable参照]
    O --> P[Float32値を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 範囲制限 | toHalfFloatの入力は-65504〜65504に制限 | toHalfFloat |
| BR-002 | 警告出力 | 範囲外の値が渡された場合は警告を出力 | toHalfFloat |
| BR-003 | クランプ処理 | 範囲外の値は境界値にクランプ | toHalfFloat |
| BR-004 | 特殊値対応 | 0、-0、Infinity、-Infinity、NaNを正しく変換 | 両関数 |

### 計算ロジック

**toHalfFloat**:
1. Float32値をArrayBufferを通じてUint32として取得
2. 指数部（ビット23-30）を抽出
3. baseTable[指数部]とshiftTable[指数部]を使用して変換

**fromHalfFloat**:
1. FP16値の上位5ビット（指数部）を抽出
2. mantissaTable、exponentTable、offsetTableを使用して逆変換

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Warning | 入力値が65504を超える | 値を範囲内に収める |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ルックアップテーブルにより高速変換を実現
- テーブル生成は初回のみ（モジュール読み込み時）
- 変換処理は数ビット操作とテーブル参照のみ

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

特になし

## 備考

- 参考: Fast Half Float Conversions (http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf)
- DataUtils.toHalfFloat() と toHalfFloat() の両方でアクセス可能（後者は直接エクスポート）

---

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

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

### 推奨読解順序

#### Step 1: ルックアップテーブル生成を理解する

モジュール読み込み時に_generateTables()でルックアップテーブルが生成される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DataUtils.js | `src/extras/DataUtils.js` | _generateTables (8-141行目) |

**読解のコツ**: Float32からFloat16への変換にはbaseTableとshiftTableを使用。Float16からFloat32への変換にはmantissaTable、exponentTable、offsetTableを使用。

#### Step 2: toHalfFloatを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DataUtils.js | `src/extras/DataUtils.js` | toHalfFloat (150-161行目) |

**主要処理フロー**:
1. **152行目**: 範囲外チェックと警告
2. **154行目**: clamp()で-65504〜65504にクランプ
3. **156行目**: Float32値をfloatView[0]に設定
4. **157行目**: uint32View[0]でビットパターンを取得
5. **158行目**: 指数部を抽出（(f >> 23) & 0x1ff）
6. **159行目**: baseTable[e] + シフト演算で結果を返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DataUtils.js | `src/extras/DataUtils.js` | fromHalfFloat (170-176行目) |

**主要処理フロー**:
1. **172行目**: 上位5ビット（指数部）を抽出（val >> 10）
2. **173行目**: テーブル参照でuint32View[0]に値を設定
3. **174行目**: floatView[0]でFloat32として読み取り

#### Step 4: DataUtilsクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DataUtils.js | `src/extras/DataUtils.js` | DataUtils (183-211行目) |

**主要処理フロー**:
- **192-194行目**: 静的メソッドtoHalfFloat()はスタンドアロン関数をラップ
- **205-207行目**: 静的メソッドfromHalfFloat()はスタンドアロン関数をラップ

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

```
モジュール読み込み
    │
    └─ _generateTables() [即時実行]
           ├─ baseTable[512] 生成
           ├─ shiftTable[512] 生成
           ├─ mantissaTable[2048] 生成
           ├─ exponentTable[64] 生成
           └─ offsetTable[64] 生成

toHalfFloat(val)
    │
    ├─ 範囲チェック + 警告
    ├─ clamp(val, -65504, 65504)
    ├─ floatView[0] = val
    ├─ f = uint32View[0]
    ├─ e = (f >> 23) & 0x1ff
    └─ return baseTable[e] + ((f & 0x007fffff) >> shiftTable[e])

fromHalfFloat(val)
    │
    ├─ m = val >> 10
    ├─ uint32View[0] = mantissaTable[offsetTable[m] + (val & 0x3ff)] + exponentTable[m]
    └─ return floatView[0]

DataUtils (静的クラス)
    │
    ├─ static toHalfFloat(val)
    │      └─ toHalfFloat(val)
    │
    └─ static fromHalfFloat(val)
           └─ fromHalfFloat(val)
```

### データフロー図

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

Float32 value ─────────▶ toHalfFloat() ────────────────▶ Half Float (16-bit)
                           ├─ 範囲チェック
                           ├─ クランプ
                           ├─ ビット抽出
                           └─ テーブル参照

Half Float ─────────────▶ fromHalfFloat() ─────────────▶ Float32 value
                           └─ テーブル参照

[ルックアップテーブル]
  baseTable[512]      - FP32→FP16 基底値
  shiftTable[512]     - FP32→FP16 シフト量
  mantissaTable[2048] - FP16→FP32 仮数部
  exponentTable[64]   - FP16→FP32 指数部
  offsetTable[64]     - FP16→FP32 オフセット
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DataUtils.js | `src/extras/DataUtils.js` | ソース | 本機能のメイン実装 |
| MathUtils.js | `src/math/MathUtils.js` | ソース | clamp関数 |
| utils.js | `src/utils.js` | ソース | warn関数 |
| DataTexture.js | `src/textures/DataTexture.js` | ソース | HalfFloatTypeテクスチャ |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | HalfFloatType属性 |
