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

View File

@ -1,5 +1,5 @@
use super::cell::CellData;
use crate::vol::Vox;
use crate::vol::FilledVox;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Material {
@ -22,10 +22,10 @@ pub enum MatCell {
Normal(CellData),
}
impl Vox for MatCell {
fn empty() -> Self { MatCell::None }
impl FilledVox for MatCell {
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)]

View File

@ -10,7 +10,7 @@ pub use self::{
use crate::{
terrain::{Block, BlockKind, SpriteKind},
vol::{IntoFullPosIterator, IntoFullVolIterator, ReadVol, SizedVol, Vox, WriteVol},
vol::{FilledVox, IntoFullPosIterator, IntoFullVolIterator, ReadVol, SizedVol, WriteVol},
volumes::dyna::Dyna,
};
use dot_vox::DotVoxData;
@ -65,7 +65,7 @@ impl Segment {
let mut segment = Segment::filled(
Vec3::new(model.size.x, model.size.y, model.size.z),
Cell::empty(),
Cell::Empty,
(),
);
@ -96,7 +96,7 @@ impl Segment {
segment
} else {
Segment::filled(Vec3::zero(), Cell::empty(), ())
Segment::filled(Vec3::zero(), Cell::Empty, ())
}
}
@ -130,9 +130,9 @@ impl Segment {
// TODO: move
/// 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)]
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>) {
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
@ -167,12 +170,12 @@ impl<V: Vox + Copy> DynaUnionizer<V> {
}
let new_size = (max_point - min_point).map(|e| e as u32);
// 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
let origin = min_point.map(|e| -e);
for (dyna, offset) in self.0 {
for (pos, vox) in dyna.full_vol_iter() {
if !vox.is_empty() {
if vox.is_filled() {
combined.set(origin + offset + pos, f(*vox)).unwrap();
}
}
@ -186,7 +189,7 @@ pub type MatSegment = Dyna<MatCell, ()>;
impl MatSegment {
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() {
let data = match vox {
MatCell::None => continue,
@ -236,7 +239,7 @@ impl MatSegment {
let mut vol = Dyna::filled(
Vec3::new(model.size.x, model.size.y, model.size.z),
MatCell::empty(),
MatCell::None,
(),
);
@ -282,7 +285,7 @@ impl MatSegment {
vol
} else {
Dyna::filled(Vec3::zero(), MatCell::empty(), ())
Dyna::filled(Vec3::zero(), MatCell::None, ())
}
}
}

View File

@ -4,7 +4,7 @@ use crate::{
consts::FRIC_GROUND,
lottery::LootSpec,
make_case_elim, rtsim,
vol::Vox,
vol::FilledVox,
};
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
@ -118,10 +118,10 @@ pub struct Block {
attr: [u8; 3],
}
impl Vox for Block {
fn empty() -> Self { Block::air(SpriteKind::Empty) }
impl FilledVox for Block {
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 {

View File

@ -13,12 +13,12 @@ pub trait RectVolSize: Clone {
}
/// A voxel.
pub trait Vox: Sized + Clone + PartialEq {
fn empty() -> Self;
fn is_empty(&self) -> bool;
pub trait FilledVox: Sized + Clone + PartialEq {
fn default_non_filled() -> Self;
fn is_filled(&self) -> bool;
#[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.

View File

@ -1,4 +1,4 @@
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox};
use crate::vol::{BaseVol, FilledVox, ReadVol, SizedVol};
use vek::*;
pub struct Scaled<V> {
@ -13,7 +13,7 @@ impl<V: BaseVol> BaseVol for Scaled<V> {
impl<V: ReadVol> ReadVol for Scaled<V>
where
V::Vox: Vox,
V::Vox: FilledVox,
{
#[inline(always)]
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> {
@ -43,7 +43,7 @@ where
})
.flatten()
.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))
}
}

View File

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

View File

@ -27,7 +27,7 @@ use common::{
},
figure::{Cell, DynaUnionizer, MatCell, MatSegment, Material, Segment},
terrain::Block,
vol::{IntoFullPosIterator, ReadVol, Vox},
vol::{IntoFullPosIterator, ReadVol},
volumes::dyna::Dyna,
};
use hashbrown::HashMap;
@ -357,7 +357,7 @@ impl HumHeadSpec {
.maybe_add(beard)
.maybe_add(accessory)
.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,
Vec3::from(spec.offset) + origin_offset.map(|e| e as f32 * -1.0),

View File

@ -1,7 +1,7 @@
use common::{
figure::Segment,
util::{linear_to_srgba, srgb_to_linear},
vol::{IntoFullVolIterator, ReadVol, SizedVol, Vox},
vol::{FilledVox, IntoFullVolIterator, ReadVol, SizedVol},
};
use euc::{buffer::Buffer2d, rasterizer, Pipeline};
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() {
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| {
// Would be nice to generate unit_x and unit_y from a given direction.
[
!is_empty(pos + dir - unit_x),
!is_empty(pos + dir - unit_x - unit_y),
!is_empty(pos + dir - unit_y),
!is_empty(pos + dir + unit_x - unit_y),
!is_empty(pos + dir + unit_x),
!is_empty(pos + dir + unit_x + unit_y),
!is_empty(pos + dir + unit_y),
!is_empty(pos + dir - unit_x + unit_y),
is_filled(pos + dir - unit_x),
is_filled(pos + dir - unit_x - unit_y),
is_filled(pos + dir - unit_y),
is_filled(pos + dir + unit_x - unit_y),
is_filled(pos + dir + unit_x),
is_filled(pos + dir + unit_x + unit_y),
is_filled(pos + dir + unit_y),
is_filled(pos + dir - unit_x + unit_y),
]
};
// -x
if is_empty(pos - Vec3::unit_x()) {
if !is_filled(pos - Vec3::unit_x()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(),
-Vec3::unit_y(),
@ -291,7 +291,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
));
}
// +x
if is_empty(pos + Vec3::unit_x()) {
if !is_filled(pos + Vec3::unit_x()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_x(),
Vec3::unit_y(),
@ -302,7 +302,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
));
}
// -y
if is_empty(pos - Vec3::unit_y()) {
if !is_filled(pos - Vec3::unit_y()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32),
Vec3::unit_x(),
@ -313,7 +313,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
));
}
// +y
if is_empty(pos + Vec3::unit_y()) {
if !is_filled(pos + Vec3::unit_y()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(),
Vec3::unit_z(),
@ -324,7 +324,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
));
}
// -z
if is_empty(pos - Vec3::unit_z()) {
if !is_filled(pos - Vec3::unit_z()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32),
Vec3::unit_y(),
@ -335,7 +335,7 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
));
}
// +z
if is_empty(pos + Vec3::unit_z()) {
if !is_filled(pos + Vec3::unit_z()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_z(),
Vec3::unit_x(),