- 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>
57 lines
2.2 KiB
Python
57 lines
2.2 KiB
Python
import os, sys, struct
|
|
sys.path.insert(0, r'C:\VWE\TeslaRel410\dpl3-revive\patha')
|
|
os.environ.setdefault('SDL_VIDEODRIVER', 'dummy')
|
|
import numpy as np
|
|
from vrboard import VirtualBoard, Msg, A
|
|
from vrview import Renderer
|
|
|
|
data = open(sys.argv[1], 'rb').read()
|
|
board = VirtualBoard()
|
|
off = 0
|
|
while off + 8 <= len(data):
|
|
if data[off:off + 4] != b'VPXM':
|
|
off += 1; continue
|
|
ln = struct.unpack_from('<I', data, off + 4)[0]
|
|
body = data[off + 8:off + 8 + ln]; off += 8 + ln
|
|
if len(body) >= 4:
|
|
a = struct.unpack_from('<I', body, 0)[0]
|
|
if a < 0x100:
|
|
try: board.handle(Msg(False, 0xff, a, body[4:]))
|
|
except Exception: pass
|
|
|
|
r = Renderer(w=832, h=512); c = r.cache; c.maybe_rebuild(board)
|
|
anim = board.anim_abs; chain = c.cam_chain
|
|
h = chain[-1] if (chain and chain[-1] in anim) else \
|
|
max(anim, key=lambda k: float(np.abs(np.array(anim[k][9:12])).sum()))
|
|
mech = np.array(anim[h][9:12])
|
|
print('MECH pos', mech.round(1))
|
|
if c.view and c.view in board.nodes:
|
|
vb = board.nodes[c.view]['body'] or b''
|
|
if len(vb) >= 96:
|
|
f = struct.unpack_from('<24f', vb, 0)
|
|
print('VIEW hither(near)=%.1f yon(far)=%.1f zeye=%.2f imageplane x[%.2f,%.2f] y[%.2f,%.2f]'
|
|
% (f[12], f[13], f[9], f[5], f[7], f[6], f[8]))
|
|
|
|
allpos = []
|
|
for inst in c.instances:
|
|
M = r.chain_matrix(board, inst['chain'])
|
|
for g in inst['geoms']:
|
|
mesh = c._mesh(board, g)
|
|
if not mesh or 'pos' not in mesh or len(mesh['pos']) == 0:
|
|
continue
|
|
pw = mesh['pos'] @ M[:3, :3] + M[3, :3]
|
|
allpos.append(pw)
|
|
allpos = np.concatenate(allpos)
|
|
print('ALL verts: %d Y[min=%.1f max=%.1f median=%.1f]'
|
|
% (len(allpos), allpos[:, 1].min(), allpos[:, 1].max(), np.median(allpos[:, 1])))
|
|
|
|
# geometry near the mech in the XZ plane (would be the ground under/around it)
|
|
d = np.sqrt((allpos[:, 0] - mech[0])**2 + (allpos[:, 2] - mech[2])**2)
|
|
for rad in (100, 300, 800, 2000):
|
|
near = allpos[d < rad]
|
|
if len(near):
|
|
print(' within %4d of mech: %6d verts Y[%.1f..%.1f] med %.1f'
|
|
% (rad, len(near), near[:, 1].min(), near[:, 1].max(), np.median(near[:, 1])))
|
|
else:
|
|
print(' within %4d of mech: 0 verts (NO geometry here)' % rad)
|