# 機能設計書 113-KeyframeTrack

## 概要

本ドキュメントは、Three.jsにおける`KeyframeTrack`クラスの機能設計を記述する。KeyframeTrackは、時間に対するキーフレーム値のシーケンスを管理し、特定のプロパティをアニメーションするためのトラック基底クラスである。

### 本機能の処理概要

KeyframeTrackは、アニメーションにおける単一プロパティのキーフレームデータを管理する基本単位である。時間配列（times）と値配列（values）を保持し、様々な補間方法（線形、離散、スムース、ベジェ）を用いて中間値を計算する機能を提供する。

**業務上の目的・背景**：3Dアニメーションにおいて、位置、回転、スケール、色、モーフターゲットなど様々なプロパティをアニメーションする必要がある。KeyframeTrackは、これらのプロパティタイプに対応した基底クラスとして機能し、データ型ごとに最適化されたサブクラス（NumberKeyframeTrack、VectorKeyframeTrack等）の共通基盤を提供する。

**機能の利用シーン**：
- オブジェクトのトランスフォーム（位置、回転、スケール）アニメーション
- マテリアルプロパティ（色、透明度）のアニメーション
- モーフターゲットの影響度アニメーション
- カスタムプロパティのアニメーション

**主要な処理内容**：
1. キーフレームの時間・値データの格納と管理
2. 補間タイプ（Linear, Discrete, Smooth, Bezier）の設定と切り替え
3. インターポラントファクトリによる補間オブジェクト生成
4. キーフレームの最適化（冗長なキーの削除）
5. トラックのトリミング、シフト、スケーリング

**関連システム・外部連携**：AnimationClipの構成要素として使用され、AnimationActionの再生時にインターポラントを生成し、PropertyMixerを介してオブジェクトプロパティを更新する。

**権限による制御**：特になし（ライブラリ内部機能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | - | - | KeyframeTrackはライブラリ内部で使用されるデータクラスであり、直接的なUI関連はない |

## 機能種別

データ管理 / 補間処理 / シリアライズ・デシリアライズ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | トラック名（プロパティパス） | undefined不可 |
| times | Array<number> | Yes | キーフレーム時間の配列 | 空配列不可 |
| values | Array<number\|string\|boolean> | Yes | キーフレーム値の配列 | - |
| interpolation | number | No | 補間タイプ | デフォルト: DefaultInterpolation |

### 入力データソース

- GLTFLoader等のアセットローダーからのアニメーションデータ
- プログラマティックに生成されたキーフレームデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | string | トラック名 |
| times | Float32Array | キーフレーム時間配列 |
| values | Float32Array | キーフレーム値配列 |
| ValueTypeName | string | 値の型名 |
| TimeBufferType | TypedArray | 時間バッファの型 |
| ValueBufferType | TypedArray | 値バッファの型 |

### 出力先

- AnimationClipのtracks配列に格納
- AnimationActionによるインターポラント生成

## 処理フロー

### 処理シーケンス

```
1. コンストラクタによるインスタンス生成
   └─ name, times, valuesの設定
   └─ Float32Arrayへの変換
   └─ 補間タイプの設定

2. createInterpolant() - 補間オブジェクト生成
   └─ 設定された補間タイプに応じたインターポラントを生成
   └─ DiscreteInterpolant / LinearInterpolant / CubicInterpolant / BezierInterpolant

3. optimize() - キーフレーム最適化
   └─ 冗長な連続キーフレームを削除
   └─ 同一時刻のキーフレームを削除

4. trim() - トラックトリミング
   └─ 指定範囲外のキーフレームを削除
```

### フローチャート

