# 機能設計書 18-ジョイント（接合）

## 概要

本ドキュメントは、Godotエンジンにおけるジョイント（接合）機能の設計仕様を記述する。ジョイント機能は、2つの物理ボディを接続し、それらの相対的な動きを制約する機能である。ヒンジ、スライダー、ピン、バネなど様々な接合タイプをサポートする。

### 本機能の処理概要

**業務上の目的・背景**：物理シミュレーションにおいて、複数の剛体を連結して複雑な機構を構成することは一般的なニーズである。ドアのヒンジ、車両のサスペンション、キャラクターのラグドール、チェーンや紐の表現など、ジョイントは多様な物理挙動の実現に不可欠である。

**機能の利用シーン**：
- ドアやゲートのヒンジ回転
- 車両のサスペンション（バネジョイント）
- ラグドール物理（キャラクターの関節）
- チェーンやロープの接続
- ピンボールのフリッパー
- クレーンやロボットアームの関節

**主要な処理内容**：
1. PhysicsServer経由でジョイントを作成
2. 2つのPhysicsBodyをノードパスで参照
3. ジョイントパラメータ（バイアス、制限角度等）の設定
4. 衝突除外の制御
5. シーンツリーとの同期

**関連システム・外部連携**：
- PhysicsServer2D/3D：ジョイントの作成と管理
- PhysicsBody2D/3D：接続対象のボディ

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 2Dエディタ | 主画面 | 2Dジョイントの設定・プレビュー |
| 4 | 3Dエディタ | 主画面 | 3Dジョイントの設定・プレビュー |

## 機能種別

物理制約 / 機構シミュレーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| node_a | NodePath | No | 接続するボディA | PhysicsBody2D/3Dへのパス |
| node_b | NodePath | No | 接続するボディB | PhysicsBody2D/3Dへのパス |
| bias | float | No | バイアス値（0-0.9） | 2Dのみ |
| solver_priority | int | No | ソルバー優先度（1-8） | 3Dのみ |
| disable_collision | bool | No | 接続ボディ間の衝突を無効化 | - |

### 入力データソース

- エディタでのプロパティ設定
- スクリプトからの動的設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| joint | RID | PhysicsServerのジョイントRID |
| configured | bool | ジョイントが正しく設定されたか |
| ba, bb | RID | 接続されたボディのRID |

### 出力先

- PhysicsServer（ジョイント制約の適用）

## 処理フロー

### 処理シーケンス

```
1. NOTIFICATION_POST_ENTER_TREEでジョイント更新
   └─ _update_joint()呼び出し
2. ノードパスからPhysicsBodyを取得
   └─ get_node_or_null(a/b)
3. バリデーションチェック
   └─ 両方PhysicsBodyか、同一ボディでないか等
4. ジョイントを設定
   └─ _configure_joint()（派生クラスで実装）
5. 衝突除外を設定
   └─ joint_disable_collisions_between_bodies()
6. シグナル接続
   └─ tree_exitingで自動切断
```

### フローチャート

