Expand description
Engine-agnostic animation linting primitives for Rust pipelines.
This crate is the embedding boundary for animsmith. It owns the core
data model (Document, Skeleton, Clip, Track), rig-role
resolution (detect_profile, ResolvedRoles::from_names),
typed configuration (Config), measurement generation
(measure::measure_document), measurement diffs
(diff::diff_measurements), structured findings (Finding), and
check execution (CheckCtx, all_checks, run_checks).
The animsmith-gltf and animsmith-fbx loader crates translate file
formats into this model; their docs.rs pages continue the library path for
format-specific loading and, for glTF, writing.
The embedding guide explains crate selection and integration boundaries. The pipeline scenario guide shows where an embedded gate fits in marketplace intake, mocap cleanup, outsourced acceptance, and CI. A runnable example exercises the complete library flow.
§Quick start
After a format crate has loaded a Document, resolve rig roles, build
a Config from the host pipeline’s contract, and share one
MetricGrids between measurements, checks, and optional report
generation:
use animsmith_core::{Config, CheckCtx, Document, MetricGrids, all_checks, run_checks};
use animsmith_core::measure::measure_document;
use animsmith_core::ResolvedRoles;
let doc = Document::default();
let roles = ResolvedRoles::default();
let config = Config::default();
let grids = MetricGrids::new(&doc);
let measurements = measure_document(&grids, &roles, &config);
let ctx = CheckCtx::new(&grids, &roles, &config);
let findings = run_checks(&ctx, &all_checks());
assert!(measurements.is_empty());
assert!(findings.is_empty());CheckCtx::new consumes already-resolved roles; it does not interpret
Config::rig automatically. Frontends may use detect_profile,
profile::resolve_named, or ResolvedRoles::from_names, then apply
their own override policy before constructing the context. Checks whose
required roles remain unresolved emit diagnostic skip notes rather than
false failures.
§API status
The Rust API is pre-1.0 and may still change before the first stable
release. The intended extension points are the data model,
configuration types, measurement and diff APIs, rig-profile APIs, the
Check trait for custom checks, and the check catalog functions
re-exported from this crate root. Built-in check ids, CLI exit-code
semantics, and the CLI’s versioned JSON envelope/schema id are treated
as the most stable automation contracts. The core Finding and
measure::ClipMeasurements serde shapes feed that envelope, but the
envelope version itself lives in the CLI crate. The scene-asset
structs in model and the pipeline-mechanical helpers in
transform are public so the loader, writer, and CLI crates can
share the same model, but they are less settled than the
measurement/check embedding flow while the crate is pre-1.0. Metric
formulas and individual Rust symbols are still subject to pre-1.0
refinement.
Public APIs that return Result document their # Errors cases.
Index-based accessors and transform helpers that rely on
loader-established invariants document their # Panics contracts.
Loader-valid documents from the format crates should flow through
checking, sampling, and measurement without panicking on untrusted
input.
Re-exports§
pub use check::Check;pub use check::CheckCtx;pub use check::all_checks;pub use check::mechanical_checks;pub use check::run_checks;pub use config::ClipExpectations;pub use config::Config;pub use config::GaitGroup;pub use config::Pinned;pub use config::SeveritySetting;pub use finding::Finding;pub use finding::Severity;pub use finding::Value;pub use metrics::MetricGrids;pub use model::Bone;pub use model::BoneId;pub use model::Clip;pub use model::Document;pub use model::Interpolation;pub use model::Property;pub use model::Skeleton;pub use model::SourceInfo;pub use model::Track;pub use model::TrackValues;pub use model::Transform;pub use profile::ResolvedRoles;pub use profile::RigProfile;pub use profile::Role;pub use profile::builtin_profiles;pub use profile::detect_profile;pub use sample::PoseGrid;pub use sample::TrackSample;pub use sample::default_frame_count;pub use sample::sample_clip;pub use sample::sample_track;pub use glam;
Modules§
- check
- The check abstraction, its execution context, and the built-in check sets.
- config
- Typed configuration: rig selection, per-check settings, per-clip
expectations, and typed clip groups. The TOML file (
animsmith.toml) is one constructor of this — embedding pipelines build it programmatically through this module and keep their own contract formats on their side. - diff
- Compare measurement maps and report per-metric movement beyond significance thresholds.
- finding
- Structured lint findings. The structured fields (not just a message
string) are what make
diff, the JSON schema, and the HTML report cheap downstream. - measure
- Measurements: the raw per-clip metric map that
measureemits andlintjudges. Kept separate from findings so pipelines (e.g. a bake’s measured sidecar) can pin their own contracts to the numbers. - metrics
- Locomotion clip metrics: loop-seam ratio, gait phase, root-motion speed. Ported from a production game pipeline’s reference implementation (verified there against Blender pose-matrix FK to <0.01×) — the algorithms are kept semantically identical so the numbers reproduce.
- model
- The loader-facing layer: clips, tracks, and the skeleton before metric
resampling or repair. The glTF loader preserves authored animation
values; the FBX loader normalizes scene coordinates and bakes takes to
linear TRS tracks. Mechanical checks (NaN, quaternion flips, key
density, …) read this layer; semantic checks read the sampled layer
built from it (see
crate::sample). - profile
- Rig profiles: checks never reference bone names, they reference roles. A profile maps roles to name matchers; built-ins cover the common rigs and auto-detection scores every built-in by resolved-role coverage. A check whose required roles don’t resolve is skipped with a note — never a false failure.
- sample
- The sampled layer: what a game runtime sees. A
PoseGridis a uniform time grid over[0, duration]sampled with glTF-spec interpolation semantics (lerp for T/S, shortest-path slerp for R, STEP hold, cubic-spline Hermite; clamp at the ends), then FK’d to model space. - transform
- Pipeline-mechanical clip transforms, ported from the incubating bake’s Python: frame-window slicing, hold-extension, and gait-anchor rotation. Scope rule (DESIGN.md §1): animsmith may rewrite a clip only in ways whose correctness its own checks can verify.