nmarshall commited on
Commit
9fde578
·
1 Parent(s): 96b1c5f

qvm: packed leaf vertices

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -712,3 +712,6 @@ Research progress: RE-678 [report](research/QVM_BASIC_TRAJECTORY.md); remaining
712
 
713
 
714
  Research progress: RE-679 [report](research/QVM_GRENADE_EVENT_PREFIX.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
712
 
713
 
714
  Research progress: RE-679 [report](research/QVM_GRENADE_EVENT_PREFIX.md); remaining native/content/runtime/platform scope stays open.
715
+
716
+
717
+ Research progress: RE-681 [report](research/QVM_LEAF_VERTICES.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -1058,3 +1058,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
1058
 
1059
 
1060
  **RE-679 — Constructed grenade through trajectory and event prelude:** Actual queried/allocated grenade enters223156, evaluates source trajectory, truncates/rebases origin and emits event55 through actual direction encoding/event writes before damage branching. [Evidence](research/QVM_GRENADE_EVENT_PREFIX.md).
 
 
 
 
1058
 
1059
 
1060
  **RE-679 — Constructed grenade through trajectory and event prelude:** Actual queried/allocated grenade enters223156, evaluates source trajectory, truncates/rebases origin and emits event55 through actual direction encoding/event writes before damage branching. [Evidence](research/QVM_GRENADE_EVENT_PREFIX.md).
1061
+
1062
+
1063
+ **RE-681 — Packed frame vertices through world triangle construction:** 23092 addresses eight-byte packed vertices by frame/count/index, sign-extends xyz16, interpolates B+(A−B)×fraction and scales1/64 before ancestry transform/origin. [Evidence](research/QVM_LEAF_VERTICES.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1041,3 +1041,6 @@ Research progress: RE-679 [report](research/QVM_GRENADE_EVENT_PREFIX.md); remain
1041
 
1042
 
1043
  RE-670–679 batch complete: [model transforms, resources and grenade prelude](research/QVM_MODEL_RESOURCE_BATCH.md). RE-680 tracks continued geometry/trace/damage/lifecycle recovery; original/native parity and playable Rust/Bevy/Solari integration remain open.
 
 
 
 
1041
 
1042
 
1043
  RE-670–679 batch complete: [model transforms, resources and grenade prelude](research/QVM_MODEL_RESOURCE_BATCH.md). RE-680 tracks continued geometry/trace/damage/lifecycle recovery; original/native parity and playable Rust/Bevy/Solari integration remain open.
1044
+
1045
+
1046
+ Research progress: RE-681 [report](research/QVM_LEAF_VERTICES.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -1052,3 +1052,8 @@ Actual277400 free-time and used state now feed277165 reuse policy; age1000 is el
1052
  ## 2026-10-21 — RE-679 Constructed grenade through trajectory and event prelude (separate task commit)
1053
 
1054
  Actual queried/allocated grenade enters223156, evaluates source trajectory, truncates/rebases origin and emits event55 through actual direction encoding/event writes before damage branching. 12 complete prelude compositions independently check every entity word, optional client event mask/parameter/time, source child ordering and unexecuted damage boundary. Full suite: 1177 tests pass. Report regenerates byte-identically (758560 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
1052
  ## 2026-10-21 — RE-679 Constructed grenade through trajectory and event prelude (separate task commit)
1053
 
1054
  Actual queried/allocated grenade enters223156, evaluates source trajectory, truncates/rebases origin and emits event55 through actual direction encoding/event writes before damage branching. 12 complete prelude compositions independently check every entity word, optional client event mask/parameter/time, source child ordering and unexecuted damage boundary. Full suite: 1177 tests pass. Report regenerates byte-identically (758560 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
1055
+
1056
+
1057
+ ## 2026-10-21 — RE-681 Packed frame vertices through world triangle construction (separate task commit)
1058
+
1059
+ 23092 addresses eight-byte packed vertices by frame/count/index, sign-extends xyz16, interpolates B+(A−B)×fraction and scales1/64 before ancestry transform/origin. 61 independent signed-unpack/float32 fixtures check every triangle vertex, reversed frames, permutations, extrema and unclamped weights. Full suite: 1181 tests pass. Report regenerates byte-identically (110810 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -1084,3 +1084,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1084
 
1085
 
1086
  - [ ] RE-680 Recover leaf primitive decoding/intersection and actual hit records, compose full model/trace cleanup, then continue damage, grenade completion, heap ownership and live scheduling toward a verified Rust gameplay slice. See the [next ten tasks](research/QVM_MODEL_RESOURCE_BATCH.md#next-ten-concrete-tasks).
 
 
 
 
1084
 
1085
 
1086
  - [ ] RE-680 Recover leaf primitive decoding/intersection and actual hit records, compose full model/trace cleanup, then continue damage, grenade completion, heap ownership and live scheduling toward a verified Rust gameplay slice. See the [next ten tasks](research/QVM_MODEL_RESOURCE_BATCH.md#next-ten-concrete-tasks).
1087
+
1088
+
1089
+ - [x] RE-681 Packed frame vertices through world triangle construction ([report](research/QVM_LEAF_VERTICES.md)).
docs/research/QVM_LEAF_VERTICES.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Packed frame vertices through world triangle construction
2
+
3
+ RE-681. Reproduce with `python3 scripts/analyze_qvm_leaf_vertices.py`; check with `python3 scripts/test_qvm_leaf_vertices.py`. The [machine report](qvm-leaf-vertices.json) retains source identity and bounded fixtures.
4
+
5
+ Actual23929–24514 reads three32-bit triangle indices and signed16 xyz from eight-byte vertex records. The last two bytes are not consumed by this slice. Frame A/B bases use part100+part plus frame×part80×8. Coordinates interpolate in integer-derived float32 order, scale1/64, multiply through the prepared basis and add origin. Full triangle outputs match independent byte/geometry oracles, including−32768/32767 and extrapolation. Part/vertex ownership, bounds and original asset identities remain unverified; no intersection/native code runs.
6
+
7
+ No original executable/full QVM/native collision/physics/rendering executes. Native responses and legal input domains are supplied or unverified where stated; full runtime/macOS/Linux Rust/Bevy/Solari gameplay remains open.
docs/research/README.md CHANGED
@@ -642,3 +642,6 @@ The extension collector adds five focused tests for native tail calls, command-r
642
 
643
 
644
  [RE-670–679: Model transforms, resources and grenade prelude](QVM_MODEL_RESOURCE_BATCH.md), with validation limits and the next ten concrete tasks.
 
 
 
 
642
 
643
 
644
  [RE-670–679: Model transforms, resources and grenade prelude](QVM_MODEL_RESOURCE_BATCH.md), with validation limits and the next ten concrete tasks.
645
+
646
+
647
+ [RE-681: Packed frame vertices through world triangle construction](QVM_LEAF_VERTICES.md). Reproduce with `python3 scripts/analyze_qvm_leaf_vertices.py`; check with `python3 scripts/test_qvm_leaf_vertices.py`.
docs/research/qvm-leaf-vertices.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_leaf_vertices.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """23092 packed vertex/frame addressing and world triangle construction."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source,execute
6
+ from analyze_qvm_acceleration import word
7
+ from analyze_qvm_slide_prefix import vec
8
+ from analyze_qvm import write_json
9
+ LOCAL=0x78a00000
10
+ NODE=LOCAL+4096
11
+ PART=LOCAL+8192
12
+ TRI=PART+512
13
+
14
+ def fixture(a=0,b=1,t=.5,indices=(0,1,2),basis=None,origin=(10,20,30),frames=None):
15
+ basis=basis or [[1,0,0],[0,1,0],[0,0,1]];frames=frames or [[[64,0,0],[0,128,0],[0,0,192]],[[-64,32,16],[64,-128,32],[16,32,-192]]];count=len(frames[0]);m={LOCAL+152:PART,LOCAL+148:TRI,LOCAL+440:NODE,NODE:a,NODE+4:b,NODE+8:word(t),PART+80:count,PART+100:1024};bytes_map={}
16
+ for j,v in enumerate(indices):m[TRI+4*j]=v
17
+ for r,row in enumerate(basis):
18
+ for c,v in enumerate(row):m[LOCAL+84+16*r+4*c]=word(v)
19
+ for j,v in enumerate(origin):m[LOCAL+132+4*j]=word(v)
20
+ for frame,vertices in enumerate(frames):
21
+ for j,vertex in enumerate(vertices):
22
+ address=PART+1024+(frame*count+j)*8;data=b''.join(int(v).to_bytes(2,'little',signed=True) for v in vertex)+b'\x12\x34';bytes_map.update({address+k:v for k,v in enumerate(data)})
23
+ return m,bytes_map,{'frames':frames,'frame_a':a,'frame_b':b,'fraction':word(t),'indices':list(indices),'basis':[[word(v) for v in row] for row in basis],'origin':[word(v) for v in origin],'vertex_count':count,'part':PART}
24
+
25
+ def vertices(ins,m,bytes_map,base=LOCAL):
26
+ m,_,e=execute(ins,23929,24515,dict(m),(0,0,0),base,byte_inputs=bytes_map);return m,{'vertices':[vec(m,base+o) for o in [212,224,236]],'frame_pointers':[m[base+248],m[base+252]],'execution':e}
27
+
28
+ def main():
29
+ q,raw,h,ins=source();rows=[]
30
+ for (a,b),t,indices,kind in itertools.product([(0,1),(1,0),(1,1)],[-.5,0,.5,1,1.5],[(0,1,2),(2,0,1)],['identity','turn-scale']):
31
+ basis=None if kind=='identity' else [[0,1,0],[-1,0,0],[0,0,2]];m,bs,inputs=fixture(a,b,t,indices,basis);_,r=vertices(ins,m,bs);r['input']=inputs;rows.append(r)
32
+ m,bs,inputs=fixture(frames=[[[-32768,32767,-1],[1,2,3],[4,5,6]],[[32767,-32768,1],[7,8,9],[10,11,12]]]);_,r=vertices(ins,m,bs);r['input']=inputs;rows.append(r)
33
+ write_json(Path('docs/research/qvm-leaf-vertices.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual23929–24514 on explicit signed16 vertex bytes/triangle indices. Coordinates scale by1/64 after B+(A−B)×fraction. No triangle intersection/model ownership/native execution.'})
34
+ if __name__=='__main__':main()
scripts/test_qvm_leaf_vertices.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,n,f
4
+
5
+ def expected(a):
6
+ frames=a['frames'];t=n(a['fraction']);matrix=[[n(x) for x in row] for row in a['basis']];origin=list(map(n,a['origin']));result=[]
7
+ for index in a['indices']:
8
+ v=[f(f(float(b)+f(float(x-b)*t))*n(1015021568)) for x,b in zip(frames[a['frame_a']][index],frames[a['frame_b']][index])];out=[]
9
+ for col in range(3):out.append(word(f(f(f(f(v[0]*matrix[0][col])+f(v[1]*matrix[1][col]))+f(v[2]*matrix[2][col]))+origin[col])))
10
+ result.append(out)
11
+ return result
12
+ class LeafVertexTests(unittest.TestCase):
13
+ @classmethod
14
+ def setUpClass(cls):cls.rows=json.loads(Path('docs/research/qvm-leaf-vertices.json').read_text())['probes']
15
+ def test_independent_signed_unpack_lerp_and_world_transform(self):
16
+ self.assertEqual(len(self.rows),61)
17
+ for p in self.rows:self.assertEqual(p['vertices'],expected(p['input']))
18
+ def test_frame_stride_is_eight_bytes_per_vertex(self):
19
+ for p in self.rows:
20
+ a=p['input'];self.assertEqual(p['frame_pointers'],[a['part']+1024+frame*a['vertex_count']*8 for frame in [a['frame_a'],a['frame_b']]])
21
+ def test_extreme_signed_halfwords_and_extrapolation_present(self):
22
+ self.assertEqual(self.rows[-1]['input']['frames'][0][0],[-32768,32767,-1]);self.assertEqual({n(p['input']['fraction']) for p in self.rows},{-.5,0,.5,1,1.5})
23
+ def test_no_geometry_or_native_calls(self):
24
+ for p in self.rows:self.assertEqual(p['execution']['calls'],[])
25
+ if __name__=='__main__':unittest.main()