gameplay: designated street crossing — zebra markings, corridor cut, up-facing street
- street_mesh.py: continental zebra markings (0.5 m bars, 0.5 m gaps, 3 m band) at all three signalised crossings, triangles not quads (FBX SDK refuses to triangulate the crown-twisted quads), stripes +6 cm above the DEM so they stay above the road surface; winding flipped so every street surface faces up (road/sidewalks/markings were 100% down-facing and invisible in engine once the terrain stopped covering them). - terrain_from_dem.py: cut a 10.7 m corridor around the Hollywood Blvd centreline so road, kerbs and sidewalks are not buried under the terrain; sidewalks themselves cover the transition band, walk-check stays at 0 holes. - Blender builders save with a writability guard + fatal failure: *.blend is LFS-lockable and checks out read-only; a failed save previously left downstream steps building from stale files. - ue_import_site.py: Crossing_Markings imports with no collision (paint on the road); ue_build_demo_map.py stages it and chmods the lockable .umap before saving (save_map silently returned False on read-only maps). - ue_build_review_map.py: demo-crossing camera moved to the real crossing (s=130.1 m -> UE -24291,-1340) and fixed the ensure_writable path (was missing the .umap suffix, so the chmod never fired).
This commit is contained in:
1 parent
985dfcbac7
commit
bc2e421d33
20 files changed
+133
-36
No files matched your search
@@ -53,6 +53,9 @@ def parse_args():
|
||||
ap.add_argument("--ymax", type=float, default=110.0)
|
||||
ap.add_argument("--osm", default=None,
|
||||
help="OSM extract; building outlines are cut out so rooftops never become terrain")
|
||||
ap.add_argument("--corridor", type=float, default=10.7,
|
||||
help="half-width in m of the Hollywood Blvd corridor to cut out so the "
|
||||
"street meshes (road, kerbs, sidewalks) are not buried under the terrain")
|
||||
return ap.parse_args(argv)
|
||||
|
||||
|
||||
@@ -110,6 +113,30 @@ def pts_flat(ring):
|
||||
return ring
|
||||
|
||||
|
||||
def centreline_polyline(osm_path):
|
||||
"""Hollywood Blvd centreline as a local-frame polyline (Highland -> Orange)."""
|
||||
nodes, ways = oc.load(osm_path)
|
||||
line, _, _, _, _ = oc.block_extent(
|
||||
nodes, ways, "Hollywood Boulevard", "North Orange Drive", "North Highland Avenue")
|
||||
utm = project_to_utm(line, find_proj())
|
||||
return [(e - ORIGIN_E, n - ORIGIN_N) for e, n in utm]
|
||||
|
||||
|
||||
def dist_to_polyline(x, y, pts):
|
||||
best = float("inf")
|
||||
for (ax, ay), (bx, by) in zip(pts, pts[1:]):
|
||||
dx, dy = bx - ax, by - ay
|
||||
l2 = dx * dx + dy * dy
|
||||
if l2 == 0.0:
|
||||
continue
|
||||
t = max(0.0, min(1.0, ((x - ax) * dx + (y - ay) * dy) / l2))
|
||||
px, py = ax + t * dx, ay + t * dy
|
||||
d = (x - px) ** 2 + (y - py) ** 2
|
||||
if d < best:
|
||||
best = d
|
||||
return best ** 0.5
|
||||
|
||||
|
||||
def inside(x, y, ring):
|
||||
"""Ray casting point-in-polygon."""
|
||||
hit = False
|
||||
@@ -146,9 +173,12 @@ def main():
|
||||
f"X {args.xmin}..{args.xmax}, Y {args.ymin}..{args.ymax}")
|
||||
|
||||
polys = []
|
||||
corridor = None
|
||||
if args.osm:
|
||||
polys = building_polygons(args.osm)
|
||||
print(f"masking {len(polys)} building footprints")
|
||||
corridor = centreline_polyline(args.osm)
|
||||
print(f"cutting {args.corridor} m corridor around the Hollywood Blvd centreline")
|
||||
|
||||
verts = []
|
||||
ok = []
|
||||
@@ -168,6 +198,10 @@ def main():
|
||||
verts.append((x, y, 0.0))
|
||||
ok.append(False)
|
||||
continue
|
||||
if corridor is not None and dist_to_polyline(x, y, corridor) <= args.corridor:
|
||||
verts.append((x, y, 0.0))
|
||||
ok.append(False)
|
||||
continue
|
||||
z = values[ri * width + ci]
|
||||
if nodata is not None and z == nodata:
|
||||
verts.append((x, y, 0.0))
|
||||
@@ -212,7 +246,14 @@ def main():
|
||||
|
||||
out = os.path.abspath(args.out)
|
||||
os.makedirs(os.path.dirname(out), exist_ok=True)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=out)
|
||||
# *.blend is LFS-lockable, so a fresh checkout marks it read-only. Make it
|
||||
# writable again or the save fails and downstream steps build from a stale
|
||||
# file — which is worse than failing here.
|
||||
if os.path.exists(out) and not os.access(out, os.W_OK):
|
||||
os.chmod(out, 0o644)
|
||||
result = bpy.ops.wm.save_as_mainfile(filepath=out)
|
||||
if result != {"FINISHED"}:
|
||||
raise RuntimeError(f"could not save {out}: {result}")
|
||||
print(f"saved {out}")
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user