From 4207f9c279e832e3afcb3f5fc6cd8d84cb4cfe4c Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Sat, 28 Mar 2015 01:43:35 +0100
Subject: Bump OculusVR RIFT SDK to 0.5.0.1

---
 LibOVR/Include/Extras/OVR_Math.h | 3663 ++++++++++++++++++++++++++++++++++++++
 LibOVR/Include/OVR.h             |   12 +-
 LibOVR/Include/OVR_CAPI.h        |    4 +
 LibOVR/Include/OVR_CAPI_0_5_0.h  | 1178 ++++++++++++
 LibOVR/Include/OVR_CAPI_GL.h     |   87 +
 LibOVR/Include/OVR_CAPI_Keys.h   |   56 +
 LibOVR/Include/OVR_CAPI_Util.h   |   79 +
 LibOVR/Include/OVR_ErrorCode.h   |   66 +
 LibOVR/Include/OVR_Kernel.h      |   30 +-
 LibOVR/Include/OVR_Version.h     |   55 +-
 10 files changed, 5204 insertions(+), 26 deletions(-)
 create mode 100644 LibOVR/Include/Extras/OVR_Math.h
 create mode 100644 LibOVR/Include/OVR_CAPI.h
 create mode 100755 LibOVR/Include/OVR_CAPI_0_5_0.h
 create mode 100644 LibOVR/Include/OVR_CAPI_GL.h
 create mode 100644 LibOVR/Include/OVR_CAPI_Keys.h
 create mode 100644 LibOVR/Include/OVR_CAPI_Util.h
 create mode 100755 LibOVR/Include/OVR_ErrorCode.h
 mode change 100644 => 100755 LibOVR/Include/OVR_Version.h

(limited to 'LibOVR/Include')

