resource: split BlockType in Copy and !Copy parts

Preparation for actually adding !Copy fields to BlockType.

Only the Copy parts are added to the processed data, avoiding .clone()
for the most part.
This commit is contained in:
Matthias Schiffer 2023-12-30 01:42:17 +01:00
parent 1874d3082d
commit 8814dcff89
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
6 changed files with 4073 additions and 2043 deletions

View file

@ -1,6 +1,6 @@
//! Functions for computations of block colors //! Functions for computations of block colors
use super::{Biome, BlockType, Color, Colorf}; use super::{Biome, BlockColor, Color, Colorf};
/// Converts an u8 RGB color to a float vector /// Converts an u8 RGB color to a float vector
fn color_vec_unscaled(color: Color) -> Colorf { fn color_vec_unscaled(color: Color) -> Colorf {
@ -91,18 +91,18 @@ const BIRCH_COLOR: Colorf = Colorf::new(0.502, 0.655, 0.333); // == color_vec(Co
/// Color multiplier for spruce leaves /// Color multiplier for spruce leaves
const EVERGREEN_COLOR: Colorf = Colorf::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97])) const EVERGREEN_COLOR: Colorf = Colorf::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97]))
/// Determined if calling [block_color] for a given [BlockType] needs biome information /// Determined if calling [block_color] for a given [BlockColor] needs biome information
pub fn needs_biome(block: BlockType) -> bool { pub fn needs_biome(block: BlockColor) -> bool {
use super::BlockFlag::*; use super::BlockFlag::*;
block.is(Grass) || block.is(Foliage) || block.is(Water) block.is(Grass) || block.is(Foliage) || block.is(Water)
} }
/// Determined the block color to display for a given [BlockType] /// Determined the block color to display for a given [BlockColor]
/// ///
/// [needs_biome] must be used to determine whether passing a [Biome] is necessary. /// [needs_biome] must be used to determine whether passing a [Biome] is necessary.
/// Will panic if a [Biome] is necessary, but none is passed. /// Will panic if a [Biome] is necessary, but none is passed.
pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> Colorf { pub fn block_color(block: BlockColor, biome: Option<&Biome>, depth: f32) -> Colorf {
use super::BlockFlag::*; use super::BlockFlag::*;
let get_biome = || biome.expect("needs biome to determine block color"); let get_biome = || biome.expect("needs biome to determine block color");

File diff suppressed because it is too large Load diff

View file

@ -42,21 +42,28 @@ pub type Colorf = glam::Vec3;
/// A block type specification /// A block type specification
#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct BlockType { pub struct BlockColor {
/// Bit set of [BlockFlag]s describing special properties of the block type /// Bit set of [BlockFlag]s describing special properties of the block type
pub flags: BitFlags<BlockFlag>, pub flags: BitFlags<BlockFlag>,
/// Base color of the block type /// Base color of the block type
pub color: Color, pub color: Color,
} }
impl BlockType { impl BlockColor {
/// Checks whether a block type has a given [BlockFlag] set /// Checks whether a block color has a given [BlockFlag] set
#[inline] #[inline]
pub fn is(&self, flag: BlockFlag) -> bool { pub fn is(&self, flag: BlockFlag) -> bool {
self.flags.contains(flag) self.flags.contains(flag)
} }
} }
/// A block type specification
#[derive(Debug, Clone)]
pub struct BlockType {
/// Determines the rendered color of the block type
pub block_color: BlockColor,
}
/// Used to look up standard Minecraft block types /// Used to look up standard Minecraft block types
#[derive(Debug)] #[derive(Debug)]
pub struct BlockTypes { pub struct BlockTypes {
@ -70,10 +77,15 @@ impl Default for BlockTypes {
fn default() -> Self { fn default() -> Self {
let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES
.iter() .iter()
.map(|(k, v)| (String::from(*k), *v)) .map(|(k, v)| (String::from(*k), v.clone()))
.collect(); .collect();
let legacy_block_types = Box::new(legacy_block_types::LEGACY_BLOCK_TYPES.map(|inner| { let legacy_block_types = Box::new(legacy_block_types::LEGACY_BLOCK_TYPES.map(|inner| {
inner.map(|id| *block_type_map.get(id).expect("Unknown legacy block type")) inner.map(|id| {
block_type_map
.get(id)
.expect("Unknown legacy block type")
.clone()
})
})); }));
BlockTypes { BlockTypes {
@ -86,15 +98,15 @@ impl Default for BlockTypes {
impl BlockTypes { impl BlockTypes {
/// Resolves a Minecraft 1.13+ string block type ID /// Resolves a Minecraft 1.13+ string block type ID
#[inline] #[inline]
pub fn get(&self, id: &str) -> Option<BlockType> { pub fn get(&self, id: &str) -> Option<&BlockType> {
let suffix = id.strip_prefix("minecraft:")?; let suffix = id.strip_prefix("minecraft:")?;
self.block_type_map.get(suffix).copied() self.block_type_map.get(suffix)
} }
/// Resolves a Minecraft pre-1.13 numeric block type ID /// Resolves a Minecraft pre-1.13 numeric block type ID
#[inline] #[inline]
pub fn get_legacy(&self, id: u8, data: u8) -> Option<BlockType> { pub fn get_legacy(&self, id: u8, data: u8) -> Option<&BlockType> {
Some(self.legacy_block_types[id as usize][data as usize]) Some(&self.legacy_block_types[id as usize][data as usize])
} }
} }

View file

@ -36,11 +36,13 @@ with open(sys.argv[2], 'w') as f:
flags.append('Water') flags.append('Water')
flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})'
print('\t("%s", BlockType { flags: %s, color: Color([%u, %u, %u]) }),' % ( print('\t("%s", BlockType { ' % name, file=f)
name, print('\t\tblock_color: BlockColor { flags: %s, color: Color([%u, %u, %u]) },' % (
flags, flags,
info['color']['r'], info['color']['r'],
info['color']['g'], info['color']['g'],
info['color']['b'], info['color']['b'],
), file=f) ), file=f)
print('}),', file=f)
print('];', file=f) print('];', file=f)

View file

@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use super::chunk::{Chunk, SectionIterItem}; use super::chunk::{Chunk, SectionIterItem};
use crate::{ use crate::{
resource::{Biome, BlockFlag, BlockType}, resource::{Biome, BlockColor, BlockFlag},
types::*, types::*,
}; };
@ -31,8 +31,8 @@ impl BlockHeight {
} }
} }
/// Array optionally storing a [BlockType] for each coordinate of a chunk /// Array optionally storing a [BlockColor] for each coordinate of a chunk
pub type BlockArray = LayerBlockArray<Option<BlockType>>; pub type BlockArray = LayerBlockArray<Option<BlockColor>>;
/// Array optionally storing a biome index for each coordinate of a chunk /// Array optionally storing a biome index for each coordinate of a chunk
/// ///
@ -49,7 +49,7 @@ pub type DepthArray = LayerBlockArray<Option<BlockHeight>>;
/// References to LayerData entries for a single coordinate pair /// References to LayerData entries for a single coordinate pair
struct LayerEntry<'a> { struct LayerEntry<'a> {
/// The block type of the referenced entry /// The block type of the referenced entry
block: &'a mut Option<BlockType>, block: &'a mut Option<BlockColor>,
/// The biome type of the referenced entry /// The biome type of the referenced entry
biome: &'a mut Option<NonZeroU16>, biome: &'a mut Option<NonZeroU16>,
/// The block light of the referenced entry /// The block light of the referenced entry
@ -86,7 +86,7 @@ impl<'a> LayerEntry<'a> {
let Some(block_type) = section let Some(block_type) = section
.section .section
.block_at(coords)? .block_at(coords)?
.filter(|block_type| block_type.is(BlockFlag::Opaque)) .filter(|block_type| block_type.block_color.is(BlockFlag::Opaque))
else { else {
if self.is_empty() { if self.is_empty() {
*self.block_light = section.block_light.block_light_at(coords); *self.block_light = section.block_light.block_light_at(coords);
@ -96,7 +96,7 @@ impl<'a> LayerEntry<'a> {
}; };
if self.is_empty() { if self.is_empty() {
*self.block = Some(block_type); *self.block = Some(block_type.block_color);
if let Some(biome) = section.biomes.biome_at(section.y, coords)? { if let Some(biome) = section.biomes.biome_at(section.y, coords)? {
let (biome_index, _) = biome_list.insert_full(*biome); let (biome_index, _) = biome_list.insert_full(*biome);
*self.biome = NonZeroU16::new( *self.biome = NonZeroU16::new(
@ -107,7 +107,7 @@ impl<'a> LayerEntry<'a> {
} }
} }
if block_type.is(BlockFlag::Water) { if block_type.block_color.is(BlockFlag::Water) {
return Ok(false); return Ok(false);
} }

View file

@ -44,7 +44,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option<u8> {
/// Trait for common functions of [SectionV1_13] and [SectionV0] /// Trait for common functions of [SectionV1_13] and [SectionV0]
pub trait Section: Debug { pub trait Section: Debug {
/// Returns the [BlockType] at a coordinate tuple inside the section /// Returns the [BlockType] at a coordinate tuple inside the section
fn block_at(&self, coords: SectionBlockCoords) -> Result<Option<BlockType>>; fn block_at(&self, coords: SectionBlockCoords) -> Result<Option<&BlockType>>;
} }
/// Minecraft v1.13+ section block data /// Minecraft v1.13+ section block data
@ -53,7 +53,7 @@ pub struct SectionV1_13<'a> {
/// Packed block type data /// Packed block type data
block_states: Option<&'a [i64]>, block_states: Option<&'a [i64]>,
/// List of block types indexed by entries encoded in *block_states* /// List of block types indexed by entries encoded in *block_states*
palette: Vec<Option<BlockType>>, palette: Vec<Option<&'a BlockType>>,
/// Number of bits per block in *block_states* /// Number of bits per block in *block_states*
bits: u8, bits: u8,
/// Set to true if packed block entries in *block_states* are aligned to i64 /// Set to true if packed block entries in *block_states* are aligned to i64
@ -146,7 +146,7 @@ impl<'a> SectionV1_13<'a> {
} }
impl<'a> Section for SectionV1_13<'a> { impl<'a> Section for SectionV1_13<'a> {
fn block_at(&self, coords: SectionBlockCoords) -> Result<Option<BlockType>> { fn block_at(&self, coords: SectionBlockCoords) -> Result<Option<&BlockType>> {
let index = self.palette_index_at(coords); let index = self.palette_index_at(coords);
Ok(*self Ok(*self
.palette .palette
@ -189,7 +189,7 @@ impl<'a> SectionV0<'a> {
} }
impl<'a> Section for SectionV0<'a> { impl<'a> Section for SectionV0<'a> {
fn block_at(&self, coords: SectionBlockCoords) -> Result<Option<BlockType>> { fn block_at(&self, coords: SectionBlockCoords) -> Result<Option<&BlockType>> {
let offset = coords.offset(); let offset = coords.offset();
let block = self.blocks[offset] as u8; let block = self.blocks[offset] as u8;