# 機能設計書 15-3D物理シミュレーション

## 概要

本ドキュメントは、Godotエンジンにおける3D物理シミュレーション機能の設計仕様を記述する。3D物理シミュレーションは、RigidBody3D、StaticBody3D、CharacterBody3D、Area3Dなどの物理ボディを使用して、3D空間での重力、衝突、反発などの物理挙動をシミュレートする機能である。

### 本機能の処理概要

**業務上の目的・背景**：3Dゲーム開発において、リアルな物理挙動をシミュレートすることは、ゲームプレイの面白さと没入感を高める。本機能は、3D空間での物体の落下、衝突、積み重ね、投擲などの物理挙動を提供し、FPSやTPS、シミュレーションゲームなど幅広いジャンルに対応する。

**機能の利用シーン**：
- FPS/TPSゲームのキャラクター移動と衝突
- 物理パズルゲームでのオブジェクト操作
- 車両や航空機のシミュレーション
- 破壊可能な環境の実装
- ラグドール物理

**主要な処理内容**：
1. PhysicsServer3Dによる物理ワールド管理
2. 6軸（X/Y/Z移動、X/Y/Z回転）の軸ロック機能
3. 衝突検出と応答処理（複数衝突対応）
4. 重力と外力の適用
5. move_and_collideによるキネマティック移動
6. test_moveによる衝突テスト

**関連システム・外部連携**：
- PhysicsServer3D：物理エンジンのサーバーサイド実装
- CollisionObject3D：衝突オブジェクトの基底クラス
- CollisionShape3D/CollisionPolygon3D：衝突形状定義

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | 3Dエディタ | 主画面 | 3D物理ノードのプレビュー・デバッグ表示 |

## 機能種別

物理シミュレーション / ゲームプレイロジック

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| motion | Vector3 | Yes | 移動ベクトル | - |
| test_only | bool | No | テストのみ実行（位置更新しない） | - |
| safe_margin | float | No | 衝突マージン（デフォルト: 0.001） | 0以上 |
| recovery_as_collision | bool | No | 回復をコリジョンとして扱う | - |
| max_collisions | int | No | 最大衝突数（デフォルト: 1） | 1以上 |

### 入力データソース

- スクリプトからの直接呼び出し（move_and_collide、apply_force等）
- PhysicsServer3Dによる自動シミュレーション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| collision | KinematicCollision3D | 衝突情報（衝突点、法線、衝突対象） |
| travel | Vector3 | 実際の移動量 |
| remainder | Vector3 | 残りの移動量 |
| collided | bool | 衝突したかどうか |

### 出力先

- 物理ボディの位置・回転
- シグナル発行（body_entered、body_exited等）

## 処理フロー

### 処理シーケンス

```
1. PhysicsServer3Dが物理ステップを開始
   └─ _physics_process呼び出し
2. 各物理ボディの状態を更新
   └─ 速度、位置、回転の計算
3. 軸ロック処理
   └─ ロックされた軸の移動/回転を制限
4. 衝突検出
   └─ ブロードフェーズ→ナローフェーズ
5. 衝突応答
   └─ 反発、摩擦、penetration解決
6. シグナル発行
   └─ body_entered、body_exited等
```

### フローチャート

```mermaid
flowchart TD
    A[move_and_collide呼び出し] --> B[MotionParameters作成]
    B --> C[PhysicsServer3D::body_test_motion]
    C --> D{衝突あり?}
    D -->|Yes| E[スライディング処理]
    D -->|No| F[全移動量を適用]
    E --> G[軸ロック処理]
    F --> G
    G --> H[衝突情報を構築]
    H --> I{test_only?}
    I -->|Yes| J[位置更新をスキップ]
    I -->|No| K[set_global_transform]
    J --> L[KinematicCollision3Dを返す]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 軸ロック | 6軸それぞれに対してロック可能（LINEAR_X/Y/Z、ANGULAR_X/Y/Z） | set_axis_lock設定時 |
| BR-02 | 複数衝突対応 | max_collisionsパラメータで複数衝突を検出可能 | 3D固有機能 |
| BR-03 | 衝突例外 | CollisionObject3D間で衝突を無視可能 | 明示的に設定した場合 |

### 計算ロジック

軸ロック処理:
```cpp
for (int i = 0; i < 3; i++) {
    if (locked_axis & (1 << i)) {
        r_result.travel[i] = 0;
    }
}
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | 物理補間未有効時 | physics_interpolation_modeを確認 |
| - | エラー | シーンツリー外でtest_move呼び出し | is_inside_tree()がfalse |

### リトライ仕様

なし

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

なし

## パフォーマンス要件

- 物理シミュレーションは固定フレームレート（デフォルト60Hz）で実行
- 衝突検出はブロードフェーズ（空間分割）で高速化
- 2Dと比較して計算コストが高いため、オブジェクト数に注意

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

特になし

## 備考

- safe_marginのデフォルト値: 3D=0.001、2D=0.08（3Dの方が精度が高い）
- 軸ロックフラグ: BODY_AXIS_LINEAR_X(1), Y(2), Z(4), ANGULAR_X(8), Y(16), Z(32)

---

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

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

### 推奨読解順序

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

物理ボディの階層構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | collision_object_3d.h | `scene/3d/physics/collision_object_3d.h` | 衝突オブジェクト基底クラス |
| 1-2 | physics_body_3d.h | `scene/3d/physics/physics_body_3d.h` | PhysicsBody3Dの定義 |
| 1-3 | kinematic_collision_3d.h | `scene/3d/physics/kinematic_collision_3d.h` | 衝突情報の構造 |

**読解のコツ**: 2Dとほぼ同じ構造だが、3D固有の軸ロック機能とmax_collisions対応がある。

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

move_and_collide関数の実装を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | physics_body_3d.cpp | `scene/3d/physics/physics_body_3d.cpp` | PhysicsBody3Dの実装 |

**主要処理フロー**:
1. **87-107行目**: _move関数（move_and_collideのラッパー）
2. **109-163行目**: move_and_collide本体実装
3. **110行目**: PhysicsServer3D::body_test_motion呼び出し
4. **150-154行目**: 軸ロック処理（3D固有）
5. **156-160行目**: 位置更新処理

#### Step 3: 軸ロック機能を理解する

3D固有の軸ロック機能を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | physics_body_3d.cpp | `scene/3d/physics/physics_body_3d.cpp` | set_axis_lock/get_axis_lock |

**主要処理フロー**:
- **38-52行目**: 軸ロックプロパティのバインド
- **189-200行目**: set_axis_lock/get_axis_lock実装

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

```
PhysicsBody3D::move_and_collide()
    │
    ├─ PhysicsServer3D::MotionParameters作成
    │
    ├─ PhysicsServer3D::body_test_motion()
    │      │
    │      └─ 内部で衝突検出実行
    │
    ├─ cancel_sliding処理（オプション）
    │
    ├─ 軸ロック処理（3D固有）
    │
    └─ set_global_transform()
```

### データフロー図

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

move_and_collide()
       │
       ▼
MotionParameters ──────▶ PhysicsServer3D
  - from                      │
  - motion                    ▼
  - margin              body_test_motion()
  - max_collisions            │
                              ▼
                       MotionResult ──────▶ KinematicCollision3D
                         - travel              - collision_point
                         - remainder           - collision_normal
                         - collisions[]        - collider
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| physics_body_3d.cpp | `scene/3d/physics/physics_body_3d.cpp` | ソース | PhysicsBody3D基底クラス |
| rigid_body_3d.cpp | `scene/3d/physics/rigid_body_3d.cpp` | ソース | 動的物理ボディ |
| static_body_3d.cpp | `scene/3d/physics/static_body_3d.cpp` | ソース | 静的物理ボディ |
| character_body_3d.cpp | `scene/3d/physics/character_body_3d.cpp` | ソース | キャラクター用ボディ |
| area_3d.cpp | `scene/3d/physics/area_3d.cpp` | ソース | トリガーエリア |
| collision_object_3d.cpp | `scene/3d/physics/collision_object_3d.cpp` | ソース | 衝突オブジェクト基底 |
| kinematic_collision_3d.cpp | `scene/3d/physics/kinematic_collision_3d.cpp` | ソース | 衝突情報クラス |
