use bevy::{ color::palettes::css as csscolors, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, window::PrimaryWindow, }; use bevy_spatial::{AutomaticUpdate, SpatialAccess, kdtree::KDTree3}; use std::ops::Deref; #[derive(Component)] struct NearestNeighbourComponent; #[derive(Component)] struct Cursor; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(AutomaticUpdate::::new()) .add_plugins(LogDiagnosticsPlugin::default()) .add_plugins(FrameTimeDiagnosticsPlugin::default()) .insert_resource(Mouse3D { pos: Vec3::ZERO }) .add_systems(Startup, setup) .add_systems( Update, (update_mouse_pos, (mouse, color, reset_color.before(color))).chain(), ) .run(); } #[derive(Resource, Clone)] struct MaterialHandles { orange_red: Handle, black: Handle, blue: Handle, } type NNTree = KDTree3; fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut ambient_light: ResMut, ) { let handles = MaterialHandles { orange_red: materials.add(Color::from(csscolors::ORANGE_RED)), black: materials.add(Color::from(csscolors::BLACK)), blue: materials.add(Color::from(csscolors::BLUE)), }; commands.insert_resource(handles.clone()); ambient_light.color = Color::WHITE; ambient_light.brightness = 500.; commands.spawn(( Camera3d::default(), Transform::from_xyz(0.0, 100.0, 900.0).looking_at(Vec3::ZERO, Vec3::Y), )); commands .spawn(( Mesh3d(meshes.add(Cuboid::new(10., 10., 10.))), MeshMaterial3d(handles.blue.clone()), Transform::from_xyz(0.0, 0.5, 0.0), )) .insert(Cursor); let mesh = meshes.add(Cuboid::new(4., 4., 4.)); for x in -25..25 { for y in -25..25 { for z in -9..9 { commands.spawn(( Mesh3d(mesh.clone()), MeshMaterial3d(handles.orange_red.clone()), Transform::from_xyz((x * 15) as f32, (y * 15) as f32, (z * 15) as f32), NearestNeighbourComponent, )); } } } } #[derive(Copy, Clone, Resource)] struct Mouse3D { pos: Vec3, } fn update_mouse_pos( window: Single<&Window, With>, camera: Single<(&Camera, &GlobalTransform)>, mut mouse: ResMut, ) { let (cam, cam_t) = camera.deref(); if let Some(w_pos) = window.cursor_position() { if let Ok(pos) = cam.viewport_to_world(cam_t, w_pos) { mouse.pos = pos.get_point(900.); } } } fn mouse(mouse: Res, mut transform: Single<&mut Transform, With>) { transform.translation = mouse.pos; } fn color( mouse: Res, treeaccess: Res, mut query: Query<&mut MeshMaterial3d, With>, colors: Res, ) { for (_, entity) in treeaccess.within_distance(mouse.pos, 100.0) { if let Ok(mut handle) = query.get_mut(entity.expect("No entity")) { *handle = colors.black.clone().into(); } } } fn reset_color( colors: Res, mut query: Query<&mut MeshMaterial3d, With>, ) { for mut handle in &mut query { *handle = colors.orange_red.clone().into(); } }