# 機能設計書 1-Object3D

## 概要

本ドキュメントは、Three.jsライブラリにおける3Dオブジェクトの基底クラスであるObject3Dの機能設計について記述する。Object3Dは、3D空間におけるオブジェクトの位置、回転、スケールの管理、親子関係の構築、およびシーングラフの走査機能を提供する中核的なクラスである。

### 本機能の処理概要

Object3Dクラスは、Three.jsにおけるほぼすべての3Dオブジェクト（Mesh、Camera、Light、Groupなど）の基底クラスとして機能し、3D空間における物体の配置と階層構造の管理を担う。

**業務上の目的・背景**：3Dグラフィックスアプリケーションでは、複数のオブジェクトを階層的に管理し、それぞれの空間的な位置関係を正確に制御する必要がある。Object3Dは、この複雑な要件を抽象化し、開発者が直感的に3Dシーンを構築できるようにするための基盤を提供する。例えば、車のモデルでは車体を親オブジェクトとし、タイヤを子オブジェクトとすることで、車体が移動すればタイヤも自動的に追従する階層構造を実現できる。

**機能の利用シーン**：
- 3Dエディタでオブジェクトの位置・回転・スケールを編集する場面
- シーングラフ内でオブジェクトの親子関係を構築・変更する場面
- レンダリング時にワールド座標系での変換行列を計算する場面
- マウスピッキングでオブジェクトを選択する場面
- アニメーション再生時にオブジェクトの変換を適用する場面

**主要な処理内容**：
1. **変換管理**: position、rotation、quaternion、scaleプロパティによるローカル座標系での変換管理
2. **行列計算**: matrix（ローカル変換行列）とmatrixWorld（ワールド変換行列）の自動計算
3. **階層構造**: add()、remove()、attach()メソッドによる親子関係の構築と管理
4. **シーングラフ走査**: traverse()、traverseVisible()、traverseAncestors()による階層構造の走査
5. **オブジェクト検索**: getObjectById()、getObjectByName()、getObjectByProperty()による子孫オブジェクトの検索
6. **イベント通知**: EventDispatcherを継承し、added、removed、childadded、childremovedイベントを発行
7. **シリアライズ**: toJSON()メソッドによるJSON形式でのシリアライズ

**関連システム・外部連携**：
- EventDispatcherクラスを継承し、イベント駆動型の通知機能を利用
- Layersクラスによるレンダリングレイヤーの管理
- Vector3、Matrix4、Quaternion、Eulerなどの数学クラスとの連携
- WebGLRenderer/WebGPURendererによるレンダリング時のワールド行列参照

**権限による制御**：特になし（ライブラリレベルの機能のため、アプリケーション側での権限管理は行わない）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | Sidebar - Object | 主機能 | 選択オブジェクトの位置・回転・スケール編集 |
| 11 | Menubar - Edit | 主機能 | オブジェクトのクローン・削除操作 |
| 16 | Toolbar | 主機能 | 変形ツール（移動・回転・スケール）の制御 |
| 27 | 物理シミュレーション | 主機能 | 物理演算対象オブジェクトの管理 |
| 28 | CSS3Dサンプル | 主機能 | CSS3D要素の3D配置 |
| 29 | CSS2Dサンプル | 主機能 | 2Dラベルの配置管理 |
| 30 | SVGサンプル | 主機能 | SVG要素の3D配置 |
| 40 | ユニットテスト | 主機能 | Object3Dクラスのテスト |

## 機能種別

オブジェクト管理 / 変換処理 / 階層構造管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| position | Vector3 | No | オブジェクトのローカル位置 | デフォルト: (0, 0, 0) |
| rotation | Euler | No | オイラー角での回転 | デフォルト: (0, 0, 0, 'XYZ') |
| quaternion | Quaternion | No | 四元数での回転 | rotationと相互同期 |
| scale | Vector3 | No | スケール | デフォルト: (1, 1, 1) |
| up | Vector3 | No | 上方向ベクトル | デフォルト: (0, 1, 0) |
| visible | boolean | No | 可視性フラグ | デフォルト: true |
| castShadow | boolean | No | 影を投影するか | デフォルト: false |
| receiveShadow | boolean | No | 影を受けるか | デフォルト: false |
| frustumCulled | boolean | No | 視錐台カリング対象か | デフォルト: true |
| renderOrder | number | No | レンダリング順序 | デフォルト: 0 |
| layers | Layers | No | レイヤーマスク | デフォルト: layer 0 |

### 入力データソース

- アプリケーションコードからの直接設定
- JSONファイルからのデシリアライズ（ObjectLoader経由）
- エディタUIからのユーザー入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| matrix | Matrix4 | ローカル変換行列 |
| matrixWorld | Matrix4 | ワールド変換行列 |
| modelViewMatrix | Matrix4 | モデルビュー行列（レンダラーが設定） |
| normalMatrix | Matrix3 | 法線行列（レンダラーが設定） |
| children | Array<Object3D> | 子オブジェクトの配列 |
| parent | Object3D | 親オブジェクトへの参照 |
| id | number | 一意のID（自動採番） |
| uuid | string | UUID |