diff --git a/LibOVR/Include/Extras/OVR_Math.h b/LibOVR/Include/Extras/OVR_Math.h
new file mode 100644
index 0000000..91f0b07
--- /dev/null
+++ b/LibOVR/Include/Extras/OVR_Math.h
@@ -0,0 +1,3663 @@
+/************************************************************************************
+
+PublicHeader:   OVR_Kernel.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, Max Katsev, Dov Katz
+
+Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 
+you may not use the Oculus VR Rift SDK except in compliance with the License, 
+which is provided at the time of installation or download, or which 
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.2 
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK 
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#ifndef OVR_Math_h
+#define OVR_Math_h
+
+
+// This file is intended to be independent of the rest of LibOVR and LibOVRKernel and thus 
+// has no #include dependencies on either.
+
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include "../OVR_CAPI.h" // Currently required due to a dependence on the ovrFovPort_ declaration.
+
+#if defined(_MSC_VER)
+    #pragma warning(push)
+    #pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+
+#if defined(_MSC_VER)
+    #define OVRMath_sprintf sprintf_s
+#else
+    #define OVRMath_sprintf snprintf
+#endif
+
+
+//-------------------------------------------------------------------------------------
+// ***** OVR_MATH_ASSERT
+//
+// Independent debug break implementation for OVR_Math.h.
+
+#if !defined(OVR_MATH_DEBUG_BREAK)
+    #if defined(_DEBUG)
+        #if defined(_MSC_VER)
+            #define OVR_MATH_DEBUG_BREAK __debugbreak()
+        #else
+            #define OVR_MATH_DEBUG_BREAK __builtin_trap()
+        #endif
+    #else
+        #define OVR_MATH_DEBUG_BREAK ((void)0)
+    #endif
+#endif
+
+
+//-------------------------------------------------------------------------------------
+// ***** OVR_MATH_ASSERT
+//
+// Independent OVR_MATH_ASSERT implementation for OVR_Math.h.
+
+#if !defined(OVR_MATH_ASSERT)
+    #if defined(_DEBUG)
+        #define OVR_MATH_ASSERT(p) if (!(p)) { OVR_MATH_DEBUG_BREAK; }
+    #else
+        #define OVR_MATH_ASSERT(p) ((void)0)
+    #endif
+#endif
+
+
+//-------------------------------------------------------------------------------------
+// ***** OVR_MATH_STATIC_ASSERT
+//
+// Independent OVR_MATH_ASSERT implementation for OVR_Math.h.
+
+#if !defined(OVR_MATH_STATIC_ASSERT)
+    #if defined(__cplusplus) && ((defined(_MSC_VER) && (defined(_MSC_VER) >= 1600)) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L))
+        #define OVR_MATH_STATIC_ASSERT static_assert
+    #else
+        #if !defined(OVR_SA_UNUSED)
+            #if defined(__GNUC__) || defined(__clang__)
+                #define OVR_SA_UNUSED __attribute__((unused))
+            #else
+                #define OVR_SA_UNUSED
+            #endif
+            #define OVR_SA_PASTE(a,b) a##b
+            #define OVR_SA_HELP(a,b)  OVR_SA_PASTE(a,b)
+        #endif
+
+        #define OVR_MATH_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED
+    #endif
+#endif
+
+
+
+namespace OVR {
+
+template<class T>
+const T OVRMath_Min(const T a, const T b)
+{ return (a < b) ? a : b; }
+
+template<class T>
+const T OVRMath_Max(const T a, const T b)
+{ return (b < a) ? a : b; }
+
+template<class T>
+void OVRMath_Swap(T& a, T& b) 
+{  T temp(a); a = b; b = temp; }
+
+
+//-------------------------------------------------------------------------------------
+// ***** Constants for 3D world/axis definitions.
+
+// Definitions of axes for coordinate and rotation conversions.
+enum Axis
+{
+    Axis_X = 0, Axis_Y = 1, Axis_Z = 2
+};
+
+// RotateDirection describes the rotation direction around an axis, interpreted as follows:
+//  CW  - Clockwise while looking "down" from positive axis towards the origin.
+//  CCW - Counter-clockwise while looking from the positive axis towards the origin,
+//        which is in the negative axis direction.
+//  CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate
+//  system defines Y up, X right, and Z back (pointing out from the screen). In this
+//  system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane.
+enum RotateDirection
+{
+    Rotate_CCW = 1,
+    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 coordinate axis points. Used by WorldAxes.
+enum AxisDirection
+{
+    Axis_Up    =  2,
+    Axis_Down  = -2,
+    Axis_Right =  1,
+    Axis_Left  = -1,
+    Axis_In    =  3,
+    Axis_Out   = -3
+};
+
+struct WorldAxes
+{
+    AxisDirection XAxis, YAxis, ZAxis;
+
+    WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z)
+        : XAxis(x), YAxis(y), ZAxis(z) 
+    { OVR_MATH_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
+};
+
+} // namespace OVR
+
+
+//------------------------------------------------------------------------------------//
+// ***** C Compatibility Types
+
+// These declarations are used to support conversion between C types used in
+// LibOVR C interfaces and their C++ versions. As an example, they allow passing
+// Vector3f into a function that expects ovrVector3f.
+
+typedef struct ovrQuatf_ ovrQuatf;
+typedef struct ovrQuatd_ ovrQuatd;
+typedef struct ovrSizei_ ovrSizei;
+typedef struct ovrSizef_ ovrSizef;
+typedef struct ovrSized_ ovrSized;
+typedef struct ovrRecti_ ovrRecti;
+typedef struct ovrVector2i_ ovrVector2i;
+typedef struct ovrVector2f_ ovrVector2f;
+typedef struct ovrVector2d_ ovrVector2d;
+typedef struct ovrVector3f_ ovrVector3f;
+typedef struct ovrVector3d_ ovrVector3d;
+typedef struct ovrVector4f_ ovrVector4f;
+typedef struct ovrVector4d_ ovrVector4d;
+typedef struct ovrMatrix2f_ ovrMatrix2f;
+typedef struct ovrMatrix2d_ ovrMatrix2d;
+typedef struct ovrMatrix3f_ ovrMatrix3f;
+typedef struct ovrMatrix3d_ ovrMatrix3d;
+typedef struct ovrMatrix4f_ ovrMatrix4f;
+typedef struct ovrMatrix4d_ ovrMatrix4d;
+typedef struct ovrPosef_ ovrPosef;
+typedef struct ovrPosed_ ovrPosed;
+typedef struct ovrPoseStatef_ ovrPoseStatef;
+typedef struct ovrPoseStated_ ovrPoseStated;
+
+namespace OVR {
+
+// Forward-declare our templates.
+template<class T> class Quat;
+template<class T> class Size;
+template<class T> class Rect;
+template<class T> class Vector2;
+template<class T> class Vector3;
+template<class T> class Vector4;
+template<class T> class Matrix3;
+template<class T> class Matrix4;
+template<class T> class Pose;
+template<class T> class PoseState;
+
+// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class.
+template<class C>
+struct CompatibleTypes
+{    
+    // Declaration here seems necessary for MSVC; specializations are
+    // used instead.
+    typedef struct {} Type;
+};
+
+// Specializations providing CompatibleTypes::Type value.
+template<> struct CompatibleTypes<Quat<float> >     { typedef ovrQuatf Type; };
+template<> struct CompatibleTypes<Quat<double> >    { typedef ovrQuatd Type; };
+template<> struct CompatibleTypes<Matrix3<float> >  { typedef ovrMatrix3f Type; };
+template<> struct CompatibleTypes<Matrix3<double> > { typedef ovrMatrix3d Type; };
+template<> struct CompatibleTypes<Matrix4<float> >  { typedef ovrMatrix4f Type; };
+template<> struct CompatibleTypes<Matrix4<double> > { typedef ovrMatrix4d Type; };
+template<> struct CompatibleTypes<Size<int> >       { typedef ovrSizei Type; };
+template<> struct CompatibleTypes<Size<float> >     { typedef ovrSizef Type; };
+template<> struct CompatibleTypes<Size<double> >    { typedef ovrSized Type; };
+template<> struct CompatibleTypes<Rect<int> >       { typedef ovrRecti Type; };
+template<> struct CompatibleTypes<Vector2<int> >    { typedef ovrVector2i Type; };
+template<> struct CompatibleTypes<Vector2<float> >  { typedef ovrVector2f Type; };
+template<> struct CompatibleTypes<Vector2<double> > { typedef ovrVector2d Type; };
+template<> struct CompatibleTypes<Vector3<float> >  { typedef ovrVector3f Type; };
+template<> struct CompatibleTypes<Vector3<double> > { typedef ovrVector3d Type; };
+template<> struct CompatibleTypes<Vector4<float> >  { typedef ovrVector4f Type; };
+template<> struct CompatibleTypes<Vector4<double> > { typedef ovrVector4d Type; };
+template<> struct CompatibleTypes<Pose<float> >     { typedef ovrPosef Type; };
+template<> struct CompatibleTypes<Pose<double> >    { typedef ovrPosed Type; };
+
+//------------------------------------------------------------------------------------//
+// ***** 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 T>
+class Math
+{  
+public:
+    // By default, support explicit conversion to float. This allows Vector2<int> to
+    // compile, for example.
+    typedef float OtherFloatType;
+
+    static int Tolerance() { return 0; }  // Default value so integer types compile
+};
+
+
+//------------------------------------------------------------------------------------//
+// ***** double constants
+#define MATH_DOUBLE_PI              3.14159265358979323846
+#define MATH_DOUBLE_TWOPI           (2*MATH_DOUBLE_PI)
+#define MATH_DOUBLE_PIOVER2         (0.5*MATH_DOUBLE_PI)
+#define MATH_DOUBLE_PIOVER4         (0.25*MATH_DOUBLE_PI)
+#define MATH_FLOAT_MAXVALUE             (FLT_MAX) 
+
+#define MATH_DOUBLE_RADTODEGREEFACTOR (360.0 / MATH_DOUBLE_TWOPI)
+#define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0)
+
+#define MATH_DOUBLE_E               2.71828182845904523536
+#define MATH_DOUBLE_LOG2E           1.44269504088896340736
+#define MATH_DOUBLE_LOG10E          0.434294481903251827651
+#define MATH_DOUBLE_LN2             0.693147180559945309417
+#define MATH_DOUBLE_LN10            2.30258509299404568402
+
+#define MATH_DOUBLE_SQRT2           1.41421356237309504880
+#define MATH_DOUBLE_SQRT1_2         0.707106781186547524401
+
+#define MATH_DOUBLE_TOLERANCE		  1e-12	    // a default number for value equality tolerance: about 4096*Epsilon;
+#define MATH_DOUBLE_SINGULARITYRADIUS 1e-12		// about 1-cos(.0001 degree), for gimbal lock numerical problems    
+
+//------------------------------------------------------------------------------------//
+// ***** float constants
+#define MATH_FLOAT_PI		        float(MATH_DOUBLE_PI)
+#define MATH_FLOAT_TWOPI	        float(MATH_DOUBLE_TWOPI)
+#define MATH_FLOAT_PIOVER2          float(MATH_DOUBLE_PIOVER2)
+#define MATH_FLOAT_PIOVER4          float(MATH_DOUBLE_PIOVER4)
+
+#define MATH_FLOAT_RADTODEGREEFACTOR float(MATH_DOUBLE_RADTODEGREEFACTOR)
+#define MATH_FLOAT_DEGREETORADFACTOR float(MATH_DOUBLE_DEGREETORADFACTOR)
+
+#define MATH_FLOAT_E                float(MATH_DOUBLE_E)
+#define MATH_FLOAT_LOG2E            float(MATH_DOUBLE_LOG2E)
+#define MATH_FLOAT_LOG10E           float(MATH_DOUBLE_LOG10E)
+#define MATH_FLOAT_LN2              float(MATH_DOUBLE_LN2)
+#define MATH_FLOAT_LN10             float(MATH_DOUBLE_LN10)
+
+#define MATH_FLOAT_SQRT2            float(MATH_DOUBLE_SQRT2)
+#define MATH_FLOAT_SQRT1_2          float(MATH_DOUBLE_SQRT1_2)
+
+#define MATH_FLOAT_TOLERANCE		 1e-5f	// a default number for value equality tolerance: 1e-5, about 64*EPSILON;
+#define MATH_FLOAT_SINGULARITYRADIUS 1e-7f	// about 1-cos(.025 degree), for gimbal lock numerical problems   
+
+
+
+// Single-precision Math constants class.
+template<>
+class Math<float>
+{
+public:
+     typedef double OtherFloatType;
+
+    static inline float Tolerance()         { return MATH_FLOAT_TOLERANCE; };	// a default number for value equality tolerance
+    static inline float SingularityRadius() { return MATH_FLOAT_SINGULARITYRADIUS; };    // for gimbal lock numerical problems    
+};
+
+// Double-precision Math constants class
+template<>
+class Math<double>
+{
+public:
+    typedef float OtherFloatType;
+
+    static inline double Tolerance()         { return MATH_DOUBLE_TOLERANCE; };	// a default number for value equality tolerance
+    static inline double SingularityRadius() { return MATH_DOUBLE_SINGULARITYRADIUS; };    // for gimbal lock numerical problems    
+};
+
+typedef Math<float>  Mathf;
+typedef Math<double> Mathd;
+
+// Conversion functions between degrees and radians
+// (non-templated to ensure passing int arguments causes warning)
+inline float  RadToDegree(float rad)         { return rad * MATH_FLOAT_RADTODEGREEFACTOR; }
+inline double RadToDegree(double rad)        { return rad * MATH_DOUBLE_RADTODEGREEFACTOR; }
+
+inline float  DegreeToRad(float deg)         { return deg * MATH_FLOAT_DEGREETORADFACTOR; }
+inline double DegreeToRad(double deg)        { return deg * MATH_DOUBLE_DEGREETORADFACTOR; }
+
+// Square function
+template<class T>
+inline T Sqr(T x) { return x*x; }
+
+// Sign: returns 0 if x == 0, -1 if x < 0, and 1 if x > 0
+template<class T>
+inline T Sign(T x) { return (x != T(0)) ? (x < T(0) ? T(-1) : T(1)) : T(0); }
+
+// Numerically stable acos function
+inline float Acos(float x)   { return (x > 1.0f) ? 0.0f : (x < -1.0f) ? MATH_FLOAT_PI : acos(x); }
+inline double Acos(double x) { return (x > 1.0) ? 0.0 : (x < -1.0) ? MATH_DOUBLE_PI : acos(x); }
+
+// Numerically stable asin function
+inline float Asin(float x)   { return (x > 1.0f) ? MATH_FLOAT_PIOVER2 : (x < -1.0f) ? -MATH_FLOAT_PIOVER2 : asin(x); }
+inline double Asin(double x) { return (x > 1.0) ? MATH_DOUBLE_PIOVER2 : (x < -1.0) ? -MATH_DOUBLE_PIOVER2 : asin(x); }
+
+#if defined(_MSC_VER)
+    inline int isnan(double x) { return ::_isnan(x); }
+#elif !defined(isnan) // Some libraries #define isnan.
+    inline int isnan(double x) { return ::isnan(x); }
+#endif
+
+template<class T>
+class Quat;
+
+
+//-------------------------------------------------------------------------------------
+// ***** Vector2<>
+
+// Vector2f (Vector2d) represents a 2-dimensional vector or point in space,
+// consisting of coordinates x and y
+
+template<class T>
+class Vector2
+{
+public:
+    typedef T ElementType;
+    static const size_t ElementCount = 2;
+
+    T x, y;
+
+    Vector2() : x(0), y(0) { }
+    Vector2(T x_, T y_) : x(x_), y(y_) { }
+    explicit Vector2(T s) : x(s), y(s) { }
+    explicit Vector2(const Vector2<typename Math<T>::OtherFloatType> &src)
+        : x((T)src.x), y((T)src.y) { }
+
+    static Vector2 Zero() { return Vector2(0, 0); }
+
+    // C-interop support.
+    typedef  typename CompatibleTypes<Vector2<T> >::Type CompatibleType;
+
+    Vector2(const CompatibleType& s) : x(s.x), y(s.y) {  }
+
+    operator const CompatibleType& () const
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(Vector2<T>) == sizeof(CompatibleType), "sizeof(Vector2<T>) failure");
+        return reinterpret_cast<const CompatibleType&>(*this);
+    }
+
+        
+    bool     operator== (const Vector2& b) const  { return x == b.x && y == b.y; }
+    bool     operator!= (const Vector2& b) const  { return x != b.x || y != b.y; }
+             
+    Vector2  operator+  (const Vector2& b) const  { return Vector2(x + b.x, y + b.y); }
+    Vector2& operator+= (const Vector2& b)        { x += b.x; y += b.y; return *this; }
+    Vector2  operator-  (const Vector2& b) const  { return Vector2(x - b.x, y - b.y); }
+    Vector2& operator-= (const Vector2& b)        { x -= b.x; y -= b.y; return *this; }
+    Vector2  operator- () const                   { return Vector2(-x, -y); }
+
+    // Scalar multiplication/division scales vector.
+    Vector2  operator*  (T s) const               { return Vector2(x*s, y*s); }
+    Vector2& operator*= (T s)                     { x *= s; y *= s; return *this; }
+
+    Vector2  operator/  (T s) const               { T rcp = T(1)/s;
+                                                    return Vector2(x*rcp, y*rcp); }
+    Vector2& operator/= (T s)                     { T rcp = T(1)/s;
+                                                    x *= rcp; y *= rcp;
+                                                    return *this; }
+
+    static Vector2  Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x,
+                                                                             (a.y < b.y) ? a.y : b.y); }
+    static Vector2  Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x,
+                                                                             (a.y > b.y) ? a.y : b.y); }
+
+    // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
+    bool	Compare(const Vector2&b, T tolerance =Math<T>::Tolerance())
+    {
+        return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance);
+    }
+    
+    // Access element by index
+    T& operator[] (int idx)
+    {
+        OVR_MATH_ASSERT(0 <= idx && idx < 2);
+        return *(&x + idx);
+    }
+    const T& operator[] (int idx) const
+    {
+        OVR_MATH_ASSERT(0 <= idx && idx < 2);
+        return *(&x + idx);
+    }
+
+    // Entry-wise product of two vectors
+    Vector2    EntrywiseMultiply(const Vector2& b) const    { return Vector2(x * b.x, y * b.y);}
+
+
+    // Multiply and divide operators do entry-wise math. Used Dot() for dot product.
+    Vector2  operator*  (const Vector2& b) const        { return Vector2(x * b.x,  y * b.y); }
+    Vector2  operator/  (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        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        
+    { 
+        T div = LengthSq()*b.LengthSq();
+        OVR_MATH_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 squared distance between two points represented by vectors.
+    T       DistanceSq(const Vector2& b) const   { return (*this - b).LengthSq(); }
+
+    // Returns distance between two points represented by vectors.
+    T       Distance(const Vector2& b) const     { return (*this - b).Length(); }
+
+    // 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()                          
+    {
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        *this *= s;
+    }
+
+    // Returns normalized (unit) version of the vector without modifying itself.
+    Vector2 Normalized() const                   
+    { 
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        return *this * s; 
+    }
+
+    // Linearly interpolates from this vector to another.
+    // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
+    Vector2 Lerp(const Vector2& b, T f) const    { return *this*(T(1) - f) + b*f; }
+
+    // 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    
+    { 
+        T l2 = b.LengthSq();
+        OVR_MATH_ASSERT(l2 != T(0));
+        return b * ( Dot(b) / l2 ); 
+    }
+    
+    // returns true if vector b is clockwise from this vector
+    bool IsClockwise(const Vector2& b) const
+    {
+        return (x * b.y - y * b.x) < 0;
+    }
+};
+
+
+typedef Vector2<float>  Vector2f;
+typedef Vector2<double> Vector2d;
+typedef Vector2<int>    Vector2i;
+
+typedef Vector2<float>  Point2f;
+typedef Vector2<double> Point2d;
+typedef Vector2<int>    Point2i;
+
+//-------------------------------------------------------------------------------------
+// ***** 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>
+class Vector3
+{
+public:
+    typedef T ElementType;
+    static const size_t ElementCount = 3;
+
+    T x, y, z;
+
+    // FIXME: default initialization of a vector class can be very expensive in a full-blown
+    // application.  A few hundred thousand vector constructions is not unlikely and can add
+    // up to milliseconds of time on processors like the PS3 PPU.
+    Vector3() : x(0), y(0), z(0) { }
+    Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
+    explicit Vector3(T s) : x(s), y(s), z(s) { }
+    explicit Vector3(const Vector3<typename Math<T>::OtherFloatType> &src)
+        : x((T)src.x), y((T)src.y), z((T)src.z) { }
+
+    static Vector3 Zero() { return Vector3(0, 0, 0); }
+
+    // C-interop support.
+    typedef  typename CompatibleTypes<Vector3<T> >::Type CompatibleType;
+
+    Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) {  }
+
+    operator const CompatibleType& () const
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(Vector3<T>) == sizeof(CompatibleType), "sizeof(Vector3<T>) failure");
+        return reinterpret_cast<const CompatibleType&>(*this);
+    }
+
+    bool     operator== (const Vector3& b) const  { return x == b.x && y == b.y && z == b.z; }
+    bool     operator!= (const Vector3& b) const  { return x != b.x || y != b.y || z != b.z; }
+             
+    Vector3  operator+  (const Vector3& b) const  { return Vector3(x + b.x, y + b.y, z + b.z); }
+    Vector3& operator+= (const Vector3& b)        { x += b.x; y += b.y; z += b.z; return *this; }
+    Vector3  operator-  (const Vector3& b) const  { return Vector3(x - b.x, y - b.y, z - b.z); }
+    Vector3& operator-= (const Vector3& b)        { x -= b.x; y -= b.y; z -= b.z; return *this; }
+    Vector3  operator- () const                   { return Vector3(-x, -y, -z); }
+
+    // Scalar multiplication/division scales vector.
+    Vector3  operator*  (T s) const               { return Vector3(x*s, y*s, z*s); }
+    Vector3& operator*= (T s)                     { x *= s; y *= s; z *= s; return *this; }
+
+    Vector3  operator/  (T s) const               { T rcp = T(1)/s;
+                                                    return Vector3(x*rcp, y*rcp, z*rcp); }
+    Vector3& operator/= (T s)                     { T rcp = T(1)/s;
+                                                    x *= rcp; y *= rcp; z *= rcp;
+                                                    return *this; }
+
+    static Vector3  Min(const Vector3& a, const Vector3& b)
+    {
+        return Vector3((a.x < b.x) ? a.x : b.x,
+                       (a.y < b.y) ? a.y : b.y,
+                       (a.z < b.z) ? a.z : b.z);
+    }
+    static Vector3  Max(const Vector3& a, const Vector3& b)
+    { 
+        return Vector3((a.x > b.x) ? a.x : b.x,
+                       (a.y > b.y) ? a.y : b.y,
+                       (a.z > b.z) ? a.z : b.z);
+    }        
+
+    // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
+    bool      IsEqual(const Vector3&b, T tolerance = Math<T>::Tolerance())
+    {
+        return (fabs(b.x-x) < tolerance) && 
+               (fabs(b.y-y) < tolerance) && 
+               (fabs(b.z-z) < tolerance);
+    }
+    
+    T& operator[] (int idx)
+    {
+        OVR_MATH_ASSERT(0 <= idx && idx < 3);
+        return *(&x + idx);
+    }
+
+    const T& operator[] (int idx) const
+    {
+        OVR_MATH_ASSERT(0 <= idx && idx < 3);
+        return *(&x + idx);
+    }
+
+    // Entrywise product of two vectors
+    Vector3    EntrywiseMultiply(const Vector3& b) const    { return Vector3(x * b.x, 
+                                                                         y * b.y, 
+                                                                         z * b.z);}
+
+    // Multiply and divide operators do entry-wise math
+    Vector3  operator*  (const Vector3& b) const        { return Vector3(x * b.x, 
+                                                                         y * b.y, 
+                                                                         z * b.z); }
+
+    Vector3  operator/  (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      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
+    // direction a and middle finger in direction b, thumb will point in a.Cross(b).
+    Vector3 Cross(const Vector3& b) const        { return Vector3(y*b.z - z*b.y,
+                                                                  z*b.x - x*b.z,
+                                                                  x*b.y - y*b.x); }
+
+    // Returns the angle from this vector to b, in radians.
+    T       Angle(const Vector3& b) const 
+    {
+        T div = LengthSq()*b.LengthSq();
+        OVR_MATH_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); }
+
+    // Return vector length.
+    T       Length() const                       { return sqrt(LengthSq()); }
+
+    // Returns squared distance between two points represented by vectors.
+    T       DistanceSq(Vector3 const& b) const         { return (*this - b).LengthSq(); }
+
+    // Returns distance between two points represented by vectors.
+    T       Distance(Vector3 const& b) const     { return (*this - b).Length(); }
+    
+    bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
+
+    // Normalize, convention vector length to 1.    
+    void    Normalize()                          
+    {
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        *this *= s;
+    }
+
+    // Returns normalized (unit) version of the vector without modifying itself.
+    Vector3 Normalized() const                   
+    { 
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        return *this * s;
+    }
+
+    // Linearly interpolates from this vector to another.
+    // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
+    Vector3 Lerp(const Vector3& b, T f) const    { return *this*(T(1) - f) + b*f; }
+
+    // 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    
+    { 
+        T l2 = b.LengthSq();
+        OVR_MATH_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); }
+};
+
+typedef Vector3<float>  Vector3f;
+typedef Vector3<double> Vector3d;
+typedef Vector3<int32_t>  Vector3i;
+    
+OVR_MATH_STATIC_ASSERT((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure");
+OVR_MATH_STATIC_ASSERT((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure");
+OVR_MATH_STATIC_ASSERT((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure");
+
+typedef Vector3<float>   Point3f;
+typedef Vector3<double>  Point3d;
+typedef Vector3<int32_t>  Point3i;
+
+
+//-------------------------------------------------------------------------------------
+// ***** Vector4<> - 4D vector of {x, y, z, w}
+
+//
+// Vector4f (Vector4d) represents a 3-dimensional vector or point in space,
+// consisting of coordinates x, y, z and w.
+
+template<class T>
+class Vector4
+{
+public:
+    typedef T ElementType;
+    static const size_t ElementCount = 4;
+
+    T x, y, z, w;
+
+    // FIXME: default initialization of a vector class can be very expensive in a full-blown
+    // application.  A few hundred thousand vector constructions is not unlikely and can add
+    // up to milliseconds of time on processors like the PS3 PPU.
+    Vector4() : x(0), y(0), z(0), w(0) { }
+    Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
+    explicit Vector4(T s) : x(s), y(s), z(s), w(s) { }
+    explicit Vector4(const Vector3<T>& v, const float w_=1) : x(v.x), y(v.y), z(v.z), w(w_) { }
+    explicit Vector4(const Vector4<typename Math<T>::OtherFloatType> &src)
+        : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { }
+
+    static Vector4 Zero() { return Vector4(0, 0, 0, 0); }
+
+    // C-interop support.
+    typedef  typename CompatibleTypes< Vector4<T> >::Type CompatibleType;
+
+    Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) {  }
+
+    operator const CompatibleType& () const
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(Vector4<T>) == sizeof(CompatibleType), "sizeof(Vector4<T>) failure");
+        return reinterpret_cast<const CompatibleType&>(*this);
+    }
+
+    Vector4& operator= (const Vector3<T>& other)  { x=other.x; y=other.y; z=other.z; w=1; return *this; }
+    bool     operator== (const Vector4& b) const  { return x == b.x && y == b.y && z == b.z && w == b.w; }
+    bool     operator!= (const Vector4& b) const  { return x != b.x || y != b.y || z != b.z || w != b.w; }
+             
+    Vector4  operator+  (const Vector4& b) const  { return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); }
+    Vector4& operator+= (const Vector4& b)        { x += b.x; y += b.y; z += b.z; w += b.w; return *this; }
+    Vector4  operator-  (const Vector4& b) const  { return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); }
+    Vector4& operator-= (const Vector4& b)        { x -= b.x; y -= b.y; z -= b.z; w -= b.w; return *this; }
+    Vector4  operator- () const                   { return Vector4(-x, -y, -z, -w); }
+
+    // Scalar multiplication/division scales vector.
+    Vector4  operator*  (T s) const               { return Vector4(x*s, y*s, z*s, w*s); }
+    Vector4& operator*= (T s)                     { x *= s; y *= s; z *= s; w *= s;return *this; }
+
+    Vector4  operator/  (T s) const               { T rcp = T(1)/s;
+                                                    return Vector4(x*rcp, y*rcp, z*rcp, w*rcp); }
+    Vector4& operator/= (T s)                     { T rcp = T(1)/s;
+                                                    x *= rcp; y *= rcp; z *= rcp; w *= rcp;
+                                                    return *this; }
+
+    static Vector4  Min(const Vector4& a, const Vector4& b)
+    {
+        return Vector4((a.x < b.x) ? a.x : b.x,
+                       (a.y < b.y) ? a.y : b.y,
+                       (a.z < b.z) ? a.z : b.z,
+                       (a.w < b.w) ? a.w : b.w);
+    }
+    static Vector4  Max(const Vector4& a, const Vector4& b)
+    { 
+        return Vector4((a.x > b.x) ? a.x : b.x,
+                       (a.y > b.y) ? a.y : b.y,
+                       (a.z > b.z) ? a.z : b.z,
+                       (a.w > b.w) ? a.w : b.w);
+    }        
+
+    // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
+    bool      Compare(const Vector4&b, T tolerance = Math<T>::Tolerance())
+    {
+        return (fabs(b.x-x) < tolerance) && 
+               (fabs(b.y-y) < tolerance) && 
+               (fabs(b.z-z) < tolerance) &&
+               (fabs(b.w-w) < tolerance);
+    }
+    
+    T& operator[] (int idx)
+    {
+        OVR_MATH_ASSERT(0 <= idx && idx < 4);
+        return *(&x + idx);
+    }
+
+    const T& operator[] (int idx) const
+    {
+        OVR_MATH_ASSERT(0 <= idx && idx < 4);
+        return *(&x + idx);
+    }
+
+    // Entry wise product of two vectors
+    Vector4    EntrywiseMultiply(const Vector4& b) const    { return Vector4(x * b.x, 
+                                                                         y * b.y, 
+                                                                         z * b.z);}
+
+    // Multiply and divide operators do entry-wise math
+    Vector4  operator*  (const Vector4& b) const        { return Vector4(x * b.x, 
+                                                                         y * b.y, 
+                                                                         z * b.z,
+                                                                         w * b.w); }
+
+    Vector4  operator/  (const Vector4& b) const        { return Vector4(x / b.x, 
+                                                                         y / b.y, 
+                                                                         z / b.z,
+                                                                         w / b.w); }
+
+
+    // Dot product
+    T       Dot(const Vector4& b) const          { return x*b.x + y*b.y + z*b.z + w*b.w; }
+
+    // Return Length of the vector squared.
+    T       LengthSq() const                     { return (x * x + y * y + z * z + w * w); }
+
+    // Return vector length.
+    T       Length() const                       { return sqrt(LengthSq()); }
+    
+    bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
+
+    // Normalize, convention vector length to 1.    
+    void    Normalize()                          
+    {
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        *this *= s;
+    }
+
+    // Returns normalized (unit) version of the vector without modifying itself.
+    Vector4 Normalized() const                   
+    { 
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        return *this * s;
+    }
+};
+
+typedef Vector4<float>  Vector4f;
+typedef Vector4<double> Vector4d;
+typedef Vector4<int>    Vector4i;
+
+
+//-------------------------------------------------------------------------------------
+// ***** Bounds3
+
+// Bounds class used to describe a 3D axis aligned bounding box.
+
+template<class T>
+class Bounds3
+{
+public:
+    Vector3<T>    b[2];
+
+    Bounds3()
+    {
+    }
+
+    Bounds3( const Vector3<T> & mins, const Vector3<T> & maxs )
+{
+        b[0] = mins;
+        b[1] = maxs;
+    }
+
+    void Clear()
+    {
+        b[0].x = b[0].y = b[0].z = Math<T>::MaxValue;
+        b[1].x = b[1].y = b[1].z = -Math<T>::MaxValue;
+    }
+
+    void AddPoint( const Vector3<T> & v )
+    {
+        b[0].x = (b[0].x < v.x ? b[0].x : v.x);
+        b[0].y = (b[0].y < v.y ? b[0].y : v.y);
+        b[0].z = (b[0].z < v.z ? b[0].z : v.z);
+        b[1].x = (v.x < b[1].x ? b[1].x : v.x);
+        b[1].y = (v.y < b[1].y ? b[1].y : v.y);
+        b[1].z = (v.z < b[1].z ? b[1].z : v.z);
+    }
+
+    const Vector3<T> & GetMins() const { return b[0]; }
+    const Vector3<T> & GetMaxs() const { return b[1]; }
+
+    Vector3<T> & GetMins() { return b[0]; }
+    Vector3<T> & GetMaxs() { return b[1]; }
+};
+
+typedef Bounds3<float>    Bounds3f;
+typedef Bounds3<double>    Bounds3d;
+
+
+//-------------------------------------------------------------------------------------
+// ***** 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   w, h;
+
+    Size()              : w(0), h(0)   { }
+    Size(T w_, T h_)    : w(w_), h(h_) { }
+    explicit Size(T s)  : w(s), h(s)   { }
+    explicit Size(const Size<typename Math<T>::OtherFloatType> &src)
+        : w((T)src.w), h((T)src.h) { }
+
+    // C-interop support.
+    typedef  typename CompatibleTypes<Size<T> >::Type CompatibleType;
+
+    Size(const CompatibleType& s) : w(s.w), h(s.h) {  }
+
+    operator const CompatibleType& () const
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(Size<T>) == sizeof(CompatibleType), "sizeof(Size<T>) failure");
+        return reinterpret_cast<const CompatibleType&>(*this);
+    }
+
+    bool     operator== (const Size& b) const  { return w == b.w && h == b.h; }
+    bool     operator!= (const Size& b) const  { return w != b.w || h != b.h; }
+             
+    Size  operator+  (const Size& b) const  { return Size(w + b.w, h + b.h); }
+    Size& operator+= (const Size& b)        { w += b.w; h += b.h; return *this; }
+    Size  operator-  (const Size& b) const  { return Size(w - b.w, h - b.h); }
+    Size& operator-= (const Size& b)        { w -= b.w; h -= b.h; return *this; }
+    Size  operator- () const                { return Size(-w, -h); }
+    Size  operator*  (const Size& b) const  { return Size(w * b.w, h * b.h); }
+    Size& operator*= (const Size& b)        { w *= b.w; h *= b.h; return *this; }
+    Size  operator/  (const Size& b) const  { return Size(w / b.w, h / b.h); }
+    Size& operator/= (const Size& b)        { w /= b.w; h /= b.h; return *this; }
+
+    // Scalar multiplication/division scales both components.
+    Size  operator*  (T s) const            { return Size(w*s, h*s); }
+    Size& operator*= (T s)                  { w *= s; h *= s; return *this; }    
+    Size  operator/  (T s) const            { return Size(w/s, h/s); }
+    Size& operator/= (T s)                  { w /= s; h /= s; return *this; }
+
+    static Size Min(const Size& a, const Size& b)  { return Size((a.w  < b.w)  ? a.w  : b.w,
+                                                                 (a.h < b.h) ? a.h : b.h); }
+    static Size Max(const Size& a, const Size& b)  { return Size((a.w  > b.w)  ? a.w  : b.w,
+                                                                 (a.h > b.h) ? a.h : b.h); }
+    
+    T       Area() const                    { return w * h; }
+
+    inline  Vector2<T> ToVector() const     { return Vector2<T>(w, h); }
+};
+
+
+typedef Size<int>       Sizei;
+typedef Size<unsigned>  Sizeu;
+typedef Size<float>     Sizef;
+typedef Size<double>    Sized;
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** Rect
+
+// Rect describes a rectangular area for rendering, that includes position and size.
+template<class T>
+class Rect
+{
+public:
+    T x, y;
+    T w, h;
+
+    Rect() { }
+    Rect(T x1, T y1, T w1, T h1)                   : x(x1), y(y1), w(w1), h(h1) { }    
+    Rect(const Vector2<T>& pos, const Size<T>& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { }
+    Rect(const Size<T>& sz)                        : x(0), y(0), w(sz.w), h(sz.h) { }
+    
+    // C-interop support.
+    typedef  typename CompatibleTypes<Rect<T> >::Type CompatibleType;
+
+    Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) {  }
+
+    operator const CompatibleType& () const
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(Rect<T>) == sizeof(CompatibleType), "sizeof(Rect<T>) failure");
+        return reinterpret_cast<const CompatibleType&>(*this);
+    }
+
+    Vector2<T> GetPos() const                { return Vector2<T>(x, y); }
+    Size<T>    GetSize() const               { return Size<T>(w, h); }
+    void       SetPos(const Vector2<T>& pos) { x = pos.x; y = pos.y; }
+    void       SetSize(const Size<T>& sz)    { w = sz.w; h = sz.h; }
+
+    bool operator == (const Rect& vp) const
+    { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
+    bool operator != (const Rect& vp) const
+    { return !operator == (vp); }
+};
+
+typedef Rect<int> Recti;
+
+
+//-------------------------------------------------------------------------------------//
+// ***** Quat
+//
+// Quatf represents a quaternion class used for rotations.
+// 
+// Quaternion multiplications are done in right-to-left order, to match the
+// behavior of matrices.
+
+
+template<class T>
+class Quat
+{
+public:
+    typedef T ElementType;
+    static const size_t ElementCount = 4;
+
+    // x,y,z = axis*sin(angle), w = cos(angle)
+    T x, y, z, w;    
+
+    Quat() : x(0), y(0), z(0), w(1) { }
+    Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
+    explicit Quat(const Quat<typename Math<T>::OtherFloatType> &src)
+        : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { }
+
+    typedef  typename CompatibleTypes<Quat<T> >::Type CompatibleType;
+
+    // C-interop support.
+    Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { }
+
+    operator CompatibleType () const
+    {
+        CompatibleType result;
+        result.x = x;
+        result.y = y;
+        result.z = z;
+        result.w = w;
+        return result;
+    }
+
+    // Constructs quaternion for rotation around the axis by an angle.
+    Quat(const Vector3<T>& axis, T angle)
+    {
+        // Make sure we don't divide by zero. 
+        if (axis.LengthSq() == 0)
+        {
+            // Assert if the axis is zero, but the angle isn't
+            OVR_MATH_ASSERT(angle == 0);
+            x = 0; y = 0; z = 0; w = 1;
+            return;
+        }
+
+        Vector3<T> unitAxis = axis.Normalized();
+        T          sinHalfAngle = sin(angle * T(0.5));
+
+        w = cos(angle * T(0.5));
+        x = unitAxis.x * sinHalfAngle;
+        y = unitAxis.y * sinHalfAngle;
+        z = unitAxis.z * sinHalfAngle;
+    }
+
+    // Constructs quaternion for rotation around one of the coordinate axis by an angle.
+    Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R)
+    {
+        T sinHalfAngle = s * d *sin(angle * T(0.5));
+        T v[3];
+        v[0] = v[1] = v[2] = T(0);
+        v[A] = sinHalfAngle;
+
+        w = cos(angle * T(0.5));
+        x = v[0];
+        y = v[1];
+        z = v[2];
+    }
+
+    // Explicit identity for clairity, saves ambiguity at callsite about Quat()
+    // being initialized or not.
+    static Quat<T> Identity() { return Quat<T>(0, 0, 0, 1); }
+
+    // Compute axis and angle from quaternion
+    void GetAxisAngle(Vector3<T>* axis, T* angle) const
+    {
+        if ( x*x + y*y + z*z > Math<T>::Tolerance() * Math<T>::Tolerance() ) {
+            *axis  = Vector3<T>(x, y, z).Normalized();
+            *angle = 2 * Acos(w);
+            if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary
+            {
+                *angle = ((T)MATH_DOUBLE_TWOPI) - *angle;
+                *axis = *axis * (-1);
+            }
+        }
+        else 
+        {
+            *axis = Vector3<T>(1, 0, 0);
+            *angle= 0;
+        }
+    }
+
+    // Convert a quaternion to a rotation vector, also known as
+    // Rodrigues vector, AxisAngle vector, SORA vector, exponential map.
+    // A rotation vector describes a rotation about an axis:
+    // the axis of rotation is the vector normalized,
+    // the angle of rotation is the magnitude of the vector.
+    Vector3<T> ToRotationVector() const
+    {
+        T s = T(0);
+        T sinHalfAngle = sqrt(x*x + y*y + z*z);
+        if (sinHalfAngle > T(0))
+        {
+            T cosHalfAngle = w;
+            T halfAngle = atan2(sinHalfAngle, cosHalfAngle);
+
+            // Ensure minimum rotation magnitude
+            if (cosHalfAngle < 0)
+                halfAngle -= T(MATH_DOUBLE_PI);
+
+            s = T(2) * (halfAngle / sinHalfAngle);
+        }
+        return Vector3<T>(x*s, y*s, z*s);
+    }
+
+    // Faster version of the above, optimized for use with small rotations, where rotation angle ~= sin(angle)
+    inline OVR::Vector3<T> FastToRotationVector() const
+    {
+        T s;
+        T sinHalfSquared = x*x + y*y + z*z;
+        if (sinHalfSquared < T(.0037))			// =~ sin(7/2 degrees)^2
+        {
+            // Max rotation magnitude error is (1 - 2*halfAngle/sin(halfAngle)) = -.0044 radians (.06%) at 7 degrees rotation
+            s = T(2);
+        }
+        else
+        {
+            T sinHalfAngle = sqrt(sinHalfSquared);
+            T cosHalfAngle = w;
+            T halfAngle = atan2(sinHalfAngle, cosHalfAngle);
+
+            // Ensure minimum rotation magnitude
+            if (cosHalfAngle < 0)
+                halfAngle -= T(MATH_DOUBLE_PI);
+
+            s = T(2) * halfAngle / sinHalfAngle;
+        }
+        return Vector3<T>(x*s, y*s, z*s);
+    }
+
+    // Given a rotation vector of form unitRotationAxis * angle,
+    // returns the equivalent quaternion (unitRotationAxis * sin(angle), cos(Angle)).
+    static Quat FromRotationVector(const Vector3<T>& v)
+    {
+        T angleSquared = v.LengthSq();
+        T s = T(0);
+        T c = T(1);
+        if (angleSquared > T(0))
+        {
+            T angle = sqrt(angleSquared);
+            s = sin(angle * T(0.5)) / angle;	// normalize
+            c = cos(angle * T(0.5));
+        }
+        return Quat(s*v.x, s*v.y, s*v.z, c);
+    }
+
+    // Faster version of above, optimized for use with small rotation magnitudes, where rotation angle =~ sin(angle).
+    // If normalize is false, small-angle quaternions are returned un-normalized.
+    inline static Quat FastFromRotationVector(const OVR::Vector3<T>& v, bool normalize = true)
+    {
+        T s, c;
+        T angleSquared = v.LengthSq();
+        if (angleSquared < T(0.0076))	// =~ (5 degrees*pi/180)^2
+        {
+            s = T(0.5);
+            c = T(1.0);
+            // Max rotation magnitude error (after normalization) is about .0031 degrees at 5 degrees, or .06%
+            if (normalize && angleSquared > 0)
+            {
+                T invLen = T(1) / sqrt(s * angleSquared + c);	// normalize
+                s = s * invLen;
+                c = c * invLen;
+            }
+        }
+        else
+        {
+            T angle = sqrt(angleSquared);
+            s = sin(angle * T(0.5)) / angle;
+            c = cos(angle * T(0.5));
+        }
+        return Quat(s*v.x, s*v.y, s*v.z, c);
+    }
+
+    // Constructs the quaternion from a rotation matrix
+    explicit Quat(const Matrix4<T>& m)
+    {
+        T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
+
+        // 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
+            w = T(0.25) * s;
+            x = (m.M[2][1] - m.M[1][2]) / s;
+            y = (m.M[0][2] - m.M[2][0]) / s;
+            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);
+            w = (m.M[2][1] - m.M[1][2]) / s;
+            x = T(0.25) * s;
+            y = (m.M[0][1] + m.M[1][0]) / s;
+            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
+            w = (m.M[0][2] - m.M[2][0]) / s;
+            x = (m.M[0][1] + m.M[1][0]) / s;
+            y = T(0.25) * s;
+            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
+            w = (m.M[1][0] - m.M[0][1]) / s;
+            x = (m.M[0][2] + m.M[2][0]) / s;
+            y = (m.M[1][2] + m.M[2][1]) / s;
+            z = T(0.25) * s;
+        }
+    }
+
+    // Constructs the quaternion from a rotation matrix
+    explicit Quat(const Matrix3<T>& m)
+    {
+        T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
+
+        // 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
+            w = T(0.25) * s;
+            x = (m.M[2][1] - m.M[1][2]) / s;
+            y = (m.M[0][2] - m.M[2][0]) / s;
+            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);
+            w = (m.M[2][1] - m.M[1][2]) / s;
+            x = T(0.25) * s;
+            y = (m.M[0][1] + m.M[1][0]) / s;
+            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
+            w = (m.M[0][2] - m.M[2][0]) / s;
+            x = (m.M[0][1] + m.M[1][0]) / s;
+            y = T(0.25) * s;
+            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
+            w = (m.M[1][0] - m.M[0][1]) / s;
+            x = (m.M[0][2] + m.M[2][0]) / s;
+            y = (m.M[1][2] + m.M[2][1]) / s;
+            z = T(0.25) * s;
+        }
+    }
+
+    bool operator== (const Quat& b) const   { return x == b.x && y == b.y && z == b.z && w == b.w; }
+    bool operator!= (const Quat& b) const   { return x != b.x || y != b.y || z != b.z || w != b.w; }
+
+    Quat  operator+  (const Quat& b) const  { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
+    Quat& operator+= (const Quat& b)        { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
+    Quat  operator-  (const Quat& b) const  { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
+    Quat& operator-= (const Quat& b)        { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
+
+    Quat  operator*  (T s) const            { return Quat(x * s, y * s, z * s, w * s); }
+    Quat& operator*= (T s)                  { w *= s; x *= s; y *= s; z *= s; return *this; }
+    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; }
+
+    // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
+    bool IsEqual(const Quat&b, T tolerance = Math<T>::Tolerance())
+    {
+        return Abs(Dot(b)) >= 1 - tolerance;
+    }
+
+    static T Abs(const T v)                 { return (v >= 0) ? v : -v; }
+
+    // Get Imaginary part vector
+    Vector3<T> Imag() const                 { return Vector3<T>(x,y,z); }
+
+    // Get quaternion length.
+    T       Length() const                  { return sqrt(LengthSq()); }
+
+    // Get quaternion length squared.
+    T       LengthSq() const                { return (x * x + y * y + z * z + w * w); }
+
+    // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
+    T       Distance(const Quat& q) const    
+    { 
+        T d1 = (*this - q).Length();
+        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(); // Antipodal point check
+        return (d1 < d2) ? d1 : d2;
+    }
+
+    T       Dot(const Quat& q) const
+    {
+        return x * q.x + y * q.y + z * q.z + w * q.w;
+    }
+
+    // Angle between two quaternions in radians
+    T       Angle(const Quat& q) const
+    {
+        return 2 * Acos(Abs(Dot(q)));
+    }
+
+    // Normalize
+    bool    IsNormalized() const            { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
+
+    void    Normalize()                     
+    {
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        *this *= s;
+    }
+
+    Quat    Normalized() const              
+    { 
+        T s = Length();
+        if (s != 0)
+            s = T(1) / s;
+        return *this * s;
+    }
+
+    inline void EnsureSameHemisphere(const Quat& o)
+    {
+        if (Dot(o) < T(0))
+        {
+            x = -x;
+            y = -y;
+            z = -z;
+            w = -w;
+        }
+    }
+
+    // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
+    Quat    Conj() const                    { return Quat(-x, -y, -z, w); }
+
+    // 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,
+                                                          w * b.y - x * b.z + y * b.w + z * b.x,
+                                                          w * b.z + x * b.y - y * b.x + z * b.w,
+                                                          w * b.w - x * b.x - y * b.y - z * b.z); }
+    const Quat& operator*= (const Quat& b)		{ *this = *this * b;  return *this; }
+
+    // 
+    // this^p normalized; same as rotating by this p times.
+    Quat PowNormalized(T p) const
+    {
+        Vector3<T> v;
+        T          a;
+        GetAxisAngle(&v, &a);
+        return Quat(v, a * p);
+    }
+
+    // Compute quaternion that rotates v into alignTo: alignTo = Quat::Align(alignTo, v).Rotate(v).
+    // NOTE: alignTo and v must be normalized.
+    static Quat Align(const Vector3<T>& alignTo, const Vector3<T>& v)
+    {
+        Vector3<T> bisector = (v + alignTo);
+        bisector.Normalize();
+        T cosHalfAngle = v.Dot(bisector);	 // 0..1
+        if (cosHalfAngle > T(0))
+        {
+            Vector3<T> imag = v.Cross(bisector);
+            return Quat(imag.x, imag.y, imag.z, cosHalfAngle);
+        }
+        else
+        {
+            // cosHalfAngle == 0: a 180 degree rotation.
+            // sinHalfAngle == 1, rotation axis is any axis perpendicular
+            // to alignTo.  Choose axis to include largest magnitude components
+            if (fabs(v.x) > fabs(v.y))
+            {
+                // x or z is max magnitude component
+                // = Cross(v, (0,1,0)).Normalized();
+                T invLen = sqrt(v.x*v.x + v.z*v.z);
+                if (invLen > T(0))
+                    invLen = T(1) / invLen;
+                return Quat(-v.z*invLen, 0, v.x*invLen, 0);
+            }
+            else
+            {
+                // y or z is max magnitude component
+                // = Cross(v, (1,0,0)).Normalized();
+                T invLen = sqrt(v.y*v.y + v.z*v.z);
+                if (invLen > T(0))
+                    invLen = T(1) / invLen;
+                return Quat(0, v.z*invLen, -v.y*invLen, 0);
+            }
+        }
+    }
+
+    // Normalized linear interpolation of quaternions
+    Quat Lerp(const Quat& b, T s) const
+    {
+        return (*this * (T(1) - s) + b * (Dot(b) < 0 ? -s : s)).Normalized();
+    }
+
+    // Normalized linear interpolation of quaternions
+    // WARNING, POSSIBLE BUG: This function doesn't work like Lerp() for other classes!
+    // If f is 1, then full value is given to *this, not "other" like other Lerp() functions
+    Quat Nlerp(const Quat& other, T a)
+    {
+        T sign = (Dot(other) >= 0) ? 1 : -1;
+        return (*this * sign * a + other * (1-a)).Normalized();
+    }
+    
+    // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
+    // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. 
+    Vector3<T> Rotate(const Vector3<T>& v) const
+    {
+        // rv = q * (v,0) * q'
+        // Same as rv = v + real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2);
+
+        // uv = 2 * Imag().Cross(v);
+        T uvx = T(2) * (y*v.z - z*v.y);
+        T uvy = T(2) * (z*v.x - x*v.z);
+        T uvz = T(2) * (x*v.y - y*v.x);
+
+        // return v + Real()*uv + Imag().Cross(uv);
+        return Vector3<T>(v.x + w*uvx + y*uvz - z*uvy,
+                          v.y + w*uvy + z*uvx - x*uvz,
+                          v.z + w*uvz + x*uvy - y*uvx);
+    }
+
+    // Rotation by inverse of *this
+    Vector3<T> InverseRotate(const Vector3<T>& v) const
+    {
+        // rv = q' * (v,0) * q
+        // Same as rv = v + real * cross(-imag,v)*2 + cross(-imag, cross(-imag,v)*2);
+        //      or rv = v - real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2);
+
+        // uv = 2 * Imag().Cross(v);
+        T uvx = T(2) * (y*v.z - z*v.y);
+        T uvy = T(2) * (z*v.x - x*v.z);
+        T uvz = T(2) * (x*v.y - y*v.x);
+
+        // return v - Real()*uv + Imag().Cross(uv);
+        return Vector3<T>(v.x - w*uvx + y*uvz - z*uvy,
+                          v.y - w*uvy + z*uvx - x*uvz,
+                          v.z - w*uvz + x*uvy - y*uvx);
+    }
+    
+    // Inversed quaternion rotates in the opposite direction.
+    Quat        Inverted() const
+    {
+        return Quat(-x, -y, -z, w);
+    }
+
+    Quat        Inverse() const
+    {
+        return Quat(-x, -y, -z, w);
+    }
+
+    // Sets this quaternion to the one rotates in the opposite direction.
+    void        Invert()
+    {
+        *this = Quat(-x, -y, -z, w);
+    }
+    
+    // Time integration of constant angular velocity over dt
+    Quat TimeIntegrate(Vector3<T> angularVelocity, T dt) const
+    {
+        // solution is: this * exp( omega*dt/2 ); FromRotationVector(v) gives exp(v*.5).
+        return (*this * FastFromRotationVector(angularVelocity * dt, false)).Normalized();
+    }
+
+    // Time integration of constant angular acceleration and velocity over dt
+    // These are the first two terms of the "Magnus expansion" of the solution
+    //
+    //   o = o * exp( W=(W1 + W2 + W3+...) * 0.5 );
+    //
+    //  omega1 = (omega + omegaDot*dt)
+    //  W1 = (omega + omega1)*dt/2              
+    //	W2 = cross(omega, omega1)/12*dt^2 % (= -cross(omega_dot, omega)/12*dt^3)
+    // Terms 3 and beyond are vanishingly small:
+    //  W3 = cross(omega_dot, cross(omega_dot, omega))/240*dt^5 
+    Quat TimeIntegrate(Vector3<T> angularVelocity, Vector3<T> angularAcceleration, T dt, T dtAcceleration) const
+    {
+        (void)dtAcceleration;
+        
+        const Vector3<T>& omega = angularVelocity;
+        const Vector3<T>& omegaDot = angularAcceleration;
+
+        Vector3<T> omega1 = (omega + omegaDot * dtAcceleration);
+        Vector3<T> W = T(0.5)*dt*((omega + omega1) / T(2) + omega.Cross(omega1)*(dt * T(1)/T(12)));
+
+        // FromRotationVector(v) is exp(v*.5)
+        return (*this * FastFromRotationVector(W, false)).Normalized();
+    }
+
+    // Decompose rotation into three rotations:
+    // roll radians about Z axis, then pitch radians about X axis, then yaw radians about Y axis.
+    // Call with nullptr if a return value is not needed.
+    void GetYawPitchRoll(T* yaw, T* pitch, T* roll) const
+    {
+        return GetEulerAngles(yaw, pitch, roll, Rotate_CCW, Handed_R);
+    }
+
+    // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
+    // axis rotations and the specified coordinate system. Right-handed coordinate system
+    // is the default, with CCW rotations while looking in the negative axis direction.
+    // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
+    // Rotation order is c, b, a:
+    // rotation c around axis A3
+    // is followed by rotation b around axis A2
+    // is followed by rotation a around axis A1
+    // rotations are CCW or CW (D) in LH or RH coordinate system (S)
+    // 
+    template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
+    void GetEulerAngles(T *a, T *b, T *c) const 
+    {
+        OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)");
+
+        T Q[3] = { x, y, z };  //Quaternion components x,y,z
+
+        T ww  = w*w;
+        T Q11 = Q[A1]*Q[A1];
+        T Q22 = Q[A2]*Q[A2];
+        T Q33 = Q[A3]*Q[A3];
+
+        T psign = T(-1);
+        // Determine whether even permutation
+        if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
+            psign = T(1);
+        
+        T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
+
+        T singularityRadius = Math<T>::SingularityRadius();
+        if (s2 < T(-1) + singularityRadius)
+        { // South pole singularity
+            if (a) *a = T(0);
+            if (b) *b = -S*D*((T)MATH_DOUBLE_PIOVER2);
+            if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33 );
+        }
+        else if (s2 > T(1) - singularityRadius)
+        {  // North pole singularity
+            if (a) *a = T(0);
+            if (b) *b = S*D*((T)MATH_DOUBLE_PIOVER2);
+            if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33);
+        }
+        else
+        {
+            if (a) *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2] * Q[A3]), ww + Q33 - Q11 - Q22);
+            if (b) *b = S*D*asin(s2);
+            if (c) *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1] * Q[A2]), ww + Q11 - Q22 - Q33);
+        }      
+    }
+
+    template <Axis A1, Axis A2, Axis A3, RotateDirection D>
+    void GetEulerAngles(T *a, T *b, T *c) const
+    { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
+
+    template <Axis A1, Axis A2, Axis A3>
+    void GetEulerAngles(T *a, T *b, T *c) const
+    { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
+
+    // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
+    // axis rotations and the specified coordinate system. Right-handed coordinate system
+    // is the default, with CCW rotations while looking in the negative axis direction.
+    // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
+    // rotation a around axis A1
+    // is followed by rotation b around axis A2
+    // is followed by rotation c around axis A1
+    // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
+    template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
+    void GetEulerAnglesABA(T *a, T *b, T *c) const
+    {
+        OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2");
+
+        T Q[3] = {x, y, z}; // Quaternion components
+
+        // Determine the missing axis that was not supplied
+        int m = 3 - A1 - A2;
+
+        T ww = w*w;
+        T Q11 = Q[A1]*Q[A1];
+        T Q22 = Q[A2]*Q[A2];
+        T Qmm = Q[m]*Q[m];
+
+        T psign = T(-1);
+        if ((A1 + 1) % 3 == A2) // Determine whether even permutation
+        {
+            psign = T(1);
+        }
+
+        T c2 = ww + Q11 - Q22 - Qmm;
+        if (c2 < T(-1) + Math<T>::SingularityRadius)
+        { // South pole singularity
+            if (a) *a = T(0);
+            if (b) *b = S*D*((T)MATH_DOUBLE_PI);
+            if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]),
+                            ww + Q22 - Q11 - Qmm);
+        }
+        else if (c2 > T(1) - Math<T>::SingularityRadius)
+        {  // North pole singularity
+            if (a) *a = T(0);
+            if (b) *b = T(0);
+            if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]),
+                           ww + Q22 - Q11 - Qmm);
+        }
+        else
+        {
+            if (a) *a = S*D*atan2(psign*w*Q[m] + Q[A1] * Q[A2],
+                           w*Q[A2] -psign*Q[A1]*Q[m]);
+            if (b) *b = S*D*acos(c2);
+            if (c) *c = S*D*atan2(-psign*w*Q[m] + Q[A1] * Q[A2],
+                           w*Q[A2] + psign*Q[A1]*Q[m]);
+        }
+    }
+};
+
+typedef Quat<float>  Quatf;
+typedef Quat<double> Quatd;
+
+OVR_MATH_STATIC_ASSERT((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure");
+OVR_MATH_STATIC_ASSERT((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure");
+
+//-------------------------------------------------------------------------------------
+// ***** Pose
+
+// Position and orientation combined.
+
+template<class T>
+class Pose
+{
+public:
+    typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType;
+
+    Pose() { }
+    Pose(const Quat<T>& orientation, const Vector3<T>& pos)
+        : Rotation(orientation), Translation(pos) {  }
+    Pose(const Pose& s)
+        : Rotation(s.Rotation), Translation(s.Translation) {  }
+    Pose(const Matrix3<T>& R, const Vector3<T>& t)
+        : Rotation((Quat<T>)R), Translation(t) {  }
+    Pose(const CompatibleType& s)
+        : Rotation(s.Orientation), Translation(s.Position) {  }
+    explicit Pose(const Pose<typename Math<T>::OtherFloatType> &s)
+        : Rotation(s.Rotation), Translation(s.Translation) {  }
+
+    static Pose Identity() { return Pose(Quat<T>(0, 0, 0, 1), Vector3<T>(0, 0, 0)); }
+
+    void SetIdentity() { Rotation = Quat<T>(0, 0, 0, 1); Translation = Vector3<T>(0, 0, 0); }
+
+    bool IsEqual(const Pose&b, T tolerance = Math<T>::Tolerance())
+    {
+        return Translation.IsEqual(b.Translation, tolerance) && Rotation.IsEqual(b.Rotation, tolerance);
+    }
+
+    operator typename CompatibleTypes<Pose<T> >::Type () const
+    {
+        typename CompatibleTypes<Pose<T> >::Type result;
+        result.Orientation = Rotation;
+        result.Position = Translation;
+        return result;
+    }
+
+    Quat<T>    Rotation;
+    Vector3<T> Translation;
+    
+    OVR_MATH_STATIC_ASSERT((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))");
+
+    void ToArray(T* arr) const
+    {
+        T temp[7] =  { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z };
+        for (int i = 0; i < 7; i++) arr[i] = temp[i];
+    }
+
+    static Pose<T> FromArray(const T* v)
+    {
+        Quat<T> rotation(v[0], v[1], v[2], v[3]);
+        Vector3<T> translation(v[4], v[5], v[6]);
+        return Pose<T>(rotation, translation);
+    }
+
+    Vector3<T> Rotate(const Vector3<T>& v) const
+    {
+        return Rotation.Rotate(v);
+    }
+
+    Vector3<T> InverseRotate(const Vector3<T>& v) const
+    {
+        return Rotation.InverseRotate(v);
+    }
+
+    Vector3<T> Translate(const Vector3<T>& v) const
+    {
+        return v + Translation;
+    }
+
+    Vector3<T> Transform(const Vector3<T>& v) const
+    {
+        return Rotate(v) + Translation;
+    }
+
+    Vector3<T> InverseTransform(const Vector3<T>& v) const
+    {
+        return InverseRotate(v - Translation);
+    }
+
+
+    Vector3<T> Apply(const Vector3<T>& v) const
+    {
+        return Transform(v);
+    }
+
+    Pose operator*(const Pose& other) const   
+    {
+        return Pose(Rotation * other.Rotation, Apply(other.Translation));
+    }
+
+    Pose Inverted() const   
+    {
+        Quat<T> inv = Rotation.Inverted();
+        return Pose(inv, inv.Rotate(-Translation));
+    }
+
+    Pose TimeIntegrate(const Vector3<T>& linearVelocity, const Vector3<T>& angularVelocity, T dt) const
+    {
+        return Pose(
+                (Rotation * Quat<T>::FastFromRotationVector(angularVelocity * dt, false)).Normalized(),
+                Translation + linearVelocity * dt);
+    }
+
+    Pose TimeIntegrate(const Vector3<T>& linearVelocity, const Vector3<T>& linearAcceleration,
+                       const Vector3<T>& angularVelocity, const Vector3<T>& angularAcceleration,
+                       T dt, T dtAcceleration) const
+    {
+        return Pose(Rotation.TimeIntegrate(angularVelocity, angularAcceleration, dt, dtAcceleration),
+                    Translation + linearVelocity*dt + linearAcceleration*dt*dt / T(2));
+    }
+};
+
+typedef Pose<float>  Posef;
+typedef Pose<double> Posed;
+
+OVR_MATH_STATIC_ASSERT((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure");
+OVR_MATH_STATIC_ASSERT((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure");
+    
+
+//-------------------------------------------------------------------------------------
+// ***** Matrix4
+//
+// Matrix4 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
+// of the first row are stored before the next one.
+//
+// The arrangement of the matrix is chosen to be in Right-Handed 
+// coordinate system and counterclockwise rotations when looking down
+// the axis
+//
+// Transformation Order:
+//   - Transformations are applied from right to left, so the expression
+//     M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
+//     followed by M2 and M1. 
+//
+// Coordinate system: Right Handed
+//
+// Rotations: Counterclockwise when looking down the axis. All angles are in radians.
+//    
+//  | sx   01   02   tx |    // First column  (sx, 10, 20): Axis X basis vector.
+//  | 10   sy   12   ty |    // Second column (01, sy, 21): Axis Y basis vector.
+//  | 20   21   sz   tz |    // Third columnt (02, 12, sz): Axis Z basis vector.
+//  | 30   31   32   33 |
+//
+//  The basis vectors are first three columns.
+
+template<class T>
+class Matrix4
+{
+public:
+    typedef T ElementType;
+    static const size_t Dimension = 4;
+
+    T M[4][4];
+
+    enum NoInitType { NoInit };
+
+    // Construct with no memory initialization.
+    Matrix4(NoInitType) { }
+
+    // By default, we construct identity matrix.
+    Matrix4()
+    {
+        M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1;
+        M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0;
+        M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0;
+        M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
+    }
+
+    Matrix4(T m11, T m12, T m13, T m14,
+            T m21, T m22, T m23, T m24,
+            T m31, T m32, T m33, T m34,
+            T m41, T m42, T m43, T m44)
+    {
+        M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
+        M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
+        M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34;
+        M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
+    }
+
+    Matrix4(T m11, T m12, T m13,
+            T m21, T m22, T m23,
+            T m31, T m32, T m33)
+    {
+        M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0;
+        M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0;
+        M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0;
+        M[3][0] = 0;   M[3][1] = 0;   M[3][2] = 0;   M[3][3] = 1;
+    }
+
+    explicit Matrix4(const Matrix3<T>& m)
+    {
+        M[0][0] = m.M[0][0]; M[0][1] = m.M[0][1]; M[0][2] = m.M[0][2]; M[0][3] = 0;
+        M[1][0] = m.M[1][0]; M[1][1] = m.M[1][1]; M[1][2] = m.M[1][2]; M[1][3] = 0;
+        M[2][0] = m.M[2][0]; M[2][1] = m.M[2][1]; M[2][2] = m.M[2][2]; M[2][3] = 0;
+        M[3][0] = 0;         M[3][1] = 0;         M[3][2] = 0;         M[3][3] = 1;
+    }
+
+    explicit Matrix4(const Quat<T>& q)
+    {
+        T ww = q.w*q.w;
+        T xx = q.x*q.x;
+        T yy = q.y*q.y;
+        T zz = q.z*q.z;
+
+        M[0][0] = ww + xx - yy - zz;       M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = 0;
+        M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz;       M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = 0;
+        M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz;       M[2][3] = 0;
+        M[3][0] = 0;                       M[3][1] = 0;                       M[3][2] = 0;                       M[3][3] = 1;
+    }
+
+    explicit Matrix4(const Pose<T>& p)
+    {
+        Matrix4 result(p.Rotation);
+        result.SetTranslation(p.Translation);
+        *this = result;
+    }
+
+
+    // C-interop support
+    explicit Matrix4(const Matrix4<typename Math<T>::OtherFloatType> &src)
+    {
+        for (int i = 0; i < 4; i++)
+            for (int j = 0; j < 4; j++)
+                M[i][j] = (T)src.M[i][j];
+    }
+
+    // C-interop support.
+    Matrix4(const typename CompatibleTypes<Matrix4<T> >::Type& s) 
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)");
+        memcpy(M, s.M, sizeof(M));
+    }
+
+    operator typename CompatibleTypes<Matrix4<T> >::Type () const
+    {
+        typename CompatibleTypes<Matrix4<T> >::Type result;
+        OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)");
+        memcpy(result.M, M, sizeof(M));
+        return result;
+    }
+
+    void ToString(char* dest, size_t destsize) const
+    {
+        size_t pos = 0;
+        for (int r=0; r<4; r++)
+        {
+            for (int c=0; c<4; c++)
+            {
+                pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
+            }
+        }
+    }
+
+    static Matrix4 FromString(const char* src)
+    {
+        Matrix4 result;
+        if (src)
+        {
+            for (int r = 0; r < 4; r++)
+            {
+                for (int c = 0; c < 4; c++)
+                {
+                    result.M[r][c] = (T)atof(src);
+                    while (*src && *src != ' ')
+                    {
+                        src++;
+                    }
+                    while (*src && *src == ' ')
+                    {
+                        src++;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    static Matrix4 Identity()  { return Matrix4(); }
+
+    void SetIdentity()
+    {
+        M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1;
+        M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0;
+        M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0;
+        M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
+    }
+
+    void SetXBasis(const Vector3f & v)
+    {
+        M[0][0] = v.x;
+        M[1][0] = v.y;
+        M[2][0] = v.z;
+    }
+    Vector3f GetXBasis() const
+    {
+        return Vector3f(M[0][0], M[1][0], M[2][0]);
+    }
+
+    void SetYBasis(const Vector3f & v)
+    {
+        M[0][1] = v.x;
+        M[1][1] = v.y;
+        M[2][1] = v.z;
+    }
+    Vector3f GetYBasis() const
+    {
+        return Vector3f(M[0][1], M[1][1], M[2][1]);
+    }
+
+    void SetZBasis(const Vector3f & v)
+    {
+        M[0][2] = v.x;
+        M[1][2] = v.y;
+        M[2][2] = v.z;
+    }
+    Vector3f GetZBasis() const
+    {
+        return Vector3f(M[0][2], M[1][2], M[2][2]);
+    }
+
+    bool operator== (const Matrix4& b) const
+    {
+        bool isEqual = true;
+        for (int i = 0; i < 4; i++)
+            for (int j = 0; j < 4; j++)
+                isEqual &= (M[i][j] == b.M[i][j]);
+
+        return isEqual;
+    }
+
+    Matrix4 operator+ (const Matrix4& b) const
+    {
+        Matrix4 result(*this);
+        result += b;
+        return result;
+    }
+
+    Matrix4& operator+= (const Matrix4& b)
+    {
+        for (int i = 0; i < 4; i++)
+            for (int j = 0; j < 4; j++)
+                M[i][j] += b.M[i][j];
+        return *this;
+    }
+
+    Matrix4 operator- (const Matrix4& b) const
+    {
+        Matrix4 result(*this);
+        result -= b;
+        return result;
+    }
+
+    Matrix4& operator-= (const Matrix4& 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 Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b)
+    {
+        OVR_MATH_ASSERT((d != &a) && (d != &b));
+        int i = 0;
+        do {
+            d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + a.M[i][3] * b.M[3][0];
+            d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + a.M[i][3] * b.M[3][1];
+            d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + a.M[i][3] * b.M[3][2];
+            d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + a.M[i][3] * b.M[3][3];
+        } while((++i) < 4);
+
+        return *d;
+    }
+
+    Matrix4 operator* (const Matrix4& b) const
+    {
+        Matrix4 result(Matrix4::NoInit);
+        Multiply(&result, *this, b);
+        return result;
+    }
+
+    Matrix4& operator*= (const Matrix4& b)
+    {
+        return Multiply(this, Matrix4(*this), b);
+    }
+
+    Matrix4 operator* (T s) const
+    {
+        Matrix4 result(*this);
+        result *= s;
+        return result;
+    }
+
+    Matrix4& operator*= (T s)
+    {
+        for (int i = 0; i < 4; i++)
+            for (int j = 0; j < 4; j++)
+                M[i][j] *= s;
+        return *this;
+    }
+
+
+    Matrix4 operator/ (T s) const
+    {
+        Matrix4 result(*this);
+        result /= s;
+        return result;
+    }
+
+    Matrix4& operator/= (T s)
+    {
+        for (int i = 0; i < 4; i++)
+            for (int j = 0; j < 4; j++)
+                M[i][j] /= s;
+        return *this;
+    }
+
+    Vector3<T> Transform(const Vector3<T>& v) const
+    {
+        const T rcpW = 1.0f / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]);
+        return Vector3<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW,
+                          (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW,
+                          (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW);
+    }
+
+    Vector4<T> Transform(const Vector4<T>& v) const
+    {
+        return Vector4<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w,
+                          M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w,
+                          M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w,
+                          M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w);
+    }
+
+    Matrix4 Transposed() const
+    {
+        return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0],
+                        M[0][1], M[1][1], M[2][1], M[3][1],
+                        M[0][2], M[1][2], M[2][2], M[3][2],
+                        M[0][3], M[1][3], M[2][3], M[3][3]);
+    }
+
+    void     Transpose()
+    {
+        *this = Transposed();
+    }
+
+
+    T SubDet (const size_t* rows, const size_t* 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]]);
+    }
+
+    T Cofactor(size_t I, size_t J) const
+    {
+        const size_t 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]);
+    }
+
+    T    Determinant() const
+    {
+        return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3);
+    }
+
+    Matrix4 Adjugated() const
+    {
+        return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), 
+                        Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), 
+                        Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
+                        Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
+    }
+
+    Matrix4 Inverted() const
+    {
+        T det = Determinant();
+        OVR_MATH_ASSERT(det != 0);
+        return Adjugated() * (1.0f/det);
+    }
+
+    void Invert()
+    {
+        *this = Inverted();
+    }
+
+    // This is more efficient than general inverse, but ONLY works
+    // correctly if it is a homogeneous transform matrix (rot + trans)
+    Matrix4 InvertedHomogeneousTransform() const
+    {
+        // Make the inverse rotation matrix
+        Matrix4 rinv = this->Transposed();
+        rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = 0.0f;
+        // Make the inverse translation matrix
+        Vector3<T> tvinv(-M[0][3],-M[1][3],-M[2][3]);
+        Matrix4 tinv = Matrix4::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
+    // is followed by rotation c around axis A3
+    // rotations are CCW or CW (D) in LH or RH coordinate system (S)
+    template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
+    void ToEulerAngles(T *a, T *b, T *c) const
+    {
+        OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)");
+
+        T psign = -1;
+        if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
+        psign = 1;
+        
+        T pm = psign*M[A1][A3];
+        if (pm < -1.0f + Math<T>::SingularityRadius)
+        { // South pole singularity
+            *a = 0;
+            *b = -S*D*((T)MATH_DOUBLE_PIOVER2);
+            *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
+        }
+        else if (pm > 1.0f - Math<T>::SingularityRadius)
+        { // North pole singularity
+            *a = 0;
+            *b = S*D*((T)MATH_DOUBLE_PIOVER2);
+            *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
+        }
+        else
+        { // Normal case (nonsingular)
+            *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] );
+            *b = S*D*asin(pm);
+            *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] );
+        }
+
+        return;
+    }
+
+    // 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
+    // is followed by rotation c around axis A1
+    // rotations are CCW or CW (D) in LH or RH coordinate system (S)
+    template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
+    void ToEulerAnglesABA(T *a, T *b, T *c) const
+    {        
+         OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2");
+  
+        // Determine the axis that was not supplied
+        int m = 3 - A1 - A2;
+
+        T psign = -1;
+        if ((A1 + 1) % 3 == A2) // Determine whether even permutation
+            psign = 1.0f;
+
+        T c2 = M[A1][A1];
+        if (c2 < -1 + Math<T>::SingularityRadius)
+        { // South pole singularity
+            *a = 0;
+            *b = S*D*((T)MATH_DOUBLE_PI);
+            *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
+        }
+        else if (c2 > 1.0f - Math<T>::SingularityRadius)
+        { // North pole singularity
+            *a = 0;
+            *b = 0;
+            *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
+        }
+        else
+        { // Normal case (nonsingular)
+            *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]);
+            *b = S*D*acos(c2);
+            *c = S*D*atan2( M[A1][A2],psign*M[A1][m]);
+        }
+        return;
+    }
+  
+    // Creates a matrix that converts the vertices from one coordinate system
+    // to another.
+    static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from)
+    {        
+        // Holds axis values from the 'to' structure
+        int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
+
+        // The inverse of the toArray
+        int inv[4]; 
+        inv[0] = inv[abs(to.XAxis)] = 0;
+        inv[abs(to.YAxis)] = 1;
+        inv[abs(to.ZAxis)] = 2;
+
+        Matrix4 m(0,  0,  0, 
+                  0,  0,  0,
+                  0,  0,  0);
+
+        // Only three values in the matrix need to be changed to 1 or -1.
+        m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]);
+        m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]);
+        m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
+        return m;
+    } 
+
+
+    // Creates a matrix for translation by vector
+    static Matrix4 Translation(const Vector3<T>& v)
+    {
+        Matrix4 t;
+        t.M[0][3] = v.x;
+        t.M[1][3] = v.y;
+        t.M[2][3] = v.z;
+        return t;
+    }
+
+    // Creates a matrix for translation by vector
+    static Matrix4 Translation(T x, T y, T z = 0.0f)
+    {
+        Matrix4 t;
+        t.M[0][3] = x;
+        t.M[1][3] = y;
+        t.M[2][3] = z;
+        return t;
+    }
+
+    // Sets the translation part
+    void SetTranslation(const Vector3<T>& v)
+    {
+        M[0][3] = v.x;
+        M[1][3] = v.y;
+        M[2][3] = v.z;
+    }
+
+    Vector3<T> GetTranslation() const
+    {
+        return Vector3<T>( M[0][3], M[1][3], M[2][3] );
+    }
+
+    // Creates a matrix for scaling by vector
+    static Matrix4 Scaling(const Vector3<T>& v)
+    {
+        Matrix4 t;
+        t.M[0][0] = v.x;
+        t.M[1][1] = v.y;
+        t.M[2][2] = v.z;
+        return t;
+    }
+
+    // Creates a matrix for scaling by vector
+    static Matrix4 Scaling(T x, T y, T z)
+    {
+        Matrix4 t;
+        t.M[0][0] = x;
+        t.M[1][1] = y;
+        t.M[2][2] = z;
+        return t;
+    }
+
+    // Creates a matrix for scaling by constant
+    static Matrix4 Scaling(T s)
+    {
+        Matrix4 t;
+        t.M[0][0] = s;
+        t.M[1][1] = s;
+        t.M[2][2] = s;
+        return t;
+    }
+
+    // Simple L1 distance in R^12
+    T Distance(const Matrix4& m2) const           
+    { 
+        T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]);
+        d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]);
+        d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]);
+        d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]);
+        d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]);
+        d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]);
+        d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]);
+        d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]);
+        return d; 
+    }
+
+    // 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 Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s)
+    {
+        T sina = s * d *sin(angle);
+        T cosa = cos(angle);
+        
+        switch(A)
+        {
+        case Axis_X:
+            return Matrix4(1,  0,     0, 
+                           0,  cosa,  -sina,
+                           0,  sina,  cosa);
+        case Axis_Y:
+            return Matrix4(cosa,  0,   sina, 
+                           0,     1,   0,
+                           -sina, 0,   cosa);
+        case Axis_Z:
+            return Matrix4(cosa,  -sina,  0, 
+                           sina,  cosa,   0,
+                           0,     0,      1);
+        }
+    }
+
+
+    // 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),
+    //                        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
+    //       negative axis direction.
+    static Matrix4 RotationX(T angle)
+    {
+        T sina = sin(angle);
+        T cosa = cos(angle);
+        return Matrix4(1,  0,     0, 
+                       0,  cosa,  -sina,
+                       0,  sina,  cosa);
+    }
+
+    // Creates a rotation matrix rotating around the Y axis by 'angle' radians.
+    // Rotation direction is depends on the coordinate system:
+    //  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
+    //       negative axis direction.
+    static Matrix4 RotationY(T angle)
+    {
+        T sina = sin(angle);
+        T cosa = cos(angle);
+        return Matrix4(cosa,  0,   sina, 
+                       0,     1,   0,
+                       -sina, 0,   cosa);
+    }
+
+    // Creates a rotation matrix rotating around the Z axis by 'angle' radians.
+    // Rotation direction is depends on the coordinate system:
+    //  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
+    //       negative axis direction.
+    static Matrix4 RotationZ(T angle)
+    {
+        T sina = sin(angle);
+        T cosa = cos(angle);
+        return Matrix4(cosa,  -sina,  0, 
+                       sina,  cosa,   0,
+                       0,     0,      1);
+    }
+
+    // LookAtRH creates a View transformation matrix for right-handed coordinate system.
+    // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
+    // specifying the up vector. The resulting matrix should be used with PerspectiveRH
+    // projection.
+    static Matrix4 LookAtRH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
+    {
+        Vector3<T> z = (eye - at).Normalized();  // Forward
+        Vector3<T> x = up.Cross(z).Normalized(); // Right
+        Vector3<T> y = z.Cross(x);
+
+        Matrix4 m(x.x,  x.y,  x.z,  -(x.Dot(eye)),
+                  y.x,  y.y,  y.z,  -(y.Dot(eye)),
+                  z.x,  z.y,  z.z,  -(z.Dot(eye)),
+                  0,    0,    0,    1 );
+        return m;
+    }
+    
+    // LookAtLH creates a View transformation matrix for left-handed coordinate system.
+    // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
+    // specifying the up vector. 
+    static Matrix4 LookAtLH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
+    {
+        Vector3<T> z = (at - eye).Normalized();  // Forward
+        Vector3<T> x = up.Cross(z).Normalized(); // Right
+        Vector3<T> y = z.Cross(x);
+
+        Matrix4 m(x.x,  x.y,  x.z,  -(x.Dot(eye)),
+                  y.x,  y.y,  y.z,  -(y.Dot(eye)),
+                  z.x,  z.y,  z.z,  -(z.Dot(eye)),
+                  0,    0,    0,    1 ); 
+        return m;
+    }
+    
+    // PerspectiveRH creates a right-handed perspective projection matrix that can be
+    // used with the Oculus sample renderer. 
+    //  yfov   - Specifies vertical field of view in radians.
+    //  aspect - Screen aspect ration, which is usually width/height for square pixels.
+    //           Note that xfov = yfov * aspect.
+    //  znear  - Absolute value of near Z clipping clipping range.
+    //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
+    // Even though RHS usually looks in the direction of negative Z, positive values
+    // are expected for znear and zfar.
+    static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar)
+    {
+        Matrix4 m;
+        T tanHalfFov = tan(yfov * 0.5f);
+
+        m.M[0][0] = 1. / (aspect * tanHalfFov);
+        m.M[1][1] = 1. / tanHalfFov;
+        m.M[2][2] = zfar / (znear - zfar);
+        m.M[3][2] = -1.;
+        m.M[2][3] = (zfar * znear) / (znear - zfar);
+        m.M[3][3] = 0.;
+
+        // Note: Post-projection matrix result assumes Left-Handed coordinate system,
+        //       with Y up, X right and Z forward. This supports positive z-buffer values.
+        // This is the case even for RHS coordinate input.
+        return m;
+    }
+    
+    // PerspectiveLH creates a left-handed perspective projection matrix that can be
+    // used with the Oculus sample renderer. 
+    //  yfov   - Specifies vertical field of view in radians.
+    //  aspect - Screen aspect ration, which is usually width/height for square pixels.
+    //           Note that xfov = yfov * aspect.
+    //  znear  - Absolute value of near Z clipping clipping range.
+    //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
+    static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar)
+    {
+        Matrix4 m;
+        T tanHalfFov = tan(yfov * 0.5f);
+
+        m.M[0][0] = 1. / (aspect * tanHalfFov);
+        m.M[1][1] = 1. / tanHalfFov;
+        //m.M[2][2] = zfar / (znear - zfar);
+         m.M[2][2] = zfar / (zfar - znear);
+        m.M[3][2] = -1.;
+        m.M[2][3] = (zfar * znear) / (znear - zfar);
+        m.M[3][3] = 0.;
+
+        // Note: Post-projection matrix result assumes Left-Handed coordinate system,    
+        //       with Y up, X right and Z forward. This supports positive z-buffer values.
+        // This is the case even for RHS coordinate input. 
+        return m;
+    }
+
+    static Matrix4 Ortho2D(T w, T h)
+    {
+        Matrix4 m;
+        m.M[0][0] = 2.0/w;
+        m.M[1][1] = -2.0/h;
+        m.M[0][3] = -1.0;
+        m.M[1][3] = 1.0;
+        m.M[2][2] = 0;
+        return m;
+    }
+};
+
+typedef Matrix4<float>  Matrix4f;
+typedef Matrix4<double> Matrix4d;
+
+//-------------------------------------------------------------------------------------
+// ***** Matrix3
+//
+// Matrix3 is a 3x3 matrix used for representing a rotation matrix.
+// The matrix is stored in row-major order in memory, meaning that values
+// of the first row are stored before the next one.
+//
+// The arrangement of the matrix is chosen to be in Right-Handed 
+// coordinate system and counterclockwise rotations when looking down
+// the axis
+//
+// Transformation Order:
+//   - Transformations are applied from right to left, so the expression
+//     M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
+//     followed by M2 and M1. 
+//
+// Coordinate system: Right Handed
+//
+// Rotations: Counterclockwise when looking down the axis. All angles are in radians.
+
+template<class T>
+class Matrix3
+{
+public:
+    typedef T ElementType;
+    static const size_t Dimension = 3;
+
+    T M[3][3];
+
+    enum NoInitType { NoInit };
+
+    // Construct with no memory initialization.
+    Matrix3(NoInitType) { }
+
+    // By default, we construct identity matrix.
+    Matrix3()
+    {
+        M[0][0] = M[1][1] = M[2][2] = 1;
+        M[0][1] = M[1][0] = M[2][0] = 0;
+        M[0][2] = M[1][2] = M[2][1] = 0;
+    }
+
+    Matrix3(T m11, T m12, T m13,
+            T m21, T m22, T m23,
+            T m31, T m32, T m33)
+    {
+        M[0][0] = m11; M[0][1] = m12; M[0][2] = m13;
+        M[1][0] = m21; M[1][1] = m22; M[1][2] = m23;
+        M[2][0] = m31; M[2][1] = m32; M[2][2] = m33;
+    }
+    
+    // Construction from X, Y, Z basis vectors
+    Matrix3(const Vector3<T>& xBasis, const Vector3<T>& yBasis, const Vector3<T>& zBasis)
+    {
+        M[0][0] = xBasis.x; M[0][1] = yBasis.x; M[0][2] = zBasis.x;
+        M[1][0] = xBasis.y; M[1][1] = yBasis.y; M[1][2] = zBasis.y;
+        M[2][0] = xBasis.z; M[2][1] = yBasis.z; M[2][2] = zBasis.z;
+    }
+
+    explicit Matrix3(const Quat<T>& q)
+    {
+        const T tx  = q.x+q.x,  ty  = q.y+q.y,  tz  = q.z+q.z;
+        const T twx = q.w*tx,   twy = q.w*ty,   twz = q.w*tz;
+        const T txx = q.x*tx,   txy = q.x*ty,   txz = q.x*tz;
+        const T tyy = q.y*ty,   tyz = q.y*tz,   tzz = q.z*tz;
+        M[0][0] = T(1) - (tyy + tzz);    M[0][1] = txy - twz;            M[0][2] = txz + twy;
+        M[1][0] = txy + twz;            M[1][1] = T(1) - (txx + tzz);    M[1][2] = tyz - twx;
+        M[2][0] = txz - twy;            M[2][1] = tyz + twx;            M[2][2] = T(1) - (txx + tyy);
+    }
+    
+    inline explicit Matrix3(T s)
+    {
+        M[0][0] = M[1][1] = M[2][2] = s;
+        M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0;
+    }
+
+    Matrix3(T m11, T m22, T m33)
+    {
+        M[0][0] = m11; M[0][1] = 0; M[0][2] = 0;
+        M[1][0] = 0; M[1][1] = m22; M[1][2] = 0;
+        M[2][0] = 0; M[2][1] = 0; M[2][2] = m33;
+    }
+
+    explicit Matrix3(const Matrix3<typename Math<T>::OtherFloatType> &src)
+    {
+        for (int i = 0; i < 3; i++)
+            for (int j = 0; j < 3; j++)
+                M[i][j] = (T)src.M[i][j];
+    }
+
+    // C-interop support.
+    Matrix3(const typename CompatibleTypes<Matrix3<T> >::Type& s) 
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)");
+        memcpy(M, s.M, sizeof(M));
+    }
+
+    operator const typename CompatibleTypes<Matrix3<T> >::Type () const
+    {
+        typename CompatibleTypes<Matrix3<T> >::Type result;
+        OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)");
+        memcpy(result.M, M, sizeof(M));
+        return result;
+    }
+
+    T  operator()(int i, int j) const	{ return M[i][j]; }
+    T& operator()(int i, int j)			{ return M[i][j]; }
+
+    void ToString(char* dest, size_t destsize) const
+    {
+        size_t pos = 0;
+        for (int r=0; r<3; r++)
+        {
+            for (int c=0; c<3; c++)
+                pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
+        }
+    }
+
+    static Matrix3 FromString(const char* src)
+    {
+        Matrix3 result;
+        if (src)
+        {
+            for (int r=0; r<3; r++)
+            {
+                for (int c=0; c<3; c++)
+                {
+                    result.M[r][c] = (T)atof(src);
+                    while (*src && *src != ' ')
+                        src++;
+                    while (*src && *src == ' ')
+                        src++;
+                }
+            }
+        }
+        return result;
+    }
+
+    static Matrix3 Identity()  { return Matrix3(); }
+
+    void SetIdentity()
+    {
+        M[0][0] = M[1][1] = M[2][2] = 1;
+        M[0][1] = M[1][0] = M[2][0] = 0;
+        M[0][2] = M[1][2] = M[2][1] = 0;
+    }
+
+    static Matrix3 Diagonal(T m00, T m11, T m22)
+    {
+        return Matrix3(m00, 0, 0,
+            0, m11, 0,
+            0, 0, m22);
+    }
+    static Matrix3 Diagonal(const Vector3<T>& v) { return Diagonal(v.x, v.y, v.z); }
+
+    T Trace() const { return M[0][0] + M[1][1] + M[2][2]; }
+    
+    bool operator== (const Matrix3& b) const
+    {
+        bool isEqual = true;
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+                isEqual &= (M[i][j] == b.M[i][j]);
+        }
+
+        return isEqual;
+    }
+
+    Matrix3 operator+ (const Matrix3& b) const
+    {
+        Matrix3<T> result(*this);
+        result += b;
+        return result;
+    }
+
+    Matrix3& operator+= (const Matrix3& b)
+    {
+        for (int i = 0; i < 3; i++)
+            for (int j = 0; j < 3; j++)
+                M[i][j] += b.M[i][j];
+        return *this;
+    }
+
+    void operator= (const Matrix3& b)
+    {
+        for (int i = 0; i < 3; i++)
+            for (int j = 0; j < 3; j++)
+                M[i][j] = b.M[i][j];
+    }
+
+    Matrix3 operator- (const Matrix3& b) const
+    {
+        Matrix3 result(*this);
+        result -= b;
+        return result;
+    }
+
+    Matrix3& operator-= (const Matrix3& b)
+    {
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+                M[i][j] -= b.M[i][j];
+        }
+
+        return *this;
+    }
+
+    // Multiplies two matrices into destination with minimum copying.
+    static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b)
+    {
+        OVR_MATH_ASSERT((d != &a) && (d != &b));
+        int i = 0;
+        do {
+            d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0];
+            d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1];
+            d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2];
+        } while((++i) < 3);
+
+        return *d;
+    }
+
+    Matrix3 operator* (const Matrix3& b) const
+    {
+        Matrix3 result(Matrix3::NoInit);
+        Multiply(&result, *this, b);
+        return result;
+    }
+
+    Matrix3& operator*= (const Matrix3& b)
+    {
+        return Multiply(this, Matrix3(*this), b);
+    }
+
+    Matrix3 operator* (T s) const
+    {
+        Matrix3 result(*this);
+        result *= s;
+        return result;
+    }
+
+    Matrix3& operator*= (T s)
+    {
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+                M[i][j] *= s;
+        }
+
+        return *this;
+    }
+
+    Vector3<T> operator* (const Vector3<T> &b) const
+    {
+        Vector3<T> result;
+        result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z;
+        result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z;
+        result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z;
+
+        return result;
+    }
+
+    Matrix3 operator/ (T s) const
+    {
+        Matrix3 result(*this);
+        result /= s;
+        return result;
+    }
+
+    Matrix3& operator/= (T s)
+    {
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+                M[i][j] /= s;
+        }
+
+        return *this;
+    }
+
+    Vector2<T> Transform(const Vector2<T>& v) const
+    {
+        const float rcpZ = 1.0f / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]);
+        return Vector2<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ,
+                          (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ);
+    }
+
+    Vector3<T> Transform(const Vector3<T>& v) const
+    {
+        return Vector3<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z,
+                          M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z,
+                          M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z);
+    }
+
+    Matrix3 Transposed() const
+    {
+        return Matrix3(M[0][0], M[1][0], M[2][0],
+                       M[0][1], M[1][1], M[2][1],
+                       M[0][2], M[1][2], M[2][2]);
+    }
+
+    void     Transpose()
+    {
+        *this = Transposed();
+    }
+
+
+    T SubDet (const size_t* rows, const size_t* 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]]);
+    }
+
+    
+    // M += a*b.t()
+    inline void Rank1Add(const Vector3<T> &a, const Vector3<T> &b)
+    {
+        M[0][0] += a.x*b.x;        M[0][1] += a.x*b.y;        M[0][2] += a.x*b.z;
+        M[1][0] += a.y*b.x;        M[1][1] += a.y*b.y;        M[1][2] += a.y*b.z;
+        M[2][0] += a.z*b.x;        M[2][1] += a.z*b.y;        M[2][2] += a.z*b.z;
+    }
+
+    // M -= a*b.t()
+    inline void Rank1Sub(const Vector3<T> &a, const Vector3<T> &b)
+    {
+        M[0][0] -= a.x*b.x;        M[0][1] -= a.x*b.y;        M[0][2] -= a.x*b.z;
+        M[1][0] -= a.y*b.x;        M[1][1] -= a.y*b.y;        M[1][2] -= a.y*b.z;
+        M[2][0] -= a.z*b.x;        M[2][1] -= a.z*b.y;        M[2][2] -= a.z*b.z;
+    }
+
+    inline Vector3<T> Col(int c) const
+    {
+        return Vector3<T>(M[0][c], M[1][c], M[2][c]);
+    }
+
+    inline Vector3<T> Row(int r) const
+    {
+        return Vector3<T>(M[r][0], M[r][1], M[r][2]);
+    }
+
+    inline Vector3<T> GetColumn(int c) const
+    {
+        return Vector3<T>(M[0][c], M[1][c], M[2][c]);
+    }
+
+    inline Vector3<T> GetRow(int r) const
+    {
+        return Vector3<T>(M[r][0], M[r][1], M[r][2]);
+    }
+
+    inline void SetColumn(int c, const Vector3<T>& v)
+    {
+        M[0][c] = v.x;
+        M[1][c] = v.y;
+        M[2][c] = v.z;
+    }
+
+    inline void SetRow(int r, const Vector3<T>& v)
+    {
+        M[r][0] = v.x;
+        M[r][1] = v.y;
+        M[r][2] = v.z;
+    }
+
+    inline T Determinant() const
+    {
+        const Matrix3<T>& m = *this;
+        T d; 
+
+        d  = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]);
+        d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]);
+        d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]);
+
+        return d;
+    }
+    
+    inline Matrix3<T> Inverse() const
+    {
+        Matrix3<T> a;
+        const  Matrix3<T>& m = *this;
+        T d = Determinant();
+
+        OVR_MATH_ASSERT(d != 0);
+        T s = T(1)/d;
+
+        a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]);   
+        a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]);   
+        a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]);   
+
+        a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]);   
+        a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]);   
+        a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]);   
+        
+        a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]);   
+        a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]);   
+        a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]);   
+        
+        return a;
+    }
+    
+    // Outer Product of two column vectors: a * b.Transpose()
+    static Matrix3 OuterProduct(const Vector3<T>& a, const Vector3<T>& b)
+    {
+        return Matrix3(a.x*b.x, a.x*b.y, a.x*b.z,
+                       a.y*b.x, a.y*b.y, a.y*b.z,
+                       a.z*b.x, a.z*b.y, a.z*b.z);
+    }
+
+    // Angle in radians between two rotation matrices
+    // Uses identity trace(a*b') = 2*cos(theta) + 1
+    T Angle(const Matrix3& b) const
+    {
+        const Matrix3& a = *this;
+        return Acos(((a * b.Transposed()).Trace() - T(1)) * T(0.5));
+    }
+};
+
+typedef Matrix3<float>  Matrix3f;
+typedef Matrix3<double> Matrix3d;
+
+//-------------------------------------------------------------------------------------
+// ***** Matrix2
+
+template<class T>
+class Matrix2
+{
+public:
+    typedef T ElementType;
+    static const size_t Dimension = 2;
+
+    T M[2][2];
+
+    enum NoInitType { NoInit };
+
+    // Construct with no memory initialization.
+    Matrix2(NoInitType) { }
+
+    // By default, we construct identity matrix.
+    Matrix2()
+    {
+        M[0][0] = M[1][1] = 1;
+        M[0][1] = M[1][0] = 0;
+    }
+
+    Matrix2(T m11, T m12,
+            T m21, T m22)
+    {
+        M[0][0] = m11; M[0][1] = m12;
+        M[1][0] = m21; M[1][1] = m22;
+    }
+
+    // Construction from X, Y basis vectors
+    Matrix2(const Vector2<T>& xBasis, const Vector2<T>& yBasis)
+    {
+        M[0][0] = xBasis.x; M[0][1] = yBasis.x;
+        M[1][0] = xBasis.y; M[1][1] = yBasis.y;
+    }
+
+    explicit Matrix2(T s)
+    {
+        M[0][0] = M[1][1] = s;
+        M[0][1] = M[1][0] = 0;
+    }
+
+    Matrix2(T m11, T m22)
+    {
+        M[0][0] = m11; M[0][1] = 0;
+        M[1][0] = 0;   M[1][1] = m22;
+    }
+
+    explicit Matrix2(const Matrix2<typename Math<T>::OtherFloatType> &src)
+    {
+        M[0][0] = T(src.M[0][0]); M[0][1] = T(src.M[0][1]);
+        M[1][0] = T(src.M[1][0]); M[1][1] = T(src.M[1][1]);
+    }
+
+    // C-interop support
+    Matrix2(const typename CompatibleTypes<Matrix2<T> >::Type& s)
+    {
+        OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix2), "sizeof(s) == sizeof(Matrix2)");
+        memcpy(M, s.M, sizeof(M));
+    }
+
+    operator const typename CompatibleTypes<Matrix2<T> >::Type() const
+    {
+        typename CompatibleTypes<Matrix2<T> >::Type result;
+        OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix2), "sizeof(result) == sizeof(Matrix2)");
+        memcpy(result.M, M, sizeof(M));
+        return result;
+    }
+
+    T  operator()(int i, int j) const	{ return M[i][j]; }
+    T& operator()(int i, int j)			{ return M[i][j]; }
+    const T*  operator[](int i) const	{ return M[i]; }
+    T*  operator[](int i)	 		{ return M[i]; }
+
+    static Matrix2 Identity()  { return Matrix2(); }
+
+    void SetIdentity()
+    {
+        M[0][0] = M[1][1] = 1;
+        M[0][1] = M[1][0] = 0;
+    }
+
+    static Matrix2 Diagonal(T m00, T m11)
+    {
+        return Matrix2(m00, m11);
+    }
+    static Matrix2 Diagonal(const Vector2<T>& v) { return Matrix2(v.x, v.y); }
+
+    T Trace() const { return M[0][0] + M[1][1]; }
+
+    bool operator== (const Matrix2& b) const
+    {
+        return M[0][0] == b.M[0][0] && M[0][1] == b.M[0][1] &&
+               M[1][0] == b.M[1][0] && M[1][1] == b.M[1][1];
+    }
+
+    Matrix2 operator+ (const Matrix2& b) const
+    {
+        return Matrix2(M[0][0] + b.M[0][0], M[0][1] + b.M[0][1],
+                       M[1][0] + b.M[1][0], M[1][1] + b.M[1][1]);
+    }
+
+    Matrix2& operator+= (const Matrix2& b)
+    {
+        M[0][0] += b.M[0][0]; M[0][1] += b.M[0][1];
+        M[1][0] += b.M[1][0]; M[1][1] += b.M[1][1];
+        return *this;
+    }
+
+    void operator= (const Matrix2& b)
+    {
+        M[0][0] = b.M[0][0]; M[0][1] = b.M[0][1];
+        M[1][0] = b.M[1][0]; M[1][1] = b.M[1][1];
+    }
+
+    Matrix2 operator- (const Matrix2& b) const
+    {
+        return Matrix2(M[0][0] - b.M[0][0], M[0][1] - b.M[0][1],
+                       M[1][0] - b.M[1][0], M[1][1] - b.M[1][1]);
+    }
+
+    Matrix2& operator-= (const Matrix2& b)
+    {
+        M[0][0] -= b.M[0][0]; M[0][1] -= b.M[0][1];
+        M[1][0] -= b.M[1][0]; M[1][1] -= b.M[1][1];
+        return *this;
+    }
+
+    Matrix2 operator* (const Matrix2& b) const
+    {
+        return Matrix2(M[0][0] * b.M[0][0] + M[0][1] * b.M[1][0], M[0][0] * b.M[0][1] + M[0][1] * b.M[1][1],
+                       M[1][0] * b.M[0][0] + M[1][1] * b.M[1][0], M[1][0] * b.M[0][1] + M[1][1] * b.M[1][1]);
+    }
+
+    Matrix2& operator*= (const Matrix2& b)
+    {
+        *this = *this * b;
+    }
+
+    Matrix2 operator* (T s) const
+    {
+        return Matrix2(M[0][0] * s, M[0][1] * s,
+                       M[1][0] * s, M[1][1] * s);
+    }
+
+    Matrix2& operator*= (T s)
+    {
+        M[0][0] *= s; M[0][1] *= s;
+        M[1][0] *= s; M[1][1] *= s;
+        return *this;
+    }
+
+    Matrix2 operator/ (T s) const
+    {
+        return *this * (T(1) / s);
+    }
+
+    Matrix2& operator/= (T s)
+    {
+        return *this *= (T(1) / s);
+    }
+
+    Vector2<T> operator* (const Vector2<T> &b) const
+    {
+        return Vector2<T>(M[0][0] * b.x + M[0][1] * b.y,
+                          M[1][0] * b.x + M[1][1] * b.y);
+    }
+
+    Vector2<T> Transform(const Vector2<T>& v) const
+    {
+        return Vector2<T>(M[0][0] * v.x + M[0][1] * v.y,
+                          M[1][0] * v.x + M[1][1] * v.y);
+    }
+
+    Matrix2 Transposed() const
+    {
+        return Matrix2(M[0][0], M[1][0],
+                       M[0][1], M[1][1]);
+    }
+
+    void Transpose()
+    {
+        OVRMath_Swap(M[1][0], M[0][1]);
+    }
+
+    Vector2<T> GetColumn(int c) const
+    {
+        return Vector2<T>(M[0][c], M[1][c]);
+    }
+
+    Vector2<T> GetRow(int r) const
+    {
+        return Vector2<T>(M[r][0], M[r][1]);
+    }
+
+    void SetColumn(int c, const Vector2<T>& v)
+    {
+        M[0][c] = v.x;
+        M[1][c] = v.y;
+    }
+
+    void SetRow(int r, const Vector2<T>& v)
+    {
+        M[r][0] = v.x;
+        M[r][1] = v.y;
+    }
+
+    T Determinant() const
+    {
+        return M[0][0] * M[1][1] - M[0][1] * M[1][0];
+    }
+
+    Matrix2 Inverse() const
+    {
+        T rcpDet = T(1) / Determinant();
+        return Matrix2( M[1][1] * rcpDet, -M[0][1] * rcpDet,
+                       -M[1][0] * rcpDet,  M[0][0] * rcpDet);
+    }
+
+    // Outer Product of two column vectors: a * b.Transpose()
+    static Matrix2 OuterProduct(const Vector2<T>& a, const Vector2<T>& b)
+    {
+        return Matrix2(a.x*b.x, a.x*b.y,
+                       a.y*b.x, a.y*b.y);
+    }
+
+    // Angle in radians between two rotation matrices
+    T Angle(const Matrix2& b) const
+    {
+        const Matrix2& a = *this;
+        return Acos(a(0, 0)*b(0, 0) + a(1, 0)*b(1, 0));
+    }
+};
+
+typedef Matrix2<float>  Matrix2f;
+typedef Matrix2<double> Matrix2d;
+
+//-------------------------------------------------------------------------------------
+
+template<class T>
+class SymMat3
+{
+private:
+    typedef SymMat3<T> this_type;
+
+public:
+    typedef T Value_t;
+    // Upper symmetric
+    T v[6]; // _00 _01 _02 _11 _12 _22
+
+    inline SymMat3() {}
+
+    inline explicit SymMat3(T s)
+    {
+        v[0] = v[3] = v[5] = s;
+        v[1] = v[2] = v[4] = 0;
+    }
+
+    inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22)
+    {
+        v[0] = a00; v[1] = a01; v[2] = a02;
+        v[3] = a11; v[4] = a12;
+        v[5] = a22;
+    }
+
+    // Cast to symmetric Matrix3
+    operator Matrix3<T>() const
+    {
+        return Matrix3<T>(v[0], v[1], v[2],
+                          v[1], v[3], v[4],
+                          v[2], v[4], v[5]);
+    }
+
+    static inline int Index(unsigned int i, unsigned int j)
+    {
+        return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i);
+    }
+
+    inline T operator()(int i, int j) const { return v[Index(i,j)]; }
+    
+    inline T &operator()(int i, int j) { return v[Index(i,j)]; }
+
+    inline this_type& operator+=(const this_type& b)
+    {
+        v[0]+=b.v[0];
+        v[1]+=b.v[1];
+        v[2]+=b.v[2];
+        v[3]+=b.v[3];
+        v[4]+=b.v[4];
+        v[5]+=b.v[5];
+        return *this;
+    }
+
+    inline this_type& operator-=(const this_type& b)
+    {
+        v[0]-=b.v[0];
+        v[1]-=b.v[1];
+        v[2]-=b.v[2];
+        v[3]-=b.v[3];
+        v[4]-=b.v[4];
+        v[5]-=b.v[5];
+
+        return *this;
+    }
+
+    inline this_type& operator*=(T s)
+    {
+        v[0]*=s;
+        v[1]*=s;
+        v[2]*=s;
+        v[3]*=s;
+        v[4]*=s;
+        v[5]*=s;
+
+        return *this;
+    }
+        
+    inline SymMat3 operator*(T s) const
+    {
+        SymMat3 d;
+        d.v[0] = v[0]*s; 
+        d.v[1] = v[1]*s; 
+        d.v[2] = v[2]*s; 
+        d.v[3] = v[3]*s; 
+        d.v[4] = v[4]*s; 
+        d.v[5] = v[5]*s; 
+                        
+        return d;
+    }
+
+    // Multiplies two matrices into destination with minimum copying.
+    static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b)
+    {        
+        // _00 _01 _02 _11 _12 _22
+
+        d->v[0] = a.v[0] * b.v[0];
+        d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3];
+        d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4];
+                    
+        d->v[3] = a.v[3] * b.v[3];
+        d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5];
+                
+        d->v[5] = a.v[5] * b.v[5];
+    
+        return *d;
+    }
+    
+    inline T Determinant() const
+    {
+        const this_type& m = *this;
+        T d; 
+
+        d  = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1));
+        d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0));
+        d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0));
+
+        return d;
+    }
+
+    inline this_type Inverse() const
+    {
+        this_type a;
+        const this_type& m = *this;
+        T d = Determinant();
+
+        OVR_MATH_ASSERT(d != 0);
+        T s = T(1)/d;
+
+        a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1));   
+
+        a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2));   
+        a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0));   
+
+        a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1));   
+        a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2));   
+        a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0));   
+
+        return a;
+    }
+
+    inline T Trace() const { return v[0] + v[3] + v[5]; }
+
+    // M = a*a.t()
+    inline void Rank1(const Vector3<T> &a)
+    {
+        v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z;
+        v[3] = a.y*a.y; v[4] = a.y*a.z;
+        v[5] = a.z*a.z;
+    }
+
+    // M += a*a.t()
+    inline void Rank1Add(const Vector3<T> &a)
+    {
+        v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z;
+        v[3] += a.y*a.y; v[4] += a.y*a.z;
+        v[5] += a.z*a.z;
+    }
+
+    // M -= a*a.t()
+    inline void Rank1Sub(const Vector3<T> &a)
+    {
+        v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z;
+        v[3] -= a.y*a.y; v[4] -= a.y*a.z;
+        v[5] -= a.z*a.z;
+    }
+};
+
+typedef SymMat3<float>  SymMat3f;
+typedef SymMat3<double> SymMat3d;
+
+template<class T>
+inline Matrix3<T> operator*(const SymMat3<T>& a, const SymMat3<T>& b)
+{
+    #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
+    return Matrix3<T>(
+        AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
+        AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
+        AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
+    #undef AJB_ARBC
+}
+
+template<class T>
+inline Matrix3<T> operator*(const Matrix3<T>& a, const SymMat3<T>& b)
+{
+    #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
+    return Matrix3<T>(
+        AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
+        AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
+        AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
+    #undef AJB_ARBC
+}
+
+//-------------------------------------------------------------------------------------
+// ***** 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_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); }
+
+    T    Get(AngularUnits u = Radians) const       { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); }
+    void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_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 <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_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 < -((T)MATH_DOUBLE_PI))
+            a += ((T)MATH_DOUBLE_TWOPI);
+        else if (a > ((T)MATH_DOUBLE_PI))
+            a -= ((T)MATH_DOUBLE_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 >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI))
+            return;
+        a = fmod(a,((T)MATH_DOUBLE_TWOPI));
+        if (a < -((T)MATH_DOUBLE_PI))
+            a += ((T)MATH_DOUBLE_TWOPI);
+        else if (a > ((T)MATH_DOUBLE_PI))
+            a -= ((T)MATH_DOUBLE_TWOPI);
+    }
+};
+
+
+typedef Angle<float>  Anglef;
+typedef Angle<double> Angled;
+
+
+//-------------------------------------------------------------------------------------
+// ***** Plane
+
+// Consists of a normal vector and distance from the origin where the plane is located.
+
+template<class T>
+class Plane
+{
+public:
+    Vector3<T> N;
+    T          D;
+
+    Plane() : D(0) {}
+
+    // Normals must already be normalized
+    Plane(const Vector3<T>& n, T d) : N(n), D(d) {}
+    Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {}
+
+    // construct from a point on the plane and the normal
+    Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {}
+
+    // 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.Dot(p)) + D;
+    }
+
+    Plane<T> Flipped() const
+    {
+        return Plane(-N, -D);
+    }
+
+    void Flip()
+    {
+        N = -N;
+        D = -D;
+    }
+
+    bool operator==(const Plane<T>& rhs) const
+    {
+        return (this->D == rhs.D && this->N == rhs.N);
+    }
+};
+
+typedef Plane<float> Planef;
+typedef Plane<double> Planed;
+
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** ScaleAndOffset2D
+
+struct ScaleAndOffset2D
+{
+    Vector2f Scale;
+    Vector2f Offset;
+
+    ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f)
+        : Scale(sx, sy), Offset(ox, oy)        
+    { }
+};
+
+
+//-----------------------------------------------------------------------------------
+// ***** FovPort
+
+// FovPort describes Field Of View (FOV) of a viewport.
+// This class has values for up, down, left and right, stored in 
+// tangent of the angle units to simplify calculations.
+//
+// As an example, for a standard 90 degree vertical FOV, we would 
+// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
+//
+// CreateFromRadians/Degrees helper functions can be used to
+// access FOV in different units.
+
+
+// ***** FovPort
+
+struct FovPort
+{
+    float UpTan;
+    float DownTan;
+    float LeftTan;
+    float RightTan;
+
+    FovPort ( float sideTan = 0.0f ) :
+        UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { }
+    FovPort ( float u, float d, float l, float r ) :
+        UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { }
+
+    // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp).
+    FovPort(const ovrFovPort &src)
+        : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan)
+    { }    
+
+    operator ovrFovPort () const
+    {
+        ovrFovPort result;
+        result.LeftTan  = LeftTan;
+        result.RightTan = RightTan;
+        result.UpTan    = UpTan;
+        result.DownTan  = DownTan;
+        return result;
+    }
+
+    static FovPort CreateFromRadians(float horizontalFov, float verticalFov)
+    {
+        FovPort result;
+        result.UpTan    = tanf (   verticalFov * 0.5f );
+        result.DownTan  = tanf (   verticalFov * 0.5f );
+        result.LeftTan  = tanf ( horizontalFov * 0.5f );
+        result.RightTan = tanf ( horizontalFov * 0.5f );
+        return result;
+    }
+
+    static FovPort CreateFromDegrees(float horizontalFovDegrees,
+                                     float verticalFovDegrees)
+    {
+        return CreateFromRadians(DegreeToRad(horizontalFovDegrees),
+                                 DegreeToRad(verticalFovDegrees));
+    }
+
+    //  Get Horizontal/Vertical components of Fov in radians.
+    float GetVerticalFovRadians() const     { return atanf(UpTan)    + atanf(DownTan); }
+    float GetHorizontalFovRadians() const   { return atanf(LeftTan)  + atanf(RightTan); }
+    //  Get Horizontal/Vertical components of Fov in degrees.
+    float GetVerticalFovDegrees() const     { return RadToDegree(GetVerticalFovRadians()); }
+    float GetHorizontalFovDegrees() const   { return RadToDegree(GetHorizontalFovRadians()); }
+
+    // Compute maximum tangent value among all four sides.
+    float GetMaxSideTan() const
+    {
+        return OVRMath_Max(OVRMath_Max(UpTan, DownTan), OVRMath_Max(LeftTan, RightTan));
+    }
+
+    static ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov )
+    {
+        float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan );
+        float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f;
+        float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan );
+        float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f;
+
+        ScaleAndOffset2D result;
+        result.Scale    = Vector2f(projXScale, projYScale);
+        result.Offset   = Vector2f(projXOffset, projYOffset);
+        // Hey - why is that Y.Offset negated?
+        // It's because a projection matrix transforms from world coords with Y=up,
+        // whereas this is from NDC which is Y=down.
+
+        return result;
+    }
+
+    // Converts Fov Tan angle units to [-1,1] render target NDC space
+    Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle)
+    {  
+        ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this);
+        return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset;
+    }
+
+    // Compute per-channel minimum and maximum of Fov.
+    static FovPort Min(const FovPort& a, const FovPort& b)
+    {   
+        FovPort fov( OVRMath_Min( a.UpTan   , b.UpTan    ),   
+                     OVRMath_Min( a.DownTan , b.DownTan  ),
+                     OVRMath_Min( a.LeftTan , b.LeftTan  ),
+                     OVRMath_Min( a.RightTan, b.RightTan ) );
+        return fov;
+    }
+
+    static FovPort Max(const FovPort& a, const FovPort& b)
+    {   
+        FovPort fov( OVRMath_Max( a.UpTan   , b.UpTan    ),   
+                     OVRMath_Max( a.DownTan , b.DownTan  ),
+                     OVRMath_Max( a.LeftTan , b.LeftTan  ),
+                     OVRMath_Max( a.RightTan, b.RightTan ) );
+        return fov;
+    }
+};
+
+
+} // Namespace OVR
+
+
+#if defined(_MSC_VER)
+    #pragma warning(pop)
+#endif
+
+
+#endif
diff --git a/LibOVR/Include/OVR.h b/LibOVR/Include/OVR.h
index b82e452..546e447 100644
--- a/LibOVR/Include/OVR.h
+++ b/LibOVR/Include/OVR.h
@@ -27,10 +27,14 @@ limitations under the License.
 #define OVR_h
 
 #include "OVR_Version.h"
-
-#include "../Src/Kernel/OVR_Math.h"
-
-#include "../Src/OVR_CAPI.h"
+#include "OVR_CAPI.h"
+
+/* The following includes are deprecated from this location and will be removed from a future version of this library. */
+#include "Kernel/OVR_Types.h"
+#include "Kernel/OVR_RefCount.h"
+#include "Kernel/OVR_Std.h"
+#include "Kernel/OVR_Alg.h"
+#include "Extras/OVR_Math.h"
 
 #endif
 
