blob: 6f091d20fcc1eb59e56e191584166478d827a759 [file] [log] [blame]
// 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_hit_test_result.h"
#include "third_party/blink/renderer/modules/xr/type_converters.h"
#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h"
#include "third_party/blink/renderer/modules/xr/xr_pose.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
#include "third_party/blink/renderer/modules/xr/xr_space.h"
namespace blink {
XRHitTestResult::XRHitTestResult(
XRSession* session,
const device::mojom::blink::XRHitResult& hit_result)
: session_(session),
mojo_from_this_(hit_result.mojo_from_result),
plane_id_(hit_result.plane_id != 0
? base::Optional<uint64_t>(hit_result.plane_id)
: base::nullopt) {}
XRPose* XRHitTestResult::getPose(XRSpace* other) {
auto maybe_other_space_native_from_mojo = other->NativeFromMojo();
DCHECK(maybe_other_space_native_from_mojo);
auto mojo_from_this =
TransformationMatrix(mojo_from_this_.ToTransform().matrix());
auto other_native_from_mojo = *maybe_other_space_native_from_mojo;
auto other_offset_from_other_native = other->OffsetFromNativeMatrix();
auto other_offset_from_mojo =
other_offset_from_other_native * other_native_from_mojo;
auto other_offset_from_this = other_offset_from_mojo * mojo_from_this;
return MakeGarbageCollected<XRPose>(other_offset_from_this, false);
}
ScriptPromise XRHitTestResult::createAnchor(ScriptState* script_state,
ExceptionState& exception_state) {
DVLOG(2) << __func__;
if (!session_->IsFeatureEnabled(device::mojom::XRSessionFeature::ANCHORS)) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
XRSession::kAnchorsFeatureNotSupported);
DVLOG(3) << __func__ << ": anchors not supported on the session";
return {};
}
// TODO(https://crbug.com/954236): Revisit the approach of plane poses not
// being stable from frame to frame - if we could guarantee that anchor poses
// are not so dynamic, anchor creation could be improved.
//
// Planes are not considered stationary for the purpose of anchor creation
// (their poses may change dramatically on a frame-by-frame basis). Grab an
// information about reference space that is well-suited for anchor creation
// from session:
base::Optional<XRSession::ReferenceSpaceInformation>
reference_space_information = session_->GetStationaryReferenceSpace();
if (!reference_space_information) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
XRSession::kUnableToRetrieveMatrix);
DVLOG(3) << __func__ << ": unable to obtain stationary reference space";
return {};
}
const TransformationMatrix& mojo_from_space =
reference_space_information->mojo_from_space;
DCHECK(mojo_from_space.IsInvertible());
auto space_from_mojo = mojo_from_space.Inverse();
auto space_from_anchor =
space_from_mojo *
TransformationMatrix(mojo_from_this_.ToTransform().matrix());
if (plane_id_) {
DVLOG(2) << __func__
<< ": hit test result's entity is a plane, creating "
"plane-attached anchor";
return session_->CreatePlaneAnchorHelper(
script_state, space_from_anchor,
reference_space_information->native_origin, *plane_id_,
exception_state);
} else {
DVLOG(2) << __func__
<< ": hit test result's entity is unavailable, creating "
"free-floating anchor ";
// Let's create free-floating anchor since plane is unavailable.
return session_->CreateAnchorHelper(
script_state, space_from_anchor,
reference_space_information->native_origin, exception_state);
}
}
void XRHitTestResult::Trace(Visitor* visitor) const {
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink