diff --git a/Cargo.lock b/Cargo.lock index 46cbe9f..05534ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2062,9 +2062,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad2dcfb6dd7a66f9eb3d181a29dcfb22d146b0bcdc2e1ed1713cbf03939a88ea" dependencies = [ + "base64 0.13.1", "byteorder", "gltf-json", + "image", "lazy_static", + "urlencoding", ] [[package]] @@ -2542,6 +2545,7 @@ dependencies = [ "anyhow", "bevy", "bevy_fmod", + "gltf", "serde", "thiserror", "toml", @@ -3684,6 +3688,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "uuid" version = "1.6.1" diff --git a/Cargo.toml b/Cargo.toml index fcdac4d..26e3bc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,7 @@ toml = { version = "0.8", features = ["parse"] } anyhow = "*" thiserror = "*" +gltf = "*" + [profile.dev] opt-level = 3 diff --git a/assets/martian.tweak.toml b/assets/martian.tweak.toml index 35c653c..a43f486 100644 --- a/assets/martian.tweak.toml +++ b/assets/martian.tweak.toml @@ -70,9 +70,20 @@ intro_a = "GameCamIntro1" intro_b = "GameCamIntro2" turn_a = "GameCamSide2>1" turn_b = "GameCamSide1>2" -pick_up = "PiecePickup" -put_down = "PiecePutDown" -idle = "PieceIdle" +[display3d.models.animations.pick_up] +pawn = "PiecePickup" +drone = "PiecePickup" +queen = "PiecePickup" + +[display3d.models.animations.put_down] +pawn = "PiecePutDown" +drone = "PiecePutDown" +queen = "PiecePutDown" + +[display3d.models.animations.idle] +pawn = "PieceIdle" +drone = "PieceIdle" +queen = "PieceIdle" [display3d.models.materials] queen_red = "Queen" @@ -107,7 +118,7 @@ Rgba = { red = 1.0, green = 1.0, blue = 1.0, alpha = 0.0 } # https://docs.rs/bevy/0.11.3/bevy/pbr/enum.FogFalloff.html ### [display3d.fog.falloff] -Exponential = { density = 0.005 } +Exponential = { density = 0.000 } # Examples: # * Linear = { start = 1.0, end = 10.0 } # * Exponential = { density = 1.0 } diff --git a/assets/models/Martian Chess.glb b/assets/models/Martian Chess.glb index 3b2fec4..c72324f 100644 --- a/assets/models/Martian Chess.glb +++ b/assets/models/Martian Chess.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aca7bf25047e219de0284ccf750a94f21169a96481e022696cb45d8f32a0fb56 -size 30079816 +oid sha256:781a89fb4e97b6873d5bbdc6a0797567ca181b82b5cc0e1c237045aaea9f383e +size 30086804 diff --git a/examples/gltf-rs-checkr.rs b/examples/gltf-rs-checkr.rs new file mode 100644 index 0000000..701d4f9 --- /dev/null +++ b/examples/gltf-rs-checkr.rs @@ -0,0 +1,11 @@ +use gltf::*; + +fn main() -> gltf::Result<()> { + let g = Gltf::open("assets/models/Martian Chess.glb")?; + g.animations() + .into_iter() + .for_each(|x| { + println!("{:?}", x.name()); + }); + Ok(()) +} \ No newline at end of file diff --git a/src/blogpost-animation-troubleshooting.md b/src/blogpost-animation-troubleshooting.md new file mode 100644 index 0000000..d57ddfc --- /dev/null +++ b/src/blogpost-animation-troubleshooting.md @@ -0,0 +1,24 @@ +# Debugging animations not working? + +OK so seems like this: +https://github.com/bevyengine/bevy/blob/22e39c4abf6e2fdf99ba0820b3c35db73be71347/crates/bevy_animation/src/lib.rs#L119C12-L122 + +Printed as this: + +``` + paths: { + EntityPath { + parts: [ + "Queen", + ], + }: 0, + }, +``` + +Means the only entity that this will play for is one called "Queen". + +Now there are a few hacks we can do. +We can add the `Name("Queen")` to all of our entities but that's BS. +They aren't Queens they are Pawns and Drones. + +So why does Bevy think the animation is only associated with Queen and not other entities? \ No newline at end of file diff --git a/src/debug.rs b/src/debug.rs index ce4f380..fc190a3 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -27,6 +27,7 @@ impl Plugin for DebugPlugin { display_diagnostics.run_if(resource_exists::()), toggle_debug_ui.run_if(resource_changed_or_removed::()), camera_info.run_if(resource_exists::()), + // gltf_info.run_if(on_event::>()), ), ); } @@ -138,4 +139,12 @@ fn camera_info(mut debug_infos: ResMut, cameras: Query<(&Camera, &Nam .intersperse(", ") .collect::(); debug_infos.set("Cameras".into(), camera_names); +} + +fn gltf_info( + gltfs: Res>, +) { + gltfs.iter().for_each(|(_, gltf)| { + info!("Named animations: {:#?}", gltf.named_animations); + }); } \ No newline at end of file diff --git a/src/display3d.rs b/src/display3d.rs index 933a34b..3e7849b 100644 --- a/src/display3d.rs +++ b/src/display3d.rs @@ -203,6 +203,7 @@ fn hydrate_camera( let skybox_handle = tweak .get_handle::("display3d_models_skybox_file") .unwrap(); + info!("Hydrating camera {:?}", entity); // Populate the components for the camera commands.entity(entity).insert(( Display3d, @@ -434,18 +435,6 @@ fn set_board_model( .expect("Game board model") .clone(); }); - // TODO: Get rid of this -- upstream asset has merged tiles back into gameboard scene - let assets_handle = tweak - .get_handle::("display3d_models_assets_file") - .unwrap(); - tiles.iter_mut().for_each(|mut handle| { - let gltf = gltfs.get(assets_handle.clone()).expect("Load GLTF content"); - *handle = gltf - .named_scenes - .get("Tiles") - .expect("Game tiles model") - .clone(); - }); } /// Sets a piece location given it's board index @@ -867,7 +856,8 @@ fn pick_up( >, gltfs: Res>, children: Query<&Children>, - mut players: Query<&mut AnimationPlayer>, + mut players: Query<(&Name, &mut AnimationPlayer)>, + clips: Res>, tweaks: Res>, tweaks_file: Res, ) { @@ -879,31 +869,40 @@ fn pick_up( .get_handle::("display3d_models_assets_file") .unwrap(); let gltf = gltfs.get(assets_handle).expect("Load GLTF content"); + info!("Pickup animation for {:?}", entity); children.iter_descendants(entity).for_each(|child| { - if let Ok(mut player) = players.get_mut(child) { - info!("Picking up {:?} {:?}", entity, piece); - let animation = gltf.named_animations.get( + info!(" Child: {:?}", child); + if let Ok((name, mut player)) = players.get_mut(child) { + info!("Picking up {:?} ({:?}) {:?}", name, entity, piece); + let pickup_handle = gltf.named_animations.get( tweak - .get::("display3d_models_animations_pick_up") + .get::("display3d_models_animations_pick_up_queen") .unwrap() .as_str(), - ); - let idle = gltf.named_animations.get( + ).expect("Pickup Animation"); + let idle_handle = gltf.named_animations.get( tweak - .get::("display3d_models_animations_idle") + .get::("display3d_models_animations_idle_queen") .unwrap() .as_str(), - ); - player - .start_with_transition( - animation.expect("Pickup Animation").clone(), - Duration::from_secs_f32(0.75), - ) - .start_with_transition( - idle.expect("Idle animation").clone(), - Duration::from_secs_f32(1.5), - ) - .set_repeat(RepeatAnimation::Forever); + ).expect("Idle animation"); + if let Some(pickup_clip) = clips.get(pickup_handle) { + info!("Animation clip: {:#?}", pickup_clip); + if let Some(idle_clip) = clips.get(idle_handle) { + if pickup_clip.compatible_with(name) && idle_clip.compatible_with(name) { + player + .start_with_transition( + pickup_handle.clone(), + Duration::from_secs_f32(0.75), + ) + .start_with_transition( + idle_handle.clone(), + Duration::from_secs_f32(1.5), + ) + .set_repeat(RepeatAnimation::Forever); + } + }; + } } }) }); @@ -914,7 +913,8 @@ fn put_down( mut query: Query<&game::Piece, (With, With, With)>, gltfs: Res>, children: Query<&Children>, - mut players: Query<&mut AnimationPlayer>, + mut players: Query<(&Name, &mut AnimationPlayer)>, + clips: Res>, tweaks: Res>, tweaks_file: Res, ) { @@ -922,26 +922,30 @@ fn put_down( .get(&tweaks_file.handle.clone()) .expect("Load tweakfile"); events.read().for_each(|entity| { - if let Ok(_piece) = query.get_mut(entity) { + if let Ok(piece) = query.get_mut(entity) { let assets_handle = tweak .get_handle::("display3d_models_assets_file") .unwrap(); let gltf = gltfs.get(assets_handle).expect("Load GLTF content"); children.iter_descendants(entity).for_each(|child| { - if let Ok(mut player) = players.get_mut(child) { + if let Ok((name, mut player)) = players.get_mut(child) { info!("Putting down {:?}", entity); - let animation = gltf.named_animations.get( + let putdown_handle = gltf.named_animations.get( tweak - .get::("display3d_models_animations_put_down") + .get::("display3d_models_animations_put_down_queen") .unwrap() .as_str(), - ); - player - .start_with_transition( - animation.expect("PutDown Animation").clone(), - Duration::from_secs_f32(0.75), - ) - .set_repeat(RepeatAnimation::Never); + ).expect("PutDown Animation"); + if let Some(putdown_clip) = clips.get(putdown_handle) { + if putdown_clip.compatible_with(name) { + player + .start_with_transition( + putdown_handle.clone(), + Duration::from_secs_f32(0.75), + ) + .set_repeat(RepeatAnimation::Never); + } + } } }) }