# 機能設計書 75-Mesh

## 概要

本ドキュメントは、Three.jsライブラリにおけるMesh（メッシュ）機能の設計を記述する。MeshはBufferGeometryとMaterialを組み合わせた三角形ポリゴンベースの3Dオブジェクトであり、Three.jsにおける最も基本的で重要なレンダリング可能オブジェクトである。

### 本機能の処理概要

Meshは、ジオメトリ（頂点データ）とマテリアル（表面特性）を組み合わせて3Dオブジェクトを表現するクラスである。レイキャスティングによる交差判定、モーフターゲットアニメーション、マルチマテリアル対応など、3Dオブジェクトの基本的な機能を提供する。

**業務上の目的・背景**：3Dグラフィックスにおいて、ポリゴンメッシュはオブジェクトを表現する最も一般的な方法である。Meshクラスは、ジオメトリとマテリアルを統合し、シーングラフへの配置、レンダリング、インタラクション（レイキャスト）を可能にする。Three.jsのあらゆる3Dアプリケーションにおいて中核的な役割を果たす。

**機能の利用シーン**：3Dモデルの表示、ゲームオブジェクトの作成、建築ビジュアライゼーション、製品モデリング、インタラクティブな3Dアプリケーション、VR/ARコンテンツ制作。

**主要な処理内容**：
1. ジオメトリ（BufferGeometry）とマテリアル（Material）の管理
2. レイキャスティングによる三角形との交差判定
3. モーフターゲットの検出と影響度管理
4. マルチマテリアル対応（マテリアル配列）
5. 頂点位置の取得（モーフ考慮）

**関連システム・外部連携**：WebGLRenderer/WebGPURenderer、Raycaster、BufferGeometry、各種Material、AnimationMixer（モーフアニメーション）。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | Menubar - Add | 主機能 | メッシュオブジェクトの追加 |
| 27 | 物理シミュレーション | 補助機能 | 物理メッシュオブジェクト |

## 機能種別

3Dオブジェクト生成 / レンダリング対象

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| geometry | BufferGeometry | No | メッシュのジオメトリ（デフォルト: 新規BufferGeometry） | BufferGeometry型 |
| material | Material/Array<Material> | No | メッシュのマテリアル（デフォルト: 新規MeshBasicMaterial） | Material型または配列 |

### 入力データソース

- JavaScriptコードからのコンストラクタ呼び出し
- ObjectLoaderによるJSONファイルからの読み込み
- GLTFLoader等による3Dモデルのインポート

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isMesh | boolean | 型識別フラグ（常にtrue） |
| type | string | オブジェクト種別（'Mesh'） |
| geometry | BufferGeometry | メッシュのジオメトリ |
| material | Material/Array<Material> | メッシュのマテリアル |
| morphTargetDictionary | Object | モーフターゲット名とインデックスのマッピング |
| morphTargetInfluences | Array<number> | モーフターゲットの影響度配列 |
| count | number | インスタンス数（WebGPU用、デフォルト: 1） |

### 出力先

3Dシーングラフ、WebGLレンダリングパイプライン

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ Object3Dの初期化
2. geometryとmaterialの設定
3. モーフターゲットの更新
   └─ updateMorphTargets()の呼び出し
