use bevy::{ prelude::*, transform::TransformSystem, window::{CursorGrabMode, PrimaryWindow}, }; use bevy_color::palettes; use big_space::{ camera::{CameraController, CameraInput}, commands::BigSpaceCommands, reference_frame::{local_origin::ReferenceFrames, ReferenceFrame}, world_query::GridTransformReadOnly, FloatingOrigin, }; fn main() { App::new() .add_plugins(( DefaultPlugins.build().disable::(), big_space::BigSpacePlugin::::default(), big_space::debug::FloatingOriginDebugPlugin::::default(), big_space::camera::CameraControllerPlugin::::default(), )) .insert_resource(ClearColor(Color::BLACK)) .add_systems(Startup, (setup, ui_setup)) .add_systems(PreUpdate, (cursor_grab_system, ui_text_system)) .add_systems( PostUpdate, highlight_nearest_sphere.after(TransformSystem::TransformPropagate), ) .run(); } fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { commands.spawn_big_space(ReferenceFrame::::default(), |root| { root.spawn_spatial(( Camera3d::default(), Projection::Perspective(PerspectiveProjection { near: 1e-18, ..default() }), Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), FloatingOrigin, // Important: marks the floating origin entity for rendering. CameraController::default() // Built-in camera controller .with_speed_bounds([10e-18, 10e35]) .with_smoothness(0.9, 0.8) .with_speed(1.0), )); let mesh_handle = meshes.add(Sphere::new(0.5).mesh().ico(32).unwrap()); let matl_handle = materials.add(StandardMaterial { base_color: Color::Srgba(palettes::basic::BLUE), perceptual_roughness: 0.8, reflectance: 1.0, ..default() }); let mut translation = Vec3::ZERO; for i in -16..=27 { let j = 10_f32.powf(i as f32); let k = 10_f32.powf((i - 1) as f32); translation.x += j / 2.0 + k; translation.y = j / 2.0; root.spawn_spatial(( Mesh3d(mesh_handle.clone()), MeshMaterial3d(matl_handle.clone()), Transform::from_scale(Vec3::splat(j)).with_translation(translation), )); } // light root.spawn_spatial(DirectionalLight { illuminance: 10_000.0, ..default() }); }); } #[derive(Component, Reflect)] pub struct BigSpaceDebugText; #[derive(Component, Reflect)] pub struct FunFactText; fn ui_setup(mut commands: Commands) { commands.spawn(( Text::default(), TextFont { font_size: 18.0, ..default() }, TextColor(Color::WHITE), TextLayout::new_with_justify(JustifyText::Left), Node { position_type: PositionType::Absolute, top: Val::Px(10.0), left: Val::Px(10.0), ..default() }, BigSpaceDebugText, )); commands.spawn(( Text::default(), TextFont { font_size: 52.0, ..default() }, TextColor(Color::WHITE), TextLayout::new_with_justify(JustifyText::Center), Node { position_type: PositionType::Absolute, bottom: Val::Px(10.0), right: Val::Px(10.0), left: Val::Px(10.0), ..default() }, FunFactText, )); } fn highlight_nearest_sphere( cameras: Query<&CameraController>, objects: Query<&GlobalTransform>, mut gizmos: Gizmos, ) { let Some((entity, _)) = cameras.single().nearest_object() else { return; }; let Ok(transform) = objects.get(entity) else { return; }; // Ignore rotation due to panicking in gizmos, as of bevy 0.13 let (scale, _, translation) = transform.to_scale_rotation_translation(); gizmos .sphere( translation, scale.x * 0.505, Color::Srgba(palettes::basic::RED), ) .resolution(128); } #[allow(clippy::type_complexity)] fn ui_text_system( mut debug_text: Query< (&mut Text, &GlobalTransform), (With, Without), >, mut fun_text: Query<&mut Text, (With, Without)>, ref_frames: ReferenceFrames, time: Res