Combat: AUTHENTIC weapon groups -- streamed per-mech button bindings + the real fire chain (task #5)
The recovered system: fire channels = LBE4ControlsManager buttonGroups (0x40/0x45/0x46/0x47); default groups = the per-mech type-6 controls-map resource in BTL4.RES, installed by the T0 CreateStreamedMappings the port already called -- it needed only the TriggerState attribute (id 0x13 PINNED to the binary value; fireImpulse@0x31C is the binary's TriggerState) and an input feed. Keyboard/harness now push press/release edges into the button groups; the gBT*Trigger bypasses, per-type keyboard split and 1,0 pulse hack are retired -- weapons sharing a button fire TOGETHER (madcat Trigger = 4 weapons). Myomers @4b9550/@4b95b8 misattribution corrected (they are MechWeapon ConfigureMappables/ChooseButton). Verified 2-node: kill through the authentic chain (12 hits vs ~36 pre-groups). Config-mode session (regrouping UI) = the remaining stage, KB-scoped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
4554ea543a
commit
8ed6184d65
@@ -0,0 +1,68 @@
|
||||
import struct, math, numpy as np
|
||||
from PIL import Image
|
||||
data=open("content/VIDEO/GEO/BLX_COP.BGF","rb").read()
|
||||
verts=[]; uvs=[]; faces=[]
|
||||
cb=[0]
|
||||
def addpoly(idx,b):
|
||||
for k in range(1,len(idx)-1): faces.append((b+idx[0],b+idx[k],b+idx[k+1]))
|
||||
def parse(p,end):
|
||||
while p+3<=end:
|
||||
tw=struct.unpack_from("<H",data,p)[0]; p+=2
|
||||
cid=tw&0x2fff; lw=4 if(tw&0x8000)else(2 if(tw&0x4000)else 1)
|
||||
if p+lw>end:return
|
||||
ln=data[p] if lw==1 else(struct.unpack_from("<H",data,p)[0] if lw==2 else struct.unpack_from("<I",data,p)[0])
|
||||
p+=lw
|
||||
if p+ln>end:return
|
||||
if cid==0x88:
|
||||
cb[0]=len(verts)
|
||||
for i in range(ln//20):
|
||||
o=p+i*20; x,y,z=struct.unpack_from("<fff",data,o); u,v=struct.unpack_from("<ff",data,o+12)
|
||||
verts.append((x,y,z)); uvs.append((u,v))
|
||||
elif cid==0x47:
|
||||
n=ln//4; idx=[struct.unpack_from("<I",data,p+i*4)[0] for i in range(n)]
|
||||
for f in range(0,(n//3)*3,3): faces.append((cb[0]+idx[f],cb[0]+idx[f+1],cb[0]+idx[f+2]))
|
||||
elif cid==0x4d:
|
||||
if ln>=1:
|
||||
ppf=data[p]; n=(ln-1)//4
|
||||
idx=[struct.unpack_from("<I",data,p+1+i*4)[0] for i in range(n)]
|
||||
for f in range(0,(n//ppf)*ppf,ppf): addpoly([idx[f+j] for j in range(ppf)],cb[0])
|
||||
if cid in {0x3,0x70,0x40,0x41,0x42,0x46,0x48,0x10,0x20,0x30}: parse(p,p+ln)
|
||||
p+=ln
|
||||
if cid==0x5:break
|
||||
parse(8,len(data))
|
||||
V=np.array(verts); UV=np.array(uvs)
|
||||
# classify each face: all-3-verts UV=(0,0) -> class0 (RED), else class1 (GREEN)
|
||||
def cls(f):
|
||||
return 0 if all(abs(UV[i,0])<1e-4 and abs(UV[i,1])<1e-4 for i in f) else 1
|
||||
c0=sum(1 for f in faces if cls(f)==0); c1=len(faces)-c0
|
||||
print(f"faces total {len(faces)}: UV(0,0) faces={c0} non-zero-UV faces={c1}")
|
||||
# render both classes in distinct colors from a few eyepoints
|
||||
def render(eye,look,fov=95,W=380,H=290):
|
||||
eye=np.array(eye,float);fwd=np.array(look,float)-eye;fwd/=np.linalg.norm(fwd)
|
||||
up=np.array([0,1,0.]);right=np.cross(fwd,up);right/=np.linalg.norm(right);upv=np.cross(right,fwd)
|
||||
f=(H/2)/math.tan(math.radians(fov)/2);img=np.zeros((H,W,3));zb=np.full((H,W),1e18)
|
||||
for face in faces:
|
||||
col=[0.9,0.15,0.15] if cls(face)==0 else [0.15,0.9,0.15]
|
||||
tri=V[list(face)]
|
||||
cam=[(np.dot(pt-eye,right),np.dot(pt-eye,upv),np.dot(pt-eye,fwd)) for pt in tri]
|
||||
if any(cz<=0.03 for _,_,cz in cam):continue
|
||||
pts=[(W/2+f*cx/cz,H/2-f*cy/cz,cz) for cx,cy,cz in cam]
|
||||
xs=[p[0] for p in pts];ys=[p[1] for p in pts]
|
||||
mnx=max(int(min(xs)),0);mxx=min(int(max(xs))+1,W-1);mny=max(int(min(ys)),0);mxy=min(int(max(ys))+1,H-1)
|
||||
if mnx>=mxx or mny>=mxy:continue
|
||||
(x0,y0,z0),(x1,y1,z1),(x2,y2,z2)=pts
|
||||
den=((y1-y2)*(x0-x2)+(x2-x1)*(y0-y2))
|
||||
if abs(den)<1e-9:continue
|
||||
ys2,xs2=np.mgrid[mny:mxy+1,mnx:mxx+1];xf=xs2+.5;yf=ys2+.5
|
||||
l0=((y1-y2)*(xf-x2)+(x2-x1)*(yf-y2))/den;l1=((y2-y0)*(xf-x2)+(x0-x2)*(yf-y2))/den;l2=1-l0-l1
|
||||
m=(l0>=0)&(l1>=0)&(l2>=0)
|
||||
z=l0*z0+l1*z1+l2*z2
|
||||
yi=ys2[m];xi=xs2[m];zz=z[m];cl_=zz<zb[yi,xi]
|
||||
zb[yi[cl_],xi[cl_]]=zz[cl_];img[yi[cl_],xi[cl_]]=col
|
||||
return (np.clip(img,0,1)*255).astype(np.uint8)
|
||||
cen=V.mean(0)
|
||||
tiles=[render(cen.tolist(),(cen+[0,0,-30]).tolist()),
|
||||
render(cen.tolist(),(cen+[0,0,30]).tolist()),
|
||||
render((0,-0.3,0),(0,-0.3,-4))]
|
||||
Image.fromarray(np.concatenate(tiles,axis=1)).save("scratchpad/cop_split.png")
|
||||
print("saved cop_split.png [RED=UV(0,0) faces, GREEN=non-zero-UV faces]")
|
||||
Reference in New Issue
Block a user