refactor: remove dead input and readback paths
Amp-Thread-ID: https://ampcode.com/threads/T-019f9d91-77c1-7206-a60f-ed6554ce92ab Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -22,7 +22,6 @@ pub struct EventListeners {
|
||||
pub click_listener: Option<Closure<dyn FnMut(web_sys::MouseEvent)>>,
|
||||
pub wheel_listener: Option<Closure<dyn FnMut(web_sys::WheelEvent)>>,
|
||||
pub contextmenu_listener: Option<Closure<dyn FnMut(web_sys::MouseEvent)>>,
|
||||
pub keyboard_listener: Option<Closure<dyn FnMut(web_sys::KeyboardEvent)>>,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
@@ -34,7 +33,6 @@ impl EventListeners {
|
||||
click_listener: None,
|
||||
wheel_listener: None,
|
||||
contextmenu_listener: None,
|
||||
keyboard_listener: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,26 +151,12 @@ pub fn setup_event_listeners(
|
||||
contextmenu_listener.as_ref().unchecked_ref(),
|
||||
)?;
|
||||
|
||||
let keyboard_worker_chan = worker_chan.clone();
|
||||
let keyboard_listener: Closure<dyn FnMut(web_sys::KeyboardEvent)> =
|
||||
Closure::new(move |event: web_sys::KeyboardEvent| {
|
||||
use crate::message::KeyboardMessage;
|
||||
|
||||
let keyboard_event_data = KeyboardMessage::from_evt(event);
|
||||
|
||||
let _ = keyboard_worker_chan.send(WindowEvent::Keyboard(keyboard_event_data));
|
||||
});
|
||||
|
||||
window
|
||||
.add_event_listener_with_callback("keydown", keyboard_listener.as_ref().unchecked_ref())?;
|
||||
|
||||
Ok(EventListeners {
|
||||
resize_listener: Some(resize_listener),
|
||||
pointer_listener: Some(pointer_listener),
|
||||
click_listener: Some(click_listener),
|
||||
wheel_listener: Some(wheel_listener),
|
||||
contextmenu_listener: Some(contextmenu_listener),
|
||||
keyboard_listener: Some(keyboard_listener),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -42,20 +42,6 @@ pub enum WindowEvent {
|
||||
PointerMove(MouseMessage),
|
||||
PointerClick(MouseMessage),
|
||||
PointerWheel(WheelMessage),
|
||||
Keyboard(KeyboardMessage),
|
||||
}
|
||||
|
||||
// Display for WindowEvent
|
||||
impl fmt::Display for WindowEvent {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
WindowEvent::Resize(msg) => write!(f, "Resize: {:?}", msg),
|
||||
WindowEvent::PointerMove(msg) => write!(f, "PointerMove: {:?}", msg),
|
||||
WindowEvent::PointerClick(msg) => write!(f, "PointerClick: {:?}", msg),
|
||||
WindowEvent::PointerWheel(msg) => write!(f, "PointerWheel: {:?}", msg),
|
||||
WindowEvent::Keyboard(msg) => write!(f, "Keyboard: {:?}", msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -68,10 +54,7 @@ pub struct ResizeMessage {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MouseMessage {
|
||||
pub scale_factor: f64,
|
||||
pub button: f64,
|
||||
pub buttons: u16,
|
||||
pub client_x: f64,
|
||||
pub client_y: f64,
|
||||
pub movement_x: f64,
|
||||
pub movement_y: f64,
|
||||
pub offset_x: f64,
|
||||
@@ -84,10 +67,7 @@ impl MouseMessage {
|
||||
let window = web_sys::window().unwrap();
|
||||
Self {
|
||||
scale_factor: window.device_pixel_ratio(),
|
||||
button: event.button() as f64,
|
||||
buttons: event.buttons(),
|
||||
client_x: event.client_x() as f64,
|
||||
client_y: event.client_y() as f64,
|
||||
movement_x: event.movement_x() as f64,
|
||||
movement_y: event.movement_y() as f64,
|
||||
offset_x: event.offset_x() as f64,
|
||||
@@ -113,33 +93,6 @@ impl WheelMessage {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KeyboardMessage {
|
||||
pub key: String,
|
||||
pub code: String,
|
||||
pub alt_key: bool,
|
||||
pub ctrl_key: bool,
|
||||
pub meta_key: bool,
|
||||
pub shift_key: bool,
|
||||
pub location: u32,
|
||||
pub repeat: bool,
|
||||
}
|
||||
|
||||
impl KeyboardMessage {
|
||||
pub fn from_evt(event: web_sys::KeyboardEvent) -> Self {
|
||||
Self {
|
||||
key: event.key(),
|
||||
code: event.code(),
|
||||
alt_key: event.alt_key(),
|
||||
ctrl_key: event.ctrl_key(),
|
||||
meta_key: event.meta_key(),
|
||||
shift_key: event.shift_key(),
|
||||
location: event.location(),
|
||||
repeat: event.repeat(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DrainEventError {
|
||||
BorrowError(BorrowMutError),
|
||||
|
||||
@@ -136,13 +136,14 @@ pub fn generate_wgsl(plan: &InstanceTraversalPlan) -> Result<String, String> {
|
||||
fixed_index(*index, 32, "u32 bit projection")?;
|
||||
format!("(({} & (1u<<{}u))!=0u)", x(*value), index)
|
||||
}
|
||||
ExpressionOp::U32Construct { bits } => bits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(bit, id)| format!("select(0u,{}u,{})", 1u32 << bit, x(*id)))
|
||||
.collect::<Vec<_>>()
|
||||
.join("|")
|
||||
.pipe(|terms| format!("({terms})")),
|
||||
ExpressionOp::U32Construct { bits } => format!(
|
||||
"({})",
|
||||
bits.iter()
|
||||
.enumerate()
|
||||
.map(|(bit, id)| format!("select(0u,{}u,{})", 1u32 << bit, x(*id)))
|
||||
.collect::<Vec<_>>()
|
||||
.join("|")
|
||||
),
|
||||
ExpressionOp::AabbMin { aabb } => format!("{}.min", x(*aabb)),
|
||||
ExpressionOp::AabbMax { aabb } => format!("{}.max", x(*aabb)),
|
||||
ExpressionOp::FrustumCulled { local_aabb, .. } => {
|
||||
@@ -201,13 +202,6 @@ fn matrix_literal<const N: usize>(name: &str, columns: &[[f32; N]; N]) -> Result
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(format!("{name}({})", values.join(",")))
|
||||
}
|
||||
trait Pipe: Sized {
|
||||
fn pipe<R>(self, f: impl FnOnce(Self) -> R) -> R {
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
impl<T> Pipe for T {}
|
||||
|
||||
pub fn dispatch_count(instances: u32, pipelines: u32) -> u32 {
|
||||
if pipelines == 0 {
|
||||
0
|
||||
@@ -403,6 +397,19 @@ impl TraversalGpu {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::render_graph::{Expression, ExpressionPlan, NodeOutputRef};
|
||||
|
||||
fn expression(semantic_type: SemanticType, op: ExpressionOp) -> Expression {
|
||||
Expression {
|
||||
semantic_type,
|
||||
op,
|
||||
origin: NodeOutputRef {
|
||||
node: "test".into(),
|
||||
socket: "value".into(),
|
||||
},
|
||||
mesh_provenance: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipeline_major_offsets_and_single_dispatch_are_deterministic() {
|
||||
@@ -424,4 +431,44 @@ mod tests {
|
||||
assert!(fixed_index(3, 3, "vector projection").is_err());
|
||||
assert_eq!(wgsl_type(&SemanticType::Mat4).unwrap(), "mat4x4<f32>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u32_construct_wgsl_is_parenthesized() {
|
||||
let plan = InstanceTraversalPlan {
|
||||
mesh: 0,
|
||||
expressions: ExpressionPlan {
|
||||
expressions: vec![
|
||||
expression(
|
||||
SemanticType::Bool,
|
||||
ExpressionOp::Literal {
|
||||
literal: TypedLiteral::Bool(true),
|
||||
},
|
||||
),
|
||||
expression(
|
||||
SemanticType::Bool,
|
||||
ExpressionOp::Literal {
|
||||
literal: TypedLiteral::Bool(false),
|
||||
},
|
||||
),
|
||||
expression(
|
||||
SemanticType::U32,
|
||||
ExpressionOp::U32Construct {
|
||||
bits: vec![
|
||||
crate::render_graph::ExprId(0),
|
||||
crate::render_graph::ExprId(1),
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
pipelines: vec![],
|
||||
requires_camera: false,
|
||||
};
|
||||
|
||||
let wgsl = generate_wgsl(&plan).unwrap();
|
||||
assert_eq!(
|
||||
wgsl.lines().find(|line| line.starts_with("let e2=")),
|
||||
Some("let e2=(select(0u,1u,e0)|select(0u,2u,e1));")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::{cell::RefCell, rc::Rc, sync::mpsc::Receiver};
|
||||
|
||||
use futures::channel::oneshot;
|
||||
use log::info;
|
||||
use ultraviolet::Vec4;
|
||||
use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use web_sys::DedicatedWorkerGlobalScope;
|
||||
@@ -1632,7 +1630,7 @@ impl<T: Scene + 'static> Renderer<T> {
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: DEPTH_FORMAT,
|
||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC,
|
||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||
view_formats: &[],
|
||||
});
|
||||
|
||||
@@ -2860,98 +2858,6 @@ impl<T: Scene + 'static> Renderer<T> {
|
||||
let _ = global.post_message(&value);
|
||||
}
|
||||
|
||||
pub async fn read_pixel_from_texture(&self, x: u32, y: u32) -> Vec4 {
|
||||
let width = self.context.depth_texture.width();
|
||||
let height = self.context.depth_texture.height();
|
||||
|
||||
if width == 0 || height == 0 {
|
||||
log::warn!("Depth texture has zero extent ({} x {})", width, height);
|
||||
return Vec4::zero();
|
||||
}
|
||||
|
||||
// Validate coordinates
|
||||
if x >= width || y >= height {
|
||||
log::warn!(
|
||||
"Pixel coordinates ({}, {}) out of bounds for texture size {}x{}",
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height
|
||||
);
|
||||
return Vec4::zero();
|
||||
}
|
||||
|
||||
let pixel_size = std::mem::size_of::<f32>() as u32;
|
||||
let unpadded_row_bytes = width * pixel_size;
|
||||
let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
|
||||
let padded_row_bytes = if unpadded_row_bytes % align == 0 {
|
||||
unpadded_row_bytes
|
||||
} else {
|
||||
(unpadded_row_bytes / align + 1) * align
|
||||
};
|
||||
let buffer_size = padded_row_bytes as u64 * height as u64;
|
||||
let buffer = self.context.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("depth pixel read buffer"),
|
||||
size: buffer_size,
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
// Copy just the single pixel
|
||||
let mut encoder =
|
||||
self.context
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("copy depth pixel to buffer"),
|
||||
});
|
||||
|
||||
encoder.copy_texture_to_buffer(
|
||||
wgpu::TexelCopyTextureInfo {
|
||||
texture: &self.context.depth_texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
|
||||
aspect: wgpu::TextureAspect::DepthOnly,
|
||||
},
|
||||
wgpu::TexelCopyBufferInfo {
|
||||
buffer: &buffer,
|
||||
layout: wgpu::TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(padded_row_bytes),
|
||||
rows_per_image: Some(height),
|
||||
},
|
||||
},
|
||||
wgpu::Extent3d {
|
||||
width,
|
||||
height,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
);
|
||||
|
||||
self.context.queue.submit(std::iter::once(encoder.finish()));
|
||||
|
||||
// Map the buffer and read the pixel
|
||||
let slice = buffer.slice(..);
|
||||
let (tx, rx) = oneshot::channel();
|
||||
slice.map_async(wgpu::MapMode::Read, move |result| {
|
||||
tx.send(result).unwrap();
|
||||
});
|
||||
|
||||
// Poll the device to process the mapping
|
||||
|
||||
rx.await.unwrap().unwrap();
|
||||
let depth_value = {
|
||||
let data = slice.get_mapped_range();
|
||||
let row_pitch = padded_row_bytes as usize;
|
||||
let byte_offset = y as usize * row_pitch + x as usize * pixel_size as usize;
|
||||
let mut depth_bytes = [0u8; 4];
|
||||
depth_bytes.copy_from_slice(&data[byte_offset..byte_offset + 4]);
|
||||
f32::from_le_bytes(depth_bytes)
|
||||
};
|
||||
buffer.unmap();
|
||||
|
||||
Vec4::new(depth_value, 0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
pub async fn handle_event(renderer: Rc<RefCell<Self>>, event: WindowEvent) {
|
||||
match event {
|
||||
WindowEvent::PointerMove(msg) => {
|
||||
@@ -2961,36 +2867,18 @@ impl<T: Scene + 'static> Renderer<T> {
|
||||
renderer.borrow_mut().resize(msg);
|
||||
}
|
||||
WindowEvent::PointerClick(msg) => {
|
||||
{
|
||||
log::info!("click start");
|
||||
log::info!("click start");
|
||||
|
||||
let mut r = renderer.borrow_mut();
|
||||
let x = (msg.offset_x * msg.scale_factor) as f32;
|
||||
let y = (msg.offset_y * msg.scale_factor) as f32;
|
||||
r.scene.handle_mouse_click(x, y);
|
||||
log::info!("clicked");
|
||||
}
|
||||
|
||||
// Read pixel from depth texture at click coordinates
|
||||
// let renderer_clone = renderer.clone();
|
||||
// let x_coord = msg.offset_x as u32;
|
||||
// let y_coord = msg.offset_y as u32;
|
||||
// let pixel_value = renderer_clone
|
||||
// .borrow()
|
||||
// .read_pixel_from_texture(x_coord, y_coord)
|
||||
// .await;
|
||||
// log::info!(
|
||||
// "Depth pixel at ({}, {}): {:?}",
|
||||
// x_coord,
|
||||
// y_coord,
|
||||
// pixel_value
|
||||
// );
|
||||
let mut r = renderer.borrow_mut();
|
||||
let x = (msg.offset_x * msg.scale_factor) as f32;
|
||||
let y = (msg.offset_y * msg.scale_factor) as f32;
|
||||
r.scene.handle_mouse_click(x, y);
|
||||
log::info!("clicked");
|
||||
}
|
||||
WindowEvent::PointerWheel(msg) => {
|
||||
let mut r = renderer.borrow_mut();
|
||||
r.scene.handle_zoom(msg.delta_y_pixels);
|
||||
}
|
||||
WindowEvent::Keyboard(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user