From 66df7fae998621285354f0f15d0e1f8bcf357174 Mon Sep 17 00:00:00 2001 From: "kaosat.dev" Date: Mon, 1 Apr 2024 00:26:23 +0200 Subject: [PATCH] feat(animation): * moved triggering of frame marker events to the blueprints crate * added additional handling of frame markers for blueprint animations (yikes is this convoluted) * added additional animated blueprint for testing blueprint animation markers --- crates/bevy_gltf_blueprints/src/animation.rs | 145 +++++++++++++++++++ crates/bevy_gltf_blueprints/src/lib.rs | 7 +- testing/bevy_example/assets/registry.json | 11 ++ testing/bevy_example/assets/testing.blend | Bin 2258592 -> 2232460 bytes testing/bevy_example/src/game/animation.rs | 94 ++++-------- testing/bevy_example/src/game/mod.rs | 3 +- 6 files changed, 192 insertions(+), 68 deletions(-) diff --git a/crates/bevy_gltf_blueprints/src/animation.rs b/crates/bevy_gltf_blueprints/src/animation.rs index ee400b3..8e73aaa 100644 --- a/crates/bevy_gltf_blueprints/src/animation.rs +++ b/crates/bevy_gltf_blueprints/src/animation.rs @@ -80,3 +80,148 @@ pub struct AnimationMarkerReached { pub frame: u32, pub marker_name: String, } + + +///////////////////// + +/// triggers events when a given animation marker is reached for INSTANCE animations +pub fn trigger_instance_animation_markers_events( + animation_infos: Query<( + Entity, + &AnimationMarkers, + &InstanceAnimationPlayerLink, + &InstanceAnimations, + &AnimationInfos, + )>, + animation_players: Query<&AnimationPlayer>, + animation_clips: Res>, + mut animation_marker_events: EventWriter, +) { + for (entity, markers, link, animations, animation_infos) in animation_infos.iter() { + let animation_player = animation_players.get(link.0).unwrap(); + let animation_clip = animation_clips.get(animation_player.animation_clip()); + + if animation_clip.is_some() { + // println!("Entity {:?} markers {:?}", entity, markers); + // println!("Player {:?} {}", animation_player.elapsed(), animation_player.completions()); + // FIMXE: yikes ! very inneficient ! perhaps add boilerplate to the "start playing animation" code so we know what is playing + let animation_name = animations.named_animations.iter().find_map(|(key, value)| { + if value == animation_player.animation_clip() { + Some(key) + } else { + None + } + }); + if animation_name.is_some() { + let animation_name = animation_name.unwrap(); + + let animation_length_seconds = animation_clip.unwrap().duration(); + let animation_length_frames = animation_infos + .animations + .iter() + .find(|anim| &anim.name == animation_name) + .unwrap() + .frames_length; + // TODO: we also need to take playback speed into account + let time_in_animation = animation_player.elapsed() + - (animation_player.completions() as f32) * animation_length_seconds; + let frame_seconds = + (animation_length_frames as f32 / animation_length_seconds) * time_in_animation; + let frame = frame_seconds as u32; + + let matching_animation_marker = &markers.0[animation_name]; + if matching_animation_marker.contains_key(&frame) { + let matching_markers_per_frame = matching_animation_marker.get(&frame).unwrap(); + // println!("FOUND A MARKER {:?} at frame {}", matching_markers_per_frame, frame); + // emit an event AnimationMarkerReached(entity, animation_name, frame, marker_name) + // FIXME: problem, this can fire multiple times in a row, depending on animation length , speed , etc + for marker_name in matching_markers_per_frame { + animation_marker_events.send(AnimationMarkerReached { + entity: entity, + animation_name: animation_name.clone(), + frame: frame, + marker_name: marker_name.clone(), + }); + } + } + } + } + } +} + +/// triggers events when a given animation marker is reached for BLUEPRINT animations +pub fn trigger_blueprint_animation_markers_events( + animation_infos: Query<( + Entity, + &BlueprintAnimationPlayerLink, + &BlueprintAnimations, + )>, + // FIXME: annoying hiearchy issue yet again: the Markers & AnimationInfos are stored INSIDE the blueprint, so we need to access them differently + all_animation_infos: Query<(Entity, &AnimationMarkers, &AnimationInfos, &Parent)>, + animation_players: Query<&AnimationPlayer>, + animation_clips: Res>, + mut animation_marker_events: EventWriter, +) { + for (entity, link, animations) in animation_infos.iter() { + let animation_player = animation_players.get(link.0).unwrap(); + let animation_clip = animation_clips.get(animation_player.animation_clip()); + + // FIXME: horrible code + let mut markers:Option<&AnimationMarkers>= None; + let mut animation_infos:Option<&AnimationInfos>=None; + for (_, _markers, _animation_infos, parent) in all_animation_infos.iter(){ + if parent.get() == entity { + markers = Some(_markers); + animation_infos = Some(_animation_infos); + break; + } + } + if animation_clip.is_some() && markers.is_some() && animation_infos.is_some() { + let markers = markers.unwrap(); + let animation_infos = animation_infos.unwrap(); + + // println!("Entity {:?} markers {:?}", entity, markers); + // println!("Player {:?} {}", animation_player.elapsed(), animation_player.completions()); + // FIMXE: yikes ! very inneficient ! perhaps add boilerplate to the "start playing animation" code so we know what is playing + let animation_name = animations.named_animations.iter().find_map(|(key, value)| { + if value == animation_player.animation_clip() { + Some(key) + } else { + None + } + }); + if animation_name.is_some() { + let animation_name = animation_name.unwrap(); + let animation_length_seconds = animation_clip.unwrap().duration(); + let animation_length_frames = animation_infos + .animations + .iter() + .find(|anim| &anim.name == animation_name) + .unwrap() + .frames_length; + // TODO: we also need to take playback speed into account + let time_in_animation = animation_player.elapsed() + - (animation_player.completions() as f32) * animation_length_seconds; + let frame_seconds = + (animation_length_frames as f32 / animation_length_seconds) * time_in_animation; + let frame = frame_seconds as u32; + + let matching_animation_marker = &markers.0[animation_name]; + if matching_animation_marker.contains_key(&frame) { + let matching_markers_per_frame = matching_animation_marker.get(&frame).unwrap(); + // println!("FOUND A MARKER {:?} at frame {}", matching_markers_per_frame, frame); + // emit an event AnimationMarkerReached(entity, animation_name, frame, marker_name) + // FIXME: problem, this can fire multiple times in a row, depending on animation length , speed , etc + for marker_name in matching_markers_per_frame { + animation_marker_events.send(AnimationMarkerReached { + entity: entity, + animation_name: animation_name.clone(), + frame: frame, + marker_name: marker_name.clone(), + }); + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/bevy_gltf_blueprints/src/lib.rs b/crates/bevy_gltf_blueprints/src/lib.rs index 612a0b0..cef5b04 100644 --- a/crates/bevy_gltf_blueprints/src/lib.rs +++ b/crates/bevy_gltf_blueprints/src/lib.rs @@ -177,6 +177,11 @@ impl Plugin for BlueprintsPlugin { (spawned_blueprint_post_process, apply_deferred) .chain() .in_set(GltfBlueprintsSet::AfterSpawn), - ); + ) + + + .add_systems(Update, (trigger_instance_animation_markers_events, trigger_blueprint_animation_markers_events)) + + ; } } diff --git a/testing/bevy_example/assets/registry.json b/testing/bevy_example/assets/registry.json index 03cf205..3752489 100644 --- a/testing/bevy_example/assets/registry.json +++ b/testing/bevy_example/assets/registry.json @@ -2993,6 +2993,17 @@ "type": "object", "typeInfo": "Struct" }, + "bevy_example::game::animation::MarkerFox": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "properties": {}, + "required": [], + "short_name": "MarkerFox", + "title": "bevy_example::game::animation::MarkerFox", + "type": "object", + "typeInfo": "Struct" + }, "bevy_example::test_components::AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut": { "additionalProperties": false, "isComponent": true, diff --git a/testing/bevy_example/assets/testing.blend b/testing/bevy_example/assets/testing.blend index bdce4f58230f2712e83bdee797af84da092006fe..0cb450086a72ac2024ca63d939f8fee3c3e07826 100644 GIT binary patch delta 83133 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 diff --git a/testing/bevy_example/src/game/animation.rs b/testing/bevy_example/src/game/animation.rs index 326b52b..38aaf92 100644 --- a/testing/bevy_example/src/game/animation.rs +++ b/testing/bevy_example/src/game/animation.rs @@ -24,6 +24,11 @@ pub struct Marker2; /// flag component for testing pub struct Marker3; +#[derive(Component, Reflect, Default, Debug)] +#[reflect(Component)] +/// flag component for testing +pub struct MarkerFox; + #[derive(Resource)] pub struct AnimTest(Handle); @@ -91,9 +96,32 @@ pub fn play_animations( (With, With), >, + animated_fox: Query< + (&BlueprintAnimationPlayerLink, &BlueprintAnimations), + (With), + >, + mut animation_players: Query<&mut AnimationPlayer>, keycode: Res>, ) { + if keycode.just_pressed(KeyCode::KeyP) { + for (link, animations) in animated_fox.iter() { + println!("animations {:?}", animations.named_animations); + let mut animation_player = animation_players.get_mut(link.0).unwrap(); + let anim_name = "Run"; + animation_player + .play_with_transition( + animations + .named_animations + .get(anim_name) + .expect("animation name should be in the list") + .clone(), + Duration::from_secs(5), + ) + .repeat(); + } + } + if keycode.just_pressed(KeyCode::KeyM) { for (link, animations) in animated_marker1.iter() { println!("animations {:?}", animations.named_animations); @@ -202,72 +230,6 @@ pub fn play_animations( } } -pub fn trigger_event_based_on_animation_marker( - animation_infos: Query<( - Entity, - &AnimationMarkers, - &InstanceAnimationPlayerLink, - &InstanceAnimations, - &AnimationInfos, - )>, - animation_players: Query<&AnimationPlayer>, - animation_clips: Res>, - mut animation_marker_events: EventWriter, -) { - for (entity, markers, link, animations, animation_infos) in animation_infos.iter() { - let animation_player = animation_players.get(link.0).unwrap(); - let animation_clip = animation_clips.get(animation_player.animation_clip()); - - if animation_clip.is_some() { - // if marker_trackers.0.contains_key(k) - // marker_trackers.0 - // println!("Entity {:?} markers {:?}", entity, markers); - // println!("Player {:?} {}", animation_player.elapsed(), animation_player.completions()); - - // FIMXE: yikes ! very inneficient ! perhaps add boilerplate to the "start playing animation" code so we know what is playing - let animation_name = animations.named_animations.iter().find_map(|(key, value)| { - if value == animation_player.animation_clip() { - Some(key) - } else { - None - } - }); - if animation_name.is_some() { - let animation_name = animation_name.unwrap(); - - let animation_length_seconds = animation_clip.unwrap().duration(); - let animation_length_frames = animation_infos - .animations - .iter() - .find(|anim| &anim.name == animation_name) - .unwrap() - .frames_length; - // TODO: we also need to take playback speed into account - let time_in_animation = animation_player.elapsed() - - (animation_player.completions() as f32) * animation_length_seconds; - let frame_seconds = - (animation_length_frames as f32 / animation_length_seconds) * time_in_animation; - let frame = frame_seconds as u32; - - let matching_animation_marker = &markers.0[animation_name]; - if matching_animation_marker.contains_key(&frame) { - let matching_markers_per_frame = matching_animation_marker.get(&frame).unwrap(); - // println!("FOUND A MARKER {:?} at frame {}", matching_markers_per_frame, frame); - //emit an event , something like AnimationMarkerReached(entity, animation_name, frame, marker_name) - // FIXME: problem, this can fire multiple times in a row, depending on animation length , speed , etc - for marker_name in matching_markers_per_frame { - animation_marker_events.send(AnimationMarkerReached { - entity: entity, - animation_name: animation_name.clone(), - frame: frame, - marker_name: marker_name.clone(), - }); - } - } - } - } - } -} pub fn react_to_animation_markers( mut animation_marker_events: EventReader, diff --git a/testing/bevy_example/src/game/mod.rs b/testing/bevy_example/src/game/mod.rs index d6d6d14..ead2735 100644 --- a/testing/bevy_example/src/game/mod.rs +++ b/testing/bevy_example/src/game/mod.rs @@ -130,6 +130,7 @@ impl Plugin for GamePlugin { app.register_type::() .register_type::() .register_type::() + .register_type::() .add_systems(Update, (spawn_test).run_if(in_state(GameState::InGame))) .add_systems(Update, validate_export) @@ -137,7 +138,7 @@ impl Plugin for GamePlugin { .add_systems(OnEnter(AppState::AppRunning), setup_game) .add_systems(OnEnter(AppState::MenuRunning), setup_main_scene_animations) - .add_systems(Update, (animations, trigger_event_based_on_animation_marker) + .add_systems(Update, (animations) .run_if(in_state(AppState::AppRunning)) .after(GltfBlueprintsSet::AfterSpawn) )