# 機能設計書 111-AnimationClip

## 概要

本ドキュメントは、Three.jsにおける`AnimationClip`クラスの機能設計を記述する。AnimationClipは、キーフレームアニメーションデータを格納し、複数のKeyframeTrackを束ねて一つのアニメーションとして管理するコンテナクラスである。

### 本機能の処理概要

AnimationClipは、3Dシーン内のオブジェクトに適用されるアニメーションの基本単位であり、キャラクターの動作やカメラワーク、オブジェクトの変形など、あらゆるアニメーション効果を実現するための中核的なデータ構造を提供する。

**業務上の目的・背景**：3Dコンテンツ制作において、アニメーションは必須の要素である。AnimationClipは、3Dモデリングソフトウェア（Blender、Maya等）で作成されたアニメーションデータをThree.jsで再生可能な形式で管理し、Webブラウザ上でリッチなアニメーション体験を実現する。GLTFローダー等が読み込んだアニメーションデータの受け皿として機能し、AnimationMixerと連携してシームレスなアニメーション再生を可能にする。

**機能の利用シーン**：
- 3Dキャラクターのスケルタルアニメーション（歩行、ジャンプ、攻撃等）
- モーフターゲットアニメーション（表情変化等）
- カメラパスアニメーション
- オブジェクトのトランスフォームアニメーション（移動、回転、スケール）
- UIエレメントの視覚効果

**主要な処理内容**：
1. 複数のKeyframeTrackを統合管理し、アニメーションクリップとして定義
2. JSONからのパース機能およびJSONへのシリアライズ機能を提供
3. モーフターゲットシーケンスからのクリップ自動生成
4. クリップの最適化（重複キーフレームの除去）とトリミング
5. アニメーションの検証とデュレーション計算

**関連システム・外部連携**：GLTFLoader、FBXLoader等のローダーがアニメーションデータを読み込む際にAnimationClipインスタンスを生成する。AnimationMixerがこのクリップを受け取り、AnimationActionを通じて再生制御を行う。

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

## 関連画面

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

## 機能種別

データ管理 / シリアライズ・デシリアライズ / アニメーションデータ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | No | クリップの名前 | デフォルト: '' |
| duration | number | No | クリップの長さ（秒） | 負の値の場合はトラックから自動計算 |
| tracks | Array<KeyframeTrack> | No | キーフレームトラックの配列 | デフォルト: [] |
| blendMode | number | No | ブレンドモード | NormalAnimationBlendModeまたはAdditiveAnimationBlendMode |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| uuid | string | クリップの一意識別子 |
| name | string | クリップ名 |
| duration | number | アニメーションの長さ（秒） |
| tracks | Array<KeyframeTrack> | キーフレームトラック配列 |
| blendMode | number | ブレンドモード |
| userData | Object | カスタムデータ格納用オブジェクト |

### 出力先

- AnimationMixerへの入力として使用
- JSONシリアライズによるファイル出力

## 処理フロー

### 処理シーケンス

```
1. コンストラクタによるインスタンス生成
   └─ name, duration, tracks, blendModeの初期化
   └─ UUIDの自動生成
   └─ duration < 0 の場合、resetDuration()でトラックから計算

2. parse() - JSONからのデシリアライズ
   └─ JSONのtracks配列をパース
   └─ 各トラックをframeTimeでスケーリング
   └─ 新しいAnimationClipインスタンスを生成

3. toJSON() - JSONへのシリアライズ
   └─ クリップの全プロパティをJSON形式に変換
   └─ 各トラックをKeyframeTrack.toJSON()で変換

4. CreateFromMorphTargetSequence() - モーフターゲットからクリップ生成
   └─ モーフターゲットシーケンスから自動的にキーフレームを生成
   └─ NumberKeyframeTrackを作成
```

### フローチャート

```mermaid
flowchart TD
    A[開始: AnimationClip生成] --> B{durationは負の値?}
    B -->|Yes| C[resetDuration呼び出し]
    B -->|No| D[duration値を使用]
    C --> E[全トラックの最大時間を計算]
    E --> D
    D --> F[インスタンス完成]
    F --> G{使用方法}
    G -->|再生| H[AnimationMixerに渡す]
    G -->|保存| I[toJSON()でシリアライズ]
    G -->|最適化| J[optimize()で冗長キー削除]
    G -->|トリミング| K[trim()で範囲指定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-111-01 | 自動デュレーション計算 | durationが負の値の場合、全トラックの最大終了時間を自動計算 | コンストラクタ実行時 |
| BR-111-02 | UUID自動生成 | 各クリップに一意のUUIDを自動付与 | コンストラクタ実行時 |
| BR-111-03 | ブレンドモード継承 | 指定がない場合はNormalAnimationBlendModeを使用 | コンストラクタ実行時 |

### 計算ロジック

**デュレーション計算**（resetDuration）:
```javascript
duration = max(track.times[最終インデックス]) for all tracks
```

**FPSからの時間変換**（parse時）:
```javascript
frameTime = 1.0 / fps
scaledTime = originalTime * frameTime
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Warning | parseAnimation()の非推奨使用 | r175以降で警告、r185で削除予定 |
| TypeError | 型エラー | 不正なJSON形式でのparse | 正しいJSON形式を使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- optimize()による冗長キーフレーム削除でメモリ使用量を削減
- Float32Arrayによる効率的なデータ格納

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

