mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Began using Grid<T> for LoD data
This commit is contained in:
parent
20b45a1202
commit
e5ebbd31fa
@ -24,6 +24,7 @@ use common::{
|
|||||||
InventoryManip, InventoryUpdateEvent,
|
InventoryManip, InventoryUpdateEvent,
|
||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent},
|
event::{EventBus, LocalEvent},
|
||||||
|
grid::Grid,
|
||||||
msg::{
|
msg::{
|
||||||
validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral, ClientMsg,
|
validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral, ClientMsg,
|
||||||
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
||||||
@ -80,15 +81,15 @@ pub struct Client {
|
|||||||
/// Just the "base" layer for LOD; currently includes colors and nothing
|
/// Just the "base" layer for LOD; currently includes colors and nothing
|
||||||
/// else. In the future we'll add more layers, like shadows, rivers, and
|
/// else. In the future we'll add more layers, like shadows, rivers, and
|
||||||
/// probably foliage, cities, roads, and other structures.
|
/// probably foliage, cities, roads, and other structures.
|
||||||
pub lod_base: Vec<u32>,
|
pub lod_base: Grid<u32>,
|
||||||
/// The "height" layer for LOD; currently includes only land altitudes, but
|
/// The "height" layer for LOD; currently includes only land altitudes, but
|
||||||
/// in the future should also water depth, and probably other
|
/// in the future should also water depth, and probably other
|
||||||
/// information as well.
|
/// information as well.
|
||||||
pub lod_alt: Vec<u32>,
|
pub lod_alt: Grid<u32>,
|
||||||
/// The "shadow" layer for LOD. Includes east and west horizon angles and
|
/// The "shadow" layer for LOD. Includes east and west horizon angles and
|
||||||
/// an approximate max occluder height, which we use to try to
|
/// an approximate max occluder height, which we use to try to
|
||||||
/// approximate soft and volumetric shadows.
|
/// approximate soft and volumetric shadows.
|
||||||
pub lod_horizon: Vec<u32>,
|
pub lod_horizon: Grid<u32>,
|
||||||
/// A fully rendered map image for use with the map and minimap; note that
|
/// A fully rendered map image for use with the map and minimap; note that
|
||||||
/// this can be constructed dynamically by combining the layers of world
|
/// this can be constructed dynamically by combining the layers of world
|
||||||
/// map data (e.g. with shadow map data or river data), but at present
|
/// map data (e.g. with shadow map data or river data), but at present
|
||||||
@ -229,11 +230,10 @@ impl Client {
|
|||||||
let sea_level = world_map.sea_level;
|
let sea_level = world_map.sea_level;
|
||||||
let rgba = world_map.rgba;
|
let rgba = world_map.rgba;
|
||||||
let alt = world_map.alt;
|
let alt = world_map.alt;
|
||||||
let expected_size = (u32::from(map_size.x) * u32::from(map_size.y)) as usize;
|
if rgba.size() != map_size.map(|e| e as i32) {
|
||||||
if rgba.len() != expected_size {
|
|
||||||
return Err(Error::Other("Server sent a bad world map image".into()));
|
return Err(Error::Other("Server sent a bad world map image".into()));
|
||||||
}
|
}
|
||||||
if alt.len() != expected_size {
|
if rgba.size() != map_size.map(|e| e as i32) {
|
||||||
return Err(Error::Other("Server sent a bad altitude map.".into()));
|
return Err(Error::Other("Server sent a bad altitude map.".into()));
|
||||||
}
|
}
|
||||||
let [west, east] = world_map.horizons;
|
let [west, east] = world_map.horizons;
|
||||||
@ -257,7 +257,7 @@ impl Client {
|
|||||||
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
||||||
|
|
||||||
// Redraw map (with shadows this time).
|
// Redraw map (with shadows this time).
|
||||||
let mut world_map_rgba = vec![0u32; rgba.len()];
|
let mut world_map_rgba = vec![0u32; rgba.size().product() as usize];
|
||||||
let mut map_config = common::terrain::map::MapConfig::orthographic(
|
let mut map_config = common::terrain::map::MapConfig::orthographic(
|
||||||
map_size_lg,
|
map_size_lg,
|
||||||
core::ops::RangeInclusive::new(0.0, max_height),
|
core::ops::RangeInclusive::new(0.0, max_height),
|
||||||
@ -274,14 +274,14 @@ impl Client {
|
|||||||
|pos| {
|
|pos| {
|
||||||
let (rgba, alt, downhill_wpos) = if bounds_check(pos) {
|
let (rgba, alt, downhill_wpos) = if bounds_check(pos) {
|
||||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||||
let [r, g, b, a] = rgba[posi].to_le_bytes();
|
let [r, g, b, a] = rgba[pos].to_le_bytes();
|
||||||
let alti = alt[posi];
|
let alti = alt[pos];
|
||||||
// Compute downhill.
|
// Compute downhill.
|
||||||
let downhill = {
|
let downhill = {
|
||||||
let mut best = -1;
|
let mut best = -1;
|
||||||
let mut besth = alti;
|
let mut besth = alti;
|
||||||
for nposi in neighbors(map_size_lg, posi) {
|
for nposi in neighbors(map_size_lg, posi) {
|
||||||
let nbh = alt[nposi];
|
let nbh = alt.raw()[nposi];
|
||||||
if nbh < besth {
|
if nbh < besth {
|
||||||
besth = nbh;
|
besth = nbh;
|
||||||
best = nposi as isize;
|
best = nposi as isize;
|
||||||
@ -317,8 +317,7 @@ impl Client {
|
|||||||
|wpos| {
|
|wpos| {
|
||||||
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||||
rescale_height(if bounds_check(pos) {
|
rescale_height(if bounds_check(pos) {
|
||||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
scale_height_big(alt[pos])
|
||||||
scale_height_big(alt[posi])
|
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
})
|
})
|
||||||
@ -361,7 +360,7 @@ impl Client {
|
|||||||
entity,
|
entity,
|
||||||
lod_base,
|
lod_base,
|
||||||
lod_alt,
|
lod_alt,
|
||||||
lod_horizon,
|
Grid::from_raw(map_size.map(|e| e as i32), lod_horizon),
|
||||||
(world_map_img, map_size, map_bounds),
|
(world_map_img, map_size, map_bounds),
|
||||||
world_map.sites,
|
world_map.sites,
|
||||||
recipe_book,
|
recipe_book,
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Grid<T> {
|
pub struct Grid<T> {
|
||||||
cells: Vec<T>,
|
cells: Vec<T>,
|
||||||
size: Vec2<i32>,
|
size: Vec2<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Grid<T> {
|
impl<T> Grid<T> {
|
||||||
|
pub fn from_raw(size: Vec2<i32>, raw: impl Into<Vec<T>>) -> Self {
|
||||||
|
let cells = raw.into();
|
||||||
|
assert_eq!(size.product() as usize, cells.len());
|
||||||
|
Self { cells, size }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn populate_from(size: Vec2<i32>, mut f: impl FnMut(Vec2<i32>) -> T) -> Self {
|
pub fn populate_from(size: Vec2<i32>, mut f: impl FnMut(Vec2<i32>) -> T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cells: (0..size.y)
|
cells: (0..size.y)
|
||||||
@ -81,4 +90,32 @@ impl<T> Grid<T> {
|
|||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn raw(&self) -> &[T] { &self.cells }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Index<Vec2<i32>> for Grid<T> {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
fn index(&self, index: Vec2<i32>) -> &Self::Output {
|
||||||
|
self.get(index).unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"Attempted to index grid of size {:?} with index {:?}",
|
||||||
|
self.size(),
|
||||||
|
index
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> IndexMut<Vec2<i32>> for Grid<T> {
|
||||||
|
fn index_mut(&mut self, index: Vec2<i32>) -> &mut Self::Output {
|
||||||
|
let size = self.size();
|
||||||
|
self.get_mut(index).unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"Attempted to index grid of size {:?} with index {:?}",
|
||||||
|
size, index
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
@ -30,6 +30,7 @@ pub mod event;
|
|||||||
pub mod explosion;
|
pub mod explosion;
|
||||||
pub mod figure;
|
pub mod figure;
|
||||||
pub mod generation;
|
pub mod generation;
|
||||||
|
pub mod grid;
|
||||||
pub mod loadout_builder;
|
pub mod loadout_builder;
|
||||||
pub mod lottery;
|
pub mod lottery;
|
||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::grid::Grid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -30,12 +31,12 @@ pub struct WorldMapMsg {
|
|||||||
pub max_height: f32,
|
pub max_height: f32,
|
||||||
/// RGB+A; the alpha channel is currently unused, but will be used in the
|
/// RGB+A; the alpha channel is currently unused, but will be used in the
|
||||||
/// future. Entries are in the usual chunk order.
|
/// future. Entries are in the usual chunk order.
|
||||||
pub rgba: Vec<u32>,
|
pub rgba: Grid<u32>,
|
||||||
/// Altitudes: bits 2 to 0 are unused, then bits 15 to 3 are used for
|
/// Altitudes: bits 2 to 0 are unused, then bits 15 to 3 are used for
|
||||||
/// altitude. The remainder are currently unused, but we have plans to
|
/// altitude. The remainder are currently unused, but we have plans to
|
||||||
/// use 7 bits for water depth (using an integer f7 encoding), and we
|
/// use 7 bits for water depth (using an integer f7 encoding), and we
|
||||||
/// will find other uses for the remaining 12 bits.
|
/// will find other uses for the remaining 12 bits.
|
||||||
pub alt: Vec<u32>,
|
pub alt: Grid<u32>,
|
||||||
/// Horizon mapping. This is a variant of shadow mapping that is
|
/// Horizon mapping. This is a variant of shadow mapping that is
|
||||||
/// specifically designed for height maps; it takes advantage of their
|
/// specifically designed for height maps; it takes advantage of their
|
||||||
/// regular structure (e.g. no holes) to compress all information needed
|
/// regular structure (e.g. no holes) to compress all information needed
|
||||||
|
@ -29,9 +29,9 @@ impl Lod {
|
|||||||
data: LodData::new(
|
data: LodData::new(
|
||||||
renderer,
|
renderer,
|
||||||
client.world_map.1,
|
client.world_map.1,
|
||||||
&client.lod_base,
|
&client.lod_base.raw(),
|
||||||
&client.lod_alt,
|
&client.lod_alt.raw(),
|
||||||
&client.lod_horizon,
|
&client.lod_horizon.raw(),
|
||||||
settings.graphics.lod_detail.max(100).min(2500),
|
settings.graphics.lod_detail.max(100).min(2500),
|
||||||
water_color().into_array().into(),
|
water_color().into_array().into(),
|
||||||
),
|
),
|
||||||
|
@ -36,6 +36,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
assets,
|
assets,
|
||||||
|
grid::Grid,
|
||||||
msg::WorldMapMsg,
|
msg::WorldMapMsg,
|
||||||
store::Id,
|
store::Id,
|
||||||
terrain::{
|
terrain::{
|
||||||
@ -1498,8 +1499,8 @@ impl WorldSim {
|
|||||||
dimensions_lg: self.map_size_lg().vec(),
|
dimensions_lg: self.map_size_lg().vec(),
|
||||||
sea_level: CONFIG.sea_level,
|
sea_level: CONFIG.sea_level,
|
||||||
max_height: self.max_height,
|
max_height: self.max_height,
|
||||||
rgba: v,
|
rgba: Grid::from_raw(self.get_size().map(|e| e as i32), v),
|
||||||
alt: alts,
|
alt: Grid::from_raw(self.get_size().map(|e| e as i32), alts),
|
||||||
horizons,
|
horizons,
|
||||||
sites: Vec::new(), // Will be substituted later
|
sites: Vec::new(), // Will be substituted later
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
pub mod fast_noise;
|
pub mod fast_noise;
|
||||||
pub mod grid;
|
|
||||||
pub mod map_vec;
|
pub mod map_vec;
|
||||||
pub mod random;
|
pub mod random;
|
||||||
pub mod sampler;
|
pub mod sampler;
|
||||||
@ -11,7 +10,6 @@ pub mod unit_chooser;
|
|||||||
// Reexports
|
// Reexports
|
||||||
pub use self::{
|
pub use self::{
|
||||||
fast_noise::FastNoise,
|
fast_noise::FastNoise,
|
||||||
grid::Grid,
|
|
||||||
map_vec::MapVec,
|
map_vec::MapVec,
|
||||||
random::{RandomField, RandomPerm},
|
random::{RandomField, RandomPerm},
|
||||||
sampler::{Sampler, SamplerMut},
|
sampler::{Sampler, SamplerMut},
|
||||||
@ -20,6 +18,8 @@ pub use self::{
|
|||||||
unit_chooser::UnitChooser,
|
unit_chooser::UnitChooser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use common::grid::Grid;
|
||||||
|
|
||||||
use fxhash::FxHasher32;
|
use fxhash::FxHasher32;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
|
Loading…
Reference in New Issue
Block a user