eco ›

cuboids

Cargo.toml

An experiment in fake 3D graphics.

// Spinning wireframe cubes

use nannou::prelude::*;

fn main() {
  nannou::app(model).run();
}

struct Model {
  cuboids: Vec<Cuboid>,
  wireframes: Vec<Vec<Cuboid>>,
}

fn create_wireframe(cuboid: &Cuboid) -> Vec<Cuboid> {
  let x = cuboid.x();
  let y = cuboid.y();
  let z = cuboid.z();
  let ww = cuboid.w();
  let xx = ww * 0.5;
  let hh = cuboid.h();
  let yy = hh * 0.5;
  let dd = cuboid.d();
  let zz = dd * 0.5;
  let w = 1.0; // wire width
  vec![
  //top
  Cuboid::from_x_y_z_w_h_d(x + -xx, y + yy, z + 0.0, w, w, dd),
  Cuboid::from_x_y_z_w_h_d(x + 0.0, y + yy, z + zz, ww, w, w),
  Cuboid::from_x_y_z_w_h_d(x + xx, y + yy, z + 0.0, w, w, dd),
  Cuboid::from_x_y_z_w_h_d(x + 0.0, y + yy, z + -zz, ww, w, w),
  //bottom
  Cuboid::from_x_y_z_w_h_d(x + -xx, y + -yy, z + 0.0, w, w, dd),
  Cuboid::from_x_y_z_w_h_d(x + 0.0, y + -yy, z + zz, ww, w, w),
  Cuboid::from_x_y_z_w_h_d(x + xx, y + -yy, z + 0.0, w, w, dd),
  Cuboid::from_x_y_z_w_h_d(x + 0.0, y + -yy, z + -zz, ww, w, w),
  //sides
  Cuboid::from_x_y_z_w_h_d(x + -xx, y + 0.0, z + -zz, w, hh, w),
  Cuboid::from_x_y_z_w_h_d(x + -xx, y + 0.0, z + zz, w, hh, w),
  Cuboid::from_x_y_z_w_h_d(x + xx, y + 0.0, z + zz, w, hh, w),
  Cuboid::from_x_y_z_w_h_d(x + xx, y + 0.0, z + -zz, w, hh, w),
  ]
}

fn model(app: &App) -> Model {
  app.new_window().size(512, 512).view(view).build().unwrap();

  // set up three cubes
  let cuboids = vec![
    Cuboid::from_x_y_z_w_h_d(0.0, 0.0, 0.0, 100.0, 120.0, 80.0),
    Cuboid::from_x_y_z_w_h_d(150.0, 0.0, 0.0, 100.0, 120.0, 50.0),
    Cuboid::from_x_y_z_w_h_d(-150.0, 0.0, 0.0, 100.0, 120.0, 30.0),
  ];

  let wireframes = cuboids.iter().map(|c| create_wireframe(c)).collect();
  Model {
    cuboids,
    wireframes,
  }
}

fn view(app: &App, model: &Model, frame: Frame) {
  frame.clear(CORNFLOWERBLUE);

  let draw = app.draw().radians(vec3(
    // global rotation
    (app.time * 0.1).sin() * 2.0,
    (app.time * 0.2).sin() * 2.0,
    (app.time * 0.3).sin() * 2.0,
  ));

  for (i, c) in model.cuboids.iter().enumerate() {
    let rot = vec3(
      // individual rotation
      (app.time + i as f32) * 1.11,
      (app.time + i as f32) * 1.22,
      (app.time + i as f32) * 1.33,
    );
    let scl = (c.z() + app.window_rect().h()) / app.window_rect().h();

    // draw the center
    let cpoints = c.triangles_iter().flat_map(geom::Tri::vertices);
    draw.radians(rot)
      .scale_axes(vec3(scl, scl, scl))
      .mesh()
      .points(cpoints)
      .color(rgba(1.0, 0.0, 0.0, 0.1));

    // draw the wireframe
    for w in &model.wireframes[i] {
      let wpoints = w.triangles_iter().flat_map(geom::Tri::vertices);
      draw.radians(rot)
        .scale_axes(vec3(scl, scl, scl))
        .mesh()
        .points(wpoints)
        .color(BLACK);
    }
  }

  draw.to_frame(app, &frame).unwrap();
}