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
@@ -52,7 +52,7 @@ namespace
|
||||
bool InstrumentTileDrain=false;
|
||||
bool ColdWorkerTimeline=false;
|
||||
bool Linux77Profile=false;
|
||||
bool ExactMidpointDensityMemo=false;
|
||||
bool ExactMidpointDensityMemo=true;
|
||||
bool ActiveLaneBatching=false;
|
||||
bool ParallelSignEdgeRepair=true;
|
||||
int ProofBlockCells=8;
|
||||
@@ -1459,6 +1459,7 @@ namespace
|
||||
" --linux77-profile (Linux-only SIGPROF stack and route census)\n"
|
||||
" --profile-passage-composer (emit per-tile passage work counters)\n"
|
||||
" --exact-midpoint-density-memo (exact-input midpoint query memo A/B)\n"
|
||||
" --no-exact-midpoint-density-memo (disable exact midpoint memo)\n"
|
||||
" --active-lane-batching --proof-block-cells=N (proof-masked density fill A/B)\n"
|
||||
" --parallel-sign-edge-repair --serial-sign-edge-repair\n"
|
||||
" --shape-helper-limit=8|12 (default 8; shape build A/B)\n"
|
||||
@@ -1526,6 +1527,7 @@ namespace
|
||||
else if(arg=="--profile-passage-composer")
|
||||
{options.ProfilePassageComposer=true;options.InstrumentTileDrain=true;}
|
||||
else if(arg=="--exact-midpoint-density-memo")options.ExactMidpointDensityMemo=true;
|
||||
else if(arg=="--no-exact-midpoint-density-memo")options.ExactMidpointDensityMemo=false;
|
||||
else if(arg=="--active-lane-batching")options.ActiveLaneBatching=true;
|
||||
else if(arg=="--parallel-sign-edge-repair")
|
||||
{options.ParallelSignEdgeRepair=true;}
|
||||
|
||||
@@ -2376,7 +2376,7 @@ namespace StandaloneStreamBenchmark
|
||||
bool bPrintTileHashes=false,bool bAuditLandmarkReachability=false,
|
||||
bool bAuditOreVeinYield=false,bool bAuditNativeCaves=false,
|
||||
bool bInstrumentTileDrain=false,bool bAuditMotifIntervals=false,
|
||||
bool bExactMidpointDensityMemo=false,
|
||||
bool bExactMidpointDensityMemo=true,
|
||||
bool bActiveLaneBatching=false,int32 ProofBlockCells=8,
|
||||
bool bParallelSignEdgeRepair=false,bool bAuditNativeLattice=false,
|
||||
bool bLatticeOrphanControl=false,bool bCaptureSkipWalkability=false,
|
||||
|
||||
@@ -1445,7 +1445,36 @@ private:
|
||||
const char* TileClassName=D.tileClass==VoxelForgeCore::TileClass::allAir?"air":
|
||||
D.tileClass==VoxelForgeCore::TileClass::allSolid?"solid":
|
||||
D.tileClass==VoxelForgeCore::TileClass::mixed?"mixed":"unknown";
|
||||
std::printf("[CpuTileStages] key=(%d,%d,%d,lod%d) worker_id=%d worker_ms=%.3f payload_ms=%.3f tile_classified=%d tile_class=%s tile_skip=%d density_point_calls=%llu density_float_points=%llu density_lattice_points=%llu density_unclamped_points=%llu density_x8_points=%llu field_eval_sample_ns=%llu field_eval_sample_points=%llu samples=%llu classify_ms=%.3f column_ms=%.3f column_exclusive_ms=%.3f mc_ms=%.3f mc_grid_ms=%.3f mc_grid_workers=%u mc_cell_ms=%.3f mc_gradient_ms=%.3f mc_interpolation_ms=%.3f mc_dedup_ms=%.3f mc_skirt_ms=%.3f mc_other_ms=%.3f connector_ms=%.3f ground_ms=%.3f cap_ms=%.3f horizon_ms=%.3f mesh_assembly_ms=%.3f candidate_cells=%llu classified_cells=%llu surface_cells=%llu proof_solid_cells=%llu proof_air_cells=%llu proof_density_samples=%llu zband_reject_cells=%llu x8_calls=%llu x8_active_lanes=%llu grad_calls=%llu grad_memo_hits=%llu grad_fallback_calls=%llu midpoint_attempts=%llu midpoint_memo_hits=%llu skirt_edges=%llu skirt_boundary_edges=%llu skirt_density_probes=%llu skirt_triangles=%u fi_local_hit=%llu fi_local_miss=%llu fi_local_conflicts=%llu fi_shared_hit=%llu fi_shared_miss=%llu fi_shared_computes=%llu fi_shared_conflicts=%llu fi_lock_wait_us=%.3f\n",
|
||||
const auto FormatCallerCounts=[](const auto& Values)
|
||||
{
|
||||
std::ostringstream Text;
|
||||
for(std::size_t Index=0;Index<Values.size();++Index)
|
||||
{
|
||||
if(Index)Text<<',';
|
||||
Text<<Values[Index];
|
||||
}
|
||||
return Text.str();
|
||||
};
|
||||
const std::string PassageSweepMissing=FormatCallerCounts(
|
||||
D.passageSweepMissingLookupsByCaller);
|
||||
const std::string PassageSweepFallbacks=FormatCallerCounts(
|
||||
D.passageSweepExactRouteFallbacksByCaller);
|
||||
const std::string PassageSweepBoundSkips=FormatCallerCounts(
|
||||
D.passageSweepFeatureBoundSkipsByCaller);
|
||||
const std::string PassageSweepTileFreeSkips=FormatCallerCounts(
|
||||
D.passageSweepTileFreeSkipsByCaller);
|
||||
const std::string PassageSweepVerticalBoundSkips=FormatCallerCounts(
|
||||
D.passageSweepVerticalBoundSkipsByCaller);
|
||||
const std::string PassageSweepNegativeReachSkips=FormatCallerCounts(
|
||||
D.passageSweepNegativeReachSkipsByCaller);
|
||||
const std::string PassageSweepPositiveReachSkips=FormatCallerCounts(
|
||||
D.passageSweepPositiveReachSkipsByCaller);
|
||||
const std::string DensityOffGridFloat=FormatCallerCounts(D.densityOffGridFloatByCaller);
|
||||
const std::string DensityOffGridUnclamped=FormatCallerCounts(
|
||||
D.densityOffGridUnclampedByCaller);
|
||||
const std::string DensityOffGridDetail=FormatCallerCounts(
|
||||
D.densityOffGridDetailByCaller);
|
||||
std::printf("[CpuTileStages] key=(%d,%d,%d,lod%d) worker_id=%d worker_ms=%.3f payload_ms=%.3f tile_classified=%d tile_class=%s tile_skip=%d density_point_calls=%llu density_float_points=%llu density_lattice_points=%llu density_unclamped_points=%llu density_x8_points=%llu field_eval_sample_ns=%llu field_eval_sample_points=%llu samples=%llu classify_ms=%.3f column_ms=%.3f column_exclusive_ms=%.3f mc_ms=%.3f mc_grid_ms=%.3f mc_grid_workers=%u mc_cell_ms=%.3f mc_gradient_ms=%.3f mc_interpolation_ms=%.3f mc_dedup_ms=%.3f mc_skirt_ms=%.3f mc_other_ms=%.3f connector_ms=%.3f ground_ms=%.3f cap_ms=%.3f horizon_ms=%.3f mesh_assembly_ms=%.3f candidate_cells=%llu classified_cells=%llu surface_cells=%llu proof_solid_cells=%llu proof_air_cells=%llu proof_density_samples=%llu zband_reject_cells=%llu x8_calls=%llu x8_active_lanes=%llu grad_calls=%llu grad_memo_hits=%llu grad_fallback_calls=%llu midpoint_attempts=%llu midpoint_memo_hits=%llu skirt_edges=%llu skirt_boundary_edges=%llu skirt_density_probes=%llu skirt_surface_vertex=%llu skirt_surface_vertex_offgrid=%llu skirt_extruded_vertex=%llu skirt_extruded_vertex_offgrid=%llu skirt_clipped_vertex=%llu skirt_clipped_vertex_offgrid=%llu skirt_refinement_face=%llu skirt_refinement_face_offgrid=%llu skirt_coarse_centroid=%llu skirt_coarse_centroid_offgrid=%llu sweep_missing_by_caller=%s sweep_exact_fallback_by_caller=%s sweep_bound_skip_by_caller=%s sweep_tile_free_skip_by_caller=%s sweep_vertical_bound_skip_by_caller=%s sweep_negative_reach_skip_by_caller=%s sweep_positive_reach_skip_by_caller=%s density_offgrid_float_by_caller=%s density_offgrid_unclamped_by_caller=%s density_offgrid_detail_by_caller=%s skirt_triangles=%u fi_local_hit=%llu fi_local_miss=%llu fi_local_conflicts=%llu fi_shared_hit=%llu fi_shared_miss=%llu fi_shared_computes=%llu fi_shared_conflicts=%llu fi_lock_wait_us=%.3f\n",
|
||||
Event.Key.Coord.X,Event.Key.Coord.Y,Event.Key.Coord.Z,Event.Key.Level,
|
||||
Event.WorkerId,Event.WorkerMilliseconds,Event.PayloadBuildMilliseconds,
|
||||
D.tileWasClassified?1:0,TileClassName,D.meshingSkipped?1:0,
|
||||
@@ -1483,6 +1512,22 @@ private:
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtEdgeCandidates),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtBoundaryCandidates),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityProbes),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityProbesByCaller[0]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityOffGridProbesByCaller[0]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityProbesByCaller[1]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityOffGridProbesByCaller[1]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityProbesByCaller[2]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityOffGridProbesByCaller[2]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityProbesByCaller[3]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityOffGridProbesByCaller[3]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityProbesByCaller[4]),
|
||||
static_cast<unsigned long long>(D.marchingCubesSkirtDensityOffGridProbesByCaller[4]),
|
||||
PassageSweepMissing.c_str(),PassageSweepFallbacks.c_str(),
|
||||
PassageSweepBoundSkips.c_str(),
|
||||
PassageSweepTileFreeSkips.c_str(),PassageSweepVerticalBoundSkips.c_str(),
|
||||
PassageSweepNegativeReachSkips.c_str(),PassageSweepPositiveReachSkips.c_str(),
|
||||
DensityOffGridFloat.c_str(),DensityOffGridUnclamped.c_str(),
|
||||
DensityOffGridDetail.c_str(),
|
||||
Event.SkirtTriangles,
|
||||
static_cast<unsigned long long>(D.islandLocalCacheHits),
|
||||
static_cast<unsigned long long>(D.islandLocalCacheMisses),
|
||||
@@ -1584,7 +1629,7 @@ private:
|
||||
bool bInstrumentTileDrain=false;
|
||||
bool bLinux77Profile=false;
|
||||
bool bProfilePassageComposer=false;
|
||||
bool bExactMidpointDensityMemo=false;
|
||||
bool bExactMidpointDensityMemo=true;
|
||||
bool bActiveLaneBatching=false;
|
||||
int32 ProofBlockCells=8;
|
||||
bool bAuditUniformBlockProofs=false;
|
||||
|
||||
@@ -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