rev |
line source |
nuclear@1
|
1 /************************************************************************************
|
nuclear@1
|
2
|
nuclear@1
|
3 PublicHeader: OVR.h
|
nuclear@1
|
4 Filename : OVR_Device.h
|
nuclear@1
|
5 Content : Definition of HMD-related Device interfaces
|
nuclear@1
|
6 Created : September 21, 2012
|
nuclear@1
|
7 Authors : Michael Antonov
|
nuclear@1
|
8
|
nuclear@1
|
9 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
nuclear@1
|
10
|
nuclear@1
|
11 Use of this software is subject to the terms of the Oculus license
|
nuclear@1
|
12 agreement provided at the time of installation or download, or which
|
nuclear@1
|
13 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@1
|
14
|
nuclear@1
|
15 *************************************************************************************/
|
nuclear@1
|
16
|
nuclear@1
|
17 #ifndef OVR_Device_h
|
nuclear@1
|
18 #define OVR_Device_h
|
nuclear@1
|
19
|
nuclear@1
|
20 #include "OVR_DeviceConstants.h"
|
nuclear@1
|
21 #include "OVR_DeviceHandle.h"
|
nuclear@1
|
22 #include "OVR_DeviceMessages.h"
|
nuclear@1
|
23 #include "OVR_HIDDeviceBase.h"
|
nuclear@1
|
24
|
nuclear@1
|
25 #include "Kernel/OVR_Atomic.h"
|
nuclear@1
|
26 #include "Kernel/OVR_RefCount.h"
|
nuclear@1
|
27 #include "Kernel/OVR_String.h"
|
nuclear@1
|
28
|
nuclear@1
|
29 namespace OVR {
|
nuclear@1
|
30
|
nuclear@1
|
31 // Declared externally
|
nuclear@1
|
32 class Profile;
|
nuclear@1
|
33 class ProfileManager; // << Should be renamed for consistency
|
nuclear@1
|
34
|
nuclear@1
|
35 // Forward declarations
|
nuclear@1
|
36 class SensorDevice;
|
nuclear@1
|
37 class DeviceCommon;
|
nuclear@1
|
38 class DeviceManager;
|
nuclear@1
|
39
|
nuclear@1
|
40 // MessageHandler is a base class from which users derive to receive messages,
|
nuclear@1
|
41 // its OnMessage handler will be called for messages once it is installed on
|
nuclear@1
|
42 // a device. Same message handler can be installed on multiple devices.
|
nuclear@1
|
43 class MessageHandler
|
nuclear@1
|
44 {
|
nuclear@1
|
45 friend class MessageHandlerImpl;
|
nuclear@1
|
46 public:
|
nuclear@1
|
47 MessageHandler();
|
nuclear@1
|
48 virtual ~MessageHandler();
|
nuclear@1
|
49
|
nuclear@1
|
50 // Returns 'true' if handler is currently installed on any devices.
|
nuclear@1
|
51 bool IsHandlerInstalled() const;
|
nuclear@1
|
52
|
nuclear@1
|
53 // Should be called from derived class destructor to avoid handler
|
nuclear@1
|
54 // being called after it exits.
|
nuclear@1
|
55 void RemoveHandlerFromDevices();
|
nuclear@1
|
56
|
nuclear@1
|
57 // Returns a pointer to the internal lock object that is locked by a
|
nuclear@1
|
58 // background thread while OnMessage() is called.
|
nuclear@1
|
59 // This lock guaranteed to survive until ~MessageHandler.
|
nuclear@1
|
60 Lock* GetHandlerLock() const;
|
nuclear@1
|
61
|
nuclear@1
|
62
|
nuclear@1
|
63 virtual void OnMessage(const Message&) { }
|
nuclear@1
|
64
|
nuclear@1
|
65 // Determines if handler supports a specific message type. Can
|
nuclear@1
|
66 // be used to filter out entire message groups. The result
|
nuclear@1
|
67 // returned by this function shouldn't change after handler creation.
|
nuclear@1
|
68 virtual bool SupportsMessageType(MessageType) const { return true; }
|
nuclear@1
|
69
|
nuclear@1
|
70 private:
|
nuclear@1
|
71 UPInt Internal[4];
|
nuclear@1
|
72 };
|
nuclear@1
|
73
|
nuclear@1
|
74
|
nuclear@1
|
75 //-------------------------------------------------------------------------------------
|
nuclear@1
|
76 // ***** DeviceBase
|
nuclear@1
|
77
|
nuclear@1
|
78 // DeviceBase is the base class for all OVR Devices. It provides the following basic
|
nuclear@1
|
79 // functionality:
|
nuclear@1
|
80 // - Reports device type, manager, and associated parent (if any).
|
nuclear@1
|
81 // - Supports installable message handlers, which are notified of device events.
|
nuclear@1
|
82 // - Device objects are created through DeviceHandle::CreateDevice or more commonly
|
nuclear@1
|
83 // through DeviceEnumerator<>::CreateDevice.
|
nuclear@1
|
84 // - Created devices are reference counted, starting with RefCount of 1.
|
nuclear@1
|
85 // - Device is resources are cleaned up when it is Released, although its handles
|
nuclear@1
|
86 // may survive longer if referenced.
|
nuclear@1
|
87
|
nuclear@1
|
88 class DeviceBase : public NewOverrideBase
|
nuclear@1
|
89 {
|
nuclear@1
|
90 friend class DeviceHandle;
|
nuclear@1
|
91 friend class DeviceManagerImpl;
|
nuclear@1
|
92 public:
|
nuclear@1
|
93
|
nuclear@1
|
94 // Enumerating DeviceBase enumerates all devices.
|
nuclear@1
|
95 enum { EnumDeviceType = Device_All };
|
nuclear@1
|
96
|
nuclear@1
|
97 virtual ~DeviceBase() { }
|
nuclear@1
|
98 virtual void AddRef();
|
nuclear@1
|
99 virtual void Release();
|
nuclear@1
|
100
|
nuclear@1
|
101 virtual DeviceBase* GetParent() const;
|
nuclear@1
|
102 virtual DeviceManager* GetManager() const;
|
nuclear@1
|
103
|
nuclear@1
|
104 virtual void SetMessageHandler(MessageHandler* handler);
|
nuclear@1
|
105 virtual MessageHandler* GetMessageHandler() const;
|
nuclear@1
|
106
|
nuclear@1
|
107 virtual DeviceType GetType() const;
|
nuclear@1
|
108 virtual bool GetDeviceInfo(DeviceInfo* info) const;
|
nuclear@1
|
109
|
nuclear@1
|
110 // returns the MessageHandler's lock
|
nuclear@1
|
111 Lock* GetHandlerLock() const;
|
nuclear@1
|
112 protected:
|
nuclear@1
|
113 // Internal
|
nuclear@1
|
114 virtual DeviceCommon* getDeviceCommon() const = 0;
|
nuclear@1
|
115 };
|
nuclear@1
|
116
|
nuclear@1
|
117
|
nuclear@1
|
118 //-------------------------------------------------------------------------------------
|
nuclear@1
|
119 // ***** DeviceInfo
|
nuclear@1
|
120
|
nuclear@1
|
121 // DeviceInfo describes a device and its capabilities, obtained by calling
|
nuclear@1
|
122 // GetDeviceInfo. This base class only contains device-independent functionality;
|
nuclear@1
|
123 // users will normally use a derived HMDInfo or SensorInfo classes for more
|
nuclear@1
|
124 // extensive device info.
|
nuclear@1
|
125
|
nuclear@1
|
126 class DeviceInfo
|
nuclear@1
|
127 {
|
nuclear@1
|
128 public:
|
nuclear@1
|
129 DeviceInfo() : InfoClassType(Device_None), Type(Device_None), Version(0)
|
nuclear@1
|
130 { ProductName[0] = Manufacturer[0] = 0; }
|
nuclear@1
|
131
|
nuclear@1
|
132 enum { MaxNameLength = 32 };
|
nuclear@1
|
133
|
nuclear@1
|
134 // Type of device for which DeviceInfo is intended.
|
nuclear@1
|
135 // This will be set to Device_HMD for HMDInfo structure, note that this may be
|
nuclear@1
|
136 // different form the actual device type since (Device_None) is valid.
|
nuclear@1
|
137 const DeviceType InfoClassType;
|
nuclear@1
|
138 // Type of device this describes. This must be the same as InfoClassType when
|
nuclear@1
|
139 // InfoClassType != Device_None.
|
nuclear@1
|
140 DeviceType Type;
|
nuclear@1
|
141 // Name string describing the product: "Oculus Rift DK1", etc.
|
nuclear@1
|
142 char ProductName[MaxNameLength];
|
nuclear@1
|
143 char Manufacturer[MaxNameLength];
|
nuclear@1
|
144 unsigned Version;
|
nuclear@1
|
145
|
nuclear@1
|
146 protected:
|
nuclear@1
|
147 DeviceInfo(DeviceType type) : InfoClassType(type), Type(type), Version(0)
|
nuclear@1
|
148 { ProductName[0] = Manufacturer[0] = 0; }
|
nuclear@1
|
149 void operator = (const DeviceInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
|
nuclear@1
|
150 };
|
nuclear@1
|
151
|
nuclear@1
|
152
|
nuclear@1
|
153 //-------------------------------------------------------------------------------------
|
nuclear@1
|
154 // DeviceEnumerationArgs provides device enumeration argumenrs for DeviceManager::EnumerateDevicesEx.
|
nuclear@1
|
155 class DeviceEnumerationArgs
|
nuclear@1
|
156 {
|
nuclear@1
|
157 public:
|
nuclear@1
|
158 DeviceEnumerationArgs(DeviceType enumType, bool availableOnly)
|
nuclear@1
|
159 : EnumType(enumType), AvailableOnly(availableOnly)
|
nuclear@1
|
160 { }
|
nuclear@1
|
161
|
nuclear@1
|
162 // Helper; returns true if args match our enumeration criteria.
|
nuclear@1
|
163 bool MatchRule(DeviceType type, bool available) const
|
nuclear@1
|
164 {
|
nuclear@1
|
165 return ((EnumType == type) || (EnumType == Device_All)) &&
|
nuclear@1
|
166 (available || !AvailableOnly);
|
nuclear@1
|
167 }
|
nuclear@1
|
168
|
nuclear@1
|
169 protected:
|
nuclear@1
|
170 DeviceType EnumType;
|
nuclear@1
|
171 bool AvailableOnly;
|
nuclear@1
|
172 };
|
nuclear@1
|
173
|
nuclear@1
|
174
|
nuclear@1
|
175 // DeviceEnumerator<> is used to enumerate and create devices of specified class,
|
nuclear@1
|
176 // it is returned by calling MeviceManager::EnumerateDevices. Initially, the enumerator will
|
nuclear@1
|
177 // refer to the first device of specified type. Additional devices can be accessed by
|
nuclear@1
|
178 // calling Next().
|
nuclear@1
|
179
|
nuclear@1
|
180 template<class T = DeviceBase>
|
nuclear@1
|
181 class DeviceEnumerator : public DeviceHandle
|
nuclear@1
|
182 {
|
nuclear@1
|
183 friend class DeviceManager;
|
nuclear@1
|
184 friend class DeviceManagerImpl;
|
nuclear@1
|
185 public:
|
nuclear@1
|
186 DeviceEnumerator()
|
nuclear@1
|
187 : DeviceHandle(), EnumArgs(Device_None, true) { }
|
nuclear@1
|
188
|
nuclear@1
|
189 // Next advances enumeration to the next device that first criteria.
|
nuclear@1
|
190 // Returns false if no more devices exist that match enumeration criteria.
|
nuclear@1
|
191 bool Next() { return enumerateNext(EnumArgs); }
|
nuclear@1
|
192
|
nuclear@1
|
193 // Creates an instance of the device referenced by enumerator; returns null
|
nuclear@1
|
194 // if enumerator does not refer to a valid device or device is unavailable.
|
nuclear@1
|
195 // If device was already created, the same object with incremented ref-count is returned.
|
nuclear@1
|
196 T* CreateDevice() { return static_cast<T*>(DeviceHandle::CreateDevice()); }
|
nuclear@1
|
197
|
nuclear@1
|
198 protected:
|
nuclear@1
|
199 DeviceEnumerator(const DeviceHandle &dev, const DeviceEnumerationArgs& args)
|
nuclear@1
|
200 : DeviceHandle(dev), EnumArgs(args)
|
nuclear@1
|
201 { }
|
nuclear@1
|
202
|
nuclear@1
|
203 DeviceEnumerationArgs EnumArgs;
|
nuclear@1
|
204 };
|
nuclear@1
|
205
|
nuclear@1
|
206 //-------------------------------------------------------------------------------------
|
nuclear@1
|
207 // ***** DeviceManager
|
nuclear@1
|
208
|
nuclear@1
|
209 // DeviceManager maintains and provides access to devices supported by OVR, such as
|
nuclear@1
|
210 // HMDs and sensors. A single instance of DeviceManager is normally created at
|
nuclear@1
|
211 // program startup, allowing devices to be enumerated and created. DeviceManager is
|
nuclear@1
|
212 // reference counted and is AddRefed by its created child devices, causing it to
|
nuclear@1
|
213 // always be the last object that is released.
|
nuclear@1
|
214 //
|
nuclear@1
|
215 // Install MessageHandler on DeviceManager to detect when devices are inserted or removed.
|
nuclear@1
|
216 //
|
nuclear@1
|
217 // The following code will create the manager and its first available HMDDevice,
|
nuclear@1
|
218 // and then release it when not needed:
|
nuclear@1
|
219 //
|
nuclear@1
|
220 // DeviceManager* manager = DeviceManager::Create();
|
nuclear@1
|
221 // HMDDevice* hmd = manager->EnumerateDevices<HMDDevice>().CreateDevice();
|
nuclear@1
|
222 //
|
nuclear@1
|
223 // if (hmd) hmd->Release();
|
nuclear@1
|
224 // if (manager) manager->Release();
|
nuclear@1
|
225
|
nuclear@1
|
226
|
nuclear@1
|
227 class DeviceManager : public DeviceBase
|
nuclear@1
|
228 {
|
nuclear@1
|
229 public:
|
nuclear@1
|
230
|
nuclear@1
|
231 DeviceManager()
|
nuclear@1
|
232 { }
|
nuclear@1
|
233
|
nuclear@1
|
234 // DeviceBase implementation.
|
nuclear@1
|
235 virtual DeviceType GetType() const { return Device_Manager; }
|
nuclear@1
|
236 virtual DeviceManager* GetManager() const { return const_cast<DeviceManager*>(this); }
|
nuclear@1
|
237
|
nuclear@1
|
238 // Every DeviceManager has an associated profile manager, which us used to store
|
nuclear@1
|
239 // user settings that may affect device behavior.
|
nuclear@1
|
240 virtual ProfileManager* GetProfileManager() const = 0;
|
nuclear@1
|
241
|
nuclear@1
|
242
|
nuclear@1
|
243 // EnumerateDevices enumerates all of the available devices of the specified class,
|
nuclear@1
|
244 // returning an enumerator that references the first device. An empty enumerator is
|
nuclear@1
|
245 // returned if no devices are available. The following APIs are exposed through
|
nuclear@1
|
246 // DeviceEnumerator:
|
nuclear@1
|
247 // DeviceEnumerator::GetType() - Check device type. Returns Device_None
|
nuclear@1
|
248 // if no device was found/pointed to.
|
nuclear@1
|
249 // DeviceEnumerator::GetDeviceInfo() - Get more information on device.
|
nuclear@1
|
250 // DeviceEnumerator::CreateDevice() - Create an instance of device.
|
nuclear@1
|
251 // DeviceEnumerator::Next() - Move onto next device.
|
nuclear@1
|
252 template<class D>
|
nuclear@1
|
253 DeviceEnumerator<D> EnumerateDevices(bool availableOnly = true)
|
nuclear@1
|
254 {
|
nuclear@1
|
255 // TBD: A cleaner (but less efficient) alternative is though enumeratorFromHandle.
|
nuclear@1
|
256 DeviceEnumerator<> e = EnumerateDevicesEx(DeviceEnumerationArgs((DeviceType)D::EnumDeviceType, availableOnly));
|
nuclear@1
|
257 return *reinterpret_cast<DeviceEnumerator<D>*>(&e);
|
nuclear@1
|
258 }
|
nuclear@1
|
259
|
nuclear@1
|
260 // EnumerateDevicesEx provides internal implementation for device enumeration, enumerating
|
nuclear@1
|
261 // devices based on dynamically specified DeviceType in DeviceEnumerationArgs.
|
nuclear@1
|
262 // End users should call DeumerateDevices<>() instead.
|
nuclear@1
|
263 virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args) = 0;
|
nuclear@1
|
264
|
nuclear@1
|
265 // Creates a new DeviceManager. Only one instance of DeviceManager should be created at a time.
|
nuclear@1
|
266 static DeviceManager* Create();
|
nuclear@1
|
267
|
nuclear@1
|
268 // Static constant for this device type, used in template cast type checks.
|
nuclear@1
|
269 enum { EnumDeviceType = Device_Manager };
|
nuclear@1
|
270
|
nuclear@1
|
271
|
nuclear@1
|
272
|
nuclear@1
|
273 // Adds a device (DeviceCreateDesc*) into Devices. Returns NULL,
|
nuclear@1
|
274 // if unsuccessful or device is already in the list.
|
nuclear@1
|
275 virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc) = 0;
|
nuclear@1
|
276
|
nuclear@1
|
277 protected:
|
nuclear@1
|
278 DeviceEnumerator<> enumeratorFromHandle(const DeviceHandle& h, const DeviceEnumerationArgs& args)
|
nuclear@1
|
279 { return DeviceEnumerator<>(h, args); }
|
nuclear@1
|
280
|
nuclear@1
|
281 DeviceManager* getThis() { return this; }
|
nuclear@1
|
282 };
|
nuclear@1
|
283
|
nuclear@1
|
284
|
nuclear@1
|
285
|
nuclear@1
|
286 //-------------------------------------------------------------------------------------
|
nuclear@1
|
287 // ***** HMDInfo
|
nuclear@1
|
288
|
nuclear@1
|
289 // This structure describes various aspects of the HMD allowing us to configure rendering.
|
nuclear@1
|
290 //
|
nuclear@1
|
291 // Currently included data:
|
nuclear@1
|
292 // - Physical screen dimensions, resolution, and eye distances.
|
nuclear@1
|
293 // (some of these will be configurable with a tool in the future).
|
nuclear@1
|
294 // These arguments allow us to properly setup projection across HMDs.
|
nuclear@1
|
295 // - DisplayDeviceName for identifying HMD screen; system-specific interpretation.
|
nuclear@1
|
296 //
|
nuclear@1
|
297 // TBD:
|
nuclear@1
|
298 // - Power on/ off?
|
nuclear@1
|
299 // - Sensor rates and capabilities
|
nuclear@1
|
300 // - Distortion radius/variables
|
nuclear@1
|
301 // - Screen update frequency
|
nuclear@1
|
302 // - Distortion needed flag
|
nuclear@1
|
303 // - Update modes:
|
nuclear@1
|
304 // Set update mode: Stereo (both sides together), mono (same in both eyes),
|
nuclear@1
|
305 // Alternating, Alternating scan-lines.
|
nuclear@1
|
306
|
nuclear@1
|
307 class HMDInfo : public DeviceInfo
|
nuclear@1
|
308 {
|
nuclear@1
|
309 public:
|
nuclear@1
|
310 // Size of the entire screen, in pixels.
|
nuclear@1
|
311 unsigned HResolution, VResolution;
|
nuclear@1
|
312 // Physical dimensions of the active screen in meters. Can be used to calculate
|
nuclear@1
|
313 // projection center while considering IPD.
|
nuclear@1
|
314 float HScreenSize, VScreenSize;
|
nuclear@1
|
315 // Physical offset from the top of the screen to the eye center, in meters.
|
nuclear@1
|
316 // This will usually, but not necessarily be half of VScreenSize.
|
nuclear@1
|
317 float VScreenCenter;
|
nuclear@1
|
318 // Distance from the eye to screen surface, in meters.
|
nuclear@1
|
319 // Useful for calculating FOV and projection.
|
nuclear@1
|
320 float EyeToScreenDistance;
|
nuclear@1
|
321 // Distance between physical lens centers useful for calculating distortion center.
|
nuclear@1
|
322 float LensSeparationDistance;
|
nuclear@1
|
323 // Configured distance between the user's eye centers, in meters. Defaults to 0.064.
|
nuclear@1
|
324 float InterpupillaryDistance;
|
nuclear@1
|
325
|
nuclear@1
|
326 // Radial distortion correction coefficients.
|
nuclear@1
|
327 // The distortion assumes that the input texture coordinates will be scaled
|
nuclear@1
|
328 // by the following equation:
|
nuclear@1
|
329 // uvResult = uvInput * (K0 + K1 * uvLength^2 + K2 * uvLength^4)
|
nuclear@1
|
330 // Where uvInput is the UV vector from the center of distortion in direction
|
nuclear@1
|
331 // of the mapped pixel, uvLength is the magnitude of that vector, and uvResult
|
nuclear@1
|
332 // the corresponding location after distortion.
|
nuclear@1
|
333 float DistortionK[4];
|
nuclear@1
|
334
|
nuclear@1
|
335 float ChromaAbCorrection[4];
|
nuclear@1
|
336
|
nuclear@1
|
337 // Desktop coordinate position of the screen (can be negative; may not be present on all platforms)
|
nuclear@1
|
338 int DesktopX, DesktopY;
|
nuclear@1
|
339
|
nuclear@1
|
340 // Windows:
|
nuclear@1
|
341 // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC.
|
nuclear@1
|
342 char DisplayDeviceName[32];
|
nuclear@1
|
343
|
nuclear@1
|
344 // MacOS:
|
nuclear@1
|
345 long DisplayId;
|
nuclear@1
|
346
|
nuclear@1
|
347
|
nuclear@1
|
348 HMDInfo()
|
nuclear@1
|
349 : DeviceInfo(Device_HMD),
|
nuclear@1
|
350 HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
|
nuclear@1
|
351 VScreenCenter(0), EyeToScreenDistance(0),
|
nuclear@1
|
352 LensSeparationDistance(0), InterpupillaryDistance(0),
|
nuclear@1
|
353 DesktopX(0), DesktopY(0), DisplayId(0)
|
nuclear@1
|
354 {
|
nuclear@1
|
355 DisplayDeviceName[0] = 0;
|
nuclear@1
|
356 memset(DistortionK, 0, sizeof(DistortionK));
|
nuclear@1
|
357 DistortionK[0] = 1;
|
nuclear@1
|
358 ChromaAbCorrection[0] = ChromaAbCorrection[2] = 1;
|
nuclear@1
|
359 ChromaAbCorrection[1] = ChromaAbCorrection[3] = 0;
|
nuclear@1
|
360 }
|
nuclear@1
|
361
|
nuclear@1
|
362 // Operator = copies local fields only (base class must be correct already)
|
nuclear@1
|
363 void operator = (const HMDInfo& src)
|
nuclear@1
|
364 {
|
nuclear@1
|
365 HResolution = src.HResolution;
|
nuclear@1
|
366 VResolution = src.VResolution;
|
nuclear@1
|
367 HScreenSize = src.HScreenSize;
|
nuclear@1
|
368 VScreenSize = src.VScreenSize;
|
nuclear@1
|
369 VScreenCenter = src.VScreenCenter;
|
nuclear@1
|
370 EyeToScreenDistance = src.EyeToScreenDistance;
|
nuclear@1
|
371 LensSeparationDistance = src.LensSeparationDistance;
|
nuclear@1
|
372 InterpupillaryDistance = src.InterpupillaryDistance;
|
nuclear@1
|
373 DistortionK[0] = src.DistortionK[0];
|
nuclear@1
|
374 DistortionK[1] = src.DistortionK[1];
|
nuclear@1
|
375 DistortionK[2] = src.DistortionK[2];
|
nuclear@1
|
376 DistortionK[3] = src.DistortionK[3];
|
nuclear@1
|
377 ChromaAbCorrection[0] = src.ChromaAbCorrection[0];
|
nuclear@1
|
378 ChromaAbCorrection[1] = src.ChromaAbCorrection[1];
|
nuclear@1
|
379 ChromaAbCorrection[2] = src.ChromaAbCorrection[2];
|
nuclear@1
|
380 ChromaAbCorrection[3] = src.ChromaAbCorrection[3];
|
nuclear@1
|
381 DesktopX = src.DesktopX;
|
nuclear@1
|
382 DesktopY = src.DesktopY;
|
nuclear@1
|
383 memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName));
|
nuclear@1
|
384 DisplayId = src.DisplayId;
|
nuclear@1
|
385 }
|
nuclear@1
|
386
|
nuclear@1
|
387 bool IsSameDisplay(const HMDInfo& o) const
|
nuclear@1
|
388 {
|
nuclear@1
|
389 return DisplayId == o.DisplayId &&
|
nuclear@1
|
390 String::CompareNoCase(DisplayDeviceName,
|
nuclear@1
|
391 o.DisplayDeviceName) == 0;
|
nuclear@1
|
392 }
|
nuclear@1
|
393
|
nuclear@1
|
394 };
|
nuclear@1
|
395
|
nuclear@1
|
396
|
nuclear@1
|
397 // HMDDevice represents an Oculus HMD device unit. An instance of this class
|
nuclear@1
|
398 // is typically created from the DeviceManager.
|
nuclear@1
|
399 // After HMD device is created, we its sensor data can be obtained by
|
nuclear@1
|
400 // first creating a Sensor object and then.
|
nuclear@1
|
401
|
nuclear@1
|
402 // TBD:
|
nuclear@1
|
403 // - Configure Sensor
|
nuclear@1
|
404 // - APIs to set On-Screen message, other states?
|
nuclear@1
|
405
|
nuclear@1
|
406 class HMDDevice : public DeviceBase
|
nuclear@1
|
407 {
|
nuclear@1
|
408 public:
|
nuclear@1
|
409 HMDDevice()
|
nuclear@1
|
410 { }
|
nuclear@1
|
411
|
nuclear@1
|
412 // Static constant for this device type, used in template cast type checks.
|
nuclear@1
|
413 enum { EnumDeviceType = Device_HMD };
|
nuclear@1
|
414
|
nuclear@1
|
415 virtual DeviceType GetType() const { return Device_HMD; }
|
nuclear@1
|
416
|
nuclear@1
|
417 // Creates a sensor associated with this HMD.
|
nuclear@1
|
418 virtual SensorDevice* GetSensor() = 0;
|
nuclear@1
|
419
|
nuclear@1
|
420
|
nuclear@1
|
421 // Requests the currently used profile. This profile affects the
|
nuclear@1
|
422 // settings reported by HMDInfo.
|
nuclear@1
|
423 virtual Profile* GetProfile() const = 0;
|
nuclear@1
|
424 // Obtains the currently used profile name. This is initialized to the default
|
nuclear@1
|
425 // profile name, if any; it can then be changed per-device by SetProfileName.
|
nuclear@1
|
426 virtual const char* GetProfileName() const = 0;
|
nuclear@1
|
427 // Sets the profile user name, changing the data returned by GetProfileInfo.
|
nuclear@1
|
428 virtual bool SetProfileName(const char* name) = 0;
|
nuclear@1
|
429
|
nuclear@1
|
430
|
nuclear@1
|
431 // Disconnects from real HMD device. This HMDDevice remains as 'fake' HMD.
|
nuclear@1
|
432 // SensorDevice ptr is used to restore the 'fake' HMD (can be NULL).
|
nuclear@1
|
433 HMDDevice* Disconnect(SensorDevice*);
|
nuclear@1
|
434
|
nuclear@1
|
435 // Returns 'true' if HMD device is a 'fake' HMD (was created this way or
|
nuclear@1
|
436 // 'Disconnect' method was called).
|
nuclear@1
|
437 bool IsDisconnected() const;
|
nuclear@1
|
438 };
|
nuclear@1
|
439
|
nuclear@1
|
440
|
nuclear@1
|
441 //-------------------------------------------------------------------------------------
|
nuclear@1
|
442 // ***** SensorRange & SensorInfo
|
nuclear@1
|
443
|
nuclear@1
|
444 // SensorRange specifies maximum value ranges that SensorDevice hardware is configured
|
nuclear@1
|
445 // to detect. Although this range doesn't affect the scale of MessageBodyFrame values,
|
nuclear@1
|
446 // physical motions whose positive or negative magnitude is outside the specified range
|
nuclear@1
|
447 // may get clamped or misreported. Setting lower values may result in higher precision
|
nuclear@1
|
448 // tracking.
|
nuclear@1
|
449 struct SensorRange
|
nuclear@1
|
450 {
|
nuclear@1
|
451 SensorRange(float maxAcceleration = 0.0f, float maxRotationRate = 0.0f,
|
nuclear@1
|
452 float maxMagneticField = 0.0f)
|
nuclear@1
|
453 : MaxAcceleration(maxAcceleration), MaxRotationRate(maxRotationRate),
|
nuclear@1
|
454 MaxMagneticField(maxMagneticField)
|
nuclear@1
|
455 { }
|
nuclear@1
|
456
|
nuclear@1
|
457 // Maximum detected acceleration in m/s^2. Up to 8*G equivalent support guaranteed,
|
nuclear@1
|
458 // where G is ~9.81 m/s^2.
|
nuclear@1
|
459 // Oculus DK1 HW has thresholds near: 2, 4 (default), 8, 16 G.
|
nuclear@1
|
460 float MaxAcceleration;
|
nuclear@1
|
461 // Maximum detected angular velocity in rad/s. Up to 8*Pi support guaranteed.
|
nuclear@1
|
462 // Oculus DK1 HW thresholds near: 1, 2, 4, 8 Pi (default).
|
nuclear@1
|
463 float MaxRotationRate;
|
nuclear@1
|
464 // Maximum detectable Magnetic field strength in Gauss. Up to 2.5 Gauss support guaranteed.
|
nuclear@1
|
465 // Oculus DK1 HW thresholds near: 0.88, 1.3, 1.9, 2.5 gauss.
|
nuclear@1
|
466 float MaxMagneticField;
|
nuclear@1
|
467 };
|
nuclear@1
|
468
|
nuclear@1
|
469 // SensorInfo describes capabilities of the sensor device.
|
nuclear@1
|
470 class SensorInfo : public DeviceInfo
|
nuclear@1
|
471 {
|
nuclear@1
|
472 public:
|
nuclear@1
|
473 SensorInfo() : DeviceInfo(Device_Sensor), VendorId(0), ProductId(0)
|
nuclear@1
|
474 {
|
nuclear@1
|
475 SerialNumber[0] = 0;
|
nuclear@1
|
476 }
|
nuclear@1
|
477
|
nuclear@1
|
478 // HID Vendor and ProductId of the device.
|
nuclear@1
|
479 UInt16 VendorId;
|
nuclear@1
|
480 UInt16 ProductId;
|
nuclear@1
|
481 // MaxRanges report maximum sensor range values supported by HW.
|
nuclear@1
|
482 SensorRange MaxRanges;
|
nuclear@1
|
483 // Sensor (and display) serial number.
|
nuclear@1
|
484 char SerialNumber[20];
|
nuclear@1
|
485
|
nuclear@1
|
486 private:
|
nuclear@1
|
487 void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
|
nuclear@1
|
488 };
|
nuclear@1
|
489
|
nuclear@1
|
490
|
nuclear@1
|
491 //-------------------------------------------------------------------------------------
|
nuclear@1
|
492 // ***** SensorDevice
|
nuclear@1
|
493
|
nuclear@1
|
494 // SensorDevice is an interface to sensor data.
|
nuclear@1
|
495 // Install a MessageHandler of SensorDevice instance to receive MessageBodyFrame
|
nuclear@1
|
496 // notifications.
|
nuclear@1
|
497 //
|
nuclear@1
|
498 // TBD: Add Polling API? More HID interfaces?
|
nuclear@1
|
499
|
nuclear@1
|
500 class SensorDevice : public HIDDeviceBase, public DeviceBase
|
nuclear@1
|
501 {
|
nuclear@1
|
502 public:
|
nuclear@1
|
503 SensorDevice()
|
nuclear@1
|
504 { }
|
nuclear@1
|
505
|
nuclear@1
|
506 // Static constant for this device type, used in template cast type checks.
|
nuclear@1
|
507 enum { EnumDeviceType = Device_Sensor };
|
nuclear@1
|
508
|
nuclear@1
|
509 virtual DeviceType GetType() const { return Device_Sensor; }
|
nuclear@1
|
510
|
nuclear@1
|
511
|
nuclear@1
|
512 // CoordinateFrame defines whether messages come in the coordinate frame
|
nuclear@1
|
513 // of the sensor device or HMD, which has a different internal sensor.
|
nuclear@1
|
514 // Sensors obtained form the HMD will automatically use HMD coordinates.
|
nuclear@1
|
515 enum CoordinateFrame
|
nuclear@1
|
516 {
|
nuclear@1
|
517 Coord_Sensor = 0,
|
nuclear@1
|
518 Coord_HMD = 1
|
nuclear@1
|
519 };
|
nuclear@1
|
520
|
nuclear@1
|
521 virtual void SetCoordinateFrame(CoordinateFrame coordframe) = 0;
|
nuclear@1
|
522 virtual CoordinateFrame GetCoordinateFrame() const = 0;
|
nuclear@1
|
523
|
nuclear@1
|
524 // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call).
|
nuclear@1
|
525 // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be
|
nuclear@1
|
526 // called twice or thrice at the same 'tick'.
|
nuclear@1
|
527 // If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three
|
nuclear@1
|
528 // times for each 'tick': the first call will contain averaged values, the second
|
nuclear@1
|
529 // and third calls will provide with most recent two recorded samples.
|
nuclear@1
|
530 virtual void SetReportRate(unsigned rateHz) = 0;
|
nuclear@1
|
531 // Returns currently set report rate, in Hz. If 0 - error occurred.
|
nuclear@1
|
532 // Note, this value may be different from the one provided for SetReportRate. The return
|
nuclear@1
|
533 // value will contain the actual rate.
|
nuclear@1
|
534 virtual unsigned GetReportRate() const = 0;
|
nuclear@1
|
535
|
nuclear@1
|
536 // Sets maximum range settings for the sensor described by SensorRange.
|
nuclear@1
|
537 // The function will fail if you try to pass values outside Maximum supported
|
nuclear@1
|
538 // by the HW, as described by SensorInfo.
|
nuclear@1
|
539 // Pass waitFlag == true to wait for command completion. For waitFlag == true,
|
nuclear@1
|
540 // returns true if the range was applied successfully (no HW error).
|
nuclear@1
|
541 // For waitFlag = false, return 'true' means that command was enqueued successfully.
|
nuclear@1
|
542 virtual bool SetRange(const SensorRange& range, bool waitFlag = false) = 0;
|
nuclear@1
|
543
|
nuclear@1
|
544 // Return the current sensor range settings for the device. These may not exactly
|
nuclear@1
|
545 // match the values applied through SetRange.
|
nuclear@1
|
546 virtual void GetRange(SensorRange* range) const = 0;
|
nuclear@1
|
547 };
|
nuclear@1
|
548
|
nuclear@1
|
549 //-------------------------------------------------------------------------------------
|
nuclear@1
|
550 // ***** LatencyTestConfiguration
|
nuclear@1
|
551 // LatencyTestConfiguration specifies configuration information for the Oculus Latency Tester device.
|
nuclear@1
|
552 struct LatencyTestConfiguration
|
nuclear@1
|
553 {
|
nuclear@1
|
554 LatencyTestConfiguration(const Color& threshold, bool sendSamples = false)
|
nuclear@1
|
555 : Threshold(threshold), SendSamples(sendSamples)
|
nuclear@1
|
556 {
|
nuclear@1
|
557 }
|
nuclear@1
|
558
|
nuclear@1
|
559 // The color threshold for triggering a detected display change.
|
nuclear@1
|
560 Color Threshold;
|
nuclear@1
|
561 // Flag specifying whether we wish to receive a stream of color values from the sensor.
|
nuclear@1
|
562 bool SendSamples;
|
nuclear@1
|
563 };
|
nuclear@1
|
564
|
nuclear@1
|
565 //-------------------------------------------------------------------------------------
|
nuclear@1
|
566 // ***** LatencyTestDisplay
|
nuclear@1
|
567 // LatencyTestDisplay sets the mode and contents of the Latency Tester LED display.
|
nuclear@1
|
568 // See the 'Latency Tester Specification' document for more details.
|
nuclear@1
|
569 struct LatencyTestDisplay
|
nuclear@1
|
570 {
|
nuclear@1
|
571 LatencyTestDisplay(UByte mode, UInt32 value)
|
nuclear@1
|
572 : Mode(mode), Value(value)
|
nuclear@1
|
573 {
|
nuclear@1
|
574 }
|
nuclear@1
|
575
|
nuclear@1
|
576 UByte Mode; // The display mode that we wish to select.
|
nuclear@1
|
577 UInt32 Value; // The value to display.
|
nuclear@1
|
578 };
|
nuclear@1
|
579
|
nuclear@1
|
580 //-------------------------------------------------------------------------------------
|
nuclear@1
|
581 // ***** LatencyTestDevice
|
nuclear@1
|
582
|
nuclear@1
|
583 // LatencyTestDevice provides an interface to the Oculus Latency Tester which is used to test 'motion to photon' latency.
|
nuclear@1
|
584 class LatencyTestDevice : public HIDDeviceBase, public DeviceBase
|
nuclear@1
|
585 {
|
nuclear@1
|
586 public:
|
nuclear@1
|
587 LatencyTestDevice()
|
nuclear@1
|
588 { }
|
nuclear@1
|
589
|
nuclear@1
|
590 // Static constant for this device type, used in template cast type checks.
|
nuclear@1
|
591 enum { EnumDeviceType = Device_LatencyTester };
|
nuclear@1
|
592
|
nuclear@1
|
593 virtual DeviceType GetType() const { return Device_LatencyTester; }
|
nuclear@1
|
594
|
nuclear@1
|
595 // Specifies configuration information including the threshold for triggering a detected color change,
|
nuclear@1
|
596 // and a flag to enable a stream of sensor values (typically used for debugging).
|
nuclear@1
|
597 virtual bool SetConfiguration(const LatencyTestConfiguration& configuration, bool waitFlag = false) = 0;
|
nuclear@1
|
598
|
nuclear@1
|
599 // Get configuration information from device.
|
nuclear@1
|
600 virtual bool GetConfiguration(LatencyTestConfiguration* configuration) = 0;
|
nuclear@1
|
601
|
nuclear@1
|
602 // Used to calibrate the latency tester at the start of a test. Display the specified color on the screen
|
nuclear@1
|
603 // beneath the latency tester and then call this method. Calibration information is lost
|
nuclear@1
|
604 // when power is removed from the device.
|
nuclear@1
|
605 virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false) = 0;
|
nuclear@1
|
606
|
nuclear@1
|
607 // Triggers the start of a measurement. This starts the millisecond timer on the device and
|
nuclear@1
|
608 // causes it to respond with the 'MessageLatencyTestStarted' message.
|
nuclear@1
|
609 virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false) = 0;
|
nuclear@1
|
610
|
nuclear@1
|
611 // Used to set the value displayed on the LED display panel.
|
nuclear@1
|
612 virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false) = 0;
|
nuclear@1
|
613
|
nuclear@1
|
614 virtual DeviceBase* GetDevice() { return this; }
|
nuclear@1
|
615 };
|
nuclear@1
|
616
|
nuclear@1
|
617 } // namespace OVR
|
nuclear@1
|
618
|
nuclear@1
|
619 #endif
|