baryon 0.3.0

Fast prototyping 3D engine
Documentation
use std::time;

fn create_prototype(builder: baryon::MeshBuilder) -> baryon::Prototype {
    fn vertex(x: i8, y: i8, z: i8) -> baryon::Position {
        baryon::Position([x as f32, y as f32, z as f32])
    }

    //TODO: can squeeze this by a factor of 3
    let vertex_data = [
        // top (0, 0, 1)
        vertex(-1, -1, 1),
        vertex(1, -1, 1),
        vertex(1, 1, 1),
        vertex(-1, 1, 1),
        // bottom (0, 0, -1)
        vertex(-1, 1, -1),
        vertex(1, 1, -1),
        vertex(1, -1, -1),
        vertex(-1, -1, -1),
        // right (1, 0, 0)
        vertex(1, -1, -1),
        vertex(1, 1, -1),
        vertex(1, 1, 1),
        vertex(1, -1, 1),
        // left (-1, 0, 0)
        vertex(-1, -1, 1),
        vertex(-1, 1, 1),
        vertex(-1, 1, -1),
        vertex(-1, -1, -1),
        // front (0, 1, 0)
        vertex(1, 1, -1),
        vertex(-1, 1, -1),
        vertex(-1, 1, 1),
        vertex(1, 1, 1),
        // back (0, -1, 0)
        vertex(1, -1, 1),
        vertex(-1, -1, 1),
        vertex(-1, -1, -1),
        vertex(1, -1, -1),
    ];

    let index_data = [
        0u16, 1, 2, 2, 3, 0, // top
        4, 5, 6, 6, 7, 4, // bottom
        8, 9, 10, 10, 11, 8, // right
        12, 13, 14, 14, 15, 12, // left
        16, 17, 18, 18, 19, 16, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    builder.vertex(&vertex_data).index(&index_data).build()
}

struct Cube {
    node: baryon::NodeRef,
    level: u8,
}

const SCALE_ROOT: f32 = 2.0;
const SCALE_LEVEL: f32 = 0.4;

struct Level {
    color: baryon::Color,
    speed: f32,
}

fn fill_scene(
    levels: &[Level],
    scene: &mut baryon::Scene,
    prototype: &baryon::Prototype,
) -> Vec<Cube> {
    let root_node = scene.add_node().scale(SCALE_ROOT).build();
    scene
        .add_entity(prototype)
        .parent(root_node)
        .component(levels[0].color)
        .build();
    let mut list = vec![Cube {
        node: root_node,
        level: 0,
    }];

    struct Stack {
        parent: baryon::NodeRef,
        level: u8,
    }
    let mut stack = vec![Stack {
        parent: root_node,
        level: 1,
    }];

    let children = [
        mint::Vector3 {
            x: 0.0,
            y: 0.0,
            z: 1.0,
        },
        mint::Vector3 {
            x: 1.0,
            y: 0.0,
            z: 0.0,
        },
        mint::Vector3 {
            x: -1.0,
            y: 0.0,
            z: 0.0,
        },
        mint::Vector3 {
            x: 0.0,
            y: 1.0,
            z: 0.0,
        },
        mint::Vector3 {
            x: 0.0,
            y: -1.0,
            z: 0.0,
        },
    ];

    while let Some(next) = stack.pop() {
        let level = match levels.get(next.level as usize) {
            Some(level) => level,
            None => continue,
        };
        for &child in children.iter() {
            let node = scene
                .add_node()
                .position(mint::Vector3 {
                    x: 0.0,
                    y: 0.0,
                    z: 1.0 + SCALE_LEVEL,
                })
                .scale(SCALE_LEVEL)
                .parent(next.parent)
                .build();
            scene[node].post_rotate(child, 90.0);

            scene
                .add_entity(prototype)
                .parent(node)
                .component(level.color)
                .build();
            list.push(Cube {
                node,
                level: next.level,
            });

            stack.push(Stack {
                parent: node,
                level: next.level + 1,
            });
        }
    }

    list
}

const LEVELS: &[Level] = &[
    Level {
        color: baryon::Color(0xFFFFFF80),
        speed: 20.0,
    },
    Level {
        color: baryon::Color(0xFF8080FF),
        speed: -30.0,
    },
    Level {
        color: baryon::Color(0xFF80FF80),
        speed: 40.0,
    },
    Level {
        color: baryon::Color(0xFFFF8080),
        speed: -60.0,
    },
    Level {
        color: baryon::Color(0xFF80FFFF),
        speed: 80.0,
    },
    Level {
        color: baryon::Color(0xFFFF80FF),
        speed: -100.0,
    },
];

fn main() {
    use baryon::window::{Event, Window};

    env_logger::init();
    let window = Window::new().title("Cubeception").build();
    let mut context = pollster::block_on(baryon::Context::init().build(&window));
    let mut scene = baryon::Scene::new();

    let camera = baryon::Camera {
        projection: baryon::Projection::Perspective { fov_y: 45.0 },
        depth: 1.0..10.0,
        node: scene
            .add_node()
            .position([1.8f32, -8.0, 3.0].into())
            .look_at([0f32; 3].into(), [0f32, 0.0, 1.0].into())
            .build(),
        background: baryon::Color(0xFF203040),
    };

    let prototype = create_prototype(context.add_mesh());
    let cubes = fill_scene(&LEVELS[..5], &mut scene, &prototype);
    println!("Initialized {} cubes", cubes.len());

    let mut pass = baryon::pass::Solid::new(
        &baryon::pass::SolidConfig {
            cull_back_faces: true,
        },
        &context,
    );

    let mut moment = time::Instant::now();

    window.run(move |event| match event {
        Event::Resize { width, height } => {
            context.resize(width, height);
        }
        Event::Draw => {
            let delta = moment.elapsed().as_secs_f32();
            moment = time::Instant::now();
            for cube in cubes.iter() {
                let level = &LEVELS[cube.level as usize];
                scene[cube.node].pre_rotate(
                    mint::Vector3 {
                        x: 0.0,
                        y: 0.0,
                        z: 1.0,
                    },
                    delta * level.speed,
                );
            }

            context.present(&mut pass, &scene, &camera);
        }
        _ => {}
    })
}