Changeset 273132 in webkit
- Timestamp:
- Feb 19, 2021 1:07:11 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 34 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r273129 r273132 1 2021-02-19 Imanol Fernandez <ifernandez@igalia.com> and Sergio Villar Senin <svillar@igalia.com> 2 3 Implement WebXR getViewerPose and getPose 4 https://bugs.webkit.org/show_bug.cgi?id=221225 5 <rdar://problem/74112910> 6 7 Reviewed by Youenn Fablet. 8 9 Mark pose related WebXR tests as passing. 10 11 * platform/wpe/TestExpectations: 12 1 13 2021-02-18 Simon Fraser <simon.fraser@apple.com> 2 14 -
trunk/LayoutTests/imported/w3c/ChangeLog
r273073 r273132 1 2021-02-19 Imanol Fernandez <ifernandez@igalia.com> and Sergio Villar Senin <svillar@igalia.com> 2 3 Implement WebXR getViewerPose and getPose 4 https://bugs.webkit.org/show_bug.cgi?id=221225 5 <rdar://problem/74112910> 6 7 Reviewed by Youenn Fablet. 8 9 Mark pose and reference space WebXR tests as passing. 10 11 * web-platform-tests/webxr/xrFrame_getPose.https-expected.txt: Added. 12 * web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https-expected.txt: Added. 13 * web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https-expected.txt: Added. 14 * web-platform-tests/webxr/xrReferenceSpace_relationships.https-expected.txt: Added. 15 * web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https-expected.txt: Added. 16 * web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https-expected.txt: Added. 17 * web-platform-tests/webxr/xrSession_viewer_referenceSpace.https-expected.txt: Added. 18 * web-platform-tests/webxr/xrView_eyes.https-expected.txt: Added. 19 * web-platform-tests/webxr/xrView_match.https-expected.txt: Added. 20 * web-platform-tests/webxr/xrView_oneframeupdate.https-expected.txt: Added. 21 1 22 2021-02-18 Martin Robinson <mrobinson@igalia.com> 2 23 -
trunk/LayoutTests/platform/wpe/TestExpectations
r273070 r273132 635 635 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html [ Pass ] 636 636 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_optionalFeatures.https.html [ Pass ] 637 webkit.org/b/209859 webkit.org/b/215637 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame.https.html [ Pass Failure ] 638 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ] 639 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ] 640 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ] 641 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ] 642 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ] 637 imported/w3c/web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https.html [ Pass ] 638 imported/w3c/web-platform-tests/webxr/xrFrame_getPose.https.html [ Pass ] 639 imported/w3c/web-platform-tests/webxr/xrFrame_session_sameObject.https.html [ Pass ] 643 640 imported/w3c/web-platform-tests/webxr/xrSession_viewer_availability.https.html [ Pass ] 644 641 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/idlharness.https.window.html [ Pass ] 645 642 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/xrDevice_isSessionSupported_immersive-ar.https.html [ Pass ] 643 imported/w3c/web-platform-tests/webxr/xrView_eyes.https.html [ Pass ] 644 imported/w3c/web-platform-tests/webxr/xrView_match.https.html [ Pass ] 645 imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https.html [ Pass ] 646 646 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_constructor.https.html [ Pass ] 647 647 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https.html [ Pass ] 648 648 imported/w3c/web-platform-tests/webxr/navigator_xr_sameObject.https.html [ Pass ] 649 imported/w3c/web-platform-tests/webxr/xrFrame_session_sameObject.https.html [ Pass ] 649 imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https.html [ Pass ] 650 imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https.html [ Pass ] 650 651 imported/w3c/web-platform-tests/webxr/xrRigidTransform_constructor.https.html [ Pass ] 651 652 imported/w3c/web-platform-tests/webxr/xrRigidTransform_inverse.https.html [ Pass ] 652 653 imported/w3c/web-platform-tests/webxr/xrRigidTransform_matrix.https.html [ Pass ] 654 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame.https.html [ Pass ] 655 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ] 656 imported/w3c/web-platform-tests/webxr/xrSession_end.https.html [ Pass ] 657 imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ] 653 658 imported/w3c/web-platform-tests/webxr/xrSession_prevent_multiple_exclusive.https.html [ Pass ] 659 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ] 660 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html [ Pass ] 661 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html [ Pass ] 662 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ] 663 imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ] 664 imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https.html [ Pass ] 654 665 imported/w3c/web-platform-tests/webxr/render_state_vertical_fov_immersive.https.html [ Pass ] 655 666 imported/w3c/web-platform-tests/webxr/render_state_update.https.html [ Pass ] 656 imported/w3c/web-platform-tests/webxr/xrSession_end.https.html [ Pass ]657 667 http/wpt/webxr/xrSession_end_device_reports_shutdown.https.html [ Pass ] 658 668 http/wpt/webxr/xrSession_ended_by_system.https.html [ Pass ] -
trunk/Source/WebCore/ChangeLog
r273129 r273132 1 2021-02-19 Imanol Fernandez <ifernandez@igalia.com> and Sergio Villar Senin <svillar@igalia.com> 2 3 Implement WebXR getViewerPose and getPose 4 https://bugs.webkit.org/show_bug.cgi?id=221225 5 <rdar://problem/74112910> 6 7 Reviewed by Youenn Fablet. 8 9 - Improve PlatformXR::FrameData struct. 10 - Implement WebXRFrame getViewerPose and getPose. 11 - Implement WebXRReferenceSpace offset, origin and effective tranforms. 12 - Implement WebXRBoundedReferenceSpace nativeOrigin. 13 - Apply frame updates in WebXRSession. 14 - Implement views for OpenXR and DummyInlineDevice inline sessions. 15 - Query and complete all the new FrameData in the OpenXR port. 16 - Complete the WebFakeXRDevice implementation for WebXR WPT tests. 17 18 Tested by the WebXR WPT tests 19 20 * Modules/webxr/WebXRBoundedReferenceSpace.cpp: Implement nativeOrigina and getOffsetReferenceSpace. 21 (WebCore::WebXRBoundedReferenceSpace::create): 22 (WebCore::WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace): 23 (WebCore::WebXRBoundedReferenceSpace::nativeOrigin const): 24 (WebCore::WebXRBoundedReferenceSpace::boundsGeometry const): 25 (WebCore::WebXRBoundedReferenceSpace::getOffsetReferenceSpace): 26 * Modules/webxr/WebXRBoundedReferenceSpace.h: 27 28 * Modules/webxr/WebXRFrame.cpp: Implement WebXR getViewerPose and getPose. 29 (WebCore::WebXRFrame::create): 30 (WebCore::WebXRFrame::WebXRFrame): 31 (WebCore::WebXRFrame::mustPosesBeLimited): 32 (WebCore::WebXRFrame::populatePose): 33 (WebCore::WebXRFrame::getViewerPose): 34 (WebCore::WebXRFrame::getPose): 35 (WebCore::WebXRFrame::matrixFromPose): add helper function. 36 * Modules/webxr/WebXRFrame.h: 37 (WebCore::WebXRFrame::setFrameData): 38 * Modules/webxr/WebXRFrame.idl: add MayThrowException. 39 40 * Modules/webxr/WebXRPose.cpp: Add WebXRRigidTransform constructor parameter. Add specialize type traits. 41 (WebCore::WebXRPose::create): 42 (WebCore::WebXRPose::WebXRPose): 43 * Modules/webxr/WebXRPose.h: 44 (WebCore::WebXRPose::isViewerPose const): 45 * Modules/webxr/WebXRPose.idl: Remove ImplementationLacksVTable 46 47 * Modules/webxr/WebXRReferenceSpace.cpp: Implement offset, origin and effective tranforms. 48 (WebCore::WebXRReferenceSpace::create): 49 (WebCore::WebXRReferenceSpace::WebXRReferenceSpace): 50 (WebCore::WebXRReferenceSpace::nativeOrigin const): 51 (WebCore::WebXRReferenceSpace::getOffsetReferenceSpace): 52 (WebCore::WebXRReferenceSpace::floorOriginTransform const): 53 (WebCore:: const): 54 * Modules/webxr/WebXRReferenceSpace.h: 55 (WebCore::WebXRReferenceSpace::type const): 56 * Modules/webxr/WebXRReferenceSpace.idl: Add SkipVTableValidation. 57 58 * Modules/webxr/WebXRSession.cpp: Apply frame updates for frame. Add active views data. 59 (WebCore::WebXRSession::WebXRSession): 60 (WebCore::WebXRSession::requestReferenceSpace): Use WeakPtr instead Ref for WebXRSession. 61 (WebCore::WebXRSession::onFrame): 62 (WebCore::WebXRSession::posesCanBeReported const): add 63 * Modules/webxr/WebXRSession.h: 64 65 * Modules/webxr/WebXRSpace.cpp: Add nativeOrigin and effectiveOrigin member functions. Add specialize type traits. 66 (WebCore::WebXRSpace::WebXRSpace): 67 (WebCore::WebXRSpace::effectiveOrigin const): 68 * Modules/webxr/WebXRSpace.h: 69 (WebCore::WebXRSpace::session const): 70 (WebCore::WebXRSpace::isReferenceSpace const): 71 (WebCore::WebXRSpace::isBoundedReferenceSpace const): 72 73 * Modules/webxr/WebXRSystem.cpp: Implement views for DummyInlineDevice. 74 (WebCore::WebXRSystem::DummyInlineDevice::requestFrame): 75 (WebCore::WebXRSystem::DummyInlineDevice::views const): 76 * Modules/webxr/WebXRSystem.h: 77 78 * Modules/webxr/WebXRView.cpp: Pass WebXRRigidTransform in the constructor. 79 (WebCore::WebXRView::create): 80 (WebCore::WebXRView::WebXRView): 81 (WebCore::WebXRView::setProjectionMatrix): Use std::array to match device data. 82 * Modules/webxr/WebXRView.h: 83 (WebCore::WebXRView::projectionMatrix const): 84 (WebCore::WebXRView::transform const): 85 86 * Modules/webxr/WebXRViewerPose.cpp: Add views setter. Add specialize type traits. 87 (WebCore::WebXRViewerPose::create): 88 (WebCore::WebXRViewerPose::WebXRViewerPose): 89 (WebCore::WebXRViewerPose::setViews): 90 * Modules/webxr/WebXRViewerPose.h: 91 * Modules/webxr/WebXRViewerPose.idl: Remove ImplementationLacksVTable. Add JSGenerateToNativeObject. 92 93 * Modules/webxr/XREye.h: Reuse PlatformXR enum. 94 95 * platform/graphics/transforms/TransformationMatrix.cpp: Add projection matrix utility functions. 96 (WebCore::TransformationMatrix::fromProjection): 97 * platform/graphics/transforms/TransformationMatrix.h: 98 99 * platform/xr/PlatformXR.h: Improve FrameData. 100 101 * platform/xr/openxr/PlatformXROpenXR.cpp: Query and complete all the new FrameData. 102 (PlatformXR::OpenXRDevice::createReferenceSpace): add helper function. 103 (PlatformXR::OpenXRDevice::recommendedResolution): Query resolution data from OpenXR. 104 (PlatformXR::OpenXRDevice::initializeTrackingAndRendering): Initialize local and view XrSpaces. 105 (PlatformXR::OpenXRDevice::initializeReferenceSpace): Lazily initialize stage XrSpace. 106 (PlatformXR::XrPosefToPose): add helper function. 107 (PlatformXR::xrViewToPose): add helper function. 108 (PlatformXR::OpenXRDevice::requestFrame): Complete all the new frame Data 109 (PlatformXR::OpenXRDevice::views const): Implement view data for OpenXR 110 * platform/xr/openxr/PlatformXROpenXR.h: 111 112 * testing/WebFakeXRDevice.cpp: Complete the required implementation for WebXR WPT tests. 113 (WebCore::FakeXRView::setProjection): 114 (WebCore::FakeXRView::setFieldOfView): 115 (WebCore::SimulatedXRDevice::frameTimerFired): 116 (WebCore::SimulatedXRDevice::requestFrame): 117 (WebCore::SimulatedXRDevice::views const): 118 (WebCore::SimulatedXRDevice::scheduleOnNextFrame): 119 (WebCore::WebFakeXRDevice::setViews): 120 (WebCore::WebFakeXRDevice::setViewerOrigin): 121 (WebCore::WebFakeXRDevice::clearViewerOrigin): 122 (WebCore::WebFakeXRDevice::setBoundsGeometry): 123 (WebCore::WebFakeXRDevice::setFloorOrigin): 124 (WebCore::WebFakeXRDevice::clearFloorOrigin): 125 (WebCore::WebFakeXRDevice::parseRigidTransform): 126 (WebCore::WebFakeXRDevice::parseView): 127 * testing/WebFakeXRDevice.h: 128 1 129 2021-02-18 Simon Fraser <simon.fraser@apple.com> 2 130 -
trunk/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.cpp
r262299 r273132 30 30 31 31 #include "DOMPointReadOnly.h" 32 #include "Document.h" 33 #include "WebXRRigidTransform.h" 34 #include "WebXRSession.h" 32 35 #include <wtf/IsoMallocInlines.h> 33 36 … … 38 41 Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) 39 42 { 40 return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), type));43 return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), WebXRRigidTransform::create(), type)); 41 44 } 42 45 43 WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) 44 : WebXRReferenceSpace(document, WTFMove(session), type) 46 47 Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) 48 { 49 return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), WTFMove(offset), type)); 50 } 51 52 53 WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) 54 : WebXRReferenceSpace(document, WTFMove(session), WTFMove(offset), type) 45 55 { 46 56 } … … 48 58 WebXRBoundedReferenceSpace::~WebXRBoundedReferenceSpace() = default; 49 59 60 TransformationMatrix WebXRBoundedReferenceSpace::nativeOrigin() const 61 { 62 // https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-bounded-floor. 63 // Bounded floor space should be at the same height as local floor space. 64 return floorOriginTransform(); 65 } 66 50 67 const Vector<Ref<DOMPointReadOnly>>& WebXRBoundedReferenceSpace::boundsGeometry() const 51 68 { 69 // FIXME: get data from device 52 70 return m_boundsGeometry; 71 } 72 73 RefPtr<WebXRReferenceSpace> WebXRBoundedReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform& offsetTransform) 74 { 75 auto* document = downcast<Document>(scriptExecutionContext()); 76 if (!document) 77 return nullptr; 78 79 // https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace 80 // Set offsetSpace’s origin offset to the result of multiplying base’s origin offset by originOffset in the relevant realm of base. 81 auto offset = WebXRRigidTransform::create(originOffset().rawTransform() * offsetTransform.rawTransform()); 82 83 // FIXME: set offsetSpace’s boundsGeometry to base’s boundsGeometry, with each point multiplied by the inverse of originOffset. 84 return create(*document, m_session.copyRef(), WTFMove(offset), m_type); 53 85 } 54 86 -
trunk/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.h
r262299 r273132 26 26 #pragma once 27 27 28 #if ENABLE(WEBXR) 29 28 30 #include "WebXRReferenceSpace.h" 29 31 #include <wtf/IsoMalloc.h> … … 31 33 #include <wtf/Vector.h> 32 34 33 #if ENABLE(WEBXR)34 35 35 namespace WebCore { 36 36 37 37 class DOMPointReadOnly; 38 38 39 class WebXRBoundedReferenceSpace : public WebXRReferenceSpace {39 class WebXRBoundedReferenceSpace final: public WebXRReferenceSpace { 40 40 WTF_MAKE_ISO_ALLOCATED(WebXRBoundedReferenceSpace); 41 41 public: 42 42 static Ref<WebXRBoundedReferenceSpace> create(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); 43 static Ref<WebXRBoundedReferenceSpace> create(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); 43 44 44 45 virtual ~WebXRBoundedReferenceSpace(); 45 46 47 TransformationMatrix nativeOrigin() const final; 46 48 const Vector<Ref<DOMPointReadOnly>>& boundsGeometry() const; 49 RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&) final; 47 50 48 51 private: 49 WebXRBoundedReferenceSpace(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); 52 WebXRBoundedReferenceSpace(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); 53 54 bool isBoundedReferenceSpace() const final { return true; } 50 55 51 56 Vector<Ref<DOMPointReadOnly>> m_boundsGeometry; … … 54 59 } // namespace WebCore 55 60 61 SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(WebXRBoundedReferenceSpace, isBoundedReferenceSpace()) 62 56 63 #endif // ENABLE(WEBXR) -
trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp
r272734 r273132 29 29 #if ENABLE(WEBXR) 30 30 31 #include "WebXRBoundedReferenceSpace.h" 32 #include "WebXRReferenceSpace.h" 31 33 #include "WebXRSession.h" 32 34 #include "WebXRViewerPose.h" … … 37 39 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRFrame); 38 40 39 Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session) 40 { 41 return adoptRef(*new WebXRFrame(WTFMove(session))); 42 } 43 44 WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session) 45 : m_session(WTFMove(session)) 41 Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session, IsAnimationFrame isAnimationFrame) 42 { 43 return adoptRef(*new WebXRFrame(WTFMove(session), isAnimationFrame)); 44 } 45 46 WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session, IsAnimationFrame isAnimationFrame) 47 : m_isAnimationFrame(isAnimationFrame == IsAnimationFrame::Yes) 48 , m_session(WTFMove(session)) 46 49 { 47 50 } … … 49 52 WebXRFrame::~WebXRFrame() = default; 50 53 51 52 RefPtr<WebXRViewerPose> WebXRFrame::getViewerPose(const WebXRReferenceSpace&) 53 { 54 return { }; 55 } 56 57 RefPtr<WebXRPose> WebXRFrame::getPose(const WebXRSpace&, const WebXRSpace&) 58 { 59 return { }; 54 bool WebXRFrame::isOutsideNativeBoundsOfBoundedReferenceSpace(const WebXRSpace& space, const WebXRSpace&) const 55 { 56 if (!is<WebXRBoundedReferenceSpace>(space)) 57 return false; 58 59 // FIXME: return true whenever the distance from the bounded geometry of 60 // |space| to the native origin of |other| space is greater than 1m 61 // (suggested by specs). 62 63 return false; 64 } 65 66 bool WebXRFrame::isLocalReferenceSpace(const WebXRSpace& space) const 67 { 68 if (!is<WebXRReferenceSpace>(space)) 69 return false; 70 71 auto type = downcast<WebXRReferenceSpace>(space).type(); 72 if (type == XRReferenceSpaceType::Local || type == XRReferenceSpaceType::LocalFloor) 73 return true; 74 75 return false; 76 } 77 78 // https://immersive-web.github.io/webxr/#poses-must-be-limited 79 bool WebXRFrame::mustPosesBeLimited(const WebXRSpace& space, const WebXRSpace& baseSpace) const 80 { 81 if (isOutsideNativeBoundsOfBoundedReferenceSpace(space, baseSpace) 82 || isOutsideNativeBoundsOfBoundedReferenceSpace(baseSpace, space)) 83 return true; 84 85 if (isLocalReferenceSpace(space) || isLocalReferenceSpace(baseSpace)) { 86 // FIXME: If the distance between native origins of spaces is greater 87 // than 15m (suggested by specs) return true. 88 } 89 90 return false; 91 } 92 93 struct WebXRFrame::PopulatedPose { 94 TransformationMatrix transform; 95 bool emulatedPosition { false }; 96 }; 97 98 // https://immersive-web.github.io/webxr/#populate-the-pose 99 ExceptionOr<Optional<WebXRFrame::PopulatedPose>> WebXRFrame::populatePose(const Document& document, const WebXRSpace& space, const WebXRSpace& baseSpace) 100 { 101 // 1. If frame’s active boolean is false, throw an InvalidStateError and abort these steps. 102 if (!m_active) 103 return Exception { InvalidStateError }; 104 105 // 2. Let session be frame’s session object. 106 // 3. If space’s session does not equal session, throw an InvalidStateError and abort these steps. 107 if (&space.session() != m_session.ptr()) 108 return Exception { InvalidStateError }; 109 110 // 4. If baseSpace’s session does not equal session, throw an InvalidStateError and abort these steps. 111 if (&baseSpace.session() != m_session.ptr()) 112 return Exception { InvalidStateError }; 113 114 // 5. Check if poses may be reported and, if not, throw a SecurityError and abort these steps. 115 if (!m_session->posesCanBeReported(document)) 116 return Exception { SecurityError }; 117 118 // 6. Let limit be the result of whether poses must be limited between space and baseSpace. 119 // 7. Let transform be pose’s transform. 120 // 8. Query the XR device's tracking system for space’s pose relative to baseSpace at the frame’s time. 121 122 if (!m_data.isTrackingValid) { 123 // FIXME: check if space’s pose relative to baseSpace has been determined in the past. 124 // Anyway this emulation is usually provided by the system in the pose (e.g. OpenXR) 125 // so we shouldn't hit this path in most XRPlatform ports. 126 return { WTF::nullopt }; 127 } 128 129 auto baseTransform = baseSpace.effectiveOrigin(); 130 if (!baseTransform.isInvertible()) 131 return { WTF::nullopt }; 132 133 auto transform = *baseTransform.inverse() * space.effectiveOrigin(); 134 bool emulatedPosition = m_data.isPositionEmulated || !m_data.isPositionValid; 135 136 bool limit = mustPosesBeLimited(space, baseSpace); 137 if (limit) { 138 // FIXME: apply pose limits logic 139 // https://immersive-web.github.io/webxr/#poses-must-be-limited 140 } 141 142 return { PopulatedPose { transform, emulatedPosition } }; 143 } 144 145 // https://immersive-web.github.io/webxr/#dom-xrframe-getviewerpose 146 ExceptionOr<RefPtr<WebXRViewerPose>> WebXRFrame::getViewerPose(const Document& document, const WebXRReferenceSpace& referenceSpace) 147 { 148 // 1. Let frame be this. 149 // 2. Let session be frame’s session object. 150 // 3. If frame’s animationFrame boolean is false, throw an InvalidStateError and abort these steps. 151 if (!m_isAnimationFrame) 152 return Exception { InvalidStateError }; 153 154 // 4. Let pose be a new XRViewerPose object in the relevant realm of session. 155 // 5. Populate the pose of session’s viewer reference space in referenceSpace at the time represented by frame into pose. 156 auto populatePoseResult = populatePose(document, m_session->viewerReferenceSpace(), referenceSpace); 157 if (populatePoseResult.hasException()) 158 return populatePoseResult.releaseException(); 159 160 // 6. If pose is null return null. 161 auto populateValue = populatePoseResult.releaseReturnValue(); 162 if (!populateValue.hasValue()) 163 return nullptr; 164 165 RefPtr<WebXRViewerPose> pose = WebXRViewerPose::create(WebXRRigidTransform::create(populateValue->transform), populateValue->emulatedPosition); 166 167 // 7. Let xrviews be an empty list. 168 Vector<Ref<WebXRView>> xrViews; 169 // 8. For each active view view in the list of views on session, perform the following steps: 170 for (auto& view : m_session->views()) { 171 auto index = xrViews.size(); 172 if (!view.active || m_data.views.size() <= index) 173 continue; 174 175 // 8.1 Let xrview be a new XRView object in the relevant realm of session. 176 // 8.2 Initialize xrview’s underlying view to view. 177 // 8.3 Initialize xrview’s eye to view’s eye. 178 // 8.4 Initialize xrview’s frame time to frame’s time. 179 // 8.5 Initialize xrview’s session to session. 180 // 8.6. Let offset be an new XRRigidTransform object equal to the view offset of view in the relevant realm of session. 181 // 8.7. Set xrview’s transform property to the result of multiplying the XRViewerPose's transform by the offset transform in the relevant realm of session 182 auto offset = matrixFromPose(m_data.views[index].offset); 183 auto transform = WebXRRigidTransform::create(pose->transform().rawTransform() * offset); 184 185 // Set projection matrix for each view 186 std::array<float, 16> projection = switchOn(m_data.views[index].projection, [&](const PlatformXR::Device::FrameData::Fov& fov) { 187 double near = m_session->renderState().depthNear(); 188 double far = m_session->renderState().depthFar(); 189 return TransformationMatrix::fromProjection(fov.up, fov.down, fov.left, fov.right, near, far).toColumnMajorFloatArray(); 190 }, [&](const std::array<float, 16>& matrix) { 191 return matrix; 192 }, [&](std::nullptr_t&) { 193 // Use aspect projection for inline sessions 194 double fov = m_session->renderState().inlineVerticalFieldOfView().valueOr(piOverTwoDouble); 195 float aspect = 1; 196 auto layer = m_session->renderState().baseLayer(); 197 if (layer) 198 aspect = static_cast<double>(layer->framebufferWidth()) / static_cast<double>(layer->framebufferHeight()); 199 double near = m_session->renderState().depthNear(); 200 double far = m_session->renderState().depthFar(); 201 return TransformationMatrix::fromProjection(fov, aspect, near, far).toColumnMajorFloatArray(); 202 }); 203 204 auto xrView = WebXRView::create(view.eye, WTFMove(transform), Float32Array::create(projection.data(), projection.size())); 205 206 // 8.8. Append xrview to xrviews 207 xrViews.append(WTFMove(xrView)); 208 } 209 210 // 9. Set pose’s views to xrviews 211 pose->setViews(WTFMove(xrViews)); 212 213 // 10. Return pose. 214 return pose; 215 } 216 217 ExceptionOr<RefPtr<WebXRPose>> WebXRFrame::getPose(const Document& document, const WebXRSpace& space, const WebXRSpace& baseSpace) 218 { 219 // 1. Let frame be this. 220 // 2. Let pose be a new XRPose object in the relevant realm of frame. 221 // 3. Populate the pose of space in baseSpace at the time represented by frame into pose. 222 223 auto populatePoseResult = populatePose(document, space, baseSpace); 224 if (populatePoseResult.hasException()) 225 return populatePoseResult.releaseException(); 226 227 auto populateValue = populatePoseResult.releaseReturnValue(); 228 if (!populateValue.hasValue()) 229 return nullptr; 230 231 // 4. Return pose. 232 return RefPtr<WebXRPose>(WebXRPose::create(WebXRRigidTransform::create(populateValue->transform), populateValue->emulatedPosition)); 233 } 234 235 TransformationMatrix WebXRFrame::matrixFromPose(const PlatformXR::Device::FrameData::Pose& pose) 236 { 237 TransformationMatrix matrix; 238 matrix.translate3d(pose.position.x(), pose.position.y(), pose.position.z()); 239 matrix.multiply(TransformationMatrix::fromQuaternion(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w)); 240 return matrix; 60 241 } 61 242 -
trunk/Source/WebCore/Modules/webxr/WebXRFrame.h
r272734 r273132 29 29 30 30 #include "DOMHighResTimeStamp.h" 31 #include "ExceptionOr.h" 32 #include "PlatformXR.h" 31 33 #include <wtf/IsoMalloc.h> 32 34 #include <wtf/Ref.h> … … 36 38 namespace WebCore { 37 39 40 class Document; 38 41 class WebXRPose; 39 42 class WebXRReferenceSpace; … … 45 48 WTF_MAKE_ISO_ALLOCATED(WebXRFrame); 46 49 public: 47 static Ref<WebXRFrame> create(Ref<WebXRSession>&&); 50 enum class IsAnimationFrame : bool { No, Yes }; 51 static Ref<WebXRFrame> create(Ref<WebXRSession>&&, IsAnimationFrame); 48 52 ~WebXRFrame(); 49 53 50 54 const WebXRSession& session() const { return m_session.get(); } 51 55 52 RefPtr<WebXRViewerPose> getViewerPose(const WebXRReferenceSpace&);53 RefPtr<WebXRPose> getPose(const WebXRSpace&, const WebXRSpace&);56 ExceptionOr<RefPtr<WebXRViewerPose>> getViewerPose(const Document&, const WebXRReferenceSpace&); 57 ExceptionOr<RefPtr<WebXRPose>> getPose(const Document&, const WebXRSpace&, const WebXRSpace&); 54 58 55 59 void setTime(DOMHighResTimeStamp time) { m_time = time; } 60 void setFrameData(PlatformXR::Device::FrameData&& data) { m_data = WTFMove(data); } 61 56 62 void setActive(bool active) { m_active = active; } 57 63 bool isActive() const { return m_active; } 58 64 65 static TransformationMatrix matrixFromPose(const PlatformXR::Device::FrameData::Pose&); 66 59 67 private: 60 explicit WebXRFrame(Ref<WebXRSession>&&); 68 WebXRFrame(Ref<WebXRSession>&&, IsAnimationFrame); 69 70 bool isOutsideNativeBoundsOfBoundedReferenceSpace(const WebXRSpace&, const WebXRSpace&) const; 71 bool isLocalReferenceSpace(const WebXRSpace&) const; 72 bool mustPosesBeLimited(const WebXRSpace&, const WebXRSpace&) const; 73 74 struct PopulatedPose; 75 ExceptionOr<Optional<PopulatedPose>> populatePose(const Document&, const WebXRSpace&, const WebXRSpace&); 61 76 62 77 bool m_active { false }; 63 DOMHighResTimeStamp m_time; 78 bool m_isAnimationFrame { false }; 79 DOMHighResTimeStamp m_time { 0 }; 80 PlatformXR::Device::FrameData m_data; 64 81 Ref<WebXRSession> m_session; 65 82 }; -
trunk/Source/WebCore/Modules/webxr/WebXRFrame.idl
r258498 r273132 34 34 [SameObject] readonly attribute WebXRSession session; 35 35 36 WebXRViewerPose? getViewerPose(WebXRReferenceSpace referenceSpace);37 WebXRPose? getPose(WebXRSpace space, WebXRSpace baseSpace);36 [MayThrowException, CallWith=Document] WebXRViewerPose? getViewerPose(WebXRReferenceSpace referenceSpace); 37 [MayThrowException, CallWith=Document] WebXRPose? getPose(WebXRSpace space, WebXRSpace baseSpace); 38 38 }; -
trunk/Source/WebCore/Modules/webxr/WebXRPose.cpp
r258498 r273132 36 36 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRPose); 37 37 38 Ref<WebXRPose> WebXRPose::create( )38 Ref<WebXRPose> WebXRPose::create(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) 39 39 { 40 return adoptRef(*new WebXRPose );40 return adoptRef(*new WebXRPose(WTFMove(transform), emulatedPosition)); 41 41 } 42 42 43 WebXRPose::WebXRPose( )44 : m_transform(W ebXRRigidTransform::create())43 WebXRPose::WebXRPose(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) 44 : m_transform(WTFMove(transform)), m_emulatedPosition(emulatedPosition) 45 45 { 46 46 } -
trunk/Source/WebCore/Modules/webxr/WebXRPose.h
r258498 r273132 27 27 28 28 #if ENABLE(WEBXR) 29 30 29 #include <wtf/IsoMalloc.h> 31 30 #include <wtf/Ref.h> … … 39 38 WTF_MAKE_ISO_ALLOCATED(WebXRPose); 40 39 public: 41 static Ref<WebXRPose> create( );42 ~WebXRPose();40 static Ref<WebXRPose> create(Ref<WebXRRigidTransform>&&, bool emulatedPosition); 41 virtual ~WebXRPose(); 43 42 44 43 const WebXRRigidTransform& transform() const; 45 44 bool emulatedPosition() const; 46 45 46 virtual bool isViewerPose() const { return false; } 47 47 48 protected: 48 WebXRPose( );49 WebXRPose(Ref<WebXRRigidTransform>&&, bool emulatedPosition); 49 50 50 51 Ref<WebXRRigidTransform> m_transform; … … 54 55 } // namespace WebCore 55 56 57 #define SPECIALIZE_TYPE_TRAITS_WEBXRPOSE(ToValueTypeName, predicate) \ 58 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ 59 static bool isType(const WebCore::WebXRPose& context) { return context.predicate; } \ 60 SPECIALIZE_TYPE_TRAITS_END() 61 56 62 #endif // ENABLE(WEBXR) -
trunk/Source/WebCore/Modules/webxr/WebXRPose.idl
r258498 r273132 29 29 SecureContext, 30 30 Exposed=Window, 31 ImplementationLacksVTable,32 31 InterfaceName=XRPose 33 32 ] interface WebXRPose { -
trunk/Source/WebCore/Modules/webxr/WebXRReferenceSpace.cpp
r262299 r273132 30 30 31 31 #include "Document.h" 32 #include "WebXRFrame.h" 33 #include "WebXRRigidTransform.h" 32 34 #include "WebXRSession.h" 33 35 #include <wtf/IsoMallocInlines.h> … … 35 37 namespace WebCore { 36 38 39 static constexpr double DefaultUserHeightInMeters = 1.65; 40 37 41 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRReferenceSpace); 38 42 39 43 Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) 40 44 { 41 return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), type)); 45 // https://immersive-web.github.io/webxr/#xrspace-native-origin 46 // The transform from the effective space to the native origin's space is 47 // defined by an origin offset, which is an XRRigidTransform initially set 48 // to an identity transform. 49 return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), WebXRRigidTransform::create(), type)); 42 50 } 43 51 44 WebXRReferenceSpace::WebXRReferenceSpace(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) 45 : WebXRSpace(document, WTFMove(session)) 52 Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) 53 { 54 return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), WTFMove(offset), type)); 55 } 56 57 WebXRReferenceSpace::WebXRReferenceSpace(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) 58 : WebXRSpace(document, WTFMove(offset)) 59 , m_session(WTFMove(session)) 46 60 , m_type(type) 47 61 { … … 50 64 WebXRReferenceSpace::~WebXRReferenceSpace() = default; 51 65 52 RefPtr<WebXRReferenceSpace> WebXRReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform&) 66 67 TransformationMatrix WebXRReferenceSpace::nativeOrigin() const 53 68 { 54 if (!scriptExecutionContext()) 69 TransformationMatrix identity; 70 71 // We assume that poses got from the devices are in local space. 72 // This will require more complex logic if we add ports with different default coordinates. 73 switch (m_type) { 74 case XRReferenceSpaceType::Viewer: { 75 // Return the current pose. Content rendered in viewer pose will stay in fixed point on HMDs. 76 auto& data = m_session->frameData(); 77 return WebXRFrame::matrixFromPose(data.origin); 78 } 79 case XRReferenceSpaceType::Local: 80 // Data from the device is already in local, use the identity matrix. 81 return identity; 82 case XRReferenceSpaceType::Unbounded: 83 // Local and unbounded use the same device space, use the identity matrix. 84 return identity; 85 case XRReferenceSpaceType::LocalFloor: { 86 // Use the floor transform provided by the device or fallback to a default height. 87 return floorOriginTransform(); 88 } 89 case XRReferenceSpaceType::BoundedFloor: 90 default: 91 // BoundedFloor is handled by WebXRBoundedReferenceSpace subclass 92 RELEASE_ASSERT_NOT_REACHED(); 93 } 94 95 return identity; 96 } 97 98 RefPtr<WebXRReferenceSpace> WebXRReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform& offsetTransform) 99 { 100 auto* document = downcast<Document>(scriptExecutionContext()); 101 if (!document) 55 102 return nullptr; 56 ASSERT(is<Document>(scriptExecutionContext())); 57 return create(downcast<Document>(*scriptExecutionContext()), m_session.copyRef(), m_type); 103 104 // https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace 105 // Set offsetSpace’s origin offset to the result of multiplying base’s origin offset by originOffset in the relevant realm of base. 106 auto offset = WebXRRigidTransform::create(originOffset().rawTransform() * offsetTransform.rawTransform()); 107 108 return create(*document, m_session.copyRef(), WTFMove(offset), m_type); 109 } 110 111 TransformationMatrix WebXRReferenceSpace::floorOriginTransform() const 112 { 113 auto& data = m_session->frameData(); 114 if (!data.floorTransform) { 115 TransformationMatrix defautTransform; 116 defautTransform.translate3d(0.0, -DefaultUserHeightInMeters, 0.0); 117 return defautTransform; 118 } 119 120 // https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-local-floor 121 // Get floor estimation from the device 122 // FIXME: Round to nearest 1cm to prevent fingerprinting 123 return WebXRFrame::matrixFromPose(*data.floorTransform); 58 124 } 59 125 -
trunk/Source/WebCore/Modules/webxr/WebXRReferenceSpace.h
r262299 r273132 38 38 class WebXRSession; 39 39 40 class WebXRReferenceSpace : public WebXRSpace {40 class WebXRReferenceSpace : public RefCounted<WebXRReferenceSpace>, public WebXRSpace { 41 41 WTF_MAKE_ISO_ALLOCATED(WebXRReferenceSpace); 42 42 public: 43 43 static Ref<WebXRReferenceSpace> create(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); 44 static Ref<WebXRReferenceSpace> create(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); 44 45 45 46 virtual ~WebXRReferenceSpace(); 46 47 47 RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&); 48 using RefCounted<WebXRReferenceSpace>::ref; 49 using RefCounted<WebXRReferenceSpace>::deref; 50 51 WebXRSession& session() const final { return m_session.get(); } 52 TransformationMatrix nativeOrigin() const override; 53 virtual RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&); 54 XRReferenceSpaceType type() const { return m_type; } 48 55 49 56 protected: 50 WebXRReferenceSpace(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType);57 WebXRReferenceSpace(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); 51 58 59 bool isReferenceSpace() const final { return true; } 60 61 TransformationMatrix floorOriginTransform() const; 62 63 Ref<WebXRSession> m_session; 52 64 XRReferenceSpaceType m_type; 65 66 private: 67 void refEventTarget() final { ref(); } 68 void derefEventTarget() final { deref(); } 53 69 }; 54 70 55 71 } // namespace WebCore 56 72 73 SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(WebXRReferenceSpace, isReferenceSpace()) 74 57 75 #endif // ENABLE(WEBXR) -
trunk/Source/WebCore/Modules/webxr/WebXRReferenceSpace.idl
r258498 r273132 31 31 JSGenerateToJSObject, 32 32 JSGenerateToNativeObject, 33 SkipVTableValidation, 33 34 InterfaceName=XRReferenceSpace 34 35 ] interface WebXRReferenceSpace : WebXRSpace { -
trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp
r272734 r273132 29 29 #if ENABLE(WEBXR) 30 30 31 #include "Document.h" 31 32 #include "EventNames.h" 32 33 #include "JSWebXRReferenceSpace.h" … … 34 35 #include "WebXRFrame.h" 35 36 #include "WebXRSystem.h" 37 #include "WebXRView.h" 36 38 #include "XRFrameRequestCallback.h" 37 39 #include "XRRenderStateInit.h" … … 56 58 , m_device(makeWeakPtr(device)) 57 59 , m_activeRenderState(WebXRRenderState::create(mode)) 60 , m_viewerReferenceSpace(makeUnique<WebXRViewerSpace>(document, *this)) 58 61 , m_timeOrigin(MonotonicTime::now()) 62 , m_views(device.views(mode)) 59 63 { 60 64 m_device->initializeTrackingAndRendering(mode); … … 479 483 480 484 // Queue a task to perform the following steps. 481 queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() {485 queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() mutable { 482 486 if (m_ended) 483 487 return; 488 489 m_frameData = frameData; 484 490 // 1.Let now be the current high resolution time. 485 491 auto now = (MonotonicTime::now() - m_timeOrigin).milliseconds(); 486 492 487 auto frame = WebXRFrame::create(makeRef(*this) );493 auto frame = WebXRFrame::create(makeRef(*this), WebXRFrame::IsAnimationFrame::Yes); 488 494 // 2.Let frame be session’s animation frame. 489 495 // 3.Set frame’s time to frameTime. … … 509 515 510 516 // 6.4.Apply frame updates for frame. 511 // FIXME: implement.517 frame->setFrameData(WTFMove(frameData)); 512 518 513 519 // 6.5.For each entry in session’s list of currently running animation frame callbacks, in order: … … 538 544 } 539 545 546 // https://immersive-web.github.io/webxr/#poses-may-be-reported 547 bool WebXRSession::posesCanBeReported(const Document& document) const 548 { 549 // 1. If session’s relevant global object is not the current global object, return false. 550 auto* sessionDocument = downcast<Document>(scriptExecutionContext()); 551 if (!sessionDocument || sessionDocument->domWindow() != document.domWindow()) 552 return false; 553 554 // 2. If session's visibilityState in not "visible", return false. 555 if (m_visibilityState != XRVisibilityState::Visible) 556 return false; 557 558 // 5. Determine if the pose data can be returned as follows: 559 // The procedure in the specs tries to ensure that we apply measures to 560 // prevent fingerprintint in pose data and return false in case we don't. 561 // We're going to apply them so let's just return true. 562 return true; 563 } 564 540 565 } // namespace WebCore 541 566 -
trunk/Source/WebCore/Modules/webxr/WebXRSession.h
r272734 r273132 34 34 #include "WebXRInputSourceArray.h" 35 35 #include "WebXRRenderState.h" 36 #include "WebXRSpace.h"37 36 #include "XREnvironmentBlendMode.h" 38 37 #include "XRInteractionMode.h" … … 49 48 50 49 class XRFrameRequestCallback; 51 class WebXRReferenceSpace;52 50 class WebXRSystem; 51 class WebXRView; 52 class WebXRViewerSpace; 53 53 struct XRRenderStateInit; 54 54 … … 91 91 XRSessionMode mode() const { return m_mode; } 92 92 93 const Vector<PlatformXR::Device::ViewData>& views() const { return m_views; } 94 const PlatformXR::Device::FrameData& frameData() const { return m_frameData; } 95 const WebXRViewerSpace& viewerReferenceSpace() const { return *m_viewerReferenceSpace; } 96 bool posesCanBeReported(const Document&) const; 97 93 98 private: 94 99 WebXRSession(Document&, WebXRSystem&, XRSessionMode, PlatformXR::Device&); … … 129 134 RefPtr<WebXRRenderState> m_activeRenderState; 130 135 RefPtr<WebXRRenderState> m_pendingRenderState; 136 std::unique_ptr<WebXRViewerSpace> m_viewerReferenceSpace; 131 137 MonotonicTime m_timeOrigin; 132 138 133 139 unsigned m_nextCallbackId { 1 }; 134 140 Vector<Ref<XRFrameRequestCallback>> m_callbacks; 141 142 Vector<PlatformXR::Device::ViewData> m_views; 143 PlatformXR::Device::FrameData m_frameData; 135 144 136 145 double m_minimumInlineFOV { 0.0 }; -
trunk/Source/WebCore/Modules/webxr/WebXRSpace.cpp
r262300 r273132 29 29 #if ENABLE(WEBXR) 30 30 31 #include "DOMPointReadOnly.h" 31 32 #include "Document.h" 33 #include "WebXRRigidTransform.h" 32 34 #include "WebXRSession.h" 33 35 #include <wtf/IsoMallocInlines.h> … … 37 39 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRSpace); 38 40 39 WebXRSpace::WebXRSpace(Document& document, Ref<WebXR Session>&& session)41 WebXRSpace::WebXRSpace(Document& document, Ref<WebXRRigidTransform>&& offset) 40 42 : ContextDestructionObserver(&document) 41 , m_ session(WTFMove(session))43 , m_originOffset(WTFMove(offset)) 42 44 { 43 45 } … … 45 47 WebXRSpace::~WebXRSpace() = default; 46 48 49 TransformationMatrix WebXRSpace::effectiveOrigin() const 50 { 51 // https://immersive-web.github.io/webxr/#xrspace-effective-origin 52 // The effective origin can be obtained by multiplying origin offset and the native origin. 53 return m_originOffset->rawTransform() * nativeOrigin(); 54 } 55 56 57 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerSpace); 58 59 WebXRViewerSpace::WebXRViewerSpace(Document& document, WebXRSession& session) 60 : WebXRSpace(document, WebXRRigidTransform::create()) 61 , m_session(session) 62 { 63 } 64 65 WebXRViewerSpace::~WebXRViewerSpace() = default; 66 67 TransformationMatrix WebXRViewerSpace::nativeOrigin() const 68 { 69 return WebXRFrame::matrixFromPose(m_session.frameData().origin); 70 } 71 72 47 73 } // namespace WebCore 48 74 -
trunk/Source/WebCore/Modules/webxr/WebXRSpace.h
r262299 r273132 30 30 #include "ContextDestructionObserver.h" 31 31 #include "EventTarget.h" 32 #include "TransformationMatrix.h" 32 33 #include <wtf/RefCounted.h> 33 34 … … 36 37 class Document; 37 38 class ScriptExecutionContext; 39 class WebXRRigidTransform; 38 40 class WebXRSession; 39 41 40 class WebXRSpace : public RefCounted<WebXRSpace>, publicEventTargetWithInlineData, public ContextDestructionObserver {42 class WebXRSpace : public EventTargetWithInlineData, public ContextDestructionObserver { 41 43 WTF_MAKE_ISO_ALLOCATED(WebXRSpace); 42 44 public: 43 45 virtual ~WebXRSpace(); 44 46 45 using RefCounted<WebXRSpace>::ref; 46 using RefCounted<WebXRSpace>::deref; 47 virtual WebXRSession& session() const = 0; 48 virtual TransformationMatrix nativeOrigin() const = 0; 49 TransformationMatrix effectiveOrigin() const; 50 51 virtual bool isReferenceSpace() const { return false; } 52 virtual bool isBoundedReferenceSpace() const { return false; } 47 53 48 54 protected: 49 WebXRSpace(Document&, Ref<WebXRSession>&&); 55 WebXRSpace(Document&, Ref<WebXRRigidTransform>&&); 56 57 const WebXRRigidTransform& originOffset() const { return m_originOffset.get(); } 50 58 51 59 // EventTarget 52 ScriptExecutionContext* scriptExecutionContext() const override { return ContextDestructionObserver::scriptExecutionContext(); } 53 54 Ref<WebXRSession> m_session; 60 ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } 55 61 56 62 private: 57 63 // EventTarget 58 EventTargetInterface eventTargetInterface() const override { return WebXRSpaceEventTargetInterfaceType; } 59 void refEventTarget() override { ref(); } 60 void derefEventTarget() override { deref(); } 64 EventTargetInterface eventTargetInterface() const final { return WebXRSpaceEventTargetInterfaceType; } 65 66 Ref<WebXRRigidTransform> m_originOffset; 67 }; 68 69 // https://immersive-web.github.io/webxr/#xrsession-viewer-reference-space 70 // This is a helper class to implement the viewer space owned by a WebXRSession. 71 // It avoids a circular reference between the session and the reference space. 72 class WebXRViewerSpace : public WebXRSpace { 73 WTF_MAKE_ISO_ALLOCATED(WebXRViewerSpace); 74 public: 75 WebXRViewerSpace(Document&, WebXRSession&); 76 virtual ~WebXRViewerSpace(); 77 78 private: 79 WebXRSession& session() const final { return m_session; } 80 TransformationMatrix nativeOrigin() const final; 81 82 void refEventTarget() final { RELEASE_ASSERT_NOT_REACHED(); } 83 void derefEventTarget() final { RELEASE_ASSERT_NOT_REACHED(); } 84 85 WebXRSession& m_session; 61 86 }; 62 87 63 88 } // namespace WebCore 64 89 90 #define SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(ToValueTypeName, predicate) \ 91 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ 92 static bool isType(const WebCore::WebXRSpace& context) { return context.predicate; } \ 93 SPECIALIZE_TYPE_TRAITS_END() 94 65 95 #endif // ENABLE(WEBXR) -
trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp
r272734 r273132 522 522 523 523 auto raf = InlineRequestAnimationFrameCallback::create(*m_scriptExecutionContext, [callback = WTFMove(callback)]() mutable { 524 callback({ }); 524 PlatformXR::Device::FrameData data; 525 data.isTrackingValid = true; 526 data.isPositionValid = true; 527 data.views.append({ }); 528 callback(WTFMove(data)); 525 529 }); 526 530 … … 528 532 } 529 533 534 Vector<PlatformXR::Device::ViewData> WebXRSystem::DummyInlineDevice::views(XRSessionMode) const 535 { 536 return { { .active = true, PlatformXR::Eye::None } }; 537 } 538 530 539 531 540 } // namespace WebCore -
trunk/Source/WebCore/Modules/webxr/WebXRSystem.h
r272734 r273132 112 112 void initializeTrackingAndRendering(PlatformXR::SessionMode) final { } 113 113 void shutDownTrackingAndRendering() final { } 114 void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { } ;114 void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { } 115 115 116 116 void requestFrame(PlatformXR::Device::RequestFrameCallback&&) final; 117 Vector<Device::ViewData> views(XRSessionMode) const final; 117 118 }; 118 119 DummyInlineDevice m_defaultInlineDevice; -
trunk/Source/WebCore/Modules/webxr/WebXRView.cpp
r260884 r273132 37 37 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRView); 38 38 39 Ref<WebXRView> WebXRView::create( )39 Ref<WebXRView> WebXRView::create(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection) 40 40 { 41 return adoptRef(*new WebXRView );41 return adoptRef(*new WebXRView(eye, WTFMove(transform), WTFMove(projection))); 42 42 } 43 43 44 WebXRView::WebXRView() 45 : m_eye(XREye::None) 44 WebXRView::WebXRView(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection) 45 : m_eye(eye) 46 , m_transform(WTFMove(transform)) 47 , m_projection(projection) 46 48 { 47 49 } … … 49 51 WebXRView::~WebXRView() = default; 50 52 51 void WebXRView::setProjectionMatrix(const Vector<float>& matrix)52 {53 m_projectionMatrix = Float32Array::create(matrix.data(), matrix.size());54 }55 56 53 } // namespace WebCore 57 54 -
trunk/Source/WebCore/Modules/webxr/WebXRView.h
r270067 r273132 38 38 namespace WebCore { 39 39 40 class WebXRFrame; 40 41 class WebXRRigidTransform; 41 42 … … 43 44 WTF_MAKE_ISO_ALLOCATED_EXPORT(WebXRView, WEBCORE_EXPORT); 44 45 public: 45 WEBCORE_EXPORT static Ref<WebXRView> create( );46 WEBCORE_EXPORT static Ref<WebXRView> create(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&); 46 47 WEBCORE_EXPORT ~WebXRView(); 47 48 48 49 XREye eye() const { return m_eye; } 49 const Float32Array& projectionMatrix() const { return *m_projectionMatrix; } 50 const WebXRRigidTransform& transform() const { return *m_transform; } 51 52 void setEye(XREye eye) { m_eye = eye; } 53 WEBCORE_EXPORT void setProjectionMatrix(const Vector<float>&); 54 void setTransform(RefPtr<WebXRRigidTransform>&& viewOffset) { m_transform = WTFMove(viewOffset); } 50 const Float32Array& projectionMatrix() const { return m_projection.get(); } 51 const WebXRRigidTransform& transform() const { return m_transform.get(); } 55 52 56 53 private: 57 WebXRView( );54 WebXRView(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&); 58 55 59 56 XREye m_eye; 60 Ref Ptr<Float32Array> m_projectionMatrix;61 Ref Ptr<WebXRRigidTransform> m_transform;57 Ref<WebXRRigidTransform> m_transform; 58 Ref<Float32Array> m_projection; 62 59 }; 63 60 -
trunk/Source/WebCore/Modules/webxr/WebXRViewerPose.cpp
r258498 r273132 26 26 #include "config.h" 27 27 #include "WebXRViewerPose.h" 28 #include <wtf/IsoMallocInlines.h> 28 29 29 30 #if ENABLE(WEBXR) … … 31 32 namespace WebCore { 32 33 33 Ref<WebXRViewerPose> WebXRViewerPose::create() 34 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerPose); 35 36 Ref<WebXRViewerPose> WebXRViewerPose::create(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) 34 37 { 35 return adoptRef(*new WebXRViewerPose );38 return adoptRef(*new WebXRViewerPose(WTFMove(transform), emulatedPosition)); 36 39 } 37 40 38 WebXRViewerPose::WebXRViewerPose() = default; 41 WebXRViewerPose::WebXRViewerPose(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) 42 : WebXRPose(WTFMove(transform), emulatedPosition) 43 { 44 } 45 39 46 WebXRViewerPose::~WebXRViewerPose() = default; 40 47 … … 44 51 } 45 52 53 void WebXRViewerPose::setViews(Vector<Ref<WebXRView>>&& views) 54 { 55 m_views = WTFMove(views); 56 } 57 46 58 } // namespace WebCore 47 59 -
trunk/Source/WebCore/Modules/webxr/WebXRViewerPose.h
r258498 r273132 38 38 39 39 class WebXRViewerPose : public WebXRPose { 40 WTF_MAKE_ISO_ALLOCATED(WebXRViewerPose); 40 41 public: 41 static Ref<WebXRViewerPose> create( );42 ~WebXRViewerPose();42 static Ref<WebXRViewerPose> create(Ref<WebXRRigidTransform>&&, bool emulatedPosition); 43 virtual ~WebXRViewerPose(); 43 44 44 45 const Vector<Ref<WebXRView>>& views() const; 46 void setViews(Vector<Ref<WebXRView>>&&); 45 47 46 48 private: 47 WebXRViewerPose(); 49 WebXRViewerPose(Ref<WebXRRigidTransform>&&, bool emulatedPosition); 50 51 bool isViewerPose() const final { return true; } 48 52 49 53 Vector<Ref<WebXRView>> m_views; … … 52 56 } // namespace WebCore 53 57 58 SPECIALIZE_TYPE_TRAITS_WEBXRPOSE(WebXRViewerPose, isViewerPose()) 59 54 60 #endif // ENABLE(WEBXR) -
trunk/Source/WebCore/Modules/webxr/WebXRViewerPose.idl
r258498 r273132 29 29 SecureContext, 30 30 Exposed=Window, 31 ImplementationLacksVTable, 31 JSGenerateToJSObject, 32 JSGenerateToNativeObject, 32 33 InterfaceName=XRViewerPose 33 34 ] interface WebXRViewerPose : WebXRPose { -
trunk/Source/WebCore/Modules/webxr/XREye.h
r258498 r273132 28 28 #if ENABLE(WEBXR) 29 29 30 #include "PlatformXR.h" 31 30 32 namespace WebCore { 31 33 32 enum class XREye { 33 None, 34 Left, 35 Right, 36 }; 34 using XREye = PlatformXR::Eye; 37 35 38 36 } // namespace WebCore -
trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
r271941 r273132 585 585 TransformationMatrix TransformationMatrix::fromQuaternion(double qx, double qy, double qz, double qw) 586 586 { 587 constdouble xx = qx * qx;588 constdouble yy = qy * qy;589 constdouble zz = qz * qz;590 constdouble xz = qx * qz;591 constdouble xy = qx * qy;592 constdouble yz = qy * qz;593 constdouble xw = qw * qx;594 constdouble yw = qw * qy;595 constdouble zw = qw * qz;587 double xx = qx * qx; 588 double yy = qy * qy; 589 double zz = qz * qz; 590 double xz = qx * qz; 591 double xy = qx * qy; 592 double yz = qy * qz; 593 double xw = qw * qx; 594 double yw = qw * qy; 595 double zw = qw * qz; 596 596 597 597 return TransformationMatrix(1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0, … … 599 599 2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0, 600 600 0, 0, 0, 1); 601 } 602 603 604 TransformationMatrix TransformationMatrix::fromProjection(double fovUp, double fovDown, double fovLeft, double fovRight, double depthNear, double depthFar) 605 { 606 double upTan = tan(fovUp); 607 double downTan = tan(fovDown); 608 double leftTan = tan(fovLeft); 609 double rightTan = tan(fovRight); 610 double xScale = 2.0 / (leftTan + rightTan); 611 double yScale = 2.0 / (upTan + downTan); 612 double invDepth = 1.0 / (depthNear - depthFar); 613 614 return TransformationMatrix(xScale, 0.0f, 0.0f, 0.0f, 615 0.0f, yScale, 0.0f, 0.0f, 616 (leftTan - rightTan) * xScale * -0.5, (upTan - downTan) * yScale * 0.5, (depthNear + depthFar) * invDepth, -1.0f, 617 0.0f, 0.0f, (2.0f * depthFar * depthNear) * invDepth, 0.0f); 618 } 619 620 TransformationMatrix TransformationMatrix::fromProjection(double fovy, double aspect, double depthNear, double depthFar) 621 { 622 double f = 1.0f / tanf(fovy / 2); 623 double invDepth = 1.0f / (depthNear - depthFar); 624 625 return TransformationMatrix(f / aspect, 0.0f, 0.0f, 0.0f, 626 0.0f, f, 0.0f, 0.0f, 627 0.0f, 0.0f, (depthFar + depthNear) * invDepth, -1.0f, 628 0.0f, 0.0f, (2.0f * depthFar * depthNear) * invDepth, 0.0f); 601 629 } 602 630 -
trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
r271941 r273132 121 121 122 122 static TransformationMatrix fromQuaternion(double qx, double qy, double qz, double qw); 123 124 // Field of view in radians 125 static TransformationMatrix fromProjection(double fovUp, double fovDown, double fovLeft, double fovRight, double depthNear, double depthFar); 126 static TransformationMatrix fromProjection(double fovy, double aspect, double depthNear, double depthFar); 123 127 124 128 static const TransformationMatrix identity; -
trunk/Source/WebCore/platform/xr/PlatformXR.h
r272734 r273132 25 25 #include <wtf/HashMap.h> 26 26 #include <wtf/UniqueRef.h> 27 #include <wtf/Variant.h> 27 28 #include <wtf/Vector.h> 28 29 #include <wtf/WeakPtr.h> … … 42 43 BoundedFloor, 43 44 Unbounded 45 }; 46 47 enum class Eye { 48 None, 49 Left, 50 Right, 44 51 }; 45 52 … … 80 87 81 88 struct FrameData { 82 long predictedDisplayTime; 83 struct ViewData { 84 struct { 85 WebCore::FloatPoint3D position; 86 struct { 87 float x; 88 float y; 89 float z; 90 float w; 91 } orientation; 92 } pose; 93 struct { 94 float rUp; 95 float rDown; 96 float rLeft; 97 float rRight; 98 } fov; 89 struct FloatQuaternion { 90 float x { 0.0f }; 91 float y { 0.0f }; 92 float z { 0.0f }; 93 float w { 1.0f }; 99 94 }; 100 Vector<ViewData> viewPoses; 95 96 struct Pose { 97 WebCore::FloatPoint3D position; 98 FloatQuaternion orientation; 99 }; 100 101 struct Fov { 102 // In radians 103 float up { 0.0f }; 104 float down { 0.0f }; 105 float left { 0.0f }; 106 float right { 0.0f }; 107 }; 108 109 using Projection = Variant<Fov, std::array<float, 16>, std::nullptr_t>; 110 111 struct View { 112 Pose offset; 113 Projection projection = { nullptr }; 114 }; 115 116 bool isTrackingValid { false }; 117 bool isPositionValid { false }; 118 bool isPositionEmulated { false }; 119 long predictedDisplayTime { 0 }; 120 Pose origin; 121 Optional<Pose> floorTransform; 122 Vector<View> views; 101 123 }; 124 125 struct ViewData { 126 bool active { false }; 127 Eye eye { Eye::None }; 128 }; 129 130 virtual Vector<ViewData> views(SessionMode) const = 0; 131 102 132 using RequestFrameCallback = Function<void(FrameData&&)>; 103 133 virtual void requestFrame(RequestFrameCallback&&) = 0; 104 105 134 protected: 106 135 Device() = default; -
trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp
r272734 r273132 300 300 } 301 301 302 XrSpace OpenXRDevice::createReferenceSpace(XrReferenceSpaceType type) 303 { 304 ASSERT(&RunLoop::current() == &m_queue.runLoop()); 305 ASSERT(m_session != XR_NULL_HANDLE); 306 ASSERT(m_instance != XR_NULL_HANDLE); 307 308 XrPosef identityPose { 309 .orientation = { .x = 0, .y = 0, .z = 0, .w = 1.0 }, 310 .position = { .x = 0, .y = 0, .z = 0 } 311 }; 312 313 auto spaceCreateInfo = createStructure<XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO>(); 314 spaceCreateInfo.referenceSpaceType = type; 315 spaceCreateInfo.poseInReferenceSpace = identityPose; 316 317 XrSpace space; 318 auto result = xrCreateReferenceSpace(m_session, &spaceCreateInfo, &space); 319 RETURN_IF_FAILED(result, "xrCreateReferenceSpace", m_instance, XR_NULL_HANDLE); 320 321 return space; 322 } 323 302 324 void OpenXRDevice::collectSupportedSessionModes() 303 325 { … … 369 391 } 370 392 371 WebCore::IntSize OpenXRDevice::recommendedResolution(SessionMode mode)372 {373 auto configType = mode == SessionMode::Inline ? XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO : XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;374 auto viewsIterator = m_configurationViews.find(configType);375 if (viewsIterator != m_configurationViews.end())376 return { static_cast<int>(viewsIterator->value[0].recommendedImageRectWidth), static_cast<int>(viewsIterator->value[0].recommendedImageRectHeight) };377 return Device::recommendedResolution(mode);378 }379 380 393 XrViewConfigurationType toXrViewConfigurationType(SessionMode mode) 381 394 { … … 401 414 } 402 415 416 WebCore::IntSize OpenXRDevice::recommendedResolution(SessionMode mode) 417 { 418 auto configType = toXrViewConfigurationType(mode); 419 auto viewsIterator = m_configurationViews.find(configType); 420 if (viewsIterator != m_configurationViews.end()) 421 return { static_cast<int>(viewsIterator->value[0].recommendedImageRectWidth), static_cast<int>(viewsIterator->value[0].recommendedImageRectHeight) }; 422 return Device::recommendedResolution(mode); 423 } 424 403 425 void OpenXRDevice::initializeTrackingAndRendering(SessionMode mode) 404 426 { … … 415 437 auto result = xrCreateSession(m_instance, &sessionCreateInfo, &m_session); 416 438 RETURN_IF_FAILED(result, "xrEnumerateInstanceExtensionProperties", m_instance); 439 440 m_localSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_LOCAL); 441 m_viewSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_VIEW); 417 442 }); 418 443 } … … 456 481 waitUntilStopping(); 457 482 }); 483 } 484 485 void OpenXRDevice::initializeReferenceSpace(PlatformXR::ReferenceSpaceType spaceType) 486 { 487 if ((spaceType == ReferenceSpaceType::LocalFloor || spaceType == ReferenceSpaceType::BoundedFloor) && m_stageSpace == XR_NULL_HANDLE) 488 m_stageSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_STAGE); 458 489 } 459 490 … … 527 558 } 528 559 529 530 Device::FrameData::ViewData xrViewToViewData(XrView view) 531 { 532 Device::FrameData::ViewData data; 533 data.fov = { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight }; 534 data.pose.orientation = { view.pose.orientation.x, view.pose.orientation.y, view.pose.orientation.z, view.pose.orientation.w }; 535 data.pose.position = { view.pose.position.x, view.pose.position.y, view.pose.position.z }; 536 return data; 560 static Device::FrameData::Pose XrPosefToPose(XrPosef pose) 561 { 562 Device::FrameData::Pose result; 563 result.orientation = { pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w }; 564 result.position = { pose.position.x, pose.position.y, pose.position.z }; 565 return result; 566 } 567 568 static Device::FrameData::View xrViewToPose(XrView view) 569 { 570 Device::FrameData::View pose; 571 pose.projection = Device::FrameData::Fov { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight }; 572 pose.offset = XrPosefToPose(view.pose); 573 return pose; 537 574 } 538 575 … … 563 600 564 601 if (isSessionActive(m_sessionState)) { 602 // Query head location 603 auto location = createStructure<XrSpaceLocation, XR_TYPE_SPACE_LOCATION>(); 604 xrLocateSpace(m_viewSpace, m_localSpace, frameState.predictedDisplayTime, &location); 605 frameData.isTrackingValid = location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT; 606 frameData.isPositionValid = location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT; 607 frameData.isPositionEmulated = location.locationFlags & XR_SPACE_LOCATION_POSITION_TRACKED_BIT; 608 609 if (frameData.isTrackingValid) 610 frameData.origin = XrPosefToPose(location.pose); 611 565 612 ASSERT(m_configurationViews.contains(m_currentViewConfigurationType)); 566 613 const auto& configurationView = m_configurationViews.get(m_currentViewConfigurationType); … … 568 615 auto viewLocateInfo = createStructure<XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO>(); 569 616 viewLocateInfo.displayTime = predictedTime; 570 // FIXME: use the current reference space. 571 // viewLocateInfo.space = m_localSpace; 617 viewLocateInfo.space = m_localSpace; 572 618 573 619 uint32_t viewCount = configurationView.size(); … … 584 630 if (!XR_FAILED(result)) { 585 631 for (auto& view : views) 586 frameData.viewPoses.append(xrViewToViewData(view)); 632 frameData.views.append(xrViewToPose(view)); 633 } 634 635 // Query floor transform 636 if (m_stageSpace != XR_NULL_HANDLE) { 637 auto floorLocation = createStructure<XrSpaceLocation, XR_TYPE_SPACE_LOCATION>(); 638 xrLocateSpace(m_stageSpace, m_localSpace, frameState.predictedDisplayTime, &floorLocation); 639 frameData.floorTransform = { XrPosefToPose(floorLocation.pose) }; 587 640 } 588 641 } … … 601 654 } 602 655 656 Vector<Device::ViewData> OpenXRDevice::views(SessionMode mode) const 657 { 658 Vector<Device::ViewData> views; 659 auto configurationType = toXrViewConfigurationType(mode); 660 661 if (configurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO) 662 views.append({ .active = true, .eye = Eye::None }); 663 else { 664 ASSERT(configurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO); 665 views.append({ .active = true, Eye::Left }); 666 views.append({ .active = true, Eye::Right }); 667 } 668 return views; 669 } 670 603 671 } // namespace PlatformXR 604 672 -
trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h
r272734 r273132 52 52 53 53 ListOfEnabledFeatures enumerateReferenceSpaces(XrSession&) const; 54 void initializeReferenceSpace(ReferenceSpaceType) final { };54 XrSpace createReferenceSpace(XrReferenceSpaceType); 55 55 56 56 WebCore::IntSize recommendedResolution(SessionMode) final; … … 58 58 void initializeTrackingAndRendering(SessionMode) final; 59 59 void shutDownTrackingAndRendering() final; 60 void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final; 60 61 bool supportsSessionShutdownNotification() const final { return true; } 61 62 void waitUntilStopping(); … … 68 69 69 70 void requestFrame(RequestFrameCallback&&) final; 71 72 Vector<ViewData> views(SessionMode) const final; 70 73 71 74 using ViewConfigurationPropertiesMap = HashMap<XrViewConfigurationType, XrViewConfigurationProperties, IntHash<XrViewConfigurationType>, WTF::StrongEnumHashTraits<XrViewConfigurationType>>; … … 82 85 83 86 XrViewConfigurationType m_currentViewConfigurationType; 87 XrSpace m_localSpace { XR_NULL_HANDLE }; 88 XrSpace m_viewSpace { XR_NULL_HANDLE }; 89 XrSpace m_stageSpace { XR_NULL_HANDLE }; 84 90 }; 85 91 -
trunk/Source/WebCore/testing/WebFakeXRDevice.cpp
r272734 r273132 33 33 #include "WebFakeXRInputController.h" 34 34 #include <wtf/CompletionHandler.h> 35 #include <wtf/MathExtras.h> 35 36 36 37 namespace WebCore { … … 38 39 static constexpr Seconds FakeXRFrameTime = 15_ms; 39 40 40 void FakeXRView::setFieldOfView(FakeXRViewInit::FieldOfViewInit fov) 41 { 42 m_fov = fov; 41 void FakeXRView::setProjection(const Vector<float>& projection) 42 { 43 std::copy(std::begin(projection), std::end(projection), std::begin(m_projection)); 44 } 45 46 void FakeXRView::setFieldOfView(const FakeXRViewInit::FieldOfViewInit& fov) 47 { 48 m_fov = PlatformXR::Device::FrameData::Fov { deg2rad(fov.upDegrees), deg2rad(fov.downDegrees), deg2rad(fov.leftDegrees), deg2rad(fov.rightDegrees) }; 43 49 } 44 50 … … 75 81 void SimulatedXRDevice::frameTimerFired() 76 82 { 77 auto callbacks = WTFMove(m_callbacks); 78 for (auto& callback : callbacks) 79 callback({ }); 83 auto updates = WTFMove(m_pendingUpdates); 84 for (auto& update : updates) 85 update(); 86 87 FrameData data; 88 if (m_viewerOrigin) { 89 data.origin = *m_viewerOrigin; 90 data.isTrackingValid = true; 91 data.isPositionValid = true; 92 } 93 94 if (m_floorOrigin) 95 data.floorTransform = { *m_floorOrigin }; 96 97 for (auto& fakeView : m_views) { 98 FrameData::View view; 99 view.offset = fakeView->offset(); 100 if (fakeView->fieldOfView().hasValue()) 101 view.projection = { *fakeView->fieldOfView() }; 102 else 103 view.projection = { fakeView->projection() }; 104 105 data.views.append(view); 106 } 107 108 if (m_FrameCallback) 109 m_FrameCallback(WTFMove(data)); 80 110 } 81 111 82 112 void SimulatedXRDevice::requestFrame(RequestFrameCallback&& callback) 83 113 { 84 m_ callbacks.append(WTFMove(callback));114 m_FrameCallback = WTFMove(callback); 85 115 if (!m_frameTimer.isActive()) 86 116 m_frameTimer.startOneShot(FakeXRFrameTime); 87 117 } 88 118 119 Vector<PlatformXR::Device::ViewData> SimulatedXRDevice::views(PlatformXR::SessionMode mode) const 120 { 121 if (mode == PlatformXR::SessionMode::ImmersiveVr) 122 return { { .active = true, PlatformXR::Eye::Left }, { .active = true, PlatformXR::Eye::Right } }; 123 124 return { { .active = true, PlatformXR::Eye::None } }; 125 } 126 127 void SimulatedXRDevice::scheduleOnNextFrame(Function<void()>&& func) 128 { 129 m_pendingUpdates.append(WTFMove(func)); 130 } 131 89 132 WebFakeXRDevice::WebFakeXRDevice() = default; 90 133 91 134 void WebFakeXRDevice::setViews(const Vector<FakeXRViewInit>& views) 92 135 { 93 Vector<Ref<FakeXRView>>& deviceViews = m_device.views(); 94 deviceViews.clear(); 95 96 // TODO: do in next animation frame. 97 for (auto& viewInit : views) { 98 auto view = parseView(viewInit); 99 if (!view.hasException()) 100 deviceViews.append(view.releaseReturnValue()); 101 } 136 m_device.scheduleOnNextFrame([this, views]() { 137 Vector<Ref<FakeXRView>> deviceViews; 138 139 for (auto& viewInit : views) { 140 auto view = parseView(viewInit); 141 if (!view.hasException()) 142 deviceViews.append(view.releaseReturnValue()); 143 } 144 145 m_device.setViews(WTFMove(deviceViews)); 146 }); 102 147 } 103 148 … … 109 154 void WebFakeXRDevice::setViewerOrigin(FakeXRRigidTransformInit origin, bool emulatedPosition) 110 155 { 111 auto r igidTransform= parseRigidTransform(origin);112 if (r igidTransform.hasException())156 auto result = parseRigidTransform(origin); 157 if (result.hasException()) 113 158 return; 114 159 115 // TODO: do in next animation frame. 116 m_device.setViewerOrigin(rigidTransform.releaseReturnValue()); 117 m_device.setEmulatedPosition(emulatedPosition); 160 auto pose = result.releaseReturnValue(); 161 162 m_device.scheduleOnNextFrame([this, pose = WTFMove(pose), emulatedPosition]() mutable { 163 m_device.setViewerOrigin(WTFMove(pose)); 164 m_device.setEmulatedPosition(emulatedPosition); 165 }); 118 166 } 119 167 120 168 void WebFakeXRDevice::clearViewerOrigin() 121 169 { 122 // TODO: do in next animation frame. 123 m_device.setViewerOrigin(nullptr); 170 m_device.scheduleOnNextFrame([this]() { 171 m_device.setViewerOrigin(WTF::nullopt); 172 }); 124 173 } 125 174 … … 128 177 } 129 178 130 void WebFakeXRDevice::setBoundsGeometry(Vector<FakeXRBoundsPoint> )179 void WebFakeXRDevice::setBoundsGeometry(Vector<FakeXRBoundsPoint>&&) 131 180 { 132 181 } … … 134 183 void WebFakeXRDevice::setFloorOrigin(FakeXRRigidTransformInit origin) 135 184 { 136 auto r igidTransform= parseRigidTransform(origin);137 if (r igidTransform.hasException())185 auto result = parseRigidTransform(origin); 186 if (result.hasException()) 138 187 return; 139 188 140 // TODO: do in next animation frame. 141 m_device.setFloorOrigin(rigidTransform.releaseReturnValue()); 189 auto pose = result.releaseReturnValue(); 190 191 m_device.scheduleOnNextFrame([this, pose = WTFMove(pose)]() mutable { 192 m_device.setFloorOrigin(WTFMove(pose)); 193 }); 142 194 } 143 195 144 196 void WebFakeXRDevice::clearFloorOrigin() 145 197 { 146 // TODO: do in next animation frame. 147 m_device.setFloorOrigin(nullptr); 198 m_device.scheduleOnNextFrame([this]() { 199 m_device.setFloorOrigin(WTF::nullopt); 200 }); 148 201 } 149 202 … … 157 210 } 158 211 159 ExceptionOr< Ref<WebXRRigidTransform>> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init)212 ExceptionOr<PlatformXR::Device::FrameData::Pose> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init) 160 213 { 161 214 if (init.position.size() != 3 || init.orientation.size() != 4) 162 215 return Exception { TypeError }; 163 216 164 DOMPointInit position; 165 position.x = init.position[0]; 166 position.y = init.position[1]; 167 position.z = init.position[2]; 168 169 DOMPointInit orientation; 170 orientation.x = init.orientation[0]; 171 orientation.y = init.orientation[1]; 172 orientation.z = init.orientation[2]; 173 orientation.w = init.orientation[3]; 174 175 return WebXRRigidTransform::create(position, orientation); 217 PlatformXR::Device::FrameData::Pose pose; 218 pose.position = { init.position[0], init.position[1], init.position[2] }; 219 pose.orientation = { init.orientation[0], init.orientation[1], init.orientation[2], init.orientation[3] }; 220 221 return pose; 176 222 } 177 223 … … 183 229 if (init.projectionMatrix.size() != 16) 184 230 return Exception { TypeError }; 185 fakeView-> view()->setProjectionMatrix(init.projectionMatrix);231 fakeView->setProjection(init.projectionMatrix); 186 232 187 233 auto viewOffset = parseRigidTransform(init.viewOffset); 188 234 if (viewOffset.hasException()) 189 235 return viewOffset.releaseException(); 190 fakeView-> view()->setTransform(viewOffset.releaseReturnValue());236 fakeView->setOffset(viewOffset.releaseReturnValue()); 191 237 192 238 fakeView->setResolution(init.resolution); … … 194 240 if (init.fieldOfView) { 195 241 fakeView->setFieldOfView(init.fieldOfView.value()); 196 // TODO: Set view’s projection matrix to the projection matrix197 // corresponding to this field of view, and depth values equal to198 // depthNear and depthFar of any XRSession associated with the device.199 // If there currently is none, use the default values of near=0.1,200 // far=1000.0.201 242 } 202 243 -
trunk/Source/WebCore/testing/WebFakeXRDevice.h
r272734 r273132 34 34 #include "PlatformXR.h" 35 35 #include "WebFakeXRInputController.h" 36 #include "WebXRRigidTransform.h"37 #include "WebXRView.h"38 36 #include "XRVisibilityState.h" 39 37 #include <wtf/RefCounted.h> … … 44 42 public: 45 43 static Ref<FakeXRView> create(XREye eye) { return adoptRef(*new FakeXRView(eye)); } 44 using Pose = PlatformXR::Device::FrameData::Pose; 45 using Fov = PlatformXR::Device::FrameData::Fov; 46 46 47 RefPtr<WebXRView> view() { return m_view; } 47 XREye eye() const { return m_eye; } 48 const Pose& offset() const { return m_offset; } 49 const std::array<float, 16>& projection() const { return m_projection; } 50 const Optional<Fov>& fieldOfView() const { return m_fov;} 51 48 52 void setResolution(FakeXRViewInit::DeviceResolution resolution) { m_resolution = resolution; } 49 void setFieldOfView(FakeXRViewInit::FieldOfViewInit); 50 53 void setOffset(Pose&& offset) { m_offset = WTFMove(offset); } 54 void setProjection(const Vector<float>&); 55 void setFieldOfView(const FakeXRViewInit::FieldOfViewInit&); 51 56 private: 52 57 FakeXRView(XREye eye) 53 { 54 m_view = WebXRView::create(); 55 m_view->setEye(eye); 56 } 58 : m_eye(eye) { } 57 59 58 RefPtr<WebXRView> m_view; 60 61 XREye m_eye; 59 62 FakeXRViewInit::DeviceResolution m_resolution; 60 FakeXRViewInit::FieldOfViewInit m_fov; 63 Pose m_offset; 64 std::array<float, 16> m_projection; 65 Optional<Fov> m_fov; 61 66 }; 62 67 … … 66 71 SimulatedXRDevice(); 67 72 ~SimulatedXRDevice(); 68 void setNativeBoundsGeometry(Vector<FakeXRBoundsPoint> geometry) { m_nativeBoundsGeometry = geometry; } 69 void setViewerOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_viewerOrigin = WTFMove(origin); } 70 void setFloorOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_floorOrigin = WTFMove(origin); } 73 void setViews(Vector<Ref<FakeXRView>>&& views) { m_views = WTFMove(views); } 74 void setNativeBoundsGeometry(const Vector<FakeXRBoundsPoint>& geometry) { m_nativeBoundsGeometry = geometry; } 75 void setViewerOrigin(Optional<FrameData::Pose>&& origin) { m_viewerOrigin = WTFMove(origin); } 76 void setFloorOrigin(Optional<FrameData::Pose>&& origin) { m_floorOrigin = WTFMove(origin); } 71 77 void setEmulatedPosition(bool emulated) { m_emulatedPosition = emulated; } 72 78 Vector<Ref<FakeXRView>>& views() { return m_views; } 73 79 void setSupportsShutdownNotification(bool supportsShutdownNotification) { m_supportsShutdownNotification = supportsShutdownNotification; } 74 80 void simulateShutdownCompleted(); 81 void scheduleOnNextFrame(Function<void()>&&); 75 82 private: 76 83 void initializeTrackingAndRendering(PlatformXR::SessionMode) final { } … … 78 85 bool supportsSessionShutdownNotification() const final { return m_supportsShutdownNotification; } 79 86 void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { } 87 Vector<PlatformXR::Device::ViewData> views(PlatformXR::SessionMode) const final; 80 88 void requestFrame(RequestFrameCallback&&) final; 81 89 … … 84 92 85 93 Optional<Vector<FakeXRBoundsPoint>> m_nativeBoundsGeometry; 86 RefPtr<WebXRRigidTransform> m_viewerOrigin;87 RefPtr<WebXRRigidTransform> m_floorOrigin;94 Optional<FrameData::Pose> m_viewerOrigin; 95 Optional<FrameData::Pose> m_floorOrigin; 88 96 bool m_emulatedPosition { false }; 89 97 Vector<Ref<FakeXRView>> m_views; 90 98 bool m_supportsShutdownNotification { false }; 91 99 Timer m_frameTimer; 92 Vector<RequestFrameCallback> m_callbacks; 100 RequestFrameCallback m_FrameCallback; 101 Vector<Function<void()>> m_pendingUpdates; 93 102 }; 94 103 … … 107 116 void simulateVisibilityChange(XRVisibilityState); 108 117 109 void setBoundsGeometry(Vector<FakeXRBoundsPoint> boundsCoordinates);118 void setBoundsGeometry(Vector<FakeXRBoundsPoint>&& boundsCoordinates); 110 119 111 120 void setFloorOrigin(FakeXRRigidTransformInit); … … 128 137 WebFakeXRDevice(); 129 138 130 static ExceptionOr< Ref<WebXRRigidTransform>> parseRigidTransform(const FakeXRRigidTransformInit&);139 static ExceptionOr<PlatformXR::Device::FrameData::Pose> parseRigidTransform(const FakeXRRigidTransformInit&); 131 140 132 141 SimulatedXRDevice m_device;
Note: See TracChangeset
for help on using the changeset viewer.