qvm: packed leaf vertices
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +3 -0
- docs/PROVISIONAL_TODO.md +3 -0
- docs/RESEARCH_LEDGER.md +5 -0
- docs/REVERSE_ENGINEERING_TODO.md +3 -0
- docs/research/QVM_LEAF_VERTICES.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-leaf-vertices.json +0 -0
- scripts/analyze_qvm_leaf_vertices.py +34 -0
- scripts/test_qvm_leaf_vertices.py +25 -0
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()
|