Panda3D
Loading...
Searching...
No Matches
inputDevice.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file inputDevice.h
10 * @author rdb
11 * @date 2015-12-11
12 */
13
14#ifndef INPUTDEVICE_H
15#define INPUTDEVICE_H
16
17#include "pandabase.h"
18
19#include "buttonEvent.h"
20#include "buttonEventList.h"
21#include "pointerEvent.h"
22#include "pointerEventList.h"
23#include "pointerData.h"
24#include "trackerData.h"
25#include "clockObject.h"
26
27#include "pdeque.h"
28#include "pvector.h"
29#include "lightMutex.h"
30#include "lightMutexHolder.h"
31
32/**
33 * This is a structure representing a single input device. Input devices may
34 * have zero or more buttons, pointers, or axes associated with them, and
35 * optionally a motion tracker.
36 *
37 * These devices are brought under a common interface because there is such a
38 * large range of devices out there that may support any number of these types
39 * of axes, we couldn't even begin to cover them with type-specific
40 * subclasses.
41 *
42 * Use the various has_() and get_num_() methods to determine information about
43 * the device capabilities. For instance, has_keyboard() will give an
44 * indication that you can receive keystroke events from this device, and
45 * get_num_buttons() will tell you that the device may send button events.
46 *
47 * There is the DeviceType enumeration, however, which will (if known) contain
48 * identification of the general category of devices this fits in, such as
49 * keyboard, mouse, gamepad, or flight stick.
50 *
51 * @since 1.10.0
52 */
53class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
54PUBLISHED:
55 // This enum contains information that can be used to identify the
56 // type of input device.
57 enum class DeviceClass {
58 // It is not known what type of device this is.
59 unknown,
60
61 // This means that the device doesn't correspond to a physical
62 // device, but rather to a dynamic source of input events.
63 virtual_device,
64
65 // A physical, alphabetical keyboard.
66 keyboard,
67
68 mouse,
69 touch,
70
71 // A gamepad with action buttons, a D-pad, and thumbsticks.
72 gamepad,
73
74 flight_stick,
75 steering_wheel,
76 dance_pad,
77
78 // Head-mounted display.
79 hmd,
80
81 // 3D mouse, such as produced by 3Dconnexion.
82 spatial_mouse,
83
84 // A graphics tablet with stylus/pen.
85 digitizer,
86 };
87
88 enum class Feature {
89 // The device provides absolute screen coordinates.
90 pointer,
91
92 // The device has an interface for providing text input.
93 keyboard,
94
95 // The device has a motion tracker, such as an HMD.
96 tracker,
97
98 // The device can produce force feedback.
99 vibration,
100
101 // The device provides information about battery life.
102 battery,
103 };
104
105 enum class Axis {
106 none,
107
108 // Generic translational axes
109 x,
110 y,
111 z,
112
113 // Generic rotational axes, used by joysticks and 3D mice
114 yaw,
115 pitch,
116 roll,
117
118 // Gamepad
119 left_x,
120 left_y,
121 left_trigger,
122 right_x,
123 right_y,
124 right_trigger,
125
126 // Flight stick specific
127 throttle,
128 rudder, // When available separately from yaw
129
130 // Steering wheel / pedals
131 wheel,
132 accelerator,
133 brake,
134
135 // Pen pressure
136 pressure,
137 };
138
139 enum State {
140 S_unknown,
141 S_up,
142 S_down
143 };
144
146 public:
147 constexpr ButtonState() = default;
148 INLINE ButtonState(ButtonHandle handle);
149 ALWAYS_INLINE bool is_known() const;
150 ALWAYS_INLINE bool is_pressed() const;
151
152 PUBLISHED:
153 operator bool() { return _state != S_unknown; }
154
155 MAKE_PROPERTY(known, is_known);
156 MAKE_PROPERTY(pressed, is_pressed);
157
158 ButtonHandle handle = ButtonHandle::none();
159
160 public:
161 State _state = S_unknown;
162 };
163
164 class AxisState {
165 public:
166 constexpr AxisState() = default;
167
168 PUBLISHED:
169 operator bool() { return known && value != 0.0; }
170
171 Axis axis = Axis::none;
172 double value = 0.0;
173 bool known = false;
174
175 public:
176 double _scale = 1.0;
177 double _bias = 0.0;
178 };
179
181 PUBLISHED:
182 // Ranges from 0 through max_level.
183 short level = -1;
184
185 // Maximum value of 'level' field.
186 short max_level = -1;
187 };
188
189protected:
190 InputDevice(const std::string &name, DeviceClass dev_class);
191
192public:
193 InputDevice();
194 InputDevice(const InputDevice &copy) = delete;
195 InputDevice &operator = (const InputDevice &copy) = delete;
196 virtual ~InputDevice();
197
198 INLINE std::string get_name() const;
199 INLINE std::string get_manufacturer() const;
200 INLINE std::string get_serial_number() const;
201 INLINE unsigned short get_vendor_id() const;
202 INLINE unsigned short get_product_id() const;
203 INLINE bool is_connected() const;
204 INLINE DeviceClass get_device_class() const;
205
206 INLINE bool has_pointer() const;
207 INLINE bool has_keyboard() const;
208 INLINE bool has_tracker() const;
209 INLINE bool has_vibration() const;
210 INLINE bool has_battery() const;
211
212 INLINE TrackerData get_tracker() const;
213 INLINE BatteryData get_battery() const;
214
215 INLINE size_t get_num_buttons() const;
216 INLINE ButtonHandle get_button_map(size_t index) const;
217 INLINE bool is_button_pressed(size_t index) const;
218 INLINE bool is_button_known(size_t index) const;
219 INLINE ButtonState get_button(size_t index) const;
220
221 INLINE size_t get_num_axes() const;
222 INLINE double get_axis_value(size_t index) const;
223 INLINE bool is_axis_known(size_t index) const;
224 INLINE AxisState get_axis(size_t index) const;
225
226PUBLISHED:
227 // The human-readable name of this input device.
228 MAKE_PROPERTY(name, get_name);
229
230 // The device's manufacturer, or the empty string if not known.
231 MAKE_PROPERTY(manufacturer, get_manufacturer);
232
233 // The device's serial number, or the empty string if not known.
234 MAKE_PROPERTY(serial_number, get_serial_number);
235
236 // USB vendor ID of the device, or 0 if not known.
237 MAKE_PROPERTY(vendor_id, get_vendor_id);
238
239 // USB product ID of the device, or 0 if not known.
240 MAKE_PROPERTY(product_id, get_product_id);
241
242 // This is false if we know that the device is not currently connected.
243 // May report false positives if we can't know this with certainty.
244 MAKE_PROPERTY(connected, is_connected);
245
246 // This contains an identification of the general type of device. If
247 // this could not be determined, it is set to DC_unknown.
248 MAKE_PROPERTY(device_class, get_device_class);
249
250 // Determine supported features
251 INLINE bool has_feature(Feature feature) const;
252
253 // Getters for the various types of device data.
254 MAKE_PROPERTY2(tracker, has_tracker, get_tracker);
255 MAKE_PROPERTY2(battery, has_battery, get_battery);
256
257 // Make device buttons and axes iterable
258 MAKE_SEQ_PROPERTY(buttons, get_num_buttons, get_button);
259 MAKE_SEQ_PROPERTY(axes, get_num_axes, get_axis);
260
261 // Associate buttons/axes with symbolic handles.
262 INLINE void map_button(size_t index, ButtonHandle handle);
263 INLINE void map_axis(size_t index, Axis axis);
264 INLINE ButtonState find_button(ButtonHandle handle) const;
265 INLINE AxisState find_axis(Axis axis) const;
266
267 // Enable rumble force-feedback effects
268 INLINE void set_vibration(double strong, double weak);
269
270 INLINE void enable_pointer_events();
271 INLINE void disable_pointer_events();
272
273 void poll();
274
275 bool has_button_event() const;
276 PT(ButtonEventList) get_button_events();
277 bool has_pointer_event() const;
278 PT(PointerEventList) get_pointer_events();
279
280 virtual void output(std::ostream &out) const;
281
282public:
283 static std::string format_device_class(DeviceClass dc);
284 static std::string format_axis(Axis axis);
285
286protected:
287 INLINE void enable_feature(Feature feature);
288
289 // Called during the constructor to add new axes or buttons
290 int add_button(ButtonHandle handle);
291 int add_axis(Axis axis, int minimum, int maximum, bool centered);
292 int add_axis(Axis axis, int minimum, int maximum);
293
294 int add_pointer(PointerType type, int id, bool primary = false);
295 void remove_pointer(int id);
296 void update_pointer(PointerData data, double time);
297 void pointer_moved(int id, double x, double y, double time);
298 void button_changed(int index, bool down);
299 void axis_changed(int index, int value);
300 void set_axis_value(int index, double state);
301
302 void tracker_changed(const LPoint3 &pos, const LOrientation &orient, double time);
303
304 virtual void do_set_vibration(double low, double high);
305 virtual void do_poll();
306
307public:
308 INLINE void set_connected(bool connected);
309
310 void output_buttons(std::ostream &out) const;
311 void write_buttons(std::ostream &out, int indent_level) const;
312 void write_axes(std::ostream &out, int indent_level) const;
313
314protected:
316
317 LightMutex _lock {"InputDevice"};
318
319 std::string _name;
320 std::string _serial_number;
321 std::string _manufacturer;
322 DeviceClass _device_class = DeviceClass::unknown;
323 unsigned int _features = 0;
324 int _event_sequence = 0;
325 unsigned short _vendor_id = 0;
326 unsigned short _product_id = 0;
327 bool _is_connected = false;
328 bool _enable_pointer_events = false;
329 PT(ButtonEventList) _button_events;
330 PT(PointerEventList) _pointer_events;
331
332 size_t _num_pointers = 0;
333 typedef pvector<PointerData> Pointers;
334 Pointers _pointers;
335
336PUBLISHED:
337 typedef pvector<ButtonState> Buttons;
338 typedef pvector<AxisState> Axes;
339 Buttons _buttons;
340 Axes _axes;
341
342 PointerData _pointer_data;
343 BatteryData _battery_data;
344 TrackerData _tracker_data;
345
346public:
347 static TypeHandle get_class_type() {
348 return _type_handle;
349 }
350 static void init_type() {
351 TypedReferenceCount::init_type();
352 register_type(_type_handle, "InputDevice",
353 TypedReferenceCount::get_class_type());
354 }
355 virtual TypeHandle get_type() const {
356 return get_class_type();
357 }
358 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
359
360private:
361 static TypeHandle _type_handle;
362};
363
364INLINE std::ostream &operator << (std::ostream &out, const InputDevice &device) {
365 device.output(out);
366 return out;
367}
368
369EXPCL_PANDA_DEVICE std::ostream &operator << (std::ostream &out, InputDevice::DeviceClass dc);
370EXPCL_PANDA_DEVICE std::ostream &operator << (std::ostream &out, InputDevice::Axis axis);
371
372#include "inputDevice.I"
373
374#endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Records a set of button events that happened recently.
A ButtonHandle represents a single button from any device, including keyboard buttons and mouse butto...
This is a structure representing a single input device.
Definition inputDevice.h:53
virtual void output(std::ostream &out) const
Writes a one-line string describing the device.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition lightMutex.h:41
Holds the data that might be generated by a 2-d pointer input device, such as the mouse in the Graphi...
Definition pointerData.h:38
Records a set of pointer events that happened recently.
Stores the kinds of data that a tracker might output.
Definition trackerData.h:23
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
This is our own Panda specialization on the default STL deque.
Definition pdeque.h:36
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_connected(MObject &node, const string &attribute_name)
Returns true if the named connection exists on the node and is connected to anything,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PointerType
Contains the types of pointer device.
Definition pointerData.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.