codecraft 0.2.0

A minimalist 3D game engine built on parts of Bevy (ECS, color) with wgpu and winit: OpenPBR materials, clustered lighting, a yakui-drawn UI, audio and gamepad haptics; its binary maps any folder, and the symbols of its Rust files, as a 3D wall of boxes
Documentation
//! Loading the game's own asset, so a bad export is caught here rather than
//! as an empty board on screen.
use codecraft::mesh::load_glb;

const GLB: &[u8] = include_bytes!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/tests/fixtures/chessrs.glb"
));

#[test]
fn every_named_node_comes_back_as_a_mesh() {
    let meshes = load_glb(GLB).expect("chessrs.glb should load");
    let mut names: Vec<&str> = meshes.iter().map(|m| m.name.as_str()).collect();
    names.sort_unstable();

    assert_eq!(
        names,
        [
            "chess_piece_bishop",
            "chess_piece_king",
            "chess_piece_knight",
            "chess_piece_pawn",
            "chess_piece_queen",
            "chess_piece_rook",
            "chess_tile",
            "chess_tile_alt",
        ],
    );
}

#[test]
fn meshes_carry_valid_geometry() {
    let meshes = load_glb(GLB).unwrap();

    for mesh in &meshes {
        assert!(!mesh.vertices.is_empty(), "{} has no vertices", mesh.name);
        assert!(!mesh.indices.is_empty(), "{} has no indices", mesh.name);
        assert_eq!(mesh.indices.len() % 3, 0, "{} is not triangles", mesh.name);

        let highest_index = mesh.indices.iter().copied().max().unwrap() as usize;
        assert!(
            highest_index < mesh.vertices.len(),
            "{} indexes past its vertices",
            mesh.name,
        );
    }
}

#[test]
fn tiles_keep_the_material_colors_from_the_blend() {
    let meshes = load_glb(GLB).unwrap();
    let tile = |name: &str| {
        meshes
            .iter()
            .find(|m| m.name == name)
            .unwrap_or_else(|| panic!("no {name}"))
            .base_color
            .unwrap_or_else(|| panic!("{name} has no material color"))
    };

    let light = tile("chess_tile").to_linear();
    let dark = tile("chess_tile_alt").to_linear();
    assert!(
        light.red > dark.red && light.green > dark.green,
        "chess_tile should be the lighter square ({light:?} vs {dark:?})",
    );
}