blob: ca85f62a01b35ab09771b8a72733a45ab7158587 [file] [log] [blame]
// Copyright 2017 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_frame.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#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_view.h"
#include "third_party/blink/renderer/modules/xr/xr_viewer_pose.h"
#include "third_party/blink/renderer/modules/xr/xr_world_information.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
namespace {
const char kInactiveFrame[] =
"XRFrame access outside the callback that produced it is invalid.";
const char kNonAnimationFrame[] =
"getViewerPose can only be called on XRFrame objects passed to "
"XRSession.requestAnimationFrame callbacks.";
const char kSessionMismatch[] = "XRSpace and XRFrame sessions do not match.";
const char kCannotReportPoses[] =
"Poses cannot be given out for the current state.";
} // namespace
XRFrame::XRFrame(XRSession* session, XRWorldInformation* world_information)
: world_information_(world_information), session_(session) {}
XRViewerPose* XRFrame::getViewerPose(XRReferenceSpace* reference_space,
ExceptionState& exception_state) const {
if (!is_active_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kInactiveFrame);
return nullptr;
}
if (!is_animation_frame_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kNonAnimationFrame);
return nullptr;
}
if (!reference_space) {
return nullptr;
}
// Must use a reference space created from the same session.
if (reference_space->session() != session_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionMismatch);
return nullptr;
}
if (!session_->CanReportPoses()) {
exception_state.ThrowSecurityError(kCannotReportPoses);
return nullptr;
}
session_->LogGetPose();
std::unique_ptr<TransformationMatrix> pose =
reference_space->SpaceFromViewerWithDefaultAndOffset(
mojo_from_viewer_.get());
if (!pose) {
return nullptr;
}
return MakeGarbageCollected<XRViewerPose>(session(), *pose);
}
XRAnchorSet* XRFrame::trackedAnchors() const {
return session_->trackedAnchors();
}
// Return an XRPose that has a transform mapping to space A from space B, while
// accounting for the base pose matrix of this frame. If computing a transform
// isn't possible, return nullptr.
XRPose* XRFrame::getPose(XRSpace* space_A,
XRSpace* space_B,
ExceptionState& exception_state) {
if (!is_active_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kInactiveFrame);
return nullptr;
}
if (!space_A || !space_B) {
DVLOG(2) << __func__
<< " : space_A or space_B is null, space_A =" << space_A
<< ", space_B = " << space_B;
return nullptr;
}
if (space_A->session() != session_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionMismatch);
return nullptr;
}
if (space_B->session() != session_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionMismatch);
return nullptr;
}
if (!session_->CanReportPoses()) {
exception_state.ThrowSecurityError(kCannotReportPoses);
return nullptr;
}
return space_A->getPose(space_B, mojo_from_viewer_.get());
}
void XRFrame::SetMojoFromViewer(const TransformationMatrix& mojo_from_viewer,
bool emulated_position) {
mojo_from_viewer_ = std::make_unique<TransformationMatrix>(mojo_from_viewer);
emulated_position_ = emulated_position;
}
void XRFrame::Deactivate() {
is_active_ = false;
is_animation_frame_ = false;
}
HeapVector<Member<XRHitTestResult>> XRFrame::getHitTestResults(
XRHitTestSource* hitTestSource,
XRSpace* relativeTo) {
return {};
}
void XRFrame::Trace(blink::Visitor* visitor) {
visitor->Trace(session_);
visitor->Trace(world_information_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink