background_example/
background-example.rs1use mittens_engine::{engine, utils};
2
3#[path = "example_util/mod.rs"]
4mod example_util;
5
6fn hash_u32(mut x: u32) -> u32 {
7 x ^= x >> 16;
9 x = x.wrapping_mul(0x7feb_352d);
10 x ^= x >> 15;
11 x = x.wrapping_mul(0x846c_a68b);
12 x ^= x >> 16;
13 x
14}
15
16fn rand01(seed: u32) -> f32 {
17 (hash_u32(seed) as f32) / (u32::MAX as f32)
18}
19
20fn main() {
21 mittens_engine::example_support::ensure_model_assets();
22 utils::logger::init();
23
24 let world = engine::ecs::World::default();
25 let mut universe = engine::Universe::new(world);
26
27 let clear = universe
29 .world
30 .add_component(engine::ecs::component::BackgroundColorComponent::new());
31 let clear_c = universe
32 .world
33 .add_component(engine::ecs::component::ColorComponent::rgba(
34 0.01, 0.01, 0.02, 1.0,
35 ));
36 let _ = universe.world.add_child(clear, clear_c);
37 universe.add(clear);
38
39 let input = universe
41 .world
42 .add_component(engine::ecs::component::InputComponent::new().with_speed(2.0));
43 let input_mode = universe.world.add_component(
44 engine::ecs::component::InputTransformModeComponent::forward_z().with_roll_axis_y(),
45 );
46 let _ = universe.attach(input, input_mode);
47
48 let rig_transform = universe.world.add_component(
50 engine::ecs::component::TransformComponent::new().with_position(0.0, 1.0, 6.0),
51 );
52 let _ = universe.attach(input, rig_transform);
53
54 let camera3d = universe
55 .world
56 .add_component(engine::ecs::component::Camera3DComponent::new());
57 let _ = universe.attach(rig_transform, camera3d);
58
59 let light = universe.world.add_component(
61 engine::ecs::component::PointLightComponent::new()
62 .with_distance(50.0)
63 .with_color(1.0, 1.0, 1.0),
64 );
65 let light_transform = universe.world.add_component(
66 engine::ecs::component::TransformComponent::new().with_position(0.0, 6.0, 2.0),
67 );
68 let _ = universe.attach(light_transform, light);
69
70 example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
72
73 universe.add(input);
74 universe.add(light_transform);
75
76 let cube_mesh = universe
77 .render_assets
78 .get_mesh(engine::graphics::BuiltinMeshType::Cube);
79
80 let bg_root = universe
83 .world
84 .add_component(engine::ecs::component::BackgroundComponent::new());
85 universe.add(bg_root);
86
87 let ground_tx = universe.world.add_component(
90 engine::ecs::component::TransformComponent::new()
91 .with_position(0.0, -40.0, 0.0)
92 .with_scale(200.0, 1.0, 200.0),
93 );
94 let ground_renderable =
95 universe
96 .world
97 .add_component(engine::ecs::component::RenderableComponent::new(
98 engine::graphics::primitives::Renderable::new(
99 cube_mesh,
100 engine::graphics::primitives::MaterialHandle::UNLIT_MESH,
101 ),
102 ));
103 let ground_color = universe
104 .world
105 .add_component(engine::ecs::component::ColorComponent::rgba(
106 0.015, 0.02, 0.03, 1.0,
107 ));
108
109 let _ = universe.attach(bg_root, ground_tx);
110 let _ = universe.attach(ground_tx, ground_renderable);
111 let _ = universe.attach(ground_renderable, ground_color);
112
113 let lat_steps: u32 = 24;
116 let lon_steps: u32 = 48;
117 let density: f32 = 0.14;
118 let radius = 25.0;
119
120 for lat in 0..lat_steps {
121 for lon in 0..lon_steps {
122 let cell = lon + lat * lon_steps;
123 if rand01(cell ^ 0x5a1d_c0de) > density {
124 continue;
125 }
126
127 let jx = rand01(cell ^ 0xA341_316C) - 0.5;
129 let jy = rand01(cell ^ 0xC801_3EA4) - 0.5;
130
131 let lat_t = (lat as f32 + 0.5 + 0.9 * jy) / (lat_steps as f32);
133 let lon_t = (lon as f32 + 0.5 + 0.9 * jx) / (lon_steps as f32);
134 let phi = (lat_t - 0.5) * std::f32::consts::PI; let theta = lon_t * std::f32::consts::TAU;
136
137 let x = phi.cos() * theta.cos();
138 let y = phi.sin();
139 let z = phi.cos() * theta.sin();
140
141 let px = x * radius;
142 let py = y * radius;
143 let pz = z * radius;
144
145 let scale = 0.12 + rand01(cell.wrapping_add(12345)) * 0.20;
146
147 let tx = universe.world.add_component(
148 engine::ecs::component::TransformComponent::new()
149 .with_position(px, py, pz)
150 .with_scale(scale, scale, scale),
151 );
152 let renderable =
153 universe
154 .world
155 .add_component(engine::ecs::component::RenderableComponent::new(
156 engine::graphics::primitives::Renderable::new(
157 cube_mesh,
158 engine::graphics::primitives::MaterialHandle::UNLIT_MESH,
159 ),
160 ));
161
162 let c = 0.75 + rand01(cell.wrapping_mul(3)) * 0.25;
163 let color = universe
164 .world
165 .add_component(engine::ecs::component::ColorComponent::rgba(c, c, c, 1.0));
166
167 let _ = universe.attach(bg_root, tx);
168 let _ = universe.attach(tx, renderable);
169 let _ = universe.attach(renderable, color);
170 }
171 }
172
173 let fg_root = universe.world.add_component(
176 engine::ecs::component::TransformComponent::new().with_position(0.0, 0.0, 0.0),
177 );
178
179 let n: i32 = 8;
180 let step: f32 = 0.8;
181 for z in 0..n {
182 for x in 0..n {
183 let px = (x - n / 2) as f32 * step;
184 let pz = -(z as f32) * step;
185
186 let tx = universe.world.add_component(
187 engine::ecs::component::TransformComponent::new()
188 .with_position(px, 0.5, pz)
189 .with_scale(0.25, 0.25, 0.25),
190 );
191 let renderable =
192 universe
193 .world
194 .add_component(engine::ecs::component::RenderableComponent::new(
195 engine::graphics::primitives::Renderable::new(
196 cube_mesh,
197 engine::graphics::primitives::MaterialHandle::TOON_MESH,
198 ),
199 ));
200
201 let fx = (x as f32) / ((n - 1) as f32);
202 let fz = (z as f32) / ((n - 1) as f32);
203 let color = universe
204 .world
205 .add_component(engine::ecs::component::ColorComponent::rgba(
206 0.2 + 0.8 * fx,
207 0.2 + 0.8 * (1.0 - fz),
208 0.4,
209 1.0,
210 ));
211
212 let _ = universe.attach(fg_root, tx);
213 let _ = universe.attach(tx, renderable);
214 let _ = universe.attach(renderable, color);
215 }
216 }
217
218 universe.add(fg_root);
219
220 universe.systems.process_commands(
221 &mut universe.world,
222 &mut universe.visuals,
223 &mut universe.render_assets,
224 &mut universe.command_queue,
225 );
226
227 universe.enable_repl();
228 engine::Windowing::run_app(universe).expect("Windowing failed");
229}