```mermaid
flowchart TD
    A[KeyframeTrack生成] --> B[times/valuesをFloat32Arrayに変換]
    B --> C[補間タイプを設定]
    C --> D{使用方法}
    D -->|再生時| E[createInterpolant呼び出し]
    E --> F{補間タイプ}
    F -->|Discrete| G[DiscreteInterpolant生成]
    F -->|Linear| H[LinearInterpolant生成]
    F -->|Smooth| I[CubicInterpolant生成]
    F -->|Bezier| J[BezierInterpolant生成]
    D -->|最適化| K[optimize呼び出し]
    K --> L[冗長キー削除]
    D -->|トリミング| M[trim呼び出し]
    M --> N[範囲外キー削除]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-113-01 | デフォルト補間 | DefaultInterpolationはInterpolateLinear | サブクラスで上書き可能 |
| BR-113-02 | バッファ型 | times/valuesはFloat32Arrayに自動変換 | コンストラクタ実行時 |
| BR-113-03 | 最小キー数 | trim後も最低1つのキーフレームを維持 | trim実行時 |

### 計算ロジック

**値サイズ計算**:
```javascript
valueSize = values.length / times.length
```

**時間シフト**:
```javascript
times[i] += timeOffset (for all i)
```

**時間スケーリング**:
```javascript
times[i] *= timeScale (for all i)
```

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

該当なし（メモリ内データ構造）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Error | 必須パラメータ不足 | nameがundefined | 適切なトラック名を指定 |
| Error | 必須パラメータ不足 | timesが空または未定義 | キーフレーム時間を指定 |
| Error | 補間エラー | サポートされない補間タイプ | DefaultInterpolationにフォールバック |
| - | 警告 | サポートされない補間タイプ（フォールバック時） | ログ出力 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- Float32Arrayによる効率的なメモリ使用
- optimize()による冗長データ削除でメモリ節約

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

特になし

## 備考

- KeyframeTrackは基底クラスであり、通常は派生クラス（NumberKeyframeTrack, VectorKeyframeTrack等）を使用
- トラック名はPropertyBindingで解析される形式に従う必要がある

---

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

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

### 推奨読解順序

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

KeyframeTrackの基本的なデータ構造とプロトタイププロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | コンストラクタ（19-59行目） |
| 1-2 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | プロトタイププロパティ（604-634行目） |

**読解のコツ**: KeyframeTrackの主要プロパティ
- `name`: プロパティパス（例: "mesh.position"）
- `times`: Float32Array - キーフレーム時間
- `values`: Float32Array - キーフレーム値
- `ValueTypeName`: 値の型名（サブクラスで定義）
- `TimeBufferType`, `ValueBufferType`: バッファの型（Float32Array）
- `DefaultInterpolation`: デフォルト補間タイプ

#### Step 2: 補間ファクトリメソッドを理解する

インターポラント生成の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | InterpolantFactoryMethodDiscrete（113-117行目） |
| 2-2 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | InterpolantFactoryMethodLinear（126-130行目） |
| 2-3 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | InterpolantFactoryMethodSmooth（139-143行目） |
| 2-4 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | InterpolantFactoryMethodBezier（157-170行目） |
| 2-5 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | setInterpolation（178-239行目） |

**主要処理フロー**:
- **113-117行目**: Discrete - DiscreteInterpolantを生成（ステップ補間）
- **126-130行目**: Linear - LinearInterpolantを生成（線形補間）
- **139-143行目**: Smooth - CubicInterpolantを生成（スムース補間）
- **157-170行目**: Bezier - BezierInterpolantを生成（ベジェ補間）
- **178-239行目**: setInterpolation - 補間タイプに応じてcreateInterpolantを設定

#### Step 3: 操作メソッドを理解する

トラックの操作・最適化メソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | shift()（287-303行目） |
| 3-2 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | scale()（311-327行目） |
| 3-3 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | trim()（339-379行目） |
| 3-4 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | optimize()（469-580行目） |

**主要処理フロー**:
- **287-303行目**: shift - 全キーフレーム時間をオフセット
- **311-327行目**: scale - 全キーフレーム時間をスケーリング
- **339-379行目**: trim - 指定範囲にトラックをトリミング
- **469-580行目**: optimize - 冗長なキーフレームを削除

#### Step 4: 検証とシリアライズを理解する

データ検証とJSON変換を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | validate()（387-461行目） |
| 4-2 | KeyframeTrack.js | `src/animation/KeyframeTrack.js` | toJSON()静的メソッド（68-104行目） |

**主要処理フロー**:
- **387-461行目**: validate - 時間順序、NaN値、値サイズの検証
- **68-104行目**: toJSON - トラックをJSON形式に変換

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

```
KeyframeTrack
    │
    ├─ constructor()
    │      ├─ AnimationUtils.convertArray(times)
    │      ├─ AnimationUtils.convertArray(values)
    │      └─ setInterpolation()
    │
    ├─ setInterpolation()
    │      └─ createInterpolant = InterpolantFactoryMethodXxx
    │
    ├─ createInterpolant() [動的設定]
    │      ├─ InterpolantFactoryMethodDiscrete()
    │      │      └─ new DiscreteInterpolant()
    │      ├─ InterpolantFactoryMethodLinear()
    │      │      └─ new LinearInterpolant()
    │      ├─ InterpolantFactoryMethodSmooth()
    │      │      └─ new CubicInterpolant()
    │      └─ InterpolantFactoryMethodBezier()
    │             └─ new BezierInterpolant()
    │
    ├─ shift() / scale()
    │      └─ times配列の直接操作
    │
    ├─ trim()
    │      └─ times/valuesのslice
    │
    ├─ validate()
    │      └─ エラーログ出力
    │
    ├─ optimize()
    │      └─ times/valuesの再構築
    │
    ├─ clone()
    │      └─ new TypedKeyframeTrack()
    │
    └─ toJSON() [静的]
           └─ AnimationUtils.convertArray(Array)
