diff options
Diffstat (limited to 'LibOVR/Src')
-rw-r--r-- | LibOVR/Src/Kernel/OVR_Timer.cpp | 2 | ||||
-rw-r--r-- | LibOVR/Src/OVR_HIDDevice.h | 2 | ||||
-rw-r--r-- | LibOVR/Src/OVR_HIDDeviceImpl.h | 13 | ||||
-rw-r--r-- | LibOVR/Src/OVR_LatencyTestImpl.cpp | 68 | ||||
-rw-r--r-- | LibOVR/Src/OVR_LatencyTestImpl.h | 8 | ||||
-rw-r--r-- | LibOVR/Src/OVR_Linux_HIDDevice.cpp | 109 | ||||
-rw-r--r-- | LibOVR/Src/OVR_Linux_HMDDevice.cpp | 92 | ||||
-rw-r--r-- | LibOVR/Src/OVR_OSX_HIDDevice.cpp | 280 | ||||
-rw-r--r-- | LibOVR/Src/OVR_OSX_HIDDevice.h | 2 | ||||
-rw-r--r-- | LibOVR/Src/OVR_OSX_HMDDevice.h | 2 | ||||
-rw-r--r-- | LibOVR/Src/OVR_SensorImpl.cpp | 71 | ||||
-rw-r--r-- | LibOVR/Src/OVR_SensorImpl.h | 30 | ||||
-rw-r--r-- | LibOVR/Src/OVR_Win32_HIDDevice.cpp | 3 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_MagCalibration.cpp | 227 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_MagCalibration.h | 138 |
15 files changed, 357 insertions, 690 deletions
diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp index 682d621..599c614 100644 --- a/LibOVR/Src/Kernel/OVR_Timer.cpp +++ b/LibOVR/Src/Kernel/OVR_Timer.cpp @@ -17,11 +17,13 @@ otherwise accompanies this software in either electronic or hard copy form. #if defined (OVR_OS_WIN32) #include <windows.h> +#pragma comment(lib, "winmm.lib") #else #include <sys/time.h> #endif + namespace OVR { //----------------------------------------------------------------------------------- diff --git a/LibOVR/Src/OVR_HIDDevice.h b/LibOVR/Src/OVR_HIDDevice.h index 512b96a..634f88f 100644 --- a/LibOVR/Src/OVR_HIDDevice.h +++ b/LibOVR/Src/OVR_HIDDevice.h @@ -115,7 +115,7 @@ public: class HIDHandler { public: - virtual void OnInputReport(UByte* pData, UInt32 length) + virtual void OnInputReport(const UByte* pData, UInt32 length) { OVR_UNUSED2(pData, length); } virtual UInt64 OnTicks(UInt64 ticksMks) diff --git a/LibOVR/Src/OVR_HIDDeviceImpl.h b/LibOVR/Src/OVR_HIDDeviceImpl.h index f9d0922..aac41ee 100644 --- a/LibOVR/Src/OVR_HIDDeviceImpl.h +++ b/LibOVR/Src/OVR_HIDDeviceImpl.h @@ -18,6 +18,7 @@ otherwise accompanies this software in either electronic or hard copy form. //#include "OVR_Device.h" #include "OVR_DeviceImpl.h" +#include "OVR_HIDDeviceImpl.h" namespace OVR { @@ -45,7 +46,7 @@ class HIDDeviceImpl : public DeviceImpl<B>, public HIDDevice::HIDHandler { public: HIDDeviceImpl(HIDDeviceCreateDesc* createDesc, DeviceBase* parent) - : DeviceImpl<B>(createDesc, parent) + : DeviceImpl<B>(createDesc, parent) { } @@ -82,11 +83,11 @@ public: case Message_DeviceAdded: manager->CallOnDeviceAdded(this->pCreateDesc); break; - + case Message_DeviceRemoved: manager->CallOnDeviceRemoved(this->pCreateDesc); break; - + default:; } } @@ -114,7 +115,7 @@ public: } virtual void Shutdown() - { + { InternalDevice->SetHandler(NULL); // Remove the handler, if any. @@ -148,7 +149,7 @@ public: }; bool SetFeatureReport(UByte* data, UInt32 length) - { + { WriteData writeData(data, length); // Push call with wait. @@ -167,7 +168,7 @@ public: } bool GetFeatureReport(UByte* data, UInt32 length) - { + { bool result = false; ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); diff --git a/LibOVR/Src/OVR_LatencyTestImpl.cpp b/LibOVR/Src/OVR_LatencyTestImpl.cpp index 4ab28e5..072a5f5 100644 --- a/LibOVR/Src/OVR_LatencyTestImpl.cpp +++ b/LibOVR/Src/OVR_LatencyTestImpl.cpp @@ -20,7 +20,7 @@ namespace OVR { //------------------------------------------------------------------------------------- // ***** Oculus Latency Tester specific packet data structures -enum { +enum { LatencyTester_VendorId = Oculus_VendorId, LatencyTester_ProductId = 0x0101, }; @@ -77,7 +77,7 @@ struct LatencyTestSamples SampleCount = buffer[1]; Timestamp = DecodeUInt16(buffer + 2); - + for (UByte i = 0; i < SampleCount; i++) { UnpackSamples(buffer + 4 + (3 * i), &Samples[i].Value[0], &Samples[i].Value[1], &Samples[i].Value[2]); @@ -93,7 +93,7 @@ struct LatencyTestSamplesMessage LatencyTestSamples Samples; }; -bool DecodeLatencyTestSamplesMessage(LatencyTestSamplesMessage* message, UByte* buffer, int size) +bool DecodeLatencyTestSamplesMessage(LatencyTestSamplesMessage* message, const UByte* buffer, int size) { memset(message, 0, sizeof(LatencyTestSamplesMessage)); @@ -146,7 +146,7 @@ struct LatencyTestColorDetectedMessage LatencyTestColorDetected ColorDetected; }; -bool DecodeLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message, UByte* buffer, int size) +bool DecodeLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message, const UByte* buffer, int size) { memset(message, 0, sizeof(LatencyTestColorDetectedMessage)); @@ -195,7 +195,7 @@ struct LatencyTestStartedMessage LatencyTestStarted TestStarted; }; -bool DecodeLatencyTestStartedMessage(LatencyTestStartedMessage* message, UByte* buffer, int size) +bool DecodeLatencyTestStartedMessage(LatencyTestStartedMessage* message, const UByte* buffer, int size) { memset(message, 0, sizeof(LatencyTestStartedMessage)); @@ -242,7 +242,7 @@ struct LatencyTestButtonMessage LatencyTestButton Button; }; -bool DecodeLatencyTestButtonMessage(LatencyTestButtonMessage* message, UByte* buffer, int size) +bool DecodeLatencyTestButtonMessage(LatencyTestButtonMessage* message, const UByte* buffer, int size) { memset(message, 0, sizeof(LatencyTestButtonMessage)); @@ -303,7 +303,7 @@ struct LatencyTestCalibrateImpl UByte Buffer[PacketSize]; Color CalibrationColor; - + LatencyTestCalibrateImpl(const Color& calibrationColor) : CalibrationColor(calibrationColor) { @@ -407,7 +407,7 @@ void LatencyTestDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) void operator = (const LatencyTestEnumerator&) { } DeviceFactory* pFactory; - EnumerateVisitor& ExternalVisitor; + EnumerateVisitor& ExternalVisitor; public: LatencyTestEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor) : pFactory(factory), ExternalVisitor(externalVisitor) { } @@ -432,10 +432,10 @@ void LatencyTestDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) bool LatencyTestDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const { - return ((vendorId == LatencyTester_VendorId) && (productId == LatencyTester_ProductId)); + return ((vendorId == LatencyTester_VendorId) && (productId == LatencyTester_ProductId)); } -bool LatencyTestDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr, +bool LatencyTestDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc) { if (MatchVendorProduct(desc.VendorId, desc.ProductId)) @@ -486,7 +486,7 @@ LatencyTestDeviceImpl::LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc* create LatencyTestDeviceImpl::~LatencyTestDeviceImpl() { // Check that Shutdown() was called. - OVR_ASSERT(!pCreateDesc->pDevice); + OVR_ASSERT(!pCreateDesc->pDevice); } // Internal creation APIs. @@ -502,20 +502,20 @@ bool LatencyTestDeviceImpl::Initialize(DeviceBase* parent) } void LatencyTestDeviceImpl::Shutdown() -{ +{ HIDDeviceImpl<OVR::LatencyTestDevice>::Shutdown(); LogText("OVR::LatencyTestDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr()); } -void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length) +void LatencyTestDeviceImpl::OnInputReport(const UByte* pData, UInt32 length) { - + bool processed = false; if (!processed) { - LatencyTestSamplesMessage message; - if (DecodeLatencyTestSamplesMessage(&message, pData, length)) + LatencyTestSamplesMessage message; + if (DecodeLatencyTestSamplesMessage(&message, pData, length)) { processed = true; onLatencyTestSamplesMessage(&message); @@ -524,8 +524,8 @@ void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length) if (!processed) { - LatencyTestColorDetectedMessage message; - if (DecodeLatencyTestColorDetectedMessage(&message, pData, length)) + LatencyTestColorDetectedMessage message; + if (DecodeLatencyTestColorDetectedMessage(&message, pData, length)) { processed = true; onLatencyTestColorDetectedMessage(&message); @@ -534,8 +534,8 @@ void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length) if (!processed) { - LatencyTestStartedMessage message; - if (DecodeLatencyTestStartedMessage(&message, pData, length)) + LatencyTestStartedMessage message; + if (DecodeLatencyTestStartedMessage(&message, pData, length)) { processed = true; onLatencyTestStartedMessage(&message); @@ -544,8 +544,8 @@ void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length) if (!processed) { - LatencyTestButtonMessage message; - if (DecodeLatencyTestButtonMessage(&message, pData, length)) + LatencyTestButtonMessage message; + if (DecodeLatencyTestButtonMessage(&message, pData, length)) { processed = true; onLatencyTestButtonMessage(&message); @@ -554,7 +554,7 @@ void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length) } bool LatencyTestDeviceImpl::SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag) -{ +{ bool result = false; ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue(); @@ -565,9 +565,9 @@ bool LatencyTestDeviceImpl::SetConfiguration(const OVR::LatencyTestConfiguration return queue->PushCall(this, &LatencyTestDeviceImpl::setConfiguration, configuration); } - if (!queue->PushCallAndWaitResult( this, + if (!queue->PushCallAndWaitResult( this, &LatencyTestDeviceImpl::setConfiguration, - &result, + &result, configuration)) { return false; @@ -586,7 +586,7 @@ bool LatencyTestDeviceImpl::setConfiguration(const OVR::LatencyTestConfiguration } bool LatencyTestDeviceImpl::GetConfiguration(OVR::LatencyTestConfiguration* configuration) -{ +{ bool result = false; ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); @@ -619,9 +619,9 @@ bool LatencyTestDeviceImpl::SetCalibrate(const Color& calibrationColor, bool wai return queue->PushCall(this, &LatencyTestDeviceImpl::setCalibrate, calibrationColor); } - if (!queue->PushCallAndWaitResult( this, + if (!queue->PushCallAndWaitResult( this, &LatencyTestDeviceImpl::setCalibrate, - &result, + &result, calibrationColor)) { return false; @@ -646,9 +646,9 @@ bool LatencyTestDeviceImpl::SetStartTest(const Color& targetColor, bool waitFlag return queue->PushCall(this, &LatencyTestDeviceImpl::setStartTest, targetColor); } - if (!queue->PushCallAndWaitResult( this, + if (!queue->PushCallAndWaitResult( this, &LatencyTestDeviceImpl::setStartTest, - &result, + &result, targetColor)) { return false; @@ -673,9 +673,9 @@ bool LatencyTestDeviceImpl::SetDisplay(const OVR::LatencyTestDisplay& display, b return queue->PushCall(this, &LatencyTestDeviceImpl::setDisplay, display); } - if (!queue->PushCallAndWaitResult( this, + if (!queue->PushCallAndWaitResult( this, &LatencyTestDeviceImpl::setDisplay, - &result, + &result, display)) { return false; @@ -700,12 +700,12 @@ void LatencyTestDeviceImpl::onLatencyTestSamplesMessage(LatencyTestSamplesMessag // Call OnMessage() within a lock to avoid conflicts with handlers. Lock::Locker scopeLock(HandlerRef.GetLock()); - + if (HandlerRef.GetHandler()) { MessageLatencyTestSamples samples(this); for (UByte i = 0; i < s.SampleCount; i++) - { + { samples.Samples.PushBack(Color(s.Samples[i].Value[0], s.Samples[i].Value[1], s.Samples[i].Value[2])); } diff --git a/LibOVR/Src/OVR_LatencyTestImpl.h b/LibOVR/Src/OVR_LatencyTestImpl.h index 727e36e..af1337a 100644 --- a/LibOVR/Src/OVR_LatencyTestImpl.h +++ b/LibOVR/Src/OVR_LatencyTestImpl.h @@ -39,7 +39,7 @@ public: virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc); protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } + DeviceManager* getManager() const { return (DeviceManager*) pManager; } }; @@ -49,7 +49,7 @@ class LatencyTestDeviceCreateDesc : public HIDDeviceCreateDesc public: LatencyTestDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc) : HIDDeviceCreateDesc(factory, Device_LatencyTester, hidDesc) { } - + virtual DeviceCreateDesc* Clone() const { return new LatencyTestDeviceCreateDesc(*this); @@ -61,7 +61,7 @@ public: DeviceCreateDesc**) const { if ((other.Type == Device_LatencyTester) && (pFactory == other.pFactory)) - { + { const LatencyTestDeviceCreateDesc& s2 = (const LatencyTestDeviceCreateDesc&) other; if (MatchHIDDevice(s2.HIDDesc)) return Match_Found; @@ -95,7 +95,7 @@ public: virtual void Shutdown(); // DeviceManagerThread::Notifier interface. - virtual void OnInputReport(UByte* pData, UInt32 length); + virtual void OnInputReport(const UByte* pData, UInt32 length); // LatencyTesterDevice interface virtual bool SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag = false); diff --git a/LibOVR/Src/OVR_Linux_HIDDevice.cpp b/LibOVR/Src/OVR_Linux_HIDDevice.cpp index c07c1ad..21d8ee5 100644 --- a/LibOVR/Src/OVR_Linux_HIDDevice.cpp +++ b/LibOVR/Src/OVR_Linux_HIDDevice.cpp @@ -3,9 +3,9 @@ Filename : OVR_Linux_HIDDevice.cpp Content : Linux HID device implementation. Created : February 26, 2013 Authors : Lee Cooper - + Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. - + Use of this software is subject to the terms of the Oculus license agreement provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. @@ -23,7 +23,7 @@ otherwise accompanies this software in either electronic or hard copy form. namespace OVR { namespace Linux { static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5; - + //------------------------------------------------------------------------------------- // **** Linux::DeviceManager //----------------------------------------------------------------------------- @@ -47,27 +47,34 @@ bool HIDDeviceManager::initializeManager() return true; } + OVR_DEBUG_LOG(("Attempting to initialize the HID Device Manager")); // Create a udev_monitor handle to watch for device changes (hot-plug detection) HIDMonitor = udev_monitor_new_from_netlink(UdevInstance, "udev"); if (HIDMonitor == NULL) { + LogError("Unable to create udev monitor"); return false; } - udev_monitor_filter_add_match_subsystem_devtype(HIDMonitor, "hidraw", NULL); // filter for hidraw only - - int err = udev_monitor_enable_receiving(HIDMonitor); + int err = udev_monitor_filter_add_match_subsystem_devtype(HIDMonitor, "hidraw", NULL); // filter for hidraw only + if (err) { + LogError("Unable to add hidraw filter %d", err); + } + + err = udev_monitor_enable_receiving(HIDMonitor); if (err) { + LogError("Unable to enable monitor receiving %d", err); udev_monitor_unref(HIDMonitor); HIDMonitor = NULL; return false; } - - // Get the file descriptor (fd) for the monitor. + + // Get the file descriptor (fd) for the monitor. HIDMonHandle = udev_monitor_get_fd(HIDMonitor); if (HIDMonHandle < 0) { + LogError("Unable to open monitor descriptor"); udev_monitor_unref(HIDMonitor); HIDMonitor = NULL; return false; @@ -77,6 +84,7 @@ bool HIDDeviceManager::initializeManager() // Add the handle to the polling list if (!DevManager->pThread->AddSelectFd(this, HIDMonHandle)) { + LogError("Failed to add udev monitor fd to select list"); close(HIDMonHandle); HIDMonHandle = -1; @@ -116,7 +124,7 @@ void HIDDeviceManager::Shutdown() } udev_unref(UdevInstance); // release the library - + LogText("OVR::Linux::HIDDeviceManager - shutting down.\n"); } @@ -202,39 +210,49 @@ bool HIDDeviceManager::getStringProperty(udev_device* device, //----------------------------------------------------------------------------- bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) { - if (!initializeManager()) { return false; } - // Get a list of hid devices + OVR_DEBUG_LOG_TEXT(("Attempting to enumerate the HID devices to find the Oculus Rift\n")); + + // Get a list of hid devices udev_enumerate* devices = udev_enumerate_new(UdevInstance); - udev_enumerate_add_match_subsystem(devices, "hidraw"); - udev_enumerate_scan_devices(devices); + if (0 != udev_enumerate_add_match_subsystem(devices, "hidraw") || + 0 != udev_enumerate_scan_devices(devices)) { + LogError("Unable to enumerate/scan hidraw devices"); + return false; + } udev_list_entry* entry = udev_enumerate_get_list_entry(devices); - // Search each device for the matching vid/pid while (entry != NULL) { // Get the device file name const char* sysfs_path = udev_list_entry_get_name(entry); + + OVR_DEBUG_LOG(("Found udev path %s", sysfs_path)); udev_device* hid; // The device's HID udev node. hid = udev_device_new_from_syspath(UdevInstance, sysfs_path); const char* dev_path = udev_device_get_devnode(hid); + OVR_DEBUG_LOG(("Found udev device node %s", dev_path)); // Get the USB device + // FIXME possible descriptor leak... if this returns NULL, the old hid value is lost and never 'unrefed' hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device"); if (hid) { + OVR_DEBUG_LOG(("Found parent USB device %s", udev_device_get_devnode(hid))); HIDDeviceDesc devDesc; // Check the VID/PID for a match + OVR_DEBUG_LOG(("Matching product/vendor ID %d:%d", devDesc.VendorId, devDesc.ProductId)); if (dev_path && initVendorProductVersion(hid, &devDesc) && enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId)) { + OVR_DEBUG_LOG_TEXT(("Found Rift tracker at %s\n", dev_path)); devDesc.Path = dev_path; getFullDesc(hid, &devDesc); @@ -244,10 +262,13 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) // will fail; therefore, we just set Enumerated to 'true' and continue. if (existingDevice && existingDevice->pDevice) { + OVR_DEBUG_LOG(("Rift device already opened in Device Manager")); existingDevice->Enumerated = true; } else - { // open the device temporarily for startup communication + { + OVR_DEBUG_LOG(("Opening Rift tracker device")); + // open the device temporarily for startup communication int device_handle = open(dev_path, O_RDWR); if (device_handle >= 0) { @@ -256,6 +277,8 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) enumVisitor->Visit(device, devDesc); close(device_handle); // close the file handle + } else { + LogError("Error %d opening Rift device at %s", errno, dev_path); } } } @@ -278,7 +301,7 @@ OVR::HIDDevice* HIDDeviceManager::Open(const String& path) if (device->HIDInitialize(path)) { - device->AddRef(); + device->AddRef(); return device; } @@ -288,20 +311,20 @@ OVR::HIDDevice* HIDDeviceManager::Open(const String& path) //----------------------------------------------------------------------------- bool HIDDeviceManager::getFullDesc(udev_device* device, HIDDeviceDesc* desc) { - + if (!initVendorProductVersion(device, desc)) { return false; } - + if (!getStringProperty(device, "serial", &(desc->SerialNumber))) { return false; } - + getStringProperty(device, "manufacturer", &(desc->Manufacturer)); getStringProperty(device, "product", &(desc->Product)); - + return true; } @@ -424,7 +447,7 @@ HIDDevice::HIDDevice(HIDDeviceManager* manager) { DeviceHandle = -1; } - + //----------------------------------------------------------------------------- // This is a minimal constructor used during enumeration for us to pass // a HIDDevice to the visit function (so that it can query feature reports). @@ -451,7 +474,7 @@ bool HIDDevice::HIDInitialize(const String& path) LogText("OVR::Linux::HIDDevice - Failed to open HIDDevice: %s", hid_path); return false; } - + HIDManager->DevManager->pThread->AddTicksNotifier(this); HIDManager->AddNotificationDevice(this); @@ -460,7 +483,7 @@ bool HIDDevice::HIDInitialize(const String& path) DevDesc.Path.ToCStr(), DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(), DevDesc.SerialNumber.ToCStr()); - + return true; } @@ -490,7 +513,7 @@ bool HIDDevice::initInfo() OVR_ASSERT_LOG(false, ("Failed to get report descriptor.")); return false; } - + /* // Get report lengths. SInt32 bufferLength; @@ -505,21 +528,21 @@ bool HIDDevice::initInfo() getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength); OVR_ASSERT(getResult); FeatureReportBufferLength = (UInt16) bufferLength; - - + + if (ReadBufferSize < InputReportBufferLength) { OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); return false; } - + // Get device desc. if (!HIDManager->getFullDesc(Device, &DevDesc)) { OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device.")); return false; } - + return true; */ @@ -528,13 +551,13 @@ bool HIDDevice::initInfo() InputReportBufferLength = 62; OutputReportBufferLength = 0; FeatureReportBufferLength = 69; - + if (ReadBufferSize < InputReportBufferLength) { OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); return false; } - + return true; } @@ -575,22 +598,22 @@ bool HIDDevice::openDevice(const char* device_path) DeviceHandle = -1; return false; } - + return true; } - + //----------------------------------------------------------------------------- void HIDDevice::HIDShutdown() { HIDManager->DevManager->pThread->RemoveTicksNotifier(this); HIDManager->RemoveNotificationDevice(this); - + if (DeviceHandle >= 0) // Device may already have been closed if unplugged. { closeDevice(false); } - + LogText("OVR::Linux::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr()); } @@ -598,13 +621,13 @@ void HIDDevice::HIDShutdown() void HIDDevice::closeDevice(bool wasUnplugged) { OVR_ASSERT(DeviceHandle >= 0); - + HIDManager->DevManager->pThread->RemoveSelectFd(this, DeviceHandle); close(DeviceHandle); // close the file handle DeviceHandle = -1; - + LogText("OVR::Linux::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr()); } @@ -618,10 +641,10 @@ void HIDDevice::closeDeviceOnIOError() //----------------------------------------------------------------------------- bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) { - + if (DeviceHandle < 0) return false; - + UByte reportID = data[0]; if (reportID == 0) @@ -652,7 +675,7 @@ UInt64 HIDDevice::OnTicks(UInt64 ticksMks) { return Handler->OnTicks(ticksMks); } - + return DeviceManagerThread::Notifier::OnTicks(ticksMks); } @@ -695,7 +718,7 @@ bool HIDDevice::OnDeviceNotification(MessageType messageType, // A closed device has been re-added. Try to reopen. if (!openDevice(device_path)) { - LogError("OVR::Linux::HIDDevice - Failed to reopen a device '%s' that was re-added.\n", + LogError("OVR::Linux::HIDDevice - Failed to reopen a device '%s' that was re-added.\n", device_path); *error = true; return true; @@ -740,7 +763,7 @@ bool HIDDevice::OnDeviceNotification(MessageType messageType, //----------------------------------------------------------------------------- HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devManager) { - + if (!System::IsInitialized()) { // Use custom message, since Log is not yet installed. @@ -765,7 +788,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devMana return manager.GetPtr(); } - + } // namespace Linux //------------------------------------------------------------------------------------- @@ -775,7 +798,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devMana HIDDeviceManager* HIDDeviceManager::Create() { OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet.")); - + if (!System::IsInitialized()) { // Use custom message, since Log is not yet installed. diff --git a/LibOVR/Src/OVR_Linux_HMDDevice.cpp b/LibOVR/Src/OVR_Linux_HMDDevice.cpp index dc94851..8683541 100644 --- a/LibOVR/Src/OVR_Linux_HMDDevice.cpp +++ b/LibOVR/Src/OVR_Linux_HMDDevice.cpp @@ -19,8 +19,7 @@ otherwise accompanies this software in either electronic or hard copy form. #include "OVR_Profile.h" -#include <X11/Xlib.h> -#include <X11/extensions/Xinerama.h> +#include "edid.h" namespace OVR { namespace Linux { @@ -70,7 +69,7 @@ HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCr if (!DeviceId.IsEmpty() || ((HScreenSize == s2.HScreenSize) && (VScreenSize == s2.VScreenSize)) ) - { + { *pcandidate = 0; return Match_Found; } @@ -92,10 +91,10 @@ HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCr *pcandidate = 0; return Match_Found; } - + // SensorDisplayInfo may override resolution settings, so store as candidate. if (s2.DeviceId.IsEmpty()) - { + { *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this); return Match_Candidate; } @@ -105,22 +104,22 @@ HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCr *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this); return Match_Candidate; } - + return Match_None; } -bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, +bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, bool* newDeviceFlag) { // This candidate was the the "best fit" to apply sensor DisplayInfo to. OVR_ASSERT(other.Type == Device_HMD); - + const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; // Force screen size on resolution from SensorDisplayInfo. // We do this because USB detection is more reliable as compared to HDMI EDID, - // which may be corrupted by splitter reporting wrong monitor + // which may be corrupted by splitter reporting wrong monitor if (s2.DeviceId.IsEmpty()) { HScreenSize = s2.HScreenSize; @@ -174,44 +173,47 @@ void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) // Rift models. bool foundHMD = false; - + RRCrtc crtcId = 0; Display* display = XOpenDisplay(NULL); - if (display && XineramaIsActive(display)) - { - int numberOfScreens; - XineramaScreenInfo* screens = XineramaQueryScreens(display, &numberOfScreens); - - for (int i = 0; i < numberOfScreens; i++) - { - XineramaScreenInfo screenInfo = screens[i]; - - if (screenInfo.width == 1280 && screenInfo.height == 800) - { - String deviceName = "OVR0001"; - - HMDDeviceCreateDesc hmdCreateDesc(this, deviceName, i); - hmdCreateDesc.SetScreenParameters(screenInfo.x_org, screenInfo.y_org, 1280, 800, 0.14976f, 0.0936f); - - OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %d\n", - deviceName.ToCStr(), i)); - - // Notify caller about detected device. This will call EnumerateAddDevice - // if the this is the first time device was detected. - visitor.Visit(hmdCreateDesc); - foundHMD = true; - break; - } + XRRScreenResources *screen = XRRGetScreenResources(display, DefaultRootWindow(display)); + for (int iscres = screen->noutput - 1; iscres >= 0; --iscres) { + RROutput output = screen->outputs[iscres]; + MonitorInfo * mi = read_edid_data(display, output); + if (mi == NULL) { + continue; } - XFree(screens); - } - + XRROutputInfo * info = XRRGetOutputInfo (display, screen, output); + if (0 == memcmp(mi->manufacturer_code, "OVR", 3)) { + int x = -1, y = -1, w = -1, h = -1; + if (info->connection == RR_Connected && info->crtc) { + XRRCrtcInfo * crtc_info = XRRGetCrtcInfo (display, screen, info->crtc); + x = crtc_info->x; + y = crtc_info->y; + w = crtc_info->width; + h = crtc_info->height; + XRRFreeCrtcInfo(crtc_info); + } + HMDDeviceCreateDesc hmdCreateDesc(this, mi->dsc_product_name, output); + hmdCreateDesc.SetScreenParameters(x, y, w, h, 0.14976f, 0.0936f); + // Notify caller about detected device. This will call EnumerateAddDevice + // if the this is the first time device was detected. + visitor.Visit(hmdCreateDesc); + foundHMD = true; + break; + } // if + + OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %d\n", + mi->dsc_product_name, screen->outputs[iscres])); + XRRFreeOutputInfo (info); + delete mi; + } // for + XRRFreeScreenResources(screen); // Real HMD device is not found; however, we still may have a 'fake' HMD // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo. // Need to find it and set 'Enumerated' to true to avoid Removal notification. - if (!foundHMD) - { + if (!foundHMD) { Ptr<DeviceCreateDesc> hmdDevDesc = getManager()->FindDevice("", Device_HMD); if (hmdDevDesc) hmdDevDesc->Enumerated = true; @@ -236,8 +238,8 @@ Profile* HMDDeviceCreateDesc::GetProfileAddRef() const const char * profileName = pDevice ? ((HMDDevice*)pDevice)->GetProfileName() : profileManager->GetDefaultProfileName(profileType); - - return profileName ? + + return profileName ? profileManager->LoadProfile(profileType, profileName) : profileManager->GetDeviceDefaultProfile(profileType); } @@ -287,7 +289,7 @@ bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const memcpy(hmdInfo->DistortionK, DistortionK, sizeof(float)*4); } else - { + { if (is7Inch) { // 7" screen. @@ -338,7 +340,7 @@ bool HMDDevice::Initialize(DeviceBase* parent) pParent = parent; // Initialize user profile to default for device. - ProfileManager* profileManager = GetManager()->GetProfileManager(); + ProfileManager* profileManager = GetManager()->GetProfileManager(); ProfileName = profileManager->GetDefaultProfileName(getDesc()->GetProfileType()); return true; @@ -351,7 +353,7 @@ void HMDDevice::Shutdown() } Profile* HMDDevice::GetProfile() const -{ +{ if (!pCachedProfile) pCachedProfile = *getDesc()->GetProfileAddRef(); return pCachedProfile.GetPtr(); diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.cpp b/LibOVR/Src/OVR_OSX_HIDDevice.cpp index e93cf67..69c9cef 100644 --- a/LibOVR/Src/OVR_OSX_HIDDevice.cpp +++ b/LibOVR/Src/OVR_OSX_HIDDevice.cpp @@ -3,9 +3,9 @@ Filename : OVR_OSX_HIDDevice.cpp Content : OSX HID device implementation. Created : February 26, 2013 Authors : Lee Cooper - + Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. - + Use of this software is subject to the terms of the Oculus license agreement provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. @@ -19,7 +19,7 @@ otherwise accompanies this software in either electronic or hard copy form. namespace OVR { namespace OSX { static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5; - + //------------------------------------------------------------------------------------- // **** OSX::DeviceManager @@ -49,21 +49,21 @@ bool HIDDeviceManager::initializeManager() { return true; } - + HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - + if (!HIDManager) { return false; } - + // Create a Matching Dictionary CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - + // Specify a device manufacturer in the Matching Dictionary UInt32 vendorId = Oculus_VendorId; CFNumberRef vendorIdRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendorId); @@ -74,15 +74,15 @@ bool HIDDeviceManager::initializeManager() IOHIDManagerSetDeviceMatching(HIDManager, matchDict); CFRelease(vendorIdRef); CFRelease(matchDict); - + // Register a callback for USB device detection with the HID Manager IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &staticDeviceMatchingCallback, this); - + IOHIDManagerScheduleWithRunLoop(HIDManager, getRunLoop(), kCFRunLoopDefaultMode); return true; } - + bool HIDDeviceManager::Initialize() { return initializeManager(); @@ -92,38 +92,38 @@ void HIDDeviceManager::Shutdown() { OVR_ASSERT_LOG(HIDManager, ("Should have called 'Initialize' before 'Shutdown'.")); CFRelease(HIDManager); - + LogText("OVR::OSX::HIDDeviceManager - shutting down.\n"); } - + bool HIDDeviceManager::getIntProperty(IOHIDDeviceRef device, CFStringRef propertyName, SInt32* pResult) { - + CFTypeRef ref = IOHIDDeviceGetProperty(device, propertyName); if (!ref) { return false; } - + if (CFGetTypeID(ref) != CFNumberGetTypeID()) { return false; } - + CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, pResult); return true; } - + bool HIDDeviceManager::initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) { - + if (!getVendorId(device, &(pDevDesc->VendorId))) { return false; } - + if (!getProductId(device, &(pDevDesc->ProductId))) { return false; @@ -135,30 +135,30 @@ bool HIDDeviceManager::initVendorProductVersion(IOHIDDeviceRef device, HIDDevice return false; } pDevDesc->VersionNumber = result; - + return true; } bool HIDDeviceManager::initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) { - + SInt32 result; - + if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey), &result)) { return false; } - + pDevDesc->UsagePage = result; - + if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsageKey), &result)) { return false; } - + pDevDesc->Usage = result; - + return true; } @@ -166,14 +166,14 @@ bool HIDDeviceManager::initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pD { return getSerialNumberString(device, &(pDevDesc->SerialNumber)); } - + bool HIDDeviceManager::initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) { // Regardless of whether they fail we'll try and get the remaining. getStringProperty(device, CFSTR(kIOHIDManufacturerKey), &(pDevDesc->Manufacturer)); getStringProperty(device, CFSTR(kIOHIDProductKey), &(pDevDesc->Product)); - + return true; } @@ -181,9 +181,9 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device, CFStringRef propertyName, String* pResult) { - + CFStringRef str = (CFStringRef) IOHIDDeviceGetProperty(device, propertyName); - + if (!str) { return false; @@ -191,7 +191,7 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device, CFIndex length = CFStringGetLength(str); CFRange range = CFRangeMake(0, length); - + // Test the conversion first to get required buffer size. CFIndex bufferLength; CFIndex numberOfChars = CFStringGetBytes(str, @@ -202,15 +202,15 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device, NULL, 0, &bufferLength); - + if (numberOfChars == 0) { return false; } - + // Now allocate buffer. char* buffer = new char[bufferLength+1]; - + numberOfChars = CFStringGetBytes(str, range, kCFStringEncodingUTF8, @@ -223,55 +223,55 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device, buffer[bufferLength] = '\0'; *pResult = String(buffer); - + return true; } - + bool HIDDeviceManager::getVendorId(IOHIDDeviceRef device, UInt16* pResult) { SInt32 result; - + if (!getIntProperty(device, CFSTR(kIOHIDVendorIDKey), &result)) { return false; } - + *pResult = result; return true; } - + bool HIDDeviceManager::getProductId(IOHIDDeviceRef device, UInt16* pResult) { SInt32 result; - + if (!getIntProperty(device, CFSTR(kIOHIDProductIDKey), &result)) { return false; } - + *pResult = result; - + return true; } - + bool HIDDeviceManager::getLocationId(IOHIDDeviceRef device, SInt32* pResult) { SInt32 result; - + if (!getIntProperty(device, CFSTR(kIOHIDLocationIDKey), &result)) { return false; } - + *pResult = result; - + return true; } - + bool HIDDeviceManager::getSerialNumberString(IOHIDDeviceRef device, String* pResult) { - + if (!getStringProperty(device, CFSTR(kIOHIDSerialNumberKey), pResult)) { return false; @@ -279,7 +279,7 @@ bool HIDDeviceManager::getSerialNumberString(IOHIDDeviceRef device, String* pRes return true; } - + bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath) { @@ -288,7 +288,7 @@ bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath) { return false; } - + UInt16 vendorId; if (!getVendorId(device, &vendorId)) { @@ -300,13 +300,13 @@ bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath) { return false; } - + String serialNumber; if (!getSerialNumberString(device, &serialNumber)) { return false; } - + StringBuffer buffer; buffer.AppendFormat("%s:vid=%04hx:pid=%04hx:ser=%s", @@ -314,9 +314,9 @@ bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath) vendorId, productId, serialNumber.ToCStr()); - + *pPath = String(buffer); - + return true; } @@ -326,31 +326,31 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) { return false; } - + CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager); if (!deviceSet) return false; - + CFIndex deviceCount = CFSetGetCount(deviceSet); - + // Allocate a block of memory and read the set into it. IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount); CFSetGetValues(deviceSet, (const void **) devices); - + // Iterate over devices. for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { IOHIDDeviceRef hidDev = devices[deviceIndex]; - + if (!hidDev) { continue; } - + HIDDeviceDesc devDesc; - + if (getPath(hidDev, &(devDesc.Path)) && initVendorProductVersion(hidDev, &devDesc) && enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) && @@ -368,17 +368,17 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) existingDevice->Enumerated = true; continue; } - + // Construct minimal device that the visitor callback can get feature reports from. OSX::HIDDevice device(this, hidDev); - + enumVisitor->Visit(device, devDesc); } } - + OVR_FREE(devices); CFRelease(deviceSet); - + return true; } @@ -393,30 +393,30 @@ OVR::HIDDevice* HIDDeviceManager::Open(const String& path) } device->AddRef(); - + return device; } - + bool HIDDeviceManager::getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc) { - + if (!initVendorProductVersion(device, desc)) { return false; } - + if (!initUsage(device, desc)) { return false; } - + if (!initSerialNumber(device, desc)) { return false; } - + initStrings(device, desc); - + return true; } @@ -430,7 +430,7 @@ void HIDDeviceManager::staticDeviceMatchingCallback(void *inContext, HIDDeviceDesc hidDevDesc; hidMgr->getPath(inIOHIDDeviceRef, &hidDevDesc.Path); hidMgr->getFullDesc(inIOHIDDeviceRef, &hidDevDesc); - + hidMgr->DevManager->DetectHIDDevice(hidDevDesc); } @@ -443,7 +443,7 @@ HIDDevice::HIDDevice(HIDDeviceManager* manager) Device = NULL; RepluggedNotificationPort = 0; } - + // This is a minimal constructor used during enumeration for us to pass // a HIDDevice to the visit function (so that it can query feature reports). HIDDevice::HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device) @@ -478,16 +478,16 @@ bool HIDDevice::HIDInitialize(const String& path) closeDevice(false); return false; } - + HIDManager->DevManager->pThread->AddTicksNotifier(this); - + LogText("OVR::OSX::HIDDevice - Opened '%s'\n" " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n", DevDesc.Path.ToCStr(), DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(), DevDesc.SerialNumber.ToCStr()); - + return true; } @@ -495,8 +495,8 @@ bool HIDDevice::initInfo() { // Device must have been successfully opened. OVR_ASSERT(Device); - - + + // Get report lengths. SInt32 bufferLength; bool getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxInputReportSizeKey), &bufferLength); @@ -510,21 +510,21 @@ bool HIDDevice::initInfo() getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength); OVR_ASSERT(getResult); FeatureReportBufferLength = (UInt16) bufferLength; - - + + if (ReadBufferSize < InputReportBufferLength) { OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); return false; } - + // Get device desc. if (!HIDManager->getFullDesc(Device, &DevDesc)) { OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device.")); return false; } - + return true; } @@ -555,53 +555,53 @@ void HIDDevice::deviceAddedCallback(io_iterator_t iterator) while (IOIteratorNext(iterator)) ; } - + bool HIDDevice::openDevice() { - + // Have to iterate through devices again to generate paths. CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager); CFIndex deviceCount = CFSetGetCount(deviceSet); - + // Allocate a block of memory and read the set into it. IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount); CFSetGetValues(deviceSet, (const void **) devices); - - + + // Iterate over devices. IOHIDDeviceRef device = NULL; for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { IOHIDDeviceRef tmpDevice = devices[deviceIndex]; - + if (!tmpDevice) { continue; } - + String path; if (!HIDManager->getPath(tmpDevice, &path)) { continue; } - + if (path == DevDesc.Path) { device = tmpDevice; break; } } - - + + OVR_FREE(devices); - + if (!device) { CFRelease(deviceSet); return false; } - + // Attempt to open device. if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) @@ -613,11 +613,11 @@ bool HIDDevice::openDevice() // Retain the device before we release the set. CFRetain(device); CFRelease(deviceSet); - - + + Device = device; - + if (!initInfo()) { IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice); @@ -625,13 +625,13 @@ bool HIDDevice::openDevice() Device = NULL; return false; } - - + + // Setup the Run Loop and callbacks. IOHIDDeviceScheduleWithRunLoop(Device, HIDManager->getRunLoop(), kCFRunLoopDefaultMode); - + IOHIDDeviceRegisterInputReportCallback(Device, ReadBuffer, ReadBufferSize, @@ -641,15 +641,15 @@ bool HIDDevice::openDevice() IOHIDDeviceRegisterRemovalCallback(Device, staticDeviceRemovedCallback, this); - + return true; } - + void HIDDevice::HIDShutdown() { HIDManager->DevManager->pThread->RemoveTicksNotifier(this); - + if (Device != NULL) // Device may already have been closed if unplugged. { closeDevice(false); @@ -658,25 +658,25 @@ void HIDDevice::HIDShutdown() IOObjectRelease(RepluggedNotification); if (RepluggedNotificationPort) IONotificationPortDestroy(RepluggedNotificationPort); - + LogText("OVR::OSX::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr()); } bool HIDDevice::setupDevicePluggedInNotification() { - + // Setup notification when devices are plugged in. RepluggedNotificationPort = IONotificationPortCreate(kIOMasterPortDefault); - + CFRunLoopSourceRef notificationRunLoopSource = IONotificationPortGetRunLoopSource(RepluggedNotificationPort); - + CFRunLoopAddSource(HIDManager->getRunLoop(), notificationRunLoopSource, kCFRunLoopDefaultMode); - + CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); - + // Have to specify vendorId and productId. Doesn't seem to accept additional // things like serial number. SInt32 vendorId = DevDesc.VendorId; @@ -685,14 +685,14 @@ bool HIDDevice::setupDevicePluggedInNotification() &vendorId); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); CFRelease(numberRef); - + SInt32 deviceProductId = DevDesc.ProductId; numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &deviceProductId); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); CFRelease(numberRef); - + kern_return_t result = IOServiceAddMatchingNotification(RepluggedNotificationPort, kIOMatchedNotification, @@ -700,26 +700,26 @@ bool HIDDevice::setupDevicePluggedInNotification() staticDeviceAddedCallback, this, &RepluggedNotification); - + if (result != KERN_SUCCESS) { CFRelease(RepluggedNotificationPort); RepluggedNotificationPort = 0; return false; } - + // Iterate through to arm. while (IOIteratorNext(RepluggedNotification)) { } - + return true; } void HIDDevice::closeDevice(bool wasUnplugged) { OVR_ASSERT(Device != NULL); - + if (!wasUnplugged) { // Clear the registered callbacks. @@ -728,18 +728,18 @@ void HIDDevice::closeDevice(bool wasUnplugged) InputReportBufferLength, NULL, this); - + IOHIDDeviceRegisterRemovalCallback(Device, NULL, this); - + IOHIDDeviceUnscheduleFromRunLoop(Device, HIDManager->getRunLoop(), kCFRunLoopDefaultMode); IOHIDDeviceClose(Device, kIOHIDOptionsTypeNone); } - + CFRelease(Device); Device = NULL; - + LogText("OVR::OSX::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr()); } @@ -755,26 +755,26 @@ void HIDDevice::staticHIDReportCallback(void* pContext, return pDevice->hidReportCallback(pReport, (UInt32)reportLength); } -void HIDDevice::hidReportCallback(UByte* pData, UInt32 length) +void HIDDevice::hidReportCallback(const UByte* pData, UInt32 length) { - + // We got data. if (Handler) { Handler->OnInputReport(pData, length); } } - + void HIDDevice::staticDeviceRemovedCallback(void* pContext, IOReturn result, void* pSender) { HIDDevice* pDevice = (HIDDevice*) pContext; pDevice->deviceRemovedCallback(); } - + void HIDDevice::deviceRemovedCallback() { Ptr<HIDDevice> _this(this); // prevent from release - + Ptr<DeviceCreateDesc> existingHIDDev = HIDManager->DevManager->FindHIDDevice(DevDesc); if (existingHIDDev && existingHIDDev->pDevice) { @@ -788,16 +788,16 @@ CFStringRef HIDDevice::generateRunLoopModeString(IOHIDDeviceRef device) const UInt32 safeBuffSize = 256; char nameBuff[safeBuffSize]; OVR_sprintf(nameBuff, safeBuffSize, "%016lX", device); - + return CFStringCreateWithCString(NULL, nameBuff, kCFStringEncodingASCII); } - + bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) { - + if (!Device) return false; - + UByte reportID = data[0]; if (reportID == 0) @@ -806,13 +806,13 @@ bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) data++; length--; } - + IOReturn result = IOHIDDeviceSetReport( Device, kIOHIDReportTypeFeature, reportID, data, length); - + return (result == kIOReturnSuccess); } @@ -820,29 +820,29 @@ bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length) { if (!Device) return false; - + CFIndex bufferLength = length; - + // Report id is in first byte of the buffer. IOReturn result = IOHIDDeviceGetReport(Device, kIOHIDReportTypeFeature, data[0], data, &bufferLength); - + return (result == kIOReturnSuccess); } - + UInt64 HIDDevice::OnTicks(UInt64 ticksMks) { - + if (Handler) { return Handler->OnTicks(ticksMks); } - + return DeviceManagerThread::Notifier::OnTicks(ticksMks); } HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManager) { - + if (!System::IsInitialized()) { // Use custom message, since Log is not yet installed. @@ -867,7 +867,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManage return manager.GetPtr(); } - + } // namespace OSX //------------------------------------------------------------------------------------- @@ -877,7 +877,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManage HIDDeviceManager* HIDDeviceManager::Create() { OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet.")); - + if (!System::IsInitialized()) { // Use custom message, since Log is not yet installed. @@ -887,7 +887,7 @@ HIDDeviceManager* HIDDeviceManager::Create() } Ptr<OSX::HIDDeviceManager> manager = *new OSX::HIDDeviceManager(NULL); - + if (manager) { if (manager->Initialize()) diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.h b/LibOVR/Src/OVR_OSX_HIDDevice.h index 564bb60..546631d 100644 --- a/LibOVR/Src/OVR_OSX_HIDDevice.h +++ b/LibOVR/Src/OVR_OSX_HIDDevice.h @@ -71,7 +71,7 @@ private: uint32_t reportId, uint8_t* pReport, CFIndex reportLength); - void hidReportCallback(UByte* pData, UInt32 length); + void hidReportCallback(const UByte* pData, UInt32 length); static void staticDeviceRemovedCallback(void* pContext, IOReturn result, diff --git a/LibOVR/Src/OVR_OSX_HMDDevice.h b/LibOVR/Src/OVR_OSX_HMDDevice.h index 52b8471..a7beeb1 100644 --- a/LibOVR/Src/OVR_OSX_HMDDevice.h +++ b/LibOVR/Src/OVR_OSX_HMDDevice.h @@ -17,7 +17,7 @@ otherwise accompanies this software in either electronic or hard copy form. #define OVR_OSX_HMDDevice_h #include "OVR_DeviceImpl.h" -#include <Kernel/OVR_String.h> +#include "Kernel/OVR_String.h" #include "OVR_Profile.h" namespace OVR { namespace OSX { diff --git a/LibOVR/Src/OVR_SensorImpl.cpp b/LibOVR/Src/OVR_SensorImpl.cpp index c54bccb..369ad15 100644 --- a/LibOVR/Src/OVR_SensorImpl.cpp +++ b/LibOVR/Src/OVR_SensorImpl.cpp @@ -19,12 +19,14 @@ otherwise accompanies this software in either electronic or hard copy form. #include "Kernel/OVR_Timer.h" +#include <iostream> + namespace OVR { - + //------------------------------------------------------------------------------------- // ***** Oculus Sensor-specific packet data structures -enum { +enum { Sensor_VendorId = Oculus_VendorId, Sensor_ProductId = 0x0001, @@ -50,8 +52,8 @@ static SInt16 DecodeSInt16(const UByte* buffer) } static UInt32 DecodeUInt32(const UByte* buffer) -{ - return (buffer[0]) | UInt32(buffer[1] << 8) | UInt32(buffer[2] << 16) | UInt32(buffer[3] << 24); +{ + return (buffer[0]) | UInt32(buffer[1] << 8) | UInt32(buffer[2] << 16) | UInt32(buffer[3] << 24); } static float DecodeFloat(const UByte* buffer) @@ -114,9 +116,9 @@ struct TrackerSensors Timestamp = DecodeUInt16(buffer + 2); LastCommandID = DecodeUInt16(buffer + 4); Temperature = DecodeSInt16(buffer + 6); - - //if (SampleCount > 2) - // OVR_DEBUG_LOG_TEXT(("TackerSensor::Decode SampleCount=%d\n", SampleCount)); + + //if (SampleCount > 2) + // OVR_DEBUG_LOG_TEXT(("TackerSensor::Decode SampleCount=%d\n", SampleCount)); // Only unpack as many samples as there actually are UByte iterationCount = (SampleCount > 2) ? 3 : SampleCount; @@ -141,7 +143,7 @@ struct TrackerMessage TrackerSensors Sensors; }; -bool DecodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size) +bool DecodeTrackerMessage(TrackerMessage* message, const UByte* buffer, int size) { memset(message, 0, sizeof(TrackerMessage)); @@ -176,7 +178,7 @@ static const UInt16 MagRangeRamp[] = { 880, 1300, 1900, 2500 }; static UInt16 SelectSensorRampValue(const UInt16* ramp, unsigned count, float val, float factor, const char* label) -{ +{ UInt16 threshold = (UInt16)(val * factor); for (unsigned i = 0; i<count; i++) @@ -197,7 +199,7 @@ struct SensorRangeImpl { enum { PacketSize = 8 }; UByte Buffer[PacketSize]; - + UInt16 CommandId; UInt16 AccelScale; UInt16 GyroScale; @@ -309,7 +311,7 @@ struct SensorConfigImpl PacketInterval = Buffer[4]; KeepAliveIntervalMs= Buffer[5] | (UInt16(Buffer[6]) << 8); } - + }; @@ -390,7 +392,7 @@ void SensorDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) void operator = (const SensorEnumerator&) { } DeviceFactory* pFactory; - EnumerateVisitor& ExternalVisitor; + EnumerateVisitor& ExternalVisitor; public: SensorEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor) : pFactory(factory), ExternalVisitor(externalVisitor) { } @@ -418,7 +420,7 @@ void SensorDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) // Check if the sensor returns DisplayInfo. If so, try to use it to override potentially // mismatching monitor information (in case wrong EDID is reported by splitter), // or to create a new "virtualized" HMD Device. - + SensorDisplayInfoImpl displayInfo; if (device.GetFeatureReport(displayInfo.Buffer, SensorDisplayInfoImpl::PacketSize)) @@ -440,7 +442,7 @@ void SensorDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) SensorEnumerator sensorEnumerator(this, visitor); GetManagerImpl()->GetHIDDeviceManager()->Enumerate(&sensorEnumerator); - //double totalSeconds = Timer::GetProfileSeconds() - start; + //double totalSeconds = Timer::GetProfileSeconds() - start; } bool SensorDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const @@ -522,7 +524,7 @@ SensorDeviceImpl::SensorDeviceImpl(SensorDeviceCreateDesc* createDesc) SensorDeviceImpl::~SensorDeviceImpl() { // Check that Shutdown() was called. - OVR_ASSERT(!pCreateDesc->pDevice); + OVR_ASSERT(!pCreateDesc->pDevice); } // Internal creation APIs. @@ -581,14 +583,14 @@ void SensorDeviceImpl::closeDeviceOnError() } void SensorDeviceImpl::Shutdown() -{ +{ HIDDeviceImpl<OVR::SensorDevice>::Shutdown(); LogText("OVR::SensorDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr()); } -void SensorDeviceImpl::OnInputReport(UByte* pData, UInt32 length) +void SensorDeviceImpl::OnInputReport(const UByte* pData, UInt32 length) { bool processed = false; @@ -606,7 +608,6 @@ void SensorDeviceImpl::OnInputReport(UByte* pData, UInt32 length) UInt64 SensorDeviceImpl::OnTicks(UInt64 ticksMks) { - if (ticksMks >= NextKeepAliveTicks) { // Use 3-seconds keep alive by default. @@ -632,10 +633,10 @@ bool SensorDeviceImpl::SetRange(const SensorRange& range, bool waitFlag) { return threadQueue->PushCall(this, &SensorDeviceImpl::setRange, range); } - - if (!threadQueue->PushCallAndWaitResult(this, + + if (!threadQueue->PushCallAndWaitResult(this, &SensorDeviceImpl::setRange, - &result, + &result, range)) { return false; @@ -653,19 +654,19 @@ void SensorDeviceImpl::GetRange(SensorRange* range) const bool SensorDeviceImpl::setRange(const SensorRange& range) { SensorRangeImpl sr(range); - + if (GetInternalDevice()->SetFeatureReport(sr.Buffer, SensorRangeImpl::PacketSize)) { Lock::Locker lockScope(GetLock()); sr.GetSensorRange(&CurrentRange); return true; } - + return false; } void SensorDeviceImpl::SetCoordinateFrame(CoordinateFrame coordframe) -{ +{ // Push call with wait. GetManagerImpl()->GetThreadQueue()-> PushCall(this, &SensorDeviceImpl::setCoordinateFrame, coordframe, true); @@ -692,7 +693,7 @@ Void SensorDeviceImpl::setCoordinateFrame(CoordinateFrame coordframe) scfg.Pack(); GetInternalDevice()->SetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize); - + // Re-read the state, in case of older firmware that doesn't support Sensor coordinates. if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize)) { @@ -707,7 +708,7 @@ Void SensorDeviceImpl::setCoordinateFrame(CoordinateFrame coordframe) } void SensorDeviceImpl::SetReportRate(unsigned rateHz) -{ +{ // Push call with wait. GetManagerImpl()->GetThreadQueue()-> PushCall(this, &SensorDeviceImpl::setReportRate, rateHz, true); @@ -755,9 +756,9 @@ void SensorDeviceImpl::SetMessageHandler(MessageHandler* handler) DeviceBase::SetMessageHandler(handler); } else - { + { DeviceBase::SetMessageHandler(handler); - } + } } // Sensor reports data in the following coordinate system: @@ -783,15 +784,15 @@ Vector3f AccelFromBodyFrameUpdate(const TrackerSensors& update, UByte sampleNumb Vector3f MagFromBodyFrameUpdate(const TrackerSensors& update, bool convertHMDToSensor = false) -{ - // Note: Y and Z are swapped in comparison to the Accel. +{ + // Note: Y and Z are swapped in comparison to the Accel. // This accounts for DK1 sensor firmware axis swap, which should be undone in future releases. if (!convertHMDToSensor) { return Vector3f( (float)update.MagX, (float)update.MagZ, (float)update.MagY) * 0.0001f; - } + } return Vector3f( (float)update.MagX, (float)update.MagY, @@ -815,10 +816,10 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message) { if (message->Type != TrackerMessage_Sensors) return; - + const float timeUnit = (1.0f / 1000.f); TrackerSensors& s = message->Sensors; - + // Call OnMessage() within a lock to avoid conflicts with handlers. Lock::Locker scopeLock(HandlerRef.GetLock()); @@ -865,7 +866,7 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message) if (HandlerRef.GetHandler()) { - MessageBodyFrame sensors(this); + MessageBodyFrame sensors(this); UByte iterations = s.SampleCount; if (s.SampleCount > 3) @@ -879,7 +880,7 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message) } for (UByte i = 0; i < iterations; i++) - { + { sensors.Acceleration = AccelFromBodyFrameUpdate(s, i, convertHMDToSensor); sensors.RotationRate = EulerFromBodyFrameUpdate(s, i, convertHMDToSensor); sensors.MagneticField= MagFromBodyFrameUpdate(s, convertHMDToSensor); diff --git a/LibOVR/Src/OVR_SensorImpl.h b/LibOVR/Src/OVR_SensorImpl.h index 4bdcc4f..672e96a 100644 --- a/LibOVR/Src/OVR_SensorImpl.h +++ b/LibOVR/Src/OVR_SensorImpl.h @@ -19,7 +19,7 @@ otherwise accompanies this software in either electronic or hard copy form. #include "OVR_HIDDeviceImpl.h" namespace OVR { - + struct TrackerMessage; class ExternalVisitor; @@ -36,7 +36,7 @@ public: virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const; virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc); protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } + DeviceManager* getManager() const { return (DeviceManager*) pManager; } }; @@ -46,7 +46,7 @@ class SensorDeviceCreateDesc : public HIDDeviceCreateDesc public: SensorDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc) : HIDDeviceCreateDesc(factory, Device_Sensor, hidDesc) { } - + virtual DeviceCreateDesc* Clone() const { return new SensorDeviceCreateDesc(*this); @@ -145,7 +145,7 @@ struct SensorDisplayInfoImpl }; UInt16 CommandId; - UByte DistortionType; + UByte DistortionType; UInt16 HResolution, VResolution; float HScreenSize, VScreenSize; float VCenter; @@ -174,24 +174,24 @@ public: // DeviceCommaon interface virtual bool Initialize(DeviceBase* parent); virtual void Shutdown(); - + virtual void SetMessageHandler(MessageHandler* handler); // HIDDevice::Notifier interface. - virtual void OnInputReport(UByte* pData, UInt32 length); + virtual void OnInputReport(const UByte* pData, UInt32 length); virtual UInt64 OnTicks(UInt64 ticksMks); // HMD-Mounted sensor has a different coordinate frame. - virtual void SetCoordinateFrame(CoordinateFrame coordframe); - virtual CoordinateFrame GetCoordinateFrame() const; + virtual void SetCoordinateFrame(CoordinateFrame coordframe); + virtual CoordinateFrame GetCoordinateFrame() const; // SensorDevice interface virtual bool SetRange(const SensorRange& range, bool waitFlag); virtual void GetRange(SensorRange* range) const; - // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). - // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be - // called twice or thrice at the same 'tick'. + // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). + // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be + // called twice or thrice at the same 'tick'. // If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three // times for each 'tick': the first call will contain averaged values, the second // and third calls will provide with most recent two recorded samples. @@ -202,7 +202,7 @@ public: virtual unsigned GetReportRate() const; // Hack to create HMD device from sensor display info. - static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo, + static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo, DeviceFactory::EnumerateVisitor& visitor); protected: @@ -223,7 +223,7 @@ protected: { return (SensorDeviceCreateDesc*)pCreateDesc.GetPtr(); } HIDDeviceDesc* getHIDDesc() const - { return &getCreateDesc()->HIDDesc; } + { return &getCreateDesc()->HIDDesc; } */ // Set if the sensor is located on the HMD. @@ -241,10 +241,10 @@ protected: Vector3f LastRotationRate; Vector3f LastMagneticField; - // Current sensor range obtained from device. + // Current sensor range obtained from device. SensorRange MaxValidRange; SensorRange CurrentRange; - + UInt16 OldCommandId; }; diff --git a/LibOVR/Src/OVR_Win32_HIDDevice.cpp b/LibOVR/Src/OVR_Win32_HIDDevice.cpp index 28a47f0..5017760 100644 --- a/LibOVR/Src/OVR_Win32_HIDDevice.cpp +++ b/LibOVR/Src/OVR_Win32_HIDDevice.cpp @@ -13,6 +13,8 @@ otherwise accompanies this software in either electronic or hard copy form. *************************************************************************************/ +#pragma comment(lib, "setupapi.lib") + #include "OVR_Win32_HIDDevice.h" #include "OVR_Win32_DeviceManager.h" @@ -21,6 +23,7 @@ otherwise accompanies this software in either electronic or hard copy form. namespace OVR { namespace Win32 { + //------------------------------------------------------------------------------------- // HIDDevicePathWrapper is a simple class used to extract HID device file path // through SetupDiGetDeviceInterfaceDetail. We use a class since this is a bit messy. diff --git a/LibOVR/Src/Util/Util_MagCalibration.cpp b/LibOVR/Src/Util/Util_MagCalibration.cpp deleted file mode 100644 index 58b8c45..0000000 --- a/LibOVR/Src/Util/Util_MagCalibration.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************************ - -Filename : Util_MagCalibration.cpp -Content : Procedures for calibrating the magnetometer -Created : April 16, 2013 -Authors : Steve LaValle, Andrew Reisse - -Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. - -Use of this software is subject to the terms of the Oculus license -agreement provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -*************************************************************************************/ - -#include "Util_MagCalibration.h" - -namespace OVR { namespace Util { - -void MagCalibration::BeginAutoCalibration(SensorFusion& sf) -{ - Stat = Mag_AutoCalibrating; - // This is a "hard" reset of the mag, so need to clear stored values - sf.ClearMagCalibration(); - SampleCount = 0; - - // reset the statistics - MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f); - MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f); - MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f); - MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f); -} - -unsigned MagCalibration::UpdateAutoCalibration(SensorFusion& sf) -{ - if (Stat != Mag_AutoCalibrating) - return Stat; - - Quatf q = sf.GetOrientation(); - Vector3f m = sf.GetMagnetometer(); - - InsertIfAcceptable(q, m); - - if ((SampleCount == 4) && (Stat == Mag_AutoCalibrating)) - { - //LogText("Magnetometer Output Spread: %f %f %f\n",MagSpread.x,MagSpread.y,MagSpread.z); - //LogText("Quaternion Spread: %f %f %f %f\n",QuatSpread.x,QuatSpread.y,QuatSpread.z,QuatSpread.w); - SetCalibration(sf); - } - - return Stat; - -} - -void MagCalibration::BeginManualCalibration(SensorFusion& sf) -{ - Stat = Mag_ManuallyCalibrating; - sf.ClearMagCalibration(); - SampleCount = 0; -} - -bool MagCalibration::IsAcceptableSample(const Quatf& q, const Vector3f& m) -{ - switch (SampleCount) - { - // Initial sample is always acceptable - case 0: - return true; - break; - case 1: - return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&& - ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq); - break; - case 2: - return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&& - (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&& - ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq)&& - ((m - MagSamples[1]).LengthSq() > MinMagDistanceSq); - break; - case 3: - return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&& - (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&& - (q.DistanceSq(QuatSamples[2]) > MinQuatDistanceSq)&& - ((PointToPlaneDistance(MagSamples[0],MagSamples[1],MagSamples[2],m) > MinMagDistance)|| - (PointToPlaneDistance(MagSamples[1],MagSamples[2],m,MagSamples[0]) > MinMagDistance)|| - (PointToPlaneDistance(MagSamples[2],m,MagSamples[0],MagSamples[1]) > MinMagDistance)|| - (PointToPlaneDistance(m,MagSamples[0],MagSamples[1],MagSamples[2]) > MinMagDistance)); - } - - return false; -} - - -bool MagCalibration::InsertIfAcceptable(const Quatf& q, const Vector3f& m) -{ - // Update some statistics - if (m.x < MinMagValues.x) - MinMagValues.x = m.x; - if (m.y < MinMagValues.y) - MinMagValues.y = m.y; - if (m.z < MinMagValues.z) - MinMagValues.z = m.z; - if (m.x > MaxMagValues.x) - MaxMagValues.x = m.x; - if (m.y > MaxMagValues.y) - MaxMagValues.y = m.y; - if (m.z > MaxMagValues.z) - MaxMagValues.z = m.z; - if (q.x < MinQuatValues.x) - MinQuatValues.x = q.x; - if (q.y < MinQuatValues.y) - MinQuatValues.y = q.y; - if (q.z < MinQuatValues.z) - MinQuatValues.z = q.z; - if (q.w < MinQuatValues.w) - MinQuatValues.w = q.w; - if (q.x > MaxQuatValues.x) - MaxQuatValues.x = q.x; - if (q.y > MaxQuatValues.y) - MaxQuatValues.y = q.y; - if (q.z > MaxQuatValues.z) - MaxQuatValues.z = q.z; - if (q.w > MaxQuatValues.w) - MaxQuatValues.w = q.w; - MagSpread = MaxMagValues - MinMagValues; - QuatSpread = MaxQuatValues - MinQuatValues; - - if (IsAcceptableSample(q, m)) - { - MagSamples[SampleCount] = m; - QuatSamples[SampleCount] = q; - SampleCount++; - return true; - } - - return false; -} - -Matrix4f MagCalibration::GetMagCalibration() const -{ - Matrix4f calMat = Matrix4f(); - calMat.M[0][3] = -MagCenter.x; - calMat.M[1][3] = -MagCenter.y; - calMat.M[2][3] = -MagCenter.z; - return calMat; -} - -bool MagCalibration::SetCalibration(SensorFusion& sf) -{ - if (SampleCount < 4) - return false; - - MagCenter = CalculateSphereCenter(MagSamples[0],MagSamples[1],MagSamples[2],MagSamples[3]); - Matrix4f calMat = GetMagCalibration(); - sf.SetMagCalibration(calMat); - Stat = Mag_Calibrated; - //LogText("MagCenter: %f %f %f\n",MagCenter.x,MagCenter.y,MagCenter.z); - - return true; -} - - -// Calculate the center of a sphere that passes through p1, p2, p3, p4 -Vector3f MagCalibration::CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2, - const Vector3f& p3, const Vector3f& p4) -{ - Matrix4f A; - int i; - Vector3f p[4]; - p[0] = p1; - p[1] = p2; - p[2] = p3; - p[3] = p4; - - for (i = 0; i < 4; i++) - { - A.M[i][0] = p[i].x; - A.M[i][1] = p[i].y; - A.M[i][2] = p[i].z; - A.M[i][3] = 1.0f; - } - float m11 = A.Determinant(); - OVR_ASSERT(m11 != 0.0f); - - for (i = 0; i < 4; i++) - { - A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z; - A.M[i][1] = p[i].y; - A.M[i][2] = p[i].z; - A.M[i][3] = 1.0f; - } - float m12 = A.Determinant(); - - for (i = 0; i < 4; i++) - { - A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z; - A.M[i][1] = p[i].x; - A.M[i][2] = p[i].z; - A.M[i][3] = 1.0f; - } - float m13 = A.Determinant(); - - for (i = 0; i < 4; i++) - { - A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z; - A.M[i][1] = p[i].x; - A.M[i][2] = p[i].y; - A.M[i][3] = 1.0f; - } - float m14 = A.Determinant(); - - float c = 0.5f / m11; - return Vector3f(c*m12, -c*m13, c*m14); -} - -// Distance from p4 to the nearest point on a plane through p1, p2, p3 -float MagCalibration::PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2, - const Vector3f& p3, const Vector3f& p4) -{ - Vector3f v1 = p1 - p2; - Vector3f v2 = p1 - p3; - Vector3f planeNormal = v1.Cross(v2); - planeNormal.Normalize(); - return (fabs((planeNormal * p4) - planeNormal * p1)); -} - -}} diff --git a/LibOVR/Src/Util/Util_MagCalibration.h b/LibOVR/Src/Util/Util_MagCalibration.h deleted file mode 100644 index 1f8e8cb..0000000 --- a/LibOVR/Src/Util/Util_MagCalibration.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : Util_MagCalibration.h -Content : Procedures for calibrating the magnetometer -Created : April 16, 2013 -Authors : Steve LaValle, Andrew Reisse - -Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. - -Use of this software is subject to the terms of the Oculus license -agreement provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -*************************************************************************************/ - -#ifndef OVR_Util_MagCalibration_h -#define OVR_Util_MagCalibration_h - -#include "../OVR_SensorFusion.h" -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_Log.h" - -namespace OVR { namespace Util { - -class MagCalibration -{ -public: - enum MagStatus - { - Mag_Uninitialized = 0, - Mag_AutoCalibrating = 1, - Mag_ManuallyCalibrating = 2, - Mag_Calibrated = 3 - }; - - MagCalibration() : - Stat(Mag_Uninitialized), - MinMagDistance(0.2f), MinQuatDistance(0.5f), - SampleCount(0) - { - MinMagDistanceSq = MinMagDistance * MinMagDistance; - MinQuatDistanceSq = MinQuatDistance * MinQuatDistance; - MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f); - MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f); - MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f); - MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f); - } - - // Methods that are useful for either auto or manual calibration - bool IsUnitialized() const { return Stat == Mag_Uninitialized; } - bool IsCalibrated() const { return Stat == Mag_Calibrated; } - int NumberOfSamples() const { return SampleCount; } - int RequiredSampleCount() const { return 4; } - void AbortCalibration() - { - Stat = Mag_Uninitialized; - SampleCount = 0; - } - - void ClearCalibration(SensorFusion& sf) - { - Stat = Mag_Uninitialized; - SampleCount = 0; - sf.ClearMagCalibration(); - }; - - // Methods for automatic magnetometer calibration - void BeginAutoCalibration(SensorFusion& sf); - unsigned UpdateAutoCalibration(SensorFusion& sf); - bool IsAutoCalibrating() const { return Stat == Mag_AutoCalibrating; } - - // Methods for building a manual (user-guided) calibraton procedure - void BeginManualCalibration(SensorFusion& sf); - bool IsAcceptableSample(const Quatf& q, const Vector3f& m); - bool InsertIfAcceptable(const Quatf& q, const Vector3f& m); - // Returns true if successful, requiring that SampleCount = 4 - bool SetCalibration(SensorFusion& sf); - bool IsManuallyCalibrating() const { return Stat == Mag_ManuallyCalibrating; } - - // This is the minimum acceptable distance (Euclidean) between raw - // magnetometer values to be acceptable for usage in calibration. - void SetMinMagDistance(float dist) - { - MinMagDistance = dist; - MinMagDistanceSq = MinMagDistance * MinMagDistance; - } - - // The minimum acceptable distance (4D Euclidean) between orientations - // to be acceptable for calibration usage. - void SetMinQuatDistance(float dist) - { - MinQuatDistance = dist; - MinQuatDistanceSq = MinQuatDistance * MinQuatDistance; - } - - // A result of the calibration, which is the center of a sphere that - // roughly approximates the magnetometer data. - Vector3f GetMagCenter() const { return MagCenter; } - // Retrieves the full magnetometer calibration matrix - Matrix4f GetMagCalibration() const; - // Retrieves the range of each quaternion term during calibration - Quatf GetCalibrationQuatSpread() const { return QuatSpread; } - // Retrieves the range of each magnetometer term during calibration - Vector3f GetCalibrationMagSpread() const { return MagSpread; } - -private: - // Determine the unique sphere through 4 non-coplanar points - Vector3f CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2, - const Vector3f& p3, const Vector3f& p4); - - // Distance from p4 to the nearest point on a plane through p1, p2, p3 - float PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2, - const Vector3f& p3, const Vector3f& p4); - - Vector3f MagCenter; - unsigned Stat; - float MinMagDistance; - float MinQuatDistance; - float MinMagDistanceSq; - float MinQuatDistanceSq; - // For gathering statistics during calibration - Vector3f MinMagValues; - Vector3f MaxMagValues; - Vector3f MagSpread; - Quatf MinQuatValues; - Quatf MaxQuatValues; - Quatf QuatSpread; - - unsigned SampleCount; - Vector3f MagSamples[4]; - Quatf QuatSamples[4]; - -}; - -}} - -#endif |