1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#![allow(dead_code, unused_imports)]
pub(crate) mod face;
pub(crate) mod mesh_metadata;
pub(crate) mod meshem;
pub(crate) mod pbs;
pub(crate) mod update;
pub(crate) mod util;
pub(crate) mod voxel_mesh;

use bevy::log::warn;
use bevy::render::mesh::{Mesh, MeshVertexAttribute};

pub mod prelude {
    pub use crate::face::Face::*;
    pub use crate::face::*;
    pub use crate::mesh_metadata::*;
    pub use crate::meshem::*;
    pub use crate::pbs::*;
    pub use crate::update::*;
    pub use crate::util::compressed_voxel_grid::*;
    pub use crate::util::vav::*;
    pub use crate::util::*;
    pub use crate::voxel_mesh::*;
    pub use crate::VoxelRegistry;
    pub use crate::*;
}

/// Implementing this trait for your own data-structure is the most important
/// prerequesite if you want to use the function.
pub trait VoxelRegistry {
    type Voxel: std::fmt::Debug + Eq + PartialEq;
    /// Returns None if the mesh is "irrelevant" as in it's air or not a Voxel.
    fn get_mesh(&self, voxel: &Self::Voxel) -> VoxelMesh<&Mesh>;
    /// Would this voxel cover the voxel that's located on it's `side`? for example, an air block
    /// would not cover any side, but a slab would only cover the bottom.
    fn is_covering(&self, voxel: &Self::Voxel, side: prelude::Face) -> bool;
    /// The center of the voxel (physical center, the center of the default block is 0,0,0 eg)
    fn get_center(&self) -> [f32; 3];
    /// All the voxels must have standard and equal dimesions (y is up).
    fn get_voxel_dimensions(&self) -> [f32; 3];
    /// The attributes we are considering while meshing the grid.
    fn all_attributes(&self) -> Vec<MeshVertexAttribute>;
}

/// (width, height, length) - note that bevy considers the "y position" to be height.
pub type Dimensions = (usize, usize, usize);

pub enum VoxelMesh<T> {
    NormalCube(T),
    CustomMesh(T),
    Null,
}

impl<T> VoxelMesh<T> {
    pub fn unwrap(self) -> T {
        match self {
            Self::NormalCube(t) => t,
            Self::CustomMesh(t) => {
                warn!("Custom Meshes are still not properly implemented!");
                t
            }
            Self::Null => panic!(),
        }
    }

    pub fn expect(self, msg: &str) -> T {
        match self {
            Self::NormalCube(t) => t,
            Self::CustomMesh(t) => {
                warn!("Custom Meshes are still not properly implemented!");
                t
            }
            Self::Null => panic!("{}", msg),
        }
    }
}

/// [+y, -y, +x, -x, +z, -z], true if that face is not covered.
pub(crate) type Neighbors = [bool; 6];