Commit 0ae15aa1 authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

Fix XRObjectSpace::MojoFromNative(), XRSession::CreateAnchor()

Fixes XRObjectSpace::MojoFromNative() returning incorrect (inverted)
results. Fixes XRSession::CreateAnchor() incorrectly assuming that
passed in initial pose is expressed relative to mojo, and creating
resolver too early in the method.

Other minor refactorings:
- XRHitTestResult::getPose() - no functional changes, clarified naming
- XRObjectSpace now assumes that T has MojoFromObject() method
- Changed XRPlane and XRAnchor - renamed poseMatrix() to
MojoFromObject() to match the changed expectations in XRObjectSpace.

Fixed: 1032070, 1031684
Change-Id: I5aeefec31c2f501c56cff5b419af9bdff3eb1159
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1958428
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723412}
parent dd54b7e0
...@@ -49,7 +49,7 @@ XRSpace* XRAnchor::anchorSpace() const { ...@@ -49,7 +49,7 @@ XRSpace* XRAnchor::anchorSpace() const {
return anchor_space_; return anchor_space_;
} }
TransformationMatrix XRAnchor::poseMatrix() const { TransformationMatrix XRAnchor::MojoFromObject() const {
if (anchor_data_) { if (anchor_data_) {
return *anchor_data_->pose_matrix_; return *anchor_data_->pose_matrix_;
} }
......
...@@ -32,7 +32,7 @@ class XRAnchor : public ScriptWrappable { ...@@ -32,7 +32,7 @@ class XRAnchor : public ScriptWrappable {
XRSpace* anchorSpace() const; XRSpace* anchorSpace() const;
TransformationMatrix poseMatrix() const; TransformationMatrix MojoFromObject() const;
double lastChangedTime(bool& is_null) const; double lastChangedTime(bool& is_null) const;
......
...@@ -13,19 +13,23 @@ namespace blink { ...@@ -13,19 +13,23 @@ namespace blink {
XRHitTestResult::XRHitTestResult(const TransformationMatrix& pose) XRHitTestResult::XRHitTestResult(const TransformationMatrix& pose)
: pose_(std::make_unique<TransformationMatrix>(pose)) {} : pose_(std::make_unique<TransformationMatrix>(pose)) {}
XRPose* XRHitTestResult::getPose(XRSpace* relative_to) { XRPose* XRHitTestResult::getPose(XRSpace* other) {
DCHECK(relative_to->MojoFromNative()); auto maybe_other_space_native_from_mojo = other->NativeFromMojo();
DCHECK(maybe_other_space_native_from_mojo);
auto mojo_from_this = *pose_; auto mojo_from_this =
*pose_; // Hit test results do not have origin-offset so pose_ contains
// mojo_from_this with origin-offset (identity) already applied.
auto mojo_from_other = *relative_to->MojoFromNative(); auto other_native_from_mojo = *maybe_other_space_native_from_mojo;
DCHECK(mojo_from_other.IsInvertible()); auto other_offset_from_other_native = other->OffsetFromNativeMatrix();
auto other_from_mojo = mojo_from_other.Inverse(); auto other_offset_from_mojo =
other_offset_from_other_native * other_native_from_mojo;
auto other_from_this = other_from_mojo * mojo_from_this; auto other_offset_from_this = other_offset_from_mojo * mojo_from_this;
return MakeGarbageCollected<XRPose>(other_from_this, false); return MakeGarbageCollected<XRPose>(other_offset_from_this, false);
} }
} // namespace blink } // namespace blink
...@@ -22,13 +22,7 @@ class XRObjectSpace : public XRSpace { ...@@ -22,13 +22,7 @@ class XRObjectSpace : public XRSpace {
: XRSpace(session), object_(object) {} : XRSpace(session), object_(object) {}
std::unique_ptr<TransformationMatrix> MojoFromNative() override { std::unique_ptr<TransformationMatrix> MojoFromNative() override {
auto object_from_mojo = object_->poseMatrix(); return std::make_unique<TransformationMatrix>(object_->MojoFromObject());
if (!object_from_mojo.IsInvertible()) {
return nullptr;
}
return std::make_unique<TransformationMatrix>(object_from_mojo.Inverse());
} }
std::unique_ptr<TransformationMatrix> NativeFromMojo() final { std::unique_ptr<TransformationMatrix> NativeFromMojo() final {
......
...@@ -53,7 +53,7 @@ XRSpace* XRPlane::planeSpace() const { ...@@ -53,7 +53,7 @@ XRSpace* XRPlane::planeSpace() const {
return plane_space_; return plane_space_;
} }
TransformationMatrix XRPlane::poseMatrix() const { TransformationMatrix XRPlane::MojoFromObject() const {
return *pose_matrix_; return *pose_matrix_;
} }
......
...@@ -42,7 +42,7 @@ class XRPlane : public ScriptWrappable { ...@@ -42,7 +42,7 @@ class XRPlane : public ScriptWrappable {
XRSpace* planeSpace() const; XRSpace* planeSpace() const;
TransformationMatrix poseMatrix() const; TransformationMatrix MojoFromObject() const;
String orientation() const; String orientation() const;
HeapVector<Member<DOMPointReadOnly>> polygon() const; HeapVector<Member<DOMPointReadOnly>> polygon() const;
......
...@@ -78,9 +78,9 @@ const char kAnchorsNotSupported[] = "Device does not support anchors!"; ...@@ -78,9 +78,9 @@ const char kAnchorsNotSupported[] = "Device does not support anchors!";
const char kDeviceDisconnected[] = "The XR device has been disconnected."; const char kDeviceDisconnected[] = "The XR device has been disconnected.";
const char kNonInvertibleMatrix[] = const char kUnableToRetrieveMatrix[] =
"The operation encountered non-invertible matrix and could not be " "The operation was unable to retrieve a matrix from passed in space and "
"completed."; "could not be completed.";
const char kUnableToDecomposeMatrix[] = const char kUnableToDecomposeMatrix[] =
"The operation was unable to decompose a matrix and could not be " "The operation was unable to decompose a matrix and could not be "
...@@ -542,18 +542,19 @@ ScriptPromise XRSession::requestReferenceSpace( ...@@ -542,18 +542,19 @@ ScriptPromise XRSession::requestReferenceSpace(
return promise; return promise;
} }
ScriptPromise XRSession::CreateAnchor(ScriptState* script_state, ScriptPromise XRSession::CreateAnchor(
XRRigidTransform* initial_pose, ScriptState* script_state,
XRSpace* space, XRRigidTransform* offset_space_from_anchor_transform,
XRPlane* plane, XRSpace* space,
ExceptionState& exception_state) { XRPlane* plane,
ExceptionState& exception_state) {
if (ended_) { if (ended_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionEnded); kSessionEnded);
return ScriptPromise(); return ScriptPromise();
} }
if (!initial_pose) { if (!offset_space_from_anchor_transform) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kNoRigidTransformSpecified); kNoRigidTransformSpecified);
return ScriptPromise(); return ScriptPromise();
...@@ -572,41 +573,34 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state, ...@@ -572,41 +573,34 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
return ScriptPromise(); return ScriptPromise();
} }
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
// Transformation from passed in |space| to mojo space. // Transformation from passed in |space| to mojo space.
std::unique_ptr<TransformationMatrix> mojo_from_native = std::unique_ptr<TransformationMatrix> mojo_from_native =
space->MojoFromNative(); space->MojoFromNative();
DVLOG(3) << __func__ if (!mojo_from_native) {
<< ": mojo_from_native = " << mojo_from_native->ToString(true);
// Matrix will be null if transformation from object space to mojo space is
// not invertible, log & bail out in that case.
if (!mojo_from_native || !mojo_from_native->IsInvertible()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kNonInvertibleMatrix); kUnableToRetrieveMatrix);
return ScriptPromise(); return ScriptPromise();
} }
auto native_from_mojo = mojo_from_native->Inverse();
DVLOG(3) << __func__ DVLOG(3) << __func__
<< ": native_from_mojo = " << native_from_mojo.ToString(true); << ": mojo_from_native = " << mojo_from_native->ToString(true);
// Transformation from passed in pose to |space|. // Transformation from passed in pose to |space|.
auto mojo_from_initial_pose = initial_pose->TransformMatrix(); auto offset_space_from_anchor =
auto space_from_initial_pose = native_from_mojo * mojo_from_initial_pose; offset_space_from_anchor_transform->TransformMatrix();
auto native_space_from_offset_space = space->NativeFromOffsetMatrix();
auto native_space_from_anchor =
native_space_from_offset_space * offset_space_from_anchor;
DVLOG(3) << __func__ << ": mojo_from_initial_pose = " auto mojo_from_native_space = *mojo_from_native;
<< mojo_from_initial_pose.ToString(true); auto mojo_from_anchor = mojo_from_native_space * native_space_from_anchor;
DVLOG(3) << __func__ << ": space_from_initial_pose = " DVLOG(3) << __func__
<< space_from_initial_pose.ToString(true); << ": mojo_from_anchor = " << mojo_from_anchor.ToString(true);
TransformationMatrix::DecomposedType decomposed; TransformationMatrix::DecomposedType decomposed;
if (!space_from_initial_pose.Decompose(decomposed)) { if (!mojo_from_anchor.Decompose(decomposed)) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kUnableToDecomposeMatrix); kUnableToDecomposeMatrix);
return ScriptPromise(); return ScriptPromise();
...@@ -624,6 +618,9 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state, ...@@ -624,6 +618,9 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
<< ": pose_ptr->orientation = " << pose_ptr->orientation.ToString() << ": pose_ptr->orientation = " << pose_ptr->orientation.ToString()
<< ", pose_ptr->position = " << pose_ptr->position.ToString(); << ", pose_ptr->position = " << pose_ptr->position.ToString();
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
if (plane) { if (plane) {
xr_->xrEnvironmentProviderRemote()->CreatePlaneAnchor( xr_->xrEnvironmentProviderRemote()->CreatePlaneAnchor(
std::move(pose_ptr), plane->id(), std::move(pose_ptr), plane->id(),
...@@ -640,12 +637,13 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state, ...@@ -640,12 +637,13 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
return promise; return promise;
} }
ScriptPromise XRSession::createAnchor(ScriptState* script_state, ScriptPromise XRSession::createAnchor(
XRRigidTransform* initial_pose, ScriptState* script_state,
XRSpace* space, XRRigidTransform* offset_space_from_anchor_transform,
ExceptionState& exception_state) { XRSpace* offset_space,
return CreateAnchor(script_state, initial_pose, space, nullptr, ExceptionState& exception_state) {
exception_state); return CreateAnchor(script_state, offset_space_from_anchor_transform,
offset_space, nullptr, exception_state);
} }
int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) { int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) {
......
...@@ -322,6 +322,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -322,6 +322,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Creates new anchor for object and places it there. // Creates new anchor for object and places it there.
function addARObjectAt(session, frame, plane, pose, space) { function addARObjectAt(session, frame, plane, pose, space) {
console.debug("Creating anchor", pose, space);
if(plane != null) { if(plane != null) {
plane.createAnchor(pose, space).then(onCreateAnchor); plane.createAnchor(pose, space).then(onCreateAnchor);
} else { } else {
...@@ -329,13 +330,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -329,13 +330,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
} }
} }
function DOMPointFromVec4(vector) {
return new DOMPointReadOnly(vector[0], vector[1], vector[2], vector[3]);
}
let rayOrigin = vec4.create();
let rayDirection = vec4.create();
function onSelect(event) { function onSelect(event) {
if (useReticle.checked && arObject.visible) { if (useReticle.checked && arObject.visible) {
// If we're using the reticle then we've already got a mesh positioned // If we're using the reticle then we've already got a mesh positioned
...@@ -364,20 +358,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -364,20 +358,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
let inputPose = event.frame.getPose(event.inputSource.targetRaySpace, xrRefSpace); let inputPose = event.frame.getPose(event.inputSource.targetRaySpace, xrRefSpace);
if (inputPose) { if (inputPose) {
let targetRay = new XRRay(inputPose.transform); let targetRay = new XRRay(inputPose.transform);
vec4.set(rayOrigin, const hitTestResults = hitTest(event.frame, targetRay, xrRefSpace);
targetRay.origin.x,
targetRay.origin.y,
targetRay.origin.z,
targetRay.origin.w);
vec4.set(rayDirection,
targetRay.direction.x,
targetRay.direction.y,
targetRay.direction.z,
targetRay.direction.w);
let ray = new XRRay(DOMPointFromVec4(rayOrigin), DOMPointFromVec4(rayDirection));
const hitTestResults = hitTest(event.frame, ray, xrRefSpace);
const hitTestFiltered = filterHitTestResults(hitTestResults, const hitTestFiltered = filterHitTestResults(hitTestResults,
extendPlanesEnabled.checked, extendPlanesEnabled.checked,
false, false,
...@@ -541,14 +522,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -541,14 +522,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// continuous hit test. For the moment we're just using the flower // continuous hit test. For the moment we're just using the flower
// as the "reticle". // as the "reticle".
if (useReticle.checked && pose && pose.transform.matrix) { if (useReticle.checked && pose && pose.transform.matrix) {
vec4.set(rayOrigin, 0, 0, 0, 1); const ray = new XRRay(pose.transform);
vec4.transformMat4(rayOrigin, rayOrigin, pose.transform.matrix);
vec4.set(rayDirection, 0, 0, -1, 0);
vec4.transformMat4(rayDirection, rayDirection, pose.transform.matrix);
vec4.normalize(rayDirection, rayDirection);
const ray = new XRRay(DOMPointFromVec4(rayOrigin), DOMPointFromVec4(rayDirection));
rayObject.matrix = ray.matrix.slice(); rayObject.matrix = ray.matrix.slice();
rayObject.visible = true; rayObject.visible = true;
......
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