# 機能設計書 60-CSG（構成立体幾何）

## 概要

本ドキュメントは、Godot EngineにおけるCSG（Constructive Solid Geometry：構成立体幾何）システムの設計を記載するものである。

### 本機能の処理概要

**業務上の目的・背景**：CSGは、複数のプリミティブ形状（ボックス、球、シリンダーなど）を組み合わせて複雑な3Dメッシュを生成するシステムである。ブーリアン演算（和集合、積集合、差集合）を用いて形状を結合・切り抜きし、プロトタイピングやレベルデザインに活用される。内部的にManifoldライブラリを使用して高精度なブーリアン演算を実現している。

**機能の利用シーン**：
- レベルデザインのプロトタイピング
- 建築物や構造物のモデリング
- 穴あき形状やくり抜き形状の作成
- 複合オブジェクトの生成

**主要な処理内容**：
1. プリミティブ形状（Box、Sphere、Cylinder、Torus、Polygon）の生成
2. ブーリアン演算（Union、Intersection、Subtraction）の適用
3. 階層構造による複合形状の構築
4. メッシュ生成とタンジェント計算
5. 物理コリジョンの自動生成
6. ナビゲーションメッシュパーシング対応

**関連システム・外部連携**：
- Manifoldライブラリ（ブーリアン演算エンジン）
- PhysicsServer3D（コリジョン処理）
- NavigationServer3D（経路探索）
- MikkTSpace（タンジェント計算）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 3Dビューポート | エディタ | CSG形状の配置・編集 |

## 機能種別

3Dゲームオブジェクト / シーンノード

## 入力仕様

### 共通プロパティ（CSGShape3D）

| プロパティ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| operation | Operation | No | ブーリアン演算タイプ | UNION/INTERSECTION/SUBTRACTION |
| calculate_tangents | Bool | No | タンジェント計算有効化 | - |
| use_collision | Bool | No | コリジョン生成有効化 | - |
| collision_layer | Int | No | コリジョンレイヤー | 1-32 |
| collision_mask | Int | No | コリジョンマスク | 1-32 |
| collision_priority | Float | No | コリジョン優先度 | - |

### CSGBox3Dプロパティ

| プロパティ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| size | Vector3 | No | ボックスサイズ | 正の値 |
| material | Material | No | マテリアル | - |

### CSGSphere3Dプロパティ

| プロパティ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| radius | Float | No | 球の半径 | 0より大きい |
| radial_segments | Int | No | 経線セグメント数 | 4以上 |
| rings | Int | No | 緯線リング数 | 1以上 |
| smooth_faces | Bool | No | スムースシェーディング | - |
| material | Material | No | マテリアル | - |

### CSGCylinder3Dプロパティ

| プロパティ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| radius | Float | No | シリンダー半径 | 正の値 |
| height | Float | No | シリンダー高さ | 正の値 |
| sides | Int | No | 側面セグメント数 | 3以上 |
| cone | Bool | No | コーン形状有効化 | - |
| smooth_faces | Bool | No | スムースシェーディング | - |
| material | Material | No | マテリアル | - |

### メソッド入力

| メソッド名 | パラメータ | 説明 |
|-----------|-----------|------|
| is_root_shape | - | ルート形状かどうか判定 |
| get_meshes | - | 生成されたメッシュを取得 |
| bake_static_mesh | - | 静的メッシュとしてベイク |
| bake_collision_shape | - | コリジョン形状をベイク |
| get_brush_faces | - | ブラシの面データを取得 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 生成メッシュ | ArrayMesh | CSG結果のメッシュ |
| コリジョン形状 | ConcavePolygonShape3D | 物理衝突形状 |
| ブラシデータ | CSGBrush | 内部ブラシデータ |

## 処理フロー

### 処理シーケンス

