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