From baf42f2203b8ae22105ecad44f181721dd44b9d1 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 20 Aug 2019 00:31:11 +0100 Subject: [PATCH] Added multiple sprite block kind support --- assets/voxygen/voxel/sprite/flowers.vox | Bin 0 -> 49973 bytes common/src/terrain/block.rs | 10 ++- voxygen/src/scene/terrain.rs | 100 ++++++++++++++++-------- world/src/block/mod.rs | 11 ++- 4 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 assets/voxygen/voxel/sprite/flowers.vox diff --git a/assets/voxygen/voxel/sprite/flowers.vox b/assets/voxygen/voxel/sprite/flowers.vox new file mode 100644 index 0000000000000000000000000000000000000000..e2090b2260dfc3f6f0b873f56233fa99d8f1068a GIT binary patch literal 49973 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 literal 0 HcmV?d00001 diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index 14894b0e91..c7276f952c 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -3,7 +3,7 @@ use serde_derive::{Deserialize, Serialize}; use std::ops::Deref; use vek::*; -#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] #[repr(u8)] pub enum BlockKind { Air, @@ -11,6 +11,8 @@ pub enum BlockKind { Dense, Water, Wheat, + LongGrass, + Flowers, } impl BlockKind { @@ -18,6 +20,8 @@ impl BlockKind { match self { BlockKind::Air => true, BlockKind::Wheat => true, + BlockKind::LongGrass => true, + BlockKind::Flowers => true, _ => false, } } @@ -34,6 +38,8 @@ impl BlockKind { BlockKind::Air => false, BlockKind::Water => false, BlockKind::Wheat => false, + BlockKind::LongGrass => false, + BlockKind::Flowers => false, _ => true, } } @@ -43,6 +49,8 @@ impl BlockKind { BlockKind::Air => false, BlockKind::Water => false, BlockKind::Wheat => false, + BlockKind::LongGrass => false, + BlockKind::Flowers => false, _ => true, } } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 89c5422197..8a3b7bce32 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -24,7 +24,7 @@ struct TerrainChunk { // GPU data opaque_model: Model, fluid_model: Model, - sprite_instances: Instances, + sprite_instances: HashMap>, locals: Consts, visible: bool, @@ -43,7 +43,7 @@ struct MeshWorkerResponse { z_bounds: (f32, f32), opaque_mesh: Mesh, fluid_mesh: Mesh, - sprite_instances: Vec, + sprite_instances: HashMap>, started_tick: u64, } @@ -63,7 +63,7 @@ fn mesh_worker( fluid_mesh, // Extract sprite locations from volume sprite_instances: { - let mut instances = Vec::new(); + let mut instances = HashMap::new(); for x in 0..TerrainChunkSize::SIZE.x as i32 { for y in 0..TerrainChunkSize::SIZE.y as i32 { @@ -72,11 +72,16 @@ fn mesh_worker( pos * Vec2::from(TerrainChunkSize::SIZE).map(|e: u32| e as i32), ) + Vec3::new(x, y, z); - match volume.get(wpos).unwrap_or(&Block::empty()).kind() { - BlockKind::Wheat => instances.push(SpriteInstance::new( - wpos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0), - Rgb::broadcast(1.0), - )), + let kind = volume.get(wpos).unwrap_or(&Block::empty()).kind(); + match kind { + BlockKind::Wheat | BlockKind::LongGrass | BlockKind::Flowers => { + instances.entry(kind).or_insert_with(|| Vec::new()).push( + SpriteInstance::new( + wpos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0), + Rgb::broadcast(1.0), + ), + ) + } _ => {} } } @@ -99,7 +104,7 @@ pub struct Terrain { mesh_todo: HashMap, ChunkMeshState>, // GPU data - wheat_model: Model, + sprite_models: HashMap>, } impl Terrain { @@ -108,20 +113,36 @@ impl Terrain { // worker threads that are meshing chunks. let (send, recv) = channel::unbounded(); - let wheat_mesh = Meshable::::generate_mesh( - &Segment::from( - assets::load_expect::("voxygen.voxel.sprite.grass-0").as_ref(), - ), - Vec3::new(6.0, 6.0, 0.0), - ) - .0; + let mut make_model = |s| { + renderer + .create_model( + &Meshable::::generate_mesh( + &Segment::from(assets::load_expect::(s).as_ref()), + Vec3::new(6.0, 6.0, 0.0), + ) + .0, + ) + .unwrap() + }; Self { chunks: HashMap::default(), mesh_send_tmp: send, mesh_recv: recv, mesh_todo: HashMap::default(), - wheat_model: renderer.create_model(&wheat_mesh).unwrap(), + sprite_models: vec![ + (BlockKind::Wheat, make_model("voxygen.voxel.sprite.wheat")), + ( + BlockKind::LongGrass, + make_model("voxygen.voxel.sprite.grass-0"), + ), + ( + BlockKind::Flowers, + make_model("voxygen.voxel.sprite.flowers"), + ), + ] + .into_iter() + .collect(), } } @@ -317,9 +338,18 @@ impl Terrain { fluid_model: renderer .create_model(&response.fluid_mesh) .expect("Failed to upload chunk mesh to the GPU!"), - sprite_instances: renderer - .create_instances(&response.sprite_instances) - .expect("Failed to upload chunk sprite instances to the GPU!"), + sprite_instances: response + .sprite_instances + .into_iter() + .map(|(kind, instances)| { + ( + kind, + renderer.create_instances(&instances).expect( + "Failed to upload chunk sprite instances to the GPU!", + ), + ) + }) + .collect(), locals: renderer .create_consts(&[TerrainLocals { model_offs: Vec3::from( @@ -391,9 +421,16 @@ impl Terrain { focus_pos: Vec3, ) { // Opaque - for (pos, chunk) in &self.chunks { + for (_, chunk) in &self.chunks { if chunk.visible { renderer.render_terrain_chunk(&chunk.opaque_model, globals, &chunk.locals, lights); + } + } + + // Translucent + for (pos, chunk) in &self.chunks { + if chunk.visible { + renderer.render_fluid_chunk(&chunk.fluid_model, globals, &chunk.locals, lights); const SPRITE_RENDER_DISTANCE: f32 = 128.0; @@ -401,21 +438,16 @@ impl Terrain { (e as f32 + 0.5) * sz as f32 }); if Vec2::from(focus_pos).distance(chunk_center) < SPRITE_RENDER_DISTANCE { - renderer.render_sprites( - &self.wheat_model, - globals, - &chunk.sprite_instances, - lights, - ); + for (kind, instances) in &chunk.sprite_instances { + renderer.render_sprites( + &self.sprite_models[&kind], + globals, + &instances, + lights, + ); + } } } } - - // Translucent - for (_pos, chunk) in &self.chunks { - if chunk.visible { - renderer.render_fluid_chunk(&chunk.fluid_model, globals, &chunk.locals, lights); - } - } } } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 776a765c7a..d627db52c3 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -258,7 +258,16 @@ impl<'a> BlockGen<'a> { && (wposf.z as f32 > water_height + 3.0) && (chaos * 4096.0).fract() < 0.025 { - Some(Block::new(BlockKind::Wheat, Rgb::broadcast(0))) + Some(Block::new( + if (height * 121.0).fract() < 0.25 { + BlockKind::Wheat + } else if (height * 121.0).fract() < 0.5 { + BlockKind::Flowers + } else { + BlockKind::LongGrass + }, + Rgb::broadcast(0), + )) } else { None };