diff --git a/common/src/terrain/structure.rs b/common/src/terrain/structure.rs index d67c275ff9..b94c1bdf00 100644 --- a/common/src/terrain/structure.rs +++ b/common/src/terrain/structure.rs @@ -7,14 +7,35 @@ use crate::{ use dot_vox::DotVoxData; use vek::*; +#[derive(Copy, Clone)] +pub enum StructureBlock { + TemperateLeaves, + PineLeaves, + PalmLeaves, + Block(Block), +} + +impl Vox for StructureBlock { + fn empty() -> Self { + StructureBlock::Block(Block::empty()) + } + + fn is_empty(&self) -> bool { + match self { + StructureBlock::Block(block) => block.is_empty(), + _ => false, + } + } +} + #[derive(Debug)] pub enum StructureError {} #[derive(Clone)] pub struct Structure { center: Vec3, - vol: Dyna, - empty: Block, + vol: Dyna, + empty: StructureBlock, } impl Structure { @@ -25,13 +46,13 @@ impl Structure { } impl BaseVol for Structure { - type Vox = Block; + type Vox = StructureBlock; type Err = StructureError; } impl ReadVol for Structure { #[inline(always)] - fn get(&self, pos: Vec3) -> Result<&Block, StructureError> { + fn get(&self, pos: Vec3) -> Result<&Self::Vox, StructureError> { match self.vol.get(pos + self.center) { Ok(block) => Ok(block), Err(DynaErr::OutOfBounds) => Ok(&self.empty), @@ -52,29 +73,37 @@ impl Asset for Structure { let mut vol = Dyna::filled( Vec3::new(model.size.x, model.size.y, model.size.z), - Block::empty(), + StructureBlock::empty(), (), ); for voxel in &model.voxels { - if let Some(&color) = palette.get(voxel.i as usize) { - let _ = vol.set( - Vec3::new(voxel.x, voxel.y, voxel.z).map(|e| e as i32), - Block::new(1, color), - ); - } + let block = match voxel.i { + 0 => StructureBlock::TemperateLeaves, + 1 => StructureBlock::PineLeaves, + 2 => StructureBlock::PalmLeaves, + index => { + let color = palette.get(index as usize).copied().unwrap_or(Rgb::broadcast(0)); + StructureBlock::Block(Block::new(1, color)) + } + }; + + let _ = vol.set( + Vec3::new(voxel.x, voxel.y, voxel.z).map(|e| e as i32), + block + ); } Ok(Structure { center: Vec3::zero(), vol, - empty: Block::empty(), + empty: StructureBlock::empty(), }) } else { Ok(Self { center: Vec3::zero(), - vol: Dyna::filled(Vec3::zero(), Block::empty(), ()), - empty: Block::empty(), + vol: Dyna::filled(Vec3::zero(), StructureBlock::empty(), ()), + empty: StructureBlock::empty(), }) } } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 03c311a4e2..fc89775334 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -4,7 +4,7 @@ use std::ops::{Add, Div, Mul, Neg, Sub}; use noise::NoiseFn; use vek::*; use common::{ - terrain::Block, + terrain::{Block, structure::StructureBlock}, vol::{Vox, ReadVol}, }; use crate::{ @@ -53,6 +53,7 @@ impl<'a> Sampler for BlockGen<'a> { cave_alt, rock, cliff, + temp, } = self.sample_column(Vec2::from(wpos))?; let wposf = wpos.map(|e| e as f64); @@ -161,6 +162,28 @@ impl<'a> Sampler for BlockGen<'a> { } }); + fn block_from_structure(sblock: StructureBlock, structure_pos: Vec2, sample: &ColumnSample) -> Block { + let temp_lerp = sample.temp * 4.0; + match sblock { + StructureBlock::TemperateLeaves => Block::new(1, Lerp::lerp( + Rgb::new(0.0, 150.0, 50.0), + Rgb::new(200.0, 255.0, 0.0), + temp_lerp, + ).map(|e| e as u8)), + StructureBlock::PineLeaves => Block::new(1, Lerp::lerp( + Rgb::new(0.0, 100.0, 90.0), + Rgb::new(50.0, 150.0, 50.0), + temp_lerp, + ).map(|e| e as u8)), + StructureBlock::PalmLeaves => Block::new(1, Lerp::lerp( + Rgb::new(80.0, 150.0, 0.0), + Rgb::new(180.0, 255.0, 0.0), + temp_lerp, + ).map(|e| e as u8)), + StructureBlock::Block(block) => block, + } + } + let block = match block { Some(block) => block, None => (&close_trees) @@ -179,7 +202,7 @@ impl<'a> Sampler for BlockGen<'a> { block.or(trees[*tree_seed as usize % trees.len()] .get((rpos * 128) / 128) // Scaling - .map(|b| b.clone()) + .map(|b| block_from_structure(*b, *tree_pos, &tree_sample)) .unwrap_or(Block::empty())) } _ => block, diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index f4d03294c9..f11548a393 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -144,6 +144,7 @@ impl<'a> Sampler for ColumnGen<'a> { cave_alt, rock, cliff: cliffiness, + temp, }) } } @@ -160,4 +161,5 @@ pub struct ColumnSample { pub cave_alt: f32, pub rock: f32, pub cliff: f32, + pub temp: f32, }