diff --git a/LibOVR/Include/OVR_CAPI.h b/LibOVR/Include/OVR_CAPI.h
new file mode 100644
index 0000000..ab950b6
--- /dev/null
+++ b/LibOVR/Include/OVR_CAPI.h
@@ -0,0 +1,4 @@
+
+// Temporary backward compatibility until we update all our internal code that's dependent on it.
+#include "OVR_CAPI_0_5_0.h"
+
diff --git a/LibOVR/Include/OVR_CAPI_0_5_0.h b/LibOVR/Include/OVR_CAPI_0_5_0.h
new file mode 100755
index 0000000..01f0dd8
--- /dev/null
+++ b/LibOVR/Include/OVR_CAPI_0_5_0.h
@@ -0,0 +1,1178 @@
+/************************************************************************************
+
+Filename    :   OVR_CAPI_0_5_0.h
+Content     :   C Interface to Oculus tracking and rendering.
+Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.2
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+/// @file OVR_CAPI_0_5_0.h
+/// Exposes all general Rift functionality.
+
+#ifndef OVR_CAPI_h  // We don't use version numbers within this, as all versioned variations of
+#define OVR_CAPI_h  // this file are currently mutually exclusive.
+
+
+#include "OVR_CAPI_Keys.h"
+#include "OVR_Version.h"
+
+
+#include <stdint.h>
+
+#if defined(_MSC_VER)
+    #pragma warning(push)
+    #pragma warning(disable: 4324) // structure was padded due to __declspec(align())
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_OS
+//
+#if !defined(OVR_OS_WIN32) && defined(_WIN32) 
+    #define OVR_OS_WIN32
+#endif
+
+#if !defined(OVR_OS_MAC) && defined(__APPLE__)
+    #define OVR_OS_MAC
+#endif
+
+#if !defined(OVR_OS_LINUX) && defined(__linux__)
+    #define OVR_OS_LINUX
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_CPP
+//
+#if !defined(OVR_CPP)
+    #if defined(__cplusplus)
+        #define OVR_CPP(x) x
+    #else
+        #define OVR_CPP(x) /* Not C++ */
+    #endif
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_CDECL
+//
+// LibOVR calling convention for 32-bit Windows builds.
+//
+#if !defined(OVR_CDECL)
+    #if defined(_WIN32)
+        #define OVR_CDECL __cdecl
+    #else
+        #define OVR_CDECL
+    #endif
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_EXTERN_C
+//
+// Defined as extern "C" when built from C++ code.
+//
+#if !defined(OVR_EXTERN_C)
+    #ifdef __cplusplus 
+        #define OVR_EXTERN_C extern "C"
+    #else
+        #define OVR_EXTERN_C
+    #endif
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_PUBLIC_FUNCTION / OVR_PRIVATE_FUNCTION
+//
+// OVR_PUBLIC_FUNCTION  - Functions that externally visible from a shared library. Corresponds to Microsoft __dllexport.
+// OVR_PUBLIC_CLASS     - C++ structs and classes that are externally visible from a shared library. Corresponds to Microsoft __dllexport.
+// OVR_PRIVATE_FUNCTION - Functions that are not visible outside of a shared library. They are private to the shared library.
+// OVR_PRIVATE_CLASS    - C++ structs and classes that are not visible outside of a shared library. They are private to the shared library.
+//
+// OVR_DLL_BUILD        - Used to indicate that the current compilation unit is of a shared library.
+// OVR_DLL_IMPORT       - Used to indicate that the current compilation unit is a user of the corresponding shared library.
+// OVR_DLL_BUILD        - used to indicate that the current compilation unit is not a shared library but rather statically linked code.
+//
+#if !defined(OVR_PUBLIC_FUNCTION)
+    #if defined(OVR_DLL_BUILD)
+        #if defined(_WIN32)
+            #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllexport) rval OVR_CDECL
+            #define OVR_PUBLIC_CLASS          __declspec(dllexport)
+            #define OVR_PRIVATE_FUNCTION
+            #define OVR_PRIVATE_CLASS
+        #else
+            #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __attribute__((visibility("default"))) rval OVR_CDECL /* Requires GCC 4.0+ */
+            #define OVR_PUBLIC_CLASS          __attribute__((visibility("default"))) /* Requires GCC 4.0+ */
+            #define OVR_PRIVATE_FUNCTION      __attribute__((visibility("hidden")))
+            #define OVR_PRIVATE_CLASS         __attribute__((visibility("hidden")))
+        #endif
+    #elif defined(OVR_DLL_IMPORT)
+        #if defined(_WIN32)
+            #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllimport) rval OVR_CDECL
+            #define OVR_PUBLIC_CLASS          __declspec(dllimport)
+            #define OVR_PRIVATE_FUNCTION
+            #define OVR_PRIVATE_CLASS
+        #else
+            #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL
+            #define OVR_PUBLIC_CLASS
+            #define OVR_PRIVATE_FUNCTION
+            #define OVR_PRIVATE_CLASS
+        #endif
+    #else // OVR_STATIC_BUILD
+        #define OVR_PUBLIC_FUNCTION(rval)     OVR_EXTERN_C rval OVR_CDECL
+        #define OVR_PUBLIC_CLASS
+        #define OVR_PRIVATE_FUNCTION
+        #define OVR_PRIVATE_CLASS
+    #endif
+#endif
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_EXPORT
+//
+// Provided for backward compatibility with older usage.
+
+#if !defined(OVR_EXPORT)
+    #ifdef OVR_OS_WIN32
+        #define OVR_EXPORT __declspec(dllexport)
+    #else
+        #define OVR_EXPORT
+    #endif
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_ALIGNAS
+//
+
+#if !defined(OVR_ALIGNAS)
+    // C++11 alignas
+    #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L))
+        #define OVR_ALIGNAS(n) alignas(n)
+    #elif defined(__clang__) && !defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 300) && (__cplusplus >= 201103L)
+        #define OVR_ALIGNAS(n) alignas(n)
+    #elif defined(__clang__) && defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 401) && (__cplusplus >= 201103L)
+        #define OVR_ALIGNAS(n) alignas(n)
+    #elif defined(_MSC_VER) && (_MSC_VER >= 1900)
+        #define OVR_ALIGNAS(n) alignas(n)
+    #elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408)
+        #define OVR_ALIGNAS(n) alignas(n)
+
+    // Pre-C++11 alignas fallbacks
+    #elif defined(__GNUC__) || defined(__clang__)
+        #define OVR_ALIGNAS(n) __attribute__((aligned(n)))
+    #elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
+        #define OVR_ALIGNAS(n) __declspec(align(n))             // For Microsoft the alignment must be a literal integer.
+    #elif defined(__CC_ARM)
+        #define OVR_ALIGNAS(n) __align(n)
+    #else
+        #error Need to define OVR_ALIGNAS
+    #endif
+#endif
+
+
+//-----------------------------------------------------------------------------------
+// ***** ovrBool
+
+typedef char ovrBool;
+#define ovrFalse 0
+#define ovrTrue  1
+
+
+//-----------------------------------------------------------------------------------
+// ***** Simple Math Structures
+
+/// A 2D vector with integer components.
+typedef struct ovrVector2i_
+{
+    int x, y;
+} ovrVector2i;
+
+/// A 2D size with integer components.
+typedef struct ovrSizei_
+{
+    int w, h;
+} ovrSizei;
+/// A 2D rectangle with a position and size.
+/// All components are integers.
+typedef struct ovrRecti_
+{
+    ovrVector2i Pos;
+    ovrSizei    Size;
+} ovrRecti;
+
+/// A quaternion rotation.
+typedef struct ovrQuatf_
+{
+    float x, y, z, w;
+} ovrQuatf;
+
+/// A 2D vector with float components.
+typedef struct ovrVector2f_
+{
+    float x, y;
+} ovrVector2f;
+
+/// A 3D vector with float components.
+typedef struct ovrVector3f_
+{
+    float x, y, z;
+} ovrVector3f;
+
+/// A 4x4 matrix with float elements.
+typedef struct ovrMatrix4f_
+{
+    float M[4][4];
+} ovrMatrix4f;
+
+/// Position and orientation together.
+typedef struct ovrPosef_
+{
+    ovrQuatf     Orientation;
+    ovrVector3f  Position;
+} ovrPosef;
+
+/// A full pose (rigid body) configuration with first and second derivatives.
+typedef struct OVR_ALIGNAS(8) ovrPoseStatef_
+{
+    ovrPosef     ThePose;               ///< The body's position and orientation.
+    ovrVector3f  AngularVelocity;       ///< The body's angular velocity in radians per second.
+    ovrVector3f  LinearVelocity;        ///< The body's velocity in meters per second.
+    ovrVector3f  AngularAcceleration;   ///< The body's angular acceleration in radians per second per second.
+    ovrVector3f  LinearAcceleration;    ///< The body's acceleration in meters per second per second.
+    float        Pad;                   ///< Unused struct padding.
+    double       TimeInSeconds;         ///< Absolute time of this state sample.
+} ovrPoseStatef;
+
+/// Field Of View (FOV) in tangent of the angle units.
+/// As an example, for a standard 90 degree vertical FOV, we would
+/// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
+typedef struct ovrFovPort_
+{
+    float UpTan;    ///< The tangent of the angle between the viewing vector and the top edge of the field of view.
+    float DownTan;  ///< The tangent of the angle between the viewing vector and the bottom edge of the field of view.
+    float LeftTan;  ///< The tangent of the angle between the viewing vector and the left edge of the field of view.
+    float RightTan; ///< The tangent of the angle between the viewing vector and the right edge of the field of view.
+} ovrFovPort;
+
+//-----------------------------------------------------------------------------------
+// ***** HMD Types
+
+/// Enumerates all HMD types that we support.
+typedef enum ovrHmdType_
+{
+    ovrHmd_None             = 0,
+    ovrHmd_DK1              = 3,
+    ovrHmd_DKHD             = 4,
+    ovrHmd_DK2              = 6,
+    ovrHmd_BlackStar        = 7,
+    ovrHmd_CB               = 8,
+    ovrHmd_Other      = 9,
+    ovrHmd_EnumSize   = 0x7fffffff ///< Force type int32_t.
+} ovrHmdType;
+
+/// HMD capability bits reported by device.
+typedef enum ovrHmdCaps_
+{
+    // Read-only flags.
+    ovrHmdCap_Present           = 0x0001,   ///< (read only) The HMD is plugged in and detected by the system.
+    ovrHmdCap_Available         = 0x0002,   ///< (read only) The HMD and its sensor are available for ownership use.
+                                            ///<             i.e. it is not already owned by another application.
+    ovrHmdCap_Captured          = 0x0004,   ///< (read only) Set to 'true' if we captured ownership of this HMD.
+    ovrHmdCap_ExtendDesktop     = 0x0008,   ///< (read only) Means the display driver works via acting as an addition display monitor.
+    ovrHmdCap_DebugDevice       = 0x0010,   ///< (read only) Means HMD device is a virtual debug device.
+
+    // Modifiable flags (through ovrHmd_SetEnabledCaps).
+    ovrHmdCap_NoMirrorToWindow  = 0x2000,   ///< Disables mirroring of HMD output to the window. This may improve 
+                                            ///< rendering performance slightly (only if 'ExtendDesktop' is off).
+    ovrHmdCap_DisplayOff        = 0x0040,   ///< Turns off HMD screen and output (only if 'ExtendDesktop' is off).
+    ovrHmdCap_LowPersistence    = 0x0080,   ///< HMD supports low persistence mode.
+    ovrHmdCap_DynamicPrediction = 0x0200,   ///< Adjust prediction dynamically based on internally measured latency.
+    ovrHmdCap_NoVSync           = 0x1000,   ///< Support rendering without VSync for debugging.
+
+    // These bits can be modified by ovrHmd_SetEnabledCaps.
+    ovrHmdCap_Writable_Mask     = ovrHmdCap_NoMirrorToWindow |
+                                  ovrHmdCap_DisplayOff |
+                                  ovrHmdCap_LowPersistence |
+                                  ovrHmdCap_DynamicPrediction |
+                                  ovrHmdCap_NoVSync,
+
+    /// These flags are currently passed into the service. May change without notice.
+    ovrHmdCap_Service_Mask      = ovrHmdCap_NoMirrorToWindow |
+                                  ovrHmdCap_DisplayOff |
+                                  ovrHmdCap_LowPersistence |
+                                  ovrHmdCap_DynamicPrediction
+  , ovrHmdCap_EnumSize          = 0x7fffffff ///< Force type int32_t.
+} ovrHmdCaps;
+
+
+/// Tracking capability bits reported by the device.
+/// Used with ovrHmd_ConfigureTracking.
+typedef enum ovrTrackingCaps_
+{
+    ovrTrackingCap_Orientation      = 0x0010,   ///< Supports orientation tracking (IMU).
+    ovrTrackingCap_MagYawCorrection = 0x0020,   ///< Supports yaw drift correction via a magnetometer or other means.
+    ovrTrackingCap_Position         = 0x0040,   ///< Supports positional tracking.
+    /// Overrides the other flags. Indicates that the application
+    /// doesn't care about tracking settings. This is the internal
+    /// default before ovrHmd_ConfigureTracking is called.
+    ovrTrackingCap_Idle             = 0x0100,
+    ovrTrackingCap_EnumSize         = 0x7fffffff    ///< Force type int32_t.
+} ovrTrackingCaps;
+
+/// Distortion capability bits reported by device.
+/// Used with ovrHmd_ConfigureRendering and ovrHmd_CreateDistortionMesh.
+typedef enum ovrDistortionCaps_
+{
+    // 0x01 unused - Previously ovrDistortionCap_Chromatic now enabled permanently.
+    ovrDistortionCap_TimeWarp           =    0x02,     ///< Supports timewarp.
+    // 0x04 unused
+
+    ovrDistortionCap_Vignette           =    0x08,     ///< Supports vignetting around the edges of the view.
+    ovrDistortionCap_NoRestore          =    0x10,     ///< Do not save and restore the graphics and compute state when rendering distortion.
+    ovrDistortionCap_FlipInput          =    0x20,     ///< Flip the vertical texture coordinate of input images.
+    ovrDistortionCap_SRGB               =    0x40,     ///< Assume input images are in sRGB gamma-corrected color space.
+    ovrDistortionCap_Overdrive          =    0x80,     ///< Overdrive brightness transitions to reduce artifacts on DK2+ displays
+    ovrDistortionCap_HqDistortion       =   0x100,     ///< High-quality sampling of distortion buffer for anti-aliasing
+    ovrDistortionCap_LinuxDevFullscreen =   0x200,     ///< Indicates window is fullscreen on a device when set. The SDK will automatically apply distortion mesh rotation if needed.
+    ovrDistortionCap_ComputeShader      =   0x400,     ///< Using compute shader (DX11+ only)
+    //ovrDistortionCap_NoTimewarpJit    =   0x800      RETIRED - do not reuse this bit without major versioning changes.
+    ovrDistortionCap_TimewarpJitDelay   =  0x1000,     ///< Enables a spin-wait that tries to push time-warp to be as close to V-sync as possible. WARNING - this may backfire and cause framerate loss - use with caution.
+
+    ovrDistortionCap_ProfileNoSpinWaits = 0x10000,    ///< Use when profiling with timewarp to remove false positives
+    ovrDistortionCap_EnumSize           = 0x7fffffff  ///< Force type int32_t.
+} ovrDistortionCaps;
+
+/// Specifies which eye is being used for rendering.
+/// This type explicitly does not include a third "NoStereo" option, as such is
+/// not required for an HMD-centered API.
+typedef enum ovrEyeType_
+{
+    ovrEye_Left  = 0,
+    ovrEye_Right = 1,
+    ovrEye_Count    = 2,
+    ovrEye_EnumSize = 0x7fffffff ///< Force type int32_t.
+} ovrEyeType;
+
+/// This is a complete descriptor of the HMD.
+typedef struct ovrHmdDesc_
+{
+    /// Internal handle of this HMD.
+    struct ovrHmdStruct* Handle;
+
+    /// This HMD's type.
+    ovrHmdType  Type;
+    
+    /// Name string describing the product: "Oculus Rift DK1", etc.
+    const char* ProductName;
+    /// String describing the manufacturer. Usually "Oculus".
+    const char* Manufacturer;
+    
+    /// HID Vendor ID of the device.
+    short       VendorId;
+    /// HID Product ID of the device.
+    short       ProductId;
+    /// Sensor (and display) serial number.
+    char        SerialNumber[24];
+    /// Sensor firmware major version number.
+    short       FirmwareMajor;
+    /// Sensor firmware minor version number.
+    short       FirmwareMinor;
+    // External tracking camera frustum dimensions (if present).
+    float       CameraFrustumHFovInRadians; ///< Horizontal field-of-view
+    float       CameraFrustumVFovInRadians; ///< Vertical field-of-view
+    float       CameraFrustumNearZInMeters; ///< Near clip distance
+    float       CameraFrustumFarZInMeters; ///< Far clip distance
+
+    /// Capability bits described by ovrHmdCaps.
+    unsigned int HmdCaps;
+    /// Capability bits described by ovrTrackingCaps.
+    unsigned int TrackingCaps;
+    /// Capability bits described by ovrDistortionCaps.
+    unsigned int DistortionCaps;
+
+    /// The recommended optical FOV for the HMD.
+    ovrFovPort  DefaultEyeFov[ovrEye_Count];
+    /// The maximum optical FOV for the HMD.
+    ovrFovPort  MaxEyeFov[ovrEye_Count];
+
+    /// Preferred eye rendering order for best performance.
+    /// Can help reduce latency on sideways-scanned screens.
+    ovrEyeType  EyeRenderOrder[ovrEye_Count];
+
+    /// Resolution of the full HMD screen (both eyes) in pixels.
+    ovrSizei    Resolution;
+    /// Location of the application window on the desktop (or 0,0).
+    ovrVector2i WindowsPos;
+
+    /// Display that the HMD should present on.
+    /// TBD: It may be good to remove this information relying on WindowPos instead.
+    /// Ultimately, we may need to come up with a more convenient alternative,
+    /// such as API-specific functions that return adapter, or something that will
+    /// work with our monitor driver.
+    /// Windows: (e.g. "\\\\.\\DISPLAY3", can be used in EnumDisplaySettings/CreateDC).
+    const char* DisplayDeviceName;
+    /// MacOS:
+    int         DisplayId;
+
+} ovrHmdDesc;
+
+/// Simple type ovrHmd is used in ovrHmd_* calls.
+typedef const ovrHmdDesc * ovrHmd;
+
+/// Bit flags describing the current status of sensor tracking.
+// The values must be the same as in enum StatusBits
+typedef enum ovrStatusBits_
+{
+    ovrStatus_OrientationTracked    = 0x0001,    ///< Orientation is currently tracked (connected and in use).
+    ovrStatus_PositionTracked       = 0x0002,    ///< Position is currently tracked (false if out of range).
+    ovrStatus_CameraPoseTracked     = 0x0004,    ///< Camera pose is currently tracked.
+    ovrStatus_PositionConnected     = 0x0020,    ///< Position tracking hardware is connected.
+    ovrStatus_HmdConnected          = 0x0080,    ///< HMD Display is available and connected.
+    ovrStatus_EnumSize              = 0x7fffffff ///< Force type int32_t.
+} ovrStatusBits;
+
+/// Specifies a reading we can query from the sensor.
+typedef struct ovrSensorData_
+{
+    ovrVector3f    Accelerometer;    /// Acceleration reading in m/s^2.
+    ovrVector3f    Gyro;             /// Rotation rate in rad/s.
+    ovrVector3f    Magnetometer;     /// Magnetic field in Gauss.
+    float          Temperature;      /// Temperature of the sensor in degrees Celsius.
+    float          TimeInSeconds;    /// Time when the reported IMU reading took place, in seconds.
+} ovrSensorData;
+
+
+/// Tracking state at a given absolute time (describes predicted HMD pose etc).
+/// Returned by ovrHmd_GetTrackingState.
+typedef struct ovrTrackingState_
+{
+    /// Predicted head pose (and derivatives) at the requested absolute time.
+    /// The look-ahead interval is equal to (HeadPose.TimeInSeconds - RawSensorData.TimeInSeconds).
+    ovrPoseStatef  HeadPose;
+
+    /// Current pose of the external camera (if present).
+    /// This pose includes camera tilt (roll and pitch). For a leveled coordinate
+    /// system use LeveledCameraPose.
+    ovrPosef       CameraPose;
+
+    /// Camera frame aligned with gravity.
+    /// This value includes position and yaw of the camera, but not roll and pitch.
+    /// It can be used as a reference point to render real-world objects in the correct location.
+    ovrPosef       LeveledCameraPose;
+
+    /// The most recent sensor data received from the HMD.
+    ovrSensorData  RawSensorData;
+
+    /// Tracking status described by ovrStatusBits.
+    unsigned int   StatusFlags;
+
+    /// Tag the vision processing results to a certain frame counter number.
+    uint32_t LastCameraFrameCounter;
+
+    /// Unused struct padding.
+    uint32_t Pad;
+} ovrTrackingState;
+
+
+
+/// Frame timing data reported by ovrHmd_BeginFrameTiming() or ovrHmd_BeginFrame().
+typedef struct OVR_ALIGNAS(8) ovrFrameTiming_
+{
+    /// The amount of time that has passed since the previous frame's
+    /// ThisFrameSeconds value (usable for movement scaling).
+    /// This will be clamped to no more than 0.1 seconds to prevent
+    /// excessive movement after pauses due to loading or initialization.
+    float DeltaSeconds;
+
+    /// Unused struct padding.
+    float Pad; 
+
+    /// It is generally expected that the following holds:
+    /// ThisFrameSeconds < TimewarpPointSeconds < NextFrameSeconds < 
+    /// EyeScanoutSeconds[EyeOrder[0]] <= ScanoutMidpointSeconds <= EyeScanoutSeconds[EyeOrder[1]].
+
+    /// Absolute time value when rendering of this frame began or is expected to
+    /// begin. Generally equal to NextFrameSeconds of the previous frame. Can be used
+    /// for animation timing.
+    double ThisFrameSeconds;
+
+    /// Absolute point when IMU expects to be sampled for this frame.
+    double TimewarpPointSeconds;
+
+    /// Absolute time when frame Present followed by GPU Flush will finish and the next frame begins.
+    double NextFrameSeconds;
+
+    /// Time when half of the screen will be scanned out. Can be passed as an absolute time
+    /// to ovrHmd_GetTrackingState() to get the predicted general orientation.
+    double ScanoutMidpointSeconds;
+
+    /// Timing points when each eye will be scanned out to display. Used when rendering each eye.
+    double EyeScanoutSeconds[2];
+} ovrFrameTiming;
+
+/// Rendering information for each eye. Computed by either ovrHmd_ConfigureRendering()
+/// or ovrHmd_GetRenderDesc() based on the specified FOV. Note that the rendering viewport
+/// is not included here as it can be specified separately and modified per frame through:
+///    (a) ovrHmd_GetRenderScaleAndOffset in the case of client rendered distortion,
+/// or (b) passing different values via ovrTexture in the case of SDK rendered distortion.
+typedef struct ovrEyeRenderDesc_
+{
+    ovrEyeType  Eye;                        ///< The eye index this instance corresponds to.
+    ovrFovPort  Fov;                        ///< The field of view.
+    ovrRecti    DistortedViewport;          ///< Distortion viewport.
+    ovrVector2f PixelsPerTanAngleAtCenter;  ///< How many display pixels will fit in tan(angle) = 1.
+    ovrVector3f HmdToEyeViewOffset;         ///< Translation to be applied to view matrix for each eye offset.
+} ovrEyeRenderDesc;
+
+/// Rendering information for positional TimeWarp.
+/// Contains the data necessary to properly calculate position info for timewarp matrices
+/// and also interpret depth info provided via the depth buffer to the timewarp shader
+typedef struct ovrPositionTimewarpDesc_
+{
+    /// The same offset value pair provided in ovrEyeRenderDesc.
+    ovrVector3f      HmdToEyeViewOffset[2];
+    /// The near clip distance used in the projection matrix.
+    float            NearClip;
+    /// The far clip distance used in the projection matrix
+    /// utilized when rendering the eye depth textures provided in ovrHmd_EndFrame
+    float            FarClip;
+} ovrPositionTimewarpDesc;
+
+//-----------------------------------------------------------------------------------
+// ***** Platform-independent Rendering Configuration
+
+/// These types are used to hide platform-specific details when passing
+/// render device, OS, and texture data to the API.
+///
+/// The benefit of having these wrappers versus platform-specific API functions is
+/// that they allow game glue code to be portable. A typical example is an
+/// engine that has multiple back ends, say GL and D3D. Portable code that calls
+/// these back ends may also use LibOVR. To do this, back ends can be modified
+/// to return portable types such as ovrTexture and ovrRenderAPIConfig.
+typedef enum ovrRenderAPIType_
+{
+    ovrRenderAPI_None,
+    ovrRenderAPI_OpenGL,
+    ovrRenderAPI_Android_GLES,  // May include extra native window pointers, etc.
+    ovrRenderAPI_D3D9,          // Deprecated: Not supported for SDK rendering
+    ovrRenderAPI_D3D10, // Deprecated: Not supported for SDK rendering
+    ovrRenderAPI_D3D11,
+    ovrRenderAPI_Count,
+    ovrRenderAPI_EnumSize = 0x7fffffff ///< Force type int32_t.
+} ovrRenderAPIType;
+
+/// Platform-independent part of rendering API-configuration data.
+/// It is a part of ovrRenderAPIConfig, passed to ovrHmd_Configure.
+typedef struct ovrRenderAPIConfigHeader_
+{
+    ovrRenderAPIType API;               ///< The graphics API in use.
+    ovrSizei         BackBufferSize;    ///< Previously named RTSize.
+    int              Multisample;       ///< The number of samples per pixel.
+} ovrRenderAPIConfigHeader;
+
+/// Contains platform-specific information for rendering.
+typedef struct ovrRenderAPIConfig_
+{
+    ovrRenderAPIConfigHeader Header;          ///< Platform-independent rendering information.
+    uintptr_t                PlatformData[8]; ///< Platform-specific rendering information.
+} ovrRenderAPIConfig;
+
+/// Platform-independent part of the eye texture descriptor.
+/// It is a part of ovrTexture, passed to ovrHmd_EndFrame.
+/// If RenderViewport is all zeros then the full texture will be used.
+typedef struct ovrTextureHeader_
+{
+    ovrRenderAPIType API;             ///< The graphics API in use.
+    ovrSizei         TextureSize;     ///< The size of the texture.
+    ovrRecti         RenderViewport;  ///< Pixel viewport in texture that holds eye image.
+} ovrTextureHeader;
+
+/// Contains platform-specific information about a texture.
+/// Specialized for different rendering APIs in:
+///     ovrGLTexture, ovrD3D11Texture
+typedef struct ovrTexture_
+{
+    ovrTextureHeader Header;          ///< Platform-independent data about the texture.
+    uintptr_t        PlatformData[8]; ///< Specialized in ovrGLTextureData, ovrD3D11TextureData etc.
+} ovrTexture;
+
+
+// -----------------------------------------------------------------------------------
+// ***** API Interfaces
+
+// Basic steps to use the API:
+//
+// Setup:
+//  * ovrInitialize()
+//  * ovrHMD hmd = ovrHmd_Create(0)
+//  * Use hmd members and ovrHmd_GetFovTextureSize() to determine graphics configuration.
+//  * Call ovrHmd_ConfigureTracking() to configure and initialize tracking.
+//  * Call ovrHmd_ConfigureRendering() to setup graphics for SDK rendering,
+//    which is the preferred approach.
+//    Please refer to "Client Distortion Rendering" below if you prefer to do that instead.
+//  * If the ovrHmdCap_ExtendDesktop flag is not set, then use ovrHmd_AttachToWindow to
+//    associate the relevant application window with the hmd.
+//  * Allocate render target textures as needed.
+//
+// Game Loop:
+//  * Call ovrHmd_BeginFrame() to get the current frame timing information.
+//  * Render each eye using ovrHmd_GetEyePoses() to get each eye pose.
+//  * Call ovrHmd_EndFrame() to render the distorted textures to the back buffer
+//    and present them on the hmd.
+//
+// Shutdown:
+//  * ovrHmd_Destroy(hmd)
+//  * ovr_Shutdown()
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/// ovr_InitializeRenderingShim initializes the rendering shim apart from everything
+/// else in LibOVR. This may be helpful if the application prefers to avoid
+/// creating any OVR resources (allocations, service connections, etc) at this point.
+/// ovr_InitializeRenderingShim does not bring up anything within LibOVR except the
+/// necessary hooks to enable the Direct-to-Rift functionality.
+///
+/// Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any
+/// Direct3D or OpenGL initialization is done by application (creation of devices, etc).
+/// ovr_Initialize() must still be called after to use the rest of LibOVR APIs.
+///
+/// Same as ovr_InitializeRenderingShim except it requests to support at least the
+/// given minor LibOVR library version.
+OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShimVersion(int requestedMinorVersion);
+
+OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShim();
+
+
+/// Library init/shutdown, must be called around all other OVR code.
+/// No other functions calls besides ovr_InitializeRenderingShim are allowed before
+/// ovr_Initialize succeeds or after ovr_Shutdown.
+/// Initializes all Oculus functionality.
+/// A second call to ovr_Initialize after successful second call returns ovrTrue.
+
+/// Flags for Initialize()
+typedef enum ovrInitFlags_
+{
+    // When a debug library is requested, a slower debugging version of the library will
+    // be run which can be used to help solve problems in the library and debug game code.
+    ovrInit_Debug          = 0x00000001,
+
+    // When ServerOptional is set, the ovr_Initialize() call not will block waiting for
+    // the server to respond.  If the server is not reachable it may still succeed.
+    ovrInit_ServerOptional = 0x00000002,
+
+    // When a version is requested, LibOVR runtime will respect the RequestedMinorVersion
+    // field and will verify that the RequestedMinorVersion is supported.
+    ovrInit_RequestVersion = 0x00000004,
+
+    // Forces debug features of LibOVR off explicitly, even if it is built in debug mode.
+    ovrInit_ForceNoDebug   = 0x00000008,
+
+} ovrInitFlags;
+
+/// Logging levels
+typedef enum ovrLogLevel_
+{
+    ovrLogLevel_Debug = 0,
+    ovrLogLevel_Info  = 1,
+    ovrLogLevel_Error = 2
+} ovrLogLevel;
+
+/// Signature for the logging callback.
+/// Level is one of the ovrLogLevel constants.
+typedef void (OVR_CDECL *ovrLogCallback)(int level, const char* message);
+
+/// Parameters for the ovr_Initialize() call.
+typedef struct
+{
+    /// Flags from ovrInitFlags to override default behavior.
+    /// Pass 0 for the defaults.
+    uint32_t       Flags;               ///< Combination of ovrInitFlags or 0
+
+    /// Request a specific minimum minor version of the LibOVR runtime.
+    /// Flags must include ovrInit_RequestVersion or this will be ignored.
+    uint32_t       RequestedMinorVersion;
+
+    /// Log callback function, which may be called at any time asynchronously from
+    /// multiple threads until ovr_Shutdown() completes.
+    /// Pass 0 for no log callback.
+    ovrLogCallback LogCallback;         ///< Function pointer or 0
+
+    /// Number of milliseconds to wait for a connection to the server.
+    /// Pass 0 for the default timeout.
+    uint32_t       ConnectionTimeoutMS; ///< Timeout in Milliseconds or 0
+} ovrInitParams;
+
+/// Initialize with extra parameters.
+/// Pass 0 to initialize with default parameters, suitable for released games.
+/// LibOVRRT shared library search order:
+///      1) Current working directory (often the same as the application directory).
+///      2) Module directory (usually the same as the application directory, but not if the module is a separate shared library).
+///      3) Application directory
+///      4) Development directory (only if OVR_ENABLE_DEVELOPER_SEARCH is enabled, which is off by default).
+///      5) Standard OS shared library search location(s) (OS-specific).
+OVR_PUBLIC_FUNCTION(ovrBool) ovr_Initialize(ovrInitParams const* params OVR_CPP(= 0));
+
+/// Shuts down all Oculus functionality.
+OVR_PUBLIC_FUNCTION(void) ovr_Shutdown();
+
+/// Returns version string representing libOVR version. Static, so
+/// string remains valid for app lifespan
+OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString();
+
+/// Detects or re-detects HMDs and reports the total number detected.
+/// Users can get information about each HMD by calling ovrHmd_Create with an index.
+/// Returns -1 when the service is unreachable.
+OVR_PUBLIC_FUNCTION(int) ovrHmd_Detect();
+
+/// Creates a handle to an HMD which doubles as a description structure.
+/// Index can [0 .. ovrHmd_Detect()-1]. Index mappings can cange after each ovrHmd_Detect call.
+/// If not null, then the returned handle must be freed with ovrHmd_Destroy.
+OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_Create(int index);
+OVR_PUBLIC_FUNCTION(void) ovrHmd_Destroy(ovrHmd hmd);
+
+/// Creates a 'fake' HMD used for debugging only. This is not tied to specific hardware,
+/// but may be used to debug some of the related rendering.
+OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_CreateDebug(ovrHmdType type);
+
+/// Returns last error for HMD state. Returns null for no error.
+/// String is valid until next call or GetLastError or HMD is destroyed.
+/// Pass null hmd to get global errors (during create etc).
+OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLastError(ovrHmd hmd);
+
+/// Platform specific function to specify the application window whose output will be 
+/// displayed on the HMD. Only used if the ovrHmdCap_ExtendDesktop flag is false.
+///   Windows: SwapChain associated with this window will be displayed on the HMD.
+///            Specify 'destMirrorRect' in window coordinates to indicate an area
+///            of the render target output that will be mirrored from 'sourceRenderTargetRect'.
+///            Null pointers mean "full size".
+/// @note Source and dest mirror rects are not yet implemented.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_AttachToWindow(ovrHmd hmd, void* window,
+                                         const ovrRecti* destMirrorRect,
+                                         const ovrRecti* sourceRenderTargetRect);
+
+/// Returns capability bits that are enabled at this time as described by ovrHmdCaps.
+/// Note that this value is different font ovrHmdDesc::HmdCaps, which describes what
+/// capabilities are available for that HMD.
+OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetEnabledCaps(ovrHmd hmd);
+
+/// Modifies capability bits described by ovrHmdCaps that can be modified,
+/// such as ovrHmdCap_LowPersistance.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int hmdCaps);
+
+//-------------------------------------------------------------------------------------
+// ***** Tracking Interface
+
+/// All tracking interface functions are thread-safe, allowing tracking state to be sampled
+/// from different threads.
+/// ConfigureTracking starts sensor sampling, enabling specified capabilities,
+///    described by ovrTrackingCaps.
+///  - supportedTrackingCaps specifies support that is requested. The function will succeed
+///   even if these caps are not available (i.e. sensor or camera is unplugged). Support
+///    will automatically be enabled if such device is plugged in later. Software should
+///    check ovrTrackingState.StatusFlags for real-time status.
+///  - requiredTrackingCaps specify sensor capabilities required at the time of the call.
+///    If they are not available, the function will fail. Pass 0 if only specifying
+///    supportedTrackingCaps.
+///  - Pass 0 for both supportedTrackingCaps and requiredTrackingCaps to disable tracking.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureTracking(ovrHmd hmd, unsigned int supportedTrackingCaps,
+                                                         unsigned int requiredTrackingCaps);
+
+/// Re-centers the sensor orientation.
+/// Normally this will recenter the (x,y,z) translational components and the yaw
+/// component of orientation.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_RecenterPose(ovrHmd hmd);
+
+/// Returns tracking state reading based on the specified absolute system time.
+/// Pass an absTime value of 0.0 to request the most recent sensor reading. In this case
+/// both PredictedPose and SamplePose will have the same value.
+/// ovrHmd_GetEyePoses relies on a valid ovrTrackingState.
+/// This may also be used for more refined timing of FrontBuffer rendering logic, etc.
+OVR_PUBLIC_FUNCTION(ovrTrackingState) ovrHmd_GetTrackingState(ovrHmd hmd, double absTime);
+
+
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** Graphics Setup
+
+/// Calculates the recommended viewport size for rendering a given eye within the HMD
+/// with a given FOV cone. Higher FOV will generally require larger textures to
+/// maintain quality.
+///  - pixelsPerDisplayPixel specifies the ratio of the number of render target pixels
+///    to display pixels at the center of distortion. 1.0 is the default value. Lower
+///    values can improve performance, higher values give improved quality.
+/// Apps packing multiple eye views together on the same textue should ensure there is
+/// roughly 8 pixels of padding between them to prevent texture filtering and chromatic
+/// aberration causing images to "leak" between the two eye views.
+OVR_PUBLIC_FUNCTION(ovrSizei) ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov,
+                                             float pixelsPerDisplayPixel);
+
+//-------------------------------------------------------------------------------------
+// *****  Rendering API Thread Safety
+
+//  All of rendering functions including the configure and frame functions
+// are *NOT thread safe*. It is ok to use ConfigureRendering on one thread and handle
+//  frames on another thread, but explicit synchronization must be done since
+//  functions that depend on configured state are not reentrant.
+//
+//  As an extra requirement, any of the following calls must be done on
+//  the render thread, which is the same thread that calls ovrHmd_BeginFrame
+//  or ovrHmd_BeginFrameTiming.
+//    - ovrHmd_EndFrame
+//    - ovrHmd_GetEyeTimewarpMatrices
+
+//-------------------------------------------------------------------------------------
+// *****  SDK Distortion Rendering Functions
+
+// These functions support rendering of distortion by the SDK through direct
+// access to the underlying rendering API, such as D3D or GL.
+// This is the recommended approach since it allows better support for future
+// Oculus hardware, and enables a range of low-level optimizations.
+
+/// Configures rendering and fills in computed render parameters.
+/// This function can be called multiple times to change rendering settings.
+/// eyeRenderDescOut is a pointer to an array of two ovrEyeRenderDesc structs
+/// that are used to return complete rendering information for each eye.
+///  - apiConfig provides D3D/OpenGL specific parameters. Pass null
+///    to shutdown rendering and release all resources.
+///  - distortionCaps describe desired distortion settings.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureRendering(ovrHmd hmd,
+                                              const ovrRenderAPIConfig* apiConfig,
+                                              unsigned int distortionCaps,
+                                              const ovrFovPort eyeFovIn[2],
+                                              ovrEyeRenderDesc eyeRenderDescOut[2] );
+
+
+/// Begins a frame, returning timing information.
+/// This should be called at the beginning of the game rendering loop (on the render thread).
+/// Pass 0 for the frame index if not using ovrHmd_GetFrameTiming.
+OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex);
+
+/// Ends a frame, submitting the rendered textures to the frame buffer.
+/// - RenderViewport within each eyeTexture can change per frame if necessary.
+/// - 'renderPose' will typically be the value returned from ovrHmd_GetEyePoses
+///   but can be different if a different head pose was used for rendering.
+/// - This may perform distortion and scaling internally, assuming is it not
+///   delegated to another thread.
+/// - Must be called on the same thread as BeginFrame.
+/// - If ovrDistortionCap_DepthProjectedTimeWarp is enabled, then app must provide eyeDepthTexture
+///   and posTimewarpDesc. Otherwise both can be NULL.
+/// - *** This Function will call Present/SwapBuffers and potentially wait for GPU Sync ***.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrame(ovrHmd hmd,
+                                    const ovrPosef renderPose[2],
+                                    const ovrTexture eyeTexture[2]);
+
+/// Returns predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses
+/// as an atomic operation. Caller need not worry about applying HmdToEyeViewOffset to the
+/// returned outEyePoses variables.
+/// - Thread-safe function where caller should increment frameIndex with every frame
+///   and pass the index where applicable to functions called on the  rendering thread.
+/// - hmdToEyeViewOffset[2] can be ovrEyeRenderDesc.HmdToEyeViewOffset returned from 
+///   ovrHmd_ConfigureRendering or ovrHmd_GetRenderDesc. For monoscopic rendering,
+///   use a vector that is the average of the two vectors for both eyes.
+/// - If frameIndex is not being utilized, pass in 0.
+/// - Assuming outEyePoses are used for rendering, it should be passed into ovrHmd_EndFrame.
+/// - If caller doesn't need outHmdTrackingState, it can be passed in as NULL
+OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyePoses(ovrHmd hmd, unsigned int frameIndex,
+                                             const ovrVector3f hmdToEyeViewOffset[2],
+                                             ovrPosef outEyePoses[2],
+                                             ovrTrackingState* outHmdTrackingState);
+
+/// Function was previously called ovrHmd_GetEyePose
+/// Returns the predicted head pose to use when rendering the specified eye.
+/// - Important: Caller must apply HmdToEyeViewOffset before using ovrPosef for rendering
+/// - Must be called between ovrHmd_BeginFrameTiming and ovrHmd_EndFrameTiming.
+/// - If returned pose is used for rendering the eye, it should be passed to ovrHmd_EndFrame.
+/// - Parameter 'eye' is used internally for prediction timing only
+OVR_PUBLIC_FUNCTION(ovrPosef) ovrHmd_GetHmdPosePerEye(ovrHmd hmd, ovrEyeType eye);
+
+
+//-------------------------------------------------------------------------------------
+// *****  Client Distortion Rendering Functions
+
+// These functions provide the distortion data and render timing support necessary to allow
+// client rendering of distortion. Client-side rendering involves the following steps:
+//
+//  1. Setup ovrEyeDesc based on the desired texture size and FOV.
+//     Call ovrHmd_GetRenderDesc to get the necessary rendering parameters for each eye.
+//
+//  2. Use ovrHmd_CreateDistortionMesh to generate the distortion mesh.
+//
+//  3. Use ovrHmd_BeginFrameTiming, ovrHmd_GetEyePoses, and ovrHmd_BeginFrameTiming in
+//     the rendering loop to obtain timing and predicted head orientation when rendering each eye.
+//      - When using timewarp, use ovr_WaitTillTime after the rendering and gpu flush, followed
+//        by ovrHmd_GetEyeTimewarpMatrices to obtain the timewarp matrices used
+//        by the distortion pixel shader. This will minimize latency.
+//
+
+/// Computes the distortion viewport, view adjust, and other rendering parameters for
+/// the specified eye. This can be used instead of ovrHmd_ConfigureRendering to do
+/// setup for client rendered distortion.
+OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovrHmd_GetRenderDesc(ovrHmd hmd,
+                                                 ovrEyeType eyeType, ovrFovPort fov);
+
+
+/// Describes a vertex used by the distortion mesh. This is intended to be converted into
+/// the engine-specific format. Some fields may be unused based on the ovrDistortionCaps
+/// flags selected. TexG and TexB, for example, are not used if chromatic correction is
+/// not requested.
+typedef struct ovrDistortionVertex_
+{
+    ovrVector2f ScreenPosNDC;    ///< [-1,+1],[-1,+1] over the entire framebuffer.
+    float       TimeWarpFactor;  ///< Lerp factor between time-warp matrices. Can be encoded in Pos.z.
+    float       VignetteFactor;  ///< Vignette fade factor. Can be encoded in Pos.w.
+    ovrVector2f TanEyeAnglesR;   ///< The tangents of the horizontal and vertical eye angles for the red channel.
+    ovrVector2f TanEyeAnglesG;   ///< The tangents of the horizontal and vertical eye angles for the green channel.
+    ovrVector2f TanEyeAnglesB;   ///< The tangents of the horizontal and vertical eye angles for the blue channel.
+} ovrDistortionVertex;
+
+/// Describes a full set of distortion mesh data, filled in by ovrHmd_CreateDistortionMesh.
+/// Contents of this data structure, if not null, should be freed by ovrHmd_DestroyDistortionMesh.
+typedef struct ovrDistortionMesh_
+{
+    ovrDistortionVertex* pVertexData; ///< The distortion vertices representing each point in the mesh.
+    unsigned short*      pIndexData;  ///< Indices for connecting the mesh vertices into polygons.
+    unsigned int         VertexCount; ///< The number of vertices in the mesh.
+    unsigned int         IndexCount;  ///< The number of indices in the mesh.
+} ovrDistortionMesh;
+
+/// Generate distortion mesh per eye.
+/// Distortion capabilities will depend on 'distortionCaps' flags. Users should 
+/// render using the appropriate shaders based on their settings.
+/// Distortion mesh data will be allocated and written into the ovrDistortionMesh data structure,
+/// which should be explicitly freed with ovrHmd_DestroyDistortionMesh.
+/// Users should call ovrHmd_GetRenderScaleAndOffset to get uvScale and Offset values for rendering.
+/// The function shouldn't fail unless theres is a configuration or memory error, in which case
+/// ovrDistortionMesh values will be set to null.
+/// This is the only function in the SDK reliant on eye relief, currently imported from profiles,
+/// or overridden here.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMesh(ovrHmd hmd,
+                                                 ovrEyeType eyeType, ovrFovPort fov,
+                                                 unsigned int distortionCaps,
+                                                 ovrDistortionMesh *meshData);
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMeshDebug(ovrHmd hmddesc,
+                                                     ovrEyeType eyeType, ovrFovPort fov,
+                                                     unsigned int distortionCaps,
+                                                     ovrDistortionMesh *meshData,
+                                                     float debugEyeReliefOverrideInMetres);
+
+
+/// Used to free the distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements
+/// are set to null and zeroes after the call.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData);
+
+/// Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or
+/// viewport changes after the fact. This can be used to adjust render size every frame if desired.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_GetRenderScaleAndOffset(ovrFovPort fov,
+                                                    ovrSizei textureSize, ovrRecti renderViewport,
+                                                    ovrVector2f uvScaleOffsetOut[2] );
+
+/// Thread-safe timing function for the main thread. Caller should increment frameIndex
+/// with every frame and pass the index where applicable to functions called on the
+/// rendering thread.
+OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex);
+
+/// Called at the beginning of the frame on the rendering thread.
+/// Pass frameIndex == 0 if ovrHmd_GetFrameTiming isn't being used. Otherwise,
+/// pass the same frame index as was used for GetFrameTiming on the main thread.
+OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex);
+
+/// Marks the end of client distortion rendered frame, tracking the necessary timing information.
+/// This function must be called immediately after Present/SwapBuffers + GPU sync. GPU sync is
+/// important before this call to reduce latency and ensure proper timing.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrameTiming(ovrHmd hmd);
+
+/// Initializes and resets frame time tracking. This is typically not necessary, but
+/// is helpful if game changes vsync state or video mode. vsync is assumed to be on if this
+/// isn't called. Resets internal frame index to the specified number.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex);
+
+/// Computes timewarp matrices used by distortion mesh shader, these are used to adjust
+/// for head orientation change since the last call to ovrHmd_GetEyePoses
+/// when rendering this eye. The ovrDistortionVertex::TimeWarpFactor is used to blend between the
+/// matrices, usually representing two different sides of the screen.
+/// Set 'calcPosition' to true when using depth based positional timewarp
+/// Must be called on the same thread as ovrHmd_BeginFrameTiming.
+OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose,
+                                                           ovrMatrix4f twmOut[2]);
+OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmddesc, ovrEyeType eye, ovrPosef renderPose,
+                                                             ovrQuatf playerTorsoMotion, ovrMatrix4f twmOut[2],
+                                                             double debugTimingOffsetInSeconds);
+
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** Stateless math setup functions
+
+/// Returns global, absolute high-resolution time in seconds. This is the same
+/// value as used in sensor messages.
+OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds();
+
+
+// -----------------------------------------------------------------------------------
+// ***** Latency Test interface
+
+/// Does latency test processing and returns 'TRUE' if specified rgb color should
+/// be used to clear the screen.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ProcessLatencyTest(ovrHmd hmd, unsigned char rgbColorOut[3]);
+
+/// Returns non-null string once with latency test result, when it is available.
+/// Buffer is valid until next call.
+OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLatencyTestResult(ovrHmd hmd);
+
+/// Returns the latency testing color in rgbColorOut to render when using a DK2
+/// Returns false if this feature is disabled or not-applicable (e.g. using a DK1)
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]);
+
+//-------------------------------------------------------------------------------------
+// ***** Health and Safety Warning Display interface
+//
+
+/// Used by ovrhmd_GetHSWDisplayState to report the current display state.
+typedef struct OVR_ALIGNAS(8) ovrHSWDisplayState_
+{
+    /// If true then the warning should be currently visible
+    /// and the following variables have meaning. Else there is no
+    /// warning being displayed for this application on the given HMD.
+    ovrBool Displayed;              ///< True if the Health&Safety Warning is currently displayed.
+    char    Pad[8-sizeof(ovrBool)]; ///< Unused struct padding.
+    double  StartTime;              ///< Absolute time when the warning was first displayed. See ovr_GetTimeInSeconds().
+    double  DismissibleTime;        ///< Earliest absolute time when the warning can be dismissed. May be a time in the past.
+} ovrHSWDisplayState;
+
+/// Returns the current state of the HSW display. If the application is doing the rendering of
+/// the HSW display then this function serves to indicate that the warning should be
+/// currently displayed. If the application is using SDK-based eye rendering then the SDK by
+/// default automatically handles the drawing of the HSW display. An application that uses
+/// application-based eye rendering should use this function to know when to start drawing the
+/// HSW display itself and can optionally use it in conjunction with ovrhmd_DismissHSWDisplay
+/// as described below.
+///
+/// Example usage for application-based rendering:
+///    bool HSWDisplayCurrentlyDisplayed = false; // global or class member variable
+///    ovrHSWDisplayState hswDisplayState;
+///    ovrhmd_GetHSWDisplayState(Hmd, &hswDisplayState);
+///
+///    if (hswDisplayState.Displayed && !HSWDisplayCurrentlyDisplayed) {
+///        <insert model into the scene that stays in front of the user>
+///        HSWDisplayCurrentlyDisplayed = true;
+///    }
+OVR_PUBLIC_FUNCTION(void) ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hasWarningState);
+
+/// Requests a dismissal of the HSWDisplay at the earliest possible time, which may be seconds
+/// into the future due to display longevity requirements.
+/// Returns true if the display is valid, in which case the request can always be honored.
+///
+/// Example usage :
+///    void ProcessEvent(int key) {
+///        if (key == escape)
+///            ovrhmd_DismissHSWDisplay(hmd);
+///    }
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_DismissHSWDisplay(ovrHmd hmd);
+
+/// Get boolean property. Returns first element if property is a boolean array.
+/// Returns defaultValue if property doesn't exist.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetBool(ovrHmd hmd, const char* propertyName, ovrBool defaultVal);
+
+/// Modify bool property; false if property doesn't exist or is readonly.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetBool(ovrHmd hmd, const char* propertyName, ovrBool value);
+
+/// Get integer property. Returns first element if property is an integer array.
+/// Returns defaultValue if property doesn't exist.
+OVR_PUBLIC_FUNCTION(int) ovrHmd_GetInt(ovrHmd hmd, const char* propertyName, int defaultVal);
+
+/// Modify integer property; false if property doesn't exist or is readonly.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetInt(ovrHmd hmd, const char* propertyName, int value);
+
+/// Get float property. Returns first element if property is a float array.
+/// Returns defaultValue if property doesn't exist.
+OVR_PUBLIC_FUNCTION(float) ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal);
+
+/// Modify float property; false if property doesn't exist or is readonly.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value);
+
+/// Get float[] property. Returns the number of elements filled in, 0 if property doesn't exist.
+/// Maximum of arraySize elements will be written.
+OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName,
+                                            float values[], unsigned int arraySize);
+
+/// Modify float[] property; false if property doesn't exist or is readonly.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloatArray(ovrHmd hmd, const char* propertyName,
+                                             float values[], unsigned int arraySize);
+
+/// Get string property. Returns first element if property is a string array.
+/// Returns defaultValue if property doesn't exist.
+/// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed.
+OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetString(ovrHmd hmd, const char* propertyName,
+                                        const char* defaultVal);
+
+/// Set string property
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetString(ovrHmd hmddesc, const char* propertyName,
+                                    const char* value);
+
+// -----------------------------------------------------------------------------------
+// ***** Logging
+
+/// Send a message string to the system tracing mechanism if enabled (currently Event Tracing for Windows)
+/// Level is one of the ovrLogLevel constants.
+/// returns the length of the message, or -1 if message is too large
+OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message);
+
+
+// DEPRECATED: These functions are being phased out in favor of a more comprehensive logging system.
+// These functions will return false and do nothing.
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StartPerfLog(ovrHmd hmd, const char* fileName, const char* userData1);
+OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StopPerfLog(ovrHmd hmd);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#if defined(_MSC_VER)
+    #pragma warning(pop)
+#endif
+
+
+
+// -----------------------------------------------------------------------------------
+// ***** Backward compatibility #includes
+//
+// This is at the bottom of this file because the following is dependent on the 
+// declarations above. 
+
+#if !defined(OVR_CAPI_NO_UTILS)
+	#include "OVR_CAPI_Util.h"
+#endif
+
+
+#endif // OVR_CAPI_h
diff --git a/LibOVR/Include/OVR_CAPI_GL.h b/LibOVR/Include/OVR_CAPI_GL.h
new file mode 100644
index 0000000..ef7cb45
--- /dev/null
+++ b/LibOVR/Include/OVR_CAPI_GL.h
@@ -0,0 +1,87 @@
+/************************************************************************************
+
+Filename    :   OVR_CAPI_GL.h
+Content     :   GL specific structures used by the CAPI interface.
+Created     :   November 7, 2013
+Authors     :   Lee Cooper
+
+Copyright   :   Copyright 2013 Oculus VR, LLC. All Rights reserved.
+
+Use of this software is subject to the terms of the Oculus Inc 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_CAPI_GL_h
+#define OVR_CAPI_GL_h
+
+/// @file OVR_CAPI_GL.h
+/// OpenGL rendering support.
+
+#include "OVR_CAPI.h"
+
+#if defined(OVR_OS_WIN32)
+    #include <Windows.h>
+    #include <gl/GL.h>
+#elif defined(__APPLE__)
+    #include <OpenGL/gl.h>
+#else
+    #include <GL/gl.h>
+#endif
+
+
+#if defined(_MSC_VER)
+    #pragma warning(push)
+    #pragma warning(disable: 4324) // structure was padded due to __declspec(align())
+#endif
+
+
+/// Used to configure slave GL rendering (i.e. for devices created externally).
+typedef struct ovrGLConfigData_s
+{
+    ovrRenderAPIConfigHeader Header;    ///< General device settings.
+
+#if defined(OVR_OS_WIN32)
+    HWND Window;                ///< The optional window handle. If unset, rendering will use the current window.
+    HDC  DC;                    ///< The optional device context. If unset, rendering will use a new context.
+#elif defined (OVR_OS_LINUX)
+    struct _XDisplay* Disp;     ///< Optional display. If unset, will issue glXGetCurrentDisplay when context is current.
+#endif
+} ovrGLConfigData;
+
+#if defined(__cplusplus)
+    static_assert(sizeof(ovrRenderAPIConfig) >= sizeof(ovrGLConfigData), "Insufficient size.");
+#endif
+
+/// Contains OpenGL-specific rendering information.
+union ovrGLConfig
+{
+    ovrRenderAPIConfig Config;  ///< General device settings.
+    ovrGLConfigData    OGL;     ///< OpenGL-specific settings.
+};
+
+/// Used to pass GL eye texture data to ovrHmd_EndFrame.
+typedef struct ovrGLTextureData_s
+{
+    ovrTextureHeader Header;    ///< General device settings.
+    GLuint           TexId;     ///< The OpenGL name for this texture.
+} ovrGLTextureData;
+
+#if defined(__cplusplus)
+    static_assert(sizeof(ovrTexture) >= sizeof(ovrGLTextureData), "Insufficient size.");
+#endif
+
+/// Contains OpenGL-specific texture information.
+typedef union ovrGLTexture_s
+{
+    ovrTexture       Texture;   ///< General device settings.
+    ovrGLTextureData OGL;       ///< OpenGL-specific settings.
+} ovrGLTexture;
+
+
+#if defined(_MSC_VER)
+    #pragma warning(pop)
+#endif
+
+
+#endif    // OVR_CAPI_GL_h
diff --git a/LibOVR/Include/OVR_CAPI_Keys.h b/LibOVR/Include/OVR_CAPI_Keys.h
new file mode 100644
index 0000000..13451e5
--- /dev/null
+++ b/LibOVR/Include/OVR_CAPI_Keys.h
@@ -0,0 +1,56 @@
+/************************************************************************************
+
+Filename    :   OVR_CAPI.h
+Content     :   Keys for CAPI calls
+Created     :   September 25, 2014
+Authors     :   
+
+Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.2
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+
+
+#define OVR_KEY_USER                        "User"              // string
+#define OVR_KEY_NAME                        "Name"              // string
+#define OVR_KEY_GENDER                      "Gender"            // string
+#define OVR_KEY_PLAYER_HEIGHT               "PlayerHeight"      // float
+#define OVR_KEY_EYE_HEIGHT                  "EyeHeight"         // float
+#define OVR_KEY_IPD                         "IPD"               // float
+#define OVR_KEY_NECK_TO_EYE_DISTANCE        "NeckEyeDistance"   // float[2]
+#define OVR_KEY_EYE_RELIEF_DIAL             "EyeReliefDial"     // int
+#define OVR_KEY_EYE_TO_NOSE_DISTANCE        "EyeToNoseDist"     // float[2]
+#define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE   "MaxEyeToPlateDist" // float[2]
+#define OVR_KEY_EYE_CUP                     "EyeCup"            // char[16]
+#define OVR_KEY_CUSTOM_EYE_RENDER           "CustomEyeRender"   // bool
+#define OVR_KEY_CAMERA_POSITION				"CenteredFromWorld" // double[7]
+
+// Default measurements empirically determined at Oculus to make us happy
+// The neck model numbers were derived as an average of the male and female averages from ANSUR-88
+// NECK_TO_EYE_HORIZONTAL = H22 - H43 = INFRAORBITALE_BACK_OF_HEAD - TRAGION_BACK_OF_HEAD
+// NECK_TO_EYE_VERTICAL = H21 - H15 = GONION_TOP_OF_HEAD - ECTOORBITALE_TOP_OF_HEAD
+// These were determined to be the best in a small user study, clearly beating out the previous default values
+#define OVR_DEFAULT_GENDER                  "Unknown"
+#define OVR_DEFAULT_PLAYER_HEIGHT           1.778f
+#define OVR_DEFAULT_EYE_HEIGHT              1.675f
+#define OVR_DEFAULT_IPD                     0.064f
+#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL  0.0805f
+#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL    0.075f
+#define OVR_DEFAULT_EYE_RELIEF_DIAL         3
+#define OVR_DEFAULT_CAMERA_POSITION			{0,0,0,1,0,0,0}
+
diff --git a/LibOVR/Include/OVR_CAPI_Util.h b/LibOVR/Include/OVR_CAPI_Util.h
new file mode 100644
index 0000000..8d2f43d
--- /dev/null
+++ b/LibOVR/Include/OVR_CAPI_Util.h
@@ -0,0 +1,79 @@
+/************************************************************************************
+
+PublicHeader:   OVR_CAPI_Util.h
+Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 
+you may not use the Oculus VR Rift SDK except in compliance with the License, 
+which is provided at the time of installation or download, or which 
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.2 
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK 
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#ifndef OVR_CAPI_Util_h
+#define OVR_CAPI_Util_h
+
+
+#include "OVR_CAPI.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Enumerates modifications to the projection matrix based on the application's needs
+typedef enum
+{
+    /// Use for generating a default projection matrix that is:
+    /// * Left-handed
+    /// * Near depth values stored in the depth buffer are smaller than far depth values
+    /// * Both near and far are explicitly defined
+    /// * With a clipping range that is (0 to w)
+    ovrProjection_None = 0x00,
+
+    /// Enable if using right-handed transformations in your application
+    ovrProjection_RightHanded = 0x01,
+
+    /// After projection transform is applied, far values stored in the depth buffer will be less than closer depth values
+    /// NOTE: Enable only if application is using a floating-point depth buffer for proper precision
+    ovrProjection_FarLessThanNear = 0x02,
+
+    /// When this flag is used, the zfar value pushed into ovrMatrix4f_Projection() will be ignored
+    /// NOTE: Enable only if ovrProjection_FarLessThanNear is also enabled where the far clipping plane will be pushed to infinity
+    ovrProjection_FarClipAtInfinity = 0x04,
+
+    /// Enable if application is rendering with OpenGL and expects a projection matrix with a clipping range of (-w to w)
+    /// Ignore this flag if your application already handles the conversion from D3D range (0 to w) to OpenGL
+    ovrProjection_ClipRangeOpenGL = 0x08,
+} ovrProjectionModifier;
+
+/// Used to generate projection from ovrEyeDesc::Fov.
+/// projectionFlags is a combination of the ovrProjectionModifier flags defined above
+OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags);
+
+/// Used for 2D rendering, Y is down
+/// orthoScale = 1.0f / pixelsPerTanAngleAtCenter
+/// orthoDistance = distance from camera, such as 0.8m
+OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale,
+                                                                float orthoDistance, float hmdToEyeViewOffsetX);
+
+/// Waits until the specified absolute time.
+OVR_PUBLIC_FUNCTION(double) ovr_WaitTillTime(double absTime);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#endif // Header include guard
diff --git a/LibOVR/Include/OVR_ErrorCode.h b/LibOVR/Include/OVR_ErrorCode.h
new file mode 100755
index 0000000..51c9d7d
--- /dev/null
+++ b/LibOVR/Include/OVR_ErrorCode.h
@@ -0,0 +1,66 @@
+/************************************************************************************
+
+PublicHeader:   OVR_ErrorCode.h
+Copyright   :   Copyright 2015 Oculus VR, LLC All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 
+you may not use the Oculus VR Rift SDK except in compliance with the License, 
+which is provided at the time of installation or download, or which 
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.2 
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK 
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#include "OVR_Version.h"
+
+
+
+
+#ifndef OVR_ErrorCode_h
+#define OVR_ErrorCode_h
+
+
+#include <stdint.h>
+
+
+/* API call results are represented at the highest level by a single ovrResult. */
+#ifndef OVR_RESULT_DEFINED
+#define OVR_RESULT_DEFINED
+typedef int32_t ovrResult;
+#endif
+
+
+/* Success is zero, while all error types are non-zero values. */
+#ifndef OVR_SUCCESS_DEFINED
+#define OVR_SUCCESS_DEFINED
+const ovrResult ovrSuccess = 0;
+#endif
+
+
+enum
+{
+    /* Initialization errors. */
+    ovrError_Initialize         = 1000,   /* Generic initialization error.                          */
+    ovrError_LibLoad            = 1001,   /* Couldn't load LibOVRRT.                                */
+    ovrError_LibVersion         = 1002,   /* LibOVRRT version incompatibility.                      */
+    ovrError_ServiceConnection  = 1003,   /* Couldn't connect to the OVR Service.                   */
+    ovrError_ServiceVersion     = 1004,   /* OVR Service version incompatibility.                   */
+    ovrError_IncompatibleOS     = 1005,   /* The operating system version is incompatible.          */
+    ovrError_DisplayInit        = 1006,   /* Unable to initialize the HMD display.                  */
+    ovrError_ServerStart        = 1007,   /* Unable to start the server. Is it already running?     */
+    ovrError_Reinitialization   = 1008    /* Attempting to re-initialize with a different version.  */
+};
+
+
+#endif /* Header include guard */
+
+
diff --git a/LibOVR/Include/OVR_Kernel.h b/LibOVR/Include/OVR_Kernel.h
index 1a8a903..72ab48a 100644
--- a/LibOVR/Include/OVR_Kernel.h
+++ b/LibOVR/Include/OVR_Kernel.h
@@ -23,20 +23,22 @@ limitations under the License.
 
 *************************************************************************************/
 