### 出力先

- レンダラー（WebGLRenderer/WebGPURenderer）への行列データ提供
- シリアライズ時のJSONオブジェクト
- イベントリスナーへのイベントオブジェクト

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ EventDispatcherの初期化
   └─ プロパティの初期化（position, rotation, quaternion, scale）
   └─ rotation/quaternionの相互同期コールバック設定
   └─ matrix, matrixWorldの初期化
   └─ Layersインスタンスの生成

2. 変換操作（position/rotation/scale変更）
   └─ プロパティ値の更新
   └─ matrixWorldNeedsUpdate = true の設定

3. updateMatrix() 呼び出し
   └─ matrix.compose(position, quaternion, scale)
   └─ pivot補正の適用（pivotが設定されている場合）
   └─ matrixWorldNeedsUpdate = true

4. updateMatrixWorld() 呼び出し
   └─ matrixAutoUpdateがtrueならupdateMatrix()
   └─ 親がある場合: matrixWorld = parent.matrixWorld * matrix
   └─ 親がない場合: matrixWorld = matrix
   └─ 子オブジェクトに対して再帰的にupdateMatrixWorld()

5. 親子関係操作（add/remove）
   └─ 子オブジェクトのparent更新
   └─ children配列の更新
   └─ イベント発行（added/removed/childadded/childremoved）
```

### フローチャート

```mermaid
flowchart TD
    A[Object3D生成] --> B[プロパティ初期化]
    B --> C{変換操作?}
    C -->|Yes| D[position/rotation/scale更新]
    D --> E[matrixWorldNeedsUpdate = true]
    E --> C
    C -->|No| F{レンダリング?}
    F -->|Yes| G[updateMatrixWorld]
    G --> H{matrixAutoUpdate?}
    H -->|Yes| I[updateMatrix]
    I --> J[matrix = compose]
    H -->|No| J
    J --> K{親あり?}
    K -->|Yes| L[matrixWorld = parent * matrix]
    K -->|No| M[matrixWorld = matrix]
    L --> N[子オブジェクトを再帰処理]
    M --> N
    N --> F
    F -->|No| O{階層操作?}
    O -->|Yes| P[add/remove/attach]
    P --> Q[parent/children更新]
    Q --> R[イベント発行]
    R --> O
    O -->|No| C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 単一親制約 | オブジェクトは同時に1つの親しか持てない | add()実行時 |
| BR-02 | 自己参照禁止 | オブジェクトを自分自身の子にできない | add()実行時 |
| BR-03 | rotation/quaternion同期 | rotationを変更するとquaternionも自動更新、逆も同様 | 常時 |
| BR-04 | ワールド行列自動更新 | matrixWorldAutoUpdateがtrueの場合、レンダリング時に自動計算 | updateMatrixWorld()実行時 |
| BR-05 | レイヤー継承なし | 子オブジェクトは親のレイヤー設定を継承しない | レンダリング時 |

### 計算ロジック

**ローカル変換行列の計算:**
```
matrix = compose(position, quaternion, scale)
```

**ピボット補正（pivotが設定されている場合）:**
```
te[12] += px - te[0]*px - te[4]*py - te[8]*pz
te[13] += py - te[1]*px - te[5]*py - te[9]*pz
te[14] += pz - te[2]*px - te[6]*py - te[10]*pz
```

**ワールド変換行列の計算:**
```
if (parent === null) {
    matrixWorld = matrix
} else {
    matrixWorld = parent.matrixWorld * matrix
}
```

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

### 操作別データベース影響一覧

該当なし（Object3Dはデータベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | add()で自分自身を追加しようとした場合 | コンソールに警告出力、処理は無視 |
| - | 警告 | add()でObject3D以外を追加しようとした場合 | コンソールに警告出力、処理は無視 |

### リトライ仕様

該当なし

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

該当なし（メモリ上のオブジェクト操作のみ）

## パフォーマンス要件

- updateMatrixWorld()は各フレームで呼び出されるため、高速に実行される必要がある
- matrixAutoUpdate/matrixWorldAutoUpdateをfalseに設定することで、静的オブジェクトの行列計算をスキップ可能
- staticプロパティをtrueに設定することで、WebGPURendererでの最適化が有効になる

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

該当なし（クライアントサイドのグラフィックスライブラリ）

## 備考

- r183以降、Clockクラスは非推奨となり、Timerクラスの使用が推奨される
- pivotプロパティはr173で追加された比較的新しい機能

---

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

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

### 推奨読解順序

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

