oculus1

diff libovr/Src/OVR_Device.h @ 1:e2f9e4603129

added LibOVR and started a simple vr wrapper.
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 14 Sep 2013 16:14:59 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libovr/Src/OVR_Device.h	Sat Sep 14 16:14:59 2013 +0300
     1.3 @@ -0,0 +1,619 @@
     1.4 +/************************************************************************************
     1.5 +
     1.6 +PublicHeader:   OVR.h
     1.7 +Filename    :   OVR_Device.h
     1.8 +Content     :   Definition of HMD-related Device interfaces
     1.9 +Created     :   September 21, 2012
    1.10 +Authors     :   Michael Antonov
    1.11 +
    1.12 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    1.13 +
    1.14 +Use of this software is subject to the terms of the Oculus license
    1.15 +agreement provided at the time of installation or download, or which
    1.16 +otherwise accompanies this software in either electronic or hard copy form.
    1.17 +
    1.18 +*************************************************************************************/
    1.19 +
    1.20 +#ifndef OVR_Device_h
    1.21 +#define OVR_Device_h
    1.22 +
    1.23 +#include "OVR_DeviceConstants.h"
    1.24 +#include "OVR_DeviceHandle.h"
    1.25 +#include "OVR_DeviceMessages.h"
    1.26 +#include "OVR_HIDDeviceBase.h"
    1.27 +
    1.28 +#include "Kernel/OVR_Atomic.h"
    1.29 +#include "Kernel/OVR_RefCount.h"
    1.30 +#include "Kernel/OVR_String.h"
    1.31 +
    1.32 +namespace OVR {
    1.33 +
    1.34 +// Declared externally
    1.35 +class Profile;
    1.36 +class ProfileManager; // << Should be renamed for consistency
    1.37 +
    1.38 +// Forward declarations
    1.39 +class SensorDevice;
    1.40 +class DeviceCommon;
    1.41 +class DeviceManager;
    1.42 +
    1.43 +// MessageHandler is a base class from which users derive to receive messages,
    1.44 +// its OnMessage handler will be called for messages once it is installed on
    1.45 +// a device. Same message handler can be installed on multiple devices.
    1.46 +class MessageHandler
    1.47 +{
    1.48 +    friend class MessageHandlerImpl;
    1.49 +public:
    1.50 +    MessageHandler();
    1.51 +    virtual ~MessageHandler();
    1.52 +
    1.53 +    // Returns 'true' if handler is currently installed on any devices.
    1.54 +    bool        IsHandlerInstalled() const;
    1.55 +
    1.56 +    // Should be called from derived class destructor to avoid handler
    1.57 +    // being called after it exits.
    1.58 +    void        RemoveHandlerFromDevices();
    1.59 +
    1.60 +    // Returns a pointer to the internal lock object that is locked by a
    1.61 +    // background thread while OnMessage() is called.
    1.62 +    // This lock guaranteed to survive until ~MessageHandler.
    1.63 +    Lock*       GetHandlerLock() const;
    1.64 +
    1.65 +
    1.66 +    virtual void OnMessage(const Message&) { }
    1.67 +
    1.68 +    // Determines if handler supports a specific message type. Can
    1.69 +    // be used to filter out entire message groups. The result
    1.70 +    // returned by this function shouldn't change after handler creation.
    1.71 +    virtual bool SupportsMessageType(MessageType) const { return true; }    
    1.72 +
    1.73 +private:    
    1.74 +    UPInt Internal[4];
    1.75 +};
    1.76 +
    1.77 +
    1.78 +//-------------------------------------------------------------------------------------
    1.79 +// ***** DeviceBase
    1.80 +
    1.81 +// DeviceBase is the base class for all OVR Devices. It provides the following basic
    1.82 +// functionality:
    1.83 +//   - Reports device type, manager, and associated parent (if any).
    1.84 +//   - Supports installable message handlers, which are notified of device events.
    1.85 +//   - Device objects are created through DeviceHandle::CreateDevice or more commonly
    1.86 +//     through DeviceEnumerator<>::CreateDevice.
    1.87 +//   - Created devices are reference counted, starting with RefCount of 1.
    1.88 +//   - Device is resources are cleaned up when it is Released, although its handles
    1.89 +//     may survive longer if referenced.
    1.90 +
    1.91 +class DeviceBase : public NewOverrideBase
    1.92 +{    
    1.93 +    friend class DeviceHandle;  
    1.94 +    friend class DeviceManagerImpl;
    1.95 +public:
    1.96 +
    1.97 +    // Enumerating DeviceBase enumerates all devices.
    1.98 +    enum { EnumDeviceType = Device_All };
    1.99 +
   1.100 +    virtual ~DeviceBase() { }
   1.101 +    virtual void            AddRef();
   1.102 +    virtual void            Release();
   1.103 +    
   1.104 +    virtual DeviceBase*     GetParent() const;
   1.105 +    virtual DeviceManager*  GetManager() const;  
   1.106 +
   1.107 +    virtual void            SetMessageHandler(MessageHandler* handler);
   1.108 +    virtual MessageHandler* GetMessageHandler() const;
   1.109 +
   1.110 +    virtual DeviceType      GetType() const;
   1.111 +    virtual bool            GetDeviceInfo(DeviceInfo* info) const;
   1.112 +
   1.113 +    // returns the MessageHandler's lock
   1.114 +    Lock*                   GetHandlerLock() const;
   1.115 +protected:
   1.116 +    // Internal
   1.117 +    virtual DeviceCommon*   getDeviceCommon() const = 0;
   1.118 +};
   1.119 +
   1.120 +
   1.121 +//-------------------------------------------------------------------------------------
   1.122 +// ***** DeviceInfo
   1.123 +
   1.124 +// DeviceInfo describes a device and its capabilities, obtained by calling
   1.125 +// GetDeviceInfo. This base class only contains device-independent functionality;
   1.126 +// users will normally use a derived HMDInfo or SensorInfo classes for more
   1.127 +// extensive device info.
   1.128 +
   1.129 +class DeviceInfo
   1.130 +{
   1.131 +public:
   1.132 +    DeviceInfo() : InfoClassType(Device_None), Type(Device_None), Version(0)
   1.133 +    {  ProductName[0] = Manufacturer[0] = 0; }
   1.134 +
   1.135 +    enum { MaxNameLength = 32 };
   1.136 +    
   1.137 +    // Type of device for which DeviceInfo is intended.
   1.138 +    // This will be set to Device_HMD for HMDInfo structure, note that this may be
   1.139 +    // different form the actual device type since (Device_None) is valid.
   1.140 +    const DeviceType InfoClassType;
   1.141 +    // Type of device this describes. This must be the same as InfoClassType when
   1.142 +    // InfoClassType != Device_None.
   1.143 +    DeviceType       Type;
   1.144 +    // Name string describing the product: "Oculus Rift DK1", etc.
   1.145 +    char             ProductName[MaxNameLength];    
   1.146 +    char             Manufacturer[MaxNameLength];
   1.147 +    unsigned         Version;
   1.148 +    
   1.149 +protected:
   1.150 +    DeviceInfo(DeviceType type) : InfoClassType(type), Type(type), Version(0)
   1.151 +    { ProductName[0] = Manufacturer[0] = 0; }
   1.152 +    void operator = (const DeviceInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
   1.153 +};
   1.154 +
   1.155 +
   1.156 +//-------------------------------------------------------------------------------------
   1.157 +// DeviceEnumerationArgs provides device enumeration argumenrs for DeviceManager::EnumerateDevicesEx.
   1.158 +class DeviceEnumerationArgs
   1.159 +{
   1.160 +public:
   1.161 +    DeviceEnumerationArgs(DeviceType enumType, bool availableOnly)
   1.162 +        : EnumType(enumType), AvailableOnly(availableOnly)
   1.163 +    { }
   1.164 +
   1.165 +    // Helper; returns true if args match our enumeration criteria.
   1.166 +    bool         MatchRule(DeviceType type, bool available) const
   1.167 +    {
   1.168 +        return ((EnumType == type) || (EnumType == Device_All)) &&
   1.169 +                (available || !AvailableOnly);
   1.170 +    }
   1.171 +
   1.172 +protected:    
   1.173 +    DeviceType   EnumType;
   1.174 +    bool         AvailableOnly;
   1.175 +};
   1.176 +
   1.177 +
   1.178 +// DeviceEnumerator<> is used to enumerate and create devices of specified class,
   1.179 +// it is returned by calling MeviceManager::EnumerateDevices. Initially, the enumerator will
   1.180 +// refer to the first device of specified type. Additional devices can be accessed by
   1.181 +// calling Next().
   1.182 +
   1.183 +template<class T = DeviceBase>
   1.184 +class DeviceEnumerator : public DeviceHandle
   1.185 +{
   1.186 +    friend class DeviceManager;
   1.187 +    friend class DeviceManagerImpl;
   1.188 +public:
   1.189 +    DeviceEnumerator()
   1.190 +        : DeviceHandle(), EnumArgs(Device_None, true) { }
   1.191 +
   1.192 +    // Next advances enumeration to the next device that first criteria.
   1.193 +    // Returns false if no more devices exist that match enumeration criteria.
   1.194 +    bool    Next()          { return enumerateNext(EnumArgs); }
   1.195 +
   1.196 +    // Creates an instance of the device referenced by enumerator; returns null
   1.197 +    // if enumerator does not refer to a valid device or device is unavailable.
   1.198 +    // If device was already created, the same object with incremented ref-count is returned.
   1.199 +    T*      CreateDevice()  { return static_cast<T*>(DeviceHandle::CreateDevice()); }
   1.200 +
   1.201 +protected:
   1.202 +    DeviceEnumerator(const DeviceHandle &dev, const DeviceEnumerationArgs& args)
   1.203 +        : DeviceHandle(dev), EnumArgs(args)
   1.204 +    { }
   1.205 +
   1.206 +    DeviceEnumerationArgs EnumArgs;
   1.207 +};
   1.208 +
   1.209 +//-------------------------------------------------------------------------------------
   1.210 +// ***** DeviceManager
   1.211 +
   1.212 +// DeviceManager maintains and provides access to devices supported by OVR, such as
   1.213 +// HMDs and sensors. A single instance of DeviceManager is normally created at
   1.214 +// program startup, allowing devices to be enumerated and created. DeviceManager is
   1.215 +// reference counted and is AddRefed by its created child devices, causing it to
   1.216 +// always be the last object that is released.
   1.217 +//
   1.218 +// Install MessageHandler on DeviceManager to detect when devices are inserted or removed.
   1.219 +//
   1.220 +// The following code will create the manager and its first available HMDDevice,
   1.221 +// and then release it when not needed:
   1.222 +//
   1.223 +//  DeviceManager* manager = DeviceManager::Create();
   1.224 +//  HMDDevice*     hmd = manager->EnumerateDevices<HMDDevice>().CreateDevice();
   1.225 +//
   1.226 +//  if (hmd) hmd->Release();
   1.227 +//  if (manager) manager->Release();
   1.228 +
   1.229 +
   1.230 +class DeviceManager : public DeviceBase
   1.231 +{
   1.232 +public:
   1.233 +  
   1.234 +    DeviceManager()
   1.235 +    { }
   1.236 +
   1.237 +    // DeviceBase implementation.
   1.238 +    virtual DeviceType      GetType() const     { return Device_Manager; }
   1.239 +    virtual DeviceManager*  GetManager() const  { return const_cast<DeviceManager*>(this); }
   1.240 +
   1.241 +    // Every DeviceManager has an associated profile manager, which us used to store
   1.242 +    // user settings that may affect device behavior. 
   1.243 +    virtual ProfileManager* GetProfileManager() const = 0;
   1.244 +
   1.245 +
   1.246 +    // EnumerateDevices enumerates all of the available devices of the specified class,
   1.247 +    // returning an enumerator that references the first device. An empty enumerator is
   1.248 +    // returned if no devices are available. The following APIs are exposed through
   1.249 +    // DeviceEnumerator:
   1.250 +    //   DeviceEnumerator::GetType()        - Check device type. Returns Device_None 
   1.251 +    //                                        if no device was found/pointed to.
   1.252 +    //   DeviceEnumerator::GetDeviceInfo()  - Get more information on device.
   1.253 +    //   DeviceEnumerator::CreateDevice()   - Create an instance of device.
   1.254 +    //   DeviceEnumerator::Next()           - Move onto next device.
   1.255 +    template<class D>
   1.256 +    DeviceEnumerator<D>     EnumerateDevices(bool availableOnly = true)
   1.257 +    {
   1.258 +        // TBD: A cleaner (but less efficient) alternative is though enumeratorFromHandle.
   1.259 +        DeviceEnumerator<> e = EnumerateDevicesEx(DeviceEnumerationArgs((DeviceType)D::EnumDeviceType, availableOnly));
   1.260 +        return *reinterpret_cast<DeviceEnumerator<D>*>(&e);
   1.261 +    }
   1.262 +  
   1.263 +    // EnumerateDevicesEx provides internal implementation for device enumeration, enumerating
   1.264 +    // devices based on dynamically specified DeviceType in DeviceEnumerationArgs.
   1.265 +    // End users should call DeumerateDevices<>() instead.
   1.266 +    virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args) = 0;
   1.267 +
   1.268 +    // Creates a new DeviceManager. Only one instance of DeviceManager should be created at a time.
   1.269 +    static   DeviceManager* Create();
   1.270 +
   1.271 +    // Static constant for this device type, used in template cast type checks.
   1.272 +    enum { EnumDeviceType = Device_Manager };
   1.273 +
   1.274 +
   1.275 +
   1.276 +    // Adds a device (DeviceCreateDesc*) into Devices. Returns NULL, 
   1.277 +    // if unsuccessful or device is already in the list.
   1.278 +    virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc) = 0;
   1.279 +
   1.280 +protected:
   1.281 +    DeviceEnumerator<> enumeratorFromHandle(const DeviceHandle& h, const DeviceEnumerationArgs& args)
   1.282 +    { return DeviceEnumerator<>(h, args); }
   1.283 +
   1.284 +    DeviceManager* getThis() { return this; }
   1.285 +};
   1.286 +
   1.287 +
   1.288 +
   1.289 +//-------------------------------------------------------------------------------------
   1.290 +// ***** HMDInfo 
   1.291 +
   1.292 +// This structure describes various aspects of the HMD allowing us to configure rendering.
   1.293 +//
   1.294 +//  Currently included data:
   1.295 +//   - Physical screen dimensions, resolution, and eye distances.
   1.296 +//     (some of these will be configurable with a tool in the future).
   1.297 +//     These arguments allow us to properly setup projection across HMDs.
   1.298 +//   - DisplayDeviceName for identifying HMD screen; system-specific interpretation.
   1.299 +//
   1.300 +// TBD:
   1.301 +//  - Power on/ off?
   1.302 +//  - Sensor rates and capabilities
   1.303 +//  - Distortion radius/variables    
   1.304 +//  - Screen update frequency
   1.305 +//  - Distortion needed flag
   1.306 +//  - Update modes:
   1.307 +//      Set update mode: Stereo (both sides together), mono (same in both eyes),
   1.308 +//                       Alternating, Alternating scan-lines.
   1.309 +
   1.310 +class HMDInfo : public DeviceInfo
   1.311 +{
   1.312 +public:
   1.313 +    // Size of the entire screen, in pixels.
   1.314 +    unsigned  HResolution, VResolution; 
   1.315 +    // Physical dimensions of the active screen in meters. Can be used to calculate
   1.316 +    // projection center while considering IPD.
   1.317 +    float     HScreenSize, VScreenSize;
   1.318 +    // Physical offset from the top of the screen to the eye center, in meters.
   1.319 +    // This will usually, but not necessarily be half of VScreenSize.
   1.320 +    float     VScreenCenter;
   1.321 +    // Distance from the eye to screen surface, in meters.
   1.322 +    // Useful for calculating FOV and projection.
   1.323 +    float     EyeToScreenDistance;
   1.324 +    // Distance between physical lens centers useful for calculating distortion center.
   1.325 +    float     LensSeparationDistance;
   1.326 +    // Configured distance between the user's eye centers, in meters. Defaults to 0.064.
   1.327 +    float     InterpupillaryDistance;
   1.328 +    
   1.329 +    // Radial distortion correction coefficients.
   1.330 +    // The distortion assumes that the input texture coordinates will be scaled
   1.331 +    // by the following equation:    
   1.332 +    //   uvResult = uvInput * (K0 + K1 * uvLength^2 + K2 * uvLength^4)
   1.333 +    // Where uvInput is the UV vector from the center of distortion in direction
   1.334 +    // of the mapped pixel, uvLength is the magnitude of that vector, and uvResult
   1.335 +    // the corresponding location after distortion.
   1.336 +    float     DistortionK[4];
   1.337 +
   1.338 +    float     ChromaAbCorrection[4];
   1.339 +
   1.340 +    // Desktop coordinate position of the screen (can be negative; may not be present on all platforms)
   1.341 +    int       DesktopX, DesktopY;
   1.342 +    
   1.343 +    // Windows:
   1.344 +    // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC.
   1.345 +    char      DisplayDeviceName[32];
   1.346 +    
   1.347 +    // MacOS:
   1.348 +    long      DisplayId;
   1.349 +
   1.350 +
   1.351 +    HMDInfo()
   1.352 +        : DeviceInfo(Device_HMD),          
   1.353 +          HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
   1.354 +          VScreenCenter(0), EyeToScreenDistance(0),
   1.355 +          LensSeparationDistance(0), InterpupillaryDistance(0),
   1.356 +          DesktopX(0), DesktopY(0), DisplayId(0)
   1.357 +    {
   1.358 +        DisplayDeviceName[0] = 0;
   1.359 +        memset(DistortionK, 0, sizeof(DistortionK));
   1.360 +        DistortionK[0] = 1;
   1.361 +        ChromaAbCorrection[0] = ChromaAbCorrection[2] = 1;
   1.362 +        ChromaAbCorrection[1] = ChromaAbCorrection[3] = 0;
   1.363 +    }
   1.364 +
   1.365 +    // Operator = copies local fields only (base class must be correct already)
   1.366 +    void operator = (const HMDInfo& src)
   1.367 +    {        
   1.368 +        HResolution             = src.HResolution;
   1.369 +        VResolution             = src.VResolution;
   1.370 +        HScreenSize             = src.HScreenSize;
   1.371 +        VScreenSize             = src.VScreenSize;
   1.372 +        VScreenCenter           = src.VScreenCenter;
   1.373 +        EyeToScreenDistance     = src.EyeToScreenDistance;
   1.374 +        LensSeparationDistance  = src.LensSeparationDistance;
   1.375 +        InterpupillaryDistance  = src.InterpupillaryDistance;
   1.376 +        DistortionK[0]          = src.DistortionK[0];
   1.377 +        DistortionK[1]          = src.DistortionK[1];
   1.378 +        DistortionK[2]          = src.DistortionK[2];
   1.379 +        DistortionK[3]          = src.DistortionK[3];
   1.380 +        ChromaAbCorrection[0]   = src.ChromaAbCorrection[0];
   1.381 +        ChromaAbCorrection[1]   = src.ChromaAbCorrection[1];
   1.382 +        ChromaAbCorrection[2]   = src.ChromaAbCorrection[2];
   1.383 +        ChromaAbCorrection[3]   = src.ChromaAbCorrection[3];
   1.384 +        DesktopX                = src.DesktopX;
   1.385 +        DesktopY                = src.DesktopY;
   1.386 +        memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName));
   1.387 +        DisplayId               = src.DisplayId;
   1.388 +    }
   1.389 +
   1.390 +    bool IsSameDisplay(const HMDInfo& o) const
   1.391 +    {
   1.392 +        return DisplayId == o.DisplayId &&
   1.393 +               String::CompareNoCase(DisplayDeviceName, 
   1.394 +                                     o.DisplayDeviceName) == 0;
   1.395 +    }
   1.396 +
   1.397 +};
   1.398 +
   1.399 +
   1.400 +// HMDDevice represents an Oculus HMD device unit. An instance of this class
   1.401 +// is typically created from the DeviceManager.
   1.402 +//  After HMD device is created, we its sensor data can be obtained by 
   1.403 +//  first creating a Sensor object and then.
   1.404 +
   1.405 +//  TBD:
   1.406 +//  - Configure Sensor
   1.407 +//  - APIs to set On-Screen message, other states?
   1.408 +
   1.409 +class HMDDevice : public DeviceBase
   1.410 +{
   1.411 +public:
   1.412 +    HMDDevice()
   1.413 +    { }
   1.414 +
   1.415 +    // Static constant for this device type, used in template cast type checks.
   1.416 +    enum { EnumDeviceType = Device_HMD };
   1.417 +
   1.418 +    virtual DeviceType      GetType() const   { return Device_HMD; }  
   1.419 +
   1.420 +    // Creates a sensor associated with this HMD.
   1.421 +    virtual SensorDevice*   GetSensor() = 0;
   1.422 +
   1.423 +
   1.424 +    // Requests the currently used profile. This profile affects the
   1.425 +    // settings reported by HMDInfo. 
   1.426 +    virtual Profile*    GetProfile() const = 0;
   1.427 +    // Obtains the currently used profile name. This is initialized to the default
   1.428 +    // profile name, if any; it can then be changed per-device by SetProfileName.    
   1.429 +    virtual const char* GetProfileName() const = 0;
   1.430 +    // Sets the profile user name, changing the data returned by GetProfileInfo.
   1.431 +    virtual bool        SetProfileName(const char* name) = 0;
   1.432 +
   1.433 +
   1.434 +    // Disconnects from real HMD device. This HMDDevice remains as 'fake' HMD.
   1.435 +    // SensorDevice ptr is used to restore the 'fake' HMD (can be NULL).
   1.436 +    HMDDevice*  Disconnect(SensorDevice*);
   1.437 +    
   1.438 +    // Returns 'true' if HMD device is a 'fake' HMD (was created this way or 
   1.439 +    // 'Disconnect' method was called).
   1.440 +    bool        IsDisconnected() const;
   1.441 +};
   1.442 +
   1.443 +
   1.444 +//-------------------------------------------------------------------------------------
   1.445 +// ***** SensorRange & SensorInfo
   1.446 +
   1.447 +// SensorRange specifies maximum value ranges that SensorDevice hardware is configured
   1.448 +// to detect. Although this range doesn't affect the scale of MessageBodyFrame values,
   1.449 +// physical motions whose positive or negative magnitude is outside the specified range
   1.450 +// may get clamped or misreported. Setting lower values may result in higher precision
   1.451 +// tracking.
   1.452 +struct SensorRange
   1.453 +{
   1.454 +    SensorRange(float maxAcceleration = 0.0f, float maxRotationRate = 0.0f,
   1.455 +                float maxMagneticField = 0.0f)
   1.456 +        : MaxAcceleration(maxAcceleration), MaxRotationRate(maxRotationRate),
   1.457 +          MaxMagneticField(maxMagneticField)
   1.458 +    { }
   1.459 +
   1.460 +    // Maximum detected acceleration in m/s^2. Up to 8*G equivalent support guaranteed,
   1.461 +    // where G is ~9.81 m/s^2.
   1.462 +    // Oculus DK1 HW has thresholds near: 2, 4 (default), 8, 16 G.
   1.463 +    float   MaxAcceleration;  
   1.464 +    // Maximum detected angular velocity in rad/s. Up to 8*Pi support guaranteed.
   1.465 +    // Oculus DK1 HW thresholds near: 1, 2, 4, 8 Pi (default).
   1.466 +    float   MaxRotationRate;
   1.467 +    // Maximum detectable Magnetic field strength in Gauss. Up to 2.5 Gauss support guaranteed.
   1.468 +    // Oculus DK1 HW thresholds near: 0.88, 1.3, 1.9, 2.5 gauss.
   1.469 +    float   MaxMagneticField;
   1.470 +};
   1.471 +
   1.472 +// SensorInfo describes capabilities of the sensor device.
   1.473 +class SensorInfo : public DeviceInfo
   1.474 +{
   1.475 +public:
   1.476 +    SensorInfo() : DeviceInfo(Device_Sensor), VendorId(0), ProductId(0)
   1.477 +    {
   1.478 +        SerialNumber[0] = 0;
   1.479 +    }
   1.480 +
   1.481 +    // HID Vendor and ProductId of the device.
   1.482 +    UInt16      VendorId;
   1.483 +    UInt16      ProductId;
   1.484 +    // MaxRanges report maximum sensor range values supported by HW.
   1.485 +    SensorRange MaxRanges;
   1.486 +    // Sensor (and display) serial number.
   1.487 +    char        SerialNumber[20];
   1.488 +
   1.489 +private:
   1.490 +    void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
   1.491 +};
   1.492 +
   1.493 +
   1.494 +//-------------------------------------------------------------------------------------
   1.495 +// ***** SensorDevice
   1.496 +
   1.497 +// SensorDevice is an interface to sensor data.
   1.498 +// Install a MessageHandler of SensorDevice instance to receive MessageBodyFrame
   1.499 +// notifications.
   1.500 +//
   1.501 +// TBD: Add Polling API? More HID interfaces?
   1.502 +
   1.503 +class SensorDevice : public HIDDeviceBase, public DeviceBase
   1.504 +{
   1.505 +public:
   1.506 +    SensorDevice() 
   1.507 +    { }
   1.508 +
   1.509 +    // Static constant for this device type, used in template cast type checks.
   1.510 +    enum { EnumDeviceType = Device_Sensor };
   1.511 +
   1.512 +    virtual DeviceType GetType() const   { return Device_Sensor; }
   1.513 +
   1.514 +    
   1.515 +    // CoordinateFrame defines whether messages come in the coordinate frame
   1.516 +    // of the sensor device or HMD, which has a different internal sensor.
   1.517 +    // Sensors obtained form the HMD will automatically use HMD coordinates.
   1.518 +    enum CoordinateFrame
   1.519 +    {
   1.520 +        Coord_Sensor = 0,
   1.521 +        Coord_HMD    = 1
   1.522 +    };
   1.523 +
   1.524 +    virtual void            SetCoordinateFrame(CoordinateFrame coordframe) = 0;
   1.525 +    virtual CoordinateFrame GetCoordinateFrame() const = 0;
   1.526 +
   1.527 +    // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). 
   1.528 +    // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be 
   1.529 +    // called twice or thrice at the same 'tick'. 
   1.530 +    // If the rate is  < 333 then the OnMessage / MessageBodyFrame will be called three
   1.531 +    // times for each 'tick': the first call will contain averaged values, the second
   1.532 +    // and third calls will provide with most recent two recorded samples.
   1.533 +    virtual void        SetReportRate(unsigned rateHz) = 0;
   1.534 +    // Returns currently set report rate, in Hz. If 0 - error occurred.
   1.535 +    // Note, this value may be different from the one provided for SetReportRate. The return
   1.536 +    // value will contain the actual rate.
   1.537 +    virtual unsigned    GetReportRate() const = 0;
   1.538 +
   1.539 +    // Sets maximum range settings for the sensor described by SensorRange.    
   1.540 +    // The function will fail if you try to pass values outside Maximum supported
   1.541 +    // by the HW, as described by SensorInfo.
   1.542 +    // Pass waitFlag == true to wait for command completion. For waitFlag == true,
   1.543 +    // returns true if the range was applied successfully (no HW error).
   1.544 +    // For waitFlag = false, return 'true' means that command was enqueued successfully.
   1.545 +    virtual bool       SetRange(const SensorRange& range, bool waitFlag = false) = 0;
   1.546 +
   1.547 +    // Return the current sensor range settings for the device. These may not exactly
   1.548 +    // match the values applied through SetRange.
   1.549 +    virtual void       GetRange(SensorRange* range) const = 0;
   1.550 +};
   1.551 +
   1.552 +//-------------------------------------------------------------------------------------
   1.553 +// ***** LatencyTestConfiguration
   1.554 +// LatencyTestConfiguration specifies configuration information for the Oculus Latency Tester device.
   1.555 +struct LatencyTestConfiguration
   1.556 +{
   1.557 +    LatencyTestConfiguration(const Color& threshold, bool sendSamples = false)
   1.558 +        : Threshold(threshold), SendSamples(sendSamples) 
   1.559 +    {
   1.560 +    }
   1.561 +
   1.562 +    // The color threshold for triggering a detected display change.
   1.563 +    Color    Threshold;
   1.564 +    // Flag specifying whether we wish to receive a stream of color values from the sensor.
   1.565 +    bool        SendSamples;
   1.566 +};
   1.567 +
   1.568 +//-------------------------------------------------------------------------------------
   1.569 +// ***** LatencyTestDisplay
   1.570 +// LatencyTestDisplay sets the mode and contents of the Latency Tester LED display.
   1.571 +// See the 'Latency Tester Specification' document for more details.
   1.572 +struct LatencyTestDisplay
   1.573 +{
   1.574 +    LatencyTestDisplay(UByte mode, UInt32 value)
   1.575 +        : Mode(mode), Value(value)
   1.576 +    {
   1.577 +    }
   1.578 +
   1.579 +    UByte       Mode;       // The display mode that we wish to select.
   1.580 +    UInt32      Value;      // The value to display.
   1.581 +};
   1.582 +
   1.583 +//-------------------------------------------------------------------------------------
   1.584 +// ***** LatencyTestDevice
   1.585 +
   1.586 +// LatencyTestDevice provides an interface to the Oculus Latency Tester which is used to test 'motion to photon' latency.
   1.587 +class LatencyTestDevice : public HIDDeviceBase, public DeviceBase
   1.588 +{
   1.589 +public:
   1.590 +    LatencyTestDevice()
   1.591 +    { }
   1.592 +
   1.593 +    // Static constant for this device type, used in template cast type checks.
   1.594 +    enum { EnumDeviceType = Device_LatencyTester };
   1.595 +
   1.596 +    virtual DeviceType GetType() const { return Device_LatencyTester; }
   1.597 +
   1.598 +    // Specifies configuration information including the threshold for triggering a detected color change,
   1.599 +    // and a flag to enable a stream of sensor values (typically used for debugging).
   1.600 +    virtual bool SetConfiguration(const LatencyTestConfiguration& configuration, bool waitFlag = false) = 0;
   1.601 +
   1.602 +    // Get configuration information from device.
   1.603 +    virtual bool GetConfiguration(LatencyTestConfiguration* configuration) = 0;
   1.604 +
   1.605 +    // Used to calibrate the latency tester at the start of a test. Display the specified color on the screen
   1.606 +    // beneath the latency tester and then call this method. Calibration information is lost
   1.607 +    // when power is removed from the device.
   1.608 +    virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false) = 0;
   1.609 +
   1.610 +    // Triggers the start of a measurement. This starts the millisecond timer on the device and 
   1.611 +    // causes it to respond with the 'MessageLatencyTestStarted' message.
   1.612 +    virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false) = 0;
   1.613 +
   1.614 +    // Used to set the value displayed on the LED display panel.
   1.615 +    virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false) = 0;
   1.616 +
   1.617 +    virtual DeviceBase* GetDevice() { return this; }
   1.618 +};
   1.619 +
   1.620 +} // namespace OVR
   1.621 +
   1.622 +#endif