```
1. ブラシ生成（_build_brush）
   └─ プリミティブ形状ごとの頂点・面データ生成
2. Manifoldへのパック
   └─ CSGBrushをManifold形式に変換
3. 子ノードの処理
   └─ 子CSGShape3Dのブラシを再帰的に取得
4. ブーリアン演算（BatchBoolean）
   └─ 同一演算タイプをバッチ処理
5. Manifoldからのアンパック
   └─ 結果をCSGBrushに変換
6. メッシュ生成（update_shape）
   └─ 頂点配列とタンジェント計算
7. コリジョン更新
   └─ ConcavePolygonShape3Dの更新
```

### フローチャート

```mermaid
flowchart TD
    A[_make_dirty呼び出し] --> B{is_root_shape?}
    B -->|No| C[親のdirty設定]
    B -->|Yes| D[update_shape呼び出し]
    D --> E[_get_brush]
    E --> F[_build_brush]
    F --> G[_pack_manifold]
    G --> H{子ノードあり?}
    H -->|Yes| I[子のブラシ取得]
    I --> J[変換・パック]
    J --> K[BatchBoolean]
    H -->|No| K
    K --> L[_unpack_manifold]
    L --> M[メッシュ配列生成]
    M --> N[MikkTSpaceタンジェント計算]
    N --> O[ArrayMesh生成]
    O --> P[コリジョン更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-60-01 | ルート形状のみ描画 | 子CSGShape3Dは単独で描画されない | 常時 |
| BR-60-02 | マニフォールドメッシュ要件 | メッシュは閉じた多様体である必要がある | 常時 |
| BR-60-03 | 演算順序 | 同一演算タイプはバッチ処理、異なる場合は順次処理 | 常時 |
| BR-60-04 | コリジョンはルートのみ | コリジョン設定はルート形状でのみ有効 | 常時 |

### 計算ロジック

ブーリアン演算タイプ:
```
OPERATION_UNION: 和集合（形状を結合）→ manifold::OpType::Add
OPERATION_INTERSECTION: 積集合（共通部分）→ manifold::OpType::Intersect
OPERATION_SUBTRACTION: 差集合（くり抜き）→ manifold::OpType::Subtract
```

球の面数計算:
```
face_count = rings * radial_segments * 2 - radial_segments * 2
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | メッシュが空 | マニフォールドメッシュを使用 |
| - | 警告 | メッシュがマニフォールドでない | 穴やギャップのないメッシュを使用 |
| ERR_INVALID_PARAMETER | パラメータ不正 | radiusが0以下 | 正の値を指定 |
| ERR_FAIL_COND | 条件不正 | コリジョンレイヤーが範囲外 | 1-32の範囲を指定 |

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

即時反映。トランザクション管理なし。

## パフォーマンス要件

- Manifoldライブラリによる高速ブーリアン演算
- バッチ処理による複数演算の最適化
- dirty flagによる不要な再計算の回避
- 遅延呼び出し（call_deferred）による更新最適化

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

特になし。

## 備考

- Manifoldライブラリを使用（外部依存）
- CSGはプロトタイピング向け、最終的にはbake_static_meshでメッシュ化推奨
- 非マニフォールドメッシュ（PlaneMesh、QuadMeshなど）はCSGMesh3Dで使用不可

---

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

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

### 推奨読解順序

#### Step 1: 基本クラス構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | csg_shape.h | `modules/csg/csg_shape.h` | CSGShape3Dクラス定義、Operation列挙型 |

**読解のコツ**: CSGShape3Dが基底クラスで、CSGPrimitive3D、CSGCombiner3D、CSGMesh3Dが派生クラス。parent_shapeで親子関係を管理。

#### Step 2: ブーリアン演算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | csg_shape.cpp | `modules/csg/csg_shape.cpp` | _get_brush、_pack_manifold、_unpack_manifold関数 |

**主要処理フロー**:
- **238-247行目**: ManifoldProperty列挙型（頂点プロパティ定義）
- **249-299行目**: _unpack_manifold関数（Manifold→CSGBrush変換）
- **367-432行目**: _pack_manifold関数（CSGBrush→Manifold変換）
- **434-451行目**: ManifoldOperation構造体と演算タイプ変換
- **453-512行目**: _get_brush関数（ブラシ取得とブーリアン演算）

