diff --git a/all-is-cubes-mesh/src/dynamic/blocks.rs b/all-is-cubes-mesh/src/dynamic/blocks.rs index 2d0555022..2022c93ce 100644 --- a/all-is-cubes-mesh/src/dynamic/blocks.rs +++ b/all-is-cubes-mesh/src/dynamic/blocks.rs @@ -1,5 +1,6 @@ use std::num::NonZeroU32; +use all_is_cubes::math::Cube; use fnv::FnvHashSet; use all_is_cubes::block::{EvaluatedBlock, Resolution}; @@ -216,7 +217,12 @@ impl Default for VersionedBlockMeshes { impl<'a, D, Vert: 'static, Tile: 'static> GetBlockMesh<'a, Vert, Tile> for &'a VersionedBlockMeshes { - fn get_block_mesh(&mut self, index: BlockIndex) -> &'a BlockMesh { + fn get_block_mesh( + &mut self, + index: BlockIndex, + _cube: Cube, + _primary: bool, + ) -> &'a BlockMesh { self.meshes .get(usize::from(index)) .map(|vbm| &vbm.mesh) diff --git a/all-is-cubes-mesh/src/space_mesh.rs b/all-is-cubes-mesh/src/space_mesh.rs index 8c2f557fd..6b82aaa31 100644 --- a/all-is-cubes-mesh/src/space_mesh.rs +++ b/all-is-cubes-mesh/src/space_mesh.rs @@ -199,7 +199,7 @@ impl SpaceMesh { None => return, // continue in for_each() loop }; let already_seen_index = bitset_set_and_get(&mut self.block_indices_used, index.into()); - let block_mesh = block_meshes.get_block_mesh(index); + let block_mesh = block_meshes.get_block_mesh(index, cube, true); if !already_seen_index { // Capture texture handles to ensure that our texture coordinates stay valid. @@ -220,8 +220,9 @@ impl SpaceMesh { |face| { let adjacent_cube = cube + face.normal_vector(); if let Some(adj_block_index) = space.get_block_index(adjacent_cube) { - if block_meshes.get_block_mesh(adj_block_index).face_vertices - [face.opposite()] + if block_meshes + .get_block_mesh(adj_block_index, adjacent_cube, false) + .face_vertices[face.opposite()] .fully_opaque { // Don't draw obscured faces, but do record that we depended on them. @@ -592,25 +593,46 @@ pub trait GetBlockMesh<'a, V, T> { /// [`Space::block_data()`] in the relevant [`Space`]. /// /// This function should be idempotent, at least within a single invocation of - /// [`SpaceMesh::compute()`]; identical input indexes should produce identical meshes. - /// If this is not the case, then the [`SpaceMesh`] may have inconsistent properties. + /// [`SpaceMesh::compute()`] to which it was given; identical inputs should + /// produce identical meshes. If this is not the case, then the resulting [`SpaceMesh`] + /// may have inconsistent properties such as gaps where block faces were presumed to be hidden. + /// + /// # `primary` + /// + /// The `primary` parameter will be `true` exactly once per cube in the meshed region, + /// per call to [`SpaceMesh::compute()`], and the block mesh returned at that time will be the + /// mesh actually included in the produced [`SpaceMesh`]. All other calls will be for consulting + /// neighbors' obscuring faces for culling. + /// + /// Thus, for example, the implementation may choose to record the presence of a particular + /// block to perform additional or substitute rendering separate from the computed mesh. /// /// # Errors and panics /// /// If the block index is out of range (which should not happen unless the [`Space`] - /// being meshed is inconsistent the state of this [`GetBlockMesh`] implementor), + /// being meshed is inconsistent with the state of this [`GetBlockMesh`] implementor), /// then the implementation may at its choice return whatever mesh it wishes to display /// instead, or panic if this suits the particular mesh generation application. /// /// Note that the returned [`BlockMesh`] may have [`Flaws`] which will be incorporated /// into the [`SpaceMesh`]'s flaws. - fn get_block_mesh(&mut self, index: BlockIndex) -> &'a BlockMesh; + fn get_block_mesh( + &mut self, + index: BlockIndex, + cube: Cube, + primary: bool, + ) -> &'a BlockMesh; } /// Basic implementation of [`GetBlockMesh`] for any slice of meshes. impl<'a, V: 'static, T: 'static> GetBlockMesh<'a, V, T> for &'a [BlockMesh] { - fn get_block_mesh(&mut self, index: BlockIndex) -> &'a BlockMesh { - // TODO: Consider changing this behavior to either panic or return a mesh with + fn get_block_mesh( + &mut self, + index: BlockIndex, + #[allow(unused)] cube: Cube, + #[allow(unused)] primary: bool, + ) -> &'a BlockMesh { + // TODO: Consider changing this out-of-bounds behavior to either panic or return a mesh with // some `Flaws` set. <[_]>::get(self, usize::from(index)).unwrap_or(BlockMesh::::EMPTY_REF) @@ -863,6 +885,9 @@ mod tests { #[test] fn slice_get_block_mesh_out_of_bounds() { let mut source: &[BlockMesh, TestTile>] = &[]; - assert_eq!(source.get_block_mesh(10), BlockMesh::EMPTY_REF); + assert_eq!( + source.get_block_mesh(10, Cube::ORIGIN, true), + BlockMesh::EMPTY_REF + ); } }