-#ifndef OVR_h
-#define OVR_h
-
-#include "../Src/Kernel/OVR_Types.h"
-#include "../Src/Kernel/OVR_Allocator.h"
-#include "../Src/Kernel/OVR_RefCount.h"
-#include "../Src/Kernel/OVR_Log.h"
-#include "../Src/Kernel/OVR_Math.h"
-#include "../Src/Kernel/OVR_System.h"
-#include "../Src/Kernel/OVR_Nullptr.h"
-#include "../Src/Kernel/OVR_String.h"
-#include "../Src/Kernel/OVR_Array.h"
-#include "../Src/Kernel/OVR_Timer.h"
-#include "../Src/Kernel/OVR_SysFile.h"
+/* This header file is deprecated and will be removed from a future version of this library */
+
+#ifndef OVR_Kernel_h
+#define OVR_Kernel_h
+
+#include "Kernel/OVR_Types.h"
+#include "Kernel/OVR_Allocator.h"
+#include "Kernel/OVR_RefCount.h"
+#include "Kernel/OVR_Log.h"
+#include "Kernel/OVR_System.h"
+#include "Kernel/OVR_Nullptr.h"
+#include "Kernel/OVR_String.h"
+#include "Kernel/OVR_Array.h"
+#include "Kernel/OVR_Timer.h"
+#include "Kernel/OVR_SysFile.h"
+#include "Extras/OVR_Math.h"
 
 #endif
 
diff --git a/LibOVR/Include/OVR_Version.h b/LibOVR/Include/OVR_Version.h
old mode 100644
new mode 100755
index 2ba20bc..c33fa3c
--- a/LibOVR/Include/OVR_Version.h
+++ b/LibOVR/Include/OVR_Version.h
@@ -22,14 +22,53 @@ limitations under the License.
 
 *************************************************************************************/
 
-#ifndef _OVR_VERSION_H
-#define _OVR_VERSION_H
+#ifndef OVR_Version_h
+#define OVR_Version_h
 
-#define OVR_MAJOR_VERSION 0
-#define OVR_MINOR_VERSION 4
-#define OVR_BUILD_VERSION 4
-#define OVR_VERSION_STRING "0.4.4"
 
-#define OVR_DK2_LATEST_FIRMWARE_MAJOR_VERSION 2
-#define OVR_DK2_LATEST_FIRMWARE_MINOR_VERSION 12
+
+
+
+#if !defined(OVR_STRINGIZE)
+    #define OVR_STRINGIZEIMPL(x) #x
+    #define OVR_STRINGIZE(x)     OVR_STRINGIZEIMPL(x)
 #endif
+
+// We are on major version 5 of the beta pre-release SDK. At some point we will
+// transition to product version 1 and reset the major version back to 1 (first 
+// product release, version 1.0).
+#define OVR_PRODUCT_VERSION 0
+#define OVR_MAJOR_VERSION   5
+#define OVR_MINOR_VERSION   0
+#define OVR_PATCH_VERSION   1
+#define OVR_BUILD_NUMBER    0
+
+// "Product.Major.Minor.Patch"
+#if !defined(OVR_VERSION_STRING)
+    #define OVR_VERSION_STRING  OVR_STRINGIZE(OVR_PRODUCT_VERSION.OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION)
+#endif
+
+// "Product.Major.Minor.Patch.Build"
+#if !defined(OVR_DETAILED_VERSION_STRING)
+    #define OVR_DETAILED_VERSION_STRING OVR_STRINGIZE(OVR_PRODUCT_VERSION.OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION.OVR_BUILD_NUMBER)
+#endif
+
+// This is the firmware version for the DK2 headset sensor board.
+//#if !defined(OVR_DK2_LATEST_FIRMWARE_MAJOR_VERSION)
+    #define OVR_DK2_LATEST_FIRMWARE_MAJOR_VERSION 2
+    #define OVR_DK2_LATEST_FIRMWARE_MINOR_VERSION 12
+//#endif
+
+// LibOVRRT description
+// This appears in the user-visible file properties. It is intended to convey publicly available additional information
+// such as feature builds.
+#if !defined(OVR_FILE_DESCRIPTION_STRING)
+    #if defined(_DEBUG)
+        #define OVR_FILE_DESCRIPTION_STRING "LibOVRRT (debug)"
+    #else
+        #define OVR_FILE_DESCRIPTION_STRING "LibOVRRT"
+    #endif
+#endif
+
+
+#endif // OVR_Version_h
-- 
cgit v1.2.3