planner: four-strate owner plan spawns (L66); pinned 2-strate regression fixture
- Core caps each passage mouth reach to its own strate's usable content band (owner DA_Strate1 exports ReachMax=5000 owner voxels, which put the SW->FI lower mouth 79.5 m below FI, inside TN). - Unreal adapter: SW route search keeps the old 64 m candidates first, then a bounded single-mouth search with shorter lengths; logs candidate/rejection counts. - Internal-chain passage floor/support tweaks (only with >2 strates): ripple 1-2 4.78->2.90 cm, 2-3 3.57->0.10 cm. Interfaces still 0/3 walkable (59/3/2 unsupported). - verify.py: legacy tiers use Standalone/data/regression/owner_world_2strate_l61.json; new four-strate stage reads its expectations from owner_world.json (currently red on interfaces). - Unreal trace L14 vs HEAD, same assets (16-chunk FlatPlain): 12.20 vs 12.56 worker-s; no x2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
47148e0a0d
commit
5e2fc53d39
17 files changed
+745
-73
No files matched your search
@@ -246,7 +246,8 @@ std::uint64_t WorldAssemblyRoundedSqrt(std::uint64_t Value)
|
||||
}
|
||||
|
||||
bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
VoxelForgeCore::WorldAssemblyStratumPlanV1& Stratum, std::string& Error)
|
||||
VoxelForgeCore::WorldAssemblyStratumPlanV1& Stratum,
|
||||
std::int64_t ArrivalRadiusQ, std::int64_t DepartureRadiusQ, std::string& Error)
|
||||
{
|
||||
using namespace VoxelForgeCore;
|
||||
constexpr std::int64_t PlayerRadiusQ = 348;
|
||||
@@ -264,9 +265,11 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
struct FCandidate
|
||||
{
|
||||
std::int64_t Score = 0;
|
||||
std::uint64_t EndpointProximityCost = 0;
|
||||
std::int32_t CenterX = 0;
|
||||
std::int32_t CenterY = 0;
|
||||
std::int32_t Direction = 0;
|
||||
std::int32_t HalfLength = 128;
|
||||
std::vector<WorldAssemblyRoutePointV1> Points;
|
||||
};
|
||||
|
||||
@@ -289,11 +292,14 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
}
|
||||
std::vector<FCandidate> Candidates;
|
||||
constexpr std::int32_t WaypointSpacing = 8;
|
||||
std::uint64_t LegacyCandidatesVisited = 0;
|
||||
std::uint64_t LegacyGradeRejected = 0;
|
||||
for (std::int32_t CenterY = -256; CenterY <= 256; CenterY += 64)
|
||||
for (std::int32_t CenterX = -256; CenterX <= 256; CenterX += 64)
|
||||
for (std::int32_t DirectionIndex = 0;
|
||||
DirectionIndex < static_cast<std::int32_t>(Directions.size()); ++DirectionIndex)
|
||||
{
|
||||
++LegacyCandidatesVisited;
|
||||
FCandidate Candidate;
|
||||
Candidate.CenterX = CenterX;
|
||||
Candidate.CenterY = CenterY;
|
||||
@@ -341,36 +347,223 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
PreviousY = Y;
|
||||
}
|
||||
if (bGradePass) Candidates.push_back(std::move(Candidate));
|
||||
else ++LegacyGradeRejected;
|
||||
}
|
||||
std::stable_sort(Candidates.begin(), Candidates.end(), [](const FCandidate& A, const FCandidate& B)
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeSurfaceRouteCandidates] stage=legacy_64m visited=%llu rejected_grade=%llu eligible=%llu arrival_radius_q=%lld departure_radius_q=%lld"),
|
||||
static_cast<unsigned long long>(LegacyCandidatesVisited),
|
||||
static_cast<unsigned long long>(LegacyGradeRejected),
|
||||
static_cast<unsigned long long>(Candidates.size()),
|
||||
static_cast<long long>(ArrivalRadiusQ), static_cast<long long>(DepartureRadiusQ));
|
||||
const auto TryCandidates = [&](const TCHAR* Stage)
|
||||
{
|
||||
if (A.Score != B.Score) return A.Score < B.Score;
|
||||
if (A.CenterY != B.CenterY) return A.CenterY < B.CenterY;
|
||||
if (A.CenterX != B.CenterX) return A.CenterX < B.CenterX;
|
||||
return A.Direction < B.Direction;
|
||||
});
|
||||
|
||||
for (const FCandidate& Candidate : Candidates)
|
||||
{
|
||||
Stratum.route = Candidate.Points;
|
||||
std::int64_t LiftQ = 0;
|
||||
constexpr std::int64_t RepairStepQ = 64;
|
||||
constexpr std::int64_t MaximumRepairLiftQ = SupportDepthQ - RepairStepQ;
|
||||
for (;;)
|
||||
std::stable_sort(Candidates.begin(), Candidates.end(), [](const FCandidate& A, const FCandidate& B)
|
||||
{
|
||||
if (LiftQ > 0)
|
||||
if (A.EndpointProximityCost != B.EndpointProximityCost)
|
||||
return A.EndpointProximityCost < B.EndpointProximityCost;
|
||||
if (A.Score != B.Score) return A.Score < B.Score;
|
||||
if (A.CenterY != B.CenterY) return A.CenterY < B.CenterY;
|
||||
if (A.CenterX != B.CenterX) return A.CenterX < B.CenterX;
|
||||
return A.Direction < B.Direction;
|
||||
});
|
||||
|
||||
std::uint64_t SweepAttempts = 0;
|
||||
std::uint64_t BestFailureCount = std::numeric_limits<std::uint64_t>::max();
|
||||
WorldAssemblyRouteAuditResult BestAudit;
|
||||
const FCandidate* BestCandidate = nullptr;
|
||||
std::int64_t BestLiftQ = 0;
|
||||
for (const FCandidate& Candidate : Candidates)
|
||||
{
|
||||
Stratum.route = Candidate.Points;
|
||||
std::int64_t LiftQ = 0;
|
||||
constexpr std::int64_t RepairStepQ = 64;
|
||||
constexpr std::int64_t MaximumRepairLiftQ = SupportDepthQ - RepairStepQ;
|
||||
for (;;)
|
||||
{
|
||||
for (std::size_t PointIndex = 0; PointIndex < Stratum.route.size(); ++PointIndex)
|
||||
if (LiftQ > 0)
|
||||
{
|
||||
Stratum.route[PointIndex].positionSubvoxels[2] =
|
||||
Candidate.Points[PointIndex].positionSubvoxels[2] + LiftQ;
|
||||
for (std::size_t PointIndex = 0; PointIndex < Stratum.route.size(); ++PointIndex)
|
||||
{
|
||||
Stratum.route[PointIndex].positionSubvoxels[2] =
|
||||
Candidate.Points[PointIndex].positionSubvoxels[2] + LiftQ;
|
||||
}
|
||||
}
|
||||
const Heightfield2D CandidateField(Recipe, Stratum);
|
||||
const WorldAssemblyRouteAuditResult Audit = AuditHeightfieldRoute(CandidateField);
|
||||
++SweepAttempts;
|
||||
const std::uint64_t FailureCount = Audit.blockedCapsuleSamples
|
||||
+ Audit.unsupportedCenterSamples + Audit.gradeFailures;
|
||||
if (FailureCount < BestFailureCount)
|
||||
{
|
||||
BestFailureCount = FailureCount;
|
||||
BestAudit = Audit;
|
||||
BestCandidate = &Candidate;
|
||||
BestLiftQ = LiftQ;
|
||||
}
|
||||
if (Audit.passed)
|
||||
{
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeSurfaceRouteAudit] stage=%s candidates=%llu sweep_attempts=%llu blocked=%llu unsupported=%llu grade_failures=%llu min_clearance_q=%lld max_support_depth_q=%lld center_x=%d center_y=%d direction=%d half_length_vox=%d lift_q=%lld status=PASS"),
|
||||
Stage, static_cast<unsigned long long>(Candidates.size()),
|
||||
static_cast<unsigned long long>(SweepAttempts),
|
||||
static_cast<unsigned long long>(Audit.blockedCapsuleSamples),
|
||||
static_cast<unsigned long long>(Audit.unsupportedCenterSamples),
|
||||
static_cast<unsigned long long>(Audit.gradeFailures),
|
||||
static_cast<long long>(Audit.minimumClearanceSubvoxels),
|
||||
static_cast<long long>(Audit.maximumSupportDepthSubvoxels),
|
||||
Candidate.CenterX, Candidate.CenterY, Candidate.Direction,
|
||||
Candidate.HalfLength, static_cast<long long>(LiftQ));
|
||||
return true;
|
||||
}
|
||||
if (LiftQ >= MaximumRepairLiftQ) break;
|
||||
LiftQ += RepairStepQ;
|
||||
}
|
||||
}
|
||||
UE_LOG(LogTemp, Warning,
|
||||
TEXT("[VoxelForgeSurfaceRouteAudit] stage=%s candidates=%llu sweep_attempts=%llu best_blocked=%llu best_unsupported=%llu best_grade_failures=%llu min_clearance_q=%lld max_support_depth_q=%lld center_x=%d center_y=%d direction=%d half_length_vox=%d lift_q=%lld status=FAIL"),
|
||||
Stage, static_cast<unsigned long long>(Candidates.size()),
|
||||
static_cast<unsigned long long>(SweepAttempts),
|
||||
static_cast<unsigned long long>(BestAudit.blockedCapsuleSamples),
|
||||
static_cast<unsigned long long>(BestAudit.unsupportedCenterSamples),
|
||||
static_cast<unsigned long long>(BestAudit.gradeFailures),
|
||||
static_cast<long long>(BestAudit.minimumClearanceSubvoxels),
|
||||
static_cast<long long>(BestAudit.maximumSupportDepthSubvoxels),
|
||||
BestCandidate ? BestCandidate->CenterX : 0,
|
||||
BestCandidate ? BestCandidate->CenterY : 0,
|
||||
BestCandidate ? BestCandidate->Direction : 0,
|
||||
BestCandidate ? BestCandidate->HalfLength : 0,
|
||||
static_cast<long long>(BestLiftQ));
|
||||
return false;
|
||||
};
|
||||
|
||||
// Keep the established candidate set first so worlds that already pass retain
|
||||
// their exact route. The bounded-mouth fallback searches different route lengths.
|
||||
if (TryCandidates(TEXT("legacy_64m"))) return true;
|
||||
|
||||
if (ArrivalRadiusQ > 0 || DepartureRadiusQ > 0)
|
||||
{
|
||||
// The endpoint radius constrains the mouth end, not the full route length. Keep
|
||||
// enough reach for a route to leave a steep portal area and find gentler terrain.
|
||||
constexpr std::int32_t maximumHalfLength = 128;
|
||||
const std::vector<std::int32_t> HalfLengths{128, 112, 96, 80, 64, 48, 32, 24, 16};
|
||||
Candidates.clear();
|
||||
std::uint64_t FallbackCandidatesVisited = 0;
|
||||
std::uint64_t FallbackGradeRejected = 0;
|
||||
std::uint64_t FallbackPlacementRejected = 0;
|
||||
std::uint64_t BestGradeEndpointDistanceQ = std::numeric_limits<std::uint64_t>::max();
|
||||
FCandidate BestGradeCandidate;
|
||||
for (const std::int32_t HalfLength : HalfLengths)
|
||||
for (std::int32_t CenterY = -256; CenterY <= 256; CenterY += 16)
|
||||
for (std::int32_t CenterX = -256; CenterX <= 256; CenterX += 16)
|
||||
for (std::int32_t DirectionIndex = 0;
|
||||
DirectionIndex < static_cast<std::int32_t>(Directions.size()); ++DirectionIndex)
|
||||
{
|
||||
++FallbackCandidatesVisited;
|
||||
FCandidate Candidate;
|
||||
Candidate.CenterX = CenterX;
|
||||
Candidate.CenterY = CenterY;
|
||||
Candidate.Direction = DirectionIndex;
|
||||
Candidate.HalfLength = HalfLength;
|
||||
Candidate.Points.reserve(33);
|
||||
std::int64_t PreviousGround = 0;
|
||||
std::int64_t PreviousX = 0;
|
||||
std::int64_t PreviousY = 0;
|
||||
bool bGradePass = true;
|
||||
bool bPlacementPass = true;
|
||||
for (std::int32_t Index = 0; Index <= 32; ++Index)
|
||||
{
|
||||
const std::int64_t Along = (Index - 16) * HalfLength / 16;
|
||||
const std::int64_t X = CenterX + WorldAssemblyRoundRatio(
|
||||
Along * Directions[DirectionIndex].X, 65536);
|
||||
const std::int64_t Y = CenterY + WorldAssemblyRoundRatio(
|
||||
Along * Directions[DirectionIndex].Y, 65536);
|
||||
const std::int64_t XQ = WorldAssemblyFixed(static_cast<double>(X));
|
||||
const std::int64_t YQ = WorldAssemblyFixed(static_cast<double>(Y));
|
||||
const auto InRadius = [](std::int64_t XValue, std::int64_t YValue,
|
||||
std::int64_t Radius)
|
||||
{
|
||||
return Radius <= 0 || XValue * XValue + YValue * YValue <= Radius * Radius;
|
||||
};
|
||||
if ((Index == 0 && ArrivalRadiusQ > 0
|
||||
&& !InRadius(XQ, YQ, ArrivalRadiusQ))
|
||||
|| (Index == 32 && DepartureRadiusQ > 0
|
||||
&& !InRadius(XQ, YQ, DepartureRadiusQ)))
|
||||
{
|
||||
bPlacementPass = false;
|
||||
}
|
||||
if (Index == 0 && ArrivalRadiusQ > 0)
|
||||
{
|
||||
Candidate.EndpointProximityCost += static_cast<std::uint64_t>(XQ * XQ + YQ * YQ) * 16ull;
|
||||
}
|
||||
if (Index == 32 && DepartureRadiusQ > 0)
|
||||
{
|
||||
Candidate.EndpointProximityCost += static_cast<std::uint64_t>(XQ * XQ + YQ * YQ);
|
||||
}
|
||||
const auto Column = BaseField.point(WorldAssemblyFixed(static_cast<double>(X)),
|
||||
WorldAssemblyFixed(static_cast<double>(Y)), 0);
|
||||
const std::int64_t DeltaX = X - PreviousX;
|
||||
const std::int64_t DeltaY = Y - PreviousY;
|
||||
const std::uint64_t HorizontalVoxels = WorldAssemblyRoundedSqrt(
|
||||
static_cast<std::uint64_t>(DeltaX * DeltaX + DeltaY * DeltaY));
|
||||
const std::int64_t HorizontalQ = static_cast<std::int64_t>(HorizontalVoxels)
|
||||
* WorldAssemblySubvoxelsPerVoxel;
|
||||
if (Index > 0)
|
||||
{
|
||||
const std::int64_t RiseQ = std::abs(Column.groundHeightSubvoxels - PreviousGround);
|
||||
if (HorizontalQ == 0 || RiseQ * 65536 > HorizontalQ * GradeQ16)
|
||||
{
|
||||
bGradePass = false;
|
||||
}
|
||||
Candidate.Score += RiseQ * 65536 / std::max<std::int64_t>(1, HorizontalQ);
|
||||
}
|
||||
WorldAssemblyRoutePointV1 Point;
|
||||
Point.positionSubvoxels = {XQ, YQ, Column.groundHeightSubvoxels + HalfHeightQ};
|
||||
Point.radiusSubvoxels = RouteRadiusQ;
|
||||
Point.stableFeatureId = WorldAssemblyFeatureId(Recipe.seed, X, Y,
|
||||
0x52540000u + static_cast<std::uint32_t>(Index));
|
||||
Candidate.Points.push_back(Point);
|
||||
PreviousGround = Column.groundHeightSubvoxels;
|
||||
PreviousX = X;
|
||||
PreviousY = Y;
|
||||
}
|
||||
Candidate.Score /= 32;
|
||||
if (bGradePass)
|
||||
{
|
||||
const auto& Endpoint = DepartureRadiusQ > 0
|
||||
? Candidate.Points.back().positionSubvoxels
|
||||
: Candidate.Points.front().positionSubvoxels;
|
||||
const std::uint64_t EndpointDistanceQ = WorldAssemblyRoundedSqrt(
|
||||
static_cast<std::uint64_t>(Endpoint[0] * Endpoint[0]
|
||||
+ Endpoint[1] * Endpoint[1]));
|
||||
if (EndpointDistanceQ < BestGradeEndpointDistanceQ)
|
||||
{
|
||||
BestGradeEndpointDistanceQ = EndpointDistanceQ;
|
||||
BestGradeCandidate.CenterX = CenterX;
|
||||
BestGradeCandidate.CenterY = CenterY;
|
||||
BestGradeCandidate.Direction = DirectionIndex;
|
||||
BestGradeCandidate.HalfLength = HalfLength;
|
||||
}
|
||||
}
|
||||
const Heightfield2D CandidateField(Recipe, Stratum);
|
||||
if (AuditHeightfieldRoute(CandidateField).passed) return true;
|
||||
if (LiftQ >= MaximumRepairLiftQ) break;
|
||||
LiftQ += RepairStepQ;
|
||||
if (bGradePass && bPlacementPass) Candidates.push_back(std::move(Candidate));
|
||||
else
|
||||
{
|
||||
if (!bGradePass) ++FallbackGradeRejected;
|
||||
if (!bPlacementPass) ++FallbackPlacementRejected;
|
||||
}
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeSurfaceRouteCandidates] stage=bounded_single_mouth visited=%llu rejected_grade=%llu rejected_placement=%llu eligible=%llu max_half_length_vox=%d half_length_variants=%d best_grade_endpoint_q=%llu best_grade_center_x=%d best_grade_center_y=%d best_grade_direction=%d best_grade_half_length_vox=%d arrival_radius_q=%lld departure_radius_q=%lld"),
|
||||
static_cast<unsigned long long>(FallbackCandidatesVisited),
|
||||
static_cast<unsigned long long>(FallbackGradeRejected),
|
||||
static_cast<unsigned long long>(FallbackPlacementRejected),
|
||||
static_cast<unsigned long long>(Candidates.size()), maximumHalfLength,
|
||||
static_cast<int32>(HalfLengths.size()),
|
||||
static_cast<unsigned long long>(BestGradeEndpointDistanceQ),
|
||||
BestGradeCandidate.CenterX, BestGradeCandidate.CenterY,
|
||||
BestGradeCandidate.Direction, BestGradeCandidate.HalfLength,
|
||||
static_cast<long long>(ArrivalRadiusQ),
|
||||
static_cast<long long>(DepartureRadiusQ));
|
||||
if (TryCandidates(TEXT("bounded_single_mouth"))) return true;
|
||||
}
|
||||
Error = "SurfaceWorld route candidates failed the capsule and support sweep.";
|
||||
return false;
|
||||
@@ -631,7 +824,29 @@ bool BuildSurfaceStratumPlan(const UVoxelStrateManager* StrateManager,
|
||||
}
|
||||
}
|
||||
std::string RouteError;
|
||||
if (!BuildFiniteSurfaceRoute(Recipe, Stratum, RouteError))
|
||||
const auto OwnerVoxelsToCoreQ = [CoreVoxelMicrometres](double OwnerVoxels)
|
||||
{
|
||||
const double OwnerVoxelMicrometres = OwnerVoxelSizeCm * 10000.0;
|
||||
return static_cast<std::int64_t>(std::llround(OwnerVoxels * OwnerVoxelMicrometres
|
||||
* WorldAssemblySubvoxelsPerVoxel / std::max<std::uint32_t>(1, CoreVoxelMicrometres)));
|
||||
};
|
||||
std::int64_t ArrivalRadiusQ = 0;
|
||||
std::int64_t DepartureRadiusQ = 0;
|
||||
for (const FStrateSlot& Neighbor : StrateManager->GetLayout())
|
||||
{
|
||||
if (Neighbor.Definition == nullptr) continue;
|
||||
if (Neighbor.StrateIndex + 1 == Slot.StrateIndex)
|
||||
{
|
||||
ArrivalRadiusQ = std::max(OwnerVoxelsToCoreQ(Neighbor.Definition->PassageConfig.DistanceMin),
|
||||
OwnerVoxelsToCoreQ(Neighbor.Definition->PassageConfig.DistanceMax));
|
||||
}
|
||||
if (Neighbor.StrateIndex == Slot.StrateIndex + 1 && Definition != nullptr)
|
||||
{
|
||||
DepartureRadiusQ = std::max(OwnerVoxelsToCoreQ(Definition->PassageConfig.DistanceMin),
|
||||
OwnerVoxelsToCoreQ(Definition->PassageConfig.DistanceMax));
|
||||
}
|
||||
}
|
||||
if (!BuildFiniteSurfaceRoute(Recipe, Stratum, ArrivalRadiusQ, DepartureRadiusQ, RouteError))
|
||||
{
|
||||
OutError = UTF8_TO_TCHAR(RouteError.c_str());
|
||||
return false;
|
||||
|
||||
@@ -14918,7 +14918,7 @@ bool CreateLoggedOwnerSurfaceSettingsCopy(
|
||||
UVoxelSettings* Source, int32 Seed,
|
||||
TStrongObjectPtr<UVoxelSettings>& OutSettings,
|
||||
TStrongObjectPtr<UVoxelStrateDefinition>& OutSurfaceDefinition,
|
||||
FString& OutError)
|
||||
FString& OutError, bool bCompactTracePlan = false)
|
||||
{
|
||||
if (Source == nullptr)
|
||||
{
|
||||
@@ -14934,11 +14934,10 @@ bool CreateLoggedOwnerSurfaceSettingsCopy(
|
||||
nullptr, TEXT("/Game/VoxelForge/DA_Strate1.DA_Strate1"));
|
||||
if (SurfaceDefinition == nullptr
|
||||
|| SurfaceDefinition->GeneratorType != ECaveGeneratorType::SurfaceWorld
|
||||
|| SurfaceDefinition->StrateHeightInChunks <= 0
|
||||
|| Source->TotalStrates != 1)
|
||||
|| SurfaceDefinition->StrateHeightInChunks <= 0)
|
||||
{
|
||||
OutError = FString::Printf(
|
||||
TEXT("The staged owner assets do not describe the logged single SurfaceWorld (definition_loaded=%d type=%d height=%d settings_strates=%d)."),
|
||||
TEXT("The staged owner assets do not contain a usable DA_Strate1 SurfaceWorld (definition_loaded=%d type=%d height=%d settings_strates=%d)."),
|
||||
SurfaceDefinition != nullptr ? 1 : 0,
|
||||
SurfaceDefinition != nullptr ? static_cast<int32>(SurfaceDefinition->GeneratorType) : INDEX_NONE,
|
||||
SurfaceDefinition != nullptr ? SurfaceDefinition->StrateHeightInChunks : INDEX_NONE,
|
||||
@@ -14953,9 +14952,24 @@ bool CreateLoggedOwnerSurfaceSettingsCopy(
|
||||
return false;
|
||||
}
|
||||
OutSettings = TStrongObjectPtr<UVoxelSettings>(SettingsCopy);
|
||||
if (bCompactTracePlan)
|
||||
{
|
||||
SurfaceDefinition = DuplicateObject<UVoxelStrateDefinition>(SurfaceDefinition,
|
||||
GetTransientPackage(), TEXT("VoxelForgeCompactSurfaceTraceDefinition"));
|
||||
if (SurfaceDefinition == nullptr)
|
||||
{
|
||||
OutError = TEXT("Could not make a transient DA_Strate1 copy for the compact common-plan trace.");
|
||||
return false;
|
||||
}
|
||||
// L14's historical fixed-length SurfaceWorld route search cannot place the
|
||||
// new trace fixture even at 16 chunks. Use the same simple, walkable FlatPlain
|
||||
// plan in both host revisions so the streaming comparison reaches AVoxelWorld.
|
||||
SurfaceDefinition->GeneratorType = ECaveGeneratorType::FlatPlain;
|
||||
SurfaceDefinition->StrateHeightInChunks = 16;
|
||||
}
|
||||
OutSurfaceDefinition = TStrongObjectPtr<UVoxelStrateDefinition>(SurfaceDefinition);
|
||||
SettingsCopy->Seed = Seed;
|
||||
SettingsCopy->TotalStrates = Source->TotalStrates;
|
||||
SettingsCopy->TotalStrates = 1;
|
||||
SettingsCopy->StratePool.Reset();
|
||||
SettingsCopy->FixedStrates.Reset();
|
||||
SettingsCopy->FixedStrates.Add(0,
|
||||
@@ -14965,8 +14979,10 @@ bool CreateLoggedOwnerSurfaceSettingsCopy(
|
||||
SettingsCopy->bUseWorldAssemblyManifestOverride = false;
|
||||
const int32 BottomChunkZ = 1 - SurfaceDefinition->StrateHeightInChunks;
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeCoreTestLayout] source=owner_asset_transient_copy definition=DA_Strate1 seed=%d strata=1 bounds=[0,%d] height_chunks=%d gap=%d imported_override=cleared"),
|
||||
Seed, BottomChunkZ, SurfaceDefinition->StrateHeightInChunks, SettingsCopy->InterStrateGapChunks);
|
||||
TEXT("[VoxelForgeCoreTestLayout] source=owner_asset_transient_copy definition=DA_Strate1 generator=%d seed=%d strata=1 bounds=[0,%d] height_chunks=%d compact_trace=%d gap=%d imported_override=cleared"),
|
||||
static_cast<int32>(SurfaceDefinition->GeneratorType), Seed, BottomChunkZ,
|
||||
SurfaceDefinition->StrateHeightInChunks,
|
||||
bCompactTracePlan ? 1 : 0, SettingsCopy->InterStrateGapChunks);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16542,7 +16558,15 @@ bool RunCoreFloatingIslandActorIntegrationTest(
|
||||
}
|
||||
float StagedWalkSpeedCmPerSecond = 0.0f;
|
||||
float StagedSprintSpeedCmPerSecond = 0.0f;
|
||||
if (!ReadStagedPlayerSpeeds(
|
||||
if (Arguments.bCoreWorldStreamTraceOnly)
|
||||
{
|
||||
StagedWalkSpeedCmPerSecond = 600.0f;
|
||||
StagedSprintSpeedCmPerSecond = 6000.0f;
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgePawnSpeedFixture] source=trace_fixture_defaults walk_cm_s=%.3f sprint_cm_s=%.3f"),
|
||||
StagedWalkSpeedCmPerSecond, StagedSprintSpeedCmPerSecond);
|
||||
}
|
||||
else if (!ReadStagedPlayerSpeeds(
|
||||
StagedWalkSpeedCmPerSecond, StagedSprintSpeedCmPerSecond, OutError))
|
||||
{
|
||||
return false;
|
||||
@@ -17764,8 +17788,16 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
|
||||
float StagedWalkSpeedCmPerSecond = 0.0f;
|
||||
float StagedSprintSpeedCmPerSecond = 0.0f;
|
||||
if (!ReadStagedPlayerSpeeds(
|
||||
StagedWalkSpeedCmPerSecond, StagedSprintSpeedCmPerSecond, OutError))
|
||||
if (Arguments.bCoreWorldStreamTraceOnly)
|
||||
{
|
||||
StagedWalkSpeedCmPerSecond = 600.0f;
|
||||
StagedSprintSpeedCmPerSecond = 6000.0f;
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgePawnSpeedFixture] source=trace_fixture_defaults walk_cm_s=%.3f sprint_cm_s=%.3f"),
|
||||
StagedWalkSpeedCmPerSecond, StagedSprintSpeedCmPerSecond);
|
||||
}
|
||||
else if (!ReadStagedPlayerSpeeds(
|
||||
StagedWalkSpeedCmPerSecond, StagedSprintSpeedCmPerSecond, OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -17773,8 +17805,26 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
const int32 OwnerSeed = ResolveCoreTestWorldSeed(AuthoredSettings);
|
||||
TStrongObjectPtr<UVoxelSettings> OwnerSurfaceSettings;
|
||||
TStrongObjectPtr<UVoxelStrateDefinition> OwnerSurfaceDefinition;
|
||||
if (!CreateLoggedOwnerSurfaceSettingsCopy(AuthoredSettings, OwnerSeed,
|
||||
OwnerSurfaceSettings, OwnerSurfaceDefinition, OutError))
|
||||
TArray<TStrongObjectPtr<UVoxelStrateDefinition>> OwnerPlanDefinitions;
|
||||
if (Arguments.bOwnerFourStratePlan)
|
||||
{
|
||||
UVoxelSettings* PlanSettings = DuplicateObject<UVoxelSettings>(
|
||||
AuthoredSettings, GetTransientPackage(), TEXT("VoxelForgeOwnerFourStrateTraceSettings"));
|
||||
if (PlanSettings == nullptr)
|
||||
{
|
||||
OutError = TEXT("Could not duplicate owner settings for the transient four-strate Core trace.");
|
||||
return false;
|
||||
}
|
||||
PlanSettings->Seed = OwnerSeed;
|
||||
if (!ApplyOwnerFourStratePlan(PlanSettings, OwnerPlanDefinitions, true, OutError))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
OwnerSurfaceSettings = TStrongObjectPtr<UVoxelSettings>(PlanSettings);
|
||||
}
|
||||
else if (!CreateLoggedOwnerSurfaceSettingsCopy(AuthoredSettings, OwnerSeed,
|
||||
OwnerSurfaceSettings, OwnerSurfaceDefinition, OutError,
|
||||
Arguments.bCoreWorldStreamTraceOnly))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user