# 通知設計書 67-NOTIFICATION_UPDATE_SKELETON

## 概要

本ドキュメントは、Godotエンジンにおける`NOTIFICATION_UPDATE_SKELETON`通知の設計仕様を定義する。この通知はSkeleton3Dクラスでスケルトン（ボーン階層）の更新処理を実行すべきタイミングで送信される内部通知である。

### 本通知の処理概要

`NOTIFICATION_UPDATE_SKELETON`通知は、3Dスケルトンのボーンポーズが更新され、スキンメッシュのレンダリングに反映される必要があるタイミングで発火される。アニメーション再生、IK処理、物理シミュレーションなどによるボーン変換の変更後に送信される。

**業務上の目的・背景**：3Dキャラクターアニメーションにおいて、スケルトンのボーンポーズが変更された際に、それに紐づくスキンメッシュ（MeshInstance3D）やボーンアタッチメント（BoneAttachment3D）を正しく更新する必要がある。この通知はスケルトン更新のライフサイクルを管理する。

**通知の送信タイミング**：Skeleton3D::force_update_all_dirty_bones()またはforce_update_deferred()が呼び出され、ボーンの変換が計算された後に送信される。通常はprocess/physics_processフレーム内で発生する。

**通知の受信者**：Skeleton3Dクラス自身、およびSkeleton3Dを参照するBoneAttachment3D、SkeletonModifier3D等の関連クラス。

**通知内容の概要**：通知値は`50`（Skeleton3D::NOTIFICATION_UPDATE_SKELETON）。追加のパラメータは含まれない。

**期待されるアクション**：受信者はスキンバインドの更新、ボーンアタッチメントの変換更新、モディファイアの処理、skeleton_updatedシグナルの発火などを実行する。

## 通知種別

アプリ内通知（エンジン内部通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | なし |

### 送信先決定ロジック

Skeleton3D自身の_notificationメソッドに対して送信される。派生クラスやアタッチされたノードは別途シグナルを介して通知を受ける。

## 通知テンプレート

### エンジン内部通知の場合

| 項目 | 内容 |
|-----|------|
| 通知定数名 | NOTIFICATION_UPDATE_SKELETON |
| 通知値 | 50 |
| 定義クラス | Skeleton3D |

### 通知ペイロード

通知に追加データは含まれない。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| p_notification | 通知ID（50） | エンジン内部 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ポーズ更新 | force_update_all_dirty_bones() | ボーンポーズ変更 | ボーンのポーズが変更された時 |
| フレーム処理 | _update_deferred | 更新フラグあり | 遅延更新がスケジュールされた時 |
| ツリー参加 | POST_ENTER_TREE | 初回更新 | シーンツリーに追加された直後 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 更新不要 | update_flags & UPDATE_FLAG_POSEがfalseの場合 |
| 更新中 | updatingフラグがtrueの場合（再入防止） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ボーンポーズ変更] --> B[_make_dirty呼び出し]
    B --> C[_update_deferred スケジュール]
    C --> D[NOTIFICATION_UPDATE_SKELETON送信]
    D --> E[force_update_all_dirty_bones]
    E --> F{モディファイアあり?}
    F -->|Yes| G[モディファイア処理]
    F -->|No| H[スキン更新]
    G --> H
    H --> I[skeleton_updatedシグナル発火]
    I --> J[処理終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

本通知はデータベースを使用しない。

### 更新テーブル一覧

本通知はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 無効なボーンインデックス | 存在しないボーンへのアクセス | ERR_FAIL_INDEX_Vで処理中断 |
| 循環参照 | ボーン親子関係の循環 | エラーメッセージを出力し処理継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（フレームレート依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

常時（ボーン更新時）

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

- 本通知はエンジン内部の通知であり、外部からの直接送信は不可能
- スケルトン処理は通常メインスレッドで実行される

## 備考

- `skeleton_updated`シグナルが通知後に発火される
- ModifierCallbackModeProcess設定により処理タイミングを制御可能（IDLE/PHYSICS/MANUAL）
- エディタのプレビュー時（EDITOR_PRE_SAVE/POST_SAVE）にはsavingフラグで制御される

---

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

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

### 推奨読解順序

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

まず、通知定数の定義場所を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | skeleton_3d.h | `scene/3d/skeleton_3d.h` | 220-222行目でNOTIFICATION_UPDATE_SKELETONが50として定義されていることを確認 |
| 1-2 | skeleton_3d.h | `scene/3d/skeleton_3d.h` | 88-92行目でUpdateFlagが定義されている |

**読解のコツ**: UPDATE_FLAG_MODIFIER、UPDATE_FLAG_POSEの2種類のフラグがあることに注目する。

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

通知を受信・処理する_notificationメソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | 288-310行目の_notification()メソッドでNOTIFICATION_UPDATE_SKELETONが処理される |
| 2-2 | skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | 301-302行目でPOST_ENTER_TREE後に通知が送信される |

**主要処理フロー**:
1. **311行目**: NOTIFICATION_UPDATE_SKELETONケース開始
2. **313行目**: force_update_all_dirty_bones()呼び出し
3. **315行目**: updating = true でロック
4. **325-337行目**: モディファイア処理
5. **347行目**: skeleton_updatedシグナル発火
6. **349-400行目**: スキンバインド更新

#### Step 3: 更新フラグ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | _update_deferred()メソッドで更新がスケジュールされる |
| 3-2 | skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | _make_dirty()でdirtyフラグが設定される |

**主要処理フロー**:
- ボーンポーズ変更時に_make_dirty()が呼ばれる
- _update_deferred()でNOTIFICATION_UPDATE_SKELETONがスケジュールされる

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

```
Skeleton3D
    │
    ├─ set_bone_pose_position/rotation/scale
    │      └─ _make_dirty()
    │
    ├─ _update_deferred()
    │      └─ notification(NOTIFICATION_UPDATE_SKELETON)
    │
    └─ _notification(NOTIFICATION_UPDATE_SKELETON)
           │
           ├─ force_update_all_dirty_bones()
           │      └─ ボーン変換計算
           │
           ├─ _process_modifiers()
           │      └─ SkeletonModifier3D処理
           │
           ├─ emit_signal("skeleton_updated")
           │
           └─ スキンバインド更新
                  └─ RenderingServer::skeleton_bone_set_transform
```

### データフロー図

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

ボーンポーズ       ───▶ _make_dirty()              ───▶ dirty = true
変更                          │                               │
                              ▼                               ▼
                    _update_deferred()               UPDATE_SKELETON通知
                              │                               │
                              ▼                               ▼
                    force_update_all_dirty_bones    ボーン変換計算
                              │                               │
                              ▼                               ▼
                    スキンバインド更新              RenderingServer更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| skeleton_3d.h | `scene/3d/skeleton_3d.h` | ソース | 通知定数・クラス定義 |
| skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | ソース | Skeleton3D実装 |
| bone_attachment_3d.cpp | `scene/3d/bone_attachment_3d.cpp` | ソース | ボーンアタッチメント実装 |
| skeleton_modifier_3d.cpp | `scene/3d/skeleton_modifier_3d.cpp` | ソース | スケルトンモディファイア基底クラス |
| skeleton_3d_editor_plugin.cpp | `editor/scene/3d/skeleton_3d_editor_plugin.cpp` | ソース | エディタプラグイン |
| skin.h | `scene/resources/3d/skin.h` | ソース | スキンリソース定義 |
