File: xr_input_source.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (194 lines) | stat: -rw-r--r-- 7,264 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// 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.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_

#include <memory>
#include <optional>

#include "base/time/time.h"
#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "ui/gfx/geometry/transform.h"

namespace device {
template <class T>
class GamepadImpl;
using Gamepad = GamepadImpl<void>;
}

namespace blink {

class Element;
class V8XRHandedness;
class V8XRTargetRayMode;
class XRGripSpace;
class XRHand;
class XRInputSourceEvent;
class XRSession;
class XRSpace;
class XRTargetRaySpace;

template <typename IDLType>
class FrozenArray;

class XRInputSource : public ScriptWrappable, public Gamepad::Client {
  DEFINE_WRAPPERTYPEINFO();

 public:
  static XRInputSource* CreateOrUpdateFrom(
      XRInputSource* other /* may be null, input */,
      XRSession* session,
      const device::mojom::blink::XRInputSourceStatePtr& state);

  XRInputSource(XRSession*,
                uint32_t source_id,
                device::mojom::XRTargetRayMode target_ray_mode =
                    device::mojom::XRTargetRayMode::GAZING);
  XRInputSource(const XRInputSource& other);
  ~XRInputSource() override = default;

  int16_t activeFrameId() const { return state_.active_frame_id; }
  void setActiveFrameId(int16_t id) { state_.active_frame_id = id; }

  XRSession* session() const { return session_.Get(); }

  device::mojom::XRHandedness xr_handedness() const {
    return state_.handedness;
  }

  V8XRHandedness handedness() const;
  V8XRTargetRayMode targetRayMode() const;
  bool emulatedPosition() const { return state_.emulated_position; }
  XRSpace* targetRaySpace() const;
  XRSpace* gripSpace() const;
  Gamepad* gamepad() const { return gamepad_.Get(); }
  XRHand* hand() const { return hand_.Get(); }
  const FrozenArray<IDLString>& profiles() const { return *profiles_.Get(); }

  uint32_t source_id() const { return state_.source_id; }

  void SetInputFromPointer(const gfx::Transform*);
  void SetGamepadConnected(bool state);

  // Gamepad::Client
  GamepadHapticActuator* GetVibrationActuatorForGamepad(
      const Gamepad&) override {
    // TODO(https://crbug.com/955097): XRInputSource implementation of
    // Gamepad::Client must manage vibration actuator state in a similar way to
    // NavigatorGamepad.
    return nullptr;
  }

  device::mojom::XRTargetRayMode TargetRayMode() const {
    return state_.target_ray_mode;
  }

  std::optional<gfx::Transform> MojoFromInput() const;

  std::optional<gfx::Transform> InputFromPointer() const;

  void OnSelectStart();
  void OnSelectEnd();
  void OnSelect();

  void OnSqueezeStart();
  void OnSqueezeEnd();
  void OnSqueeze();

  void UpdateButtonStates(
      const device::mojom::blink::XRInputSourceStatePtr& state);
  void OnRemoved();

  // Check which element within the DOM overlay is hit by the input source's
  // pointer ray, and update primary input state based on that, including
  // suppressing event data for cross-origin iframes. For background, see
  // https://immersive-web.github.io/dom-overlays/#cross-origin-content-events
  void ProcessOverlayHitTest(
      Element* overlay_element,
      const device::mojom::blink::XRInputSourceStatePtr& state);
  bool IsVisible() const { return state_.is_visible; }

  void Trace(Visitor*) const override;

 private:
  // In order to ease copying, any new member variables that can be trivially
  // copied (except for Member<T> variables), should go here
  struct InternalState {
    int16_t active_frame_id = -1;
    bool primary_input_pressed = false;
    bool selection_cancelled = false;
    bool primary_squeeze_pressed = false;
    bool squeezing_cancelled = false;
    // Input sources have two separate states, visible/invisible and select
    // events active/suppressed. All input sources, including auxiliary, should
    // use DOM overlay hit test (the ProcessOverlayHitTest() method) to check if
    // they intersect cross-origin content. If that's the case, the input source
    // is set as invisible, and must not return poses or hit test results. This
    // also automatically suppresses select events (this matches the "poses are
    // limited" conditional in the main WebXR spec). If the hit test doesn't
    // intersect cross-origin content, and if this is the first touch, it fires
    // a beforexrselect event and suppresses select events if that's been
    // preventDefault()ed. For auxiliary input sources, the event does not need
    // to be fired - per spec, their select events need to be suppressed anyway.
    bool xr_select_events_suppressed = false;
    bool is_visible = true;
    const uint32_t source_id;
    device::mojom::XRHandedness handedness = device::mojom::XRHandedness::NONE;
    device::mojom::XRTargetRayMode target_ray_mode;
    bool emulated_position = false;
    base::TimeTicks base_timestamp;

    InternalState(uint32_t source_id,
                  device::mojom::XRTargetRayMode,
                  base::TimeTicks base_timestamp);
    InternalState(const InternalState& other);
    ~InternalState();
  };

  // Use to check if the updates that would/should be made by a given
  // XRInputSourceState would invalidate any SameObject properties guaranteed
  // by the idl, and thus require the xr_input_source to be recreated.
  bool InvalidatesSameObject(
      const device::mojom::blink::XRInputSourceStatePtr& state);

  // Note that UpdateGamepad should only be called after a check/recreation
  // from InvalidatesSameObject
  void UpdateGamepad(const std::optional<device::Gamepad>& gamepad);

  void UpdateHand(
      const device::mojom::blink::XRHandTrackingData* hand_joint_data);

  XRInputSourceEvent* CreateInputSourceEvent(const AtomicString& type);

  // These member variables all require special behavior when being copied or
  // are Member<T> type variables.  When adding another one, be sure to keep the
  // deep-copy constructor updated, when adding any new variable.
  InternalState state_;
  const Member<XRSession> session_;
  Member<XRTargetRaySpace> target_ray_space_;
  Member<XRGripSpace> grip_space_;
  Member<Gamepad> gamepad_;
  Member<XRHand> hand_;
  Member<FrozenArray<IDLString>> profiles_;

  // Input device pose in mojo space. This is the grip pose for
  // tracked controllers, and the viewer pose for screen input.
  std::unique_ptr<gfx::Transform> mojo_from_input_;

  // Pointer pose in input device space, this is the transform to apply to
  // mojo_from_input_ to get the pointer matrix. In most cases it should be
  // static.
  std::unique_ptr<gfx::Transform> input_from_pointer_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_