mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #24776 - jdm:xr-translate, r=Manishearth
Support translation in webxr on desktop This makes it possible to roam around webxr scenes using the WASD keys, and the arrow keys continue to change the user's orientation. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #24773 - [x] These changes do not require tests because no tests for interactive webxr content
This commit is contained in:
commit
e07f0280fe
3 changed files with 49 additions and 6 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -6011,7 +6011,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "webxr"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/webxr#0ae9b56ef7e646c54382f75fe79012e0f889363d"
|
||||
source = "git+https://github.com/servo/webxr#27c83fde49d820bc3ffd0396d9aea01a3b5c5729"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"euclid",
|
||||
|
@ -6031,7 +6031,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "webxr-api"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/webxr#0ae9b56ef7e646c54382f75fe79012e0f889363d"
|
||||
source = "git+https://github.com/servo/webxr#27c83fde49d820bc3ffd0396d9aea01a3b5c5729"
|
||||
dependencies = [
|
||||
"euclid",
|
||||
"ipc-channel",
|
||||
|
|
|
@ -9,7 +9,10 @@ use crate::context::GlContext;
|
|||
use crate::events_loop::EventsLoop;
|
||||
use crate::keyutils::keyboard_event_from_winit;
|
||||
use crate::window_trait::{WindowPortsMethods, LINE_HEIGHT};
|
||||
use euclid::{Angle, default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector2D};
|
||||
use euclid::{
|
||||
Angle, default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit,
|
||||
Vector2D, Vector3D,
|
||||
};
|
||||
use gleam::gl;
|
||||
use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||
#[cfg(target_os = "macos")]
|
||||
|
@ -71,6 +74,7 @@ pub struct Window {
|
|||
fullscreen: Cell<bool>,
|
||||
gl: Rc<dyn gl::Gl>,
|
||||
xr_rotation: Cell<Rotation3D<f32, UnknownUnit, UnknownUnit>>,
|
||||
xr_translation: Cell<Vector3D<f32, UnknownUnit>>,
|
||||
angle: bool,
|
||||
enable_vsync: bool,
|
||||
use_msaa: bool,
|
||||
|
@ -206,6 +210,7 @@ impl Window {
|
|||
primary_monitor,
|
||||
screen_size,
|
||||
xr_rotation: Cell::new(Rotation3D::identity()),
|
||||
xr_translation: Cell::new(Vector3D::zero()),
|
||||
angle,
|
||||
enable_vsync,
|
||||
use_msaa,
|
||||
|
@ -240,6 +245,7 @@ impl Window {
|
|||
KeyboardEvent::default()
|
||||
};
|
||||
event.key = Key::Character(ch.to_string());
|
||||
self.handle_xr_translation(&event);
|
||||
self.event_queue
|
||||
.borrow_mut()
|
||||
.push(WindowEvent::Keyboard(event));
|
||||
|
@ -259,6 +265,33 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_xr_translation(&self, input: &KeyboardEvent) {
|
||||
if input.state != KeyState::Down {
|
||||
return;
|
||||
}
|
||||
const NORMAL_TRANSLATE: f32 = 0.1;
|
||||
const QUICK_TRANSLATE: f32 = 1.0;
|
||||
let mut x = 0.0;
|
||||
let mut z = 0.0;
|
||||
match input.key {
|
||||
Key::Character(ref k) => match &**k {
|
||||
"w" => z = -NORMAL_TRANSLATE,
|
||||
"W" => z = -QUICK_TRANSLATE,
|
||||
"s" => z = NORMAL_TRANSLATE,
|
||||
"S" => z = QUICK_TRANSLATE,
|
||||
"a" => x = -NORMAL_TRANSLATE,
|
||||
"A" => x = -QUICK_TRANSLATE,
|
||||
"d" => x = NORMAL_TRANSLATE,
|
||||
"D" => x = QUICK_TRANSLATE,
|
||||
_ => return,
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
let (old_x, old_y, old_z) = self.xr_translation.get().to_tuple();
|
||||
let vec = Vector3D::new(x + old_x, old_y, z + old_z);
|
||||
self.xr_translation.set(vec);
|
||||
}
|
||||
|
||||
fn handle_xr_rotation(&self, input: &KeyboardInput) {
|
||||
if input.state != glutin::ElementState::Pressed {
|
||||
return;
|
||||
|
@ -540,19 +573,25 @@ impl webxr::glwindow::GlWindow for Window {
|
|||
|
||||
fn size(&self) -> UntypedSize2D<gl::GLsizei> {
|
||||
let dpr = self.device_hidpi_factor().get() as f64;
|
||||
let LogicalSize { width, height } = self
|
||||
let size = self
|
||||
.gl_context
|
||||
.borrow()
|
||||
.window()
|
||||
.get_inner_size()
|
||||
.expect("Failed to get window inner size.");
|
||||
Size2D::new(width * dpr, height *dpr).to_i32()
|
||||
let size = size.to_physical(dpr);
|
||||
let (w, h): (u32, u32) = size.into();
|
||||
Size2D::new(w as i32, h as i32)
|
||||
}
|
||||
|
||||
fn get_rotation(&self) -> Rotation3D<f32, UnknownUnit, UnknownUnit> {
|
||||
self.xr_rotation.get().clone()
|
||||
}
|
||||
|
||||
fn get_translation(&self) -> Vector3D<f32, UnknownUnit> {
|
||||
self.xr_translation.get().clone()
|
||||
}
|
||||
|
||||
fn new_window(&self) -> Result<Rc<dyn webxr::glwindow::GlWindow>, ()> {
|
||||
let window = Rc::new(Window::new(
|
||||
self.inner_size.get(),
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! A headless window implementation.
|
||||
|
||||
use crate::window_trait::WindowPortsMethods;
|
||||
use euclid::{default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit};
|
||||
use euclid::{default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D};
|
||||
use gleam::gl;
|
||||
use glutin;
|
||||
use servo::compositing::windowing::{AnimationState, WindowEvent};
|
||||
|
@ -246,4 +246,8 @@ impl webxr::glwindow::GlWindow for Window {
|
|||
fn get_rotation(&self) -> Rotation3D<f32, UnknownUnit, UnknownUnit> {
|
||||
Rotation3D::identity()
|
||||
}
|
||||
|
||||
fn get_translation(&self) -> Vector3D<f32, UnknownUnit> {
|
||||
Vector3D::zero()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue