diff --git a/assets/martian.tweak.toml b/assets/martian.tweak.toml index bdab7a3..82f6040 100644 --- a/assets/martian.tweak.toml +++ b/assets/martian.tweak.toml @@ -43,7 +43,7 @@ Neothic Font by Daymarius: https://www.dafont.com/neothic.font # Colors are in hex (RED GREEN BLUE ALPHA) rgba_hidden = "#00000000" rgba_visible = "#FFFFFFFF" -rgba_background = "#000000FF" +rgba_background = "#000000AA" # Higher rate is slower typing speed. Integers only! delay = 0.1 text = [ @@ -69,7 +69,7 @@ Will you be a part of the universal rhyme, and if so, which side are you on? # Hex colors for in/visible text (only visible used for now) rgba_hidden = "#00000000" rgba_visible = "#FFFFFFFF" -rgba_background = "#000000FF" +rgba_background = "#000000AA" intro = [ """ diff --git a/src/credits.rs b/src/credits.rs index 6dcb18c..4adc336 100644 --- a/src/credits.rs +++ b/src/credits.rs @@ -47,7 +47,7 @@ fn init_credits_ui( padding: UiRect::all(Val::Px(25.0)), ..default() }, - background_color: Color::BLACK.into(), + background_color: Color::BLACK.with_a(0.9).into(), ..default() }, )) diff --git a/src/display3d.rs b/src/display3d.rs index cf27c04..6d619ee 100644 --- a/src/display3d.rs +++ b/src/display3d.rs @@ -558,49 +558,72 @@ fn select( mut selections: EventWriter, state: Res>, ) { + // For every mouse click event events .read() + // Only read button presses .filter(|ev| ev.state == ButtonState::Pressed) .for_each(|_| { + // For each window (there should be only one) windows.iter().for_each(|window| { + // Get the cursor position if let Some(pos) = window.cursor_position() { + // iterate over every camera cameras.iter().for_each(|(camera, gt)| { + // Get a ray from the camera through the cursor into the world if let Some(ray) = camera.viewport_to_world(gt, pos) { + // Iterate over every entity with a 3d scene query .iter() + // Transform the scene handle into mesh data .filter_map(|(entity, handle, gt)| { meshes.get(handle).map(|mesh| (entity, mesh, gt)) }) - .for_each(|(entity, mesh, gt)| { - if let Some(_hit) = hit::intersects3d(&ray, mesh, gt) { - selectable - .iter() - .find_map(|(e, &board_index, &side)| { - // Check the side of the selection if no piece is selected - // Otherwise this is fine, select away - let side_check = - !selected.is_empty() || state.get().0 == side; - - let hit_check = { - // This entity was hit (tile hitboxes) - let primary = entity == e; - - // A child was hit (pieces) - let secondary = children - .iter_descendants(e) - .any(|child| child == entity); - - primary || secondary - }; - - (side_check && hit_check).then_some(board_index) - }) - .iter() - .for_each(|&board_index| { - info!("Board index selected: {:?}", board_index); - selections.send(game::Selection(board_index)); - }); - } + // Iterate over every mesh + global transform + .filter_map(|(entity, mesh, gt)| { + // If the camera -> cursor -> * ray intersects with the mesh + hit3d::intersects3d(&ray, mesh, gt).map(|hit| (entity, hit)) + }) + .filter_map(|(entity, hit)| { + // Find this entity in the set of selectable entities + selectable + .iter() + .find_map(|(e, &board_index, &side)| { + // Check the side of the selection if no piece is selected + // Otherwise this is fine, select away + let side_check = + !selected.is_empty() || state.get().0 == side; + + let hit_check = { + // This entity was hit (tile hitboxes) + let primary = entity == e; + + // A child was hit (pieces) + let secondary = children + .iter_descendants(e) + .any(|child| child == entity); + + primary || secondary + }; + + // Return the board index of this piece + (side_check && hit_check).then_some(board_index) + }) + .map(|board_index| { + // Include the hit from the camera + (hit, board_index) + }) + }) + // Compare the distance of all hits, choosing the closest one + .min_by(|(hit_a, _), (hit_b, _)| { + hit_a.distance.partial_cmp(&hit_b.distance).unwrap() + }) + // Iterate over the 0 or 1 outcomes of the above + .iter() + // Send an event that this board index was selected + .for_each(|(_, board_index)| { + info!("Board index selected: {:?}", board_index); + selections.send(game::Selection(*board_index)); }); } }); @@ -1337,4 +1360,4 @@ fn monitor_animations( commands.entity(entity).insert(Animating); } }); -} \ No newline at end of file +} diff --git a/src/hit.rs b/src/hit3d.rs similarity index 99% rename from src/hit.rs rename to src/hit3d.rs index 7f0842e..a5a5481 100644 --- a/src/hit.rs +++ b/src/hit3d.rs @@ -3,7 +3,7 @@ use crate::prelude::*; /// Hit data for 3d objects in Global (not Local) space and the distance from the Camera #[derive(Debug)] pub(crate) struct Hit3d { - distance: f32, + pub distance: f32, _point: Vec3, } diff --git a/src/main.rs b/src/main.rs index eb42c4d..a914df5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ mod credits; mod debug; mod display3d; mod game; -mod hit; +mod hit3d; mod intro; mod loading; mod menu;