mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into metavoxels
This commit is contained in:
commit
91aa9918ee
75 changed files with 2394 additions and 775 deletions
|
@ -20,6 +20,13 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
|
|||
|
||||
if (APPLE)
|
||||
find_library(LIBOVR_LIBRARIES libovr.a ${LIBOVR_ROOT_DIR}/Lib/MacOS/)
|
||||
elseif (UNIX)
|
||||
find_library(UDEV_LIBRARY libudev.a /usr/lib/x86_64-linux-gnu/)
|
||||
find_library(XINERAMA_LIBRARY libXinerama.a /usr/lib/x86_64-linux-gnu/)
|
||||
find_library(OVR_LIBRARY libovr.a ${LIBOVR_ROOT_DIR}/Lib/UNIX/)
|
||||
if (UDEV_LIBRARY AND XINERAMA_LIBRARY AND OVR_LIBRARY)
|
||||
set(LIBOVR_LIBRARIES ${OVR_LIBRARY} ${UDEV_LIBRARY} ${XINERAMA_LIBRARY})
|
||||
endif (UDEV_LIBRARY AND XINERAMA_LIBRARY AND OVR_LIBRARY)
|
||||
elseif (WIN32)
|
||||
find_library(LIBOVR_LIBRARIES libovr.lib ${LIBOVR_ROOT_DIR}/Lib/Win32/)
|
||||
endif ()
|
||||
|
@ -41,4 +48,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)
|
||||
|
|
|
@ -117,6 +117,14 @@ if (SIXENSE_FOUND AND NOT DISABLE_SIXENSE)
|
|||
target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
||||
endif (SIXENSE_FOUND AND NOT DISABLE_SIXENSE)
|
||||
|
||||
# and with LibOVR for Oculus Rift
|
||||
if (LIBOVR_FOUND AND NOT DISABLE_LIBOVR)
|
||||
add_definitions(-DHAVE_LIBOVR)
|
||||
include_directories(SYSTEM ${LIBOVR_INCLUDE_DIRS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${LIBOVR_INCLUDE_DIRS}")
|
||||
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES})
|
||||
endif (LIBOVR_FOUND AND NOT DISABLE_LIBOVR)
|
||||
|
||||
qt5_use_modules(${TARGET_NAME} Core Gui Multimedia Network OpenGL Svg WebKit WebKitWidgets)
|
||||
|
||||
# include headers for interface and InterfaceConfig.
|
||||
|
@ -131,7 +139,6 @@ include_directories(
|
|||
SYSTEM
|
||||
${FACESHIFT_INCLUDE_DIRS}
|
||||
${GLM_INCLUDE_DIRS}
|
||||
${LIBOVR_INCLUDE_DIRS}
|
||||
${LIBVPX_INCLUDE_DIRS}
|
||||
${LEAP_INCLUDE_DIRS}
|
||||
${MOTIONDRIVER_INCLUDE_DIRS}
|
||||
|
@ -180,7 +187,6 @@ if (APPLE)
|
|||
${QTKit}
|
||||
${QuartzCore}
|
||||
${UVCCAMERACONTROL_LIBRARIES}
|
||||
${LIBOVR_LIBRARIES}
|
||||
)
|
||||
|
||||
if (LEAP_FOUND)
|
||||
|
|
1
interface/external/LibOVR/Include/OVR.h
vendored
1
interface/external/LibOVR/Include/OVR.h
vendored
|
@ -25,6 +25,7 @@ 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"
|
||||
|
||||
|
|
|
@ -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 5
|
||||
#define OVR_VERSION_STRING "0.2.5"
|
||||
|
||||
#endif
|
||||
|
|
BIN
interface/external/LibOVR/Lib/MacOS/libovr.a
vendored
BIN
interface/external/LibOVR/Lib/MacOS/libovr.a
vendored
Binary file not shown.
BIN
interface/external/LibOVR/Lib/UNIX/libovr.a
vendored
Normal file
BIN
interface/external/LibOVR/Lib/UNIX/libovr.a
vendored
Normal file
Binary file not shown.
BIN
interface/external/LibOVR/Lib/Win32/libovr.lib
vendored
BIN
interface/external/LibOVR/Lib/Win32/libovr.lib
vendored
Binary file not shown.
BIN
interface/external/LibOVR/Lib/x64/libovr64.lib
vendored
BIN
interface/external/LibOVR/Lib/x64/libovr64.lib
vendored
Binary file not shown.
0
interface/external/LibOVR/Src/Kernel/OVR_Alg.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Alg.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Allocator.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Allocator.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Array.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Array.h
vendored
Executable file → Normal file
1
interface/external/LibOVR/Src/Kernel/OVR_Atomic.h
vendored
Executable file → Normal file
1
interface/external/LibOVR/Src/Kernel/OVR_Atomic.h
vendored
Executable file → Normal file
|
@ -824,6 +824,7 @@ public:
|
|||
|
||||
Lock (unsigned dummy = 0)
|
||||
{
|
||||
OVR_UNUSED(dummy);
|
||||
if (!RecursiveAttrInit)
|
||||
{
|
||||
pthread_mutexattr_init(&RecursiveAttr);
|
||||
|
|
0
interface/external/LibOVR/Src/Kernel/OVR_Color.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Color.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_ContainerAllocator.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_ContainerAllocator.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_File.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_File.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Hash.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Hash.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_KeyCodes.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_KeyCodes.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_List.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_List.h
vendored
Executable file → Normal file
|
@ -115,7 +115,7 @@ struct ListNode
|
|||
// }
|
||||
//
|
||||
|
||||
// List<> represents a doubly-linked list if T, where each T must derive
|
||||
// List<> represents a doubly-linked list of T, where each T must derive
|
||||
// from ListNode<B>. B specifies the base class that was directly
|
||||
// derived from ListNode, and is only necessary if there is an intermediate
|
||||
// inheritance chain.
|
||||
|
|
0
interface/external/LibOVR/Src/Kernel/OVR_Log.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Log.h
vendored
Executable file → Normal file
596
interface/external/LibOVR/Src/Kernel/OVR_Math.h
vendored
Executable file → Normal file
596
interface/external/LibOVR/Src/Kernel/OVR_Math.h
vendored
Executable file → Normal file
|
@ -4,7 +4,7 @@ PublicHeader: OVR.h
|
|||
Filename : OVR_Math.h
|
||||
Content : Implementation of 3D primitives such as vectors, matrices.
|
||||
Created : September 4, 2012
|
||||
Authors : Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova
|
||||
Authors : Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova, Max Katsev
|
||||
|
||||
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
||||
|
||||
|
@ -23,11 +23,12 @@ otherwise accompanies this software in either electronic or hard copy form.
|
|||
|
||||
#include "OVR_Types.h"
|
||||
#include "OVR_RefCount.h"
|
||||
#include "OVR_Std.h"
|
||||
|
||||
namespace OVR {
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Constants for 3D world/axis definitions.
|
||||
// ***** Constants for 3D world/axis definitions.
|
||||
|
||||
// Definitions of axes for coordinate and rotation conversions.
|
||||
enum Axis
|
||||
|
@ -48,12 +49,13 @@ enum RotateDirection
|
|||
Rotate_CW = -1
|
||||
};
|
||||
|
||||
// Constants for right handed and left handed coordinate systems
|
||||
enum HandedSystem
|
||||
{
|
||||
Handed_R = 1, Handed_L = -1
|
||||
};
|
||||
|
||||
// AxisDirection describes which way the axis points. Used by WorldAxes.
|
||||
// AxisDirection describes which way the coordinate axis points. Used by WorldAxes.
|
||||
enum AxisDirection
|
||||
{
|
||||
Axis_Up = 2,
|
||||
|
@ -74,9 +76,9 @@ struct WorldAxes
|
|||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Math
|
||||
|
||||
//------------------------------------------------------------------------------------//
|
||||
// ************************************ Math *****************************************//
|
||||
//
|
||||
// Math class contains constants and functions. This class is a template specialized
|
||||
// per type, with Math<float> and Math<double> being distinct.
|
||||
template<class Type>
|
||||
|
@ -95,14 +97,14 @@ public:
|
|||
static const float PiOver4;
|
||||
static const float E;
|
||||
|
||||
static const float MaxValue; // Largest positive float Value
|
||||
static const float MinPositiveValue; // Smallest possible positive value
|
||||
static const float MaxValue; // Largest positive float Value
|
||||
static const float MinPositiveValue; // Smallest possible positive value
|
||||
|
||||
static const float RadToDegreeFactor;
|
||||
static const float DegreeToRadFactor;
|
||||
|
||||
static const float Tolerance; // 0.00001f;
|
||||
static const float SingularityRadius; //0.00000000001f for Gimbal lock numerical problems
|
||||
static const float Tolerance; // 0.00001f;
|
||||
static const float SingularityRadius; // 0.0000001f for Gimbal lock numerical problems
|
||||
};
|
||||
|
||||
// Double-precision Math constants class.
|
||||
|
@ -116,33 +118,54 @@ public:
|
|||
static const double PiOver4;
|
||||
static const double E;
|
||||
|
||||
static const double MaxValue; // Largest positive double Value
|
||||
static const double MinPositiveValue; // Smallest possible positive value
|
||||
static const double MaxValue; // Largest positive double Value
|
||||
static const double MinPositiveValue; // Smallest possible positive value
|
||||
|
||||
static const double RadToDegreeFactor;
|
||||
static const double DegreeToRadFactor;
|
||||
|
||||
static const double Tolerance; // 0.00001f;
|
||||
static const double SingularityRadius; //0.00000000001 for Gimbal lock numerical problems
|
||||
static const double Tolerance; // 0.00001;
|
||||
static const double SingularityRadius; // 0.000000000001 for Gimbal lock numerical problems
|
||||
|
||||
};
|
||||
|
||||
typedef Math<float> Mathf;
|
||||
typedef Math<double> Mathd;
|
||||
|
||||
// Conversion functions between degrees and radians
|
||||
template<class FT>
|
||||
FT RadToDegree(FT rads) { return rads * Math<FT>::RadToDegreeFactor; }
|
||||
template<class FT>
|
||||
FT DegreeToRad(FT rads) { return rads * Math<FT>::DegreeToRadFactor; }
|
||||
template<class T>
|
||||
T RadToDegree(T rads) { return rads * Math<T>::RadToDegreeFactor; }
|
||||
template<class T>
|
||||
T DegreeToRad(T rads) { return rads * Math<T>::DegreeToRadFactor; }
|
||||
|
||||
// Numerically stable acos function
|
||||
template<class T>
|
||||
T Acos(T val) {
|
||||
if (val > T(1)) return T(0);
|
||||
else if (val < T(-1)) return Math<T>::Pi;
|
||||
else return acos(val);
|
||||
};
|
||||
|
||||
// Numerically stable asin function
|
||||
template<class T>
|
||||
T Asin(T val) {
|
||||
if (val > T(1)) return Math<T>::PiOver2;
|
||||
else if (val < T(-1)) return Math<T>::PiOver2 * T(3);
|
||||
else return asin(val);
|
||||
};
|
||||
|
||||
#ifdef OVR_CC_MSVC
|
||||
inline int isnan(double x) { return _isnan(x); };
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
class Quat;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Vector2f - 2D Vector2f
|
||||
// ***** Vector2<>
|
||||
|
||||
// Vector2f represents a 2-dimensional vector or point in space,
|
||||
// consisting of coordinates x and y,
|
||||
// Vector2f (Vector2d) represents a 2-dimensional vector or point in space,
|
||||
// consisting of coordinates x and y
|
||||
|
||||
template<class T>
|
||||
class Vector2
|
||||
|
@ -174,33 +197,53 @@ public:
|
|||
return *this; }
|
||||
|
||||
// Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
|
||||
bool Compare(const Vector2&b, T tolerance = Mathf::Tolerance)
|
||||
bool Compare(const Vector2&b, T tolerance = Mathf::Tolerance)
|
||||
{
|
||||
return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance);
|
||||
}
|
||||
|
||||
// Dot product overload.
|
||||
// Entrywise product of two vectors
|
||||
Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);}
|
||||
|
||||
// Dot product
|
||||
// Used to calculate angle q between two vectors among other things,
|
||||
// as (A dot B) = |a||b|cos(q).
|
||||
T operator* (const Vector2& b) const { return x*b.x + y*b.y; }
|
||||
T Dot(const Vector2& b) const { return x*b.x + y*b.y; }
|
||||
|
||||
// Returns the angle from this vector to b, in radians.
|
||||
T Angle(const Vector2& b) const { return acos((*this * b)/(Length()*b.Length())); }
|
||||
T Angle(const Vector2& b) const
|
||||
{
|
||||
T div = LengthSq()*b.LengthSq();
|
||||
OVR_ASSERT(div != T(0));
|
||||
T result = Acos((this->Dot(b))/sqrt(div));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return Length of the vector squared.
|
||||
T LengthSq() const { return (x * x + y * y); }
|
||||
// Return vector length.
|
||||
T Length() const { return sqrt(LengthSq()); }
|
||||
|
||||
// Returns distance between two points represented by vectors.
|
||||
// Returns distance between two points represented by vectors.
|
||||
T Distance(Vector2& b) const { return (*this - b).Length(); }
|
||||
|
||||
// Determine if this a unit vector.
|
||||
|
||||
// Determine if this a unit vector.
|
||||
bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
|
||||
|
||||
// Normalize, convention vector length to 1.
|
||||
void Normalize() { *this /= Length(); }
|
||||
void Normalize()
|
||||
{
|
||||
T l = Length();
|
||||
OVR_ASSERT(l != T(0));
|
||||
*this /= l;
|
||||
}
|
||||
// Returns normalized (unit) version of the vector without modifying itself.
|
||||
Vector2 Normalized() const { return *this / Length(); }
|
||||
Vector2 Normalized() const
|
||||
{
|
||||
T l = Length();
|
||||
OVR_ASSERT(l != T(0));
|
||||
return *this / l;
|
||||
}
|
||||
|
||||
// Linearly interpolates from this vector to another.
|
||||
// Factor should be between 0.0 and 1.0, with 0 giving full value to this.
|
||||
|
@ -208,17 +251,24 @@ public:
|
|||
|
||||
// Projects this vector onto the argument; in other words,
|
||||
// A.Project(B) returns projection of vector A onto B.
|
||||
Vector2 ProjectTo(const Vector2& b) const { return b * ((*this * b) / b.LengthSq()); }
|
||||
Vector2 ProjectTo(const Vector2& b) const
|
||||
{
|
||||
T l2 = b.LengthSq();
|
||||
OVR_ASSERT(l2 != T(0));
|
||||
return b * ( Dot(b) / l2 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef Vector2<float> Vector2f;
|
||||
typedef Vector2<double> Vector2d;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Vector3f - 3D Vector3f
|
||||
|
||||
// Vector3f represents a 3-dimensional vector or point in space,
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Vector3<> - 3D vector of {x, y, z}
|
||||
|
||||
//
|
||||
// Vector3f (Vector3d) represents a 3-dimensional vector or point in space,
|
||||
// consisting of coordinates x, y and z.
|
||||
|
||||
template<class T>
|
||||
|
@ -253,13 +303,20 @@ public:
|
|||
// Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
|
||||
bool Compare(const Vector3&b, T tolerance = Mathf::Tolerance)
|
||||
{
|
||||
return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance) && (fabs(b.z-z) < tolerance);
|
||||
return (fabs(b.x-x) < tolerance) &&
|
||||
(fabs(b.y-y) < tolerance) &&
|
||||
(fabs(b.z-z) < tolerance);
|
||||
}
|
||||
|
||||
// Dot product overload.
|
||||
// Entrywise product of two vectors
|
||||
Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x,
|
||||
y * b.y,
|
||||
z * b.z);}
|
||||
|
||||
// Dot product
|
||||
// Used to calculate angle q between two vectors among other things,
|
||||
// as (A dot B) = |a||b|cos(q).
|
||||
T operator* (const Vector3& b) const { return x*b.x + y*b.y + z*b.z; }
|
||||
T Dot(const Vector3& b) const { return x*b.x + y*b.y + z*b.z; }
|
||||
|
||||
// Compute cross product, which generates a normal vector.
|
||||
// Direction vector can be determined by right-hand rule: Pointing index finder in
|
||||
|
@ -269,7 +326,13 @@ public:
|
|||
x*b.y - y*b.x); }
|
||||
|
||||
// Returns the angle from this vector to b, in radians.
|
||||
T Angle(const Vector3& b) const { return acos((*this * b)/(Length()*b.Length())); }
|
||||
T Angle(const Vector3& b) const
|
||||
{
|
||||
T div = LengthSq()*b.LengthSq();
|
||||
OVR_ASSERT(div != T(0));
|
||||
T result = Acos((this->Dot(b))/sqrt(div));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return Length of the vector squared.
|
||||
T LengthSq() const { return (x * x + y * y + z * z); }
|
||||
|
@ -281,10 +344,22 @@ public:
|
|||
|
||||
// Determine if this a unit vector.
|
||||
bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
|
||||
|
||||
// Normalize, convention vector length to 1.
|
||||
void Normalize() { *this /= Length(); }
|
||||
void Normalize()
|
||||
{
|
||||
T l = Length();
|
||||
OVR_ASSERT(l != T(0));
|
||||
*this /= l;
|
||||
}
|
||||
|
||||
// Returns normalized (unit) version of the vector without modifying itself.
|
||||
Vector3 Normalized() const { return *this / Length(); }
|
||||
Vector3 Normalized() const
|
||||
{
|
||||
T l = Length();
|
||||
OVR_ASSERT(l != T(0));
|
||||
return *this / l;
|
||||
}
|
||||
|
||||
// Linearly interpolates from this vector to another.
|
||||
// Factor should be between 0.0 and 1.0, with 0 giving full value to this.
|
||||
|
@ -292,7 +367,15 @@ public:
|
|||
|
||||
// Projects this vector onto the argument; in other words,
|
||||
// A.Project(B) returns projection of vector A onto B.
|
||||
Vector3 ProjectTo(const Vector3& b) const { return b * ((*this * b) / b.LengthSq()); }
|
||||
Vector3 ProjectTo(const Vector3& b) const
|
||||
{
|
||||
T l2 = b.LengthSq();
|
||||
OVR_ASSERT(l2 != T(0));
|
||||
return b * ( Dot(b) / l2 );
|
||||
}
|
||||
|
||||
// Projects this vector onto a plane defined by a normal vector
|
||||
Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -301,8 +384,55 @@ typedef Vector3<double> Vector3d;
|
|||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Matrix4f
|
||||
// ***** Size
|
||||
|
||||
// Size class represents 2D size with Width, Height components.
|
||||
// Used to describe distentions of render targets, etc.
|
||||
|
||||
template<class T>
|
||||
class Size
|
||||
{
|
||||
public:
|
||||
T Width, Height;
|
||||
|
||||
Size() : Width(0), Height(0) { }
|
||||
Size(T w_, T h_) : Width(w_), Height(h_) { }
|
||||
explicit Size(T s) : Width(s), Height(s) { }
|
||||
|
||||
bool operator== (const Size& b) const { return Width == b.Width && Height == b.Height; }
|
||||
bool operator!= (const Size& b) const { return Width != b.Width || Height != b.Height; }
|
||||
|
||||
Size operator+ (const Size& b) const { return Size(Width + b.Width, Height + b.Height); }
|
||||
Size& operator+= (const Size& b) { Width += b.Width; Height += b.Height; return *this; }
|
||||
Size operator- (const Size& b) const { return Size(Width - b.Width, Height - b.Height); }
|
||||
Size& operator-= (const Size& b) { Width -= b.Width; Height -= b.Height; return *this; }
|
||||
Size operator- () const { return Size(-Width, -Height); }
|
||||
Size operator* (const Size& b) const { return Size(Width * b.Width, Height * b.Height); }
|
||||
Size& operator*= (const Size& b) { Width *= b.Width; Height *= b.Height; return *this; }
|
||||
Size operator/ (const Size& b) const { return Size(Width / b.Width, Height / b.Height); }
|
||||
Size& operator/= (const Size& b) { Width /= b.Width; Height /= b.Height; return *this; }
|
||||
|
||||
// Scalar multiplication/division scales both components.
|
||||
Size operator* (T s) const { return Size(Width*s, Height*s); }
|
||||
Size& operator*= (T s) { Width *= s; Height *= s; return *this; }
|
||||
Size operator/ (T s) const { return Size(Width/s, Height/s); }
|
||||
Size& operator/= (T s) { Width /= s; Height /= s; return *this; }
|
||||
|
||||
T Area() const { return Width * Height; }
|
||||
|
||||
inline Vector2<T> ToVector() const { return Vector2<T>(Width, Height); }
|
||||
};
|
||||
|
||||
|
||||
typedef Size<int> Sizei;
|
||||
typedef Size<unsigned> Sizeu;
|
||||
typedef Size<float> Sizef;
|
||||
typedef Size<double> Sized;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Matrix4f
|
||||
//
|
||||
// Matrix4f is a 4x4 matrix used for 3d transformations and projections.
|
||||
// Translation stored in the last column.
|
||||
// The matrix is stored in row-major order in memory, meaning that values
|
||||
|
@ -367,6 +497,29 @@ public:
|
|||
M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1;
|
||||
}
|
||||
|
||||
void ToString(char* dest, UPInt destsize)
|
||||
{
|
||||
UPInt pos = 0;
|
||||
for (int r=0; r<4; r++)
|
||||
for (int c=0; c<4; c++)
|
||||
pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
|
||||
}
|
||||
|
||||
static Matrix4f FromString(const char* src)
|
||||
{
|
||||
Matrix4f result;
|
||||
for (int r=0; r<4; r++)
|
||||
for (int c=0; c<4; c++)
|
||||
{
|
||||
result.M[r][c] = (float)atof(src);
|
||||
while (src && *src != ' ')
|
||||
src++;
|
||||
while (src && *src == ' ')
|
||||
src++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const Matrix4f& Identity() { return IdentityValue; }
|
||||
|
||||
void SetIdentity()
|
||||
|
@ -377,6 +530,36 @@ public:
|
|||
M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
|
||||
}
|
||||
|
||||
Matrix4f operator+ (const Matrix4f& b) const
|
||||
{
|
||||
Matrix4f result(*this);
|
||||
result += b;
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4f& operator+= (const Matrix4f& b)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
M[i][j] += b.M[i][j];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4f operator- (const Matrix4f& b) const
|
||||
{
|
||||
Matrix4f result(*this);
|
||||
result -= b;
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4f& operator-= (const Matrix4f& b)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
M[i][j] -= b.M[i][j];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Multiplies two matrices into destination with minimum copying.
|
||||
static Matrix4f& Multiply(Matrix4f* d, const Matrix4f& a, const Matrix4f& b)
|
||||
{
|
||||
|
@ -406,18 +589,32 @@ public:
|
|||
|
||||
Matrix4f operator* (float s) const
|
||||
{
|
||||
return Matrix4f(M[0][0] * s, M[0][1] * s, M[0][2] * s, M[0][3] * s,
|
||||
M[1][0] * s, M[1][1] * s, M[1][2] * s, M[1][3] * s,
|
||||
M[2][0] * s, M[2][1] * s, M[2][2] * s, M[2][3] * s,
|
||||
M[3][0] * s, M[3][1] * s, M[3][2] * s, M[3][3] * s);
|
||||
Matrix4f result(*this);
|
||||
result *= s;
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4f& operator*= (float s)
|
||||
{
|
||||
M[0][0] *= s; M[0][1] *= s; M[0][2] *= s; M[0][3] *= s;
|
||||
M[1][0] *= s; M[1][1] *= s; M[1][2] *= s; M[1][3] *= s;
|
||||
M[2][0] *= s; M[2][1] *= s; M[2][2] *= s; M[2][3] *= s;
|
||||
M[3][0] *= s; M[3][1] *= s; M[3][2] *= s; M[3][3] *= s;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
M[i][j] *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Matrix4f operator/ (float s) const
|
||||
{
|
||||
Matrix4f result(*this);
|
||||
result /= s;
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4f& operator/= (float s)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
M[i][j] /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -442,16 +639,16 @@ public:
|
|||
}
|
||||
|
||||
|
||||
float SubDet (const int* rows, const int* cols) const
|
||||
float SubDet (const UPInt* rows, const UPInt* cols) const
|
||||
{
|
||||
return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
|
||||
- M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
|
||||
+ M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
|
||||
}
|
||||
|
||||
float Cofactor(int I, int J) const
|
||||
float Cofactor(UPInt I, UPInt J) const
|
||||
{
|
||||
const int indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
|
||||
const UPInt indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
|
||||
return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
|
||||
}
|
||||
|
||||
|
@ -480,7 +677,27 @@ public:
|
|||
*this = Inverted();
|
||||
}
|
||||
|
||||
//AnnaSteve:
|
||||
// This is more efficient than general inverse, but ONLY works
|
||||
// correctly if it is a homogeneous transform matrix (rot + trans)
|
||||
Matrix4f InvertedHomogeneousTransform() const
|
||||
{
|
||||
// Make the inverse rotation matrix
|
||||
Matrix4f rinv = this->Transposed();
|
||||
rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = 0.0f;
|
||||
// Make the inverse translation matrix
|
||||
Vector3f tvinv = Vector3f(-M[0][3],-M[1][3],-M[2][3]);
|
||||
Matrix4f tinv = Matrix4f::Translation(tvinv);
|
||||
return rinv * tinv; // "untranslate", then "unrotate"
|
||||
}
|
||||
|
||||
// This is more efficient than general inverse, but ONLY works
|
||||
// correctly if it is a homogeneous transform matrix (rot + trans)
|
||||
void InvertHomogeneousTransform()
|
||||
{
|
||||
*this = InvertedHomogeneousTransform();
|
||||
}
|
||||
|
||||
// Matrix to Euler Angles conversion
|
||||
// a,b,c, are the YawPitchRoll angles to be returned
|
||||
// rotation a around axis A1
|
||||
// is followed by rotation b around axis A2
|
||||
|
@ -502,7 +719,7 @@ public:
|
|||
*b = -S*D*Math<float>::PiOver2;
|
||||
*c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
|
||||
}
|
||||
else if (pm > 1.0 - Math<float>::SingularityRadius)
|
||||
else if (pm > 1.0f - Math<float>::SingularityRadius)
|
||||
{ // North pole singularity
|
||||
*a = 0.0f;
|
||||
*b = S*D*Math<float>::PiOver2;
|
||||
|
@ -518,7 +735,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
//AnnaSteve:
|
||||
// Matrix to Euler Angles conversion
|
||||
// a,b,c, are the YawPitchRoll angles to be returned
|
||||
// rotation a around axis A1
|
||||
// is followed by rotation b around axis A2
|
||||
|
@ -537,13 +754,13 @@ public:
|
|||
psign = 1.0f;
|
||||
|
||||
float c2 = M[A1][A1];
|
||||
if (c2 < -1.0 + Math<float>::SingularityRadius)
|
||||
if (c2 < -1.0f + Math<float>::SingularityRadius)
|
||||
{ // South pole singularity
|
||||
*a = 0.0f;
|
||||
*b = S*D*Math<float>::Pi;
|
||||
*c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
|
||||
}
|
||||
else if (c2 > 1.0 - Math<float>::SingularityRadius)
|
||||
else if (c2 > 1.0f - Math<float>::SingularityRadius)
|
||||
{ // North pole singularity
|
||||
*a = 0.0f;
|
||||
*b = 0.0f;
|
||||
|
@ -560,7 +777,6 @@ public:
|
|||
|
||||
// Creates a matrix that converts the vertices from one coordinate system
|
||||
// to another.
|
||||
//
|
||||
static Matrix4f AxisConversion(const WorldAxes& to, const WorldAxes& from)
|
||||
{
|
||||
// Holds axis values from the 'to' structure
|
||||
|
@ -584,7 +800,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Creates a matrix for translation by vector
|
||||
static Matrix4f Translation(const Vector3f& v)
|
||||
{
|
||||
Matrix4f t;
|
||||
|
@ -594,6 +810,7 @@ public:
|
|||
return t;
|
||||
}
|
||||
|
||||
// Creates a matrix for translation by vector
|
||||
static Matrix4f Translation(float x, float y, float z = 0.0f)
|
||||
{
|
||||
Matrix4f t;
|
||||
|
@ -603,6 +820,7 @@ public:
|
|||
return t;
|
||||
}
|
||||
|
||||
// Creates a matrix for scaling by vector
|
||||
static Matrix4f Scaling(const Vector3f& v)
|
||||
{
|
||||
Matrix4f t;
|
||||
|
@ -612,6 +830,7 @@ public:
|
|||
return t;
|
||||
}
|
||||
|
||||
// Creates a matrix for scaling by vector
|
||||
static Matrix4f Scaling(float x, float y, float z)
|
||||
{
|
||||
Matrix4f t;
|
||||
|
@ -621,6 +840,7 @@ public:
|
|||
return t;
|
||||
}
|
||||
|
||||
// Creates a matrix for scaling by constant
|
||||
static Matrix4f Scaling(float s)
|
||||
{
|
||||
Matrix4f t;
|
||||
|
@ -632,7 +852,8 @@ public:
|
|||
|
||||
|
||||
|
||||
//AnnaSteve : Just for quick testing. Not for final API. Need to remove case.
|
||||
// Creates a rotation matrix rotating around the X axis by 'angle' radians.
|
||||
// Just for quick testing. Not for final API. Need to remove case.
|
||||
static Matrix4f RotationAxis(Axis A, float angle, RotateDirection d, HandedSystem s)
|
||||
{
|
||||
float sina = s * d *sin(angle);
|
||||
|
@ -658,10 +879,10 @@ public:
|
|||
|
||||
// Creates a rotation matrix rotating around the X axis by 'angle' radians.
|
||||
// Rotation direction is depends on the coordinate system:
|
||||
// RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
|
||||
// RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
|
||||
// while looking in the negative axis direction. This is the
|
||||
// same as looking down from positive axis values towards origin.
|
||||
// LHS: Positive angle values rotate clock-wise (CW), while looking in the
|
||||
// LHS: Positive angle values rotate clock-wise (CW), while looking in the
|
||||
// negative axis direction.
|
||||
static Matrix4f RotationX(float angle)
|
||||
{
|
||||
|
@ -743,9 +964,9 @@ public:
|
|||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Quat
|
||||
|
||||
//-------------------------------------------------------------------------------------//
|
||||
// **************************************** Quat **************************************//
|
||||
//
|
||||
// Quatf represents a quaternion class used for rotations.
|
||||
//
|
||||
// Quaternion multiplications are done in right-to-left order, to match the
|
||||
|
@ -763,7 +984,7 @@ public:
|
|||
Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {}
|
||||
|
||||
|
||||
// Constructs rotation quaternion around the axis.
|
||||
// Constructs quaternion for rotation around the axis by an angle.
|
||||
Quat(const Vector3<T>& axis, T angle)
|
||||
{
|
||||
Vector3<T> unitAxis = axis.Normalized();
|
||||
|
@ -775,33 +996,33 @@ public:
|
|||
z = unitAxis.z * sinHalfAngle;
|
||||
}
|
||||
|
||||
//AnnaSteve:
|
||||
// Constructs quaternion for rotation around one of the coordinate axis by an angle.
|
||||
void AxisAngle(Axis A, T angle, RotateDirection d, HandedSystem s)
|
||||
{
|
||||
T sinHalfAngle = s * d *sin(angle * (T)0.5);
|
||||
T sinHalfAngle = s * d *sin(angle * T(0.5));
|
||||
T v[3];
|
||||
v[0] = v[1] = v[2] = (T)0;
|
||||
v[0] = v[1] = v[2] = T(0);
|
||||
v[A] = sinHalfAngle;
|
||||
//return Quat(v[0], v[1], v[2], cos(angle * (T)0.5));
|
||||
w = cos(angle * (T)0.5);
|
||||
|
||||
w = cos(angle * T(0.5));
|
||||
x = v[0];
|
||||
y = v[1];
|
||||
z = v[2];
|
||||
}
|
||||
|
||||
|
||||
void GetAxisAngle(Vector3<T>* axis, T* angle) const
|
||||
// Compute axis and angle from quaternion
|
||||
void GetAxisAngle(Vector3<T>* axis, T* angle) const
|
||||
{
|
||||
if (LengthSq() > Math<T>::Tolerance * Math<T>::Tolerance)
|
||||
{
|
||||
*axis = Vector3<T>(x, y, z).Normalized();
|
||||
*angle = 2 * acos(w);
|
||||
}
|
||||
else
|
||||
{
|
||||
*axis = Vector3<T>(1, 0, 0);
|
||||
*angle= 0;
|
||||
}
|
||||
if ( x*x + y*y + z*z > Math<T>::Tolerance * Math<T>::Tolerance ) {
|
||||
*axis = Vector3<T>(x, y, z).Normalized();
|
||||
*angle = T(2) * Acos(w);
|
||||
}
|
||||
else
|
||||
{
|
||||
*axis = Vector3<T>(1, 0, 0);
|
||||
*angle= 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
|
||||
|
@ -817,6 +1038,7 @@ public:
|
|||
Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
|
||||
Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
|
||||
|
||||
|
||||
// Get Imaginary part vector
|
||||
Vector3<T> Imag() const { return Vector3<T>(x,y,z); }
|
||||
|
||||
|
@ -824,29 +1046,42 @@ public:
|
|||
T Length() const { return sqrt(x * x + y * y + z * z + w * w); }
|
||||
// Get quaternion length squared.
|
||||
T LengthSq() const { return (x * x + y * y + z * z + w * w); }
|
||||
|
||||
// Simple Eulidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
|
||||
T Distance(const Quat& q) const
|
||||
{
|
||||
T Distance(const Quat& q) const
|
||||
{
|
||||
T d1 = (*this - q).Length();
|
||||
T d2 = (*this + q).Length(); // Antipoldal point check
|
||||
T d2 = (*this + q).Length(); // Antipodal point check
|
||||
return (d1 < d2) ? d1 : d2;
|
||||
}
|
||||
}
|
||||
|
||||
T DistanceSq(const Quat& q) const
|
||||
{
|
||||
T d1 = (*this - q).LengthSq();
|
||||
T d2 = (*this + q).LengthSq(); // Antipoldal point check
|
||||
T d2 = (*this + q).LengthSq(); // Antipodal point check
|
||||
return (d1 < d2) ? d1 : d2;
|
||||
}
|
||||
|
||||
// Normalize
|
||||
bool IsNormalized() const { return fabs(LengthSq() - 1) < Math<T>::Tolerance; }
|
||||
void Normalize() { *this /= Length(); }
|
||||
Quat Normalized() const { return *this / Length(); }
|
||||
bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
T l = Length();
|
||||
OVR_ASSERT(l != T(0));
|
||||
*this /= l;
|
||||
}
|
||||
|
||||
Quat Normalized() const
|
||||
{
|
||||
T l = Length();
|
||||
OVR_ASSERT(l != T(0));
|
||||
return *this / l;
|
||||
}
|
||||
|
||||
// Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
|
||||
Quat Conj() const { return Quat(-x, -y, -z, w); }
|
||||
|
||||
// AnnaSteve fixed: order of quaternion multiplication
|
||||
// Quaternion multiplication. Combines quaternion rotations, performing the one on the
|
||||
// right hand side first.
|
||||
Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
|
||||
|
@ -868,7 +1103,7 @@ public:
|
|||
// assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1.
|
||||
Vector3<T> Rotate(const Vector3<T>& v) const
|
||||
{
|
||||
return ((*this * Quat<T>(v.x, v.y, v.z, 0)) * Inverted()).Imag();
|
||||
return ((*this * Quat<T>(v.x, v.y, v.z, T(0))) * Inverted()).Imag();
|
||||
}
|
||||
|
||||
|
||||
|
@ -879,7 +1114,7 @@ public:
|
|||
}
|
||||
|
||||
// Sets this quaternion to the one rotates in the opposite direction.
|
||||
void Invert() const
|
||||
void Invert()
|
||||
{
|
||||
*this = Quat(-x, -y, -z, w);
|
||||
}
|
||||
|
@ -897,6 +1132,52 @@ public:
|
|||
float(T(2) * (x*z - w*y)), float(T(2) * (y*z + w*x)), float(ww - xx - yy + zz) );
|
||||
}
|
||||
|
||||
|
||||
// Converting matrix to quaternion
|
||||
static Quat<T> Matrix4fToQuat(const Matrix4f& m)
|
||||
{
|
||||
T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
|
||||
Quat<T> q;
|
||||
|
||||
// In almost all cases, the first part is executed.
|
||||
// However, if the trace is not positive, the other
|
||||
// cases arise.
|
||||
if (trace > T(0))
|
||||
{
|
||||
T s = sqrt(trace + T(1)) * T(2); // s=4*qw
|
||||
q.w = T(0.25) * s;
|
||||
q.x = (m.M[2][1] - m.M[1][2]) / s;
|
||||
q.y = (m.M[0][2] - m.M[2][0]) / s;
|
||||
q.z = (m.M[1][0] - m.M[0][1]) / s;
|
||||
}
|
||||
else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
|
||||
{
|
||||
T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
|
||||
q.w = (m.M[2][1] - m.M[1][2]) / s;
|
||||
q.x = T(0.25) * s;
|
||||
q.y = (m.M[0][1] + m.M[1][0]) / s;
|
||||
q.z = (m.M[2][0] + m.M[0][2]) / s;
|
||||
}
|
||||
else if (m.M[1][1] > m.M[2][2])
|
||||
{
|
||||
T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
|
||||
q.w = (m.M[0][2] - m.M[2][0]) / s;
|
||||
q.x = (m.M[0][1] + m.M[1][0]) / s;
|
||||
q.y = T(0.25) * s;
|
||||
q.z = (m.M[1][2] + m.M[2][1]) / s;
|
||||
}
|
||||
else
|
||||
{
|
||||
T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
|
||||
q.w = (m.M[1][0] - m.M[0][1]) / s;
|
||||
q.x = (m.M[0][2] + m.M[2][0]) / s;
|
||||
q.y = (m.M[1][2] + m.M[2][1]) / s;
|
||||
q.z = T(0.25) * s;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
|
||||
// axis rotations and the specified coordinate system. Right-handed coordinate system
|
||||
|
@ -918,33 +1199,33 @@ public:
|
|||
T Q22 = Q[A2]*Q[A2];
|
||||
T Q33 = Q[A3]*Q[A3];
|
||||
|
||||
T psign = T(-1.0);
|
||||
T psign = T(-1);
|
||||
// Determine whether even permutation
|
||||
if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
|
||||
psign = T(1.0);
|
||||
psign = T(1);
|
||||
|
||||
T s2 = psign * T(2.0) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
|
||||
T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
|
||||
|
||||
if (s2 < (T)-1.0 + Math<T>::SingularityRadius)
|
||||
if (s2 < T(-1) + Math<T>::SingularityRadius)
|
||||
{ // South pole singularity
|
||||
*a = T(0.0);
|
||||
*a = T(0);
|
||||
*b = -S*D*Math<T>::PiOver2;
|
||||
*c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
|
||||
*c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]),
|
||||
ww + Q22 - Q11 - Q33 );
|
||||
}
|
||||
else if (s2 > (T)1.0 - Math<T>::SingularityRadius)
|
||||
else if (s2 > T(1) - Math<T>::SingularityRadius)
|
||||
{ // North pole singularity
|
||||
*a = (T)0.0;
|
||||
*a = T(0);
|
||||
*b = S*D*Math<T>::PiOver2;
|
||||
*c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
|
||||
*c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]),
|
||||
ww + Q22 - Q11 - Q33);
|
||||
}
|
||||
else
|
||||
{
|
||||
*a = -S*D*atan2((T)-2.0*(w*Q[A1] - psign*Q[A2]*Q[A3]),
|
||||
*a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2]*Q[A3]),
|
||||
ww + Q33 - Q11 - Q22);
|
||||
*b = S*D*asin(s2);
|
||||
*c = S*D*atan2((T)2.0*(w*Q[A3] - psign*Q[A1]*Q[A2]),
|
||||
*c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1]*Q[A2]),
|
||||
ww + Q11 - Q22 - Q33);
|
||||
}
|
||||
return;
|
||||
|
@ -982,25 +1263,25 @@ public:
|
|||
T Q22 = Q[A2]*Q[A2];
|
||||
T Qmm = Q[m]*Q[m];
|
||||
|
||||
T psign = T(-1.0);
|
||||
T psign = T(-1);
|
||||
if ((A1 + 1) % 3 == A2) // Determine whether even permutation
|
||||
{
|
||||
psign = (T)1.0;
|
||||
psign = T(1);
|
||||
}
|
||||
|
||||
T c2 = ww + Q11 - Q22 - Qmm;
|
||||
if (c2 < (T)-1.0 + Math<T>::SingularityRadius)
|
||||
if (c2 < T(-1) + Math<T>::SingularityRadius)
|
||||
{ // South pole singularity
|
||||
*a = (T)0.0;
|
||||
*a = T(0);
|
||||
*b = S*D*Math<T>::Pi;
|
||||
*c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
|
||||
*c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]),
|
||||
ww + Q22 - Q11 - Qmm);
|
||||
}
|
||||
else if (c2 > (T)1.0 - Math<T>::SingularityRadius)
|
||||
else if (c2 > T(1) - Math<T>::SingularityRadius)
|
||||
{ // North pole singularity
|
||||
*a = (T)0.0;
|
||||
*b = (T)0.0;
|
||||
*c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
|
||||
*a = T(0);
|
||||
*b = T(0);
|
||||
*c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]),
|
||||
ww + Q22 - Q11 - Qmm);
|
||||
}
|
||||
else
|
||||
|
@ -1013,12 +1294,93 @@ public:
|
|||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
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) { a = a + b.a; FastFixRange(); return *this; }
|
||||
Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; }
|
||||
Angle operator+ (const Angle& b) const { Angle res = *this; res += b; return res; }
|
||||
Angle operator+ (const T& x) const { Angle res = *this; res += x; return res; }
|
||||
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 { Angle res = *this; res -= b; return res; }
|
||||
Angle operator- (const T& x) const { Angle res = *this; res -= x; return res; }
|
||||
|
||||
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()
|
||||
{
|
||||
// do nothing if the value is already in the correct range, since fmod call is expensive
|
||||
if (a >= -Math<T>::Pi && a <= Math<T>::Pi)
|
||||
return;
|
||||
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
|
||||
|
||||
|
@ -1043,7 +1405,7 @@ public:
|
|||
// Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane).
|
||||
T TestSide(const Vector3<T>& p) const
|
||||
{
|
||||
return (N * p) + D;
|
||||
return (N.Dot(p)) + D;
|
||||
}
|
||||
|
||||
Plane<T> Flipped() const
|
||||
|
@ -1065,6 +1427,6 @@ public:
|
|||
|
||||
typedef Plane<float> Planef;
|
||||
|
||||
}
|
||||
} // Namespace OVR
|
||||
|
||||
#endif
|
||||
|
|
0
interface/external/LibOVR/Src/Kernel/OVR_RefCount.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_RefCount.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Std.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Std.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_String.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_String.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_StringHash.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_StringHash.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_SysFile.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_SysFile.h
vendored
Executable file → Normal file
|
@ -88,6 +88,6 @@ public:
|
|||
virtual bool Close();
|
||||
};
|
||||
|
||||
} // Scaleform
|
||||
} // Namespace OVR
|
||||
|
||||
#endif
|
||||
|
|
0
interface/external/LibOVR/Src/Kernel/OVR_System.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_System.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Threads.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_Threads.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_Timer.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_Timer.h
vendored
Executable file → Normal file
|
@ -95,6 +95,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
} // Scaleform::Timer
|
||||
} // Namespace OVR
|
||||
|
||||
#endif
|
||||
|
|
2
interface/external/LibOVR/Src/Kernel/OVR_Types.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/Kernel/OVR_Types.h
vendored
Executable file → Normal file
|
@ -291,7 +291,7 @@ namespace BaseTypes
|
|||
#if defined(OVR_CC_MSVC)
|
||||
# define OVR_FORCE_INLINE __forceinline
|
||||
#elif defined(OVR_CC_GNU)
|
||||
# define OVR_FORCE_INLINE __attribute__((always_inline))
|
||||
# define OVR_FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#else
|
||||
# define OVR_FORCE_INLINE inline
|
||||
#endif // OVR_CC_MSVC
|
||||
|
|
0
interface/external/LibOVR/Src/Kernel/OVR_UTF8Util.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/Kernel/OVR_UTF8Util.h
vendored
Executable file → Normal file
101
interface/external/LibOVR/Src/OVR_Device.h
vendored
Executable file → Normal file
101
interface/external/LibOVR/Src/OVR_Device.h
vendored
Executable file → Normal 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
|
||||
|
|
1
interface/external/LibOVR/Src/OVR_DeviceConstants.h
vendored
Executable file → Normal file
1
interface/external/LibOVR/Src/OVR_DeviceConstants.h
vendored
Executable file → Normal file
|
@ -30,6 +30,7 @@ enum DeviceType
|
|||
Device_HMD = 2,
|
||||
Device_Sensor = 3,
|
||||
Device_LatencyTester = 4,
|
||||
Device_BootLoader = 5,
|
||||
Device_All = 0xFF // Set for enumeration only, to enumerate all device types.
|
||||
};
|
||||
|
||||
|
|
15
interface/external/LibOVR/Src/OVR_DeviceHandle.h
vendored
Executable file → Normal file
15
interface/external/LibOVR/Src/OVR_DeviceHandle.h
vendored
Executable file → Normal 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();
|
||||
|
||||
|
|
57
interface/external/LibOVR/Src/OVR_DeviceImpl.h
vendored
Executable file → Normal file
57
interface/external/LibOVR/Src/OVR_DeviceImpl.h
vendored
Executable file → Normal 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 is 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;
|
||||
};
|
||||
|
||||
|
||||
|
|
3
interface/external/LibOVR/Src/OVR_DeviceMessages.h
vendored
Executable file → Normal file
3
interface/external/LibOVR/Src/OVR_DeviceMessages.h
vendored
Executable file → Normal 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:
|
||||
|
|
4
interface/external/LibOVR/Src/OVR_HIDDevice.h
vendored
Executable file → Normal file
4
interface/external/LibOVR/Src/OVR_HIDDevice.h
vendored
Executable file → Normal 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)
|
||||
|
|
0
interface/external/LibOVR/Src/OVR_HIDDeviceBase.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/OVR_HIDDeviceBase.h
vendored
Executable file → Normal file
50
interface/external/LibOVR/Src/OVR_HIDDeviceImpl.h
vendored
Executable file → Normal file
50
interface/external/LibOVR/Src/OVR_HIDDeviceImpl.h
vendored
Executable file → Normal 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
Normal file
143
interface/external/LibOVR/Src/OVR_JSON.h
vendored
Normal 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
|
22
interface/external/LibOVR/Src/OVR_LatencyTestImpl.h
vendored
Executable file → Normal file
22
interface/external/LibOVR/Src/OVR_LatencyTestImpl.h
vendored
Executable file → Normal 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
|
||||
|
|
111
interface/external/LibOVR/Src/OVR_Linux_DeviceManager.h
vendored
Normal file
111
interface/external/LibOVR/Src/OVR_Linux_DeviceManager.h
vendored
Normal 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
|
124
interface/external/LibOVR/Src/OVR_Linux_HIDDevice.h
vendored
Normal file
124
interface/external/LibOVR/Src/OVR_Linux_HIDDevice.h
vendored
Normal 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
|
156
interface/external/LibOVR/Src/OVR_Linux_HMDDevice.h
vendored
Normal file
156
interface/external/LibOVR/Src/OVR_Linux_HMDDevice.h
vendored
Normal 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
|
||||
|
12
interface/external/LibOVR/Src/OVR_OSX_DeviceManager.h
vendored
Executable file → Normal file
12
interface/external/LibOVR/Src/OVR_OSX_DeviceManager.h
vendored
Executable file → Normal 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;
|
||||
|
||||
|
|
9
interface/external/LibOVR/Src/OVR_OSX_HIDDevice.h
vendored
Executable file → Normal file
9
interface/external/LibOVR/Src/OVR_OSX_HIDDevice.h
vendored
Executable file → Normal 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;
|
||||
|
|
26
interface/external/LibOVR/Src/OVR_OSX_HMDDevice.h
vendored
Executable file → Normal file
26
interface/external/LibOVR/Src/OVR_OSX_HMDDevice.h
vendored
Executable file → Normal 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;
|
||||
};
|
||||
|
||||
|
||||
|
|
243
interface/external/LibOVR/Src/OVR_Profile.h
vendored
Normal file
243
interface/external/LibOVR/Src/OVR_Profile.h
vendored
Normal file
|
@ -0,0 +1,243 @@
|
|||
/************************************************************************************
|
||||
|
||||
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_GenericHMD = 10,
|
||||
Profile_RiftDK1 = 11,
|
||||
Profile_RiftDKHD = 12,
|
||||
};
|
||||
|
||||
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 users. This object is not created directly.
|
||||
// Instead derived device objects provide add specific device members to
|
||||
// the base profile
|
||||
|
||||
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:
|
||||
virtual Profile* Clone() const = 0;
|
||||
|
||||
// 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 bool ParseProperty(const char* prop, const char* sval);
|
||||
|
||||
friend class ProfileManager;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ***** HMDProfile
|
||||
|
||||
// The generic HMD profile is used for properties that are common to all headsets
|
||||
class HMDProfile : public Profile
|
||||
{
|
||||
protected:
|
||||
// FOV extents in pixels measured by a user
|
||||
int LL; // left eye outer extent
|
||||
int LR; // left eye inner extent
|
||||
int RL; // right eye inner extent
|
||||
int RR; // right eye outer extent
|
||||
|
||||
public:
|
||||
virtual Profile* Clone() const;
|
||||
|
||||
void SetLL(int val) { LL = val; };
|
||||
void SetLR(int val) { LR = val; };
|
||||
void SetRL(int val) { RL = val; };
|
||||
void SetRR(int val) { RR = val; };
|
||||
|
||||
int GetLL() { return LL; };
|
||||
int GetLR() { return LR; };
|
||||
int GetRL() { return RL; };
|
||||
int GetRR() { return RR; };
|
||||
|
||||
protected:
|
||||
HMDProfile(ProfileType type, const char* name);
|
||||
|
||||
virtual bool ParseProperty(const char* prop, const char* sval);
|
||||
|
||||
friend class ProfileManager;
|
||||
};
|
||||
|
||||
// For headsets that use eye cups
|
||||
enum EyeCupType
|
||||
{
|
||||
EyeCup_A = 0,
|
||||
EyeCup_B = 1,
|
||||
EyeCup_C = 2
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ***** 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 HMDProfile
|
||||
{
|
||||
protected:
|
||||
EyeCupType EyeCups; // Which eye cup does the player use
|
||||
|
||||
public:
|
||||
virtual Profile* Clone() const;
|
||||
|
||||
EyeCupType GetEyeCup() { return EyeCups; };
|
||||
void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
|
||||
|
||||
protected:
|
||||
RiftDK1Profile(const char* name);
|
||||
|
||||
virtual bool ParseProperty(const char* prop, const char* sval);
|
||||
|
||||
friend class ProfileManager;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ***** RiftDKHDProfile
|
||||
|
||||
// This profile is specific to the Rift HD Dev Kit and contains overrides specific
|
||||
// to that device and lens cup settings.
|
||||
class RiftDKHDProfile : public HMDProfile
|
||||
{
|
||||
protected:
|
||||
EyeCupType EyeCups; // Which eye cup does the player use
|
||||
|
||||
public:
|
||||
virtual Profile* Clone() const;
|
||||
|
||||
EyeCupType GetEyeCup() { return EyeCups; };
|
||||
void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
|
||||
|
||||
protected:
|
||||
RiftDKHDProfile(const char* name);
|
||||
|
||||
virtual bool ParseProperty(const char* prop, const char* sval);
|
||||
|
||||
friend class ProfileManager;
|
||||
};
|
||||
|
||||
|
||||
String GetBaseOVRPath(bool create_dir);
|
||||
|
||||
}
|
||||
|
||||
#endif // OVR_Profile_h
|
203
interface/external/LibOVR/Src/OVR_SensorFilter.h
vendored
Executable file → Normal file
203
interface/external/LibOVR/Src/OVR_SensorFilter.h
vendored
Executable file → Normal file
|
@ -4,7 +4,7 @@ PublicHeader: OVR.h
|
|||
Filename : OVR_SensorFilter.h
|
||||
Content : Basic filtering of sensor data
|
||||
Created : March 7, 2013
|
||||
Authors : Steve LaValle, Anna Yershova
|
||||
Authors : Steve LaValle, Anna Yershova, Max Katsev
|
||||
|
||||
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
||||
|
||||
|
@ -22,74 +22,179 @@ otherwise accompanies this software in either electronic or hard copy form.
|
|||
|
||||
namespace OVR {
|
||||
|
||||
// This class maintains a sliding window of sensor data taken over time and implements
|
||||
// various simple filters, most of which are linear functions of the data history.
|
||||
class SensorFilter
|
||||
// A simple circular buffer data structure that stores last N elements in an array
|
||||
template <typename T>
|
||||
class CircularBuffer
|
||||
{
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
MaxFilterSize = 100,
|
||||
DefaultFilterSize = 20
|
||||
DefaultFilterCapacity = 20
|
||||
};
|
||||
|
||||
private:
|
||||
int LastIdx; // The index of the last element that was added to the array
|
||||
int Size; // The window size (number of elements)
|
||||
Vector3f Elements[MaxFilterSize];
|
||||
int LastIdx; // The index of the last element that was added to the buffer
|
||||
int Capacity; // The buffer size (maximum number of elements)
|
||||
int Count; // Number of elements in the filter
|
||||
T* Elements;
|
||||
|
||||
public:
|
||||
// Create a new filter with default size
|
||||
SensorFilter()
|
||||
CircularBuffer(int capacity = DefaultFilterCapacity)
|
||||
: LastIdx(-1), Capacity(capacity), Count(0)
|
||||
{
|
||||
LastIdx = -1;
|
||||
Size = DefaultFilterSize;
|
||||
};
|
||||
Elements = (T*)OVR_ALLOC(capacity * sizeof(T));
|
||||
for (int i = 0; i < Capacity; i++)
|
||||
Elements[i] = T();
|
||||
}
|
||||
|
||||
// Create a new filter with size i
|
||||
SensorFilter(const int &i)
|
||||
~CircularBuffer() {
|
||||
OVR_FREE(Elements);
|
||||
}
|
||||
|
||||
private:
|
||||
// Make the class non-copyable
|
||||
CircularBuffer(const CircularBuffer& other);
|
||||
CircularBuffer& operator=(const CircularBuffer& other);
|
||||
|
||||
public:
|
||||
// Add a new element to the filter
|
||||
void AddElement (const T &e)
|
||||
{
|
||||
OVR_ASSERT(i <= MaxFilterSize);
|
||||
LastIdx = -1;
|
||||
Size = i;
|
||||
};
|
||||
|
||||
|
||||
// Create a new element to the filter
|
||||
void AddElement (const Vector3f &e)
|
||||
{
|
||||
if (LastIdx == Size - 1)
|
||||
LastIdx = 0;
|
||||
else
|
||||
LastIdx++;
|
||||
|
||||
LastIdx = (LastIdx + 1) % Capacity;
|
||||
Elements[LastIdx] = e;
|
||||
};
|
||||
if (Count < Capacity)
|
||||
Count++;
|
||||
}
|
||||
|
||||
// Get element i. 0 is the most recent, 1 is one step ago, 2 is two steps ago, ...
|
||||
Vector3f GetPrev(const int &i)
|
||||
T GetPrev(int i = 0) const
|
||||
{
|
||||
int idx = (LastIdx - i) % Size;
|
||||
if (idx < 0) // Fix the negative mod problem
|
||||
idx += Size;
|
||||
OVR_ASSERT(i >= 0);
|
||||
if (i >= Count) // return 0 if the filter doesn't have enough elements
|
||||
return T();
|
||||
int idx = (LastIdx - i);
|
||||
if (idx < 0) // Fix the wraparound case
|
||||
idx += Capacity;
|
||||
OVR_ASSERT(idx >= 0); // Multiple wraparounds not allowed
|
||||
return Elements[idx];
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// A base class for filters that maintains a buffer of sensor data taken over time and implements
|
||||
// various simple filters, most of which are linear functions of the data history.
|
||||
// Maintains the running sum of its elements for better performance on large capacity values
|
||||
template <typename T>
|
||||
class SensorFilterBase : public CircularBuffer<T>
|
||||
{
|
||||
protected:
|
||||
T RunningTotal; // Cached sum of the elements
|
||||
|
||||
public:
|
||||
SensorFilterBase(int capacity = CircularBuffer<T>::DefaultFilterCapacity) : CircularBuffer<T>(capacity), RunningTotal() { };
|
||||
|
||||
// Add a new element to the filter
|
||||
// Updates the running sum value
|
||||
void AddElement (const T &e)
|
||||
{
|
||||
int NextIdx = (this->LastIdx + 1) % this->Capacity;
|
||||
RunningTotal += (e - this->Elements[NextIdx]);
|
||||
CircularBuffer<T>::AddElement(e);
|
||||
if (this->LastIdx == 0)
|
||||
{
|
||||
// update the cached total to avoid error accumulation
|
||||
RunningTotal = T();
|
||||
for (int i = 0; i < this->Count; i++)
|
||||
RunningTotal += this->Elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Simple statistics
|
||||
Vector3f Total();
|
||||
Vector3f Mean();
|
||||
Vector3f Median();
|
||||
Vector3f Variance(); // The diagonal of covariance matrix
|
||||
Matrix4f Covariance();
|
||||
Vector3f PearsonCoefficient();
|
||||
T Total() const
|
||||
{
|
||||
return RunningTotal;
|
||||
}
|
||||
|
||||
T Mean() const
|
||||
{
|
||||
return (this->Count == 0) ? T() : (Total() / (float) this->Count);
|
||||
}
|
||||
|
||||
// A popular family of smoothing filters and smoothed derivatives
|
||||
Vector3f SavitzkyGolaySmooth8();
|
||||
Vector3f SavitzkyGolayDerivative4();
|
||||
Vector3f SavitzkyGolayDerivative5();
|
||||
Vector3f SavitzkyGolayDerivative12();
|
||||
Vector3f SavitzkyGolayDerivativeN(const int &n);
|
||||
T SavitzkyGolaySmooth8() const
|
||||
{
|
||||
OVR_ASSERT(this->Capacity >= 8);
|
||||
return this->GetPrev(0)*0.41667f +
|
||||
this->GetPrev(1)*0.33333f +
|
||||
this->GetPrev(2)*0.25f +
|
||||
this->GetPrev(3)*0.16667f +
|
||||
this->GetPrev(4)*0.08333f -
|
||||
this->GetPrev(6)*0.08333f -
|
||||
this->GetPrev(7)*0.16667f;
|
||||
}
|
||||
|
||||
~SensorFilter() {};
|
||||
T SavitzkyGolayDerivative4() const
|
||||
{
|
||||
OVR_ASSERT(this->Capacity >= 4);
|
||||
return this->GetPrev(0)*0.3f +
|
||||
this->GetPrev(1)*0.1f -
|
||||
this->GetPrev(2)*0.1f -
|
||||
this->GetPrev(3)*0.3f;
|
||||
}
|
||||
|
||||
T SavitzkyGolayDerivative5() const
|
||||
{
|
||||
OVR_ASSERT(this->Capacity >= 5);
|
||||
return this->GetPrev(0)*0.2f +
|
||||
this->GetPrev(1)*0.1f -
|
||||
this->GetPrev(3)*0.1f -
|
||||
this->GetPrev(4)*0.2f;
|
||||
}
|
||||
|
||||
T SavitzkyGolayDerivative12() const
|
||||
{
|
||||
OVR_ASSERT(this->Capacity >= 12);
|
||||
return this->GetPrev(0)*0.03846f +
|
||||
this->GetPrev(1)*0.03147f +
|
||||
this->GetPrev(2)*0.02448f +
|
||||
this->GetPrev(3)*0.01748f +
|
||||
this->GetPrev(4)*0.01049f +
|
||||
this->GetPrev(5)*0.0035f -
|
||||
this->GetPrev(6)*0.0035f -
|
||||
this->GetPrev(7)*0.01049f -
|
||||
this->GetPrev(8)*0.01748f -
|
||||
this->GetPrev(9)*0.02448f -
|
||||
this->GetPrev(10)*0.03147f -
|
||||
this->GetPrev(11)*0.03846f;
|
||||
}
|
||||
|
||||
T SavitzkyGolayDerivativeN(int n) const
|
||||
{
|
||||
OVR_ASSERT(this->Capacity >= n);
|
||||
int m = (n-1)/2;
|
||||
T result = T();
|
||||
for (int k = 1; k <= m; k++)
|
||||
{
|
||||
int ind1 = m - k;
|
||||
int ind2 = n - m + k - 1;
|
||||
result += (this->GetPrev(ind1) - this->GetPrev(ind2)) * (float) k;
|
||||
}
|
||||
float coef = 3.0f/(m*(m+1.0f)*(2.0f*m+1.0f));
|
||||
result = result*coef;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// This class maintains a buffer of sensor data taken over time and implements
|
||||
// various simple filters, most of which are linear functions of the data history.
|
||||
class SensorFilter : public SensorFilterBase<Vector3f>
|
||||
{
|
||||
public:
|
||||
SensorFilter(int capacity = DefaultFilterCapacity) : SensorFilterBase<Vector3f>(capacity) { };
|
||||
|
||||
// Simple statistics
|
||||
Vector3f Median() const;
|
||||
Vector3f Variance() const; // The diagonal of covariance matrix
|
||||
Matrix4f Covariance() const;
|
||||
Vector3f PearsonCoefficient() const;
|
||||
};
|
||||
|
||||
} //namespace OVR
|
||||
|
|
267
interface/external/LibOVR/Src/OVR_SensorFusion.h
vendored
Executable file → Normal file
267
interface/external/LibOVR/Src/OVR_SensorFusion.h
vendored
Executable file → Normal file
|
@ -4,7 +4,7 @@ PublicHeader: OVR.h
|
|||
Filename : OVR_SensorFusion.h
|
||||
Content : Methods that determine head orientation from sensor data over time
|
||||
Created : October 9, 2012
|
||||
Authors : Michael Antonov, Steve LaValle
|
||||
Authors : Michael Antonov, Steve LaValle, Max Katsev
|
||||
|
||||
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
||||
|
||||
|
@ -19,6 +19,7 @@ otherwise accompanies this software in either electronic or hard copy form.
|
|||
|
||||
#include "OVR_Device.h"
|
||||
#include "OVR_SensorFilter.h"
|
||||
#include <time.h>
|
||||
|
||||
namespace OVR {
|
||||
|
||||
|
@ -27,6 +28,8 @@ namespace OVR {
|
|||
|
||||
// SensorFusion class accumulates Sensor notification messages to keep track of
|
||||
// orientation, which involves integrating the gyro and doing correction with gravity.
|
||||
// Magnetometer based yaw drift correction is also supported; it is usually enabled
|
||||
// automatically based on loaded magnetometer configuration.
|
||||
// Orientation is reported as a quaternion, from which users can obtain either the
|
||||
// rotation matrix or Euler angles.
|
||||
//
|
||||
|
@ -35,11 +38,20 @@ namespace OVR {
|
|||
// - By attaching SensorFusion to a SensorDevice, in which case it will
|
||||
// automatically handle notifications from that device.
|
||||
|
||||
|
||||
class SensorFusion : public NewOverrideBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
MagMaxReferences = 1000
|
||||
};
|
||||
|
||||
public:
|
||||
SensorFusion(SensorDevice* sensor = 0);
|
||||
~SensorFusion();
|
||||
|
||||
|
||||
// *** Setup
|
||||
|
||||
// Attaches this SensorFusion to a sensor device, from which it will receive
|
||||
// notification messages. If a sensor is attached, manual message notification
|
||||
|
@ -47,53 +59,108 @@ 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; }
|
||||
|
||||
bool IsGravityEnabled() const { return EnableGravity;}
|
||||
|
||||
void SetYawCorrectionEnabled(bool enableYawCorrection) { EnableYawCorrection = enableYawCorrection; }
|
||||
|
||||
// Yaw correction is set up to work
|
||||
bool IsYawCorrectionEnabled() const { return EnableYawCorrection;}
|
||||
|
||||
// Yaw correction is currently working (forcing a corrective yaw rotation)
|
||||
bool IsYawCorrectionInProgress() const { return YawCorrectionInProgress;}
|
||||
// *** State Query
|
||||
|
||||
// Obtain the current accumulated orientation. Many apps will want to use GetPredictedOrientation
|
||||
// instead to reduce latency.
|
||||
Quatf GetOrientation() const { return lockedGet(&Q); }
|
||||
|
||||
// Get predicted orientaion in the near future; predictDt is lookahead amount in seconds.
|
||||
Quatf GetPredictedOrientation(float predictDt);
|
||||
Quatf GetPredictedOrientation() { return GetPredictedOrientation(PredictionDT); }
|
||||
|
||||
// Obtain the last absolute acceleration reading, in m/s^2.
|
||||
Vector3f GetAcceleration() const { return lockedGet(&A); }
|
||||
// Obtain the last angular velocity reading, in rad/s.
|
||||
Vector3f GetAngularVelocity() const { return lockedGet(&AngV); }
|
||||
|
||||
// Obtain the last raw magnetometer reading, in Gauss
|
||||
Vector3f GetMagnetometer() const { return lockedGet(&RawMag); }
|
||||
// Obtain the calibrated magnetometer reading (direction and field strength)
|
||||
Vector3f GetCalibratedMagnetometer() const { OVR_ASSERT(MagCalibrated); return lockedGet(&CalMag); }
|
||||
|
||||
|
||||
// Resets the current orientation.
|
||||
void Reset();
|
||||
|
||||
|
||||
|
||||
// *** Configuration
|
||||
|
||||
void EnableMotionTracking(bool enable = true) { MotionTrackingEnabled = enable; }
|
||||
bool IsMotionTrackingEnabled() const { return MotionTrackingEnabled; }
|
||||
|
||||
|
||||
|
||||
// *** Prediction Control
|
||||
|
||||
// Prediction functions.
|
||||
// Prediction delta specifes how much prediction should be applied in seconds; it should in
|
||||
// general be under the average rendering latency. Call GetPredictedOrientation() to get
|
||||
// predicted orientation.
|
||||
float GetPredictionDelta() const { return PredictionDT; }
|
||||
void SetPrediction(float dt, bool enable = true) { PredictionDT = dt; EnablePrediction = enable; }
|
||||
void SetPredictionEnabled(bool enable = true) { EnablePrediction = enable; }
|
||||
bool IsPredictionEnabled() { return EnablePrediction; }
|
||||
|
||||
|
||||
// *** Accelerometer/Gravity Correction Control
|
||||
|
||||
// Enables/disables gravity correction (on by default).
|
||||
void SetGravityEnabled(bool enableGravity) { EnableGravity = enableGravity; }
|
||||
bool IsGravityEnabled() const { return EnableGravity;}
|
||||
|
||||
// Gain used to correct gyro with accel. Default value is appropriate for typical use.
|
||||
float GetAccelGain() const { return Gain; }
|
||||
void SetAccelGain(float ag) { Gain = ag; }
|
||||
|
||||
|
||||
// *** Magnetometer and Yaw Drift Correction Control
|
||||
|
||||
// Methods to load and save a mag calibration. Calibrations can optionally
|
||||
// be specified by name to differentiate multiple calibrations under different conditions
|
||||
// If LoadMagCalibration succeeds, it will override YawCorrectionEnabled based on
|
||||
// saved calibration setting.
|
||||
bool SaveMagCalibration(const char* calibrationName = NULL) const;
|
||||
bool LoadMagCalibration(const char* calibrationName = NULL);
|
||||
|
||||
// Enables/disables magnetometer based yaw drift correction. Must also have mag calibration
|
||||
// data for this correction to work.
|
||||
void SetYawCorrectionEnabled(bool enable) { EnableYawCorrection = enable; }
|
||||
// Determines if yaw correction is enabled.
|
||||
bool IsYawCorrectionEnabled() const { return EnableYawCorrection;}
|
||||
|
||||
// Store the calibration matrix for the magnetometer
|
||||
void SetMagCalibration(const Matrix4f& m)
|
||||
{
|
||||
MagCalibrationMatrix = m;
|
||||
time(&MagCalibrationTime); // time stamp the calibration
|
||||
MagCalibrated = true;
|
||||
}
|
||||
|
||||
// Retrieves the magnetometer calibration matrix
|
||||
Matrix4f GetMagCalibration() const { return MagCalibrationMatrix; }
|
||||
// Retrieve the time of the calibration
|
||||
time_t GetMagCalibrationTime() const { return MagCalibrationTime; }
|
||||
|
||||
// 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;
|
||||
}
|
||||
void ClearMagCalibration() { MagCalibrated = 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); }
|
||||
// These refer to reference points that associate mag readings with orientations
|
||||
void ClearMagReferences() { MagNumReferences = 0; }
|
||||
|
||||
bool HasMagReference() const { return MagReferenced; }
|
||||
|
||||
void ClearMagReference()
|
||||
{
|
||||
MagReferenced = false;
|
||||
MagReady = false;
|
||||
}
|
||||
Vector3f GetCalibratedMagValue(const Vector3f& rawMag) const;
|
||||
|
||||
bool IsMagReady() const { return MagReady; }
|
||||
|
||||
void SetMagRefDistance(const float d) { MagRefDistance = d; }
|
||||
|
||||
// *** Message Handler Logic
|
||||
|
||||
// Notifies SensorFusion object about a new BodyFrame message from a sensor.
|
||||
// Should be called by user if not attaching to a sensor.
|
||||
|
@ -103,99 +170,33 @@ public:
|
|||
handleMessage(msg);
|
||||
}
|
||||
|
||||
// Obtain the current accumulated orientation.
|
||||
Quatf GetOrientation() const
|
||||
{
|
||||
Lock::Locker lockScope(Handler.GetHandlerLock());
|
||||
return Q;
|
||||
}
|
||||
Quatf GetPredictedOrientation() const
|
||||
{
|
||||
Lock::Locker lockScope(Handler.GetHandlerLock());
|
||||
return QP;
|
||||
}
|
||||
// Obtain the last absolute acceleration reading, in m/s^2.
|
||||
Vector3f GetAcceleration() const
|
||||
{
|
||||
Lock::Locker lockScope(Handler.GetHandlerLock());
|
||||
return A;
|
||||
}
|
||||
|
||||
// Obtain the last angular velocity reading, in rad/s.
|
||||
Vector3f GetAngularVelocity() const
|
||||
{
|
||||
Lock::Locker lockScope(Handler.GetHandlerLock());
|
||||
return AngV;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
float GetMagRefYaw() const
|
||||
{
|
||||
return MagRefYaw;
|
||||
}
|
||||
// For later
|
||||
//Vector3f GetGravity() const;
|
||||
|
||||
// Resets the current orientation
|
||||
void Reset()
|
||||
{
|
||||
MagReferenced = false;
|
||||
|
||||
Lock::Locker lockScope(Handler.GetHandlerLock());
|
||||
Q = Quatf();
|
||||
QP = Quatf();
|
||||
|
||||
Stage = 0;
|
||||
}
|
||||
|
||||
// Configuration
|
||||
|
||||
// Gain used to correct gyro with accel. Default value is appropriate for typical use.
|
||||
float GetAccelGain() const { return Gain; }
|
||||
void SetAccelGain(float ag) { Gain = ag; }
|
||||
|
||||
// Multiplier for yaw rotation (turning); setting this higher than 1 (the default) can allow the game
|
||||
// to be played without auxillary rotation controls, possibly making it more immersive. Whether this is more
|
||||
// or less likely to cause motion sickness is unknown.
|
||||
float GetYawMultiplier() const { return YawMult; }
|
||||
void SetYawMultiplier(float y) { YawMult = y; }
|
||||
|
||||
void SetDelegateMessageHandler(MessageHandler* handler)
|
||||
{ pDelegate = handler; }
|
||||
|
||||
// Prediction functions.
|
||||
// Prediction delta specifes how much prediction should be applied in seconds; it should in
|
||||
// general be under the average rendering latency. Call GetPredictedOrientation() to get
|
||||
// predicted orientation.
|
||||
float GetPredictionDelta() const { return PredictionDT; }
|
||||
void SetPrediction(float dt, bool enable = true) { PredictionDT = dt; EnablePrediction = enable; }
|
||||
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);
|
||||
// Helper used to read and return value within a Lock.
|
||||
template<class C>
|
||||
C lockedGet(const C* p) const
|
||||
{
|
||||
Lock::Locker lockScope(Handler.GetHandlerLock());
|
||||
return *p;
|
||||
}
|
||||
|
||||
class BodyFrameHandler : public MessageHandler
|
||||
// Internal handler for messages; bypasses error checking.
|
||||
void handleMessage(const MessageBodyFrame& msg);
|
||||
|
||||
// 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:
|
||||
|
@ -206,44 +207,44 @@ private:
|
|||
virtual bool SupportsMessageType(MessageType type) const;
|
||||
};
|
||||
|
||||
SensorInfo CachedSensorInfo;
|
||||
|
||||
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;
|
||||
float YawMult;
|
||||
volatile bool EnableGravity;
|
||||
|
||||
bool EnablePrediction;
|
||||
float PredictionDT;
|
||||
Quatf QP;
|
||||
float PredictionTimeIncrement;
|
||||
|
||||
SensorFilter FMag;
|
||||
SensorFilter FAccW;
|
||||
SensorFilter FRawMag;
|
||||
SensorFilter FAngV;
|
||||
|
||||
int TiltCondCount;
|
||||
float TiltErrorAngle;
|
||||
Vector3f TiltErrorAxis;
|
||||
Vector3f GyroOffset;
|
||||
SensorFilterBase<float> TiltAngleFilter;
|
||||
|
||||
|
||||
bool EnableYawCorrection;
|
||||
Matrix4f MagCalibrationMatrix;
|
||||
bool MagCalibrated;
|
||||
int MagCondCount;
|
||||
bool MagReferenced;
|
||||
float MagRefDistance;
|
||||
bool MagReady;
|
||||
Quatf MagRefQ;
|
||||
Vector3f MagRefM;
|
||||
float MagRefYaw;
|
||||
float YawErrorAngle;
|
||||
int YawErrorCount;
|
||||
bool YawCorrectionInProgress;
|
||||
Matrix4f MagCalibrationMatrix;
|
||||
time_t MagCalibrationTime;
|
||||
int MagNumReferences;
|
||||
Vector3f MagRefsInBodyFrame[MagMaxReferences];
|
||||
Vector3f MagRefsInWorldFrame[MagMaxReferences];
|
||||
int MagRefIdx;
|
||||
int MagRefScore;
|
||||
|
||||
bool MotionTrackingEnabled;
|
||||
};
|
||||
|
||||
|
||||
|
|
76
interface/external/LibOVR/Src/OVR_SensorImpl.h
vendored
Executable file → Normal file
76
interface/external/LibOVR/Src/OVR_SensorImpl.h
vendored
Executable file → Normal 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,16 +60,68 @@ 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) &&
|
||||
(HIDDesc.VersionNumber == hidDesc.VersionNumber));
|
||||
}
|
||||
|
||||
virtual bool GetDeviceInfo(DeviceInfo* info) const;
|
||||
};
|
||||
|
||||
// A simple stub for notification of a sensor in Boot Loader mode
|
||||
// This descriptor does not support the creation of a device, only the detection
|
||||
// of its existence to warn apps that the sensor device needs firmware.
|
||||
// The Boot Loader descriptor reuses and is created by the Sensor device factory
|
||||
// but in the future may use a dedicated factory
|
||||
class BootLoaderDeviceCreateDesc : public HIDDeviceCreateDesc
|
||||
{
|
||||
public:
|
||||
BootLoaderDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc)
|
||||
: HIDDeviceCreateDesc(factory, Device_BootLoader, hidDesc) { }
|
||||
|
||||
virtual DeviceCreateDesc* Clone() const
|
||||
{
|
||||
return new BootLoaderDeviceCreateDesc(*this);
|
||||
}
|
||||
|
||||
// Boot Loader device creation is not allowed
|
||||
virtual DeviceBase* NewDeviceInstance() { return NULL; };
|
||||
|
||||
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
|
||||
DeviceCreateDesc**) const
|
||||
{
|
||||
if ((other.Type == Device_BootLoader) && (pFactory == other.pFactory))
|
||||
{
|
||||
const BootLoaderDeviceCreateDesc& s2 = (const BootLoaderDeviceCreateDesc&) other;
|
||||
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
|
||||
{
|
||||
OVR_UNUSED(info);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** OVR::SensorDisplayInfoImpl
|
||||
|
@ -135,9 +189,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 +212,8 @@ protected:
|
|||
Void setCoordinateFrame(CoordinateFrame coordframe);
|
||||
bool setRange(const SensorRange& range);
|
||||
|
||||
Void setReportRate(unsigned rateHz);
|
||||
|
||||
// Called for decoded messages
|
||||
void onTrackerMessage(TrackerMessage* message);
|
||||
|
||||
|
|
0
interface/external/LibOVR/Src/OVR_ThreadCommandQueue.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/OVR_ThreadCommandQueue.h
vendored
Executable file → Normal file
15
interface/external/LibOVR/Src/OVR_Win32_DeviceManager.h
vendored
Executable file → Normal file
15
interface/external/LibOVR/Src/OVR_Win32_DeviceManager.h
vendored
Executable file → Normal 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
|
||||
|
|
2
interface/external/LibOVR/Src/OVR_Win32_DeviceStatus.h
vendored
Executable file → Normal file
2
interface/external/LibOVR/Src/OVR_Win32_DeviceStatus.h
vendored
Executable file → Normal file
|
@ -92,6 +92,8 @@ private: // data
|
|||
|
||||
UINT_PTR LastTimerId;
|
||||
Array<RecoveryTimerDesc> RecoveryTimers;
|
||||
|
||||
GUID HidGuid;
|
||||
};
|
||||
|
||||
}} // namespace OVR::Win32
|
||||
|
|
17
interface/external/LibOVR/Src/OVR_Win32_HIDDevice.h
vendored
Executable file → Normal file
17
interface/external/LibOVR/Src/OVR_Win32_HIDDevice.h
vendored
Executable file → Normal 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
|
||||
|
|
31
interface/external/LibOVR/Src/OVR_Win32_HMDDevice.h
vendored
Executable file → Normal file
31
interface/external/LibOVR/Src/OVR_Win32_HMDDevice.h
vendored
Executable file → Normal 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;
|
||||
};
|
||||
|
||||
|
||||
|
|
0
interface/external/LibOVR/Src/OVR_Win32_SensorDevice.h
vendored
Executable file → Normal file
0
interface/external/LibOVR/Src/OVR_Win32_SensorDevice.h
vendored
Executable file → Normal file
3
interface/external/LibOVR/Src/Util/Util_LatencyTest.h
vendored
Executable file → Normal file
3
interface/external/LibOVR/Src/Util/Util_LatencyTest.h
vendored
Executable file → Normal 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; }
|
||||
|
||||
|
|
|
@ -1,109 +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() :
|
||||
Status(Mag_Uninitialized),
|
||||
MinMagDistance(0.3f), MinQuatDistance(0.5f),
|
||||
SampleCount(0)
|
||||
{
|
||||
MinMagDistanceSq = MinMagDistance * MinMagDistance;
|
||||
MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Methods for automatic magnetometer calibration
|
||||
void BeginAutoCalibration(SensorFusion& sf);
|
||||
unsigned UpdateAutoCalibration(SensorFusion& sf);
|
||||
bool IsAutoCalibrating() const { return Status == 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 Status == 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; }
|
||||
|
||||
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 Status;
|
||||
float MinMagDistance;
|
||||
float MinQuatDistance;
|
||||
float MinMagDistanceSq;
|
||||
float MinQuatDistanceSq;
|
||||
|
||||
unsigned SampleCount;
|
||||
Vector3f MagSamples[4];
|
||||
Quatf QuatSamples[4];
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
3
interface/external/LibOVR/Src/Util/Util_Render_Stereo.h
vendored
Executable file → Normal file
3
interface/external/LibOVR/Src/Util/Util_Render_Stereo.h
vendored
Executable file → Normal 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;
|
||||
|
|
|
@ -30,6 +30,12 @@ uniform vec2 leftBottom;
|
|||
// the right and top edges of the view window
|
||||
uniform vec2 rightTop;
|
||||
|
||||
// an offset value to apply to the texture coordinates
|
||||
uniform vec2 texCoordOffset;
|
||||
|
||||
// a scale value to apply to the texture coordinates
|
||||
uniform vec2 texCoordScale;
|
||||
|
||||
// the radius of the effect
|
||||
uniform float radius;
|
||||
|
||||
|
@ -38,7 +44,7 @@ uniform vec2 noiseScale;
|
|||
|
||||
// given a texture coordinate, returns the 3D view space z coordinate
|
||||
float texCoordToViewSpaceZ(vec2 texCoord) {
|
||||
return (far * near) / (texture2D(depthTexture, texCoord).r * (far - near) - far);
|
||||
return (far * near) / (texture2D(depthTexture, texCoord * texCoordScale + texCoordOffset).r * (far - near) - far);
|
||||
}
|
||||
|
||||
// given a texture coordinate, returns the 3D view space coordinate
|
||||
|
@ -54,11 +60,15 @@ void main(void) {
|
|||
|
||||
vec3 center = texCoordToViewSpace(gl_TexCoord[0].st);
|
||||
|
||||
vec2 rdenominator = 1.0 / (rightTop - leftBottom);
|
||||
vec2 xyFactor = 2.0 * near * rdenominator;
|
||||
vec2 zFactor = (rightTop + leftBottom) * rdenominator;
|
||||
|
||||
float occlusion = 4.0;
|
||||
for (int i = 0; i < SAMPLE_KERNEL_SIZE; i++) {
|
||||
vec3 offset = center + rotation * (radius * sampleKernel[i]);
|
||||
vec4 projected = gl_ProjectionMatrix * vec4(offset, 1.0);
|
||||
float depth = texCoordToViewSpaceZ(projected.xy * 0.5 / projected.w + vec2(0.5, 0.5));
|
||||
vec2 projected = offset.xy * xyFactor + offset.z * zFactor;
|
||||
float depth = texCoordToViewSpaceZ(projected * -0.5 / offset.z + vec2(0.5, 0.5));
|
||||
occlusion += 1.0 - step(offset.z, depth);
|
||||
}
|
||||
|
||||
|
|
36
interface/resources/shaders/oculus.frag
Normal file
36
interface/resources/shaders/oculus.frag
Normal file
|
@ -0,0 +1,36 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// oculus.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 11/26/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// this shader is an adaptation (HLSL -> GLSL, removed conditional) of the one in the Oculus sample
|
||||
// code (Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp), which is under the Apache license
|
||||
// (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
//
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
uniform vec2 lensCenter;
|
||||
uniform vec2 screenCenter;
|
||||
uniform vec2 scale;
|
||||
uniform vec2 scaleIn;
|
||||
uniform vec4 hmdWarpParam;
|
||||
|
||||
vec2 hmdWarp(vec2 in01) {
|
||||
vec2 theta = (in01 - lensCenter) * scaleIn;
|
||||
float rSq = theta.x * theta.x + theta.y * theta.y;
|
||||
vec2 theta1 = theta * (hmdWarpParam.x + hmdWarpParam.y * rSq +
|
||||
hmdWarpParam.z * rSq * rSq + hmdWarpParam.w * rSq * rSq * rSq);
|
||||
return lensCenter + scale * theta1;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec2 tc = hmdWarp(gl_TexCoord[0].st);
|
||||
vec2 below = step(screenCenter.st + vec2(-0.25, -0.5), tc.st);
|
||||
vec2 above = vec2(1.0, 1.0) - step(screenCenter.st + vec2(0.25, 0.5), tc.st);
|
||||
gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), texture2D(texture, tc), above.s * above.t * below.s * below.t);
|
||||
}
|
|
@ -133,8 +133,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_lookatIndicatorScale(1.0f),
|
||||
_perfStatsOn(false),
|
||||
_chatEntryOn(false),
|
||||
_oculusProgram(0),
|
||||
_oculusDistortionScale(1.25),
|
||||
#ifndef _WIN32
|
||||
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
|
||||
#endif
|
||||
|
@ -252,7 +250,6 @@ Application::~Application() {
|
|||
VoxelNode::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown
|
||||
delete Menu::getInstance();
|
||||
|
||||
delete _oculusProgram;
|
||||
delete _settings;
|
||||
delete _followMode;
|
||||
delete _glWidget;
|
||||
|
@ -429,7 +426,7 @@ void Application::paintGL() {
|
|||
}
|
||||
|
||||
if (OculusManager::isConnected()) {
|
||||
displayOculus(whichCamera);
|
||||
OculusManager::display(whichCamera);
|
||||
|
||||
} else {
|
||||
_glowEffect.prepare();
|
||||
|
@ -520,14 +517,11 @@ void Application::paintGL() {
|
|||
}
|
||||
|
||||
void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
|
||||
float aspectRatio = ((float)width/(float)height); // based on screen resize
|
||||
|
||||
if (OculusManager::isConnected()) {
|
||||
// more magic numbers; see Oculus SDK docs, p. 32
|
||||
camera.setAspectRatio(aspectRatio *= 0.5);
|
||||
camera.setFieldOfView(2 * atan((0.0468 * _oculusDistortionScale) / 0.041) * (180 / PIf));
|
||||
OculusManager::configureCamera(camera, width, height);
|
||||
|
||||
} else {
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
camera.setAspectRatio((float)width / height);
|
||||
camera.setFieldOfView(Menu::getInstance()->getFieldOfView());
|
||||
}
|
||||
}
|
||||
|
@ -1473,7 +1467,6 @@ void Application::checkBandwidthMeterClick() {
|
|||
void Application::setFullscreen(bool fullscreen) {
|
||||
_window->setWindowState(fullscreen ? (_window->windowState() | Qt::WindowFullScreen) :
|
||||
(_window->windowState() & ~Qt::WindowFullScreen));
|
||||
updateCursor();
|
||||
}
|
||||
|
||||
void Application::setRenderVoxels(bool voxelRender) {
|
||||
|
@ -1487,6 +1480,54 @@ void Application::doKillLocalVoxels() {
|
|||
_wantToKillLocalVoxels = true;
|
||||
}
|
||||
|
||||
void Application::removeVoxel(glm::vec3 position,
|
||||
float scale) {
|
||||
VoxelDetail voxel;
|
||||
voxel.x = position.x / TREE_SCALE;
|
||||
voxel.y = position.y / TREE_SCALE;
|
||||
voxel.z = position.z / TREE_SCALE;
|
||||
voxel.s = scale / TREE_SCALE;
|
||||
_voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxel);
|
||||
|
||||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||
}
|
||||
|
||||
void Application::makeVoxel(glm::vec3 position,
|
||||
float scale,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
bool isDestructive) {
|
||||
VoxelDetail voxel;
|
||||
voxel.x = position.x / TREE_SCALE;
|
||||
voxel.y = position.y / TREE_SCALE;
|
||||
voxel.z = position.z / TREE_SCALE;
|
||||
voxel.s = scale / TREE_SCALE;
|
||||
voxel.red = red;
|
||||
voxel.green = green;
|
||||
voxel.blue = blue;
|
||||
PACKET_TYPE message = isDestructive ? PACKET_TYPE_SET_VOXEL_DESTRUCTIVE : PACKET_TYPE_SET_VOXEL;
|
||||
_voxelEditSender.sendVoxelEditMessage(message, voxel);
|
||||
|
||||
// create the voxel locally so it appears immediately
|
||||
|
||||
_voxels.createVoxel(voxel.x, voxel.y, voxel.z, voxel.s,
|
||||
voxel.red, voxel.green, voxel.blue,
|
||||
isDestructive);
|
||||
|
||||
// Implement voxel fade effect
|
||||
VoxelFade fade(VoxelFade::FADE_OUT, 1.0f, 1.0f, 1.0f);
|
||||
const float VOXEL_BOUNDS_ADJUST = 0.01f;
|
||||
float slightlyBigger = voxel.s * VOXEL_BOUNDS_ADJUST;
|
||||
fade.voxelDetails.x = voxel.x - slightlyBigger;
|
||||
fade.voxelDetails.y = voxel.y - slightlyBigger;
|
||||
fade.voxelDetails.z = voxel.z - slightlyBigger;
|
||||
fade.voxelDetails.s = voxel.s + slightlyBigger + slightlyBigger;
|
||||
_voxelFades.push_back(fade);
|
||||
|
||||
}
|
||||
|
||||
const glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel) {
|
||||
return glm::vec3((_mouseVoxel.x + _mouseVoxel.s / 2.f) * TREE_SCALE,
|
||||
(_mouseVoxel.y + _mouseVoxel.s / 2.f) * TREE_SCALE,
|
||||
|
@ -2221,11 +2262,11 @@ void Application::updateLeap(float deltaTime) {
|
|||
LeapManager::nextFrame();
|
||||
}
|
||||
|
||||
void Application::updateSixense() {
|
||||
void Application::updateSixense(float deltaTime) {
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateSixense()");
|
||||
|
||||
_sixenseManager.update();
|
||||
_sixenseManager.update(deltaTime);
|
||||
}
|
||||
|
||||
void Application::updateSerialDevices(float deltaTime) {
|
||||
|
@ -2435,7 +2476,7 @@ void Application::update(float deltaTime) {
|
|||
updateMouseVoxels(deltaTime, mouseRayOrigin, mouseRayDirection, distance, face); // UI/UX related to voxels
|
||||
updateHandAndTouch(deltaTime); // Update state for touch sensors
|
||||
updateLeap(deltaTime); // Leap finger-sensing device
|
||||
updateSixense(); // Razer Hydra controllers
|
||||
updateSixense(deltaTime); // Razer Hydra controllers
|
||||
updateSerialDevices(deltaTime); // Read serial port interface devices
|
||||
updateAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||
|
@ -2857,146 +2898,7 @@ void Application::updateShadowMap() {
|
|||
|
||||
glViewport(0, 0, _glWidget->width(), _glWidget->height());
|
||||
}
|
||||
|
||||
// this shader is an adaptation (HLSL -> GLSL, removed conditional) of the one in the Oculus sample
|
||||
// code (Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp), which is under the Apache license
|
||||
// (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
static const char* DISTORTION_FRAGMENT_SHADER =
|
||||
"#version 120\n"
|
||||
"uniform sampler2D texture;"
|
||||
"uniform vec2 lensCenter;"
|
||||
"uniform vec2 screenCenter;"
|
||||
"uniform vec2 scale;"
|
||||
"uniform vec2 scaleIn;"
|
||||
"uniform vec4 hmdWarpParam;"
|
||||
"vec2 hmdWarp(vec2 in01) {"
|
||||
" vec2 theta = (in01 - lensCenter) * scaleIn;"
|
||||
" float rSq = theta.x * theta.x + theta.y * theta.y;"
|
||||
" vec2 theta1 = theta * (hmdWarpParam.x + hmdWarpParam.y * rSq + "
|
||||
" hmdWarpParam.z * rSq * rSq + hmdWarpParam.w * rSq * rSq * rSq);"
|
||||
" return lensCenter + scale * theta1;"
|
||||
"}"
|
||||
"void main(void) {"
|
||||
" vec2 tc = hmdWarp(gl_TexCoord[0].st);"
|
||||
" vec2 below = step(screenCenter.st + vec2(-0.25, -0.5), tc.st);"
|
||||
" vec2 above = vec2(1.0, 1.0) - step(screenCenter.st + vec2(0.25, 0.5), tc.st);"
|
||||
" gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), texture2D(texture, tc), "
|
||||
" above.s * above.t * below.s * below.t);"
|
||||
"}";
|
||||
|
||||
void Application::displayOculus(Camera& whichCamera) {
|
||||
_glowEffect.prepare();
|
||||
|
||||
// magic numbers ahoy! in order to avoid pulling in the Oculus utility library that calculates
|
||||
// the rendering parameters from the hardware stats, i just folded their calculations into
|
||||
// constants using the stats for the current-model hardware as contained in the SDK file
|
||||
// LibOVR/Src/Util/Util_Render_Stereo.cpp
|
||||
|
||||
// eye
|
||||
|
||||
// render the left eye view to the left side of the screen
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.151976, 0, 0); // +h, see Oculus SDK docs p. 26
|
||||
gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(),
|
||||
whichCamera.getNearClip(), whichCamera.getFarClip());
|
||||
|
||||
glViewport(0, 0, _glWidget->width() / 2, _glWidget->height());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.032, 0, 0); // dip/2, see p. 27
|
||||
|
||||
displaySide(whichCamera);
|
||||
|
||||
// and the right eye to the right side
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glTranslatef(-0.151976, 0, 0); // -h
|
||||
gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(),
|
||||
whichCamera.getNearClip(), whichCamera.getFarClip());
|
||||
|
||||
glViewport(_glWidget->width() / 2, 0, _glWidget->width() / 2, _glWidget->height());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(-0.032, 0, 0);
|
||||
|
||||
displaySide(whichCamera);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// restore our normal viewport
|
||||
glViewport(0, 0, _glWidget->width(), _glWidget->height());
|
||||
|
||||
QOpenGLFramebufferObject* fbo = _glowEffect.render(true);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->texture());
|
||||
|
||||
if (_oculusProgram == 0) {
|
||||
_oculusProgram = new ProgramObject();
|
||||
_oculusProgram->addShaderFromSourceCode(QGLShader::Fragment, DISTORTION_FRAGMENT_SHADER);
|
||||
_oculusProgram->link();
|
||||
|
||||
_textureLocation = _oculusProgram->uniformLocation("texture");
|
||||
_lensCenterLocation = _oculusProgram->uniformLocation("lensCenter");
|
||||
_screenCenterLocation = _oculusProgram->uniformLocation("screenCenter");
|
||||
_scaleLocation = _oculusProgram->uniformLocation("scale");
|
||||
_scaleInLocation = _oculusProgram->uniformLocation("scaleIn");
|
||||
_hmdWarpParamLocation = _oculusProgram->uniformLocation("hmdWarpParam");
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, _glWidget->width(), 0, _glWidget->height());
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// for reference on setting these values, see SDK file Samples/OculusRoomTiny/RenderTiny_Device.cpp
|
||||
|
||||
float scaleFactor = 1.0 / _oculusDistortionScale;
|
||||
float aspectRatio = (_glWidget->width() * 0.5) / _glWidget->height();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
_oculusProgram->bind();
|
||||
_oculusProgram->setUniformValue(_textureLocation, 0);
|
||||
_oculusProgram->setUniformValue(_lensCenterLocation, 0.287994, 0.5); // see SDK docs, p. 29
|
||||
_oculusProgram->setUniformValue(_screenCenterLocation, 0.25, 0.5);
|
||||
_oculusProgram->setUniformValue(_scaleLocation, 0.25 * scaleFactor, 0.5 * scaleFactor * aspectRatio);
|
||||
_oculusProgram->setUniformValue(_scaleInLocation, 4, 2 / aspectRatio);
|
||||
_oculusProgram->setUniformValue(_hmdWarpParamLocation, 1.0, 0.22, 0.24, 0);
|
||||
|
||||
glColor3f(1, 0, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glTexCoord2f(0.5, 0);
|
||||
glVertex2f(_glWidget->width()/2, 0);
|
||||
glTexCoord2f(0.5, 1);
|
||||
glVertex2f(_glWidget->width() / 2, _glWidget->height());
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(0, _glWidget->height());
|
||||
glEnd();
|
||||
|
||||
_oculusProgram->setUniformValue(_lensCenterLocation, 0.787994, 0.5);
|
||||
_oculusProgram->setUniformValue(_screenCenterLocation, 0.75, 0.5);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.5, 0);
|
||||
glVertex2f(_glWidget->width() / 2, 0);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(_glWidget->width(), 0);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(_glWidget->width(), _glWidget->height());
|
||||
glTexCoord2f(0.5, 1);
|
||||
glVertex2f(_glWidget->width() / 2, _glWidget->height());
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
_oculusProgram->release();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
const GLfloat WHITE_SPECULAR_COLOR[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
const GLfloat NO_SPECULAR_COLOR[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
|
@ -3019,18 +2921,6 @@ void Application::setupWorldLight() {
|
|||
glMateriali(GL_FRONT, GL_SHININESS, 96);
|
||||
}
|
||||
|
||||
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||
glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix);
|
||||
glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y,
|
||||
translation.z + _viewMatrixTranslation.z);
|
||||
}
|
||||
|
||||
void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near,
|
||||
float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
|
||||
|
||||
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, near, far, nearClipPlane, farClipPlane);
|
||||
}
|
||||
|
||||
void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||
// transform by eye offset
|
||||
|
@ -3274,6 +3164,18 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||
glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix);
|
||||
glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y,
|
||||
translation.z + _viewMatrixTranslation.z);
|
||||
}
|
||||
|
||||
void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near,
|
||||
float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
|
||||
|
||||
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, near, far, nearClipPlane, farClipPlane);
|
||||
}
|
||||
|
||||
void Application::displayOverlay() {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displayOverlay()");
|
||||
|
||||
|
@ -4091,29 +3993,18 @@ bool Application::maybeEditVoxelUnderCursor() {
|
|||
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)
|
||||
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode)) {
|
||||
if (_mouseVoxel.s != 0) {
|
||||
PACKET_TYPE message = Menu::getInstance()->isOptionChecked(MenuOption::DestructiveAddVoxel)
|
||||
? PACKET_TYPE_SET_VOXEL_DESTRUCTIVE
|
||||
: PACKET_TYPE_SET_VOXEL;
|
||||
_voxelEditSender.sendVoxelEditMessage(message, _mouseVoxel);
|
||||
|
||||
// create the voxel locally so it appears immediately
|
||||
_voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s,
|
||||
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue,
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::DestructiveAddVoxel));
|
||||
|
||||
// Implement voxel fade effect
|
||||
VoxelFade fade(VoxelFade::FADE_OUT, 1.0f, 1.0f, 1.0f);
|
||||
const float VOXEL_BOUNDS_ADJUST = 0.01f;
|
||||
float slightlyBigger = _mouseVoxel.s * VOXEL_BOUNDS_ADJUST;
|
||||
fade.voxelDetails.x = _mouseVoxel.x - slightlyBigger;
|
||||
fade.voxelDetails.y = _mouseVoxel.y - slightlyBigger;
|
||||
fade.voxelDetails.z = _mouseVoxel.z - slightlyBigger;
|
||||
fade.voxelDetails.s = _mouseVoxel.s + slightlyBigger + slightlyBigger;
|
||||
_voxelFades.push_back(fade);
|
||||
|
||||
makeVoxel(glm::vec3(_mouseVoxel.x * TREE_SCALE,
|
||||
_mouseVoxel.y * TREE_SCALE,
|
||||
_mouseVoxel.z * TREE_SCALE),
|
||||
_mouseVoxel.s * TREE_SCALE,
|
||||
_mouseVoxel.red,
|
||||
_mouseVoxel.green,
|
||||
_mouseVoxel.blue,
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::DestructiveAddVoxel));
|
||||
|
||||
// inject a sound effect
|
||||
injectVoxelAddedSoundEffect();
|
||||
|
||||
|
||||
// remember the position for drag detection
|
||||
_justEditedVoxel = true;
|
||||
|
||||
|
@ -4203,6 +4094,7 @@ void Application::resetSensors() {
|
|||
_webcam.reset();
|
||||
_faceshift.reset();
|
||||
LeapManager::reset();
|
||||
OculusManager::reset();
|
||||
QCursor::setPos(_headMouseX, _headMouseY);
|
||||
_myAvatar.reset();
|
||||
_myTransmitter.resetLevels();
|
||||
|
@ -4231,11 +4123,6 @@ void Application::setMenuShortcutsEnabled(bool enabled) {
|
|||
setShortcutsEnabled(_window->menuBar(), enabled);
|
||||
}
|
||||
|
||||
void Application::updateCursor() {
|
||||
_glWidget->setCursor(OculusManager::isConnected() && _window->windowState().testFlag(Qt::WindowFullScreen) ?
|
||||
Qt::BlankCursor : Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
void Application::attachNewHeadToNode(Node* newNode) {
|
||||
if (newNode->getLinkedData() == NULL) {
|
||||
newNode->setLinkedData(new Avatar(newNode));
|
||||
|
|
|
@ -117,6 +117,15 @@ public:
|
|||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
void makeVoxel(glm::vec3 position,
|
||||
float scale,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
bool isDestructive);
|
||||
|
||||
void removeVoxel(glm::vec3 position, float scale);
|
||||
|
||||
const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel);
|
||||
|
||||
QGLWidget* getGLWidget() { return _glWidget; }
|
||||
|
@ -155,6 +164,8 @@ public:
|
|||
|
||||
void setupWorldLight();
|
||||
|
||||
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false);
|
||||
|
||||
/// Loads a view matrix that incorporates the specified model translation without the precision issues that can
|
||||
/// result from matrix multiplication at high translation magnitudes.
|
||||
void loadTranslatedViewMatrix(const glm::vec3& translation);
|
||||
|
@ -247,7 +258,7 @@ private:
|
|||
glm::vec3& eyePosition);
|
||||
void updateHandAndTouch(float deltaTime);
|
||||
void updateLeap(float deltaTime);
|
||||
void updateSixense();
|
||||
void updateSixense(float deltaTime);
|
||||
void updateSerialDevices(float deltaTime);
|
||||
void updateThreads(float deltaTime);
|
||||
void updateMyAvatarSimulation(float deltaTime);
|
||||
|
@ -272,8 +283,6 @@ private:
|
|||
glm::vec3 getSunDirection();
|
||||
|
||||
void updateShadowMap();
|
||||
void displayOculus(Camera& whichCamera);
|
||||
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false);
|
||||
void displayOverlay();
|
||||
void displayStats();
|
||||
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
|
||||
|
@ -288,8 +297,6 @@ private:
|
|||
|
||||
void setMenuShortcutsEnabled(bool enabled);
|
||||
|
||||
void updateCursor();
|
||||
|
||||
static void attachNewHeadToNode(Node *newNode);
|
||||
static void* networkReceive(void* args); // network receive thread
|
||||
|
||||
|
@ -416,15 +423,6 @@ private:
|
|||
ChatEntry _chatEntry; // chat entry field
|
||||
bool _chatEntryOn; // Whether to show the chat entry
|
||||
|
||||
ProgramObject* _oculusProgram; // The GLSL program containing the distortion shader
|
||||
float _oculusDistortionScale; // Controls the Oculus field of view
|
||||
int _textureLocation;
|
||||
int _lensCenterLocation;
|
||||
int _screenCenterLocation;
|
||||
int _scaleLocation;
|
||||
int _scaleInLocation;
|
||||
int _hmdWarpParamLocation;
|
||||
|
||||
GeometryCache _geometryCache;
|
||||
TextureCache _textureCache;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
InfoView::InfoView(bool forced) :
|
||||
_forced(forced) {
|
||||
|
||||
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);
|
||||
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
|
||||
|
||||
switchToResourcesParentIfRequired();
|
||||
QString absPath = QFileInfo("resources/html/interface-welcome-allsvg.html").absoluteFilePath();
|
||||
|
|
|
@ -61,6 +61,33 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
|
||||
updateRaveGloveParticles(deltaTime);
|
||||
}
|
||||
|
||||
// Create a voxel at fingertip if controller button is pressed
|
||||
const float FINGERTIP_VOXEL_SIZE = 0.0125;
|
||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
if (palm.isActive()) {
|
||||
FingerData& finger = palm.getFingers()[0];
|
||||
glm::vec3 newVoxelPosition = finger.getTipPosition();
|
||||
if (palm.getControllerButtons() & BUTTON_1) {
|
||||
if (glm::length(newVoxelPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
||||
QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value<QColor>();
|
||||
Application::getInstance()->makeVoxel(newVoxelPosition,
|
||||
FINGERTIP_VOXEL_SIZE,
|
||||
paintColor.red(),
|
||||
paintColor.green(),
|
||||
paintColor.blue(),
|
||||
true);
|
||||
_lastFingerAddVoxel = newVoxelPosition;
|
||||
}
|
||||
} else if (palm.getControllerButtons() & BUTTON_2) {
|
||||
if (glm::length(newVoxelPosition - _lastFingerDeleteVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
||||
Application::getInstance()->removeVoxel(newVoxelPosition, FINGERTIP_VOXEL_SIZE);
|
||||
_lastFingerDeleteVoxel = newVoxelPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hand::calculateGeometry() {
|
||||
|
@ -157,6 +184,45 @@ void Hand::render() {
|
|||
}
|
||||
}
|
||||
|
||||
// If hand controller buttons pressed, render stuff as needed
|
||||
if (getPalms().size() > 0) {
|
||||
for (size_t i = 0; i < getPalms().size(); ++i) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
// If trigger pulled, thrust in that direction and draw beam
|
||||
const float MAX_THRUSTER_BEAM_LENGTH = 5.f;
|
||||
const float THRUSTER_MARKER_SIZE = 0.0125f;
|
||||
if (palm.getJoystickY() != 0.f) {
|
||||
FingerData& finger = palm.getFingers()[0];
|
||||
if (finger.isActive()) {
|
||||
if (palm.getJoystickY() > 0.f) {
|
||||
glColor3f(0, 1, 0);
|
||||
} else {
|
||||
glColor3f(1, 0, 0);
|
||||
}
|
||||
glm::vec3 palmPosition = palm.getPosition();
|
||||
glm::vec3 pointerPosition = palmPosition +
|
||||
glm::normalize(finger.getTipPosition() - palmPosition) *
|
||||
MAX_THRUSTER_BEAM_LENGTH;
|
||||
glPushMatrix();
|
||||
glm::vec3 markerPosition = palmPosition +
|
||||
glm::normalize(finger.getTipPosition() - palmPosition) *
|
||||
MAX_THRUSTER_BEAM_LENGTH *
|
||||
(0.5f + palm.getJoystickY() / 2.f);
|
||||
|
||||
glTranslatef(markerPosition.x, markerPosition.y, markerPosition.z);
|
||||
glutSolidSphere(THRUSTER_MARKER_SIZE, 10, 10);
|
||||
glPopMatrix();
|
||||
glLineWidth(2.0);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(palmPosition.x, palmPosition.y, palmPosition.z);
|
||||
glVertex3f(pointerPosition.x, pointerPosition.y, pointerPosition.z);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
|
@ -227,8 +293,8 @@ void Hand::renderLeapHands() {
|
|||
//const glm::vec3 handColor = _ballColor;
|
||||
const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glPushMatrix();
|
||||
// Draw the leap balls
|
||||
for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) {
|
||||
|
|
|
@ -30,6 +30,7 @@ enum RaveLightsSetting {
|
|||
RAVE_LIGHTS_PARTICLES
|
||||
};
|
||||
|
||||
|
||||
class Avatar;
|
||||
class ProgramObject;
|
||||
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
bool isCollidable; // whether or not the ball responds to collisions
|
||||
float touchForce; // a scalar determining the amount that the cursor (or hand) is penetrating the ball
|
||||
};
|
||||
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine);
|
||||
|
@ -62,7 +63,7 @@ public:
|
|||
// getters
|
||||
const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;}
|
||||
const glm::vec3& getLeapFingerRootBallPosition(int ball) const { return _leapFingerRootBalls[ball].position;}
|
||||
|
||||
|
||||
private:
|
||||
// disallow copies of the Hand, copy of owning Avatar is disallowed too
|
||||
Hand(const Hand&);
|
||||
|
@ -72,6 +73,8 @@ private:
|
|||
float _raveGloveClock;
|
||||
bool _raveGloveInitialized;
|
||||
int _raveGloveEmitter[NUM_FINGERS];
|
||||
|
||||
int _controllerButtons; /// Button states read from hand-held controllers
|
||||
|
||||
Avatar* _owningAvatar;
|
||||
float _renderAlpha;
|
||||
|
@ -79,6 +82,8 @@ private:
|
|||
std::vector<HandBall> _leapFingerTipBalls;
|
||||
std::vector<HandBall> _leapFingerRootBalls;
|
||||
|
||||
glm::vec3 _lastFingerAddVoxel, _lastFingerDeleteVoxel;
|
||||
|
||||
// private methods
|
||||
void setLeapHands(const std::vector<glm::vec3>& handPositions,
|
||||
const std::vector<glm::vec3>& handNormals);
|
||||
|
|
|
@ -848,7 +848,25 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
|||
up;
|
||||
}
|
||||
}
|
||||
|
||||
// Add thrust and rotation from hand controllers
|
||||
const float THRUST_MAG_HAND_JETS = THRUST_MAG_FWD;
|
||||
const float JOYSTICK_YAW_MAG = YAW_MAG;
|
||||
for (size_t i = 0; i < getHand().getPalms().size(); ++i) {
|
||||
PalmData& palm = getHand().getPalms()[i];
|
||||
if (palm.isActive()) {
|
||||
if (palm.getJoystickY() != 0.f) {
|
||||
FingerData& finger = palm.getFingers()[0];
|
||||
if (finger.isActive()) {
|
||||
}
|
||||
glm::vec3 thrustDirection = glm::normalize(finger.getTipPosition() - palm.getPosition());
|
||||
_thrust += thrustDirection * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickY() * _thrustMultiplier * deltaTime;
|
||||
}
|
||||
if (palm.getJoystickX() != 0.f) {
|
||||
_bodyYawDelta -= palm.getJoystickX() * JOYSTICK_YAW_MAG * deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update speed brake status
|
||||
const float MIN_SPEED_BRAKE_VELOCITY = _scale * 0.4f;
|
||||
if ((glm::length(_thrust) == 0.0f) && _isThrustOn && (glm::length(_velocity) > MIN_SPEED_BRAKE_VELOCITY)) {
|
||||
|
|
|
@ -6,21 +6,37 @@
|
|||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "OculusManager.h"
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
bool OculusManager::_isConnected = false;
|
||||
#include "Application.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "OculusManager.h"
|
||||
|
||||
ProgramObject OculusManager::_program;
|
||||
int OculusManager::_textureLocation;
|
||||
int OculusManager::_lensCenterLocation;
|
||||
int OculusManager::_screenCenterLocation;
|
||||
int OculusManager::_scaleLocation;
|
||||
int OculusManager::_scaleInLocation;
|
||||
int OculusManager::_hmdWarpParamLocation;
|
||||
bool OculusManager::_isConnected = false;
|
||||
float OculusManager::_yawOffset = 0;
|
||||
|
||||
#ifdef HAVE_LIBOVR
|
||||
using namespace OVR;
|
||||
using namespace OVR::Util::Render;
|
||||
|
||||
#ifdef __APPLE__
|
||||
Ptr<DeviceManager> OculusManager::_deviceManager;
|
||||
Ptr<HMDDevice> OculusManager::_hmdDevice;
|
||||
Ptr<SensorDevice> OculusManager::_sensorDevice;
|
||||
SensorFusion OculusManager::_sensorFusion;
|
||||
float OculusManager::_yawOffset = 0;
|
||||
SensorFusion* OculusManager::_sensorFusion;
|
||||
StereoConfig OculusManager::_stereoConfig;
|
||||
#endif
|
||||
|
||||
void OculusManager::connect() {
|
||||
#ifdef __APPLE__
|
||||
#ifdef HAVE_LIBOVR
|
||||
System::Init();
|
||||
_deviceManager = *DeviceManager::Create();
|
||||
_hmdDevice = *_deviceManager->EnumerateDevices<HMDDevice>().CreateDevice();
|
||||
|
@ -29,25 +45,152 @@ void OculusManager::connect() {
|
|||
_isConnected = true;
|
||||
|
||||
_sensorDevice = *_hmdDevice->GetSensor();
|
||||
_sensorFusion.AttachToSensor(_sensorDevice);
|
||||
_sensorFusion = new SensorFusion;
|
||||
_sensorFusion->AttachToSensor(_sensorDevice);
|
||||
|
||||
// default the yaw to the current orientation
|
||||
_sensorFusion.SetMagReference();
|
||||
HMDInfo info;
|
||||
_hmdDevice->GetDeviceInfo(&info);
|
||||
_stereoConfig.SetHMDInfo(info);
|
||||
|
||||
switchToResourcesParentIfRequired();
|
||||
_program.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/oculus.frag");
|
||||
_program.link();
|
||||
|
||||
_textureLocation = _program.uniformLocation("texture");
|
||||
_lensCenterLocation = _program.uniformLocation("lensCenter");
|
||||
_screenCenterLocation = _program.uniformLocation("screenCenter");
|
||||
_scaleLocation = _program.uniformLocation("scale");
|
||||
_scaleInLocation = _program.uniformLocation("scaleIn");
|
||||
_hmdWarpParamLocation = _program.uniformLocation("hmdWarpParam");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) {
|
||||
#ifdef HAVE_LIBOVR
|
||||
_stereoConfig.SetFullViewport(Viewport(0, 0, screenWidth, screenHeight));
|
||||
camera.setAspectRatio(_stereoConfig.GetAspect());
|
||||
camera.setFieldOfView(_stereoConfig.GetYFOVDegrees());
|
||||
#endif
|
||||
}
|
||||
|
||||
void OculusManager::display(Camera& whichCamera) {
|
||||
#ifdef HAVE_LIBOVR
|
||||
Application::getInstance()->getGlowEffect()->prepare();
|
||||
|
||||
// render the left eye view to the left side of the screen
|
||||
const StereoEyeParams& leftEyeParams = _stereoConfig.GetEyeRenderParams(StereoEye_Left);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(_stereoConfig.GetProjectionCenterOffset(), 0, 0);
|
||||
gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(),
|
||||
whichCamera.getNearClip(), whichCamera.getFarClip());
|
||||
|
||||
glViewport(leftEyeParams.VP.x, leftEyeParams.VP.y, leftEyeParams.VP.w, leftEyeParams.VP.h);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(_stereoConfig.GetIPD() * 0.5f, 0, 0);
|
||||
|
||||
Application::getInstance()->displaySide(whichCamera);
|
||||
|
||||
// and the right eye to the right side
|
||||
const StereoEyeParams& rightEyeParams = _stereoConfig.GetEyeRenderParams(StereoEye_Right);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glTranslatef(-_stereoConfig.GetProjectionCenterOffset(), 0, 0);
|
||||
gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(),
|
||||
whichCamera.getNearClip(), whichCamera.getFarClip());
|
||||
|
||||
glViewport(rightEyeParams.VP.x, rightEyeParams.VP.y, rightEyeParams.VP.w, rightEyeParams.VP.h);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(_stereoConfig.GetIPD() * -0.5f, 0, 0);
|
||||
|
||||
Application::getInstance()->displaySide(whichCamera);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// restore our normal viewport
|
||||
const Viewport& fullViewport = _stereoConfig.GetFullViewport();
|
||||
glViewport(fullViewport.x, fullViewport.y, fullViewport.w, fullViewport.h);
|
||||
|
||||
QOpenGLFramebufferObject* fbo = Application::getInstance()->getGlowEffect()->render(true);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->texture());
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(fullViewport.x, fullViewport.x + fullViewport.w, fullViewport.y, fullViewport.y + fullViewport.h);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// for reference on setting these values, see SDK file Samples/OculusRoomTiny/RenderTiny_Device.cpp
|
||||
|
||||
float scaleFactor = 1.0 / _stereoConfig.GetDistortionScale();
|
||||
float aspectRatio = _stereoConfig.GetAspect();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
_program.bind();
|
||||
_program.setUniformValue(_textureLocation, 0);
|
||||
const DistortionConfig& distortionConfig = _stereoConfig.GetDistortionConfig();
|
||||
_program.setUniformValue(_lensCenterLocation, (0.5 + distortionConfig.XCenterOffset * 0.5) * 0.5, 0.5);
|
||||
_program.setUniformValue(_screenCenterLocation, 0.25, 0.5);
|
||||
_program.setUniformValue(_scaleLocation, 0.25 * scaleFactor, 0.5 * scaleFactor * aspectRatio);
|
||||
_program.setUniformValue(_scaleInLocation, 4, 2 / aspectRatio);
|
||||
_program.setUniformValue(_hmdWarpParamLocation, distortionConfig.K[0], distortionConfig.K[1],
|
||||
distortionConfig.K[2], distortionConfig.K[3]);
|
||||
|
||||
glColor3f(1, 0, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glTexCoord2f(0.5, 0);
|
||||
glVertex2f(leftEyeParams.VP.w, 0);
|
||||
glTexCoord2f(0.5, 1);
|
||||
glVertex2f(leftEyeParams.VP.w, leftEyeParams.VP.h);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(0, leftEyeParams.VP.h);
|
||||
glEnd();
|
||||
|
||||
_program.setUniformValue(_lensCenterLocation, 0.5 + (0.5 - distortionConfig.XCenterOffset * 0.5) * 0.5, 0.5);
|
||||
_program.setUniformValue(_screenCenterLocation, 0.75, 0.5);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.5, 0);
|
||||
glVertex2f(leftEyeParams.VP.w, 0);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(fullViewport.w, 0);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(fullViewport.w, leftEyeParams.VP.h);
|
||||
glTexCoord2f(0.5, 1);
|
||||
glVertex2f(leftEyeParams.VP.w, leftEyeParams.VP.h);
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
_program.release();
|
||||
|
||||
glPopMatrix();
|
||||
#endif
|
||||
}
|
||||
|
||||
void OculusManager::reset() {
|
||||
#ifdef HAVE_LIBOVR
|
||||
_sensorFusion->Reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void OculusManager::updateYawOffset() {
|
||||
#ifdef __APPLE__
|
||||
#ifdef HAVE_LIBOVR
|
||||
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);
|
||||
#ifdef HAVE_LIBOVR
|
||||
_sensorFusion->GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
|
||||
|
||||
// convert each angle to degrees
|
||||
// remove the yaw offset from the returned yaw
|
||||
|
|
|
@ -10,26 +10,50 @@
|
|||
#define __hifi__OculusManager__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_LIBOVR
|
||||
#include <OVR.h>
|
||||
#endif
|
||||
|
||||
using namespace OVR;
|
||||
#include "renderer/ProgramObject.h"
|
||||
|
||||
class Camera;
|
||||
|
||||
/// Handles interaction with the Oculus Rift.
|
||||
class OculusManager {
|
||||
public:
|
||||
static void connect();
|
||||
|
||||
static bool isConnected() { return _isConnected; }
|
||||
|
||||
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
||||
|
||||
static void display(Camera& whichCamera);
|
||||
|
||||
static void reset();
|
||||
|
||||
static void getEulerAngles(float& yaw, float& pitch, float& roll);
|
||||
|
||||
static void updateYawOffset();
|
||||
private:
|
||||
|
||||
private:
|
||||
static ProgramObject _program;
|
||||
static int _textureLocation;
|
||||
static int _lensCenterLocation;
|
||||
static int _screenCenterLocation;
|
||||
static int _scaleLocation;
|
||||
static int _scaleInLocation;
|
||||
static int _hmdWarpParamLocation;
|
||||
static bool _isConnected;
|
||||
static Ptr<DeviceManager> _deviceManager;
|
||||
static Ptr<HMDDevice> _hmdDevice;
|
||||
static Ptr<SensorDevice> _sensorDevice;
|
||||
static SensorFusion _sensorFusion;
|
||||
static float _yawOffset;
|
||||
|
||||
#ifdef HAVE_LIBOVR
|
||||
static OVR::Ptr<OVR::DeviceManager> _deviceManager;
|
||||
static OVR::Ptr<OVR::HMDDevice> _hmdDevice;
|
||||
static OVR::Ptr<OVR::SensorDevice> _sensorDevice;
|
||||
static OVR::SensorFusion* _sensorFusion;
|
||||
static OVR::Util::Render::StereoConfig _stereoConfig;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__OculusManager__) */
|
||||
|
|
|
@ -25,7 +25,7 @@ SixenseManager::~SixenseManager() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::update() {
|
||||
void SixenseManager::update(float deltaTime) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
if (sixenseGetNumActiveControllers() == 0) {
|
||||
return;
|
||||
|
@ -42,27 +42,19 @@ void SixenseManager::update() {
|
|||
sixenseControllerData data;
|
||||
sixenseGetNewestData(i, &data);
|
||||
|
||||
// drive avatar with joystick and triggers
|
||||
if (data.controller_index) {
|
||||
avatar->setDriveKeys(ROT_LEFT, qMax(0.0f, -data.joystick_x));
|
||||
avatar->setDriveKeys(ROT_RIGHT, qMax(0.0f, data.joystick_x));
|
||||
avatar->setDriveKeys(ROT_UP, qMax(0.0f, data.joystick_y));
|
||||
avatar->setDriveKeys(ROT_DOWN, qMax(0.0f, -data.joystick_y));
|
||||
avatar->setDriveKeys(UP, data.trigger);
|
||||
|
||||
} else {
|
||||
avatar->setDriveKeys(FWD, qMax(0.0f, data.joystick_y));
|
||||
avatar->setDriveKeys(BACK, qMax(0.0f, -data.joystick_y));
|
||||
avatar->setDriveKeys(LEFT, qMax(0.0f, -data.joystick_x));
|
||||
avatar->setDriveKeys(RIGHT, qMax(0.0f, data.joystick_x));
|
||||
avatar->setDriveKeys(DOWN, data.trigger);
|
||||
}
|
||||
|
||||
// Set palm position and normal based on Hydra position/orientation
|
||||
PalmData palm(&hand);
|
||||
palm.setActive(true);
|
||||
glm::vec3 position(data.pos[0], data.pos[1], data.pos[2]);
|
||||
|
||||
// Compute current velocity from position change
|
||||
palm.setVelocity((position - palm.getPosition()) / deltaTime);
|
||||
|
||||
// Read controller buttons and joystick into the hand
|
||||
palm.setControllerButtons(data.buttons);
|
||||
palm.setTrigger(data.trigger);
|
||||
palm.setJoystick(data.joystick_x, data.joystick_y);
|
||||
|
||||
// Adjust for distance between acquisition 'orb' and the user's torso
|
||||
// (distance to the right of body center, distance below torso, distance behind torso)
|
||||
const glm::vec3 SPHERE_TO_TORSO(-250.f, -300.f, -300.f);
|
||||
|
|
|
@ -16,7 +16,7 @@ public:
|
|||
SixenseManager();
|
||||
~SixenseManager();
|
||||
|
||||
void update();
|
||||
void update(float deltaTime);
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__SixenseManager__) */
|
||||
|
|
|
@ -57,6 +57,8 @@ void AmbientOcclusionEffect::init() {
|
|||
_leftBottomLocation = _occlusionProgram->uniformLocation("leftBottom");
|
||||
_rightTopLocation = _occlusionProgram->uniformLocation("rightTop");
|
||||
_noiseScaleLocation = _occlusionProgram->uniformLocation("noiseScale");
|
||||
_texCoordOffsetLocation = _occlusionProgram->uniformLocation("texCoordOffset");
|
||||
_texCoordScaleLocation = _occlusionProgram->uniformLocation("texCoordScale");
|
||||
|
||||
// generate the random rotation texture
|
||||
glGenTextures(1, &_rotationTextureID);
|
||||
|
@ -106,22 +108,25 @@ void AmbientOcclusionEffect::render() {
|
|||
Application::getInstance()->computeOffAxisFrustum(
|
||||
left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
|
||||
int viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
const int VIEWPORT_X_INDEX = 0;
|
||||
const int VIEWPORT_WIDTH_INDEX = 2;
|
||||
QSize widgetSize = Application::getInstance()->getGLWidget()->size();
|
||||
float sMin = viewport[VIEWPORT_X_INDEX] / (float)widgetSize.width();
|
||||
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)widgetSize.width();
|
||||
|
||||
_occlusionProgram->bind();
|
||||
_occlusionProgram->setUniformValue(_nearLocation, nearVal);
|
||||
_occlusionProgram->setUniformValue(_farLocation, farVal);
|
||||
_occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom);
|
||||
_occlusionProgram->setUniformValue(_rightTopLocation, right, top);
|
||||
QSize widgetSize = Application::getInstance()->getGLWidget()->size();
|
||||
_occlusionProgram->setUniformValue(_noiseScaleLocation, widgetSize.width() / (float)ROTATION_WIDTH,
|
||||
_occlusionProgram->setUniformValue(_noiseScaleLocation, viewport[VIEWPORT_WIDTH_INDEX] / (float)ROTATION_WIDTH,
|
||||
widgetSize.height() / (float)ROTATION_HEIGHT);
|
||||
_occlusionProgram->setUniformValue(_texCoordOffsetLocation, sMin, 0.0f);
|
||||
_occlusionProgram->setUniformValue(_texCoordScaleLocation, sWidth, 1.0f);
|
||||
|
||||
int viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
const int VIEWPORT_X_INDEX = 0;
|
||||
const int VIEWPORT_WIDTH_INDEX = 2;
|
||||
float sMin = viewport[VIEWPORT_X_INDEX] / (float)widgetSize.width();
|
||||
float sMax = (viewport[VIEWPORT_X_INDEX] + viewport[VIEWPORT_WIDTH_INDEX]) / (float)widgetSize.width();
|
||||
renderFullscreenQuad(sMin, sMax);
|
||||
renderFullscreenQuad();
|
||||
|
||||
_occlusionProgram->release();
|
||||
|
||||
|
@ -141,7 +146,7 @@ void AmbientOcclusionEffect::render() {
|
|||
_blurProgram->bind();
|
||||
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / widgetSize.width(), 1.0f / widgetSize.height());
|
||||
|
||||
renderFullscreenQuad(sMin, sMax);
|
||||
renderFullscreenQuad(sMin, sMin + sWidth);
|
||||
|
||||
_blurProgram->release();
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ private:
|
|||
int _leftBottomLocation;
|
||||
int _rightTopLocation;
|
||||
int _noiseScaleLocation;
|
||||
int _texCoordOffsetLocation;
|
||||
int _texCoordScaleLocation;
|
||||
|
||||
ProgramObject* _blurProgram;
|
||||
int _blurScaleLocation;
|
||||
|
|
|
@ -37,6 +37,8 @@ PalmData& HandData::addNewPalm() {
|
|||
PalmData::PalmData(HandData* owningHandData) :
|
||||
_rawPosition(0, 0, 0),
|
||||
_rawNormal(0, 1, 0),
|
||||
_velocity(0, 0, 0),
|
||||
_controllerButtons(0),
|
||||
_isActive(false),
|
||||
_leapID(LEAPID_INVALID),
|
||||
_numFramesWithoutData(0),
|
||||
|
|
|
@ -41,6 +41,12 @@ enum RaveGloveEffectsMode
|
|||
NUM_RAVE_GLOVE_EFFECTS_MODES
|
||||
};
|
||||
|
||||
const int BUTTON_1 = 32;
|
||||
const int BUTTON_2 = 64;
|
||||
const int BUTTON_3 = 8;
|
||||
const int BUTTON_4 = 16;
|
||||
const int BUTTON_FWD = 128;
|
||||
|
||||
class HandData {
|
||||
public:
|
||||
HandData(AvatarData* owningAvatar);
|
||||
|
@ -144,17 +150,34 @@ public:
|
|||
void setLeapID(int id) { _leapID = id; }
|
||||
void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; }
|
||||
void setRawNormal(const glm::vec3& normal) { _rawNormal = normal; }
|
||||
void setVelocity(const glm::vec3& velocity) { _velocity = velocity; }
|
||||
const glm::vec3& getVelocity() const { return _velocity; }
|
||||
|
||||
void incrementFramesWithoutData() { _numFramesWithoutData++; }
|
||||
void resetFramesWithoutData() { _numFramesWithoutData = 0; }
|
||||
int getFramesWithoutData() const { return _numFramesWithoutData; }
|
||||
|
||||
// Controller buttons
|
||||
void setControllerButtons(int controllerButtons) { _controllerButtons = controllerButtons; }
|
||||
int getControllerButtons() { return _controllerButtons; }
|
||||
|
||||
void setTrigger(float trigger) { _trigger = trigger; }
|
||||
float getTrigger() { return _trigger; }
|
||||
void setJoystick(float joystickX, float joystickY) { _joystickX = joystickX; _joystickY = joystickY; }
|
||||
float getJoystickX() { return _joystickX; }
|
||||
float getJoystickY() { return _joystickY; }
|
||||
|
||||
private:
|
||||
std::vector<FingerData> _fingers;
|
||||
glm::vec3 _rawPosition;
|
||||
glm::vec3 _rawNormal;
|
||||
bool _isActive; // This has current valid data
|
||||
int _leapID; // the Leap's serial id for this tracked object
|
||||
glm::vec3 _velocity;
|
||||
int _controllerButtons;
|
||||
float _trigger;
|
||||
float _joystickX, _joystickY;
|
||||
|
||||
bool _isActive; // This has current valid data
|
||||
int _leapID; // the Leap's serial id for this tracked object
|
||||
int _numFramesWithoutData; // after too many frames without data, this tracked object assumed lost.
|
||||
HandData* _owningHandData;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue