Working on upgrading to latest version of Oculus software and adding Linux

support.
This commit is contained in:
Andrzej Kapolka 2013-08-05 14:10:47 -07:00
parent fe877b0ec8
commit 98a0c01b29
35 changed files with 1220 additions and 200 deletions

View file

@ -20,6 +20,10 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
if (APPLE)
find_library(LIBOVR_LIBRARIES libovr.a ${LIBOVR_ROOT_DIR}/Lib/MacOS/)
elseif (UNIX)
find_library(LIBOVR_LIBRARY libovr.a ${LIBOVR_ROOT_DIR}/Lib/UNIX/)
find_library(LIBUDEV_LIBRARY libudev.a)
set(LIBOVR_LIBRARIES ${LIBOVR_LIBRARY} ${LIBUDEV_LIBRARY})
elseif (WIN32)
find_library(LIBOVR_LIBRARIES libovr.lib ${LIBOVR_ROOT_DIR}/Lib/Win32/)
endif ()
@ -41,4 +45,4 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
# show the LIBOVR_INCLUDE_DIRS and LIBOVR_LIBRARIES variables only in the advanced view
mark_as_advanced(LIBOVR_INCLUDE_DIRS LIBOVR_LIBRARIES)
endif (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
endif (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)

View file

@ -131,6 +131,7 @@ include_directories(
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${OPENCV_INCLUDE_DIRS}")
target_link_libraries(
${TARGET_NAME}
${LIBOVR_LIBRARIES}
${LIBVPX_LIBRARIES}
${MOTIONDRIVER_LIBRARIES}
${OPENCV_LIBRARIES}
@ -170,7 +171,6 @@ if (APPLE)
${QTKit}
${QuartzCore}
${UVCCAMERACONTROL_LIBRARIES}
${LIBOVR_LIBRARIES}
)
if (LEAP_FOUND)

View file

@ -25,8 +25,10 @@ otherwise accompanies this software in either electronic or hard copy form.
#include "../Src/OVR_DeviceHandle.h"
#include "../Src/OVR_DeviceMessages.h"
#include "../Src/OVR_SensorFusion.h"
#include "../Src/OVR_Profile.h"
#include "../Src/Util/Util_LatencyTest.h"
#include "../Src/Util/Util_Render_Stereo.h"
#include "../Src/Util/Util_MagCalibration.h"
#endif

View file

@ -16,7 +16,7 @@ otherwise accompanies this software in either electronic or hard copy form.
#define OVR_MAJOR_VERSION 0
#define OVR_MINOR_VERSION 2
#define OVR_BUILD_VERSION 1
#define OVR_VERSION_STRING "0.2.1"
#define OVR_BUILD_VERSION 3
#define OVR_VERSION_STRING "0.2.3"
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1019,6 +1019,85 @@ public:
typedef Quat<float> Quatf;
typedef Quat<double> Quatd;
//-------------------------------------------------------------------------------------
// ***** Angle
// Cleanly representing the algebra of 2D rotations.
// The operations maintain the angle between -Pi and Pi, the same range as atan2.
//
template<class T>
class Angle
{
public:
enum AngularUnits
{
Radians = 0,
Degrees = 1
};
Angle() : a(0) {}
// Fix the range to be between -Pi and Pi
Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*Math<T>::DegreeToRadFactor) { FixRange(); }
T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*Math<T>::RadToDegreeFactor; }
void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*Math<T>::DegreeToRadFactor; FixRange(); }
int Sign() const { if (a == 0) return 0; else return (a > 0) ? 1 : -1; }
T Abs() const { return (a > 0) ? a : -a; }
bool operator== (const Angle& b) const { return a == b.a; }
bool operator!= (const Angle& b) const { return a != b.a; }
// bool operator< (const Angle& b) const { return a < a.b; }
// bool operator> (const Angle& b) const { return a > a.b; }
// bool operator<= (const Angle& b) const { return a <= a.b; }
// bool operator>= (const Angle& b) const { return a >= a.b; }
// bool operator= (const T& x) { a = x; FixRange(); }
// These operations assume a is already between -Pi and Pi.
Angle operator+ (const Angle& b) const { return Angle(a + b.a); }
Angle operator+ (const T& x) const { return Angle(a + x); }
Angle& operator+= (const Angle& b) { a = a + b.a; FastFixRange(); return *this; }
Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; }
Angle operator- (const Angle& b) const { return Angle(a - b.a); }
Angle operator- (const T& x) const { return Angle(a - x); }
Angle& operator-= (const Angle& b) { a = a - b.a; FastFixRange(); return *this; }
Angle& operator-= (const T& x) { a = a - x; FixRange(); return *this; }
T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= Math<T>::Pi) ? c : Math<T>::TwoPi - c; }
private:
// The stored angle, which should be maintained between -Pi and Pi
T a;
// Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side
inline void FastFixRange()
{
if (a < -Math<T>::Pi)
a += Math<T>::TwoPi;
else if (a > Math<T>::Pi)
a -= Math<T>::TwoPi;
}
// Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method
inline void FixRange()
{
a = fmod(a,Math<T>::TwoPi);
if (a < -Math<T>::Pi)
a += Math<T>::TwoPi;
else if (a > Math<T>::Pi)
a -= Math<T>::TwoPi;
}
};
typedef Angle<float> Anglef;
typedef Angle<double> Angled;
//-------------------------------------------------------------------------------------
// ***** Plane

View file

@ -24,14 +24,19 @@ otherwise accompanies this software in either electronic or hard copy form.
#include "Kernel/OVR_Atomic.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
namespace OVR {
// Declared externally
class Profile;
class ProfileManager; // << Should be renamed for consistency
// Forward declarations
class SensorDevice;
class DeviceCommon;
class DeviceManager;
// MessageHandler is a base class from which users derive to receive messages,
// its OnMessage handler will be called for messages once it is installed on
// a device. Same message handler can be installed on multiple devices.
@ -102,6 +107,8 @@ public:
virtual DeviceType GetType() const;
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// returns the MessageHandler's lock
Lock* GetHandlerLock() const;
protected:
// Internal
virtual DeviceCommon* getDeviceCommon() const = 0;
@ -228,6 +235,10 @@ public:
virtual DeviceType GetType() const { return Device_Manager; }
virtual DeviceManager* GetManager() const { return const_cast<DeviceManager*>(this); }
// Every DeviceManager has an associated profile manager, which us used to store
// user settings that may affect device behavior.
virtual ProfileManager* GetProfileManager() const = 0;
// EnumerateDevices enumerates all of the available devices of the specified class,
// returning an enumerator that references the first device. An empty enumerator is
@ -251,14 +262,18 @@ public:
// End users should call DeumerateDevices<>() instead.
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args) = 0;
// Creates a new DeviceManager. Only one instance of DeviceManager should be created at a time.
static DeviceManager* Create();
// Static constant for this device type, used in template cast type checks.
enum { EnumDeviceType = Device_Manager };
// Adds a device (DeviceCreateDesc*) into Devices. Returns NULL,
// if unsuccessful or device is already in the list.
virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc) = 0;
protected:
DeviceEnumerator<> enumeratorFromHandle(const DeviceHandle& h, const DeviceEnumerationArgs& args)
{ return DeviceEnumerator<>(h, args); }
@ -368,6 +383,14 @@ public:
memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName));
DisplayId = src.DisplayId;
}
bool IsSameDisplay(const HMDInfo& o) const
{
return DisplayId == o.DisplayId &&
String::CompareNoCase(DisplayDeviceName,
o.DisplayDeviceName) == 0;
}
};
@ -389,10 +412,29 @@ public:
// Static constant for this device type, used in template cast type checks.
enum { EnumDeviceType = Device_HMD };
virtual DeviceType GetType() const { return Device_HMD; }
virtual DeviceType GetType() const { return Device_HMD; }
// Creates a sensor associated with this HMD.
virtual SensorDevice* GetSensor() = 0;
// Requests the currently used profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const = 0;
// Obtains the currently used profile name. This is initialized to the default
// profile name, if any; it can then be changed per-device by SetProfileName.
virtual const char* GetProfileName() const = 0;
// Sets the profile user name, changing the data returned by GetProfileInfo.
virtual bool SetProfileName(const char* name) = 0;
// Disconnects from real HMD device. This HMDDevice remains as 'fake' HMD.
// SensorDevice ptr is used to restore the 'fake' HMD (can be NULL).
HMDDevice* Disconnect(SensorDevice*);
// Returns 'true' if HMD device is a 'fake' HMD (was created this way or
// 'Disconnect' method was called).
bool IsDisconnected() const;
};
@ -479,6 +521,17 @@ public:
virtual void SetCoordinateFrame(CoordinateFrame coordframe) = 0;
virtual CoordinateFrame GetCoordinateFrame() const = 0;
// 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.
virtual void SetReportRate(unsigned rateHz) = 0;
// Returns currently set report rate, in Hz. If 0 - error occurred.
// Note, this value may be different from the one provided for SetReportRate. The return
// value will contain the actual rate.
virtual unsigned GetReportRate() const = 0;
// Sets maximum range settings for the sensor described by SensorRange.
// The function will fail if you try to pass values outside Maximum supported
@ -509,34 +562,6 @@ struct LatencyTestConfiguration
bool SendSamples;
};
//-------------------------------------------------------------------------------------
// ***** LatencyTestCalibrate
// LatencyTestCalibrate specifies colors used for Latency Tester calibration.
struct LatencyTestCalibrate
{
LatencyTestCalibrate(const Color& value)
: Value(value)
{
}
// The color being calibrated to.
Color Value;
};
//-------------------------------------------------------------------------------------
// ***** LatencyTestStartTest
// LatencyTestStartTest specifies values used when starting the Latency Tester test.
struct LatencyTestStartTest
{
LatencyTestStartTest(const Color& targetValue)
: TargetValue(targetValue)
{
}
// The color value that the display is being set to.
Color TargetValue;
};
//-------------------------------------------------------------------------------------
// ***** LatencyTestDisplay
// LatencyTestDisplay sets the mode and contents of the Latency Tester LED display.
@ -574,19 +599,19 @@ public:
// Get configuration information from device.
virtual bool GetConfiguration(LatencyTestConfiguration* configuration) = 0;
// Used to calibrate the latency tester at the start of a test. Calibration information is lost
// Used to calibrate the latency tester at the start of a test. Display the specified color on the screen
// beneath the latency tester and then call this method. Calibration information is lost
// when power is removed from the device.
virtual bool SetCalibrate(const LatencyTestCalibrate& calibrate, bool waitFlag = false) = 0;
// Get calibration information from device.
virtual bool GetCalibrate(LatencyTestCalibrate* calibrate) = 0;
virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false) = 0;
// Triggers the start of a measurement. This starts the millisecond timer on the device and
// causes it to respond with the 'MessageLatencyTestStarted' message.
virtual bool SetStartTest(const LatencyTestStartTest& start, bool waitFlag = false) = 0;
virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false) = 0;
// Used to set the value displayed on the LED display panel.
virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false) = 0;
virtual DeviceBase* GetDevice() { return this; }
};
} // namespace OVR

View file

@ -59,15 +59,30 @@ public:
// operator bool() returns true if Handle/Enumerator points to a valid device.
operator bool () const { return GetType() != Device_None; }
// Returns existing device, or NULL if !IsCreated. The returned ptr is
// addref-ed.
DeviceBase* GetDevice_AddRef() const;
DeviceType GetType() const;
bool GetDeviceInfo(DeviceInfo* info) const;
bool IsAvailable() const;
bool IsCreated() const;
// Returns true, if the handle contains the same device ptr
// as specified in the parameter.
bool IsDevice(DeviceBase*) const;
// Creates a device, or returns AddRefed pointer if one is already created.
// New devices start out with RefCount of 1.
DeviceBase* CreateDevice();
// Creates a device, or returns AddRefed pointer if one is already created.
// New devices start out with RefCount of 1. DeviceT is used to cast the
// DeviceBase* to a concreete type.
template <class DeviceT>
DeviceT* CreateDeviceTyped() const
{
return static_cast<DeviceT*>(DeviceHandle(*this).CreateDevice());
}
// Resets the device handle to uninitialized state.
void Clear();

View file

@ -30,12 +30,18 @@ namespace OVR {
class DeviceManagerImpl;
class DeviceFactory;
enum
{
Oculus_VendorId = 0x2833
};
//-------------------------------------------------------------------------------------
// Globally shared Lock implementation used for MessageHandlers.
class SharedLock
{
public:
SharedLock() : UseCount(0) {}
Lock* GetLockAddRef();
void ReleaseLock(Lock* plock);
@ -127,8 +133,8 @@ public:
RemoveNode();
}
DeviceManagerImpl* GetManagerImpl() { return pLock->pManager; }
Lock* GetLock() const { return &pLock->CreateLock; }
DeviceManagerImpl* GetManagerImpl() const { return pLock->pManager; }
Lock* GetLock() const { return &pLock->CreateLock; }
// DeviceCreateDesc reference counting is tied to Devices list management,
// see comments for HandleCount.
@ -160,12 +166,21 @@ public:
// but more searching is necessary. If this is the case UpdateMatchedCandidate will be called.
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc** pcandidate) const = 0;
// Called for matched candidate after all potential matches are iterated.
// Used to update HMDevice creation arguments from Sensor.
// Optional return param 'newDeviceFlag' will be set to true if the
// 'desc' refers to a new device; false, otherwise.
// Return 'false' to create new object, 'true' if done with this argument.
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&) { return false; }
virtual bool UpdateMatchedCandidate(
const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL)
{ OVR_UNUSED2(desc, newDeviceFlag); return false; }
// Matches HID device to the descriptor.
virtual bool MatchHIDDevice(const HIDDeviceDesc&) const { return false; }
// Matches device by path.
virtual bool MatchDevice(const String& /*path*/) { return false; }
//protected:
DeviceFactory* const pFactory;
const DeviceType Type;
@ -292,6 +307,22 @@ public:
// Enumerates factory devices by notifying EnumerateVisitor about every
// device that is present.
virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0;
// Matches vendorId/productId pair with the factory; returns 'true'
// if the factory can handle the device.
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
{
OVR_UNUSED2(vendorId, productId);
return false;
}
// Detects the HID device and adds the DeviceCreateDesc into Devices list, if
// the device belongs to this factory. Returns 'false', if not.
virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
{
OVR_UNUSED2(pdevMgr, desc);
return false;
}
protected:
DeviceManagerImpl* pManager;
@ -318,10 +349,17 @@ public:
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Every DeviceManager has an associated profile manager, which us used to store
// user settings that may affect device behavior.
virtual ProfileManager* GetProfileManager() const { return pProfileManager.GetPtr(); }
// Override to return ThreadCommandQueue implementation used to post commands
// to the background device manager thread (that must be created by Initialize).
virtual ThreadCommandQueue* GetThreadQueue() = 0;
// Returns the thread id of the DeviceManager.
virtual ThreadId GetThreadId() const = 0;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
@ -361,11 +399,21 @@ public:
// Enumerates devices for a particular factory.
virtual Void EnumerateFactoryDevices(DeviceFactory* factory);
virtual HIDDeviceManager* GetHIDDeviceManager()
virtual HIDDeviceManager* GetHIDDeviceManager() const
{
return HidDeviceManager;
}
// Adds device (DeviceCreateDesc*) into Devices. Returns NULL,
// if unsuccessful or device is already in the list.
virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc);
// Finds a device descriptor by path and optional type.
Ptr<DeviceCreateDesc> FindDevice(const String& path, DeviceType = Device_None);
// Finds HID device by HIDDeviceDesc.
Ptr<DeviceCreateDesc> FindHIDDevice(const HIDDeviceDesc&);
void DetectHIDDevice(const HIDDeviceDesc&);
// Manager Lock-protected list of devices.
List<DeviceCreateDesc> Devices;
@ -375,6 +423,7 @@ public:
protected:
Ptr<HIDDeviceManager> HidDeviceManager;
Ptr<ProfileManager> pProfileManager;
};

