loading animation

This commit is contained in:
Lee-Orr
2024-02-08 19:01:18 -05:00
parent 5ce86b6f9b
commit 725a56aa5a
5 changed files with 52 additions and 12 deletions
+18
View File
@@ -1,7 +1,10 @@
#![allow(clippy::type_complexity)]
use bevy::{
pbr::{CascadeShadowConfigBuilder, DirectionalLightShadowMap},
prelude::*,
};
use bevy_facial_mocap::{CSVAnimationLoader, CSVAnimationLoaderSettings};
use bevy_inspector_egui::quick::WorldInspectorPlugin;
fn main() {
@@ -9,10 +12,15 @@ fn main() {
.insert_resource(DirectionalLightShadowMap { size: 4096 })
.add_plugins(DefaultPlugins)
.add_plugins(WorldInspectorPlugin::new())
.init_asset_loader::<CSVAnimationLoader>()
.add_systems(Startup, setup)
.add_systems(Update, setup_animation)
.run();
}
#[derive(Component)]
struct AnimationRunning(Handle<AnimationClip>);
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
@@ -42,3 +50,13 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default()
});
}
fn setup_animation(mut commands: Commands, asset_server: Res<AssetServer>, mut players: Query<Entity, (With<MorphWeights>, Without<AnimationRunning>)>) {
for entity in &mut players {
let handle = asset_server.load_with_settings("20240205_shapekey_BevyImplementationFaceCap_5/shapekey_BevyImplementationFaceCap_5_ScottiPhone_raw.morph_anim.csv", |s: &mut CSVAnimationLoaderSettings| { s.0.parts = vec![Name::new("pascal_Head")]; });
let mut player = AnimationPlayer::default();
player.play(handle.clone()).repeat();
commands.entity(entity).insert((AnimationRunning(handle), player));
}
}
+34 -12
View File
@@ -1,11 +1,9 @@
use std::{num::ParseFloatError, str::FromStr};
use bevy::{
animation::{AnimationClip, EntityPath, Keyframes, VariableCurve},
asset::{Asset, AssetLoader, AsyncReadExt},
reflect::Reflect,
animation::{self, AnimationClip, EntityPath, Keyframes, VariableCurve}, asset::{meta::Settings, Asset, AssetLoader, AsyncReadExt}, core::Name, reflect::Reflect
};
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
#[derive(
Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Reflect, Default,
@@ -222,10 +220,10 @@ impl From<CSVAnimation> for VariableCurve {
}
}
impl From<CSVAnimation> for AnimationClip {
fn from(val: CSVAnimation) -> Self {
let mut clip = Self::default();
clip.add_curve_to_path(EntityPath::default(), val.into());
impl CSVAnimation {
fn generate_clip(self, path: &EntityPath) -> AnimationClip {
let mut clip = AnimationClip::default();
clip.add_curve_to_path(path.clone(), self.into());
clip
}
@@ -249,17 +247,38 @@ impl std::fmt::Display for CSVAnimationLoaderError {
impl std::error::Error for CSVAnimationLoaderError {}
#[derive(Default)]
pub struct CSVAnimationLoaderSettings(pub EntityPath);
impl Serialize for CSVAnimationLoaderSettings {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer {
let names = self.0.parts.iter().map(|name| name.to_string()).collect::<Vec<String>>();
names.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for CSVAnimationLoaderSettings {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de> {
let names = Vec::<String>::deserialize(deserializer)?;
Ok(CSVAnimationLoaderSettings(EntityPath { parts: names.into_iter().map(|name| Name::new(name)).collect() }))
}
}
impl AssetLoader for CSVAnimationLoader {
type Asset = AnimationClip;
type Settings = ();
type Settings = CSVAnimationLoaderSettings;
type Error = CSVAnimationLoaderError;
fn load<'a>(
&'a self,
reader: &'a mut bevy::asset::io::Reader,
_settings: &'a Self::Settings,
settings: &'a Self::Settings,
_load_context: &'a mut bevy::asset::LoadContext,
) -> bevy::utils::BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
Box::pin(async move {
@@ -270,7 +289,10 @@ impl AssetLoader for CSVAnimationLoader {
.map_err(CSVAnimationLoaderError::Io)?;
let csv_animation =
CSVAnimation::parse(&csv).map_err(CSVAnimationLoaderError::CSVParseError)?;
Ok(csv_animation.into())
let animation = csv_animation.generate_clip(&settings.0);
Ok(animation)
})
}
@@ -423,7 +445,7 @@ mod tests {
00:00:01:01.00, 0, 0, 0",
)
.unwrap();
let clip: AnimationClip = animation.into();
let clip: AnimationClip = animation.generate_clip(&EntityPath::default());
assert!(clip.duration() - 1.33333 < 0.1);
let curves = clip
.get_curves_by_path(&EntityPath::default())