diff --git a/core/grim/src/model/import.rs b/core/grim/src/model/import.rs index ea8b1df..eb829db 100644 --- a/core/grim/src/model/import.rs +++ b/core/grim/src/model/import.rs @@ -27,7 +27,7 @@ pub struct SceneHelper { #[derive(Default)] pub struct MiloAssets { - char_clip_samples: CharClipSamples, + char_clip_samples: Vec, } impl GltfImporter2 { @@ -186,35 +186,48 @@ impl GltfImporter2 { .iter() .filter_map(|b| match full_samples.get(b) { Some(s) if s.pos.is_some() && s.quat.is_some() => None, - Some(s) => { - let (_name, node) = node_map.get(b).expect("Get bone node for one anim"); + s @ _ => { // Has 0 or some transformations + let (name, node) = node_map.get(b).expect("Get bone node for one anim"); let ([tx, ty, tz], [rx, ry, rz, rw], [_sx, _sy, _sz]) = node.transform().decomposed(); Some(CharBoneSample { - symbol: s.symbol.to_owned(), - pos: if s.pos.is_none() { + symbol: name.to_string(), + pos: if s.is_none_or(|s| s.pos.is_none()) { Some((1.0, vec![Vector3 { x: tx, y: ty, z: tz }])) } else { None }, - quat: if s.quat.is_none() { + quat: if s.is_none_or(|s| s.quat.is_none()) { Some((1.0, vec![Quat { x: rx, y: ry, z: rz, w: rw }])) } else { None }, ..Default::default() }) - }, - _ => None + } }) - .collect(); + .collect::>(); let mut clip = CharClipSamples { one: CharBonesSamples { + bones: one_samples + .iter() + .map(|s| CharBone { + symbol: s.symbol.to_owned(), + weight: 1.0, + }) + .collect(), samples: EncodedSamples::Uncompressed(one_samples), ..Default::default() }, full: CharBonesSamples { + bones: full_samples + .values() + .map(|s| CharBone { + symbol: s.symbol.to_owned(), + weight: 1.0, + }) + .collect(), samples: EncodedSamples::Uncompressed(full_samples .into_values() .collect()), @@ -223,7 +236,13 @@ impl GltfImporter2 { ..Default::default() }; - // Compress anim samples here? Re-compute char bones from sample names too + // Re-compute char bones from sample names + for sam in [&mut clip.one, &mut clip.full] { + sam.recompute_sizes(); + sam.generate_bones_from_samples(); + } + + assets.char_clip_samples.push(clip); } assets diff --git a/core/grim/src/scene/char_bones_samples/mod.rs b/core/grim/src/scene/char_bones_samples/mod.rs index 171ee94..4e569e1 100644 --- a/core/grim/src/scene/char_bones_samples/mod.rs +++ b/core/grim/src/scene/char_bones_samples/mod.rs @@ -7,7 +7,7 @@ use grim_macros::*; use grim_traits::scene::*; pub use io::*; -#[derive(Debug, Default)] +#[derive(Debug, Clone, Default)] pub struct CharBone { pub symbol: String, // Bone name + transform property ext pub weight: f32, @@ -120,6 +120,38 @@ impl CharBonesSamples { self.computed_flags = (self.computed_sizes.last().unwrap() + 0xF) & 0xFFFF_FFF0; } + pub fn generate_bones_from_samples(&mut self) { + self.bones = match &self.samples { + EncodedSamples::Compressed(bones, _) => bones.to_vec(), + EncodedSamples::Uncompressed(samples) => { + let (pos, quat) = samples + .iter() + .fold((Vec::new(), Vec::new()), |(mut pos, mut quat), s| { + if let Some((w, _)) = s.pos { + pos.push(CharBone { + symbol: format!("{}.pos", s.symbol), + weight: w, + }); + } + + if let Some((w, _)) = s.quat { + quat.push(CharBone { + symbol: format!("{}.quat", s.symbol), + weight: w, + }); + } + + (pos, quat) + }); + + pos + .into_iter() + .chain(quat) + .collect() + }, + }; + } + pub fn decode_samples(&self, sys_info: &SystemInfo) -> Vec { let EncodedSamples::Compressed(bones, compressed_samples) = &self.samples else { // Maybe throw error?