Bridge: pre-movement camera, munga yaw fix, fogged background; net conf plasma

- fp_cam works before the first vehicle articulation (a freshly dropped
  mech sends no 0x1f until it moves; bailing out left the raw chain
  convention showing the inside of the mech at every drop)
- The FLYK stand-in +90-deg yaw correction no longer applies to munga
  content (it yawed the player's own mech -- and every animated model --
  90 degrees: "looking through the right shoulder")
- With fog on, the clear colour saturates to the fog colour (background
  at infinite distance); the pre-drop hold is FULLY black, as period
  pilots confirm
- net_full.conf: COM2 plasma passthrough + setenv plasma flag

Networked console session verified live: black hold at ready, flash +
fade on console launch, drop-bay doors present, own mech visible, and
the full death sequence captured on the wire (fade-to-black, escape-pod
interior via near-fog exemption, world reload, white flash, blue-violet
respawn fade = the blue swirly's home).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-08 19:15:04 -05:00
co-authored by Claude Fable 5
parent 817c3ad4a4
commit c5659b8d3e
4 changed files with 36 additions and 13 deletions
+12 -2
View File
@@ -827,7 +827,12 @@ class Renderer:
'fog': (500, 4000, 0.05, 0.1, 0.12)} 'fog': (500, 4000, 0.05, 0.1, 0.12)}
V = np.linalg.inv(self.cam_matrix(board)) V = np.linalg.inv(self.cam_matrix(board))
back = np.array(vp['back']) * 255 # fogged background: at infinite distance the clear must be the fog
# colour (pre-drop hold is FULLY black; flash covers the sky band)
if vp['fog_on'] and vp['fog'][1] > vp['fog'][0]:
back = np.array(vp['fog'][2:5]) * 255
else:
back = np.array(vp['back']) * 255
img = np.empty((H, W, 3), np.float32); img[:] = back img = np.empty((H, W, 3), np.float32); img[:] = back
zbuf = np.full((H, W), np.inf, np.float32) zbuf = np.full((H, W), np.inf, np.float32)
@@ -855,7 +860,12 @@ class Renderer:
if (NEARCULL and inst.get('gated') and not inst.get('hud') if (NEARCULL and inst.get('gated') and not inst.get('hud')
and np.linalg.norm(M[3, :3]) + inst.get('radius', 0) < 10.0): and np.linalg.norm(M[3, :3]) + inst.get('radius', 0) < 10.0):
continue continue
if inst['chain'] and inst['chain'][0] in board.anim: # FIX is the FLYK stand-in shark's +90-deg yaw correction (the
# replacement model was authored nose-along-+X). BT/munga models
# are authored correctly -- applying it yawed the player's own
# mech 90 degrees ("looking through the right shoulder").
if (not getattr(board, 'munga', False)
and inst['chain'] and inst['chain'][0] in board.anim):
M = FIX @ M M = FIX @ M
if inst['billboard']: if inst['billboard']:
# spherical billboard: keep scale + eye position, face the camera # spherical billboard: keep scale + eye position, face the camera
+8 -2
View File
@@ -429,7 +429,11 @@ class GLRenderer(vrview.Renderer):
ctx.viewport = (0, 0, W, H) ctx.viewport = (0, 0, W, H)
ctx.enable(mgl.DEPTH_TEST) ctx.enable(mgl.DEPTH_TEST)
ctx.disable(mgl.BLEND) ctx.disable(mgl.BLEND)
back = vp['back'] # With fog on, the background sits at infinite distance and must
# saturate to the FOG colour (the pod's pre-drop hold is FULLY black
# and the start flash covers the sky band too -- period-pilot
# confirmed); raw back_color left a clear blue stripe.
back = vp['fog'][2:5] if fog_on else vp['back']
fbo.clear(back[0], back[1], back[2], depth=1.0) fbo.clear(back[0], back[1], back[2], depth=1.0)
# frame-constant uniforms # frame-constant uniforms
@@ -473,7 +477,9 @@ class GLRenderer(vrview.Renderer):
if (vrview.NEARCULL and inst.get('gated') and not inst.get('hud') if (vrview.NEARCULL and inst.get('gated') and not inst.get('hud')
and np.linalg.norm(M[3, :3]) + inst.get('radius', 0) < 10.0): and np.linalg.norm(M[3, :3]) + inst.get('radius', 0) < 10.0):
continue continue
if inst['chain'] and inst['chain'][0] in board.anim: # FLYK-only +90 yaw stand-in correction (see vrview draw loop)
if (not getattr(board, 'munga', False)
and inst['chain'] and inst['chain'][0] in board.anim):
M = FIX @ M M = FIX @ M
if inst['billboard']: if inst['billboard']:
s = np.linalg.norm(M[0, :3]) s = np.linalg.norm(M[0, :3])
+2 -2
View File
@@ -40,7 +40,7 @@ blocksize=1024
prebuffer=60 prebuffer=60
[serial] [serial]
serial1=directserial realport:COM1 rxpollus:100 rxburst:16 serial1=directserial realport:COM1 rxpollus:100 rxburst:16
serial2=disabled serial2=directserial realport:COM2
[autoexec] [autoexec]
mount c "C:\VWE\TeslaRel410\ALPHA_1" mount c "C:\VWE\TeslaRel410\ALPHA_1"
mount d "C:\VWE\TeslaRel410\emulator\net-boot" mount d "C:\VWE\TeslaRel410\emulator\net-boot"
@@ -60,7 +60,7 @@ set BLASTER=A220 I5 D1 H5 P330 T6
set TEMP=c:\ set TEMP=c:\
set HEAPSIZE=15000000 set HEAPSIZE=15000000
set L4GAUGE=640x480x16 set L4GAUGE=640x480x16
call setenv.bat r f s g call setenv.bat r f s p
echo === launching game via NetNub (RIO + sound; no -egg; waits for console) === echo === launching game via NetNub (RIO + sound; no -egg; waits for console) ===
32rtm.exe -x 32rtm.exe -x
netnub -p -f btl4opt > nn.log netnub -p -f btl4opt > nn.log
+14 -7
View File
@@ -83,12 +83,17 @@ def fp_cam(board, cache):
h = chain[-1] h = chain[-1]
elif anim: elif anim:
h = max(anim, key=lambda k: float(np.abs(np.array(anim[k][9:12])).sum())) h = max(anim, key=lambda k: float(np.abs(np.array(anim[k][9:12])).sum()))
if h is None: # h may be None before the FIRST vehicle articulation arrives (a freshly
return None # dropped mech that hasn't moved sends no 0x1f yet -- both -egg and the
fp_cam.root = h # player vehicle root DCS (for the pick backchannel) # console flow). The CHAIN camera below works fine without it; bailing
f = anim[h] # out here left the raw default chain convention on screen, which put
R = np.array(f[:9]).reshape(3, 3) # the pre-movement view inside the mech's own geometry.
t = np.array(f[9:12]) R = t = None
if h is not None:
fp_cam.root = h # player vehicle root DCS (for the pick backchannel)
f = anim[h]
R = np.array(f[:9]).reshape(3, 3)
t = np.array(f[9:12])
worldup = np.array([0.0, 1.0, 0.0]) worldup = np.array([0.0, 1.0, 0.0])
eye = fwd = None eye = fwd = None
if os.environ.get('FP_CAM', 'chain') != 'vehicle': if os.environ.get('FP_CAM', 'chain') != 'vehicle':
@@ -97,11 +102,13 @@ def fp_cam(board, cache):
ec, fc = Mc[3, :3], Mc[2, :3] # eye row; look = +Z row here ec, fc = Mc[3, :3], Mc[2, :3] # eye row; look = +Z row here
n = np.linalg.norm(fc) n = np.linalg.norm(fc)
if (np.isfinite(ec).all() and n > 1e-6 and if (np.isfinite(ec).all() and n > 1e-6 and
np.linalg.norm(ec - t) < 100.0): # sane cockpit offset (t is None or np.linalg.norm(ec - t) < 100.0)):
eye = ec + worldup * UPOFF[0] eye = ec + worldup * UPOFF[0]
fwd = fc / n fwd = fc / n
except Exception: except Exception:
pass pass
if eye is None and R is None:
return None
if eye is None: if eye is None:
# vehicle-root fallback: -Z row rendered forward (user-verified); # vehicle-root fallback: -Z row rendered forward (user-verified);
# FP_FWD_SIGN flips it back if needed. # FP_FWD_SIGN flips it back if needed.