File: xr_bounded_reference_space.cc

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (140 lines) | stat: -rw-r--r-- 5,405 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2018 The Chromium Authors
// 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_bounded_reference_space.h"

#include <memory>

#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/frozen_array.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space_event.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_utils.h"
#include "ui/gfx/geometry/point3_f.h"

namespace blink {
namespace {

// Bounds must be a valid polygon (at least 3 vertices).
constexpr wtf_size_t kMinimumNumberOfBoundVertices = 3;

float RoundCm(float val) {
  // Float round will only round to the nearest whole number. In order to get
  // two decimal points of precision, we need to move the decimal out then
  // back.
  return std::round(val * 100) / 100;
}

Member<DOMPointReadOnly> RoundedDOMPoint(const gfx::Point3F& val) {
  return DOMPointReadOnly::Create(RoundCm(val.x()), RoundCm(val.y()),
                                  RoundCm(val.z()), 1.0);
}
}  // anonymous namespace

XRBoundedReferenceSpace::XRBoundedReferenceSpace(XRSession* session)
    : XRReferenceSpace(
          session,
          device::mojom::blink::XRReferenceSpaceType::kBoundedFloor),
      offset_bounds_geometry_(
          MakeGarbageCollected<FrozenArray<DOMPointReadOnly>>()) {}

XRBoundedReferenceSpace::XRBoundedReferenceSpace(
    XRSession* session,
    XRRigidTransform* origin_offset)
    : XRReferenceSpace(
          session,
          origin_offset,
          device::mojom::blink::XRReferenceSpaceType::kBoundedFloor),
      offset_bounds_geometry_(
          MakeGarbageCollected<FrozenArray<DOMPointReadOnly>>()) {}

XRBoundedReferenceSpace::~XRBoundedReferenceSpace() = default;

void XRBoundedReferenceSpace::EnsureUpdated() const {
  // Check first to see if the stage parameters have updated since the last
  // call. We only need to update the transform and bounds if it has.
  if (stage_parameters_id_ == session()->StageParametersId())
    return;

  stage_parameters_id_ = session()->StageParametersId();

  const device::mojom::blink::VRStageParametersPtr& stage_parameters =
      session()->GetStageParameters();

  if (stage_parameters) {
    // Use the transform given by stage_parameters if available.
    mojo_from_bounded_native_ =
        std::make_unique<gfx::Transform>(stage_parameters->mojo_from_stage);

    // In order to ensure that the bounds continue to line up with the user's
    // physical environment we need to transform them from native to offset.
    // Bounds are provided in our native coordinate space.
    // TODO(https://crbug.com/1008466): move originOffset to separate class? If
    // yes, that class would need to apply a transform in the boundsGeometry
    // accessor.
    gfx::Transform offset_from_native = OffsetFromNativeMatrix();

    // We may not have bounds if we've lost tracking after being created.
    // Whether we have them or not, we need to clear the existing bounds.
    FrozenArray<DOMPointReadOnly>::VectorType offset_bounds_geometry;
    if (stage_parameters->bounds &&
        stage_parameters->bounds->size() >= kMinimumNumberOfBoundVertices) {
      for (const auto& bound : *(stage_parameters->bounds)) {
        gfx::Point3F p = offset_from_native.MapPoint(
            gfx::Point3F(bound.x(), 0.0, bound.z()));
        offset_bounds_geometry.push_back(RoundedDOMPoint(p));
      }
    }
    offset_bounds_geometry_ =
        MakeGarbageCollected<FrozenArray<DOMPointReadOnly>>(
            std::move(offset_bounds_geometry));
  } else {
    // If stage parameters aren't available set the transform to null, which
    // will subsequently cause this reference space to return null poses.
    mojo_from_bounded_native_.reset();
    offset_bounds_geometry_ =
        MakeGarbageCollected<FrozenArray<DOMPointReadOnly>>();
  }

  // DispatchEvent inherited from core/dom/events/event_target.h isn't const.
  XRBoundedReferenceSpace* mutable_this =
      const_cast<XRBoundedReferenceSpace*>(this);
  mutable_this->DispatchEvent(
      *XRReferenceSpaceEvent::Create(event_type_names::kReset, mutable_this));
}

std::optional<gfx::Transform> XRBoundedReferenceSpace::MojoFromNative() const {
  EnsureUpdated();

  if (!mojo_from_bounded_native_)
    return std::nullopt;

  return *mojo_from_bounded_native_;
}

const FrozenArray<DOMPointReadOnly>& XRBoundedReferenceSpace::boundsGeometry()
    const {
  EnsureUpdated();
  return *offset_bounds_geometry_.Get();
}

void XRBoundedReferenceSpace::Trace(Visitor* visitor) const {
  visitor->Trace(offset_bounds_geometry_);
  XRReferenceSpace::Trace(visitor);
}

void XRBoundedReferenceSpace::OnReset() {
  // Anything that would cause an external source to try to tell us that we've
  // been reset should have also updated the stage_parameters, and thus caused
  // us to reset via that mechanism instead.
}

XRBoundedReferenceSpace* XRBoundedReferenceSpace::cloneWithOriginOffset(
    XRRigidTransform* origin_offset) const {
  return MakeGarbageCollected<XRBoundedReferenceSpace>(this->session(),
                                                       origin_offset);
}

}  // namespace blink