Commit b4569fac authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

Use XRPlaneSet instead of array of XRPlanes

XRPlaneSet is a readonly setlike<XRPlane>.

Change-Id: Ifefac1ff5f04a5d52dfb80828b2a2c769c62ebf8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1663456
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#670328}
parent 59d7c6ab
...@@ -505,6 +505,7 @@ modules_idl_files = ...@@ -505,6 +505,7 @@ modules_idl_files =
"xr/xr_layer.idl", "xr/xr_layer.idl",
"xr/xr_plane.idl", "xr/xr_plane.idl",
"xr/xr_plane_detection_state.idl", "xr/xr_plane_detection_state.idl",
"xr/xr_plane_set.idl",
"xr/xr_pose.idl", "xr/xr_pose.idl",
"xr/xr_ray.idl", "xr/xr_ray.idl",
"xr/xr_reference_space.idl", "xr/xr_reference_space.idl",
......
...@@ -40,6 +40,8 @@ blink_modules_sources("xr") { ...@@ -40,6 +40,8 @@ blink_modules_sources("xr") {
"xr_plane.h", "xr_plane.h",
"xr_plane_detection_state.cc", "xr_plane_detection_state.cc",
"xr_plane_detection_state.h", "xr_plane_detection_state.h",
"xr_plane_set.cc",
"xr_plane_set.h",
"xr_pose.cc", "xr_pose.cc",
"xr_pose.h", "xr_pose.h",
"xr_ray.cc", "xr_ray.cc",
......
// 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_plane_set.h"
namespace blink {
XRPlaneSet::XRPlaneSet(HeapHashSet<Member<XRPlane>> planes) : planes_(planes) {}
unsigned XRPlaneSet::size() const {
return planes_.size();
}
bool XRPlaneSet::hasForBinding(ScriptState*,
XRPlane* plane,
ExceptionState&) const {
DCHECK(plane);
return planes_.find(plane) != planes_.end();
}
XRPlaneSet::IterationSource* XRPlaneSet::StartIteration(
ScriptState* script_state,
ExceptionState& exception_state) {
return MakeGarbageCollected<XRPlaneSet::IterationSource>(planes_);
}
void XRPlaneSet::Trace(blink::Visitor* visitor) {
visitor->Trace(planes_);
ScriptWrappable::Trace(visitor);
}
XRPlaneSet::IterationSource::IterationSource(
const HeapHashSet<Member<XRPlane>>& planes)
: index_(0) {
for (auto plane : planes) {
planes_.push_back(plane);
}
}
bool XRPlaneSet::IterationSource::Next(ScriptState* script_state,
Member<XRPlane>& key,
Member<XRPlane>& value,
ExceptionState& exception_state) {
if (index_ >= planes_.size()) {
return false;
}
key = value = planes_[index_];
++index_;
return true;
}
void XRPlaneSet::IterationSource::Trace(blink::Visitor* visitor) {
visitor->Trace(planes_);
SetlikeIterable<Member<XRPlane>>::IterationSource::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_PLANE_SET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_PLANE_SET_H_
#include "third_party/blink/renderer/bindings/core/v8/iterable.h"
#include "third_party/blink/renderer/modules/xr/xr_plane.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
class XRPlaneSet : public ScriptWrappable,
public SetlikeIterable<Member<XRPlane>> {
DEFINE_WRAPPERTYPEINFO();
public:
explicit XRPlaneSet(HeapHashSet<Member<XRPlane>> planes);
unsigned size() const;
// Returns true if passed in |plane| is a member of the XRPlaneSet.
bool hasForBinding(ScriptState* script_state,
XRPlane* plane,
ExceptionState& exception_state) const;
void Trace(blink::Visitor* visitor) override;
private:
class IterationSource final
: public SetlikeIterable<Member<XRPlane>>::IterationSource {
public:
explicit IterationSource(const HeapHashSet<Member<XRPlane>>& planes);
bool Next(ScriptState* script_state,
Member<XRPlane>& key,
Member<XRPlane>& value,
ExceptionState& exception_state) override;
void Trace(blink::Visitor* visitor) override;
private:
HeapVector<Member<XRPlane>> planes_;
unsigned index_;
};
// Starts iteration over XRPlaneSet.
// Needed for SetlikeIterable to work properly.
XRPlaneSet::IterationSource* StartIteration(
ScriptState* script_state,
ExceptionState& exception_state) override;
HeapHashSet<Member<XRPlane>> planes_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_PLANE_SET_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.
// More details about the plane detection API can be found here:
// https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md
[
SecureContext,
Exposed=Window,
RuntimeEnabled=WebXRPlaneDetection
]
interface XRPlaneSet {
readonly setlike<XRPlane>;
};
...@@ -17,21 +17,19 @@ void XRWorldInformation::Trace(blink::Visitor* visitor) { ...@@ -17,21 +17,19 @@ void XRWorldInformation::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor); ScriptWrappable::Trace(visitor);
} }
HeapVector<Member<XRPlane>> XRWorldInformation::detectedPlanes( XRPlaneSet* XRWorldInformation::detectedPlanes() const {
bool& is_null) const {
DVLOG(3) << __func__; DVLOG(3) << __func__;
HeapVector<Member<XRPlane>> result; HeapHashSet<Member<XRPlane>> result;
is_null = is_detected_planes_null_; if (is_detected_planes_null_)
if (is_null) return nullptr;
return result;
for (auto& plane_id_and_plane : plane_ids_to_planes_) { for (auto& plane_id_and_plane : plane_ids_to_planes_) {
result.push_back(plane_id_and_plane.value); result.insert(plane_id_and_plane.value);
} }
return result; return MakeGarbageCollected<XRPlaneSet>(result);
} }
void XRWorldInformation::ProcessPlaneInformation( void XRWorldInformation::ProcessPlaneInformation(
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/modules/xr/xr_plane.h" #include "third_party/blink/renderer/modules/xr/xr_plane.h"
#include "third_party/blink/renderer/modules/xr/xr_plane_set.h"
namespace blink { namespace blink {
...@@ -18,9 +19,9 @@ class XRWorldInformation : public ScriptWrappable { ...@@ -18,9 +19,9 @@ class XRWorldInformation : public ScriptWrappable {
public: public:
XRWorldInformation(XRSession* session); XRWorldInformation(XRSession* session);
// Returns vector containing detected planes, |is_null| will be set to true // Returns set of detected planes. Returns null if plane detection is
// if plane detection is not enabled. // disabled.
HeapVector<Member<XRPlane>> detectedPlanes(bool& is_null) const; XRPlaneSet* detectedPlanes() const;
void Trace(blink::Visitor* visitor) override; void Trace(blink::Visitor* visitor) override;
......
...@@ -10,6 +10,6 @@ ...@@ -10,6 +10,6 @@
RuntimeEnabled=WebXRPlaneDetection RuntimeEnabled=WebXRPlaneDetection
] ]
interface XRWorldInformation { interface XRWorldInformation {
readonly attribute FrozenArray<XRPlane>? detectedPlanes; readonly attribute XRPlaneSet? detectedPlanes;
}; };
...@@ -175,11 +175,18 @@ function hitTestPlane(ray, plane, frameOfReference) { ...@@ -175,11 +175,18 @@ function hitTestPlane(ray, plane, frameOfReference) {
// multiple planes hit test // multiple planes hit test
export function hitTest(ray, planes, frameOfReference) { export function hitTest(ray, planes, frameOfReference) {
const hit_test_results = planes.map(plane => hitTestPlane(ray, plane, frameOfReference)); let hit_test_results = [];
planes.forEach(plane => {
let result = hitTestPlane(ray, plane, frameOfReference);
if(result) {
// throw away results with no intersection with plane
hit_test_results.push(result);
}
});
// throw away all strange results (no intersection with plane, ray lies on plane) // throw away all strange results (ray lies on plane)
let hit_test_results_with_points = hit_test_results.filter( let hit_test_results_with_points = hit_test_results.filter(
maybe_plane => maybe_plane && typeof maybe_plane.point != "undefined"); maybe_plane => typeof maybe_plane.point != "undefined");
// sort results by distance // sort results by distance
hit_test_results_with_points.sort((l, r) => l.distance - r.distance); hit_test_results_with_points.sort((l, r) => l.distance - r.distance);
......
...@@ -412,7 +412,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -412,7 +412,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
} }
} }
let all_planes = new Set(); // Set with all planes detected in a previous frame.
let all_previous_planes = new Set();
// Called every time a XRSession requests that a new frame be drawn. // Called every time a XRSession requests that a new frame be drawn.
async function onXRFrame(t, frame) { async function onXRFrame(t, frame) {
...@@ -420,32 +421,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -420,32 +421,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
let session = frame.session; let session = frame.session;
let pose = frame.getViewerPose(xrRefSpace); let pose = frame.getViewerPose(xrRefSpace);
let previous_planes = new Set(all_planes);
let detected_planes = frame.worldInformation.detectedPlanes; let detected_planes = frame.worldInformation.detectedPlanes;
detected_planes.forEach(plane => {
addPlaneToScene(plane, t);
if(previous_planes.has(plane)) {
previous_planes.delete(plane);
}
});
previous_planes.forEach(plane => { // Check if any of the old planes is no longer present in detected planes set.
console.log("Removing plane, id:", plane.id); // If it's no longer present, it was removed - clean up after.
all_previous_planes.forEach(plane => {
if(!detected_planes.has(plane)) {
console.log("Removing plane, id:", plane.id);
let index = all_plane_origins.findIndex(element => element === plane.scene_node.origins); let index = all_plane_origins.findIndex(
if(index != -1){ element => element === plane.scene_node.origins);
all_plane_origins.splice(index, 1); if(index != -1){
} all_plane_origins.splice(index, 1);
}
index = all_extended_planes.findIndex(element => element === plane.extended_polygon_node); index = all_extended_planes.findIndex(
if(index != -1){ element => element === plane.extended_polygon_node);
all_extended_planes.splice(index, 1); if(index != -1){
} all_extended_planes.splice(index, 1);
}
scene.removeNode(plane.scene_node); scene.removeNode(plane.scene_node);
}
}); });
all_planes = new Set(detected_planes); // Store currently detected planes to check against them in subsequent frame.
all_previous_planes = detected_planes;
// Process all currently detected planes.
detected_planes.forEach(plane => {
addPlaneToScene(plane, t);
});
// If requested, use the pose to cast a reticle into the scene using a // If requested, use the pose to cast a reticle into the scene using a
// continuous hit test. For the moment we're just using the flower // continuous hit test. For the moment we're just using the flower
......
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