Skip to content

Commit f94f79a

Browse files
committed
web: extract render::screen_to_world_ray and use it in pointer move; no behavior change.
1 parent 5cd08b0 commit f94f79a

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

crates/app-web/src/lib.rs

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use web_sys as web;
1616
// (DeviceExt no longer needed; legacy vertex buffers removed)
1717

1818
mod input;
19+
mod render;
1920
mod ui;
2021

2122
// Rendering/picking shared constants to keep math consistent
@@ -497,30 +498,12 @@ async fn init() -> anyhow::Result<()> {
497498
ms.y = pos.y;
498499
// noisy move debug log removed
499500
// Compute hover or drag update
500-
let width = canvas_mouse.width() as f32;
501-
let height = canvas_mouse.height() as f32;
502-
let ndc_x = (2.0 * pos.x / width) - 1.0;
503-
let ndc_y = 1.0 - (2.0 * pos.y / height);
504-
let aspect = width / height.max(1.0);
505-
let proj = Mat4::perspective_rh(
506-
std::f32::consts::FRAC_PI_4,
507-
aspect,
508-
0.1,
509-
100.0,
501+
let (ro, rd) = render::screen_to_world_ray(
502+
&canvas_mouse,
503+
pos.x,
504+
pos.y,
505+
CAMERA_Z,
510506
);
511-
let view = Mat4::look_at_rh(
512-
Vec3::new(0.0, 0.0, CAMERA_Z),
513-
Vec3::ZERO,
514-
Vec3::Y,
515-
);
516-
let inv = (proj * view).inverse();
517-
let p_near = inv * Vec4::new(ndc_x, ndc_y, 0.0, 1.0);
518-
let p_far = inv * Vec4::new(ndc_x, ndc_y, 1.0, 1.0);
519-
let _p0: Vec3 = p_near.truncate() / p_near.w;
520-
let p1: Vec3 = p_far.truncate() / p_far.w;
521-
// Ray origin from camera eye to improve drag intersection stability
522-
let ro = Vec3::new(0.0, 0.0, CAMERA_Z);
523-
let rd = (p1 - ro).normalize();
524507
let mut best = None::<(usize, f32)>;
525508
let spread = SPREAD;
526509
let z_offset = z_offset_vec3();

crates/app-web/src/render.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use glam::{Mat4, Vec3, Vec4};
2+
use web_sys as web;
3+
4+
#[inline]
5+
pub fn screen_to_world_ray(
6+
canvas: &web::HtmlCanvasElement,
7+
sx: f32,
8+
sy: f32,
9+
camera_z: f32,
10+
) -> (Vec3, Vec3) {
11+
let width = canvas.width() as f32;
12+
let height = canvas.height() as f32;
13+
let ndc_x = (2.0 * sx / width) - 1.0;
14+
let ndc_y = 1.0 - (2.0 * sy / height);
15+
let aspect = width / height.max(1.0);
16+
let proj = Mat4::perspective_rh(std::f32::consts::FRAC_PI_4, aspect, 0.1, 100.0);
17+
let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, camera_z), Vec3::ZERO, Vec3::Y);
18+
let inv = (proj * view).inverse();
19+
let p_near = inv * Vec4::new(ndc_x, ndc_y, 0.0, 1.0);
20+
let p_far = inv * Vec4::new(ndc_x, ndc_y, 1.0, 1.0);
21+
let _p0: Vec3 = p_near.truncate() / p_near.w;
22+
let p1: Vec3 = p_far.truncate() / p_far.w;
23+
let ro = Vec3::new(0.0, 0.0, camera_z);
24+
let rd = (p1 - ro).normalize();
25+
(ro, rd)
26+
}

0 commit comments

Comments
 (0)