mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
support for hollow voxels ty zesterer
This commit is contained in:
@ -5,24 +5,28 @@ use vek::*;
|
|||||||
|
|
||||||
const GLOWY: u8 = 1 << 1;
|
const GLOWY: u8 = 1 << 1;
|
||||||
const SHINY: u8 = 1 << 2;
|
const SHINY: u8 = 1 << 2;
|
||||||
|
const HOLLOW: u8 = 1 << 3;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct CellData {
|
pub struct CellData {
|
||||||
pub col: Rgb<u8>,
|
pub col: Rgb<u8>,
|
||||||
pub attr: NonZeroU8, // 1 = glowy, 2 = shiny
|
pub attr: NonZeroU8, // 1 = glowy, 2 = shiny, 3 = hollow
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellData {
|
impl CellData {
|
||||||
pub(super) fn new(col: Rgb<u8>, glowy: bool, shiny: bool) -> Self {
|
pub(super) fn new(col: Rgb<u8>, glowy: bool, shiny: bool, hollow: bool) -> Self {
|
||||||
CellData {
|
CellData {
|
||||||
col,
|
col,
|
||||||
attr: NonZeroU8::new(1 + glowy as u8 * GLOWY + shiny as u8 * SHINY).unwrap(),
|
attr: NonZeroU8::new(
|
||||||
|
1 + glowy as u8 * GLOWY + shiny as u8 * SHINY + hollow as u8 * HOLLOW,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CellData {
|
impl Default for CellData {
|
||||||
fn default() -> Self { Self::new(Rgb::broadcast(255), false, false) }
|
fn default() -> Self { Self::new(Rgb::broadcast(255), false, false, false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type representing a single voxel in a figure.
|
/// A type representing a single voxel in a figure.
|
||||||
@ -33,8 +37,8 @@ pub enum Cell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cell {
|
impl Cell {
|
||||||
pub fn new(col: Rgb<u8>, glowy: bool, shiny: bool) -> Self {
|
pub fn new(col: Rgb<u8>, glowy: bool, shiny: bool, hollow: bool) -> Self {
|
||||||
Cell::Filled(CellData::new(col, glowy, shiny))
|
Cell::Filled(CellData::new(col, glowy, shiny, hollow))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_color(&self) -> Option<Rgb<u8>> {
|
pub fn get_color(&self) -> Option<Rgb<u8>> {
|
||||||
@ -57,6 +61,13 @@ impl Cell {
|
|||||||
Cell::Empty => false,
|
Cell::Empty => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_hollow(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Cell::Filled(data) => data.attr.get() & HOLLOW != 0,
|
||||||
|
Cell::Empty => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vox for Cell {
|
impl Vox for Cell {
|
||||||
|
@ -67,6 +67,7 @@ impl Segment {
|
|||||||
color,
|
color,
|
||||||
(13..16).contains(&voxel.i), // Glowy
|
(13..16).contains(&voxel.i), // Glowy
|
||||||
(8..13).contains(&voxel.i), // Shiny
|
(8..13).contains(&voxel.i), // Shiny
|
||||||
|
voxel.i == 16, // Hollow
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -93,8 +94,14 @@ impl Segment {
|
|||||||
/// Transform cell colors
|
/// Transform cell colors
|
||||||
pub fn map_rgb(self, transform: impl Fn(Rgb<u8>) -> Rgb<u8>) -> Self {
|
pub fn map_rgb(self, transform: impl Fn(Rgb<u8>) -> Rgb<u8>) -> Self {
|
||||||
self.map(|cell| {
|
self.map(|cell| {
|
||||||
cell.get_color()
|
cell.get_color().map(|rgb| {
|
||||||
.map(|rgb| Cell::new(transform(rgb), cell.is_glowy(), cell.is_shiny()))
|
Cell::new(
|
||||||
|
transform(rgb),
|
||||||
|
cell.is_glowy(),
|
||||||
|
cell.is_shiny(),
|
||||||
|
cell.is_hollow(),
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +126,9 @@ impl<V: Vox + Copy> DynaUnionizer<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unify(self) -> (Dyna<V, ()>, Vec3<i32>) {
|
pub fn unify(self) -> (Dyna<V, ()>, Vec3<i32>) { self.unify_with(|v| v) }
|
||||||
|
|
||||||
|
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::empty(), ()), Vec3::zero());
|
||||||
}
|
}
|
||||||
@ -140,7 +149,7 @@ impl<V: Vox + Copy> DynaUnionizer<V> {
|
|||||||
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_empty() {
|
||||||
combined.set(origin + offset + pos, *vox).unwrap();
|
combined.set(origin + offset + pos, f(*vox)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +166,7 @@ impl MatSegment {
|
|||||||
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,
|
||||||
MatCell::Mat(mat) => CellData::new(map(*mat), false, false),
|
MatCell::Mat(mat) => CellData::new(map(*mat), false, false, false),
|
||||||
MatCell::Normal(data) => *data,
|
MatCell::Normal(data) => *data,
|
||||||
};
|
};
|
||||||
vol.set(pos, Cell::Filled(data)).unwrap();
|
vol.set(pos, Cell::Filled(data)).unwrap();
|
||||||
@ -221,6 +230,7 @@ impl MatSegment {
|
|||||||
color,
|
color,
|
||||||
(13..16).contains(&index),
|
(13..16).contains(&index),
|
||||||
(8..13).contains(&index),
|
(8..13).contains(&index),
|
||||||
|
index == 16, // Hollow
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,8 @@ use common::{
|
|||||||
},
|
},
|
||||||
theropod::{self, BodyType as TBodyType, Species as TSpecies},
|
theropod::{self, BodyType as TBodyType, Species as TSpecies},
|
||||||
},
|
},
|
||||||
figure::{DynaUnionizer, MatSegment, Material, Segment},
|
figure::{Cell, DynaUnionizer, MatSegment, Material, Segment},
|
||||||
|
vol::Vox,
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -317,8 +318,7 @@ impl HumHeadSpec {
|
|||||||
.maybe_add(beard)
|
.maybe_add(beard)
|
||||||
.maybe_add(accessory)
|
.maybe_add(accessory)
|
||||||
.maybe_add(helmet)
|
.maybe_add(helmet)
|
||||||
.unify();
|
.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),
|
||||||
|
Reference in New Issue
Block a user