- userDataオブジェクトには関数を格納しないこと（クローン時に失われる）
- 外部JSONをパースする際は入力値の検証を推奨

## 備考

- AnimationClipは不変（immutable）ではないが、複数のAnimationActionで共有される場合がある
- clone()メソッドで安全なコピーを作成可能

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AnimationClip.js | `src/animation/AnimationClip.js` | クラス定義とコンストラクタ（16-86行目） |
| 1-2 | constants.js | `src/constants.js` | NormalAnimationBlendMode, AdditiveAnimationBlendModeの定義 |

**読解のコツ**: AnimationClipは以下のプロパティを持つ
- `name`: クリップ名
- `tracks`: KeyframeTrackの配列（最重要）
- `duration`: 秒単位のアニメーション長
- `blendMode`: ブレンドモード
- `uuid`: 一意識別子
- `userData`: カスタムデータ

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

クリップの生成方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AnimationClip.js | `src/animation/AnimationClip.js` | parse()メソッド（95-114行目） |
| 2-2 | AnimationClip.js | `src/animation/AnimationClip.js` | toJSON()メソッド（123-147行目） |
| 2-3 | AnimationClip.js | `src/animation/AnimationClip.js` | CreateFromMorphTargetSequence()（163-203行目） |

**主要処理フロー**:
1. **95-114行目**: JSONパース処理 - fps値から時間変換し、トラックをスケーリング
2. **123-147行目**: JSON出力 - 全プロパティとトラックをシリアライズ
3. **163-203行目**: モーフターゲットからクリップ自動生成

#### Step 3: インスタンスメソッドを理解する

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AnimationClip.js | `src/animation/AnimationClip.js` | resetDuration()（441-458行目） |
| 3-2 | AnimationClip.js | `src/animation/AnimationClip.js` | trim()（465-475行目） |
| 3-3 | AnimationClip.js | `src/animation/AnimationClip.js` | optimize()（503-513行目） |
| 3-4 | AnimationClip.js | `src/animation/AnimationClip.js` | validate()（483-495行目） |

**主要処理フロー**:
- **441-458行目**: 全トラックの最大終了時間からdurationを再計算
- **465-475行目**: 指定範囲にトラックをトリミング
- **503-513行目**: 冗長なキーフレームを削除して最適化

#### Step 4: ヘルパー関数を理解する

モジュール内のヘルパー関数の役割を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AnimationClip.js | `src/animation/AnimationClip.js` | getTrackTypeForValueTypeName()（551-591行目） |
| 4-2 | AnimationClip.js | `src/animation/AnimationClip.js` | parseKeyframeTrack()（593-626行目） |

**主要処理フロー**:
- **551-591行目**: 型名から適切なKeyframeTrackサブクラスを返す
- **593-626行目**: JSON形式のトラックデータをパースしてKeyframeTrackインスタンスを生成

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

```
AnimationClip
    │
    ├─ constructor()
    │      └─ resetDuration() [duration < 0 の場合]
    │
    ├─ parse() [静的]
    │      ├─ parseKeyframeTrack()
    │      │      └─ getTrackTypeForValueTypeName()
    │      └─ track.scale()
    │
    ├─ toJSON() [静的]
    │      └─ KeyframeTrack.toJSON()
    │
    ├─ CreateFromMorphTargetSequence() [静的]
    │      ├─ AnimationUtils.getKeyframeOrder()
    │      ├─ AnimationUtils.sortedArray()
    │      └─ NumberKeyframeTrack()
    │
    ├─ findByName() [静的]
    │
    ├─ CreateClipsFromMorphTargetSequences() [静的]
    │      └─ CreateFromMorphTargetSequence()
    │
    ├─ resetDuration()
    │      └─ track.times の最大値取得
    │
    ├─ trim()
    │      └─ track.trim()
    │
    ├─ validate()
    │      └─ track.validate()
    │
    ├─ optimize()
    │      └─ track.optimize()
    │
    └─ clone()
           └─ track.clone()
```

### データフロー図

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

JSON/GLTF ──────────────▶ AnimationClip.parse() ──────▶ AnimationClip インスタンス
                                │
                                ▼
                         parseKeyframeTrack()
                                │
                                ▼
                         KeyframeTrack インスタンス群
                                │
                                ▼
AnimationClip ──────────▶ AnimationMixer.clipAction() ▶ AnimationAction
                                │
                                ▼
                         アニメーション再生

AnimationClip ──────────▶ toJSON() ──────────────────▶ JSON オブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AnimationClip.js | `src/animation/AnimationClip.js` | ソース | メインクラス定義 |
| 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` | ソース | 真偽値トラック |
| AnimationUtils.js | `src/animation/AnimationUtils.js` | ソース | ユーティリティ関数 |
| AnimationMixer.js | `src/animation/AnimationMixer.js` | ソース | クリップ再生管理 |
| constants.js | `src/constants.js` | ソース | 定数定義 |
