Skip to main content

gizmo_renderer/components/
animation.rs

1use std::sync::Arc;
2
3pub use crate::animation_state_machine::{
4    ActiveBlend, AnimationState, AnimationStateMachine, AnimationTransition,
5};
6
7#[derive(Clone)]
8pub struct Skeleton {
9    pub bind_group: Arc<wgpu::BindGroup>,
10    pub buffer: Arc<wgpu::Buffer>,
11    pub hierarchy: Arc<crate::animation::SkeletonHierarchy>,
12    pub local_poses: Vec<gizmo_math::Mat4>,
13    pub global_poses: Vec<gizmo_math::Mat4>,
14}
15
16impl Skeleton {
17    pub fn new(
18        bind_group: Arc<wgpu::BindGroup>,
19        buffer: Arc<wgpu::Buffer>,
20        hierarchy: Arc<crate::animation::SkeletonHierarchy>,
21        local_poses: Vec<gizmo_math::Mat4>,
22    ) -> Self {
23        assert_eq!(
24            hierarchy.joints.len(),
25            local_poses.len(),
26            "Skeleton joints uzunlugu ile local_poses esit olmali"
27        );
28        let global_poses = local_poses.clone(); // Initial
29        Self {
30            bind_group,
31            buffer,
32            hierarchy,
33            local_poses,
34            global_poses,
35        }
36    }
37}
38
39#[derive(Clone)]
40pub struct AnimationPlayer {
41    pub current_time: f32,
42    pub active_animation: usize,
43    pub loop_anim: bool,
44    pub speed: f32,
45    pub animations: Arc<[crate::animation::AnimationClip]>,
46    // Blending support
47    pub blend_time: f32,
48    pub blend_duration: f32,
49    pub prev_animation: Option<usize>,
50    pub prev_time: f32,
51}
52
53impl Default for AnimationPlayer {
54    fn default() -> Self {
55        Self {
56            current_time: 0.0,
57            active_animation: 0,
58            loop_anim: true,
59            speed: 1.0,
60            animations: Arc::new([]),
61            blend_time: 0.0,
62            blend_duration: 0.0,
63            prev_animation: None,
64            prev_time: 0.0,
65        }
66    }
67}
68
69impl AnimationPlayer {
70    pub fn current_clip(&self) -> Option<&crate::animation::AnimationClip> {
71        self.animations.get(self.active_animation)
72    }
73
74    pub fn play_animation_by_name(&mut self, name: &str, blend: f32, loop_anim: bool) -> bool {
75        if let Some(idx) = self.animations.iter().position(|a| a.name == name) {
76            if self.active_animation != idx {
77                self.prev_animation = Some(self.active_animation);
78                self.prev_time = self.current_time;
79                self.active_animation = idx;
80                self.current_time = 0.0;
81                self.blend_duration = blend;
82                self.blend_time = 0.0;
83                self.loop_anim = loop_anim;
84            }
85            true
86        } else {
87            false
88        }
89    }
90}
91
92#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
93pub struct BoneAttachment {
94    pub target_entity: gizmo_core::entity::Entity,
95    pub bone_index: usize,
96    pub offset: gizmo_math::Mat4,
97}
98
99impl Default for BoneAttachment {
100    fn default() -> Self {
101        Self {
102            target_entity: gizmo_core::entity::Entity::new(0, 0),
103            bone_index: 0,
104            offset: gizmo_math::Mat4::IDENTITY,
105        }
106    }
107}
108
109gizmo_core::impl_component!(BoneAttachment);