1use mittens_engine::{engine, utils};
2
3#[path = "example_util/mod.rs"]
4mod example_util;
5
6fn main() {
7 mittens_engine::example_support::ensure_model_assets();
8 utils::logger::init();
9
10 const LABEL_WRAP_AT: usize = 13;
11
12 let world = engine::ecs::World::default();
13 let mut universe = engine::Universe::new(world);
14
15 let clock = universe
17 .world
18 .add_component(engine::ecs::component::ClockComponent::new().with_bpm(60.0));
19 universe.add(clock);
20
21 let input = universe
24 .world
25 .add_component(engine::ecs::component::InputComponent::new().with_speed(1.5));
26 let camera3d = universe
27 .world
28 .add_component(engine::ecs::component::Camera3DComponent::new());
29 let rig_transform = universe.world.add_component(
30 engine::ecs::component::TransformComponent::new().with_position(0.0, 0.0, 11.0),
31 );
32 let input_mode = universe.world.add_component(
33 engine::ecs::component::InputTransformModeComponent::forward_z().with_roll_axis_y(),
34 );
35 let _ = universe.attach(input, input_mode);
36 let _ = universe.attach(input, rig_transform);
37 let _ = universe.attach(rig_transform, camera3d);
38
39 example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
41 universe.add(input);
42
43 let light_transform = universe.world.add_component(
45 engine::ecs::component::TransformComponent::new().with_position(0.0, 2.0, 2.0),
46 );
47 let light = universe.world.add_component(
48 engine::ecs::component::PointLightComponent::new()
49 .with_distance(50.0)
50 .with_color(1.0, 1.0, 1.0),
51 );
52 let _ = universe.attach(light_transform, light);
53 universe.add(light_transform);
54
55 fn spawn_labeled_mesh(
56 universe: &mut engine::Universe,
57 x: f32,
58 y: f32,
59 label: &str,
60 mesh: engine::graphics::primitives::CpuMeshHandle,
61 scale: [f32; 3],
62 color: [f32; 4],
63 ) {
64 use engine::ecs::component::{
65 ActionComponent, AnimationComponent, AnimationState, ColorComponent, EmissiveComponent,
66 KeyframeComponent, RenderableComponent, TextComponent, TransformComponent,
67 };
68 use engine::graphics::primitives::{MaterialHandle, Renderable};
69
70 let root = universe.world.add_component(
72 TransformComponent::new()
73 .with_position(x, y, 0.0)
74 .with_scale(scale[0], scale[1], scale[2]),
75 );
76
77 let anim = universe
80 .world
81 .add_component(AnimationComponent::new().with_state(AnimationState::Looping));
82 let _ = universe.attach(root, anim);
83
84 let steps: usize = 64;
85 for i in 0..steps {
86 let beat = (i as f64) * (2.0 / (steps as f64));
87 let kf = universe.world.add_component(KeyframeComponent::new(beat));
88 let _ = universe.attach(anim, kf);
89
90 let angle = (std::f64::consts::TAU * (beat / 2.0)) as f32;
92 let rotation = utils::math::quat_from_axis_angle([0.0, 1.0, 0.0], angle);
93
94 let action_cid = universe.world.add_component(ActionComponent::new(
95 engine::ecs::IntentValue::UpdateTransform {
96 component_ids: vec![root],
97 translation: [x, y, 0.0],
98 rotation_quat_xyzw: rotation,
99 scale,
100 },
101 ));
102 let _ = universe.attach(kf, action_cid);
103 }
104
105 let renderable = universe
106 .world
107 .add_component(RenderableComponent::new(Renderable::new(
108 mesh,
109 MaterialHandle::TOON_MESH,
110 )));
111 let color_c = universe
112 .world
113 .add_component(ColorComponent::rgba(color[0], color[1], color[2], color[3]));
114 let emissive = universe.world.add_component(EmissiveComponent::on());
115
116 let _ = universe.attach(root, renderable);
117 let _ = universe.attach(renderable, color_c);
118 let _ = universe.attach(renderable, emissive);
119
120 universe.add(root);
121
122 let text_root = universe.world.add_component(
124 TransformComponent::new()
125 .with_position(x, y + 0.75, 0.05)
126 .with_scale(0.09, 0.09, 1.0),
127 );
128 let text = universe
129 .world
130 .add_component(TextComponent::with_word_wrap_tokens(
131 label,
132 LABEL_WRAP_AT,
133 ["::", "(", ")", ",", "."],
134 ));
135 let text_color = universe
136 .world
137 .add_component(ColorComponent::rgba(1.0, 1.0, 1.0, 1.0));
138 let text_emissive = universe.world.add_component(EmissiveComponent::on());
139 let _ = universe.attach(text_root, text);
140 let _ = universe.attach(text, text_color);
141 let _ = universe.attach(text, text_emissive);
142 universe.add(text_root);
143 }
144
145 let tri = universe
147 .render_assets
148 .get_mesh(engine::graphics::BuiltinMeshType::Triangle2D);
149 let quad = universe
150 .render_assets
151 .get_mesh(engine::graphics::BuiltinMeshType::Quad2D);
152 let cube = universe
153 .render_assets
154 .get_mesh(engine::graphics::BuiltinMeshType::Cube);
155 let tetra = universe
156 .render_assets
157 .get_mesh(engine::graphics::BuiltinMeshType::Tetrahedron);
158 let sphere = universe
159 .render_assets
160 .get_mesh(engine::graphics::BuiltinMeshType::Sphere);
161 let cone = universe
162 .render_assets
163 .get_mesh(engine::graphics::BuiltinMeshType::Cone);
164 let circle = universe
165 .render_assets
166 .get_mesh(engine::graphics::BuiltinMeshType::Circle2D);
167
168 let y = 0.0;
170 let dx = 1.8;
171 let x0 = -dx * 3.0;
172
173 spawn_labeled_mesh(
174 &mut universe,
175 x0 + dx * 0.0,
176 y,
177 "Triangle2D\nMeshFactory::triangle_2d()",
178 tri,
179 [1.0, 1.0, 1.0],
180 [1.0, 1.0, 1.0, 1.0],
181 );
182 spawn_labeled_mesh(
183 &mut universe,
184 x0 + dx * 1.0,
185 y,
186 "Quad2D\nMeshFactory::quad_2d()",
187 quad,
188 [1.0, 1.0, 1.0],
189 [1.0, 1.0, 1.0, 1.0],
190 );
191 spawn_labeled_mesh(
192 &mut universe,
193 x0 + dx * 2.0,
194 y,
195 "Cube\nMeshFactory::cube()",
196 cube,
197 [0.9, 0.9, 0.9],
198 [1.0, 1.0, 1.0, 1.0],
199 );
200 spawn_labeled_mesh(
201 &mut universe,
202 x0 + dx * 3.0,
203 y,
204 "Tetrahedron\nMeshFactory::tetrahedron()",
205 tetra,
206 [1.0, 1.0, 1.0],
207 [1.0, 1.0, 1.0, 1.0],
208 );
209 spawn_labeled_mesh(
210 &mut universe,
211 x0 + dx * 4.0,
212 y,
213 "Sphere\nMeshFactory::sphere()",
214 sphere,
215 [1.0, 1.0, 1.0],
216 [1.0, 1.0, 1.0, 1.0],
217 );
218 spawn_labeled_mesh(
219 &mut universe,
220 x0 + dx * 5.0,
221 y,
222 "Cone\nMeshFactory::cone(32)",
223 cone,
224 [1.0, 1.0, 1.0],
225 [1.0, 1.0, 1.0, 1.0],
226 );
227 spawn_labeled_mesh(
228 &mut universe,
229 x0 + dx * 6.0,
230 y,
231 "Circle2D\nMeshFactory::circle_2d(0.45, 0.5, 64)",
232 circle,
233 [1.0, 1.0, 1.0],
234 [1.0, 1.0, 1.0, 1.0],
235 );
236
237 universe.systems.process_commands(
239 &mut universe.world,
240 &mut universe.visuals,
241 &mut universe.render_assets,
242 &mut universe.command_queue,
243 );
244
245 engine::Windowing::run_app(universe).expect("Windowing failed");
246}