View file

@ -93,7 +93,8 @@ public:
float TimeDelta; // Time passed since last Body Frame, in seconds.
};
// Sent when we receive a device status changes.
// Sent when we receive a device status changes (e.g.:
// Message_DeviceAdded, Message_DeviceRemoved).
class MessageDeviceStatus : public Message
{
public:

View file

@ -123,8 +123,8 @@ public:
enum HIDDeviceMessageType
{
HIDDeviceMessage_DeviceAdded = 0,
HIDDeviceMessage_DeviceRemoved = 1,
HIDDeviceMessage_DeviceAdded = 0,
HIDDeviceMessage_DeviceRemoved = 1
};
virtual void OnDeviceMessage(HIDDeviceMessageType messageType)

View file

@ -30,6 +30,12 @@ public:
HIDDeviceCreateDesc(const HIDDeviceCreateDesc& other)
: DeviceCreateDesc(other.pFactory, other.Type), HIDDesc(other.HIDDesc) { }
virtual bool MatchDevice(const String& path)
{
// should it be case insensitive?
return HIDDesc.Path.CompareNoCase(path) == 0;
}
HIDDeviceDesc HIDDesc;
};
@ -46,19 +52,18 @@ public:
// HIDDevice::Handler interface.
virtual void OnDeviceMessage(HIDDeviceMessageType messageType)
{
MessageType handlerMessageType = handlerMessageType = Message_DeviceAdded;
if (messageType == HIDDeviceMessage_DeviceAdded)
{
}
else if (messageType == HIDDeviceMessage_DeviceRemoved)
{
handlerMessageType = Message_DeviceRemoved;
}
else
{
OVR_ASSERT(0);
}
MessageType handlerMessageType;
switch (messageType) {
case HIDDeviceMessage_DeviceAdded:
handlerMessageType = Message_DeviceAdded;
break;
case HIDDeviceMessage_DeviceRemoved:
handlerMessageType = Message_DeviceRemoved;
break;
default: OVR_ASSERT(0); return;
}
// Do device notification.
{
@ -71,17 +76,18 @@ public:
}
}
// Do device manager notification.
DeviceManagerImpl* manager = this->GetManagerImpl();
if (handlerMessageType == Message_DeviceAdded)
{
manager->CallOnDeviceAdded(this->pCreateDesc);
}
else if (handlerMessageType == Message_DeviceRemoved)
{
manager->CallOnDeviceRemoved(this->pCreateDesc);
switch (handlerMessageType) {
case Message_DeviceAdded:
manager->CallOnDeviceAdded(this->pCreateDesc);
break;
case Message_DeviceRemoved:
manager->CallOnDeviceRemoved(this->pCreateDesc);
break;
default:;
}
}
@ -177,7 +183,7 @@ public:
}
protected:
HIDDevice* GetInternalDevice()
HIDDevice* GetInternalDevice() const
{
return InternalDevice;
}

143
interface/external/LibOVR/Src/OVR_JSON.h vendored Executable file
View file

