Commit 8736d781 authored by Brandon Jones's avatar Brandon Jones Committed by Commit Bot

Added XRRay type, converted XRInputPose to use it.

New type provides origin and direction for the ray as DOMPointReadOnly
values.

Bug: 868461
Cq-Include-Trybots: luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I918d8cad2569919b3d159eb910da4dddb31d3562
Reviewed-on: https://chromium-review.googlesource.com/1153475
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579264}
parent 20f6fb7c
......@@ -10023,7 +10023,7 @@ interface XRInputPose
attribute @@toStringTag
getter emulatedPosition
getter gripMatrix
getter pointerMatrix
getter targetRay
method constructor
interface XRInputSource
attribute @@toStringTag
......@@ -10042,6 +10042,12 @@ interface XRPresentationContext
attribute @@toStringTag
getter canvas
method constructor
interface XRRay
attribute @@toStringTag
getter direction
getter origin
getter transformMatrix
method constructor
interface XRSession : EventTarget
attribute @@toStringTag
getter baseLayer
......
......@@ -11,8 +11,8 @@
<script>
let testName = "XRInputSources with a pointer origin of 'hand' properly "
+ "communicate their poses";
let testName = "XRInputSources with a target ray mode of 'tracked-pointer' "
+ "properly communicate their poses";
let fakeDeviceInitParams = { supportsImmersive: true };
......@@ -72,9 +72,9 @@ let testFunction =
// the grip and pointer matrices should be the same.
assert_matrices_approx_equal(input_pose.gripMatrix, VALID_GRIP,
FLOAT_EPSILON, "Grip matrix is not equal to input.");
assert_matrices_approx_equal(input_pose.pointerMatrix,
assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
input_pose.gripMatrix, FLOAT_EPSILON,
"Grip matrix is not equal to pointer matrix.");
"Grip matrix is not equal to target ray matrix.");
});
input_source.pointerOffset = VALID_POINTER_OFFSET;
......@@ -93,7 +93,7 @@ let testFunction =
// offset.
assert_matrices_approx_equal(input_pose.gripMatrix, VALID_GRIP,
FLOAT_EPSILON, "Grip matrix is not equal to input valid grip.");
assert_matrices_approx_equal(input_pose.pointerMatrix,
assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
VALID_GRIP_WITH_POINTER_OFFSET, FLOAT_EPSILON,
"Grip matrix not multipled properly.");
});
......
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-internal-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "XRInputSources produce valid target rays";
let fakeDeviceInitParams = { supportsImmersive: true };
let requestSessionOptions = [{ immersive: true }];
let testFunction =
(session, t, fakeDeviceController) => new Promise((resolve) => {
// Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl);
// Need to have a valid pose or input events don't process.
fakeDeviceController.setXRPresentationFrameData(VALID_POSE_MATRIX, [{
eye:"left",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VALID_VIEW_MATRIX
}, {
eye:"right",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VALID_VIEW_MATRIX
}]);
let input_source = new MockXRInputSource();
input_source.targetRayMode = "tracked-pointer";
input_source.handedness = "right";
input_source.grip = VALID_GRIP;
fakeDeviceController.addInputSource(input_source);
// Must have a frameOfReference to get input poses. eye-level doesn't apply
// any transforms to the given matrix.
session.requestFrameOfReference("eye-level").then( (frameOfRef) => {
function CheckTargetRayNoOffset(time, xrFrame) {
let source = session.getInputSources()[0];
let input_pose = xrFrame.getInputPose(source, frameOfRef);
t.step( () => {
assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
input_pose.gripMatrix, FLOAT_EPSILON,
"Target ray matrix is incorrect.");
assert_equals(input_pose.targetRay.origin.x, 4.0);
assert_equals(input_pose.targetRay.origin.y, 3.0);
assert_equals(input_pose.targetRay.origin.z, 2.0);
assert_equals(input_pose.targetRay.origin.w, 1.0);
assert_equals(input_pose.targetRay.direction.x, 0.0);
assert_equals(input_pose.targetRay.direction.y, 0.0);
assert_equals(input_pose.targetRay.direction.z, -1.0);
assert_equals(input_pose.targetRay.direction.w, 0.0);
}, "Target ray computed properly with no pointer offset");
input_source.pointerOffset = VALID_POINTER_OFFSET;
session.requestAnimationFrame(CheckTargetRayOffset);
}
function CheckTargetRayOffset(time, xrFrame) {
let source = session.getInputSources()[0];
let input_pose = xrFrame.getInputPose(source, frameOfRef);
t.step( () => {
assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
VALID_GRIP_WITH_POINTER_OFFSET, FLOAT_EPSILON,
"Target ray matrix is not offset properly.");
assert_equals(input_pose.targetRay.origin.x, 4.0);
assert_equals(input_pose.targetRay.origin.y, 3.0);
assert_equals(input_pose.targetRay.origin.z, 3.0);
assert_equals(input_pose.targetRay.origin.w, 1.0);
assert_equals(input_pose.targetRay.direction.x, 0.0);
assert_equals(input_pose.targetRay.direction.y, 0.0);
assert_equals(input_pose.targetRay.direction.z, -1.0);
assert_equals(input_pose.targetRay.direction.w, 0.0);
}, "Target ray computed properly with a pointer offset");
resolve();
}
// Can only request input poses in an xr frame.
session.requestAnimationFrame(CheckTargetRayNoOffset);
});
});
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
......@@ -437,6 +437,7 @@ modules_idl_files =
"xr/xr_input_source_event.idl",
"xr/xr_layer.idl",
"xr/xr_presentation_context.idl",
"xr/xr_ray.idl",
"xr/xr_session.idl",
"xr/xr_session_event.idl",
"xr/xr_stage_bounds.idl",
......
......@@ -36,6 +36,8 @@ blink_modules_sources("xr") {
"xr_layer.h",
"xr_presentation_context.cc",
"xr_presentation_context.h",
"xr_ray.cc",
"xr_ray.h",
"xr_session.cc",
"xr_session.h",
"xr_session_event.cc",
......
......@@ -11,18 +11,12 @@ namespace blink {
XRInputPose::XRInputPose(std::unique_ptr<TransformationMatrix> pointer_matrix,
std::unique_ptr<TransformationMatrix> grip_matrix,
bool emulated_position)
: pointer_matrix_(std::move(pointer_matrix)),
: target_ray_(new XRRay(std::move(pointer_matrix))),
grip_matrix_(std::move(grip_matrix)),
emulated_position_(emulated_position) {}
XRInputPose::~XRInputPose() {}
DOMFloat32Array* XRInputPose::pointerMatrix() const {
if (!pointer_matrix_)
return nullptr;
return transformationMatrixToFloat32Array(*pointer_matrix_);
}
DOMFloat32Array* XRInputPose::gripMatrix() const {
if (!grip_matrix_)
return nullptr;
......@@ -30,6 +24,7 @@ DOMFloat32Array* XRInputPose::gripMatrix() const {
}
void XRInputPose::Trace(blink::Visitor* visitor) {
visitor->Trace(target_ray_);
ScriptWrappable::Trace(visitor);
}
......
......@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_POSE_H_
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/modules/xr/xr_ray.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
......@@ -17,19 +18,19 @@ class XRInputPose final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
XRInputPose(std::unique_ptr<TransformationMatrix> pointer_matrix,
XRInputPose(std::unique_ptr<TransformationMatrix> target_ray_matrix,
std::unique_ptr<TransformationMatrix> grip_matrix,
bool emulated_position = false);
~XRInputPose() override;
DOMFloat32Array* pointerMatrix() const;
XRRay* targetRay() const { return target_ray_; }
DOMFloat32Array* gripMatrix() const;
bool emulatedPosition() const { return emulated_position_; }
void Trace(blink::Visitor*) override;
private:
const std::unique_ptr<TransformationMatrix> pointer_matrix_;
const Member<XRRay> target_ray_;
const std::unique_ptr<TransformationMatrix> grip_matrix_;
const bool emulated_position_;
};
......
......@@ -6,7 +6,7 @@
SecureContext,
OriginTrialEnabled=WebXR
] interface XRInputPose {
readonly attribute Float32Array pointerMatrix;
readonly attribute XRRay targetRay;
readonly attribute Float32Array? gripMatrix;
readonly attribute boolean emulatedPosition;
};
\ No newline at end of file
// Copyright 2018 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_ray.h"
#include "third_party/blink/renderer/modules/xr/xr_utils.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
namespace blink {
XRRay::XRRay(std::unique_ptr<TransformationMatrix> transform_matrix)
: transform_matrix_(std::move(transform_matrix)) {
FloatPoint3D origin = transform_matrix_->MapPoint(FloatPoint3D(0, 0, 0));
FloatPoint3D dir = transform_matrix_->MapPoint(FloatPoint3D(0, 0, -1));
dir.Move(-origin.X(), -origin.Y(), -origin.Z());
dir.Normalize();
origin_ = DOMPointReadOnly::Create(origin.X(), origin.Y(), origin.Z(), 1.0);
direction_ = DOMPointReadOnly::Create(dir.X(), dir.Y(), dir.Z(), 0.0);
}
XRRay::~XRRay() {}
DOMFloat32Array* XRRay::transformMatrix() const {
if (!transform_matrix_)
return nullptr;
// TODO(https://crbug.com/845296): rename
// transformationMatrixToFloat32Array() to
// TransformationMatrixToDOMFloat32Array().
return transformationMatrixToFloat32Array(*transform_matrix_);
}
void XRRay::Trace(blink::Visitor* visitor) {
visitor->Trace(origin_);
visitor->Trace(direction_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2018 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_RAY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_RAY_H_
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class TransformationMatrix;
class XRRay final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit XRRay(std::unique_ptr<TransformationMatrix>);
~XRRay() override;
DOMPointReadOnly* origin() const { return origin_; }
DOMPointReadOnly* direction() const { return direction_; }
DOMFloat32Array* transformMatrix() const;
void Trace(blink::Visitor*) override;
private:
Member<DOMPointReadOnly> origin_;
Member<DOMPointReadOnly> direction_;
const std::unique_ptr<TransformationMatrix> transform_matrix_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_RAY_H_
// Copyright 2018 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.
// https://immersive-web.github.io/webxr/#xrray-interface
[SecureContext, OriginTrialEnabled=WebXR] interface XRRay {
readonly attribute DOMPointReadOnly origin;
readonly attribute DOMPointReadOnly direction;
readonly attribute Float32Array transformMatrix;
};
\ No newline at end of file
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