use crate::ui::{UIMessage, UiState}; use bevy::input::mouse::{MouseButton, MouseMotion}; use bevy::prelude::*; use crossbeam_channel::{Receiver, Sender}; #[derive(Component)] pub struct DynamicCube; #[derive(Component)] pub struct OrbitCamera { pub distance: f32, pub yaw: f32, pub pitch: f32, pub sensitivity: f32, } impl Default for OrbitCamera { fn default() -> Self { Self { distance: 3.0, yaw: 0.0, pitch: 0.0, sensitivity: 0.01, } } } #[derive(Resource, Deref)] struct UIMessageSender(Sender); #[derive(Resource, Deref)] struct UIMessageReceiver(Receiver); #[derive(Resource)] struct CubeTranslationSpeed(f32); impl Default for CubeTranslationSpeed { fn default() -> Self { Self(UiState::DEFAULT_CUBE_TRANSLATION_SPEED) } } #[derive(Resource)] struct CubeRotationSpeed(f32); impl Default for CubeRotationSpeed { fn default() -> Self { Self(UiState::DEFAULT_CUBE_ROTATION_SPEED) } } pub struct BevyScenePlugin { pub app_sender: Sender, pub ui_receiver: Receiver, } impl Plugin for BevyScenePlugin { fn build(&self, app: &mut App) { app.insert_resource(ClearColor(bevy::color::Color::srgba(0.0, 0.0, 0.0, 0.0))); app.insert_resource(UIMessageSender(self.app_sender.clone())); app.insert_resource(UIMessageReceiver(self.ui_receiver.clone())); app.insert_resource(CubeTranslationSpeed::default()); app.insert_resource(CubeRotationSpeed::default()); app.add_systems(Startup, setup); app.add_systems(Update, (sync_with_ui, animate, orbit_camera_system)); } } fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { commands.spawn(( Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), MeshMaterial3d(materials.add(StandardMaterial { base_color: Color::Srgba(bevy::color::Srgba::from_f32_array( UiState::DEFAULT_CUBE_COLOR, )), metallic: 0.0, perceptual_roughness: 0.5, ..default() })), Transform::from_xyz(0.0, 0.0, 0.0), DynamicCube, )); commands.spawn(( DirectionalLight { color: bevy::color::Color::WHITE, illuminance: 10000.0, shadows_enabled: false, ..default() }, Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y), )); commands.insert_resource(AmbientLight { color: bevy::color::Color::WHITE, brightness: 100.0, affects_lightmapped_meshes: true, }); commands.spawn(( Camera3d::default(), Transform::from_xyz(0.0, 0.0, 3.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), Name::new("MainCamera"), OrbitCamera::default(), )); } fn sync_with_ui( sender: Res, receiver: Res, cube_query: Query<&MeshMaterial3d, With>, mut materials: ResMut>, mut translation_speed: ResMut, mut rotation_speed: ResMut, time: Res