mirror of
https://github.com/vladtrc/iw4L
synced 2026-10-26 10:19:50 -04:00
846ab99a73
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KkgiSVEPTbsVZ1RpARujF6
2.5 KiB
2.5 KiB
Animation: what lives where
Three floors, deliberately different: the curve facts (pure mathematics), the runtime tree (pose state) and who picked which clip (the game).
anim_iw4 — facts only, #![no_std], no clock and no allocator
XAnimParts— curve storage, unpacking ofhalf_quat/full_quatand quantized translations (XAnimCalcParts); translations are deltas;- span/sample/
time_to_frame— a pure function of (clip, time); - the blend rule
bind + scale * Δ, rotation replaced (DObjCompose); DObj— how model, skeleton and attachments compose (0x9c, prefix mapped out);XBoneInfo— the OBBs for bone hits (DObjGeom_RayBones);PartBits— the six-word requested/ignore mask (DObjCalcAnimInternal);PlayerAnimValue— 10-bitlegsAnim/torsoAnim, a 9-bit index and the0x200"restart" bit: a restart changes only that bit, not the index;- the leaf time step and the goal-weight ramp are measured IW4 constants;
- script name tables:
ANIM_MT_NAMES,ANIM_BODY_PART_NAMES,ANIM_COND_NAMES.
No Vec, no AnimationClip, no glam matrices and no playback clock here.
xmodel_runtime — a runtime without Bevy and without ECS
A pure evaluator, used by both the authority and the client:
XAnimTreeDefinition(the immutable hierarchy) +XAnimTreeRuntime(state; leaf time normalized into[0,1],updateis the per-leaf advance);DObjAnimRuntime—update/pose_request/compose; DObj reuse is equality of(eType, model*), not "always a fresh one";RetainedModelCapability— pose,XBoneInfo, collSurf/collTris for hitscan;build_body_head_weapon_dobj— body + head onj_spine4+ weapon on its tag.
A missing clip never turns into the bind pose; additive nodes are a typed gap, not "ordinary blending".
Who picks the clip
sim—player_anim_script.rs,mantle_xanim.rs,anim_script_gap.rs: what animation the player is in, and it travels into the snapshot as semantics, not as a tree;assets—XAnimParts→ owning clips;render_frontend/adapters/anim/+render_anim— the viewmodel (fpv*.rs,viewmodel_controller.rs), third person (third_person.rs,remote_body.rs), kick and sway (view_kick.rs,view_sway.rs), items and projectiles. FPV actions come from the presentedweapAnim, never from the keyboard; the identity of the FPV mesh isweapon_iw4::bg_get_viewmodel_weapon_index.
To watch it live: IW4L_PERF=1 / PERF.md.