wip(assembler): round S1 -- one Core voxel-size source; per-tile feature lists (islands)
AVoxelWorld::CoreVoxelSizeCm (default 25, 32 voxels/tile) flows through plan, field, mesher, content, water, atmosphere, edits and collision. Staged-owner BuildHost passes at 20 cm (SurfaceWorld + islands, W1/W8/W16, anchors, BP edits, collision) with a fixed-25cm negative control; default-size hashes match round 4; Core off stays legacy 12.5 cm. Reusable BuildWorldAssemblyFeatureTileListV1; wired into FloatingIslands only so far. 256-island stress: tile p95 112.5 -> 2.0 ms, 0 mismatches, dropped-feature control fails. Content placement measured (no populated cells): island ground search 7.25 ms/cell vs legacy 0.29 ms -- open. Outside-review evaluation in Round5/REPORT.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
111cf3d262
commit
d6e69420e8
25 files changed
+2136
-250
No files matched your search
@@ -337,12 +337,13 @@ namespace
|
||||
|
||||
const int32 LOD = static_cast<int32>(Mesh.key.lod);
|
||||
const VoxelForgeCore::WorldConfiguration& Configuration = World.configuration();
|
||||
const double CoreVoxelSizeCm = static_cast<double>(Configuration.voxelSizeMicrons) / 10000.0;
|
||||
const int32 ExtentVoxels = CHUNK_SIZE << FMath::Clamp(LOD, 0, 20);
|
||||
const int32 Cells = LOD < Configuration.fullResolutionLodCount
|
||||
? CHUNK_SIZE : FMath::Max(1, Configuration.coarseTileCells);
|
||||
const double Step = static_cast<double>(FMath::Max(1, ExtentVoxels / Cells));
|
||||
const int32 StepVoxels = FMath::Max(1, FMath::RoundToInt(Step));
|
||||
const double CellWorldCm = 25.0 * Step;
|
||||
const double CellWorldCm = CoreVoxelSizeCm * Step;
|
||||
// Les coutures lointaines peuvent depasser deux cellules en plan sans former une pointe verticale.
|
||||
// Far LOD transitions can span slightly over two horizontal cells without creating a vertical spike.
|
||||
const double MaxEdgeCellMultiple = LOD >= 7 ? 4.0 : 2.0;
|
||||
@@ -488,13 +489,13 @@ namespace
|
||||
// The full-resolution field does not represent the decimated far-LOD surface.
|
||||
const double NormalOffsetVoxels = std::min(0.5 * Step, 1.0);
|
||||
const VoxelForgeCore::Vec3d Positive{
|
||||
Vertex.position.x / 25.0 + NX * NormalOffsetVoxels,
|
||||
Vertex.position.y / 25.0 + NY * NormalOffsetVoxels,
|
||||
Vertex.position.z / 25.0 + NZ * NormalOffsetVoxels};
|
||||
Vertex.position.x / CoreVoxelSizeCm + NX * NormalOffsetVoxels,
|
||||
Vertex.position.y / CoreVoxelSizeCm + NY * NormalOffsetVoxels,
|
||||
Vertex.position.z / CoreVoxelSizeCm + NZ * NormalOffsetVoxels};
|
||||
const VoxelForgeCore::Vec3d Negative{
|
||||
Vertex.position.x / 25.0 - NX * NormalOffsetVoxels,
|
||||
Vertex.position.y / 25.0 - NY * NormalOffsetVoxels,
|
||||
Vertex.position.z / 25.0 - NZ * NormalOffsetVoxels};
|
||||
Vertex.position.x / CoreVoxelSizeCm - NX * NormalOffsetVoxels,
|
||||
Vertex.position.y / CoreVoxelSizeCm - NY * NormalOffsetVoxels,
|
||||
Vertex.position.z / CoreVoxelSizeCm - NZ * NormalOffsetVoxels};
|
||||
const float PositiveDensity = World.densityAt(Positive);
|
||||
const float NegativeDensity = World.densityAt(Negative);
|
||||
if (PositiveDensity + 0.01f < NegativeDensity)
|
||||
@@ -520,7 +521,7 @@ namespace
|
||||
OutAudit.Tile = FIntVector(static_cast<int32>(Mesh.key.coordinate.x),
|
||||
static_cast<int32>(Mesh.key.coordinate.y),
|
||||
static_cast<int32>(Mesh.key.coordinate.z));
|
||||
OutAudit.ExpectedTileSpanCm = static_cast<double>(ExtentVoxels) * 25.0;
|
||||
OutAudit.ExpectedTileSpanCm = static_cast<double>(ExtentVoxels) * CoreVoxelSizeCm;
|
||||
OutAudit.CellWorldCm = CellWorldCm;
|
||||
OutAudit.SpanXcm = MaxX - MinX;
|
||||
OutAudit.SpanYcm = MaxY - MinY;
|
||||
@@ -798,6 +799,7 @@ struct FExploreArguments
|
||||
FString SettingsReference;
|
||||
FString CoreWorldAssemblyManifestPath;
|
||||
int32 CoreHybridMesherVersion = 0;
|
||||
float CoreVoxelSizeCm = 25.0f;
|
||||
bool bCoreHybridMesher = false;
|
||||
bool bCoreHybridMesherV2 = false;
|
||||
bool bCoreHybridFixturePlacement = false;
|
||||
@@ -921,6 +923,14 @@ bool ParseArguments(const FString& Params, FExploreArguments& OutArguments, FStr
|
||||
int32 CoreWorldTest = 0;
|
||||
FParse::Value(*Params, TEXT("coreworldtest="), CoreWorldTest);
|
||||
OutArguments.bCoreWorldTest = CoreWorldTest != 0;
|
||||
FParse::Value(*Params, TEXT("corevoxelsizecm="), OutArguments.CoreVoxelSizeCm);
|
||||
if (!FMath::IsFinite(OutArguments.CoreVoxelSizeCm)
|
||||
|| OutArguments.CoreVoxelSizeCm < VOXEL_SIZE
|
||||
|| OutArguments.CoreVoxelSizeCm > 2.0f * VOXEL_SIZE)
|
||||
{
|
||||
OutError = TEXT("corevoxelsizecm must be between one and two legacy voxel widths.");
|
||||
return false;
|
||||
}
|
||||
int32 CoreFloatingIslandTest = 0;
|
||||
FParse::Value(*Params, TEXT("coreislandtest="), CoreFloatingIslandTest);
|
||||
OutArguments.bCoreFloatingIslandTest = CoreFloatingIslandTest != 0;
|
||||
@@ -14909,9 +14919,9 @@ bool RunCorePlanOnlyTest(const FExploreArguments& Arguments, FString& OutError)
|
||||
FString RuntimeJson;
|
||||
FString RepeatJson;
|
||||
if (!VoxelForgeCoreAdapter::SerializeResolvedWorld(
|
||||
PlanSettings, PlanManager.Get(), 3, 8, RuntimeJson, OutError)
|
||||
PlanSettings, PlanManager.Get(), 3, 8, Arguments.CoreVoxelSizeCm, RuntimeJson, OutError)
|
||||
|| !VoxelForgeCoreAdapter::SerializeResolvedWorld(
|
||||
PlanSettings, PlanManager.Get(), 3, 8, RepeatJson, OutError))
|
||||
PlanSettings, PlanManager.Get(), 3, 8, Arguments.CoreVoxelSizeCm, RepeatJson, OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -15137,6 +15147,9 @@ bool RunCoreOffActorTest(const FExploreArguments& Arguments, FString& OutError)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RunCoreContentPlacementCostAudit(AVoxelWorld* Actor, const FVector& CoreLocalProbeCm,
|
||||
const TCHAR* Label, FString& OutError);
|
||||
|
||||
bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
const FExploreArguments& Arguments, FString& OutError)
|
||||
{
|
||||
@@ -15237,7 +15250,7 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
|
||||
FString RuntimeJson;
|
||||
if (!VoxelForgeCoreAdapter::SerializeResolvedWorld(
|
||||
TestSettings.Get(), Manager.Get(), 3, 8, RuntimeJson, OutError))
|
||||
TestSettings.Get(), Manager.Get(), 3, 8, Arguments.CoreVoxelSizeCm, RuntimeJson, OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -15287,18 +15300,19 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
const VoxelForgeCore::WorldAssemblyRoutePointV1& StartRoute =
|
||||
NativeIslandPlan.manifest.plan.route.front();
|
||||
constexpr double SubvoxelsPerCoreVoxel = 256.0;
|
||||
constexpr double CoreVoxelSizeCm = 25.0;
|
||||
const double CoreVoxelSizeCm = Arguments.CoreVoxelSizeCm;
|
||||
const FVector CameraVoxels(
|
||||
static_cast<double>(StartRoute.positionSubvoxels[0]) / SubvoxelsPerCoreVoxel,
|
||||
static_cast<double>(StartRoute.positionSubvoxels[1]) / SubvoxelsPerCoreVoxel,
|
||||
static_cast<double>(StartRoute.positionSubvoxels[2]) / SubvoxelsPerCoreVoxel);
|
||||
const FVector CameraLocalCm = CameraVoxels * CoreVoxelSizeCm;
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreIslandTest] plan_generated=PASS hash=%016llx recipe_hash=%016llx plan_hash=%016llx seed=%d strate=%d owner_bounds=[%d,%d] scale_owner_cm=12.5 scale_core_cm=25 islands=%d connectors=%d route_segments=%llu route_clearance_subvoxels=%lld water_fixed=%d"),
|
||||
TEXT("[VoxelForgeCoreIslandTest] plan_generated=PASS hash=%016llx recipe_hash=%016llx plan_hash=%016llx seed=%d strate=%d owner_bounds=[%d,%d] scale_owner_cm=%.3f scale_core_cm=%.3f islands=%d connectors=%d route_segments=%llu route_clearance_subvoxels=%lld water_fixed=%d"),
|
||||
static_cast<unsigned long long>(NativeAssembly.contentHash),
|
||||
static_cast<unsigned long long>(NativeIslandPlan.manifest.recipe.contentHash),
|
||||
static_cast<unsigned long long>(NativeIslandPlan.manifest.plan.contentHash),
|
||||
EffectiveSeed, IslandStrateIndex, IslandSlot->TopChunkZ, IslandSlot->BottomChunkZ,
|
||||
static_cast<double>(VOXEL_SIZE), CoreVoxelSizeCm,
|
||||
static_cast<int32>(NativeIslandPlan.manifest.plan.islands.size()),
|
||||
static_cast<int32>(NativeIslandPlan.manifest.plan.clusterEdges.size()),
|
||||
static_cast<unsigned long long>(RouteAudit.segmentsTested),
|
||||
@@ -15740,6 +15754,7 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
Actor->Settings = TestSettings.Get();
|
||||
Actor->bManageAtmosphere = true;
|
||||
Actor->bUseVoxelForgeCore = true;
|
||||
Actor->CoreVoxelSizeCm = Arguments.CoreVoxelSizeCm;
|
||||
Actor->CoreMesherRecipe = EVoxelForgeCoreMesherRecipe::MarchingCubesV1;
|
||||
Actor->CoreClipRadius = 3;
|
||||
Actor->CoreMaxClipLevel = 8;
|
||||
@@ -15763,7 +15778,8 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
FString ActorRuntimeJson;
|
||||
FString ActorRuntimeError;
|
||||
const bool bActorRuntimeSerialized = VoxelForgeCoreAdapter::SerializeResolvedWorld(
|
||||
Actor->Settings, Actor->StrateManager, 3, 8, ActorRuntimeJson, ActorRuntimeError);
|
||||
Actor->Settings, Actor->StrateManager, 3, 8, Actor->CoreVoxelSizeCm,
|
||||
ActorRuntimeJson, ActorRuntimeError);
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreIslandTest] world_initialized=1 core=1 actor_initialized=%d player=(%.1f,%.1f,%.1f) possessed=(%.1f,%.1f,%.1f) snapshot_parity=%d expected_bytes=%d actor_bytes=%d"),
|
||||
Actor->IsActorInitialized() ? 1 : 0,
|
||||
@@ -16020,23 +16036,23 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
Actor->CollisionReadyTiles.Num(), Actor->CollisionNotRequiredTiles.Num(),
|
||||
Lod0Tiles, Lod1Tiles, TransitionFaces);
|
||||
|
||||
const auto LocalPointFromSubvoxels = [](const std::int64_t Position[3])
|
||||
const auto LocalPointFromSubvoxels = [CoreVoxelSizeCm](const std::int64_t Position[3])
|
||||
{
|
||||
return FVector(
|
||||
static_cast<double>(Position[0]) * 25.0 / 256.0,
|
||||
static_cast<double>(Position[1]) * 25.0 / 256.0,
|
||||
static_cast<double>(Position[2]) * 25.0 / 256.0);
|
||||
static_cast<double>(Position[0]) * CoreVoxelSizeCm / 256.0,
|
||||
static_cast<double>(Position[1]) * CoreVoxelSizeCm / 256.0,
|
||||
static_cast<double>(Position[2]) * CoreVoxelSizeCm / 256.0);
|
||||
};
|
||||
const FVector IslandTopXY = LocalPointFromSubvoxels(
|
||||
NativeIslandPlan.manifest.plan.islands.front().centerSubvoxels.data());
|
||||
const auto& Connector = NativeIslandPlan.manifest.plan.clusterEdges.front();
|
||||
const FVector SpanXY(
|
||||
(static_cast<double>(Connector.startSubvoxels[0] + Connector.endSubvoxels[0]) * 0.5)
|
||||
* 25.0 / 256.0,
|
||||
* CoreVoxelSizeCm / 256.0,
|
||||
(static_cast<double>(Connector.startSubvoxels[1] + Connector.endSubvoxels[1]) * 0.5)
|
||||
* 25.0 / 256.0,
|
||||
* CoreVoxelSizeCm / 256.0,
|
||||
(static_cast<double>(Connector.startSubvoxels[2] + Connector.endSubvoxels[2]) * 0.5)
|
||||
* 25.0 / 256.0);
|
||||
* CoreVoxelSizeCm / 256.0);
|
||||
float IslandContentGroundCm = 0.0f;
|
||||
float SpanContentGroundCm = 0.0f;
|
||||
if (Actor->ContentManager == nullptr
|
||||
@@ -16147,7 +16163,7 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
return false;
|
||||
}
|
||||
const FVector LocalHit = Actor->GetActorTransform().InverseTransformPosition(Hit.ImpactPoint);
|
||||
constexpr double CoreTileExtentCm = 32.0 * 25.0;
|
||||
const double CoreTileExtentCm = static_cast<double>(CHUNK_SIZE) * Arguments.CoreVoxelSizeCm;
|
||||
const FVoxelTileKey Tile(FIntVector(
|
||||
FMath::FloorToInt(LocalHit.X / CoreTileExtentCm),
|
||||
FMath::FloorToInt(LocalHit.Y / CoreTileExtentCm),
|
||||
@@ -16202,7 +16218,8 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
return false;
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreIslandTest] blueprint_edit=PASS carve_sign=air fill_sign=solid radius_legacy_voxels=6 radius_cm=75 strength_legacy=10 density_before=%.4f carved=%.4f filled=%.4f outside_90cm_delta=%.6f"),
|
||||
TEXT("[VoxelForgeCoreIslandTest] blueprint_edit=PASS carve_sign=air fill_sign=solid radius_legacy_voxels=6 radius_cm=%.3f strength_legacy=10 density_before=%.4f carved=%.4f filled=%.4f outside_90cm_delta=%.6f"),
|
||||
6.0 * static_cast<double>(VOXEL_SIZE),
|
||||
DensityBefore, CarvedDensity, FilledDensity,
|
||||
FMath::Abs(OutsideAfterFill - OutsideBefore));
|
||||
|
||||
@@ -16231,10 +16248,89 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
*CoreSeasonHash, *LegacySeasonHash, VOXEL_SIZE,
|
||||
LegacyDensityBeforeSwitch, LegacyDensityAfterSwitch);
|
||||
|
||||
if (!RunCoreContentPlacementCostAudit(Actor,
|
||||
FVector(IslandTopXY.X, IslandTopXY.Y, IslandContentGroundCm + 100.0f),
|
||||
TEXT("FloatingIslands"), OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UE_LOG(LogTemp, Display, TEXT("[VoxelForgeCoreIslandTest] pass complete=1"));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RunCoreContentPlacementCostAudit(AVoxelWorld* Actor, const FVector& CoreLocalProbeCm,
|
||||
const TCHAR* Label, FString& OutError)
|
||||
{
|
||||
if (Actor == nullptr || Actor->ContentManager == nullptr)
|
||||
{
|
||||
OutError = TEXT("Content placement cost audit has no owner actor or content manager.");
|
||||
return false;
|
||||
}
|
||||
constexpr int32 SampleCells = 64;
|
||||
constexpr int32 SampleFrames = 32;
|
||||
const float CoreVoxelSizeCm = Actor->CoreVoxelSizeCm;
|
||||
const FTransform OwnerXf = Actor->GetActorTransform();
|
||||
|
||||
UVoxelContentManager::FDecorationPlacementCostAudit CoreAudit;
|
||||
Actor->bUseVoxelForgeCore = true;
|
||||
const FVector CorePlayerWorld = OwnerXf.TransformPosition(CoreLocalProbeCm);
|
||||
if (!Actor->ContentManager->MeasurePlacementCostForValidation(
|
||||
CorePlayerWorld, SampleCells, SampleFrames, CoreAudit, OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UVoxelContentManager::FDecorationPlacementCostAudit LegacyAudit;
|
||||
Actor->bUseVoxelForgeCore = false;
|
||||
const float CoreToOwnerScale = VOXEL_SIZE / CoreVoxelSizeCm;
|
||||
const FVector LegacyPlayerWorld = OwnerXf.TransformPosition(CoreLocalProbeCm * CoreToOwnerScale);
|
||||
if (!Actor->ContentManager->MeasurePlacementCostForValidation(
|
||||
LegacyPlayerWorld, SampleCells, SampleFrames, LegacyAudit, OutError))
|
||||
{
|
||||
Actor->bUseVoxelForgeCore = true;
|
||||
return false;
|
||||
}
|
||||
Actor->bUseVoxelForgeCore = true;
|
||||
|
||||
if (CoreAudit.bSyntheticWorkload && CoreAudit.AnchorChecks > 0
|
||||
&& (CoreAudit.MaximumAnchorErrorCm > 0.5 || CoreAudit.MaximumDensityResidual > 0.25))
|
||||
{
|
||||
OutError = FString::Printf(
|
||||
TEXT("Core synthetic decoration anchors drifted: height_error_cm=%.6f density_residual=%.6f."),
|
||||
CoreAudit.MaximumAnchorErrorCm, CoreAudit.MaximumDensityResidual);
|
||||
return false;
|
||||
}
|
||||
if (LegacyAudit.bSyntheticWorkload && LegacyAudit.AnchorChecks > 0
|
||||
&& LegacyAudit.MaximumDensityResidual > 0.25)
|
||||
{
|
||||
OutError = FString::Printf(
|
||||
TEXT("Legacy synthetic decoration anchors drifted: density_residual=%.6f."),
|
||||
LegacyAudit.MaximumDensityResidual);
|
||||
return false;
|
||||
}
|
||||
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeContentCost] label=%s route=core voxel_cm=%.3f tile_cell_cm=%.3f authored_entries=%d synthetic=%d cells=%d columns_per_cell=%d density_queries_per_cell=%.2f surface_queries_per_cell=%.2f cell_median_ms=%.5f cell_p95_ms=%.5f update_median_ms=%.5f update_p95_ms=%.5f placements=%d anchor_checks=%d max_anchor_error_cm=%.6f max_density_residual=%.6f"),
|
||||
Label, CoreVoxelSizeCm, CHUNK_SIZE * CoreVoxelSizeCm,
|
||||
CoreAudit.NearEntries + CoreAudit.FarEntries, CoreAudit.bSyntheticWorkload ? 1 : 0,
|
||||
CoreAudit.SampledCells, CoreAudit.ColumnsPerCell, CoreAudit.DensityQueriesPerCell,
|
||||
CoreAudit.SurfaceQueriesPerCell, CoreAudit.CellMedianMilliseconds,
|
||||
CoreAudit.CellP95Milliseconds, CoreAudit.UpdateMedianMilliseconds,
|
||||
CoreAudit.UpdateP95Milliseconds, CoreAudit.Placements, CoreAudit.AnchorChecks,
|
||||
CoreAudit.MaximumAnchorErrorCm, CoreAudit.MaximumDensityResidual);
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeContentCost] label=%s route=legacy voxel_cm=%.3f tile_cell_cm=%.3f authored_entries=%d synthetic=%d cells=%d columns_per_cell=%d density_queries_per_cell=%.2f surface_queries_per_cell=%.2f cell_median_ms=%.5f cell_p95_ms=%.5f update_median_ms=%.5f update_p95_ms=%.5f placements=%d anchor_checks=%d max_anchor_error_cm=%.6f max_density_residual=%.6f"),
|
||||
Label, VOXEL_SIZE, CHUNK_SIZE * VOXEL_SIZE,
|
||||
LegacyAudit.NearEntries + LegacyAudit.FarEntries, LegacyAudit.bSyntheticWorkload ? 1 : 0,
|
||||
LegacyAudit.SampledCells, LegacyAudit.ColumnsPerCell, LegacyAudit.DensityQueriesPerCell,
|
||||
LegacyAudit.SurfaceQueriesPerCell, LegacyAudit.CellMedianMilliseconds,
|
||||
LegacyAudit.CellP95Milliseconds, LegacyAudit.UpdateMedianMilliseconds,
|
||||
LegacyAudit.UpdateP95Milliseconds, LegacyAudit.Placements, LegacyAudit.AnchorChecks,
|
||||
LegacyAudit.MaximumAnchorErrorCm, LegacyAudit.MaximumDensityResidual);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FString& OutError)
|
||||
{
|
||||
if (Arguments.bCoreFloatingIslandTest)
|
||||
@@ -16349,7 +16445,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
}
|
||||
FString Json;
|
||||
if (!VoxelForgeCoreAdapter::SerializeResolvedWorld(
|
||||
AuthoredSettings, Manager.Get(), 3, 8, Json, OutError))
|
||||
AuthoredSettings, Manager.Get(), 3, 8, Arguments.CoreVoxelSizeCm, Json, OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -16373,7 +16469,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
FVector CarveLocalPositionCm = FVector::ZeroVector;
|
||||
FVoxelTileKey CarveTargetTile;
|
||||
constexpr float CarveBrushRadiusLegacyVoxels = 6.0f;
|
||||
constexpr double CoreVoxelSizeCm = 25.0;
|
||||
const double CoreVoxelSizeCm = Arguments.CoreVoxelSizeCm;
|
||||
const double CarveBrushRadiusCoreVoxels =
|
||||
CarveBrushRadiusLegacyVoxels * static_cast<double>(VOXEL_SIZE) / CoreVoxelSizeCm;
|
||||
const int32 CollisionRadius = FMath::Clamp(AuthoredSettings->PawnCollisionRadiusChunks, 1, 4);
|
||||
@@ -16857,7 +16953,18 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
Brush.halfExtent = {5.0, 5.0, 5.0};
|
||||
Brush.radius = CarveBrushRadiusCoreVoxels;
|
||||
Brush.falloff = 2.0f;
|
||||
Brush.strength = 5.0f;
|
||||
const double ExpectedCoreBrushStrength = 10.0 * VOXEL_SIZE / CoreVoxelSizeCm;
|
||||
Brush.strength = static_cast<float>(ExpectedCoreBrushStrength);
|
||||
if (!FMath::IsNearlyEqual(CoreVoxelSizeCm, 25.0, 0.000001)
|
||||
&& FMath::IsNearlyEqual(ExpectedCoreBrushStrength, 5.0, 0.000001))
|
||||
{
|
||||
OutError = TEXT("Non-default Core voxel size reused the fixed 25 cm carve strength.");
|
||||
return false;
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreWorldTest] carve_scale_control=PASS legacy_fixed_strength=5.000 dynamic_strength=%.3f stale_default_control_detected=%d"),
|
||||
ExpectedCoreBrushStrength,
|
||||
FMath::IsNearlyEqual(ExpectedCoreBrushStrength, 5.0, 0.000001) ? 0 : 1);
|
||||
Transaction.brushes.push_back(Brush);
|
||||
const std::optional<VoxelForgeCore::EditResult> Edit =
|
||||
ReferenceWorld.applyEditTransaction(Transaction, Desired, CoreError);
|
||||
@@ -17112,7 +17219,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
BestSpanGeometryAuditL0 = Candidate;
|
||||
}
|
||||
}
|
||||
if (SpanRatioX >= 0.75 && SpanRatioY >= 0.75
|
||||
if (SpanRatioX >= 0.95 && SpanRatioY >= 0.95
|
||||
&& SpanRatioX <= 1.05 && SpanRatioY <= 1.05)
|
||||
{
|
||||
if (LOD == 0 && Distance < GeometryAuditL0Distance)
|
||||
@@ -17188,6 +17295,21 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
HorizonAuditLOD, GeometryAuditHorizon.bValid ? 1 : 0);
|
||||
return false;
|
||||
}
|
||||
if (!FMath::IsNearlyEqual(Arguments.CoreVoxelSizeCm, 25.0f, 0.0001f))
|
||||
{
|
||||
const double StaleDefault25CmSpan = static_cast<double>(CHUNK_SIZE) * 25.0;
|
||||
const bool bFixed25CmControlWouldFail =
|
||||
!FMath::IsNearlyEqual(GeometryAuditL0.SpanXcm, StaleDefault25CmSpan, 0.1)
|
||||
|| !FMath::IsNearlyEqual(GeometryAuditL0.SpanYcm, StaleDefault25CmSpan, 0.1);
|
||||
if (!bFixed25CmControlWouldFail)
|
||||
{
|
||||
OutError = TEXT("The injected fixed-25-cm geometry negative control was not detected.");
|
||||
return false;
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreWorldTest] geometry_scale_negative_control=DETECTED injected_fixed_voxel_cm=25 expected_tile_span_cm=%.1f actual_span_cm=(%.1f,%.1f)"),
|
||||
StaleDefault25CmSpan, GeometryAuditL0.SpanXcm, GeometryAuditL0.SpanYcm);
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreWorldTest] geometry_scale_agreement=PASS legacy_default_cm=%.1f core_voxel_cm=%.1f "
|
||||
"pre_fix_scale_ratio=%.4f lod0_expected_cm=%.1f span_cm=(%.1f,%.1f) ratio=(%.4f,%.4f) max_edge_cm=%.2f normal_samples=%d normal_mismatches=%d rmesh_reversed_winding=%d/%d skirts_excluded=%d "
|
||||
@@ -17531,6 +17653,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
Actor->Settings = AuthoredSettings;
|
||||
Actor->bManageAtmosphere = false;
|
||||
Actor->bUseVoxelForgeCore = true;
|
||||
Actor->CoreVoxelSizeCm = Arguments.CoreVoxelSizeCm;
|
||||
Actor->CoreMesherRecipe = Arguments.CoreHybridMesherVersion == 2
|
||||
? EVoxelForgeCoreMesherRecipe::WorldAssemblerHybridV2
|
||||
: (Arguments.CoreHybridMesherVersion == 1
|
||||
@@ -17555,6 +17678,23 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
: TEXT("MarchingCubesV1")),
|
||||
TestWorld->HasBegunPlay() ? 1 : 0, Actor->IsActorInitialized() ? 1 : 0,
|
||||
Actor->HasActorBegunPlay() ? 1 : 0);
|
||||
const float ActiveCoreVoxelSizeCm = Actor->CoreVoxelSizeCm;
|
||||
const FString ActiveSeasonIdentity = Actor->GetCurrentSeasonContentHash();
|
||||
const float AlternateCoreVoxelSizeCm = FMath::IsNearlyEqual(ActiveCoreVoxelSizeCm, 25.0f, 0.0001f)
|
||||
? 20.0f : 25.0f;
|
||||
Actor->CoreVoxelSizeCm = AlternateCoreVoxelSizeCm;
|
||||
const FString AlternateSeasonIdentity = Actor->GetCurrentSeasonContentHash();
|
||||
Actor->CoreVoxelSizeCm = ActiveCoreVoxelSizeCm;
|
||||
if (ActiveSeasonIdentity.IsEmpty() || AlternateSeasonIdentity.IsEmpty()
|
||||
|| ActiveSeasonIdentity == AlternateSeasonIdentity)
|
||||
{
|
||||
OutError = TEXT("Core voxel size did not distinguish the hashed season/world identity.");
|
||||
return false;
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreWorldTest] voxel_size_identity=PASS active_cm=%.3f active_hash=%s alternate_cm=%.3f alternate_hash=%s distinct=1"),
|
||||
ActiveCoreVoxelSizeCm, *ActiveSeasonIdentity, AlternateCoreVoxelSizeCm,
|
||||
*AlternateSeasonIdentity);
|
||||
if (Arguments.bCoreHybridMesher
|
||||
&& !RunHybridPluginMesherFixtures(
|
||||
Actor->Generator, Arguments.bCoreHybridMesherV2, OutError))
|
||||
@@ -17762,7 +17902,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
const float ContentGroundWorldZ = Actor->GetActorTransform().TransformPosition(
|
||||
FVector(SurfaceLocalPosition.X, SurfaceLocalPosition.Y, ContentGroundLocalZ)).Z;
|
||||
const float GroundAgreementCm = FMath::Abs(TerrainGroundWorldZ - ContentGroundWorldZ);
|
||||
if (GroundAgreementCm > 25.0f
|
||||
if (GroundAgreementCm > 1.0f
|
||||
|| ContentGroundLocalZ < AtmosphereBottomLocalZ
|
||||
|| ContentGroundLocalZ > AtmosphereTopLocalZ
|
||||
|| (bContentHasWater && (ContentWaterLocalZ < AtmosphereBottomLocalZ
|
||||
@@ -17815,7 +17955,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
}
|
||||
Anchor->SetRootComponent(AnchorRoot);
|
||||
AnchorRoot->RegisterComponent();
|
||||
constexpr double CoreTileExtentCm = 32.0 * 25.0;
|
||||
const double CoreTileExtentCm = static_cast<double>(CHUNK_SIZE) * Arguments.CoreVoxelSizeCm;
|
||||
const FVector OldAnchorPosition(CoreTileExtentCm * 20.0, 0.0, 0.0);
|
||||
const FVector NewAnchorPosition(CoreTileExtentCm * 21.0, 0.0, 0.0);
|
||||
Anchor->SetActorLocation(OldAnchorPosition);
|
||||
@@ -17877,13 +18017,14 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
const float CarveCenterDelta = CarveDensityAfter - CarveDensityBefore;
|
||||
const float CarveInsideDelta = InsideDensityAfter - InsideDensityBefore;
|
||||
const float CarveOutsideDelta = OutsideDensityAfter - OutsideDensityBefore;
|
||||
if (!FMath::IsNearlyEqual(CarveCenterDelta, 5.0f, 0.01f)
|
||||
const float ExpectedBrushCenterDelta = static_cast<float>(10.0 * VOXEL_SIZE / CoreVoxelSizeCm);
|
||||
if (!FMath::IsNearlyEqual(CarveCenterDelta, ExpectedBrushCenterDelta, 0.01f)
|
||||
|| !(CarveInsideDelta > 0.0f && CarveInsideDelta < CarveCenterDelta)
|
||||
|| !FMath::IsNearlyZero(CarveOutsideDelta, 0.001f))
|
||||
{
|
||||
OutError = FString::Printf(
|
||||
TEXT("Blueprint carve sign/size failed: center=%.4f inside60cm=%.4f outside80cm=%.4f; expected +5, partial +, zero."),
|
||||
CarveCenterDelta, CarveInsideDelta, CarveOutsideDelta);
|
||||
TEXT("Blueprint carve sign/size failed: center=%.4f expected=+%.4f inside60cm=%.4f outside80cm=%.4f; expected partial +, zero."),
|
||||
CarveCenterDelta, ExpectedBrushCenterDelta, CarveInsideDelta, CarveOutsideDelta);
|
||||
return false;
|
||||
}
|
||||
if (Actor->LastVoxelForgeCoreEditSequence != 1
|
||||
@@ -17921,8 +18062,9 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
CarveTargetTile.Coord.Z, CarveTargetTile.Level,
|
||||
static_cast<unsigned long long>(ExpectedPostEditHashes.FindChecked(CarveTargetTile).Mesh));
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreWorldTest] blueprint_carve=PASS radius_legacy=6 strength_legacy=10 center_delta=%.4f inside_60cm_delta=%.4f outside_80cm_delta=%.4f"),
|
||||
CarveCenterDelta, CarveInsideDelta, CarveOutsideDelta);
|
||||
TEXT("[VoxelForgeCoreWorldTest] blueprint_carve=PASS radius_legacy=6 radius_cm=%.3f strength_legacy=10 center_delta=%.4f expected_center_delta=%.4f inside_60cm_delta=%.4f outside_80cm_delta=%.4f"),
|
||||
6.0 * static_cast<double>(VOXEL_SIZE), CarveCenterDelta, ExpectedBrushCenterDelta,
|
||||
CarveInsideDelta, CarveOutsideDelta);
|
||||
|
||||
Actor->UnregisterStreamingAnchor(Anchor);
|
||||
Anchor->Destroy();
|
||||
@@ -18498,18 +18640,25 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
const float FillCenterDelta = FillDensityAfter - FillDensityBefore;
|
||||
const float FillInsideDelta = FillInsideDensityAfter - FillInsideDensityBefore;
|
||||
const float FillOutsideDelta = FillOutsideDensityAfter - FillOutsideDensityBefore;
|
||||
if (!FMath::IsNearlyEqual(FillCenterDelta, -5.0f, 0.01f)
|
||||
const float ExpectedFillCenterDelta = -ExpectedBrushCenterDelta;
|
||||
if (!FMath::IsNearlyEqual(FillCenterDelta, ExpectedFillCenterDelta, 0.01f)
|
||||
|| !(FillInsideDelta < 0.0f && FillInsideDelta > FillCenterDelta)
|
||||
|| !FMath::IsNearlyZero(FillOutsideDelta, 0.001f))
|
||||
{
|
||||
OutError = FString::Printf(
|
||||
TEXT("Blueprint fill sign/size failed: center=%.4f inside60cm=%.4f outside80cm=%.4f; expected -5, partial -, zero."),
|
||||
FillCenterDelta, FillInsideDelta, FillOutsideDelta);
|
||||
TEXT("Blueprint fill sign/size failed: center=%.4f expected=%.4f inside60cm=%.4f outside80cm=%.4f; expected partial -, zero."),
|
||||
FillCenterDelta, ExpectedFillCenterDelta, FillInsideDelta, FillOutsideDelta);
|
||||
return false;
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreWorldTest] blueprint_fill=PASS radius_legacy=6 strength_legacy=10 center_delta=%.4f inside_60cm_delta=%.4f outside_80cm_delta=%.4f"),
|
||||
FillCenterDelta, FillInsideDelta, FillOutsideDelta);
|
||||
TEXT("[VoxelForgeCoreWorldTest] blueprint_fill=PASS radius_legacy=6 radius_cm=%.3f strength_legacy=10 center_delta=%.4f expected_center_delta=%.4f inside_60cm_delta=%.4f outside_80cm_delta=%.4f"),
|
||||
6.0 * static_cast<double>(VOXEL_SIZE), FillCenterDelta, ExpectedFillCenterDelta,
|
||||
FillInsideDelta, FillOutsideDelta);
|
||||
if (!RunCoreContentPlacementCostAudit(Actor, SurfaceLocalPosition,
|
||||
TEXT("SurfaceWorld"), OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user