mouse controls
This commit is contained in:
@@ -17,9 +17,9 @@ It's normal rust, so `cargo run` should fully compile and start it. It requires
|
||||
|
||||
## Controls
|
||||
|
||||
- WASD for movement
|
||||
- WASD or left click & drag for movement
|
||||
- Scroll to zoom
|
||||
- Q to take a snapshot
|
||||
- Q or right click to take a snapshot
|
||||
|
||||
Snapshots will copy the current texture and let you view it as the new one generates, which is very important for your sanity when you zoom in really far; the undecided regions will be replaced with a darkened version of your snapshot, so you can still know where you are and move around.
|
||||
|
||||
@@ -48,8 +48,6 @@ not in order of priority
|
||||
- add auto snapshot; hard to figure out exactly when to take; maybe wait until at iter threshold dependent on zoom?
|
||||
- add ability to have multiple snapshots at once, so you can easily navigate around; also fade out snapshots that are far away zoom wise; also maybe save manual ones to disk so you can easily contiune exploring areas
|
||||
- add checkpointing that somehow lets you save & return to locations; even if this isn't added, add camera reset to easily get back to initial state; would also let you share locations with other people
|
||||
- zoom in on mouse
|
||||
- others controls for mouse; click & drag to move, maybe right click could be snapshot
|
||||
|
||||
## Cool Screenshots
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use nalgebra::Vector2;
|
||||
use std::ops::AddAssign;
|
||||
use std::ops::{AddAssign, Neg};
|
||||
|
||||
use crate::util::FixedDec;
|
||||
|
||||
@@ -15,20 +15,44 @@ pub struct Zoom {
|
||||
pub struct Camera {
|
||||
pub pos: Vector2<FixedDec>,
|
||||
pub zoom: Zoom,
|
||||
pub size: Vector2<u32>,
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
pub fn scale(&self, size: &Vector2<u32>) -> Vector2<f32> {
|
||||
let fsize: Vector2<f32> = size.cast();
|
||||
if size.x < size.y {
|
||||
pub fn world_pos(&self, screen_pos: Vector2<f32>) -> Vector2<FixedDec> {
|
||||
let mut pos = screen_pos
|
||||
.component_div(&self.size.cast())
|
||||
.add_scalar(-0.5)
|
||||
.component_mul(&self.stretch())
|
||||
.map(FixedDec::from);
|
||||
pos.y.negate();
|
||||
pos *= self.zoom.mult().clone();
|
||||
pos += &self.pos;
|
||||
pos
|
||||
}
|
||||
|
||||
pub fn world_delta(&self, screen_delta: Vector2<f32>) -> Vector2<FixedDec> {
|
||||
let mut pos = screen_delta
|
||||
.component_div(&self.size.cast())
|
||||
.component_mul(&(self.stretch() * 1.5))
|
||||
.map(FixedDec::from);
|
||||
pos.y.negate();
|
||||
pos *= self.zoom.mult().clone();
|
||||
pos
|
||||
}
|
||||
|
||||
pub fn stretch(&self) -> Vector2<f32> {
|
||||
let fsize: Vector2<f32> = self.size.cast();
|
||||
if self.size.x < self.size.y {
|
||||
Vector2::new(fsize.x / fsize.y, 1.0)
|
||||
} else {
|
||||
Vector2::new(1.0, fsize.y / fsize.x)
|
||||
}
|
||||
}
|
||||
pub fn inv_scale(&self, size: &Vector2<u32>) -> Vector2<f32> {
|
||||
let fsize: Vector2<f32> = size.cast();
|
||||
if size.x < size.y {
|
||||
|
||||
pub fn inv_stretch(&self) -> Vector2<f32> {
|
||||
let fsize: Vector2<f32> = self.size.cast();
|
||||
if self.size.x < self.size.y {
|
||||
Vector2::new(fsize.y / fsize.x, 1.0)
|
||||
} else {
|
||||
Vector2::new(1.0, fsize.x / fsize.y)
|
||||
@@ -39,6 +63,7 @@ impl Camera {
|
||||
impl Default for Camera {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
size: Vector2::zeros(),
|
||||
pos: Vector2::new(-0.5, 0.0).map(FixedDec::from),
|
||||
zoom: Zoom::new(0, 2.1),
|
||||
}
|
||||
|
||||
@@ -1,18 +1,46 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use winit::keyboard::KeyCode as K;
|
||||
use winit::{event::MouseButton, keyboard::KeyCode as K};
|
||||
|
||||
use crate::util::FixedDec;
|
||||
|
||||
use super::Client;
|
||||
|
||||
pub struct InputHandling {
|
||||
pub snapshot: bool,
|
||||
}
|
||||
|
||||
impl InputHandling {
|
||||
pub fn new() -> Self {
|
||||
Self { snapshot: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl Client<'_> {
|
||||
pub fn handle_input(&mut self, delta: Duration) {
|
||||
let Client { input, camera, .. } = self;
|
||||
let Client {
|
||||
input,
|
||||
camera,
|
||||
handling,
|
||||
..
|
||||
} = self;
|
||||
if delta > Duration::from_secs_f32(0.5) {
|
||||
// skip input handling if lag spike so you don't go flying
|
||||
return;
|
||||
}
|
||||
let per_sec = delta.as_secs_f32();
|
||||
|
||||
if input.scroll_delta != 0.0 {
|
||||
let old_pos = camera.world_pos(input.mouse_pos);
|
||||
camera.zoom += input.scroll_delta / 5.0;
|
||||
let new_pos = camera.world_pos(input.mouse_pos);
|
||||
camera.pos += old_pos - new_pos;
|
||||
}
|
||||
|
||||
if input.mouse_pressed(MouseButton::Left)
|
||||
&& (input.mouse_delta.x != 0.0 || input.mouse_delta.y != 0.0)
|
||||
{
|
||||
camera.pos -= camera.world_delta(input.mouse_delta);
|
||||
}
|
||||
|
||||
let speed = FixedDec::from(per_sec * 0.5) * camera.zoom.mult();
|
||||
@@ -28,8 +56,8 @@ impl Client<'_> {
|
||||
if input.pressed(K::KeyD) {
|
||||
camera.pos.x += &speed;
|
||||
}
|
||||
if input.pressed(K::KeyQ) {
|
||||
self.snapshot = true;
|
||||
if input.just_pressed(K::KeyQ) || input.mouse_just_pressed(MouseButton::Right) {
|
||||
handling.snapshot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use winit::{
|
||||
};
|
||||
|
||||
pub struct Input {
|
||||
pub mouse_pixel_pos: Vector2<f32>,
|
||||
pub mouse_pos: Vector2<f32>,
|
||||
pub mouse_delta: Vector2<f32>,
|
||||
|
||||
pressed: HashSet<KeyCode>,
|
||||
@@ -23,7 +23,7 @@ pub struct Input {
|
||||
impl Input {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
mouse_pixel_pos: Vector2::zeros(),
|
||||
mouse_pos: Vector2::zeros(),
|
||||
mouse_delta: Vector2::zeros(),
|
||||
pressed: HashSet::new(),
|
||||
just_pressed: HashSet::new(),
|
||||
@@ -67,11 +67,10 @@ impl Input {
|
||||
};
|
||||
}
|
||||
WindowEvent::CursorLeft { .. } => {
|
||||
self.pressed.clear();
|
||||
self.mouse_pressed.clear();
|
||||
self.clear();
|
||||
}
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
self.mouse_pixel_pos = Vector2::new(position.x as f32, position.y as f32);
|
||||
self.mouse_pos = Vector2::new(position.x as f32, position.y as f32);
|
||||
}
|
||||
WindowEvent::MouseInput { button, state, .. } => match state {
|
||||
ElementState::Pressed => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::{sync::Arc, time::Instant};
|
||||
|
||||
use camera::Camera;
|
||||
use handle_input::InputHandling;
|
||||
use input::Input;
|
||||
use render::Renderer;
|
||||
use winit::{
|
||||
@@ -23,7 +24,7 @@ pub struct Client<'a> {
|
||||
exit: bool,
|
||||
prev_update: Instant,
|
||||
renderer: Renderer<'a>,
|
||||
snapshot: bool,
|
||||
handling: InputHandling,
|
||||
}
|
||||
|
||||
impl Client<'_> {
|
||||
@@ -41,7 +42,7 @@ impl Client<'_> {
|
||||
exit: false,
|
||||
prev_update: Instant::now(),
|
||||
renderer,
|
||||
snapshot: false,
|
||||
handling: InputHandling::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +61,17 @@ impl Client<'_> {
|
||||
pub fn window_event(&mut self, event: WindowEvent) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => self.exit = true,
|
||||
WindowEvent::Resized(size) => self.renderer.resize(size),
|
||||
WindowEvent::Resized(size) => {
|
||||
self.renderer.resize(size);
|
||||
self.camera.size = *self.renderer.size();
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
self.renderer.render(&self.camera, self.snapshot);
|
||||
self.snapshot = false;
|
||||
self.renderer.render(&self.camera, self.handling.snapshot);
|
||||
self.handling.snapshot = false;
|
||||
self.window.request_redraw();
|
||||
}
|
||||
WindowEvent::CursorLeft { .. } => {
|
||||
self.input.clear();
|
||||
}
|
||||
_ => self.input.update_window(event),
|
||||
_ => (),
|
||||
}
|
||||
self.input.update_window(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ impl ComputeView {
|
||||
impl Default for ComputeView {
|
||||
fn default() -> Self {
|
||||
let val = FixedDec::from_parts(false, 0, vec![0, 0, 0]);
|
||||
Self::new(true, Vector2::zeros(), 0, &val, &val, &val)
|
||||
Self::new(true, Vector2::zeros(), Vector2::zeros(), 0, &val, &val, &val)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ impl ComputeView {
|
||||
fn new(
|
||||
reset: bool,
|
||||
dims: Vector2<u32>,
|
||||
stretch: Vector2<f32>,
|
||||
level: i32,
|
||||
scale: &FixedDec,
|
||||
x: &FixedDec,
|
||||
@@ -36,6 +37,7 @@ impl ComputeView {
|
||||
bytes.extend((reset as u32).to_le_bytes());
|
||||
bytes.extend(level.to_le_bytes());
|
||||
bytes.extend(bytemuck::cast_slice(&[dims.x, dims.y]));
|
||||
bytes.extend(bytemuck::cast_slice(&[stretch.x, stretch.y]));
|
||||
scale.to_bytes(&mut bytes);
|
||||
x.to_bytes(&mut bytes);
|
||||
y.to_bytes(&mut bytes);
|
||||
@@ -46,7 +48,7 @@ impl ComputeView {
|
||||
Self { bytes }
|
||||
}
|
||||
|
||||
pub fn from_camera_size(camera: &Camera, size: &Vector2<u32>, reset: bool, len: usize) -> Self {
|
||||
pub fn from_camera(camera: &Camera, reset: bool, len: usize) -> Self {
|
||||
let mut x = camera.pos.x.clone();
|
||||
x.set_whole_len(1);
|
||||
x.set_dec_len(len as i32 - 1);
|
||||
@@ -54,17 +56,11 @@ impl ComputeView {
|
||||
y.set_whole_len(1);
|
||||
y.set_dec_len(len as i32 - 1);
|
||||
|
||||
let fsize: Vector2<f32> = size.cast();
|
||||
let stretch = if size.x < size.y {
|
||||
Vector2::new(fsize.x / fsize.y, 1.0)
|
||||
} else {
|
||||
Vector2::new(1.0, fsize.y / fsize.x)
|
||||
};
|
||||
|
||||
let stretch = camera.stretch();
|
||||
let mut scale = camera.zoom.mult().clone();
|
||||
scale.set_precision(len);
|
||||
|
||||
Self::new(reset, *size, camera.zoom.level(), &scale, &x, &y)
|
||||
Self::new(reset, camera.size, stretch, camera.zoom.level(), &scale, &x, &y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,9 @@ impl ComputePipeline {
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
belt: &mut wgpu::util::StagingBelt,
|
||||
camera: &Camera,
|
||||
size: &Vector2<u32>,
|
||||
len: usize,
|
||||
) {
|
||||
let mut view = ComputeView::from_camera_size(camera, size, false, len);
|
||||
let mut view = ComputeView::from_camera(camera, false, len);
|
||||
if view != self.old_view {
|
||||
for (i, b) in 1u32.to_le_bytes().iter().enumerate() {
|
||||
view.bytes[i] = *b;
|
||||
@@ -49,7 +48,7 @@ impl ComputePipeline {
|
||||
println!("new len: {}", len);
|
||||
self.old_len = len;
|
||||
self.pipeline = self.pipeline(device, &Self::shader(device, len));
|
||||
self.work.set(work_vec(size.x, size.y, len));
|
||||
self.work.set(work_vec(camera.size.x, camera.size.y, len));
|
||||
}
|
||||
let updated = self.work.update(device, encoder, belt)
|
||||
| self.view.update(device, encoder, belt, view.bytes());
|
||||
@@ -66,14 +65,7 @@ impl ComputePipeline {
|
||||
pass.dispatch_workgroups(240, 135, 1);
|
||||
}
|
||||
|
||||
pub fn resize(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
belt: &mut wgpu::util::StagingBelt,
|
||||
size: Vector2<u32>,
|
||||
len: usize,
|
||||
) {
|
||||
pub fn resize(&mut self, device: &wgpu::Device, size: Vector2<u32>, len: usize) {
|
||||
self.work.set(work_vec(size.x, size.y, len));
|
||||
self.old_len = len;
|
||||
self.output.resize(
|
||||
|
||||
@@ -9,6 +9,7 @@ struct View {
|
||||
reset: u32,
|
||||
level: i32,
|
||||
dims: vec2<u32>,
|
||||
stretch: vec2<f32>,
|
||||
scale: FixedDec,
|
||||
corner_x: FixedDec,
|
||||
corner_y: FixedDec,
|
||||
@@ -28,30 +29,14 @@ fn main(
|
||||
if id.x > view.dims.x - 1 || id.y > view.dims.y - 1 {
|
||||
return;
|
||||
}
|
||||
// TODO: actually use width
|
||||
let varwidth = LEN + 2;
|
||||
let workwidth = varwidth * 2 + 1;
|
||||
let worki = (id.x * view.dims.y + id.y) * workwidth;
|
||||
let xidx = worki + 1;
|
||||
let yidx = xidx + varwidth;
|
||||
|
||||
// let dec = view.corner_x.dec;
|
||||
// var rel_x = FixedDec(POS, dec, array<u32, LEN>());
|
||||
// rel_x.parts[0] = id.x;
|
||||
// rel_x = shr(rel_x, view.level);
|
||||
// var rel_y = FixedDec(POS, dec, array<u32, LEN>());
|
||||
// rel_y.parts[0] = id.y;
|
||||
// rel_y = shr(rel_y, view.level);
|
||||
// let cx = add(view.corner_x, rel_x);
|
||||
// let cy = add(view.corner_y, rel_y);
|
||||
let fdims = vec2<f32>(view.dims);
|
||||
var stretch: vec2<f32>;
|
||||
if fdims.x < fdims.y {
|
||||
stretch = vec2(fdims.x / fdims.y, 1.0);
|
||||
} else {
|
||||
stretch = vec2(1.0, fdims.y / fdims.x);
|
||||
}
|
||||
let fpos = (vec2<f32>(id.xy) / fdims - 0.5) * stretch;
|
||||
let fpos = (vec2<f32>(id.xy) / fdims - 0.5) * view.stretch;
|
||||
let cx = add(mul(from_f32(fpos.x), view.scale), view.corner_x);
|
||||
let cy = add(mul(from_f32(fpos.y), view.scale), view.corner_y);
|
||||
var x: FixedDec;
|
||||
|
||||
@@ -122,17 +122,14 @@ impl Renderer<'_> {
|
||||
}
|
||||
|
||||
pub fn render(&mut self, camera: &Camera, snapshot: bool) {
|
||||
|
||||
// this comes from the fact that I want (0, 2) and (30, 4)
|
||||
// probably a much better formula, or better yet let the user select
|
||||
self.len = (camera.zoom.level() as f32 / 32.0 + 2.0).round() as usize;
|
||||
// at level 0 I want 2, and should increase respective to bits needed for positioning
|
||||
self.len = (camera.zoom.level() / 32) as usize + 2;
|
||||
|
||||
self.compute_pipeline.update(
|
||||
&self.device,
|
||||
&mut self.encoder,
|
||||
&mut self.staging_belt,
|
||||
camera,
|
||||
&self.size,
|
||||
self.len,
|
||||
);
|
||||
self.chunk_view.update(camera, &self.size, snapshot);
|
||||
@@ -168,8 +165,10 @@ impl Renderer<'_> {
|
||||
self.config.width = size.width;
|
||||
self.config.height = size.height;
|
||||
self.surface.configure(&self.device, &self.config);
|
||||
self.compute_pipeline.resize(&self.device, &mut self.encoder, &mut self.staging_belt, self.size, self.len);
|
||||
self.render_pipeline.resize(&self.device, self.size, &self.compute_pipeline.output);
|
||||
self.compute_pipeline
|
||||
.resize(&self.device, self.size, self.len);
|
||||
self.render_pipeline
|
||||
.resize(&self.device, self.size, &self.compute_pipeline.output);
|
||||
}
|
||||
|
||||
fn create_encoder(device: &wgpu::Device) -> wgpu::CommandEncoder {
|
||||
@@ -177,4 +176,8 @@ impl Renderer<'_> {
|
||||
label: Some("Render Encoder"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn size(&self) -> &Vector2<u32> {
|
||||
&self.size
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use nalgebra::Vector2;
|
||||
|
||||
use crate::client::render::CHUNK_POW;
|
||||
|
||||
use super::{Camera, CHUNK_WIDTH};
|
||||
|
||||
#[repr(C, align(8))]
|
||||
@@ -44,10 +42,12 @@ impl WindowView {
|
||||
// let stretch = size.cast::<f32>() * camera.zoom.rel_zoom() / (CHUNK_WIDTH as f32);
|
||||
|
||||
let (pos, stretch) = if let Some(ss_cam) = ss_cam {
|
||||
let aspect = camera.inv_scale(size) * 2.0;
|
||||
let aspect = camera.inv_stretch() * 2.0;
|
||||
let s = camera.zoom.mult() * ss_cam.zoom.inv_mult();
|
||||
(
|
||||
((&camera.pos - &ss_cam.pos) * ss_cam.zoom.inv_mult().clone()).map(f32::from).component_mul(&aspect),
|
||||
((&camera.pos - &ss_cam.pos) * ss_cam.zoom.inv_mult().clone())
|
||||
.map(f32::from)
|
||||
.component_mul(&aspect),
|
||||
Vector2::from_element(f32::from(s)),
|
||||
)
|
||||
} else {
|
||||
|
||||
@@ -21,9 +21,8 @@ var ss_s: sampler;
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) vertex_pos: vec4<f32>,
|
||||
@location(0) world_pos: vec2<f32>,
|
||||
@location(1) tex_pos: vec2<f32>,
|
||||
@location(2) ss_pos: vec2<f32>,
|
||||
@location(0) tex_pos: vec2<f32>,
|
||||
@location(1) ss_pos: vec2<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
@@ -35,22 +34,16 @@ fn vs_main(
|
||||
|
||||
let pos = vec2<f32>(
|
||||
f32(vi % 2u),
|
||||
f32(vi / 2u),
|
||||
f32(1 - vi / 2u),
|
||||
) * 2.0 - 1.0;
|
||||
out.vertex_pos = vec4<f32>(pos.x, -pos.y, 0.0, 1.0);
|
||||
out.world_pos = pos / 2.0;
|
||||
out.world_pos.y *= -1.0;
|
||||
out.world_pos *= view.stretch;
|
||||
out.world_pos += view.pos;
|
||||
out.vertex_pos = vec4<f32>(pos.x, pos.y, 0.0, 1.0);
|
||||
|
||||
let pos2 = vec2<f32>(
|
||||
f32(vi % 2u),
|
||||
f32(vi / 2u),
|
||||
f32(1 - vi / 2u),
|
||||
);
|
||||
out.tex_pos = pos2;
|
||||
out.tex_pos.y = 1.0 - out.tex_pos.y;
|
||||
let pos3 = vec2(pos.x, -pos.y);
|
||||
out.ss_pos = pos3 * view.stretch + view.pos;
|
||||
out.ss_pos = pos * view.stretch + view.pos;
|
||||
out.ss_pos = (out.ss_pos + 1.0) / 2.0;
|
||||
|
||||
return out;
|
||||
@@ -60,16 +53,6 @@ fn vs_main(
|
||||
fn fs_main(
|
||||
in: VertexOutput,
|
||||
) -> @location(0) vec4<f32> {
|
||||
// let a = textureLoad(chunks, vec2<u32>(0), 0, 0);
|
||||
// let rc = vec2<i32>(view.rendered_chunks);
|
||||
// let rcf = vec2<f32>(rc);
|
||||
// let cposi = vec2<i32>(floor(in.world_pos));
|
||||
// let cposu = vec2<i32>(
|
||||
// rem_euclid(cposi.x, rc.x),
|
||||
// rem_euclid(cposi.y, rc.y)
|
||||
// );
|
||||
// let cposf = vec2<f32>(cposu);
|
||||
// return vec4(cposf / rcf, 0.0, 1.0);
|
||||
let cur = textureSample(tex, sam, in.tex_pos);
|
||||
let snp_bounds = all(in.ss_pos >= vec2(0.0)) && all(in.ss_pos <= vec2(1.0));
|
||||
if all(cur.rgb == vec3(0.0)) && snp_bounds {
|
||||
|
||||
@@ -2,15 +2,13 @@ use std::collections::HashSet;
|
||||
|
||||
use nalgebra::Vector2;
|
||||
|
||||
use crate::{client::camera::Camera, util::FixedDec};
|
||||
use crate::client::camera::Camera;
|
||||
|
||||
use super::{output::WindowView, CHUNK_POW};
|
||||
use super::output::WindowView;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ChunkView {
|
||||
pub render: WindowView,
|
||||
pub chunk_queue: HashSet<Vector2<FixedDec>>,
|
||||
pub visible_chunks: HashSet<Vector2<FixedDec>>,
|
||||
pub snapshot: Option<Camera>,
|
||||
}
|
||||
|
||||
@@ -29,42 +27,5 @@ impl ChunkView {
|
||||
return;
|
||||
}
|
||||
self.render = render;
|
||||
|
||||
let corner_offset = ((size / 2).cast() * camera.zoom.rel_zoom())
|
||||
.map(|x| FixedDec::from(x) >> camera.zoom.level());
|
||||
let bot_left = &camera.pos - &corner_offset;
|
||||
let top_right = &camera.pos + &corner_offset;
|
||||
let mult = FixedDec::one() >> (CHUNK_POW as i32 - camera.zoom.level());
|
||||
let blc = bot_left
|
||||
.component_mul(&Vector2::from_element(mult.clone()))
|
||||
.map(FixedDec::floor);
|
||||
let trc = top_right
|
||||
.component_mul(&Vector2::from_element(mult))
|
||||
.map(FixedDec::floor);
|
||||
|
||||
let mut visible = HashSet::new();
|
||||
let mut x = blc.x.clone();
|
||||
// while x <= trc.x {
|
||||
// let mut y = blc.y.clone();
|
||||
// while y <= trc.y {
|
||||
// visible.insert(Vector2::new(x.clone(), y.clone()));
|
||||
// y += FixedDec::one();
|
||||
// }
|
||||
// x += FixedDec::one();
|
||||
// }
|
||||
|
||||
|
||||
let new = visible
|
||||
.difference(&self.visible_chunks)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
let old = self
|
||||
.visible_chunks
|
||||
.difference(&visible)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
self.chunk_queue.retain(|p| !old.contains(p));
|
||||
self.chunk_queue.extend(new);
|
||||
self.visible_chunks = visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#![feature(bigint_helper_methods)]
|
||||
#![feature(int_roundings)]
|
||||
#![feature(let_chains)]
|
||||
|
||||
use client::ClientApp;
|
||||
|
||||
|
||||
@@ -139,6 +139,12 @@ impl FixedDec {
|
||||
pub fn parts(&self) -> &[u32] {
|
||||
&self.parts
|
||||
}
|
||||
|
||||
pub fn negate(&mut self) {
|
||||
if !self.is_zero() {
|
||||
self.sign = !self.sign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FixedDec {
|
||||
|
||||
Reference in New Issue
Block a user