diff --git a/editor.ron b/editor.ron index 5ec76bc..b349112 100644 --- a/editor.ron +++ b/editor.ron @@ -1,6 +1,6 @@ { "space_editor_core::hotkeys::HotkeySet": "{\"space_editor_core::hotkeys::HotkeySet\":(bindings:{Rotate:[R],Translate:[G],Scale:[S],Multiple:[ShiftLeft],Clone:[AltLeft],Delete:[X]},name:\"GizmoHotkey\")}", - "space_undo::ChangeChainSettings": "{\"space_undo::ChangeChainSettings\":(max_change_chain_size:200)}", "space_persistence::PersistenceSettings": "{\"space_persistence::PersistenceSettings\":(load_on_startup:true,save_on_close:true)}", + "space_undo::ChangeChainSettings": "{\"space_undo::ChangeChainSettings\":(max_change_chain_size:200)}", "space_editor_ui::settings::NewWindowSettings": "{\"space_editor_ui::settings::NewWindowSettings\":(new_tab:SameNode)}", } \ No newline at end of file diff --git a/studio-bvh/src/joint.rs b/studio-bvh/src/joint.rs index 4632498..d5dc1c1 100644 --- a/studio-bvh/src/joint.rs +++ b/studio-bvh/src/joint.rs @@ -488,10 +488,12 @@ impl<'a> Iterator for Joints<'a> { return None; } - Some(Joint { + let next = Some(Joint { index: *current, joints: self.joints, - }) + }); + *current += 1; + next } JointIterType::Sequence(ref mut joints) => { let Some(next) = joints.pop_front() else { diff --git a/studio-bvh/src/lib.rs b/studio-bvh/src/lib.rs index d47195b..a0f0883 100644 --- a/studio-bvh/src/lib.rs +++ b/studio-bvh/src/lib.rs @@ -525,6 +525,10 @@ impl Bvh { pub fn joints_mut(&mut self) -> JointsMut<'_> { JointsMut::iter_root(&mut self.joints[..]) } + + pub fn joints_len(&self) -> usize { + self.joints.len() + } /// Returns a `Frames` iterator over the frames of the bvh. /// diff --git a/studio/src/anim/retargeting.rs b/studio/src/anim/retargeting.rs index 4e95b31..4efb17f 100644 --- a/studio/src/anim/retargeting.rs +++ b/studio/src/anim/retargeting.rs @@ -234,8 +234,8 @@ pub struct RetargetMap { impl RetargetMap { const MOCAP_NET: [(&'static str, &'static str); 80] = [ // Spine - ("LowerBack", "DEF-spine"), ("hip", "DEF-spine"), + ("LowerBack", "DEF-spine.001"), ("abdomen", "DEF-spine.002"), ("chest", "DEF-spine.003"), ("Neck", "DEF-spine.004"), diff --git a/studio/src/bvh/loader.rs b/studio/src/bvh/loader.rs index a5f4d32..bdc3a5c 100644 --- a/studio/src/bvh/loader.rs +++ b/studio/src/bvh/loader.rs @@ -1,7 +1,7 @@ use bevy::{ animation::{AnimationClip, EntityPath, Keyframes, VariableCurve}, asset::{io::Reader, AssetLoader, AsyncReadExt, LoadContext}, core::Name, math::{Quat, Vec3}, utils::BoxedFuture }; -use studio_bvh::Joint; +use studio_bvh::{joint, Joint}; use crate::anim::RetargetMap; @@ -28,11 +28,13 @@ impl AssetLoader for BvhLoader { let mut buf = vec![]; reader.read_to_end(&mut buf).await.anyhow()?; let bvh = studio_bvh::from_bytes(&buf).anyhow()?; + // println!("{:?}", bvh.joints_len()); let mut anim_clip = AnimationClip::default(); - for joint in bvh.joints() { + for (index, joint) in bvh.joints().enumerate() { let path = get_entity_path(&joint, &RetargetMap::default()); + println!("{} - {:?}", index, path); let mut timestamps = Vec::new(); let mut motions = Vec::new(); let mut rotations = Vec::new(); @@ -54,16 +56,16 @@ impl AssetLoader for BvhLoader { } motions.push(frame_pos); - rotations.push(Quat::from_euler(bevy::math::EulerRot::ZXY, frame_rot.x, frame_rot.y, frame_rot.z)); + rotations.push(Quat::from_euler(bevy::math::EulerRot::ZXY, frame_rot.x.to_radians(), frame_rot.y.to_radians(), frame_rot.z.to_radians())); } - if joint.is_root() { - let motion_curve = VariableCurve { - keyframe_timestamps: timestamps.clone(), - keyframes: Keyframes::Translation(motions), - }; - anim_clip.add_curve_to_path(path.clone(), motion_curve); - } + // if joint.is_root() { + // let motion_curve = VariableCurve { + // keyframe_timestamps: timestamps.clone(), + // keyframes: Keyframes::Translation(motions), + // }; + // anim_clip.add_curve_to_path(path.clone(), motion_curve); + // } let rotation_curve = VariableCurve { keyframe_timestamps: timestamps, @@ -91,6 +93,7 @@ pub fn get_entity_path(current_joint : &Joint, retarget_map : &RetargetMap) -> E path } else { let mut path = EntityPath::default(); + path.parts.push("Mannequin_gamerig".into()); path.parts.push(Name::new(name)); path } diff --git a/studio/src/lib.rs b/studio/src/lib.rs index ddc51fb..f0c88a8 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -10,7 +10,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; #[cfg(feature = "wasm")] use wasm_bindgen::prelude::*; -mod anim; +pub mod anim; mod bvh; mod camera_controller; mod change_tracking; @@ -26,7 +26,7 @@ mod mixamo; mod path; mod persistance; mod remote; -mod scene; +pub mod scene; pub mod screenshot; mod skybox; mod ui; @@ -92,6 +92,7 @@ impl PluginGroup for CommonPlugins { .add(WorldGridPlugin) .add(PersistancePlugin) .add(AnimPlugin) + .add(BvhPlugin) } } diff --git a/studio/src/main.rs b/studio/src/main.rs index f15a89d..0d0d6d6 100644 --- a/studio/src/main.rs +++ b/studio/src/main.rs @@ -1,9 +1,8 @@ use bevy::{ - app::Update, - window::{close_on_esc, Window}, + app::Update, ecs::{query::With, system::Query}, window::{close_on_esc, Window}, prelude::* }; use clap::Parser; -use studio::{screenshot::ScreenShotPlugin, InitAsset, InitParams, StudioMode}; +use studio::{anim::Skeleton, scene::{tag_scene_elements, SceneState}, screenshot::ScreenShotPlugin, InitAsset, InitParams, StudioMode}; #[derive(Parser)] #[command(name = "StorytellerStudio")] @@ -37,7 +36,30 @@ fn main() { // Add any additional systems, resources, etc. for local debugging app.add_systems(Update, close_on_esc); + app.add_systems(Update, add_anim); app.add_plugins(ScreenShotPlugin); app.run(); } + +fn add_anim( + mut commands : Commands, + skeletons : Query>, + asset_server : Res, +) { + let bvh_anim : Handle = asset_server.load("mocap/shuffle.bvh"); + + if skeletons.iter().count() > 0 { + println!("Adding animation to skeletons {}", skeletons.iter().count()); + } + + for skeleton in skeletons.iter() { + let mut animation_player = AnimationPlayer::default(); + animation_player.play(bvh_anim.clone()); + println!("{:?}", skeleton); + commands.entity(skeleton).insert(( + animation_player, + bvh_anim.clone() + )); + } +} \ No newline at end of file diff --git a/studio/src/scene.rs b/studio/src/scene.rs index 81af07f..291e0f8 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -376,7 +376,7 @@ fn init_scene_loading( } } -fn tag_scene_elements( +pub fn tag_scene_elements( mut cmd: Commands, // A "glTF mesh" is actually a container for one or more "glTF primitives", // which is basically a bundle of vertices paired with the material used to