@ -0,0 +1,143 @@
/************************************************************************************
PublicHeader: None
Filename : OVR_JSON.h
Content : JSON format reader and writer
Created : April 9, 2013
Author : Brant Lewis
Notes :
Copyright : Copyright 2012 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_JSON_H
#define OVR_JSON_H
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_List.h"
namespace OVR {
// JSONItemType describes the type of JSON item, specifying the type of
// data that can be obtained from it.
enum JSONItemType
{
JSON_None = 0,
JSON_Null = 1,
JSON_Bool = 2,
JSON_Number = 3,
JSON_String = 4,
JSON_Array = 5,
JSON_Object = 6
};
//-----------------------------------------------------------------------------
// ***** JSON
// JSON object represents a JSON node that can be either a root of the JSON tree
// or a child item. Every node has a type that describes what is is.
// New JSON trees are typically loaded JSON::Load or created with JSON::Parse.
class JSON : public RefCountBase<JSON>, public ListNode<JSON>
{
protected:
List<JSON> Children;
public:
JSONItemType Type; // Type of this JSON node.
String Name; // Name part of the {Name, Value} pair in a parent object.
String Value;
double dValue;
public:
~JSON();
// *** Creation of NEW JSON objects
static JSON* CreateObject() { return new JSON(JSON_Object);}
static JSON* CreateNull() { return new JSON(JSON_Null); }
static JSON* CreateArray() { return new JSON(JSON_Array); }
static JSON* CreateBool(bool b) { return createHelper(JSON_Bool, b ? 1.0 : 0.0); }
static JSON* CreateNumber(double num) { return createHelper(JSON_Number, num); }
static JSON* CreateString(const char *s) { return createHelper(JSON_String, 0.0, s); }
// Creates a new JSON object from parsing string.
// Returns null pointer and fills in *perror in case of parse error.
static JSON* Parse(const char* buff, const char** perror = 0);
// Loads and parses a JSON object from a file.
// Returns 0 and assigns perror with error message on fail.
static JSON* Load(const char* path, const char** perror = 0);
// Saves a JSON object to a file.
bool Save(const char* path);
// *** Object Member Access
// These provide access to child items of the list.
bool HasItems() const { return Children.IsEmpty(); }
// Returns first/last child item, or null if child list is empty
JSON* GetFirstItem() { return (!Children.IsEmpty()) ? Children.GetFirst() : 0; }
JSON* GetLastItem() { return (!Children.IsEmpty()) ? Children.GetLast() : 0; }
// Counts the number of items in the object; these methods are inefficient.
unsigned GetItemCount() const;
JSON* GetItemByIndex(unsigned i);
JSON* GetItemByName(const char* name);
// Returns next item in a list of children; 0 if no more items exist.
JSON* GetNextItem(JSON* item) { return Children.IsNull(item->pNext) ? 0 : item->pNext; }
JSON* GetPrevItem(JSON* item) { return Children.IsNull(item->pPrev) ? 0 : item->pPrev; }
// Child item access functions
void AddItem(const char *string, JSON* item);
void AddNullItem(const char* name) { AddItem(name, CreateNull()); }
void AddBoolItem(const char* name, bool b) { AddItem(name, CreateBool(b)); }
void AddNumberItem(const char* name, double n) { AddItem(name, CreateNumber(n)); }
void AddStringItem(const char* name, const char* s) { AddItem(name, CreateString(s)); }
// void ReplaceItem(unsigned index, JSON* new_item);
// void DeleteItem(unsigned index);
// *** Array Element Access
// Add new elements to the end of array.
void AddArrayElement(JSON *item);
void AddArrayNumber(double n) { AddArrayElement(CreateNumber(n)); }
void AddArrayString(const char* s) { AddArrayElement(CreateString(s)); }
// Accessed array elements; currently inefficient.
int GetArraySize();
double GetArrayNumber(int index);
const char* GetArrayString(int index);
protected:
JSON(JSONItemType itemType = JSON_Object);
static JSON* createHelper(JSONItemType itemType, double dval, const char* strVal = 0);
// JSON Parsing helper functions.
const char* parseValue(const char *buff, const char** perror);
const char* parseNumber(const char *num);
const char* parseArray(const char* value, const char** perror);
const char* parseObject(const char* value, const char** perror);
const char* parseString(const char* str, const char** perror);
char* PrintValue(int depth, bool fmt);
char* PrintObject(int depth, bool fmt);
char* PrintArray(int depth, bool fmt);
};
}
#endif

View file

@ -35,6 +35,9 @@ public:
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const;
virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
@ -60,13 +63,18 @@ public:
if ((other.Type == Device_LatencyTester) && (pFactory == other.pFactory))
{
const LatencyTestDeviceCreateDesc& s2 = (const LatencyTestDeviceCreateDesc&) other;
if ((HIDDesc.Path == s2.HIDDesc.Path) &&
(HIDDesc.SerialNumber == s2.HIDDesc.SerialNumber))
if (MatchHIDDevice(s2.HIDDesc))
return Match_Found;
}
return Match_None;
}
virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
{
// should paths comparison be case insensitive?
return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
(HIDDesc.SerialNumber == hidDesc.SerialNumber));
}
virtual bool GetDeviceInfo(DeviceInfo* info) const;
};
@ -93,10 +101,9 @@ public:
virtual bool SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag = false);
virtual bool GetConfiguration(OVR::LatencyTestConfiguration* configuration);
virtual bool SetCalibrate(const OVR::LatencyTestCalibrate& calibrate, bool waitFlag = false);
virtual bool GetCalibrate(OVR::LatencyTestCalibrate* calibrate);
virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false);
virtual bool SetStartTest(const OVR::LatencyTestStartTest& start, bool waitFlag = false);
virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false);
virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false);
protected:
@ -109,9 +116,8 @@ protected:
bool setConfiguration(const OVR::LatencyTestConfiguration& configuration);
bool getConfiguration(OVR::LatencyTestConfiguration* configuration);
bool setCalibrate(const OVR::LatencyTestCalibrate& calibrate);
bool getCalibrate(OVR::LatencyTestCalibrate* calibrate);
bool setStartTest(const OVR::LatencyTestStartTest& start);
bool setCalibrate(const Color& calibrationColor);
bool setStartTest(const Color& targetColor);
bool setDisplay(const OVR::LatencyTestDisplay& display);
// Called for decoded messages

View file

@ -0,0 +1,111 @@
/************************************************************************************
Filename : OVR_Linux_DeviceManager.h
Content : Linux-specific DeviceManager header.
Created :
Authors :
Copyright : Copyright 2012 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_Linux_DeviceManager_h
#define OVR_Linux_DeviceManager_h
#include "OVR_DeviceImpl.h"
#include <unistd.h>
#include <sys/poll.h>
namespace OVR { namespace Linux {
class DeviceManagerThread;
//-------------------------------------------------------------------------------------
// ***** Linux DeviceManager
class DeviceManager : public DeviceManagerImpl
{
public:
DeviceManager();
~DeviceManager();
// Initialize/Shutdowncreate and shutdown manger thread.
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
virtual ThreadCommandQueue* GetThreadQueue();
virtual ThreadId GetThreadId() const;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
Ptr<DeviceManagerThread> pThread;
};
//-------------------------------------------------------------------------------------
// ***** Device Manager Background Thread
class DeviceManagerThread : public Thread, public ThreadCommandQueue
{
friend class DeviceManager;
enum { ThreadStackSize = 64 * 1024 };
public:
DeviceManagerThread();
~DeviceManagerThread();
virtual int Run();
// ThreadCommandQueue notifications for CommandEvent handling.
virtual void OnPushNonEmpty_Locked() { write(CommandFd[1], this, 1); }
virtual void OnPopEmpty_Locked() { }
class Notifier
{
public:
// Called when I/O is received
virtual void OnEvent(int i, int fd) = 0;
// Called when timing ticks are updated.
// Returns the largest number of microseconds this function can
// wait till next call.
virtual UInt64 OnTicks(UInt64 ticksMks)
{
OVR_UNUSED1(ticksMks);
return Timer::MksPerSecond * 1000;
}
};
// Add I/O notifier
bool AddSelectFd(Notifier* notify, int fd);
bool RemoveSelectFd(Notifier* notify, int fd);
// Add notifier that will be called at regular intervals.
bool AddTicksNotifier(Notifier* notify);
bool RemoveTicksNotifier(Notifier* notify);
private:
bool threadInitialized() { return CommandFd[0] != 0; }
// pipe used to signal commands
int CommandFd[2];
Array<struct pollfd> PollFds;
Array<Notifier*> FdNotifiers;
Event StartupEvent;
// Ticks notifiers - used for time-dependent events such as keep-alive.
Array<Notifier*> TicksNotifiers;
};
}} // namespace Linux::OVR
#endif // OVR_Linux_DeviceManager_h

View file

@ -0,0 +1,124 @@
/************************************************************************************
Filename : OVR_Linux_HIDDevice.h
Content : Linux HID device implementation.
Created : June 13, 2013
Authors : Brant Lewis
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_LINUX_HIDDevice_h
#define OVR_LINUX_HIDDevice_h
#include "OVR_HIDDevice.h"
#include "OVR_Linux_DeviceManager.h"
#include <libudev.h>
namespace OVR { namespace Linux {
class HIDDeviceManager;
//-------------------------------------------------------------------------------------
// ***** Linux HIDDevice
class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
{
private:
friend class HIDDeviceManager;
public:
HIDDevice(HIDDeviceManager* manager);
// 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(HIDDeviceManager* manager, int device_handle);
virtual ~HIDDevice();
bool HIDInitialize(const String& path);
void HIDShutdown();
virtual bool SetFeatureReport(UByte* data, UInt32 length);
virtual bool GetFeatureReport(UByte* data, UInt32 length);
// DeviceManagerThread::Notifier
void OnEvent(int i, int fd);
UInt64 OnTicks(UInt64 ticksMks);
bool OnDeviceNotification(MessageType messageType,
HIDDeviceDesc* device_info,
bool* error);
private:
bool initInfo();
bool openDevice(const char* dev_path);
void closeDevice(bool wasUnplugged);
void closeDeviceOnIOError();
bool setupDevicePluggedInNotification();
bool InMinimalMode;
HIDDeviceManager* HIDManager;
int DeviceHandle; // file handle to the device
HIDDeviceDesc DevDesc;
enum { ReadBufferSize = 96 };
UByte ReadBuffer[ReadBufferSize];
UInt16 InputReportBufferLength;
UInt16 OutputReportBufferLength;
UInt16 FeatureReportBufferLength;
};
//-------------------------------------------------------------------------------------
// ***** Linux HIDDeviceManager
class HIDDeviceManager : public OVR::HIDDeviceManager, public DeviceManagerThread::Notifier
{
friend class HIDDevice;
public:
HIDDeviceManager(Linux::DeviceManager* Manager);
virtual ~HIDDeviceManager();
virtual bool Initialize();
virtual void Shutdown();
virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
virtual OVR::HIDDevice* Open(const String& path);
static HIDDeviceManager* CreateInternal(DeviceManager* manager);
void OnEvent(int i, int fd);
private:
bool initializeManager();
bool initVendorProductVersion(udev_device* device, HIDDeviceDesc* pDevDesc);
bool getPath(udev_device* device, String* pPath);
bool getIntProperty(udev_device* device, const char* key, int32_t* pResult);
bool getStringProperty(udev_device* device,
const char* propertyName,
OVR::String* pResult);
bool getFullDesc(udev_device* device, HIDDeviceDesc* desc);
bool GetDescriptorFromPath(const char* dev_path, HIDDeviceDesc* desc);
bool AddNotificationDevice(HIDDevice* device);
bool RemoveNotificationDevice(HIDDevice* device);
DeviceManager* DevManager;
udev* UdevInstance; // a handle to the udev library instance
udev_monitor* HIDMonitor;
int HIDMonHandle; // the udev_monitor file handle
Array<HIDDevice*> NotificationDevices;
};
}} // namespace OVR::Linux
#endif // OVR_Linux_HIDDevice_h

View file

@ -0,0 +1,156 @@
/************************************************************************************
Filename : OVR_Linux_HMDDevice.h
Content : Linux HMDDevice implementation
Created : June 17, 2013
Authors : Brant Lewis
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_Linux_HMDDevice_h
#define OVR_Linux_HMDDevice_h
#include "OVR_Linux_DeviceManager.h"
#include "OVR_Profile.h"
namespace OVR { namespace Linux {
class HMDDevice;
//-------------------------------------------------------------------------------------
// HMDDeviceFactory enumerates attached Oculus HMD devices.
//
// This is currently done by matching monitor device strings.
class HMDDeviceFactory : public DeviceFactory
{
public:
static HMDDeviceFactory Instance;
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
class HMDDeviceCreateDesc : public DeviceCreateDesc
{
friend class HMDDevice;
protected:
enum
{
Contents_Screen = 1,
Contents_Distortion = 2,
Contents_7Inch = 4,
};
String DeviceId;
String DisplayDeviceName;
int DesktopX, DesktopY;
unsigned Contents;
unsigned HResolution, VResolution;
float HScreenSize, VScreenSize;
long DisplayId;
float DistortionK[4];
public:
HMDDeviceCreateDesc(DeviceFactory* factory, const String& displayDeviceName, long dispId);
HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other);
virtual DeviceCreateDesc* Clone() const
{
return new HMDDeviceCreateDesc(*this);
}
virtual DeviceBase* NewDeviceInstance();
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const;
// Matches device by path.
virtual bool MatchDevice(const String& path);
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
Profile* GetProfileAddRef() const;
ProfileType GetProfileType() const
{
return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
}
void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
{
DesktopX = x;
DesktopY = y;
HResolution = hres;
VResolution = vres;
HScreenSize = hsize;
VScreenSize = vsize;
Contents |= Contents_Screen;
}
void SetDistortion(const float* dks)
{
for (int i = 0; i < 4; i++)
DistortionK[i] = dks[i];
Contents |= Contents_Distortion;
}
void Set7Inch() { Contents |= Contents_7Inch; }
bool Is7Inch() const;
};
//-------------------------------------------------------------------------------------
// HMDDevice represents an Oculus HMD device unit. An instance of this class
// is typically created from the DeviceManager.
// After HMD device is created, we its sensor data can be obtained by
// first creating a Sensor object and then wrappig it in SensorFusion.
class HMDDevice : public DeviceImpl<OVR::HMDDevice>
{
public:
HMDDevice(HMDDeviceCreateDesc* createDesc);
~HMDDevice();
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const;
virtual const char* GetProfileName() const;
virtual bool SetProfileName(const char* name);
// Query associated sensor.
virtual OVR::SensorDevice* GetSensor();
protected:
HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
// User name for the profile used with this device.
String ProfileName;
mutable Ptr<Profile> pCachedProfile;
};
}} // namespace OVR::Linux
#endif // OVR_Linux_HMDDevice_h

View file

@ -21,6 +21,8 @@ otherwise accompanies this software in either electronic or hard copy form.
#include "Kernel/OVR_Timer.h"
#include <IOKit/hid/IOHIDManager.h>
#include <CoreGraphics/CGDirectDisplay.h>
#include <CoreGraphics/CGDisplayConfiguration.h>
namespace OVR { namespace OSX {
@ -41,11 +43,18 @@ public:
virtual void Shutdown();
virtual ThreadCommandQueue* GetThreadQueue();
virtual ThreadId GetThreadId() const;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
protected:
static void displayReconfigurationCallBack (CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
public: // data
Ptr<DeviceManagerThread> pThread;
};
@ -90,6 +99,7 @@ public:
CFRunLoopRef GetRunLoop()
{ return RunLoop; }
void Shutdown();
private:
CFRunLoopRef RunLoop;

View file

@ -45,8 +45,8 @@ public:
bool HIDInitialize(const String& path);
void HIDShutdown();
bool SetFeatureReport(UByte* data, UInt32 length);
bool GetFeatureReport(UByte* data, UInt32 length);
virtual bool SetFeatureReport(UByte* data, UInt32 length);
virtual bool GetFeatureReport(UByte* data, UInt32 length);
bool Write(UByte* data, UInt32 length);
@ -134,6 +134,11 @@ private:
bool getStringProperty(IOHIDDeviceRef device, CFStringRef propertyName, String* pResult);
bool getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc);
static void staticDeviceMatchingCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef);
DeviceManager* DevManager;
IOHIDManagerRef HIDManager;

View file

@ -18,6 +18,7 @@ otherwise accompanies this software in either electronic or hard copy form.
#include "OVR_DeviceImpl.h"
#include <Kernel/OVR_String.h>
#include "OVR_Profile.h"
namespace OVR { namespace OSX {
@ -71,10 +72,19 @@ public:
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const;
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&);
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
Profile* GetProfileAddRef() const;
ProfileType GetProfileType() const
{
return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
}
void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
{
DesktopX = x;
@ -125,8 +135,22 @@ public:
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const;
virtual const char* GetProfileName() const;
virtual bool SetProfileName(const char* name);
// Query associated sensor.
virtual OVR::SensorDevice* GetSensor();
protected:
HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
// User name for the profile used with this device.
String ProfileName;
mutable Ptr<Profile> pCachedProfile;
};

186
interface/external/LibOVR/Src/OVR_Profile.h vendored Executable file
View file

@ -0,0 +1,186 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Profile.h
Content : Structs and functions for loading and storing device profile settings
Created : February 14, 2013
Notes :
Profiles are used to store per-user settings that can be transferred and used
across multiple applications. For example, player IPD can be configured once
and reused for a unified experience across games. Configuration and saving of profiles
can be accomplished in game via the Profile API or by the official Oculus Configuration
Utility.
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_Profile_h
#define OVR_Profile_h
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_Array.h"
namespace OVR {
// Defines the profile object for each device type
enum ProfileType
{
Profile_Unknown = 0,
Profile_RiftDK1 = 1,
Profile_RiftDKHD = 2,
};
class Profile;
// -----------------------------------------------------------------------------
// ***** ProfileManager
// Profiles are interfaced through a ProfileManager object. Applications should
// create a ProfileManager each time they intend to read or write user profile data.
// The scope of the ProfileManager object defines when disk I/O is performed. Disk
// reads are performed on the first profile access and disk writes are performed when
// the ProfileManager goes out of scope. All profile interactions between these times
// are performed in local memory and are fast. A typical profile interaction might
// look like this:
//
// {
// Ptr<ProfileManager> pm = *ProfileManager::Create();
// Ptr<Profile> profile = pm->LoadProfile(Profile_RiftDK1,
// pm->GetDefaultProfileName(Profile_RiftDK1));
// if (profile)
// { // Retrieve the current profile settings
// }
// } // Profile will be destroyed and any disk I/O completed when going out of scope
class ProfileManager : public RefCountBase<ProfileManager>
{
protected:
// Synchronize ProfileManager access since it may be accessed from multiple threads,
// as it's shared through DeviceManager.
Lock ProfileLock;
Array<Ptr<Profile> > ProfileCache;
ProfileType CacheDevice;
String DefaultProfile;
bool Changed;
char NameBuff[32];
public:
static ProfileManager* Create();
// Static interface functions
int GetProfileCount(ProfileType device);
const char* GetProfileName(ProfileType device, unsigned int index);
bool HasProfile(ProfileType device, const char* name);
Profile* LoadProfile(ProfileType device, unsigned int index);
Profile* LoadProfile(ProfileType device, const char* name);
Profile* GetDeviceDefaultProfile(ProfileType device);
const char* GetDefaultProfileName(ProfileType device);
bool SetDefaultProfileName(ProfileType device, const char* name);
bool Save(const Profile* profile);
bool Delete(const Profile* profile);
protected:
ProfileManager();
~ProfileManager();
void LoadCache(ProfileType device);
void SaveCache();
void ClearCache();
Profile* CreateProfileObject(const char* user,
ProfileType device,
const char** device_name);
};
//-------------------------------------------------------------------
// ***** Profile
// The base profile for all HMD devices. This object is never created directly.
// Instead derived objects provide specific data implementations. Some settings
// such as IPD will be tied to a specific user and be consistent between ,
// implementations but other settings like optical distortion may vary between devices.
class Profile : public RefCountBase<Profile>
{
public:
enum { MaxNameLen = 32 };
enum GenderType
{
Gender_Unspecified = 0,
Gender_Male = 1,
Gender_Female = 2
};
ProfileType Type; // The type of device profile
char Name[MaxNameLen]; // The name given to this profile
protected:
GenderType Gender; // The gender of the user
float PlayerHeight; // The height of the user in meters
float IPD; // Distance between eyes in meters
public:
// These are properties which are intrinsic to the user and affect scene setup
GenderType GetGender() { return Gender; };
float GetPlayerHeight() { return PlayerHeight; };
float GetIPD() { return IPD; };
float GetEyeHeight();
void SetGender(GenderType gender) { Gender = gender; };
void SetPlayerHeight(float height) { PlayerHeight = height; };
void SetIPD(float ipd) { IPD = ipd; };
protected:
Profile(ProfileType type, const char* name);
virtual Profile* Clone() const = 0;
virtual bool ParseProperty(const char* prop, const char* sval);
friend class ProfileManager;
};
//-----------------------------------------------------------------------------
// ***** RiftDK1Profile
// This profile is specific to the Rift Dev Kit 1 and contains overrides specific
// to that device and lens cup settings.
class RiftDK1Profile : public Profile
{
public:
enum EyeCupType
{
EyeCup_A = 0,
EyeCup_B = 1,
EyeCup_C = 2
};
protected:
EyeCupType EyeCups; // Which eye cup does the player use
int LL; // Configuration Utility IPD setting
int LR; // Configuration Utility IPD setting
int RL; // Configuration Utility IPD setting
int RR; // Configuration Utility IPD setting
public:
EyeCupType GetEyeCup() { return EyeCups; };
void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
protected:
RiftDK1Profile(const char* name);
virtual Profile* Clone() const;
virtual bool ParseProperty(const char* prop, const char* sval);
friend class ProfileManager;
};
}
#endif // OVR_Profile_h

View file

@ -46,7 +46,7 @@ public:
};
// Create a new filter with size i
SensorFilter(const int &i)
SensorFilter(int i)
{
OVR_ASSERT(i <= MaxFilterSize);
LastIdx = -1;
@ -66,28 +66,30 @@ public:
};
// Get element i. 0 is the most recent, 1 is one step ago, 2 is two steps ago, ...
Vector3f GetPrev(const int &i)
Vector3f GetPrev(int i) const
{
int idx = (LastIdx - i) % Size;
if (idx < 0) // Fix the negative mod problem
OVR_ASSERT(i >= 0); //
int idx = (LastIdx - i);
if (idx < 0) // Fix the wraparound case
idx += Size;
OVR_ASSERT(idx >= 0); // Multiple wraparounds not allowed
return Elements[idx];
};
// Simple statistics
Vector3f Total();
Vector3f Mean();
Vector3f Median();
Vector3f Variance(); // The diagonal of covariance matrix
Matrix4f Covariance();
Vector3f PearsonCoefficient();
Vector3f Total() const;
Vector3f Mean() const;
Vector3f Median() const;
Vector3f Variance() const; // The diagonal of covariance matrix
Matrix4f Covariance() const;
Vector3f PearsonCoefficient() const;
// A popular family of smoothing filters and smoothed derivatives
Vector3f SavitzkyGolaySmooth8();
Vector3f SavitzkyGolayDerivative4();
Vector3f SavitzkyGolayDerivative5();
Vector3f SavitzkyGolayDerivative12();
Vector3f SavitzkyGolayDerivativeN(const int &n);
Vector3f SavitzkyGolaySmooth8() const;
Vector3f SavitzkyGolayDerivative4() const;
Vector3f SavitzkyGolayDerivative5() const;
Vector3f SavitzkyGolayDerivative12() const;
Vector3f SavitzkyGolayDerivativeN(int n) const;
~SensorFilter() {};
};

View file

@ -37,6 +37,11 @@ namespace OVR {
class SensorFusion : public NewOverrideBase
{
enum
{
MagMaxReferences = 80
};
public:
SensorFusion(SensorDevice* sensor = 0);
~SensorFusion();
@ -47,19 +52,19 @@ public:
bool AttachToSensor(SensorDevice* sensor);
// Returns true if this Sensor fusion object is attached to a sensor.
bool IsAttachedToSensor() const { return Handler.IsHandlerInstalled(); }
bool IsAttachedToSensor() const { return Handler.IsHandlerInstalled(); }
void SetGravityEnabled(bool enableGravity) { EnableGravity = enableGravity; }
void SetGravityEnabled(bool enableGravity) { EnableGravity = enableGravity; }
bool IsGravityEnabled() const { return EnableGravity;}
bool IsGravityEnabled() const { return EnableGravity;}
void SetYawCorrectionEnabled(bool enableYawCorrection) { EnableYawCorrection = enableYawCorrection; }
void SetYawCorrectionEnabled(bool enableYawCorrection) { EnableYawCorrection = enableYawCorrection; }
// Yaw correction is set up to work
bool IsYawCorrectionEnabled() const { return EnableYawCorrection;}
bool IsYawCorrectionEnabled() const { return EnableYawCorrection;}
// Yaw correction is currently working (forcing a corrective yaw rotation)
bool IsYawCorrectionInProgress() const { return YawCorrectionInProgress;}
bool IsYawCorrectionInProgress() const { return YawCorrectionInProgress;}
// Store the calibration matrix for the magnetometer
void SetMagCalibration(const Matrix4f& m)
@ -69,30 +74,13 @@ public:
}
// True only if the mag has calibration values stored
bool HasMagCalibration() const { return MagCalibrated;}
bool HasMagCalibration() const { return MagCalibrated;}
// Force the mag into the uncalibrated state
void ClearMagCalibration()
{
MagCalibrated = false;
MagReady = false;
}
// Set the magnetometer's reference orientation for use in yaw correction
void SetMagReference(const Quatf& q);
// Default to current HMD orientation
void SetMagReference() { SetMagReference(Q); }
bool HasMagReference() const { return MagReferenced; }
void ClearMagReference()
{
MagReferenced = false;
MagReady = false;
}
bool IsMagReady() const { return MagReady; }
void ClearMagCalibration() { MagCalibrated = false; }
// These refer to reference points that associate mag readings with orientations
void ClearMagReferences() { MagNumReferences = 0; }
void SetMagRefDistance(const float d) { MagRefDistance = d; }
// Notifies SensorFusion object about a new BodyFrame message from a sensor.
@ -109,11 +97,11 @@ public:
Lock::Locker lockScope(Handler.GetHandlerLock());
return Q;
}
Quatf GetPredictedOrientation() const
{
Lock::Locker lockScope(Handler.GetHandlerLock());
return QP;
}
// Use a predictive filter to estimate the future orientation
Quatf GetPredictedOrientation(float pdt); // Specify lookahead time in ms
Quatf GetPredictedOrientation() { return GetPredictedOrientation(PredictionDT); }
// Obtain the last absolute acceleration reading, in m/s^2.
Vector3f GetAcceleration() const
{
@ -129,35 +117,40 @@ public:
}
// Obtain the last magnetometer reading, in Gauss
Vector3f GetMagnetometer() const
{
Lock::Locker lockScope(Handler.GetHandlerLock());
return Mag;
}
// Obtain the raw magnetometer reading, in Gauss (uncalibrated!)
Vector3f GetRawMagnetometer() const
{
Lock::Locker lockScope(Handler.GetHandlerLock());
return RawMag;
}
// Obtain the filtered magnetometer reading, in Gauss
Vector3f GetFilteredMagnetometer() const
{
Lock::Locker lockScope(Handler.GetHandlerLock());
return FRawMag.Mean();
}
// Obtain the calibrated magnetometer reading (direction and field strength)
Vector3f GetCalibratedMagnetometer() const
{
OVR_ASSERT(MagCalibrated);
Lock::Locker lockScope(Handler.GetHandlerLock());
return CalMag;
}
Vector3f GetCalibratedMagValue(const Vector3f& rawMag) const;
float GetMagRefYaw() const
{
return MagRefYaw;
}
float GetYawErrorAngle() const
{
return YawErrorAngle;
}
// For later
//Vector3f GetGravity() const;
// Resets the current orientation
void Reset()
{
MagReferenced = false;
Lock::Locker lockScope(Handler.GetHandlerLock());
Q = Quatf();
QP = Quatf();
Stage = 0;
}
void Reset();
// Configuration
@ -183,19 +176,19 @@ public:
void SetPredictionEnabled(bool enable = true) { EnablePrediction = enable; }
bool IsPredictionEnabled() { return EnablePrediction; }
// Methods for magnetometer calibration
float AngleDifference(float theta1, float theta2);
Vector3f CalculateSphereCenter(Vector3f p1, Vector3f p2,
Vector3f p3, Vector3f p4);
private:
SensorFusion* getThis() { return this; }
// Internal handler for messages; bypasses error checking.
void handleMessage(const MessageBodyFrame& msg);
class BodyFrameHandler : public MessageHandler
// Set the magnetometer's reference orientation for use in yaw correction
// The supplied mag is an uncalibrated value
void SetMagReference(const Quatf& q, const Vector3f& rawMag);
// Default to current HMD orientation
void SetMagReference() { SetMagReference(Q, RawMag); }
class BodyFrameHandler : public MessageHandler
{
SensorFusion* pFusion;
public:
@ -207,11 +200,14 @@ private:
};
Quatf Q;
Quatf QUncorrected;
Vector3f A;
Vector3f AngV;
Vector3f Mag;
Vector3f CalMag;
Vector3f RawMag;
unsigned int Stage;
float RunningTime;
float DeltaT;
BodyFrameHandler Handler;
MessageHandler* pDelegate;
float Gain;
@ -220,9 +216,9 @@ private:
bool EnablePrediction;
float PredictionDT;
Quatf QP;
float PredictionTimeIncrement;
SensorFilter FMag;
SensorFilter FRawMag;
SensorFilter FAccW;
SensorFilter FAngV;
@ -234,15 +230,19 @@ private:
Matrix4f MagCalibrationMatrix;
bool MagCalibrated;
int MagCondCount;
bool MagReferenced;
float MagRefDistance;
bool MagReady;
Quatf MagRefQ;
Vector3f MagRefM;
float MagRefYaw;
bool MagHasNearbyReference;
Quatf MagRefTableQ[MagMaxReferences];
Vector3f MagRefTableM[MagMaxReferences];
float MagRefTableYaw[MagMaxReferences];
int MagNumReferences;
float YawErrorAngle;
int YawErrorCount;
bool YawCorrectionInProgress;
bool YawCorrectionActivated;
};

View file

@ -33,6 +33,8 @@ public:
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const;
virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
@ -58,13 +60,19 @@ public:
if ((other.Type == Device_Sensor) && (pFactory == other.pFactory))
{
const SensorDeviceCreateDesc& s2 = (const SensorDeviceCreateDesc&) other;
if ((HIDDesc.Path == s2.HIDDesc.Path) &&
(HIDDesc.SerialNumber == s2.HIDDesc.SerialNumber))
if (MatchHIDDevice(s2.HIDDesc))
return Match_Found;
}
return Match_None;
}
virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
{
// should paths comparison be case insensitive?
return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
(HIDDesc.SerialNumber == hidDesc.SerialNumber));
}
virtual bool GetDeviceInfo(DeviceInfo* info) const;
};
@ -135,9 +143,21 @@ public:
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'.
// 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.
virtual void SetReportRate(unsigned rateHz);
// Returns currently set report rate, in Hz. If 0 - error occurred.
// Note, this value may be different from the one provided for SetReportRate. The return
// value will contain the actual rate.
virtual unsigned GetReportRate() const;
// Hack to create HMD device from sensor display info.
static void EnumerateHMDFromSensorDisplayInfo( const SensorDisplayInfoImpl& displayInfo,
DeviceFactory::EnumerateVisitor& visitor);
static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo,
DeviceFactory::EnumerateVisitor& visitor);
protected:
void openDevice();
@ -146,6 +166,8 @@ protected:
Void setCoordinateFrame(CoordinateFrame coordframe);
bool setRange(const SensorRange& range);
Void setReportRate(unsigned rateHz);
// Called for decoded messages
void onTrackerMessage(TrackerMessage* message);

View file

@ -40,11 +40,16 @@ public:
virtual void Shutdown();
virtual ThreadCommandQueue* GetThreadQueue();
virtual ThreadId GetThreadId() const;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Fills HIDDeviceDesc by using the path.
// Returns 'true' if successful, 'false' otherwise.
bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const;
Ptr<DeviceManagerThread> pThread;
};
@ -56,7 +61,7 @@ class DeviceManagerThread : public Thread, public ThreadCommandQueue, public Dev
friend class DeviceManager;
enum { ThreadStackSize = 32 * 1024 };
public:
DeviceManagerThread();
DeviceManagerThread(DeviceManager* pdevMgr);
~DeviceManagerThread();
virtual int Run();
@ -67,7 +72,7 @@ public:
// Notifier used for different updates (EVENT or regular timing or messages).
class Notifier
class Notifier
{
public:
// Called when overlapped I/O handle is signaled.
@ -108,6 +113,8 @@ public:
// DeviceStatus::Notifier interface.
bool OnMessage(MessageType type, const String& devicePath);
void DetachDeviceManager();
private:
bool threadInitialized() { return hCommandEvent != 0; }
@ -128,6 +135,10 @@ private:
// Object that manages notifications originating from Windows messages.
Ptr<DeviceStatus> pStatusObject;
Lock DevMgrLock;
// pDeviceMgr should be accessed under DevMgrLock
DeviceManager* pDeviceMgr; // back ptr, no addref.
};
}} // namespace Win32::OVR

View file

@ -92,6 +92,8 @@ private: // data
UINT_PTR LastTimerId;
Array<RecoveryTimerDesc> RecoveryTimers;
GUID HidGuid;
};
}} // namespace OVR::Win32

View file

@ -140,9 +140,12 @@ public:
virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
virtual OVR::HIDDevice* Open(const String& path);
GUID GetHIDGuid()
{ return HidGuid; }
// Fills HIDDeviceDesc by using the path.
// Returns 'true' if successful, 'false' otherwise.
bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const;
GUID GetHIDGuid() { return HidGuid; }
static HIDDeviceManager* CreateInternal(DeviceManager* manager);
private:
@ -171,7 +174,7 @@ func = (PFn_##func)::GetProcAddress(hHidLib, #func)
OVR_DECLARE_HIDFUNC(HidD_FreePreparsedData, BOOLEAN, (HIDP_PREPARSED_DATA *preparsedData));
OVR_DECLARE_HIDFUNC(HidP_GetCaps, NTSTATUS,(HIDP_PREPARSED_DATA *preparsedData, HIDP_CAPS* caps));
HANDLE CreateHIDFile(const char* path, bool exclusiveAccess = true)
HANDLE CreateHIDFile(const char* path, bool exclusiveAccess = true) const
{
return ::CreateFileA(path, GENERIC_WRITE|GENERIC_READ,
(!exclusiveAccess) ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : 0x0,
@ -179,11 +182,11 @@ func = (PFn_##func)::GetProcAddress(hHidLib, #func)
}
// Helper functions to fill in HIDDeviceDesc from open device handle.
bool initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc);
bool initUsage(HANDLE hidDev, HIDDeviceDesc* desc);
void initStrings(HANDLE hidDev, HIDDeviceDesc* desc);
bool initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const;
bool initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const;
void initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const;
bool getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc);
bool getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc) const;
};
}} // namespace OVR::Win32

View file

@ -17,6 +17,7 @@ otherwise accompanies this software in either electronic or hard copy form.
#define OVR_Win32_HMDDevice_h
#include "OVR_Win32_DeviceManager.h"
#include "OVR_Profile.h"
namespace OVR { namespace Win32 {
@ -76,10 +77,23 @@ public:
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const;
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&);
// Matches device by path.
virtual bool MatchDevice(const String& path);
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
Profile* GetProfileAddRef() const;
ProfileType GetProfileType() const
{
return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
}
void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
{
DesktopX = x;
@ -114,13 +128,26 @@ class HMDDevice : public DeviceImpl<OVR::HMDDevice>
{
public:
HMDDevice(HMDDeviceCreateDesc* createDesc);
~HMDDevice();
~HMDDevice();
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const;
virtual const char* GetProfileName() const;
virtual bool SetProfileName(const char* name);
// Query associated sensor.
virtual OVR::SensorDevice* GetSensor();
protected:
HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
// User name for the profile used with this device.
String ProfileName;
mutable Ptr<Profile> pCachedProfile;
};

View file

@ -69,6 +69,9 @@ public:
bool DisplayScreenColor(Color& colorToDisplay);
const char* GetResultsString();
// Begin test. Equivalent to pressing the button on the latency tester.
void BeginTest();
private:
LatencyTest* getThis() { return this; }

View file

@ -31,12 +31,12 @@ public:
Mag_Uninitialized = 0,
Mag_AutoCalibrating = 1,
Mag_ManuallyCalibrating = 2,
Mag_Calibrated = 3,
Mag_Calibrated = 3
};
MagCalibration() :
Status(Mag_Uninitialized),
MinMagDistance(0.3f), MinQuatDistance(0.5f),
Stat(Mag_Uninitialized),
MinMagDistance(0.2f), MinQuatDistance(0.5f),
SampleCount(0)
{
MinMagDistanceSq = MinMagDistance * MinMagDistance;
@ -44,15 +44,27 @@ public:
}
// Methods that are useful for either auto or manual calibration
bool IsUnitialized() const { return Status == Mag_Uninitialized; }
bool IsCalibrated() const { return Status == Mag_Calibrated; }
int NumberOfSamples() const { return SampleCount; }
void ClearCalibration(SensorFusion& sf);
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 Status == Mag_AutoCalibrating; }
bool IsAutoCalibrating() const { return Stat == Mag_AutoCalibrating; }
// Methods for building a manual (user-guided) calibraton procedure
void BeginManualCalibration(SensorFusion& sf);
@ -60,7 +72,7 @@ public:
bool InsertIfAcceptable(const Quatf& q, const Vector3f& m);
// Returns true if successful, requiring that SampleCount = 4
bool SetCalibration(SensorFusion& sf);
bool IsManuallyCalibrating() const { return Status == Mag_ManuallyCalibrating; }
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.
@ -92,7 +104,7 @@ private:
const Vector3f& p3, const Vector3f& p4);
Vector3f MagCenter;
unsigned Status;
unsigned Stat;
float MinMagDistance;
float MinQuatDistance;
float MinMagDistanceSq;

View file

@ -189,7 +189,7 @@ public:
void SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
// Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
void SetIPD(float ipd) { InterpupillaryDistance = ipd; DirtyFlag = true; }
void SetIPD(float ipd) { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
float GetIPD() const { return InterpupillaryDistance; }
// Set full render target viewport; for HMD this includes both eyes.
@ -279,6 +279,7 @@ private:
// *** Computed State
bool DirtyFlag; // Set when any if the modifiable state changed.
bool IPDOverride; // True after SetIPD was called.
float YFov; // Vertical FOV.
float Aspect; // Aspect ratio: (w/h)*AspectMultiplier.
float ProjectionCenterOffset;

View file

@ -11,42 +11,34 @@
bool OculusManager::_isConnected = false;
#ifdef __APPLE__
Ptr<DeviceManager> OculusManager::_deviceManager;
Ptr<HMDDevice> OculusManager::_hmdDevice;
Ptr<SensorDevice> OculusManager::_sensorDevice;
SensorFusion OculusManager::_sensorFusion;
float OculusManager::_yawOffset = 0;
#endif
void OculusManager::connect() {
#ifdef __APPLE__
System::Init();
_deviceManager = *DeviceManager::Create();
_hmdDevice = *_deviceManager->EnumerateDevices<HMDDevice>().CreateDevice();
_deviceManager = DeviceManager::Create();
_sensorDevice = _deviceManager->EnumerateDevices<SensorDevice>().CreateDevice();
if (_hmdDevice) {
if (_sensorDevice) {
_isConnected = true;
_sensorDevice = *_hmdDevice->GetSensor();
_sensorFusion.AttachToSensor(_sensorDevice);
// default the yaw to the current orientation
_sensorFusion.SetMagReference();
//_sensorFusion.SetMagReference();
}
#endif
}
void OculusManager::updateYawOffset() {
#ifdef __APPLE__
float yaw, pitch, roll;
_sensorFusion.GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
_sensorFusion.GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
_yawOffset = yaw;
#endif
}
void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
#ifdef __APPLE__
_sensorFusion.GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
// convert each angle to degrees
@ -54,6 +46,5 @@ void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
yaw = glm::degrees(yaw - _yawOffset);
pitch = glm::degrees(pitch);
roll = glm::degrees(roll);
#endif
}