mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Demystify map site icon placement calculations
This commit is contained in:
parent
e461fbd951
commit
898bba8884
@ -6,8 +6,8 @@ rustflags = [
|
||||
[alias]
|
||||
generate = "run --package tools --"
|
||||
test-server = "-Zpackage-features run --bin veloren-server-cli --no-default-features"
|
||||
tracy-server = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --no-default-features --features tracy --profile dev"
|
||||
tracy-server = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --no-default-features --features tracy,simd --profile no_overflow"
|
||||
test-voxygen = "-Zpackage-features run --bin veloren-voxygen --no-default-features --features gl,simd"
|
||||
tracy-voxygen = "-Zunstable-options -Zpackage-features run --bin veloren-voxygen --no-default-features --features tracy,gl,simd --profile dev"
|
||||
tracy-voxygen = "-Zunstable-options -Zpackage-features run --bin veloren-voxygen --no-default-features --features tracy,gl,simd --profile no_overflow"
|
||||
server = "run --bin veloren-server-cli"
|
||||
|
||||
|
@ -230,7 +230,6 @@ impl<'a> Widget for Map<'a> {
|
||||
.set(state.ids.grid, ui);
|
||||
// Map Image
|
||||
let (world_map, worldsize) = self.world_map;
|
||||
let worldsize = worldsize.map2(TerrainChunkSize::RECT_SIZE, |e, f| e as f64 * f as f64);
|
||||
|
||||
// Coordinates
|
||||
let player_pos = self
|
||||
@ -241,8 +240,8 @@ impl<'a> Widget for Map<'a> {
|
||||
.get(self.client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
let max_zoom = (worldsize / TerrainChunkSize::RECT_SIZE.map(|e| e as f64))
|
||||
.reduce_partial_max()/*.min(f64::MAX)*/;
|
||||
let max_zoom = worldsize
|
||||
.reduce_partial_max() as f64/*.min(f64::MAX)*/;
|
||||
|
||||
let map_size = Vec2::new(760.0, 760.0);
|
||||
|
||||
@ -256,13 +255,14 @@ impl<'a> Widget for Map<'a> {
|
||||
.left()
|
||||
.map(|drag| Vec2::<f64>::from(drag.delta_xy))
|
||||
.sum();
|
||||
let drag_new = drag + dragged / zoom;
|
||||
// Drag represents offset of view from the player_pos in chunk coords
|
||||
let drag_new = drag + dragged / map_size / zoom * worldsize.map(|e| e as f64);
|
||||
events.push(Event::MapDrag(drag_new));
|
||||
|
||||
let rect_src = position::Rect::from_xy_dim(
|
||||
[
|
||||
(player_pos.x as f64 / TerrainChunkSize::RECT_SIZE.x as f64) - drag.x,
|
||||
((worldsize.y - player_pos.y as f64) / TerrainChunkSize::RECT_SIZE.y as f64)
|
||||
(worldsize.y as f64 - (player_pos.y as f64 / TerrainChunkSize::RECT_SIZE.y as f64))
|
||||
+ drag.y,
|
||||
],
|
||||
[w_src, h_src],
|
||||
@ -302,13 +302,13 @@ impl<'a> Widget for Map<'a> {
|
||||
events.push(Event::MapZoom(new_val as f64));
|
||||
}*/
|
||||
// Handle zooming with the mousewheel
|
||||
let zoom_lvl = self.global_state.settings.gameplay.map_zoom;
|
||||
let scrolled: f64 = ui
|
||||
.widget_input(state.ids.grid)
|
||||
.scrolls()
|
||||
.map(|scroll| scroll.y)
|
||||
.sum();
|
||||
let new_zoom_lvl = (zoom_lvl * (1.0 + scrolled * 0.05 * PLATFORM_FACTOR))
|
||||
let new_zoom_lvl = (self.global_state.settings.gameplay.map_zoom
|
||||
* (1.0 + scrolled * 0.05 * PLATFORM_FACTOR))
|
||||
.clamped(1.22, 20.0 /* max_zoom */);
|
||||
events.push(Event::MapZoom(new_zoom_lvl as f64));
|
||||
// Icon settings
|
||||
@ -471,13 +471,17 @@ impl<'a> Widget for Map<'a> {
|
||||
});
|
||||
}
|
||||
for (i, site) in self.client.sites().iter().enumerate() {
|
||||
// Site pos in world coordinates relative to the player
|
||||
let rwpos = site.wpos.map(|e| e as f32) - player_pos;
|
||||
let rcpos =
|
||||
rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32) * zoom as f32 * 3.0
|
||||
/ 4.0;
|
||||
let rpos = Vec2::unit_x().rotated_z(0.0) * rcpos.x
|
||||
+ Vec2::unit_y().rotated_z(0.0) * rcpos.y
|
||||
+ drag.map(|e| (e * zoom_lvl) as f32 / 1.67);
|
||||
// Convert to chunk coordinates
|
||||
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32)
|
||||
// Add map dragging
|
||||
+ drag.map(|e| e as f32);
|
||||
// Convert to fractional coordinates relative to the worldsize
|
||||
let rfpos = rcpos.map2(*worldsize, |e, sz| e / sz as f32);
|
||||
// Convert to relative pixel coordinates from the center of the map
|
||||
// Accounting for zooming
|
||||
let rpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32);
|
||||
|
||||
if rpos
|
||||
.map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0)
|
||||
@ -639,16 +643,27 @@ impl<'a> Widget for Map<'a> {
|
||||
(e as f64 / sz).clamped(0.0, 1.0)
|
||||
});*/
|
||||
//let xy = rel * 760.0;
|
||||
let rpos = drag.map(|e| (e * zoom_lvl) as f32 / 2.6);
|
||||
|
||||
// Offset from map center due to dragging
|
||||
let rcpos = drag.map(|e| e as f32);
|
||||
// Convert to fractional coordinates relative to the worldsize
|
||||
let rfpos = rcpos.map2(*worldsize, |e, sz| e / sz as f32);
|
||||
// Convert to relative pixel coordinates from the center of the map
|
||||
// Accounting for zooming
|
||||
let rpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32);
|
||||
// Don't show if outside or near the edge of the map
|
||||
let arrow_sz = {
|
||||
let scale = 0.6f64;
|
||||
Vec2::new(32.0, 37.0) * scale
|
||||
};
|
||||
// Hide if icon could go off of the edge of the map
|
||||
if !rpos
|
||||
.map2(map_size, |e, sz| e > sz as f32 / 1.67)
|
||||
.map2(map_size, |e, sz| {
|
||||
e.abs() + arrow_sz.map(|e| e as f32 / 2.0).magnitude() > sz as f32 / 2.0
|
||||
})
|
||||
.reduce_or()
|
||||
{
|
||||
let scale = 0.6;
|
||||
let arrow_sz = Vec2::new(32.0, 37.0) * scale;
|
||||
if drag.x == 0.0 && drag.y == 0.0 {
|
||||
Image::new(self.rot_imgs.indicator_mmap_small.target_north)
|
||||
//.top_left_with_margins_on(state.ids.grid, 407.0 - drag.y * zoom_lvl, 417.0 + drag.x * zoom_lvl)
|
||||
Image::new(self.rot_imgs.indicator_mmap_small.target_north)
|
||||
.x_y_position_relative_to(
|
||||
state.ids.grid,
|
||||
position::Relative::Scalar(rpos.x as f64),
|
||||
@ -656,10 +671,7 @@ impl<'a> Widget for Map<'a> {
|
||||
)
|
||||
.w_h(arrow_sz.x, arrow_sz.y)
|
||||
.color(Some(UI_HIGHLIGHT_0))
|
||||
.floating(true)
|
||||
//.parent(ui.window)
|
||||
.set(state.ids.indicator, ui);
|
||||
}
|
||||
}
|
||||
// Info about controls
|
||||
let icon_size = Vec2::new(tweak!(25.6), tweak!(28.8));
|
||||
@ -699,7 +711,7 @@ impl<'a> Widget for Map<'a> {
|
||||
.set(state.ids.recenter_button, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
events.push(Event::MapDrag(drag_new - drag_new));
|
||||
events.push(Event::MapDrag(Vec2::zero()));
|
||||
};
|
||||
|
||||
Image::new(self.imgs.m_move_ico)
|
||||
|
@ -1,7 +1,8 @@
|
||||
use super::{
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
Show, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE,
|
||||
};
|
||||
Show, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE,
|
||||
TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
||||
};
|
||||
use crate::ui::{fonts::Fonts, img_ids};
|
||||
use client::{self, Client};
|
||||
use common::{comp, msg::world_msg::SiteKind, terrain::TerrainChunkSize, vol::RectVolSize};
|
||||
@ -124,9 +125,8 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
.mid_top_with_margin_on(state.ids.mmap_frame_2, 18.0 * SCALE)
|
||||
.set(state.ids.mmap_frame_bg, ui);
|
||||
|
||||
// Map size
|
||||
// Map size in chunk coords
|
||||
let (world_map, worldsize) = self.world_map;
|
||||
let worldsize = worldsize.map2(TerrainChunkSize::RECT_SIZE, |e, f| e as f64 * f as f64);
|
||||
|
||||
// Zoom Buttons
|
||||
|
||||
@ -136,8 +136,8 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
// TODO: Either prevent zooming all the way in, *or* see if we can interpolate
|
||||
// somehow if you zoom in too far. Or both.
|
||||
let min_zoom = 1.0;
|
||||
let max_zoom = (worldsize / TerrainChunkSize::RECT_SIZE.map(|e| e as f64))
|
||||
.reduce_partial_max()/*.min(f64::MAX)*/;
|
||||
let max_zoom = worldsize
|
||||
.reduce_partial_max() as f64/*.min(f64::MAX)*/;
|
||||
|
||||
// NOTE: Not sure if a button can be clicked while disabled, but we still double
|
||||
// check for both kinds of zoom to make sure that not only was the
|
||||
@ -200,17 +200,18 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
let rect_src = position::Rect::from_xy_dim(
|
||||
[
|
||||
player_pos.x as f64 / TerrainChunkSize::RECT_SIZE.x as f64,
|
||||
(worldsize.y - player_pos.y as f64) / TerrainChunkSize::RECT_SIZE.y as f64,
|
||||
worldsize.y as f64
|
||||
- (player_pos.y as f64 / TerrainChunkSize::RECT_SIZE.y as f64),
|
||||
],
|
||||
[w_src, h_src],
|
||||
);
|
||||
|
||||
let map_size = Vec2::new(170.0, 170.0);
|
||||
let map_size = Vec2::new(170.0 * SCALE, 170.0 * SCALE);
|
||||
|
||||
// Map Image
|
||||
Image::new(world_map.source_north)
|
||||
.middle_of(state.ids.mmap_frame_bg)
|
||||
.w_h(map_size.x * SCALE, map_size.y * SCALE)
|
||||
.w_h(map_size.x, map_size.y)
|
||||
.parent(state.ids.mmap_frame_bg)
|
||||
.source_rectangle(rect_src)
|
||||
.set(state.ids.grid, ui);
|
||||
@ -221,8 +222,6 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
.middle_of(state.ids.grid)
|
||||
.w_h(32.0 * ind_scale, 37.0 * ind_scale)
|
||||
.color(Some(UI_HIGHLIGHT_0))
|
||||
.floating(true)
|
||||
.parent(ui.window)
|
||||
.set(state.ids.indicator, ui);
|
||||
|
||||
// Map icons
|
||||
@ -243,17 +242,21 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
});
|
||||
}
|
||||
for (i, site) in self.client.sites().iter().enumerate() {
|
||||
// Site pos in world coordinates relative to the player
|
||||
let rwpos = site.wpos.map(|e| e as f32) - player_pos;
|
||||
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32)
|
||||
* state.zoom as f32
|
||||
/ 4.0;
|
||||
let rpos = Vec2::unit_x().rotated_z(self.ori.x) * rcpos.x
|
||||
+ Vec2::unit_y().rotated_z(self.ori.x) * rcpos.y;
|
||||
// Convert to chunk coordinates
|
||||
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32);
|
||||
// Convert to fractional coordinates relative to the worldsize
|
||||
let rfpos = rcpos.map2(*worldsize, |e, sz| e / sz as f32);
|
||||
// Convert to unrotated pixel coordinates from the player location on the map
|
||||
// (the center)
|
||||
// Accounting for zooming
|
||||
let rpixpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32);
|
||||
let rpos = Vec2::unit_x().rotated_z(self.ori.x) * rpixpos.x
|
||||
+ Vec2::unit_y().rotated_z(self.ori.x) * rpixpos.y;
|
||||
|
||||
// TODO: Why does this require the magic constant 0.73? This this related to
|
||||
// scaling issues?
|
||||
if rpos
|
||||
.map2(map_size, |e, sz| e.abs() > sz as f32 / 0.73 / 2.0)
|
||||
.map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0)
|
||||
.reduce_or()
|
||||
{
|
||||
continue;
|
||||
@ -270,22 +273,20 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
position::Relative::Scalar(rpos.y as f64),
|
||||
)
|
||||
.w_h(20.0, 20.0)
|
||||
.color(Some(
|
||||
match &site.kind {
|
||||
SiteKind::Town => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
SiteKind::Castle => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
SiteKind::Dungeon { difficulty } => match difficulty {
|
||||
0 => QUALITY_LOW,
|
||||
1 => QUALITY_COMMON,
|
||||
2 => QUALITY_MODERATE,
|
||||
3 => QUALITY_HIGH,
|
||||
4 => QUALITY_EPIC,
|
||||
5 => QUALITY_DEBUG,
|
||||
_ => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
},
|
||||
},))
|
||||
.floating(true)
|
||||
.parent(ui.window)
|
||||
.color(Some(match &site.kind {
|
||||
SiteKind::Town => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
SiteKind::Castle => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
SiteKind::Dungeon { difficulty } => match difficulty {
|
||||
0 => QUALITY_LOW,
|
||||
1 => QUALITY_COMMON,
|
||||
2 => QUALITY_MODERATE,
|
||||
3 => QUALITY_HIGH,
|
||||
4 => QUALITY_EPIC,
|
||||
5 => QUALITY_DEBUG,
|
||||
_ => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
},
|
||||
}))
|
||||
.parent(state.ids.grid)
|
||||
.set(state.ids.mmap_site_icons_bgs[i], ui);
|
||||
Image::new(match &site.kind {
|
||||
SiteKind::Town => self.imgs.mmap_site_town,
|
||||
@ -295,7 +296,6 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
.middle_of(state.ids.mmap_site_icons_bgs[i])
|
||||
.w_h(20.0, 20.0)
|
||||
.color(Some(UI_HIGHLIGHT_0))
|
||||
.floating(true)
|
||||
.set(state.ids.mmap_site_icons[i], ui);
|
||||
}
|
||||
|
||||
@ -309,9 +309,8 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
for (dir, id, name, bold) in dirs.iter() {
|
||||
let cardinal_dir = Vec2::unit_x().rotated_z(self.ori.x as f64) * dir.x
|
||||
+ Vec2::unit_y().rotated_z(self.ori.x as f64) * dir.y;
|
||||
let clamped = (cardinal_dir * 3.0)
|
||||
/ (cardinal_dir * 3.0).map(|e| e.abs()).reduce_partial_max();
|
||||
let pos = clamped * (map_size * 0.73 - 10.0);
|
||||
let clamped = cardinal_dir / cardinal_dir.map(|e| e.abs()).reduce_partial_max();
|
||||
let pos = clamped * (map_size / 2.0 - 10.0);
|
||||
Text::new(name)
|
||||
.x_y_position_relative_to(
|
||||
state.ids.grid,
|
||||
|
Loading…
Reference in New Issue
Block a user