fix(site): slice the road too - the 2 m lid was a convex hull, not geometry

The road was never mis-modelled: a 279 m strip imports with ONE auto-generated convex hull, and a
convex hull's top is the strip's maximum height. A downward trace therefore landed at 366 cm - a flat
lid about 2 m above the visible road, which sits at roughly 152 cm there. That single fact explains
every failed sidewalk fix, the 'road above its own sidewalk' reading, and why the player always ended
up on Road_Hollywood.

Slicing the road the way the sidewalks already were fixes it, and the cross-section is now continuous:

  Terrain_DEM       154
  Sidewalk_North_07 158
  Road_Hollywood_07 158   (was 366)

Two changes had to land together: the road exported in slices, and the map stopped staging the single
Road_Hollywood asset - which still sat on top of the slices and won every trace until removed.

All 23 captures regenerated; the player and the car both stand on a continuous ground plane.
This commit is contained in:
zwitschi committed 2026-11-09 19:15:10 +01:00
1 parent 4132dc77e3
commit 1b4b46e957
131 files changed
+224 -160

No files matched your search

@@ -1053,12 +1053,15 @@ void AGigLineCharacter::Tick(float DeltaSeconds)
const FVector Base = GetActorLocation();
for (int32 Step = 0; Step < 14; ++Step)
{
const float X = Base.X + Step * 2000.0f - 1000.0f;
// Sweep ACROSS the street, not along it: the cross-section is where the
// sidewalk and road heights meet, and where they disagreed.
const float X = Base.X;
const float YOffset = (Step - 7) * 400.0f;
FHitResult Hit;
FCollisionQueryParams Q(TEXT("GigLineProfile"), false, this);
const bool bHit = GetWorld()->LineTraceSingleByChannel(Hit,
FVector(X, Base.Y, Base.Z + 2000.0f),
FVector(X, Base.Y, Base.Z - 4000.0f), ECC_WorldStatic, Q);
const FVector From(X, Base.Y + YOffset, Base.Z + 2000.0f);
const bool bHit = GetWorld()->LineTraceSingleByChannel(Hit, From,
From - FVector(0.f, 0.f, 4000.f), ECC_WorldStatic, Q);
FString MeshName = TEXT("none");
if (bHit)
{
@@ -1071,8 +1074,8 @@ void AGigLineCharacter::Tick(float DeltaSeconds)
}
}
}
UE_LOG(LogTemp, Warning, TEXT("GigLine profile x=%.0f z=%.0f mesh=%s"),
X, bHit ? Hit.ImpactPoint.Z : -9999.f, *MeshName);
UE_LOG(LogTemp, Warning, TEXT("GigLine profile y=%.0f z=%.0f mesh=%s"),
Base.Y + YOffset, bHit ? Hit.ImpactPoint.Z : -9999.f, *MeshName);
}
}
if (bProbeAndQuit && GetWorld())