Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbbfd46bd3 | ||
|
|
044cd6d9c5 | ||
|
|
b96dd739b8 |
No files matched your search
@@ -494,7 +494,10 @@ namespace VoxelForgeCore
|
|||||||
// Version 223 projects the floor onto one continuous arc-length profile and groups
|
// Version 223 projects the floor onto one continuous arc-length profile and groups
|
||||||
// dense passage samples into coarse tile candidates. Version 224 keeps the same
|
// dense passage samples into coarse tile candidates. Version 224 keeps the same
|
||||||
// continuous floor while relaxing the spline chord tolerance and bounding shell work.
|
// continuous floor while relaxing the spline chord tolerance and bounding shell work.
|
||||||
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 225;
|
// Version 226 unifies the passage influence reach in metres and converts it to core
|
||||||
|
// voxels for every broadphase and proof bound. Version 227 uses the exact smooth-max
|
||||||
|
// support width/6 when deriving that reach.
|
||||||
|
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 227;
|
||||||
|
|
||||||
enum class FieldChannel : std::uint32_t
|
enum class FieldChannel : std::uint32_t
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,11 +72,28 @@ static bool VF_IsL98PassagePrepareTraceEnabled()
|
|||||||
return bEnabled;
|
return bEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double VF_L93PassageCarveReachMetres()
|
static bool VF_IsL130PassageReachProofAuditEnabled()
|
||||||
{
|
{
|
||||||
// The generated world uses a fixed bounded tube influence. An explicit diagnostic
|
static const bool bEnabled=VF_IsL88DiagnosticSwitchEnabled(
|
||||||
// option can still select the legacy point-evaluation path for comparisons.
|
"VOXELFORGE_L130_PASSAGE_REACH_PROOF_AUDIT");
|
||||||
return 4.0;
|
return bEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr double VF_PassageShellThicknessMetres=0.75;
|
||||||
|
static constexpr double VF_PassageWallReliefMetres=0.21;
|
||||||
|
static constexpr double VF_PassageCornerBlendMetres=0.50;
|
||||||
|
static constexpr double VF_PassageReachMarginMetres=0.01;
|
||||||
|
// Radial support in metres: shell + maximum relief + the smooth-max support
|
||||||
|
// (corner-blend width / 6) + a 1 cm guard for float and bound rounding.
|
||||||
|
static constexpr double VF_PassageInfluenceReachMetres=
|
||||||
|
VF_PassageShellThicknessMetres+VF_PassageWallReliefMetres
|
||||||
|
+VF_PassageCornerBlendMetres/6.0+VF_PassageReachMarginMetres;
|
||||||
|
|
||||||
|
static double VF_PassageInfluenceReachCoreVoxels(
|
||||||
|
std::uint32_t coreVoxelSizeMicrometres)
|
||||||
|
{
|
||||||
|
return VF_PassageInfluenceReachMetres*1000000.0
|
||||||
|
/std::max<std::uint32_t>(1,coreVoxelSizeMicrometres);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class EPassageDensityQueryCaller : std::size_t
|
enum class EPassageDensityQueryCaller : std::size_t
|
||||||
@@ -306,7 +323,7 @@ public:
|
|||||||
profileStats_(profileStats),profileLod_(profileLod),
|
profileStats_(profileStats),profileLod_(profileLod),
|
||||||
passageCarveReachMetres_(std::isfinite(passageCarveReachMetres)
|
passageCarveReachMetres_(std::isfinite(passageCarveReachMetres)
|
||||||
&&passageCarveReachMetres>=0.0?passageCarveReachMetres
|
&&passageCarveReachMetres>=0.0?passageCarveReachMetres
|
||||||
:VF_L93PassageCarveReachMetres())
|
:VF_PassageInfluenceReachMetres)
|
||||||
{
|
{
|
||||||
mayContainResolvedBoundaryBand_=shape.ResolvedBoundaryBandsIntersectSubvoxelRange(
|
mayContainResolvedBoundaryBand_=shape.ResolvedBoundaryBandsIntersectSubvoxelRange(
|
||||||
minimumSubvoxels_[2],maximumSubvoxels_[2]);
|
minimumSubvoxels_[2],maximumSubvoxels_[2]);
|
||||||
@@ -1204,8 +1221,8 @@ public:
|
|||||||
if(!ResolvedLayout||ResolvedLayout->passages.empty()||!std::isfinite(X)
|
if(!ResolvedLayout||ResolvedLayout->passages.empty()||!std::isfinite(X)
|
||||||
||!std::isfinite(Y)||!std::isfinite(Z))return density;
|
||!std::isfinite(Y)||!std::isfinite(Z))return density;
|
||||||
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||||||
constexpr double FloorShellThicknessMetres=0.75;
|
constexpr double FloorShellThicknessMetres=VF_PassageShellThicknessMetres;
|
||||||
constexpr double WallReliefMetres=0.21;
|
constexpr double WallReliefMetres=VF_PassageWallReliefMetres;
|
||||||
constexpr double OpenAirSideWallHeightMetres=1.0;
|
constexpr double OpenAirSideWallHeightMetres=1.0;
|
||||||
constexpr double MouthShellBlendMetres=5.0;
|
constexpr double MouthShellBlendMetres=5.0;
|
||||||
const double qPerMetre=Q*1000000.0/
|
const double qPerMetre=Q*1000000.0/
|
||||||
@@ -1630,8 +1647,8 @@ public:
|
|||||||
{
|
{
|
||||||
constexpr double Q=static_cast<double>(
|
constexpr double Q=static_cast<double>(
|
||||||
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||||||
const double qPerMetre=Q*1000000.0/
|
const double reachCoreVoxels=VF_PassageInfluenceReachCoreVoxels(
|
||||||
std::max<std::uint32_t>(1,ResolvedLayout->coreVoxelSizeMicrometres);
|
ResolvedLayout->coreVoxelSizeMicrometres);
|
||||||
const auto overlaps=[&](const double low[3],const double high[3])
|
const auto overlaps=[&](const double low[3],const double high[3])
|
||||||
{
|
{
|
||||||
for(int axis=0;axis<3;++axis)
|
for(int axis=0;axis<3;++axis)
|
||||||
@@ -1648,7 +1665,8 @@ public:
|
|||||||
const auto& p3=passage.controlPoints[
|
const auto& p3=passage.controlPoints[
|
||||||
std::min(segment+2,passage.controlPoints.size()-1)];
|
std::min(segment+2,passage.controlPoints.size()-1)];
|
||||||
const double radius=std::max(static_cast<double>(a.radiusSubvoxels),
|
const double radius=std::max(static_cast<double>(a.radiusSubvoxels),
|
||||||
static_cast<double>(b.radiusSubvoxels))/Q+1.0;
|
static_cast<double>(b.radiusSubvoxels))/Q
|
||||||
|
+reachCoreVoxels+0.01;
|
||||||
double low[3]{},high[3]{};
|
double low[3]{},high[3]{};
|
||||||
for(int axis=0;axis<3;++axis)
|
for(int axis=0;axis<3;++axis)
|
||||||
{
|
{
|
||||||
@@ -3499,7 +3517,7 @@ private:
|
|||||||
double centerZSubvoxels,double queryZSubvoxels,double floorDepthSubvoxels,
|
double centerZSubvoxels,double queryZSubvoxels,double floorDepthSubvoxels,
|
||||||
double qPerMetre)
|
double qPerMetre)
|
||||||
{
|
{
|
||||||
constexpr double CornerBlendMetres=0.50;
|
constexpr double CornerBlendMetres=VF_PassageCornerBlendMetres;
|
||||||
const float floorDistance=static_cast<float>(centerZSubvoxels
|
const float floorDistance=static_cast<float>(centerZSubvoxels
|
||||||
-floorDepthSubvoxels-queryZSubvoxels);
|
-floorDepthSubvoxels-queryZSubvoxels);
|
||||||
return SmoothMaxDistance(roundDistanceSubvoxels,floorDistance,
|
return SmoothMaxDistance(roundDistanceSubvoxels,floorDistance,
|
||||||
@@ -4811,13 +4829,9 @@ private:
|
|||||||
PassageNearestNodes.resize(ResolvedLayout?ResolvedLayout->passages.size():0);
|
PassageNearestNodes.resize(ResolvedLayout?ResolvedLayout->passages.size():0);
|
||||||
if(!ResolvedLayout||ResolvedLayout->passages.empty())return;
|
if(!ResolvedLayout||ResolvedLayout->passages.empty())return;
|
||||||
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||||||
constexpr double PassageShellMetres=0.75;
|
|
||||||
constexpr double ReliefMetres=0.21;
|
|
||||||
constexpr double SweepReachMetres=4.0;
|
|
||||||
constexpr double CornerBlendMetres=0.50;
|
|
||||||
constexpr std::size_t CandidateFineSamplesPerSpan=5;
|
constexpr std::size_t CandidateFineSamplesPerSpan=5;
|
||||||
const double requiredReach=std::max(SweepReachMetres+ReliefMetres
|
const double requiredReachCoreVoxels=VF_PassageInfluenceReachCoreVoxels(
|
||||||
+CornerBlendMetres*0.25,PassageShellMetres+ReliefMetres);
|
ResolvedLayout->coreVoxelSizeMicrometres);
|
||||||
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();
|
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();
|
||||||
++passageIndex)
|
++passageIndex)
|
||||||
{
|
{
|
||||||
@@ -4854,7 +4868,7 @@ private:
|
|||||||
routeMinimum[axis]=std::min(routeMinimum[axis],localMinimum[axis]);
|
routeMinimum[axis]=std::min(routeMinimum[axis],localMinimum[axis]);
|
||||||
routeMaximum[axis]=std::max(routeMaximum[axis],localMaximum[axis]);
|
routeMaximum[axis]=std::max(routeMaximum[axis],localMaximum[axis]);
|
||||||
}
|
}
|
||||||
const double localExtent=requiredReach
|
const double localExtent=requiredReachCoreVoxels
|
||||||
+std::max(prepared.radiusA,prepared.radiusB)/Q+0.01;
|
+std::max(prepared.radiusA,prepared.radiusB)/Q+0.01;
|
||||||
FPassageProofBound proof;
|
FPassageProofBound proof;
|
||||||
for(std::size_t axis=0;axis<3;++axis)
|
for(std::size_t axis=0;axis<3;++axis)
|
||||||
@@ -4872,7 +4886,8 @@ private:
|
|||||||
std::ceil((localMaximum[axis]+localExtent)*Q));
|
std::ceil((localMaximum[axis]+localExtent)*Q));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const double routeExtent=maximumRadiusSubvoxels/Q+requiredReach+0.01;
|
const double routeExtent=maximumRadiusSubvoxels/Q
|
||||||
|
+requiredReachCoreVoxels+0.01;
|
||||||
const double tileExtent=routeExtent;
|
const double tileExtent=routeExtent;
|
||||||
std::array<std::int64_t,3> featureMinimum{},featureMaximum{};
|
std::array<std::int64_t,3> featureMinimum{},featureMaximum{};
|
||||||
for(std::size_t axis=0;axis<3;++axis)
|
for(std::size_t axis=0;axis<3;++axis)
|
||||||
@@ -4899,6 +4914,113 @@ private:
|
|||||||
BuildPassageFeatureNode(0,PassageFeatureOrder.size());
|
BuildPassageFeatureNode(0,PassageFeatureOrder.size());
|
||||||
if(!PassageProofBounds.empty())
|
if(!PassageProofBounds.empty())
|
||||||
BuildPassageProofNode(0,PassageProofBounds.size());
|
BuildPassageProofNode(0,PassageProofBounds.size());
|
||||||
|
|
||||||
|
if(VF_IsL130PassageReachProofAuditEnabled())
|
||||||
|
{
|
||||||
|
constexpr double Q=static_cast<double>(
|
||||||
|
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||||||
|
constexpr std::array<std::array<double,2>,8> RadialDirections={{
|
||||||
|
{1.0,0.0},{0.7071067811865475,0.7071067811865475},
|
||||||
|
{0.0,1.0},{-0.7071067811865475,0.7071067811865475},
|
||||||
|
{-1.0,0.0},{-0.7071067811865475,-0.7071067811865475},
|
||||||
|
{0.0,-1.0},{0.7071067811865475,-0.7071067811865475}}};
|
||||||
|
constexpr std::array<double,2> CrestHeightsMetres={0.625,0.875};
|
||||||
|
const double qPerMetre=Q*1000000.0/
|
||||||
|
std::max<std::uint32_t>(1,ResolvedLayout->coreVoxelSizeMicrometres);
|
||||||
|
const std::array<double,6> shellOffsetsMetres={0.70,0.78,0.86,0.94,
|
||||||
|
VF_PassageInfluenceReachMetres-0.005,
|
||||||
|
VF_PassageInfluenceReachMetres+0.005};
|
||||||
|
std::uint64_t sampled=0,signRelevant=0,proofMisses=0,featureMisses=0;
|
||||||
|
for(std::size_t passageIndex=0;
|
||||||
|
passageIndex<PassageSegmentData.size();++passageIndex)
|
||||||
|
{
|
||||||
|
const auto& segments=PassageSegmentData[passageIndex];
|
||||||
|
if(segments.empty())continue;
|
||||||
|
const auto& constants=PassageComposerConstants[passageIndex];
|
||||||
|
const std::size_t stride=std::max<std::size_t>(1,
|
||||||
|
(segments.size()+127)/128);
|
||||||
|
for(std::size_t segmentIndex=0;segmentIndex<segments.size();
|
||||||
|
segmentIndex+=stride)
|
||||||
|
{
|
||||||
|
const auto& segment=segments[segmentIndex];
|
||||||
|
if(segment.lengthSq<=1.0e-12)continue;
|
||||||
|
constexpr double T=0.5;
|
||||||
|
const double centerX=segment.a[0]+T*segment.delta[0];
|
||||||
|
const double centerY=segment.a[1]+T*segment.delta[1];
|
||||||
|
const double centerZ=segment.a[2]+T*segment.delta[2];
|
||||||
|
const double radius=segment.radiusA+T*segment.radiusDelta;
|
||||||
|
const double floorDepth=PassageFlatFloorDepthSubvoxels(
|
||||||
|
constants,segmentIndex,T,radius,qPerMetre);
|
||||||
|
const double floorCenterZ=PassageFlatFloorCenterZSubvoxels(
|
||||||
|
constants,segments,segmentIndex,T,segment,centerX,centerY,
|
||||||
|
floorDepth,qPerMetre);
|
||||||
|
for(const double crestHeightMetres:CrestHeightsMetres)
|
||||||
|
{
|
||||||
|
const double sampleZ=floorCenterZ-floorDepth
|
||||||
|
+crestHeightMetres*qPerMetre;
|
||||||
|
const double verticalDelta=sampleZ-centerZ;
|
||||||
|
for(const double shellOffsetMetres:shellOffsetsMetres)
|
||||||
|
{
|
||||||
|
const double radialDistance=radius
|
||||||
|
+shellOffsetMetres*qPerMetre;
|
||||||
|
if(radialDistance*radialDistance
|
||||||
|
<=verticalDelta*verticalDelta)continue;
|
||||||
|
const double horizontalDistance=std::sqrt(
|
||||||
|
radialDistance*radialDistance
|
||||||
|
-verticalDelta*verticalDelta);
|
||||||
|
for(const auto& direction:RadialDirections)
|
||||||
|
{
|
||||||
|
const double sampleQ[3]={
|
||||||
|
centerX+direction[0]*horizontalDistance,
|
||||||
|
centerY+direction[1]*horizontalDistance,sampleZ};
|
||||||
|
const double sampleVoxel[3]={sampleQ[0]/Q,
|
||||||
|
sampleQ[1]/Q,sampleQ[2]/Q};
|
||||||
|
const float contribution=ApplyResolvedStratePassageCarves(
|
||||||
|
0.0f,static_cast<float>(sampleVoxel[0]),
|
||||||
|
static_cast<float>(sampleVoxel[1]),
|
||||||
|
static_cast<float>(sampleVoxel[2]));
|
||||||
|
++sampled;
|
||||||
|
if(std::abs(contribution)<=1.0e-6f)continue;
|
||||||
|
++signRelevant;
|
||||||
|
if(PassageProofNodes.empty()
|
||||||
|
||!PassageProofBoundsOverlapNode(0,sampleVoxel,
|
||||||
|
sampleVoxel))
|
||||||
|
++proofMisses;
|
||||||
|
std::array<std::int64_t,3> sampleMinimum{},sampleMaximum{};
|
||||||
|
for(std::size_t axis=0;axis<3;++axis)
|
||||||
|
{
|
||||||
|
sampleMinimum[axis]=static_cast<std::int64_t>(
|
||||||
|
std::floor(sampleQ[axis]));
|
||||||
|
sampleMaximum[axis]=static_cast<std::int64_t>(
|
||||||
|
std::ceil(sampleQ[axis]));
|
||||||
|
}
|
||||||
|
const auto candidates=BuildPassageFeatureTileList(
|
||||||
|
sampleMinimum,sampleMaximum);
|
||||||
|
const bool featureContainsSample=std::any_of(
|
||||||
|
candidates.begin(),candidates.end(),
|
||||||
|
[&](std::uint32_t featureIndex)
|
||||||
|
{
|
||||||
|
return featureIndex<PassageTileFeatures.size()
|
||||||
|
&&PassageTileFeatures[featureIndex].passageIndex
|
||||||
|
==passageIndex;
|
||||||
|
});
|
||||||
|
if(!featureContainsSample)++featureMisses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bool auditPassed=sampled>0&&signRelevant>0
|
||||||
|
&&proofMisses==0&&featureMisses==0;
|
||||||
|
std::printf("[L130PassageReachProofAudit] reach_m=%.3f sampled=%llu sign_relevant=%llu proof_misses=%llu feature_misses=%llu status=%s\n",
|
||||||
|
VF_PassageInfluenceReachMetres,
|
||||||
|
static_cast<unsigned long long>(sampled),
|
||||||
|
static_cast<unsigned long long>(signRelevant),
|
||||||
|
static_cast<unsigned long long>(proofMisses),
|
||||||
|
static_cast<unsigned long long>(featureMisses),
|
||||||
|
auditPassed?"PASS":"FAIL");
|
||||||
|
if(!auditPassed)std::abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PassageProofBoundsOverlapNode(int nodeIndex,const double minimum[3],
|
bool PassageProofBoundsOverlapNode(int nodeIndex,const double minimum[3],
|
||||||
@@ -11442,10 +11564,9 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
|
|||||||
const FIntVector& origin,std::int32_t step,std::int32_t cells,std::uint32_t seed)
|
const FIntVector& origin,std::int32_t step,std::int32_t cells,std::uint32_t seed)
|
||||||
{
|
{
|
||||||
constexpr std::int64_t Q=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
constexpr std::int64_t Q=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||||
constexpr double InfluenceMetres=4.0;
|
|
||||||
constexpr double OpenAirSideWallHeightMetres=1.0;
|
constexpr double OpenAirSideWallHeightMetres=1.0;
|
||||||
if(!shape_||step<=0||cells<=0||!std::isfinite(passageCarveReachMetres_)
|
if(!shape_||step<=0||cells<=0||!std::isfinite(passageCarveReachMetres_)
|
||||||
||std::abs(passageCarveReachMetres_-InfluenceMetres)>1.0e-9)return;
|
||std::abs(passageCarveReachMetres_-VF_PassageInfluenceReachMetres)>1.0e-9)return;
|
||||||
const bool profile=profileStats_!=nullptr;
|
const bool profile=profileStats_!=nullptr;
|
||||||
const auto prepareStart=profile?std::chrono::steady_clock::now()
|
const auto prepareStart=profile?std::chrono::steady_clock::now()
|
||||||
:std::chrono::steady_clock::time_point{};
|
:std::chrono::steady_clock::time_point{};
|
||||||
@@ -11459,7 +11580,7 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
|
|||||||
sweep->dimension=cells+3;
|
sweep->dimension=cells+3;
|
||||||
const std::size_t gridSampleCount=static_cast<std::size_t>(sweep->dimension)
|
const std::size_t gridSampleCount=static_cast<std::size_t>(sweep->dimension)
|
||||||
*static_cast<std::size_t>(sweep->dimension)*static_cast<std::size_t>(sweep->dimension);
|
*static_cast<std::size_t>(sweep->dimension)*static_cast<std::size_t>(sweep->dimension);
|
||||||
sweep->influenceSubvoxels=InfluenceMetres*static_cast<double>(Q)*1000000.0
|
sweep->influenceSubvoxels=passageCarveReachMetres_*static_cast<double>(Q)*1000000.0
|
||||||
/std::max<std::uint32_t>(1,shape_->ResolvedLayout
|
/std::max<std::uint32_t>(1,shape_->ResolvedLayout
|
||||||
?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000);
|
?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000);
|
||||||
sweep->passageToSweep.assign(passageRouteSegments_.size(),-1);
|
sweep->passageToSweep.assign(passageRouteSegments_.size(),-1);
|
||||||
@@ -11473,7 +11594,7 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
|
|||||||
const double qPerMetre=static_cast<double>(Q)*1000000.0/
|
const double qPerMetre=static_cast<double>(Q)*1000000.0/
|
||||||
std::max<std::uint32_t>(1,shape_->ResolvedLayout
|
std::max<std::uint32_t>(1,shape_->ResolvedLayout
|
||||||
?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000);
|
?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000);
|
||||||
const double shellThickness=0.75*qPerMetre;
|
const double shellThickness=VF_PassageShellThicknessMetres*qPerMetre;
|
||||||
const double stampedOutsideDistance=sweep->influenceSubvoxels+1.0;
|
const double stampedOutsideDistance=sweep->influenceSubvoxels+1.0;
|
||||||
constexpr double MouthShellBlendMetres=5.0;
|
constexpr double MouthShellBlendMetres=5.0;
|
||||||
const double wallReliefShell=0.41*qPerMetre;
|
const double wallReliefShell=0.41*qPerMetre;
|
||||||
@@ -11633,7 +11754,7 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
|
|||||||
// more than cornerWidth/6. Skip its work for pairs outside this exact
|
// more than cornerWidth/6. Skip its work for pairs outside this exact
|
||||||
// support, with a small subvoxel guard for float rounding. The final
|
// support, with a small subvoxel guard for float rounding. The final
|
||||||
// shell union only consumes negative distances.
|
// shell union only consumes negative distances.
|
||||||
constexpr double CornerBlendMetres=0.50;
|
constexpr double CornerBlendMetres=VF_PassageCornerBlendMetres;
|
||||||
const float roundDistanceFloat=static_cast<float>(signedDistance);
|
const float roundDistanceFloat=static_cast<float>(signedDistance);
|
||||||
const float floorDistanceFloat=static_cast<float>(floorCenterZ-floorDepth-qz);
|
const float floorDistanceFloat=static_cast<float>(floorCenterZ-floorDepth-qz);
|
||||||
const double flatDistanceLowerBound=std::max(
|
const double flatDistanceLowerBound=std::max(
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# VoxelForge — read-only design review: per-block bit flags (masks) to skip work
|
||||||
|
|
||||||
|
You are reviewing an idea against real code. **Do not edit, create or delete any file, and do not build or run
|
||||||
|
anything.** Read code and reason. Be thorough; mark each claim as [CODE] (with file:line), [MEASURED] (from a report),
|
||||||
|
or [INFERENCE].
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
VoxelForge Core (`Standalone/Core`) generates a density field: negative = solid, positive = air, 25 cm voxels, 32³ tiles,
|
||||||
|
LOD0–8 clipmap, marching cubes. The production mesher for the standalone path is in `Standalone/Source/...`, and Core is
|
||||||
|
also compiled into Unreal. Same seed must give the same world on every machine and worker count; byte-identity with
|
||||||
|
older versions is NOT required.
|
||||||
|
|
||||||
|
Branch `assembler/world` (HEAD `7022d02`'s parent line, currently `4041d4b`) has the smooth inter-strate tunnels.
|
||||||
|
Readiness target: LOD0–2 near terrain in ~1 s on arrival. Measured today: SW ~0.7–0.8 s, VS ~0.9 s, FI/TN ~1.0 s
|
||||||
|
headless. In Linux UE, start→LOD0–2 is ~2.2–2.5 s. At 30 m/s in UE, near coverage is ~40%.
|
||||||
|
|
||||||
|
Reports to consult: `Standalone/Research/WorldAssemblerM3/Linux1*/REPORT.md`, especially:
|
||||||
|
- L77/L87/L117, cost census;
|
||||||
|
- L124, shape gate and per-strate timings;
|
||||||
|
- L125/L126/L128, tunnel prepare: per-segment work, 67–73% pair overlap, support up to 7.9 m;
|
||||||
|
- L128, where an exact one-owner slab scheme halved pairs but got slower because of per-sample ownership tests.
|
||||||
|
|
||||||
|
Tile skipping already exists at tile level: box verdicts / classify, where all-solid or all-air tiles are skipped.
|
||||||
|
|
||||||
|
## The idea (from the owner)
|
||||||
|
|
||||||
|
Keep bit flags per block (1 bit per voxel, or per small brick of e.g. 4³ or 8³ voxels): for example "certainly deep
|
||||||
|
solid", "certainly deep air", "near a surface", "touched by a tunnel", "already evaluated". Use them to skip work in
|
||||||
|
generation and meshing, and possibly elsewhere (collision, streaming, edits, AI/nav, lighting).
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
1. Where does time actually go per tile today, and which of that work a mask could skip? Cover density fill,
|
||||||
|
classification, mesher (marching cubes, normals/gradients, skirts, seam refinement), passage prepare, and composition.
|
||||||
|
Use measured census numbers where they exist.
|
||||||
|
2. Which flags are sound? A flag must be a proof, never a guess. A mask "certainly solid" must be derived from a
|
||||||
|
conservative bound (the bound must be the supremum of what the evaluator produces), or the mesher will delete
|
||||||
|
surfaces. Which bounds already exist in the code (box verdicts, interval bounds) that a brick-level mask could reuse?
|
||||||
|
Name the existing hazards. For example, `Identity` means `Sdf >= T`, and `ClassifyTile` proving below-TerrainZ solid
|
||||||
|
would delete 3D caves.
|
||||||
|
3. Granularity: per-voxel bits vs per-brick (4³/8³) vs per-column. What does each cost to build, versus what it
|
||||||
|
saves? Consider SIMD and cache behaviour. Marching cubes needs only cells whose corner signs differ, and gradients
|
||||||
|
need a halo.
|
||||||
|
4. "Already evaluated" or "checked" flags: where would they be correct (memoisation of identical queries), and where
|
||||||
|
would they be wrong (nearest-of-many queries like the tunnel segments)? Is there repeated identical evaluation today,
|
||||||
|
for example halo samples shared between neighbouring tiles, or skirt/seam re-queries?
|
||||||
|
5. Other uses: player edits (diff layer), collision-only server tiles, streaming priority, nav. Which would a mask
|
||||||
|
genuinely help, given the multiplayer rule (replicate seed + layout + diff, never geometry)?
|
||||||
|
6. Recommendation: the one or two mask designs most likely to pay off, with the expected gain (a range, marked
|
||||||
|
inference), the measurement that would prove or kill each, and the risks. Keep it short.
|
||||||
|
|
||||||
|
Write plain Markdown, at most ~1,200 words.
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
[INFERENCE] **Improve the existing brick-proof system; don’t add a general “checked voxel” mask.** The promising savings are avoided field/composition work and passage preparation, rather than marching-cubes classification.
|
||||||
|
|
||||||
|
References below abbreviate these files: [M = production mesher](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp), [S = ShapeWorldInternal.h](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h), [C = VoxelForgeCore.cpp](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp), [O = VoxelDensityOpStack.cpp](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/VoxelForge/Private/VoxelDensityOpStack.cpp). L-numbers identify `Standalone/Research/WorldAssemblerM3/LinuxN/REPORT.md`.
|
||||||
|
|
||||||
|
[INFERENCE] Evidence limitation: Linux128 is absent from this checkout. Its supplied 7.9 m support and slower one-owner result remain unverified here. The reports below span different revisions; their percentages must not be presented as today’s census.
|
||||||
|
|
||||||
|
**1. Where time goes**
|
||||||
|
|
||||||
|
[MEASURED] L77’s exclusive FI/TN LOD0–2 worker account:
|
||||||
|
|
||||||
|
| Work | FI | TN |
|
||||||
|
|---|---:|---:|
|
||||||
|
| Total worker CPU/view | 23.02 s | 21.50 s |
|
||||||
|
| Passage composition | 65.9% | 65.4% |
|
||||||
|
| Support | 14.2% | 13.5% |
|
||||||
|
| Base field | 3.2% | 3.3% |
|
||||||
|
| Bands / dispatch | 2.3% / 3.7% | 2.6% / 3.6% |
|
||||||
|
| MC / skirts / refinement, excluding field work | 1.6% / 0.1% / 7.5% | 1.2% / 0.2% / 8.6% |
|
||||||
|
|
||||||
|
[MEASURED] Grid fill occupied 19.058/17.377 worker-seconds, **overlapping** those phase categories. L117’s later census found support zero; its smooth-tunnel regression concentrated about 95% of added tile CPU in passage-feature tiles. Cell classification stayed flat; gradients became cheaper. Thus L77 identifies historical leverage, not current percentages.
|
||||||
|
|
||||||
|
[MEASURED] L125 preparation averaged 514/130/4.1 ms worker work at LOD0/1/2. LOD0 evaluated 3.11–8.49 million segment/sample pairs with 67–72% overlap, although the exact band occupied only 5–7% of grid samples. L126 reduced floor-profile calls 20–23% without useful readiness improvement.
|
||||||
|
|
||||||
|
[CODE] Brick skipping already exists: configurable block verdicts, required-sample masks, and active-block gradient halos (M:646,1053). MC already rejects cells without sign crossings before interpolation/gradients (M:2186). Gradient memoisation exists (M:1956). Skirts issue separate density queries (M:2491); refinement has its own stage (C:2975).
|
||||||
|
|
||||||
|
[INFERENCE] A pre-evaluation proof can save density, composition, and subsequent MC work. A sign mask constructed after density evaluation saves only downstream scanning. Classification itself costs work; no isolated current classification percentage is established by these reports.
|
||||||
|
|
||||||
|
[MEASURED] L124’s shape gate alone took 179–226 ms, with no near-tile admissions before completion. L87 additionally measured a 107–153 ms far-parent gate and no headless collision wait. Tile masks cannot directly remove these gates or explain the supplied UE/headless gap.
|
||||||
|
|
||||||
|
**2. Sound flags and hazards**
|
||||||
|
|
||||||
|
[INFERENCE] For final density \(D\), solid requires an upper bound covering the evaluator’s supremum, \(U<0\); air requires a valid lower bound \(L\ge0\). “Deep” requires an explicit margin. Unknown must stay unknown. A crossing proves an MC-active cell; uniform sampled signs do not prove an entire continuous volume surface-free.
|
||||||
|
|
||||||
|
[CODE] Reusable proofs include:
|
||||||
|
|
||||||
|
- S:5428: halo-expanded box classification.
|
||||||
|
- S:5974: exact surface-column extrema over the MC lattice.
|
||||||
|
- S:6019: floating-island density intervals.
|
||||||
|
- S:5197,6032: native cave intervals.
|
||||||
|
- S:5949: stamp interval composition with outward numerical padding.
|
||||||
|
- O:6998: operation-specific inactivity from SDF lower bounds.
|
||||||
|
|
||||||
|
[CODE] These proofs have guards: passage overlap returns unknown (S:5687); unsupported stamp composition returns unknown (S:5655); stratum crossings are rejected (S:5900). The mesher distinguishes uniform candidates from `bSkipSafe` certificates (M:715,756), and otherwise validates candidates against actual samples (M:1838).
|
||||||
|
|
||||||
|
[CODE] For gated modifiers, `Identity` can mean `Sdf >= T`, not `abs(Sdf) >= T` (O:1496,6998). Noise bounds cannot assume nominal `[-1,1]`: FBM and unclamped cellular bounds are explicitly discussed at O:848,301.
|
||||||
|
|
||||||
|
[INFERENCE] Additional hazards: confusing internal SDF with final density; certifying base terrain before caves, tunnels, shells, stamps or edits; using lattice proofs for off-grid queries; ignoring rounding or gradient halos. A below-`TerrainZ` solid rule applied to 3D caves deletes caves. “Touched by tunnel” should mean conservative candidate overlap; only **proven untouched** authorizes omission.
|
||||||
|
|
||||||
|
**3. Granularity**
|
||||||
|
|
||||||
|
[INFERENCE] Storage per flag for 32³ cells:
|
||||||
|
|
||||||
|
| Granularity | Storage | Construction/tradeoff |
|
||||||
|
|---|---:|---|
|
||||||
|
| Per cell | 4 KiB | 32,768 decisions; expensive unless derived during necessary work |
|
||||||
|
| 4³ bricks | 64 B | 512 proofs; tighter boundaries, more proof/halo overhead |
|
||||||
|
| 8³ bricks | 8 B | 64 proofs; cheaper, more mixed bricks |
|
||||||
|
| XY columns | 128 B | 1,024 decisions; useful mainly for heightfield-specific proofs |
|
||||||
|
|
||||||
|
[INFERENCE] These exclude corner/halo samples, metadata and additional flags. A column bit cannot represent multiple cave intervals. Brick runs preserve contiguous X sampling and SIMD better than scattered per-sample branches; bit packing alone does not establish a speedup.
|
||||||
|
|
||||||
|
[CODE] The existing implementation uses byte arrays and preserves exact samples around active bricks (M:1053–1083). Replacing densities with arbitrary same-sign constants near active cells would corrupt interpolated positions or normals.
|
||||||
|
|
||||||
|
**4. “Already evaluated”**
|
||||||
|
|
||||||
|
[CODE] Passage preparation precedes meshing (C:2747). Its valid sentinel is initialization, not completion: subsequent segments update floor selection, shell minima and round-distance winners, with deterministic tie-breaking (S:11520,11615,11688).
|
||||||
|
|
||||||
|
[INFERENCE] Therefore first-visitor wins is invalid. Memoisation is valid only for identical queries against identical seed/layout/evaluator/edit revision and query semantics; cache the value, not just a bit.
|
||||||
|
|
||||||
|
[MEASURED] L77 counted 8.6–8.9% halo points, without measuring duplicate coordinates. L125 verified 4,900 shared samples across four neighbour pairs and still recorded substantial off-grid skirt/midpoint fallbacks.
|
||||||
|
|
||||||
|
[CODE] Shared-grid reuse and gradient validity caches already exist (M:1031,1956). [INFERENCE] Skirt/seam queries are reuse candidates only when coordinates and semantics actually match; “same voxel” is insufficient.
|
||||||
|
|
||||||
|
**5. Other uses**
|
||||||
|
|
||||||
|
[INFERENCE] Edit-dirty bricks can localize regeneration, with invalidation expanded through normals, seams and collision dependencies. Collision-only servers can skip certified empty regions, but still need boundary geometry. Streaming can prioritize potentially occupied bricks; nav and lighting need clearance/connectivity or visibility data beyond occupancy. Keep masks derived locally from replicated seed + layout + diff, versioned with that state.
|
||||||
|
|
||||||
|
**6. Recommendation**
|
||||||
|
|
||||||
|
- [INFERENCE] **Tune existing 4³/8³ certificates**, caching proofs and emitting contiguous required-sample runs. Plausible incremental near-ready saving: **0–5%**, with regressions possible. Measure proof time, samples avoided, halo expansion, total worker CPU and UE readiness.
|
||||||
|
- [INFERENCE] **Pass required-region information into passage preparation**, rejecting whole segment/brick regions conservatively. Plausible near-ready saving: **0–10%**, highly uncertain because passage overlap currently vetoes proofs. Kill it if pair reduction fails to reduce preparation and end-to-end time.
|
||||||
|
|
||||||
|
[INFERENCE] Both require seam/off-grid validation, adversarial bound checks, edit invalidation tests, and cross-machine/worker determinism. Preserve canonical tie-breaking; old-version byte identity need not constrain a sound redesign.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# VoxelForge — open read-only review: what should be done and focused on now?
|
||||||
|
|
||||||
|
You are an outside reviewer. **Do not edit, create or delete any file, and do not build or run anything.** Read the
|
||||||
|
repository and its reports and reason. Be thorough; mark each claim as [CODE] (with file:line), [MEASURED] (from a
|
||||||
|
report), or [INFERENCE].
|
||||||
|
|
||||||
|
## The project, in the owner's words and goals
|
||||||
|
|
||||||
|
- VoxelForge is a UE5 density-field voxel plugin for a **multiplayer** game. The world is made of stacked "strates"
|
||||||
|
(layers) linked by tunnels. The standalone C++ generator is "Core" (`Standalone/Core`), and it is also compiled into
|
||||||
|
Unreal. Read `CLAUDE.md`, `CODEMAP.md`, `ARCHITECTURE.md`, `GDD.md`, `COMPOSER-NOTES.md` and `fable-idea.md` at the
|
||||||
|
plugin root for the game and design intent. The research reports are in
|
||||||
|
`Standalone/Research/WorldAssemblerM3/Linux*/REPORT.md` and the `Astra*/` reviews.
|
||||||
|
- Owner goals stated over time:
|
||||||
|
- the near terrain (LOD0–2) ready in ~1 s on arrival, then far terrain keeps filling in at low priority;
|
||||||
|
- same seed gives the same world on every machine (byte-identity with older versions is NOT required);
|
||||||
|
- smooth for VR and high-speed travel;
|
||||||
|
- all generators (surface, floating islands, caves, dreamcore/liminal, etc.) working in Core;
|
||||||
|
- the system should eventually *invent* strates and worlds from tagged authored content plus a seed;
|
||||||
|
- keep things simple and avoid over-complication.
|
||||||
|
- The current main line is branch `assembler/world`.
|
||||||
|
|
||||||
|
## Your task
|
||||||
|
|
||||||
|
Look at the whole: code, reports, design docs, and the direction of the last few dozen rounds. Tell the owner what
|
||||||
|
should be done and focused on now, whatever it is. That may be performance, features, generation quality, gameplay
|
||||||
|
foundations, architecture, technical debt, tooling, process, or stopping something. Don't assume the recent focus is
|
||||||
|
the right one; question it if the evidence says so.
|
||||||
|
|
||||||
|
Answer:
|
||||||
|
1. **Where the project actually is**: what works, what's fragile, what's missing for the game to exist.
|
||||||
|
2. **The top 3–5 things to focus on now**, ranked, each with why, a rough size, what "done" looks like, and how to
|
||||||
|
tell it worked.
|
||||||
|
3. **What to stop or deprioritise**, and why.
|
||||||
|
4. **Risks or debts** that will bite later if ignored.
|
||||||
|
|
||||||
|
Write plain Markdown, at most ~1,500 words, readable by a non-specialist owner (explain jargon briefly).
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
[INFERENCE] **Focus now on a small, persistent multiplayer descent, supported by end-to-end Unreal performance work.** VoxelForge has substantial terrain technology. The larger uncertainty is whether it delivers a reliable, interesting shared expedition. Another sequence of tunnel optimizations will not resolve that.
|
||||||
|
|
||||||
|
Read-only review of `assembler/world` at `044cd6d`; no files changed and no builds, tests, or project execution. [CODE] identifies repository evidence; design-document references establish intent, not implementation. [MEASURED] means reported results, not independently reproduced measurements.
|
||||||
|
|
||||||
|
**1. Where the project actually is**
|
||||||
|
|
||||||
|
[CODE] **Core is real and integrated, but generator implementation remains mixed.** Unreal compiles the canonical standalone sources through validated wrappers. Core dispatches to surface, floating-island and native graph evaluators, with a legacy-generator fallback when appropriate. That is useful coverage, but does not mean every family has a complete native implementation. See [VoxelForgeCore.Build.cs:15](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForgeCore/VoxelForgeCore.Build.cs:15) and [ShapeWorldInternal.h:600](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:600).
|
||||||
|
|
||||||
|
[MEASURED] **Passage correctness and speed have improved substantially.** L109 simplified tunnels and removed support-restoration machinery, reducing floating-island and tunnel-network near-generation times by approximately 31–38%. L125 reports 21,425/21,425 open route samples, a maximum sampled floor offset of 7.884 mm, and matching cross-compiler/worker hashes. These are meaningful engineering achievements. [L109](Standalone/Research/WorldAssemblerM3/Linux109/REPORT.md), [L125](Standalone/Research/WorldAssemblerM3/Linux125/REPORT.md).
|
||||||
|
|
||||||
|
[MEASURED] **The one-second player experience is not achieved.** L125’s standalone near-ready medians were approximately 0.78–1.03 seconds. L127’s Unreal startup took 2.22–2.51 seconds; at 30 m/s, median near coverage fell from 43.36% to 40.22% after the smooth-tunnel merge. Both versions recovered after stopping. L130 found no measurable timing improvement and skipped Unreal movement. These are different workloads; subtracting their times would not isolate a particular overhead. [L125](Standalone/Research/WorldAssemblerM3/Linux125/REPORT.md), [L127](Standalone/Research/WorldAssemblerM3/Linux127/REPORT.md), [L130](Standalone/Research/WorldAssemblerM3/Linux130/REPORT.md).
|
||||||
|
|
||||||
|
[CODE] **Multiplayer foundations exist; the multiplayer lifecycle remains unfinished here.** There are season hashes, local terrain-edit entry points, and streaming-anchor infrastructure. The architecture explicitly leaves join replication, authoritative edit messages, late-join snapshots and networked season changes open. The edit entry point directly dispatches to local modification paths. [VoxelWorld.h:574](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Public/VoxelWorld.h:574), [VoxelWorld.cpp:15771](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:15771), [ARCHITECTURE.md:2408](/home/jahni/VoxelM/Plugins/VoxelForge/ARCHITECTURE.md:2408).
|
||||||
|
|
||||||
|
[CODE] **The composer is more than a proposal, but less than the full content vision.** It rolls candidates, measures them and rejects failures. The intended system additionally combines tagged geometry, materials, decorations, creatures and audio; theme coherence remains an open design item. [VoxelSeasonManifest.cpp:2523](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelSeasonManifest.cpp:2523), [COMPOSER-NOTES.md:1512](/home/jahni/VoxelM/Plugins/VoxelForge/COMPOSER-NOTES.md:1512).
|
||||||
|
|
||||||
|
[INFERENCE] **This repository demonstrates a capable terrain platform, not yet a validated game loop.** I cannot establish what gameplay exists outside the plugin. The GDD itself identifies “Is the descent fun?” as its first unresolved question. [GDD.md:441](/home/jahni/VoxelM/Plugins/VoxelForge/GDD.md:441).
|
||||||
|
|
||||||
|
**2. Ranked priorities**
|
||||||
|
|
||||||
|
All sizes below are [INFERENCE]: rough focused engineering estimates, excluding substantial art production.
|
||||||
|
|
||||||
|
**1 — Deliver one multiplayer expedition that survives reconnecting. Size: 3–6 weeks.**
|
||||||
|
|
||||||
|
[INFERENCE] Use two contrasting strates and their connecting tunnel. Two players descend, find one destination, uncover or collect something, return, and retain their changes after restart. Include a third player joining after terrain has changed. Avoid expanding immediately into the city economy or community backend.
|
||||||
|
|
||||||
|
[INFERENCE] The necessary foundation is a server-approved world identity, ordered authoritative edits, a saved snapshot plus subsequent edits, and collision around separated players. Give edits stable identifiers so retransmission cannot apply them twice. Reuse the existing local edit and anchor systems.
|
||||||
|
|
||||||
|
[INFERENCE] **Done:** host/client edits agree; a late joiner reconstructs the same terrain; restart preserves it; incompatible world versions fail clearly; remote players have ground when away from the host.
|
||||||
|
|
||||||
|
[INFERENCE] **Success:** a complete shared expedition without terrain disagreement, lost progress or collision failures—and players can explain what made them want to descend again. This tests the project’s central assumptions much earlier than a complete RPG would.
|
||||||
|
|
||||||
|
**2 — Close the Unreal arrival and movement gap. Size: 1–3 weeks initially.**
|
||||||
|
|
||||||
|
[MEASURED] L122 found idle generation capacity while admission was blocked; L123 measured approximately 19 ms from region request to game-thread observation despite sub-millisecond median compilation. Simple lookahead and admission relaxations failed their combined coverage/frame-time gates. L121’s modest extra far-apply lane did improve far coverage. [L121](Standalone/Research/WorldAssemblerM3/Linux121/REPORT.md), [L122](Standalone/Research/WorldAssemblerM3/Linux122/REPORT.md), [L123](Standalone/Research/WorldAssemblerM3/Linux123/REPORT.md).
|
||||||
|
|
||||||
|
[INFERENCE] First establish one current-build, rendered Unreal baseline on intended hardware. Measure arrival through **visible terrain and usable collision**, then walking, 30 m/s travel, turns, teleporting and edits. Record near coverage, far gaps, frame-time spikes and memory separately. NullRHI measurements, which omit rendering, cannot certify VR comfort.
|
||||||
|
|
||||||
|
[INFERENCE] Investigate region completion, admission and publication before another broad density rewrite. A game-thread continuation is a candidate experiment, not a proven solution; keep world mutation on its owning thread.
|
||||||
|
|
||||||
|
[INFERENCE] **Done:** approximately one-second LOD0–2 readiness on the agreed hardware, safe collision, steadily filling far terrain, and an explicit movement-coverage target without worsening frame spikes. **Success:** repeated rendered runs meet those limits, including with remote-player collision work. Do not redefine “ready” as only the nearest handful of tiles.
|
||||||
|
|
||||||
|
**3 — Turn generator breadth into playable variety. Size: 2–4 weeks for the first content slice.**
|
||||||
|
|
||||||
|
[INFERENCE] Establish a compact capability matrix for each family: Core dispatch, entrances/exits, interior connectivity, edits, materials/content, far terrain and performance. Include dreamcore/liminal explicitly; motif generation alone does not establish a convincing anomalous place.
|
||||||
|
|
||||||
|
[MEASURED] L58 illustrates the distinction: its lattice route passed reachability checks, but the review described a corkscrew tunnel rather than the intended open vertical shaft. Technical validity and identity are separate acceptance criteria. [L58](Standalone/Research/WorldAssemblerM3/Linux58/REPORT.md).
|
||||||
|
|
||||||
|
[INFERENCE] Extend the existing offline composer with a small tagged library: a grounded cave, an island environment and one liminal identity, each with coherent materials, sound and a destination. Preserve owner review before publishing a season.
|
||||||
|
|
||||||
|
[INFERENCE] **Done:** several seeds produce recognizably different, coherent places with findable progression and usable encounter spaces. **Success:** players navigate them without developer guidance and distinguish their identities without reading labels. Expand families after this works.
|
||||||
|
|
||||||
|
**4 — Consolidate the evidence and remove obsolete complexity incrementally. Size: 2–4 days, then ongoing.**
|
||||||
|
|
||||||
|
[INFERENCE] Maintain one short current-state page: shipped behavior, open defects, active baseline, hardware and next acceptance test. Keep historical reports as history. Remove rejected experimental paths when they no longer serve a specific comparison; extract stable responsibilities when touching oversized files.
|
||||||
|
|
||||||
|
[INFERENCE] **Done:** a contributor can identify the current evaluator, runtime path, multiplayer gaps and performance limits without reconstructing 130 rounds. **Success:** new work no longer repeats rejected experiments or treats old measurements as current.
|
||||||
|
|
||||||
|
**3. Stop or deprioritise**
|
||||||
|
|
||||||
|
- [INFERENCE] **Pause open-ended tunnel micro-optimization.** L125/L126 missed the older speed bar; L130’s reach correction produced no measurable speedup. Keep correctness fixes, but require a current cost account and a bounded experiment before further optimization. [MEASURED: L126](Standalone/Research/WorldAssemblerM3/Linux126/REPORT.md), [L130](Standalone/Research/WorldAssemblerM3/Linux130/REPORT.md).
|
||||||
|
- [INFERENCE] **Do not implement Astra recommendations mechanically.** Astra1’s support-heavy model predates L109’s simplification. Astra2/3 offer hypotheses, not measured wins for today’s code. Re-profile before adopting them.
|
||||||
|
- [INFERENCE] **Defer GPU generation, a mesher replacement, elaborate discovery systems and large-scale backend work.** None currently resolves the missing shared expedition.
|
||||||
|
- [INFERENCE] **Stop requiring old-version byte identity for deliberate generation changes.** Preserve peer agreement within a version and explicit versioned saves; permit reviewed geometry improvements.
|
||||||
|
|
||||||
|
**4. Debts that will bite later**
|
||||||
|
|
||||||
|
[INFERENCE] **Determinism needs a deployment contract.** Linux Clang/GCC and worker-count agreement is strong evidence, not proof across every intended machine. Include Windows/compiler/CPU combinations actually supported. World identity must cover evaluator, content, layout, scale and edit state—not merely seed. [MEASURED: L130](Standalone/Research/WorldAssemblerM3/Linux130/REPORT.md).
|
||||||
|
|
||||||
|
[CODE] **Scale and fallback complexity remain active integration risks.** Core is opt-in, and runtime queries bridge different coordinate conventions. [VoxelWorld.h:300](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Public/VoxelWorld.h:300), [VoxelWorld.cpp:15612](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:15612). [INFERENCE] Test edits, content placement and collision across those boundaries before broadening authoring.
|
||||||
|
|
||||||
|
[INFERENCE] **A passing route audit does not prove a whole strate is enjoyable, connected or suitable for six-player combat.** Retain geometric checks, but add actual traversal, destination discovery and encounter-space evaluation. Those are now more valuable than another polished tunnel benchmark.
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# L128 slab ownership
|
|
||||||
|
|
||||||
Base `4041d4b`; branch `wip/l128-slab-ownership`; core version 226. Source stamp: `8682a9a088f0f02357b3b9722cda9b18a5ebce9886a13cba2d114bc0655d8c70`.
|
|
||||||
|
|
||||||
Each route body uses half-open frame-plane slabs, so a boundary sample belongs to one segment. The required support is `S = r + max(4.0 + 0.21 + 0.125, 0.75 + 0.21) + 0.05 m`: bore radius plus the larger sweep/relief/corner or shell/relief reach, with a 5 cm audit margin. The largest body support is 7.885 m; the 4.5 m mouth profile reaches 8.885 m and is assigned to transition slabs. Local uniqueness requires curvature radius `R > S` (`κS < 1`). For equal adjacent chord lengths `L` and turn `θ`, this is `L / (2 sin(θ/2)) > S`. Nonlocal mutually-normal centerline pairs must be farther apart than the sum of their supports. Intersections between different passages remain a deterministic field union.
|
|
||||||
|
|
||||||
All three owner-world routes pass the body curvature and self-separation checks; no route control points changed. Minimum body curvature radii are 11.565 m (0–1), 14.042 m (1–2), and 8.869 m (2–3), giving at least 0.984 m margin over body support. Route 0–1's 8 tight mouth joints and 5 nonlocal mouth pairs use transitions. The prepared/off-grid query paths share ownership. The audit tested 33,813 support samples: zero missing or duplicate owners, and both negative controls were detected.
|
|
||||||
|
|
||||||
The slab projection supplies `s` to the continuous floor profile `h(s)`; round-distance does not choose floor height. Across 459 floor roots at nine stations, the largest adjacent root step was 1.765 mm and the largest absolute station offset was 7.884 mm. Seam audit: 4,900 shared samples, zero mismatches. Fast suite passed (264 checks, 5 diagnostic); walkability passed. Clang and GCC W1/W8/W12 hashes matched across all three datasets. The 23 L125 captures are in `captures/L128/` (19 pass; 4 low-contrast with geometry visible).
|
|
||||||
|
|
||||||
**Performance bar failed.** Five interleaved runs per group across all four strates and W8/W12 put LOD0–2 readiness 14.8–28.0% behind L109 and 8.0–20.6% behind `4041d4b`. The five-run 30 m/s UE median also failed versus `4041d4b`: near coverage 31.46% vs 40.22%, moving far holes 5.66% vs 3.46%, p99 tick 12.42 ms vs 10.80 ms, and worst tick 14.35 ms vs 13.27 ms. L128 is not ready.
|
|
||||||
|
|
||||||
Linux UE host build succeeded (27/27 actions, `-NoUBA -MaxParallelActions=4`); Unreal ran without `prlimit`. No commit made. Detailed logs are under `Saved/Linux/l128/`.
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Render the exact 23 L125 camera views with the L128 slab-ownership candidate."""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import importlib.util
|
|
||||||
import json
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
sys.dont_write_bytecode = True
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[4]
|
|
||||||
RESEARCH = Path(__file__).resolve().parent
|
|
||||||
CAPTURES = RESEARCH / "captures"
|
|
||||||
SAVED = ROOT / "Saved/Linux/l128/captures"
|
|
||||||
BASELINE_INDEX = (ROOT / "Standalone/Research/WorldAssemblerM3/Linux125"
|
|
||||||
/ "captures/L125/capture-index.json")
|
|
||||||
LAYOUT = ROOT / "Saved/Linux/l128/hashes/owner4-surface-world-w12-clang.layout.json"
|
|
||||||
CLANG = ROOT / os.environ.get("L128_CAPTURE_CLANG",
|
|
||||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19")
|
|
||||||
RENDERER = ROOT / os.environ.get("L128_CAPTURE_RENDERER",
|
|
||||||
"Saved/Linux/l128/bin/VoxelForgeOffscreenCapture-clang19")
|
|
||||||
HELPER_PATH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113/RunL113Captures.py"
|
|
||||||
|
|
||||||
SPEC = importlib.util.spec_from_file_location("l113_capture_helpers", HELPER_PATH)
|
|
||||||
if SPEC is None or SPEC.loader is None:
|
|
||||||
raise SystemExit("cannot load the verified L113 capture helpers")
|
|
||||||
HELPERS = importlib.util.module_from_spec(SPEC)
|
|
||||||
SPEC.loader.exec_module(HELPERS)
|
|
||||||
HELPERS.RESEARCH = RESEARCH
|
|
||||||
HELPERS.CAPTURES = CAPTURES
|
|
||||||
HELPERS.SAVED = SAVED
|
|
||||||
HELPERS.BINARIES = {"L128": CLANG}
|
|
||||||
HELPERS.RENDERERS = {"L128": RENDERER}
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
if any(not path.is_file() for path in (BASELINE_INDEX, LAYOUT, CLANG, RENDERER)):
|
|
||||||
raise SystemExit("missing L125 camera set, L128 layout, or capture binary")
|
|
||||||
baseline = json.loads(BASELINE_INDEX.read_text(encoding="utf-8"))
|
|
||||||
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
|
|
||||||
rows = []
|
|
||||||
CAPTURES.mkdir(parents=True, exist_ok=True)
|
|
||||||
SAVED.mkdir(parents=True, exist_ok=True)
|
|
||||||
for view in baseline["captures"]:
|
|
||||||
row = HELPERS.capture("L128", view, layout)
|
|
||||||
row["variant"] = "L128-slab-ownership-v226"
|
|
||||||
if view["kind"] == "rock-floor-close":
|
|
||||||
scene = ROOT / row["scene"]
|
|
||||||
anchor = HELPERS.nearest_surface_anchor(scene, view["target"], margin_m=5.0,
|
|
||||||
preferred_normal=(0.0, 0.0, 1.0), minimum_alignment=0.85)
|
|
||||||
alignment = HELPERS.dot(anchor["normal"], (0.0, 0.0, 1.0))
|
|
||||||
camera_distance = math.dist(row["camera_actual_m"], anchor["position_m"])
|
|
||||||
row.update({"floor_anchor_position_m": anchor["position_m"],
|
|
||||||
"floor_anchor_normal": anchor["normal"],
|
|
||||||
"closeup_camera_to_floor_distance_m": camera_distance,
|
|
||||||
"closeup_floor_normal_alignment": alignment,
|
|
||||||
"verified_upward_floor_normal": alignment >= 0.85})
|
|
||||||
if (not row["verified"] or not 2.0 <= camera_distance <= 3.2
|
|
||||||
or anchor["distance_m"] > 0.25 or alignment < 0.85
|
|
||||||
or row["drawn_triangles"] <= 0
|
|
||||||
or row["pixel_quality_status"] not in
|
|
||||||
("pass", "low_contrast_geometry_visible")):
|
|
||||||
raise RuntimeError(f"L128 floor close-up failed at {view['name']}")
|
|
||||||
rows.append(row)
|
|
||||||
if len(rows) != len(baseline["captures"]) or len(rows) != 23:
|
|
||||||
raise RuntimeError(f"expected all 23 L125 views, captured {len(rows)}")
|
|
||||||
index = CAPTURES / "L128" / "capture-index.json"
|
|
||||||
index.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
index.write_text(json.dumps({"captures": rows}, indent=2) + "\n",
|
|
||||||
encoding="utf-8")
|
|
||||||
|
|
||||||
html = ["<!doctype html><meta charset='utf-8'>",
|
|
||||||
"<title>L125 / L128 tunnel capture comparison</title>",
|
|
||||||
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
|
|
||||||
"section{margin:28px 0}h2{font-size:18px}div{display:grid;"
|
|
||||||
"grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}"
|
|
||||||
"p{color:#bbb}</style>",
|
|
||||||
"<h1>L125 / L128 slab ownership: identical views</h1>"]
|
|
||||||
old_by_name = {Path(row["capture"]).name: row for row in baseline["captures"]}
|
|
||||||
for row in rows:
|
|
||||||
name = Path(row["capture"]).name
|
|
||||||
old = old_by_name[name]
|
|
||||||
old_path = os.path.relpath(ROOT / "Standalone/Research/WorldAssemblerM3/Linux125"
|
|
||||||
/ old["capture"], CAPTURES)
|
|
||||||
new_path = os.path.relpath(RESEARCH / row["capture"], CAPTURES)
|
|
||||||
html.extend(["<section>", f"<h2>{row['passage']} — {row['station']}</h2>",
|
|
||||||
f"<p>{row['kind']} · L125 {old['pixel_quality_status']} · "
|
|
||||||
f"L128 {row['pixel_quality_status']}</p>", "<div>",
|
|
||||||
f"<figure><figcaption>L125</figcaption><img src='{old_path}'></figure>",
|
|
||||||
f"<figure><figcaption>L128 slab ownership</figcaption><img src='{new_path}'></figure>",
|
|
||||||
"</div>", "</section>"])
|
|
||||||
(CAPTURES / "COMPARE.html").write_text("\n".join(html) + "\n",
|
|
||||||
encoding="utf-8")
|
|
||||||
print(f"[L128Captures] rendered={len(rows)} views index={index.relative_to(ROOT)}",
|
|
||||||
flush=True)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Probe reconstructed tunnel floor roots at the nine L119 stations."""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import csv
|
|
||||||
import json
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import statistics
|
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[4]
|
|
||||||
OUT = ROOT / os.environ.get("L128_PROBE_DIR", "Saved/Linux/l128/floor-probe")
|
|
||||||
BINARY = ROOT / os.environ.get("L128_PROBE_BINARY",
|
|
||||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19")
|
|
||||||
DATA = ROOT / "Standalone/data/owner_world.json"
|
|
||||||
SLOPE = re.compile(
|
|
||||||
r"^\[L115DensitySlopeSample\] passage=(\S+) station=(\S+) s_m=([\d.]+) "
|
|
||||||
r".*?planned_floor_m=(-?[\d.]+) root_floor_m=(-?[\d.]+|nan) "
|
|
||||||
r"residual_m=(-?[\d.]+|nan)", re.M)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
OUT.mkdir(parents=True, exist_ok=True)
|
|
||||||
log, layout = OUT / "owner4-clang.log", OUT / "layout.json"
|
|
||||||
command = [
|
|
||||||
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
|
||||||
"timeout", "1740s", str(BINARY), str(DATA), "--world-assembler-prototype",
|
|
||||||
"--stream-benchmark", "--stream-pipeline", "--workers=12", "--clip-radius=3",
|
|
||||||
"--max-clip-level=8", "--max-level=8",
|
|
||||||
"--camera=8,16,-372.2626953125,0,0", "--audit-resolved-layout-passages",
|
|
||||||
f"--resolved-layout-output={layout}",
|
|
||||||
]
|
|
||||||
with log.open("w", encoding="utf-8") as stream:
|
|
||||||
result = subprocess.run(command, cwd=ROOT,
|
|
||||||
env={**os.environ, "VOXELFORGE_L115_DENSITY_PROFILE": "1"},
|
|
||||||
stdout=stream, stderr=subprocess.STDOUT, check=False, timeout=1740)
|
|
||||||
if result.returncode:
|
|
||||||
raise SystemExit(f"density probe failed: {log}; exit={result.returncode}")
|
|
||||||
text = log.read_text(encoding="utf-8", errors="replace")
|
|
||||||
groups: dict[tuple[str, str], list[dict]] = {}
|
|
||||||
for passage, station, distance, planned, root, residual in SLOPE.findall(text):
|
|
||||||
root_value = float(root) if root != "nan" else math.nan
|
|
||||||
residual_value = float(residual) if residual != "nan" else math.nan
|
|
||||||
groups.setdefault((passage, station), []).append({
|
|
||||||
"route_s_m": float(distance), "planned_floor_m": float(planned),
|
|
||||||
"root_floor_m": root_value, "offset_m": residual_value})
|
|
||||||
summary = []
|
|
||||||
with (OUT / "zero-crossing-offsets.csv").open("w", newline="", encoding="utf-8") as stream:
|
|
||||||
writer = csv.DictWriter(stream, fieldnames=("passage", "station", "route_s_m",
|
|
||||||
"planned_floor_m", "root_floor_m", "offset_m"))
|
|
||||||
writer.writeheader()
|
|
||||||
for (passage, station), samples in sorted(groups.items()):
|
|
||||||
samples.sort(key=lambda sample: sample["route_s_m"])
|
|
||||||
for sample in samples:
|
|
||||||
writer.writerow({"passage": passage, "station": station, **sample})
|
|
||||||
finite = [sample["offset_m"] for sample in samples
|
|
||||||
if math.isfinite(sample["offset_m"])]
|
|
||||||
adjacent_steps = [abs(right["offset_m"] - left["offset_m"])
|
|
||||||
for left, right in zip(samples, samples[1:])
|
|
||||||
if math.isfinite(left["offset_m"])
|
|
||||||
and math.isfinite(right["offset_m"])]
|
|
||||||
summary.append({"passage": passage, "station": station,
|
|
||||||
"samples": len(samples), "finite_roots": len(finite),
|
|
||||||
"max_abs_offset_m": max(map(abs, finite)) if finite else None,
|
|
||||||
"max_adjacent_root_step_m": max(adjacent_steps)
|
|
||||||
if adjacent_steps else None,
|
|
||||||
"median_abs_offset_m": statistics.median(map(abs, finite))
|
|
||||||
if finite else None,
|
|
||||||
"p95_abs_offset_m": sorted(map(abs, finite))[
|
|
||||||
min(len(finite)-1, math.ceil(0.95*len(finite))-1)]
|
|
||||||
if finite else None})
|
|
||||||
if not summary or any(item["samples"] != 51 for item in summary):
|
|
||||||
raise RuntimeError("density profile is missing 51-sample route stations")
|
|
||||||
worst_step = max(item["max_adjacent_root_step_m"] or 0.0 for item in summary)
|
|
||||||
if worst_step > 0.003:
|
|
||||||
raise RuntimeError(f"floor root jumps by {worst_step:.6f} m between 0.1 m probes")
|
|
||||||
(OUT / "zero-crossing-summary.json").write_text(
|
|
||||||
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
|
|
||||||
print(f"[L128DensityProbe] exit={result.returncode} stations={len(summary)} "
|
|
||||||
f"log={log.relative_to(ROOT)}", flush=True)
|
|
||||||
return result.returncode
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Check Clang/GCC W1/W8/W12 hash determinism for L128."""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[4]
|
|
||||||
OUT = ROOT / os.environ.get("L128_HASH_DIR", "Saved/Linux/l128/hashes")
|
|
||||||
DATASETS = {
|
|
||||||
"owner4": ROOT / "Standalone/data/owner_world.json",
|
|
||||||
"owner2": ROOT / "Standalone/data/regression/owner_world_2strate_l61.json",
|
|
||||||
}
|
|
||||||
BINARIES = {
|
|
||||||
"clang": ROOT / os.environ.get("L128_HASH_CLANG",
|
|
||||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19"),
|
|
||||||
"gcc": ROOT / os.environ.get("L128_HASH_GCC",
|
|
||||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-l128-gcc"),
|
|
||||||
}
|
|
||||||
HASH = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
|
|
||||||
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=(\S+)$", re.M)
|
|
||||||
|
|
||||||
|
|
||||||
def run(dataset: str, recipe: str, workers: int, compiler: str) -> dict:
|
|
||||||
OUT.mkdir(parents=True, exist_ok=True)
|
|
||||||
label = f"{dataset}-{recipe}-w{workers}-{compiler}"
|
|
||||||
log = OUT / f"{label}.log"
|
|
||||||
layout = OUT / f"{label}.layout.json"
|
|
||||||
command = [
|
|
||||||
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
|
||||||
"timeout", "1740s", str(BINARIES[compiler]), str(DATASETS[dataset]),
|
|
||||||
f"--workers={workers}", "--world-assembler-prototype", "--stream-benchmark",
|
|
||||||
"--stream-pipeline", "--force-generate", "--clip-radius=3",
|
|
||||||
"--max-clip-level=8", "--max-level=8", f"--recipe={recipe}",
|
|
||||||
"--stream-hash", f"--resolved-layout-output={layout}",
|
|
||||||
]
|
|
||||||
started = time.monotonic()
|
|
||||||
with log.open("w", encoding="utf-8") as stream:
|
|
||||||
result = subprocess.run(command, cwd=ROOT, stdout=stream,
|
|
||||||
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
|
||||||
output = log.read_text(encoding="utf-8", errors="replace")
|
|
||||||
hashes = HASH.findall(output)
|
|
||||||
if result.returncode or len(hashes) != 12:
|
|
||||||
raise SystemExit(f"hash run failed or incomplete: {label}; exit={result.returncode} "
|
|
||||||
f"hashes={len(hashes)} log={log}")
|
|
||||||
row = {"dataset": dataset, "recipe": recipe, "workers": workers,
|
|
||||||
"compiler": compiler, "exit_code": result.returncode, "hashes": hashes,
|
|
||||||
"source_stamp": (STAMP.search(output).group(1)
|
|
||||||
if STAMP.search(output) else None),
|
|
||||||
"elapsed_s": round(time.monotonic() - started, 3),
|
|
||||||
"log": str(log.relative_to(ROOT))}
|
|
||||||
print("[L128HashRun] " + json.dumps(row, sort_keys=True), flush=True)
|
|
||||||
return row
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
if any(not path.is_file() for path in (*DATASETS.values(), *BINARIES.values())):
|
|
||||||
raise SystemExit("missing L128 hash input")
|
|
||||||
rows = []
|
|
||||||
recipes = {"owner4": ("surface-world",),
|
|
||||||
"owner2": ("surface-world", "floating-islands")}
|
|
||||||
for dataset, dataset_recipes in recipes.items():
|
|
||||||
for recipe in dataset_recipes:
|
|
||||||
for workers in (1, 8, 12):
|
|
||||||
for compiler in ("clang", "gcc"):
|
|
||||||
rows.append(run(dataset, recipe, workers, compiler))
|
|
||||||
(OUT / "runs-partial.json").write_text(
|
|
||||||
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
|
|
||||||
groups = {}
|
|
||||||
for dataset, dataset_recipes in recipes.items():
|
|
||||||
for recipe in dataset_recipes:
|
|
||||||
key = f"{dataset}/{recipe}"
|
|
||||||
group = [row for row in rows if row["dataset"] == dataset
|
|
||||||
and row["recipe"] == recipe]
|
|
||||||
reference = group[0]["hashes"]
|
|
||||||
stable = all(row["hashes"] == reference for row in group)
|
|
||||||
groups[key] = {
|
|
||||||
"all_worker_compiler_hashes_match": stable,
|
|
||||||
"source_stamps": sorted({row["source_stamp"] for row in group}),
|
|
||||||
"runs": [{"workers": row["workers"], "compiler": row["compiler"],
|
|
||||||
"log": row["log"]} for row in group],
|
|
||||||
}
|
|
||||||
if not stable:
|
|
||||||
raise SystemExit(f"determinism mismatch: {key}")
|
|
||||||
summary = {"runs": rows, "groups": groups}
|
|
||||||
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n",
|
|
||||||
encoding="utf-8")
|
|
||||||
baseline_dir = ROOT / "Standalone/Tools/verify/baselines/owner-hash/canonical"
|
|
||||||
for dataset, recipe, style, baseline_name in (
|
|
||||||
("owner4", "surface-world", 1,
|
|
||||||
"owner-hash-owner4-surface-world-style1-v226.baseline"),
|
|
||||||
("owner2", "surface-world", 1,
|
|
||||||
"owner-hash-surface-world-style1-v226.baseline"),
|
|
||||||
("owner2", "floating-islands", 2,
|
|
||||||
"owner-hash-floating-islands-style2-v226.baseline"),
|
|
||||||
):
|
|
||||||
canonical = next(row for row in rows if row["dataset"] == dataset
|
|
||||||
and row["recipe"] == recipe and row["workers"] == 12
|
|
||||||
and row["compiler"] == "clang")
|
|
||||||
baseline = baseline_dir / baseline_name
|
|
||||||
baseline.write_text("\n".join(canonical["hashes"]) + "\n",
|
|
||||||
encoding="utf-8")
|
|
||||||
print("[L128HashSummary] " + json.dumps(groups, sort_keys=True), flush=True)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Five interleaved L80 readiness runs for L109, 4041d4b and L128."""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import statistics
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[4]
|
|
||||||
OUT = ROOT / os.environ.get("L128_TIMING_DIR", "Saved/Linux/l128/timing")
|
|
||||||
DATA = ROOT / "Standalone/data/owner_world.json"
|
|
||||||
BINARIES = {
|
|
||||||
"L109": ROOT / "Saved/Linux/l109/bin-final/VoxelForgeCoreHeadless-l109-clang",
|
|
||||||
"4041d4b": ROOT / "Saved/Linux/l127/bin-clang/VoxelForgeCoreHeadless-l127-clang",
|
|
||||||
"L128": ROOT / os.environ.get("L128_CANDIDATE_BINARY",
|
|
||||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19"),
|
|
||||||
}
|
|
||||||
CAMERAS = {
|
|
||||||
0: (8.0, 16.0, -372.2626953125),
|
|
||||||
1: (25.8369140625, 3.19921875, -737.0),
|
|
||||||
2: (19.166015625, -14.2001953125, -753.3740234375),
|
|
||||||
3: (-20.0625, -5.068359375, -900.353515625),
|
|
||||||
}
|
|
||||||
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
|
|
||||||
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
|
|
||||||
NEAR = re.compile(
|
|
||||||
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
|
|
||||||
re.M)
|
|
||||||
|
|
||||||
|
|
||||||
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
|
|
||||||
OUT.mkdir(parents=True, exist_ok=True)
|
|
||||||
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
|
|
||||||
log = OUT / f"{label}.log"
|
|
||||||
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
|
|
||||||
command = [
|
|
||||||
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
|
||||||
"timeout", "1740s", str(BINARIES[version]), str(DATA),
|
|
||||||
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
|
|
||||||
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
|
|
||||||
"--max-level=8", f"--camera={camera}", "--profile-lod-work",
|
|
||||||
"--stream-scheduler-policy=3",
|
|
||||||
]
|
|
||||||
started = time.monotonic()
|
|
||||||
with log.open("w", encoding="utf-8") as output:
|
|
||||||
result = subprocess.run(command, cwd=ROOT, stdout=output,
|
|
||||||
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
|
||||||
content = log.read_text(encoding="utf-8", errors="replace")
|
|
||||||
pipeline_match, near_match = PIPELINE.search(content), NEAR.search(content)
|
|
||||||
if result.returncode or pipeline_match is None or near_match is None:
|
|
||||||
raise SystemExit(f"readiness run failed or incomplete: {log}; exit={result.returncode}")
|
|
||||||
pipeline = dict(FIELDS.findall(pipeline_match.group(1)))
|
|
||||||
row = {"strate": strate, "workers": workers, "version": version,
|
|
||||||
"phase": phase, "replicate": replicate, "exit_code": result.returncode,
|
|
||||||
"wall_s": round(time.monotonic() - started, 3),
|
|
||||||
"lod02_ready_s": float(near_match.group(3)),
|
|
||||||
"whole_view_ready_s": float(pipeline["whole_view_ready"].removesuffix("s")),
|
|
||||||
"whole_tiles": int(pipeline["whole_tiles"].split("/")[0]),
|
|
||||||
"log": str(log.relative_to(ROOT))}
|
|
||||||
print("[L128TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
|
|
||||||
return row
|
|
||||||
|
|
||||||
|
|
||||||
def cpu_idle_percent(interval_s: float = 2.0) -> float:
|
|
||||||
def totals() -> tuple[int, int]:
|
|
||||||
fields = Path("/proc/stat").read_text(encoding="utf-8").splitlines()[0].split()
|
|
||||||
values = [int(value) for value in fields[1:]]
|
|
||||||
return sum(values), values[3] + (values[4] if len(values) > 4 else 0)
|
|
||||||
before_total, before_idle = totals()
|
|
||||||
time.sleep(interval_s)
|
|
||||||
after_total, after_idle = totals()
|
|
||||||
return 100.0 * (after_idle-before_idle) / max(1, after_total-before_total)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
if not DATA.is_file() or any(not binary.is_file() for binary in BINARIES.values()):
|
|
||||||
raise SystemExit("missing L109/4041d4b/L128 timing input")
|
|
||||||
OUT.mkdir(parents=True, exist_ok=True)
|
|
||||||
load_1m, idle_pct = os.getloadavg()[0], cpu_idle_percent()
|
|
||||||
uptime = subprocess.run(["uptime"], cwd=ROOT, text=True,
|
|
||||||
capture_output=True, check=True).stdout.strip()
|
|
||||||
top = subprocess.run(["ps", "-eo", "pid,pcpu,comm", "--sort=-pcpu"],
|
|
||||||
cwd=ROOT, text=True, capture_output=True, check=True).stdout
|
|
||||||
(OUT / "machine-load-before.txt").write_text(
|
|
||||||
f"uptime: {uptime}\n1-minute load: {load_1m:.2f}\n"
|
|
||||||
f"2-second CPU idle: {idle_pct:.1f}%\ntop CPU users:\n{top}", encoding="utf-8")
|
|
||||||
print(f"[L128TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle_pct:.1f}%",
|
|
||||||
flush=True)
|
|
||||||
if load_1m >= 0.9 or idle_pct < 97.0:
|
|
||||||
raise SystemExit("timing refused: machine is above the quiet-load gate")
|
|
||||||
|
|
||||||
rows = []
|
|
||||||
versions = ("L109", "4041d4b", "L128")
|
|
||||||
for strate in range(4):
|
|
||||||
for workers in (8, 12):
|
|
||||||
for version in versions:
|
|
||||||
run(strate, workers, version, "warmup", 0)
|
|
||||||
for replicate in range(1, 6):
|
|
||||||
offset = (replicate - 1) % len(versions)
|
|
||||||
order = versions[offset:] + versions[:offset]
|
|
||||||
for version in order:
|
|
||||||
rows.append(run(strate, workers, version, "measured", replicate))
|
|
||||||
(OUT / "runs-partial.json").write_text(
|
|
||||||
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
|
|
||||||
|
|
||||||
summary = []
|
|
||||||
for strate in range(4):
|
|
||||||
for workers in (8, 12):
|
|
||||||
item = {"strate": strate, "workers": workers, "replicates": 5}
|
|
||||||
medians = {}
|
|
||||||
for version in versions:
|
|
||||||
group = [row for row in rows if row["strate"] == strate
|
|
||||||
and row["workers"] == workers and row["version"] == version]
|
|
||||||
medians[version] = {}
|
|
||||||
for key in ("lod02_ready_s", "whole_view_ready_s"):
|
|
||||||
values = [row[key] for row in group]
|
|
||||||
medians[version][key] = statistics.median(values)
|
|
||||||
item[f"{version}_{key}_values"] = values
|
|
||||||
item[f"{version}_{key}_median"] = medians[version][key]
|
|
||||||
for comparison in ("L109", "4041d4b"):
|
|
||||||
for key in ("lod02_ready_s", "whole_view_ready_s"):
|
|
||||||
item[f"L128_vs_{comparison}_{key}_delta_pct"] = round(
|
|
||||||
100.0 * (medians["L128"][key] / medians[comparison][key]-1.0), 2)
|
|
||||||
summary.append(item)
|
|
||||||
(OUT / "summary.json").write_text(
|
|
||||||
json.dumps({"runs": rows, "summary": summary}, indent=2) + "\n",
|
|
||||||
encoding="utf-8")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Run five UE 30 m/s movement trials and compare with the L127 4041d4b baseline."""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import importlib.util
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import statistics
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[4]
|
|
||||||
RESEARCH = ROOT / "Standalone/Research/WorldAssemblerM3"
|
|
||||||
OUT = ROOT / "Saved/Linux/l128/ue"
|
|
||||||
HOST = Path("/home/jahni/VFHost")
|
|
||||||
EDITOR = Path("/home/jahni/UnrealEngine/Engine/Binaries/Linux/UnrealEditor-Cmd")
|
|
||||||
MOVEMENT_PATH = RESEARCH / "Linux121/RunL121Movement.py"
|
|
||||||
BASELINE_PATH = ROOT / "Saved/Linux/l127/ue/movement-pairs-summary.json"
|
|
||||||
|
|
||||||
|
|
||||||
def load_movement_module():
|
|
||||||
spec = importlib.util.spec_from_file_location("l128_movement", MOVEMENT_PATH)
|
|
||||||
if spec is None or spec.loader is None:
|
|
||||||
raise RuntimeError(f"cannot load UE movement runner: {MOVEMENT_PATH}")
|
|
||||||
module = importlib.util.module_from_spec(spec)
|
|
||||||
spec.loader.exec_module(module)
|
|
||||||
return module
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
if not BASELINE_PATH.is_file():
|
|
||||||
raise SystemExit(f"missing 4041d4b movement baseline: {BASELINE_PATH}")
|
|
||||||
OUT.mkdir(parents=True, exist_ok=True)
|
|
||||||
module = load_movement_module()
|
|
||||||
module.HOST = HOST
|
|
||||||
module.EDITOR = EDITOR
|
|
||||||
module.OUT = OUT / "movement"
|
|
||||||
module.HOST_SAVED = HOST / "Saved/Linux/l128/host"
|
|
||||||
module.HOST_OUT = HOST / "Plugins/VoxelForge/Saved/Linux/l128/movement"
|
|
||||||
module.RUN_TIMEOUT_S = 1740
|
|
||||||
module.HOST_OUT.mkdir(parents=True, exist_ok=True)
|
|
||||||
os.environ["XDG_CONFIG_HOME"] = str(OUT / "config")
|
|
||||||
|
|
||||||
rows = []
|
|
||||||
for repetition in range(1, 6):
|
|
||||||
row = module.run_unreal("L128", repetition)
|
|
||||||
events = module.parse_events(ROOT / row["trace"])
|
|
||||||
row["supplemental_far_applies_total"] = sum(
|
|
||||||
int(event.get("supplemental_far_applies", 0))
|
|
||||||
for event in events if event.get("type") == "apply_frame")
|
|
||||||
row["supplemental_far_applies_moving"] = sum(
|
|
||||||
int(event.get("supplemental_far_applies", 0))
|
|
||||||
for event in events if event.get("type") == "apply_frame"
|
|
||||||
and float(event.get("speed_cm_s", 0.0)) >= 50.0)
|
|
||||||
if row.get("effective_tile_slots") != 8 or row["supplemental_far_applies_moving"] <= 0:
|
|
||||||
raise SystemExit(f"movement run missed the configured apply lane: {row}")
|
|
||||||
rows.append(row)
|
|
||||||
(OUT / "movement-runs-partial.json").write_text(
|
|
||||||
json.dumps(rows, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
||||||
print("[L128UEMovement] " + json.dumps({
|
|
||||||
key: row[key] for key in (
|
|
||||||
"condition", "repetition", "near_ready_moving_mean_pct",
|
|
||||||
"far_holes_moving_mean_pct", "game_thread_tick_p99_ms",
|
|
||||||
"game_thread_tick_max_ms", "supplemental_far_applies_moving",
|
|
||||||
"wall_s", "trace")}, sort_keys=True), flush=True)
|
|
||||||
|
|
||||||
baseline_doc = json.loads(BASELINE_PATH.read_text(encoding="utf-8"))
|
|
||||||
baseline_rows = [row for row in baseline_doc["runs"]
|
|
||||||
if row["condition"] == "merge"]
|
|
||||||
if len(baseline_rows) != 5:
|
|
||||||
raise SystemExit(f"expected five 4041d4b baseline runs, got {len(baseline_rows)}")
|
|
||||||
metrics = ("near_ready_moving_mean_pct", "far_holes_moving_mean_pct",
|
|
||||||
"game_thread_tick_p99_ms", "game_thread_tick_max_ms")
|
|
||||||
baseline = {metric: statistics.median(row[metric] for row in baseline_rows)
|
|
||||||
for metric in metrics}
|
|
||||||
candidate = {metric: statistics.median(row[metric] for row in rows)
|
|
||||||
for metric in metrics}
|
|
||||||
build_log = (ROOT / "Saved/Linux/l128/build-clang.log").read_text(
|
|
||||||
encoding="utf-8", errors="replace")
|
|
||||||
stamp_match = re.search(r"^Source stamp: (\S+)$", build_log, re.M)
|
|
||||||
if stamp_match is None:
|
|
||||||
raise SystemExit("missing L128 Clang source stamp")
|
|
||||||
summary = {
|
|
||||||
"baseline": {"commit": "4041d4b", "runs": len(baseline_rows),
|
|
||||||
"metrics": baseline},
|
|
||||||
"candidate": {"source_stamp": stamp_match.group(1),
|
|
||||||
"runs": len(rows), "metrics": candidate},
|
|
||||||
"candidate_vs_4041d4b_delta": {
|
|
||||||
metric: candidate[metric] - baseline[metric] for metric in metrics},
|
|
||||||
"bar_pass": candidate["near_ready_moving_mean_pct"]
|
|
||||||
> baseline["near_ready_moving_mean_pct"]
|
|
||||||
and all(candidate[metric] <= baseline[metric] for metric in (
|
|
||||||
"far_holes_moving_mean_pct", "game_thread_tick_p99_ms",
|
|
||||||
"game_thread_tick_max_ms")),
|
|
||||||
}
|
|
||||||
(OUT / "movement-summary.json").write_text(
|
|
||||||
json.dumps({"runs": rows, "summary": summary}, indent=2, sort_keys=True) + "\n",
|
|
||||||
encoding="utf-8")
|
|
||||||
print("[L128UEMovementSummary] " + json.dumps(summary, sort_keys=True), flush=True)
|
|
||||||
if not summary["bar_pass"]:
|
|
||||||
raise SystemExit("L128 UE movement medians missed the 4041d4b coverage/tick bar")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
<!doctype html><meta charset='utf-8'>
|
|
||||||
<title>L125 / L128 tunnel capture comparison</title>
|
|
||||||
<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}section{margin:28px 0}h2{font-size:18px}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}p{color:#bbb}</style>
|
|
||||||
<h1>L125 / L128 slab ownership: identical views</h1>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — rock-floor/401.7m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-1.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-rock-floor-station-1.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — rock-floor/792.8m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-2.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-rock-floor-station-2.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — rock-floor/1634.5m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-3.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-rock-floor-station-3.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — rock-floor/27.0m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-1.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-rock-floor-station-1.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — rock-floor/52.9m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-2.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-rock-floor-station-2.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — rock-floor/78.9m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-3.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-rock-floor-station-3.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — rock-floor/323.4m</h2>
|
|
||||||
<p>rock-floor-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-1.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-rock-floor-station-1.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — rock-floor/333.4m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-2.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-rock-floor-station-2.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — rock-floor/343.4m</h2>
|
|
||||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-3.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-rock-floor-station-3.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — section-1/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-1-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-1-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — section-1/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — section-2/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-2-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-2-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — section-2/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — section-3/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-3-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-3-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/0-1/0 — section-3/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — section-1/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-1-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-1-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — section-1/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — section-2/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-2-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-2-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/1-2/0 — section-2/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — section-1/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-1-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-1-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — section-1/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — section-2/4m-outside</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-2-4m-outside.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-2-4m-outside.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>passage/2-3/0 — section-2/4m-interior-wall</h2>
|
|
||||||
<p>open-air-close · L125 pass · L128 pass</p>
|
|
||||||
<div>
|
|
||||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
|
|
||||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
Before Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 104 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
# Linux130 — passage reach
|
||||||
|
|
||||||
|
On `wip/l130-reach-units` from `b96dd73`, passage influence is now **1.0533 m**: 0.75 m shell + 0.21 m relief + 0.50 m smooth-max support (`width/6`) + 0.01 m margin. One metres-to-core-voxels conversion feeds proof, feature, fallback and off-grid bounds; the sweep cutoff uses the same metre value. The dead 4 m cutoff is removed. Evaluator version is 227.
|
||||||
|
|
||||||
|
The debug shell/crest audit sampled 25,728 points, including 5 mm inside and outside the reach; 18,993 had sign-relevant passage contribution. Proof and feature bounds missed none. The nine-station floor probe still peaks at **7.884 mm**, matching L125. The 23 L125 views and six L129 mouth close-ups are byte-identical. Fast verification, walkability and shell audits pass; the seam audit found 0 mismatches across 4 pairs / 4,900 shared samples.
|
||||||
|
|
||||||
|
Clang/GCC W1/W8/W12 hashes agree across all 18 runs. Versus v225, hashes changed for owner4 full-detail, whole-view and LOD0–3; owner2 surface-world and floating-islands whole-view and LOD2–3. Exact-query hashes stayed unchanged. The v227 canonical baselines are recorded; changed hashes reflect the shorter density influence halo, while sampled sign-relevant bounds and captured surfaces remain covered.
|
||||||
|
|
||||||
|
L80 timing used 10 interleaved pairs per stratum/worker count. Across the eight case medians, the weighted deltas were +0.33% for LOD0–2 and +0.31% whole-view. Across 80 paired runs, mean deltas were +0.26% (95% interval −0.44% to +0.96%) and +0.47% (−0.06% to +1.00%); both intervals include zero. No measurable timing change; UE movement was skipped. The Linux UE host build succeeded in 76.30 s with `-NoUBA -MaxParallelActions=4`, without `prlimit`. `ARCHITECTURE.md` and `CODEMAP.md` had no note for this optimized influence reach, so they were unchanged.
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run Clang/GCC owner hashes at W1/W8/W12 and compare with b96dd73."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[4]
|
||||||
|
OUT = ROOT / "Saved/Linux/l130/hashes"
|
||||||
|
BASELINE = json.loads((ROOT / "Saved/Linux/l125/hashes/summary.json").read_text())
|
||||||
|
DATASETS = {
|
||||||
|
"owner4": ROOT / "Standalone/data/owner_world.json",
|
||||||
|
"owner2": ROOT / "Standalone/data/regression/owner_world_2strate_l61.json",
|
||||||
|
}
|
||||||
|
RECIPES = {"owner4": ("surface-world",),
|
||||||
|
"owner2": ("surface-world", "floating-islands")}
|
||||||
|
BINARIES = {
|
||||||
|
"clang": ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang",
|
||||||
|
"gcc": ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-gcc",
|
||||||
|
}
|
||||||
|
HASH_RE = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
|
||||||
|
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=(\S+)$", re.M)
|
||||||
|
|
||||||
|
|
||||||
|
def run(dataset: str, recipe: str, workers: int, compiler: str) -> dict:
|
||||||
|
OUT.mkdir(parents=True, exist_ok=True)
|
||||||
|
label = f"{dataset}-{recipe}-w{workers}-{compiler}"
|
||||||
|
log = OUT / f"{label}.log"
|
||||||
|
layout = OUT / f"{label}.layout.json"
|
||||||
|
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||||
|
"timeout", "1740s", str(BINARIES[compiler]), str(DATASETS[dataset]),
|
||||||
|
f"--workers={workers}", "--world-assembler-prototype", "--stream-benchmark",
|
||||||
|
"--stream-pipeline", "--force-generate", "--clip-radius=3",
|
||||||
|
"--max-clip-level=8", "--max-level=8", f"--recipe={recipe}",
|
||||||
|
"--stream-hash", f"--resolved-layout-output={layout}"]
|
||||||
|
started = time.monotonic()
|
||||||
|
with log.open("w", encoding="utf-8") as stream:
|
||||||
|
result = subprocess.run(command, cwd=ROOT, stdout=stream,
|
||||||
|
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
||||||
|
output = log.read_text(encoding="utf-8", errors="replace")
|
||||||
|
hashes = HASH_RE.findall(output)
|
||||||
|
if result.returncode or len(hashes) != 12:
|
||||||
|
raise SystemExit(f"hash run failed: {label}; exit={result.returncode} "
|
||||||
|
f"hashes={len(hashes)} log={log}")
|
||||||
|
stamp = STAMP_RE.search(output)
|
||||||
|
row = {"dataset": dataset, "recipe": recipe, "workers": workers,
|
||||||
|
"compiler": compiler, "exit_code": result.returncode, "hashes": hashes,
|
||||||
|
"source_stamp": stamp.group(1) if stamp else None,
|
||||||
|
"elapsed_s": round(time.monotonic() - started, 3),
|
||||||
|
"log": str(log.relative_to(ROOT))}
|
||||||
|
print("[L130HashRun] " + json.dumps(row, sort_keys=True), flush=True)
|
||||||
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if any(not path.is_file() for path in (*DATASETS.values(), *BINARIES.values())):
|
||||||
|
raise SystemExit("missing L130 hash input")
|
||||||
|
old = {(row["dataset"], row["recipe"], row["workers"], row["compiler"]): row
|
||||||
|
for row in BASELINE["runs"]}
|
||||||
|
rows = []
|
||||||
|
for dataset, recipes in RECIPES.items():
|
||||||
|
for recipe in recipes:
|
||||||
|
for workers in (1, 8, 12):
|
||||||
|
for compiler in ("clang", "gcc"):
|
||||||
|
rows.append(run(dataset, recipe, workers, compiler))
|
||||||
|
(OUT / "runs-partial.json").write_text(
|
||||||
|
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
|
||||||
|
groups = {}
|
||||||
|
for dataset, recipes in RECIPES.items():
|
||||||
|
for recipe in recipes:
|
||||||
|
group = [row for row in rows if row["dataset"] == dataset
|
||||||
|
and row["recipe"] == recipe]
|
||||||
|
key = f"{dataset}/{recipe}"
|
||||||
|
stable = all(row["hashes"] == group[0]["hashes"] for row in group)
|
||||||
|
baseline = old[(dataset, recipe, 12, "clang")]["hashes"]
|
||||||
|
changed = [i for i, (before, after) in enumerate(zip(baseline,
|
||||||
|
group[0]["hashes"])) if before != after]
|
||||||
|
groups[key] = {"all_workers_and_compilers_match": stable,
|
||||||
|
"matches_b96dd73_v225": not changed,
|
||||||
|
"changed_hash_rows_from_v225": changed,
|
||||||
|
"source_stamps": sorted({row["source_stamp"] for row in group})}
|
||||||
|
if not stable:
|
||||||
|
raise SystemExit(f"worker/compiler hash mismatch: {key}")
|
||||||
|
(OUT / "summary.json").write_text(
|
||||||
|
json.dumps({"baseline_source": "b96dd73", "runs": rows,
|
||||||
|
"groups": groups}, indent=2) + "\n", encoding="utf-8")
|
||||||
|
print("[L130HashSummary] " + json.dumps(groups, sort_keys=True), flush=True)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Render the six L129 b96dd73 mouth views against the L130 meshes."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import html
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[4]
|
||||||
|
SOURCE = ROOT / "Saved/Linux/l129/captures/mouth-closeups/before"
|
||||||
|
SAVED = ROOT / "Saved/Linux/l130/captures/mouth-closeups"
|
||||||
|
CAPTURES = ROOT / "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups"
|
||||||
|
DATA = ROOT / "Standalone/data/owner_world.json"
|
||||||
|
HEADLESS = ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang"
|
||||||
|
RENDERER = ROOT / "Saved/Linux/l130/bin/VoxelForgeOffscreenCapture-l130-clang"
|
||||||
|
HEADLESS_CONFIG = re.compile(
|
||||||
|
r"^\[HeadlessConfig\].*?camera_m=\(([^)]*)\) camera_rotation_deg=\(([^)]*)\)", re.M)
|
||||||
|
SCENE = re.compile(r"^\[OffscreenScene\].*?height_center_m=(-?[\d.]+)", re.M)
|
||||||
|
DRAWN = re.compile(r"drawn_triangles=(\d+)")
|
||||||
|
|
||||||
|
|
||||||
|
def wrapped(command: list[str]) -> list[str]:
|
||||||
|
return ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||||
|
"timeout", "1740s", *map(str, command)]
|
||||||
|
|
||||||
|
|
||||||
|
def run(label: str, command: list[str], log: Path) -> str:
|
||||||
|
started = time.monotonic()
|
||||||
|
log.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with log.open("w", encoding="utf-8") as output:
|
||||||
|
result = subprocess.run(wrapped(command), cwd=ROOT, stdout=output,
|
||||||
|
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
||||||
|
content = log.read_text(encoding="utf-8", errors="replace")
|
||||||
|
if result.returncode:
|
||||||
|
raise SystemExit(f"{label} failed exit={result.returncode}: {log}")
|
||||||
|
print(f"[L130MouthProcess] {label} elapsed_s={time.monotonic()-started:.2f}",
|
||||||
|
flush=True)
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def parse_vector(text: str) -> tuple[float, ...]:
|
||||||
|
return tuple(float(value) for value in text.split(","))
|
||||||
|
|
||||||
|
|
||||||
|
def sha256(path: Path) -> str:
|
||||||
|
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if any(not path.is_file() for path in (DATA, HEADLESS, RENDERER)):
|
||||||
|
raise SystemExit("missing L130 mouth capture input")
|
||||||
|
(CAPTURES / "b96dd73").mkdir(parents=True, exist_ok=True)
|
||||||
|
(CAPTURES / "L130").mkdir(parents=True, exist_ok=True)
|
||||||
|
rows = []
|
||||||
|
for source_log in sorted(SOURCE.glob("*-mouth-mesh.log")):
|
||||||
|
name = source_log.name.removesuffix("-mesh.log")
|
||||||
|
source_render = SOURCE / f"{name}-render.log"
|
||||||
|
baseline_mesh = SOURCE / f"{name}.vfmesh"
|
||||||
|
if not all(path.is_file() for path in (source_render, baseline_mesh)):
|
||||||
|
raise SystemExit(f"missing b96dd73 source artifact for {name}")
|
||||||
|
config = HEADLESS_CONFIG.search(source_log.read_text())
|
||||||
|
scene = SCENE.search(source_render.read_text())
|
||||||
|
if config is None or scene is None:
|
||||||
|
raise SystemExit(f"missing camera metadata for {name}")
|
||||||
|
camera = parse_vector(config.group(1))
|
||||||
|
yaw, pitch = parse_vector(config.group(2))
|
||||||
|
height_center = float(scene.group(1))
|
||||||
|
camera_arg = ",".join(f"{value:.6f}" for value in (*camera, yaw, pitch))
|
||||||
|
candidate_mesh = SAVED / "L130" / f"{name}.vfmesh"
|
||||||
|
candidate_mesh.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
run(f"{name}-mesh", [HEADLESS, DATA, "--world-assembler-prototype",
|
||||||
|
"--stream-benchmark", "--stream-pipeline", "--workers=12",
|
||||||
|
"--clip-radius=3", "--max-clip-level=0", "--max-level=0",
|
||||||
|
"--force-generate", "--recipe=surface-world", f"--camera={camera_arg}",
|
||||||
|
"--render-distance-chunks=1", f"--mesh-export={candidate_mesh}"],
|
||||||
|
SAVED / "L130" / f"{name}-mesh.log")
|
||||||
|
if not candidate_mesh.is_file() or candidate_mesh.stat().st_size == 0:
|
||||||
|
raise SystemExit(f"empty L130 mesh for {name}")
|
||||||
|
|
||||||
|
render_args = ["--size=1920x1080",
|
||||||
|
f"--camera-m={','.join(f'{value:.6f}' for value in camera)}",
|
||||||
|
f"--yaw-deg={yaw:.6f}", f"--pitch-deg={pitch:.6f}",
|
||||||
|
"--shade=readable", "--headlamp=on", "--height-tint=on",
|
||||||
|
f"--height-center-m={height_center:.6f}", "--height-range-m=32"]
|
||||||
|
images = {}
|
||||||
|
draw_counts = {}
|
||||||
|
for variant, mesh in (("b96dd73", baseline_mesh), ("L130", candidate_mesh)):
|
||||||
|
image = CAPTURES / variant / f"{name}.png"
|
||||||
|
render_log = SAVED / variant / f"{name}-render.log"
|
||||||
|
content = run(f"{name}-{variant}-render",
|
||||||
|
[RENDERER, mesh, image, *render_args], render_log)
|
||||||
|
drawn = DRAWN.search(content)
|
||||||
|
if drawn is None or int(drawn.group(1)) <= 0 or not image.is_file():
|
||||||
|
raise SystemExit(f"render has no visible triangles for {name}/{variant}")
|
||||||
|
images[variant] = image
|
||||||
|
draw_counts[variant] = int(drawn.group(1))
|
||||||
|
equal = images["b96dd73"].read_bytes() == images["L130"].read_bytes()
|
||||||
|
row = {"name": name, "camera_m": camera, "yaw_deg": yaw,
|
||||||
|
"pitch_deg": pitch, "height_center_m": height_center,
|
||||||
|
"source_mesh": str(baseline_mesh.relative_to(ROOT)),
|
||||||
|
"candidate_mesh": str(candidate_mesh.relative_to(ROOT)),
|
||||||
|
"baseline_png": str(images["b96dd73"].relative_to(ROOT)),
|
||||||
|
"candidate_png": str(images["L130"].relative_to(ROOT)),
|
||||||
|
"baseline_sha256": sha256(images["b96dd73"]),
|
||||||
|
"candidate_sha256": sha256(images["L130"]),
|
||||||
|
"byte_identical": equal, "drawn_triangles": draw_counts}
|
||||||
|
rows.append(row)
|
||||||
|
print(f"[L130MouthCompare] {name} byte_identical={equal} "
|
||||||
|
f"sha256={row['candidate_sha256']}", flush=True)
|
||||||
|
|
||||||
|
if len(rows) != 6:
|
||||||
|
raise SystemExit(f"expected six L129 mouth views, found {len(rows)}")
|
||||||
|
(CAPTURES / "summary.json").write_text(json.dumps(rows, indent=2) + "\n")
|
||||||
|
sections = []
|
||||||
|
for row in rows:
|
||||||
|
name = html.escape(row["name"])
|
||||||
|
sections.append(f"<section><h2>{name}</h2><p>byte identical: "
|
||||||
|
f"{str(row['byte_identical']).lower()}</p><div>"
|
||||||
|
f"<figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/{name}.png'></figure>"
|
||||||
|
f"<figure><figcaption>L130 reach units</figcaption><img src='L130/{name}.png'></figure>"
|
||||||
|
"</div></section>")
|
||||||
|
page = ("<!doctype html><meta charset='utf-8'><title>L130 mouth closeups</title>"
|
||||||
|
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
|
||||||
|
"section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}"
|
||||||
|
"img{width:100%;height:auto}p{color:#bbb}</style>"
|
||||||
|
"<h1>L129 mouth closeups: b96dd73 vs L130</h1>" + "\n".join(sections))
|
||||||
|
(CAPTURES / "COMPARE.html").write_text(page)
|
||||||
|
return 0 if all(row["byte_identical"] for row in rows) else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Render the 23 L125 camera poses with the L130 evaluator and compare them."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import html
|
||||||
|
import importlib.util
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[4]
|
||||||
|
RESEARCH = Path(__file__).resolve().parent
|
||||||
|
CAPTURES = RESEARCH / "captures"
|
||||||
|
SAVED = ROOT / "Saved/Linux/l130/captures"
|
||||||
|
BASELINE_INDEX = (ROOT / "Standalone/Research/WorldAssemblerM3/Linux119"
|
||||||
|
/ "captures/L119/capture-index.json")
|
||||||
|
REFERENCE = ROOT / "Standalone/Research/WorldAssemblerM3/Linux125/captures/L125"
|
||||||
|
LAYOUT = ROOT / "Saved/Linux/l130/hashes/owner4-surface-world-w12-clang.layout.json"
|
||||||
|
HEADLESS = ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang"
|
||||||
|
RENDERER = ROOT / "Saved/Linux/l130/bin/VoxelForgeOffscreenCapture-l130-clang"
|
||||||
|
HELPER_PATH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113/RunL113Captures.py"
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if any(not path.is_file() for path in
|
||||||
|
(BASELINE_INDEX, REFERENCE / "passage-0-1-0-rock-floor-station-1.png",
|
||||||
|
LAYOUT, HEADLESS, RENDERER)):
|
||||||
|
raise SystemExit("missing pose, layout, or L130 capture input")
|
||||||
|
spec = importlib.util.spec_from_file_location("l125_capture_runner",
|
||||||
|
ROOT / "Standalone/Research/WorldAssemblerM3/Linux125/RunL125Captures.py")
|
||||||
|
if spec is None or spec.loader is None:
|
||||||
|
raise SystemExit("cannot load the verified L125 pose set")
|
||||||
|
runner = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(runner)
|
||||||
|
runner.RESEARCH = RESEARCH
|
||||||
|
runner.CAPTURES = CAPTURES
|
||||||
|
runner.SAVED = SAVED
|
||||||
|
runner.LAYOUT = LAYOUT
|
||||||
|
runner.CLANG = HEADLESS
|
||||||
|
runner.RENDERER = RENDERER
|
||||||
|
runner.HELPERS.RESEARCH = RESEARCH
|
||||||
|
runner.HELPERS.CAPTURES = CAPTURES
|
||||||
|
runner.HELPERS.SAVED = SAVED
|
||||||
|
runner.HELPERS.BINARIES = {"L125": HEADLESS}
|
||||||
|
runner.HELPERS.RENDERERS = {"L125": RENDERER}
|
||||||
|
if runner.main() != 0:
|
||||||
|
raise SystemExit("L130 pose generation failed")
|
||||||
|
|
||||||
|
new_captures = CAPTURES / "L125"
|
||||||
|
new_saved = SAVED / "L125"
|
||||||
|
index_path = new_captures / "capture-index.json"
|
||||||
|
data = json.loads(index_path.read_text())
|
||||||
|
if len(data["captures"]) != 23:
|
||||||
|
raise SystemExit(f"expected 23 poses, found {len(data['captures'])}")
|
||||||
|
identical = 0
|
||||||
|
sections = []
|
||||||
|
for row in data["captures"]:
|
||||||
|
name = row["name"]
|
||||||
|
old_image = REFERENCE / f"{name}.png"
|
||||||
|
new_image = new_captures / f"{name}.png"
|
||||||
|
if not old_image.is_file() or not new_image.is_file():
|
||||||
|
raise SystemExit(f"missing comparison image for {name}")
|
||||||
|
same = old_image.read_bytes() == new_image.read_bytes()
|
||||||
|
identical += int(same)
|
||||||
|
row["variant"] = "L130-v227"
|
||||||
|
row["capture"] = row["capture"].replace("captures/L125/", "captures/L130/")
|
||||||
|
row["scene"] = row["scene"].replace("captures/L125/", "captures/L130/")
|
||||||
|
row["logs"] = [path.replace("captures/L125/", "captures/L130/")
|
||||||
|
for path in row.get("logs", [])]
|
||||||
|
sections.append(f"<section><h2>{html.escape(row['passage'])} — "
|
||||||
|
f"{html.escape(row.get('station', ''))}</h2><p>{html.escape(row['kind'])} · "
|
||||||
|
f"byte identical: {str(same).lower()}</p><div>"
|
||||||
|
f"<figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/{html.escape(name)}.png'></figure>"
|
||||||
|
f"<figure><figcaption>L130 v227</figcaption><img src='L130/{html.escape(name)}.png'></figure>"
|
||||||
|
"</div></section>")
|
||||||
|
if identical != 23:
|
||||||
|
raise SystemExit(f"only {identical}/23 L125 pose captures are byte-identical")
|
||||||
|
|
||||||
|
index_path.write_text(json.dumps(data, indent=2) + "\n")
|
||||||
|
old_captures, old_saved = CAPTURES / "L130", SAVED / "L130"
|
||||||
|
if old_captures.exists():
|
||||||
|
shutil.rmtree(old_captures)
|
||||||
|
if old_saved.exists():
|
||||||
|
shutil.rmtree(old_saved)
|
||||||
|
new_captures.rename(old_captures)
|
||||||
|
new_saved.rename(old_saved)
|
||||||
|
page = ("<!doctype html><meta charset='utf-8'><title>L130 passage captures</title>"
|
||||||
|
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
|
||||||
|
"section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}"
|
||||||
|
"img{width:100%;height:auto}p{color:#bbb}</style>"
|
||||||
|
"<h1>L125 v225 vs L130 v227: passage captures</h1>" + "\n".join(sections))
|
||||||
|
(CAPTURES / "COMPARE.html").write_text(page)
|
||||||
|
print(f"[L130PoseCapture] poses=23 byte_identical={identical}/23", flush=True)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Five interleaved L80 near-ready runs per stratum/worker vs b96dd73."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import statistics
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[4]
|
||||||
|
OUT = ROOT / "Saved/Linux/l130/timing"
|
||||||
|
PASS_ID = int(os.environ.get("VOXELFORGE_L130_TIMING_PASS", "1"))
|
||||||
|
REPLICATE_FIRST = (PASS_ID - 1) * 5 + 1
|
||||||
|
DATA = ROOT / "Standalone/data/owner_world.json"
|
||||||
|
BINARIES = {
|
||||||
|
"b96dd73": ROOT / "Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang",
|
||||||
|
"L130": ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang",
|
||||||
|
}
|
||||||
|
CAMERAS = {
|
||||||
|
0: (8.0, 16.0, -372.2626953125),
|
||||||
|
1: (25.8369140625, 3.19921875, -737.0),
|
||||||
|
2: (19.166015625, -14.2001953125, -753.3740234375),
|
||||||
|
3: (-20.0625, -5.068359375, -900.353515625),
|
||||||
|
}
|
||||||
|
PIPELINE_RE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
|
||||||
|
FIELDS_RE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
|
||||||
|
NEAR_RE = re.compile(
|
||||||
|
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
|
||||||
|
re.M)
|
||||||
|
|
||||||
|
|
||||||
|
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
|
||||||
|
OUT.mkdir(parents=True, exist_ok=True)
|
||||||
|
pass_suffix = "" if PASS_ID == 1 else f"-p{PASS_ID}"
|
||||||
|
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}-l130-v227{pass_suffix}"
|
||||||
|
log = OUT / f"{label}.log"
|
||||||
|
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
|
||||||
|
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||||
|
"timeout", "1740s", str(BINARIES[version]), str(DATA),
|
||||||
|
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
|
||||||
|
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
|
||||||
|
"--max-level=8", f"--camera={camera}", "--profile-lod-work",
|
||||||
|
"--stream-scheduler-policy=3"]
|
||||||
|
started = time.monotonic()
|
||||||
|
with log.open("w", encoding="utf-8") as output:
|
||||||
|
result = subprocess.run(command, cwd=ROOT, stdout=output,
|
||||||
|
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
||||||
|
content = log.read_text(encoding="utf-8", errors="replace")
|
||||||
|
pipeline, near = PIPELINE_RE.search(content), NEAR_RE.search(content)
|
||||||
|
if result.returncode or pipeline is None or near is None:
|
||||||
|
raise SystemExit(f"timing run failed: {log}; exit={result.returncode}")
|
||||||
|
fields = dict(FIELDS_RE.findall(pipeline.group(1)))
|
||||||
|
row = {"strate": strate, "workers": workers, "version": version,
|
||||||
|
"phase": phase, "replicate": replicate, "exit_code": result.returncode,
|
||||||
|
"wall_s": round(time.monotonic() - started, 3),
|
||||||
|
"lod02_ready_s": float(near.group(3)),
|
||||||
|
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
|
||||||
|
"log": str(log.relative_to(ROOT))}
|
||||||
|
print("[L130TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
|
||||||
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
|
||||||
|
raise SystemExit("missing L130 timing input")
|
||||||
|
OUT.mkdir(parents=True, exist_ok=True)
|
||||||
|
load_1m = __import__("os").getloadavg()[0]
|
||||||
|
def cpu_idle(interval: float = 2.0) -> float:
|
||||||
|
def totals() -> tuple[int, int]:
|
||||||
|
fields = Path("/proc/stat").read_text().splitlines()[0].split()
|
||||||
|
values = [int(value) for value in fields[1:]]
|
||||||
|
return sum(values), values[3] + (values[4] if len(values) > 4 else 0)
|
||||||
|
before = totals()
|
||||||
|
time.sleep(interval)
|
||||||
|
after = totals()
|
||||||
|
return 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
|
||||||
|
idle = cpu_idle()
|
||||||
|
pass_suffix = "" if PASS_ID == 1 else f"-p{PASS_ID}"
|
||||||
|
(OUT / f"machine-load-v227{pass_suffix}-before.txt").write_text(
|
||||||
|
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
|
||||||
|
print(f"[L130TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%",
|
||||||
|
flush=True)
|
||||||
|
if load_1m >= 0.9 or idle < 97.0:
|
||||||
|
raise SystemExit("timing refused: machine is above the quiet-load gate")
|
||||||
|
|
||||||
|
rows = []
|
||||||
|
for strate in range(4):
|
||||||
|
for workers in (8, 12):
|
||||||
|
for version in BINARIES:
|
||||||
|
run(strate, workers, version, "warmup", 0)
|
||||||
|
for replicate in range(REPLICATE_FIRST, REPLICATE_FIRST + 5):
|
||||||
|
order = tuple(BINARIES) if replicate % 2 else tuple(reversed(BINARIES))
|
||||||
|
for version in order:
|
||||||
|
rows.append(run(strate, workers, version, "measured", replicate))
|
||||||
|
(OUT / f"runs-v227{pass_suffix}-partial.json").write_text(
|
||||||
|
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
|
||||||
|
prior_runs = []
|
||||||
|
if PASS_ID > 1:
|
||||||
|
previous = OUT / ("v227-summary.json" if PASS_ID == 2
|
||||||
|
else "v227-combined-summary.json")
|
||||||
|
if previous.is_file():
|
||||||
|
prior_runs = json.loads(previous.read_text(encoding="utf-8")).get("runs", [])
|
||||||
|
all_rows = prior_runs + rows
|
||||||
|
measured_rows = [row for row in all_rows if row["phase"] == "measured"]
|
||||||
|
summary = []
|
||||||
|
for strate in range(4):
|
||||||
|
for workers in (8, 12):
|
||||||
|
group_size = sum(row["strate"] == strate and row["workers"] == workers
|
||||||
|
for row in measured_rows) // 2
|
||||||
|
item = {"strate": strate, "workers": workers,
|
||||||
|
"replicates_per_version": group_size}
|
||||||
|
medians = {}
|
||||||
|
for version in BINARIES:
|
||||||
|
group = [row for row in measured_rows if row["strate"] == strate
|
||||||
|
and row["workers"] == workers and row["version"] == version]
|
||||||
|
medians[version] = {}
|
||||||
|
for key in ("lod02_ready_s", "whole_view_ready_s"):
|
||||||
|
values = [row[key] for row in group]
|
||||||
|
medians[version][key] = statistics.median(values)
|
||||||
|
item[f"{version}_{key}_values"] = values
|
||||||
|
item[f"{version}_{key}_median"] = medians[version][key]
|
||||||
|
for key in ("lod02_ready_s", "whole_view_ready_s"):
|
||||||
|
item[f"L130_vs_b96dd73_{key}_delta_pct"] = round(
|
||||||
|
100.0*(medians["L130"][key]/medians["b96dd73"][key]-1.0), 2)
|
||||||
|
summary.append(item)
|
||||||
|
summary_path = OUT / ("v227-summary.json" if PASS_ID == 1
|
||||||
|
else f"v227-combined-summary.json")
|
||||||
|
summary_path.write_text(json.dumps(
|
||||||
|
{"runs": all_rows, "summary": summary}, indent=2) + "\n", encoding="utf-8")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<!doctype html><meta charset='utf-8'><title>L130 passage captures</title><style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}p{color:#bbb}</style><h1>L125 v225 vs L130 v227: passage captures</h1><section><h2>passage/0-1/0 — rock-floor/401.7m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-1.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-rock-floor-station-1.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — rock-floor/792.8m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-2.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-rock-floor-station-2.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — rock-floor/1634.5m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-3.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-rock-floor-station-3.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — rock-floor/27.0m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-1.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-rock-floor-station-1.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — rock-floor/52.9m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-2.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-rock-floor-station-2.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — rock-floor/78.9m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-3.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-rock-floor-station-3.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — rock-floor/323.4m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-1.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-rock-floor-station-1.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — rock-floor/333.4m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-2.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-rock-floor-station-2.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — rock-floor/343.4m</h2><p>rock-floor-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-3.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-rock-floor-station-3.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — section-1/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-1-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-openair-1-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — section-1/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-1-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-openair-1-4m-interior-wall.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — section-2/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-2-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-openair-2-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — section-2/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-2-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-openair-2-4m-interior-wall.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — section-3/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-3-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-openair-3-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/0-1/0 — section-3/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-3-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-0-1-0-openair-3-4m-interior-wall.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — section-1/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-1-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-openair-1-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — section-1/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-1-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-openair-1-4m-interior-wall.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — section-2/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-2-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-openair-2-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/1-2/0 — section-2/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-2-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-1-2-0-openair-2-4m-interior-wall.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — section-1/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-1-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-openair-1-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — section-1/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-1-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-openair-1-4m-interior-wall.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — section-2/4m-outside</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-2-4m-outside.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-openair-2-4m-outside.png'></figure></div></section>
|
||||||
|
<section><h2>passage/2-3/0 — section-2/4m-interior-wall</h2><p>open-air-close · byte identical: true</p><div><figure><figcaption>L125 v225</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-2-4m-interior-wall.png'></figure><figure><figcaption>L130 v227</figcaption><img src='L130/passage-2-3-0-openair-2-4m-interior-wall.png'></figure></div></section>
|
||||||
@@ -28,11 +28,11 @@
|
|||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"planned_floor_m": -445.66373993191075,
|
"planned_floor_m": -445.66373993191075,
|
||||||
"planned_grade_deg": 10.372328677972732,
|
"planned_grade_deg": 10.372328677972732,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-rock-floor-station-1.png",
|
"capture": "captures/L130/passage-0-1-0-rock-floor-station-1.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-1.vfmesh",
|
||||||
"drawn_triangles": 122264,
|
"drawn_triangles": 122294,
|
||||||
"source_triangles": 146688,
|
"source_triangles": 146798,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 401.6612010038529,
|
"route_distance_actual_m": 401.6612010038529,
|
||||||
@@ -54,9 +54,9 @@
|
|||||||
-445.66373993191075
|
-445.66373993191075
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-1-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-1-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-1-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
-7.026885053959959,
|
-7.026885053959959,
|
||||||
@@ -100,11 +100,11 @@
|
|||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"planned_floor_m": -516.0616688299093,
|
"planned_floor_m": -516.0616688299093,
|
||||||
"planned_grade_deg": 10.367725129664787,
|
"planned_grade_deg": 10.367725129664787,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-rock-floor-station-2.png",
|
"capture": "captures/L130/passage-0-1-0-rock-floor-station-2.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-2.vfmesh",
|
||||||
"drawn_triangles": 586094,
|
"drawn_triangles": 586092,
|
||||||
"source_triangles": 626214,
|
"source_triangles": 626196,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 792.8284020077059,
|
"route_distance_actual_m": 792.8284020077059,
|
||||||
@@ -126,9 +126,9 @@
|
|||||||
-516.0616688299093
|
-516.0616688299093
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-2-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-2-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-2-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
-2.471476828908,
|
-2.471476828908,
|
||||||
@@ -172,11 +172,11 @@
|
|||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"planned_floor_m": -667.5348848643227,
|
"planned_floor_m": -667.5348848643227,
|
||||||
"planned_grade_deg": 10.360515186362372,
|
"planned_grade_deg": 10.360515186362372,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-rock-floor-station-3.png",
|
"capture": "captures/L130/passage-0-1-0-rock-floor-station-3.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-3.vfmesh",
|
||||||
"drawn_triangles": 137258,
|
"drawn_triangles": 137288,
|
||||||
"source_triangles": 166706,
|
"source_triangles": 166736,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 1634.4566030115589,
|
"route_distance_actual_m": 1634.4566030115589,
|
||||||
@@ -198,9 +198,9 @@
|
|||||||
-667.5348848643227
|
-667.5348848643227
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-3-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-3-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-rock-floor-station-3-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
17.33622182815858,
|
17.33622182815858,
|
||||||
@@ -244,11 +244,11 @@
|
|||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"planned_floor_m": -738.1970266319915,
|
"planned_floor_m": -738.1970266319915,
|
||||||
"planned_grade_deg": 10.657740387934142,
|
"planned_grade_deg": 10.657740387934142,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-rock-floor-station-1.png",
|
"capture": "captures/L130/passage-1-2-0-rock-floor-station-1.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-1.vfmesh",
|
||||||
"drawn_triangles": 652040,
|
"drawn_triangles": 652056,
|
||||||
"source_triangles": 719644,
|
"source_triangles": 719660,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 26.963657939523273,
|
"route_distance_actual_m": 26.963657939523273,
|
||||||
@@ -270,9 +270,9 @@
|
|||||||
-738.1970266319915
|
-738.1970266319915
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-1-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-1-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-1-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
15.354124807038394,
|
15.354124807038394,
|
||||||
@@ -316,11 +316,11 @@
|
|||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"planned_floor_m": -742.995373541633,
|
"planned_floor_m": -742.995373541633,
|
||||||
"planned_grade_deg": 10.645569354114926,
|
"planned_grade_deg": 10.645569354114926,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-rock-floor-station-2.png",
|
"capture": "captures/L130/passage-1-2-0-rock-floor-station-2.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-2.vfmesh",
|
||||||
"drawn_triangles": 636134,
|
"drawn_triangles": 636162,
|
||||||
"source_triangles": 700530,
|
"source_triangles": 700558,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 52.927315879046546,
|
"route_distance_actual_m": 52.927315879046546,
|
||||||
@@ -342,9 +342,9 @@
|
|||||||
-742.995373541633
|
-742.995373541633
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-2-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-2-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-2-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
-4.766428465537912,
|
-4.766428465537912,
|
||||||
@@ -388,11 +388,11 @@
|
|||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"planned_floor_m": -747.7963166548619,
|
"planned_floor_m": -747.7963166548619,
|
||||||
"planned_grade_deg": 10.659092990906162,
|
"planned_grade_deg": 10.659092990906162,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-rock-floor-station-3.png",
|
"capture": "captures/L130/passage-1-2-0-rock-floor-station-3.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-3.vfmesh",
|
||||||
"drawn_triangles": 580464,
|
"drawn_triangles": 580472,
|
||||||
"source_triangles": 639368,
|
"source_triangles": 639376,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 78.89097381856982,
|
"route_distance_actual_m": 78.89097381856982,
|
||||||
@@ -414,9 +414,9 @@
|
|||||||
-747.7963166548619
|
-747.7963166548619
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-3-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-3-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-rock-floor-station-3-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
-12.283352972838873,
|
-12.283352972838873,
|
||||||
@@ -460,11 +460,11 @@
|
|||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"planned_floor_m": -871.0755965556104,
|
"planned_floor_m": -871.0755965556104,
|
||||||
"planned_grade_deg": 10.274530613220444,
|
"planned_grade_deg": 10.274530613220444,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-rock-floor-station-1.png",
|
"capture": "captures/L130/passage-2-3-0-rock-floor-station-1.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-1.vfmesh",
|
||||||
"drawn_triangles": 474960,
|
"drawn_triangles": 474964,
|
||||||
"source_triangles": 502358,
|
"source_triangles": 502362,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "low_contrast_geometry_visible",
|
"pixel_quality_status": "low_contrast_geometry_visible",
|
||||||
"route_distance_actual_m": 323.4481319239866,
|
"route_distance_actual_m": 323.4481319239866,
|
||||||
@@ -486,9 +486,9 @@
|
|||||||
-871.0755965556104
|
-871.0755965556104
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-1-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-1-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-1-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
9.103799793973732,
|
9.103799793973732,
|
||||||
@@ -532,11 +532,11 @@
|
|||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"planned_floor_m": -872.8561420785873,
|
"planned_floor_m": -872.8561420785873,
|
||||||
"planned_grade_deg": 10.266334408339132,
|
"planned_grade_deg": 10.266334408339132,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-rock-floor-station-2.png",
|
"capture": "captures/L130/passage-2-3-0-rock-floor-station-2.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-2.vfmesh",
|
||||||
"drawn_triangles": 494500,
|
"drawn_triangles": 494504,
|
||||||
"source_triangles": 524338,
|
"source_triangles": 524342,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 333.4481319239866,
|
"route_distance_actual_m": 333.4481319239866,
|
||||||
@@ -558,9 +558,9 @@
|
|||||||
-872.8561420785873
|
-872.8561420785873
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-2-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-2-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-2-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
15.204108325185125,
|
15.204108325185125,
|
||||||
@@ -604,11 +604,11 @@
|
|||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"planned_floor_m": -874.6379150751349,
|
"planned_floor_m": -874.6379150751349,
|
||||||
"planned_grade_deg": 10.259484647608062,
|
"planned_grade_deg": 10.259484647608062,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-rock-floor-station-3.png",
|
"capture": "captures/L130/passage-2-3-0-rock-floor-station-3.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-3.vfmesh",
|
||||||
"drawn_triangles": 485352,
|
"drawn_triangles": 485356,
|
||||||
"source_triangles": 512660,
|
"source_triangles": 512664,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 343.4481319239866,
|
"route_distance_actual_m": 343.4481319239866,
|
||||||
@@ -630,9 +630,9 @@
|
|||||||
-874.6379150751349
|
-874.6379150751349
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-3-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-3-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-rock-floor-station-3-quality.log"
|
||||||
],
|
],
|
||||||
"floor_anchor_position_m": [
|
"floor_anchor_position_m": [
|
||||||
15.464091528009144,
|
15.464091528009144,
|
||||||
@@ -682,11 +682,11 @@
|
|||||||
"route_distance_m": 8.3545,
|
"route_distance_m": 8.3545,
|
||||||
"requested_route_distance_m": 8.3545,
|
"requested_route_distance_m": 8.3545,
|
||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-openair-1-4m-outside.png",
|
"capture": "captures/L130/passage-0-1-0-openair-1-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 275333,
|
"drawn_triangles": 275333,
|
||||||
"source_triangles": 327761,
|
"source_triangles": 327745,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 8.3545,
|
"route_distance_actual_m": 8.3545,
|
||||||
@@ -708,9 +708,9 @@
|
|||||||
-373.75
|
-373.75
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -747,11 +747,11 @@
|
|||||||
"route_distance_m": 8.3545,
|
"route_distance_m": 8.3545,
|
||||||
"requested_route_distance_m": 8.3545,
|
"requested_route_distance_m": 8.3545,
|
||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-openair-1-4m-interior-wall.png",
|
"capture": "captures/L130/passage-0-1-0-openair-1-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 308012,
|
"drawn_triangles": 308012,
|
||||||
"source_triangles": 368140,
|
"source_triangles": 368124,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "low_contrast_geometry_visible",
|
"pixel_quality_status": "low_contrast_geometry_visible",
|
||||||
"route_distance_actual_m": 8.3545,
|
"route_distance_actual_m": 8.3545,
|
||||||
@@ -773,9 +773,9 @@
|
|||||||
-373.75
|
-373.75
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-1-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -812,11 +812,11 @@
|
|||||||
"route_distance_m": 14.4925,
|
"route_distance_m": 14.4925,
|
||||||
"requested_route_distance_m": 14.4925,
|
"requested_route_distance_m": 14.4925,
|
||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-openair-2-4m-outside.png",
|
"capture": "captures/L130/passage-0-1-0-openair-2-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 275333,
|
"drawn_triangles": 275333,
|
||||||
"source_triangles": 327761,
|
"source_triangles": 327745,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 14.4925,
|
"route_distance_actual_m": 14.4925,
|
||||||
@@ -838,9 +838,9 @@
|
|||||||
-376.0
|
-376.0
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -877,11 +877,11 @@
|
|||||||
"route_distance_m": 14.4925,
|
"route_distance_m": 14.4925,
|
||||||
"requested_route_distance_m": 14.4925,
|
"requested_route_distance_m": 14.4925,
|
||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-openair-2-4m-interior-wall.png",
|
"capture": "captures/L130/passage-0-1-0-openair-2-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 345044,
|
"drawn_triangles": 345026,
|
||||||
"source_triangles": 414692,
|
"source_triangles": 414658,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 14.4925,
|
"route_distance_actual_m": 14.4925,
|
||||||
@@ -903,9 +903,9 @@
|
|||||||
-376.0
|
-376.0
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-2-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -942,35 +942,35 @@
|
|||||||
"route_distance_m": 1265.3425000000002,
|
"route_distance_m": 1265.3425000000002,
|
||||||
"requested_route_distance_m": 1265.3425000000002,
|
"requested_route_distance_m": 1265.3425000000002,
|
||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-openair-3-4m-outside.png",
|
"capture": "captures/L130/passage-0-1-0-openair-3-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 151372,
|
"drawn_triangles": 149234,
|
||||||
"source_triangles": 183724,
|
"source_triangles": 181128,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 1265.3425000000002,
|
"route_distance_actual_m": 1265.3425000000002,
|
||||||
"route_station_adjustment_m": 0.0,
|
"route_station_adjustment_m": 0.0,
|
||||||
"closeup_camera_target_distance_m": 3.9999999999999947,
|
"closeup_camera_target_distance_m": 3.9999999999999907,
|
||||||
"closeup_target_surface_distance_m": 0.06828066292003203,
|
"closeup_target_surface_distance_m": 0.06836631107301705,
|
||||||
"closeup_predicted_target_offset_m": 0.06828066292003203,
|
"closeup_predicted_target_offset_m": 0.06836631107301705,
|
||||||
"closeup_wall_normal_alignment": 0.9604791479186932,
|
"closeup_wall_normal_alignment": 0.9604329420550252,
|
||||||
"fallback_kind": null,
|
"fallback_kind": null,
|
||||||
"fallback_surface_distance_m": null,
|
"fallback_surface_distance_m": null,
|
||||||
"camera_actual_m": [
|
"camera_actual_m": [
|
||||||
-28.639699107248397,
|
-28.63982379180018,
|
||||||
-15.583356294879769,
|
-15.582695163623317,
|
||||||
-601.2437793015765
|
-601.2438490311043
|
||||||
],
|
],
|
||||||
"target_actual_m": [
|
"target_actual_m": [
|
||||||
-24.95574413685722,
|
-24.955621627611308,
|
||||||
-14.176529326299274,
|
-14.176566764792845,
|
||||||
-600.5734706737007
|
-600.5734332352072
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1007,35 +1007,35 @@
|
|||||||
"route_distance_m": 1265.3425000000002,
|
"route_distance_m": 1265.3425000000002,
|
||||||
"requested_route_distance_m": 1265.3425000000002,
|
"requested_route_distance_m": 1265.3425000000002,
|
||||||
"route_length_m": 2026.6238040154117,
|
"route_length_m": 2026.6238040154117,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-0-1-0-openair-3-4m-interior-wall.png",
|
"capture": "captures/L130/passage-0-1-0-openair-3-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 150614,
|
"drawn_triangles": 148100,
|
||||||
"source_triangles": 183232,
|
"source_triangles": 180244,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 1265.3425000000002,
|
"route_distance_actual_m": 1265.3425000000002,
|
||||||
"route_station_adjustment_m": 0.0,
|
"route_station_adjustment_m": 0.0,
|
||||||
"closeup_camera_target_distance_m": 4.000000000000011,
|
"closeup_camera_target_distance_m": 4.000000000000004,
|
||||||
"closeup_target_surface_distance_m": 0.15815699667954516,
|
"closeup_target_surface_distance_m": 0.15667051955483755,
|
||||||
"closeup_predicted_target_offset_m": 0.15815699667954516,
|
"closeup_predicted_target_offset_m": 0.15667051955483755,
|
||||||
"closeup_wall_normal_alignment": 0.9379407978793181,
|
"closeup_wall_normal_alignment": 0.936006465878356,
|
||||||
"fallback_kind": null,
|
"fallback_kind": null,
|
||||||
"fallback_surface_distance_m": null,
|
"fallback_surface_distance_m": null,
|
||||||
"camera_actual_m": [
|
"camera_actual_m": [
|
||||||
-21.87278031692096,
|
-21.875641690065105,
|
||||||
-11.881551644506661,
|
-11.887416826703374,
|
||||||
-599.3233300443438
|
-599.3020917133557
|
||||||
],
|
],
|
||||||
"target_actual_m": [
|
"target_actual_m": [
|
||||||
-24.868945473985846,
|
-24.866552934428398,
|
||||||
-14.149254069257264,
|
-14.149067333208382,
|
||||||
-600.6946505992728
|
-600.6947104389109
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-0-1-0-openair-3-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1072,11 +1072,11 @@
|
|||||||
"route_distance_m": 83.504,
|
"route_distance_m": 83.504,
|
||||||
"requested_route_distance_m": 83.504,
|
"requested_route_distance_m": 83.504,
|
||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-openair-1-4m-outside.png",
|
"capture": "captures/L130/passage-1-2-0-openair-1-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 620798,
|
"drawn_triangles": 620814,
|
||||||
"source_triangles": 684760,
|
"source_triangles": 684776,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 83.504,
|
"route_distance_actual_m": 83.504,
|
||||||
@@ -1098,9 +1098,9 @@
|
|||||||
-747.5006103515625
|
-747.5006103515625
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1137,11 +1137,11 @@
|
|||||||
"route_distance_m": 83.504,
|
"route_distance_m": 83.504,
|
||||||
"requested_route_distance_m": 83.504,
|
"requested_route_distance_m": 83.504,
|
||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-openair-1-4m-interior-wall.png",
|
"capture": "captures/L130/passage-1-2-0-openair-1-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 609749,
|
"drawn_triangles": 609757,
|
||||||
"source_triangles": 668123,
|
"source_triangles": 668131,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 83.504,
|
"route_distance_actual_m": 83.504,
|
||||||
@@ -1163,9 +1163,9 @@
|
|||||||
-748.1744141343152
|
-748.1744141343152
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-1-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1202,11 +1202,11 @@
|
|||||||
"route_distance_m": 104.362,
|
"route_distance_m": 104.362,
|
||||||
"requested_route_distance_m": 104.362,
|
"requested_route_distance_m": 104.362,
|
||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-openair-2-4m-outside.png",
|
"capture": "captures/L130/passage-1-2-0-openair-2-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 584534,
|
"drawn_triangles": 584542,
|
||||||
"source_triangles": 636994,
|
"source_triangles": 637002,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 104.362,
|
"route_distance_actual_m": 104.362,
|
||||||
@@ -1228,9 +1228,9 @@
|
|||||||
-752.0293187551489
|
-752.0293187551489
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1267,11 +1267,11 @@
|
|||||||
"route_distance_m": 104.362,
|
"route_distance_m": 104.362,
|
||||||
"requested_route_distance_m": 104.362,
|
"requested_route_distance_m": 104.362,
|
||||||
"route_length_m": 114.99063175809309,
|
"route_length_m": 114.99063175809309,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-1-2-0-openair-2-4m-interior-wall.png",
|
"capture": "captures/L130/passage-1-2-0-openair-2-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 572250,
|
"drawn_triangles": 572258,
|
||||||
"source_triangles": 618638,
|
"source_triangles": 618646,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 104.362,
|
"route_distance_actual_m": 104.362,
|
||||||
@@ -1293,9 +1293,9 @@
|
|||||||
-752.0074179101423
|
-752.0074179101423
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-1-2-0-openair-2-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1332,9 +1332,9 @@
|
|||||||
"route_distance_m": 16.616500000000002,
|
"route_distance_m": 16.616500000000002,
|
||||||
"requested_route_distance_m": 16.616500000000002,
|
"requested_route_distance_m": 16.616500000000002,
|
||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-openair-1-4m-outside.png",
|
"capture": "captures/L130/passage-2-3-0-openair-1-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 104612,
|
"drawn_triangles": 104612,
|
||||||
"source_triangles": 129326,
|
"source_triangles": 129326,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
@@ -1358,9 +1358,9 @@
|
|||||||
-816.1078690565205
|
-816.1078690565205
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1397,9 +1397,9 @@
|
|||||||
"route_distance_m": 16.616500000000002,
|
"route_distance_m": 16.616500000000002,
|
||||||
"requested_route_distance_m": 16.616500000000002,
|
"requested_route_distance_m": 16.616500000000002,
|
||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-openair-1-4m-interior-wall.png",
|
"capture": "captures/L130/passage-2-3-0-openair-1-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 94962,
|
"drawn_triangles": 94962,
|
||||||
"source_triangles": 118028,
|
"source_triangles": 118028,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
@@ -1423,9 +1423,9 @@
|
|||||||
-815.6327986602337
|
-815.6327986602337
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-1-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1462,11 +1462,11 @@
|
|||||||
"route_distance_m": 374.929,
|
"route_distance_m": 374.929,
|
||||||
"requested_route_distance_m": 374.929,
|
"requested_route_distance_m": 374.929,
|
||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-openair-2-4m-outside.png",
|
"capture": "captures/L130/passage-2-3-0-openair-2-4m-outside.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-outside.vfmesh",
|
||||||
"drawn_triangles": 475856,
|
"drawn_triangles": 475860,
|
||||||
"source_triangles": 504240,
|
"source_triangles": 504244,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
"pixel_quality_status": "pass",
|
"pixel_quality_status": "pass",
|
||||||
"route_distance_actual_m": 374.929,
|
"route_distance_actual_m": 374.929,
|
||||||
@@ -1488,9 +1488,9 @@
|
|||||||
-879.7662205769708
|
-879.7662205769708
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-outside-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-outside-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-outside-quality.log"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1527,9 +1527,9 @@
|
|||||||
"route_distance_m": 374.929,
|
"route_distance_m": 374.929,
|
||||||
"requested_route_distance_m": 374.929,
|
"requested_route_distance_m": 374.929,
|
||||||
"route_length_m": 494.0722798830563,
|
"route_length_m": 494.0722798830563,
|
||||||
"variant": "L128-slab-ownership-v226",
|
"variant": "L130-v227",
|
||||||
"capture": "captures/L128/passage-2-3-0-openair-2-4m-interior-wall.png",
|
"capture": "captures/L130/passage-2-3-0-openair-2-4m-interior-wall.png",
|
||||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall.vfmesh",
|
"scene": "Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-interior-wall.vfmesh",
|
||||||
"drawn_triangles": 486480,
|
"drawn_triangles": 486480,
|
||||||
"source_triangles": 513552,
|
"source_triangles": 513552,
|
||||||
"verified": true,
|
"verified": true,
|
||||||
@@ -1553,9 +1553,9 @@
|
|||||||
-879.75
|
-879.75
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall-mesh.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-interior-wall-mesh.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall-render.log",
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-interior-wall-render.log",
|
||||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall-quality.log"
|
"Saved/Linux/l130/captures/L130/passage-2-3-0-openair-2-4m-interior-wall-quality.log"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 163 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 106 KiB |
@@ -0,0 +1,6 @@
|
|||||||
|
<!doctype html><meta charset='utf-8'><title>L130 mouth closeups</title><style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}p{color:#bbb}</style><h1>L129 mouth closeups: b96dd73 vs L130</h1><section><h2>passage-0-1-0-lower-mouth</h2><p>byte identical: true</p><div><figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/passage-0-1-0-lower-mouth.png'></figure><figure><figcaption>L130 reach units</figcaption><img src='L130/passage-0-1-0-lower-mouth.png'></figure></div></section>
|
||||||
|
<section><h2>passage-0-1-0-upper-mouth</h2><p>byte identical: true</p><div><figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/passage-0-1-0-upper-mouth.png'></figure><figure><figcaption>L130 reach units</figcaption><img src='L130/passage-0-1-0-upper-mouth.png'></figure></div></section>
|
||||||
|
<section><h2>passage-1-2-0-lower-mouth</h2><p>byte identical: true</p><div><figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/passage-1-2-0-lower-mouth.png'></figure><figure><figcaption>L130 reach units</figcaption><img src='L130/passage-1-2-0-lower-mouth.png'></figure></div></section>
|
||||||
|
<section><h2>passage-1-2-0-upper-mouth</h2><p>byte identical: true</p><div><figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/passage-1-2-0-upper-mouth.png'></figure><figure><figcaption>L130 reach units</figcaption><img src='L130/passage-1-2-0-upper-mouth.png'></figure></div></section>
|
||||||
|
<section><h2>passage-2-3-0-lower-mouth</h2><p>byte identical: true</p><div><figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/passage-2-3-0-lower-mouth.png'></figure><figure><figcaption>L130 reach units</figcaption><img src='L130/passage-2-3-0-lower-mouth.png'></figure></div></section>
|
||||||
|
<section><h2>passage-2-3-0-upper-mouth</h2><p>byte identical: true</p><div><figure><figcaption>b96dd73 source mesh</figcaption><img src='b96dd73/passage-2-3-0-upper-mouth.png'></figure><figure><figcaption>L130 reach units</figcaption><img src='L130/passage-2-3-0-upper-mouth.png'></figure></div></section>
|
||||||
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,134 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "passage-0-1-0-lower-mouth",
|
||||||
|
"camera_m": [
|
||||||
|
32.688347,
|
||||||
|
9.553723,
|
||||||
|
-735.48053
|
||||||
|
],
|
||||||
|
"yaw_deg": -132.845,
|
||||||
|
"pitch_deg": -6.052,
|
||||||
|
"height_center_m": -736.267,
|
||||||
|
"source_mesh": "Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-lower-mouth.vfmesh",
|
||||||
|
"candidate_mesh": "Saved/Linux/l130/captures/mouth-closeups/L130/passage-0-1-0-lower-mouth.vfmesh",
|
||||||
|
"baseline_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/b96dd73/passage-0-1-0-lower-mouth.png",
|
||||||
|
"candidate_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/L130/passage-0-1-0-lower-mouth.png",
|
||||||
|
"baseline_sha256": "aff7310b94e1b57e9cd1e42d3294e10964aed4a56e74bec8c1cdc0a5b2bffa98",
|
||||||
|
"candidate_sha256": "aff7310b94e1b57e9cd1e42d3294e10964aed4a56e74bec8c1cdc0a5b2bffa98",
|
||||||
|
"byte_identical": true,
|
||||||
|
"drawn_triangles": {
|
||||||
|
"b96dd73": 549170,
|
||||||
|
"L130": 549170
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "passage-0-1-0-upper-mouth",
|
||||||
|
"camera_m": [
|
||||||
|
8.324777,
|
||||||
|
20.450708,
|
||||||
|
-371.84259
|
||||||
|
],
|
||||||
|
"yaw_deg": -175.826,
|
||||||
|
"pitch_deg": -0.889,
|
||||||
|
"height_center_m": -372.122,
|
||||||
|
"source_mesh": "Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-upper-mouth.vfmesh",
|
||||||
|
"candidate_mesh": "Saved/Linux/l130/captures/mouth-closeups/L130/passage-0-1-0-upper-mouth.vfmesh",
|
||||||
|
"baseline_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/b96dd73/passage-0-1-0-upper-mouth.png",
|
||||||
|
"candidate_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/L130/passage-0-1-0-upper-mouth.png",
|
||||||
|
"baseline_sha256": "76dbb3263eb4f2018d13496f42b6eff7eb875e2029358776e22337aea8893a6d",
|
||||||
|
"candidate_sha256": "76dbb3263eb4f2018d13496f42b6eff7eb875e2029358776e22337aea8893a6d",
|
||||||
|
"byte_identical": true,
|
||||||
|
"drawn_triangles": {
|
||||||
|
"b96dd73": 243380,
|
||||||
|
"L130": 243380
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "passage-1-2-0-lower-mouth",
|
||||||
|
"camera_m": [
|
||||||
|
27.129938,
|
||||||
|
-19.07345,
|
||||||
|
-751.877197
|
||||||
|
],
|
||||||
|
"yaw_deg": -58.537,
|
||||||
|
"pitch_deg": -5.944,
|
||||||
|
"height_center_m": -751.734,
|
||||||
|
"source_mesh": "Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-lower-mouth.vfmesh",
|
||||||
|
"candidate_mesh": "Saved/Linux/l130/captures/mouth-closeups/L130/passage-1-2-0-lower-mouth.vfmesh",
|
||||||
|
"baseline_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/b96dd73/passage-1-2-0-lower-mouth.png",
|
||||||
|
"candidate_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/L130/passage-1-2-0-lower-mouth.png",
|
||||||
|
"baseline_sha256": "1c193b6fcb65b98b1c721704990392dc816486639e047b53bb72b4a17d89ae4c",
|
||||||
|
"candidate_sha256": "1c193b6fcb65b98b1c721704990392dc816486639e047b53bb72b4a17d89ae4c",
|
||||||
|
"byte_identical": true,
|
||||||
|
"drawn_triangles": {
|
||||||
|
"b96dd73": 544808,
|
||||||
|
"L130": 544808
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "passage-1-2-0-upper-mouth",
|
||||||
|
"camera_m": [
|
||||||
|
23.391808,
|
||||||
|
-15.509525,
|
||||||
|
-731.781067
|
||||||
|
],
|
||||||
|
"yaw_deg": -72.785,
|
||||||
|
"pitch_deg": -0.897,
|
||||||
|
"height_center_m": -730.561,
|
||||||
|
"source_mesh": "Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-upper-mouth.vfmesh",
|
||||||
|
"candidate_mesh": "Saved/Linux/l130/captures/mouth-closeups/L130/passage-1-2-0-upper-mouth.vfmesh",
|
||||||
|
"baseline_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/b96dd73/passage-1-2-0-upper-mouth.png",
|
||||||
|
"candidate_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/L130/passage-1-2-0-upper-mouth.png",
|
||||||
|
"baseline_sha256": "28576cefb1b59601d2e68981a7b77fc28a1d667c58ab27292deac0acd9deb338",
|
||||||
|
"candidate_sha256": "28576cefb1b59601d2e68981a7b77fc28a1d667c58ab27292deac0acd9deb338",
|
||||||
|
"byte_identical": true,
|
||||||
|
"drawn_triangles": {
|
||||||
|
"b96dd73": 593026,
|
||||||
|
"L130": 593026
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "passage-2-3-0-lower-mouth",
|
||||||
|
"camera_m": [
|
||||||
|
-28.589163,
|
||||||
|
-1.226313,
|
||||||
|
-898.811707
|
||||||
|
],
|
||||||
|
"yaw_deg": 114.256,
|
||||||
|
"pitch_deg": -6.159,
|
||||||
|
"height_center_m": -898.713,
|
||||||
|
"source_mesh": "Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-lower-mouth.vfmesh",
|
||||||
|
"candidate_mesh": "Saved/Linux/l130/captures/mouth-closeups/L130/passage-2-3-0-lower-mouth.vfmesh",
|
||||||
|
"baseline_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/b96dd73/passage-2-3-0-lower-mouth.png",
|
||||||
|
"candidate_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/L130/passage-2-3-0-lower-mouth.png",
|
||||||
|
"baseline_sha256": "58cd3ea88c754afab20d1cdcaf5f0edf676f0303d9f392d3632a6f2257205766",
|
||||||
|
"candidate_sha256": "58cd3ea88c754afab20d1cdcaf5f0edf676f0303d9f392d3632a6f2257205766",
|
||||||
|
"byte_identical": true,
|
||||||
|
"drawn_triangles": {
|
||||||
|
"b96dd73": 293832,
|
||||||
|
"L130": 293832
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "passage-2-3-0-upper-mouth",
|
||||||
|
"camera_m": [
|
||||||
|
-24.455027,
|
||||||
|
-5.631774,
|
||||||
|
-811.975403
|
||||||
|
],
|
||||||
|
"yaw_deg": 82.691,
|
||||||
|
"pitch_deg": -0.896,
|
||||||
|
"height_center_m": -810.755,
|
||||||
|
"source_mesh": "Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-upper-mouth.vfmesh",
|
||||||
|
"candidate_mesh": "Saved/Linux/l130/captures/mouth-closeups/L130/passage-2-3-0-upper-mouth.vfmesh",
|
||||||
|
"baseline_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/b96dd73/passage-2-3-0-upper-mouth.png",
|
||||||
|
"candidate_png": "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups/L130/passage-2-3-0-upper-mouth.png",
|
||||||
|
"baseline_sha256": "6b903c68fac1a20783185afbac8cdad717c6e9374e665e3618e118c5a6aadf51",
|
||||||
|
"candidate_sha256": "6b903c68fac1a20783185afbac8cdad717c6e9374e665e3618e118c5a6aadf51",
|
||||||
|
"byte_identical": true,
|
||||||
|
"drawn_triangles": {
|
||||||
|
"b96dd73": 59554,
|
||||||
|
"L130": 59554
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[PipelineFullDetailHash] tiles=960 density=0x91931a57a067fd92 mesh=0xa818654be89790ac payload=0x370ff80451105a39 topology=0x06e507557aa70173
|
||||||
|
[PipelineWholeViewHash] tiles=2370 density=0xf4d3d09d3f31d9bc mesh=0x520f545165440f40 payload=0x6a45502e6bb7ae01 topology=0x8f7d03ba1e2000f3
|
||||||
|
[PipelineLODHash] lod=0 tiles=512 density=0x2fd4c78685a43cfe mesh=0x50478cff1c1f8ca0 payload=0x54e48e57e0af26de topology=0x860c011cfdb9833a
|
||||||
|
[PipelineLODHash] lod=1 tiles=448 density=0x4b8d9a6dcd2942ad mesh=0x17e89b7087bfe711 payload=0x2389c109eb780db6 topology=0x7eccd4cf560d0630
|
||||||
|
[PipelineLODHash] lod=2 tiles=320 density=0x7640a0646ee5ac17 mesh=0x9b63c5aa29160969 payload=0x91cd7ca9a828149b topology=0xcb558843c345a327
|
||||||
|
[PipelineLODHash] lod=3 tiles=208 density=0xdd07fe8f31ede73a mesh=0xfaa2f90438226625 payload=0x86904d144f5db47c topology=0xcfd10c90d38f3fca
|
||||||
|
[PipelineLODHash] lod=4 tiles=240 density=0xfb11591772a3d18e mesh=0xebf2baee8764591b payload=0xe491d7ac9c0061ad topology=0xd618ac33b95ce494
|
||||||
|
[PipelineLODHash] lod=5 tiles=144 density=0x2f8b7b7fb1e67258 mesh=0x4cd508cbe97344fd payload=0x2b6e96a6050458c9 topology=0x4ff6d0eda8988573
|
||||||
|
[PipelineLODHash] lod=6 tiles=96 density=0x0114a34c8b8d6113 mesh=0xb1fec4d01ae1fa44 payload=0x3e50cfd429b8e950 topology=0x08090c96d15c1618
|
||||||
|
[PipelineLODHash] lod=7 tiles=96 density=0x3836ed8cfce73418 mesh=0x40bc6589c5fc1aac payload=0x677349bcae16790f topology=0x36e3aa53192e6a6b
|
||||||
|
[PipelineLODHash] lod=8 tiles=306 density=0x144f3c1fd722708b mesh=0xef77b28bf7fd9453 payload=0xe3f47b37fcd61489 topology=0x5a3c73e295494e04
|
||||||
|
[PipelineExactQueryHash] probes=9 density=0x7b7c50ac24ccadcc unclamped=0x7b7c50ac24ccadcc detail=0xefcba20c0c70c415 collision=0xe604823a249029bf path=direct-Core-queries
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[PipelineFullDetailHash] tiles=960 density=0x11802e529414a62a mesh=0xee7dab071f572c46 payload=0x824a7c07f3cd3f8f topology=0x14a372c4f0003a9b
|
||||||
|
[PipelineWholeViewHash] tiles=2578 density=0x077534532d13b549 mesh=0x0932314a7475fed4 payload=0x6c2bfa3e4a72f8dc topology=0x7e6b3b76ed31bd0f
|
||||||
|
[PipelineLODHash] lod=0 tiles=512 density=0xf8cbb499fca6f62b mesh=0xf3b8e097407eb9e1 payload=0xeef6bfe266279de5 topology=0x79c5ed3811360d1e
|
||||||
|
[PipelineLODHash] lod=1 tiles=448 density=0x7d95c955a8433cac mesh=0xa803bb427deeba9a payload=0xf4718f1ce85d4f4f topology=0x7b770585aafd8174
|
||||||
|
[PipelineLODHash] lod=2 tiles=320 density=0x1c9445d15cce0de3 mesh=0x4da3bcf40eb6d137 payload=0x561116e3bbf34b8e topology=0x5e0e5a961bea641e
|
||||||
|
[PipelineLODHash] lod=3 tiles=272 density=0xe505981dea225509 mesh=0x1b13027b94137ad0 payload=0x3f93cd2fda3fef1c topology=0x8e160cd2f5ab0805
|
||||||
|
[PipelineLODHash] lod=4 tiles=272 density=0xb743eb64967bddcd mesh=0xf6b5bd36b0ebfead payload=0xd1284c1540f50636 topology=0x4a6e197e2a1a9500
|
||||||
|
[PipelineLODHash] lod=5 tiles=208 density=0x38706b628a74dd17 mesh=0x445b1c7b51489cbb payload=0x713efc66290768f7 topology=0x56486b919146bb1e
|
||||||
|
[PipelineLODHash] lod=6 tiles=144 density=0xd53849b2002a1faa mesh=0xaa210abc8498c415 payload=0xd109aef8639706d1 topology=0x61a4d75fbbc35268
|
||||||
|
[PipelineLODHash] lod=7 tiles=96 density=0xb0ea9a140275c9cc mesh=0x3ffd8365c8b0ec29 payload=0x3577afb0a2e4a420 topology=0x97530aafde15b7e0
|
||||||
|
[PipelineLODHash] lod=8 tiles=306 density=0x8b3d1816799d67a0 mesh=0x80bf554f17700e1e payload=0xccbe22c3333a9c34 topology=0xcb11b28f6b6bcc50
|
||||||
|
[PipelineExactQueryHash] probes=9 density=0xf2df67b38b7802df unclamped=0x48b347986345b557 detail=0xefcba20c0c70c415 collision=0x137e8f6c0b03a624 path=direct-Core-queries
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[PipelineFullDetailHash] tiles=960 density=0xace56c8f205238ad mesh=0xa9c603a1248de6b8 payload=0xea55f1f4fcc6a894 topology=0x5ea7bc78a1b678ae
|
||||||
|
[PipelineWholeViewHash] tiles=2370 density=0x03331b1721d89092 mesh=0x1fa61520dc6c6d7b payload=0xe5c306e087381056 topology=0xef499f11d87ca569
|
||||||
|
[PipelineLODHash] lod=0 tiles=512 density=0xcd6ab28cfa504aca mesh=0xf03dc80a669fca31 payload=0x397aded1c3d2d297 topology=0xb4a1dc84fabc1fe3
|
||||||
|
[PipelineLODHash] lod=1 tiles=448 density=0xce6e713828b2a20a mesh=0x1cf408c25d67d18c payload=0x8a2b5d20571c997e topology=0x51cd985fe8e7d100
|
||||||
|
[PipelineLODHash] lod=2 tiles=320 density=0x8581c27a6966cccd mesh=0x610a6eb3ef75fe11 payload=0xdecaf47d125efd5c topology=0xa5ea883ebeb628e4
|
||||||
|
[PipelineLODHash] lod=3 tiles=208 density=0x5d87341a6428ea0b mesh=0x662096703512f5e2 payload=0x5703acca3ad9c2c7 topology=0xc8fb411f09c46f60
|
||||||
|
[PipelineLODHash] lod=4 tiles=240 density=0x0be8798407724eaf mesh=0x131c303cbbe51434 payload=0x2a90ecf0a2411ca0 topology=0xe3e054a371152e08
|
||||||
|
[PipelineLODHash] lod=5 tiles=144 density=0xf20897ad272103a9 mesh=0x13d00b6253ae1f72 payload=0x0db3880693a962fa topology=0x462bd87a80f15e89
|
||||||
|
[PipelineLODHash] lod=6 tiles=96 density=0xc040fcac457d6313 mesh=0x1ed132eeb718fb62 payload=0xcd0214e35577c6e3 topology=0x2c56c69e6fdcfd64
|
||||||
|
[PipelineLODHash] lod=7 tiles=96 density=0xc2d419446355fdb8 mesh=0x4ea44452574fc84b payload=0xfd9779bedfc9ae0f topology=0x8948546e770c9b72
|
||||||
|
[PipelineLODHash] lod=8 tiles=306 density=0x62db31696f2da831 mesh=0xd373f9e9481532fe payload=0x540a60526e0e3e46 topology=0xc725cb901e6dc335
|
||||||
|
[PipelineExactQueryHash] probes=9 density=0xc949c4df2ce6f9d9 unclamped=0xc949c4df2ce6f9d9 detail=0x114c501e2d830d94 collision=0xe6011d3a248d4849 path=direct-Core-queries
|
||||||
@@ -122,11 +122,11 @@ RECIPE_RE = re.compile(
|
|||||||
|
|
||||||
def owner_hash_baseline(recipe: str, style: int) -> tuple[Path, str]:
|
def owner_hash_baseline(recipe: str, style: int) -> tuple[Path, str]:
|
||||||
if recipe == "surface-world" and style == 1:
|
if recipe == "surface-world" and style == 1:
|
||||||
return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v225.baseline",
|
return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v227.baseline",
|
||||||
"L125-v225-stamped-passage-sweep")
|
"L130-v227-reach-units")
|
||||||
if recipe == "floating-islands" and style == 2:
|
if recipe == "floating-islands" and style == 2:
|
||||||
return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v225.baseline",
|
return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v227.baseline",
|
||||||
"L125-v225-stamped-passage-sweep")
|
"L130-v227-reach-units")
|
||||||
raise VerificationFailure(f"no pinned owner hash baseline for {recipe} style {style}")
|
raise VerificationFailure(f"no pinned owner hash baseline for {recipe} style {style}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||