use ponko::*;
struct Orbiting;
fn fly(ctx: &mut Ctx) {
let t = ctx.time() as f32;
ctx.world.query::<(&mut Transform3D, &Orbiting)>().for_each(|(at, _)| {
at.position = vec3(t.cos() * 3.0, 1.0 + (t * 2.0).sin() * 0.5, t.sin() * 3.0);
});
}
fn setup(ctx: &mut Ctx) {
ctx.camera3d.position = vec3(0.0, 4.0, 9.0);
ctx.camera3d.look_at(vec3(0.0, 0.5, 0.0));
let floor_material = ctx.create_material(MaterialDesc::color(Color::hex(0x6B7B58)));
let floor_data = MeshData::plane(12.0);
let floor = ctx.create_mesh(&floor_data, floor_material);
ctx.world.spawn((Transform3D::default(), Model::new(floor)));
let mut tracer = Trail3D::new(0.25, 0.12);
tracer.color = ParticleGradient::new(vec![
(0.0, Color::rgb(1.0, 0.8, 0.3)),
(1.0, Color::rgba(1.0, 0.3, 0.0, 0.0)),
]);
tracer.blend = ParticleBlend3D::Additive;
let white = ctx.default_material();
let ball = ctx.create_mesh(&MeshData::sphere(0.15, 16), white);
ctx.world
.spawn((Transform3D::default(), Model::new(ball), tracer, Orbiting));
let beam = Line3D {
blend: ParticleBlend3D::Additive,
..Line3D::new(vec![Vec3::ZERO, vec3(0.0, 0.0, -5.0)], 0.03, Color::RED)
};
ctx.world.spawn((Transform3D::at(vec3(-4.0, 1.5, 3.0)), beam));
let up = Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2);
let projector = Mat4::from_scale_rotation_translation(vec3(1.0, 1.0, 0.4), up, vec3(1.0, 0.0, -1.0));
let mark = floor_data.decal(projector, 0.003);
if !mark.indices.is_empty() {
let scorch = ctx.create_material(MaterialDesc {
blend: Blend::Transparent,
..MaterialDesc::color(Color::rgba(0.05, 0.04, 0.03, 0.8))
});
let mark = ctx.create_mesh(&mark, scorch);
ctx.world.spawn((Transform3D::default(), Model::new(mark)));
}
}
fn main() {
Game::new("Ribbons", 960, 640).system(fly).run(setup);
}