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
|
## Controls
|
||||||
|
|
||||||
- WASD for movement
|
- WASD or left click & drag for movement
|
||||||
- Scroll to zoom
|
- 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.
|
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 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 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
|
- 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
|
## Cool Screenshots
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
use std::ops::AddAssign;
|
use std::ops::{AddAssign, Neg};
|
||||||
|
|
||||||
use crate::util::FixedDec;
|
use crate::util::FixedDec;
|
||||||
|
|
||||||
@@ -15,20 +15,44 @@ pub struct Zoom {
|
|||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
pub pos: Vector2<FixedDec>,
|
pub pos: Vector2<FixedDec>,
|
||||||
pub zoom: Zoom,
|
pub zoom: Zoom,
|
||||||
|
pub size: Vector2<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
pub fn scale(&self, size: &Vector2<u32>) -> Vector2<f32> {
|
pub fn world_pos(&self, screen_pos: Vector2<f32>) -> Vector2<FixedDec> {
|
||||||
let fsize: Vector2<f32> = size.cast();
|
let mut pos = screen_pos
|
||||||
if size.x < size.y {
|
.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)
|
Vector2::new(fsize.x / fsize.y, 1.0)
|
||||||
} else {
|
} else {
|
||||||
Vector2::new(1.0, fsize.y / fsize.x)
|
Vector2::new(1.0, fsize.y / fsize.x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn inv_scale(&self, size: &Vector2<u32>) -> Vector2<f32> {
|
|
||||||
let fsize: Vector2<f32> = size.cast();
|
pub fn inv_stretch(&self) -> Vector2<f32> {
|
||||||
if size.x < size.y {
|
let fsize: Vector2<f32> = self.size.cast();
|
||||||
|
if self.size.x < self.size.y {
|
||||||
Vector2::new(fsize.y / fsize.x, 1.0)
|
Vector2::new(fsize.y / fsize.x, 1.0)
|
||||||
} else {
|
} else {
|
||||||
Vector2::new(1.0, fsize.x / fsize.y)
|
Vector2::new(1.0, fsize.x / fsize.y)
|
||||||
@@ -39,6 +63,7 @@ impl Camera {
|
|||||||
impl Default for Camera {
|
impl Default for Camera {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
size: Vector2::zeros(),
|
||||||
pos: Vector2::new(-0.5, 0.0).map(FixedDec::from),
|
pos: Vector2::new(-0.5, 0.0).map(FixedDec::from),
|
||||||
zoom: Zoom::new(0, 2.1),
|
zoom: Zoom::new(0, 2.1),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,46 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use winit::keyboard::KeyCode as K;
|
use winit::{event::MouseButton, keyboard::KeyCode as K};
|
||||||
|
|
||||||
use crate::util::FixedDec;
|
use crate::util::FixedDec;
|
||||||
|
|
||||||
use super::Client;
|
use super::Client;
|
||||||
|
|
||||||
|
pub struct InputHandling {
|
||||||
|
pub snapshot: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputHandling {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { snapshot: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Client<'_> {
|
impl Client<'_> {
|
||||||
pub fn handle_input(&mut self, delta: Duration) {
|
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();
|
let per_sec = delta.as_secs_f32();
|
||||||
|
|
||||||
if input.scroll_delta != 0.0 {
|
if input.scroll_delta != 0.0 {
|
||||||
|
let old_pos = camera.world_pos(input.mouse_pos);
|
||||||
camera.zoom += input.scroll_delta / 5.0;
|
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();
|
let speed = FixedDec::from(per_sec * 0.5) * camera.zoom.mult();
|
||||||
@@ -28,8 +56,8 @@ impl Client<'_> {
|
|||||||
if input.pressed(K::KeyD) {
|
if input.pressed(K::KeyD) {
|
||||||
camera.pos.x += &speed;
|
camera.pos.x += &speed;
|
||||||
}
|
}
|
||||||
if input.pressed(K::KeyQ) {
|
if input.just_pressed(K::KeyQ) || input.mouse_just_pressed(MouseButton::Right) {
|
||||||
self.snapshot = true;
|
handling.snapshot = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use winit::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
pub mouse_pixel_pos: Vector2<f32>,
|
pub mouse_pos: Vector2<f32>,
|
||||||
pub mouse_delta: Vector2<f32>,
|
pub mouse_delta: Vector2<f32>,
|
||||||
|
|
||||||
pressed: HashSet<KeyCode>,
|
pressed: HashSet<KeyCode>,
|
||||||
@@ -23,7 +23,7 @@ pub struct Input {
|
|||||||
impl Input {
|
impl Input {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mouse_pixel_pos: Vector2::zeros(),
|
mouse_pos: Vector2::zeros(),
|
||||||
mouse_delta: Vector2::zeros(),
|
mouse_delta: Vector2::zeros(),
|
||||||
pressed: HashSet::new(),
|
pressed: HashSet::new(),
|
||||||
just_pressed: HashSet::new(),
|
just_pressed: HashSet::new(),
|
||||||
@@ -67,11 +67,10 @@ impl Input {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
WindowEvent::CursorLeft { .. } => {
|
WindowEvent::CursorLeft { .. } => {
|
||||||
self.pressed.clear();
|
self.clear();
|
||||||
self.mouse_pressed.clear();
|
|
||||||
}
|
}
|
||||||
WindowEvent::CursorMoved { position, .. } => {
|
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 {
|
WindowEvent::MouseInput { button, state, .. } => match state {
|
||||||
ElementState::Pressed => {
|
ElementState::Pressed => {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::{sync::Arc, time::Instant};
|
use std::{sync::Arc, time::Instant};
|
||||||
|
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
|
use handle_input::InputHandling;
|
||||||
use input::Input;
|
use input::Input;
|
||||||
use render::Renderer;
|
use render::Renderer;
|
||||||
use winit::{
|
use winit::{
|
||||||
@@ -23,7 +24,7 @@ pub struct Client<'a> {
|
|||||||
exit: bool,
|
exit: bool,
|
||||||
prev_update: Instant,
|
prev_update: Instant,
|
||||||
renderer: Renderer<'a>,
|
renderer: Renderer<'a>,
|
||||||
snapshot: bool,
|
handling: InputHandling,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client<'_> {
|
impl Client<'_> {
|
||||||
@@ -41,7 +42,7 @@ impl Client<'_> {
|
|||||||
exit: false,
|
exit: false,
|
||||||
prev_update: Instant::now(),
|
prev_update: Instant::now(),
|
||||||
renderer,
|
renderer,
|
||||||
snapshot: false,
|
handling: InputHandling::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,16 +61,17 @@ impl Client<'_> {
|
|||||||
pub fn window_event(&mut self, event: WindowEvent) {
|
pub fn window_event(&mut self, event: WindowEvent) {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::CloseRequested => self.exit = true,
|
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 => {
|
WindowEvent::RedrawRequested => {
|
||||||
self.renderer.render(&self.camera, self.snapshot);
|
self.renderer.render(&self.camera, self.handling.snapshot);
|
||||||
self.snapshot = false;
|
self.handling.snapshot = false;
|
||||||
self.window.request_redraw();
|
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 {
|
impl Default for ComputeView {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let val = FixedDec::from_parts(false, 0, vec![0, 0, 0]);
|
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(
|
fn new(
|
||||||
reset: bool,
|
reset: bool,
|
||||||
dims: Vector2<u32>,
|
dims: Vector2<u32>,
|
||||||
|
stretch: Vector2<f32>,
|
||||||
level: i32,
|
level: i32,
|
||||||
scale: &FixedDec,
|
scale: &FixedDec,
|
||||||
x: &FixedDec,
|
x: &FixedDec,
|
||||||
@@ -36,6 +37,7 @@ impl ComputeView {
|
|||||||
bytes.extend((reset as u32).to_le_bytes());
|
bytes.extend((reset as u32).to_le_bytes());
|
||||||
bytes.extend(level.to_le_bytes());
|
bytes.extend(level.to_le_bytes());
|
||||||
bytes.extend(bytemuck::cast_slice(&[dims.x, dims.y]));
|
bytes.extend(bytemuck::cast_slice(&[dims.x, dims.y]));
|
||||||
|
bytes.extend(bytemuck::cast_slice(&[stretch.x, stretch.y]));
|
||||||
scale.to_bytes(&mut bytes);
|
scale.to_bytes(&mut bytes);
|
||||||
x.to_bytes(&mut bytes);
|
x.to_bytes(&mut bytes);
|
||||||
y.to_bytes(&mut bytes);
|
y.to_bytes(&mut bytes);
|
||||||
@@ -46,7 +48,7 @@ impl ComputeView {
|
|||||||
Self { bytes }
|
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();
|
let mut x = camera.pos.x.clone();
|
||||||
x.set_whole_len(1);
|
x.set_whole_len(1);
|
||||||
x.set_dec_len(len as i32 - 1);
|
x.set_dec_len(len as i32 - 1);
|
||||||
@@ -54,17 +56,11 @@ impl ComputeView {
|
|||||||
y.set_whole_len(1);
|
y.set_whole_len(1);
|
||||||
y.set_dec_len(len as i32 - 1);
|
y.set_dec_len(len as i32 - 1);
|
||||||
|
|
||||||
let fsize: Vector2<f32> = size.cast();
|
let stretch = camera.stretch();
|
||||||
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 mut scale = camera.zoom.mult().clone();
|
let mut scale = camera.zoom.mult().clone();
|
||||||
scale.set_precision(len);
|
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,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
belt: &mut wgpu::util::StagingBelt,
|
belt: &mut wgpu::util::StagingBelt,
|
||||||
camera: &Camera,
|
camera: &Camera,
|
||||||
size: &Vector2<u32>,
|
|
||||||
len: usize,
|
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 {
|
if view != self.old_view {
|
||||||
for (i, b) in 1u32.to_le_bytes().iter().enumerate() {
|
for (i, b) in 1u32.to_le_bytes().iter().enumerate() {
|
||||||
view.bytes[i] = *b;
|
view.bytes[i] = *b;
|
||||||
@@ -49,7 +48,7 @@ impl ComputePipeline {
|
|||||||
println!("new len: {}", len);
|
println!("new len: {}", len);
|
||||||
self.old_len = len;
|
self.old_len = len;
|
||||||
self.pipeline = self.pipeline(device, &Self::shader(device, 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)
|
let updated = self.work.update(device, encoder, belt)
|
||||||
| self.view.update(device, encoder, belt, view.bytes());
|
| self.view.update(device, encoder, belt, view.bytes());
|
||||||
@@ -66,14 +65,7 @@ impl ComputePipeline {
|
|||||||
pass.dispatch_workgroups(240, 135, 1);
|
pass.dispatch_workgroups(240, 135, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(
|
pub fn resize(&mut self, device: &wgpu::Device, size: Vector2<u32>, len: usize) {
|
||||||
&mut self,
|
|
||||||
device: &wgpu::Device,
|
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
|
||||||
belt: &mut wgpu::util::StagingBelt,
|
|
||||||
size: Vector2<u32>,
|
|
||||||
len: usize,
|
|
||||||
) {
|
|
||||||
self.work.set(work_vec(size.x, size.y, len));
|
self.work.set(work_vec(size.x, size.y, len));
|
||||||
self.old_len = len;
|
self.old_len = len;
|
||||||
self.output.resize(
|
self.output.resize(
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ struct View {
|
|||||||
reset: u32,
|
reset: u32,
|
||||||
level: i32,
|
level: i32,
|
||||||
dims: vec2<u32>,
|
dims: vec2<u32>,
|
||||||
|
stretch: vec2<f32>,
|
||||||
scale: FixedDec,
|
scale: FixedDec,
|
||||||
corner_x: FixedDec,
|
corner_x: FixedDec,
|
||||||
corner_y: FixedDec,
|
corner_y: FixedDec,
|
||||||
@@ -28,30 +29,14 @@ fn main(
|
|||||||
if id.x > view.dims.x - 1 || id.y > view.dims.y - 1 {
|
if id.x > view.dims.x - 1 || id.y > view.dims.y - 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: actually use width
|
|
||||||
let varwidth = LEN + 2;
|
let varwidth = LEN + 2;
|
||||||
let workwidth = varwidth * 2 + 1;
|
let workwidth = varwidth * 2 + 1;
|
||||||
let worki = (id.x * view.dims.y + id.y) * workwidth;
|
let worki = (id.x * view.dims.y + id.y) * workwidth;
|
||||||
let xidx = worki + 1;
|
let xidx = worki + 1;
|
||||||
let yidx = xidx + varwidth;
|
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);
|
let fdims = vec2<f32>(view.dims);
|
||||||
var stretch: vec2<f32>;
|
let fpos = (vec2<f32>(id.xy) / fdims - 0.5) * view.stretch;
|
||||||
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 cx = add(mul(from_f32(fpos.x), view.scale), view.corner_x);
|
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);
|
let cy = add(mul(from_f32(fpos.y), view.scale), view.corner_y);
|
||||||
var x: FixedDec;
|
var x: FixedDec;
|
||||||
|
|||||||
@@ -122,17 +122,14 @@ impl Renderer<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self, camera: &Camera, snapshot: bool) {
|
pub fn render(&mut self, camera: &Camera, snapshot: bool) {
|
||||||
|
// at level 0 I want 2, and should increase respective to bits needed for positioning
|
||||||
// this comes from the fact that I want (0, 2) and (30, 4)
|
self.len = (camera.zoom.level() / 32) as usize + 2;
|
||||||
// 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;
|
|
||||||
|
|
||||||
self.compute_pipeline.update(
|
self.compute_pipeline.update(
|
||||||
&self.device,
|
&self.device,
|
||||||
&mut self.encoder,
|
&mut self.encoder,
|
||||||
&mut self.staging_belt,
|
&mut self.staging_belt,
|
||||||
camera,
|
camera,
|
||||||
&self.size,
|
|
||||||
self.len,
|
self.len,
|
||||||
);
|
);
|
||||||
self.chunk_view.update(camera, &self.size, snapshot);
|
self.chunk_view.update(camera, &self.size, snapshot);
|
||||||
@@ -168,8 +165,10 @@ impl Renderer<'_> {
|
|||||||
self.config.width = size.width;
|
self.config.width = size.width;
|
||||||
self.config.height = size.height;
|
self.config.height = size.height;
|
||||||
self.surface.configure(&self.device, &self.config);
|
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.compute_pipeline
|
||||||
self.render_pipeline.resize(&self.device, self.size, &self.compute_pipeline.output);
|
.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 {
|
fn create_encoder(device: &wgpu::Device) -> wgpu::CommandEncoder {
|
||||||
@@ -177,4 +176,8 @@ impl Renderer<'_> {
|
|||||||
label: Some("Render Encoder"),
|
label: Some("Render Encoder"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> &Vector2<u32> {
|
||||||
|
&self.size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
|
|
||||||
use crate::client::render::CHUNK_POW;
|
|
||||||
|
|
||||||
use super::{Camera, CHUNK_WIDTH};
|
use super::{Camera, CHUNK_WIDTH};
|
||||||
|
|
||||||
#[repr(C, align(8))]
|
#[repr(C, align(8))]
|
||||||
@@ -44,10 +42,12 @@ impl WindowView {
|
|||||||
// let stretch = size.cast::<f32>() * camera.zoom.rel_zoom() / (CHUNK_WIDTH as f32);
|
// let stretch = size.cast::<f32>() * camera.zoom.rel_zoom() / (CHUNK_WIDTH as f32);
|
||||||
|
|
||||||
let (pos, stretch) = if let Some(ss_cam) = ss_cam {
|
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();
|
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)),
|
Vector2::from_element(f32::from(s)),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ var ss_s: sampler;
|
|||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@builtin(position) vertex_pos: vec4<f32>,
|
@builtin(position) vertex_pos: vec4<f32>,
|
||||||
@location(0) world_pos: vec2<f32>,
|
@location(0) tex_pos: vec2<f32>,
|
||||||
@location(1) tex_pos: vec2<f32>,
|
@location(1) ss_pos: vec2<f32>,
|
||||||
@location(2) ss_pos: vec2<f32>,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
@@ -35,22 +34,16 @@ fn vs_main(
|
|||||||
|
|
||||||
let pos = vec2<f32>(
|
let pos = vec2<f32>(
|
||||||
f32(vi % 2u),
|
f32(vi % 2u),
|
||||||
f32(vi / 2u),
|
f32(1 - vi / 2u),
|
||||||
) * 2.0 - 1.0;
|
) * 2.0 - 1.0;
|
||||||
out.vertex_pos = vec4<f32>(pos.x, -pos.y, 0.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;
|
|
||||||
|
|
||||||
let pos2 = vec2<f32>(
|
let pos2 = vec2<f32>(
|
||||||
f32(vi % 2u),
|
f32(vi % 2u),
|
||||||
f32(vi / 2u),
|
f32(1 - vi / 2u),
|
||||||
);
|
);
|
||||||
out.tex_pos = pos2;
|
out.tex_pos = pos2;
|
||||||
out.tex_pos.y = 1.0 - out.tex_pos.y;
|
out.ss_pos = pos * view.stretch + view.pos;
|
||||||
let pos3 = vec2(pos.x, -pos.y);
|
|
||||||
out.ss_pos = pos3 * view.stretch + view.pos;
|
|
||||||
out.ss_pos = (out.ss_pos + 1.0) / 2.0;
|
out.ss_pos = (out.ss_pos + 1.0) / 2.0;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -60,16 +53,6 @@ fn vs_main(
|
|||||||
fn fs_main(
|
fn fs_main(
|
||||||
in: VertexOutput,
|
in: VertexOutput,
|
||||||
) -> @location(0) vec4<f32> {
|
) -> @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 cur = textureSample(tex, sam, in.tex_pos);
|
||||||
let snp_bounds = all(in.ss_pos >= vec2(0.0)) && all(in.ss_pos <= vec2(1.0));
|
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 {
|
if all(cur.rgb == vec3(0.0)) && snp_bounds {
|
||||||
|
|||||||
@@ -2,15 +2,13 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use nalgebra::Vector2;
|
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)]
|
#[derive(Default)]
|
||||||
pub struct ChunkView {
|
pub struct ChunkView {
|
||||||
pub render: WindowView,
|
pub render: WindowView,
|
||||||
pub chunk_queue: HashSet<Vector2<FixedDec>>,
|
|
||||||
pub visible_chunks: HashSet<Vector2<FixedDec>>,
|
|
||||||
pub snapshot: Option<Camera>,
|
pub snapshot: Option<Camera>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,42 +27,5 @@ impl ChunkView {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.render = render;
|
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(bigint_helper_methods)]
|
||||||
#![feature(int_roundings)]
|
#![feature(int_roundings)]
|
||||||
|
#![feature(let_chains)]
|
||||||
|
|
||||||
use client::ClientApp;
|
use client::ClientApp;
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,12 @@ impl FixedDec {
|
|||||||
pub fn parts(&self) -> &[u32] {
|
pub fn parts(&self) -> &[u32] {
|
||||||
&self.parts
|
&self.parts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn negate(&mut self) {
|
||||||
|
if !self.is_zero() {
|
||||||
|
self.sign = !self.sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FixedDec {
|
impl Display for FixedDec {
|
||||||
|
|||||||
Reference in New Issue
Block a user