Weapon visuals + aim: beams render from the guns; pick self-target fixes
Renderer (dpl3-revive/patha): - Instance visibility honored at DRAW time (stored word 4 = live dpl_SetInstanceVisibility field): laser beams (4-frame pulses) and missile models now render; cache tags w3 0/1 instances 'gated' - PSFX world bursts (dcs=0 muzzle/impact/explosion) rendered; psfx storage list-based so one-shot bursts stop collapsing onto one key - fix_degenerate applied to INSTANCE chains (was camera-only): the beam chain rides four rank-2 rig DCSs; composed rank-2 drew beams away from the guns. Offline f1635 now shows both arm beams converging on the aim point - First-person canopy cull: the always-armed cockpit model at the head drew as a vertical line down screen center (user-confirmed fixed live) Device (vpx-device/vpxlog.cpp): - CAM backchannel on the fifosock: bridge streams its validated camera (+ vehicle root DCS); raycast_pick aims along the player's real look instead of the static view-node pose, which had locked every missile/beam onto one fixed wrong world point - raycast_pick skips hidden-until-armed instances and the player's own articulation subtree: picking own beams created a target feedback loop, picking own missiles retargeted salvos mid-flight, and a picked missile's deleted DCS froze the game (arena2 crash) Sound (vpx-device/vweawe.cpp): stereo-linked peak limiter replaces the hard output clamp (the "generator out" crackle); VWE_AWE_LOG reports pre-limit peaks + duck counts, enabled in launch_pod.ps1. Missile-fire crackle persists: per-voice EMU8000 clamp suspected. Eggs/confs: TESTAR2.EGG + gauge_arena2_sound.conf (map=arena2 city variant); cavern.egg (console-era reference); plasma display on COM2 in the gauge confs; gauge_arena_net_sound.conf (slirp net stack). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -463,8 +463,16 @@ class GLRenderer(vrview.Renderer):
|
||||
FIX[:3, :3] = [[0, 0, -1], [0, 1, 0], [1, 0, 0]]
|
||||
|
||||
for inst in c.instances:
|
||||
Mw = self.chain_matrix(board, inst['chain'])
|
||||
if not vrview.inst_visible(board.nodes, inst):
|
||||
continue
|
||||
# fix_degenerate: see vrview draw loop (rank-2 rig DCSs skewed
|
||||
# the laser beam off the gun)
|
||||
Mw = self.chain_matrix(board, inst['chain'], fix_degenerate=True)
|
||||
M = Mw if inst.get('hud') else Mw @ V
|
||||
# first-person canopy cull (see SceneCache radius note in vrview)
|
||||
if (inst.get('gated') and not inst.get('hud')
|
||||
and np.linalg.norm(M[3, :3]) + inst.get('radius', 0) < 10.0):
|
||||
continue
|
||||
if inst['chain'] and inst['chain'][0] in board.anim:
|
||||
M = FIX @ M
|
||||
if inst['billboard']:
|
||||
@@ -488,6 +496,7 @@ class GLRenderer(vrview.Renderer):
|
||||
self._draw_geom(board, c, gh, mesh, M, Mw)
|
||||
|
||||
self._draw_particles(board, V, vp, self.skip / 60.0)
|
||||
self._draw_psfx(board, V)
|
||||
self._draw_hud2d_gl(board, vp)
|
||||
|
||||
# present: FBO -> window with the DAC gamma
|
||||
@@ -686,3 +695,82 @@ class GLRenderer(vrview.Renderer):
|
||||
self._points_vao(data).render(mgl.POINTS, vertices=len(data))
|
||||
self._fbo.depth_mask = True
|
||||
ctx.disable(mgl.BLEND)
|
||||
|
||||
def _draw_psfx(self, board, V):
|
||||
"""Triggered PSFX (0x1d) as glowing additive discs, two kinds:
|
||||
|
||||
- DCS-attached bolts (weapon fire): the emitter rides the flying
|
||||
projectile DCS, so the glow tracks the shot. We keep a short trail of
|
||||
recent world positions and draw a fading tail, so the continuous
|
||||
particle stream (rate ~300/s) reads as a streak, not a lone dot. The
|
||||
bolt lives until the projectile DCS is deleted (impact).
|
||||
- DCS=0 world bursts (muzzle flash, impact spark, explosion): a fixed
|
||||
world-space burst at (px,py,pz); big-radius explosions expand and the
|
||||
colour lerps from the start interior toward the end interior over the
|
||||
burst's ttl, then it fades out."""
|
||||
if not board.psfx:
|
||||
return
|
||||
cache = {}
|
||||
rows, live = [], []
|
||||
for e in board.psfx:
|
||||
dcs = e['dcs']
|
||||
if dcs:
|
||||
nd = board.nodes.get(dcs)
|
||||
if not nd or nd.get('type') != 5:
|
||||
continue # projectile consumed (impact)
|
||||
m = cache.get(dcs)
|
||||
if m is None:
|
||||
try:
|
||||
m = self.chain_matrix(board, self._chain(board, dcs, links=True))
|
||||
except Exception:
|
||||
m = self.dcs_matrix(board, dcs)
|
||||
cache[dcs] = m
|
||||
pos = np.asarray(m[3, :3], float)
|
||||
else:
|
||||
e['ttl'] -= 1
|
||||
if e['ttl'] <= 0:
|
||||
continue
|
||||
pos = np.asarray(e['pos'], float)
|
||||
if not np.all(np.isfinite(pos)):
|
||||
continue
|
||||
e['age'] += 1
|
||||
live.append(e)
|
||||
frac = e['age'] / max(e['maxttl'], 1) # 0..1 over life
|
||||
col = np.clip((1.0 - frac) * np.array(e['col'])
|
||||
+ frac * np.array(e['ecol']), 0.0, 2.0)
|
||||
a0 = min(e['alpha'], 1.0)
|
||||
if dcs: # bolt + trail
|
||||
tr = e.setdefault('trail', [])
|
||||
tr.append(pos)
|
||||
if len(tr) > 9:
|
||||
del tr[0]
|
||||
nt = len(tr)
|
||||
for k, tp in enumerate(tr):
|
||||
w = (k + 1) / nt # head brightest
|
||||
rows.append([tp[0], tp[1], tp[2],
|
||||
max(e['rad'] * (0.35 + 0.65 * w), 1.2),
|
||||
col[0], col[1], col[2], a0 * w * w])
|
||||
else: # world burst
|
||||
grow = 1.0 + min(e['exp'], 12.0) * 0.09 * frac # explosions swell
|
||||
fade = min(1.0, e['ttl'] / 10.0)
|
||||
rows.append([pos[0], pos[1], pos[2], max(e['rad'] * grow, 1.5),
|
||||
col[0], col[1], col[2], a0 * fade])
|
||||
board.psfx = live
|
||||
if not rows:
|
||||
return
|
||||
data = np.array(rows, '<f4')
|
||||
# back-to-front for the order-dependent additive-over blend
|
||||
pe_z = data[:, 0:3] @ V[:3, :3] + V[3, :3]
|
||||
data = data[np.argsort(pe_z[:, 2])]
|
||||
ctx, mgl = self.ctx, self.moderngl
|
||||
prog = self._point_prog
|
||||
self._mat(prog, 'u_mv', V)
|
||||
self._set(prog, 'u_minpr', 0.6)
|
||||
self._set(prog, 'u_maxpr', float(self.h * 0.22))
|
||||
self._set(prog, 'u_particle', 1)
|
||||
ctx.enable(mgl.BLEND)
|
||||
ctx.blend_func = (mgl.ONE, mgl.ONE_MINUS_SRC_ALPHA)
|
||||
self._fbo.depth_mask = False
|
||||
self._points_vao(data).render(mgl.POINTS, vertices=len(data))
|
||||
self._fbo.depth_mask = True
|
||||
ctx.disable(mgl.BLEND)
|
||||
|
||||
Reference in New Issue
Block a user