- emulator/render-bridge/: the pod->Dave's-renderer live bridge (rescued from session scratchpad): live_bridge.py (first-person cam from the 0x1f pose, arrow-key eye-height trim), fp/chase offline renders, fifobridge, diagnostics, gauge_arena[_sound].conf, and launch_pod.ps1 (one-command pod+bridge restart: pentapus VPX_EXPLODE + AWE32 sound + GL bridge). - _backend.py: renderer selection -- vrview_gl.GLRenderer (moderngl) by default, VRVIEW_SOFT=1 for the software reference; backend-agnostic frame save via last_frame. - GPU backend runs on side-by-side CPython 3.13 (moderngl/glcontext cp313 wheels; no MSVC needed): 63fps headless / 60.7 windowed vs 21fps software on the same scene, and the GL path also draws the vertex-alpha cloud dome. - vrview.py: VRVIEW_GAMMA env selects DAC gamma (1.25 live-renderer legacy vs 1.7 per the original GAMMA.C) for A/B against the real pod. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Show OUR BTL4OPT arena (decoded by the friend's board from a captured wire
|
|
stream) in a real on-screen window, orbiting a synthetic camera around it.
|
|
Decode once, then orbit forever; close the window to stop."""
|
|
import os, sys, struct, math
|
|
sys.path.insert(0, r'C:\VWE\TeslaRel410\dpl3-revive\patha')
|
|
# real window (no SDL dummy)
|
|
import numpy as np
|
|
from vrboard import VirtualBoard, Assembler
|
|
from decode_anim import find_framed_start
|
|
from vrview import Renderer
|
|
|
|
cap = sys.argv[1] if len(sys.argv) > 1 else r'C:\VWE\TeslaRel410\dpl3-revive\patha\bt8.raw.bin'
|
|
upto = int(sys.argv[2]) if len(sys.argv) > 2 else 800
|
|
W, H = 720, 450
|
|
|
|
data = open(cap, 'rb').read()
|
|
board = VirtualBoard()
|
|
asm = Assembler(); asm.feed(data[find_framed_start(data):])
|
|
for m in asm:
|
|
try: board.handle(m)
|
|
except Exception: pass
|
|
if board.frames >= upto: break
|
|
print(f'decoded: nodes={len(board.nodes)} frames={board.frames}')
|
|
|
|
W, H = 560, 350
|
|
r = Renderer(w=W, h=H, title='VWE pod - Division render (dpl3-revive) - our BTL4OPT arena')
|
|
r.cache.maybe_rebuild(board)
|
|
c = r.cache
|
|
|
|
# aim at the mechs (anim_abs vehicle positions); ignore ones still at origin
|
|
mechs = np.array([np.array(f[9:12]) for f in board.anim_abs.values()])
|
|
real = mechs[np.abs(mechs).sum(1) > 1.0]
|
|
center = real.mean(0) if len(real) else np.zeros(3)
|
|
radius = 480.0 # close orbit around the mech/dome cluster
|
|
print(f'mechs={mechs.round(0).tolist()} target={center.round(1)} radius={radius}')
|
|
|
|
# lift the far clip so the whole arena renders (yon = view float idx 13, off 52)
|
|
if c.view is not None and c.view in board.nodes:
|
|
vb = bytearray(board.nodes[c.view].get('body') or b'')
|
|
if len(vb) >= 56:
|
|
struct.pack_into('<f', vb, 52, 1.0e6)
|
|
board.nodes[c.view]['body'] = bytes(vb)
|
|
|
|
def cam_at(angle_deg):
|
|
a = math.radians(angle_deg)
|
|
dist = radius * 2.2
|
|
# y-down world: negative y = up, so raise the eye with -height
|
|
eye = center + np.array([math.sin(a) * dist, -radius * 0.7, math.cos(a) * dist])
|
|
fwd = center - eye; fwd /= max(np.linalg.norm(fwd), 1e-6)
|
|
back = -fwd
|
|
right = np.cross([0.0, -1.0, 0.0], back); right /= max(np.linalg.norm(right), 1e-6)
|
|
up = np.cross(back, right)
|
|
M = np.eye(4)
|
|
M[0, :3], M[1, :3], M[2, :3], M[3, :3] = right, up, back, eye
|
|
return M
|
|
|
|
r.fps = 60
|
|
ang = 0.0
|
|
print('orbiting; close the window to stop')
|
|
try:
|
|
while True:
|
|
M = cam_at(ang)
|
|
r.cam_matrix = lambda _b, _M=M: _M
|
|
r.draw(board) # renders + paces
|
|
ang = (ang + 2.0) % 360.0
|
|
except KeyboardInterrupt:
|
|
print('window closed')
|