Initial commit: Vertical Partition Streaming plugin (UE 5.7)
Bounded vertical route partition / streaming for handcrafted spiral climb maps (Only Up / Only Climb). Not World Partition, not Level Instances as core arch. - Z-cell segmentation + optional XY subcells, editor builder + commandlet - NonDestructive visibility backend + streaming-level backend - Offline HLOD proxies: MergedMesh / SimplifiedProxy (ProxyLOD) - Universal Level Instance + Packed Level Actor + HISM support (flatten+merge) - Vertical-aware runtime streamer (full/preload/HLOD/unload, hysteresis, velocity prediction, fall-risk), WP-style debug viz + vp.* console - Safe-by-default: only static decor streams; sky/lights/gameplay stay persistent Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,89 @@
|
||||
// Copyright IHY. Vertical Partition Streaming plugin (editor module).
|
||||
//
|
||||
// Editor-only conversion pipeline: scan -> validate -> assign -> generate
|
||||
// descriptor -> generate HLOD proxies -> (optionally) bake streaming sub-levels.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "VerticalPartitionTypes.h"
|
||||
#include "VerticalPartitionBuilder.generated.h"
|
||||
|
||||
class AVerticalPartitionVolume;
|
||||
class UVerticalPartitionDescriptor;
|
||||
class UWorld;
|
||||
class AActor;
|
||||
|
||||
/** One actor's analysed placement, shared between Analyze and Build. */
|
||||
struct FVerticalActorAssignment
|
||||
{
|
||||
TWeakObjectPtr<AActor> Actor;
|
||||
/** The renderable static-decor leaf actors this unit streams. For a normal actor this
|
||||
* is just [Actor]; for a Level Instance it is its (recursively flattened) static child
|
||||
* actors; for a Packed Level Actor it is [Actor] (its baked HISM live on it). */
|
||||
TArray<TWeakObjectPtr<AActor>> LeafActors;
|
||||
FVerticalCellId Cell;
|
||||
FBox Bounds = FBox(ForceInit);
|
||||
bool bCrossesMultiple = false;
|
||||
bool bExcluded = false;
|
||||
bool bLargeKeepPersistent = false;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class UVerticalPartitionBuilder : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Scan the level, classify every actor, return a report without writing anything. */
|
||||
static FVerticalPartitionBuildReport AnalyzeCurrentLevel(AVerticalPartitionVolume* Volume);
|
||||
|
||||
/** Full build: analyze -> create/refresh descriptor -> generate HLOD proxies ->
|
||||
* (DestructiveCommit only) bake streaming sub-levels + remove source actors.
|
||||
* Returns the report; writes the descriptor asset. */
|
||||
static bool Build(AVerticalPartitionVolume* Volume, FVerticalPartitionBuildReport& OutReport);
|
||||
|
||||
/** Re-run only cells whose source content hash changed since the last build. */
|
||||
static bool RebuildChangedCells(AVerticalPartitionVolume* Volume, FVerticalPartitionBuildReport& OutReport);
|
||||
|
||||
/** (Re)generate HLOD proxy meshes for all cells. */
|
||||
static bool RebuildHLOD(AVerticalPartitionVolume* Volume, FVerticalPartitionBuildReport& OutReport);
|
||||
|
||||
/** Re-run analysis against the existing descriptor and flag drift / problems. */
|
||||
static FVerticalPartitionBuildReport ValidateCells(AVerticalPartitionVolume* Volume);
|
||||
|
||||
/** Promote a NonDestructive descriptor to baked streaming sub-levels. */
|
||||
static bool CommitConversion(AVerticalPartitionVolume* Volume, FVerticalPartitionBuildReport& OutReport);
|
||||
|
||||
static bool CreateBackup(UWorld* World, FString& OutBackupPath);
|
||||
static bool RestoreFromBackup(UWorld* World);
|
||||
|
||||
/** Delete generated descriptor / cell maps / proxies under the output root. */
|
||||
static void ClearGenerated(AVerticalPartitionVolume* Volume);
|
||||
|
||||
/** Write the report to Saved/VerticalPartition/<Map>_Report.txt and log it. */
|
||||
static FString DumpReport(const FVerticalPartitionBuildReport& Report, const FString& MapName);
|
||||
|
||||
private:
|
||||
// ---- pipeline steps ----
|
||||
static void GatherActors(AVerticalPartitionVolume* Volume, const FBox& VolumeBounds,
|
||||
TArray<FVerticalActorAssignment>& OutAssignments, FVerticalPartitionBuildReport& Report);
|
||||
|
||||
static void ClassifyActorWarnings(const FVerticalActorAssignment& A, const FVerticalPartitionSettings& S,
|
||||
FVerticalPartitionBuildReport& Report);
|
||||
|
||||
static UVerticalPartitionDescriptor* CreateOrLoadDescriptor(AVerticalPartitionVolume* Volume);
|
||||
|
||||
static void BuildCells(AVerticalPartitionVolume* Volume, const FBox& VolumeBounds,
|
||||
const TArray<FVerticalActorAssignment>& Assignments,
|
||||
UVerticalPartitionDescriptor* Descriptor, FVerticalPartitionBuildReport& Report);
|
||||
|
||||
/** Generate one proxy mesh for a cell from its static-mesh actors. Returns the
|
||||
* asset path or an empty path (with a warning) on failure / unavailable API. */
|
||||
static FSoftObjectPath GenerateHLODProxyForCell(const FVerticalCellId& Cell,
|
||||
const TArray<AActor*>& CellActors, const FVerticalPartitionSettings& S,
|
||||
const FString& PackageRoot, FVerticalPartitionBuildReport& Report);
|
||||
|
||||
static int64 ComputeContentHash(const TArray<FVerticalActorAssignment>& Assignments);
|
||||
static bool SaveAsset(UObject* Asset);
|
||||
};
|
||||
Reference in New Issue
Block a user