```

### データフロー図

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

times[] ────────────────▶ convertArray(Float32Array) ──▶ this.times
values[] ───────────────▶ convertArray(Float32Array) ──▶ this.values
interpolation ──────────▶ setInterpolation() ─────────▶ this.createInterpolant

再生時
AnimationAction ────────▶ track.createInterpolant() ──▶ Interpolant インスタンス
                                │
                                ▼
                        interpolant.evaluate(time)
                                │
                                ▼
                        補間された値

シリアライズ時
KeyframeTrack ──────────▶ toJSON() ────────────────────▶ JSON オブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| KeyframeTrack.js | `src/animation/KeyframeTrack.js` | ソース | 基底クラス定義 |
| NumberKeyframeTrack.js | `src/animation/tracks/NumberKeyframeTrack.js` | ソース | 数値トラック |
| VectorKeyframeTrack.js | `src/animation/tracks/VectorKeyframeTrack.js` | ソース | ベクトルトラック |
| QuaternionKeyframeTrack.js | `src/animation/tracks/QuaternionKeyframeTrack.js` | ソース | 四元数トラック |
| ColorKeyframeTrack.js | `src/animation/tracks/ColorKeyframeTrack.js` | ソース | カラートラック |
| StringKeyframeTrack.js | `src/animation/tracks/StringKeyframeTrack.js` | ソース | 文字列トラック |
| BooleanKeyframeTrack.js | `src/animation/tracks/BooleanKeyframeTrack.js` | ソース | 真偽値トラック |
| LinearInterpolant.js | `src/math/interpolants/LinearInterpolant.js` | ソース | 線形補間 |
| DiscreteInterpolant.js | `src/math/interpolants/DiscreteInterpolant.js` | ソース | 離散補間 |
| CubicInterpolant.js | `src/math/interpolants/CubicInterpolant.js` | ソース | 3次補間 |
| BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | ソース | ベジェ補間 |
| AnimationUtils.js | `src/animation/AnimationUtils.js` | ソース | ユーティリティ関数 |
| constants.js | `src/constants.js` | ソース | 補間タイプ定数 |
