nd_vector 0.1.0

[WIP] Lengthen! Shrink! Iterate! Scale! Twist and turn to your imagination along any dimension on a vector!
Documentation
use bevy::{prelude::*, render::{mesh::{Indices, PrimitiveTopology}, render_asset::RenderAssetUsages}};

use crate::air::Air;

use super::{voxel_mesher::VoxelMesher, Transparent};

pub const SIDE_INDICES: [u32; 6] = [0, 1, 2, 3, 2, 1];

pub const SIDE_UV: [Vec2; 4] = [
    Vec2 { x: 0.0, y: 1.0 },
    Vec2 { x: 1.0, y: 1.0 },
    Vec2 { x: 0.0, y: 0.0 },
    Vec2 { x: 1.0, y: 0.0 },
];

pub const CUBE_NORMALS: [Vec3; 6] = [
    Vec3 { x: -1.0, y: 0.0, z: 0.0 },
    Vec3 { x: 1.0, y: 0.0, z: 0.0 },
    Vec3 { x: 0.0, y: -1.0, z: 0.0 },
    Vec3 { x: 0.0, y: 1.0, z: 0.0 },
    Vec3 { x: 0.0, y: 0.0, z: -1.0 },
    Vec3 { x: 0.0, y: 0.0, z: 1.0 },
];

pub const CUBE_VERTECIES: [[Vec3; 4]; 6] = [
    [
        Vec3 { x: 0.0, y: 0.0, z: 0.0 }, Vec3 { x: 0.0, y: 0.0, z: 1.0 },
        Vec3 { x: 0.0, y: 1.0, z: 0.0 }, Vec3 { x: 0.0, y: 1.0, z: 1.0 },
    ],
    [
        Vec3 { x: 1.0, y: 0.0, z: 0.0 }, Vec3 { x: 1.0, y: 1.0, z: 0.0 },
        Vec3 { x: 1.0, y: 0.0, z: 1.0 }, Vec3 { x: 1.0, y: 1.0, z: 1.0 },
    ],
    [
        Vec3 { x: 0.0, y: 0.0, z: 0.0 }, Vec3 { x: 1.0, y: 0.0, z: 0.0 },
        Vec3 { x: 0.0, y: 0.0, z: 1.0 }, Vec3 { x: 1.0, y: 0.0, z: 1.0 },
    ],
    [
        Vec3 { x: 0.0, y: 1.0, z: 0.0 }, Vec3 { x: 0.0, y: 1.0, z: 1.0 },
        Vec3 { x: 1.0, y: 1.0, z: 0.0 }, Vec3 { x: 1.0, y: 1.0, z: 1.0 },
    ],
    [
        Vec3 { x: 0.0, y: 0.0, z: 0.0 }, Vec3 { x: 0.0, y: 1.0, z: 0.0 },
        Vec3 { x: 1.0, y: 0.0, z: 0.0 }, Vec3 { x: 1.0, y: 1.0, z: 0.0 },
    ],
    [
        Vec3 { x: 0.0, y: 0.0, z: 1.0 }, Vec3 { x: 1.0, y: 0.0, z: 1.0 },
        Vec3 { x: 0.0, y: 1.0, z: 1.0 }, Vec3 { x: 1.0, y: 1.0, z: 1.0 },
    ],
];

pub fn generate_side_mesh(side_n: usize) -> Mesh {
    Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::default())
    .with_inserted_indices(Indices::U32(SIDE_INDICES.to_vec()))
    .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, CUBE_VERTECIES[side_n].to_vec())
    .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vec![CUBE_NORMALS[side_n]; 4])
}

pub struct CubeMesher {
    pub is_air: bool
}

impl Default for CubeMesher {
    fn default() -> Self {
        Self { is_air: true }
    }
}

impl Air for CubeMesher {
    fn is_air(&self) -> bool {
        self.is_air
    }
}

impl Transparent for CubeMesher {
    fn is_transparent(&self) -> bool {
        self.is_air
    }
}

impl VoxelMesher for CubeMesher {
    fn generate(&self, visible_sides: [bool; 6]) -> Mesh {
        let mut result = Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::default())
        .with_inserted_indices(Indices::U32(vec![]))
        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vec![Vec3::ZERO; 0])
        .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vec![Vec3::ZERO; 0])
        .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, vec![Vec2::ZERO; 0]);
        
        for (side_n, is_visible) in visible_sides.iter().enumerate() {
            if *is_visible {
                let side_mesh = generate_side_mesh(side_n)
                .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, SIDE_UV.to_vec());
                result.merge(side_mesh);
            }
        }
        result
    }
}