mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
voxygen: Make the Terrain
struct generic
This commit is contained in:
@ -18,7 +18,11 @@ use crate::{
|
|||||||
window::Event,
|
window::Event,
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{comp, terrain::BlockKind, vol::ReadVol};
|
use common::{
|
||||||
|
comp,
|
||||||
|
terrain::{BlockKind, TerrainChunk},
|
||||||
|
vol::ReadVol,
|
||||||
|
};
|
||||||
use specs::Join;
|
use specs::Join;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -45,7 +49,7 @@ pub struct Scene {
|
|||||||
|
|
||||||
skybox: Skybox,
|
skybox: Skybox,
|
||||||
postprocess: PostProcess,
|
postprocess: PostProcess,
|
||||||
terrain: Terrain,
|
terrain: Terrain<TerrainChunk>,
|
||||||
loaded_distance: f32,
|
loaded_distance: f32,
|
||||||
|
|
||||||
figure_mgr: FigureMgr,
|
figure_mgr: FigureMgr,
|
||||||
|
@ -10,15 +10,15 @@ use client::Client;
|
|||||||
use common::{
|
use common::{
|
||||||
assets,
|
assets,
|
||||||
figure::Segment,
|
figure::Segment,
|
||||||
terrain::{Block, BlockKind, TerrainChunkSize, TerrainGrid},
|
terrain::{Block, BlockKind},
|
||||||
vol::{ReadVol, RectVolSize, SampleVol, Vox},
|
vol::{BaseVol, ReadVol, RectRasterableVol, SampleVol, Vox},
|
||||||
volumes::vol_grid_2d::VolGrid2dError,
|
volumes::vol_grid_2d::{VolGrid2d, VolGrid2dError},
|
||||||
};
|
};
|
||||||
use crossbeam::channel;
|
use crossbeam::channel;
|
||||||
use dot_vox::DotVoxData;
|
use dot_vox::DotVoxData;
|
||||||
use frustum_query::frustum::Frustum;
|
use frustum_query::frustum::Frustum;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use std::{f32, i32, ops::Mul, time::Duration};
|
use std::{f32, fmt::Debug, i32, marker::PhantomData, ops::Mul, time::Duration};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
struct TerrainChunk {
|
struct TerrainChunk {
|
||||||
@ -135,11 +135,11 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Function executed by worker threads dedicated to chunk meshing.
|
/// Function executed by worker threads dedicated to chunk meshing.
|
||||||
fn mesh_worker(
|
fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||||
pos: Vec2<i32>,
|
pos: Vec2<i32>,
|
||||||
z_bounds: (f32, f32),
|
z_bounds: (f32, f32),
|
||||||
started_tick: u64,
|
started_tick: u64,
|
||||||
volume: <TerrainGrid as SampleVol<Aabr<i32>>>::Sample,
|
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
||||||
range: Aabb<i32>,
|
range: Aabb<i32>,
|
||||||
) -> MeshWorkerResponse {
|
) -> MeshWorkerResponse {
|
||||||
let (opaque_mesh, fluid_mesh) = volume.generate_mesh(range);
|
let (opaque_mesh, fluid_mesh) = volume.generate_mesh(range);
|
||||||
@ -152,12 +152,11 @@ fn mesh_worker(
|
|||||||
sprite_instances: {
|
sprite_instances: {
|
||||||
let mut instances = HashMap::new();
|
let mut instances = HashMap::new();
|
||||||
|
|
||||||
for x in 0..TerrainChunkSize::RECT_SIZE.x as i32 {
|
for x in 0..V::RECT_SIZE.x as i32 {
|
||||||
for y in 0..TerrainChunkSize::RECT_SIZE.y as i32 {
|
for y in 0..V::RECT_SIZE.y as i32 {
|
||||||
for z in z_bounds.0 as i32..z_bounds.1 as i32 + 1 {
|
for z in z_bounds.0 as i32..z_bounds.1 as i32 + 1 {
|
||||||
let wpos = Vec3::from(
|
let wpos = Vec3::from(pos * V::RECT_SIZE.map(|e: u32| e as i32))
|
||||||
pos * Vec2::from(TerrainChunkSize::RECT_SIZE).map(|e: u32| e as i32),
|
+ Vec3::new(x, y, z);
|
||||||
) + Vec3::new(x, y, z);
|
|
||||||
|
|
||||||
let kind = volume.get(wpos).unwrap_or(&Block::empty()).kind();
|
let kind = volume.get(wpos).unwrap_or(&Block::empty()).kind();
|
||||||
|
|
||||||
@ -189,7 +188,7 @@ fn mesh_worker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Terrain {
|
pub struct Terrain<V: RectRasterableVol> {
|
||||||
chunks: HashMap<Vec2<i32>, TerrainChunk>,
|
chunks: HashMap<Vec2<i32>, TerrainChunk>,
|
||||||
|
|
||||||
// The mpsc sender and receiver used for talking to meshing worker threads.
|
// The mpsc sender and receiver used for talking to meshing worker threads.
|
||||||
@ -200,9 +199,11 @@ pub struct Terrain {
|
|||||||
|
|
||||||
// GPU data
|
// GPU data
|
||||||
sprite_models: HashMap<(BlockKind, usize), Model<SpritePipeline>>,
|
sprite_models: HashMap<(BlockKind, usize), Model<SpritePipeline>>,
|
||||||
|
|
||||||
|
phantom: PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Terrain {
|
impl<V: RectRasterableVol> Terrain<V> {
|
||||||
pub fn new(renderer: &mut Renderer) -> Self {
|
pub fn new(renderer: &mut Renderer) -> Self {
|
||||||
// Create a new mpsc (Multiple Produced, Single Consumer) pair for communicating with
|
// Create a new mpsc (Multiple Produced, Single Consumer) pair for communicating with
|
||||||
// worker threads that are meshing chunks.
|
// worker threads that are meshing chunks.
|
||||||
@ -597,6 +598,7 @@ impl Terrain {
|
|||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,10 +730,10 @@ impl Terrain {
|
|||||||
let aabr = Aabr {
|
let aabr = Aabr {
|
||||||
min: todo
|
min: todo
|
||||||
.pos
|
.pos
|
||||||
.map2(TerrainGrid::chunk_size(), |e, sz| e * sz as i32 - 1),
|
.map2(VolGrid2d::<V>::chunk_size(), |e, sz| e * sz as i32 - 1),
|
||||||
max: todo
|
max: todo.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||||
.pos
|
(e + 1) * sz as i32 + 1
|
||||||
.map2(TerrainGrid::chunk_size(), |e, sz| (e + 1) * sz as i32 + 1),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Copy out the chunk data we need to perform the meshing. We do this by taking a
|
// Copy out the chunk data we need to perform the meshing. We do this by taking a
|
||||||
@ -807,7 +809,7 @@ impl Terrain {
|
|||||||
locals: renderer
|
locals: renderer
|
||||||
.create_consts(&[TerrainLocals {
|
.create_consts(&[TerrainLocals {
|
||||||
model_offs: Vec3::from(
|
model_offs: Vec3::from(
|
||||||
response.pos.map2(TerrainGrid::chunk_size(), |e, sz| {
|
response.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||||
e as f32 * sz as f32
|
e as f32 * sz as f32
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -836,7 +838,7 @@ impl Terrain {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Update chunk visibility
|
// Update chunk visibility
|
||||||
let chunk_sz = TerrainChunkSize::RECT_SIZE.x as f32;
|
let chunk_sz = V::RECT_SIZE.x as f32;
|
||||||
for (pos, chunk) in &mut self.chunks {
|
for (pos, chunk) in &mut self.chunks {
|
||||||
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
||||||
|
|
||||||
@ -886,10 +888,8 @@ impl Terrain {
|
|||||||
if chunk.visible {
|
if chunk.visible {
|
||||||
const SPRITE_RENDER_DISTANCE: f32 = 128.0;
|
const SPRITE_RENDER_DISTANCE: f32 = 128.0;
|
||||||
|
|
||||||
let chunk_center = pos
|
let chunk_center =
|
||||||
.map2(Vec2::from(TerrainChunkSize::RECT_SIZE), |e, sz: u32| {
|
pos.map2(V::RECT_SIZE, |e, sz: u32| (e as f32 + 0.5) * sz as f32);
|
||||||
(e as f32 + 0.5) * sz as f32
|
|
||||||
});
|
|
||||||
if Vec2::from(focus_pos).distance_squared(chunk_center)
|
if Vec2::from(focus_pos).distance_squared(chunk_center)
|
||||||
< SPRITE_RENDER_DISTANCE * SPRITE_RENDER_DISTANCE
|
< SPRITE_RENDER_DISTANCE * SPRITE_RENDER_DISTANCE
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user