diff --git a/Cargo.lock b/Cargo.lock index 0c3af44..4e240cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -457,6 +457,15 @@ dependencies = [ "glam 0.13.1", ] +[[package]] +name = "bevy_mod_raycast" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b699d78034aaf5730a4c10a09fd5a2e6886964a42fa7453b9e5f8b926cd846e" +dependencies = [ + "bevy", +] + [[package]] name = "bevy_pbr" version = "0.5.0" @@ -2124,6 +2133,7 @@ name = "moria" version = "0.1.0" dependencies = [ "bevy", + "bevy_mod_raycast", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 2f436f8..bc8dd57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" [dependencies] bevy = "0.5.0" +bevy_mod_raycast = "0.2.2" diff --git a/src/camera.rs b/src/camera.rs index 91dc6be..df0e633 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,8 +1,18 @@ use bevy::prelude::*; +use bevy_mod_raycast::{RayCastMethod, RayCastSource}; use crate::player::*; +pub struct MyRaycastSet; + pub struct Camera; +pub fn spawn_camera(commands: &mut Commands) { + commands + .spawn_bundle(PerspectiveCameraBundle::default()) + .insert(Camera) + .insert(RayCastSource::::new()); +} + pub fn camera_follow_player( player: Query<(&Transform, &Player), Without>, mut camera: Query<(&mut Transform, &Camera), Without>, @@ -18,3 +28,31 @@ pub fn camera_follow_player( trans.look_at(player_pos, Vec3::Y); } } + +// update our `RayCastSource` with the current cursor position every frame. +pub fn update_raycast_with_cursor( + mut cursor: EventReader, + mut query: Query<&mut RayCastSource>, +) { + for mut pick_source in query.iter_mut() { + // Grab the most recent cursor event if it exists: + if let Some(cursor_latest) = cursor.iter().last() { + pick_source.cast_method = RayCastMethod::Screenspace(cursor_latest.position); + } + } +} + +#[derive(Default)] +pub struct MouseCoords(pub Vec3); + +// Update our `RayCastSource` with the current cursor position every frame. +pub fn update_mouse_coords( + query: Query<&RayCastSource>, + mut coords: ResMut, +) { + for pick_source in query.iter() { + if let Some((_, intersection)) = pick_source.intersect_top() { + coords.0 = intersection.position(); + } + } +} diff --git a/src/main.rs b/src/main.rs index 3d83b89..c79b4ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,16 @@ use bevy::{input::system::exit_on_esc_system, pbr::AmbientLight, prelude::*}; +use bevy_mod_raycast::{build_rays, update_raycast, PluginState, RayCastMesh, RaycastSystem}; +mod camera; +mod columns; +mod light_balls; +mod loading; +mod player; mod rendering; -mod light_balls; -use light_balls::*; -mod player; -use player::*; -mod camera; use camera::*; -mod columns; - -mod loading; +use light_balls::*; +use player::*; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum AppState { @@ -24,8 +24,31 @@ fn main() { .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) .add_plugins(rendering::CustomPlugins) .init_resource::() + .init_resource::() + .init_resource::() .init_resource::() .add_state(AppState::Loading) + // raycasting + .init_resource::>() + .add_system_to_stage( + CoreStage::PostUpdate, + build_rays:: + .system() + .label(RaycastSystem::BuildRays), + ) + .add_system_to_stage( + CoreStage::PostUpdate, + update_raycast:: + .system() + .label(RaycastSystem::UpdateRaycast) + .after(RaycastSystem::BuildRays), + ) + .add_system_to_stage( + CoreStage::PreUpdate, + update_raycast_with_cursor + .system() + .before(RaycastSystem::BuildRays), + ) // loading .add_system_set( SystemSet::on_update(AppState::Loading).with_system(loading::loading.system()), @@ -34,8 +57,11 @@ fn main() { .add_system_set(SystemSet::on_enter(AppState::Game).with_system(setup.system())) .add_system_set( SystemSet::on_update(AppState::Game) + .with_system(update_mouse_coords.system()) .with_system(exit_on_esc_system.system()) .with_system(light_movement.system()) + .with_system(move_light_friends.system()) + .with_system(update_floating_orbs_interpolation.system()) .with_system(move_player.system()) .with_system(camera_follow_player.system()) .with_system(light_up_ball_when_close_to_player.system()), @@ -66,12 +92,14 @@ fn setup( let floor_material = materials.add(floor_material); for i in -10..10 { for j in -10..10 { - commands.spawn_bundle(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })), - material: floor_material.clone(), - transform: Transform::from_xyz(100.0 * i as f32, 0.0, 100.0 * j as f32), - ..Default::default() - }); + commands + .spawn_bundle(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })), + material: floor_material.clone(), + transform: Transform::from_xyz(100.0 * i as f32, 0.0, 100.0 * j as f32), + ..Default::default() + }) + .insert(RayCastMesh::::default()); } } @@ -96,7 +124,5 @@ fn setup( } // camera - commands - .spawn_bundle(PerspectiveCameraBundle::default()) - .insert(Camera); + spawn_camera(&mut commands); } diff --git a/src/player.rs b/src/player.rs index 8ac3b7e..c28ec63 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,5 +1,7 @@ use bevy::prelude::*; +use crate::camera::MouseCoords; + pub struct Player; pub struct PlayerLight { i: u8, @@ -20,18 +22,23 @@ pub fn spawn_player( transform: Transform::from_xyz(0.0, 1.0, 0.0), ..Default::default() }) - .insert(Player) - .with_children(|parent| { - // light - let mut light_material: StandardMaterial = - Color::rgb(0.737255, 0.560784, 0.560784).into(); - light_material.metallic = 0.5; - light_material.reflectance = 0.5; - light_material.emissive = Color::rgb(7.52, 5.72, 5.72); - let light_material = materials.add(light_material); + .insert(Player); + // light + let mut light_material: StandardMaterial = Color::rgb(0.737255, 0.560784, 0.560784).into(); + light_material.metallic = 0.5; + light_material.reflectance = 0.5; + light_material.emissive = Color::rgb(7.52, 5.72, 5.72); + let light_material = materials.add(light_material); + + commands + .spawn() + .insert(LightFriends) + .insert(Transform::default()) + .insert(GlobalTransform::default()) + .with_children(|children| { for i in 0..6 { - parent + children .spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Icosphere { radius: 0.2, @@ -54,14 +61,56 @@ pub fn spawn_player( }); } +pub struct LightFriends; +pub fn move_light_friends( + mut query: Query<(&mut Transform, &LightFriends)>, + player: Query<(&Transform, &Player), Without>, + coords: Res, + interpolation: Res, + time: Res