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>
90 lines
3.9 KiB
C++
90 lines
3.9 KiB
C++
// 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);
|
|
};
|