@@ -26,7 +26,7 @@ static TAutoConsoleVariable<int32> CVDrawDebugLandscapeTraceFailures(
2626
2727static TAutoConsoleVariable<int32> CVMeshToLandscapeMaxTraceRetries (
2828 TEXT (" CARLA.MeshToLandscape.MaxTraceRetries" ),
29- 16 ,
29+ 8 ,
3030 TEXT(" Max parallel line trace retries." ));
3131
3232static TAutoConsoleVariable<int32> CVDrawDebugBoxes (
@@ -109,15 +109,15 @@ void UMeshToLandscapeUtil::FilterInvalidStaticMeshComponents(
109109 UE_LOG (
110110 LogCarla, Warning,
111111 TEXT (" Skipping static mesh asset %s due to invalid RenderData or invalid Nanite data." ),
112- *SM-> GetName ( ));
112+ *UKismetSystemLibrary::GetDisplayName (Component ));
113113 }
114114 }
115115 else
116116 {
117117 UE_LOG (
118118 LogCarla, Warning,
119119 TEXT (" Skipping static mesh asset %s due to missing static mesh data (GetStaticMesh returned nullptr)." ),
120- *SM-> GetName ( ));
120+ *UKismetSystemLibrary::GetDisplayName (Component ));
121121 }
122122 Components.RemoveAtSwap (i, EAllowShrinking::No);
123123 }
@@ -322,20 +322,29 @@ ALandscape* UMeshToLandscapeUtil::ConvertMeshesToLandscape(
322322
323323 int32 MaxRetries = CVMeshToLandscapeMaxTraceRetries.GetValueOnAnyThread ();
324324
325- auto LockedPhysObject = FPhysicsObjectExternalInterface::LockRead (
326- World-> GetPhysicsScene ()) ;
325+ constexpr auto RingSampleCount = 8U ;
326+ const double I2R = 2.0 * PI / ( double )RingSampleCount ;
327327
328- std::array<FVector2d, 8 > Ring ;
328+ double MaxOffsetRadius = CellSize. GetMin () * 0.5 ;
329329
330- constexpr double I2R = 2.0 * PI / (double )Ring.size ();
331- double MaxOffsetRadius = CellSize.GetMin () / 2.0 ;
332- for (size_t i = 0 ; i != Ring.size (); ++i)
330+ FVector2d OffsetRing[RingSampleCount];
331+ for (size_t i = 0 ; i != RingSampleCount; ++i)
333332 {
334333 FVector2d D;
335334 FMath::SinCos (&D.Y , &D.X , (double )i * I2R);
336- Ring [i] = D;
335+ OffsetRing [i] = D;
337336 }
338337
338+ FCollisionShape TestGeometry;
339+ TestGeometry.SetBox (
340+ FVector3f (
341+ CellSize.X ,
342+ CellSize.Y ,
343+ UE_M_TO_CM) * 2 .5F );
344+
345+ auto LockedPhysObject = FPhysicsObjectExternalInterface::LockRead (
346+ World->GetPhysicsScene ());
347+
339348 ParallelFor (HeightmapData.Num (), [&](int32 Index)
340349 {
341350 int32 Y = Index / HeightmapExtent.X ;
@@ -347,7 +356,7 @@ ALandscape* UMeshToLandscapeUtil::ConvertMeshesToLandscape(
347356 FVector3d Begin = Begin0;
348357 FVector3d End = End0;
349358 FHitResult Hit;
350- double HitZ = 0.0 ;
359+ double HitZ = Min. Z ;
351360
352361 FCollisionQueryParams CQParams = FCollisionQueryParams::DefaultQueryParam;
353362 CQParams.bTraceComplex = true ;
@@ -358,66 +367,82 @@ ALandscape* UMeshToLandscapeUtil::ConvertMeshesToLandscape(
358367
359368 FRandomStream PRNG (Index);
360369
361- bool Failed = false ;
370+ if (!World->ParallelSweepSingleByChannel (
371+ Hit,
372+ Begin,
373+ End,
374+ FQuat::Identity,
375+ ECollisionChannel::ECC_WorldStatic,
376+ TestGeometry,
377+ CQParams))
378+ {
379+ HeightmapData[Index] = 0 ;
380+ return ;
381+ }
382+
362383 int32 Retry = 0 ;
363- for (; Retry != MaxRetries; ++Retry)
384+ for (; Retry < MaxRetries; ++Retry) // Sometimes, LTSBC fails on geometry seams
364385 {
365- if (! World->ParallelLineTraceSingleByChannel (
386+ if (World->ParallelLineTraceSingleByChannel (
366387 Hit,
367388 Begin, End,
368389 ECollisionChannel::ECC_GameTraceChannel2,
369390 CQParams))
370391 {
371- int32 Index = PRNG.RandRange (0 , (int32)Ring.size () - 1 );
372- FVector3d Offset = FVector3d (Ring[Index], 0.0 );
392+ if (ComponentMap.Contains (Hit.GetComponent ())) // Done
393+ {
394+ HitZ = Hit.Location .Z ;
395+ break ;
396+ }
397+ CQParams.AddIgnoredComponent (Hit.GetComponent ());
398+ }
399+ else
400+ {
401+ int32 Index = PRNG.RandRange (0 , (int32)RingSampleCount - 1 );
402+ FVector3d Offset = FVector3d (OffsetRing[Index], 0.0 );
373403 Offset *= PRNG.FRandRange (0.0 , MaxOffsetRadius);
374404 Begin = Begin0 + Offset;
375405 End = End0 + Offset;
376- continue ;
377406 }
407+ }
378408
409+ if (Retry != MaxRetries)
410+ {
379411 UPrimitiveComponent* HitComponent = Hit.GetComponent ();
380- if (ComponentMap.Contains (HitComponent))
412+ FString TestName;
413+ double ZDisplacement = 0.0 ;
414+ for (auto & [Pattern, Displacement] : HitDisplacementMap)
381415 {
382- HitZ = Hit. Location . Z ;
383- FString TestName ;
384- double ZDisplacement = 0.0 ;
385- for ( auto & [ Pattern, Displacement] : HitDisplacementMap )
416+ if ( std::abs (Displacement) <= std::abs (ZDisplacement))
417+ continue ;
418+ TestName = UKismetSystemLibrary::GetDisplayName (HitComponent) ;
419+ if (TestName. MatchesWildcard ( Pattern) )
386420 {
387- if (std::abs (Displacement) <= std::abs (ZDisplacement))
388- continue ;
389- TestName = UKismetSystemLibrary::GetDisplayName (HitComponent);
390- if (TestName.MatchesWildcard (Pattern))
391- {
392- ZDisplacement = Displacement;
393- continue ;
394- }
395- TestName = UKismetSystemLibrary::GetDisplayName (HitComponent->GetOwner ());
396- if (TestName.MatchesWildcard (Pattern))
397- {
398- ZDisplacement = Displacement;
399- continue ;
400- }
421+ ZDisplacement = Displacement;
422+ continue ;
423+ }
424+ TestName = UKismetSystemLibrary::GetDisplayName (HitComponent->GetOwner ());
425+ if (TestName.MatchesWildcard (Pattern))
426+ {
427+ ZDisplacement = Displacement;
428+ continue ;
401429 }
402- HitZ += ZDisplacement;
403- break ;
404430 }
405- CQParams.AddIgnoredComponent (Hit.GetComponent ());
431+ HitZ += ZDisplacement;
432+ HitZ -= Min.Z ;
433+ HitZ *= UE_CM_TO_M;
434+ HitZ += 256.0 ;
435+ HitZ /= 512.0 ;
436+ HitZ = std::clamp (HitZ, 0.0 , 1.0 );
437+ HeightmapData[Index] = (uint16)std::lround (
438+ HitZ * TNumericLimits<uint16>::Max ());
406439 }
407-
408- HitZ -= Min.Z ;
409- HitZ *= UE_CM_TO_M;
410- HitZ += 256.0 ;
411- HitZ /= 512.0 ;
412- HitZ = std::clamp (HitZ, 0.0 , 1.0 );
413- HeightmapData[Index] = (uint16)std::lround (
414- HitZ * TNumericLimits<uint16>::Max ());
415-
416- if (Retry == MaxRetries)
440+ else
417441 {
418442 FailuresCS.Lock ();
419443 Failures.Add ({ Begin, End });
420444 FailuresCS.Unlock ();
445+ HeightmapData[Index] = 0 ;
421446 }
422447 }, EParallelForFlags::Unbalanced);
423448 LockedPhysObject.Release ();
0 commit comments