# 機能設計書 173-TextureUtils

## 概要

本ドキュメントは、Three.jsのテクスチャ処理ユーティリティクラス「TextureUtils」の機能設計について記述する。TextureUtilsはテクスチャのスケーリング調整とメモリサイズ計算機能を提供する。

### 本機能の処理概要

TextureUtilsクラスは、テクスチャのアスペクト比調整とメモリ使用量計算を行うユーティリティクラスである。CSSのobject-fitプロパティに類似した3種類のスケーリングモード（contain, cover, fill）を提供し、テクスチャを表示領域に適切にフィットさせる機能を実装している。

**業務上の目的・背景**：3Dグラフィックスにおいて、テクスチャ画像と表示領域のアスペクト比が異なる場合、画像の歪みやクロッピングの問題が発生する。TextureUtilsはCSSと同様の直感的なスケーリングオプションを提供し、開発者がテクスチャの表示を細かく制御できるようにする。また、GPUメモリ管理のためにテクスチャのバイトサイズを正確に計算する機能も重要である。

**機能の利用シーン**：
- 背景画像をビューポートに適切にフィットさせる場合
- UIテクスチャのアスペクト比を維持したまま表示する場合
- テクスチャメモリ使用量を監視・最適化する場合
- 圧縮テクスチャのサイズを計算する場合

**主要な処理内容**：
1. contain: アスペクト比を維持してテクスチャを領域内に収める
2. cover: アスペクト比を維持してテクスチャで領域を完全に覆う
3. fill: テクスチャを領域いっぱいに伸縮（デフォルト）
4. getByteLength: テクスチャのメモリサイズを計算

**関連システム・外部連携**：
- Textureクラス: repeat/offsetプロパティを操作してスケーリングを実現
- Three.js定数: テクスチャフォーマットとタイプの定義を参照

**権限による制御**：特になし（クライアントサイドで実行される汎用ユーティリティ）

## 関連画面

画面機能マッピングに直接的な関連画面の登録なし。本機能は内部ユーティリティとして他の機能から呼び出される。

## 機能種別

計算処理 / テクスチャ変換 / ユーティリティ

## 入力仕様

### 入力パラメータ

#### contain メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| texture | Texture | Yes | 対象のテクスチャオブジェクト | imageプロパティが必要 |
| aspect | number | Yes | 表示領域のアスペクト比（幅/高さ） | 正の数値 |

#### cover メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| texture | Texture | Yes | 対象のテクスチャオブジェクト | imageプロパティが必要 |
| aspect | number | Yes | 表示領域のアスペクト比（幅/高さ） | 正の数値 |

#### fill メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| texture | Texture | Yes | 対象のテクスチャオブジェクト | - |

#### getByteLength メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| width | number | Yes | テクスチャの幅（ピクセル） | 正の整数 |
| height | number | Yes | テクスチャの高さ（ピクセル） | 正の整数 |
| format | number | Yes | テクスチャフォーマット定数 | サポートされる形式 |
| type | number | Yes | テクスチャタイプ定数 | サポートされる形式 |

### 入力データソース

- Textureオブジェクト: image, repeat, offsetプロパティを持つ
- Three.js定数: AlphaFormat, RGBAFormat, 各種圧縮形式など

## 出力仕様

### 出力データ

#### contain/cover/fill メソッド

| 項目名 | 型 | 説明 |
|--------|-----|------|
| texture | Texture | repeat/offsetが調整されたテクスチャ（同一オブジェクト） |

#### getByteLength メソッド

| 項目名 | 型 | 説明 |
|--------|-----|------|
| byteLength | number | テクスチャのバイトサイズ |

### 出力先

- メモリ上のオブジェクト（入力テクスチャを直接変更して返却）

## 処理フロー

### 処理シーケンス

#### contain

```
1. 画像のアスペクト比を計算（width/height）
2. 画像と表示領域のアスペクト比を比較
3. 画像が横長の場合（imageAspect > aspect）：
   └─ repeat.x = 1, repeat.y = imageAspect / aspect
   └─ offset.x = 0, offset.y = (1 - repeat.y) / 2
4. 画像が縦長の場合：
   └─ repeat.x = aspect / imageAspect, repeat.y = 1
   └─ offset.x = (1 - repeat.x) / 2, offset.y = 0
5. テクスチャを返却
```

#### cover

```
1. 画像のアスペクト比を計算（width/height）
2. 画像と表示領域のアスペクト比を比較
3. 画像が横長の場合（imageAspect > aspect）：
   └─ repeat.x = aspect / imageAspect, repeat.y = 1
   └─ offset.x = (1 - repeat.x) / 2, offset.y = 0
4. 画像が縦長の場合：
   └─ repeat.x = 1, repeat.y = imageAspect / aspect
   └─ offset.x = 0, offset.y = (1 - repeat.y) / 2
5. テクスチャを返却
```

#### fill

```
1. repeat.x = 1, repeat.y = 1を設定
2. offset.x = 0, offset.y = 0を設定
3. テクスチャを返却
```

#### getByteLength

