Skip to content

get-up: two knocked figures getting up side by side are drawn inside each other for up to 2 s #835

Open

Description

@nicolas-maman

Two figures the car has knocked down, getting up next to each other, are drawn inside each other for up to two seconds. The keyed way up (motion.get_up, ANIMATED while it plays) plans its keys on the ground under the figure. It takes no account of another body beside it.

Seen in the plaza scorecard (AE3D_TICK=60, 28 walkers, seed 8, on #832's branch). Walkers 5 and 7, both KNOCKED and ANIMATED, are inside each other for 128 frames, from 27.9 s to 30 s. Their hips rise from 0.41 and 0.28 m to 0.84 and 0.44 m, 0.4 m apart. That one event is 2.1 s of the run's 2.85 s of "figures inside each other".

Main has the same class. For example, main at 24 walkers, seed 5 has 1.08 s, all with a struck figure. Which seeds show it depends on where the car leaves people, so it moves with anything that changes the walkers' paths. Over seeds 1 to 8 at 20, 24 and 28 walkers, "inside each other with one struck" was 4.25 s on main and 9.27 s on #832. About 80% of the branch's time comes from three such events.

Wanted: a figure getting up keeps its body off another figure's, struck or standing. Its planned contacts (hands, knees, feet) and the trunk's way up should avoid the space another body occupies, or it should wait and shift first, as a person does. Measure it with the scorecard's "inside each other with one struck", over seeds.

Activity

  1. nicolas-maman commented on Oct 20, 2026

    @nicolas-maman
    CollaboratorAuthor

    Plan, before the code:

    1. A space check on the way up. Before get_up commits to its keys, test each planned key's body capsules against other figures' bodies, own ragdoll filtered out. It uses aephysics' physics_world.overlap_shape (and cast_shape for the stretches between keys), through a new physics.ragdoll_pose_clear(r, pose) in ae3d. This is the check shipped get-ups make: GTA V and RDR2 pick a get-up variant by probing the space around the body, rather than playing one blind.
    2. A free way, else wait.
      • If the way up the figure would take is blocked, try the way turned toward the free side: a person lying against another rolls away from them to rise.
      • If no way is free, get_up answers false and the figure stays down (writhing, as now), and the caller retries.
      • To avoid two figures lying side by side each waiting on the other, a body that is itself waiting to get up does not block. Only bodies standing, rising or lying still count, so one of the two rises first.
    3. Test: two figures lying side by side, hips 0.4 m apart, both told to get up. No part of one comes within the other's thickness (the plaza's inside measure). On main they rise through each other.
    4. Measure: the plaza's "inside each other with one struck" over seeds 1 to 8, against main.
  2. nicolas-maman commented on Oct 20, 2026

    @nicolas-maman
    CollaboratorAuthor

    Correction to the plan above: get-up already keeps out of other figures. pushed_way (src/ae3d/motion/module.ae) was added for exactly this case: "Two figures rising into each other in the plaza were drawn up to 11 cm inside each other."

    • Each step it asks the world about the pose drawn and the pose LOOK_AHEAD on (physics.ragdoll_pose_push, against what moves).
    • It moves the whole way up out of the overlap at PUSHED_SPEED.
    • It holds the rise while the pose ahead is in something, up to HOLD_MOST.

    So a new check before get_up would duplicate it. The question is why it did not keep walkers 5 and 7 apart for those 2.1 s. Three candidates, to trace in the plaza run (28 walkers, seed 8, 27.9 to 30 s):

    1. ragdoll_pose_push may not count the other figure's bodies while that figure is itself getting up, because those bodies follow their keys rather than move freely.
    2. PUSHED_SPEED may be too slow for two figures rising at once.
    3. HOLD_MOST may run out.
  3. nicolas-maman commented on Oct 20, 2026

    @nicolas-maman
    CollaboratorAuthor

    Traced pushed_way in the plaza run (28 walkers, seed 8, 25 to 30 s), on main cc7e968. It is candidate 3, and more:

    • Both figures hold at once.
      • Walker 5, still lying (pelvis 0.18 m up), holds with the pose ahead 2.5 to 10.8 cm into something. It is moved out 27 cm along its way over the second.
      • Walker 7, sitting up (pelvis 0.48 m), holds too, and its depth grows while it is moved out: 0 to 11 cm over the hold.
    • Then both go. At HOLD_MOST (1 s) the holds run out (held 1 hold false). Each way up goes on with its pose 15 to 17 cm inside what is in the way. That is the 2.1 s drawn inside each other.
    • Walker 7's depth growing as it is moved out suggests a third body, or the pile they lie in, pressing on it, not walker 5 alone.

    So the defect is the policy, not the push. After HOLD_MOST the way proceeds blocked, and two figures in each other's way both hold, then both rise. A fix needs to know whose way is blocked by whom: one rises, the other waits until it is clear. Possible rules:

    • The way furthest along goes first, the other holds without a limit while the blocker is a figure that is rising.
    • A blocked way gives up after HOLD_MOST: the figure lies back down and tries again after its get-up delay, instead of rising through the body in its way.

    Next: a test of two figures lying one partly across the other, both told to get up, to reproduce it without the plaza.

  4. nicolas-maman commented on Oct 20, 2026

    @nicolas-maman
    CollaboratorAuthor

    Reproduced without the plaza, and one rule tried and dropped.

    Probe. Figure A is knocked onto its back. Once it lies there, figure C is stood beside A's hips and made LIMP, so it crumples onto A. Both are then told to get up on the same frame, and the probe measures the plaza's drawn "inside each other" (hips, chest and knees against the bodies' thickness, past 2 cm). On main, with C 0.2 m from A's hips and turned a quarter, they are drawn 1.77 s inside each other, 26.3 cm at the deepest: the plaza event.

    Rule tried: a figure whose way ahead is blocked by another figure that rises first (further along its way, or as far along and higher at the hips) holds past HOLD_MOST until it is clear. That needs physics.ragdoll_pose_push_by, the blocker's ragdoll, taken from the body's user data. Over 32 layouts (C 0.1 to 0.4 m from the hips, turned 0, a quarter either way or half round, beside A or 0.3 m along it):

    main with the rule
    drawn inside each other, all 32 12.37 s 11.12 s
    layouts past 2 cm 11 11
    deepest 26.3 cm 20.9 cm

    Mixed layout by layout:

    • Gap 0.2 to 0.4 m with C 0.3 m along goes from 1.2 to 1.6 s down to 0.17 to 0.43 s.
    • Gap 0.1 m, C 0.3 m along goes from 0.95 to 2.88 s.
    • Gap 0.1 m turned +90° goes from 0.08 to 1.57 s.

    The figure that waits lies still in the other's path, and the one going first still rises through it after its own HOLD_MOST. The hold order is not the cause, so the rule is dropped.

    Where the cause is: the first riser's way is planned on the ground as if alone. pushed_way then moves it only along the level part of an overlap (the push visitor drops overlaps whose normal is mostly vertical), at PUSHED_SPEED, and only up to HOLD_MOST. On another figure, its hands and knees are planted into that figure. The fix is in the planning: choose the way up and its contacts clear of other bodies (turned toward the free side, with contacts that rest on what is under them), as the plan above said.

    The probe is kept for that work.

  5. nicolas-maman commented on Oct 22, 2026

    @nicolas-maman
    CollaboratorAuthor

    Moved under the animation epic #853, milestone #859: get-ups become authored clips chosen from a pose snapshot, warped onto where the body lies, clear of other bodies and the ground.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions