mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added multiple sprite block kind support
This commit is contained in:
parent
7960e6ea6d
commit
5f09ab3a4f
BIN
assets/voxygen/voxel/sprite/flowers.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/flowers.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ struct TerrainChunk {
|
||||
// GPU data
|
||||
opaque_model: Model<TerrainPipeline>,
|
||||
fluid_model: Model<FluidPipeline>,
|
||||
sprite_instances: Instances<SpriteInstance>,
|
||||
sprite_instances: HashMap<BlockKind, Instances<SpriteInstance>>,
|
||||
locals: Consts<TerrainLocals>,
|
||||
|
||||
visible: bool,
|
||||
@ -43,7 +43,7 @@ struct MeshWorkerResponse {
|
||||
z_bounds: (f32, f32),
|
||||
opaque_mesh: Mesh<TerrainPipeline>,
|
||||
fluid_mesh: Mesh<FluidPipeline>,
|
||||
sprite_instances: Vec<SpriteInstance>,
|
||||
sprite_instances: HashMap<BlockKind, Vec<SpriteInstance>>,
|
||||
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<Vec2<i32>, ChunkMeshState>,
|
||||
|
||||
// GPU data
|
||||
wheat_model: Model<SpritePipeline>,
|
||||
sprite_models: HashMap<BlockKind, Model<SpritePipeline>>,
|
||||
}
|
||||
|
||||
impl Terrain {
|
||||
@ -108,20 +113,36 @@ impl Terrain {
|
||||
// worker threads that are meshing chunks.
|
||||
let (send, recv) = channel::unbounded();
|
||||
|
||||
let wheat_mesh = Meshable::<SpritePipeline, SpritePipeline>::generate_mesh(
|
||||
&Segment::from(
|
||||
assets::load_expect::<DotVoxData>("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::<SpritePipeline, SpritePipeline>::generate_mesh(
|
||||
&Segment::from(assets::load_expect::<DotVoxData>(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<f32>,
|
||||
) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user