279 lines
11 KiB
C++
279 lines
11 KiB
C++
// Copyright Ngonart OU. All Rights Reserved.
|
|
// UE5 Modular Game Framework — BPC_PlanarCapture (136)
|
|
// The heart of the Planar Capture System. Attached to any actor that needs
|
|
// a scene capture — mirrors, portals, monitors, horror surfaces.
|
|
//
|
|
// Manages USceneCaptureComponent2D lifetime, render target pool allocation,
|
|
// camera transform computation per mode, oblique clip plane injection,
|
|
// show/hide actor lists, quality tier application, frame ring buffer,
|
|
// and MPC parameter pushes.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Components/ActorComponent.h"
|
|
#include "Capture/PlanarCaptureCommon.h"
|
|
#include "BPC_PlanarCapture.generated.h"
|
|
|
|
// Forward declarations
|
|
class USceneCaptureComponent2D;
|
|
class UTextureRenderTarget2D;
|
|
class UMaterialInstanceDynamic;
|
|
class UMaterialParameterCollection;
|
|
class USS_PlanarCaptureManager;
|
|
class ABP_PlanarCaptureActor;
|
|
|
|
// ============================================================================
|
|
// Delegates
|
|
// ============================================================================
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnCaptureQualityChanged, EPlanarCaptureQualityTier, OldTier, EPlanarCaptureQualityTier, NewTier);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCaptureInitialized, EPlanarCaptureInitResult, Result);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnCaptureRendered);
|
|
|
|
/**
|
|
* BPC_PlanarCapture — Core capture component for mirrors, portals, monitors, etc.
|
|
*
|
|
* Owns the USceneCaptureComponent2D lifecycle. All camera math, render target
|
|
* management, and per-frame capture decisions happen here in C++ for performance.
|
|
* Designer configuration flows through Blueprint children.
|
|
*
|
|
* Multiplayer: Capture is always local-only. Each client renders their own view.
|
|
* No replication needed. This component only exists on clients.
|
|
*/
|
|
UCLASS(Blueprintable, ClassGroup = (Framework), meta = (BlueprintSpawnableComponent))
|
|
class PG_FRAMEWORK_API UBPC_PlanarCapture : public UActorComponent
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UBPC_PlanarCapture();
|
|
|
|
// ========================================================================
|
|
// Lifecycle
|
|
// ========================================================================
|
|
|
|
virtual void BeginPlay() override;
|
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
|
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
|
|
FActorComponentTickFunction* ThisTickFunction) override;
|
|
|
|
// ========================================================================
|
|
// Configuration — Set in Blueprint Defaults
|
|
// ========================================================================
|
|
|
|
/** What kind of surface this capture represents. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Capture|Config")
|
|
EPlanarCaptureMode CaptureMode = EPlanarCaptureMode::Mirror;
|
|
|
|
/** Quality profiles per tier (0=Low, 1=Medium, 2=High, 3=Hero). Index maps to EPlanarCaptureQualityTier. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Capture|Config")
|
|
TArray<FPlanarCaptureQualityProfile> QualityProfiles;
|
|
|
|
/** FOV for the capture camera. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Capture|Config")
|
|
float CaptureFOV = 90.0f;
|
|
|
|
/** Maximum view distance for the capture (0 = unlimited). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Capture|Config")
|
|
float MaxViewDistance = 5000.0f;
|
|
|
|
// ========================================================================
|
|
// Portal Configuration
|
|
// ========================================================================
|
|
|
|
/** For Portal mode: the linked target surface actor. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Portal")
|
|
TSoftObjectPtr<ABP_PlanarCaptureActor> LinkedTargetSurface;
|
|
|
|
// ========================================================================
|
|
// Monitor Configuration
|
|
// ========================================================================
|
|
|
|
/** For Monitor mode: a fixed camera actor to capture from. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Monitor")
|
|
TSoftObjectPtr<AActor> FixedCameraActor;
|
|
|
|
// ========================================================================
|
|
// Actor Lists
|
|
// ========================================================================
|
|
|
|
/** Actors to show exclusively in the capture (empty = show all). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|ActorLists")
|
|
TArray<FPlanarCaptureActorListEntry> ShowOnlyActors;
|
|
|
|
/** Actors to hide from the capture. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|ActorLists")
|
|
TArray<FPlanarCaptureActorListEntry> HiddenActors;
|
|
|
|
// ========================================================================
|
|
// Horror Configuration
|
|
// ========================================================================
|
|
|
|
/** Actor to swap into the ShowOnly list during wrong-reflection events. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Horror")
|
|
TSoftObjectPtr<AActor> WrongReflectionActor;
|
|
|
|
/** Mesh component of the surface plane (for clip plane calculation). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Config")
|
|
TSoftObjectPtr<UStaticMeshComponent> SurfaceMeshComponent;
|
|
|
|
// ========================================================================
|
|
// Runtime State (Read-Only)
|
|
// ========================================================================
|
|
|
|
/** Current assigned quality tier (set by SS_PlanarCaptureManager). */
|
|
UPROPERTY(BlueprintReadOnly, Category = "Capture|Runtime")
|
|
EPlanarCaptureQualityTier CurrentQualityTier = EPlanarCaptureQualityTier::Off;
|
|
|
|
/** Is this capture currently active (capturing frames)? */
|
|
UPROPERTY(BlueprintReadOnly, Category = "Capture|Runtime")
|
|
bool bIsCapturing = false;
|
|
|
|
/** The render target this capture writes to. */
|
|
UPROPERTY(BlueprintReadOnly, Category = "Capture|Runtime")
|
|
TObjectPtr<UTextureRenderTarget2D> CaptureRenderTarget;
|
|
|
|
// ========================================================================
|
|
// Public API — BlueprintCallable
|
|
// ========================================================================
|
|
|
|
/**
|
|
* Initialize the capture component. Allocates render target, creates and
|
|
* configures the USceneCaptureComponent2D. Called by the owning actor on BeginPlay.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture")
|
|
EPlanarCaptureInitResult InitializeCapture();
|
|
|
|
/**
|
|
* Shut down the capture, release render target back to pool, destroy SceneCaptureComponent2D.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture")
|
|
void ShutdownCapture();
|
|
|
|
/**
|
|
* Apply a quality tier profile immediately. Called by SS_PlanarCaptureManager.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture")
|
|
void ApplyQualityTier(EPlanarCaptureQualityTier Tier);
|
|
|
|
/**
|
|
* Trigger a single capture frame immediately (bypasses tick interval).
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture")
|
|
void CaptureNow();
|
|
|
|
/**
|
|
* Swap the ShowOnly actor list to the wrong-reflection actor (horror mode).
|
|
* Original list is preserved and restored on DeactivateHorrorReflection().
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture|Horror")
|
|
void ActivateHorrorReflection();
|
|
|
|
/**
|
|
* Restore the original ShowOnly actor list after a horror event.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture|Horror")
|
|
void DeactivateHorrorReflection();
|
|
|
|
/**
|
|
* Push a frame from the ring buffer into the render target for delayed reflection (horror lag).
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture|Horror")
|
|
void PushDelayedFrame();
|
|
|
|
/**
|
|
* Set a scripted priority override (0.0 to 1.0). Higher values force higher quality tier.
|
|
* Example: a scare event elevates a specific mirror to Hero tier.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture")
|
|
void SetScriptedPriority(float Priority);
|
|
|
|
/**
|
|
* Push all Material Parameter Collection values for this surface.
|
|
* Called every frame when capturing, or on event trigger for horror params.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Capture|Material")
|
|
void PushMPCParameters(UMaterialParameterCollection* MPC);
|
|
|
|
// ========================================================================
|
|
// Compute — BlueprintPure
|
|
// ========================================================================
|
|
|
|
/** Compute the capture camera transform for the current mode. */
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Capture")
|
|
FTransform ComputeCaptureCameraTransform(const FTransform& ViewerCameraTransform) const;
|
|
|
|
/** Get the current composite quality score. */
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Capture")
|
|
FPlanarCaptureScore GetCurrentScore() const;
|
|
|
|
// ========================================================================
|
|
// Event Dispatchers
|
|
// ========================================================================
|
|
|
|
UPROPERTY(BlueprintAssignable, Category = "Capture|Events")
|
|
FOnCaptureQualityChanged OnCaptureQualityChanged;
|
|
|
|
UPROPERTY(BlueprintAssignable, Category = "Capture|Events")
|
|
FOnCaptureInitialized OnCaptureInitialized;
|
|
|
|
UPROPERTY(BlueprintAssignable, Category = "Capture|Events")
|
|
FOnCaptureRendered OnCaptureRendered;
|
|
|
|
protected:
|
|
// ========================================================================
|
|
// Internal State
|
|
// ========================================================================
|
|
|
|
/** The actual UE5 SceneCaptureComponent2D — created at runtime. */
|
|
UPROPERTY()
|
|
TObjectPtr<USceneCaptureComponent2D> SceneCapture;
|
|
|
|
/** Cached reference to the manager subsystem. */
|
|
UPROPERTY()
|
|
TObjectPtr<USS_PlanarCaptureManager> CachedManager;
|
|
|
|
/** Cached reference to the owning actor. */
|
|
UPROPERTY()
|
|
TObjectPtr<ABP_PlanarCaptureActor> CachedOwningActor;
|
|
|
|
/** Time accumulator for capture interval throttling. */
|
|
float TimeSinceLastCapture = 0.0f;
|
|
|
|
/** Current quality profile (cached from QualityProfiles[Tier]). */
|
|
FPlanarCaptureQualityProfile ActiveProfile;
|
|
|
|
/** Scripted priority override (0.0 to 1.0). */
|
|
float ScriptedPriorityOverride = 0.0f;
|
|
|
|
/** Ring buffer of render targets for delayed reflection (horror mode). */
|
|
UPROPERTY()
|
|
TArray<TObjectPtr<UTextureRenderTarget2D>> FrameRingBuffer;
|
|
|
|
/** Current write index into the frame ring buffer. */
|
|
int32 RingBufferWriteIndex = 0;
|
|
|
|
/** Saved ShowOnly list before horror swap. */
|
|
TArray<TSoftObjectPtr<AActor>> SavedShowOnlyActors;
|
|
|
|
// ========================================================================
|
|
// Internal Methods
|
|
// ========================================================================
|
|
|
|
/** Create and configure the USceneCaptureComponent2D. */
|
|
void CreateSceneCaptureComponent();
|
|
|
|
/** Apply show flags from the active quality profile to the SceneCapture. */
|
|
void ApplyShowFlags();
|
|
|
|
/** Update the ShowOnly and Hidden actor lists on the SceneCapture. */
|
|
void UpdateActorLists();
|
|
|
|
/** Resolve soft references on initialization. */
|
|
void ResolveSoftReferences();
|
|
|
|
/** Compute the surface plane in world space for clip plane and mirror math. */
|
|
FPlane GetSurfacePlane() const;
|
|
};
|