Standalone/ (C++20, MSVC /O2 /arch:AVX2 /fp:precise, Build.ps1): copied density pipeline, op stack, cave morphology, passages, strate manager/composer, noise, DetSinCos, mesher, clipmap selection, with a UE compatibility layer (Compat/). Owner data exported once to Standalone/data/owner_world.json by a default-off explore-commandlet exporter (the only plugin-source change). 25 cm voxels. Parity: seed 0, 3,436 samples (strate edges, negative/far coords, rooms, tunnels, passages, landings): bit-identical. Viewer: full 7-level clipmap, per-level toggles 1-7, T = round winding tunnels (standalone option), N/P seed, F wireframe. Timing NOT yet a baseline: 515 s for 12,054 tiles (L0 70 s, L6 296 s); the compat TMap/TSet are vector-backed with linear lookup, which the plugin's caches do not expect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
80 lines
2.9 KiB
C++
80 lines
2.9 KiB
C++
// Serialized strate-definition migrations.
|
|
|
|
#include "VoxelStrateDefinition.h"
|
|
|
|
#include "Serialization/CustomVersion.h"
|
|
#include "VoxelPassageGeometry.h"
|
|
|
|
namespace
|
|
{
|
|
// The field name is retained for package compatibility, but version 1 changes its meaning
|
|
// from a raw tangent/gradient to authored degrees. This GUID is local to the plugin.
|
|
const FGuid GVoxelForgeStrateSerializationVersion(
|
|
0xA76D5E31, 0x4B2C4F9A, 0xB8C1D204, 0x6E9F7738);
|
|
constexpr int32 GVoxelForgeStrateGentleSlopeDegreesVersion = 1;
|
|
FCustomVersionRegistration GVoxelForgeStrateSerializationRegistration(
|
|
GVoxelForgeStrateSerializationVersion,
|
|
GVoxelForgeStrateGentleSlopeDegreesVersion,
|
|
TEXT("VoxelForgeStrateSerialization"));
|
|
|
|
float LegacyGradientToDegrees(float LegacyGradient)
|
|
{
|
|
if (!VoxelMath::IsFinite(LegacyGradient) || LegacyGradient <= 0.0f)
|
|
{
|
|
return 0.0f;
|
|
}
|
|
if (LegacyGradient >= 4096.0f)
|
|
{
|
|
return VoxelPassageGeometry::TunnelFloorGentleSlopeMaximumDegrees;
|
|
}
|
|
|
|
// Invert the old gradient without atan/tan. The same deterministic sine/cosine helper
|
|
// used by generation makes this migration independent of the host CRT.
|
|
float LowDegrees = 0.0f;
|
|
float HighDegrees = VoxelPassageGeometry::TunnelFloorGentleSlopeMaximumDegrees;
|
|
for (int32 Iteration = 0; Iteration < 32; ++Iteration)
|
|
{
|
|
const float MidDegrees = (LowDegrees + HighDegrees) * 0.5f;
|
|
float SinValue = 0.0f;
|
|
float CosValue = 0.0f;
|
|
VoxelMath::DetSinCos(
|
|
SinValue, CosValue, MidDegrees * (PI / 180.0f));
|
|
const float MidGradient = FMath::Min(
|
|
FMath::Abs(SinValue) / FMath::Max(FMath::Abs(CosValue), 1.0e-3f),
|
|
4096.0f);
|
|
if (MidGradient < LegacyGradient)
|
|
{
|
|
LowDegrees = MidDegrees;
|
|
}
|
|
else
|
|
{
|
|
HighDegrees = MidDegrees;
|
|
}
|
|
}
|
|
return FMath::Clamp(
|
|
(LowDegrees + HighDegrees) * 0.5f,
|
|
0.0f,
|
|
VoxelPassageGeometry::TunnelFloorGentleSlopeMaximumDegrees);
|
|
}
|
|
}
|
|
|
|
void UVoxelStrateDefinition::PostLoad()
|
|
{
|
|
Super::PostLoad();
|
|
|
|
// The field remains reflected solely so old packages deserialize without shifting the
|
|
// following members. Tunnel geometry owns the floor now, so every serialized legacy value
|
|
// is normalized to the ignored compatibility default before any runtime copy is made.
|
|
GenerationParams.bTunnelFloorEnabled = true;
|
|
|
|
if (GetLinkerCustomVersion(GVoxelForgeStrateSerializationVersion)
|
|
>= GVoxelForgeStrateGentleSlopeDegreesVersion)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const float LegacyGradient = GenerationParams.TunnelFloorGentleSlopeThreshold;
|
|
GenerationParams.TunnelFloorGentleSlopeThreshold =
|
|
LegacyGradientToDegrees(LegacyGradient);
|
|
}
|