Files
vertical-partition-system-p…/Source/VerticalPartition/Private/VerticalPartitionVolume.cpp
Bonchellon 04ad6d3f25 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>
2026-06-30 17:42:41 +03:00

72 lines
3.3 KiB
C++

// Copyright IHY. Vertical Partition Streaming plugin.
#include "VerticalPartitionVolume.h"
#include "VerticalPartitionSettings.h"
#include "VerticalPartitionLog.h"
#include "Components/BoxComponent.h"
#if WITH_EDITOR
TFunction<void(AVerticalPartitionVolume*, EVerticalPartitionAction)> FVerticalPartitionEditorBridge::Handler;
#endif
AVerticalPartitionVolume::AVerticalPartitionVolume()
{
PrimaryActorTick.bCanEverTick = false;
Box = CreateDefaultSubobject<UBoxComponent>(TEXT("Bounds"));
SetRootComponent(Box);
Box->SetBoxExtent(FVector(5000.f, 5000.f, 25000.f));
Box->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Box->SetCollisionProfileName(TEXT("NoCollision"));
Box->SetGenerateOverlapEvents(false);
Box->ShapeColor = FColor(80, 200, 255);
Box->bDrawOnlyIfSelected = false;
Box->SetHiddenInGame(true);
// Seed per-volume settings from project defaults.
if (const UVerticalPartitionDeveloperSettings* Project = UVerticalPartitionDeveloperSettings::Get())
{
Settings = Project->DefaultSettings;
}
}
FBox AVerticalPartitionVolume::GetVolumeBounds() const
{
if (!Box)
{
return FBox(ForceInit);
}
const FVector Extent = Box->GetScaledBoxExtent();
const FVector Origin = Box->GetComponentLocation();
return FBox(Origin - Extent, Origin + Extent);
}
void AVerticalPartitionVolume::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
}
#if WITH_EDITOR
void AVerticalPartitionVolume::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
// Keep preview drawing fresh when ranges/segmentation change.
if (Box)
{
Box->MarkRenderStateDirty();
}
}
void AVerticalPartitionVolume::AnalyzeCurrentLevel() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::Analyze); }
void AVerticalPartitionVolume::BuildVerticalPartition(){ FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::Build); }
void AVerticalPartitionVolume::RebuildChangedCells() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::RebuildChangedCells); }
void AVerticalPartitionVolume::RebuildHLOD() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::RebuildHLOD); }
void AVerticalPartitionVolume::ValidateCells() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::Validate); }
void AVerticalPartitionVolume::PreviewChunks() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::PreviewChunks); }
void AVerticalPartitionVolume::SpawnHLODPreview() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::SpawnHLODPreview); }
void AVerticalPartitionVolume::ClearPreview() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::ClearPreview); }
void AVerticalPartitionVolume::CommitConversion() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::Commit); }
void AVerticalPartitionVolume::RestoreFromBackup() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::RestoreBackup); }
void AVerticalPartitionVolume::ClearGeneratedData() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::ClearGenerated); }
void AVerticalPartitionVolume::DumpReport() { FVerticalPartitionEditorBridge::Execute(this, EVerticalPartitionAction::DumpReport); }
#endif