# 機能設計書 82-Sprite

## 概要

本ドキュメントは、Three.jsにおけるビルボードスプライト `Sprite` クラスの機能設計を定義する。Spriteは常にカメラ方向を向く平面オブジェクトであり、2Dラベル、パーティクル、UIオーバーレイなどの表現に使用される。

### 本機能の処理概要

Spriteクラスは、3D空間に配置されながらも常にカメラを向く（ビルボード）平面を描画するためのオブジェクトである。SpriteMaterialと組み合わせて使用し、テクスチャマッピングや透過処理を適用できる。

**業務上の目的・背景**：3Dアプリケーションにおいて、オブジェクトのラベル表示、パーティクルエフェクト、HUD要素、常にカメラを向く必要のあるUI要素を実現するために必要な機能である。カメラの視点が変わっても常に正面を向くため、テキストや2Dアイコンの表示に最適である。

**機能の利用シーン**：
- 3Dオブジェクトに付随するラベルやアノテーション
- パーティクルエフェクト（煙、火花など）の個別粒子
- ゲームUI（体力バー、名前表示など）
- 3D空間内のマーカーやピン
- 広告看板やサイネージの表現

**主要な処理内容**：
1. 共有ジオメトリ（単一の四角形）の初期化
2. SpriteMaterialによる外観定義
3. カメラ空間でのビルボード変換
4. レイキャスティングによるスプライトとの交差判定
5. 中心点（anchor）の制御による配置調整

**関連システム・外部連携**：WebGLRenderer/WebGPURendererと連携し、ビルボード変換を適用してレンダリングする。Raycasterと連携してマウスピッキングを実現する。

**権限による制御**：特になし（Three.jsはクライアントサイドライブラリ）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | Menubar - Add | 補助機能 | スプライトの追加 |

## 機能種別

オブジェクト生成・レンダリング / レイキャスト判定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| material | SpriteMaterial\|SpriteNodeMaterial | No | スプライトのマテリアル | 省略時はデフォルトのSpriteMaterial |

### 入力データソース

- SpriteMaterial: 色、テクスチャ、回転角度、サイズ減衰設定
- center: アンカーポイント（Vector2）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isSprite | boolean | 型判定フラグ（常にtrue） |
| geometry | BufferGeometry | 共有される四角形ジオメトリ |
| material | SpriteMaterial\|SpriteNodeMaterial | 関連付けられたマテリアル |
| center | Vector2 | アンカーポイント（デフォルト: 0.5, 0.5） |
| count | number | インスタンス数（WebGPU用、デフォルト: 1） |

### 出力先

レンダリング結果はWebGLまたはWebGPUフレームバッファに出力される。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 共有ジオメトリの初期化（初回のみ）、material/centerの設定
2. レンダリング時
   └─ ビルボード変換の適用、マテリアルに基づく描画
3. raycast()呼び出し時
   └─ カメラ空間での頂点変換 → 三角形交差判定 → 結果収集
```

### フローチャート

```mermaid
flowchart TD
    A[Sprite生成] --> B{共有ジオメトリ存在?}
    B -->|No| C[InterleavedBufferで四角形生成]
    B -->|Yes| D[既存ジオメトリ使用]
    C --> E[geometry/material/center設定]
    D --> E
    E --> F[レンダリング待機]
    F --> G{raycast要求?}
    G -->|Yes| H[カメラ設定チェック]
    H --> I{camera設定あり?}
    I -->|No| J[エラー出力]
    I -->|Yes| K[ビルボード変換]
    K --> L[三角形交差判定]
    L --> M{交差あり?}
    M -->|Yes| N[交差結果返却]
    M -->|No| O[処理終了]
    G -->|No| P[ビルボードレンダリング]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-82-01 | 共有ジオメトリ | 全Spriteインスタンスで単一のジオメトリを共有 | 常時 |
| BR-82-02 | ビルボード変換 | レンダリング時に常にカメラ方向を向く | 常時 |
| BR-82-03 | カメラ必須 | raycast時はraycaster.cameraの設定が必須 | raycast実行時 |
| BR-82-04 | 影非対応 | castShadow=trueを設定しても影は描画されない | 常時 |
| BR-82-05 | サイズ減衰 | sizeAttenuation=falseで画面サイズ固定 | 透視投影カメラ使用時 |

### 計算ロジック

スプライト頂点のビルボード変換:
```javascript
// 回転適用
rotatedPosition.x = cos * alignedPosition.x - sin * alignedPosition.y
rotatedPosition.y = sin * alignedPosition.x + cos * alignedPosition.y
// ワールド空間変換
vertexPosition = mvPosition + rotatedPosition
vertexPosition.applyMatrix4(viewWorldMatrix)
```

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

該当なし（Three.jsはクライアントサイドライブラリ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | カメラ未設定エラー | raycaster.camera === null | エラーメッセージ出力（コンソール） |

### リトライ仕様

特になし

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

該当なし

## パフォーマンス要件

- 共有ジオメトリによるメモリ効率化
- InterleavedBufferによるGPUメモリ最適化
- WebGPUではcountによるインスタンス描画サポート

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

特になし（クライアントサイドレンダリング）

## 備考

- Spriteは影を落とさない（castShadow設定は無視される）
- 回転はmaterial.rotationで制御（Z軸回転のみ）
- アンカーポイント(0,0)は左下、(1,1)は右上を示す

---

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

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

### 推奨読解順序

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

Spriteで使用されるマテリアルと共有ジオメトリの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SpriteMaterial.js | `src/materials/SpriteMaterial.js` | スプライトの外観定義（color, map, rotation等） |
| 1-2 | InterleavedBuffer.js | `src/core/InterleavedBuffer.js` | 共有ジオメトリで使用されるインターリーブバッファ |

**読解のコツ**: SpriteMaterialのrotation, sizeAttenuationがビルボード処理でどう影響するか把握する。

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

Spriteクラス本体の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Sprite.js | `src/objects/Sprite.js` | スプライトオブジェクトのメインクラス |

**主要処理フロー**:
1. **54-121行目**: コンストラクタで共有ジオメトリの初期化とプロパティ設定
2. **69-86行目**: 共有ジオメトリの生成（InterleavedBufferを使用）
3. **129-202行目**: raycast()でカメラ空間での交差判定
4. **218-243行目**: transformVertex()ヘルパーでビルボード変換

#### Step 3: 継承関係を理解する

Object3Dからの継承による基本機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Object3D.js | `src/core/Object3D.js` | 位置・回転・スケール管理の基底クラス |

**主要処理フロー**:
- **140-143行目**: position, rotation, quaternion, scaleのプロパティ定義

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

```
Sprite
    │
    ├─ Object3D (継承)
    │      ├─ EventDispatcher (継承)
    │      └─ Layers (レイヤー管理)
    │
    ├─ BufferGeometry (_geometry: 静的共有)
    │      ├─ InterleavedBuffer (頂点/UV結合)
    │      └─ InterleavedBufferAttribute (属性アクセス)
    │
    ├─ SpriteMaterial (material)
    │      └─ Material (継承)
    │
    └─ raycast()
           ├─ Matrix4 (座標変換)
           ├─ Vector3 (頂点計算)
           ├─ Vector2 (UV計算)
           ├─ Triangle (交差判定)
           └─ transformVertex() (ビルボード変換)
```

### データフロー図

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

SpriteMaterial ────▶ Sprite Constructor ────▶ Sprite Object
(color, map, rotation)         │                    │
                               │                    ├─ isSprite: true
_geometry (共有) ─────────────┘                    ├─ geometry
                                                    ├─ material
Vector2(0.5, 0.5) ────────────────────────────▶   └─ center

Raycaster ────▶ raycast() ────▶ intersects[]
(ray, camera)      │              (distance, point, uv, object)
                   │
                   ├─ カメラチェック
                   ├─ transformVertex()でビルボード変換
                   └─ Triangle.intersectTriangle()で判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Sprite.js | `src/objects/Sprite.js` | ソース | スプライトオブジェクトのメインクラス |
| Object3D.js | `src/core/Object3D.js` | ソース | 3Dオブジェクトの基底クラス |
| SpriteMaterial.js | `src/materials/SpriteMaterial.js` | ソース | スプライトマテリアル |
| Material.js | `src/materials/Material.js` | ソース | マテリアル基底クラス |
| InterleavedBuffer.js | `src/core/InterleavedBuffer.js` | ソース | インターリーブバッファ |
| InterleavedBufferAttribute.js | `src/core/InterleavedBufferAttribute.js` | ソース | インターリーブ属性 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | ジオメトリクラス |
| Matrix4.js | `src/math/Matrix4.js` | ソース | 行列変換 |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトル |
| Vector2.js | `src/math/Vector2.js` | ソース | 2Dベクトル |
| Triangle.js | `src/math/Triangle.js` | ソース | 三角形・交差判定 |
