Files
tokyo-wangan-racing/tools/capture_defects.py
T
jesse c297b20aed Disable PA on/off ramps; restore mainline to pre-ramp state
Three iterations of the Daikoku PA ramps never read as a real
interchange. Measured why, rather than tuning further:

  * the entry and exit decks INTERSECTED -- 2547 sample pairs within
    30 studs horizontally at <12 studs dY, worst case 0.5 studs apart
    at dY=0.0. On screen that is the bowtie tangle of white rails.
  * both real Daikoku ramps turn the SAME way (clockwise; the guide
    video says "right, right"). This build mirrored them into each
    other.
  * the real arc wraps OUTSIDE the lot and forms its north/east
    boundary. This build cut across the apron interior.

Gated behind BUILD_PA_RAMPS=false rather than deleted -- the radius
was already correct (470 studs vs an OSM-measured mean of 469) and
the merge lands tangent at 0.1-0.2 deg divergence. Both worth keeping.

Also removed two leftovers that would have outlived the ramps:

  * rampOpen punched holes in the mainline's outer parapet, railing
    and kill wall for ramps that no longer exist -- a barrier gap with
    a drop behind it. Sealed via RAMP_EDGE_OPENINGS=false. Verified:
    Barrier/EdgeRail/KillWall = 1646 each = 823 samples x 2 edges,
    0 road samples without a guard within 90 studs.
  * gore zebra hatching painted 1024 bars + 64 boundary lines marking
    a junction that is not there. Sealed via RAMP_GORE_MARKINGS=false.

Verified after a cache-busting fresh rebuild (Studio's require() cache
otherwise serves the previous map and reports a false pass):
  parts 22628 -> 15988
  all ramp part classes = 0
  Road = 823 (unchanged), spawn pad + PASpawn intact
  clip probe TRUSTWORTHY (control +11/-0), CLIPPING=0

Research and rebuild spec kept for when this is revisited:
reference/ramps/BUILD_SPEC.md, INDEX.md (10 CC-licensed Commons
photos), docs/daikoku-reference-spec.md (OSM circle fits).
2026-08-03 21:15:25 -04:00

73 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Eyes-on shots at the two REPORTED defects (not generic beauty angles).
Targets:
A entry ramp start (-4122, 47, -7860) -- the 390-stud access gap
B exit ramp start (-4258, 47, -7836)
C mainline junction (-3700, 102, -7184) -- the dY -6.0 step
D ramp vs nearest building(-4419, 223, -6751)
"""
import shutil
import sys
import time
sys.path.insert(0, "/tmp")
import rbx # noqa: E402
OUT = "/home/jesse/roblox/tokyo-wangan-racing/tools/shots"
SHOTS = [
# name, camera pos, look-at
("D1_entry_ramp_start", (-4122 + 210, 47 + 120, -7860 + 210), (-4122, 47, -7860)),
("D2_entry_start_low", (-4122 + 70, 47 + 25, -7860 + 70), (-4122, 55, -7860)),
("D3_exit_ramp_start", (-4258 - 200, 47 + 110, -7836 + 200), (-4258, 47, -7836)),
("D4_junction_step", (-3700 + 190, 102 + 90, -7184 + 190), (-3700, 102, -7184)),
("D5_ramp_vs_building", (-4419 + 520, 223 + 180, -6751 + 520), (-4300, 120, -7100)),
("D6_corridor_along", (-4122, 47 + 260, -7860 + 480), (-4300, 110, -7200)),
]
CAM = """
local cam = workspace.CurrentCamera
cam.CameraType = Enum.CameraType.Scriptable
cam.FieldOfView = {fov}
cam.CFrame = CFrame.lookAt(Vector3.new({px},{py},{pz}), Vector3.new({tx},{ty},{tz}))
return "ok"
"""
def main():
made = []
for name, (px, py, pz), (tx, ty, tz) in SHOTS:
fov = 70 if "low" in name or "along" in name else 55
r = rbx.call(
"execute_luau",
{
"datamodel_type": "Edit",
"code": CAM.format(
fov=fov, px=px, py=py, pz=pz, tx=tx, ty=ty, tz=tz
),
},
wait=12,
timeout=300,
)
if isinstance(r, dict) and r.get("isError"):
print(f"{name}: CAM FAIL {str(r)[:120]}")
continue
time.sleep(1.5)
cap = rbx.call(
"screen_capture", {"capture_id": "ScreenCapture_1"}, wait=22, timeout=300
)
imgs = cap.get("images") if isinstance(cap, dict) else None
if not imgs:
print(f"{name}: CAPTURE FAIL {str(cap)[:140]}")
continue
dest = f"{OUT}/{name}.jpg"
shutil.copy(imgs[0], dest)
made.append(dest)
print(f"{name}: OK -> {dest}")
print(f"\nMADE {len(made)}")
if __name__ == "__main__":
main()