Commit 2e3ac049 authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

Add Web IDL for transient input variant of hit test subscription

Along with blink-side implementation of the Web IDL.

Change-Id: I1f975c0b36f2a0e8d38400368455fd4a23cb19c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1919942
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Auto-Submit: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718819}
parent 31ceb036
......@@ -541,8 +541,8 @@ enum SubscribeToHitTestResult {
};
enum EntityTypeForHitTest {
POINT = 0,
PLANE = 1,
POINT = 1,
PLANE = 2,
};
// Provides functionality for integrating environment information into an
......
......@@ -531,6 +531,8 @@ modules_idl_files =
"xr/xr_session.idl",
"xr/xr_session_event.idl",
"xr/xr_space.idl",
"xr/xr_transient_input_hit_test_result.idl",
"xr/xr_transient_input_hit_test_source.idl",
"xr/xr_view.idl",
"xr/xr_viewer_pose.idl",
"xr/xr_viewport.idl",
......@@ -890,6 +892,7 @@ modules_dictionary_idl_files =
"xr/xr_render_state_init.idl",
"xr/xr_session_event_init.idl",
"xr/xr_session_init.idl",
"xr/xr_transient_input_hit_test_options_init.idl",
"xr/xr_webgl_layer_init.idl",
"xr/xr_world_tracking_state_init.idl",
],
......
......@@ -72,6 +72,10 @@ blink_modules_sources("xr") {
"xr_space.h",
"xr_target_ray_space.cc",
"xr_target_ray_space.h",
"xr_transient_input_hit_test_result.cc",
"xr_transient_input_hit_test_result.h",
"xr_transient_input_hit_test_source.cc",
"xr_transient_input_hit_test_source.h",
"xr_utils.cc",
"xr_utils.h",
"xr_view.cc",
......
......@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
#include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h"
#include "third_party/blink/renderer/modules/xr/xr_view.h"
#include "third_party/blink/renderer/modules/xr/xr_viewer_pose.h"
#include "third_party/blink/renderer/modules/xr/xr_world_information.h"
......@@ -133,7 +134,17 @@ void XRFrame::Deactivate() {
HeapVector<Member<XRHitTestResult>> XRFrame::getHitTestResults(
XRHitTestSource* hit_test_source) {
if (!session_->ValidateHitTestSourceExists(hit_test_source))
if (!hit_test_source ||
!session_->ValidateHitTestSourceExists(hit_test_source))
return {};
return hit_test_source->Results();
}
HeapVector<Member<XRTransientInputHitTestResult>>
XRFrame::getHitTestResultsForTransientInput(
XRTransientInputHitTestSource* hit_test_source) {
if (!hit_test_source ||
!session_->ValidateHitTestSourceExists(hit_test_source))
return {};
return hit_test_source->Results();
}
......
......@@ -17,6 +17,7 @@
namespace blink {
class ExceptionState;
class XRAnchorSet;
class XRHitTestResult;
class XRHitTestSource;
class XRInputSource;
......@@ -24,8 +25,9 @@ class XRPose;
class XRReferenceSpace;
class XRSession;
class XRSpace;
class XRTransientInputHitTestResult;
class XRTransientInputHitTestSource;
class XRViewerPose;
class XRAnchorSet;
class XRWorldInformation;
class XRFrame final : public ScriptWrappable {
......@@ -54,6 +56,10 @@ class XRFrame final : public ScriptWrappable {
HeapVector<Member<XRHitTestResult>> getHitTestResults(
XRHitTestSource* hit_test_source);
HeapVector<Member<XRTransientInputHitTestResult>>
getHitTestResultsForTransientInput(
XRTransientInputHitTestSource* hit_test_source);
bool EmulatedPosition() const { return emulated_position_; }
private:
......
......@@ -19,5 +19,8 @@
[RaisesException] XRViewerPose? getViewerPose(XRReferenceSpace referenceSpace);
[RaisesException] XRPose? getPose(XRSpace space, XRSpace relativeTo);
[RuntimeEnabled=WebXRHitTest] FrozenArray<XRHitTestResult> getHitTestResults(XRHitTestSource hitTestSource);
[RuntimeEnabled=WebXRHitTest]
FrozenArray<XRHitTestResult> getHitTestResults(XRHitTestSource hitTestSource);
[RuntimeEnabled=WebXRHitTest]
FrozenArray<XRTransientInputHitTestResult> getHitTestResultsForTransientInput(XRTransientInputHitTestSource hitTestSource);
};
......@@ -2,7 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
enum XRHitTestTrackableType {
"point",
"plane"
};
dictionary XRHitTestOptionsInit {
required XRSpace space;
FrozenArray<XRHitTestTrackableType> entityTypes;
XRRay offsetRay;
};
......@@ -10,10 +10,8 @@
namespace blink {
XRHitTestResult::XRHitTestResult(XRHitTestSource* hit_test_source,
const TransformationMatrix& pose)
: hit_test_source_(hit_test_source),
pose_(std::make_unique<TransformationMatrix>(pose)) {}
XRHitTestResult::XRHitTestResult(const TransformationMatrix& pose)
: pose_(std::make_unique<TransformationMatrix>(pose)) {}
XRPose* XRHitTestResult::getPose(XRSpace* relative_to) {
DCHECK(relative_to->MojoFromSpace());
......@@ -30,9 +28,4 @@ XRPose* XRHitTestResult::getPose(XRSpace* relative_to) {
return MakeGarbageCollected<XRPose>(other_from_this, false);
}
void XRHitTestResult::Trace(blink::Visitor* visitor) {
visitor->Trace(hit_test_source_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
......@@ -10,7 +10,6 @@
namespace blink {
class TransformationMatrix;
class XRHitTestSource;
class XRPose;
class XRSpace;
......@@ -18,15 +17,11 @@ class XRHitTestResult : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
XRHitTestResult(XRHitTestSource* hit_test_source,
const TransformationMatrix& pose);
explicit XRHitTestResult(const TransformationMatrix& pose);
XRPose* getPose(XRSpace* relative_to);
void Trace(blink::Visitor* visitor) override;
private:
Member<XRHitTestSource> hit_test_source_;
std::unique_ptr<TransformationMatrix> pose_;
};
......
......@@ -19,7 +19,7 @@ HeapVector<Member<XRHitTestResult>> XRHitTestSource::Results() {
HeapVector<Member<XRHitTestResult>> results;
for (const auto& result : last_frame_results_) {
results.emplace_back(MakeGarbageCollected<XRHitTestResult>(this, *result));
results.emplace_back(MakeGarbageCollected<XRHitTestResult>(*result));
}
return results;
......
......@@ -48,6 +48,8 @@ class XRRenderState;
class XRRenderStateInit;
class XRRigidTransform;
class XRSpace;
class XRTransientInputHitTestOptionsInit;
class XRTransientInputHitTestSource;
class XRViewData;
class XRWebGLLayer;
class XRWorldInformation;
......@@ -146,6 +148,10 @@ class XRSession final
ScriptPromise requestHitTestSource(ScriptState* script_state,
XRHitTestOptionsInit* options,
ExceptionState& exception_state);
ScriptPromise requestHitTestSourceForTransientInput(
ScriptState* script_state,
XRTransientInputHitTestOptionsInit* options_init,
ExceptionState& exception_state);
ScriptPromise requestHitTest(ScriptState* script_state,
XRRay* ray,
......@@ -235,6 +241,8 @@ class XRSession final
// Returns true if the session recognizes passed in hit_test_source as still
// existing.
bool ValidateHitTestSourceExists(XRHitTestSource* hit_test_source);
bool ValidateHitTestSourceExists(
XRTransientInputHitTestSource* hit_test_source);
void SetXRDisplayInfo(device::mojom::blink::VRDisplayInfoPtr display_info);
......@@ -291,6 +299,15 @@ class XRSession final
void ProcessInputSourceEvents(
base::span<const device::mojom::blink::XRInputSourceStatePtr>
input_states);
// Processes world understanding state for current frame:
// - updates state of hit test sources & fills them out with results
// - updates state of detected planes
// - updates state of anchors
// In order to correctly set the state of hit test sources, this *must* be
// called after updating XRInputSourceArray (performed by
// OnInputStateChangeInternal) as hit test results for transient input sources
// use the mapping of input source id to XRInputSource object.
void UpdateWorldUnderstandingStateForFrame(
double timestamp,
const device::mojom::blink::XRFrameDataPtr& frame_data);
......@@ -313,6 +330,11 @@ class XRSession final
device::mojom::SubscribeToHitTestResult result,
uint64_t subscription_id);
void OnSubscribeToHitTestForTransientInputResult(
ScriptPromiseResolver* resolver,
device::mojom::SubscribeToHitTestResult result,
uint64_t subscription_id);
void OnCreateAnchorResult(ScriptPromiseResolver* resolver,
device::mojom::CreateAnchorResult result,
uint64_t id);
......@@ -368,6 +390,8 @@ class XRSession final
// that we don't keep the XRHitTestSources alive.
HeapHashMap<uint64_t, WeakMember<XRHitTestSource>>
hit_test_source_ids_to_hit_test_sources_;
HeapHashMap<uint64_t, WeakMember<XRTransientInputHitTestSource>>
hit_test_source_ids_to_transient_input_hit_test_sources_;
WTF::Vector<XRViewData> views_;
......@@ -379,8 +403,8 @@ class XRSession final
HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises_;
// Set of promises returned from CreateAnchor that are still in-flight.
HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_;
// Set of promises returned from requestHitTestSource that are still
// in-flight.
// Set of promises returned from requestHitTestSource and
// requestHitTestSourceForTransientInput that are still in-flight.
HeapHashSet<Member<ScriptPromiseResolver>> request_hit_test_source_promises_;
HeapVector<Member<XRReferenceSpace>> reference_spaces_;
......
......@@ -58,5 +58,9 @@ enum XRVisibilityState {
[CallWith=ScriptState, Measure, RaisesException] Promise<void> end();
[RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException] Promise<XRHitTestSource> requestHitTestSource(XRHitTestOptionsInit options);
// https://github.com/immersive-web/hit-test/blob/master/hit-testing-explainer.md
[RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException]
Promise<XRHitTestSource> requestHitTestSource(XRHitTestOptionsInit options);
[RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException]
Promise<XRTransientInputHitTestSource> requestHitTestSourceForTransientInput(XRTransientInputHitTestOptionsInit options);
};
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
dictionary XRTransientInputHitTestOptionsInit {
required DOMString profile;
FrozenArray<XRHitTestTrackableType> entityTypes;
XRRay offsetRay;
};
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h"
#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/modules/xr/xr_hit_test_result.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
namespace blink {
XRTransientInputHitTestResult::XRTransientInputHitTestResult(
XRInputSource* input_source,
const WTF::Vector<device::mojom::blink::XRHitResultPtr>& results)
: input_source_(input_source) {
for (const auto& result : results) {
results_.push_back(
MakeGarbageCollected<XRHitTestResult>(result->hit_matrix.matrix()));
}
}
XRInputSource* XRTransientInputHitTestResult::inputSource() {
return input_source_;
}
HeapVector<Member<XRHitTestResult>> XRTransientInputHitTestResult::results() {
return results_;
}
void XRTransientInputHitTestResult::Trace(blink::Visitor* visitor) {
visitor->Trace(input_source_);
visitor->Trace(results_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_TRANSIENT_INPUT_HIT_TEST_RESULT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_TRANSIENT_INPUT_HIT_TEST_RESULT_H_
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
namespace blink {
class XRInputSource;
class XRHitTestResult;
class XRTransientInputHitTestResult : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
XRTransientInputHitTestResult(
XRInputSource* input_source,
const WTF::Vector<device::mojom::blink::XRHitResultPtr>& results);
XRInputSource* inputSource();
HeapVector<Member<XRHitTestResult>> results();
void Trace(blink::Visitor* visitor) override;
private:
Member<XRInputSource> input_source_;
HeapVector<Member<XRHitTestResult>> results_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_TRANSIENT_INPUT_HIT_TEST_RESULT_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest]
interface XRTransientInputHitTestResult {
[SameObject] readonly attribute XRInputSource inputSource;
[SameObject] readonly attribute FrozenArray<XRHitTestResult> results;
};
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source_array.h"
#include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h"
#include "device/vr/public/mojom/vr_service.mojom-blink.h"
namespace blink {
XRTransientInputHitTestSource::XRTransientInputHitTestSource(uint64_t id)
: id_(id) {}
uint64_t XRTransientInputHitTestSource::id() const {
return id_;
}
void XRTransientInputHitTestSource::Update(
const WTF::HashMap<uint32_t,
WTF::Vector<device::mojom::blink::XRHitResultPtr>>&
hit_test_results,
XRInputSourceArray* input_source_array) {
// TODO: Be smarter about the update - it's possible to add new resulst /
// remove the ones that were removed & update the ones that are being changed.
current_frame_results_.clear();
// If we don't know anything about input sources, we won't be able to
// construct any results so we are done (and current_frame_results_ should
// stay empty).
if (!input_source_array) {
return;
}
for (const auto& source_id_and_results : hit_test_results) {
XRInputSource* input_source =
input_source_array->GetWithSourceId(source_id_and_results.key);
// If the input source with the given ID could not be found, just skip
// processing results for this input source.
if (!input_source)
continue;
current_frame_results_.push_back(
MakeGarbageCollected<XRTransientInputHitTestResult>(
input_source, source_id_and_results.value));
}
}
HeapVector<Member<XRTransientInputHitTestResult>>
XRTransientInputHitTestSource::Results() {
return current_frame_results_;
}
void XRTransientInputHitTestSource::Trace(blink::Visitor* visitor) {
visitor->Trace(current_frame_results_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_TRANSIENT_INPUT_HIT_TEST_SOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_TRANSIENT_INPUT_HIT_TEST_SOURCE_H_
#include <memory>
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
namespace blink {
class XRInputSourceArray;
class XRTransientInputHitTestResult;
class XRTransientInputHitTestSource : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit XRTransientInputHitTestSource(uint64_t id);
uint64_t id() const;
void Update(
const WTF::HashMap<uint32_t,
WTF::Vector<device::mojom::blink::XRHitResultPtr>>&
hit_test_results,
XRInputSourceArray* input_source_array);
HeapVector<Member<XRTransientInputHitTestResult>> Results();
void Trace(blink::Visitor*) override;
private:
HeapVector<Member<XRTransientInputHitTestResult>> current_frame_results_;
const uint64_t id_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_TRANSIENT_INPUT_HIT_TEST_SOURCE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest]
interface XRTransientInputHitTestSource {
};
......@@ -11068,6 +11068,7 @@ interface XRFrame
getter session
method constructor
method getHitTestResults
method getHitTestResultsForTransientInput
method getPose
method getViewerPose
interface XRHitResult
......@@ -11164,6 +11165,7 @@ interface XRSession : EventTarget
method requestAnimationFrame
method requestHitTest
method requestHitTestSource
method requestHitTestSourceForTransientInput
method requestReferenceSpace
method updateRenderState
setter onend
......@@ -11179,6 +11181,14 @@ interface XRSessionEvent : Event
interface XRSpace : EventTarget
attribute @@toStringTag
method constructor
interface XRTransientInputHitTestResult
attribute @@toStringTag
getter inputSource
getter results
method constructor
interface XRTransientInputHitTestSource
attribute @@toStringTag
method constructor
interface XRView
attribute @@toStringTag
getter eye
......
......@@ -80,6 +80,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
let xrViewerSpace = null;
let xrOffsetSpace = null;
let xrViewerSpaceHitTestSource = null;
let xrTransientInputHitTestSource = null;
// WebGL scene globals.
let gl = null;
......@@ -163,6 +164,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
session.addEventListener('select', onSelect);
session.addEventListener('inputsourceschange', onInputSourcesChange);
session.requestHitTestSourceForTransientInput({
profile : "generic-touchscreen"
}).then(transient_input_hit_test_source => {
console.debug("Hit test source for generic touchscreen created!");
xrTransientInputHitTestSource = transient_input_hit_test_source;
});
if (!gl) {
gl = createWebGLContext({
xrCompatible: true
......@@ -245,33 +253,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
let rayDirection = vec3.create();
function onSelect(event) {
if (useReticle.checked && arObject.visible) {
if (arObject.visible) {
// If we're using the reticle then we've already got a mesh positioned
// at the latest hit point and we should just use its matrix to save
// an unnecessary requestHitTest call.
addARObjectAt(arObject.matrix);
} else {
// Otherwise we'll use the target ray from the input source that generated
// this event to fire off a new hit test.
let inputPose = event.frame.getPose(event.inputSource.targetRaySpace, xrRefSpace);
if (inputPose) {
let targetRay = new XRRay(inputPose.transform);
vec3.set(rayOrigin,
targetRay.origin.x,
targetRay.origin.y,
targetRay.origin.z);
vec3.set(rayDirection,
targetRay.direction.x,
targetRay.direction.y,
targetRay.direction.z);
let ray = new XRRay(DOMPointFromVec3(rayOrigin), DOMPointFromVec3(rayDirection));
event.frame.session.requestHitTest(ray, xrRefSpace).then((results) => {
if (results.length) {
addARObjectAt(results[0].hitMatrix);
}
});
}
}
}
......@@ -305,6 +291,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
arObject.visible = false;
}
} else if (!useReticle.checked && xrTransientInputHitTestSource) {
let results_by_input_source = frame.getHitTestResultsForTransientInput(xrTransientInputHitTestSource);
if(results_by_input_source.length && results_by_input_source[0].results.length) {
let hitResult = results_by_input_source[0].results[0];
arObject.visible = true;
arObject.matrix = hitResult.getPose(xrRefSpace).transform.matrix;
} else {
arObject.visible = false;
}
} else {
arObject.visible = false;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment