# 136 — Planar Capture Component (`BPC_PlanarCapture`)

## Purpose
Core capture component managing `USceneCaptureComponent2D` lifecycle for mirrors, portals, monitors, and horror surfaces. All camera math, render target management, and per-frame capture decisions happen here in C++ for performance.

## Dependencies
- **Requires:** `SS_PlanarCaptureManager` (138) for quality tier assignment and RT pool, `UPlanarCaptureCameraUtils` for camera math, [`BPC_RenderPipelineManager`](../12-settings/149_BPC_RenderPipelineManager.md) for global Lumen/Nanite state awareness
- **Required By:** `BP_PlanarCaptureActor` (137) — owned by parent actor
- **Engine/Plugin Requirements:** Renderer, RenderCore modules

## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `ActorComponent` (C++ `UBPC_PlanarCapture`) |
| **Class Type** | Blueprint Component (C++ Full Implementation) |
| **Asset Path** | `Content/Framework/Capture/` |
| **C++ Header** | `Source/PG_Framework/Public/Capture/BPC_PlanarCapture.h` |
| **C++ Source** | `Source/PG_Framework/Private/Capture/BPC_PlanarCapture.cpp` |
| **C++ Status** | ✅ Full Implementation |
| **BP Asset** | None — use C++ component directly on actors |

## 1. Enums
*Defined in `PlanarCaptureCommon.h` — see Architecture doc for full listing.*

| Enum | Values | Description |
|------|--------|-------------|
| `EPlanarCaptureMode` | Mirror, Portal, Monitor, HorrorMirror, HorrorPortal, FakeWindow | Capture surface mode |
| `EPlanarCaptureQualityTier` | Off, Low, Medium, High, Hero | Quality tier levels |
| `EPlanarCaptureInitResult` | Success, NoRenderTargetPool, InvalidSurfaceMesh, BudgetExceeded, ManagerUnavailable | Init result codes |

## 2. Structs
*Defined in `PlanarCaptureCommon.h`*

### `FPlanarCaptureQualityProfile`
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `RenderTargetSize` | int32 | 512 | Square RT resolution (256/512/1024/2048) |
| `CaptureInterval` | float | 0.0667 | Min seconds between captures (~15fps default) |
| `bEnableShadows` | bool | true | Shadow rendering toggle |
| `bEnablePostProcess` | bool | false | Post-process toggle |
| `bEnableFog` | bool | false | Exponential height fog toggle |
| `bEnableBloom` | bool | false | Bloom toggle |
| `bEnableAO` | bool | false | Ambient occlusion toggle |
| `bEnableLumen` | bool | false | Lumen GI toggle (expensive — auto-disabled if global pipeline has Lumen OFF) |
| `bEnableNanite` | bool | false | Nanite in capture (expensive — auto-disabled if global pipeline has Nanite OFF) |
| `bEnableMotionBlur` | bool | false | Motion blur toggle |
| `bEnableClipPlane` | bool | true | Oblique near-plane toggle |
| `DelayedFrameCount` | int32 | 0 | Horror delayed frame ring buffer size |

## 3. Variables

### Configuration (EditAnywhere, BlueprintReadOnly)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `CaptureMode` | EPlanarCaptureMode | Mirror | `Capture\|Config` | Surface type |
| `QualityProfiles` | TArray〈FPlanarCaptureQualityProfile〉 | 4 entries | `Capture\|Config` | Quality profiles per tier [0=Low,1=Med,2=High,3=Hero] |
| `CaptureFOV` | float | 90.0 | `Capture\|Config` | Capture camera FOV |
| `MaxViewDistance` | float | 5000.0 | `Capture\|Config` | Max render distance |
| `ShowOnlyActors` | TArray〈FPlanarCaptureActorListEntry〉 | — | `Capture\|ActorLists` | Exclusive show actors |
| `HiddenActors` | TArray〈FPlanarCaptureActorListEntry〉 | — | `Capture\|ActorLists` | Hidden actors |
| `WrongReflectionActor` | TSoftObjectPtr〈AActor〉 | — | `Capture\|Horror` | Horror mode wrong reflection swap |
| `SurfaceMeshComponent` | TSoftObjectPtr〈UStaticMeshComponent〉 | — | `Capture\|Config` | Mesh for clip plane calculation |
| `LinkedTargetSurface` | TSoftObjectPtr〈ABP_PlanarCaptureActor〉 | — | `Capture\|Portal` | Portal destination surface |
| `FixedCameraActor` | TSoftObjectPtr〈AActor〉 | — | `Capture\|Monitor` | Monitor fixed camera |

### Runtime (BlueprintReadOnly)
| Variable | Type | Description |
|----------|------|-------------|
| `CurrentQualityTier` | EPlanarCaptureQualityTier | Assigned quality tier |
| `bIsCapturing` | bool | Is capture currently active |
| `CaptureRenderTarget` | UTextureRenderTarget2D* | Active render target |

## 4. Functions

### Public (BlueprintCallable)

#### `InitializeCapture()` → `EPlanarCaptureInitResult`
- **Description:** Allocates RT from pool, creates USceneCaptureComponent2D, configures show flags
- **Flow:** Request RT → Create SceneCapture → ApplyShowFlags → UpdateActorLists → Set bIsCapturing
- **Nodes Used:** `RequestRenderTarget`, `CreateSceneCaptureComponent2D`, `ApplyShowFlags`, `UpdateActorLists`

#### `ShutdownCapture()`
- **Description:** Stops capture, releases RT to pool, destroys SceneCapture2D
- **Flow:** Set bIsCapturing=false → DestroyComponent → ReleaseRenderTarget → Clear ring buffer

#### `ApplyQualityTier(Tier: EPlanarCaptureQualityTier)`
- **Description:** Apply a quality tier profile immediately. Called by SS_PlanarCaptureManager.
- **Flow:** If Off → ShutdownCapture. If transitioning from Off → InitializeCapture. Else → UpdateShowFlags + ApplyProfile.

#### `CaptureNow()`
- **Description:** Bypasses tick interval, captures immediately. Used for event-driven captures.
- **Blueprint Authority:** Any (local)
- **Flow:** Get viewer camera → ComputeCaptureCameraTransform → Set SceneCapture transform → CaptureScene → PushMPCParameters

#### `ActivateHorrorReflection()`
- **Description:** Saves original ShowOnly list, swaps to WrongReflectionActor
- **Flow:** Save ShowOnlyActors → Clear list → Add WrongReflectionActor → UpdateActorLists

#### `DeactivateHorrorReflection()`
- **Description:** Restores original ShowOnly list after horror event
- **Flow:** Clear list → Restore from SavedShowOnlyActors → UpdateActorLists

#### `SetScriptedPriority(Priority: float)`
- **Description:** Scripted priority override (0.0-1.0). Higher values force higher quality tier.

#### `PushMPCParameters(MPC: UMaterialParameterCollection*)`
- **Description:** Push all 10 MPC scalar parameters for surface material effects

### Compute (BlueprintPure)

#### `ComputeCaptureCameraTransform(ViewerCamera: FTransform)` → `FTransform`
- **Description:** Computes capture camera position based on mode (mirror reflection, portal relative, etc.)

#### `GetCurrentScore()` → `FPlanarCaptureScore`
- **Description:** Returns current composite quality score for this surface

## 5. Event Dispatchers
| Dispatcher | Parameters | Description |
|------------|-----------|-------------|
| `OnCaptureQualityChanged` | OldTier, NewTier | Quality tier changed |
| `OnCaptureInitialized` | Result: EPlanarCaptureInitResult | Init completed |
| `OnCaptureRendered` | — | Each frame rendered |

## 6. Communication Matrix
| Target System | Method | What |
|---------------|--------|------|
| `SS_PlanarCaptureManager` | Direct (cached reference) | RT requests, quality tier reception, pipeline state |
| `BPC_RenderPipelineManager` (149) | Direct (cached reference) | Query `IsLumenEnabled()`, `IsNaniteEnabled()` — auto-disable incompatible features |
| `BP_PlanarCaptureActor` | Direct (owner) | Surface mesh, MPC reference |
| `UPlanarCaptureCameraUtils` | Static function calls | Mirror/portal/oblique math |
| `USceneCaptureComponent2D` | Direct (owns) | Full lifecycle control |

## 7. Manual Implementation Guide

*The C++ component is fully functional. Blueprint users interact through the public API:*

1. To force a capture (e.g., on a sequencer event):
   ```
   Get BPC_PlanarCapture → Call CaptureNow()
   ```

2. To trigger a horror mirror wrong reflection:
   ```
   Get BPC_PlanarCapture → Call ActivateHorrorReflection()
   Wait (duration from curve) → Call DeactivateHorrorReflection()
   ```

3. To boost a specific mirror for a scare moment:
   ```
   Get BPC_PlanarCapture → Call SetScriptedPriority(1.0)
   Wait (scare duration) → Call SetScriptedPriority(0.0)
   ```

## 8. Build Checklist
- [ ] C++ component compiled and functional
- [ ] No BP child needed — attach directly to actor
- [ ] Configure QualityProfiles array in component defaults (4 entries)
- [ ] Set CaptureMode in component defaults
- [ ] Assign SurfaceMeshComponent reference