```
1. タイプからバイト長とコンポーネント数を取得
2. フォーマットに応じてバイトサイズを計算：
   └─ 非圧縮形式: width * height * チャンネル数 / コンポーネント数 * バイト長
   └─ 圧縮形式: ブロックベースで計算（4x4ブロック等）
3. サポートされない形式ではエラーをスロー
4. バイトサイズを返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: contain] --> B[画像アスペクト比計算]
    B --> C{imageAspect > aspect?}
    C -->|Yes: 画像が横長| D[repeat.x=1, repeat.y調整]
    C -->|No: 画像が縦長| E[repeat.x調整, repeat.y=1]
    D --> F[offset計算でセンタリング]
    E --> F
    F --> G[テクスチャを返却]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-173-01 | アスペクト比デフォルト | 画像がない場合はアスペクト比1として処理 | contain/cover実行時 |
| BR-173-02 | センタリング | repeatが1未満の軸はoffsetでセンタリング | contain/cover実行時 |
| BR-173-03 | 圧縮テクスチャブロック | 圧縮形式は4x4または8x8ブロック単位で計算 | getByteLength実行時 |
| BR-173-04 | 直接変更 | テクスチャオブジェクトを直接変更して返却 | contain/cover/fill実行時 |

### 計算ロジック

**アスペクト比計算**：
```
imageAspect = texture.image.width / texture.image.height
```

**contain計算**（画像が横長の場合）：
```
repeat.x = 1
repeat.y = imageAspect / aspect
offset.y = (1 - repeat.y) / 2
```

**cover計算**（画像が横長の場合）：
```
repeat.x = aspect / imageAspect
repeat.y = 1
offset.x = (1 - repeat.x) / 2
```

**圧縮テクスチャのバイトサイズ計算**（DXT1の例）：
```
blocks_x = floor((width + 3) / 4)
blocks_y = floor((height + 3) / 4)
byteLength = blocks_x * blocks_y * 8
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Error | 例外スロー | getBytelengthでサポートされないformat | エラーメッセージを含む例外をスロー |
| Error | 例外スロー | getTextureTypeByteLengthでサポートされないtype | エラーメッセージを含む例外をスロー |

### リトライ仕様

リトライ処理は実装されていない（同期処理のため）

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

トランザクション処理は適用されない（メモリ上の処理のみ）

## パフォーマンス要件

- contain/cover/fill: O(1)の計算量
- getByteLength: O(1)の計算量（switch文による分岐のみ）

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

特になし（純粋な数学計算処理）

## 備考

- contain/cover/fillは静的メソッドとモジュール関数の両方で提供
- 圧縮テクスチャは多数のフォーマット（S3TC, PVRTC, ETC, ASTC, BPTC, RGTC）をサポート
- getBytelengthはWebGL/WebGPUのメモリ管理に使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Texture.js | `src/textures/Texture.js` | repeat, offset, imageプロパティの構造 |
| 1-2 | constants.js | `src/constants.js` | テクスチャフォーマットとタイプの定数定義 |

**読解のコツ**: Textureクラスのrepeat（Vector2）とoffset（Vector2）プロパティがUVマッピングを制御することを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TextureUtils.js | `src/extras/TextureUtils.js` | 4つの主要関数（contain, cover, fill, getByteLength）を確認 |

**主要処理フロー**:
1. **12-36行目**: contain関数 - アスペクト比比較と条件分岐
2. **14行目**: 画像アスペクト比のデフォルト値計算（三項演算子）
3. **47-71行目**: cover関数 - containの逆ロジック
4. **79-89行目**: fill関数 - デフォルト値にリセット
5. **100-201行目**: getByteLength関数 - フォーマット別のバイト計算

#### Step 3: バイトサイズ計算ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TextureUtils.js | `src/extras/TextureUtils.js` | 203-229行目 getTextureTypeByteLength関数 |

**主要処理フロー**:
- **203-229行目**: タイプ別のバイト長とコンポーネント数を返却
- **207-209行目**: UnsignedByteType/ByteTypeは1バイト、1コンポーネント
- **214-216行目**: UnsignedShort4444Type等はパック形式で特殊なコンポーネント数

#### Step 4: 圧縮テクスチャの計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TextureUtils.js | `src/extras/TextureUtils.js` | 124-194行目の圧縮形式別計算 |

**主要処理フロー**:
- **125-130行目**: S3TC（DXT）形式 - 4x4ブロック、8または16バイト/ブロック
- **132-138行目**: PVRTC形式 - 最小サイズ制約あり
- **140-149行目**: ETC形式 - 4x4ブロック
- **151-179行目**: ASTC形式 - 可変ブロックサイズ（4x4〜12x12）
- **181-185行目**: BPTC形式 - 4x4ブロック、16バイト/ブロック
- **187-193行目**: RGTC形式 - 4x4ブロック、8または16バイト/ブロック

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

```
TextureUtils.contain(texture, aspect)
    │
    ├─ texture.image.width / height → アスペクト比計算
    │
    ├─ texture.repeat.x / .y 設定
    │
    └─ texture.offset.x / .y 設定

TextureUtils.getByteLength(width, height, format, type)
    │
    └─ getTextureTypeByteLength(type)
           └─ { byteLength, components } を返却
```

### データフロー図

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

Texture ─────────────────▶ contain(texture, aspect) ─────────▶ Texture
  (image, repeat, offset)       │                                (repeat/offset変更済み)
number (aspect)                 └─ アスペクト比比較
                                   repeat/offset計算


width ─────────────────┐
height ────────────────┤
format ────────────────┼──▶ getByteLength() ──────────────────▶ number (bytes)
type ──────────────────┘         │
                                 ├─ getTextureTypeByteLength()
                                 │      └─ バイト長/コンポーネント数
                                 │
                                 └─ フォーマット別計算
                                        └─ 非圧縮: w*h*ch*byte
                                        └─ 圧縮: ブロック数*ブロックサイズ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TextureUtils.js | `src/extras/TextureUtils.js` | ソース | テクスチャユーティリティの本体 |
| Texture.js | `src/textures/Texture.js` | ソース | テクスチャクラス（repeat/offset定義） |
| constants.js | `src/constants.js` | ソース | テクスチャフォーマット/タイプ定数 |
| Vector2.js | `src/math/Vector2.js` | ソース | repeat/offsetの型（Vector2） |
