bones3_remesh/mesh/
block_model.rs

1//! Defines how a block model should be added to a chunk mesh.
2
3use bevy::prelude::*;
4use bitflags::bitflags;
5use bones3_core::prelude::*;
6
7use crate::vertex_data::{ShapeBuilder, TempMesh};
8
9bitflags! {
10    #[derive(Copy, Clone)]
11    /// A bitflag-based enum that defines how a block is currently being occluded.
12    pub struct BlockOcclusion: u8 {
13        /// If true, the block is occluded in the negative X direction.
14        const NEG_X = 0b00000001;
15
16        /// If true, the block is occluded in the positive X direction.
17        const POS_X = 0b00000010;
18
19        /// If true, the block is occluded in the negative Y direction.
20        const NEG_Y = 0b00000100;
21
22        /// If true, the block is occluded in the positive Y direction.
23        const POS_Y = 0b00001000;
24
25        /// If true, the block is occluded in the negative Z direction.
26        const NEG_Z = 0b00010000;
27
28        /// If true, the block is occluded in the positive Z direction.
29        const POS_Z = 0b00100000;
30    }
31}
32
33impl BlockOcclusion {
34    /// Converts this block occlusion value into a directional offset vector.
35    pub fn into_offset(self) -> IVec3 {
36        let mut offset = IVec3::ZERO;
37
38        if self.contains(BlockOcclusion::NEG_X) {
39            offset += IVec3::NEG_X;
40        }
41
42        if self.contains(BlockOcclusion::POS_X) {
43            offset += IVec3::X;
44        }
45
46        if self.contains(BlockOcclusion::NEG_Y) {
47            offset += IVec3::NEG_Y;
48        }
49
50        if self.contains(BlockOcclusion::POS_Y) {
51            offset += IVec3::Y;
52        }
53
54        if self.contains(BlockOcclusion::NEG_Z) {
55            offset += IVec3::NEG_Z;
56        }
57
58        if self.contains(BlockOcclusion::POS_Z) {
59            offset += IVec3::Z;
60        }
61
62        offset
63    }
64
65    /// Gets the opposite facing value for this block occlusion.
66    ///
67    /// For a positive value along an axis, this function will return the
68    /// negative value of that axis. Likewise, negative value will return
69    /// the positive counter parts. This effect is applied for all defined
70    /// directional values.
71    pub fn opposite_face(self) -> BlockOcclusion {
72        let mut value = BlockOcclusion::empty();
73
74        if self.contains(BlockOcclusion::NEG_X) {
75            value |= BlockOcclusion::POS_X;
76        }
77
78        if self.contains(BlockOcclusion::POS_X) {
79            value |= BlockOcclusion::NEG_X;
80        }
81
82        if self.contains(BlockOcclusion::NEG_Y) {
83            value |= BlockOcclusion::POS_Y;
84        }
85
86        if self.contains(BlockOcclusion::POS_Y) {
87            value |= BlockOcclusion::NEG_Y;
88        }
89
90        if self.contains(BlockOcclusion::NEG_Z) {
91            value |= BlockOcclusion::POS_Z;
92        }
93
94        if self.contains(BlockOcclusion::POS_Z) {
95            value |= BlockOcclusion::NEG_Z;
96        }
97
98        value
99    }
100}
101
102impl Default for BlockOcclusion {
103    fn default() -> Self {
104        BlockOcclusion::empty()
105    }
106}
107
108/// A generator for creating a block model that can be written to a temporary
109/// chunk mesh.
110pub trait BlockModelGenerator {
111    /// Writes the block model to the provided temporary chunk mesh.
112    fn write_to_mesh(&self, mesh: &mut TempMesh, pos: IVec3);
113}
114
115/// A trait that can be defined for a block data object in order to specify how
116/// a block model should be generated and added to the chunk mesh.
117pub trait BlockShape: BlockData {
118    /// Writes an instance of this block shape to the provided shape builder,
119    ///
120    /// Information such as the current block occlusion may be retrieved from
121    /// the shape builder as needed.
122    fn write_shape(&self, shape_builder: &mut ShapeBuilder);
123
124    /// Checks if one tile is to occlude another tile. Returns True if face is
125    /// occluded.
126    fn check_occlude(&self, face: BlockOcclusion, other: Self) -> bool;
127}