qvm: pose movement yaw
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_POSE_MOTION_YAW.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-pose-motion-yaw.json +0 -0
- scripts/analyze_qvm_pose_motion_yaw.py +29 -0
- scripts/test_qvm_pose_motion_yaw.py +31 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -661,3 +661,6 @@ Research progress: RE-660 [report](research/QVM_POSE_CONTROLLERS.md); remaining
|
|
| 661 |
|
| 662 |
|
| 663 |
Research progress: RE-661 [report](research/QVM_VECTOR_ANGLES.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 661 |
|
| 662 |
|
| 663 |
Research progress: RE-661 [report](research/QVM_VECTOR_ANGLES.md); remaining native/content/runtime/platform scope stays open.
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
Research progress: RE-662 [report](research/QVM_POSE_MOTION_YAW.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -1007,3 +1007,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 1007 |
|
| 1008 |
|
| 1009 |
**RE-661 — Complete vector-to-angle helper and alias behavior:** 62944 converts vectors through explicit quadrant/vertical branches and finite atan2/sqrt responses; the zero vector yields pitch−270 and yaw0. [Evidence](research/QVM_VECTOR_ANGLES.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1007 |
|
| 1008 |
|
| 1009 |
**RE-661 — Complete vector-to-angle helper and alias behavior:** 62944 converts vectors through explicit quadrant/vertical branches and finite atan2/sqrt responses; the zero vector yields pitch−270 and yaw0. [Evidence](research/QVM_VECTOR_ANGLES.md).
|
| 1010 |
+
|
| 1011 |
+
|
| 1012 |
+
**RE-662 — Animation-dispatched movement yaw and speed scaling:** 32254 dispatches forward/reverse/default yaw branches, clamps integer horizontal speed to200 and yaw delta to±60, and preserves an integer reciprocal scratch calculation. [Evidence](research/QVM_POSE_MOTION_YAW.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -984,3 +984,6 @@ Research progress: RE-660 [report](research/QVM_POSE_CONTROLLERS.md); remaining
|
|
| 984 |
|
| 985 |
|
| 986 |
Research progress: RE-661 [report](research/QVM_VECTOR_ANGLES.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 984 |
|
| 985 |
|
| 986 |
Research progress: RE-661 [report](research/QVM_VECTOR_ANGLES.md); remaining native/content/runtime/platform scope stays open.
|
| 987 |
+
|
| 988 |
+
|
| 989 |
+
Research progress: RE-662 [report](research/QVM_POSE_MOTION_YAW.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -967,3 +967,8 @@ One direct append caller156173 and three direct reset callers174399/203011/21963
|
|
| 967 |
## 2026-10-20 — RE-661 Complete vector-to-angle helper and alias behavior (separate task commit)
|
| 968 |
|
| 969 |
62944 converts vectors through explicit quadrant/vertical branches and finite atan2/sqrt responses; the zero vector yields pitch−270 and yaw0. 24 axis/quadrant/zero/general fixtures check independent source-order float32 outputs, exact input/output aliasing and reached native call order. Full suite: 1109 tests pass. Report regenerates byte-identically (42673 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 967 |
## 2026-10-20 — RE-661 Complete vector-to-angle helper and alias behavior (separate task commit)
|
| 968 |
|
| 969 |
62944 converts vectors through explicit quadrant/vertical branches and finite atan2/sqrt responses; the zero vector yields pitch−270 and yaw0. 24 axis/quadrant/zero/general fixtures check independent source-order float32 outputs, exact input/output aliasing and reached native call order. Full suite: 1109 tests pass. Report regenerates byte-identically (42673 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 970 |
+
|
| 971 |
+
|
| 972 |
+
## 2026-10-20 — RE-662 Animation-dispatched movement yaw and speed scaling (separate task commit)
|
| 973 |
+
|
| 974 |
+
32254 dispatches forward/reverse/default yaw branches, clamps integer horizontal speed to200 and yaw delta to±60, and preserves an integer reciprocal scratch calculation. 144 fixtures independently check dispatch, integer/sqrt boundaries, signed deltas, capped speed, actual62944/63746 composition and signed zero scratch vectors. Full suite: 1113 tests pass. Report regenerates byte-identically (588314 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
|
@@ -1027,3 +1027,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1027 |
|
| 1028 |
|
| 1029 |
- [x] RE-661 Complete vector-to-angle helper and alias behavior ([report](research/QVM_VECTOR_ANGLES.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1027 |
|
| 1028 |
|
| 1029 |
- [x] RE-661 Complete vector-to-angle helper and alias behavior ([report](research/QVM_VECTOR_ANGLES.md)).
|
| 1030 |
+
|
| 1031 |
+
|
| 1032 |
+
- [x] RE-662 Animation-dispatched movement yaw and speed scaling ([report](research/QVM_POSE_MOTION_YAW.md)).
|
docs/research/QVM_POSE_MOTION_YAW.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Animation-dispatched movement yaw and speed scaling
|
| 2 |
+
|
| 3 |
+
RE-662. Reproduce with `python3 scripts/analyze_qvm_pose_motion_yaw.py`; check with `python3 scripts/test_qvm_pose_motion_yaw.py`. The [machine report](qvm-pose-motion-yaw.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Actual32428–32796 loads the full22..40 jump table. Reverse entries23/24/30/35/40 add180 to movement yaw; forward22/26/34/38/39 omit that offset; other IDs reload the external controller angle. Reached branches run actual62944, zero vertical scratch velocity, truncate horizontal length to integer, clamp it to200 and interpolate view yaw toward a clamped±60 integer delta using source63746. The scratch normalization computes integer1/speed before converting to float, so magnitudes above1 zero horizontal components, retaining signed zeros. This arithmetic is retained rather than silently replaced with vector normalization. Native finite math models remain explicit and semantic animation names/live scheduling remain unknown.
|
| 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
|
@@ -585,3 +585,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 585 |
|
| 586 |
|
| 587 |
[RE-661: Complete vector-to-angle helper and alias behavior](QVM_VECTOR_ANGLES.md). Reproduce with `python3 scripts/analyze_qvm_vector_angles.py`; check with `python3 scripts/test_qvm_vector_angles.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
|
| 586 |
|
| 587 |
[RE-661: Complete vector-to-angle helper and alias behavior](QVM_VECTOR_ANGLES.md). Reproduce with `python3 scripts/analyze_qvm_vector_angles.py`; check with `python3 scripts/test_qvm_vector_angles.py`.
|
| 588 |
+
|
| 589 |
+
|
| 590 |
+
[RE-662: Animation-dispatched movement yaw and speed scaling](QVM_POSE_MOTION_YAW.md). Reproduce with `python3 scripts/analyze_qvm_pose_motion_yaw.py`; check with `python3 scripts/test_qvm_pose_motion_yaw.py`.
|
docs/research/qvm-pose-motion-yaw.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_pose_motion_yaw.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""32254 animation dispatch and horizontal speed/yaw through32796."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source,execute,constants
|
| 6 |
+
from analyze_qvm_pose_prefix import fixture,LOCAL,VELOCITY
|
| 7 |
+
from analyze_qvm_pose_controllers import controllers
|
| 8 |
+
from analyze_qvm_vector_angles import vector_angles
|
| 9 |
+
from analyze_qvm_history_angle_lerp import angle
|
| 10 |
+
from analyze_qvm_acceleration import word
|
| 11 |
+
from analyze_qvm_slide_prefix import vec
|
| 12 |
+
from analyze_qvm import write_json
|
| 13 |
+
|
| 14 |
+
def motion(ins,m):
|
| 15 |
+
m=dict(m);initial_yaw=m[LOCAL+52]&0xffffffff;previous=m[LOCAL+64]&0xffffffff;ident=m[LOCAL+88];velocity=vec(m,m[LOCAL+248])
|
| 16 |
+
def direction(i,m,a,c):m,r=vector_angles(i,m,a);return m,c,0,r
|
| 17 |
+
def blend(i,m,a,c):m,r=angle(i,m,a);return m,c,r['result'],r
|
| 18 |
+
m,_,e=execute(ins,32428,32797,m,(0,0,0),LOCAL,{62944:direction,63746:blend})
|
| 19 |
+
active=any(c['target']==62944 for c in e['calls'])
|
| 20 |
+
return m,{'animation_id':ident,'input_yaw':initial_yaw,'previous_yaw':previous,'velocity':velocity,'result_yaw':m[LOCAL+64]&0xffffffff,'speed_cap':m.get(LOCAL+132) if active else None,'clamped_delta':m.get(LOCAL+152) if active else None,'scratch_velocity':vec(m,LOCAL+72) if active else None,'execution':e}
|
| 21 |
+
|
| 22 |
+
def main():
|
| 23 |
+
q,raw,h,ins=source();table=constants(raw,h,range(20536+22*4,20536+41*4,4));rows=[]
|
| 24 |
+
for ident,velocity,angles in itertools.product([0,22,23,25,26,30,34,35,38,39,40,41],[(0,0,0),(.5,0,3),(1,0,0),(3,4,12),(300,400,0),(-1,-2,0)],[(0,45,0),(0,-170,0)]):
|
| 25 |
+
m,a=fixture(ident,22,angles);m.update(table)
|
| 26 |
+
for j,v in enumerate(velocity):m[VELOCITY+4*j]=word(v)
|
| 27 |
+
m,_=controllers(ins,m,a);rows.append(motion(ins,m)[1])
|
| 28 |
+
write_json(Path('docs/research/qvm-pose-motion-yaw.json'),{'source':q['source'],'sha256':q['sha256'],'dispatch':{str(j):table[20536+4*j] for j in range(22,41)},'probes':rows,'limits':'Actual32428–32796 after actual prefix/controllers; complete62944/63746 with explicit finite native math. Integer reciprocal scratch scaling is preserved. Animation names/live speed legality and later pose outputs remain unverified.'})
|
| 29 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_pose_motion_yaw.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,math,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import word,n,f
|
| 4 |
+
from test_qvm_vector_angles import expected as angles
|
| 5 |
+
from test_qvm_history_angle_lerp import expected as blend
|
| 6 |
+
REVERSE={23,24,30,35,40}
|
| 7 |
+
FORWARD={22,26,34,38,39}
|
| 8 |
+
|
| 9 |
+
def expected(p):
|
| 10 |
+
ident=p['animation_id'];view=n(p['input_yaw'])
|
| 11 |
+
if ident not in REVERSE|FORWARD:return p['previous_yaw'],None,None,None
|
| 12 |
+
x,y,z=map(n,p['velocity']);yaw=n(angles(p['velocity'])[1]);speed=int(f(math.sqrt(f(f(x*x)+f(y*y)))));delta=int(f(f(yaw+180)-view)) if ident in REVERSE else int(f(yaw-view))
|
| 13 |
+
if delta>=180:delta-=360
|
| 14 |
+
elif delta<=-180:delta+=360
|
| 15 |
+
delta=max(-60,min(60,delta));cap=min(200,speed);result=blend(view,f(view+f(float(delta))),f(f(float(cap))*n(1000593162)))[1];scale=f(float(1//speed)) if speed else 1;scratch=[word(f(x*scale)),word(f(y*scale)),0]
|
| 16 |
+
return result,cap,delta,scratch
|
| 17 |
+
class MotionYawTests(unittest.TestCase):
|
| 18 |
+
@classmethod
|
| 19 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-pose-motion-yaw.json').read_text())
|
| 20 |
+
def test_independent_animation_speed_delta_and_lerp(self):
|
| 21 |
+
self.assertEqual(len(self.r['probes']),144)
|
| 22 |
+
for p in self.r['probes']:self.assertEqual((p['result_yaw'],p['speed_cap'],p['clamped_delta'],p['scratch_velocity']),expected(p),p)
|
| 23 |
+
def test_full_dispatch_table(self):
|
| 24 |
+
self.assertEqual(self.r['dispatch'],{str(j):32444 if j in REVERSE else 32619 if j in FORWARD else 32792 for j in range(22,41)})
|
| 25 |
+
def test_reached_calls_or_default_reload(self):
|
| 26 |
+
for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[62944,-107,63746] if p['animation_id'] in REVERSE|FORWARD else [])
|
| 27 |
+
def test_integer_reciprocal_and_speed_cap_exposed(self):
|
| 28 |
+
self.assertTrue(any(p['speed_cap']==200 for p in self.r['probes']))
|
| 29 |
+
for p in self.r['probes']:
|
| 30 |
+
if p['speed_cap'] and p['speed_cap']>1:self.assertEqual(p['scratch_velocity'],[0,0,0] if all(n(v)>=0 for v in p['velocity'][:2]) else [word(-0.0) if n(v)<0 else 0 for v in p['velocity'][:2]]+[0])
|
| 31 |
+
if __name__=='__main__':unittest.main()
|