1mod animator;
2mod clip;
3#[cfg(any(test, feature = "fixture"))]
4pub mod fixture;
5pub mod math;
6mod pose;
7mod skeleton;
8mod skin;
9mod sprite;
10
11pub use animator::{Animator, Fired, MAX_MIXES, MAX_REPEATS, Playback};
12pub use clip::{Channel, Clip, ClipEvent, Interpolation, Property};
13pub use math::{Mat4, Quat, Trs};
14pub use pose::Pose;
15pub use skeleton::{Joint, MAX_JOINTS, Rig, Skeleton};
16pub use skin::{Skinned, blend_matrix, check_skin, normalize_weights, skin};
17pub use sprite::{Atlas, FrameEvent, SpriteClip, SpritePlayer, SpriteSheet};
18
19#[cfg(test)]
20mod tests;
21#[cfg(test)]
22mod tests_sprite;
23
24#[derive(Clone, Debug, PartialEq)]
25pub enum AnimError {
26 NoJoints,
27 TooManyJoints(usize),
28 InverseBinds {
29 joints: usize,
30 binds: usize,
31 },
32 ParentOrder(String),
33 NotFinite(String),
34 DuplicateClip(String),
35 UnknownClip(String),
36 NotPlaying(String),
37 NotAnimated(String),
38 Channel {
39 clip: String,
40 reason: String,
41 },
42 Event {
43 clip: String,
44 event: String,
45 reason: String,
46 },
47 Weight {
48 clip: String,
49 weight: f32,
50 },
51 Speed(f32),
52 Fade(f32),
53 Start(f32),
54 Skin(String),
55 Atlas(String),
56 Sprite {
57 clip: String,
58 reason: String,
59 },
60}
61
62impl std::fmt::Display for AnimError {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 match self {
65 AnimError::NoJoints => write!(f, "a skeleton needs at least one joint"),
66 AnimError::TooManyJoints(count) => {
67 write!(f, "a skeleton of {count} joints is over {MAX_JOINTS}")
68 }
69 AnimError::InverseBinds { joints, binds } => {
70 write!(f, "{binds} inverse bind matrices for {joints} joints")
71 }
72 AnimError::ParentOrder(joint) => {
73 write!(f, "joint {joint} comes before its parent")
74 }
75 AnimError::NotFinite(what) => write!(f, "{what} is not finite"),
76 AnimError::DuplicateClip(clip) => write!(f, "two clips are named {clip}"),
77 AnimError::UnknownClip(clip) => write!(f, "no clip is named {clip}"),
78 AnimError::NotPlaying(clip) => write!(f, "clip {clip} is not playing"),
79 AnimError::NotAnimated(reason) => f.write_str(reason),
80 AnimError::Channel { clip, reason } => write!(f, "clip {clip}: {reason}"),
81 AnimError::Event {
82 clip,
83 event,
84 reason,
85 } => write!(f, "clip {clip}, event {event}: {reason}"),
86 AnimError::Weight { clip, weight } => {
87 write!(f, "clip {clip}: a weight of {weight} is outside 0 to 1")
88 }
89 AnimError::Speed(speed) => write!(f, "a speed of {speed} is below 0 or not finite"),
90 AnimError::Fade(seconds) => {
91 write!(f, "a fade of {seconds} seconds is below 0 or not finite")
92 }
93 AnimError::Start(seconds) => {
94 write!(f, "a start of {seconds} seconds is below 0 or not finite")
95 }
96 AnimError::Skin(reason) => write!(f, "skin: {reason}"),
97 AnimError::Atlas(reason) => write!(f, "atlas: {reason}"),
98 AnimError::Sprite { clip, reason } => write!(f, "sprite clip {clip}: {reason}"),
99 }
100 }
101}
102
103impl std::error::Error for AnimError {}