Initial work on ledge & improved baking of root motion. (#90)
Reviewed-on: #90 Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #90.
This commit is contained in:
@@ -27,6 +27,7 @@ struct FighterBakeSource {
|
||||
model_bytes: Vec<u8>,
|
||||
buffers: Vec<Vec<u8>>,
|
||||
animations: HashMap<AnimKind, String>,
|
||||
root_motion_bone: String,
|
||||
}
|
||||
#[derive(Default, TypePath)]
|
||||
struct FighterBakeSourceLoader;
|
||||
@@ -82,6 +83,7 @@ impl AssetLoader for FighterBakeSourceLoader {
|
||||
model_bytes,
|
||||
buffers,
|
||||
animations: manifest.animations,
|
||||
root_motion_bone: manifest.root_motion_bone,
|
||||
})
|
||||
}
|
||||
fn extensions(&self) -> &[&str] {
|
||||
@@ -123,7 +125,12 @@ impl AssetTransformer for FighterBakeTransformer {
|
||||
source: TransformedAsset<Self::AssetInput>,
|
||||
_: &'a Self::Settings,
|
||||
) -> Result<TransformedAsset<Self::AssetOutput>, Self::Error> {
|
||||
let baked = bake_gltf(&source.model_bytes, &source.buffers, &source.animations)?;
|
||||
let baked = bake_gltf(
|
||||
&source.model_bytes,
|
||||
&source.buffers,
|
||||
&source.animations,
|
||||
&source.root_motion_bone,
|
||||
)?;
|
||||
Ok(source.replace_asset(baked))
|
||||
}
|
||||
}
|
||||
@@ -201,6 +208,7 @@ fn bake_gltf(
|
||||
bytes: &[u8],
|
||||
buffer_bytes: &[Vec<u8>],
|
||||
animations: &HashMap<AnimKind, String>,
|
||||
root_motion_bone: &str,
|
||||
) -> io::Result<BakedFighterAnimations> {
|
||||
let gltf = gltf::Gltf::from_slice(bytes)
|
||||
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
|
||||
@@ -228,13 +236,14 @@ fn bake_gltf(
|
||||
"glTF buffer data is incomplete",
|
||||
));
|
||||
}
|
||||
bake_gltf_document(gltf.document, buffers, animations)
|
||||
bake_gltf_document(gltf.document, buffers, animations, root_motion_bone)
|
||||
}
|
||||
|
||||
pub(super) fn bake_gltf_document(
|
||||
document: gltf::Document,
|
||||
buffers: Vec<gltf::buffer::Data>,
|
||||
animations: &HashMap<AnimKind, String>,
|
||||
root_motion_bone: &str,
|
||||
) -> io::Result<BakedFighterAnimations> {
|
||||
let nodes: Vec<_> = document.nodes().collect();
|
||||
if nodes.is_empty() {
|
||||
@@ -260,6 +269,15 @@ pub(super) fn bake_gltf_document(
|
||||
})
|
||||
})
|
||||
.collect::<io::Result<Vec<_>>>()?;
|
||||
let root_bone_index = names
|
||||
.iter()
|
||||
.position(|name| name == root_motion_bone)
|
||||
.ok_or_else(|| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("fighter model has no root-motion bone named {root_motion_bone}"),
|
||||
)
|
||||
})?;
|
||||
let mut pending = HashMap::<&str, Vec<AnimKind>>::new();
|
||||
for (kind, name) in animations {
|
||||
pending.entry(name).or_default().push(*kind);
|
||||
@@ -286,17 +304,28 @@ pub(super) fn bake_gltf_document(
|
||||
.fold(0.0_f32, f32::max);
|
||||
let frame_count = baked_frame_count(duration, BAKED_ANIMATION_FPS);
|
||||
let mut frames = Vec::with_capacity(frame_count);
|
||||
let mut root_positions = Vec::with_capacity(frame_count);
|
||||
for frame in 0..frame_count {
|
||||
let time = (frame as f32 / BAKED_ANIMATION_FPS as f32).min(duration);
|
||||
frames.push(
|
||||
nodes
|
||||
.iter()
|
||||
.map(|node| local_transform(node.clone(), &channels, time))
|
||||
.collect::<io::Result<Vec<_>>>()?,
|
||||
);
|
||||
let local = nodes
|
||||
.iter()
|
||||
.map(|node| local_transform(node.clone(), &channels, time))
|
||||
.collect::<io::Result<Vec<_>>>()?;
|
||||
let mut model = vec![None; local.len()];
|
||||
let root = super::runtime::resolve_model_transform(
|
||||
root_bone_index,
|
||||
&parents,
|
||||
&local,
|
||||
&mut model,
|
||||
)?;
|
||||
root_positions.push(root.get_translation());
|
||||
frames.push(local);
|
||||
}
|
||||
let index = clips.len();
|
||||
clips.push(BakedAnimationClip { frames });
|
||||
clips.push(BakedAnimationClip {
|
||||
frames,
|
||||
root_positions,
|
||||
});
|
||||
for kind in kinds {
|
||||
clip_indices.insert(kind, index);
|
||||
}
|
||||
@@ -322,6 +351,7 @@ pub(super) fn bake_gltf_document(
|
||||
frame_rate: BAKED_ANIMATION_FPS,
|
||||
bone_names: names,
|
||||
parents,
|
||||
root_bone_index,
|
||||
clips,
|
||||
clip_indices,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user