passages: memoized exact MC midpoints + wider conservative sweep bounds (L101, exact vs L100)
Off-grid census by caller (MC midpoints, skirts, far shells); all 63.0M sweep misses accounted (1.9M exact-route fallbacks, 61.1M counted bound skips). Exact MC midpoint queries memoized by float bits (Unreal enables it too); feature bounds expanded. L100/L101 whole-view hashes equal in all four strata (v216 unchanged); 0 added/removed crossings; 15 capture pairs pixel-identical. Near-ready @W12 L100 -> L101: FI 1.77 -> 1.65, TN 1.66 -> 1.54, SW 0.85 -> 0.84, VS 1.03 -> 1.03 s (L98 2.28/2.23/1.02/1.11). Fast tier PASS; Linux UE host builds. Unreal arrival traces not obtained (the runner wrongly applied the 6 GiB address-space cap to Unreal). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
2d5822cdf7
commit
55e20f4a7e
48 files changed
+2087
-38
No files matched your search
@@ -205,6 +205,8 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
bool bForceFullDensityCapture)
|
||||
{
|
||||
TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_MesherGenerateMesh);
|
||||
FStandaloneShapeWorld::FScopedPassageDensityQueryCaller densityQueryCaller(
|
||||
EPassageDensityQueryCaller::DensityGrid);
|
||||
const uint64 StageMesherStartCycles=OutStageTimings?FPlatformTime::Cycles64():0;
|
||||
FVoxelMeshData MeshData;
|
||||
if (OutCaptureGrid) { OutCaptureGrid->Reset(); }
|
||||
@@ -1450,6 +1452,8 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
FVoxelMarchingCubesStageTimings& StageTimings=LaneTimings[Lane];
|
||||
{
|
||||
FVoxelMesherThreadStateScope ThreadStateScope(TileThreadState);
|
||||
FStandaloneShapeWorld::FScopedPassageDensityQueryCaller queryCaller(
|
||||
EPassageDensityQueryCaller::DensityGrid);
|
||||
if(bUseOperatorBlock)
|
||||
Generator->BeginDensityBlock(
|
||||
OriginVoxels+FIntVector(-Step,-Step,GzLo*Step),Step,
|
||||
@@ -1974,6 +1978,8 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
return Cached;
|
||||
}
|
||||
if(OutStageTimings)++OutStageTimings->GradientFallbackDensityCalls;
|
||||
FStandaloneShapeWorld::FScopedPassageDensityQueryCaller queryCaller(
|
||||
EPassageDensityQueryCaller::GradientNormalFallback);
|
||||
return ShapeWorldContext->DensityAtUnclamped(
|
||||
static_cast<float>(OriginVoxels.X + gx * Step),
|
||||
static_cast<float>(OriginVoxels.Y + gy * Step),
|
||||
@@ -2245,6 +2251,13 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
const double MidX=Midpoint.X/GeometryVoxelSize;
|
||||
const double MidY=Midpoint.Y/GeometryVoxelSize;
|
||||
const double MidZ=Midpoint.Z/GeometryVoxelSize;
|
||||
const auto EvaluateExactMidpoint=[&]()
|
||||
{
|
||||
FStandaloneShapeWorld::FScopedPassageDensityQueryCaller
|
||||
queryCaller(EPassageDensityQueryCaller::MidpointCorrection);
|
||||
return ShapeWorldContext->DensityAtUnclamped(
|
||||
MidX,MidY,MidZ);
|
||||
};
|
||||
float MidDensity=0.0f;
|
||||
if(bStandaloneEnableExactMidpointDensityMemo)
|
||||
{
|
||||
@@ -2259,11 +2272,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
}
|
||||
else
|
||||
{
|
||||
MidDensity=ShapeWorldContext->DensityAtUnclamped(MidX,MidY,MidZ);
|
||||
MidDensity=EvaluateExactMidpoint();
|
||||
MidpointDensityMemo.emplace(Key,MidDensity);
|
||||
}
|
||||
}
|
||||
else MidDensity=ShapeWorldContext->DensityAtUnclamped(MidX,MidY,MidZ);
|
||||
else MidDensity=EvaluateExactMidpoint();
|
||||
if(FMath::Abs(MidDensity-IsoLevel)<1.0e-6f)
|
||||
T=0.5f;
|
||||
else if((MidDensity<IsoLevel)==(D1<IsoLevel))
|
||||
@@ -2458,8 +2471,46 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
};
|
||||
|
||||
std::vector<float> SurfaceVertexDensitySamples;
|
||||
const auto CountSkirtDensityProbe=[&]()
|
||||
{if(OutStageTimings)++OutStageTimings->SkirtDensityProbes;};
|
||||
const auto CountSkirtDensityProbe=[&](EVoxelSkirtDensityProbeCaller Caller,
|
||||
double X,double Y,double Z)
|
||||
{
|
||||
if(!OutStageTimings)return;
|
||||
const std::size_t CallerIndex=static_cast<std::size_t>(Caller);
|
||||
++OutStageTimings->SkirtDensityProbes;
|
||||
++OutStageTimings->SkirtDensityProbesByCaller[CallerIndex];
|
||||
const auto IsLatticeCoordinate=[](double Value)
|
||||
{
|
||||
const double QueryValue=static_cast<double>(static_cast<float>(Value));
|
||||
return std::isfinite(QueryValue)
|
||||
&&std::abs(QueryValue-std::round(QueryValue))<=1.0e-5;
|
||||
};
|
||||
if(!IsLatticeCoordinate(X)||!IsLatticeCoordinate(Y)
|
||||
||!IsLatticeCoordinate(Z))
|
||||
++OutStageTimings->SkirtDensityOffGridProbesByCaller[CallerIndex];
|
||||
};
|
||||
const auto QuerySkirtDensity=[&](EVoxelSkirtDensityProbeCaller Caller,
|
||||
double X,double Y,double Z)
|
||||
{
|
||||
CountSkirtDensityProbe(Caller,X,Y,Z);
|
||||
EPassageDensityQueryCaller QueryCaller=
|
||||
EPassageDensityQueryCaller::SkirtSurfaceVertex;
|
||||
switch(Caller)
|
||||
{
|
||||
case EVoxelSkirtDensityProbeCaller::SurfaceVertex:
|
||||
QueryCaller=EPassageDensityQueryCaller::SkirtSurfaceVertex;break;
|
||||
case EVoxelSkirtDensityProbeCaller::ExtrudedVertex:
|
||||
QueryCaller=EPassageDensityQueryCaller::SkirtExtrudedVertex;break;
|
||||
case EVoxelSkirtDensityProbeCaller::ClippedVertex:
|
||||
QueryCaller=EPassageDensityQueryCaller::SkirtClippedVertex;break;
|
||||
case EVoxelSkirtDensityProbeCaller::RefinementFace:
|
||||
QueryCaller=EPassageDensityQueryCaller::SkirtRefinementFace;break;
|
||||
case EVoxelSkirtDensityProbeCaller::CoarseCentroid:
|
||||
QueryCaller=EPassageDensityQueryCaller::SkirtCoarseCentroid;break;
|
||||
case EVoxelSkirtDensityProbeCaller::Count:break;
|
||||
}
|
||||
FStandaloneShapeWorld::FScopedPassageDensityQueryCaller queryCaller(QueryCaller);
|
||||
return ShapeWorldContext->DensityAt(X,Y,Z);
|
||||
};
|
||||
if(ShapeWorldContext)
|
||||
SurfaceVertexDensitySamples.assign(static_cast<size_t>(MeshData.Vertices.Num()),
|
||||
std::numeric_limits<float>::quiet_NaN());
|
||||
@@ -2468,16 +2519,20 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
if(!ShapeWorldContext)return 0.0f;
|
||||
if(OriginalIndex<0||static_cast<size_t>(OriginalIndex)>=SurfaceVertexDensitySamples.size())
|
||||
{
|
||||
CountSkirtDensityProbe();
|
||||
return ShapeWorldContext->DensityAt(Position.X/GeometryVoxelSize,
|
||||
Position.Y/GeometryVoxelSize,Position.Z/GeometryVoxelSize);
|
||||
const double X=Position.X/GeometryVoxelSize;
|
||||
const double Y=Position.Y/GeometryVoxelSize;
|
||||
const double Z=Position.Z/GeometryVoxelSize;
|
||||
return QuerySkirtDensity(EVoxelSkirtDensityProbeCaller::SurfaceVertex,
|
||||
X,Y,Z);
|
||||
}
|
||||
float& Density=SurfaceVertexDensitySamples[static_cast<size_t>(OriginalIndex)];
|
||||
if(std::isnan(Density))
|
||||
{
|
||||
CountSkirtDensityProbe();
|
||||
Density=ShapeWorldContext->DensityAt(Position.X/GeometryVoxelSize,
|
||||
Position.Y/GeometryVoxelSize,Position.Z/GeometryVoxelSize);
|
||||
const double X=Position.X/GeometryVoxelSize;
|
||||
const double Y=Position.Y/GeometryVoxelSize;
|
||||
const double Z=Position.Z/GeometryVoxelSize;
|
||||
Density=QuerySkirtDensity(EVoxelSkirtDensityProbeCaller::SurfaceVertex,
|
||||
X,Y,Z);
|
||||
}
|
||||
return Density;
|
||||
};
|
||||
@@ -2503,9 +2558,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
FSkirtVertex Vertex{Position,Normal,Color,0.0f,OriginalIndex};
|
||||
if(!bOnSurface&&ShapeWorldContext)
|
||||
{
|
||||
CountSkirtDensityProbe();
|
||||
Vertex.Density=ShapeWorldContext->DensityAt(Position.X/GeometryVoxelSize,
|
||||
Position.Y/GeometryVoxelSize,Position.Z/GeometryVoxelSize);
|
||||
const double X=Position.X/GeometryVoxelSize;
|
||||
const double Y=Position.Y/GeometryVoxelSize;
|
||||
const double Z=Position.Z/GeometryVoxelSize;
|
||||
Vertex.Density=QuerySkirtDensity(
|
||||
EVoxelSkirtDensityProbeCaller::ExtrudedVertex,X,Y,Z);
|
||||
}
|
||||
return Vertex;
|
||||
};
|
||||
@@ -2523,9 +2580,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
static_cast<uint8>(FMath::Clamp(FMath::RoundToInt(FMath::Lerp(static_cast<float>(A.Color.A),static_cast<float>(B.Color.A),T)),0,255)));
|
||||
if(ShapeWorldContext)
|
||||
{
|
||||
CountSkirtDensityProbe();
|
||||
Out.Density=ShapeWorldContext->DensityAt(Out.Position.X/GeometryVoxelSize,
|
||||
Out.Position.Y/GeometryVoxelSize,Out.Position.Z/GeometryVoxelSize);
|
||||
const double X=Out.Position.X/GeometryVoxelSize;
|
||||
const double Y=Out.Position.Y/GeometryVoxelSize;
|
||||
const double Z=Out.Position.Z/GeometryVoxelSize;
|
||||
Out.Density=QuerySkirtDensity(
|
||||
EVoxelSkirtDensityProbeCaller::ClippedVertex,X,Y,Z);
|
||||
}
|
||||
else Out.Density=FMath::Lerp(A.Density,B.Density,T);
|
||||
Out.OriginalIndex=INDEX_NONE;
|
||||
@@ -2586,9 +2645,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
const FVector Position=P0.Position*static_cast<float>(WA)
|
||||
+P1.Position*static_cast<float>(WB)
|
||||
+P2.Position*static_cast<float>(WC);
|
||||
CountSkirtDensityProbe();
|
||||
return ShapeWorldContext->DensityAt(Position.X/GeometryVoxelSize,
|
||||
Position.Y/GeometryVoxelSize,Position.Z/GeometryVoxelSize);
|
||||
const double X=Position.X/GeometryVoxelSize;
|
||||
const double Y=Position.Y/GeometryVoxelSize;
|
||||
const double Z=Position.Z/GeometryVoxelSize;
|
||||
return QuerySkirtDensity(
|
||||
EVoxelSkirtDensityProbeCaller::RefinementFace,X,Y,Z);
|
||||
};
|
||||
const auto VertexProbeDensity=[&](const FSkirtVertex& Vertex)
|
||||
{
|
||||
@@ -2636,8 +2697,8 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
{
|
||||
const FVector Center=(P0.Position+P1.Position+P2.Position)
|
||||
/(3.0f*GeometryVoxelSize);
|
||||
CountSkirtDensityProbe();
|
||||
if(ShapeWorldContext->DensityAt(Center.X,Center.Y,Center.Z)>0.0f)continue;
|
||||
if(QuerySkirtDensity(EVoxelSkirtDensityProbeCaller::CoarseCentroid,
|
||||
Center.X,Center.Y,Center.Z)>0.0f)continue;
|
||||
}
|
||||
Tris.Add(PolygonIndices[0]);Tris.Add(PolygonIndices[Fan]);Tris.Add(PolygonIndices[Fan+1]);
|
||||
Tris.Add(PolygonIndices[0]);Tris.Add(PolygonIndices[Fan+1]);Tris.Add(PolygonIndices[Fan]);
|
||||
|
||||
@@ -62,6 +62,16 @@ struct FVoxelGridFillExecution
|
||||
|
||||
// Optional, sampled timing output for the research audit; null in production calls.
|
||||
// Mesures echantillonnees facultatives pour l'audit; pointeur nul en production.
|
||||
enum class EVoxelSkirtDensityProbeCaller : std::size_t
|
||||
{
|
||||
SurfaceVertex,
|
||||
ExtrudedVertex,
|
||||
ClippedVertex,
|
||||
RefinementFace,
|
||||
CoarseCentroid,
|
||||
Count
|
||||
};
|
||||
|
||||
struct FVoxelMarchingCubesStageTimings
|
||||
{
|
||||
uint32 GridFillWorkerCount = 1;
|
||||
@@ -91,6 +101,10 @@ struct FVoxelMarchingCubesStageTimings
|
||||
uint64 SkirtEdgeCandidates = 0;
|
||||
uint64 SkirtBoundaryCandidates = 0;
|
||||
uint64 SkirtDensityProbes = 0;
|
||||
std::array<uint64,static_cast<std::size_t>(EVoxelSkirtDensityProbeCaller::Count)>
|
||||
SkirtDensityProbesByCaller{};
|
||||
std::array<uint64,static_cast<std::size_t>(EVoxelSkirtDensityProbeCaller::Count)>
|
||||
SkirtDensityOffGridProbesByCaller{};
|
||||
};
|
||||
|
||||
// Opt-in soundness audit for density blocks which the Core mesher would skip.
|
||||
|
||||
Reference in new issue
Block a user