Add Planar Capture System implementation checklist and developer reference
- Created a comprehensive implementation checklist for the Planar Capture System (Systems 136-147) detailing tasks across multiple phases including C++ core, material foundation, Blueprint actors, data assets, integration, and performance testing. - Added a developer reference document outlining the architecture, data flow, state machine, budget enforcement, render target pooling, horror features, integration points, multiplayer networking, performance characteristics, debugging methods, and build order for the capture systems. - Introduced examples of capture surface usage in the Project Void horror game, including specific implementations for mirrors, monitors, portals, and fake windows, along with a checklist for integration tasks.
This commit is contained in:
232
Source/PG_Framework/Public/Capture/SS_PlanarCaptureManager.h
Normal file
232
Source/PG_Framework/Public/Capture/SS_PlanarCaptureManager.h
Normal file
@@ -0,0 +1,232 @@
|
||||
// Copyright Ngonart OU. All Rights Reserved.
|
||||
// UE5 Modular Game Framework — SS_PlanarCaptureManager (138)
|
||||
// Global budget manager for all planar capture surfaces in the world.
|
||||
//
|
||||
// One instance per World (World Subsystem). Each frame, scores every registered
|
||||
// capture surface by distance, screen coverage, facing angle, and scripted priority.
|
||||
// Assigns quality tiers across all surfaces respecting a global budget
|
||||
// (max simultaneous high-quality captures, max total render target memory).
|
||||
// Forces idle/disabled state on surfaces outside active rooms/sublevels.
|
||||
//
|
||||
// Also manages the render target pool — allocates, reuses, and resizes RTs
|
||||
// to minimize memory churn.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Subsystems/WorldSubsystem.h"
|
||||
#include "Capture/PlanarCaptureCommon.h"
|
||||
#include "SS_PlanarCaptureManager.generated.h"
|
||||
|
||||
class ABP_PlanarCaptureActor;
|
||||
class UBPC_PlanarCapture;
|
||||
|
||||
// Delegates
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSurfaceRegistered, ABP_PlanarCaptureActor*, Surface, int32, TotalSurfaces);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSurfaceUnregistered, ABP_PlanarCaptureActor*, Surface, int32, TotalSurfaces);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGlobalQualityCapChanged, EPlanarCaptureQualityTier, NewCap);
|
||||
|
||||
/**
|
||||
* SS_PlanarCaptureManager — Global Planar Capture Budget Manager.
|
||||
*
|
||||
* Manages all ABP_PlanarCaptureActor instances per world. Evaluates priority
|
||||
* and assigns quality tiers to stay within a configurable budget.
|
||||
* Also owns the render target pool to reduce memory allocation overhead.
|
||||
*
|
||||
* Multiplayer: This subsystem exists on both server and clients.
|
||||
* On the server, it tracks surfaces for replication state.
|
||||
* On clients, it drives actual capture rendering.
|
||||
*/
|
||||
UCLASS()
|
||||
class PG_FRAMEWORK_API ASS_PlanarCaptureManager : public UWorldSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
ASS_PlanarCaptureManager();
|
||||
|
||||
// ========================================================================
|
||||
// Lifecycle
|
||||
// ========================================================================
|
||||
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual TStatId GetStatId() const override;
|
||||
|
||||
// ========================================================================
|
||||
// Surface Registry
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Register a capture surface actor with the global manager.
|
||||
* Called by ABP_PlanarCaptureActor::BeginPlay.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Capture|Manager")
|
||||
void RegisterSurface(ABP_PlanarCaptureActor* Surface);
|
||||
|
||||
/**
|
||||
* Unregister a capture surface actor. Called on EndPlay.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Capture|Manager")
|
||||
void UnregisterSurface(ABP_PlanarCaptureActor* Surface);
|
||||
|
||||
/**
|
||||
* Get all currently registered surfaces.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Capture|Manager")
|
||||
TArray<ABP_PlanarCaptureActor*> GetRegisteredSurfaces() const;
|
||||
|
||||
/**
|
||||
* Get the number of registered surfaces.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Capture|Manager")
|
||||
int32 GetSurfaceCount() const { return RegisteredSurfaces.Num(); }
|
||||
|
||||
// ========================================================================
|
||||
// Quality Budget Management
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Global quality ceiling — caps all surfaces at this tier regardless of score.
|
||||
* Use this for lower-end hardware targets.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
EPlanarCaptureQualityTier GlobalQualityCap = EPlanarCaptureQualityTier::High;
|
||||
|
||||
/**
|
||||
* Maximum number of simultaneous Hero-tier captures.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
int32 MaxHeroSurfaces = 1;
|
||||
|
||||
/**
|
||||
* Maximum number of simultaneous High-tier captures.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
int32 MaxHighSurfaces = 3;
|
||||
|
||||
/**
|
||||
* Maximum number of simultaneous Medium-tier captures.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
int32 MaxMediumSurfaces = 6;
|
||||
|
||||
/**
|
||||
* Maximum total render target memory in megabytes across all surfaces.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
float MaxTotalRenderTargetMemoryMB = 128.0f;
|
||||
|
||||
/**
|
||||
* Distance at which capture quality drops to Off (world units).
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
float MaxCaptureDistance = 10000.0f;
|
||||
|
||||
/**
|
||||
* Interval between full re-evaluation of all surfaces (seconds).
|
||||
* Individual surfaces check their own interval every frame via their component.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture|Manager|Budget")
|
||||
float FullEvaluationInterval = 0.5f;
|
||||
|
||||
// ========================================================================
|
||||
// Render Target Pool
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Request a render target from the pool. Returns nullptr if none available.
|
||||
*/
|
||||
UTextureRenderTarget2D* RequestRenderTarget(int32 Size);
|
||||
|
||||
/**
|
||||
* Release a render target back to the pool.
|
||||
*/
|
||||
void ReleaseRenderTarget(UTextureRenderTarget2D* RenderTarget);
|
||||
|
||||
/**
|
||||
* Get the total memory used by the render target pool (in MB).
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Capture|Manager")
|
||||
float GetPoolMemoryUsageMB() const;
|
||||
|
||||
// ========================================================================
|
||||
// Query
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Get the nearest capture surface of a given mode to a world location.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Capture|Manager")
|
||||
ABP_PlanarCaptureActor* GetNearestSurfaceOfMode(
|
||||
EPlanarCaptureMode Mode, FVector WorldLocation, float MaxDistance = 0.0f) const;
|
||||
|
||||
/**
|
||||
* Force all surfaces to a specific quality tier (e.g., for cutscenes).
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Capture|Manager")
|
||||
void ForceAllSurfacesToTier(EPlanarCaptureQualityTier Tier);
|
||||
|
||||
/**
|
||||
* Release the force-tier override and resume normal scoring.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Capture|Manager")
|
||||
void ReleaseForceTier();
|
||||
|
||||
// ========================================================================
|
||||
// Event Dispatchers
|
||||
// ========================================================================
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Capture|Manager|Events")
|
||||
FOnSurfaceRegistered OnSurfaceRegistered;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Capture|Manager|Events")
|
||||
FOnSurfaceUnregistered OnSurfaceUnregistered;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Capture|Manager|Events")
|
||||
FOnGlobalQualityCapChanged OnGlobalQualityCapChanged;
|
||||
|
||||
protected:
|
||||
// ========================================================================
|
||||
// Internal State
|
||||
// ========================================================================
|
||||
|
||||
/** All registered capture surface actors. */
|
||||
UPROPERTY()
|
||||
TArray<TWeakObjectPtr<ABP_PlanarCaptureActor>> RegisteredSurfaces;
|
||||
|
||||
/** Render target pool. */
|
||||
TArray<FPlanarCaptureRenderTargetEntry> RenderTargetPool;
|
||||
|
||||
/** Time accumulator for full re-evaluation interval. */
|
||||
float TimeSinceLastEvaluation = 0.0f;
|
||||
|
||||
/** Force-tier override — if set, all surfaces use this tier. */
|
||||
TOptional<EPlanarCaptureQualityTier> ForceTierOverride;
|
||||
|
||||
/** Count of surfaces at each tier (tracked for budget enforcement). */
|
||||
TMap<EPlanarCaptureQualityTier, int32> TierAssignmentCounts;
|
||||
|
||||
// ========================================================================
|
||||
// Internal Methods
|
||||
// ========================================================================
|
||||
|
||||
/** Evaluate all registered surfaces and assign quality tiers. */
|
||||
void EvaluateAllSurfaces();
|
||||
|
||||
/**
|
||||
* Score a single surface and determine its quality tier within budget constraints.
|
||||
* @return The assigned tier.
|
||||
*/
|
||||
EPlanarCaptureQualityTier ScoreAndAssignTier(UBPC_PlanarCapture* Capture);
|
||||
|
||||
/** Enforce budget limits — demote lower-priority surfaces if budget exceeded. */
|
||||
void EnforceBudgetLimits();
|
||||
|
||||
/** Create a new render target of the given size. */
|
||||
UTextureRenderTarget2D* CreateRenderTarget(int32 Size);
|
||||
|
||||
/** Get or create a render target for a given size (first checks pool). */
|
||||
UTextureRenderTarget2D* GetOrCreateRenderTarget(int32 Size);
|
||||
};
|
||||
Reference in New Issue
Block a user