Skip to content

Commit

Permalink
Generate bones from samples
Browse files Browse the repository at this point in the history
  • Loading branch information
PikminGuts92 committed Feb 7, 2025
1 parent 3b4ac30 commit 9f7adbb
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 11 deletions.
39 changes: 29 additions & 10 deletions core/grim/src/model/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct SceneHelper {

#[derive(Default)]
pub struct MiloAssets {
char_clip_samples: CharClipSamples,
char_clip_samples: Vec<CharClipSamples>,
}

impl GltfImporter2 {
Expand Down Expand Up @@ -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::<Vec<_>>();

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()),
Expand All @@ -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
Expand Down
34 changes: 33 additions & 1 deletion core/grim/src/scene/char_bones_samples/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<CharBoneSample> {
let EncodedSamples::Compressed(bones, compressed_samples) = &self.samples else {
// Maybe throw error?
Expand Down

0 comments on commit 9f7adbb

Please sign in to comment.