Skip to content

Motion, continued: every open motion issue, in full - #939

Open
nicolas-maman wants to merge 237 commits into
mainfrom
feat/motion-next
Open

nicolas-maman wants to merge 237 commits into
mainfrom
feat/motion-next

Conversation

@nicolas-maman

@nicolas-maman nicolas-maman commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Every motion issue still open, implemented in full, in this one pull request, continuing #921 (merged at 61964ad): #853 and its milestones, #903, #907, #909 to #911, #922, #929 to #938, #940 to #974. 32 of them are met here and closed by hand so far (listed at the end).

On this branch so far (to 2026-11-04)

Since 2026-11-05 (pushed, CI green unless said)

Done locally, landing next (each after the full list)

In progress (one agent each, in its own worktree)

Order of work from here

The full plan is in #853, section "Road to the merge and to Siltreach".

  1. Land Crowd instances stepped on the GPU: a million figures with the CPU's share near zero #991 once its shaders are regenerated; character: walk and run as separate gaits with a timed change between them, not mixed by weight across a speed band #974 with metrics: a foot thrown faster than its clip has it reads as nothing (FOOT_THROW) #972, then Motion warping: a take's root bent onto a target point and facing #987 and mover: a runner asked to a goal inside its turning circle orbits it and never arrives (one ran off the plaza) #973 on it; Animation over the network: the graph's inputs and events, not poses #911.
  2. The plaza (M6 migration onto the animation pipeline; old writers retired #860, Plaza: walkers by the ramp and steps cross their feet 263 mm and pop joints at 112 to 165 rad/s #977, Plaza on characters: frame time 6.9 ms to 9.7 to 15.7 ms mean with 24 mannequins #980), the car fixes (Plaza: when the car ends up above a dummy, both fly off into space #982, Avoidance does not see a person lying struck: walkers walk through the body #979), the steering speed-up redone on the new mover.
  3. Phase C: Traversal: jump, fall and land, vault, mantle, ledges and ladders #986 traversal (on Motion warping: a take's root bent onto a target point and facing #987), M3 IK and constraints: two-bone with limits, FABRIK, full-body IK, foot placement, aim, hand IK (L3) #857's one foot system, Two-person scenes: handing over, carrying, grappling, talking #909, Get-up: an arm the protective reach leaves overhead is swept through the floor at the hand-over (seed 26: a finger 25.8 cm under); blocks the reach as default #1001, Faces: blend shapes, blinks, saccades, eyes that look, visemes #910's consonants. Phase B: Shared meshes: world bounds written into the mesh would race once bounds run on the job pool #999.
  4. M6 migration onto the animation pipeline; old writers retired #860's retirement of the old writers, then the merge gate.

Every motion issue, in full

#854 M0, ground truth

  • tests/fixtures/people, as the issue lists
  • the metrics module, as the issue lists
  • a viewer tool: the figure with a skeleton overlay, the clip list, scrubbing, two figures side by side, the metrics on screen
  • the old motion modules frozen: bug fixes only

#855 M1, skeleton, pose, clips, retargeting, root motion

  • skeleton: up to 256 bones, skinning's 96-bone cap lifted, a humanoid map onto the UE5 names
  • pose: flat local transforms; local and model space; blend, additive, mirror
  • clip: skeleton-indexed tracks with a sampling cursor; a root track; events; contact and sync markers found at import
  • retarget: chain retargeting with rest alignment, chain scaling, pelvis height, feet and hands kept on their contacts (UAL1 Rigify and 100STYLE onto the UE5 mannequin)
  • root motion moving the capsule, or held for in-place use

#857 M3, IK and constraints

  • two-bone IK with limits, soft reach and twist distribution in rig; motion's private copy gone (3dccf75)
  • FABRIK chains (spine; chain_solve, a cone per joint; no tail rig to test yet)
  • full-body IK with effector weights (body_new/body_set)
  • foot placement from contact markers (pelvis offset, lock, toe and heel, slopes and stairs): one foot system replacing the four
  • look and aim over several bones (look_solve, aim_chain)
  • hand IK on props: a bowl in both hands (Hand-backs between motion and the animator pop joints, sink a sole and slide the feet #933), a rifle with two hands

#858 M4, physics asset and physical animation

#859 M5, ragdoll and get-up

  • full ragdoll on a knockdown or death, keeping the animation's velocities
  • rest detection (motion.down; test_knockdowns, 100 of 100 up within 0.22 s of rest)
  • get-up from a pose snapshot into a matched clip, the capsule under the body, the clip warped onto it, inertialized back into the graph
  • get-ups clear of other bodies and of the ground
  • partial ragdoll for hits, blending back

#860 M6, migration

  • the plaza, the motion showcase and the editor's figures on the new pipeline
  • Siltreach told how to move, with the SHAs
  • eating with a bowl on the pipeline: the bites to the mouth over a held carry, as test_eat holds motion.eat
  • retired: per-node clips and string lookup, every direct writer of skeleton bones, locomotion's second foot lock, motion's keyed get-up, sit, kneel and lie, hold and eat

#861 M7, behaviours on physical animation

  • balance, catch steps, staggers, protective falls, crawl and writhe on L4, the animation as the reference, measured against L5 and shipped only where they look better

#862 M8, crowds and animation LOD

  • crowd pose banks baked from the graph's clip data (0cbba27)
  • update-rate LOD for distant figures (0cbba27)
  • hand-over between a crowd instance and the full graph by pose snapshot (0cbba27)
  • a cost per figure per frame at each LOD, against a 2,000-figure budget (1a268f4; 3.1 ms against 2 ms planned, still open)

#907 the generic pieces fighting is built on (rescoped: the moves, their order, timing and damage are the game's)

#903 the character component

  • the showcase's figures each set up in a few lines through it (all eight, 6d524e6); the README's animation example the real code (examples/people)
  • every check in test_anim_pipeline and test_ik_constraints holding through it (so far through it: walking, stopping, strafing, turning on the spot, looking, aiming, stairs, a ramp, seats; test_humanoid 15, test_use 4)
  • states, takes and transitions declared as data: ae3d.animgraph (test_animgraph)

#909 the generic pieces two figures need (rescoped: the scenes themselves are the game's)

#910 faces

  • morph targets imported and drawn on both renderers, their weights as pose channels (487dfff)
  • an ARKit-like face set mapped as the body's humanoid map is (e444397 maps it; no CC0 face with ARKit's 52 shapes exists to commit; VRoid's own set is mapped for blinks and vowels)
  • procedural blinks and saccades, eyes turned by the look IK (834e998, 97c2dc2)
  • visemes from a voice track (dddae7f: five vowels; consonants and recorded speech left)

#911 animation over the network

  • the graph bit for bit the same on two peers from the same inputs, across platforms
  • a remote figure under 150 ms latency with jitter and loss within 2 cm and 2 degrees at its feet and hands
  • bytes per figure per second measured

#922 the get-up after a trip at a run

  • reproduced in an ae3d test, and the figure stands

Part of

Closed by hand once met on this branch (the PR says Part of, never Closes):

…er it (#934)

The ground under a foot was the first standable surface down from 0.6 m
over it, so whatever hung over a foot within that was its ground. A figure
stood with its heels 6 cm under a bench's edge (its underside 10 cm up) stood
with its heels on the bench, 45 cm up; as a heel rose into the underside
walking off, it took the bench's top for its ground and its right leg turned
74 rad/s (29 walking off the open floor).

physics.ground_below reads the ground as a foot does: down from just under
the underside of whatever is over the point (or from 0.6 m over it), the
first surface a foot can stand on. A point that came into a solid from
under it (the solid over a gap a foot fits in, 5 cm or more between its
underside and the ground under it, and the point nearer that underside
than the solid's top: a heel risen into a bench or a log's rounded flank)
stands on what is under the solid. One pressed into a solid from over it
(a sole a clip has in a ramp or a tread) or inside one resting on the
ground (a step's riser a toe comes to, a block set under a foot) stands on
its top, as before; read as come in from under it, test_humanoid's soles
in its 20 degree ramp, a slab with room under its high end, were drawn
532 mm into it. An underside counts as over a point only with that room
under it: a block's bottom flush on the floor
over a sole at the floor's top is the block resting there, read from over
it (taken as an overhang, test_anim_pipeline's foot over a block set under
it read the floor under the block while its soles stood on the block's top,
jumped 10 cm onto it in a frame and bent its toes 80 degrees; eased onto it
as before, 4.4 degrees a step at the most). ikrig and the meter read
the ground through it, and the meter how far a sole is in a solid as the
shorter way out, up or down (static_depth): a heel risen 3 mm into the
bench's underside read 347 mm, the depth to the bench's top. A point is in
a solid only 1 mm or more under its surface (INSIDE_SKIN): one on it reads
either way as a ray's rounding falls, and a heel standing on test_humanoid's
floor read 600 mm into it.

feet_reset forgets the toes' speed and the swing's clearance: read from where
a moved figure's toe stood before, its speed raised a clearance and looked
ahead for an edge as if it had swung there in a frame.

test_feet_overhang: the mannequin standing with its heels under a bench's
edge, then walking off: its heels on the floor (9.5 mm), no sole more than
3.0 mm into the bench, its fastest joint 29.4 rad/s as off the open floor.
test_ground_queries: under the bench the ground is the floor (0.45 read from
over it), risen into it from under it too; inside a step, and at the
floor's top under it, the step's top; 1 cm into a ramp's top over room
under it, the ramp. test_humanoid's stairs and ramp read as on 61964ad (a
planted toe 1.6 and 4.5 mm, no sole into them).

Part of #934
Aether 0.880.0 removes contrib.host.lua, which ae3d does not import, and
0.871 reads s[i] on a string as a checked int from 0 to 255 and compiles in
time linear in a program's size again (aether#3499). All 311 programs ci.sh
builds and the editor (against aether-ui 51d1ae75, AETHER_UI_REF) compile on
it without an error or a warning; aephysics ad0cae2, its main, builds on it.
…e9fa15)

The editor was checked on 0.880 against 51d1ae75 before main moved
AETHER_UI_REF to 58e9fa15 (#924); CI's linux-editor builds it on 0.880
against 58e9fa15, warning-free.
#921 merged without its changes note; this one says what it brought, with
the numbers it was measured at, and what #939 has added since.
…less slots (#940, #942, #944, #949)

Four gaps Siltreach met moving its people onto ae3d.character:

- character.physical(c) (#940): the figure's ragdoll (ae3d.physanim) put on
  it now rather than at its first blow, its bodies following the
  animation. Put on at the first blow alone, an unhurt person had no
  bodies, and ae3d.items' edge, which meets only moving bodies, passed
  through it. test_items: a person standing where a sword's edge passes,
  unhurt, is not hit (no bodies); made physical, it is hit once on its
  ragdoll. character.hit puts the bodies on through it as before.
- character.pause(c), resume(c, at, facing), paused(c) (#942): held by
  something else (ae3d.motion's fall and get-up, a cutscene), the character
  leaves its object, mover and capsule alone and asks for no look or aim;
  resumed, the object is put where the body was left, the mover settled on
  it at rest and the feet planted afresh. Stepped on through it, a mover
  walked its object on at the last speed asked, under the body a fall
  held. test_character_pause: paused a second while asked to walk on, the
  object moves 0 mm; resumed 3 m aside facing back, it stands there (0 cm,
  0 degrees) and walks 3.1 m in 3 s, a toe skating 2.1 mm.
- Takes shared (#944): the gaits make a figure file's 14 takes (the stand,
  the eight gaits and mirrors, the starts and stops and their mirrors)
  once, keep them, and every character of that figure shares them
  (animator.share_take), the first one too. Each character read and
  retargeted every capture again, a camp of 20 settlers 20 times.
  test_character_share: 20 mannequins on one set of gaits play the same
  takes; the first is made in 227 ms, the others in 72 ms each; the first
  and the twentieth asked alike stay within 6e-8 rad of each other for
  3 s, and with the first freed the others walk on alike. The gaits are
  freed after the characters on them, as every caller already did.
- A slot that names no takes (#949) is held as it is reached, facing its
  way, until the figure leaves; it was refused, so a bedroll with no
  lie-down takes could not even be claimed and walked to.
  tests/fixtures/usable/spot.usable; test_use: from eight ways 3 m off,
  1.1 cm off the approach point and 9.6 degrees off its way at the most,
  held until it left, a toe skating 0.57 mm while held. Walking there and
  turning, a toe skates 11.9 mm, as it does for every slot (#952).

Part of #940
Part of #942
Part of #944
Part of #949
character.humanoid and graphed take a `scale` (1 by default): the figure's
object is scaled so before its animator, gaits, feet and capsule are made
from it, so all of them are at that size. Made at its file's size and
scaled after, a figure kept a capsule and gaits for the size it was made at
(Siltreach's people, scaled to 1.75 m). The capsule's radius and the room
over its head scale with it; the gaits keep a figure file's takes per scale
(the same file at another size is another set).

physics.character_height and character_radius say a capsule's size.

test_character_scale: the UE5 mannequin at 0.9 and 1.1 of its size, walking
at 1.2 m/s: its capsule 0.9 and 1.1 of its own, tall and round; its drawn
head 0.900 and 1.100 as high; a toe skating 1.6 and 1.9 mm.

Part of #943
A slot's take line can name the file it is read from, as an animgraph's
`take x Y from file` does: `enter Interact from people/ual1.glb`. Named by
name alone, a slot's takes came from the figure's own file or the one
character.use_takes gives, so a camp's people could not take UAL1's
Sitting and UAL2's Consume both. A take from a file is retargeted onto the
figure as use_takes' are, kept by file and name. A slot that names no enter
plays its loop where it holds the figure, if it names one (#949).

test_use_files: the UE5 mannequin, whose own takes are UAL2's, at a
workbench whose Interact and Idle_Loop are read from UAL1's file: its right
hand on the tool's grip at the contact (1e-14 cm); at a chopping block
naming no enter, its own TreeChopping_Loop played there, held until it
leaves, a toe skating 0.28 mm. test_use as before.

Part of #950
Part of #949
… comes down on its heading (#953, #954)

play_at and the matcher inertialized from the pose drawn last frame, its
lift and feet already on it, and the lift was laid on again: the drawn
pelvis moved 28.7 cm in a frame at a slot's take switches (Siltreach:
15 to 18 cm on a 0.38 m log). They ease out of the graph's own pose now,
kept before the layers, aims, lift and feet go on, as UE5 inertializes
ahead of its foot placement: 2.5 cm at the most.

A stepping foot came down on the clip's heading after its travel ended,
its toe swinging round the held ankle on the floor (9 mm, a fade's 2.5
degrees). It comes down on the heading it got to and is locked on it.

test_use: the drawn pelvis never moves 3 cm in a frame sitting on and
standing up from each seat.
…s takes listed; a reach from a point (#955, #957)

physanim dressed its ragdoll in place, which never weighed it, and a
kinematic body reads no mass: the UE5 mannequin's bodies weighed 34.3 kg,
Siltreach's people 38.5. attach weighs them as physics.person_mass of the
figure's height, character.physical as its standing height's, and
physanim.set_mass gives a game's own; ragdoll_mass and ragdoll_set_mass
weigh a body by its shapes, kinematic or not (69.7 kg; set to 80, 80).

animator.state_count, state_take_count and state_take_at list every take
every state plays, and metrics.animator_fastest reads the fastest joint
turn over them: 23.9 rad/s over the mannequin's 14 takes, against the
16.3 a game could read off the stand and the first gait.

physics.character_reach_from casts the capsule from a point, as a move
from there meets the world and the solid characters: within 0 m of the
reach stood there from five points four ways (test_character_reach).
…uches (#932, #952)

A stop's last step put its take's sole under the floor through the end of
its swing, and marked the foot down only 55 ms after it touched: left to
the clip till then, the drawn foot overshot and slid back 12 mm into its
lock, every walk to a slot (test_use's spot, 10.2 mm) and a seat's
landings at a fade's start (4.95 mm). A foot whose take has its sole on
the floor it was taken on, drawn within TOUCH of its ground and slowing,
lands there and is held until the take has it down or lifts it clear.
A take that sets its foot down above its floor lands on its own contact:
landed early on its heel, a toe swung 5.3 mm along a 20 degree ramp.

test_use: seats 1.18 mm (4.95); the walk to a slot 7.6 mm, its start's
creep (#932's second half) now its worst. test_humanoid: as before.
…tay on the haft (#959)

A held hand's fingers closed each frame onto the first touch alone: a
thumb whose arc ran along a haft opened a quarter of a fist in a frame for
4 mm of the hand's play, an index that could not reach shut to a fist, and
the fingers turned 23.5 rad/s through a walk (96 on Siltreach's people).
Each now closes from last frame's no faster than the captures' own fingers
turn (WRAP_RATE, 9 rad/s), and one out of reach rests where it comes
nearest the handle.

The handle's line was fitted to the second hand of the heaviest take of
a blend: a stopping figure's blend went from its run to its walk, the line
jumped, and the hand was 9.9 mm off its grip. It is fitted to the graph's
own pose (animator.pose_graph), every take of the blend.

test_items: held two-handed through a walk, a run and a stop, a finger
turns 7.6 rad/s at most (the takes' own 9.1), the second hand 0 mm off.
… and head (#960)

A character aiming looks at its target too, and the look, solved after the
trunk's aim, turned the aimed chest by a fifth of the head's remaining
turn: the rifleman's barrel went 4.79 degrees off its target as it looked
(Siltreach's pistol 4.2). The look's spine share is now what the aim leaves
(ikrig.look_spine, 1 less the aim's weight), as UE's look-at goes on the
neck and head over an aim offset: 0.15 degrees, as aimed alone.
…it (#932, #952)

A locked foot moved its lock from its heel to its toe only when the take
planted its ball. A start's foot rolled onto its toe, its heel 3.8 cm up,
its plant never said so, and its toe slid 6 mm forward about the heel. It
goes onto its toe as well once the clip lifts its heel TOE_FIRST over the
toe's tip.

test_use: walking to a slot and turning, a toe skates 3.7 mm at most (7.6
before, 10.2 before the landing hold). test_humanoid, test_anim_pipeline,
test_crowd_feet: as before.
…tops (#961, #930)

The mover braked at the stop take's deceleration from any speed: a walk
stop's 0.41 m/s^2 left a figure let go from a 3 m/s run going 1.35 m/s
four seconds on. A stop serves the speeds about its own
(clips.braking_speed, a quarter over): faster, the springs slow it to
them through its gaits first (mover.set_braking_below), and the stop is
played from there.

tests/test_stop_settle (#930): let go from a walk or a run, at rest
within 4 s (1.9 and 2.2); at rest no foot moves 5 mm in a frame; no toe
skates 5 mm.
… to its own item (#959)

Siltreach's play station sheathed its two-handed axe and drew a pistol in
one frame: the second hand flew off the haft at 34 m/s (44.9 in
test_items). Two causes: a one-handed item let the other hand go every
frame, whoever held it, and a hand was let go toward the world's origin
while its weight eased out. An item now moves only the hands it holds,
and lets one go eased off where it holds it, its fingers round the handle
till it is off: 0.43 m/s.

Held through a stop, whose take hangs its arms apart, the haft's line put
its second grip 15 cm past the second arm's reach, the hand 7 cm off it.
The line now turns about the main grip the least that brings the second
grip within reach (SOFT_REACH of the arm): 0 mm.

test_items: 13 checks; held two-handed through a walk, a run and a stop,
the second hand 0 mm off its grip, a finger 7.6 rad/s at most.
…e capsule (#958)

A game played a knock-down, a get-up or any one-off take by pausing the
character, turning root motion on, playing a state and resuming it at the
object's place, and had to get that order right itself. character.act(c,
state, blend) plays a state once, its root motion moving the figure
through its capsule (a wall stops it), the mover left alone whatever is
asked; at its end, at act_stop or once the graph leaves the state, it
takes up its stand where it got to, the mover settled there: as UE's
PlayAnimMontage on a Character. acting(c) says whether it still plays.

tests/test_character_act: UAL2's Hit_Knockback_RM moves the mannequin its
take's 3 m (within 1 cm); a wall behind it stops it at its capsule's
radius; knocked down and got up by LayToIdle, it stands, a toe skating
2.8 mm; ended part way, it walks on asked.
…932)

A foot held where it touched, ahead of its take's contact, kept the
take's sole height: Siltreach's walk to a log's slot stood a sole 95 mm
into the floor. Its sole is laid on the ground while it is held (soles and
tilts down). test_use, test_humanoid, test_anim_pipeline: as before.
…963)

skeleton_clip_limb named the cut's joints by their places in the
skeleton passed, on every primitive: a figure whose eyes, brows and hair
are skinned apart, each skin's joints in its own order, had its head cut
for its left arm (Siltreach's MPFB drifter). It names the places, in the
skin the mesh is posed by, of the bone named and every bone below it.

tests/test_skin: the elbow's cut through one skin names the elbow and the
wrist of a mesh posed by another skin of the same bones in another order.
A knock-down lies for a while before its get-up: a snapshot of where the
body fell (animator.snapshot) is a state with no take, and act refused
it. It is held now until act_stop or the next act, so knocked down, out
and up again are three acts (Siltreach). test_character_act: lying a
second held where it fell, then up by LayToIdle.
…932)

A foot locked on its toe's tip, its toes bent to the ground, was put back
over its lock by one more solve of its leg: the leg solved again turned
the foot a little, and a toe rolling off a 20 degree ramp, 3 to 6 cm off
its lock after its bend, was left up to 5 mm off it. It is put back until
within TIP_HELD (0.5 mm), in at most TIP_PASSES (4) solves.

test_humanoid: over the ramp a planted toe slides 2.9 mm at the most
(4.5 before); the rest as before.
seal_loop refused a take any of whose joints ended more than LOOP_GAP
(10 degrees) off where it began, and left every joint unsealed: five of
100STYLE's six gait loops wrapped with a seam (0.2 to 0.4 rad at an arm,
the head, a foot or a toe), and the forward run's hands jumped 5 cm at
it. Held two-handed through a run, an axe's second arm turned 77 rad/s
there. loop_cut's loops are sealed whatever the gap (crop_sealed,
seal_within); other loops keep LOOP_GAP. Spreading a leg's gap over its
foot's swing alone, tried for the ramp, moved the swing a matcher
searches by and slid a matched walk's toe 124 mm; spread over the loop it
does not.

test_items: held two-handed through a walk, a run and a stop, no arm
joint turns faster than the takes' own fastest (26.1 rad/s, the takes'
30.2). test_anim_pipeline's matcher: the fastest joint 17.8 rad/s (24.9).
test_humanoid's ramp 3.8 mm.
…s real time (CLOCK_MOST), as UE5's distance matching clamps its play rate; transition_need kept in the animator's state (#937)
…n off and walked back: within 1.5 times real time, no joint faster than the takes' own plus the easing's need, no toe skating 5 mm (#937)
… not lifted; the stagger sways again (#1000)

The feet drawn off pose_now with every leg body at weight 0 were not a stale
animation pose: the calves read back exactly, and the mannequin's 12-body
ragdoll has no foot body for capture_animation to keep. pose_rig_from's
toe_on_ground turned the drawn ankle up wherever the drawn toe dipped under
the ground plus TOE_UP, which a walk's roll-off does, so any physanim drawing
(a hit's chain on the trunk) turned the animation's planted foot by up to
0.116 rad and its toe slid 10 mm. ragdoll_show_pose takes per-side toes;
physanim lifts a side's toe only where that leg or the pelvis is drawn off its
bodies. character.shove sways the struck bodies with STAGGER_SWAY of the blow
again; test_balance holds the legs on the animation drawn as the graph has
them, toe skating under 5 mm (2.93 mm), and the joints within the gaits' own
plus the sway's share and easing.
#999)

geometry.mesh_world_bounds returns a mesh's world bounding sphere at a
transform and writes nothing but the mesh's own bounds the first time;
mesh_local_bounds reads those. The mesh's world fields, mesh_compute_bounds
and mesh_bound_x/y/z/radius are gone: written into a mesh every figure on
it shares (core.model_share_mesh), two figures bounding on the job pool
would each have read the other's. Their callers, core's
model_recalculate_bounds and vulkan's figure_reach, keep what it returns.
model_share_mesh works the shared mesh's own bounds out as it shares it,
local_bounds marks them known only once written, and a clone takes its
source's own bounds.

Found on the way: mesh_set_pos left the mesh's own bounds where its
vertices had been; now they are worked out again.

tests/test_shared_bounds: two models on one 60,000-vertex mesh, placed,
scaled and turned apart, updated from two jobs at once 2,000 times: 0
bounds not their own transform's to the bit, 0 of 16,000 values differ
run to run. test_geometry checks a vertex moved in place.
… one call

The plaza's box men on ae3d.locomotion, ae3d.feet, ae3d.lookat and their
POWERED motion ragdolls are now the UE5 mannequin made a character
(character.humanoid on 100STYLE's neutral gaits), its capsule solid, its
bodies on it from the start (character.physical). The car's strike is
test_knockdowns': the character and its animator paused, its physanim
bodies released to ae3d.motion LIMP, the car meeting them; at rest
(motion.down) it gets up with character.get_up(c, m, 0.4), stands 0.4 s
and walks on. The scene, layout, car, lanes, camera and report lines are
kept; the walking crowd is metered by ae3d.metrics as people_plaza is
(toe skate, feet crossing, fastest joint, FOOT_THROW) and the get-ups
against their take's own fastest joint. Retired from the tool: the parked
ragdolls and their waking, the look's own module, motion matching on the
box man, the flat-floor feet and the box man's toe thresholds. A stance
is now a foot locked by ikrig with its pad within metrics.CONTACT, its
toe tip measured; the knee's hinge is taken from the way the figure
faces (the box man faced -z, the mannequin +z).

Seeds 2, 4, 5, 4800 steps at AE3D_TICK=60, before (box men) and after:
  stances, toe slid mean / most / over 1 cm:
    2: 3667, 0.064 cm / 9.31 / 77  ->  2802, 0.010 cm / 3.16 / 5
    4: 3687, 0.074 cm / 10.0 / 86  ->  2812, 0.024 cm / 2.59 / 10
    5: 3673, 0.053 cm / 8.56 / 63  ->  2662, 0.016 cm / 2.22 / 8
  struck, walking again, s struck to walking:
    2: 30, 30, 5.94 -> 8, 8, 3.64
    4: 28, 25, 6.44 -> 32, 30, 3.59
    5: 26, 25, 6.79 -> 19, 15, 3.61
  frame, mean ms: 6.9 -> 9.7, 9.8, 15.7
  heads spinning s: 0.32, 0.60, 0.92 -> 0.47, 1.67, 0.78
  legs splayed s: 0.40, 0.52, 0.30 -> 0.57, 3.63, 9.90
  in the car s: 0.25, 0.75, 0.08 -> 0.15, 0.23, 0.10
  sunk s: 0.07, 0.07, 0.07 -> 0, 0, 0
  bodies walked through s: 2.02, 0.02, 0 -> 0.17, 0.03, 0
  metrics, walking (new only): toe skate 29.7 / 37.9 / 48.1 mm at worst,
  feet crossed 263 / 242 / 282 mm, fastest joint 112 / 165 / 121 rad/s
  (takes' own 27.9), FOOT_THROW 7.4 / 19.8 / 8.0 m/s.

Part of #860
The scene's ramp was tilted the wrong way and its steps stood in the
wrong order: the ramp's high end stood 0.5 m over the floor facing the
plaza, and the steps' 0.45 m riser faced it, the 0.15 m one against the
deck's 0.6, where the comments have a ramp up to the deck and steps down
from its side. Both were walls the crowd walked into (#977). The ramp
now rises from under the floor at z -0.6 to 0.5 m at the deck, and the
steps rise 0.15 m each to the deck's side.

AE3D_TRACE=k prints person k step by step while it walks: its meter's
reading, each foot's ikrig target and lock, and the ground under its
heel, pad and toe.

Seeds 2 / 4 / 5, 4800 steps at AE3D_TICK=60, with the mover and ikrig
changes (before: ee1e2116):
  sole into the ground: 104 / 167 / 128 mm (583 / 600 / 599);
  feet crossed: 209 / 174 / 163 mm (263 / 242 / 282);
  fastest joint: 148 / 89 / 132 rad/s (112 / 165 / 121);
  toe thrown: 5.8 / 7.0 / 6.8 m/s (7.4 / 19.8 / 8.0);
  toe skate: 14.6 / 100 / 96 mm (29.7 / 37.9 / 48.1);
  struck, walking again: 6, 5 / 33, 31 / 24, 23.
#977's bounds (crossing under 5 mm, throw under 1.5 m/s, sole under
5 mm) are not met yet on the plaza.

Part of #977
… over it

The plaza's car flew off with a dummy (#982), on seeds 2 and 5 of ten
(4,800 steps): 12 m up at 15.7 m/s, 45 m/s level. Traced step by step,
both the same: a struck person got up beside or under the car where it
stood. Its capsule, stood up into the car's box, was pushed out by the
mover 0.85 m (seed 5) and 1.3 m (seed 2) in one step; physanim's
kinematic hips and legs, driven onto the rig at the speed that takes,
went after it at 48 and 75 m/s with no mass to give, and hit the car's
wheels and box. Not aephysics: its contact push-out is capped at 3 m/s;
a kinematic body asked to move 1.3 m in a step moves so.

- physics: a figure whose kinematic pelvis is farther from its rig than
  KINEMATIC_TELEPORT (20 m/s) goes in a step was put somewhere, not
  moved: every body and anchor is put on the rig at once and still
  (put_on_rig), a limp one carried with the pelvis, as Unreal teleports
  the bodies on a teleport move. capsule_room: whether a capsule stood
  at a place is clear of every body that moves but the figures', asked
  as an overlap at any depth (the mover's planes end once the axis is
  inside a box).
- character: one wait for a get-up, merged with #835's way scoring. A
  figure told to get up (get_up) lies on by itself while something that
  moves, not a figure, stands where it would stand up (room_to_rise: its
  capsule 0.25 m wider on the ground under the pelvis), as it does while
  its way is not clear: get_up_waiting says so, and it looks again every
  WAIT_LOOK (up_wait). With no room at all it waits past WAIT_MOST, for as
  long as the car stands there (up_blocked). The waiting setup is one
  function (up_wait_set) for both.

test_car_over_body (new), the plaza's car (1.2 t on sprung wheels) and
the mannequin knocked down LIMP, 8 seeds; before / after:
  put 1.3 m past a 200 kg crate in a step: the crate 6.1 / 0.004 m/s,
    a body up 18.4 / 0.84 m/s;
  run over at 7 m/s and braked over the body: car up 0.74 / 0.74 m/s,
    a body up 2.8 / 2.8 m/s (no change);
  got up under it, told once: the car lifted 0.65 / 0.08 m, a body up
    12.7 / 4.9 m/s; get_up_waiting holds on 8 of 8 seeds while the car
    stands, and all 8 are up once it is gone.

Part of #982
steer skipped a paused character, so walkers walked through a person
lying struck (#979). A character paused with its ragdoll let go to
another writer (physanim.released: a fall) is now its bodies on the
ground: each body's capsule, its two ends and its middle
(physics.ragdoll_bone_segment), a neighbour standing still as wide as the
capsule, the body met when any of them is, and the meeting counted once
per body. A body lying turns no way, so its meeting is read against the
walker's own way (not RVO's 2v - v_mine - v_theirs) and weighs twice a
person's share: at a person's share the turn to clear a body lying along
the way cost more than the meeting until the walker was already in it,
and it walked through the body unturned.

test_walk_round_body (new): the mannequin knocked down LIMP 3 m ahead of
another asked to walk straight on at 1.2 m/s, 16 seeds; before / after:
  the walker's capsule kept -0.265 / +0.063 m off the lying bodies'
    capsules at least (32 seeds after: +0.063);
  got past it, 1.5 m beyond: 3.28 / 3.59 m at least.

Part of #979
- A struck person asked to get up while the car stands over it
  (character.GET_UP_WAIT) lies on and is asked again the next step;
  handed over regardless, it was put in RISING with no get-up played.
- Measured every step and reported (#982): the car's chassis risen over
  its ride height and its fastest up, any person's body fastest up and
  highest, and the seconds get-ups waited. AE3D_LAUNCH=1 prints what goes
  up faster than the car comes (7 m/s): the car, the people within 3 m of
  it and the fastest's bodies; AE3D_LAUNCH_AT=n prints steps n to n+30
  body by body, with the car's wheels.

Seeds 0 to 9, 4,800 steps at AE3D_TICK=60, the car's fastest up and its
most over its ride height, before (da0b8a11) / after:
  seed 2: 15.7 m/s, 11.7 m / 2.65 m/s, 0.46 m;
  seed 5: 15.8 m/s, 12.2 m / 0.76 m/s, 0.02 m;
  the other eight: under 1.2 m/s and 0.18 m / under 1.5 m/s and 0.21 m,
  but seed 0, 2.5 m/s and 1.35 m: a struck body squeezed under the
  braked car off the plaza's edge lifts it (not a get-up; left open).
Struck people sunk in the ground: 0 s on seeds 2, 4, 5 (216 / 100 /
0.05 s before). Get-ups waited 1.2 to 8.5 s a seed for the car.

Part of #982
Traced on the plaza (#977, AE3D_FLAG), the worst crossed feet were walkers
shouldered by a neighbour's capsule, not struck people: seed 5 person 9
went 0.29 m sideways in one step (17.4 m/s) as a person got up where it
stood, and its locked feet crossed 235 mm; seed 4 person 0 was shoved at
4.2 m/s and crossed 325 mm. A solid character's move put each near one as
a plane at the gap between them, so one found inside another (put there:
a get-up, a teleport) was pushed out of the whole overlap in one move.

Now the gap each near one had as the move began is kept (gather_near), and
a capsule inside another ends the move no deeper, eased out at
CHARACTER_PART (0.5 m/s), as a person shouldered steps aside.

test_character_walls: two scenes.
  walking on while a solid capsule is put 0.29 m inside its own beside
  it: sideways at 17.03 / 0.16 m/s at most (before / after), feet crossed
  206.8 / -28.8 mm, a toe thrown past 1.5 m/s / not;
  walking into a 0.6 m block 27 degrees off square to its face, as the
  plaza's walkers came to the deck: -7.8 mm crossing, 1.17 m/s thrown (held on
  both).

Part of #977
…p's own feet

AE3D_FLAG=1 prints every walking person's step past a crossing (5 mm), a
pop (40 rad/s), a throw (1.5 m/s), a skate or a sole into the ground (5 mm):
where, its mover's velocity against how fast its capsule really went, the
nearest person, and how long since it set off again after a get-up. The
trace (AE3D_TRACE=k) gains the mover's velocity and facing, the graph's
state and how far the clip's own foot crosses, which told the causes of
#977 apart: a wall or a neighbour holding the capsule, not the get-up.

Part of #977
…d its contacts

AE3D_TRACE=k now prints where the graph's pose has each ankle (the clip's
own feet over the ground), the current state's ground speed and each
foot's contact weight: what showed seed 2 person 22's clip foot drifting
29 cm off its lock as the blend swung at the deck's face (#977).

Part of #977
…977)

- physics.ground_below: a point inside a solid that rests on the ground
  under it is in that one, whatever hanging solid it is also in; and one
  nearer a hanging solid's side than its underside came in through the
  side. A sole in a ramp's end sunk into a deck's side was read as under
  the ramp and dropped 10 cm into the 13 cm lip.
- physics.static_way_out: the shortest way out of the static world for a
  point inside it, up, down or level, through the solids it comes into.
- ikrig.off_walls: a foot whose heel, pad or toe would stand in a solid it
  cannot stand on, its shortest way out level, is moved out of the face,
  and a locked foot's lock with it. Toes went 167 to 187 mm into the
  plaza's deck as walkers strode on against it.
…e face it came in by (#977)

- ikrig.off_walls moves a sole out only of a solid that goes on up
  physics.STEP_HEIGHT over it: a slab's side within that is ground the foot
  comes onto. Moved out of the plaza ramp's side, a foot walking along its
  edge was put off it and in it by turns, 29 mm in and a calf at 68 rad/s.
- It goes out the way it went out last frame while that comes out within
  WALL_KEEP of the shortest (physics.static_way_along): out of its shortest
  way alone, a toe in a deck's corner went out of one face, then the other.
- physics.ground_below no longer takes a point nearer a hanging solid's side
  than its underside as come in through the side: off_walls no longer needs
  it, and it put a walker's sole 6 mm into the ramp's edge.
- test_feet_edges measures a toe thrown past its clip too.
Rebased onto the get-up's way scoring (#835): character.get_up is told
once and the character lies on by itself while its way or its room is
not clear; the plaza counts those steps, and makes the capsule solid and
measures the get-up once it is on its way up.

Part of #977
, #977)

test_get_up_pair went 7.8 cm past its 0.02 m bound once the figure put is
put (KINEMATIC_TELEPORT). Traced (AE3D_PAIR_TRACE, the puts printed): the
test stands the second figure beside the first's hips, 3.3 m from where it
stood. Swept there, its kinematic bodies went at 200 m/s through the first
lying body and threw it 2.5 m: in the layout 0.1 m apart turned a quarter
the two lay 0.96 m apart, and the case the test sweeps never came about.
Put there, they lie 0.50 m apart, one across the other's hips, and every
way up of either figure, as laid and at every turn (0, +-0.5, +-1 rad, and
tried to +-2 and a half turn), went 0.10 to 0.27 metre-seconds into the
other's body. The least went first and drew its hips 7.8 cm into the
other.

Now a way still into a body near at every turn is laid off the body
(up_shift): 0.15, 0.30 and 0.45 m, eight ways round, its pose's distance
paying for the shift, the hand-over easing the body there. test_get_up_pair,
18 runs: inside each other 0.167 / 0 s, deepest 77.7 / 0 mm (before /
after); waited 1.65 / 1.3 s at most; planning 1.16 / 1.00 ms mean. The
test notes how the stand is put and prints where both lie
(AE3D_PAIR_TRACE=1). test_knockdowns, test_get_up, test_get_up_feet and
test_car_over_body pass.
…, #909)

Three scenes walked from eight starts 0.1 m apart, so the capsule is
stopped at every point of the stride; the single start the 27 degree
scene had passed (-7.8 mm, 1.17 m/s), stopped where the gait's feet
happened to be fine. Their worst, today (held to with AE3D_WALLS_ALL=1,
not met yet):
  into a 0.6 m block 27 degrees off square (the plaza's deck, seed 2
    persons 22 and 2): a foot 155.7 mm past the hips' middle, a toe
    thrown 3.77 m/s, 22.8 rad/s;
  square into it: 54.4 rad/s (the gaits' own 14.7), a toe thrown 6.86 m/s;
  into a person standing on its driven bodies (#909's embrace, test_pair
    PAIR_ONLY=3): a foot 174.6 mm past the middle, 37.3 rad/s, a toe
    thrown 5.68 m/s.
The ramp's calf now reads 32.8 rad/s (gated as before). AE3D_WALLS_EACH=1
prints each start, AE3D_WALLS_START=n walks one.

Tried and not kept: the graph told it stops when what is asked goes only
into the wall it is held against (mover: asking by the asked less the wall,
along_wall): square into the block 37.8 rad/s and 2.31 m/s, the person
37.1 rad/s and 11.3 m/s; not a fix at the root.

Part of #977
…n bodies (#977, #909)

A walker coming to embrace another (#909's test_pair, PAIR_ONLY=3) was
stopped mid-stride by the other's arms while its walk played on, a ball
turning 38.6 rad/s. A capsule's moves met every shape but its own figure's
ragdoll, so a figure standing on its animation was met twice: by its
capsule (character_set_solid) and by its kinematic bodies, which reach
past the capsule (arms out to embrace) and which no capsule can push.

Now, between solid capsules, a body of another figure's ragdoll driven on its animation (its pelvis
kinematic, not let go) whose figure has a capsule is passed by the capsule's
casts and planes (driven_figure), as Unreal's capsules meet each other and
not the other's physics asset. A figure let go (limp, lying) is still a
body walked into and pushed; capsules that are not solid still meet the
bodies (two figures getting up side by side, met by neither, went 14 cm
into each other: test_get_up_pair).

test_character_walls, walking into a person standing (its avoidance off,
both capsules solid), eight starts over the stride: a foot 174.6 / 1.0 mm
past the hips' middle (before / after; held to now), 37.3 / 54.4 rad/s and
a toe thrown 5.68 / 6.80 m/s: now met by the capsule as square at a wall,
the root still open (held to with AE3D_WALLS_ALL=1).

Part of #977
… foot's lock and target

AE3D_WALLS_TRACE=n now prints, a step at a time, the toe thrown past its
clip and each foot's lock and target: what showed a walker stopped square
at a wall, stood in its idle, stepping its feet together at 2.3 m/s past
the idle's still feet (#977).

Part of #977
…le steps out

Traced on the plaza (#977, AE3D_TRACE with the clip's own feet): seed 2
person 22, held back by the deck's face while its velocity swung to the
side and its gait's blend with it, kept its left foot locked 0.67 s while
its body went 26 cm left over it. The clip's own left foot drifted 29 cm
off the lock (the blend's weights swinging and the facing turning
0.9 rad/s), just under LOCK_SLIP, so the lock never let go: the foot drawn
179 mm past the hips' middle, the clip's own 100 to 214 mm short of it.

Now a locked foot is let go as a slip (lock_crossed) when it is drawn past
the hips' middle toward the other foot's side while the body itself goes
over it sideways (0.1 m/s or faster, by the figure's place over the
ground, Feet.going) and the clip keeps that foot on its own side, 2 cm or
more further out than the lock. Judged against the clip's own foot: a
catwalk's or a run's own crossing is left to the clip, and a side gait's
stance foot, which never comes past the middle drawn, is held as the clip
has it. Let go, the foot is drawn no further past the middle than the
middle itself, as it is let go and through its step (not_past_middle), its
step carries it from its first frame, and once down it is held again at
once (left to a blend 93 to 97% down it went along the floor with the
clip's drift: a toe skated 77 mm beside a neighbour).

Tried and not kept: read 0.1 s ahead at the body's rate, the 2D blend's
side steps (drawn and clip stance feet 50 to 60 mm apart by the blend's
drift alone) were let go 50 mm out and a toe slid 21 to 55 mm; ahead at the
rate the drawn foot nears the middle, a walk's hip sway let straight-walk
stance feet go 45 to 117 mm out; a foot set down mid-release caught where
drawn (088be2b3) broke the start/stop's 5 mm slide (33 mm), and is left out.

Functions changed in ikrig: feet_solve (Feet.going from the place it
already tracks, the clip's hips' middle and line across them), lock_foot
(the let-go test and the immediate re-hold of a crossing slip), slip_step_at
(the step's carry and clamp); new: lock_crossed, not_past_middle,
cross_slip_set, cross_slipping.

test_character_walls: walking ahead at 0.7 m/s while its capsule is moved
0.45 m/s to its left for a second, its mover not told: crossed 225 / 0.0 mm
(before / after), a toe thrown 2.93 / 0.80 m/s. Its other six scenes read
the same as before.

Plaza (AE3D_TICK=60, 4800 steps), seeds 2/4/5, before / after:
  crossing   179 / 244 / 169 mm  ->  111 / 27 / 14 mm
  thrown     7.2 / 4.8 / 4.3 m/s ->  7.6 / 7.2 / 7.0 m/s
  skate      3.4 / 114 / - mm    ->  139 / 100 / 87 mm
people_plaza seeds 0/1/2 (1800 steps): crossing 0.97 / 2.27 / 3.82 mm and
skate 2.99 / 3.01 / 2.98 mm, as before.

Part of #977
…o edge ahead the figure cannot step onto (#977)

Traced in test_character_walls' swept scenes (#977, #909): a walker
stopped square at a wall or a person mid-stride, stood in its idle, stepped
its feet 0.3 m together in STEP_TIME (0.28 s), 2.3 m/s past the idle's
still feet. Now a standing step takes as long as STEP_GAP_SPEED (0.65 m/s)
takes to cover its gap when that is longer than STEP_TIME, as a turning
step already does by TURN_TOE_SPEED.

A swing's look ahead for an edge (foot_ground) takes one only no more than
physics.STEP_HEIGHT over the figure's floor: beside the plaza's steps, one
foot on a 0.3 m tread and the capsule on the ground, a swing toward the
0.6 m deck's face read the deck's top ahead and lifted the foot 0.58 m in
four frames, a calf at 40 rad/s (test_feet_edges' walk 10, the walker
coming to the deck slower).

Tried and not kept: a release taking as long as 0.6 m/s takes to cover how
far it goes (a trailing foot 0.26 m off its clip eased there in 0.15 s, a
toe thrown 3.1 m/s): the swept walls' throws fell from 6.86 to 2.18 m/s,
but test_items' second swing from a stand skated 7.2 mm and test_use's
sits 6.4 mm, the release still easing along the floor after the clip set
the foot down.

Part of #977
… pipeline, gets up and walks on (#922)

The mannequin running at 3.45 m/s at a 0.2 m kerb set 3.0 to 4.0 m ahead.
Its legs drawn on the animation pass through what they meet, so the trip is
the moment a drawn foot meets the kerb, answered with character.knock and no
blow: physanim lets every body go at the velocity the run gives it, the kerb
catches the shins and the body goes on. Down, then the planned get-up. Held
to test_get_up_kerb's numbers on all nine: it falls and rises, its trunk
0.006 rad off how it stood once its stand is taken up, it moves 0 cm the
second after and stands, walks on 3.1 m in three seconds never falling, and
ten seconds on stands at its standing height.
…st the take's own (#994)

Seed 40 struck 1.3 times as hard with its side turned 0.5 rad: over the 0.4 s
turn the forearm turned 2.7 rad and its upper arm 2.3, and the elbow's and the
shoulder's lifts (1 and 0.6 rad, each about its own axis) composed with them
turned the forearm against the upper arm at 35 rad/s, the turn alone at 13.8,
against LayToIdle's own 26.5. plan_slower plays the planned hand-over back at
60 Hz (the take, the turn, the drop and the lifts, from its first moment as
get_up draws it) against the take's own fastest; plan_turn lengthens the turn
and the drop by the ratio (5% more, up to EASE_MOST) and plans the lifts again.
Seed 40 so: 7.96 rad/s under the take's own.
… the hand-over held to the take's own (#994)

Two more landings of each seed, struck 1.3 times as hard with the side
turned 0.5 rad either way, and the snapshot-to-clip check held over every
landing. 500 of 500 up; the worst joint 0.22 rad/s under LayToIdle's own,
under the floor 1.06 cm. The test takes 96 s, 61 before.
…'s leaks found it (physics_free releases only the world's own characters)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant