tools: viewport capture + cache-bust rebuild harness
screen_capture DOES work via the bridge (capture_id='ScreenCapture_1'); the prior assumption that the Studio viewport couldn't be captured from this box was wrong. capture_shots.py sets the Edit camera per shot and pulls a jpg for each angle. rebuild_cachebust.luau documents the require() cache trap: pushing new .Source does not invalidate the per-instance module cache, so a rebuild silently runs the OLD code and the diagnostic reports already-fixed failures. Swapping in Clone()s at the same paths forces a fresh compile.
This commit is contained in:
@@ -15,3 +15,4 @@ wally.lock
|
||||
.DS_Store
|
||||
*.log
|
||||
audio-work/
|
||||
tools/shots/
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Capture a set of Studio viewport angles of the Daikoku PA junction.
|
||||
|
||||
Sets the Edit-mode camera via execute_luau, then pulls a screen_capture for
|
||||
each shot. Bridge calls are slow (~30-60s each), so this runs as one batch.
|
||||
|
||||
NOTE (corrects an old assumption): screen_capture DOES work on this setup.
|
||||
It needs capture_id='ScreenCapture_1'. Earlier notes claimed the Studio
|
||||
viewport could not be screenshotted from wks-victus -- that was wrong.
|
||||
"""
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, "/tmp")
|
||||
import rbx # noqa: E402
|
||||
|
||||
OUT = "/home/jesse/roblox/tokyo-wangan-racing/tools/shots"
|
||||
|
||||
# PA centre measured from the built parts.
|
||||
CX, CY, CZ = -4116, 51, -7479
|
||||
|
||||
SHOTS = [
|
||||
# name, camera offset from PA centre, look-at offset
|
||||
("01_overview_oblique", (520, 340, 520), (0, 0, 0)),
|
||||
("02_top_down", (5, 900, 5), (0, 0, 0)),
|
||||
("03_underneath_clearance", (330, 20, 300), (0, 30, 0)),
|
||||
("04_onramp_low", (-250, 70, 60), (60, 20, -40)),
|
||||
("05_offramp_low", (300, 75, -160), (-60, 20, 40)),
|
||||
("06_section_side", (900, 120, 40), (0, 25, 0)),
|
||||
]
|
||||
|
||||
CAM_TPL = """
|
||||
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 "cam ok"
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
made = []
|
||||
for name, (ox, oy, oz), (tx, ty, tz) in SHOTS:
|
||||
fov = 55 if "top_down" not in name else 40
|
||||
code = CAM_TPL.format(
|
||||
fov=fov,
|
||||
px=CX + ox,
|
||||
py=CY + oy,
|
||||
pz=CZ + oz,
|
||||
tx=CX + tx,
|
||||
ty=CY + ty,
|
||||
tz=CZ + tz,
|
||||
)
|
||||
r = rbx.call("execute_luau", {"datamodel_type": "Edit", "code": code})
|
||||
if isinstance(r, dict) and r.get("isError"):
|
||||
print(f"{name}: CAM FAIL {r}")
|
||||
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)[:160]}")
|
||||
continue
|
||||
dest = f"{OUT}/{name}.jpg"
|
||||
shutil.copy(imgs[0], dest)
|
||||
made.append(dest)
|
||||
print(f"{name}: OK -> {dest}")
|
||||
print("\nMADE " + str(len(made)) + " shots")
|
||||
for m in made:
|
||||
print(m)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user