rename Vox trait to FilledVox, and change is_empty to is_filled

This commit is contained in:
Isse 2023-05-09 19:36:27 +02:00
parent 7dde25df39
commit 6219b52f87
9 changed files with 68 additions and 72 deletions

View File

@ -1,6 +1,6 @@
use std::num::NonZeroU8; use std::num::NonZeroU8;
use crate::vol::Vox; use crate::vol::FilledVox;
use vek::*; use vek::*;
const GLOWY: u8 = 1 << 1; const GLOWY: u8 = 1 << 1;
@ -72,15 +72,10 @@ impl Cell {
} }
} }
impl Vox for Cell { impl FilledVox for Cell {
fn empty() -> Self { Cell::Empty } fn default_non_filled() -> Self { Cell::Empty }
fn is_empty(&self) -> bool { fn is_filled(&self) -> bool { matches!(self, Cell::Filled(_)) }
match self {
Cell::Filled(_) => false,
Cell::Empty => true,
}
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,5 +1,5 @@
use super::cell::CellData; use super::cell::CellData;
use crate::vol::Vox; use crate::vol::FilledVox;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Material { pub enum Material {
@ -22,10 +22,10 @@ pub enum MatCell {
Normal(CellData), Normal(CellData),
} }
impl Vox for MatCell { impl FilledVox for MatCell {
fn empty() -> Self { MatCell::None } fn default_non_filled() -> Self { MatCell::None }
fn is_empty(&self) -> bool { matches!(self, MatCell::None) } fn is_filled(&self) -> bool { !matches!(self, MatCell::None) }
} }
#[cfg(test)] #[cfg(test)]

View File

@ -10,7 +10,7 @@ pub use self::{
use crate::{ use crate::{
terrain::{Block, BlockKind, SpriteKind}, terrain::{Block, BlockKind, SpriteKind},
vol::{IntoFullPosIterator, IntoFullVolIterator, ReadVol, SizedVol, Vox, WriteVol}, vol::{FilledVox, IntoFullPosIterator, IntoFullVolIterator, ReadVol, SizedVol, WriteVol},
volumes::dyna::Dyna, volumes::dyna::Dyna,
}; };
use dot_vox::DotVoxData; use dot_vox::DotVoxData;
@ -65,7 +65,7 @@ impl Segment {
let mut segment = Segment::filled( let mut segment = Segment::filled(
Vec3::new(model.size.x, model.size.y, model.size.z), Vec3::new(model.size.x, model.size.y, model.size.z),
Cell::empty(), Cell::Empty,
(), (),
); );
@ -96,7 +96,7 @@ impl Segment {
segment segment
} else { } else {
Segment::filled(Vec3::zero(), Cell::empty(), ()) Segment::filled(Vec3::zero(), Cell::Empty, ())
} }
} }
@ -130,9 +130,9 @@ impl Segment {
// TODO: move // TODO: move
/// A `Dyna` builder that combines Dynas /// A `Dyna` builder that combines Dynas
pub struct DynaUnionizer<V: Vox>(Vec<(Dyna<V, ()>, Vec3<i32>)>); pub struct DynaUnionizer<V: FilledVox>(Vec<(Dyna<V, ()>, Vec3<i32>)>);
impl<V: Vox + Copy> DynaUnionizer<V> { impl<V: FilledVox + Copy> DynaUnionizer<V> {
#[allow(clippy::new_without_default)] #[allow(clippy::new_without_default)]
pub fn new() -> Self { DynaUnionizer(Vec::new()) } pub fn new() -> Self { DynaUnionizer(Vec::new()) }
@ -154,7 +154,10 @@ impl<V: Vox + Copy> DynaUnionizer<V> {
pub fn unify_with(self, mut f: impl FnMut(V) -> V) -> (Dyna<V, ()>, Vec3<i32>) { pub fn unify_with(self, mut f: impl FnMut(V) -> V) -> (Dyna<V, ()>, Vec3<i32>) {
if self.0.is_empty() { if self.0.is_empty() {
return (Dyna::filled(Vec3::zero(), V::empty(), ()), Vec3::zero()); return (
Dyna::filled(Vec3::zero(), V::default_non_filled(), ()),
Vec3::zero(),
);
} }
// Determine size of the new Dyna // Determine size of the new Dyna
@ -167,12 +170,12 @@ impl<V: Vox + Copy> DynaUnionizer<V> {
} }
let new_size = (max_point - min_point).map(|e| e as u32); let new_size = (max_point - min_point).map(|e| e as u32);
// Allocate new segment // Allocate new segment
let mut combined = Dyna::filled(new_size, V::empty(), ()); let mut combined = Dyna::filled(new_size, V::default_non_filled(), ());
// Copy segments into combined // Copy segments into combined
let origin = min_point.map(|e| -e); let origin = min_point.map(|e| -e);
for (dyna, offset) in self.0 { for (dyna, offset) in self.0 {
for (pos, vox) in dyna.full_vol_iter() { for (pos, vox) in dyna.full_vol_iter() {
if !vox.is_empty() { if vox.is_filled() {
combined.set(origin + offset + pos, f(*vox)).unwrap(); combined.set(origin + offset + pos, f(*vox)).unwrap();
} }
} }
@ -186,7 +189,7 @@ pub type MatSegment = Dyna<MatCell, ()>;
impl MatSegment { impl MatSegment {
pub fn to_segment(&self, map: impl Fn(Material) -> Rgb<u8>) -> Segment { pub fn to_segment(&self, map: impl Fn(Material) -> Rgb<u8>) -> Segment {
let mut vol = Dyna::filled(self.size(), Cell::empty(), ()); let mut vol = Dyna::filled(self.size(), Cell::Empty, ());
for (pos, vox) in self.full_vol_iter() { for (pos, vox) in self.full_vol_iter() {
let data = match vox { let data = match vox {
MatCell::None => continue, MatCell::None => continue,
@ -236,7 +239,7 @@ impl MatSegment {
let mut vol = Dyna::filled( let mut vol = Dyna::filled(
Vec3::new(model.size.x, model.size.y, model.size.z), Vec3::new(model.size.x, model.size.y, model.size.z),
MatCell::empty(), MatCell::None,
(), (),
); );
@ -282,7 +285,7 @@ impl MatSegment {
vol vol
} else { } else {
Dyna::filled(Vec3::zero(), MatCell::empty(), ()) Dyna::filled(Vec3::zero(), MatCell::None, ())
} }
} }
} }

View File

@ -4,7 +4,7 @@ use crate::{
consts::FRIC_GROUND, consts::FRIC_GROUND,
lottery::LootSpec, lottery::LootSpec,
make_case_elim, rtsim, make_case_elim, rtsim,
vol::Vox, vol::FilledVox,
}; };
use num_derive::FromPrimitive; use num_derive::FromPrimitive;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
@ -118,10 +118,10 @@ pub struct Block {
attr: [u8; 3], attr: [u8; 3],
} }
impl Vox for Block { impl FilledVox for Block {
fn empty() -> Self { Block::air(SpriteKind::Empty) } fn default_non_filled() -> Self { Block::air(SpriteKind::Empty) }
fn is_empty(&self) -> bool { self.is_air() && self.get_sprite().is_none() } fn is_filled(&self) -> bool { self.kind.is_filled() }
} }
impl Deref for Block { impl Deref for Block {

View File

@ -13,12 +13,12 @@ pub trait RectVolSize: Clone {
} }
/// A voxel. /// A voxel.
pub trait Vox: Sized + Clone + PartialEq { pub trait FilledVox: Sized + Clone + PartialEq {
fn empty() -> Self; fn default_non_filled() -> Self;
fn is_empty(&self) -> bool; fn is_filled(&self) -> bool;
#[must_use] #[must_use]
fn or(self, other: Self) -> Self { if self.is_empty() { other } else { self } } fn or(self, other: Self) -> Self { if self.is_filled() { self } else { other } }
} }
/// A volume that contains voxel data. /// A volume that contains voxel data.

View File

@ -1,4 +1,4 @@
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox}; use crate::vol::{BaseVol, FilledVox, ReadVol, SizedVol};
use vek::*; use vek::*;
pub struct Scaled<V> { pub struct Scaled<V> {
@ -13,7 +13,7 @@ impl<V: BaseVol> BaseVol for Scaled<V> {
impl<V: ReadVol> ReadVol for Scaled<V> impl<V: ReadVol> ReadVol for Scaled<V>
where where
V::Vox: Vox, V::Vox: FilledVox,
{ {
#[inline(always)] #[inline(always)]
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> { fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> {
@ -43,7 +43,7 @@ where
}) })
.flatten() .flatten()
.map(|offs| self.inner.get(pos + offs)) .map(|offs| self.inner.get(pos + offs))
.find(|vox| vox.as_ref().map(|v| !v.is_empty()).unwrap_or(false)) .find(|vox| vox.as_ref().map_or(false, |v| v.is_filled()))
.unwrap_or_else(|| self.inner.get(pos)) .unwrap_or_else(|| self.inner.get(pos))
} }
} }

View File

@ -10,7 +10,7 @@ use crate::{
use common::{ use common::{
figure::Cell, figure::Cell,
terrain::Block, terrain::Block,
vol::{BaseVol, ReadVol, SizedVol, Vox}, vol::{BaseVol, FilledVox, ReadVol, SizedVol},
}; };
use core::convert::TryFrom; use core::convert::TryFrom;
use vek::*; use vek::*;
@ -56,19 +56,18 @@ where
let draw_delta = lower_bound; let draw_delta = lower_bound;
let get_light = |vol: &mut V, pos: Vec3<i32>| { let get_light = |vol: &mut V, pos: Vec3<i32>| {
if vol.get(pos).map(|vox| vox.is_empty()).unwrap_or(true) { if vol.get(pos).map_or(true, |vox| !vox.is_filled()) {
1.0 1.0
} else { } else {
0.0 0.0
} }
}; };
let get_glow = |_vol: &mut V, _pos: Vec3<i32>| 0.0; let get_glow = |_vol: &mut V, _pos: Vec3<i32>| 0.0;
let get_opacity = |vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| vox.is_empty()); let get_opacity =
|vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| !vox.is_filled());
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| { let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
should_draw_greedy(pos, delta, uv, |vox| { should_draw_greedy(pos, delta, uv, |vox| {
vol.get(vox) vol.get(vox).map(|vox| *vox).unwrap_or_else(|_| Cell::Empty)
.map(|vox| *vox)
.unwrap_or_else(|_| Cell::empty())
}) })
}; };
let create_opaque = |atlas_pos, pos, norm| { let create_opaque = |atlas_pos, pos, norm| {
@ -270,13 +269,13 @@ where
let (flat, flat_get) = { let (flat, flat_get) = {
let (w, h, d) = (greedy_size + 2).into_tuple(); let (w, h, d) = (greedy_size + 2).into_tuple();
let flat = { let flat = {
let mut flat = vec![Cell::empty(); (w * h * d) as usize]; let mut flat = vec![Cell::Empty; (w * h * d) as usize];
let mut i = 0; let mut i = 0;
for x in -1..greedy_size.x + 1 { for x in -1..greedy_size.x + 1 {
for y in -1..greedy_size.y + 1 { for y in -1..greedy_size.y + 1 {
for z in -1..greedy_size.z + 1 { for z in -1..greedy_size.z + 1 {
let wpos = lower_bound + Vec3::new(x, y, z); let wpos = lower_bound + Vec3::new(x, y, z);
let block = vol.get(wpos).map(|b| *b).unwrap_or_else(|_| Cell::empty()); let block = vol.get(wpos).map(|b| *b).unwrap_or_else(|_| Cell::Empty);
flat[i] = block; flat[i] = block;
i += 1; i += 1;
} }
@ -304,7 +303,7 @@ where
let draw_delta = Vec3::new(1, 1, 1); let draw_delta = Vec3::new(1, 1, 1);
let get_light = move |flat: &mut _, pos: Vec3<i32>| { let get_light = move |flat: &mut _, pos: Vec3<i32>| {
if flat_get(flat, pos).is_empty() { if !flat_get(flat, pos).is_filled() {
1.0 1.0
} else { } else {
0.0 0.0
@ -314,7 +313,7 @@ where
let get_color = move |flat: &mut _, pos: Vec3<i32>| { let get_color = move |flat: &mut _, pos: Vec3<i32>| {
flat_get(flat, pos).get_color().unwrap_or_else(Rgb::zero) flat_get(flat, pos).get_color().unwrap_or_else(Rgb::zero)
}; };
let get_opacity = move |flat: &mut _, pos: Vec3<i32>| flat_get(flat, pos).is_empty(); let get_opacity = move |flat: &mut _, pos: Vec3<i32>| !flat_get(flat, pos).is_filled();
let should_draw = move |flat: &mut _, pos: Vec3<i32>, delta: Vec3<i32>, uv| { let should_draw = move |flat: &mut _, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
should_draw_greedy_ao(vertical_stripes, pos, delta, uv, |vox| flat_get(flat, vox)) should_draw_greedy_ao(vertical_stripes, pos, delta, uv, |vox| flat_get(flat, vox))
}; };
@ -391,7 +390,7 @@ where
let draw_delta = lower_bound; let draw_delta = lower_bound;
let get_light = |vol: &mut V, pos: Vec3<i32>| { let get_light = |vol: &mut V, pos: Vec3<i32>| {
if vol.get(pos).map(|vox| vox.is_empty()).unwrap_or(true) { if vol.get(pos).map_or(true, |vox| !vox.is_filled()) {
1.0 1.0
} else { } else {
0.0 0.0
@ -404,12 +403,11 @@ where
.and_then(|vox| vox.get_color()) .and_then(|vox| vox.get_color())
.unwrap_or_else(Rgb::zero) .unwrap_or_else(Rgb::zero)
}; };
let get_opacity = |vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| vox.is_empty()); let get_opacity =
|vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| !vox.is_filled());
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| { let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
should_draw_greedy(pos, delta, uv, |vox| { should_draw_greedy(pos, delta, uv, |vox| {
vol.get(vox) vol.get(vox).map(|vox| *vox).unwrap_or_else(|_| Cell::Empty)
.map(|vox| *vox)
.unwrap_or_else(|_| Cell::empty())
}) })
}; };
let create_opaque = |_atlas_pos, pos: Vec3<f32>, norm| ParticleVertex::new(pos, norm); let create_opaque = |_atlas_pos, pos: Vec3<f32>, norm| ParticleVertex::new(pos, norm);
@ -452,8 +450,8 @@ fn should_draw_greedy(
) -> Option<(bool, /* u8 */ ())> { ) -> Option<(bool, /* u8 */ ())> {
let from = flat_get(pos - delta); let from = flat_get(pos - delta);
let to = flat_get(pos); let to = flat_get(pos);
let from_opaque = !from.is_empty(); let from_opaque = from.is_filled();
if from_opaque != to.is_empty() { if from_opaque != !to.is_filled() {
None None
} else { } else {
// If going from transparent to opaque, backward facing; otherwise, forward // If going from transparent to opaque, backward facing; otherwise, forward
@ -471,8 +469,8 @@ fn should_draw_greedy_ao(
) -> Option<(bool, bool)> { ) -> Option<(bool, bool)> {
let from = flat_get(pos - delta); let from = flat_get(pos - delta);
let to = flat_get(pos); let to = flat_get(pos);
let from_opaque = !from.is_empty(); let from_opaque = from.is_filled();
if from_opaque != to.is_empty() { if from_opaque != !to.is_filled() {
None None
} else { } else {
let faces_forward = from_opaque; let faces_forward = from_opaque;

View File

@ -27,7 +27,7 @@ use common::{
}, },
figure::{Cell, DynaUnionizer, MatCell, MatSegment, Material, Segment}, figure::{Cell, DynaUnionizer, MatCell, MatSegment, Material, Segment},
terrain::Block, terrain::Block,
vol::{IntoFullPosIterator, ReadVol, Vox}, vol::{IntoFullPosIterator, ReadVol},
volumes::dyna::Dyna, volumes::dyna::Dyna,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
@ -357,7 +357,7 @@ impl HumHeadSpec {
.maybe_add(beard) .maybe_add(beard)
.maybe_add(accessory) .maybe_add(accessory)
.maybe_add(helmet) .maybe_add(helmet)
.unify_with(|v| if v.is_hollow() { Cell::empty() } else { v }); .unify_with(|v| if v.is_hollow() { Cell::Empty } else { v });
( (
head, head,
Vec3::from(spec.offset) + origin_offset.map(|e| e as f32 * -1.0), Vec3::from(spec.offset) + origin_offset.map(|e| e as f32 * -1.0),

View File

@ -1,7 +1,7 @@
use common::{ use common::{
figure::Segment, figure::Segment,
util::{linear_to_srgba, srgb_to_linear}, util::{linear_to_srgba, srgb_to_linear},
vol::{IntoFullVolIterator, ReadVol, SizedVol, Vox}, vol::{FilledVox, IntoFullVolIterator, ReadVol, SizedVol},
}; };
use euc::{buffer::Buffer2d, rasterizer, Pipeline}; use euc::{buffer::Buffer2d, rasterizer, Pipeline};
use image::{DynamicImage, RgbaImage}; use image::{DynamicImage, RgbaImage};
@ -263,24 +263,24 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
if let Some(col) = vox.get_color() { if let Some(col) = vox.get_color() {
let col = col.map(|e| e as f32 / 255.0); let col = col.map(|e| e as f32 / 255.0);
let is_empty = |pos| segment.get(pos).map(|v| v.is_empty()).unwrap_or(true); let is_filled = |pos| segment.get(pos).map(|v| v.is_filled()).unwrap_or(false);
let occluders = |unit_x, unit_y, dir| { let occluders = |unit_x, unit_y, dir| {
// Would be nice to generate unit_x and unit_y from a given direction. // Would be nice to generate unit_x and unit_y from a given direction.
[ [
!is_empty(pos + dir - unit_x), is_filled(pos + dir - unit_x),
!is_empty(pos + dir - unit_x - unit_y), is_filled(pos + dir - unit_x - unit_y),
!is_empty(pos + dir - unit_y), is_filled(pos + dir - unit_y),
!is_empty(pos + dir + unit_x - unit_y), is_filled(pos + dir + unit_x - unit_y),
!is_empty(pos + dir + unit_x), is_filled(pos + dir + unit_x),
!is_empty(pos + dir + unit_x + unit_y), is_filled(pos + dir + unit_x + unit_y),
!is_empty(pos + dir + unit_y), is_filled(pos + dir + unit_y),
!is_empty(pos + dir - unit_x + unit_y), is_filled(pos + dir - unit_x + unit_y),
] ]
}; };
// -x // -x
if is_empty(pos - Vec3::unit_x()) { if !is_filled(pos - Vec3::unit_x()) {
vertices.extend_from_slice(&create_quad( vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(), offs + pos.map(|e| e as f32) + Vec3::unit_y(),
-Vec3::unit_y(), -Vec3::unit_y(),
@ -291,7 +291,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
)); ));
} }
// +x // +x
if is_empty(pos + Vec3::unit_x()) { if !is_filled(pos + Vec3::unit_x()) {
vertices.extend_from_slice(&create_quad( vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_x(), offs + pos.map(|e| e as f32) + Vec3::unit_x(),
Vec3::unit_y(), Vec3::unit_y(),
@ -302,7 +302,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
)); ));
} }
// -y // -y
if is_empty(pos - Vec3::unit_y()) { if !is_filled(pos - Vec3::unit_y()) {
vertices.extend_from_slice(&create_quad( vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32), offs + pos.map(|e| e as f32),
Vec3::unit_x(), Vec3::unit_x(),
@ -313,7 +313,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
)); ));
} }
// +y // +y
if is_empty(pos + Vec3::unit_y()) { if !is_filled(pos + Vec3::unit_y()) {
vertices.extend_from_slice(&create_quad( vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(), offs + pos.map(|e| e as f32) + Vec3::unit_y(),
Vec3::unit_z(), Vec3::unit_z(),
@ -324,7 +324,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
)); ));
} }
// -z // -z
if is_empty(pos - Vec3::unit_z()) { if !is_filled(pos - Vec3::unit_z()) {
vertices.extend_from_slice(&create_quad( vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32), offs + pos.map(|e| e as f32),
Vec3::unit_y(), Vec3::unit_y(),
@ -335,7 +335,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
)); ));
} }
// +z // +z
if is_empty(pos + Vec3::unit_z()) { if !is_filled(pos + Vec3::unit_z()) {
vertices.extend_from_slice(&create_quad( vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_z(), offs + pos.map(|e| e as f32) + Vec3::unit_z(),
Vec3::unit_x(), Vec3::unit_x(),