Path: blob/main/examples/large_scenes/bevy_city/src/main.rs
9730 views
//! A procedurally generated city12use argh::FromArgs;3use assets::{load_assets, CityAssets};4use bevy::{5anti_alias::taa::TemporalAntiAliasing,6camera::{Exposure, Hdr},7camera_controller::free_camera::{FreeCamera, FreeCameraPlugin},8color::palettes::css::WHITE,9feathers::{dark_theme::create_dark_theme, theme::UiTheme, FeathersPlugins},10light::{atmosphere::ScatteringMedium, Atmosphere, AtmosphereEnvironmentMapLight},11pbr::{12wireframe::{WireframeConfig, WireframePlugin},13AtmosphereSettings, ContactShadows,14},15post_process::bloom::Bloom,16prelude::*,17window::{PresentMode, WindowResolution},18winit::WinitSettings,19};2021use crate::settings::Settings;22use crate::{generate_city::spawn_city, settings::setup_settings_ui};2324mod assets;25mod generate_city;26mod settings;2728#[derive(FromArgs, Resource, Clone)]29/// Config30pub struct Args {31/// seed32#[argh(option, default = "42")]33seed: u64,3435/// size36#[argh(option, default = "30")]37size: u32,38}3940fn main() {41let args: Args = argh::from_env();4243App::new()44.add_plugins((45DefaultPlugins.set(WindowPlugin {46primary_window: Some(Window {47title: "bevy_city".into(),48resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),49present_mode: PresentMode::AutoNoVsync,50..default()51}),52..default()53}),54FreeCameraPlugin,55FeathersPlugins,56WireframePlugin::default(),57))58.insert_resource(args.clone())59.insert_resource(ClearColor(Color::BLACK))60.insert_resource(WinitSettings::continuous())61.init_resource::<Settings>()62.insert_resource(UiTheme(create_dark_theme()))63.insert_resource(WireframeConfig {64global: false,65default_color: WHITE.into(),66..default()67})68.add_systems(69Startup,70(71setup,72setup_settings_ui,73load_assets,74setup_city.after(load_assets),75),76)77.add_systems(Update, simulate_cars)78.run();79}8081fn setup(mut commands: Commands, mut scattering_mediums: ResMut<Assets<ScatteringMedium>>) {82commands.spawn((83Camera3d::default(),84Hdr,85Transform::from_xyz(15.0, 10.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),86FreeCamera::default(),87Atmosphere::earthlike(scattering_mediums.add(ScatteringMedium::default())),88AtmosphereSettings::default(),89// The directional light illuminance used in this scene is90// quite bright, so raising the exposure compensation helps91// bring the scene to a nicer brightness range.92Exposure { ev100: 13.0 },93// Bloom gives the sun a much more natural look.94Bloom::NATURAL,95// Enables the atmosphere to drive reflections and ambient lighting (IBL) for this view96AtmosphereEnvironmentMapLight::default(),97Msaa::Off,98TemporalAntiAliasing::default(),99ContactShadows::default(),100));101102commands.spawn((103DirectionalLight {104shadow_maps_enabled: Settings::default().shadow_maps_enabled,105contact_shadows_enabled: Settings::default().contact_shadows_enabled,106illuminance: light_consts::lux::RAW_SUNLIGHT,107..default()108},109Transform::from_xyz(1.0, 0.15, 1.0).looking_at(Vec3::ZERO, Vec3::Y),110));111}112113fn setup_city(mut commands: Commands, assets: Res<CityAssets>, args: Res<Args>) {114spawn_city(&mut commands, &assets, args.seed, args.size);115}116117#[derive(Component)]118struct Road {119start: Vec3,120end: Vec3,121}122123#[derive(Component)]124struct Car {125offset: Vec3,126distance_traveled: f32,127dir: f32,128}129130fn simulate_cars(131settings: Res<Settings>,132roads: Query<(&Road, &Transform, &Children), Without<Car>>,133mut cars: Query<(&mut Car, &mut Transform), Without<Road>>,134time: Res<Time>,135) {136if !settings.simulate_cars {137return;138}139let speed = 1.5;140141for (road, _, children) in &roads {142for child in children {143let Ok((mut car, mut car_transform)) = cars.get_mut(*child) else {144continue;145};146147car.distance_traveled += speed * time.delta_secs();148let road_len = (road.end - road.start).length();149if car.distance_traveled > road_len {150car.distance_traveled = 0.0;151}152let direction = (road.end - road.start).normalize() * car.dir;153154let progress = car.distance_traveled / road_len;155car_transform.translation = (road.start + car.offset) + direction * road_len * progress;156}157}158}159160161