mirror of
https://github.com/vladtrc/iw4L
synced 2026-10-26 18:25:39 -04:00
38aa9cf741
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.9 KiB
2.9 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::get_viewmodel_weapon_index. The FPV consumer readsPreparedFpvonly, never the weapon registry: views, rigs and material bindings are built before Ready; an equip picks one, and a mandatory material that failed is a refusal naming model, surface and material. Remote kits (PreparedRemoteKits: models, hide bits, shared DObj) and dropped items are composed at install, not on first sight.
To watch it live: IW4L_PERF=1 / PERF.md.