j
This commit is contained in:
@@ -3,15 +3,19 @@
|
||||
#include "VoxelAtmosphereManager.h"
|
||||
#include "VoxelStrateManager.h"
|
||||
#include "VoxelStrateDefinition.h"
|
||||
#include "VoxelBiomeDefinition.h"
|
||||
#include "VoxelGenerator.h"
|
||||
#include "VoxelTypes.h" // CHUNK_SIZE / VOXEL_SIZE
|
||||
#include "Components/ExponentialHeightFogComponent.h"
|
||||
#include "Components/SkyLightComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "Engine/World.h"
|
||||
|
||||
void UVoxelAtmosphereManager::Initialize(AActor* InOwner, UVoxelStrateManager* InStrateManager)
|
||||
void UVoxelAtmosphereManager::Initialize(AActor* InOwner, UVoxelStrateManager* InStrateManager, UVoxelGenerator* InGenerator)
|
||||
{
|
||||
Owner = InOwner;
|
||||
StrateManager = InStrateManager;
|
||||
Generator = InGenerator;
|
||||
|
||||
if (!InOwner) return;
|
||||
USceneComponent* Root = InOwner->GetRootComponent();
|
||||
@@ -41,11 +45,28 @@ void UVoxelAtmosphereManager::UpdateForPlayer(const FVector& PlayerWorldPos)
|
||||
const int32 Idx = StrateManager->GetStrateIndex(PlayerWorldPos.Z);
|
||||
const UVoxelStrateDefinition* Def = StrateManager->GetStrateAt(PlayerWorldPos.Z);
|
||||
|
||||
// React only when the player changes strate (cheap on every other frame).
|
||||
// Player's dominant biome (XY field) — atmosphere can vary by biome within a strate.
|
||||
// Convention matches GetStrateAt: world cm = voxel * VOXEL_SIZE (actor at origin/identity).
|
||||
const UVoxelBiomeDefinition* Biome = nullptr;
|
||||
if (Generator && Def)
|
||||
{
|
||||
const int32 ChunkZ = FMath::FloorToInt((PlayerWorldPos.Z / VOXEL_SIZE) / CHUNK_SIZE);
|
||||
Biome = Generator->GetDominantBiomeAt(PlayerWorldPos.X / VOXEL_SIZE,
|
||||
PlayerWorldPos.Y / VOXEL_SIZE, ChunkZ);
|
||||
}
|
||||
|
||||
// React on strate change (full apply) OR biome change within a strate (fog/sky only —
|
||||
// layer actors + atmosphere BP are strate-level). Cheap no-op otherwise.
|
||||
if (Idx != CurrentStrateIndex)
|
||||
{
|
||||
CurrentStrateIndex = Idx;
|
||||
ApplyStrate(Def);
|
||||
CurrentBiome = Biome;
|
||||
ApplyStrate(Def, Biome);
|
||||
}
|
||||
else if (Biome != CurrentBiome.Get())
|
||||
{
|
||||
CurrentBiome = Biome;
|
||||
ApplyFogSky(Def, Biome);
|
||||
}
|
||||
|
||||
// Anchor the full-atmosphere BP to the player (so any localized volumes/effects
|
||||
@@ -78,7 +99,54 @@ void UVoxelAtmosphereManager::UpdateForPlayer(const FVector& PlayerWorldPos)
|
||||
}
|
||||
}
|
||||
|
||||
void UVoxelAtmosphereManager::ApplyStrate(const UVoxelStrateDefinition* Def)
|
||||
void UVoxelAtmosphereManager::ApplyFogSky(const UVoxelStrateDefinition* Def, const UVoxelBiomeDefinition* Biome)
|
||||
{
|
||||
// A strate's full atmosphere BP owns the entire look — managed fog/sky stay off.
|
||||
const bool bUseOverride = (Def && Def->AtmosphereActor);
|
||||
|
||||
// Biome retint beats the strate's fog/sky when the biome opts in.
|
||||
const bool bBiome = (Biome && Biome->bOverrideAtmosphere);
|
||||
const FLinearColor FogCol = bBiome ? Biome->FogColor : (Def ? Def->FogColor : FLinearColor::Black);
|
||||
const float FogDen = bBiome ? Biome->FogDensity : (Def ? Def->FogDensity : 0.0f);
|
||||
const FLinearColor AmbCol = bBiome ? Biome->AmbientLightColor : (Def ? Def->AmbientLightColor : FLinearColor::Black);
|
||||
const float AmbInt = bBiome ? Biome->AmbientLightIntensity : (Def ? Def->AmbientLightIntensity : 0.0f);
|
||||
const bool bVol = Def ? Def->bVolumetricFog : false;
|
||||
|
||||
// ── Managed fog (only when NOT overridden by a full atmosphere BP) ──
|
||||
if (Fog)
|
||||
{
|
||||
if (!bUseOverride && FogDen > 0.0f)
|
||||
{
|
||||
Fog->SetVisibility(true);
|
||||
// FogDensity is authored 0..1; EHF density is tiny — scale into a sane range.
|
||||
Fog->SetFogDensity(FogDen * 0.05f);
|
||||
Fog->SetFogInscatteringColor(FogCol);
|
||||
Fog->SetVolumetricFog(bVol);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fog->SetVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Managed ambient skylight (only when NOT overridden) ──
|
||||
if (Sky)
|
||||
{
|
||||
if (!bUseOverride && Def)
|
||||
{
|
||||
Sky->SetIntensity(AmbInt);
|
||||
Sky->SetLightColor(AmbCol);
|
||||
Sky->SetLowerHemisphereColor(AmbCol);
|
||||
Sky->RecaptureSky();
|
||||
}
|
||||
else
|
||||
{
|
||||
Sky->SetIntensity(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UVoxelAtmosphereManager::ApplyStrate(const UVoxelStrateDefinition* Def, const UVoxelBiomeDefinition* Biome)
|
||||
{
|
||||
AActor* O = Owner.Get();
|
||||
UWorld* W = O ? O->GetWorld() : nullptr;
|
||||
@@ -98,38 +166,8 @@ void UVoxelAtmosphereManager::ApplyStrate(const UVoxelStrateDefinition* Def)
|
||||
AtmosphereActorInstance = W->SpawnActor<AActor>(Def->AtmosphereActor, FTransform::Identity, Params);
|
||||
}
|
||||
|
||||
// ── Managed fog (only when NOT overridden) ──
|
||||
if (Fog)
|
||||
{
|
||||
if (!bUseOverride && Def && Def->FogDensity > 0.0f)
|
||||
{
|
||||
Fog->SetVisibility(true);
|
||||
// FogDensity is authored 0..1; EHF density is tiny — scale into a sane range.
|
||||
Fog->SetFogDensity(Def->FogDensity * 0.05f);
|
||||
Fog->SetFogInscatteringColor(Def->FogColor);
|
||||
Fog->SetVolumetricFog(Def->bVolumetricFog);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fog->SetVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Managed ambient skylight (only when NOT overridden) ──
|
||||
if (Sky)
|
||||
{
|
||||
if (!bUseOverride && Def)
|
||||
{
|
||||
Sky->SetIntensity(Def->AmbientLightIntensity);
|
||||
Sky->SetLightColor(Def->AmbientLightColor);
|
||||
Sky->SetLowerHemisphereColor(Def->AmbientLightColor);
|
||||
Sky->RecaptureSky();
|
||||
}
|
||||
else
|
||||
{
|
||||
Sky->SetIntensity(0.0f);
|
||||
}
|
||||
}
|
||||
// ── Managed fog + ambient skylight (biome-aware) ──
|
||||
ApplyFogSky(Def, Biome);
|
||||
|
||||
// ── Ceiling / floor layer actors — destroy old, spawn new for this strate ──
|
||||
// (Independent of the override — you can have cloud seas with either fog path.)
|
||||
@@ -155,5 +193,6 @@ void UVoxelAtmosphereManager::Reset()
|
||||
if (CeilingActor) { CeilingActor->Destroy(); CeilingActor = nullptr; }
|
||||
if (FloorActor) { FloorActor->Destroy(); FloorActor = nullptr; }
|
||||
CurrentStrateIndex = INT32_MIN;
|
||||
CurrentBiome = nullptr;
|
||||
if (Fog) Fog->SetVisibility(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user