mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improve the efficiency of the voxel minimap by only updating it when crossing a chunk boundary or changing z-level. Allows making the 9 chunks nearest to the player fancier by compositing multiple z levels.
This commit is contained in:
parent
937815d8c3
commit
6df2e96d25
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -2415,6 +2415,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inline_tweak"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7033e97b20277cc0d043226d1940fa7719ff08d2305d1fc7421e53066d00eb4b"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inotify"
|
name = "inotify"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -5833,6 +5842,7 @@ dependencies = [
|
|||||||
"iced_native",
|
"iced_native",
|
||||||
"iced_winit",
|
"iced_winit",
|
||||||
"image",
|
"image",
|
||||||
|
"inline_tweak",
|
||||||
"itertools 0.10.0",
|
"itertools 0.10.0",
|
||||||
"keyboard-keynames",
|
"keyboard-keynames",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -104,7 +104,7 @@ treeculler = "0.2"
|
|||||||
tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }
|
tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
# vec_map = { version = "0.8.2" }
|
# vec_map = { version = "0.8.2" }
|
||||||
# inline_tweak = "1.0.2"
|
inline_tweak = "1.0.2"
|
||||||
itertools = "0.10.0"
|
itertools = "0.10.0"
|
||||||
|
|
||||||
# Tracy
|
# Tracy
|
||||||
|
@ -30,9 +30,10 @@ use std::sync::Arc;
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub struct VoxelMinimap {
|
pub struct VoxelMinimap {
|
||||||
chunk_minimaps: HashMap<Vec2<i32>, HashMap<i32, Grid<[u8; 4]>>>,
|
chunk_minimaps: HashMap<Vec2<i32>, (i32, Vec<Grid<[u8; 4]>>)>,
|
||||||
composited: RgbaImage,
|
composited: RgbaImage,
|
||||||
image_id: img_ids::Rotations,
|
image_id: img_ids::Rotations,
|
||||||
|
last_pos: Vec3<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const VOXEL_MINIMAP_SIDELENGTH: u32 = 512;
|
const VOXEL_MINIMAP_SIDELENGTH: u32 = 512;
|
||||||
@ -51,6 +52,7 @@ impl VoxelMinimap {
|
|||||||
Some(Rgba::from([0.0, 0.0, 0.0, 0.0])),
|
Some(Rgba::from([0.0, 0.0, 0.0, 0.0])),
|
||||||
)),
|
)),
|
||||||
composited,
|
composited,
|
||||||
|
last_pos: Vec3::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +60,7 @@ impl VoxelMinimap {
|
|||||||
let terrain = client.state().terrain();
|
let terrain = client.state().terrain();
|
||||||
for (key, chunk) in terrain.iter() {
|
for (key, chunk) in terrain.iter() {
|
||||||
if !self.chunk_minimaps.contains_key(&key) {
|
if !self.chunk_minimaps.contains_key(&key) {
|
||||||
let mut layers = HashMap::new();
|
let mut layers = Vec::new();
|
||||||
for z in chunk.get_min_z()..chunk.get_max_z() {
|
for z in chunk.get_min_z()..chunk.get_max_z() {
|
||||||
let grid = Grid::populate_from(Vec2::new(32, 32), |v| {
|
let grid = Grid::populate_from(Vec2::new(32, 32), |v| {
|
||||||
chunk
|
chunk
|
||||||
@ -68,35 +70,56 @@ impl VoxelMinimap {
|
|||||||
.map(|rgb| [rgb.r, rgb.g, rgb.b, 192])
|
.map(|rgb| [rgb.r, rgb.g, rgb.b, 192])
|
||||||
.unwrap_or([0, 0, 0, 0])
|
.unwrap_or([0, 0, 0, 0])
|
||||||
});
|
});
|
||||||
layers.insert(z, grid);
|
layers.push(grid);
|
||||||
}
|
}
|
||||||
self.chunk_minimaps.insert(key, layers);
|
self.chunk_minimaps.insert(key, (chunk.get_min_z(), layers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let player = client.entity();
|
let player = client.entity();
|
||||||
if let Some(pos) = client.state().ecs().read_storage::<comp::Pos>().get(player) {
|
if let Some(pos) = client.state().ecs().read_storage::<comp::Pos>().get(player) {
|
||||||
let pos = pos.0;
|
let pos = pos.0;
|
||||||
for x in 0..VOXEL_MINIMAP_SIDELENGTH {
|
let vpos = pos.xy() - VOXEL_MINIMAP_SIDELENGTH as f32 / 2.0;
|
||||||
|
let cpos: Vec2<i32> = vpos.map(|i| (i as i32).div_euclid(32));
|
||||||
|
if cpos.distance_squared(self.last_pos.xy()) >= 1 || self.last_pos.z != pos.z as i32 {
|
||||||
|
self.last_pos = cpos.with_z(pos.z as i32);
|
||||||
for y in 0..VOXEL_MINIMAP_SIDELENGTH {
|
for y in 0..VOXEL_MINIMAP_SIDELENGTH {
|
||||||
let vpos = pos.xy() + Vec2::new(x as f32, y as f32)
|
for x in 0..VOXEL_MINIMAP_SIDELENGTH {
|
||||||
- VOXEL_MINIMAP_SIDELENGTH as f32 / 2.0;
|
let voff = Vec2::new(x as f32, y as f32);
|
||||||
let cpos: Vec2<i32> = (vpos / 32.0).as_();
|
let coff: Vec2<i32> = voff.map(|i| (i as i32).div_euclid(32));
|
||||||
let cmod: Vec2<i32> = (vpos % 32.0).as_();
|
let cmod: Vec2<i32> = voff.map(|i| (i as i32).rem_euclid(32));
|
||||||
if let Some(grid) = self
|
let mut rgba = Vec4::<u16>::zero();
|
||||||
.chunk_minimaps
|
let (weights, zoff) =
|
||||||
.get(&cpos)
|
if (x as i32 - VOXEL_MINIMAP_SIDELENGTH as i32 / 2).abs() < 96
|
||||||
.and_then(|l| l.get(&(pos.z as i32)))
|
&& (y as i32 - VOXEL_MINIMAP_SIDELENGTH as i32 / 2).abs() < 96
|
||||||
{
|
{
|
||||||
self.composited.put_pixel(
|
(&[2, 4, 1, 1, 1][..], -1)
|
||||||
x,
|
} else {
|
||||||
VOXEL_MINIMAP_SIDELENGTH - y - 1,
|
(&[1][..], 0)
|
||||||
grid.get(cmod)
|
};
|
||||||
.map(|c| image::Rgba(*c))
|
for z in 0..weights.len() {
|
||||||
.unwrap_or(image::Rgba([0, 0, 0, 0])),
|
if let Some(grid) =
|
||||||
);
|
self.chunk_minimaps
|
||||||
|
.get(&(cpos + coff))
|
||||||
|
.and_then(|(zlo, g)| {
|
||||||
|
g.get((pos.z as i32 + z as i32 - zlo + zoff) as usize)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let tmp: Vec4<u16> = grid
|
||||||
|
.get(cmod)
|
||||||
|
.map(|c| Vec4::<u8>::from(*c).as_())
|
||||||
|
.unwrap_or(Vec4::one());
|
||||||
|
rgba += tmp.as_() * weights[z];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let color = {
|
||||||
|
let rgba: Vec4<u8> = (rgba / weights.iter().sum::<u16>()).as_();
|
||||||
|
image::Rgba([rgba.x, rgba.y, rgba.z, rgba.w])
|
||||||
|
};
|
||||||
|
self.composited
|
||||||
|
.put_pixel(x, VOXEL_MINIMAP_SIDELENGTH - y - 1, color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui.replace_graphic(
|
ui.replace_graphic(
|
||||||
self.image_id.none,
|
self.image_id.none,
|
||||||
Graphic::Image(
|
Graphic::Image(
|
||||||
@ -107,6 +130,7 @@ impl VoxelMinimap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
widget_ids! {
|
widget_ids! {
|
||||||
struct Ids {
|
struct Ids {
|
||||||
@ -378,10 +402,11 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
self.voxel_minimap.image_id.source_north
|
self.voxel_minimap.image_id.source_north
|
||||||
};
|
};
|
||||||
let scaling = (VOXEL_MINIMAP_SIDELENGTH as f64 / 32.0) * max_zoom / zoom;
|
let scaling = (VOXEL_MINIMAP_SIDELENGTH as f64 / 32.0) * max_zoom / zoom;
|
||||||
|
let cmod: Vec2<f64> = (player_pos.xy() % 32.0).as_();
|
||||||
let rect_src = position::Rect::from_xy_dim(
|
let rect_src = position::Rect::from_xy_dim(
|
||||||
[
|
[
|
||||||
VOXEL_MINIMAP_SIDELENGTH as f64 / 2.0,
|
cmod.x + VOXEL_MINIMAP_SIDELENGTH as f64 / 2.0,
|
||||||
VOXEL_MINIMAP_SIDELENGTH as f64 / 2.0,
|
-cmod.y + VOXEL_MINIMAP_SIDELENGTH as f64 / 2.0,
|
||||||
],
|
],
|
||||||
[scaling, scaling],
|
[scaling, scaling],
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user