1use crate::{
2 assets::{
3 Assets,
4 skin::{ JointTransform, JointIndex, MAX_JOINTS, Skin },
5 },
6 id::Id,
7 renderer::{ Renderer, UniformBuffer },
8};
9
10use dotrix_math::{ Mat4, SquareMatrix };
11
12pub struct Pose {
14 pub skin: Id<Skin>,
16 pub joints: Vec<JointTransform>,
18 pub uniform: UniformBuffer,
20}
21
22impl Pose {
23 pub fn load(&mut self, renderer: &Renderer, assets: &Assets) -> bool {
25 if let Some(skin) = assets.get(self.skin) {
26 let joints_matrices = self.matrices(&skin.index);
27 renderer.load_uniform_buffer(
28 &mut self.uniform,
29 bytemuck::cast_slice(joints_matrices.as_slice())
30 );
31 return true;
32 }
33 false
34 }
35
36 fn matrices(&self, index: &[JointIndex]) -> Vec<[[f32; 4]; 4]> {
38 let mut result = index.iter().map(|i| {
39 let joint_transform = self.joints.iter().find(|j| j.id == i.id).unwrap();
40 let global_transform = &joint_transform.global_transform;
41 let inverse_bind_matrix = i.inverse_bind_matrix;
42 inverse_bind_matrix
43 .as_ref()
44 .map(|ibmx| global_transform * ibmx)
45 .unwrap_or(*global_transform)
46 .into()
47 }).collect::<Vec<_>>();
48
49 while result.len() < MAX_JOINTS {
50 result.push(Mat4::identity().into());
51 }
52 result
53 }
54}
55
56impl From<Id<Skin>> for Pose {
57 fn from(skin: Id<Skin>) -> Self {
59 Self {
60 skin,
61 joints: vec![JointTransform::default(); MAX_JOINTS], uniform: UniformBuffer::default(),
63 }
64 }
65}