```mermaid
flowchart TD
    A[NOTIFICATION_POST_ENTER_TREE] --> B[_update_joint]
    B --> C{既存衝突除外あり?}
    C -->|Yes| D[衝突除外を解除]
    C -->|No| E[続行]
    D --> E
    E --> F[ノードパスからボディ取得]
    F --> G{バリデーション}
    G -->|失敗| H[警告設定、joint_clear]
    G -->|成功| I[force_update_transform]
    I --> J[_configure_joint]
    J --> K[バイアス/優先度を設定]
    K --> L[シグナル接続]
    L --> M[joint_disable_collisions_between_bodies]
    M --> N[終了]
    H --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 両ボディ必須 | node_aとnode_bの両方がPhysicsBodyである必要がある | 常時 |
| BR-02 | 異ボディ制約 | node_aとnode_bは異なるボディである必要がある | 常時 |
| BR-03 | 自動切断 | 接続ボディがシーンから削除されるとジョイントも無効化 | tree_exiting時 |

### 計算ロジック

特になし

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | Node AがPhysicsBodyでない | 正しいノードパスを設定 |
| - | 警告 | Node BがPhysicsBodyでない | 正しいノードパスを設定 |
| - | 警告 | Node AとNode Bが同じ | 異なるボディを設定 |
| - | 警告 | ジョイントが接続されていない | 両方のボディを設定 |

### リトライ仕様

なし

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

なし

## パフォーマンス要件

- ジョイントの設定変更は即時反映
- solver_priorityでジョイント解決の優先順位を制御可能

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

特になし

## 備考

- 2Dジョイント種別: PinJoint2D, GrooveJoint2D, DampedSpringJoint2D
- 3Dジョイント種別: PinJoint3D, HingeJoint3D, SliderJoint3D, ConeTwistJoint3D, Generic6DOFJoint3D

---

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

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

### 推奨読解順序

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

Joint2Dの基底クラス構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | joint_2d.h | `scene/2d/physics/joints/joint_2d.h` | Joint2Dクラスのメンバ変数（a, b, joint, ba, bb） |

**読解のコツ**: a/bはNodePath、ba/bbはRID。jointはPhysicsServerのジョイントRID。configuredは有効な接続状態を示す。

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

ジョイント更新処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | joint_2d.cpp | `scene/2d/physics/joints/joint_2d.cpp` | _notification関数と_update_joint関数 |

**主要処理フロー**:
1. **173-189行目**: _notification - ENTER/EXIT_TREEでのジョイント更新
2. **55-127行目**: _update_joint - ジョイント設定の本体

#### Step 3: _update_jointを詳細に理解する

ジョイント設定の詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | joint_2d.cpp | `scene/2d/physics/joints/joint_2d.cpp` | _update_joint関数 |

**主要処理フロー**:
- **56-58行目**: 既存の衝突除外解除
- **70-74行目**: ノードパスからPhysicsBody取得
- **78-91行目**: バリデーションと警告生成
- **100-106行目**: force_update_transform
- **110行目**: _configure_joint（派生クラス実装）
- **114行目**: バイアス設定
- **119-124行目**: tree_exitingシグナル接続
- **126行目**: 衝突除外設定

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

```
Joint2D::_notification(NOTIFICATION_POST_ENTER_TREE)
    │
    └─ Joint2D::_update_joint()
           │
           ├─ get_node_or_null() [ノードパス解決]
           │
           ├─ PhysicsBody2D::force_update_transform()
           │
           ├─ _configure_joint() [派生クラス]
           │      │
           │      └─ PhysicsServer2D::joint_make_*()
           │
           ├─ PhysicsServer2D::joint_set_param()
           │
           └─ PhysicsServer2D::joint_disable_collisions_between_bodies()

コンストラクタ: Joint2D::Joint2D()
    │
    └─ PhysicsServer2D::joint_create()
```

### データフロー図

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

node_a (NodePath) ──────▶ _update_joint()
node_b (NodePath)              │
                               ▼
                        get_node_or_null()
                               │
                               ▼
                        PhysicsBody2D A, B
                               │
                               ▼
                        _configure_joint()
                               │
                               ▼
                        PhysicsServer2D ──────▶ ジョイント制約
                               │
                               ▼
                        物理シミュレーション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| joint_2d.cpp | `scene/2d/physics/joints/joint_2d.cpp` | ソース | 2Dジョイント基底クラス |
| pin_joint_2d.cpp | `scene/2d/physics/joints/pin_joint_2d.cpp` | ソース | ピンジョイント |
| groove_joint_2d.cpp | `scene/2d/physics/joints/groove_joint_2d.cpp` | ソース | グルーブジョイント |
| damped_spring_joint_2d.cpp | `scene/2d/physics/joints/damped_spring_joint_2d.cpp` | ソース | バネジョイント |
| joint_3d.cpp | `scene/3d/physics/joints/joint_3d.cpp` | ソース | 3Dジョイント基底クラス |
| pin_joint_3d.cpp | `scene/3d/physics/joints/pin_joint_3d.cpp` | ソース | 3Dピンジョイント |
| hinge_joint_3d.cpp | `scene/3d/physics/joints/hinge_joint_3d.cpp` | ソース | ヒンジジョイント |
| slider_joint_3d.cpp | `scene/3d/physics/joints/slider_joint_3d.cpp` | ソース | スライダージョイント |
