diff --git a/.cargo/config b/.cargo/config index d08998512b..9884717112 100644 --- a/.cargo/config +++ b/.cargo/config @@ -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" diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index 1bc2ab3615..8ef2e6856f 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -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::::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) diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 98dec7dc4f..cdea80e8eb 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -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 @@ -241,19 +240,23 @@ impl<'a> Widget for MiniMap<'a> { .mmap_site_icons_bgs .resize(self.client.sites().len(), &mut ui.widget_id_generator()) }); - } - for (i, site) in self.client.sites().iter().enumerate() { + } + 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,