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
|
.DS_Store
|
||||||
*.log
|
*.log
|
||||||
audio-work/
|
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