wip(assembler): M2 round 4 -- WorldAssemblerHybridV2: exact contacts, tagged tiles 1.18-1.27x MC
The round-3 'field contact error' measured hit-to-anchor distance; V2 contacts are 0 cm and on the zero isosurface. Tagged-tile cost 5.7-6.7x -> 1.175-1.270x MC; organic 0.998x. Bound, shelf-thickness and route audits rerun with negative controls; W1/W8/W16 stable; V1 and MarchingCubesV1 unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
22a6b30494
commit
4661a445be
48 files changed
+106493
-71
No files matched your search
@@ -1073,8 +1073,9 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
// Le DC reste limite aux surfaces LOD0 balisees; les patches connectes au bord restent MC.
|
||||
VoxelHybridSharpMesher::FResult HybridResult;
|
||||
MeshData.HybridFeatureCount = HybridSharpFeatures.Num();
|
||||
if (bUseHybridSharpMesher && Step == 1 && CellsPerAxis == CHUNK_SIZE
|
||||
&& CzLo == 0 && CzHi == CellsPerAxis - 1 && !HybridSharpFeatures.IsEmpty())
|
||||
const bool bHybridLod0Interior = Step == 1 && CellsPerAxis == CHUNK_SIZE
|
||||
&& CzLo == 0 && CzHi == CellsPerAxis - 1 && !HybridSharpFeatures.IsEmpty();
|
||||
if (bUseHybridSharpMesher && bHybridLod0Interior)
|
||||
{
|
||||
MeshData.bHybridMesherInvoked = true;
|
||||
HybridResult = VoxelHybridSharpMesher::Generate(
|
||||
@@ -1083,6 +1084,12 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
[&](int32 X, int32 Y, int32 Z) { return SampleG(X, Y, Z); },
|
||||
[&](int32 X, int32 Y, int32 Z) { return GradAt(X, Y, Z); });
|
||||
}
|
||||
const bool bHybridSharpSnap = bUseHybridSharpFeatureSnap && bHybridLod0Interior;
|
||||
const std::vector<VoxelHybridSharpMesher::FPreparedFeatureBox> PreparedSharpFeatures =
|
||||
bHybridSharpSnap
|
||||
? VoxelHybridSharpMesher::PrepareFeatureBoxes(HybridSharpFeatures)
|
||||
: std::vector<VoxelHybridSharpMesher::FPreparedFeatureBox>{};
|
||||
if (bHybridSharpSnap) MeshData.bHybridMesherInvoked = true;
|
||||
MeshData.HybridSharpCellCount = HybridResult.SharpCells;
|
||||
MeshData.HybridDualCellCount = HybridResult.DualCells;
|
||||
MeshData.HybridActiveEdgeRootCount = HybridResult.ActiveEdgeRoots;
|
||||
@@ -1182,6 +1189,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
? FPlatformTime::Cycles64() : 0;
|
||||
FVector EdgeVertices[12];
|
||||
FVector EdgeNormals[12];
|
||||
uint64 EdgeSplitKeys[12]{};
|
||||
for (int32 i = 0; i < 12; i++)
|
||||
{
|
||||
if (MCEdgeTable[CaseIndex] & (1 << i))
|
||||
@@ -1194,6 +1202,28 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
: FMath::Clamp((IsoLevel - D1) / (D2 - D1), 0.0f, 1.0f);
|
||||
EdgeVertices[i] = Positions[A] + T * (Positions[B] - Positions[A]);
|
||||
EdgeNormals[i] = Gradients[A] + T * (Gradients[B] - Gradients[A]);
|
||||
if (bHybridSharpSnap)
|
||||
{
|
||||
const int32 Axis = CornerOffsets[A].X != CornerOffsets[B].X ? 0
|
||||
: (CornerOffsets[A].Y != CornerOffsets[B].Y ? 1 : 2);
|
||||
const FIntVector LocalStart(cx + CornerOffsets[A].X,
|
||||
cy + CornerOffsets[A].Y, cz + CornerOffsets[A].Z);
|
||||
// Every cell incident to this lattice edge must be interior so all
|
||||
// copies of the shared root take the same exact or MC path.
|
||||
const bool bCanSnapEdge = bHybridSharpSnap
|
||||
&& LocalStart.X >= 2 && LocalStart.Y >= 2 && LocalStart.Z >= 2
|
||||
&& LocalStart.X <= CellsPerAxis - 2
|
||||
&& LocalStart.Y <= CellsPerAxis - 2
|
||||
&& LocalStart.Z <= CellsPerAxis - 2;
|
||||
FVector AnalyticNormal;
|
||||
if (bCanSnapEdge && VoxelHybridSharpMesher::TrySnapFeatureEdge(
|
||||
PreparedSharpFeatures, OriginVoxels, LocalStart, Axis,
|
||||
ChunkWorldPos, GeometryVoxelSize, EdgeVertices[i],
|
||||
AnalyticNormal, EdgeSplitKeys[i]))
|
||||
{
|
||||
EdgeNormals[i] = AnalyticNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bSampleCell)
|
||||
@@ -1216,9 +1246,12 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const int32 Idx0 = GetOrCreateVertex(EdgeVertices[E0], EdgeNormals[E0]);
|
||||
const int32 Idx1 = GetOrCreateVertex(EdgeVertices[E1], EdgeNormals[E1]);
|
||||
const int32 Idx2 = GetOrCreateVertex(EdgeVertices[E2], EdgeNormals[E2]);
|
||||
const int32 Idx0 = GetOrCreateVertex(
|
||||
EdgeVertices[E0], EdgeNormals[E0], EdgeSplitKeys[E0]);
|
||||
const int32 Idx1 = GetOrCreateVertex(
|
||||
EdgeVertices[E1], EdgeNormals[E1], EdgeSplitKeys[E1]);
|
||||
const int32 Idx2 = GetOrCreateVertex(
|
||||
EdgeVertices[E2], EdgeNormals[E2], EdgeSplitKeys[E2]);
|
||||
|
||||
// F17 — vote majoritaire (≥ 2 vertex sky-cap ⇒ triangle sky-cap).
|
||||
const int32 CapVotes = (int32)VertexClasses[Idx0]
|
||||
|
||||
Reference in new issue
Block a user