Object3Dが使用する数学クラスの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Vector3.js | `src/math/Vector3.js` | 3次元ベクトルの構造と演算メソッド |
| 1-2 | Quaternion.js | `src/math/Quaternion.js` | 四元数による回転表現 |
| 1-3 | Euler.js | `src/math/Euler.js` | オイラー角による回転表現、Quaternionとの相互変換 |
| 1-4 | Matrix4.js | `src/math/Matrix4.js` | 4x4変換行列の構造とcompose/decomposeメソッド |

**読解のコツ**: Object3Dのposition, rotation, quaternion, scaleプロパティは、それぞれVector3, Euler, Quaternion, Vector3のインスタンス。これらの相互作用を理解することが重要。

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

Object3Dクラスの基本構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Object3D.js | `src/core/Object3D.js` | コンストラクタでのプロパティ初期化 |

**主要処理フロー**:
1. **69-388行目**: コンストラクタ - すべてのプロパティ初期化
2. **140-155行目**: rotation/quaternion相互同期のコールバック設定
3. **89行目**: 自動採番ID生成
4. **97行目**: UUID生成

#### Step 3: 変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Object3D.js | `src/core/Object3D.js` | updateMatrix(), updateMatrixWorld()メソッド |

**主要処理フロー**:
- **1131-1150行目**: updateMatrix() - ローカル行列の計算とピボット補正
- **1163-1201行目**: updateMatrixWorld() - ワールド行列の再帰計算
- **1210-1252行目**: updateWorldMatrix() - 親子を選択的に更新

#### Step 4: 階層構造管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Object3D.js | `src/core/Object3D.js` | add(), remove(), attach()メソッド |

**主要処理フロー**:
- **744-785行目**: add() - 子オブジェクトの追加とイベント発行
- **796-827行目**: remove() - 子オブジェクトの削除とイベント発行
- **872-906行目**: attach() - ワールド座標を維持した子追加

#### Step 5: イベントシステムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | EventDispatcher.js | `src/core/EventDispatcher.js` | イベント発行・購読の基盤 |

**主要処理フロー**:
- **31-49行目**: addEventListener() - リスナー登録
- **74-94行目**: removeEventListener() - リスナー解除
- **101-126行目**: dispatchEvent() - イベント発行

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

```
Object3D (extends EventDispatcher)
    │
    ├─ constructor()
    │      ├─ super() → EventDispatcher
    │      ├─ Vector3() × 2 (position, scale)
    │      ├─ Euler() (rotation)
    │      ├─ Quaternion() (quaternion)
    │      ├─ Matrix4() × 2 (matrix, matrixWorld)
    │      ├─ Matrix3() (normalMatrix)
    │      └─ Layers()
    │
    ├─ updateMatrix()
    │      └─ matrix.compose(position, quaternion, scale)
    │
    ├─ updateMatrixWorld()
    │      ├─ updateMatrix() [if matrixAutoUpdate]
    │      ├─ matrixWorld.copy(matrix) [if no parent]
    │      ├─ matrixWorld.multiplyMatrices() [if has parent]
    │      └─ children[].updateMatrixWorld() [recursive]
    │
    ├─ add(object)
    │      ├─ object.removeFromParent()
    │      ├─ children.push(object)
    │      ├─ dispatchEvent('added')
    │      └─ dispatchEvent('childadded')
    │
    └─ traverse(callback)
           ├─ callback(this)
           └─ children[].traverse(callback) [recursive]
```

### データフロー図

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

position ─────┐
              │
rotation ────┼─→ updateMatrix() ─→ matrix
              │        │
quaternion ──┼────────┘
              │
scale ───────┘
                    │
                    ↓
           ┌─────────────────┐
           │updateMatrixWorld│
           └────────┬────────┘
                    │
    ┌───────────────┼───────────────┐
    ↓               ↓               ↓
parent.matrixWorld  matrix    children[]
    │               │               │
    └───────┬───────┘               │
            │                       │
            ↓                       ↓
       matrixWorld ←─────── [recursive]
            │
            ↓
    ┌───────────────────┐
    │ Renderer          │
    │ (modelViewMatrix, │
    │  normalMatrix)    │
    └───────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Object3D.js | `src/core/Object3D.js` | ソース | Object3Dクラス本体 |
| EventDispatcher.js | `src/core/EventDispatcher.js` | ソース | イベント機能の基底クラス |
| Layers.js | `src/core/Layers.js` | ソース | レイヤー管理クラス |
| Vector3.js | `src/math/Vector3.js` | ソース | 3次元ベクトル |
| Quaternion.js | `src/math/Quaternion.js` | ソース | 四元数 |
| Euler.js | `src/math/Euler.js` | ソース | オイラー角 |
| Matrix4.js | `src/math/Matrix4.js` | ソース | 4x4変換行列 |
| Matrix3.js | `src/math/Matrix3.js` | ソース | 3x3行列（法線行列用） |
| MathUtils.js | `src/math/MathUtils.js` | ソース | UUID生成などのユーティリティ |