#### Step 3: メッシュ生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | csg_shape.cpp | `modules/csg/csg_shape.cpp` | update_shape関数 |

**主要処理フロー**:
- **568-734行目**: update_shape関数でメッシュ生成
- **514-566行目**: MikkTSpace関数群（タンジェント計算）
- **690-727行目**: サーフェス配列生成とArrayMesh作成

#### Step 4: コリジョン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | csg_shape.cpp | `modules/csg/csg_shape.cpp` | コリジョン関連関数 |

**主要処理フロー**:
- **85-118行目**: set_use_collision関数
- **745-765行目**: _get_brush_collision_faces関数
- **767-775行目**: _update_collision_faces関数
- **777-787行目**: bake_collision_shape関数

#### Step 5: プリミティブ形状を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | csg_shape.cpp | `modules/csg/csg_shape.cpp` | CSGBox3D、CSGSphere3D、CSGCylinder3Dの_build_brush |

**主要処理フロー**:
- **1324-1453行目**: CSGSphere3D::_build_brush（球形状生成）
- **1536-1599行目**: CSGBox3D::_build_brush（ボックス形状生成）
- **1125-1270行目**: CSGMesh3D::_build_brush（メッシュからブラシ生成）

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

```
CSGShape3D
    │
    ├─ _make_dirty
    │      └─ update_shape.call_deferred（ルート形状の場合）
    │
    ├─ update_shape（ルート形状のみ）
    │      ├─ _get_brush
    │      │      ├─ _build_brush（派生クラスで実装）
    │      │      ├─ _pack_manifold
    │      │      │      └─ manifold::MeshGL64構築
    │      │      ├─ 子ノード処理
    │      │      │      ├─ child->_get_brush
    │      │      │      └─ _pack_manifold
    │      │      ├─ manifold::BatchBoolean
    │      │      └─ _unpack_manifold
    │      │             └─ CSGBrush::Face生成
    │      │
    │      ├─ スムースグループ計算
    │      ├─ サーフェス配列構築
    │      ├─ MikkTSpace::genTangSpaceDefault
    │      ├─ ArrayMesh::add_surface_from_arrays
    │      └─ _update_collision_faces
    │             └─ ConcavePolygonShape3D::set_faces
    │
    ├─ CSGPrimitive3D（派生）
    │      └─ _create_brush_from_arrays
    │
    ├─ CSGBox3D（派生）
    │      └─ _build_brush（12面のボックス）
    │
    ├─ CSGSphere3D（派生）
    │      └─ _build_brush（rings * radial_segments）
    │
    ├─ CSGCylinder3D（派生）
    │      └─ _build_brush（sides * 4 + sides * 2）
    │
    └─ CSGMesh3D（派生）
           └─ _build_brush（Meshから変換）
```

### データフロー図

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

プリミティブパラメータ ────▶ _build_brush ─────────────────▶ CSGBrush

CSGBrush ─────────────────▶ _pack_manifold ────────────────▶ manifold::Manifold

子CSGShape3D ─────────────▶ ブラシ取得・変換 ──────────────▶ manifold::Manifold[]

manifold::Manifold[] ─────▶ BatchBoolean ──────────────────▶ 結果Manifold

結果Manifold ─────────────▶ _unpack_manifold ──────────────▶ CSGBrush

CSGBrush ─────────────────▶ update_shape ──────────────────▶ ArrayMesh
                                                              ConcavePolygonShape3D
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| csg_shape.cpp | `modules/csg/csg_shape.cpp` | ソース | CSGShape3D本体・プリミティブ |
| csg_shape.h | `modules/csg/csg_shape.h` | ヘッダ | クラス定義 |
| csg.cpp | `modules/csg/csg.cpp` | ソース | CSGBrushクラス |
| csg.h | `modules/csg/csg.h` | ヘッダ | CSGBrush定義 |
| manifold.h | 外部ライブラリ | ヘッダ | Manifoldブーリアン演算 |
| csg_gizmos.cpp | `modules/csg/csg_gizmos.cpp` | ソース | エディタギズモ |
