Adds limb bending, the main reason for replacing player-animation-lib. It uses the same approach as the cloak renderer: a spine, rings of shared vertices along it, and faces drawn between the rings.
Core (no Minecraft)
Bezier: Bézier curves of any degree, with points and derivatives.
LimbBend: bends a limb along a single axis.
The spine is a cubic Bézier through the rigid "upper half, joint, lower half" shape. sharpness goes from a round curve to a tight joint (fixed at 0.5 for now).
The limb is cut into one piece per texture row (12 per limb), spaced evenly by arc length so the limb keeps its length.
Each ring moves as a unit, so neighbouring pieces share vertices and the mesh stays closed.
anchoredAtEnd keeps the far end in place, which the torso uses so the hips stay on the legs.
QuadSplitter: cuts vanilla faces at the rings and splits their UVs to match, so the texture is unchanged apart from the cuts.
Fabric
ModelPartMixin / BentCubeRenderer: any part with a bend is drawn by deforming vanilla's own cubes. Slim arms, sleeves, pants and armor all bend. Overlays and armor use the limb's spine, not their own inflated box, so they stay attached.
PoseApplier:
Bends are cleared on every setupAnim, because models are shared between entities.
The body bends from the hips, and the head and arms follow it: their pivots move with the bent torso and they turn with it.
Version differences: the only one so far is the vertex format, which changed in 1.21.9. It's handled with a Stonecutter branch.
Tester
New animations: flap, squat, bow and a rough twerk. The twerk is only a test pose and isn't close to other clients' twerks yet.
Screenshot test: ./gradlew :<mc>:runClientGameTest is a Fabric client gametest. It creates a world and screenshots each animation from several angles into versions/<mc>/build/run/clientGameTest/screenshots/.
Full Fabric API: the tester now runs with all of Fabric API, because single modules don't bring their dependencies, which differ between versions.
Testing
./gradlew :core:test: 27 tests pass (Bézier, limb and torso bends, face splitting, animation timing).
buildAll builds all 8 versions.
The screenshot test passes on all 8 versions. I checked the screenshots from 1.21.4, 1.21.9 and 1.21.11: joints stay closed and textures stay intact.
The final twerk tweak (arching the lower back) was only compiled on 1.21.4 and 1.21.11 and checked by hand in game, not in the screenshot test.
Known gaps
Held items still attach to the unbent arm.
The cape doesn't follow the torso.
The head and arms follow the body's bend but not its rotation, so emotes have to add the rotation themselves. This is a proposed follow-up.
Adds limb bending, the main reason for replacing player-animation-lib. It uses the same approach as the cloak renderer: a spine, rings of shared vertices along it, and faces drawn between the rings.
## Core (no Minecraft)
- **`Bezier`**: Bézier curves of any degree, with points and derivatives.
- **`LimbBend`**: bends a limb along a single axis.
- The spine is a cubic Bézier through the rigid "upper half, joint, lower half" shape. `sharpness` goes from a round curve to a tight joint (fixed at 0.5 for now).
- The limb is cut into one piece per texture row (12 per limb), spaced evenly by arc length so the limb keeps its length.
- Each ring moves as a unit, so neighbouring pieces share vertices and the mesh stays closed.
- `anchoredAtEnd` keeps the far end in place, which the torso uses so the hips stay on the legs.
- **`QuadSplitter`**: cuts vanilla faces at the rings and splits their UVs to match, so the texture is unchanged apart from the cuts.
## Fabric
- **`ModelPartMixin` / `BentCubeRenderer`**: any part with a bend is drawn by deforming vanilla's own cubes. Slim arms, sleeves, pants and armor all bend. Overlays and armor use the limb's spine, not their own inflated box, so they stay attached.
- **`PoseApplier`**:
- Bends are cleared on every `setupAnim`, because models are shared between entities.
- The body bends from the hips, and the head and arms follow it: their pivots move with the bent torso and they turn with it.
- **Version differences**: the only one so far is the vertex format, which changed in 1.21.9. It's handled with a Stonecutter branch.
## Tester
- **New animations**: `flap`, `squat`, `bow` and a rough `twerk`. The twerk is only a test pose and isn't close to other clients' twerks yet.
- **Screenshot test**: `./gradlew :<mc>:runClientGameTest` is a Fabric client gametest. It creates a world and screenshots each animation from several angles into `versions/<mc>/build/run/clientGameTest/screenshots/`.
- **Full Fabric API**: the tester now runs with all of Fabric API, because single modules don't bring their dependencies, which differ between versions.
## Testing
- `./gradlew :core:test`: 27 tests pass (Bézier, limb and torso bends, face splitting, animation timing).
- `buildAll` builds all 8 versions.
- The screenshot test passes on all 8 versions. I checked the screenshots from 1.21.4, 1.21.9 and 1.21.11: joints stay closed and textures stay intact.
- The final twerk tweak (arching the lower back) was only compiled on 1.21.4 and 1.21.11 and checked by hand in game, not in the screenshot test.
## Known gaps
- Held items still attach to the unbent arm.
- The cape doesn't follow the torso.
- The head and arms follow the body's bend but not its rotation, so emotes have to add the rotation themselves. This is a proposed follow-up.
- The unit tests may still change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- core: Bezier (any degree, De Casteljau), LimbBend (cubic spine through
the rigid upper/joint/lower shape, one ring per texture row spaced by
arc length, rigid rings so pieces share vertices) and QuadSplitter
(cuts faces at the rings, interpolating UVs).
- fabric: ModelPartMixin draws parts that have a bend with
BentCubeRenderer, which deforms vanilla's own cubes. Overlays and armor
use the limb's spine so they stay attached. Bends are reset every
setupAnim because models are shared between entities.
- testmod: flap and squat animations, and a client gametest that
screenshots each animation from the front and side
(runClientGameTest). The tester runs with the full Fabric API because
single modules don't bring their version-specific dependencies.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- LimbBend.anchoredAtEnd keeps the far end in place (the hips on the
legs) and folds the other half, and angleAt/axis expose how far the
limb has turned at a point.
- PoseApplier bends the body from the hips and carries the head and arms
with it: their pivots follow the bent torso and they turn with its ring.
- Test animations: bow (torso only) and twerk. The gametest shoots the
twerk at the top and bottom of its bounce, including from behind.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The torso tips forward around the hips and bends backwards, so the lower
back curves in and the chest comes up. The head and arms get the tilt
themselves, since they only follow the torso's bend.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds limb bending, the main reason for replacing player-animation-lib. It uses the same approach as the cloak renderer: a spine, rings of shared vertices along it, and faces drawn between the rings.
Core (no Minecraft)
Bezier: Bézier curves of any degree, with points and derivatives.LimbBend: bends a limb along a single axis.sharpnessgoes from a round curve to a tight joint (fixed at 0.5 for now).anchoredAtEndkeeps the far end in place, which the torso uses so the hips stay on the legs.QuadSplitter: cuts vanilla faces at the rings and splits their UVs to match, so the texture is unchanged apart from the cuts.Fabric
ModelPartMixin/BentCubeRenderer: any part with a bend is drawn by deforming vanilla's own cubes. Slim arms, sleeves, pants and armor all bend. Overlays and armor use the limb's spine, not their own inflated box, so they stay attached.PoseApplier:setupAnim, because models are shared between entities.Tester
flap,squat,bowand a roughtwerk. The twerk is only a test pose and isn't close to other clients' twerks yet../gradlew :<mc>:runClientGameTestis a Fabric client gametest. It creates a world and screenshots each animation from several angles intoversions/<mc>/build/run/clientGameTest/screenshots/.Testing
./gradlew :core:test: 27 tests pass (Bézier, limb and torso bends, face splitting, animation timing).buildAllbuilds all 8 versions.Known gaps
🤖 Generated with Claude Code