# 機能設計書 20-OrthographicCamera

## 概要

本ドキュメントは、Three.jsライブラリにおけるOrthographicCamera機能の設計を詳細に記述するものである。OrthographicCameraは、正射影投影を使用して3Dシーンを描画するためのカメラクラスである。

### 本機能の処理概要

OrthographicCameraクラスは、遠近感のない正射影投影を提供する。すべてのオブジェクトは距離に関係なく同じサイズで描画され、平行線は平行のまま保たれる。左・右・上・下・ニア・ファーの6つのパラメータで直方体の視錐台を定義する。

**業務上の目的・背景**：正射影は、2Dゲーム、建築図面、CADソフトウェア、UIオーバーレイ、アイソメトリックビューなど、遠近感を必要としない表現に使用される。PerspectiveCameraと異なり、オブジェクトのサイズが距離によって変化しないため、正確な寸法の表現が可能である。

**機能の利用シーン**：2Dゲーム、アイソメトリックゲーム、建築ビジュアライゼーション（平面図・立面図）、CADアプリケーション、UIレンダリング、シャドウマップ生成、ミニマップ、技術図面。

**主要な処理内容**：
1. 左右上下のクリッピングプレーン境界の管理
2. ニア/ファークリッピングプレーンの設定
3. 正射影プロジェクション行列の計算
4. ズーム機能によるビューのスケーリング
5. ビューオフセット（マルチモニター対応）

**関連システム・外部連携**：Camera（継承元）、Matrix4（プロジェクション行列）、DirectionalLight（シャドウカメラ）。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | エディタメイン画面 | 補助機能 | 正射影ビュー（Top/Front/Side） |
| 2 | Viewport | 主機能 | 正射影カメラでの表示 |
| 12 | Menubar - Add | 補助機能 | 正射影カメラの追加 |

## 機能種別

3Dオブジェクト / カメラ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| left | number | No | 左クリッピングプレーン | デフォルト: -1 |
| right | number | No | 右クリッピングプレーン | デフォルト: 1 |
| top | number | No | 上クリッピングプレーン | デフォルト: 1 |
| bottom | number | No | 下クリッピングプレーン | デフォルト: -1 |
| near | number | No | ニアクリッピングプレーン | デフォルト: 0.1 |
| far | number | No | ファークリッピングプレーン | デフォルト: 2000 |

### 入力データソース

- コンストラクタパラメータ
- プロパティへの直接代入

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| projectionMatrix | Matrix4 | 正射影プロジェクション行列 |
| projectionMatrixInverse | Matrix4 | プロジェクション行列の逆行列 |
| left | number | 現在の左境界 |
| right | number | 現在の右境界 |
| top | number | 現在の上境界 |
| bottom | number | 現在の下境界 |

### 出力先

- レンダラーに渡されてシェーダーで使用

## 処理フロー

### 処理シーケンス

```
1. OrthographicCameraインスタンスの生成
   └─ Camera初期化、パラメータ設定、updateProjectionMatrix()

2. パラメータ変更時
   ├─ left, right, top, bottom, near, far等を変更
   └─ updateProjectionMatrix()を手動呼び出し

3. リサイズ対応
   ├─ アスペクト比に応じてleft/right/top/bottomを再計算
   └─ updateProjectionMatrix()

4. updateProjectionMatrix()内部
   ├─ zoom適用: dx = (right - left) / 2 / zoom
   ├─ 中心点計算: cx = (right + left) / 2
   ├─ ビューオフセット適用（マルチモニター用）
   └─ projectionMatrix.makeOrthographic()

5. レンダリング時
   └─ レンダラーがprojectionMatrixを使用
```

### フローチャート

```mermaid
flowchart TD
    A[OrthographicCamera生成] --> B[Camera基底クラス初期化]
    B --> C[left, right, top, bottom設定]
    C --> D[near, far設定]
    D --> E[updateProjectionMatrix]
    E --> F[dx = width/2 / zoom]
    F --> G[dy = height/2 / zoom]
    G --> H[cx, cy = 中心点計算]
    H --> I{view設定あり?}
    I -->|Yes| J[ビューオフセット適用]
    I -->|No| K[projectionMatrix.makeOrthographic]
    J --> K
    K --> L[projectionMatrixInverse.invert]
    L --> M[レンダリング準備完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Camera継承 | Cameraクラスを継承 | クラス定義 |
| BR-02 | タイプフラグ | isOrthographicCamera=trueを設定 | インスタンス生成時 |
| BR-03 | 境界デフォルト | left=-1, right=1, top=1, bottom=-1 | パラメータ未指定時 |
| BR-04 | 手動更新 | プロパティ変更後はupdateProjectionMatrix()が必要 | パラメータ変更時 |
| BR-05 | ズーム適用 | 境界はzoom値で除算される | プロジェクション計算時 |
| BR-06 | 逆深度対応 | reversedDepth時はmakeOrthographicReversedを使用 | 逆深度バッファ使用時 |

### 計算ロジック

- dx = (right - left) / (2 * zoom)
- dy = (top - bottom) / (2 * zoom)
- cx = (right + left) / 2
- cy = (top + bottom) / 2
- left' = cx - dx, right' = cx + dx
- top' = cy + dy, bottom' = cy - dy

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 視覚問題 | left >= right | leftはrightより小さく設定 |
| - | 視覚問題 | bottom >= top | bottomはtopより小さく設定 |
| - | 数学エラー | zoom <= 0 | zoomは正の値を設定 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- updateProjectionMatrix()は必要時のみ呼び出し
- フレームごとの不要な再計算を避ける

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

該当なし

## 備考

- setViewOffset()でマルチモニター対応可能
- DirectionalLightのシャドウカメラとして使用される
- 2Dゲームでは通常zoomでスケーリングを制御

---

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

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

### 推奨読解順序

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

OrthographicCameraの構造とその依存関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OrthographicCamera.js | `src/cameras/OrthographicCamera.js` | クラス定義全体 |
| 1-2 | Camera.js | `src/cameras/Camera.js` | 継承元クラス |
| 1-3 | Matrix4.js | `src/math/Matrix4.js` | makeOrthographic/makeOrthographicReversed |

**読解のコツ**: OrthographicCameraはCameraを継承し、left/right/top/bottom/near/farでプロジェクション行列を計算する。PerspectiveCameraと異なりFOVを使わず、直接境界を指定する。

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

OrthographicCameraの初期化と主要メソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OrthographicCamera.js | `src/cameras/OrthographicCamera.js` | コンストラクタ・メソッド |

**主要処理フロー**:
1. **21行目**: コンストラクタでleft, right, top, bottom, near, farを受け取る
2. **30行目**: isOrthographicCameraフラグをtrueに設定
3. **32行目**: type = 'OrthographicCamera'
4. **39行目**: zoomプロパティ（デフォルト1）
5. **47行目**: viewプロパティ（nullまたはオブジェクト）
6. **56行目**: leftプロパティ（デフォルト-1）
7. **64行目**: rightプロパティ（デフォルト1）
8. **72行目**: topプロパティ（デフォルト1）
9. **80行目**: bottomプロパティ（デフォルト-1）
10. **88行目**: nearプロパティ（デフォルト0.1）
11. **96行目**: farプロパティ（デフォルト2000）
12. **98行目**: コンストラクタ最後にupdateProjectionMatrix()呼び出し
13. **129-155行目**: setViewOffset() - マルチモニター対応
14. **160-170行目**: clearViewOffset() - ビューオフセット解除
15. **176-217行目**: updateProjectionMatrix() - 核心メソッド

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

プロジェクション行列計算の詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OrthographicCamera.js | `src/cameras/OrthographicCamera.js` | updateProjectionMatrix内部 |

**主要処理フロー**:
1. **178行目**: dx = (right - left) / (2 * zoom)
2. **179行目**: dy = (top - bottom) / (2 * zoom)
3. **180行目**: cx = (right + left) / 2
4. **181行目**: cy = (top + bottom) / 2
5. **183-186行目**: left, right, top, bottomをズーム適用で再計算
6. **188行目**: viewオフセット取得
7. **190-201行目**: view.enabled時のオフセット適用
8. **203-209行目**: reversedDepth判定でmakeOrthographicReversedまたはmakeOrthographic
9. **211行目**: projectionMatrixInverse.invert()

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

```
OrthographicCamera
    │
    └─ extends Camera
            │
            └─ extends Object3D

OrthographicCamera.updateProjectionMatrix()
    │
    ├─ dx = (right - left) / (2 * zoom)
    │
    ├─ dy = (top - bottom) / (2 * zoom)
    │
    ├─ cx = (right + left) / 2
    │
    ├─ cy = (top + bottom) / 2
    │
    ├─ left' = cx - dx
    │
    ├─ right' = cx + dx
    │
    ├─ top' = cy + dy
    │
    ├─ bottom' = cy - dy
    │
    ├─ [view offset適用]
    │
    ├─ projectionMatrix.makeOrthographic(left', right', top', bottom', near, far)
    │   または
    │   projectionMatrix.makeOrthographicReversed(...)  ※reversedDepth時
    │
    └─ projectionMatrixInverse.invert()
```

### データフロー図

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

left, right, top, bottom, near, far
    │
    ▼
OrthographicCamera() ───────────▶ 初期パラメータ設定 ────────────▶ プロパティ設定
    │
    ▼
updateProjectionMatrix() ────────▶ 境界計算（zoom適用）────────────▶ projectionMatrix
    │                                   │
    │                                   ▼
    │                            Matrix4.makeOrthographic()
    │
    ▼
setViewOffset() ─────────────────▶ view設定 ───────────────────────▶ マルチモニター対応

[レンダリング]

projectionMatrix ────────────────▶ シェーダー ──────────────────────▶ 正射影描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OrthographicCamera.js | `src/cameras/OrthographicCamera.js` | ソース | 正射影カメラ |
| Camera.js | `src/cameras/Camera.js` | ソース | 基底カメラクラス |
| Object3D.js | `src/core/Object3D.js` | ソース | 3Dオブジェクト基底 |
| Matrix4.js | `src/math/Matrix4.js` | ソース | 行列クラス（makeOrthographic） |
| Vector2.js | `src/math/Vector2.js` | ソース | getViewBounds用 |
| DirectionalLightShadow.js | `src/lights/DirectionalLightShadow.js` | ソース | シャドウカメラとして使用 |
