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,
|
||||
},
|
||||
event::{EventBus, LocalEvent},
|
||||
grid::Grid,
|
||||
msg::{
|
||||
validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral, ClientMsg,
|
||||
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
||||
@ -80,15 +81,15 @@ pub struct Client {
|
||||
/// Just the "base" layer for LOD; currently includes colors and nothing
|
||||
/// else. In the future we'll add more layers, like shadows, rivers, and
|
||||
/// 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
|
||||
/// in the future should also water depth, and probably other
|
||||
/// 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
|
||||
/// an approximate max occluder height, which we use to try to
|
||||
/// 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
|
||||
/// 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
|
||||
@ -229,11 +230,10 @@ impl Client {
|
||||
let sea_level = world_map.sea_level;
|
||||
let rgba = world_map.rgba;
|
||||
let alt = world_map.alt;
|
||||
let expected_size = (u32::from(map_size.x) * u32::from(map_size.y)) as usize;
|
||||
if rgba.len() != expected_size {
|
||||
if rgba.size() != map_size.map(|e| e as i32) {
|
||||
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()));
|
||||
}
|
||||
let [west, east] = world_map.horizons;
|
||||
@ -257,7 +257,7 @@ impl Client {
|
||||
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
||||
|
||||
// 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(
|
||||
map_size_lg,
|
||||
core::ops::RangeInclusive::new(0.0, max_height),
|
||||
@ -274,14 +274,14 @@ impl Client {
|
||||
|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 [r, g, b, a] = rgba[posi].to_le_bytes();
|
||||
let alti = alt[posi];
|
||||
let [r, g, b, a] = rgba[pos].to_le_bytes();
|
||||
let alti = alt[pos];
|
||||
// Compute downhill.
|
||||
let downhill = {
|
||||
let mut best = -1;
|
||||
let mut besth = alti;
|
||||
for nposi in neighbors(map_size_lg, posi) {
|
||||
let nbh = alt[nposi];
|
||||
let nbh = alt.raw()[nposi];
|
||||
if nbh < besth {
|
||||
besth = nbh;
|
||||
best = nposi as isize;
|
||||
@ -317,8 +317,7 @@ impl Client {
|
||||
|wpos| {
|
||||
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||
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[posi])
|
||||
scale_height_big(alt[pos])
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
@ -361,7 +360,7 @@ impl Client {
|
||||
entity,
|
||||
lod_base,
|
||||
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.sites,
|
||||
recipe_book,
|
||||
|
@ -1,11 +1,20 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::{Index, IndexMut};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Grid<T> {
|
||||
cells: Vec<T>,
|
||||
size: Vec2<i32>,
|
||||
}
|
||||
|
||||
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 {
|
||||
Self {
|
||||
cells: (0..size.y)
|
||||
@ -81,4 +90,32 @@ impl<T> Grid<T> {
|
||||
})
|
||||
.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 figure;
|
||||
pub mod generation;
|
||||
pub mod grid;
|
||||
pub mod loadout_builder;
|
||||
pub mod lottery;
|
||||
pub mod metrics;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::grid::Grid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vek::*;
|
||||
|
||||
@ -30,12 +31,12 @@ pub struct WorldMapMsg {
|
||||
pub max_height: f32,
|
||||
/// RGB+A; the alpha channel is currently unused, but will be used in the
|
||||
/// 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
|
||||
/// altitude. The remainder are currently unused, but we have plans to
|
||||
/// use 7 bits for water depth (using an integer f7 encoding), and we
|
||||
/// 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
|
||||
/// specifically designed for height maps; it takes advantage of their
|
||||
/// regular structure (e.g. no holes) to compress all information needed
|
||||
|
@ -29,9 +29,9 @@ impl Lod {
|
||||
data: LodData::new(
|
||||
renderer,
|
||||
client.world_map.1,
|
||||
&client.lod_base,
|
||||
&client.lod_alt,
|
||||
&client.lod_horizon,
|
||||
&client.lod_base.raw(),
|
||||
&client.lod_alt.raw(),
|
||||
&client.lod_horizon.raw(),
|
||||
settings.graphics.lod_detail.max(100).min(2500),
|
||||
water_color().into_array().into(),
|
||||
),
|
||||
|
@ -36,6 +36,7 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
grid::Grid,
|
||||
msg::WorldMapMsg,
|
||||
store::Id,
|
||||
terrain::{
|
||||
@ -1498,8 +1499,8 @@ impl WorldSim {
|
||||
dimensions_lg: self.map_size_lg().vec(),
|
||||
sea_level: CONFIG.sea_level,
|
||||
max_height: self.max_height,
|
||||
rgba: v,
|
||||
alt: alts,
|
||||
rgba: Grid::from_raw(self.get_size().map(|e| e as i32), v),
|
||||
alt: Grid::from_raw(self.get_size().map(|e| e as i32), alts),
|
||||
horizons,
|
||||
sites: Vec::new(), // Will be substituted later
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub mod fast_noise;
|
||||
pub mod grid;
|
||||
pub mod map_vec;
|
||||
pub mod random;
|
||||
pub mod sampler;
|
||||
@ -11,7 +10,6 @@ pub mod unit_chooser;
|
||||
// Reexports
|
||||
pub use self::{
|
||||
fast_noise::FastNoise,
|
||||
grid::Grid,
|
||||
map_vec::MapVec,
|
||||
random::{RandomField, RandomPerm},
|
||||
sampler::{Sampler, SamplerMut},
|
||||
@ -20,6 +18,8 @@ pub use self::{
|
||||
unit_chooser::UnitChooser,
|
||||
};
|
||||
|
||||
pub use common::grid::Grid;
|
||||
|
||||
use fxhash::FxHasher32;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
Loading…
Reference in New Issue
Block a user