diff --git a/assets/models/Martian Chess.glb b/assets/models/Martian Chess.glb index e69e2d6..85b072c 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:ddf012ed8fd66bd1fc0ae468584a1bc7167e1a682d1ee4176d66801f799dd59e -size 38887344 +oid sha256:e48f65900648c1d5972aa14fea00f39e3cc7d4f8060df34d14f423cc621fc82e +size 50950760 diff --git a/src/display3d.rs b/src/display3d.rs index ec334c8..9e0f086 100644 --- a/src/display3d.rs +++ b/src/display3d.rs @@ -17,39 +17,33 @@ impl Plugin for Display3dPlugin { OnExit(GameState::Loading), (initialize, fix_skybox.before(initialize)), ) - .add_systems( - Update, - menu::exit_to_menu.run_if(in_state(GameState::Display3d)), - ) .add_systems( Update, ( - set_piece_position.run_if(any_component_changed::), - set_piece_model.run_if(any_component_changed::), + menu::exit_to_menu.run_if(in_state(GameState::Display3d)), + set_piece_model.run_if(any_component_added::), set_board_model.run_if(any_component_added::), + set_piece_position.run_if(any_component_changed::), + set_piece_texture.run_if(any_component_changed::), ), ) .add_systems( Update, - gizmo_system - .run_if(in_state(GameState::Display3d)) - .run_if(resource_exists::()), - ) - .add_systems( - Update, - move_camera - .run_if(in_state(GameState::Display3d)) - .run_if(on_event::()) + ( + move_camera + .run_if(in_state(GameState::Display3d)) + .run_if(on_event::()), + gizmo_system.run_if(in_state(GameState::Display3d)), + mouse_zoom + .run_if(in_state(GameState::Display3d)) + .run_if(on_event::()), + ) .run_if(resource_exists::()), ) .add_systems( - Update, - mouse_zoom - .run_if(in_state(GameState::Display3d)) - .run_if(on_event::()) - .run_if(resource_exists::()), + OnEnter(GameState::Display3d), + (activate::, set_piece_texture), ) - .add_systems(OnEnter(GameState::Display3d), activate::) .add_systems(OnExit(GameState::Display3d), deactivate::); } } @@ -80,7 +74,7 @@ fn load_assets(server: Res, mut commands: Commands) { } /// Initialize the 3d board -fn initialize(mut commands: Commands, board: Option>, assets: Res) { +fn initialize(mut commands: Commands, board: Res, assets: Res) { info!("Initialize 3d camera"); // let handle = server.load("images/mars.hdr"); commands.spawn(( @@ -130,7 +124,7 @@ fn initialize(mut commands: Commands, board: Option>, assets: R parent .spawn((Display3d, Board3d, SceneBundle { ..default() })) .with_children(|parent| { - board.unwrap().pieces().iter().for_each(|(index, piece)| { + board.pieces().iter().for_each(|(index, piece)| { let side = Board::side(index).expect("Spawn valid side"); parent.spawn(( @@ -161,14 +155,14 @@ fn fix_skybox(mut images: ResMut>, assets: Res) { } } +/// Set the model for each piece based on the game::Piece::* marker fn set_piece_model( - mut events: Query<(&mut Handle, &Piece), (With, Changed)>, - assets_map: Option>, + mut events: Query<(&mut Handle, &Piece), Added>, + assets_map: Res, gltfs: Res>, ) { - let mf = assets_map.expect("Models file"); events.iter_mut().for_each(|(mut handle, piece)| { - let gltf = gltfs.get(&mf.models).expect("Load GLTF content"); + let gltf = gltfs.get(&assets_map.models).expect("Load GLTF content"); *handle = match piece { game::Piece::Pawn => gltf.named_scenes.get("Pawn"), game::Piece::Drone => gltf.named_scenes.get("Drone"), @@ -181,12 +175,11 @@ fn set_piece_model( fn set_board_model( mut events: Query<&mut Handle, With>, - assets_map: Option>, + assets_map: Res, gltfs: Res>, ) { - let mf = assets_map.expect("Models file"); events.iter_mut().for_each(|mut handle| { - let gltf = gltfs.get(&mf.models).expect("Load GLTF content"); + let gltf = gltfs.get(&assets_map.models).expect("Load GLTF content"); *handle = gltf .named_scenes .get("Gameboard") @@ -259,3 +252,118 @@ fn mouse_zoom( }); }); } + +/// Set the Texture for a piece given it's position (left or right) on the bord. +/// Executed when Side is changed or upon entry to Display3d state +/// Getting this to run _after_ GLTF is loaded is a pain. +/// PERF: We are saving what to work on in a Vector which is bad. +/// CAVEAT: We are only exeucting this when a piece changes or state is changed. +fn set_piece_texture( + events: Query<(Entity, &Piece, &Side), (With, Changed)>, + all: Query<(Entity, &Piece, &Side), With>, + gltfs: Res>, + assets_map: Res, + children: Query<&Children>, + mut models: Query<(&Name, &mut Handle)>, +) { + let pieces = if events.is_empty() { + all.iter().collect::>() + } else { + events.iter().collect::>() + }; + pieces.iter().for_each(|(entity, piece, side)| { + if let Some(gltf) = gltfs.get(&assets_map.models) { + children.iter_descendants(*entity).for_each(|child| { + if let Ok((n, mut m)) = models.get_mut(child) { + match (*piece, *side, n.as_str()) { + (Piece::Queen, Side::A, "Queen.0") => { + *m = gltf + .named_materials + .get("Queen") + .expect("Load Red Queen texture") + .clone() + } + (Piece::Queen, Side::A, "Queen.1") => { + *m = gltf + .named_materials + .get("Dots") + .expect("Load Red Dots texture") + .clone() + } + (Piece::Queen, Side::B, "Queen.0") => { + *m = gltf + .named_materials + .get("QueenBlue") + .expect("Load Blue Queen texture") + .clone() + } + (Piece::Queen, Side::B, "Queen.1") => { + *m = gltf + .named_materials + .get("DotsBlue") + .expect("Load Red Dots texture") + .clone() + } + (Piece::Drone, Side::A, "Drone.0") => { + *m = gltf + .named_materials + .get("Drone") + .expect("Load Red Drone texture") + .clone() + } + (Piece::Drone, Side::A, "Drone.1") => { + *m = gltf + .named_materials + .get("Dots") + .expect("Load Red Dots texture") + .clone() + } + (Piece::Drone, Side::B, "Drone.0") => { + *m = gltf + .named_materials + .get("DroneBlue") + .expect("Load Blue Drone texture") + .clone() + } + (Piece::Drone, Side::B, "Drone.1") => { + *m = gltf + .named_materials + .get("DotsBlue") + .expect("Load Blue Dots texture") + .clone() + } + (Piece::Pawn, Side::A, "Pawn.0") => { + *m = gltf + .named_materials + .get("Pawn") + .expect("Load Red Pawn texture") + .clone() + } + (Piece::Pawn, Side::A, "Pawn.1") => { + *m = gltf + .named_materials + .get("Dots") + .expect("Load Red Dots texture") + .clone() + } + (Piece::Pawn, Side::B, "Pawn.0") => { + *m = gltf + .named_materials + .get("DroneBlue") // TODO: FIX + .expect("Load Blue Pawn texture") + .clone() + } + (Piece::Pawn, Side::B, "Pawn.1") => { + *m = gltf + .named_materials + .get("DotsBlue") + .expect("Load Blue Dots texture") + .clone() + } + _ => warn!("???"), + } + } + }); + } + }) +} diff --git a/src/main.rs b/src/main.rs index 750ecb9..c76002b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -159,3 +159,9 @@ pub(crate) fn any_component_changed(q: Query>) pub(crate) fn any_component_added(q: Query>) -> bool { !q.is_empty() } + +pub(crate) fn any_component_added_or_changed( + q: Query, Changed)>>, +) -> bool { + !q.is_empty() +}