Animation review built exclusively for AI agents: a clip in, exact motion measurements + evidence renders out.
Project description
animationsight
Animation review built exclusively for AI agents. A clip in; exact motion measurements, located findings, and renders of the frames that are wrong out.
An animator judges a clip by watching it. An agent cannot watch anything — and the defects that matter are the ones that hide from watching anyway: a foot that slides 2 mm per frame, a single-frame pop in a 4-second take, a toe 40 mm through the floor for 5 frames. Those are all exact arithmetic. So do the arithmetic.
clip.bvh -> animationsight inspect -> report.json + flagged frames -> fix -> diff
What it measures
| kinematics | per-joint velocity, acceleration, jerk (mm/s, /s², /s³) and true geodesic angular speed |
| contacts | plant/lift events per foot, with frames and times |
| foot sliding | drift while planted: total slip, peak speed, worst frame — the classic defect |
| balance | COM (real segment masses) vs the support base, per frame, with airborne frames separated |
| ballistics | effective gravity per airborne span from a parabola fit — floaty/heavy flights, quantified |
| penetration | any joint through the floor, with depth and frames |
| smoothness | discontinuity events, clustered: "pose snap" (many joints, one frame) vs "joint pop" (one bad key) |
| loops | seam gap judged against the clip's own per-frame motion, convention-aware; --kind oneshot declares the intent |
Findings carry where (frame, joint, magnitude) and a try:. Renders
mark the offending joint and draw the COM, the floor and the support.
Everything is deterministic: same clip, byte-identical report.
Quickstart
pip install "git+https://github.com/VortexJer/AISight#subdirectory=animationsight"
animationsight inspect walk.bvh --unit cm --up y
# -> out/report.json
# -> out/frames/frame_0022.png (the flagged frames, offender circled)
# -> out/track_foot_speed.png (time series, slides marked)
animationsight diff before.bvh after.bvh # prove the fix
animationsight track walk.bvh LeftFoot # one joint, every frame
Exit codes: 0 ok, 1 bad clip, 2 a FAIL-level finding.
Proof it works: known ground truth
examples/01-walk is synthetic on purpose. Real mocap has unknown
defects; a clip whose defects are known by construction is the only kind
that can prove a measurement is right.
make_clips.py builds a walk by authoring the foot's world trajectory
(stance planted, swing arcing) and solving the leg by inverse
kinematics, then writes two files: a clean reference, and the same walk
with three injected defects of exact magnitude.
| injected | measured |
|---|---|
| right foot dipped 40 mm, frames 22-26 | [FAIL] 'RightFoot_end' goes 40.0 mm through the floor — worst at frame 22, 5 frames |
| left arm displaced 26° on frame 47 only | [WARN] 9 single-frame acceleration spike(s); worst on 'LeftForearm' — frame 47, robust z 102.5 |
| root travels 15 % faster than the stride | [WARN] 'LeftFoot_end' slides while planted: 130.5 mm over 58 frame(s) |
And the clean reference reports OK, exit 0 — no findings. Both
directions are asserted in tests/.
real committed output: frame 22 with the penetrating foot circled below the floor line · the foot-speed track with the sliding frames marked
Before / after: one turn of the loop
examples/02-jump is the defect nobody can see and
everybody can feel: a jump whose flight falls at 0.58x gravity.
Every still frame looks fine; the parabola fit does not care.
flight: frames 27..45 (0.6333s, apex +266.2 mm) -> 0.58x gravity
[WARN] ... at 1 g that apex takes 0.47s of airtime
try: T = 2*sqrt(2h/g): shorten the airtime or raise the apex
Apply the try: line, re-inspect, and prove it:
animationsight diff jump_floaty.bvh jump_fixed.bvh --kind oneshot
flight 0: 0.58x gravity (0.6333s) -> 1.064x gravity (0.4667s)
GONE [floaty-flight] flight at frames [27, 45] falls at 0.58x gravity ...
the arc sheet inspect writes for every flight: ghosted poses, the measured COM arc (red, one dot per frame) vs the 1 g reference (green, dashed). Left: floaty — the red arc overshoots the reference by a third of the jump. Right: fixed — the arcs coincide.
Blind vs measured: the parkour vault
examples/03-parkour is the full study: a
240-frame run → vault → land → turn → settle sequence authored twice —
once by a cold-context agent with no tools at all (numpy and
arithmetic, one shot), once through this tool's loop. The blind clip is
genuinely strong — hand-solved vault ballistics that measure 1.03x g,
IK-pinned feet, zero sliding — and still ships what no eye can see: a
stride flight at 0.47x g, a turn step whose "flight" is really IK
overreach lifting the planted foot, a 116607 mm/s² knee pop at the
landing. The after clip audits OK, zero findings, and the diff
proves each fix did what it meant.
left: the blind one-shot — competent enough that its defects are exactly the invisible kind · right: the after clip — same choreography, physics that measures clean
the stride flight's arc sheet — blind: the measured COM arc (red) runs flat at 0.47x g while the 1 g reference (green) falls · after: 1.0x g, the arcs coincide
Four bugs this found in itself
Worth stating plainly, because they are the same class of bug the tool exists to catch:
- The first walk generator did not plant its feet. It was built
from sinusoids, which look like a walk and are not one — every frame
slid. animationsight caught it immediately (min foot speed 81 mm/s,
never zero), which is why the generator now uses IK and why
test_clean_clip_plants_its_feetexists. - The floor was inferred from the clip's lowest point — so the
injected penetration defined the floor and made itself invisible.
Now it is the 10th percentile of the per-frame lowest point: a defect
is rare by nature and stays below it.
(
test_a_penetration_cannot_define_the_floor) - The author's own jump was floaty. While dogfooding, the ballistics
metric measured the freshly-authored demo jump at 0.68 g — written as
an "arbitrary nice parabola" and shipped without a second look. It is
now
examples/02-jump, defect preserved, with the fix beside it. diffprintedNonex gravitywhen a flight exists on only one side — which is precisely what a good fix produces (the parkour turn step stopped being a "flight" once its planted foot stayed down). It saysno flightnow, regression-tested.
Scope, honestly
Reads BVH. Measures kinematics, contacts, balance, smoothness, loops.
Does not do: character rendering, blend shapes / facial rigs, retargeting, physics simulation, or editing clips. It reviews; you fix the clip in the tool that made it.
For 3D geometry — parts, assemblies, robot URDF, collision sweeps — see solidsight, the sibling tool this shares its philosophy with.
The Claude Code skill
skill/SKILL.md ships inside the pip package and installs itself into
~/.claude/skills/animationsight on the first run. animationsight uninstall removes the skill and the package.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file animationsight-0.7.1.tar.gz.
File metadata
- Download URL: animationsight-0.7.1.tar.gz
- Upload date:
- Size: 44.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2f147bd9f20c490c6dfa26f3eafa49b0f6302c0b410c001755e9c4a83fe6323
|
|
| MD5 |
87acebc761a28df4f0c2151471496842
|
|
| BLAKE2b-256 |
a80482c13cf5aec074efa08a9a7cd54f44f555627e2007ccfbab1b64386f27a0
|
Provenance
The following attestation bundles were made for animationsight-0.7.1.tar.gz:
Publisher:
release.yml on VortexJer/AISight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
animationsight-0.7.1.tar.gz -
Subject digest:
c2f147bd9f20c490c6dfa26f3eafa49b0f6302c0b410c001755e9c4a83fe6323 - Sigstore transparency entry: 2224577177
- Sigstore integration time:
-
Permalink:
VortexJer/AISight@54fc06c5021ec832d4a8199a195266a6c0acdd8b -
Branch / Tag:
refs/tags/animationsight-v0.7.1 - Owner: https://github.com/VortexJer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@54fc06c5021ec832d4a8199a195266a6c0acdd8b -
Trigger Event:
push
-
Statement type:
File details
Details for the file animationsight-0.7.1-py3-none-any.whl.
File metadata
- Download URL: animationsight-0.7.1-py3-none-any.whl
- Upload date:
- Size: 39.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6db259c7a7758285a17baf337a3403cf167729a3482614fb8362ade075372638
|
|
| MD5 |
831f2a1f79ea25defd76b5874cc373d2
|
|
| BLAKE2b-256 |
c52c15548eeca08d3a7f55721eaf5216219dd2a310a028d3886d93fdb63e8bf3
|
Provenance
The following attestation bundles were made for animationsight-0.7.1-py3-none-any.whl:
Publisher:
release.yml on VortexJer/AISight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
animationsight-0.7.1-py3-none-any.whl -
Subject digest:
6db259c7a7758285a17baf337a3403cf167729a3482614fb8362ade075372638 - Sigstore transparency entry: 2224577812
- Sigstore integration time:
-
Permalink:
VortexJer/AISight@54fc06c5021ec832d4a8199a195266a6c0acdd8b -
Branch / Tag:
refs/tags/animationsight-v0.7.1 - Owner: https://github.com/VortexJer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@54fc06c5021ec832d4a8199a195266a6c0acdd8b -
Trigger Event:
push
-
Statement type: