nuclear@1: /************************************************************************************ nuclear@1: nuclear@1: Filename : OVR_SensorImpl.h nuclear@1: Content : Sensor device specific implementation. nuclear@1: Created : March 7, 2013 nuclear@1: Authors : Lee Cooper nuclear@1: nuclear@1: Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. nuclear@1: nuclear@1: Use of this software is subject to the terms of the Oculus license nuclear@1: agreement provided at the time of installation or download, or which nuclear@1: otherwise accompanies this software in either electronic or hard copy form. nuclear@1: nuclear@1: *************************************************************************************/ nuclear@1: nuclear@1: #ifndef OVR_SensorImpl_h nuclear@1: #define OVR_SensorImpl_h nuclear@1: nuclear@1: #include "OVR_HIDDeviceImpl.h" nuclear@1: nuclear@1: namespace OVR { nuclear@1: nuclear@1: struct TrackerMessage; nuclear@1: class ExternalVisitor; nuclear@1: nuclear@1: //------------------------------------------------------------------------------------- nuclear@1: // SensorDeviceFactory enumerates Oculus Sensor devices. nuclear@1: class SensorDeviceFactory : public DeviceFactory nuclear@1: { nuclear@1: public: nuclear@1: static SensorDeviceFactory Instance; nuclear@1: nuclear@1: // Enumerates devices, creating and destroying relevant objects in manager. nuclear@1: virtual void EnumerateDevices(EnumerateVisitor& visitor); nuclear@1: nuclear@1: virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const; nuclear@1: virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc); nuclear@1: protected: nuclear@1: DeviceManager* getManager() const { return (DeviceManager*) pManager; } nuclear@1: }; nuclear@1: nuclear@1: nuclear@1: // Describes a single a Oculus Sensor device and supports creating its instance. nuclear@1: class SensorDeviceCreateDesc : public HIDDeviceCreateDesc nuclear@1: { nuclear@1: public: nuclear@1: SensorDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc) nuclear@1: : HIDDeviceCreateDesc(factory, Device_Sensor, hidDesc) { } nuclear@1: nuclear@1: virtual DeviceCreateDesc* Clone() const nuclear@1: { nuclear@1: return new SensorDeviceCreateDesc(*this); nuclear@1: } nuclear@1: nuclear@1: virtual DeviceBase* NewDeviceInstance(); nuclear@1: nuclear@1: virtual MatchResult MatchDevice(const DeviceCreateDesc& other, nuclear@1: DeviceCreateDesc**) const nuclear@1: { nuclear@1: if ((other.Type == Device_Sensor) && (pFactory == other.pFactory)) nuclear@1: { nuclear@1: const SensorDeviceCreateDesc& s2 = (const SensorDeviceCreateDesc&) other; nuclear@1: if (MatchHIDDevice(s2.HIDDesc)) nuclear@1: return Match_Found; nuclear@1: } nuclear@1: return Match_None; nuclear@1: } nuclear@1: nuclear@1: virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const nuclear@1: { nuclear@1: // should paths comparison be case insensitive? nuclear@1: return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) && nuclear@1: (HIDDesc.SerialNumber == hidDesc.SerialNumber)); nuclear@1: } nuclear@1: nuclear@1: virtual bool GetDeviceInfo(DeviceInfo* info) const; nuclear@1: }; nuclear@1: nuclear@1: nuclear@1: //------------------------------------------------------------------------------------- nuclear@1: // ***** OVR::SensorDisplayInfoImpl nuclear@1: nuclear@1: // DisplayInfo obtained from sensor; these values are used to report distortion nuclear@1: // settings and other coefficients. nuclear@1: // Older SensorDisplayInfo will have all zeros, causing the library to apply hard-coded defaults. nuclear@1: // Currently, only resolutions and sizes are used. nuclear@1: struct SensorDisplayInfoImpl nuclear@1: { nuclear@1: enum { PacketSize = 56 }; nuclear@1: UByte Buffer[PacketSize]; nuclear@1: nuclear@1: enum nuclear@1: { nuclear@1: Mask_BaseFmt = 0x0f, nuclear@1: Mask_OptionFmts = 0xf0, nuclear@1: Base_None = 0, nuclear@1: Base_ScreenOnly = 1, nuclear@1: Base_Distortion = 2, nuclear@1: }; nuclear@1: nuclear@1: UInt16 CommandId; nuclear@1: UByte DistortionType; nuclear@1: UInt16 HResolution, VResolution; nuclear@1: float HScreenSize, VScreenSize; nuclear@1: float VCenter; nuclear@1: float LensSeparation; nuclear@1: float EyeToScreenDistance[2]; nuclear@1: float DistortionK[6]; nuclear@1: nuclear@1: SensorDisplayInfoImpl(); nuclear@1: nuclear@1: void Unpack(); nuclear@1: }; nuclear@1: nuclear@1: nuclear@1: //------------------------------------------------------------------------------------- nuclear@1: // ***** OVR::SensorDeviceImpl nuclear@1: nuclear@1: // Oculus Sensor interface. nuclear@1: nuclear@1: class SensorDeviceImpl : public HIDDeviceImpl nuclear@1: { nuclear@1: public: nuclear@1: SensorDeviceImpl(SensorDeviceCreateDesc* createDesc); nuclear@1: ~SensorDeviceImpl(); nuclear@1: nuclear@1: nuclear@1: // DeviceCommaon interface nuclear@1: virtual bool Initialize(DeviceBase* parent); nuclear@1: virtual void Shutdown(); nuclear@1: nuclear@1: virtual void SetMessageHandler(MessageHandler* handler); nuclear@1: nuclear@1: // HIDDevice::Notifier interface. nuclear@1: virtual void OnInputReport(UByte* pData, UInt32 length); nuclear@1: virtual UInt64 OnTicks(UInt64 ticksMks); nuclear@1: nuclear@1: // HMD-Mounted sensor has a different coordinate frame. nuclear@1: virtual void SetCoordinateFrame(CoordinateFrame coordframe); nuclear@1: virtual CoordinateFrame GetCoordinateFrame() const; nuclear@1: nuclear@1: // SensorDevice interface nuclear@1: virtual bool SetRange(const SensorRange& range, bool waitFlag); nuclear@1: virtual void GetRange(SensorRange* range) const; nuclear@1: nuclear@1: // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). nuclear@1: // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be nuclear@1: // called twice or thrice at the same 'tick'. nuclear@1: // If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three nuclear@1: // times for each 'tick': the first call will contain averaged values, the second nuclear@1: // and third calls will provide with most recent two recorded samples. nuclear@1: virtual void SetReportRate(unsigned rateHz); nuclear@1: // Returns currently set report rate, in Hz. If 0 - error occurred. nuclear@1: // Note, this value may be different from the one provided for SetReportRate. The return nuclear@1: // value will contain the actual rate. nuclear@1: virtual unsigned GetReportRate() const; nuclear@1: nuclear@1: // Hack to create HMD device from sensor display info. nuclear@1: static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo, nuclear@1: DeviceFactory::EnumerateVisitor& visitor); nuclear@1: protected: nuclear@1: nuclear@1: void openDevice(); nuclear@1: void closeDeviceOnError(); nuclear@1: nuclear@1: Void setCoordinateFrame(CoordinateFrame coordframe); nuclear@1: bool setRange(const SensorRange& range); nuclear@1: nuclear@1: Void setReportRate(unsigned rateHz); nuclear@1: nuclear@1: // Called for decoded messages nuclear@1: void onTrackerMessage(TrackerMessage* message); nuclear@1: nuclear@1: // Helpers to reduce casting. nuclear@1: /* nuclear@1: SensorDeviceCreateDesc* getCreateDesc() const nuclear@1: { return (SensorDeviceCreateDesc*)pCreateDesc.GetPtr(); } nuclear@1: nuclear@1: HIDDeviceDesc* getHIDDesc() const nuclear@1: { return &getCreateDesc()->HIDDesc; } nuclear@1: */ nuclear@1: nuclear@1: // Set if the sensor is located on the HMD. nuclear@1: // Older prototype firmware doesn't support changing HW coordinates, nuclear@1: // so we track its state. nuclear@1: CoordinateFrame Coordinates; nuclear@1: CoordinateFrame HWCoordinates; nuclear@1: UInt64 NextKeepAliveTicks; nuclear@1: nuclear@1: bool SequenceValid; nuclear@1: SInt16 LastTimestamp; nuclear@1: UByte LastSampleCount; nuclear@1: float LastTemperature; nuclear@1: Vector3f LastAcceleration; nuclear@1: Vector3f LastRotationRate; nuclear@1: Vector3f LastMagneticField; nuclear@1: nuclear@1: // Current sensor range obtained from device. nuclear@1: SensorRange MaxValidRange; nuclear@1: SensorRange CurrentRange; nuclear@1: nuclear@1: UInt16 OldCommandId; nuclear@1: }; nuclear@1: nuclear@1: nuclear@1: } // namespace OVR nuclear@1: nuclear@1: #endif // OVR_SensorImpl_h