mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Add hit test mocking at initialization
This commit is contained in:
parent
3f88310e23
commit
d01d9065aa
7 changed files with 126 additions and 9 deletions
|
@ -2,8 +2,10 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
|
||||||
use crate::dom::bindings::codegen::Bindings::FakeXRDeviceBinding::{
|
use crate::dom::bindings::codegen::Bindings::FakeXRDeviceBinding::{
|
||||||
FakeXRDeviceMethods, FakeXRRigidTransformInit, FakeXRViewInit,
|
FakeXRDeviceMethods, FakeXRRegionType, FakeXRRigidTransformInit, FakeXRViewInit,
|
||||||
|
FakeXRWorldInit,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::FakeXRInputSourceInit;
|
use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::FakeXRInputSourceInit;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
||||||
|
@ -21,15 +23,15 @@ use crate::dom::promise::Promise;
|
||||||
use crate::task_source::TaskSource;
|
use crate::task_source::TaskSource;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use euclid::{Point2D, Rect, Size2D};
|
use euclid::{Point2D, Rect, Size2D};
|
||||||
use euclid::{RigidTransform3D, Rotation3D, Transform3D, Vector3D};
|
use euclid::{Point3D, RigidTransform3D, Rotation3D, Transform3D, Vector3D};
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use profile_traits::ipc;
|
use profile_traits::ipc;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webxr_api::{
|
use webxr_api::{
|
||||||
Handedness, InputId, InputSource, MockDeviceMsg, MockInputInit, MockViewInit, MockViewsInit,
|
EntityType, Handedness, InputId, InputSource, MockDeviceMsg, MockInputInit, MockRegion,
|
||||||
TargetRayMode, Visibility,
|
MockViewInit, MockViewsInit, MockWorld, TargetRayMode, Triangle, Visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -97,6 +99,7 @@ pub fn view<Eye>(view: &FakeXRViewInit) -> Fallible<MockViewInit<Eye>> {
|
||||||
fov,
|
fov,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_views(views: &[FakeXRViewInit]) -> Fallible<MockViewsInit> {
|
pub fn get_views(views: &[FakeXRViewInit]) -> Fallible<MockViewsInit> {
|
||||||
match views.len() {
|
match views.len() {
|
||||||
1 => Ok(MockViewsInit::Mono(view(&views[0])?)),
|
1 => Ok(MockViewsInit::Mono(view(&views[0])?)),
|
||||||
|
@ -133,6 +136,50 @@ pub fn get_origin<T, U>(
|
||||||
Ok(RigidTransform3D::new(o, p))
|
Ok(RigidTransform3D::new(o, p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_point<T>(pt: &DOMPointInit) -> Point3D<f32, T> {
|
||||||
|
Point3D::new(pt.x / pt.w, pt.y / pt.w, pt.z / pt.w).cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_world(world: &FakeXRWorldInit) -> Fallible<MockWorld> {
|
||||||
|
let regions = world
|
||||||
|
.hitTestRegions
|
||||||
|
.iter()
|
||||||
|
.map(|region| {
|
||||||
|
let ty = region.type_.into();
|
||||||
|
let faces = region
|
||||||
|
.faces
|
||||||
|
.iter()
|
||||||
|
.map(|face| {
|
||||||
|
if face.vertices.len() != 3 {
|
||||||
|
return Err(Error::Type(
|
||||||
|
"Incorrectly sized array for triangle list".into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Triangle {
|
||||||
|
first: get_point(&face.vertices[0]),
|
||||||
|
second: get_point(&face.vertices[1]),
|
||||||
|
third: get_point(&face.vertices[2]),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Fallible<Vec<_>>>()?;
|
||||||
|
Ok(MockRegion { faces, ty })
|
||||||
|
})
|
||||||
|
.collect::<Fallible<Vec<_>>>()?;
|
||||||
|
|
||||||
|
Ok(MockWorld { regions })
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FakeXRRegionType> for EntityType {
|
||||||
|
fn from(x: FakeXRRegionType) -> Self {
|
||||||
|
match x {
|
||||||
|
FakeXRRegionType::Point => EntityType::Point,
|
||||||
|
FakeXRRegionType::Plane => EntityType::Plane,
|
||||||
|
FakeXRRegionType::Mesh => EntityType::Mesh,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FakeXRDeviceMethods for FakeXRDevice {
|
impl FakeXRDeviceMethods for FakeXRDevice {
|
||||||
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
||||||
fn SetViews(&self, views: Vec<FakeXRViewInit>) -> Fallible<()> {
|
fn SetViews(&self, views: Vec<FakeXRViewInit>) -> Fallible<()> {
|
||||||
|
|
|
@ -25,6 +25,10 @@ interface FakeXRDevice {
|
||||||
|
|
||||||
// behaves as if device was disconnected
|
// behaves as if device was disconnected
|
||||||
Promise<void> disconnect();
|
Promise<void> disconnect();
|
||||||
|
|
||||||
|
// Hit test extensions:
|
||||||
|
// void setWorld(FakeXRWorldInit world);
|
||||||
|
// void clearWorld();
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport
|
// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport
|
||||||
|
@ -61,3 +65,26 @@ dictionary FakeXRFieldOfViewInit {
|
||||||
required float leftDegrees;
|
required float leftDegrees;
|
||||||
required float rightDegrees;
|
required float rightDegrees;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// hit testing
|
||||||
|
dictionary FakeXRWorldInit {
|
||||||
|
required sequence<FakeXRRegionInit> hitTestRegions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
dictionary FakeXRRegionInit {
|
||||||
|
required sequence<FakeXRTriangleInit> faces;
|
||||||
|
required FakeXRRegionType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
dictionary FakeXRTriangleInit {
|
||||||
|
required sequence<DOMPointInit> vertices; // size = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum FakeXRRegionType {
|
||||||
|
"point",
|
||||||
|
"plane",
|
||||||
|
"mesh"
|
||||||
|
};
|
||||||
|
|
|
@ -33,5 +33,8 @@ dictionary FakeXRDeviceInit {
|
||||||
// Eye level used for calculating floor-level spaces
|
// Eye level used for calculating floor-level spaces
|
||||||
FakeXRRigidTransformInit floorOrigin;
|
FakeXRRigidTransformInit floorOrigin;
|
||||||
FakeXRRigidTransformInit viewerOrigin;
|
FakeXRRigidTransformInit viewerOrigin;
|
||||||
|
|
||||||
|
// Hit test extensions:
|
||||||
|
FakeXRWorldInit world;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::dom::bindings::codegen::Bindings::XRTestBinding::{FakeXRDeviceInit, X
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::fakexrdevice::{get_origin, get_views, FakeXRDevice};
|
use crate::dom::fakexrdevice::{get_origin, get_views, get_world, FakeXRDevice};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::script_thread::ScriptThread;
|
use crate::script_thread::ScriptThread;
|
||||||
|
@ -106,6 +106,19 @@ impl XRTestMethods for XRTest {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let world = if let Some(ref w) = init.world {
|
||||||
|
let w = match get_world(w) {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => {
|
||||||
|
p.reject_error(e);
|
||||||
|
return p;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Some(w)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let init = MockDeviceInit {
|
let init = MockDeviceInit {
|
||||||
viewer_origin: origin,
|
viewer_origin: origin,
|
||||||
views,
|
views,
|
||||||
|
@ -114,7 +127,7 @@ impl XRTestMethods for XRTest {
|
||||||
supports_ar: false,
|
supports_ar: false,
|
||||||
floor_origin,
|
floor_origin,
|
||||||
supported_features,
|
supported_features,
|
||||||
world: None,
|
world,
|
||||||
};
|
};
|
||||||
|
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
|
|
|
@ -1,2 +1,10 @@
|
||||||
[ar_hittest_subscription_inputSources.https.html]
|
[ar_hittest_subscription_inputSources.https.html]
|
||||||
expected: ERROR
|
[Ensures subscription to hit test works with an XRSpace from input source - after move - no results]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to hit test works with an XRSpace from input source - after move - 1 result]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to hit test works with an XRSpace from input source - no move]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,13 @@
|
||||||
[ar_hittest_subscription_refSpaces.https.html]
|
[ar_hittest_subscription_refSpaces.https.html]
|
||||||
expected: ERROR
|
[Ensures subscription to hit test works with viewer space - straight up - no results]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to hit test works with viewer space - straight ahead - plane]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to hit test works with local space]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to hit test works with local-floor space]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,10 @@
|
||||||
[ar_hittest_subscription_transientInputSources.https.html]
|
[ar_hittest_subscription_transientInputSources.https.html]
|
||||||
expected: ERROR
|
[Ensures subscription to transient hit test works with an XRSpace from input source - after move - 1 result]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to transient hit test works with an XRSpace from input source - after move - no results]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Ensures subscription to transient hit test works with an XRSpace from input source - no move]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue