wip(assembler): M2 round 3 -- opt-in hybrid sharp mesher (WorldAssemblerHybridV1) in the Unreal Core route
Default MarchingCubesV1 unchanged (W1/W8/W16 = round-6 hashes). Hybrid DC only in LOD0 interior cells with tagged features; tile-border cells and LOD1+ stay MC. BuildHost: fixtures repeat exactly, cooked collision bounds = render bounds, same-LOD borders pass, sampled SurfaceWorld cliff bit-identical to MC. Open: tagged tiles cost 5.7-6.7x MC; corner-top field contact error 20 cm; 5 MC doorway LOD cases. 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
a3b7d2015e
commit
22a6b30494
21 files changed
+3009
-23
No files matched your search
@@ -8725,6 +8725,7 @@ void AVoxelWorld::HandleTileCollisionCookComplete(
|
||||
const int32 NumVertices = Pending->NumVertices;
|
||||
const int32 NumTriangles = Pending->NumTriangles;
|
||||
const int32 NumSkirtTriangles = Pending->NumSkirtTriangles;
|
||||
const bool bPooledComponent = Pending->bPooledComponent;
|
||||
const int32 PendingCooksAtSubmit = Pending->PendingCooksAtSubmit;
|
||||
const bool bUseAsyncCook = Pending->bUseAsyncCook;
|
||||
const bool bUseComplexAsSimpleCollision = Pending->bUseComplexAsSimpleCollision;
|
||||
@@ -8745,6 +8746,15 @@ void AVoxelWorld::HandleTileCollisionCookComplete(
|
||||
CollisionSuppressedAtCycles.Remove(Tile);
|
||||
if (URealtimeMeshComponent* Comp = TileComponents.FindRef(Tile))
|
||||
{
|
||||
// RMC caches local bounds on pooled components; rebinding after the async cook
|
||||
// invalidates that cache and rebuilds scene-query bounds from the installed mesh.
|
||||
// RMC met les bornes locales en cache sur les composants reutilises ; le rebranchement
|
||||
// apres la cuisson invalide ce cache et recalcule les bornes des traces.
|
||||
if (bPooledComponent && Comp->GetRealtimeMesh() == CompletedMesh)
|
||||
{
|
||||
Comp->SetRealtimeMesh(nullptr);
|
||||
Comp->SetRealtimeMesh(CompletedMesh);
|
||||
}
|
||||
Comp->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
|
||||
}
|
||||
CollisionReadyTiles.Add(Tile);
|
||||
@@ -11439,6 +11449,9 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
||||
|
||||
const VoxelForgeCore::TileKey CoreKey{{Tile.Coord.X, Tile.Coord.Y, Tile.Coord.Z}, Tile.Level};
|
||||
VoxelForgeCore::TileGenerationOptions Options;
|
||||
Options.mesherRecipe = CoreMesherRecipe == EVoxelForgeCoreMesherRecipe::WorldAssemblerHybridV1
|
||||
? VoxelForgeCore::MesherRecipe::worldAssemblerHybridV1
|
||||
: VoxelForgeCore::MesherRecipe::marchingCubesV1;
|
||||
Options.hashDensity = bCaptureHashes;
|
||||
std::string CoreError;
|
||||
std::optional<VoxelForgeCore::TileMesh> CoreMesh;
|
||||
@@ -12248,7 +12261,7 @@ bool AVoxelWorld::ApplyMeshToTile(FChunkResult& Result)
|
||||
MeshComp = AcquireTileComponent(
|
||||
bProfileApply ? &ComponentCreationSeconds : nullptr,
|
||||
bProfileApply ? &ComponentRegistrationSeconds : nullptr,
|
||||
bProfileApply ? &bComponentCreated : nullptr);
|
||||
&bComponentCreated);
|
||||
TileComponents.Add(Tile, MeshComp);
|
||||
}
|
||||
if (!IsValid(MeshComp))
|
||||
@@ -12263,6 +12276,7 @@ bool AVoxelWorld::ApplyMeshToTile(FChunkResult& Result)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const bool bWasPooledComponent = !bComponentAlreadyPresent && !bComponentCreated;
|
||||
const double ComponentSeconds = bProfileApply
|
||||
? FPlatformTime::ToSeconds64(FPlatformTime::Cycles64() - ComponentStartCycles)
|
||||
: 0.0;
|
||||
@@ -12407,6 +12421,7 @@ bool AVoxelWorld::ApplyMeshToTile(FChunkResult& Result)
|
||||
Pending.NumTriangles = Result.NumTriangles;
|
||||
Pending.NumSkirtTriangles = Result.NumSkirtTriangles;
|
||||
Pending.PendingCooksAtSubmit = PendingCollisionCooks.Num();
|
||||
Pending.bPooledComponent = bWasPooledComponent;
|
||||
Pending.bUseAsyncCook = CollisionConfig.bUseAsyncCook;
|
||||
Pending.bUseComplexAsSimpleCollision = CollisionConfig.bUseComplexAsSimpleCollision;
|
||||
Pending.bShouldFastCookMeshes = CollisionConfig.bShouldFastCookMeshes;
|
||||
@@ -13275,7 +13290,8 @@ FString AVoxelWorld::GetCurrentSeasonContentHash() const
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
if (AssemblyHash.IsEmpty())
|
||||
const bool bHybridMesher = CoreMesherRecipe == EVoxelForgeCoreMesherRecipe::WorldAssemblerHybridV1;
|
||||
if (AssemblyHash.IsEmpty() && !bHybridMesher)
|
||||
{
|
||||
return SeasonHash;
|
||||
}
|
||||
@@ -13295,8 +13311,15 @@ FString AVoxelWorld::GetCurrentSeasonContentHash() const
|
||||
}
|
||||
}
|
||||
}
|
||||
Payload += TEXT("|world_assembly=");
|
||||
Payload += AssemblyHash;
|
||||
if (!AssemblyHash.IsEmpty())
|
||||
{
|
||||
Payload += TEXT("|world_assembly=");
|
||||
Payload += AssemblyHash;
|
||||
}
|
||||
if (bHybridMesher)
|
||||
{
|
||||
Payload += TEXT("|core_mesher=WorldAssemblerHybridV1");
|
||||
}
|
||||
FTCHARToUTF8 Utf8Payload(*Payload);
|
||||
uint8 Digest[FSHA1::DigestSize];
|
||||
FSHA1::HashBuffer(Utf8Payload.Get(), Utf8Payload.Length(), Digest);
|
||||
|
||||
Reference in new issue
Block a user