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();
}