pub mod bind_pose;
pub mod constant_track;
pub mod duration_sanity;
pub mod foot_slide;
pub mod fps;
pub mod frozen_bone;
pub mod gait_group;
pub mod in_place;
pub mod loop_seam;
pub mod missing_bones;
pub mod nan;
pub mod quat_flip;
pub mod quat_norm;
pub mod root_motion_speed;
pub mod scale_keys;
pub mod time_monotonic;
use crate::check::Readiness;
use crate::model::{Document, Track};
use crate::profile::{ResolvedRoles, Role};
pub(crate) fn root_motion_readiness(roles: &ResolvedRoles) -> Readiness {
if roles.get(Role::Root).is_some() || roles.get(Role::Hips).is_some() {
Readiness::Ready
} else {
Readiness::Skipped(format!(
"root/hips role not resolved (rig profile '{}')",
roles.profile
))
}
}
pub(crate) fn gait_readiness(roles: &ResolvedRoles) -> Readiness {
let has_foot = [
Role::LeftFoot,
Role::LeftToe,
Role::RightFoot,
Role::RightToe,
]
.iter()
.any(|&r| roles.get(r).is_some());
if roles.get(Role::Hips).is_some() && has_foot {
Readiness::Ready
} else {
Readiness::Skipped(format!(
"hips/foot roles not resolved (rig profile '{}') — needs hips and at least one foot role",
roles.profile
))
}
}
pub(crate) fn tracks(doc: &Document) -> impl Iterator<Item = (&str, &str, &Track)> {
doc.clips.iter().flat_map(move |clip| {
clip.tracks.iter().map(move |track| {
let bone = doc
.skeleton
.bones
.get(track.bone)
.map(|b| b.name.as_str())
.unwrap_or("<unknown>");
(clip.name.as_str(), bone, track)
})
})
}