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:
bors-servo 2019-11-19 21:56:25 -05:00 committed by GitHub
commit e07f0280fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 6 deletions

4
Cargo.lock generated
View file

@ -6011,7 +6011,7 @@ dependencies = [
[[package]] [[package]]
name = "webxr" name = "webxr"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/servo/webxr#0ae9b56ef7e646c54382f75fe79012e0f889363d" source = "git+https://github.com/servo/webxr#27c83fde49d820bc3ffd0396d9aea01a3b5c5729"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"euclid", "euclid",
@ -6031,7 +6031,7 @@ dependencies = [
[[package]] [[package]]
name = "webxr-api" name = "webxr-api"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/servo/webxr#0ae9b56ef7e646c54382f75fe79012e0f889363d" source = "git+https://github.com/servo/webxr#27c83fde49d820bc3ffd0396d9aea01a3b5c5729"
dependencies = [ dependencies = [
"euclid", "euclid",
"ipc-channel", "ipc-channel",

View file

@ -9,7 +9,10 @@ use crate::context::GlContext;
use crate::events_loop::EventsLoop; use crate::events_loop::EventsLoop;
use crate::keyutils::keyboard_event_from_winit; use crate::keyutils::keyboard_event_from_winit;
use crate::window_trait::{WindowPortsMethods, LINE_HEIGHT}; 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 gleam::gl;
use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalSize}; use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -71,6 +74,7 @@ pub struct Window {
fullscreen: Cell<bool>, fullscreen: Cell<bool>,
gl: Rc<dyn gl::Gl>, gl: Rc<dyn gl::Gl>,
xr_rotation: Cell<Rotation3D<f32, UnknownUnit, UnknownUnit>>, xr_rotation: Cell<Rotation3D<f32, UnknownUnit, UnknownUnit>>,
xr_translation: Cell<Vector3D<f32, UnknownUnit>>,
angle: bool, angle: bool,
enable_vsync: bool, enable_vsync: bool,
use_msaa: bool, use_msaa: bool,
@ -206,6 +210,7 @@ impl Window {
primary_monitor, primary_monitor,
screen_size, screen_size,
xr_rotation: Cell::new(Rotation3D::identity()), xr_rotation: Cell::new(Rotation3D::identity()),
xr_translation: Cell::new(Vector3D::zero()),
angle, angle,
enable_vsync, enable_vsync,
use_msaa, use_msaa,
@ -240,6 +245,7 @@ impl Window {
KeyboardEvent::default() KeyboardEvent::default()
}; };
event.key = Key::Character(ch.to_string()); event.key = Key::Character(ch.to_string());
self.handle_xr_translation(&event);
self.event_queue self.event_queue
.borrow_mut() .borrow_mut()
.push(WindowEvent::Keyboard(event)); .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) { fn handle_xr_rotation(&self, input: &KeyboardInput) {
if input.state != glutin::ElementState::Pressed { if input.state != glutin::ElementState::Pressed {
return; return;
@ -540,19 +573,25 @@ impl webxr::glwindow::GlWindow for Window {
fn size(&self) -> UntypedSize2D<gl::GLsizei> { fn size(&self) -> UntypedSize2D<gl::GLsizei> {
let dpr = self.device_hidpi_factor().get() as f64; let dpr = self.device_hidpi_factor().get() as f64;
let LogicalSize { width, height } = self let size = self
.gl_context .gl_context
.borrow() .borrow()
.window() .window()
.get_inner_size() .get_inner_size()
.expect("Failed to get window 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> { fn get_rotation(&self) -> Rotation3D<f32, UnknownUnit, UnknownUnit> {
self.xr_rotation.get().clone() 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>, ()> { fn new_window(&self) -> Result<Rc<dyn webxr::glwindow::GlWindow>, ()> {
let window = Rc::new(Window::new( let window = Rc::new(Window::new(
self.inner_size.get(), self.inner_size.get(),

View file

@ -5,7 +5,7 @@
//! A headless window implementation. //! A headless window implementation.
use crate::window_trait::WindowPortsMethods; 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 gleam::gl;
use glutin; use glutin;
use servo::compositing::windowing::{AnimationState, WindowEvent}; use servo::compositing::windowing::{AnimationState, WindowEvent};
@ -246,4 +246,8 @@ impl webxr::glwindow::GlWindow for Window {
fn get_rotation(&self) -> Rotation3D<f32, UnknownUnit, UnknownUnit> { fn get_rotation(&self) -> Rotation3D<f32, UnknownUnit, UnknownUnit> {
Rotation3D::identity() Rotation3D::identity()
} }
fn get_translation(&self) -> Vector3D<f32, UnknownUnit> {
Vector3D::zero()
}
} }