nmarshall commited on
Commit
37a275a
·
1 Parent(s): 0196d8e

qvm: original pose driven model hits

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -760,3 +760,6 @@ Research progress: RE-696 [report](research/MD3_ORIGINAL_LEAF.md); remaining nat
760
 
761
 
762
  Research progress: RE-697 [report](research/MD3_ORIGINAL_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
760
 
761
 
762
  Research progress: RE-697 [report](research/MD3_ORIGINAL_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
763
+
764
+
765
+ Research progress: RE-698 [report](research/MD3_ORIGINAL_MODEL_HIT.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -1106,3 +1106,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
1106
 
1107
 
1108
  **RE-697 — Original tag attachment through complete hierarchy geometry:** Actual21770 attaches original tag_torso/tag_head chains and25341 processes all four original model parts for both characters and first/last frame fixtures. [Evidence](research/MD3_ORIGINAL_HIERARCHY.md).
 
 
 
 
1106
 
1107
 
1108
  **RE-697 — Original tag attachment through complete hierarchy geometry:** Actual21770 attaches original tag_torso/tag_head chains and25341 processes all four original model parts for both characters and first/last frame fixtures. [Evidence](research/MD3_ORIGINAL_HIERARCHY.md).
1109
+
1110
+
1111
+ **RE-698 — Complete pose-driven model hits on original MD3 hierarchies:** Complete144766 now uses original Athena/Orion lower/upper/head/helmet buffers, actual tag attachment, pose, geometry and sorting to publish source-derived hits/misses. [Evidence](research/MD3_ORIGINAL_MODEL_HIT.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1092,3 +1092,6 @@ Research progress: RE-696 [report](research/MD3_ORIGINAL_LEAF.md); remaining nat
1092
 
1093
 
1094
  Research progress: RE-697 [report](research/MD3_ORIGINAL_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
1092
 
1093
 
1094
  Research progress: RE-697 [report](research/MD3_ORIGINAL_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
1095
+
1096
+
1097
+ Research progress: RE-698 [report](research/MD3_ORIGINAL_MODEL_HIT.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -1132,3 +1132,8 @@ Complete23092 processes all eight original selected MD3 models; aimed rays produ
1132
  ## 2026-10-21 — RE-697 Original tag attachment through complete hierarchy geometry (separate task commit)
1133
 
1134
  Actual21770 attaches original tag_torso/tag_head chains and25341 processes all four original model parts for both characters and first/last frame fixtures. Four complete hierarchy probes independently check all twelve tag transforms, every full leaf context, source postorder and bounded recognized hit records. Full suite: 1243 tests pass. Report regenerates byte-identically (874680 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
1132
  ## 2026-10-21 — RE-697 Original tag attachment through complete hierarchy geometry (separate task commit)
1133
 
1134
  Actual21770 attaches original tag_torso/tag_head chains and25341 processes all four original model parts for both characters and first/last frame fixtures. Four complete hierarchy probes independently check all twelve tag transforms, every full leaf context, source postorder and bounded recognized hit records. Full suite: 1243 tests pass. Report regenerates byte-identically (874680 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
1135
+
1136
+
1137
+ ## 2026-10-21 — RE-698 Complete pose-driven model hits on original MD3 hierarchies (separate task commit)
1138
+
1139
+ Complete144766 now uses original Athena/Orion lower/upper/head/helmet buffers, actual tag attachment, pose, geometry and sorting to publish source-derived hits/misses. Six full compositions independently check complete pose, every original leaf context, final sorted context/trace words, both selector bindings and frame0/22. Full suite: 1247 tests pass. Report regenerates byte-identically (1675425 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
@@ -1135,3 +1135,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1135
 
1136
 
1137
  - [x] RE-697 Original tag attachment through complete hierarchy geometry ([report](research/MD3_ORIGINAL_HIERARCHY.md)).
 
 
 
 
1135
 
1136
 
1137
  - [x] RE-697 Original tag attachment through complete hierarchy geometry ([report](research/MD3_ORIGINAL_HIERARCHY.md)).
1138
+
1139
+
1140
+ - [x] RE-698 Complete pose-driven model hits on original MD3 hierarchies ([report](research/MD3_ORIGINAL_MODEL_HIT.md)).
docs/research/MD3_ORIGINAL_MODEL_HIT.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Complete pose-driven model hits on original MD3 hierarchies
2
+
3
+ RE-698. Reproduce with `python3 scripts/analyze_md3_original_model_hit.py`; check with `python3 scripts/test_md3_original_model_hit.py`. The [machine report](md3-original-model-hit.json) retains source identity and bounded fixtures.
4
+
5
+ The model wrapper accepts an optional original-geometry resolver and validates zero-fill destinations against the actual selector table rather than hardcoded fixture addresses. Default fixture reports remain compatible. Original first/22nd-frame windows are mapped verbatim; actual21770 attachments and complete32254/25341/22009/23092/25835 run through144766. Aimed rays are selected from original geometry for animated probes. All outputs match independent pose/geometry/sorting/publication oracles. Allocation, zero fill and finite math remain modeled; no original loader18183/process/world-collision/native parity is asserted.
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
@@ -693,3 +693,6 @@ The extension collector adds five focused tests for native tail calls, command-r
693
 
694
 
695
  [RE-697: Original tag attachment through complete hierarchy geometry](MD3_ORIGINAL_HIERARCHY.md). Reproduce with `python3 scripts/analyze_md3_original_hierarchy.py`; check with `python3 scripts/test_md3_original_hierarchy.py`.
 
 
 
 
693
 
694
 
695
  [RE-697: Original tag attachment through complete hierarchy geometry](MD3_ORIGINAL_HIERARCHY.md). Reproduce with `python3 scripts/analyze_md3_original_hierarchy.py`; check with `python3 scripts/test_md3_original_hierarchy.py`.
696
+
697
+
698
+ [RE-698: Complete pose-driven model hits on original MD3 hierarchies](MD3_ORIGINAL_MODEL_HIT.md). Reproduce with `python3 scripts/analyze_md3_original_model_hit.py`; check with `python3 scripts/test_md3_original_model_hit.py`.
docs/research/md3-original-model-hit.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_md3_original_hierarchy.py CHANGED
@@ -29,10 +29,10 @@ def attach(ins,m,bs,parent,child,tag,allocator):
29
  m,_,e=execute(ins,21771,21918,m,(0,0,0),ATTACH,{16817:alloc,-101:zero,36306:strcmp},byte_inputs=bs)
30
  return m,{'parent':parent,'child':child,'tag':tag,'result':e['return'],'execution':e}
31
 
32
- def scene(raw,h,ins,character,last=False):
33
  files={virtual(p).casefold():p for p in paths()};m,bs=support(raw,h);models={};bindings=[]
34
  for j,role in enumerate(ROLES):
35
- p=files[f'models/players/{character}/{role}_3.md3'];model=MD3(p.read_bytes());address=0x70000000+0x1000000*j;frame=model.frames-1 if last else 0;map_md3(m,bs,model,address,[0,frame]);node_record(m,NODES[j],address,frame);models[NODES[j]]=model;bindings.append({'role':role,'path':str(p),'node':NODES[j],'address':address,'frame':frame})
36
  allocator=[0x79b10000];attachments=[]
37
  for parent,child,tag in [(0,1,'tag_torso'),(1,2,'tag_head'),(2,3,'tag_head')]:m,r=attach(ins,m,bs,NODES[parent],NODES[child],tag,allocator);attachments.append(r)
38
  return m,bs,models,bindings,attachments
 
29
  m,_,e=execute(ins,21771,21918,m,(0,0,0),ATTACH,{16817:alloc,-101:zero,36306:strcmp},byte_inputs=bs)
30
  return m,{'parent':parent,'child':child,'tag':tag,'result':e['return'],'execution':e}
31
 
32
+ def scene(raw,h,ins,character,last=False,extra_frames=()):
33
  files={virtual(p).casefold():p for p in paths()};m,bs=support(raw,h);models={};bindings=[]
34
  for j,role in enumerate(ROLES):
35
+ p=files[f'models/players/{character}/{role}_3.md3'];model=MD3(p.read_bytes());address=0x70000000+0x1000000*j;frame=model.frames-1 if last else 0;map_md3(m,bs,model,address,[0,frame]+[f for f in extra_frames if f<model.frames]);node_record(m,NODES[j],address,frame);models[NODES[j]]=model;bindings.append({'role':role,'path':str(p),'node':NODES[j],'address':address,'frame':frame})
36
  allocator=[0x79b10000];attachments=[]
37
  for parent,child,tag in [(0,1,'tag_torso'),(1,2,'tag_head'),(2,3,'tag_head')]:m,r=attach(ins,m,bs,NODES[parent],NODES[child],tag,allocator);attachments.append(r)
38
  return m,bs,models,bindings,attachments
scripts/analyze_md3_original_model_hit.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Complete144766 using original character bindings, tags, surfaces and frame bytes."""
3
+ from pathlib import Path
4
+ from qvm_research_support import source
5
+ from analyze_qvm_complete_model_hit import prepare,complete
6
+ from analyze_md3_original_hierarchy import scene,geometry,NODES
7
+ from analyze_qvm_model_transforms import TABLES
8
+ from analyze_qvm_entity_init import POOL,STRIDE
9
+ from analyze_qvm_acceleration import word
10
+ from analyze_qvm import write_json
11
+ from analyze_md3_original_leaf import aimed_ray
12
+
13
+ def main():
14
+ q,raw,h,ins=source();rows=[]
15
+ cases=[(character,frame,hit) for character in ['athena','orion'] for frame,hit in [(0,False),(0,True),(22,True)]]
16
+ for character,frame,hit in cases:
17
+ m,bs,args,names=prepare(raw,h,frame);original,original_bs,models,bindings,attachments=scene(raw,h,ins,character,extra_frames=[frame]);m.update(original);bs.update(original_bs);client=m[POOL+65*STRIDE+520];selector=int(character=='orion');m[client+700]=selector
18
+ for o in [6196,6204,6248,6256]:m[client+o]=frame
19
+ for table,p in zip(TABLES,NODES):m[table+16*selector]=p
20
+ start,end=((0,0,100),(0,0,-100)) if hit else ((10000,10000,100),(10000,10000,-100))
21
+ if hit and frame:
22
+ start,direction=aimed_ray(models[NODES[0]],frame);end=[x+200*y for x,y in zip(start,direction)]
23
+ for p,v in [(args[16],start),(args[20],end)]:
24
+ for j,x in enumerate(v):m[p+4*j]=word(x)
25
+ def resolved(i,m,a):return geometry(i,m,bs,models,a)
26
+ m,r=complete(ins,m,bs,args,{},geometry_resolver=resolved);r.update({'character':character,'frame_fixture':frame,'aimed_fixture':hit,'bindings':bindings,'attachments':attachments});rows.append(r)
27
+ write_json(Path('docs/research/md3-original-model-hit.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Complete144766 with actual pose, original MD3/tag hierarchy, full leaf geometry and sorting/publication. Explicit target/clock/frame/ray fixtures, finite native math and bounded allocation/zero fill models. No original loader/native process/world collision parity.'})
28
+ if __name__=='__main__':main()
scripts/analyze_qvm_complete_model_hit.py CHANGED
@@ -19,15 +19,18 @@ from analyze_qvm import write_json
19
 
20
  START=END+0x3000
21
 
22
- def complete(ins,m,bs,args,names):
23
- m=dict(m);before=words(m,args[12],14);poses=[];hierarchies=[];sorts=[]
24
  for o,v in args.items():m[LOCAL+312+o]=v
25
  def posed(i,m,a,c):m,r=pose(i,m,a);poses.append(r);return m,c,0,{'pose_index':len(poses)-1}
26
  def zero(i,m,a,c):
27
- assert a[8] in BUFFERS and a[12]==0 and a[16]==88
28
  for o in range(0,88,4):m[a[8]+o]=0
29
  return m,c,0,{'bounded_zero_fill':a}
30
- def geometry(i,m,a,c):m,r=geometric_walk(i,m,bs,a,names);hierarchies.append(r);return m,c,0,{'hierarchy_index':len(hierarchies)-1}
 
 
 
31
  def sort(i,m,a,c):
32
  pointer=a[8];initial=words(m,pointer);m[SORT+56]=pointer;m,_,e=execute(i,25836,26036,m,c,SORT);r={'before':initial,'after':words(m,pointer),'execution':e};sorts.append(r);return m,c,0,{'sort_index':len(sorts)-1}
33
  m,_,e=execute(ins,144767,146621,m,(0,0,0),LOCAL,{**TRIG,32254:posed,-101:zero,25341:geometry,25835:sort})
 
19
 
20
  START=END+0x3000
21
 
22
+ def complete(ins,m,bs,args,names,geometry_resolver=None):
23
+ m=dict(m);before=words(m,args[12],14);poses=[];hierarchies=[];sorts=[];target=POOL+m[args[12]+52]*STRIDE;selector=m[m[target+520]+700];allowed_buffers={m[table+16*selector] for table in TABLES}
24
  for o,v in args.items():m[LOCAL+312+o]=v
25
  def posed(i,m,a,c):m,r=pose(i,m,a);poses.append(r);return m,c,0,{'pose_index':len(poses)-1}
26
  def zero(i,m,a,c):
27
+ assert a[8] in allowed_buffers and a[12]==0 and a[16]==88
28
  for o in range(0,88,4):m[a[8]+o]=0
29
  return m,c,0,{'bounded_zero_fill':a}
30
+ def geometry(i,m,a,c):
31
+ if geometry_resolver is None:m,r=geometric_walk(i,m,bs,a,names)
32
+ else:m,r=geometry_resolver(i,m,a)
33
+ hierarchies.append(r);return m,c,0,{'hierarchy_index':len(hierarchies)-1}
34
  def sort(i,m,a,c):
35
  pointer=a[8];initial=words(m,pointer);m[SORT+56]=pointer;m,_,e=execute(i,25836,26036,m,c,SORT);r={'before':initial,'after':words(m,pointer),'execution':e};sorts.append(r);return m,c,0,{'sort_index':len(sorts)-1}
36
  m,_,e=execute(ins,144767,146621,m,(0,0,0),LOCAL,{**TRIG,32254:posed,-101:zero,25341:geometry,25835:sort})
scripts/test_md3_original_model_hit.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_complete_leaf import expected as leaf
4
+ from test_qvm_complete_pose import expected as pose
5
+ from test_qvm_model_multi_hits import sorted_context
6
+ class OriginalModelHitTests(unittest.TestCase):
7
+ @classmethod
8
+ def setUpClass(cls):cls.rows=json.loads(Path('docs/research/md3-original-model-hit.json').read_text())['probes']
9
+ def test_independent_pose_and_every_original_leaf_context(self):
10
+ self.assertEqual(len(self.rows),6)
11
+ for p in self.rows:
12
+ state,angles,flag=pose(p['poses'][0]);self.assertEqual(p['poses'][0]['final_state'],state);self.assertEqual(p['poses'][0]['output_legs_body_head'],angles)
13
+ for r in p['hierarchies'][0]['leaf_reports']:self.assertEqual(r['effect']['after'],leaf(r['effect']))
14
+ def test_sorted_context_and_geometric_return(self):
15
+ for p in self.rows:self.assertEqual(p['context'],sorted_context(p['sorts'][0]['before']));self.assertEqual(p['execution']['return'],int(bool(p['context'][16])));self.assertEqual(bool(p['context'][16]),p['aimed_fixture'])
16
+ def test_exact_original_model_trace_publication(self):
17
+ for p in self.rows:
18
+ expected=p['before_trace'][:]
19
+ if p['context'][16]:expected[3:6]=p['context'][3:6];expected[6:9]=p['context'][9:12];expected[13]=65
20
+ self.assertEqual(p['after_trace'],expected)
21
+ def test_two_selectors_and_actual_animations_have_original_bindings(self):
22
+ self.assertEqual({p['character'] for p in self.rows},{'athena','orion'});self.assertEqual({p['frame_fixture'] for p in self.rows},{0,22})
23
+ for p in self.rows:self.assertEqual([r['role'] for r in p['bindings']],['lower','upper','head','helmet']);self.assertTrue(all(a['result']==1 for a in p['attachments']))
24
+ if __name__=='__main__':unittest.main()