1use ponko::*;
3
4struct Orbiting;
6
7fn fly(ctx: &mut Ctx) {
8 let t = ctx.time() as f32;
9 ctx.world.query::<(&mut Transform3D, &Orbiting)>().for_each(|(at, _)| {
10 at.position = vec3(t.cos() * 3.0, 1.0 + (t * 2.0).sin() * 0.5, t.sin() * 3.0);
11 });
12}
13
14fn setup(ctx: &mut Ctx) {
15 ctx.camera3d.position = vec3(0.0, 4.0, 9.0);
16 ctx.camera3d.look_at(vec3(0.0, 0.5, 0.0));
17 let floor_material = ctx.create_material(MaterialDesc::color(Color::hex(0x6B7B58)));
18 let floor_data = MeshData::plane(12.0);
19 let floor = ctx.create_mesh(&floor_data, floor_material);
20 ctx.world.spawn((Transform3D::default(), Model::new(floor)));
21
22 let mut tracer = Trail3D::new(0.25, 0.12);
26 tracer.color = ParticleGradient::new(vec![
27 (0.0, Color::rgb(1.0, 0.8, 0.3)),
28 (1.0, Color::rgba(1.0, 0.3, 0.0, 0.0)),
29 ]);
30 tracer.blend = ParticleBlend3D::Additive;
31 let white = ctx.default_material();
32 let ball = ctx.create_mesh(&MeshData::sphere(0.15, 16), white);
33 ctx.world
34 .spawn((Transform3D::default(), Model::new(ball), tracer, Orbiting));
35 let beam = Line3D {
41 blend: ParticleBlend3D::Additive,
42 ..Line3D::new(vec![Vec3::ZERO, vec3(0.0, 0.0, -5.0)], 0.03, Color::RED)
43 };
44 ctx.world.spawn((Transform3D::at(vec3(-4.0, 1.5, 3.0)), beam));
45 let up = Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2);
51 let projector = Mat4::from_scale_rotation_translation(vec3(1.0, 1.0, 0.4), up, vec3(1.0, 0.0, -1.0));
52 let mark = floor_data.decal(projector, 0.003);
53 if !mark.indices.is_empty() {
54 let scorch = ctx.create_material(MaterialDesc {
55 blend: Blend::Transparent,
56 ..MaterialDesc::color(Color::rgba(0.05, 0.04, 0.03, 0.8))
57 });
58 let mark = ctx.create_mesh(&mark, scorch);
59 ctx.world.spawn((Transform3D::default(), Model::new(mark)));
61 }
62 }
65
66fn main() {
67 Game::new("Ribbons", 960, 640).system(fly).run(setup);
68}