4. レイキャスト時
   └─ 境界球テスト -> 境界ボックステスト -> 三角形交差判定
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Object3Dコンストラクタ]
    B --> C[isMesh = true]
    C --> D[geometry設定]
    D --> E[material設定]
    E --> F[updateMorphTargets]
    F --> G[終了]

    H[raycast] --> I{境界球テスト}
    I -->|通過| J{境界ボックステスト}
    I -->|失敗| K[終了]
    J -->|通過| L[三角形交差判定]
    J -->|失敗| K
    L --> M[交差点を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-1 | マルチマテリアル | geometryのgroupsに基づいてマテリアルを切り替え | material配列使用時 |
| BR-75-2 | モーフターゲット自動検出 | ジオメトリのmorphAttributesから自動的にモーフターゲットを検出 | コンストラクタ/ジオメトリ変更時 |
| BR-75-3 | 境界判定の最適化 | raycastは境界球->境界ボックス->三角形の順で判定 | 常時 |

### 計算ロジック

**レイキャスト交差判定**：
1. 境界球をワールド空間に変換し、レイとの交差をテスト
2. 境界ボックスとレイの交差をテスト（ローカル空間）
3. インデックス付きジオメトリの場合、三角形ごとに交差判定
4. 交差点の距離、位置、UV座標、法線、面情報を返却

**頂点位置取得（モーフ考慮）**：
```javascript
// morphTargetsRelative = true の場合
target = basePosition + sum(morphInfluences[i] * morphDelta[i])

// morphTargetsRelative = false の場合
target = basePosition + sum(morphInfluences[i] * (morphPosition[i] - basePosition))
```

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 表示異常 | materialがundefined | raycastでスキップ |
| - | パフォーマンス低下 | 境界球/ボックス未計算 | 自動計算が実行される |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- メッシュの生成は即座に完了すること
- レイキャストは境界判定で早期リターンを行い、不要な三角形判定を回避
- モーフターゲット数に応じてメモリ使用量が増加

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

特になし。

## 備考

- WebGPURendererでは、countプロパティを使用してインスタンス描画数を設定可能
- マルチマテリアル使用時は、ジオメトリのgroupsを適切に設定する必要がある
- モーフターゲットの名前は、BufferAttribute.nameプロパティで設定

---

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

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

### 推奨読解順序

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

Meshが持つプロパティの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BufferGeometry.js | `src/core/BufferGeometry.js` | ジオメトリの構造 |
| 1-2 | Material.js | `src/materials/Material.js` | マテリアルの基底クラス |
| 1-3 | MeshBasicMaterial.js | `src/materials/MeshBasicMaterial.js` | デフォルトマテリアル |

**読解のコツ**: geometryはattributes（position, normal, uv等）とindex（インデックスバッファ）で構成される。

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

Meshクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Mesh.js | `src/objects/Mesh.js` | クラス全体の構造 |

**主要処理フロー**:
1. **47行目**: コンストラクタでgeometryとmaterialを受け取る
2. **58行目**: isMeshフラグの設定
3. **67行目**: geometryの設定
4. **75行目**: materialの設定
5. **106行目**: updateMorphTargets()の呼び出し

#### Step 3: レイキャスト処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Mesh.js | `src/objects/Mesh.js` | raycast()（226-270行目） |
| 3-2 | Mesh.js | `src/objects/Mesh.js` | _computeIntersections()（272-405行目） |
| 3-3 | Mesh.js | `src/objects/Mesh.js` | checkGeometryIntersection()（440-493行目） |

**主要処理フロー**:
- **236-237行目**: 境界球の計算と取得
- **243行目**: レイの再キャスト（near距離考慮）
- **245-250行目**: 境界球との交差判定
- **260-262行目**: 境界ボックスとの交差判定
- **268行目**: _computeIntersections()の呼び出し

#### Step 4: モーフターゲット処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Mesh.js | `src/objects/Mesh.js` | updateMorphTargets()（137-166行目） |
| 4-2 | Mesh.js | `src/objects/Mesh.js` | getVertexPosition()（176-218行目） |

**主要処理フロー**:
- **141-142行目**: morphAttributesからキーを取得
- **150-151行目**: morphTargetInfluencesとmorphTargetDictionaryの初期化
- **183-186行目**: 頂点位置へのモーフ影響の適用

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

```
Mesh
    │
    ├─ extends Object3D
    │      └─ extends EventDispatcher
    │
    ├─ uses BufferGeometry
    │      ├─ attributes (position, normal, uv, ...)
    │      ├─ index
    │      └─ morphAttributes
    │
    └─ uses Material (or Array<Material>)
           └─ MeshBasicMaterial (default)

Mesh.raycast()
    │
    ├─ geometry.computeBoundingSphere()
    ├─ _ray.intersectSphere()
    ├─ _ray.intersectsBox()
    └─ _computeIntersections()
           ├─ checkGeometryIntersection()
           │      └─ checkIntersection()
           └─ getVertexPosition()
```

### データフロー図

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

geometry (引数) ──────────────▶ 直接代入 ───────────────────────▶ this.geometry
material (引数) ──────────────▶ 直接代入 ───────────────────────▶ this.material

Raycaster.ray ────────────────▶ raycast() ─────────────────────▶ intersects[]
                               │
                               ├─ 境界球テスト
                               ├─ 境界ボックステスト
                               └─ 三角形交差判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Mesh.js | `src/objects/Mesh.js` | ソース | メッシュクラスの実装 |
| Object3D.js | `src/core/Object3D.js` | ソース | 3Dオブジェクトの基底クラス |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | ジオメトリデータ管理 |
| Material.js | `src/materials/Material.js` | ソース | マテリアルの基底クラス |
| MeshBasicMaterial.js | `src/materials/MeshBasicMaterial.js` | ソース | デフォルトマテリアル |
| Triangle.js | `src/math/Triangle.js` | ソース | 三角形計算（交差判定） |
| Ray.js | `src/math/Ray.js` | ソース | レイ計算 |
| Sphere.js | `src/math/Sphere.js` | ソース | 境界球 |
