use crate::data::{ConstraintId, SkeletonData, SliderData, Timeline};
use crate::skeleton::bone;
use crate::skeleton::constraint::Constraint;
use crate::skeleton::transform::from_value;
use crate::skeleton::{Skeleton, UpdateCacheEntry};
impl Skeleton {
pub(crate) fn sort_slider(&mut self, id: ConstraintId, data: &SliderData, sd: &SkeletonData) {
if let Some(b) = data.bone
&& !data.local
{
self.sort_bone(b);
}
self.update_cache.push(UpdateCacheEntry::Constraint(id));
let Some(animation) = data.animation else {
return;
};
let animation = &sd.animations[animation.index()];
for &b in &animation.bones {
self.bones[b.index()].sorted = false;
self.sort_reset(b);
self.constrain_bone(b);
}
for t in &animation.timelines {
match t {
Timeline::Attachment { slot, .. }
| Timeline::Rgba { slot, .. }
| Timeline::Rgb { slot, .. }
| Timeline::Alpha { slot, .. }
| Timeline::Rgba2 { slot, .. }
| Timeline::Rgb2 { slot, .. }
| Timeline::Deform { slot, .. }
| Timeline::Sequence { slot, .. } => self.constrain_slot(*slot),
Timeline::DrawOrder { .. } | Timeline::DrawOrderFolder { .. } => {
self.draw_order.constrain();
}
Timeline::Physics {
constraint: None, ..
}
| Timeline::PhysicsReset {
constraint: None, ..
} => {
for i in 0..self.physics.len() {
self.constrain_constraint(self.physics[i]);
}
}
Timeline::IkConstraint { constraint, .. }
| Timeline::TransformConstraint { constraint, .. }
| Timeline::PathConstraintPosition { constraint, .. }
| Timeline::PathConstraintSpacing { constraint, .. }
| Timeline::PathConstraintMix { constraint, .. }
| Timeline::Physics {
constraint: Some(constraint),
..
}
| Timeline::PhysicsReset {
constraint: Some(constraint),
..
}
| Timeline::Slider { constraint, .. }
| Timeline::SliderMix { constraint, .. } => self.constrain_constraint(*constraint),
_ => {}
}
}
}
pub(crate) fn update_slider(&mut self, id: ConstraintId, data: &SliderData, sd: &SkeletonData) {
let Constraint::Slider(c) = &self.constraints[id.index()] else {
unreachable!()
};
let mut p = *c.posed.applied();
if p.mix == 0.0 {
return;
}
let Some(animation_id) = data.animation else {
return;
};
let animation = &sd.animations[animation_id.index()];
let f = self.frame();
if let (Some(b), Some(property)) = (data.bone, data.property) {
if !self.bones[b.index()].active {
return;
}
if data.local {
bone::validate_local_transform(&mut self.bones, b.index(), &f);
}
let source = *self.bones[b.index()].applied();
p.time = data.offset
+ (from_value(property.property, &f, &source, data.local, &[0.0; 6])
- property.offset)
* data.scale;
if data.looping {
p.time = animation.duration + p.time % animation.duration;
} else {
p.time = p.time.max(0.0);
}
if let Constraint::Slider(c) = &mut self.constraints[id.index()] {
c.posed.applied_mut().time = p.time;
}
}
for &b in &animation.bones {
bone::modify_local(&mut self.bones, b.index(), &f);
}
self.apply_animation(
animation_id,
p.time,
p.time,
data.looping,
None,
p.mix,
crate::animation::MixFrom::Current,
data.additive,
false,
true,
);
}
}