use crate::runtime::context::RuntimeStepContext;
use crate::runtime::plugin::{RuntimePlugin, phase};
use super::clip::AnimationClip;
use super::skeleton::Pose;
pub struct ClipPlayerPlugin {
pub clip: AnimationClip,
pub bind_pose: Pose,
pub speed: f32,
pub looping: bool,
pub playhead: f32,
pub playing: bool,
}
impl ClipPlayerPlugin {
pub fn new(clip: AnimationClip, bind_pose: Pose) -> Self {
Self {
clip,
bind_pose,
speed: 1.0,
looping: true,
playhead: 0.0,
playing: true,
}
}
pub fn with_speed(mut self, speed: f32) -> Self {
self.speed = speed;
self
}
pub fn with_looping(mut self, looping: bool) -> Self {
self.looping = looping;
self
}
}
impl RuntimePlugin for ClipPlayerPlugin {
fn priority(&self) -> i32 {
phase::ANIMATE
}
fn step(&mut self, ctx: &mut RuntimeStepContext<'_>) {
if self.playing {
self.playhead += ctx.dt * self.speed;
if self.clip.duration > 0.0 {
if self.looping {
self.playhead = self.playhead.rem_euclid(self.clip.duration);
} else {
self.playhead = self.playhead.clamp(0.0, self.clip.duration);
}
}
}
let mut pose = self.bind_pose.clone();
self.clip.sample_into(self.playhead, &mut pose);
ctx.resources.insert(pose);
}
}