# 通知設計書 5-pinchstart

## 概要

本ドキュメントは、three.jsライブラリにおける`pinchstart`イベント通知の設計について記載する。`pinchstart`イベントは、WebXRハンドトラッキングにおいてピンチジェスチャーが開始された際に発火するイベントである。

### 本通知の処理概要

`pinchstart`イベントは、WebXR APIのハンドトラッキング機能を使用したアプリケーションにおいて、ユーザーの親指と人差し指によるピンチジェスチャーの開始を検知するためのイベントである。

**業務上の目的・背景**：WebXRアプリケーションでは、コントローラーの代わりにハンドトラッキングでの入力が可能である。ピンチジェスチャーはVR/AR環境において最も一般的なインタラクション方法の一つであり、オブジェクトの選択、UIボタンの押下、ドラッグ操作の開始等に使用される。`pinchstart`イベントにより、アプリケーションはピンチ操作の開始を検知し、適切なインタラクションを開始できる。

**通知の送信タイミング**：XRフレームごとの更新処理で、親指の先端（thumb-tip）と人差し指の先端（index-finger-tip）の距離が閾値（0.02m - 0.005m = 0.015m）以下になった際に発火される。

**通知の受信者**：`pinchstart`イベントの受信者は、XRコントローラーの各座標空間（targetRay、grip、hand）を表すGroupオブジェクトに登録されたリスナーである。

**通知内容の概要**：イベントオブジェクトには`type: 'pinchstart'`、`handedness`（左右の手を示す）、`target`（WebXRController参照）が含まれる。

**期待されるアクション**：受信者は、ピンチ位置にあるオブジェクトの選択、ドラッグ操作の開始、UI要素のアクティベート等を実行する。

## 通知種別

アプリ内イベント通知（EventDispatcherパターン）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | 無 |

### 送信先決定ロジック

WebXRControllerクラスの`dispatchEvent()`メソッドにより、targetRay、grip、handの3つのGroupオブジェクトに対して順次イベントが送信される。

## 通知テンプレート

### イベントオブジェクト形式

| 項目 | 内容 |
|-----|------|
| type | 'pinchstart' |
| handedness | 'left' または 'right' |
| target | WebXRControllerインスタンス |

### イベントオブジェクト例

```javascript
{
  type: 'pinchstart',
  handedness: 'right',  // または 'left'
  target: <WebXRController>
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | イベントタイプ | 固定値 'pinchstart' | Yes |
| handedness | 左右の手識別 | inputSource.handedness | Yes |
| target | コントローラー参照 | this（WebXRController） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| フレーム更新 | WebXRController.update() | 距離が閾値以下かつ以前はpinching=false | ピンチジェスチャー開始時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| hand.inputState.pinching === true | 既にピンチ中の場合 |
| distance > distanceToPinch - threshold | 指間距離が閾値より大きい場合（0.015m超） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[update処理 - handモード] --> B[indexTip/thumbTipの位置取得]
    B --> C[distance = 指間距離計算]
    C --> D{hand.inputState.pinching?}
    D -->|true| E[pinchend判定へ]
    D -->|false| F{distance <= 0.015?}
    F -->|No| G[処理スキップ]
    F -->|Yes| H[hand.inputState.pinching = true]
    H --> I[dispatchEvent type: pinchstart]
    I --> J[終了]
```

## データベース参照・更新仕様

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リスナーエラー | リスナー関数内で例外が発生 | 例外はキャッチされず呼び出し元に伝播 |

### リトライ仕様

リトライなし

## 配信設定

### レート制限

制限なし

### 配信時間帯

制限なし（XRセッション中、ハンドトラッキング有効時のみ発火）

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

- ハンドトラッキングデータはWebXR API経由で取得され、ユーザー許可が必要

## 備考

- ピンチ検出の閾値: distanceToPinch = 0.02m、threshold = 0.005m
- ピンチ開始条件: distance <= 0.02 - 0.005 = 0.015m
- inputState.pinchingフラグでピンチ状態を管理

---

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

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

### 推奨読解順序

#### Step 1: ピンチ検出ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebXRController.js | `src/renderers/webxr/WebXRController.js` | 260-288行目のピンチ検出処理 |

**主要処理フロー**:
1. **263-265行目**: indexTipとthumbTipの位置取得
2. **266行目**: 指間距離の計算
3. **268-269行目**: 閾値定義（distanceToPinch=0.02, threshold=0.005）
4. **279-287行目**: pinchstart判定とイベント発火

#### Step 2: inputStateの初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WebXRController.js | `src/renderers/webxr/WebXRController.js` | 65行目のinputState初期化 |

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

```
WebXRController.update()
    │
    ├─ hand && inputSource.hand の確認
    │
    ├─ jointPose更新
    │
    └─ ピンチ検出
           │
           ├─ indexTip = hand.joints['index-finger-tip']
           ├─ thumbTip = hand.joints['thumb-tip']
           │
           ├─ distance = indexTip.position.distanceTo(thumbTip.position)
           │
           └─ !pinching && distance <= 0.015
                  │
                  ├─ inputState.pinching = true
                  │
                  └─ this.dispatchEvent({
                         type: 'pinchstart',
                         handedness: inputSource.handedness,
                         target: this
                     })
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WebXRController.js | `src/renderers/webxr/WebXRController.js` | ソース | pinchstartイベント発火、ピンチ検出ロジック |
| WebXRManager.js | `src/renderers/webxr/WebXRManager.js` | ソース | update呼び出し元 |
