mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-22 11:50:53 +00:00
feat(animation): changes & some reverts of the latests experiments
This commit is contained in:
parent
0528286b12
commit
0998decb39
@ -48,9 +48,11 @@ pub struct AnimationInfos {
|
|||||||
pub animations: Vec<AnimationInfo>,
|
pub animations: Vec<AnimationInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive( Reflect, Default, Debug)]
|
||||||
pub struct AnimationMarker {
|
pub struct AnimationMarker {
|
||||||
pub frame: u32,
|
// pub frame: u32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub handled_for_cycle: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores information about animation markers: practical for adding things like triggering events at specific keyframes etc
|
/// Stores information about animation markers: practical for adding things like triggering events at specific keyframes etc
|
||||||
@ -59,18 +61,6 @@ pub struct AnimationMarker {
|
|||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct AnimationMarkers(pub HashMap<String, HashMap<u32, Vec<String>>>);
|
pub struct AnimationMarkers(pub HashMap<String, HashMap<u32, Vec<String>>>);
|
||||||
|
|
||||||
// FIXME: ugh, ugly, there has to be a better way to do this ?
|
|
||||||
#[derive(Component, Default, Debug)]
|
|
||||||
pub struct AnimationMarkerTrackers(pub HashMap<String, HashMap<u32, Vec<AnimationMarkerTracker>>>);
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
|
||||||
pub struct AnimationMarkerTracker {
|
|
||||||
// pub frame:u32,
|
|
||||||
// pub name: String,
|
|
||||||
// pub processed_for_cycle: bool,
|
|
||||||
pub prev_frame: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Event that gets triggered once a specific marker inside an animation has been reached (frame based)
|
/// Event that gets triggered once a specific marker inside an animation has been reached (frame based)
|
||||||
/// Provides some usefull information about which entity , wich animation, wich frame & which marker got triggered
|
/// Provides some usefull information about which entity , wich animation, wich frame & which marker got triggered
|
||||||
#[derive(Event, Debug)]
|
#[derive(Event, Debug)]
|
||||||
@ -132,15 +122,19 @@ pub fn trigger_instance_animation_markers_events(
|
|||||||
let matching_animation_marker = &markers.0[animation_name];
|
let matching_animation_marker = &markers.0[animation_name];
|
||||||
if matching_animation_marker.contains_key(&frame) {
|
if matching_animation_marker.contains_key(&frame) {
|
||||||
let matching_markers_per_frame = matching_animation_marker.get(&frame).unwrap();
|
let matching_markers_per_frame = matching_animation_marker.get(&frame).unwrap();
|
||||||
|
|
||||||
|
let foo = animation_length_seconds - time_in_animation;
|
||||||
|
println!("foo {}", foo);
|
||||||
// println!("FOUND A MARKER {:?} at frame {}", matching_markers_per_frame, frame);
|
// println!("FOUND A MARKER {:?} at frame {}", matching_markers_per_frame, frame);
|
||||||
// emit an event AnimationMarkerReached(entity, animation_name, frame, marker_name)
|
// 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
|
// FIXME: problem, this can fire multiple times in a row, depending on animation length , speed , etc
|
||||||
for marker_name in matching_markers_per_frame {
|
for marker in matching_markers_per_frame {
|
||||||
|
|
||||||
animation_marker_events.send(AnimationMarkerReached {
|
animation_marker_events.send(AnimationMarkerReached {
|
||||||
entity: entity,
|
entity: entity,
|
||||||
animation_name: animation_name.clone(),
|
animation_name: animation_name.clone(),
|
||||||
frame: frame,
|
frame: frame,
|
||||||
marker_name: marker_name.clone(),
|
marker_name: marker.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,61 +161,67 @@ pub fn trigger_blueprint_animation_markers_events(
|
|||||||
let animation_clip = animation_clips.get(animation_player.animation_clip());
|
let animation_clip = animation_clips.get(animation_player.animation_clip());
|
||||||
|
|
||||||
// FIXME: horrible code
|
// FIXME: horrible code
|
||||||
let mut markers:Option<&AnimationMarkers>= None;
|
for (_, markers, animation_infos, parent) in all_animation_infos.iter(){
|
||||||
let mut animation_infos:Option<&AnimationInfos>=None;
|
|
||||||
for (_, _markers, _animation_infos, parent) in all_animation_infos.iter(){
|
|
||||||
if parent.get() == entity {
|
if parent.get() == entity {
|
||||||
markers = Some(_markers);
|
if animation_clip.is_some() {
|
||||||
animation_infos = Some(_animation_infos);
|
|
||||||
|
// 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 / animation_length_seconds) * time_in_animation;
|
||||||
|
// println!("frame seconds {}", frame_seconds);
|
||||||
|
let frame = frame_seconds.ceil() as u32; // FIXME , bad hack
|
||||||
|
|
||||||
|
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: complete hack-ish solution , otherwise this can fire multiple times in a row, depending on animation length , speed , etc
|
||||||
|
let diff = frame as f32 - frame_seconds;
|
||||||
|
if diff < 0.03 {
|
||||||
|
for marker in matching_markers_per_frame {
|
||||||
|
|
||||||
|
animation_marker_events.send(AnimationMarkerReached {
|
||||||
|
entity: entity,
|
||||||
|
animation_name: animation_name.clone(),
|
||||||
|
frame: frame,
|
||||||
|
marker_name: marker.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
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(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -119,6 +119,7 @@ impl Plugin for BlueprintsPlugin {
|
|||||||
.register_type::<BlueprintName>()
|
.register_type::<BlueprintName>()
|
||||||
.register_type::<MaterialInfo>()
|
.register_type::<MaterialInfo>()
|
||||||
.register_type::<SpawnHere>()
|
.register_type::<SpawnHere>()
|
||||||
|
|
||||||
.register_type::<BlueprintAnimations>()
|
.register_type::<BlueprintAnimations>()
|
||||||
.register_type::<InstanceAnimations>()
|
.register_type::<InstanceAnimations>()
|
||||||
.register_type::<AnimationInfo>()
|
.register_type::<AnimationInfo>()
|
||||||
@ -127,7 +128,9 @@ impl Plugin for BlueprintsPlugin {
|
|||||||
.register_type::<AnimationMarkers>()
|
.register_type::<AnimationMarkers>()
|
||||||
.register_type::<HashMap<u32, Vec<String>>>()
|
.register_type::<HashMap<u32, Vec<String>>>()
|
||||||
.register_type::<HashMap<String, HashMap<u32, Vec<String>>>>()
|
.register_type::<HashMap<String, HashMap<u32, Vec<String>>>>()
|
||||||
|
|
||||||
.add_event::<AnimationMarkerReached>()
|
.add_event::<AnimationMarkerReached>()
|
||||||
|
|
||||||
.register_type::<BlueprintsList>()
|
.register_type::<BlueprintsList>()
|
||||||
.register_type::<HashMap<String, Vec<String>>>()
|
.register_type::<HashMap<String, Vec<String>>>()
|
||||||
.insert_resource(BluePrintsConfig {
|
.insert_resource(BluePrintsConfig {
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bevy_gltf_blueprints::{
|
use bevy_gltf_blueprints::{
|
||||||
AnimationInfos, AnimationMarkerReached, AnimationMarkerTrackers, AnimationMarkers,
|
AnimationInfos, AnimationMarkerReached,
|
||||||
BlueprintAnimationPlayerLink, BlueprintAnimations, BlueprintName, BlueprintsList,
|
BlueprintAnimationPlayerLink, BlueprintAnimations,
|
||||||
GltfBlueprintsSet, InstanceAnimationPlayerLink, InstanceAnimations,
|
InstanceAnimationPlayerLink, InstanceAnimations,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{gltf::Gltf, prelude::*};
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
use bevy_gltf_worlflow_examples_common_rapier::{AppState, GameState};
|
|
||||||
|
|
||||||
#[derive(Component, Reflect, Default, Debug)]
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
|
@ -6,7 +6,6 @@ pub use in_game::*;
|
|||||||
use std::{collections::HashMap, fs, time::Duration};
|
use std::{collections::HashMap, fs, time::Duration};
|
||||||
|
|
||||||
use bevy_gltf_blueprints::{
|
use bevy_gltf_blueprints::{
|
||||||
AnimationInfos, AnimationMarkerReached, AnimationMarkerTrackers, AnimationMarkers,
|
|
||||||
BlueprintAnimationPlayerLink, BlueprintAnimations, BlueprintName, BlueprintsList,
|
BlueprintAnimationPlayerLink, BlueprintAnimations, BlueprintName, BlueprintsList,
|
||||||
GltfBlueprintsSet, InstanceAnimationPlayerLink, InstanceAnimations,
|
GltfBlueprintsSet, InstanceAnimationPlayerLink, InstanceAnimations,
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,6 @@ import json
|
|||||||
import os
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
from .get_standard_exporter_settings import get_standard_exporter_settings
|
|
||||||
from .preferences import (AutoExportGltfPreferenceNames)
|
from .preferences import (AutoExportGltfPreferenceNames)
|
||||||
|
|
||||||
def generate_gltf_export_preferences(addon_prefs):
|
def generate_gltf_export_preferences(addon_prefs):
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
import bpy
|
|
||||||
|
|
||||||
def get_standard_exporter_settings():
|
|
||||||
settings_key = 'glTF2ExportSettings'
|
|
||||||
for scene in bpy.data.scenes:
|
|
||||||
if settings_key in scene:
|
|
||||||
settings = scene[settings_key]
|
|
||||||
#print("standard exporter settings", settings, dict(settings))
|
|
||||||
return dict(settings)
|
|
@ -80,7 +80,7 @@ def copy_animation_data(source, target):
|
|||||||
markers_formated += '}, '
|
markers_formated += '}, '
|
||||||
markers_formated += '}'
|
markers_formated += '}'
|
||||||
target["AnimationMarkers"] = f'( {markers_formated} )'
|
target["AnimationMarkers"] = f'( {markers_formated} )'
|
||||||
|
|
||||||
"""print("copying animation data for", source.name, target.animation_data)
|
"""print("copying animation data for", source.name, target.animation_data)
|
||||||
properties = [p.identifier for p in source.animation_data.bl_rna.properties if not p.is_readonly]
|
properties = [p.identifier for p in source.animation_data.bl_rna.properties if not p.is_readonly]
|
||||||
for prop in properties:
|
for prop in properties:
|
||||||
|
Loading…
Reference in New Issue
Block a user