diff options
| author | victorfisac <victorfisac@gmail.com> | 2017-07-15 16:05:00 +0200 |
|---|---|---|
| committer | victorfisac <victorfisac@gmail.com> | 2017-07-15 16:05:00 +0200 |
| commit | eb7b5e59bbaec0f556c4fde21cd0bf20819a8108 (patch) | |
| tree | 37d153ffc14c5ba799169b91b2e14a32b06a710a /src/external | |
| parent | f9277f216372179560c560427beccdd2e5c5d094 (diff) | |
| parent | 910b4b5d53d9a904070807de5e8a66edadd939e3 (diff) | |
| download | raylib-eb7b5e59bbaec0f556c4fde21cd0bf20819a8108.tar.gz raylib-eb7b5e59bbaec0f556c4fde21cd0bf20819a8108.zip | |
Merge branch 'master' of https://github.com/raysan5/raylib
Diffstat (limited to 'src/external')
39 files changed, 2461 insertions, 10771 deletions
diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h deleted file mode 100644 index 552f3b12..00000000 --- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h +++ /dev/null @@ -1,196 +0,0 @@ -/********************************************************************************//** -\file OVR_CAPI_Util.h -\brief This header provides LibOVR utility function declarations -\copyright Copyright 2015-2016 Oculus VR, LLC All Rights reserved. -*************************************************************************************/ - -#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. -/// -/// \see ovrMatrix4f_Projection -/// -typedef enum ovrProjectionModifier_ -{ - /// Use for generating a default projection matrix that is: - /// * Right-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 left-handed transformations in your application. - ovrProjection_LeftHanded = 0x01, - - /// After the projection transform is applied, far values stored in the depth buffer will be less than closer depth values. - /// NOTE: Enable only if the 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 the 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; - - -/// Return values for ovr_Detect. -/// -/// \see ovr_Detect -/// -typedef struct OVR_ALIGNAS(8) ovrDetectResult_ -{ - /// Is ovrFalse when the Oculus Service is not running. - /// This means that the Oculus Service is either uninstalled or stopped. - /// IsOculusHMDConnected will be ovrFalse in this case. - /// Is ovrTrue when the Oculus Service is running. - /// This means that the Oculus Service is installed and running. - /// IsOculusHMDConnected will reflect the state of the HMD. - ovrBool IsOculusServiceRunning; - - /// Is ovrFalse when an Oculus HMD is not detected. - /// If the Oculus Service is not running, this will be ovrFalse. - /// Is ovrTrue when an Oculus HMD is detected. - /// This implies that the Oculus Service is also installed and running. - ovrBool IsOculusHMDConnected; - - OVR_UNUSED_STRUCT_PAD(pad0, 6) ///< \internal struct padding - -} ovrDetectResult; - -OVR_STATIC_ASSERT(sizeof(ovrDetectResult) == 8, "ovrDetectResult size mismatch"); - - -/// Detects Oculus Runtime and Device Status -/// -/// Checks for Oculus Runtime and Oculus HMD device status without loading the LibOVRRT -/// shared library. This may be called before ovr_Initialize() to help decide whether or -/// not to initialize LibOVR. -/// -/// \param[in] timeoutMilliseconds Specifies a timeout to wait for HMD to be attached or 0 to poll. -/// -/// \return Returns an ovrDetectResult object indicating the result of detection. -/// -/// \see ovrDetectResult -/// -OVR_PUBLIC_FUNCTION(ovrDetectResult) ovr_Detect(int timeoutMilliseconds); - -// On the Windows platform, -#ifdef _WIN32 - /// This is the Windows Named Event name that is used to check for HMD connected state. - #define OVR_HMD_CONNECTED_EVENT_NAME L"OculusHMDConnected" -#endif // _WIN32 - - -/// Used to generate projection from ovrEyeDesc::Fov. -/// -/// \param[in] fov Specifies the ovrFovPort to use. -/// \param[in] znear Distance to near Z limit. -/// \param[in] zfar Distance to far Z limit. -/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags. -/// -/// \return Returns the calculated projection matrix. -/// -/// \see ovrProjectionModifier -/// -OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags); - - -/// Extracts the required data from the result of ovrMatrix4f_Projection. -/// -/// \param[in] projection Specifies the project matrix from which to extract ovrTimewarpProjectionDesc. -/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags. -/// \return Returns the extracted ovrTimewarpProjectionDesc. -/// \see ovrTimewarpProjectionDesc -/// -OVR_PUBLIC_FUNCTION(ovrTimewarpProjectionDesc) ovrTimewarpProjectionDesc_FromProjection(ovrMatrix4f projection, unsigned int projectionModFlags); - - -/// Generates an orthographic sub-projection. -/// -/// Used for 2D rendering, Y is down. -/// -/// \param[in] projection The perspective matrix that the orthographic matrix is derived from. -/// \param[in] orthoScale Equal to 1.0f / pixelsPerTanAngleAtCenter. -/// \param[in] orthoDistance Equal to the distance from the camera in meters, such as 0.8m. -/// \param[in] HmdToEyeOffsetX Specifies the offset of the eye from the center. -/// -/// \return Returns the calculated projection matrix. -/// -OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, - float orthoDistance, float HmdToEyeOffsetX); - - - -/// Computes offset eye poses based on headPose returned by ovrTrackingState. -/// -/// \param[in] headPose Indicates the HMD position and orientation to use for the calculation. -/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from -/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average -/// of the two vectors for both eyes. -/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to -/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose. -/// -OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose, - const ovrVector3f hmdToEyeOffset[2], - ovrPosef outEyePoses[2]); - - -/// Returns the predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses. -/// -/// This is a thread-safe function where caller should increment frameIndex with every frame -/// and pass that index where applicable to functions called on the rendering thread. -/// Assuming outEyePoses are used for rendering, it should be passed as a part of ovrLayerEyeFov. -/// The caller does not need to worry about applying HmdToEyeOffset to the returned outEyePoses variables. -/// -/// \param[in] hmd Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after -/// the last time ovr_SubmitFrame was called. -/// \param[in] latencyMarker Specifies that this call is the point in time where -/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer -/// provides "SensorSampleTimestamp", that will override the value stored here. -/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from -/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average -/// of the two vectors for both eyes. -/// \param[out] outEyePoses The predicted eye poses. -/// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which case it is ignored. -/// -OVR_PUBLIC_FUNCTION(void) ovr_GetEyePoses(ovrSession session, long long frameIndex, ovrBool latencyMarker, - const ovrVector3f hmdToEyeOffset[2], - ovrPosef outEyePoses[2], - double* outSensorSampleTime); - - - -/// Tracking poses provided by the SDK come in a right-handed coordinate system. If an application -/// is passing in ovrProjection_LeftHanded into ovrMatrix4f_Projection, then it should also use -/// this function to flip the HMD tracking poses to be left-handed. -/// -/// While this utility function is intended to convert a left-handed ovrPosef into a right-handed -/// coordinate system, it will also work for converting right-handed to left-handed since the -/// flip operation is the same for both cases. -/// -/// \param[in] inPose that is right-handed -/// \param[out] outPose that is requested to be left-handed (can be the same pointer to inPose) -/// -OVR_PUBLIC_FUNCTION(void) ovrPosef_FlipHandedness(const ovrPosef* inPose, ovrPosef* outPose); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // Header include guard diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h deleted file mode 100644 index 89293ff8..00000000 --- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h +++ /dev/null @@ -1,3804 +0,0 @@ -/********************************************************************************//** -\file OVR_Math.h -\brief Implementation of 3D primitives such as vectors, matrices. -\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved. -*************************************************************************************/ - -#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 Matrix2; -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<Matrix2<float> > { typedef ovrMatrix2f Type; }; -template<> struct CompatibleTypes<Matrix2<double> > { typedef ovrMatrix2d 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 4500*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 84*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 : acosf(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 : asinf(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); } - - Vector2 Clamped(T maxMag) const - { - T magSquared = LengthSq(); - if (magSquared <= Sqr(maxMag)) - return *this; - else - return *this * (maxMag / sqrt(magSquared)); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool IsEqual(const Vector2& b, T tolerance =Math<T>::Tolerance()) const - { - return (fabs(b.x-x) <= tolerance) && - (fabs(b.y-y) <= tolerance); - } - bool Compare(const Vector2& b, T tolerance = Math<T>::Tolerance()) const - { - return IsEqual(b, 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 != T(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 != T(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); - } - - Vector3 Clamped(T maxMag) const - { - T magSquared = LengthSq(); - if (magSquared <= Sqr(maxMag)) - return *this; - else - return *this * (maxMag / sqrt(magSquared)); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool IsEqual(const Vector3& b, T tolerance = Math<T>::Tolerance()) const - { - return (fabs(b.x-x) <= tolerance) && - (fabs(b.y-y) <= tolerance) && - (fabs(b.z-z) <= tolerance); - } - bool Compare(const Vector3& b, T tolerance = Math<T>::Tolerance()) const - { - return IsEqual(b, 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 (T)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 != T(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 != T(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 T w_=T(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); - } - - Vector4 Clamped(T maxMag) const - { - T magSquared = LengthSq(); - if (magSquared <= Sqr(maxMag)) - return *this; - else - return *this * (maxMag / sqrt(magSquared)); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool IsEqual(const Vector4& b, T tolerance = Math<T>::Tolerance()) const - { - return (fabs(b.x-x) <= tolerance) && - (fabs(b.y-y) <= tolerance) && - (fabs(b.z-z) <= tolerance) && - (fabs(b.w-w) <= tolerance); - } - bool Compare(const Vector4& b, T tolerance = Math<T>::Tolerance()) const - { - return IsEqual(b, 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, - w * b.w);} - - // 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 != T(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 != T(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. - Vector4 Lerp(const Vector4& b, T f) const { return *this*(T(1) - f) + b*f; } -}; - -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) - { - // NOTE: Converting a normalized Quat<float> to Quat<double> - // will generally result in an un-normalized quaternion. - // But we don't normalize here in case the quaternion - // being converted is not a normalized rotation quaternion. - } - - 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() == T(0)) - { - // Assert if the axis is zero, but the angle isn't - OVR_MATH_ASSERT(angle == T(0)); - x = y = z = T(0); w = T(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]; - } - - Quat operator-() { return Quat(-x, -y, -z, -w); } // unary minus - - static Quat Identity() { return Quat(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= T(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 - { - OVR_MATH_ASSERT(IsNormalized() || LengthSq() == 0); - 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 - { - OVR_MATH_ASSERT(IsNormalized()); - T s; - T sinHalfSquared = x*x + y*y + z*z; - if (sinHalfSquared < T(.0037)) // =~ sin(7/2 degrees)^2 - { - // Max rotation magnitude error is about .062% at 7 degrees rotation, or about .0043 degrees - s = T(2) * Sign(w); - } - 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 .064% at 5 degrees rotation, or .0032 degrees - if (normalize && angleSquared > 0) - { - // sin(angle/2)^2 ~= (angle/2)^2 and cos(angle/2)^2 ~= 1 - T invLen = T(1) / sqrt(angleSquared * T(0.25) + T(1)); // 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; - } - OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal - } - - // 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; - } - OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal - } - - 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 quats for equality within tolerance. Returns true if quats match withing tolerance. - bool IsEqual(const Quat& b, T tolerance = Math<T>::Tolerance()) const - { - return Abs(Dot(b)) >= T(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 T(2) * Acos(Abs(Dot(q))); - } - - // Angle of quaternion - T Angle() const - { - return T(2) * Acos(Abs(w)); - } - - // Normalize - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); } - - void Normalize() - { - T s = Length(); - if (s != T(0)) - s = T(1) / s; - *this *= s; - } - - Quat Normalized() const - { - T s = Length(); - if (s != T(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) - { - OVR_MATH_ASSERT(alignTo.IsNormalized() && v.IsNormalized()); - 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); - } - } - } - - // Decompose a quat into quat = swing * twist, where twist is a rotation about axis, - // and swing is a rotation perpendicular to axis. - Quat GetSwingTwist(const Vector3<T>& axis, Quat* twist) const - { - OVR_MATH_ASSERT(twist); - OVR_MATH_ASSERT(axis.IsNormalized()); - - // Create a normalized quaternion from projection of (x,y,z) onto axis - T d = axis.Dot(Vector3<T>(x, y, z)); - *twist = Quat(axis.x*d, axis.y*d, axis.z*d, w); - T len = twist->Length(); - if (len == 0) - twist->w = T(1); // identity - else - *twist /= len; // normalize - - return *this * twist->Inverted(); - } - - // Normalized linear interpolation of quaternions - // NOTE: This function is a bad approximation of Slerp() - // when the angle between the *this and b is large. - // Use FastSlerp() or Slerp() instead. - Quat Lerp(const Quat& b, T s) const - { - return (*this * (T(1) - s) + b * (Dot(b) < 0 ? -s : s)).Normalized(); - } - - // Spherical linear interpolation between rotations - Quat Slerp(const Quat& b, T s) const - { - Vector3<T> delta = (b * this->Inverted()).ToRotationVector(); - return (FromRotationVector(delta * s) * *this).Normalized(); // normalize so errors don't accumulate - } - - // Spherical linear interpolation: much faster for small rotations, accurate for large rotations. See FastTo/FromRotationVector - Quat FastSlerp(const Quat& b, T s) const - { - Vector3<T> delta = (b * this->Inverted()).FastToRotationVector(); - return (FastFromRotationVector(delta * s, false) * *this).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 - { - OVR_MATH_ASSERT(isnan(w) || IsNormalized()); - - // 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 - { - OVR_MATH_ASSERT(IsNormalized()); - - // 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) const - { - const Vector3<T>& omega = angularVelocity; - const Vector3<T>& omegaDot = angularAcceleration; - - Vector3<T> omega1 = (omega + omegaDot * dt); - Vector3<T> W = ( (omega + omega1) + omega.Cross(omega1) * (dt/T(6)) ) * (dt/T(2)); - - // 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<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(yaw, pitch, roll); - } - - // 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_ASSERT(IsNormalized()); - 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_ASSERT(IsNormalized()); - 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; - T singularityRadius = Math<T>::SingularityRadius(); - if (c2 < T(-1) + 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) - 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. -// -// This structure needs to be the same size and layout on 32-bit and 64-bit arch. -// Update OVR_PadCheck.cpp when updating this object. -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) - { - // Ensure normalized rotation if converting from float to double - if (sizeof(T) > sizeof(typename Math<T>::OtherFloatType)) - Rotation.Normalize(); - } - - 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); } - - // used to make things obviously broken if someone tries to use the value - void SetInvalid() { Rotation = Quat<T>(NAN, NAN, NAN, NAN); Translation = Vector3<T>(NAN, NAN, NAN); } - - bool IsEqual(const Pose&b, T tolerance = Math<T>::Tolerance()) const - { - 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]); - // Ensure rotation is normalized, in case it was originally a float, stored in a .json file, etc. - return Pose<T>(rotation.Normalized(), 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)); - } - - // Interpolation between two poses: translation is interpolated with Lerp(), - // and rotations are interpolated with Slerp(). - Pose Lerp(const Pose& b, T s) - { - return Pose(Rotation.Slerp(b.Rotation, s), Translation.Lerp(b.Translation, s)); - } - - // Similar to Lerp above, except faster in case of small rotation differences. See Quat<T>::FastSlerp. - Pose FastLerp(const Pose& b, T s) - { - return Pose(Rotation.FastSlerp(b.Rotation, s), Translation.Lerp(b.Translation, s)); - } - - 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) const - { - return Pose(Rotation.TimeIntegrate(angularVelocity, angularAcceleration, dt), - Translation + linearVelocity*dt + linearAcceleration*dt*dt * T(0.5)); - } -}; - -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] = T(1); - M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0); - M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0); - M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(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] = T(0); - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = T(0); - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = T(0); - M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(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] = T(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] = T(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] = T(0); - M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1); - } - - explicit Matrix4(const Quat<T>& q) - { - OVR_MATH_ASSERT(q.IsNormalized()); - 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] = T(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] = T(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] = T(0); - M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(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] = T(1); - M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0); - M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0); - M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0); - } - - void SetXBasis(const Vector3<T>& v) - { - M[0][0] = v.x; - M[1][0] = v.y; - M[2][0] = v.z; - } - Vector3<T> GetXBasis() const - { - return Vector3<T>(M[0][0], M[1][0], M[2][0]); - } - - void SetYBasis(const Vector3<T> & v) - { - M[0][1] = v.x; - M[1][1] = v.y; - M[2][1] = v.z; - } - Vector3<T> GetYBasis() const - { - return Vector3<T>(M[0][1], M[1][1], M[2][1]); - } - - void SetZBasis(const Vector3<T> & v) - { - M[0][2] = v.x; - M[1][2] = v.y; - M[2][2] = v.z; - } - Vector3<T> GetZBasis() const - { - return Vector3<T>(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 = T(1) / (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() * (T(1)/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] = T(0); - // 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 = T(-1); - if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation - psign = T(1); - - T pm = psign*M[A1][A3]; - T singularityRadius = Math<T>::SingularityRadius(); - if (pm < T(-1) + singularityRadius) - { // South pole singularity - *a = T(0); - *b = -S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); - } - else if (pm > T(1) - singularityRadius) - { // North pole singularity - *a = T(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] ); - } - } - - // 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 = T(-1); - if ((A1 + 1) % 3 == A2) // Determine whether even permutation - psign = T(1); - - T c2 = M[A1][A1]; - T singularityRadius = Math<T>::SingularityRadius(); - if (c2 < T(-1) + singularityRadius) - { // South pole singularity - *a = T(0); - *b = S*D*((T)MATH_DOUBLE_PI); - *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); - } - else if (c2 > T(1) - singularityRadius) - { // North pole singularity - *a = T(0); - *b = T(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]); - } - } - - // 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 = T(0)) - { - 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); - default: - return Matrix4(); - } - } - - - // 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 = (T)sin(angle); - T cosa = (T)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 * T(0.5)); - - m.M[0][0] = T(1) / (aspect * tanHalfFov); - m.M[1][1] = T(1) / tanHalfFov; - m.M[2][2] = zfar / (znear - zfar); - m.M[3][2] = T(-1); - m.M[2][3] = (zfar * znear) / (znear - zfar); - m.M[3][3] = T(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 * T(0.5)); - - m.M[0][0] = T(1) / (aspect * tanHalfFov); - m.M[1][1] = T(1) / tanHalfFov; - //m.M[2][2] = zfar / (znear - zfar); - m.M[2][2] = zfar / (zfar - znear); - m.M[3][2] = T(-1); - m.M[2][3] = (zfar * znear) / (znear - zfar); - m.M[3][3] = T(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] = T(2.0)/w; - m.M[1][1] = T(-2.0)/h; - m.M[0][3] = T(-1.0); - m.M[1][3] = T(1.0); - m.M[2][2] = T(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] = T(1); - M[0][1] = M[1][0] = M[2][0] = T(0); - M[0][2] = M[1][2] = M[2][1] = T(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) - { - OVR_MATH_ASSERT(q.IsNormalized()); - 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] = T(0); - } - - Matrix3(T m11, T m22, T m33) - { - M[0][0] = m11; M[0][1] = T(0); M[0][2] = T(0); - M[1][0] = T(0); M[1][1] = m22; M[1][2] = T(0); - M[2][0] = T(0); M[2][1] = T(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] = T(1); - M[0][1] = M[1][0] = M[2][0] = T(0); - M[0][2] = M[1][2] = M[2][1] = T(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 T rcpZ = T(1) / (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); - } - - // Vector cross product as a premultiply matrix: - // L.Cross(R) = LeftCrossAsMatrix(L) * R - static Matrix3 LeftCrossAsMatrix(const Vector3<T>& L) - { - return Matrix3( - T(0), -L.z, +L.y, - +L.z, T(0), -L.x, - -L.y, +L.x, T(0)); - } - - // Vector cross product as a premultiply matrix: - // L.Cross(R) = RightCrossAsMatrix(R) * L - static Matrix3 RightCrossAsMatrix(const Vector3<T>& R) - { - return Matrix3( - T(0), +R.z, -R.y, - -R.z, T(0), +R.x, - +R.y, -R.x, T(0)); - } - - // Angle in radians of a rotation matrix - // Uses identity trace(a) = 2*cos(theta) + 1 - T Angle() const - { - return Acos((Trace() - T(1)) * T(0.5)); - } - - // Angle in radians between two rotation matrices - T Angle(const Matrix3& b) const - { - // Compute trace of (this->Transposed() * b) - // This works out to sum of products of elements. - T trace = T(0); - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 3; j++) - { - trace += M[i][j] * b.M[i][j]; - } - } - return Acos((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] = T(1); - M[0][1] = M[1][0] = T(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] = T(0); - } - - Matrix2(T m11, T m22) - { - M[0][0] = m11; M[0][1] = T(0); - M[1][0] = T(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] = T(1); - M[0][1] = M[1][0] = T(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; - return *this; - } - - 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] = T(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/src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h deleted file mode 100644 index b4bc3bc7..00000000 --- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************ - -Filename : OVR_StereoProjection.h -Content : Stereo projection functions -Created : November 30, 2013 -Authors : Tom Fosyth - -Copyright : Copyright 2014-2016 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.3 (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.3 - -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_StereoProjection_h -#define OVR_StereoProjection_h - - -#include "Extras/OVR_Math.h" - - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// ***** Stereo Enumerations - -// StereoEye specifies which eye we are rendering for; it is used to -// retrieve StereoEyeParams. -enum StereoEye -{ - StereoEye_Left, - StereoEye_Right, - StereoEye_Center -}; - - - -//----------------------------------------------------------------------------------- -// ***** Propjection functions - -Matrix4f CreateProjection ( bool rightHanded, bool isOpenGL, FovPort fov, StereoEye eye, - float zNear = 0.01f, float zFar = 10000.0f, - bool flipZ = false, bool farAtInfinity = false); - -Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType, - float tanHalfFovX, float tanHalfFovY, - float unitsX, float unitsY, float distanceFromCamera, - float interpupillaryDistance, Matrix4f const &projection, - float zNear = 0.0f, float zFar = 0.0f, - bool flipZ = false, bool farAtInfinity = false); - -ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov ); - - -} //namespace OVR - -#endif // OVR_StereoProjection_h diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h deleted file mode 100644 index eaabcf59..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h +++ /dev/null @@ -1,2234 +0,0 @@ -/********************************************************************************//** -\file OVR_CAPI.h -\brief C Interface to the Oculus PC SDK tracking and rendering library. -\copyright Copyright 2014 Oculus VR, LLC All Rights reserved. -************************************************************************************/ - -#ifndef OVR_CAPI_h // We don't use version numbers within this name, as all versioned variations of this file are currently mutually exclusive. -#define OVR_CAPI_h ///< Header include guard - - -#include "OVR_CAPI_Keys.h" -#include "OVR_Version.h" -#include "OVR_ErrorCode.h" - - -#include <stdint.h> - -#if defined(_MSC_VER) - #pragma warning(push) - #pragma warning(disable: 4324) // structure was padded due to __declspec(align()) - #pragma warning(disable: 4359) // The alignment specified for a type is less than the alignment of the type of one of its data members -#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_STATIC_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(rval) rval OVR_CDECL - #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(rval) __attribute__((visibility("hidden"))) rval OVR_CDECL - #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) - #else - #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL - #define OVR_PUBLIC_CLASS - #endif - #define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL - #define OVR_PRIVATE_CLASS - #else // OVR_STATIC_BUILD - #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL - #define OVR_PUBLIC_CLASS - #define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL - #define OVR_PRIVATE_CLASS - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_EXPORT -// -/// Provided for backward compatibility with older versions of this library. -// -#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) - #if 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)) - #elif defined(__CC_ARM) - #define OVR_ALIGNAS(n) __align(n) - #else - #error Need to define OVR_ALIGNAS - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_HAS_FEATURE -// -// This is a portable way to use compile-time feature identification available -// with some compilers in a clean way. Direct usage of __has_feature in preprocessing -// statements of non-supporting compilers results in a preprocessing error. -// -// Example usage: -// #if OVR_CC_HAS_FEATURE(is_pod) -// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it. -// memcpy(&destObject, &srcObject, sizeof(object)); -// #endif -// -#if !defined(OVR_CC_HAS_FEATURE) - #if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 - #define OVR_CC_HAS_FEATURE(x) __has_feature(x) - #else - #define OVR_CC_HAS_FEATURE(x) 0 - #endif -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_STATIC_ASSERT -// -// Portable support for C++11 static_assert(). -// Acts as if the following were declared: -// void OVR_STATIC_ASSERT(bool const_expression, const char* msg); -// -// Example usage: -// OVR_STATIC_ASSERT(sizeof(int32_t) == 4, "int32_t expected to be 4 bytes."); - -#if !defined(OVR_STATIC_ASSERT) - #if !(defined(__cplusplus) && (__cplusplus >= 201103L)) /* Other */ && \ - !(defined(__GXX_EXPERIMENTAL_CXX0X__)) /* GCC */ && \ - !(defined(__clang__) && defined(__cplusplus) && OVR_CC_HAS_FEATURE(cxx_static_assert)) /* clang */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) /* VS2010+ */ - - #if !defined(OVR_SA_UNUSED) - #if defined(OVR_CC_GNU) || defined(OVR_CC_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 - - #if defined(__COUNTER__) - #define OVR_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __COUNTER__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED - #else - #define OVR_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED - #endif - - #else - #define OVR_STATIC_ASSERT(expression, msg) static_assert(expression, msg) - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** Padding -// -/// Defines explicitly unused space for a struct. -/// When used correcly, usage of this macro should not change the size of the struct. -/// Compile-time and runtime behavior with and without this defined should be identical. -/// -#if !defined(OVR_UNUSED_STRUCT_PAD) - #define OVR_UNUSED_STRUCT_PAD(padName, size) char padName[size]; -#endif - - -//----------------------------------------------------------------------------------- -// ***** Word Size -// -/// Specifies the size of a pointer on the given platform. -/// -#if !defined(OVR_PTR_SIZE) - #if defined(__WORDSIZE) - #define OVR_PTR_SIZE ((__WORDSIZE) / 8) - #elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64) - #define OVR_PTR_SIZE 8 - #elif defined(__CC_ARM) && (__sizeof_ptr == 8) - #define OVR_PTR_SIZE 8 - #else - #define OVR_PTR_SIZE 4 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_ON32 / OVR_ON64 -// -#if OVR_PTR_SIZE == 8 - #define OVR_ON32(x) - #define OVR_ON64(x) x -#else - #define OVR_ON32(x) x - #define OVR_ON64(x) -#endif - - -//----------------------------------------------------------------------------------- -// ***** ovrBool - -typedef char ovrBool; ///< Boolean type -#define ovrFalse 0 ///< ovrBool value of false. -#define ovrTrue 1 ///< ovrBool value of true. - - -//----------------------------------------------------------------------------------- -// ***** Simple Math Structures - -/// A RGBA color with normalized float components. -typedef struct OVR_ALIGNAS(4) ovrColorf_ -{ - float r, g, b, a; -} ovrColorf; - -/// A 2D vector with integer components. -typedef struct OVR_ALIGNAS(4) ovrVector2i_ -{ - int x, y; -} ovrVector2i; - -/// A 2D size with integer components. -typedef struct OVR_ALIGNAS(4) ovrSizei_ -{ - int w, h; -} ovrSizei; - -/// A 2D rectangle with a position and size. -/// All components are integers. -typedef struct OVR_ALIGNAS(4) ovrRecti_ -{ - ovrVector2i Pos; - ovrSizei Size; -} ovrRecti; - -/// A quaternion rotation. -typedef struct OVR_ALIGNAS(4) ovrQuatf_ -{ - float x, y, z, w; -} ovrQuatf; - -/// A 2D vector with float components. -typedef struct OVR_ALIGNAS(4) ovrVector2f_ -{ - float x, y; -} ovrVector2f; - -/// A 3D vector with float components. -typedef struct OVR_ALIGNAS(4) ovrVector3f_ -{ - float x, y, z; -} ovrVector3f; - -/// A 4x4 matrix with float elements. -typedef struct OVR_ALIGNAS(4) ovrMatrix4f_ -{ - float M[4][4]; -} ovrMatrix4f; - - -/// Position and orientation together. -typedef struct OVR_ALIGNAS(4) ovrPosef_ -{ - ovrQuatf Orientation; - ovrVector3f Position; -} ovrPosef; - -/// A full pose (rigid body) configuration with first and second derivatives. -/// -/// Body refers to any object for which ovrPoseStatef is providing data. -/// It can be the HMD, Touch controller, sensor or something else. The context -/// depends on the usage of the struct. -typedef struct OVR_ALIGNAS(8) ovrPoseStatef_ -{ - ovrPosef ThePose; ///< Position and orientation. - ovrVector3f AngularVelocity; ///< Angular velocity in radians per second. - ovrVector3f LinearVelocity; ///< Velocity in meters per second. - ovrVector3f AngularAcceleration; ///< Angular acceleration in radians per second per second. - ovrVector3f LinearAcceleration; ///< Acceleration in meters per second per second. - OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad. - double TimeInSeconds; ///< Absolute time that this pose refers to. \see ovr_GetTimeInSeconds -} ovrPoseStatef; - -/// Describes the up, down, left, and right angles of the field of view. -/// -/// Field Of View (FOV) tangent of the angle units. -/// \note For a standard 90 degree vertical FOV, we would -/// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. -typedef struct OVR_ALIGNAS(4) 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. -/// -/// The currently released developer kits are ovrHmd_DK1 and ovrHmd_DK2. The other enumerations are for internal use only. -typedef enum ovrHmdType_ -{ - ovrHmd_None = 0, - ovrHmd_DK1 = 3, - ovrHmd_DKHD = 4, - ovrHmd_DK2 = 6, - ovrHmd_CB = 8, - ovrHmd_Other = 9, - ovrHmd_E3_2015 = 10, - ovrHmd_ES06 = 11, - ovrHmd_ES09 = 12, - ovrHmd_ES11 = 13, - ovrHmd_CV1 = 14, - - ovrHmd_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrHmdType; - - -/// HMD capability bits reported by device. -/// -typedef enum ovrHmdCaps_ -{ - // Read-only flags - ovrHmdCap_DebugDevice = 0x0010, ///< <B>(read only)</B> Specifies that the HMD is a virtual debug device. - - - ovrHmdCap_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrHmdCaps; - - -/// Tracking capability bits reported by the device. -/// Used with ovr_GetTrackingCaps. -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. - ovrTrackingCap_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrTrackingCaps; - - -/// Specifies which eye is being used for rendering. -/// This type explicitly does not include a third "NoStereo" monoscopic option, as such is -/// not required for an HMD-centered API. -typedef enum ovrEyeType_ -{ - ovrEye_Left = 0, ///< The left eye, from the viewer's perspective. - ovrEye_Right = 1, ///< The right eye, from the viewer's perspective. - ovrEye_Count = 2, ///< \internal Count of enumerated elements. - ovrEye_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrEyeType; - -/// Specifies the coordinate system ovrTrackingState returns tracking poses in. -/// Used with ovr_SetTrackingOriginType() -typedef enum ovrTrackingOrigin_ -{ - /// \brief Tracking system origin reported at eye (HMD) height - /// \details Prefer using this origin when your application requires - /// matching user's current physical head pose to a virtual head pose - /// without any regards to a the height of the floor. Cockpit-based, - /// or 3rd-person experiences are ideal candidates. - /// When used, all poses in ovrTrackingState are reported as an offset - /// transform from the profile calibrated or recentered HMD pose. - /// It is recommended that apps using this origin type call ovr_RecenterTrackingOrigin - /// prior to starting the VR experience, but notify the user before doing so - /// to make sure the user is in a comfortable pose, facing a comfortable - /// direction. - ovrTrackingOrigin_EyeLevel = 0, - /// \brief Tracking system origin reported at floor height - /// \details Prefer using this origin when your application requires the - /// physical floor height to match the virtual floor height, such as - /// standing experiences. - /// When used, all poses in ovrTrackingState are reported as an offset - /// transform from the profile calibrated floor pose. Calling ovr_RecenterTrackingOrigin - /// will recenter the X & Z axes as well as yaw, but the Y-axis (i.e. height) will continue - /// to be reported using the floor height as the origin for all poses. - ovrTrackingOrigin_FloorLevel = 1, - ovrTrackingOrigin_Count = 2, ///< \internal Count of enumerated elements. - ovrTrackingOrigin_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrTrackingOrigin; - -/// Identifies a graphics device in a platform-specific way. -/// For Windows this is a LUID type. -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrGraphicsLuid_ -{ - // Public definition reserves space for graphics API-specific implementation - char Reserved[8]; -} ovrGraphicsLuid; - - -/// This is a complete descriptor of the HMD. -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrHmdDesc_ -{ - ovrHmdType Type; ///< The type of HMD. - OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad0, 4)) ///< \internal struct paddding. - char ProductName[64]; ///< UTF8-encoded product identification string (e.g. "Oculus Rift DK1"). - char Manufacturer[64]; ///< UTF8-encoded HMD manufacturer identification string. - short VendorId; ///< HID (USB) vendor identifier of the device. - short ProductId; ///< HID (USB) product identifier of the device. - char SerialNumber[24]; ///< HMD serial number. - short FirmwareMajor; ///< HMD firmware major version. - short FirmwareMinor; ///< HMD firmware minor version. - unsigned int AvailableHmdCaps; ///< Capability bits described by ovrHmdCaps which the HMD currently supports. - unsigned int DefaultHmdCaps; ///< Capability bits described by ovrHmdCaps which are default for the current Hmd. - unsigned int AvailableTrackingCaps; ///< Capability bits described by ovrTrackingCaps which the system currently supports. - unsigned int DefaultTrackingCaps; ///< Capability bits described by ovrTrackingCaps which are default for the current system. - ovrFovPort DefaultEyeFov[ovrEye_Count]; ///< Defines the recommended FOVs for the HMD. - ovrFovPort MaxEyeFov[ovrEye_Count]; ///< Defines the maximum FOVs for the HMD. - ovrSizei Resolution; ///< Resolution of the full HMD screen (both eyes) in pixels. - float DisplayRefreshRate; ///< Nominal refresh rate of the display in cycles per second at the time of HMD creation. - OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad1, 4)) ///< \internal struct paddding. -} ovrHmdDesc; - - -/// Used as an opaque pointer to an OVR session. -typedef struct ovrHmdStruct* ovrSession; - - - -/// Bit flags describing the current status of sensor tracking. -/// The values must be the same as in enum StatusBits -/// -/// \see ovrTrackingState -/// -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_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrStatusBits; - - -/// Specifies the description of a single sensor. -/// -/// \see ovr_GetTrackerDesc -/// -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTrackerDesc_ -{ - float FrustumHFovInRadians; ///< Sensor frustum horizontal field-of-view (if present). - float FrustumVFovInRadians; ///< Sensor frustum vertical field-of-view (if present). - float FrustumNearZInMeters; ///< Sensor frustum near Z (if present). - float FrustumFarZInMeters; ///< Sensor frustum far Z (if present). -} ovrTrackerDesc; - - -/// Specifies sensor flags. -/// -/// /see ovrTrackerPose -/// -typedef enum ovrTrackerFlags_ -{ - ovrTracker_Connected = 0x0020, ///< The sensor is present, else the sensor is absent or offline. - ovrTracker_PoseTracked = 0x0004 ///< The sensor has a valid pose, else the pose is unavailable. This will only be set if ovrTracker_Connected is set. -} ovrTrackerFlags; - - -/// Specifies the pose for a single sensor. -/// -typedef struct OVR_ALIGNAS(8) _ovrTrackerPose -{ - unsigned int TrackerFlags; ///< ovrTrackerFlags. - ovrPosef Pose; ///< The sensor's pose. This pose includes sensor tilt (roll and pitch). For a leveled coordinate system use LeveledPose. - ovrPosef LeveledPose; ///< The sensor's leveled pose, aligned with gravity. This value includes position and yaw of the sensor, but not roll and pitch. It can be used as a reference point to render real-world objects in the correct location. - OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad. -} ovrTrackerPose; - - -/// Tracking state at a given absolute time (describes predicted HMD pose, etc.). -/// Returned by ovr_GetTrackingState. -/// -/// \see ovr_GetTrackingState -/// -typedef struct OVR_ALIGNAS(8) ovrTrackingState_ -{ - /// Predicted head pose (and derivatives) at the requested absolute time. - ovrPoseStatef HeadPose; - - /// HeadPose tracking status described by ovrStatusBits. - unsigned int StatusFlags; - - /// The most recent calculated pose for each hand when hand controller tracking is present. - /// HandPoses[ovrHand_Left] refers to the left hand and HandPoses[ovrHand_Right] to the right hand. - /// These values can be combined with ovrInputState for complete hand controller information. - ovrPoseStatef HandPoses[2]; - - /// HandPoses status flags described by ovrStatusBits. - /// Only ovrStatus_OrientationTracked and ovrStatus_PositionTracked are reported. - unsigned int HandStatusFlags[2]; - - /// The pose of the origin captured during calibration. - /// Like all other poses here, this is expressed in the space set by ovr_RecenterTrackingOrigin, - /// and so will change every time that is called. This pose can be used to calculate - /// where the calibrated origin lands in the new recentered space. - /// If an application never calls ovr_RecenterTrackingOrigin, expect this value to be the identity - /// pose and as such will point respective origin based on ovrTrackingOrigin requested when - /// calling ovr_GetTrackingState. - ovrPosef CalibratedOrigin; - -} ovrTrackingState; - - -/// Rendering information for each eye. Computed by ovr_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 by -/// passing different Viewport values in the layer structure. -/// -/// \see ovr_GetRenderDesc -/// -typedef struct OVR_ALIGNAS(4) ovrEyeRenderDesc_ -{ - ovrEyeType Eye; ///< The eye index to which this instance corresponds. - ovrFovPort Fov; ///< The field of view. - ovrRecti DistortedViewport; ///< Distortion viewport. - ovrVector2f PixelsPerTanAngleAtCenter; ///< How many display pixels will fit in tan(angle) = 1. - ovrVector3f HmdToEyeOffset; ///< Translation of each eye, in meters. -} ovrEyeRenderDesc; - - -/// Projection information for ovrLayerEyeFovDepth. -/// -/// Use the utility function ovrTimewarpProjectionDesc_FromProjection to -/// generate this structure from the application's projection matrix. -/// -/// \see ovrLayerEyeFovDepth, ovrTimewarpProjectionDesc_FromProjection -/// -typedef struct OVR_ALIGNAS(4) ovrTimewarpProjectionDesc_ -{ - float Projection22; ///< Projection matrix element [2][2]. - float Projection23; ///< Projection matrix element [2][3]. - float Projection32; ///< Projection matrix element [3][2]. -} ovrTimewarpProjectionDesc; - - -/// Contains the data necessary to properly calculate position info for various layer types. -/// - HmdToEyeOffset is the same value pair provided in ovrEyeRenderDesc. -/// - HmdSpaceToWorldScaleInMeters is used to scale player motion into in-application units. -/// In other words, it is how big an in-application unit is in the player's physical meters. -/// For example, if the application uses inches as its units then HmdSpaceToWorldScaleInMeters would be 0.0254. -/// Note that if you are scaling the player in size, this must also scale. So if your application -/// units are inches, but you're shrinking the player to half their normal size, then -/// HmdSpaceToWorldScaleInMeters would be 0.0254*2.0. -/// -/// \see ovrEyeRenderDesc, ovr_SubmitFrame -/// -typedef struct OVR_ALIGNAS(4) ovrViewScaleDesc_ -{ - ovrVector3f HmdToEyeOffset[ovrEye_Count]; ///< Translation of each eye. - float HmdSpaceToWorldScaleInMeters; ///< Ratio of viewer units to meter units. -} ovrViewScaleDesc; - - -//----------------------------------------------------------------------------------- -// ***** Platform-independent Rendering Configuration - -/// The type of texture resource. -/// -/// \see ovrTextureSwapChainDesc -/// -typedef enum ovrTextureType_ -{ - ovrTexture_2D, ///< 2D textures. - ovrTexture_2D_External, ///< External 2D texture. Not used on PC - ovrTexture_Cube, ///< Cube maps. Not currently supported on PC. - ovrTexture_Count, - ovrTexture_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrTextureType; - -/// The bindings required for texture swap chain. -/// -/// All texture swap chains are automatically bindable as shader -/// input resources since the Oculus runtime needs this to read them. -/// -/// \see ovrTextureSwapChainDesc -/// -typedef enum ovrTextureBindFlags_ -{ - ovrTextureBind_None, - ovrTextureBind_DX_RenderTarget = 0x0001, ///< The application can write into the chain with pixel shader - ovrTextureBind_DX_UnorderedAccess = 0x0002, ///< The application can write to the chain with compute shader - ovrTextureBind_DX_DepthStencil = 0x0004, ///< The chain buffers can be bound as depth and/or stencil buffers - - ovrTextureBind_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrTextureBindFlags; - -/// The format of a texture. -/// -/// \see ovrTextureSwapChainDesc -/// -typedef enum ovrTextureFormat_ -{ - OVR_FORMAT_UNKNOWN, - OVR_FORMAT_B5G6R5_UNORM, ///< Not currently supported on PC. Would require a DirectX 11.1 device. - OVR_FORMAT_B5G5R5A1_UNORM, ///< Not currently supported on PC. Would require a DirectX 11.1 device. - OVR_FORMAT_B4G4R4A4_UNORM, ///< Not currently supported on PC. Would require a DirectX 11.1 device. - OVR_FORMAT_R8G8B8A8_UNORM, - OVR_FORMAT_R8G8B8A8_UNORM_SRGB, - OVR_FORMAT_B8G8R8A8_UNORM, - OVR_FORMAT_B8G8R8A8_UNORM_SRGB, ///< Not supported for OpenGL applications - OVR_FORMAT_B8G8R8X8_UNORM, ///< Not supported for OpenGL applications - OVR_FORMAT_B8G8R8X8_UNORM_SRGB, ///< Not supported for OpenGL applications - OVR_FORMAT_R16G16B16A16_FLOAT, - OVR_FORMAT_D16_UNORM, - OVR_FORMAT_D24_UNORM_S8_UINT, - OVR_FORMAT_D32_FLOAT, - OVR_FORMAT_D32_FLOAT_S8X24_UINT, - - // Added in 1.5 compressed formats can be used for static layers - OVR_FORMAT_BC1_UNORM, - OVR_FORMAT_BC1_UNORM_SRGB, - OVR_FORMAT_BC2_UNORM, - OVR_FORMAT_BC2_UNORM_SRGB, - OVR_FORMAT_BC3_UNORM, - OVR_FORMAT_BC3_UNORM_SRGB, - OVR_FORMAT_BC6H_UF16, - OVR_FORMAT_BC6H_SF16, - OVR_FORMAT_BC7_UNORM, - OVR_FORMAT_BC7_UNORM_SRGB, - - OVR_FORMAT_ENUMSIZE = 0x7fffffff ///< \internal Force type int32_t. -} ovrTextureFormat; - -/// Misc flags overriding particular -/// behaviors of a texture swap chain -/// -/// \see ovrTextureSwapChainDesc -/// -typedef enum ovrTextureMiscFlags_ -{ - ovrTextureMisc_None, - - /// DX only: The underlying texture is created with a TYPELESS equivalent of the - /// format specified in the texture desc. The SDK will still access the - /// texture using the format specified in the texture desc, but the app can - /// create views with different formats if this is specified. - ovrTextureMisc_DX_Typeless = 0x0001, - - /// DX only: Allow generation of the mip chain on the GPU via the GenerateMips - /// call. This flag requires that RenderTarget binding also be specified. - ovrTextureMisc_AllowGenerateMips = 0x0002, - - /// Texture swap chain contains protected content, and requires - /// HDCP connection in order to display to HMD. Also prevents - /// mirroring or other redirection of any frame containing this contents - ovrTextureMisc_ProtectedContent = 0x0004, - - ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrTextureFlags; - -/// Description used to create a texture swap chain. -/// -/// \see ovr_CreateTextureSwapChainDX -/// \see ovr_CreateTextureSwapChainGL -/// -typedef struct ovrTextureSwapChainDesc_ -{ - ovrTextureType Type; - ovrTextureFormat Format; - int ArraySize; ///< Only supported with ovrTexture_2D. Not supported on PC at this time. - int Width; - int Height; - int MipLevels; - int SampleCount; ///< Current only supported on depth textures - ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change - unsigned int MiscFlags; ///< ovrTextureFlags - unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL. -} ovrTextureSwapChainDesc; - -/// Description used to create a mirror texture. -/// -/// \see ovr_CreateMirrorTextureDX -/// \see ovr_CreateMirrorTextureGL -/// -typedef struct ovrMirrorTextureDesc_ -{ - ovrTextureFormat Format; - int Width; - int Height; - unsigned int MiscFlags; ///< ovrTextureFlags -} ovrMirrorTextureDesc; - -typedef struct ovrTextureSwapChainData* ovrTextureSwapChain; -typedef struct ovrMirrorTextureData* ovrMirrorTexture; - -//----------------------------------------------------------------------------------- - -/// Describes button input types. -/// Button inputs are combined; that is they will be reported as pressed if they are -/// pressed on either one of the two devices. -/// The ovrButton_Up/Down/Left/Right map to both XBox D-Pad and directional buttons. -/// The ovrButton_Enter and ovrButton_Return map to Start and Back controller buttons, respectively. -typedef enum ovrButton_ -{ - ovrButton_A = 0x00000001, - ovrButton_B = 0x00000002, - ovrButton_RThumb = 0x00000004, - ovrButton_RShoulder = 0x00000008, - - ovrButton_X = 0x00000100, - ovrButton_Y = 0x00000200, - ovrButton_LThumb = 0x00000400, - ovrButton_LShoulder = 0x00000800, - - // Navigation through DPad. - ovrButton_Up = 0x00010000, - ovrButton_Down = 0x00020000, - ovrButton_Left = 0x00040000, - ovrButton_Right = 0x00080000, - ovrButton_Enter = 0x00100000, // Start on XBox controller. - ovrButton_Back = 0x00200000, // Back on Xbox controller. - ovrButton_VolUp = 0x00400000, // only supported by Remote. - ovrButton_VolDown = 0x00800000, // only supported by Remote. - ovrButton_Home = 0x01000000, - ovrButton_Private = ovrButton_VolUp | ovrButton_VolDown | ovrButton_Home, - - // Bit mask of all buttons on the right Touch controller - ovrButton_RMask = ovrButton_A | ovrButton_B | ovrButton_RThumb | ovrButton_RShoulder, - - // Bit mask of all buttons on the left Touch controller - ovrButton_LMask = ovrButton_X | ovrButton_Y | ovrButton_LThumb | ovrButton_LShoulder | - ovrButton_Enter, - - - ovrButton_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrButton; - -/// Describes touch input types. -/// These values map to capacitive touch values reported ovrInputState::Touch. -/// Some of these values are mapped to button bits for consistency. -typedef enum ovrTouch_ -{ - ovrTouch_A = ovrButton_A, - ovrTouch_B = ovrButton_B, - ovrTouch_RThumb = ovrButton_RThumb, - ovrTouch_RThumbRest = 0x00000008, - ovrTouch_RIndexTrigger = 0x00000010, - - // Bit mask of all the button touches on the right controller - ovrTouch_RButtonMask = ovrTouch_A | ovrTouch_B | ovrTouch_RThumb | ovrTouch_RThumbRest | ovrTouch_RIndexTrigger, - - ovrTouch_X = ovrButton_X, - ovrTouch_Y = ovrButton_Y, - ovrTouch_LThumb = ovrButton_LThumb, - ovrTouch_LThumbRest = 0x00000800, - ovrTouch_LIndexTrigger = 0x00001000, - - // Bit mask of all the button touches on the left controller - ovrTouch_LButtonMask = ovrTouch_X | ovrTouch_Y | ovrTouch_LThumb | ovrTouch_LThumbRest | ovrTouch_LIndexTrigger, - - // Finger pose state - // Derived internally based on distance, proximity to sensors and filtering. - ovrTouch_RIndexPointing = 0x00000020, - ovrTouch_RThumbUp = 0x00000040, - - // Bit mask of all right controller poses - ovrTouch_RPoseMask = ovrTouch_RIndexPointing | ovrTouch_RThumbUp, - - ovrTouch_LIndexPointing = 0x00002000, - ovrTouch_LThumbUp = 0x00004000, - - // Bit mask of all left controller poses - ovrTouch_LPoseMask = ovrTouch_LIndexPointing | ovrTouch_LThumbUp, - - ovrTouch_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrTouch; - -/// Describes the Touch Haptics engine. -/// Currently, those values will NOT change during a session. -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTouchHapticsDesc_ -{ - // Haptics engine frequency/sample-rate, sample time in seconds equals 1.0/sampleRateHz - int SampleRateHz; - // Size of each Haptics sample, sample value range is [0, 2^(Bytes*8)-1] - int SampleSizeInBytes; - - // Queue size that would guarantee Haptics engine would not starve for data - // Make sure size doesn't drop below it for best results - int QueueMinSizeToAvoidStarvation; - - // Minimum, Maximum and Optimal number of samples that can be sent to Haptics through ovr_SubmitControllerVibration - int SubmitMinSamples; - int SubmitMaxSamples; - int SubmitOptimalSamples; -} ovrTouchHapticsDesc; - -/// Specifies which controller is connected; multiple can be connected at once. -typedef enum ovrControllerType_ -{ - ovrControllerType_None = 0x00, - ovrControllerType_LTouch = 0x01, - ovrControllerType_RTouch = 0x02, - ovrControllerType_Touch = 0x03, - ovrControllerType_Remote = 0x04, - ovrControllerType_XBox = 0x10, - - ovrControllerType_Active = 0xff, ///< Operate on or query whichever controller is active. - - ovrControllerType_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrControllerType; - -/// Haptics buffer submit mode -typedef enum ovrHapticsBufferSubmitMode_ -{ - // Enqueue buffer for later playback - ovrHapticsBufferSubmit_Enqueue -} ovrHapticsBufferSubmitMode; - -/// Haptics buffer descriptor, contains amplitude samples used for Touch vibration -typedef struct ovrHapticsBuffer_ -{ - const void* Samples; - int SamplesCount; - ovrHapticsBufferSubmitMode SubmitMode; -} ovrHapticsBuffer; - -/// State of the Haptics playback for Touch vibration -typedef struct ovrHapticsPlaybackState_ -{ - // Remaining space available to queue more samples - int RemainingQueueSpace; - - // Number of samples currently queued - int SamplesQueued; -} ovrHapticsPlaybackState; - -/// Position tracked devices -typedef enum ovrTrackedDeviceType_ -{ - ovrTrackedDevice_HMD = 0x0001, - ovrTrackedDevice_LTouch = 0x0002, - ovrTrackedDevice_RTouch = 0x0004, - ovrTrackedDevice_Touch = 0x0006, - ovrTrackedDevice_All = 0xFFFF, -} ovrTrackedDeviceType; - -/// Provides names for the left and right hand array indexes. -/// -/// \see ovrInputState, ovrTrackingState -/// -typedef enum ovrHandType_ -{ - ovrHand_Left = 0, - ovrHand_Right = 1, - ovrHand_Count = 2, - ovrHand_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrHandType; - - - -/// ovrInputState describes the complete controller input state, including Oculus Touch, -/// and XBox gamepad. If multiple inputs are connected and used at the same time, -/// their inputs are combined. -typedef struct ovrInputState_ -{ - /// System type when the controller state was last updated. - double TimeInSeconds; - - /// Values for buttons described by ovrButton. - unsigned int Buttons; - - /// Touch values for buttons and sensors as described by ovrTouch. - unsigned int Touches; - - /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. - /// Returns 0 if the value would otherwise be less than 0.1176, for ovrControllerType_XBox - float IndexTrigger[ovrHand_Count]; - - /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. - float HandTrigger[ovrHand_Count]; - - /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range -1.0f to 1.0f. - /// Returns a deadzone (value 0) per each axis if the value on that axis would otherwise have been between -.2746 to +.2746, for ovrControllerType_XBox - ovrVector2f Thumbstick[ovrHand_Count]; - - /// The type of the controller this state is for. - ovrControllerType ControllerType; - - /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. - /// Does not apply a deadzone - /// Added in 1.7 - float IndexTriggerNoDeadzone[ovrHand_Count]; - - /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. - /// Does not apply a deadzone - /// Added in 1.7 - float HandTriggerNoDeadzone[ovrHand_Count]; - - /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range -1.0f to 1.0f - /// Does not apply a deadzone - /// Added in 1.7 - ovrVector2f ThumbstickNoDeadzone[ovrHand_Count]; -} ovrInputState; - - - -//----------------------------------------------------------------------------------- -// ***** Initialize structures - -/// Initialization flags. -/// -/// \see ovrInitParams, ovr_Initialize -/// -typedef enum ovrInitFlags_ -{ - /// When a debug library is requested, a slower debugging version of the library will - /// run which can be used to help solve problems in the library and debug application code. - ovrInit_Debug = 0x00000001, - - /// When a version is requested, the LibOVR runtime respects the RequestedMinorVersion - /// field and verifies that the RequestedMinorVersion is supported. - ovrInit_RequestVersion = 0x00000004, - - // These bits are writable by user code. - ovrinit_WritableBits = 0x00ffffff, - - ovrInit_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrInitFlags; - - -/// Logging levels -/// -/// \see ovrInitParams, ovrLogCallback -/// -typedef enum ovrLogLevel_ -{ - ovrLogLevel_Debug = 0, ///< Debug-level log event. - ovrLogLevel_Info = 1, ///< Info-level log event. - ovrLogLevel_Error = 2, ///< Error-level log event. - - ovrLogLevel_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrLogLevel; - - -/// Signature of the logging callback function pointer type. -/// -/// \param[in] userData is an arbitrary value specified by the user of ovrInitParams. -/// \param[in] level is one of the ovrLogLevel constants. -/// \param[in] message is a UTF8-encoded null-terminated string. -/// \see ovrInitParams, ovrLogLevel, ovr_Initialize -/// -typedef void (OVR_CDECL* ovrLogCallback)(uintptr_t userData, int level, const char* message); - - -/// Parameters for ovr_Initialize. -/// -/// \see ovr_Initialize -/// -typedef struct OVR_ALIGNAS(8) ovrInitParams_ -{ - /// Flags from ovrInitFlags to override default behavior. - /// Use 0 for the defaults. - uint32_t Flags; - - /// Requests a specific minimum minor version of the LibOVR runtime. - /// Flags must include ovrInit_RequestVersion or this will be ignored - /// and OVR_MINOR_VERSION will be used. - uint32_t RequestedMinorVersion; - - /// User-supplied log callback function, which may be called at any time - /// asynchronously from multiple threads until ovr_Shutdown completes. - /// Use NULL to specify no log callback. - ovrLogCallback LogCallback; - - /// User-supplied data which is passed as-is to LogCallback. Typically this - /// is used to store an application-specific pointer which is read in the - /// callback function. - uintptr_t UserData; - - /// Relative number of milliseconds to wait for a connection to the server - /// before failing. Use 0 for the default timeout. - uint32_t ConnectionTimeoutMS; - - OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad0, 4)) ///< \internal - -} ovrInitParams; - - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(OVR_EXPORTING_CAPI) - -// ----------------------------------------------------------------------------------- -// ***** API Interfaces - -/// Initializes LibOVR -/// -/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT -/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can -/// be called unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually -/// followed by a call to ovr_Shutdown. ovr_Initialize calls are idempotent. -/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown. -/// If already initialized, the return value is ovr_Success. -/// -/// LibOVRRT shared library search order: -/// -# Current working directory (often the same as the application directory). -/// -# Module directory (usually the same as the application directory, -/// but not if the module is a separate shared library). -/// -# Application directory -/// -# Development directory (only if OVR_ENABLE_DEVELOPER_SEARCH is enabled, -/// which is off by default). -/// -# Standard OS shared library search location(s) (OS-specific). -/// -/// \param params Specifies custom initialization options. May be NULL to indicate default options. -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. Example failed results include: -/// - ovrError_Initialize: Generic initialization error. -/// - ovrError_LibLoad: Couldn't load LibOVRRT. -/// - ovrError_LibVersion: LibOVRRT version incompatibility. -/// - ovrError_ServiceConnection: Couldn't connect to the OVR Service. -/// - ovrError_ServiceVersion: OVR Service version incompatibility. -/// - ovrError_IncompatibleOS: The operating system version is incompatible. -/// - ovrError_DisplayInit: Unable to initialize the HMD display. -/// - ovrError_ServerStart: Unable to start the server. Is it already running? -/// - ovrError_Reinitialization: Attempted to re-initialize with a different version. -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovrResult result = ovr_Initialize(NULL); -/// if(OVR_FAILURE(result)) { -/// ovrErrorInfo errorInfo; -/// ovr_GetLastErrorInfo(&errorInfo); -/// DebugLog("ovr_Initialize failed: %s", errorInfo.ErrorString); -/// return false; -/// } -/// [...] -/// \endcode -/// -/// \see ovr_Shutdown -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_Initialize(const ovrInitParams* params); - - -/// Shuts down LibOVR -/// -/// A successful call to ovr_Initialize must be eventually matched by a call to ovr_Shutdown. -/// After calling ovr_Shutdown, no LibOVR functions can be called except ovr_GetLastErrorInfo -/// or another ovr_Initialize. ovr_Shutdown invalidates all pointers, references, and created objects -/// previously returned by LibOVR functions. The LibOVRRT shared library can be unloaded by -/// ovr_Shutdown. -/// -/// \see ovr_Initialize -/// -OVR_PUBLIC_FUNCTION(void) ovr_Shutdown(); - -/// Returns information about the most recent failed return value by the -/// current thread for this library. -/// -/// This function itself can never generate an error. -/// The last error is never cleared by LibOVR, but will be overwritten by new errors. -/// Do not use this call to determine if there was an error in the last API -/// call as successful API calls don't clear the last ovrErrorInfo. -/// To avoid any inconsistency, ovr_GetLastErrorInfo should be called immediately -/// after an API function that returned a failed ovrResult, with no other API -/// functions called in the interim. -/// -/// \param[out] errorInfo The last ovrErrorInfo for the current thread. -/// -/// \see ovrErrorInfo -/// -OVR_PUBLIC_FUNCTION(void) ovr_GetLastErrorInfo(ovrErrorInfo* errorInfo); - - -/// Returns the version string representing the LibOVRRT version. -/// -/// The returned string pointer is valid until the next call to ovr_Shutdown. -/// -/// Note that the returned version string doesn't necessarily match the current -/// OVR_MAJOR_VERSION, etc., as the returned string refers to the LibOVRRT shared -/// library version and not the locally compiled interface version. -/// -/// The format of this string is subject to change in future versions and its contents -/// should not be interpreted. -/// -/// \return Returns a UTF8-encoded null-terminated version string. -/// -OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString(); - - -/// Writes a message string to the LibOVR tracing mechanism (if enabled). -/// -/// This message will be passed back to the application via the ovrLogCallback if -/// it was registered. -/// -/// \param[in] level One of the ovrLogLevel constants. -/// \param[in] message A UTF8-encoded null-terminated string. -/// \return returns the strlen of the message or a negative value if the message is too large. -/// -/// \see ovrLogLevel, ovrLogCallback -/// -OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message); - - -/// Identify client application info. -/// -/// The string is one or more newline-delimited lines of optional info -/// indicating engine name, engine version, engine plugin name, engine plugin -/// version, engine editor. The order of the lines is not relevant. Individual -/// lines are optional. A newline is not necessary at the end of the last line. -/// Call after ovr_Initialize and before the first call to ovr_Create. -/// Each value is limited to 20 characters. Key names such as 'EngineName:' -/// 'EngineVersion:' do not count towards this limit. -/// -/// \param[in] identity Specifies one or more newline-delimited lines of optional info: -/// EngineName: %s\n -/// EngineVersion: %s\n -/// EnginePluginName: %s\n -/// EnginePluginVersion: %s\n -/// EngineEditor: <boolean> ('true' or 'false')\n -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovr_IdentifyClient("EngineName: Unity\n" -/// "EngineVersion: 5.3.3\n" -/// "EnginePluginName: OVRPlugin\n" -/// "EnginePluginVersion: 1.2.0\n" -/// "EngineEditor: true"); -/// \endcode -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity); - - -//------------------------------------------------------------------------------------- -/// @name HMD Management -/// -/// Handles the enumeration, creation, destruction, and properties of an HMD (head-mounted display). -///@{ - - -/// Returns information about the current HMD. -/// -/// ovr_Initialize must have first been called in order for this to succeed, otherwise ovrHmdDesc::Type -/// will be reported as ovrHmd_None. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create, else NULL in which -/// case this function detects whether an HMD is present and returns its info if so. -/// -/// \return Returns an ovrHmdDesc. If the hmd is NULL and ovrHmdDesc::Type is ovrHmd_None then -/// no HMD is present. -/// -OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session); - - -/// Returns the number of sensors. -/// -/// The number of sensors may change at any time, so this function should be called before use -/// as opposed to once on startup. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// -/// \return Returns unsigned int count. -/// -OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetTrackerCount(ovrSession session); - - -/// Returns a given sensor description. -/// -/// It's possible that sensor desc [0] may indicate a unconnnected or non-pose tracked sensor, but -/// sensor desc [1] may be connected. -/// -/// ovr_Initialize must have first been called in order for this to succeed, otherwise the returned -/// trackerDescArray will be zero-initialized. The data returned by this function can change at runtime. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// -/// \param[in] trackerDescIndex Specifies a sensor index. The valid indexes are in the range of 0 to -/// the sensor count returned by ovr_GetTrackerCount. -/// -/// \return Returns ovrTrackerDesc. An empty ovrTrackerDesc will be returned if trackerDescIndex is out of range. -/// -/// \see ovrTrackerDesc, ovr_GetTrackerCount -/// -OVR_PUBLIC_FUNCTION(ovrTrackerDesc) ovr_GetTrackerDesc(ovrSession session, unsigned int trackerDescIndex); - - -/// Creates a handle to a VR session. -/// -/// Upon success the returned ovrSession must be eventually freed with ovr_Destroy when it is no longer needed. -/// A second call to ovr_Create will result in an error return value if the previous session has not been destroyed. -/// -/// \param[out] pSession Provides a pointer to an ovrSession which will be written to upon success. -/// \param[out] luid Provides a system specific graphics adapter identifier that locates which -/// graphics adapter has the HMD attached. This must match the adapter used by the application -/// or no rendering output will be possible. This is important for stability on multi-adapter systems. An -/// application that simply chooses the default adapter will not run reliably on multi-adapter systems. -/// \return Returns an ovrResult indicating success or failure. Upon failure -/// the returned ovrSession will be NULL. -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovrSession session; -/// ovrGraphicsLuid luid; -/// ovrResult result = ovr_Create(&session, &luid); -/// if(OVR_FAILURE(result)) -/// ... -/// \endcode -/// -/// \see ovr_Destroy -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid); - - -/// Destroys the session. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \see ovr_Create -/// -OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session); - -#endif // !defined(OVR_EXPORTING_CAPI) - -/// Specifies status information for the current session. -/// -/// \see ovr_GetSessionStatus -/// -typedef struct ovrSessionStatus_ -{ - ovrBool IsVisible; ///< True if the process has VR focus and thus is visible in the HMD. - ovrBool HmdPresent; ///< True if an HMD is present. - ovrBool HmdMounted; ///< True if the HMD is on the user's head. - ovrBool DisplayLost; ///< True if the session is in a display-lost state. See ovr_SubmitFrame. - ovrBool ShouldQuit; ///< True if the application should initiate shutdown. - ovrBool ShouldRecenter; ///< True if UX has requested re-centering. Must call ovr_ClearShouldRecenterFlag or ovr_RecenterTrackingOrigin. -}ovrSessionStatus; - -#if !defined(OVR_EXPORTING_CAPI) - -/// Returns status information for the application. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[out] sessionStatus Provides an ovrSessionStatus that is filled in. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of -/// failure, use ovr_GetLastErrorInfo to get more information. -// Return values include but aren't limited to: -/// - ovrSuccess: Completed successfully. -/// - ovrError_ServiceConnection: The service connection was lost and the application -// must destroy the session. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetSessionStatus(ovrSession session, ovrSessionStatus* sessionStatus); - - -//@} - - - -//------------------------------------------------------------------------------------- -/// @name Tracking -/// -/// Tracking functions handle the position, orientation, and movement of the HMD in space. -/// -/// All tracking interface functions are thread-safe, allowing tracking state to be sampled -/// from different threads. -/// -///@{ - - - -/// Sets the tracking origin type -/// -/// When the tracking origin is changed, all of the calls that either provide -/// or accept ovrPosef will use the new tracking origin provided. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] origin Specifies an ovrTrackingOrigin to be used for all ovrPosef -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// \see ovrTrackingOrigin, ovr_GetTrackingOriginType -OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetTrackingOriginType(ovrSession session, ovrTrackingOrigin origin); - - -/// Gets the tracking origin state -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// -/// \return Returns the ovrTrackingOrigin that was either set by default, or previous set by the application. -/// -/// \see ovrTrackingOrigin, ovr_SetTrackingOriginType -OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession session); - - -/// Re-centers the sensor position and orientation. -/// -/// This resets the (x,y,z) positional components and the yaw orientation component. -/// The Roll and pitch orientation components are always determined by gravity and cannot -/// be redefined. All future tracking will report values relative to this new reference position. -/// If you are using ovrTrackerPoses then you will need to call ovr_GetTrackerPose after -/// this, because the sensor position(s) will change as a result of this. -/// -/// The headset cannot be facing vertically upward or downward but rather must be roughly -/// level otherwise this function will fail with ovrError_InvalidHeadsetOrientation. -/// -/// For more info, see the notes on each ovrTrackingOrigin enumeration to understand how -/// recenter will vary slightly in its behavior based on the current ovrTrackingOrigin setting. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. Return values include but aren't limited to: -/// - ovrSuccess: Completed successfully. -/// - ovrError_InvalidHeadsetOrientation: The headset was facing an invalid direction when -/// attempting recentering, such as facing vertically. -/// -/// \see ovrTrackingOrigin, ovr_GetTrackerPose -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_RecenterTrackingOrigin(ovrSession session); - - -/// Clears the ShouldRecenter status bit in ovrSessionStatus. -/// -/// Clears the ShouldRecenter status bit in ovrSessionStatus, allowing further recenter -/// requests to be detected. Since this is automatically done by ovr_RecenterTrackingOrigin, -/// this is only needs to be called when application is doing its own re-centering. -OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session); - - -/// 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. -/// -/// This may also be used for more refined timing of front buffer rendering logic, and so on. -/// This may be called by multiple threads. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] absTime Specifies the absolute future time to predict the return -/// ovrTrackingState value. Use 0 to request the most recent tracking state. -/// \param[in] latencyMarker Specifies that this call is the point in time where -/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer -/// provides "SensorSampleTime", that will override the value stored here. -/// \return Returns the ovrTrackingState that is predicted for the given absTime. -/// -/// \see ovrTrackingState, ovr_GetEyePoses, ovr_GetTimeInSeconds -/// -OVR_PUBLIC_FUNCTION(ovrTrackingState) ovr_GetTrackingState(ovrSession session, double absTime, ovrBool latencyMarker); - - - -/// Returns the ovrTrackerPose for the given sensor. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] trackerPoseIndex Index of the sensor being requested. -/// -/// \return Returns the requested ovrTrackerPose. An empty ovrTrackerPose will be returned if trackerPoseIndex is out of range. -/// -/// \see ovr_GetTrackerCount -/// -OVR_PUBLIC_FUNCTION(ovrTrackerPose) ovr_GetTrackerPose(ovrSession session, unsigned int trackerPoseIndex); - - - -/// Returns the most recent input state for controllers, without positional tracking info. -/// -/// \param[out] inputState Input state that will be filled in. -/// \param[in] ovrControllerType Specifies which controller the input will be returned for. -/// \return Returns ovrSuccess if the new state was successfully obtained. -/// -/// \see ovrControllerType -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetInputState(ovrSession session, ovrControllerType controllerType, ovrInputState* inputState); - - -/// Returns controller types connected to the system OR'ed together. -/// -/// \return A bitmask of ovrControllerTypes connected to the system. -/// -/// \see ovrControllerType -/// -OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession session); - -/// Gets information about Haptics engine for the specified Touch controller. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] controllerType The controller to retrieve the information from. -/// -/// \return Returns an ovrTouchHapticsDesc. -/// -OVR_PUBLIC_FUNCTION(ovrTouchHapticsDesc) ovr_GetTouchHapticsDesc(ovrSession session, ovrControllerType controllerType); - -/// Sets constant vibration (with specified frequency and amplitude) to a controller. -/// Note: ovr_SetControllerVibration cannot be used interchangeably with ovr_SubmitControllerVibration. -/// -/// This method should be called periodically, vibration lasts for a maximum of 2.5 seconds. -/// It's recommended to call this method once a second, calls will be rejected if called too frequently (over 30hz). -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] controllerType The controller to set the vibration to. -/// \param[in] frequency Vibration frequency. Supported values are: 0.0 (disabled), 0.5 and 1.0. Non valid values will be clamped. -/// \param[in] amplitude Vibration amplitude in the [0.0, 1.0] range. -/// \return Returns ovrSuccess upon success. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetControllerVibration(ovrSession session, ovrControllerType controllerType, float frequency, float amplitude); - -/// Submits a Haptics buffer (used for vibration) to Touch (only) controllers. -/// Note: ovr_SubmitControllerVibration cannot be used interchangeably with ovr_SetControllerVibration. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] controllerType Controller where the Haptics buffer will be played. -/// \param[in] buffer Haptics buffer containing amplitude samples to be played. -/// \return Returns ovrSuccess upon success. -/// \see ovrHapticsBuffer -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_SubmitControllerVibration(ovrSession session, ovrControllerType controllerType, const ovrHapticsBuffer* buffer); - -/// Gets the Haptics engine playback state of a specific Touch controller. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] controllerType Controller where the Haptics buffer wil be played. -/// \param[in] outState State of the haptics engine. -/// \return Returns ovrSuccess upon success. -/// \see ovrHapticsPlaybackState -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetControllerVibrationState(ovrSession session, ovrControllerType controllerType, ovrHapticsPlaybackState* outState); - - -#endif // !defined(OVR_EXPORTING_CAPI) - -//------------------------------------------------------------------------------------- -// @name Layers -// -///@{ - - -/// Specifies the maximum number of layers supported by ovr_SubmitFrame. -/// -/// /see ovr_SubmitFrame -/// -enum { - ovrMaxLayerCount = 16 -}; - -/// Describes layer types that can be passed to ovr_SubmitFrame. -/// Each layer type has an associated struct, such as ovrLayerEyeFov. -/// -/// \see ovrLayerHeader -/// -typedef enum ovrLayerType_ -{ - ovrLayerType_Disabled = 0, ///< Layer is disabled. - ovrLayerType_EyeFov = 1, ///< Described by ovrLayerEyeFov. - ovrLayerType_Quad = 3, ///< Described by ovrLayerQuad. Previously called ovrLayerType_QuadInWorld. - /// enum 4 used to be ovrLayerType_QuadHeadLocked. Instead, use ovrLayerType_Quad with ovrLayerFlag_HeadLocked. - ovrLayerType_EyeMatrix = 5, ///< Described by ovrLayerEyeMatrix. - ovrLayerType_EnumSize = 0x7fffffff ///< Force type int32_t. -} ovrLayerType; - - -/// Identifies flags used by ovrLayerHeader and which are passed to ovr_SubmitFrame. -/// -/// \see ovrLayerHeader -/// -typedef enum ovrLayerFlags_ -{ - /// ovrLayerFlag_HighQuality enables 4x anisotropic sampling during the composition of the layer. - /// The benefits are mostly visible at the periphery for high-frequency & high-contrast visuals. - /// For best results consider combining this flag with an ovrTextureSwapChain that has mipmaps and - /// instead of using arbitrary sized textures, prefer texture sizes that are powers-of-two. - /// Actual rendered viewport and doesn't necessarily have to fill the whole texture. - ovrLayerFlag_HighQuality = 0x01, - - /// ovrLayerFlag_TextureOriginAtBottomLeft: the opposite is TopLeft. - /// Generally this is false for D3D, true for OpenGL. - ovrLayerFlag_TextureOriginAtBottomLeft = 0x02, - - /// Mark this surface as "headlocked", which means it is specified - /// relative to the HMD and moves with it, rather than being specified - /// relative to sensor/torso space and remaining still while the head moves. - /// What used to be ovrLayerType_QuadHeadLocked is now ovrLayerType_Quad plus this flag. - /// However the flag can be applied to any layer type to achieve a similar effect. - ovrLayerFlag_HeadLocked = 0x04 - -} ovrLayerFlags; - - -/// Defines properties shared by all ovrLayer structs, such as ovrLayerEyeFov. -/// -/// ovrLayerHeader is used as a base member in these larger structs. -/// This struct cannot be used by itself except for the case that Type is ovrLayerType_Disabled. -/// -/// \see ovrLayerType, ovrLayerFlags -/// -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerHeader_ -{ - ovrLayerType Type; ///< Described by ovrLayerType. - unsigned Flags; ///< Described by ovrLayerFlags. -} ovrLayerHeader; - - -/// Describes a layer that specifies a monoscopic or stereoscopic view. -/// This is the kind of layer that's typically used as layer 0 to ovr_SubmitFrame, -/// as it is the kind of layer used to render a 3D stereoscopic view. -/// -/// Three options exist with respect to mono/stereo texture usage: -/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, respectively. -/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively. -/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL, -/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0]. -/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and -/// Viewport[1] both refer to that rendering. -/// -/// \see ovrTextureSwapChain, ovr_SubmitFrame -/// -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeFov_ -{ - /// Header.Type must be ovrLayerType_EyeFov. - ovrLayerHeader Header; - - /// ovrTextureSwapChains for the left and right eye respectively. - /// The second one of which can be NULL for cases described above. - ovrTextureSwapChain ColorTexture[ovrEye_Count]; - - /// Specifies the ColorTexture sub-rect UV coordinates. - /// Both Viewport[0] and Viewport[1] must be valid. - ovrRecti Viewport[ovrEye_Count]; - - /// The viewport field of view. - ovrFovPort Fov[ovrEye_Count]; - - /// Specifies the position and orientation of each eye view, with the position specified in meters. - /// RenderPose will typically be the value returned from ovr_CalcEyePoses, - /// but can be different in special cases if a different head pose is used for rendering. - ovrPosef RenderPose[ovrEye_Count]; - - /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose) - /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds - /// around the instant the application calls ovr_GetTrackingState - /// The main purpose for this is to accurately track app tracking latency. - double SensorSampleTime; - -} ovrLayerEyeFov; - - - - -/// Describes a layer that specifies a monoscopic or stereoscopic view. -/// This uses a direct 3x4 matrix to map from view space to the UV coordinates. -/// It is essentially the same thing as ovrLayerEyeFov but using a much -/// lower level. This is mainly to provide compatibility with specific apps. -/// Unless the application really requires this flexibility, it is usually better -/// to use ovrLayerEyeFov. -/// -/// Three options exist with respect to mono/stereo texture usage: -/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, respectively. -/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively. -/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL, -/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0]. -/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and -/// Viewport[1] both refer to that rendering. -/// -/// \see ovrTextureSwapChain, ovr_SubmitFrame -/// -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeMatrix_ -{ - /// Header.Type must be ovrLayerType_EyeMatrix. - ovrLayerHeader Header; - - /// ovrTextureSwapChains for the left and right eye respectively. - /// The second one of which can be NULL for cases described above. - ovrTextureSwapChain ColorTexture[ovrEye_Count]; - - /// Specifies the ColorTexture sub-rect UV coordinates. - /// Both Viewport[0] and Viewport[1] must be valid. - ovrRecti Viewport[ovrEye_Count]; - - /// Specifies the position and orientation of each eye view, with the position specified in meters. - /// RenderPose will typically be the value returned from ovr_CalcEyePoses, - /// but can be different in special cases if a different head pose is used for rendering. - ovrPosef RenderPose[ovrEye_Count]; - - /// Specifies the mapping from a view-space vector - /// to a UV coordinate on the textures given above. - /// P = (x,y,z,1)*Matrix - /// TexU = P.x/P.z - /// TexV = P.y/P.z - ovrMatrix4f Matrix[ovrEye_Count]; - - /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose) - /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds - /// around the instant the application calls ovr_GetTrackingState - /// The main purpose for this is to accurately track app tracking latency. - double SensorSampleTime; - -} ovrLayerEyeMatrix; - - - - - -/// Describes a layer of Quad type, which is a single quad in world or viewer space. -/// It is used for ovrLayerType_Quad. This type of layer represents a single -/// object placed in the world and not a stereo view of the world itself. -/// -/// A typical use of ovrLayerType_Quad is to draw a television screen in a room -/// that for some reason is more convenient to draw as a layer than as part of the main -/// view in layer 0. For example, it could implement a 3D popup GUI that is drawn at a -/// higher resolution than layer 0 to improve fidelity of the GUI. -/// -/// Quad layers are visible from both sides; they are not back-face culled. -/// -/// \see ovrTextureSwapChain, ovr_SubmitFrame -/// -typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerQuad_ -{ - /// Header.Type must be ovrLayerType_Quad. - ovrLayerHeader Header; - - /// Contains a single image, never with any stereo view. - ovrTextureSwapChain ColorTexture; - - /// Specifies the ColorTexture sub-rect UV coordinates. - ovrRecti Viewport; - - /// Specifies the orientation and position of the center point of a Quad layer type. - /// The supplied direction is the vector perpendicular to the quad. - /// The position is in real-world meters (not the application's virtual world, - /// the physical world the user is in) and is relative to the "zero" position - /// set by ovr_RecenterTrackingOrigin unless the ovrLayerFlag_HeadLocked flag is used. - ovrPosef QuadPoseCenter; - - /// Width and height (respectively) of the quad in meters. - ovrVector2f QuadSize; - -} ovrLayerQuad; - - - - -/// Union that combines ovrLayer types in a way that allows them -/// to be used in a polymorphic way. -typedef union ovrLayer_Union_ -{ - ovrLayerHeader Header; - ovrLayerEyeFov EyeFov; - ovrLayerQuad Quad; -} ovrLayer_Union; - - -//@} - -#if !defined(OVR_EXPORTING_CAPI) - -/// @name SDK Distortion Rendering -/// -/// 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. -/// -/// These functions support rendering of distortion by the SDK. -/// -//@{ - -/// TextureSwapChain creation is rendering API-specific. -/// ovr_CreateTextureSwapChainDX and ovr_CreateTextureSwapChainGL can be found in the -/// rendering API-specific headers, such as OVR_CAPI_D3D.h and OVR_CAPI_GL.h - -/// Gets the number of buffers in an ovrTextureSwapChain. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies the ovrTextureSwapChain for which the length should be retrieved. -/// \param[out] out_Length Returns the number of buffers in the specified chain. -/// -/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. -/// -/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainLength(ovrSession session, ovrTextureSwapChain chain, int* out_Length); - -/// Gets the current index in an ovrTextureSwapChain. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies the ovrTextureSwapChain for which the index should be retrieved. -/// \param[out] out_Index Returns the current (free) index in specified chain. -/// -/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. -/// -/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainCurrentIndex(ovrSession session, ovrTextureSwapChain chain, int* out_Index); - -/// Gets the description of the buffers in an ovrTextureSwapChain -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies the ovrTextureSwapChain for which the description should be retrieved. -/// \param[out] out_Desc Returns the description of the specified chain. -/// -/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. -/// -/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainDesc(ovrSession session, ovrTextureSwapChain chain, ovrTextureSwapChainDesc* out_Desc); - -/// Commits any pending changes to an ovrTextureSwapChain, and advances its current index -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies the ovrTextureSwapChain to commit. -/// -/// \note When Commit is called, the texture at the current index is considered ready for use by the -/// runtime, and further writes to it should be avoided. The swap chain's current index is advanced, -/// providing there's room in the chain. The next time the SDK dereferences this texture swap chain, -/// it will synchronize with the app's graphics context and pick up the submitted index, opening up -/// room in the swap chain for further commits. -/// -/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. -/// Failures include but aren't limited to: -/// - ovrError_TextureSwapChainFull: ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain. -/// -/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_CommitTextureSwapChain(ovrSession session, ovrTextureSwapChain chain); - -/// Destroys an ovrTextureSwapChain and frees all the resources associated with it. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies the ovrTextureSwapChain to destroy. If it is NULL then this function has no effect. -/// -/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL -/// -OVR_PUBLIC_FUNCTION(void) ovr_DestroyTextureSwapChain(ovrSession session, ovrTextureSwapChain chain); - - -/// MirrorTexture creation is rendering API-specific. -/// ovr_CreateMirrorTextureDX and ovr_CreateMirrorTextureGL can be found in the -/// rendering API-specific headers, such as OVR_CAPI_D3D.h and OVR_CAPI_GL.h - -/// Destroys a mirror texture previously created by one of the mirror texture creation functions. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] mirrorTexture Specifies the ovrTexture to destroy. If it is NULL then this function has no effect. -/// -/// \see ovr_CreateMirrorTextureDX, ovr_CreateMirrorTextureGL -/// -OVR_PUBLIC_FUNCTION(void) ovr_DestroyMirrorTexture(ovrSession session, ovrMirrorTexture mirrorTexture); - - -/// 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. -/// Apps packing multiple eye views together on the same texture should ensure there are -/// at least 8 pixels of padding between them to prevent texture filtering and chromatic -/// aberration causing images to leak between the two eye views. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] eye Specifies which eye (left or right) to calculate for. -/// \param[in] fov Specifies the ovrFovPort to use. -/// \param[in] 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. -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); -/// ovrSizei eyeSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[ovrEye_Left], 1.0f); -/// ovrSizei eyeSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[ovrEye_Right], 1.0f); -/// \endcode -/// -/// \return Returns the texture width and height size. -/// -OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov, - float pixelsPerDisplayPixel); - -/// Computes the distortion viewport, view adjust, and other rendering parameters for -/// the specified eye. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] eyeType Specifies which eye (left or right) for which to perform calculations. -/// \param[in] fov Specifies the ovrFovPort to use. -/// -/// \return Returns the computed ovrEyeRenderDesc for the given eyeType and field of view. -/// -/// \see ovrEyeRenderDesc -/// -OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovr_GetRenderDesc(ovrSession session, - ovrEyeType eyeType, ovrFovPort fov); - -/// Submits layers for distortion and display. -/// -/// ovr_SubmitFrame triggers distortion and processing which might happen asynchronously. -/// The function will return when there is room in the submission queue and surfaces -/// are available. Distortion might or might not have completed. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// -/// \param[in] frameIndex Specifies the targeted application frame index, or 0 to refer to one frame -/// after the last time ovr_SubmitFrame was called. -/// -/// \param[in] viewScaleDesc Provides additional information needed only if layerPtrList contains -/// an ovrLayerType_Quad. If NULL, a default version is used based on the current configuration and a 1.0 world scale. -/// -/// \param[in] layerPtrList Specifies a list of ovrLayer pointers, which can include NULL entries to -/// indicate that any previously shown layer at that index is to not be displayed. -/// Each layer header must be a part of a layer structure such as ovrLayerEyeFov or ovrLayerQuad, -/// with Header.Type identifying its type. A NULL layerPtrList entry in the array indicates the -// absence of the given layer. -/// -/// \param[in] layerCount Indicates the number of valid elements in layerPtrList. The maximum -/// supported layerCount is not currently specified, but may be specified in a future version. -/// -/// - Layers are drawn in the order they are specified in the array, regardless of the layer type. -/// -/// - Layers are not remembered between successive calls to ovr_SubmitFrame. A layer must be -/// specified in every call to ovr_SubmitFrame or it won't be displayed. -/// -/// - If a layerPtrList entry that was specified in a previous call to ovr_SubmitFrame is -/// passed as NULL or is of type ovrLayerType_Disabled, that layer is no longer displayed. -/// -/// - A layerPtrList entry can be of any layer type and multiple entries of the same layer type -/// are allowed. No layerPtrList entry may be duplicated (i.e. the same pointer as an earlier entry). -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovrLayerEyeFov layer0; -/// ovrLayerQuad layer1; -/// ... -/// ovrLayerHeader* layers[2] = { &layer0.Header, &layer1.Header }; -/// ovrResult result = ovr_SubmitFrame(session, frameIndex, nullptr, layers, 2); -/// \endcode -/// -/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true -/// upon success. Return values include but aren't limited to: -/// - ovrSuccess: rendering completed successfully. -/// - ovrSuccess_NotVisible: rendering completed successfully but was not displayed on the HMD, -/// usually because another application currently has ownership of the HMD. Applications receiving -/// this result should stop rendering new content, but continue to call ovr_SubmitFrame periodically -/// until it returns a value other than ovrSuccess_NotVisible. -/// - ovrError_DisplayLost: The session has become invalid (such as due to a device removal) -/// and the shared resources need to be released (ovr_DestroyTextureSwapChain), the session needs to -/// destroyed (ovr_Destroy) and recreated (ovr_Create), and new resources need to be created -/// (ovr_CreateTextureSwapChainXXX). The application's existing private graphics resources do not -/// need to be recreated unless the new ovr_Create call returns a different GraphicsLuid. -/// - ovrError_TextureSwapChainInvalid: The ovrTextureSwapChain is in an incomplete or inconsistent state. -/// Ensure ovr_CommitTextureSwapChain was called at least once first. -/// -/// \see ovr_GetPredictedDisplayTime, ovrViewScaleDesc, ovrLayerHeader -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_SubmitFrame(ovrSession session, long long frameIndex, - const ovrViewScaleDesc* viewScaleDesc, - ovrLayerHeader const * const * layerPtrList, unsigned int layerCount); -///@} - -#endif // !defined(OVR_EXPORTING_CAPI) - -//------------------------------------------------------------------------------------- -/// @name Frame Timing -/// -//@{ - - -#if !defined(OVR_EXPORTING_CAPI) - -/// Gets the time of the specified frame midpoint. -/// -/// Predicts the time at which the given frame will be displayed. The predicted time -/// is the middle of the time period during which the corresponding eye images will -/// be displayed. -/// -/// The application should increment frameIndex for each successively targeted frame, -/// and pass that index to any relevant OVR functions that need to apply to the frame -/// identified by that index. -/// -/// This function is thread-safe and allows for multiple application threads to target -/// their processing to the same displayed frame. -/// -/// In the even that prediction fails due to various reasons (e.g. the display being off -/// or app has yet to present any frames), the return value will be current CPU time. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] frameIndex Identifies the frame the caller wishes to target. -/// A value of zero returns the next frame index. -/// \return Returns the absolute frame midpoint time for the given frameIndex. -/// \see ovr_GetTimeInSeconds -/// -OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex); - - -/// Returns global, absolute high-resolution time in seconds. -/// -/// The time frame of reference for this function is not specified and should not be -/// depended upon. -/// -/// \return Returns seconds as a floating point value. -/// \see ovrPoseStatef, ovrFrameTiming -/// -OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds(); - -#endif // !defined(OVR_EXPORTING_CAPI) - -/// Performance HUD enables the HMD user to see information critical to -/// the real-time operation of the VR application such as latency timing, -/// and CPU & GPU performance metrics -/// -/// App can toggle performance HUD modes as such: -/// \code{.cpp} -/// ovrPerfHudMode PerfHudMode = ovrPerfHud_LatencyTiming; -/// ovr_SetInt(session, OVR_PERF_HUD_MODE, (int)PerfHudMode); -/// \endcode -/// -typedef enum ovrPerfHudMode_ -{ - ovrPerfHud_Off = 0, ///< Turns off the performance HUD - ovrPerfHud_PerfSummary = 1, ///< Shows performance summary and headroom - ovrPerfHud_LatencyTiming = 2, ///< Shows latency related timing info - ovrPerfHud_AppRenderTiming = 3, ///< Shows render timing info for application - ovrPerfHud_CompRenderTiming = 4, ///< Shows render timing info for OVR compositor - ovrPerfHud_VersionInfo = 5, ///< Shows SDK & HMD version Info - ovrPerfHud_Count = 6, ///< \internal Count of enumerated elements. - ovrPerfHud_EnumSize = 0x7fffffff ///< \internal Force type int32_t. -} ovrPerfHudMode; - -/// Layer HUD enables the HMD user to see information about a layer -/// -/// App can toggle layer HUD modes as such: -/// \code{.cpp} -/// ovrLayerHudMode LayerHudMode = ovrLayerHud_Info; -/// ovr_SetInt(session, OVR_LAYER_HUD_MODE, (int)LayerHudMode); -/// \endcode -/// -typedef enum ovrLayerHudMode_ -{ - ovrLayerHud_Off = 0, ///< Turns off the layer HUD - ovrLayerHud_Info = 1, ///< Shows info about a specific layer - ovrLayerHud_EnumSize = 0x7fffffff -} ovrLayerHudMode; - -///@} - -/// Debug HUD is provided to help developers gauge and debug the fidelity of their app's -/// stereo rendering characteristics. Using the provided quad and crosshair guides, -/// the developer can verify various aspects such as VR tracking units (e.g. meters), -/// stereo camera-parallax properties (e.g. making sure objects at infinity are rendered -/// with the proper separation), measuring VR geometry sizes and distances and more. -/// -/// App can toggle the debug HUD modes as such: -/// \code{.cpp} -/// ovrDebugHudStereoMode DebugHudMode = ovrDebugHudStereo_QuadWithCrosshair; -/// ovr_SetInt(session, OVR_DEBUG_HUD_STEREO_MODE, (int)DebugHudMode); -/// \endcode -/// -/// The app can modify the visual properties of the stereo guide (i.e. quad, crosshair) -/// using the ovr_SetFloatArray function. For a list of tweakable properties, -/// see the OVR_DEBUG_HUD_STEREO_GUIDE_* keys in the OVR_CAPI_Keys.h header file. -typedef enum ovrDebugHudStereoMode_ -{ - ovrDebugHudStereo_Off = 0, ///< Turns off the Stereo Debug HUD - ovrDebugHudStereo_Quad = 1, ///< Renders Quad in world for Stereo Debugging - ovrDebugHudStereo_QuadWithCrosshair = 2, ///< Renders Quad+crosshair in world for Stereo Debugging - ovrDebugHudStereo_CrosshairAtInfinity = 3, ///< Renders screen-space crosshair at infinity for Stereo Debugging - ovrDebugHudStereo_Count, ///< \internal Count of enumerated elements - - ovrDebugHudStereo_EnumSize = 0x7fffffff ///< \internal Force type int32_t -} ovrDebugHudStereoMode; - - -#if !defined(OVR_EXPORTING_CAPI) - -// ----------------------------------------------------------------------------------- -/// @name Property Access -/// -/// These functions read and write OVR properties. Supported properties -/// are defined in OVR_CAPI_Keys.h -/// -//@{ - -/// Reads a boolean property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid for only the call. -/// \param[in] defaultVal specifes the value to return if the property couldn't be read. -/// \return Returns the property interpreted as a boolean value. Returns defaultVal if -/// the property doesn't exist. -OVR_PUBLIC_FUNCTION(ovrBool) ovr_GetBool(ovrSession session, const char* propertyName, ovrBool defaultVal); - -/// Writes or creates a boolean property. -/// If the property wasn't previously a boolean property, it is changed to a boolean property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] value The value to write. -/// \return Returns true if successful, otherwise false. A false result should only occur if the property -/// name is empty or if the property is read-only. -OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetBool(ovrSession session, const char* propertyName, ovrBool value); - - -/// Reads an integer property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] defaultVal Specifes the value to return if the property couldn't be read. -/// \return Returns the property interpreted as an integer value. Returns defaultVal if -/// the property doesn't exist. -OVR_PUBLIC_FUNCTION(int) ovr_GetInt(ovrSession session, const char* propertyName, int defaultVal); - -/// Writes or creates an integer property. -/// -/// If the property wasn't previously a boolean property, it is changed to an integer property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] value The value to write. -/// \return Returns true if successful, otherwise false. A false result should only occur if the property -/// name is empty or if the property is read-only. -OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetInt(ovrSession session, const char* propertyName, int value); - - -/// Reads a float property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] defaultVal specifes the value to return if the property couldn't be read. -/// \return Returns the property interpreted as an float value. Returns defaultVal if -/// the property doesn't exist. -OVR_PUBLIC_FUNCTION(float) ovr_GetFloat(ovrSession session, const char* propertyName, float defaultVal); - -/// Writes or creates a float property. -/// If the property wasn't previously a float property, it's changed to a float property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] value The value to write. -/// \return Returns true if successful, otherwise false. A false result should only occur if the property -/// name is empty or if the property is read-only. -OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetFloat(ovrSession session, const char* propertyName, float value); - - -/// Reads a float array property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] values An array of float to write to. -/// \param[in] valuesCapacity Specifies the maximum number of elements to write to the values array. -/// \return Returns the number of elements read, or 0 if property doesn't exist or is empty. -OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetFloatArray(ovrSession session, const char* propertyName, - float values[], unsigned int valuesCapacity); - -/// Writes or creates a float array property. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] values An array of float to write from. -/// \param[in] valuesSize Specifies the number of elements to write. -/// \return Returns true if successful, otherwise false. A false result should only occur if the property -/// name is empty or if the property is read-only. -OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetFloatArray(ovrSession session, const char* propertyName, - const float values[], unsigned int valuesSize); - - -/// Reads a string property. -/// Strings are UTF8-encoded and null-terminated. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] defaultVal Specifes the value to return if the property couldn't be read. -/// \return Returns the string property if it exists. Otherwise returns defaultVal, which can be specified as NULL. -/// The return memory is guaranteed to be valid until next call to ovr_GetString or -/// until the session is destroyed, whichever occurs first. -OVR_PUBLIC_FUNCTION(const char*) ovr_GetString(ovrSession session, const char* propertyName, - const char* defaultVal); - -/// Writes or creates a string property. -/// Strings are UTF8-encoded and null-terminated. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] propertyName The name of the property, which needs to be valid only for the call. -/// \param[in] value The string property, which only needs to be valid for the duration of the call. -/// \return Returns true if successful, otherwise false. A false result should only occur if the property -/// name is empty or if the property is read-only. -OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetString(ovrSession session, const char* propertyName, - const char* value); - -///@} - -#endif // !defined(OVR_EXPORTING_CAPI) - -#ifdef __cplusplus -} // extern "C" -#endif - - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - -/// @cond DoxygenIgnore -//----------------------------------------------------------------------------- -// ***** Compiler packing validation -// -// These checks ensure that the compiler settings being used will be compatible -// with with pre-built dynamic library provided with the runtime. - -OVR_STATIC_ASSERT(sizeof(ovrBool) == 1, "ovrBool size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrVector2i) == 4 * 2, "ovrVector2i size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrSizei) == 4 * 2, "ovrSizei size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrRecti) == sizeof(ovrVector2i) + sizeof(ovrSizei), "ovrRecti size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrQuatf) == 4 * 4, "ovrQuatf size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrVector2f) == 4 * 2, "ovrVector2f size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrVector3f) == 4 * 3, "ovrVector3f size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrMatrix4f) == 4 * 16, "ovrMatrix4f size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrPosef) == (7 * 4), "ovrPosef size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrPoseStatef) == (22 * 4), "ovrPoseStatef size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrFovPort) == (4 * 4), "ovrFovPort size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrHmdCaps) == 4, "ovrHmdCaps size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrTrackingCaps) == 4, "ovrTrackingCaps size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrEyeType) == 4, "ovrEyeType size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrHmdType) == 4, "ovrHmdType size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrTrackerDesc) == 4 + 4 + 4 + 4, "ovrTrackerDesc size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrTrackerPose) == 4 + 4 + sizeof(ovrPosef) + sizeof(ovrPosef), "ovrTrackerPose size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrTrackingState) == sizeof(ovrPoseStatef) + 4 + 4 + (sizeof(ovrPoseStatef) * 2) + (sizeof(unsigned int) * 2) + sizeof(ovrPosef) + 4, "ovrTrackingState size mismatch"); - - -//OVR_STATIC_ASSERT(sizeof(ovrTextureHeader) == sizeof(ovrRenderAPIType) + sizeof(ovrSizei), -// "ovrTextureHeader size mismatch"); -//OVR_STATIC_ASSERT(sizeof(ovrTexture) == sizeof(ovrTextureHeader) OVR_ON64(+4) + sizeof(uintptr_t) * 8, -// "ovrTexture size mismatch"); -// -OVR_STATIC_ASSERT(sizeof(ovrStatusBits) == 4, "ovrStatusBits size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrSessionStatus) == 6, "ovrSessionStatus size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrEyeRenderDesc) == sizeof(ovrEyeType) + sizeof(ovrFovPort) + sizeof(ovrRecti) + - sizeof(ovrVector2f) + sizeof(ovrVector3f), - "ovrEyeRenderDesc size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrTimewarpProjectionDesc) == 4 * 3, "ovrTimewarpProjectionDesc size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrInitFlags) == 4, "ovrInitFlags size mismatch"); -OVR_STATIC_ASSERT(sizeof(ovrLogLevel) == 4, "ovrLogLevel size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrInitParams) == 4 + 4 + sizeof(ovrLogCallback) + sizeof(uintptr_t) + 4 + 4, - "ovrInitParams size mismatch"); - -OVR_STATIC_ASSERT(sizeof(ovrHmdDesc) == - + sizeof(ovrHmdType) // Type - OVR_ON64(+ 4) // pad0 - + 64 // ProductName - + 64 // Manufacturer - + 2 // VendorId - + 2 // ProductId - + 24 // SerialNumber - + 2 // FirmwareMajor - + 2 // FirmwareMinor - + 4 * 4 // AvailableHmdCaps - DefaultTrackingCaps - + sizeof(ovrFovPort) * 2 // DefaultEyeFov - + sizeof(ovrFovPort) * 2 // MaxEyeFov - + sizeof(ovrSizei) // Resolution - + 4 // DisplayRefreshRate - OVR_ON64(+ 4) // pad1 - , "ovrHmdDesc size mismatch"); - - -// ----------------------------------------------------------------------------------- -// ***** 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 "Extras/OVR_CAPI_Util.h" -#endif - -/// @endcond - -#endif // OVR_CAPI_h diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h deleted file mode 100644 index dc61e19e..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h +++ /dev/null @@ -1,84 +0,0 @@ -/********************************************************************************//** -\file OVR_CAPI_Audio.h -\brief CAPI audio functions. -\copyright Copyright 2015 Oculus VR, LLC. All Rights reserved. -************************************************************************************/ - - -#ifndef OVR_CAPI_Audio_h -#define OVR_CAPI_Audio_h - -#ifdef _WIN32 -// Prevents <Windows.h> from defining min() and max() macro symbols. -#ifndef NOMINMAX -#define NOMINMAX -#endif -#include <windows.h> -#include "OVR_CAPI.h" -#define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128 - -#if !defined(OVR_EXPORTING_CAPI) - -/// Gets the ID of the preferred VR audio output device. -/// -/// \param[out] deviceOutId The ID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be WAVE_MAPPER. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(UINT* deviceOutId); - -/// Gets the ID of the preferred VR audio input device. -/// -/// \param[out] deviceInId The ID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be WAVE_MAPPER. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(UINT* deviceInId); - - -/// Gets the GUID of the preferred VR audio device as a string. -/// -/// \param[out] deviceOutStrBuffer A buffer where the GUID string for the device will copied to. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR deviceOutStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]); - - -/// Gets the GUID of the preferred VR audio device. -/// -/// \param[out] deviceOutGuid The GUID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be NULL. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid); - - -/// Gets the GUID of the preferred VR microphone device as a string. -/// -/// \param[out] deviceInStrBuffer A buffer where the GUID string for the device will copied to. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR deviceInStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]); - - -/// Gets the GUID of the preferred VR microphone device. -/// -/// \param[out] deviceInGuid The GUID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be NULL. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid); - -#endif // !defined(OVR_EXPORTING_CAPI) - -#endif //OVR_OS_MS - -#endif // OVR_CAPI_Audio_h diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h deleted file mode 100644 index 374dab84..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h +++ /dev/null @@ -1,158 +0,0 @@ -/********************************************************************************//** -\file OVR_CAPI_D3D.h -\brief D3D specific structures used by the CAPI interface. -\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved. -************************************************************************************/ - -#ifndef OVR_CAPI_D3D_h -#define OVR_CAPI_D3D_h - -#include "OVR_CAPI.h" -#include "OVR_Version.h" - - -#if defined (_WIN32) -#include <Unknwn.h> - -#if !defined(OVR_EXPORTING_CAPI) - -//----------------------------------------------------------------------------------- -// ***** Direct3D Specific - -/// Create Texture Swap Chain suitable for use with Direct3D 11 and 12. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with or the D3D12CommandQueue -/// which must be the same one the application renders to the eye textures with. -/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format. -/// \param[in] bindFlags Specifies what ovrTextureBindFlags the application requires for this texture chain. -/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon a successful return value, else it will be NULL. -/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// \note The texture format provided in \a desc should be thought of as the format the distortion-compositor will use for the -/// ShaderResourceView when reading the contents of the texture. To that end, it is highly recommended that the application -/// requests texture swapchain formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor -/// does sRGB-correct rendering. As such, the compositor relies on the GPU's hardware sampler to do the sRGB-to-linear -/// conversion. If the application still prefers to render to a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) while handling the -/// linear-to-gamma conversion via HLSL code, then the application must still request the corresponding sRGB format and also use -/// the \a ovrTextureMisc_DX_Typeless flag in the ovrTextureSwapChainDesc's Flag field. This will allow the application to create -/// a RenderTargetView that is the desired linear format while the compositor continues to treat it as sRGB. Failure to do so -/// will cause the compositor to apply unexpected gamma conversions leading to gamma-curve artifacts. The \a ovrTextureMisc_DX_Typeless -/// flag for depth buffer formats (e.g. OVR_FORMAT_D32_FLOAT) is ignored as they are always converted to be typeless. -/// -/// \see ovr_GetTextureSwapChainLength -/// \see ovr_GetTextureSwapChainCurrentIndex -/// \see ovr_GetTextureSwapChainDesc -/// \see ovr_GetTextureSwapChainBufferDX -/// \see ovr_DestroyTextureSwapChain -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session, - IUnknown* d3dPtr, - const ovrTextureSwapChainDesc* desc, - ovrTextureSwapChain* out_TextureSwapChain); - - -/// Get a specific buffer within the chain as any compatible COM interface (similar to QueryInterface) -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by ovr_CreateTextureSwapChainDX -/// \param[in] index Specifies the index within the chain to retrieve. Must be between 0 and length (see ovr_GetTextureSwapChainLength), -/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to GetTextureSwapChainCurrentIndex) -/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for. -/// \param[out] out_Buffer Returns the COM interface pointer retrieved. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovr_GetTextureSwapChainBufferDX(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture); -/// ovr_GetTextureSwapChainBufferDX(session, chain, 1, IID_PPV_ARGS(&dxgiResource)); -/// \endcode -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session, - ovrTextureSwapChain chain, - int index, - IID iid, - void** out_Buffer); - - -/// Create Mirror Texture which is auto-refreshed to mirror Rift contents produced by this application. -/// -/// A second call to ovr_CreateMirrorTextureDX for a given ovrSession before destroying the first one -/// is not supported and will result in an error return. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with or the D3D12CommandQueue -/// which must be the same one the application renders to the textures with. -/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format. -/// \param[out] out_MirrorTexture Returns the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL. -/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the session with ovr_Destroy. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// \note The texture format provided in \a desc should be thought of as the format the compositor will use for the RenderTargetView when -/// writing into mirror texture. To that end, it is highly recommended that the application requests a mirror texture format that is -/// in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor does sRGB-correct rendering. If however the application wants -/// to still read the mirror texture as a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) and handle the sRGB-to-linear conversion in -/// HLSL code, then it is recommended the application still requests an sRGB format and also use the \a ovrTextureMisc_DX_Typeless flag in the -/// ovrMirrorTextureDesc's Flags field. This will allow the application to bind a ShaderResourceView that is a linear format while the -/// compositor continues to treat is as sRGB. Failure to do so will cause the compositor to apply unexpected gamma conversions leading to -/// gamma-curve artifacts. -/// -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ovrMirrorTexture mirrorTexture = nullptr; -/// ovrMirrorTextureDesc mirrorDesc = {}; -/// mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; -/// mirrorDesc.Width = mirrorWindowWidth; -/// mirrorDesc.Height = mirrorWindowHeight; -/// ovrResult result = ovr_CreateMirrorTextureDX(session, d3d11Device, &mirrorDesc, &mirrorTexture); -/// [...] -/// // Destroy the texture when done with it. -/// ovr_DestroyMirrorTexture(session, mirrorTexture); -/// mirrorTexture = nullptr; -/// \endcode -/// -/// \see ovr_GetMirrorTextureBufferDX -/// \see ovr_DestroyMirrorTexture -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureDX(ovrSession session, - IUnknown* d3dPtr, - const ovrMirrorTextureDesc* desc, - ovrMirrorTexture* out_MirrorTexture); - -/// Get a the underlying buffer as any compatible COM interface (similar to QueryInterface) -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by ovr_CreateMirrorTextureDX -/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for. -/// \param[out] out_Buffer Returns the COM interface pointer retrieved. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// <b>Example code</b> -/// \code{.cpp} -/// ID3D11Texture2D* d3d11Texture = nullptr; -/// ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&d3d11Texture)); -/// d3d11DeviceContext->CopyResource(d3d11TextureBackBuffer, d3d11Texture); -/// d3d11Texture->Release(); -/// dxgiSwapChain->Present(0, 0); -/// \endcode -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session, - ovrMirrorTexture mirrorTexture, - IID iid, - void** out_Buffer); - -#endif // !defined(OVR_EXPORTING_CAPI) - -#endif // _WIN32 - -#endif // OVR_CAPI_D3D_h diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h deleted file mode 100644 index 1c073f46..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h +++ /dev/null @@ -1,102 +0,0 @@ -/********************************************************************************//** -\file OVR_CAPI_GL.h -\brief OpenGL-specific structures used by the CAPI interface. -\copyright Copyright 2015 Oculus VR, LLC. All Rights reserved. -************************************************************************************/ - -#ifndef OVR_CAPI_GL_h -#define OVR_CAPI_GL_h - -#include "OVR_CAPI.h" - -#if !defined(OVR_EXPORTING_CAPI) - -/// Creates a TextureSwapChain suitable for use with OpenGL. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] desc Specifies the requested texture properties. See notes for more info about texture format. -/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon -/// a successful return value, else it will be NULL. This texture swap chain must be eventually -/// destroyed via ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// \note The \a format provided should be thought of as the format the distortion compositor will use when reading -/// the contents of the texture. To that end, it is highly recommended that the application requests texture swap chain -/// formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the distortion compositor does sRGB-correct -/// rendering. Furthermore, the app should then make sure "glEnable(GL_FRAMEBUFFER_SRGB);" is called before rendering -/// into these textures. Even though it is not recommended, if the application would like to treat the texture as a linear -/// format and do linear-to-gamma conversion in GLSL, then the application can avoid calling "glEnable(GL_FRAMEBUFFER_SRGB);", -/// but should still pass in an sRGB variant for the \a format. Failure to do so will cause the distortion compositor -/// to apply incorrect gamma conversions leading to gamma-curve artifacts. -/// -/// \see ovr_GetTextureSwapChainLength -/// \see ovr_GetTextureSwapChainCurrentIndex -/// \see ovr_GetTextureSwapChainDesc -/// \see ovr_GetTextureSwapChainBufferGL -/// \see ovr_DestroyTextureSwapChain -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainGL(ovrSession session, - const ovrTextureSwapChainDesc* desc, - ovrTextureSwapChain* out_TextureSwapChain); - -/// Get a specific buffer within the chain as a GL texture name -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by ovr_CreateTextureSwapChainGL -/// \param[in] index Specifies the index within the chain to retrieve. Must be between 0 and length (see ovr_GetTextureSwapChainLength) -/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to GetTextureSwapChainCurrentIndex) -/// \param[out] out_TexId Returns the GL texture object name associated with the specific index requested -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferGL(ovrSession session, - ovrTextureSwapChain chain, - int index, - unsigned int* out_TexId); - - -/// Creates a Mirror Texture which is auto-refreshed to mirror Rift contents produced by this application. -/// -/// A second call to ovr_CreateMirrorTextureGL for a given ovrSession before destroying the first one -/// is not supported and will result in an error return. -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] desc Specifies the requested mirror texture description. -/// \param[out] out_MirrorTexture Specifies the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL. -/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the session with ovr_Destroy. -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -/// \note The \a format provided should be thought of as the format the distortion compositor will use when writing into the mirror -/// texture. It is highly recommended that mirror textures are requested as sRGB formats because the distortion compositor -/// does sRGB-correct rendering. If the application requests a non-sRGB format (e.g. R8G8B8A8_UNORM) as the mirror texture, -/// then the application might have to apply a manual linear-to-gamma conversion when reading from the mirror texture. -/// Failure to do so can result in incorrect gamma conversions leading to gamma-curve artifacts and color banding. -/// -/// \see ovr_GetMirrorTextureBufferGL -/// \see ovr_DestroyMirrorTexture -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureGL(ovrSession session, - const ovrMirrorTextureDesc* desc, - ovrMirrorTexture* out_MirrorTexture); - -/// Get a the underlying buffer as a GL texture name -/// -/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. -/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by ovr_CreateMirrorTextureGL -/// \param[out] out_TexId Specifies the GL texture object name associated with the mirror texture -/// -/// \return Returns an ovrResult indicating success or failure. In the case of failure, use -/// ovr_GetLastErrorInfo to get more information. -/// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferGL(ovrSession session, - ovrMirrorTexture mirrorTexture, - unsigned int* out_TexId); - -#endif // !defined(OVR_EXPORTING_CAPI) - -#endif // OVR_CAPI_GL_h diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Keys.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Keys.h deleted file mode 100644 index e3e9d689..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Keys.h +++ /dev/null @@ -1,53 +0,0 @@ -/********************************************************************************//** -\file OVR_CAPI.h -\brief Keys for CAPI proprty function calls -\copyright Copyright 2015 Oculus VR, LLC All Rights reserved. -************************************************************************************/ - -#ifndef OVR_CAPI_Keys_h -#define OVR_CAPI_Keys_h - -#include "OVR_Version.h" - - - -#define OVR_KEY_USER "User" // string - -#define OVR_KEY_NAME "Name" // string - -#define OVR_KEY_GENDER "Gender" // string "Male", "Female", or "Unknown" -#define OVR_DEFAULT_GENDER "Unknown" - -#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" // float meters -#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f - -#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters -#define OVR_DEFAULT_EYE_HEIGHT 1.675f - -#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" // float[2] meters -#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f -#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f - - -#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" // float[2] meters - - - - - -#define OVR_PERF_HUD_MODE "PerfHudMode" // int, allowed values are defined in enum ovrPerfHudMode - -#define OVR_LAYER_HUD_MODE "LayerHudMode" // int, allowed values are defined in enum ovrLayerHudMode -#define OVR_LAYER_HUD_CURRENT_LAYER "LayerHudCurrentLayer" // int, The layer to show -#define OVR_LAYER_HUD_SHOW_ALL_LAYERS "LayerHudShowAll" // bool, Hide other layers when the hud is enabled - -#define OVR_DEBUG_HUD_STEREO_MODE "DebugHudStereoMode" // int, allowed values are defined in enum ovrDebugHudStereoMode -#define OVR_DEBUG_HUD_STEREO_GUIDE_INFO_ENABLE "DebugHudStereoGuideInfoEnable" // bool -#define OVR_DEBUG_HUD_STEREO_GUIDE_SIZE "DebugHudStereoGuideSize2f" // float[2] -#define OVR_DEBUG_HUD_STEREO_GUIDE_POSITION "DebugHudStereoGuidePosition3f" // float[3] -#define OVR_DEBUG_HUD_STEREO_GUIDE_YAWPITCHROLL "DebugHudStereoGuideYawPitchRoll3f" // float[3] -#define OVR_DEBUG_HUD_STEREO_GUIDE_COLOR "DebugHudStereoGuideColor4f" // float[4] - - - -#endif // OVR_CAPI_Keys_h diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h b/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h deleted file mode 100644 index a8b810ea..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h +++ /dev/null @@ -1,156 +0,0 @@ -/********************************************************************************//** -\file OVR_ErrorCode.h -\brief This header provides LibOVR error code declarations. -\copyright Copyright 2015-2016 Oculus VR, LLC All Rights reserved. -*************************************************************************************/ - -#ifndef OVR_ErrorCode_h -#define OVR_ErrorCode_h - - -#include "OVR_Version.h" -#include <stdint.h> - - - - -#ifndef OVR_RESULT_DEFINED -#define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined. -/// API call results are represented at the highest level by a single ovrResult. -typedef int32_t ovrResult; -#endif - - -/// \brief Indicates if an ovrResult indicates success. -/// -/// Some functions return additional successful values other than ovrSucces and -/// require usage of this macro to indicate successs. -/// -#if !defined(OVR_SUCCESS) - #define OVR_SUCCESS(result) (result >= 0) -#endif - - -/// \brief Indicates if an ovrResult indicates an unqualified success. -/// -/// This is useful for indicating that the code intentionally wants to -/// check for result == ovrSuccess as opposed to OVR_SUCCESS(), which -/// checks for result >= ovrSuccess. -/// -#if !defined(OVR_UNQUALIFIED_SUCCESS) - #define OVR_UNQUALIFIED_SUCCESS(result) (result == ovrSuccess) -#endif - - -/// \brief Indicates if an ovrResult indicates failure. -/// -#if !defined(OVR_FAILURE) - #define OVR_FAILURE(result) (!OVR_SUCCESS(result)) -#endif - - -// Success is a value greater or equal to 0, while all error types are negative values. -#ifndef OVR_SUCCESS_DEFINED -#define OVR_SUCCESS_DEFINED ///< Allows ovrResult to be independently defined. -typedef enum ovrSuccessType_ -{ - /// This is a general success result. Use OVR_SUCCESS to test for success. - ovrSuccess = 0, -} ovrSuccessType; -#endif - -// Public success types -// Success is a value greater or equal to 0, while all error types are negative values. -typedef enum ovrSuccessTypes_ -{ - /// Returned from a call to SubmitFrame. The call succeeded, but what the app - /// rendered will not be visible on the HMD. Ideally the app should continue - /// calling SubmitFrame, but not do any rendering. When the result becomes - /// ovrSuccess, rendering should continue as usual. - ovrSuccess_NotVisible = 1000, - -} ovrSuccessTypes; - -// Public error types -typedef enum ovrErrorType_ -{ - /* General errors */ - ovrError_MemoryAllocationFailure = -1000, ///< Failure to allocate memory. - ovrError_InvalidSession = -1002, ///< Invalid ovrSession parameter provided. - ovrError_Timeout = -1003, ///< The operation timed out. - ovrError_NotInitialized = -1004, ///< The system or component has not been initialized. - ovrError_InvalidParameter = -1005, ///< Invalid parameter provided. See error info or log for details. - ovrError_ServiceError = -1006, ///< Generic service error. See error info or log for details. - ovrError_NoHmd = -1007, ///< The given HMD doesn't exist. - ovrError_Unsupported = -1009, ///< Function call is not supported on this hardware/software - ovrError_DeviceUnavailable = -1010, ///< Specified device type isn't available. - ovrError_InvalidHeadsetOrientation = -1011, ///< The headset was in an invalid orientation for the requested operation (e.g. vertically oriented during ovr_RecenterPose). - ovrError_ClientSkippedDestroy = -1012, ///< The client failed to call ovr_Destroy on an active session before calling ovr_Shutdown. Or the client crashed. - ovrError_ClientSkippedShutdown = -1013, ///< The client failed to call ovr_Shutdown or the client crashed. - ovrError_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock. - ovrError_InvalidOperation = -1015, ///< Function call is invalid for object's current state - - /* Audio error range, reserved for Audio errors. */ - ovrError_AudioDeviceNotFound = -2001, ///< Failure to find the specified audio device. - ovrError_AudioComError = -2002, ///< Generic COM error. - - /* Initialization errors. */ - ovrError_Initialize = -3000, ///< Generic initialization error. - ovrError_LibLoad = -3001, ///< Couldn't load LibOVRRT. - ovrError_LibVersion = -3002, ///< LibOVRRT version incompatibility. - ovrError_ServiceConnection = -3003, ///< Couldn't connect to the OVR Service. - ovrError_ServiceVersion = -3004, ///< OVR Service version incompatibility. - ovrError_IncompatibleOS = -3005, ///< The operating system version is incompatible. - ovrError_DisplayInit = -3006, ///< Unable to initialize the HMD display. - ovrError_ServerStart = -3007, ///< Unable to start the server. Is it already running? - ovrError_Reinitialization = -3008, ///< Attempting to re-initialize with a different version. - ovrError_MismatchedAdapters = -3009, ///< Chosen rendering adapters between client and service do not match - ovrError_LeakingResources = -3010, ///< Calling application has leaked resources - ovrError_ClientVersion = -3011, ///< Client version too old to connect to service - ovrError_OutOfDateOS = -3012, ///< The operating system is out of date. - ovrError_OutOfDateGfxDriver = -3013, ///< The graphics driver is out of date. - ovrError_IncompatibleGPU = -3014, ///< The graphics hardware is not supported - ovrError_NoValidVRDisplaySystem = -3015, ///< No valid VR display system found. - ovrError_Obsolete = -3016, ///< Feature or API is obsolete and no longer supported. - ovrError_DisabledOrDefaultAdapter = -3017, ///< No supported VR display system found, but disabled or driverless adapter found. - ovrError_HybridGraphicsNotSupported = -3018, ///< The system is using hybrid graphics (Optimus, etc...), which is not support. - ovrError_DisplayManagerInit = -3019, ///< Initialization of the DisplayManager failed. - ovrError_TrackerDriverInit = -3020, ///< Failed to get the interface for an attached tracker - ovrError_LibSignCheck = -3021, ///< LibOVRRT signature check failure. - ovrError_LibPath = -3022, ///< LibOVRRT path failure. - ovrError_LibSymbols = -3023, ///< LibOVRRT symbol resolution failure. - - /* Rendering errors */ - ovrError_DisplayLost = -6000, ///< In the event of a system-wide graphics reset or cable unplug this is returned to the app. - ovrError_TextureSwapChainFull = -6001, ///< ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain. - ovrError_TextureSwapChainInvalid = -6002, ///< The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first. - ovrError_GraphicsDeviceReset = -6003, ///< Graphics device has been reset (TDR, etc...) - ovrError_DisplayRemoved = -6004, ///< HMD removed from the display adapter - ovrError_ContentProtectionNotAvailable = -6005,///<Content protection is not available for the display - ovrError_ApplicationInvisible = -6006, ///< Application declared itself as an invisible type and is not allowed to submit frames. - ovrError_Disallowed = -6007, ///< The given request is disallowed under the current conditions. - ovrError_DisplayPluggedIncorrectly = -6008, ///< Display portion of HMD is plugged into an incompatible port (ex: IGP) - - /* Fatal errors */ - ovrError_RuntimeException = -7000, ///< A runtime exception occurred. The application is required to shutdown LibOVR and re-initialize it before this error state will be cleared. - - /* Calibration errors */ - ovrError_NoCalibration = -9000, ///< Result of a missing calibration block - ovrError_OldVersion = -9001, ///< Result of an old calibration block - ovrError_MisformattedBlock = -9002, ///< Result of a bad calibration block due to lengths - - -} ovrErrorType; - - - -/// Provides information about the last error. -/// \see ovr_GetLastErrorInfo -typedef struct ovrErrorInfo_ -{ - ovrResult Result; ///< The result from the last API call that generated an error ovrResult. - char ErrorString[512]; ///< A UTF8-encoded null-terminated English string describing the problem. The format of this string is subject to change in future versions. -} ovrErrorInfo; - - -#endif /* OVR_ErrorCode_h */ diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h b/src/external/OculusSDK/LibOVR/Include/OVR_Version.h deleted file mode 100644 index 8d213df5..00000000 --- a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h +++ /dev/null @@ -1,60 +0,0 @@ -/********************************************************************************//** -\file OVR_Version.h -\brief This header provides LibOVR version identification. -\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved. -*************************************************************************************/ - -#ifndef OVR_Version_h -#define OVR_Version_h - - - -/// Conventional string-ification macro. -#if !defined(OVR_STRINGIZE) - #define OVR_STRINGIZEIMPL(x) #x - #define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) -#endif - - -// Master version numbers -#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning. -#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel. -#define OVR_MINOR_VERSION 7 // -#define OVR_PATCH_VERSION 0 -#define OVR_BUILD_NUMBER 0 - -// This is the ((product * 100) + major) version of the service that the DLL is compatible with. -// When we backport changes to old versions of the DLL we update the old DLLs -// to move this version number up to the latest version. -// The DLL is responsible for checking that the service is the version it supports -// and returning an appropriate error message if it has not been made compatible. -#define OVR_DLL_COMPATIBLE_VERSION 101 - -#define OVR_FEATURE_VERSION 0 - - -/// "Major.Minor.Patch" -#if !defined(OVR_VERSION_STRING) - #define OVR_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION) -#endif - - -/// "Major.Minor.Patch.Build" -#if !defined(OVR_DETAILED_VERSION_STRING) - #define OVR_DETAILED_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION.OVR_BUILD_NUMBER) -#endif - - -/// \brief file description for version info -/// 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 "dev build debug" - #else - #define OVR_FILE_DESCRIPTION_STRING "dev build" - #endif -#endif - - -#endif // OVR_Version_h diff --git a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll b/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll Binary files differdeleted file mode 100644 index 7a42d443..00000000 --- a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll +++ /dev/null diff --git a/src/external/android/native_app_glue/Android.mk b/src/external/android/native_app_glue/Android.mk new file mode 100644 index 00000000..00252fcb --- /dev/null +++ b/src/external/android/native_app_glue/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE:= android_native_app_glue +LOCAL_SRC_FILES:= android_native_app_glue.c +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) +LOCAL_EXPORT_LDLIBS := -llog + +include $(BUILD_STATIC_LIBRARY) diff --git a/src/external/android/native_app_glue/NOTICE b/src/external/android/native_app_glue/NOTICE new file mode 100644 index 00000000..d6c09229 --- /dev/null +++ b/src/external/android/native_app_glue/NOTICE @@ -0,0 +1,13 @@ +Copyright (C) 2016 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +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. diff --git a/src/external/android/native_app_glue/android_native_app_glue.c b/src/external/android/native_app_glue/android_native_app_glue.c new file mode 100644 index 00000000..d503d8da --- /dev/null +++ b/src/external/android/native_app_glue/android_native_app_glue.c @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 <jni.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/resource.h> + +#include "android_native_app_glue.h" +#include <android/log.h> + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__)) + +/* For debug builds, always enable the debug traces in this library */ +#ifndef NDEBUG +# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__)) +#else +# define LOGV(...) ((void)0) +#endif + +static void free_saved_state(struct android_app* android_app) { + pthread_mutex_lock(&android_app->mutex); + if (android_app->savedState != NULL) { + free(android_app->savedState); + android_app->savedState = NULL; + android_app->savedStateSize = 0; + } + pthread_mutex_unlock(&android_app->mutex); +} + +int8_t android_app_read_cmd(struct android_app* android_app) { + int8_t cmd; + if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { + switch (cmd) { + case APP_CMD_SAVE_STATE: + free_saved_state(android_app); + break; + } + return cmd; + } else { + LOGE("No data on command pipe!"); + } + return -1; +} + +static void print_cur_config(struct android_app* android_app) { + char lang[2], country[2]; + AConfiguration_getLanguage(android_app->config, lang); + AConfiguration_getCountry(android_app->config, country); + + LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " + "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " + "modetype=%d modenight=%d", + AConfiguration_getMcc(android_app->config), + AConfiguration_getMnc(android_app->config), + lang[0], lang[1], country[0], country[1], + AConfiguration_getOrientation(android_app->config), + AConfiguration_getTouchscreen(android_app->config), + AConfiguration_getDensity(android_app->config), + AConfiguration_getKeyboard(android_app->config), + AConfiguration_getNavigation(android_app->config), + AConfiguration_getKeysHidden(android_app->config), + AConfiguration_getNavHidden(android_app->config), + AConfiguration_getSdkVersion(android_app->config), + AConfiguration_getScreenSize(android_app->config), + AConfiguration_getScreenLong(android_app->config), + AConfiguration_getUiModeType(android_app->config), + AConfiguration_getUiModeNight(android_app->config)); +} + +void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { + switch (cmd) { + case APP_CMD_INPUT_CHANGED: + LOGV("APP_CMD_INPUT_CHANGED\n"); + pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) { + AInputQueue_detachLooper(android_app->inputQueue); + } + android_app->inputQueue = android_app->pendingInputQueue; + if (android_app->inputQueue != NULL) { + LOGV("Attaching input queue to looper"); + AInputQueue_attachLooper(android_app->inputQueue, + android_app->looper, LOOPER_ID_INPUT, NULL, + &android_app->inputPollSource); + } + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_INIT_WINDOW: + LOGV("APP_CMD_INIT_WINDOW\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->window = android_app->pendingWindow; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_TERM_WINDOW: + LOGV("APP_CMD_TERM_WINDOW\n"); + pthread_cond_broadcast(&android_app->cond); + break; + + case APP_CMD_RESUME: + case APP_CMD_START: + case APP_CMD_PAUSE: + case APP_CMD_STOP: + LOGV("activityState=%d\n", cmd); + pthread_mutex_lock(&android_app->mutex); + android_app->activityState = cmd; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_CONFIG_CHANGED: + LOGV("APP_CMD_CONFIG_CHANGED\n"); + AConfiguration_fromAssetManager(android_app->config, + android_app->activity->assetManager); + print_cur_config(android_app); + break; + + case APP_CMD_DESTROY: + LOGV("APP_CMD_DESTROY\n"); + android_app->destroyRequested = 1; + break; + } +} + +void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) { + switch (cmd) { + case APP_CMD_TERM_WINDOW: + LOGV("APP_CMD_TERM_WINDOW\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->window = NULL; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_SAVE_STATE: + LOGV("APP_CMD_SAVE_STATE\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->stateSaved = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_RESUME: + free_saved_state(android_app); + break; + } +} + +void app_dummy() { + +} + +static void android_app_destroy(struct android_app* android_app) { + LOGV("android_app_destroy!"); + free_saved_state(android_app); + pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) { + AInputQueue_detachLooper(android_app->inputQueue); + } + AConfiguration_delete(android_app->config); + android_app->destroyed = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + // Can't touch android_app object after this. +} + +static void process_input(struct android_app* app, struct android_poll_source* source) { + AInputEvent* event = NULL; + while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { + LOGV("New input event: type=%d\n", AInputEvent_getType(event)); + if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { + continue; + } + int32_t handled = 0; + if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); + AInputQueue_finishEvent(app->inputQueue, event, handled); + } +} + +static void process_cmd(struct android_app* app, struct android_poll_source* source) { + int8_t cmd = android_app_read_cmd(app); + android_app_pre_exec_cmd(app, cmd); + if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); + android_app_post_exec_cmd(app, cmd); +} + +static void* android_app_entry(void* param) { + struct android_app* android_app = (struct android_app*)param; + + android_app->config = AConfiguration_new(); + AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); + + print_cur_config(android_app); + + android_app->cmdPollSource.id = LOOPER_ID_MAIN; + android_app->cmdPollSource.app = android_app; + android_app->cmdPollSource.process = process_cmd; + android_app->inputPollSource.id = LOOPER_ID_INPUT; + android_app->inputPollSource.app = android_app; + android_app->inputPollSource.process = process_input; + + ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, + &android_app->cmdPollSource); + android_app->looper = looper; + + pthread_mutex_lock(&android_app->mutex); + android_app->running = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + + android_main(android_app); + + android_app_destroy(android_app); + return NULL; +} + +// -------------------------------------------------------------------- +// Native activity interaction (called from main thread) +// -------------------------------------------------------------------- + +static struct android_app* android_app_create(ANativeActivity* activity, + void* savedState, size_t savedStateSize) { + struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); + memset(android_app, 0, sizeof(struct android_app)); + android_app->activity = activity; + + pthread_mutex_init(&android_app->mutex, NULL); + pthread_cond_init(&android_app->cond, NULL); + + if (savedState != NULL) { + android_app->savedState = malloc(savedStateSize); + android_app->savedStateSize = savedStateSize; + memcpy(android_app->savedState, savedState, savedStateSize); + } + + int msgpipe[2]; + if (pipe(msgpipe)) { + LOGE("could not create pipe: %s", strerror(errno)); + return NULL; + } + android_app->msgread = msgpipe[0]; + android_app->msgwrite = msgpipe[1]; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&android_app->thread, &attr, android_app_entry, android_app); + + // Wait for thread to start. + pthread_mutex_lock(&android_app->mutex); + while (!android_app->running) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); + + return android_app; +} + +static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { + if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { + LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); + } +} + +static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { + pthread_mutex_lock(&android_app->mutex); + android_app->pendingInputQueue = inputQueue; + android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); + while (android_app->inputQueue != android_app->pendingInputQueue) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { + pthread_mutex_lock(&android_app->mutex); + if (android_app->pendingWindow != NULL) { + android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); + } + android_app->pendingWindow = window; + if (window != NULL) { + android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); + } + while (android_app->window != android_app->pendingWindow) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { + pthread_mutex_lock(&android_app->mutex); + android_app_write_cmd(android_app, cmd); + while (android_app->activityState != cmd) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_free(struct android_app* android_app) { + pthread_mutex_lock(&android_app->mutex); + android_app_write_cmd(android_app, APP_CMD_DESTROY); + while (!android_app->destroyed) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); + + close(android_app->msgread); + close(android_app->msgwrite); + pthread_cond_destroy(&android_app->cond); + pthread_mutex_destroy(&android_app->mutex); + free(android_app); +} + +static void onDestroy(ANativeActivity* activity) { + LOGV("Destroy: %p\n", activity); + android_app_free((struct android_app*)activity->instance); +} + +static void onStart(ANativeActivity* activity) { + LOGV("Start: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); +} + +static void onResume(ANativeActivity* activity) { + LOGV("Resume: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); +} + +static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { + struct android_app* android_app = (struct android_app*)activity->instance; + void* savedState = NULL; + + LOGV("SaveInstanceState: %p\n", activity); + pthread_mutex_lock(&android_app->mutex); + android_app->stateSaved = 0; + android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); + while (!android_app->stateSaved) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + + if (android_app->savedState != NULL) { + savedState = android_app->savedState; + *outLen = android_app->savedStateSize; + android_app->savedState = NULL; + android_app->savedStateSize = 0; + } + + pthread_mutex_unlock(&android_app->mutex); + + return savedState; +} + +static void onPause(ANativeActivity* activity) { + LOGV("Pause: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); +} + +static void onStop(ANativeActivity* activity) { + LOGV("Stop: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); +} + +static void onConfigurationChanged(ANativeActivity* activity) { + struct android_app* android_app = (struct android_app*)activity->instance; + LOGV("ConfigurationChanged: %p\n", activity); + android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); +} + +static void onLowMemory(ANativeActivity* activity) { + struct android_app* android_app = (struct android_app*)activity->instance; + LOGV("LowMemory: %p\n", activity); + android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); +} + +static void onWindowFocusChanged(ANativeActivity* activity, int focused) { + LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); + android_app_write_cmd((struct android_app*)activity->instance, + focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); +} + +static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { + LOGV("NativeWindowCreated: %p -- %p\n", activity, window); + android_app_set_window((struct android_app*)activity->instance, window); +} + +static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { + LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); + android_app_set_window((struct android_app*)activity->instance, NULL); +} + +static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { + LOGV("InputQueueCreated: %p -- %p\n", activity, queue); + android_app_set_input((struct android_app*)activity->instance, queue); +} + +static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { + LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); + android_app_set_input((struct android_app*)activity->instance, NULL); +} + +void ANativeActivity_onCreate(ANativeActivity* activity, + void* savedState, size_t savedStateSize) { + LOGV("Creating: %p\n", activity); + activity->callbacks->onDestroy = onDestroy; + activity->callbacks->onStart = onStart; + activity->callbacks->onResume = onResume; + activity->callbacks->onSaveInstanceState = onSaveInstanceState; + activity->callbacks->onPause = onPause; + activity->callbacks->onStop = onStop; + activity->callbacks->onConfigurationChanged = onConfigurationChanged; + activity->callbacks->onLowMemory = onLowMemory; + activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; + activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; + activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; + activity->callbacks->onInputQueueCreated = onInputQueueCreated; + activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; + + activity->instance = android_app_create(activity, savedState, savedStateSize); +} diff --git a/src/external/android/native_app_glue/android_native_app_glue.h b/src/external/android/native_app_glue/android_native_app_glue.h new file mode 100644 index 00000000..97202e09 --- /dev/null +++ b/src/external/android/native_app_glue/android_native_app_glue.h @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 _ANDROID_NATIVE_APP_GLUE_H +#define _ANDROID_NATIVE_APP_GLUE_H + +#include <poll.h> +#include <pthread.h> +#include <sched.h> + +#include <android/configuration.h> +#include <android/looper.h> +#include <android/native_activity.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The native activity interface provided by <android/native_activity.h> + * is based on a set of application-provided callbacks that will be called + * by the Activity's main thread when certain events occur. + * + * This means that each one of this callbacks _should_ _not_ block, or they + * risk having the system force-close the application. This programming + * model is direct, lightweight, but constraining. + * + * The 'android_native_app_glue' static library is used to provide a different + * execution model where the application can implement its own main event + * loop in a different thread instead. Here's how it works: + * + * 1/ The application must provide a function named "android_main()" that + * will be called when the activity is created, in a new thread that is + * distinct from the activity's main thread. + * + * 2/ android_main() receives a pointer to a valid "android_app" structure + * that contains references to other important objects, e.g. the + * ANativeActivity obejct instance the application is running in. + * + * 3/ the "android_app" object holds an ALooper instance that already + * listens to two important things: + * + * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX + * declarations below. + * + * - input events coming from the AInputQueue attached to the activity. + * + * Each of these correspond to an ALooper identifier returned by + * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT, + * respectively. + * + * Your application can use the same ALooper to listen to additional + * file-descriptors. They can either be callback based, or with return + * identifiers starting with LOOPER_ID_USER. + * + * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event, + * the returned data will point to an android_poll_source structure. You + * can call the process() function on it, and fill in android_app->onAppCmd + * and android_app->onInputEvent to be called for your own processing + * of the event. + * + * Alternatively, you can call the low-level functions to read and process + * the data directly... look at the process_cmd() and process_input() + * implementations in the glue to see how to do this. + * + * See the sample named "native-activity" that comes with the NDK with a + * full usage example. Also look at the JavaDoc of NativeActivity. + */ + +struct android_app; + +/** + * Data associated with an ALooper fd that will be returned as the "outData" + * when that source has data ready. + */ +struct android_poll_source { + // The identifier of this source. May be LOOPER_ID_MAIN or + // LOOPER_ID_INPUT. + int32_t id; + + // The android_app this ident is associated with. + struct android_app* app; + + // Function to call to perform the standard processing of data from + // this source. + void (*process)(struct android_app* app, struct android_poll_source* source); +}; + +/** + * This is the interface for the standard glue code of a threaded + * application. In this model, the application's code is running + * in its own thread separate from the main thread of the process. + * It is not required that this thread be associated with the Java + * VM, although it will need to be in order to make JNI calls any + * Java objects. + */ +struct android_app { + // The application can place a pointer to its own state object + // here if it likes. + void* userData; + + // Fill this in with the function to process main app commands (APP_CMD_*) + void (*onAppCmd)(struct android_app* app, int32_t cmd); + + // Fill this in with the function to process input events. At this point + // the event has already been pre-dispatched, and it will be finished upon + // return. Return 1 if you have handled the event, 0 for any default + // dispatching. + int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); + + // The ANativeActivity object instance that this app is running in. + ANativeActivity* activity; + + // The current configuration the app is running in. + AConfiguration* config; + + // This is the last instance's saved state, as provided at creation time. + // It is NULL if there was no state. You can use this as you need; the + // memory will remain around until you call android_app_exec_cmd() for + // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. + // These variables should only be changed when processing a APP_CMD_SAVE_STATE, + // at which point they will be initialized to NULL and you can malloc your + // state and place the information here. In that case the memory will be + // freed for you later. + void* savedState; + size_t savedStateSize; + + // The ALooper associated with the app's thread. + ALooper* looper; + + // When non-NULL, this is the input queue from which the app will + // receive user input events. + AInputQueue* inputQueue; + + // When non-NULL, this is the window surface that the app can draw in. + ANativeWindow* window; + + // Current content rectangle of the window; this is the area where the + // window's content should be placed to be seen by the user. + ARect contentRect; + + // Current state of the app's activity. May be either APP_CMD_START, + // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. + int activityState; + + // This is non-zero when the application's NativeActivity is being + // destroyed and waiting for the app thread to complete. + int destroyRequested; + + // ------------------------------------------------- + // Below are "private" implementation of the glue code. + + pthread_mutex_t mutex; + pthread_cond_t cond; + + int msgread; + int msgwrite; + + pthread_t thread; + + struct android_poll_source cmdPollSource; + struct android_poll_source inputPollSource; + + int running; + int stateSaved; + int destroyed; + int redrawNeeded; + AInputQueue* pendingInputQueue; + ANativeWindow* pendingWindow; + ARect pendingContentRect; +}; + +enum { + /** + * Looper data ID of commands coming from the app's main thread, which + * is returned as an identifier from ALooper_pollOnce(). The data for this + * identifier is a pointer to an android_poll_source structure. + * These can be retrieved and processed with android_app_read_cmd() + * and android_app_exec_cmd(). + */ + LOOPER_ID_MAIN = 1, + + /** + * Looper data ID of events coming from the AInputQueue of the + * application's window, which is returned as an identifier from + * ALooper_pollOnce(). The data for this identifier is a pointer to an + * android_poll_source structure. These can be read via the inputQueue + * object of android_app. + */ + LOOPER_ID_INPUT = 2, + + /** + * Start of user-defined ALooper identifiers. + */ + LOOPER_ID_USER = 3, +}; + +enum { + /** + * Command from main thread: the AInputQueue has changed. Upon processing + * this command, android_app->inputQueue will be updated to the new queue + * (or NULL). + */ + APP_CMD_INPUT_CHANGED, + + /** + * Command from main thread: a new ANativeWindow is ready for use. Upon + * receiving this command, android_app->window will contain the new window + * surface. + */ + APP_CMD_INIT_WINDOW, + + /** + * Command from main thread: the existing ANativeWindow needs to be + * terminated. Upon receiving this command, android_app->window still + * contains the existing window; after calling android_app_exec_cmd + * it will be set to NULL. + */ + APP_CMD_TERM_WINDOW, + + /** + * Command from main thread: the current ANativeWindow has been resized. + * Please redraw with its new size. + */ + APP_CMD_WINDOW_RESIZED, + + /** + * Command from main thread: the system needs that the current ANativeWindow + * be redrawn. You should redraw the window before handing this to + * android_app_exec_cmd() in order to avoid transient drawing glitches. + */ + APP_CMD_WINDOW_REDRAW_NEEDED, + + /** + * Command from main thread: the content area of the window has changed, + * such as from the soft input window being shown or hidden. You can + * find the new content rect in android_app::contentRect. + */ + APP_CMD_CONTENT_RECT_CHANGED, + + /** + * Command from main thread: the app's activity window has gained + * input focus. + */ + APP_CMD_GAINED_FOCUS, + + /** + * Command from main thread: the app's activity window has lost + * input focus. + */ + APP_CMD_LOST_FOCUS, + + /** + * Command from main thread: the current device configuration has changed. + */ + APP_CMD_CONFIG_CHANGED, + + /** + * Command from main thread: the system is running low on memory. + * Try to reduce your memory use. + */ + APP_CMD_LOW_MEMORY, + + /** + * Command from main thread: the app's activity has been started. + */ + APP_CMD_START, + + /** + * Command from main thread: the app's activity has been resumed. + */ + APP_CMD_RESUME, + + /** + * Command from main thread: the app should generate a new saved state + * for itself, to restore from later if needed. If you have saved state, + * allocate it with malloc and place it in android_app.savedState with + * the size in android_app.savedStateSize. The will be freed for you + * later. + */ + APP_CMD_SAVE_STATE, + + /** + * Command from main thread: the app's activity has been paused. + */ + APP_CMD_PAUSE, + + /** + * Command from main thread: the app's activity has been stopped. + */ + APP_CMD_STOP, + + /** + * Command from main thread: the app's activity is being destroyed, + * and waiting for the app thread to clean up and exit before proceeding. + */ + APP_CMD_DESTROY, +}; + +/** + * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next + * app command message. + */ +int8_t android_app_read_cmd(struct android_app* android_app); + +/** + * Call with the command returned by android_app_read_cmd() to do the + * initial pre-processing of the given command. You can perform your own + * actions for the command after calling this function. + */ +void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); + +/** + * Call with the command returned by android_app_read_cmd() to do the + * final post-processing of the given command. You must have done your own + * actions for the command before calling this function. + */ +void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); + +/** + * Dummy function you can call to ensure glue code isn't stripped. + */ +void app_dummy(); + +/** + * This is the function that application code must implement, representing + * the main entry to the app. + */ +extern void android_main(struct android_app* app); + +#ifdef __cplusplus +} +#endif + +#endif /* _ANDROID_NATIVE_APP_GLUE_H */ diff --git a/src/external/gif.h b/src/external/gif.h new file mode 100644 index 00000000..1c0aeb18 --- /dev/null +++ b/src/external/gif.h @@ -0,0 +1,931 @@ +/********************************************************************************************** +* +* gif.h by Charlie Tangora [ctangora -at- gmail -dot- com] +* adapted to C99 and reformatted by Ramon Santamaria (@raysan5) +* +* This file offers a simple, very limited way to create animated GIFs directly in code. +* +* Those looking for particular cleverness are likely to be disappointed; it's pretty +* much a straight-ahead implementation of the GIF format with optional Floyd-Steinberg +* dithering. (It does at least use delta encoding - only the changed portions of each +* frame are saved.) +* +* So resulting files are often quite large. The hope is that it will be handy nonetheless +* as a quick and easily-integrated way for programs to spit out animations. +* +* Only RGBA8 is currently supported as an input format. (The alpha is ignored.) +* +* CONFIGURATION: +* +* #define GIF_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* USAGE: +* 1) Create a GifWriter struct. Pass it to GifBegin() to initialize and write the header. +* 2) Pass subsequent frames to GifWriteFrame(). +* 3) Finally, call GifEnd() to close the file handle and free memory. +* +* +* LICENSE: public domain (www.unlicense.org) +* +* This is free and unencumbered software released into the public domain. +* Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +* software, either in source code form or as a compiled binary, for any purpose, +* commercial or non-commercial, and by any means. +* +* In jurisdictions that recognize copyright laws, the author or authors of this +* software dedicate any and all copyright interest in the software to the public +* domain. We make this dedication for the benefit of the public at large and to +* the detriment of our heirs and successors. We intend this dedication to be an +* overt act of relinquishment in perpetuity of all present and future rights to +* this software under copyright law. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +**********************************************************************************************/ + +#ifndef GIF_H +#define GIF_H + +#include <stdio.h> // Required for: FILE +#include <stdint.h> // Required for for integer typedefs + +//#define GIF_STATIC +#ifdef GIF_STATIC + #define GIFDEF static // Functions just visible to module including this file +#else + #ifdef __cplusplus + #define GIFDEF extern "C" // Functions visible from other files (no name mangling of functions in C++) + #else + #define GIFDEF extern // Functions visible from other files + #endif +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +//#define MAX_RESOURCES_SUPPORTED 256 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct GifWriter { + FILE *f; + uint8_t *oldImage; + bool firstFrame; +} GifWriter; + +//---------------------------------------------------------------------------------- +// Global variables +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- + +// NOTE: By default use bitDepth = 8, dither = false +GIFDEF bool GifBegin(GifWriter *writer, const char *filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth, bool dither); +GIFDEF bool GifWriteFrame(GifWriter *writer, const uint8_t *image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth, bool dither); +GIFDEF bool GifEnd(GifWriter *writer); + +#endif // GIF_H + + +/*********************************************************************************** +* + * GIF IMPLEMENTATION +* +************************************************************************************/ + +#if defined(GIF_IMPLEMENTATION) + +#include <stdio.h> // Required for: FILE, fopen(), fclose() +#include <string.h> // Required for: memcpy() +#include <stdint.h> // Required for for integer typedefs + +// Define these macros to hook into a custom memory allocator. +// GIF_TEMP_MALLOC and GIF_TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs +// and any temp memory allocated by a function will be freed before it exits. +#if !defined(GIF_TEMP_MALLOC) + #include <stdlib.h> + + #define GIF_TEMP_MALLOC malloc + #define GIF_TEMP_FREE free +#endif + +// Check if custom malloc/free functions defined, if not, using standard ones +// GIF_MALLOC and GIF_FREE are used only by GifBegin and GifEnd respectively, +// to allocate a buffer the size of the image, which is used to find changed pixels for delta-encoding. +#if !defined(GIF_MALLOC) + #include <stdlib.h> // Required for: malloc(), free() + + #define GIF_MALLOC(size) malloc(size) + #define GIF_FREE(ptr) free(ptr) +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define GIFMIN(a, b) (((a)<(b))?(a):(b)) +#define GIFMAX(a, b) (((a)>(b))?(a):(b)) +#define GIFABS(x) ((x)<0?-(x):(x)) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +//Gif palette structure +typedef struct GifPalette { + int bitDepth; + + uint8_t r[256]; + uint8_t g[256]; + uint8_t b[256]; + + // k-d tree over RGB space, organized in heap fashion + // i.e. left child of node i is node i*2, right child is node i*2 + 1 + // nodes 256-511 are implicitly the leaves, containing a color + uint8_t treeSplitElt[255]; + uint8_t treeSplit[255]; +} GifPalette; + + +// Simple structure to write out the LZW-compressed +// portion of the imageone bit at a time +typedef struct GifBitStatus { + uint8_t bitIndex; // how many bits in the partial byte written so far + uint8_t byte; // current partial byte + + uint32_t chunkIndex; + uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file +} GifBitStatus; + +// The LZW dictionary is a 256-ary tree constructed +// as the file is encoded, this is one node +typedef struct GifLzwNode { + uint16_t m_next[256]; +} GifLzwNode; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +const int kGifTransIndex = 0; + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int *bestInd, int *bestDiff, int treeRoot); +static void GifSwapPixels(uint8_t *image, int pixA, int pixB); +static int GifPartition(uint8_t *image, const int left, const int right, const int elt, int pivotIndex); +static void GifPartitionByMedian(uint8_t *image, int left, int right, int com, int neededCenter); +static void GifSplitPalette(uint8_t *image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette *pal); +static int GifPickChangedPixels(const uint8_t *lastFrame, uint8_t *frame, int numPixels); +static void GifMakePalette(const uint8_t *lastFrame, const uint8_t *nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette *pPal); +static void GifDitherImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal); +static void GifThresholdImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal); +static void GifWriteBit(GifBitStatus *stat, uint32_t bit); +static void GifWriteChunk(FILE *f, GifBitStatus *stat); +static void GifWriteCode(FILE *f, GifBitStatus *stat, uint32_t code, uint32_t length); +static void GifWritePalette(const GifPalette *pPal, FILE *f); +static void GifWriteLzwImage(FILE *f, uint8_t *image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette *pPal); + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Creates a gif file. +// The input GIFWriter is assumed to be uninitialized. +// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value. +GIFDEF bool GifBegin(GifWriter *writer, const char *filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth, bool dither) +{ +#if _MSC_VER >= 1400 + writer->f = 0; + fopen_s(&writer->f, filename, "wb"); +#else + writer->f = fopen(filename, "wb"); +#endif + if (!writer->f) return false; + + writer->firstFrame = true; + + // allocate + writer->oldImage = (uint8_t*)GIF_MALLOC(width*height*4); + + fputs("GIF89a", writer->f); + + // screen descriptor + fputc(width & 0xff, writer->f); + fputc((width >> 8) & 0xff, writer->f); + fputc(height & 0xff, writer->f); + fputc((height >> 8) & 0xff, writer->f); + + fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries + fputc(0, writer->f); // background color + fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989) + + // now the "global" palette (really just a dummy palette) + // color 0: black + fputc(0, writer->f); + fputc(0, writer->f); + fputc(0, writer->f); + // color 1: also black + fputc(0, writer->f); + fputc(0, writer->f); + fputc(0, writer->f); + + if (delay != 0) + { + // animation header + fputc(0x21, writer->f); // extension + fputc(0xff, writer->f); // application specific + fputc(11, writer->f); // length 11 + fputs("NETSCAPE2.0", writer->f); // yes, really + fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data + + fputc(1, writer->f); // JUST BECAUSE + fputc(0, writer->f); // loop infinitely (byte 0) + fputc(0, writer->f); // loop infinitely (byte 1) + + fputc(0, writer->f); // block terminator + } + + return true; +} + +// Writes out a new frame to a GIF in progress. +// The GIFWriter should have been created by GIFBegin. +// AFAIK, it is legal to use different bit depths for different frames of an image - +// this may be handy to save bits in animations that don't change much. +GIFDEF bool GifWriteFrame(GifWriter *writer, const uint8_t *image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth, bool dither) +{ + if (!writer->f) return false; + + const uint8_t *oldImage = writer->firstFrame? NULL : writer->oldImage; + writer->firstFrame = false; + + GifPalette pal; + GifMakePalette((dither? NULL : oldImage), image, width, height, bitDepth, dither, &pal); + + if (dither) + GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal); + else + GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal); + + GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal); + + return true; +} + +// Writes the EOF code, closes the file handle, and frees temp memory used by a GIF. +// Many if not most viewers will still display a GIF properly if the EOF code is missing, +// but it's still a good idea to write it out. +GIFDEF bool GifEnd(GifWriter *writer) +{ + if (!writer->f) return false; + + fputc(0x3b, writer->f); // end of file + fclose(writer->f); + GIF_FREE(writer->oldImage); + + writer->f = NULL; + writer->oldImage = NULL; + + return true; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- +// walks the k-d tree to pick the palette entry for a desired color. +// Takes as in/out parameters the current best color and its error - +// only changes them if it finds a better color in its subtree. +// this is the major hotspot in the code at the moment. +static void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int *bestInd, int *bestDiff, int treeRoot) +{ + // base case, reached the bottom of the tree + if (treeRoot > (1<<pPal->bitDepth)-1) + { + int ind = treeRoot-(1<<pPal->bitDepth); + if (ind == kGifTransIndex) return; + + // check whether this color is better than the current winner + int r_err = r - ((int32_t)pPal->r[ind]); + int g_err = g - ((int32_t)pPal->g[ind]); + int b_err = b - ((int32_t)pPal->b[ind]); + int diff = GIFABS(r_err)+GIFABS(g_err)+GIFABS(b_err); + + if (diff < *bestDiff) + { + *bestInd = ind; + *bestDiff = diff; + } + + return; + } + + // take the appropriate color (r, g, or b) for this node of the k-d tree + int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b; + int splitComp = comps[pPal->treeSplitElt[treeRoot]]; + + int splitPos = pPal->treeSplit[treeRoot]; + if (splitPos > splitComp) + { + // check the left subtree + GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2); + + if (*bestDiff > (splitPos - splitComp)) + { + // cannot prove there's not a better value in the right subtree, check that too + GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2 + 1); + } + } + else + { + GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2 + 1); + + if (*bestDiff > splitComp - splitPos) + { + GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2); + } + } +} + +static void GifSwapPixels(uint8_t *image, int pixA, int pixB) +{ + uint8_t rA = image[pixA*4]; + uint8_t gA = image[pixA*4 + 1]; + uint8_t bA = image[pixA*4+2]; + uint8_t aA = image[pixA*4+3]; + + uint8_t rB = image[pixB*4]; + uint8_t gB = image[pixB*4 + 1]; + uint8_t bB = image[pixB*4+2]; + uint8_t aB = image[pixA*4+3]; + + image[pixA*4] = rB; + image[pixA*4 + 1] = gB; + image[pixA*4+2] = bB; + image[pixA*4+3] = aB; + + image[pixB*4] = rA; + image[pixB*4 + 1] = gA; + image[pixB*4+2] = bA; + image[pixB*4+3] = aA; +} + +// just the partition operation from quicksort +static int GifPartition(uint8_t *image, const int left, const int right, const int elt, int pivotIndex) +{ + const int pivotValue = image[(pivotIndex)*4+elt]; + GifSwapPixels(image, pivotIndex, right-1); + int storeIndex = left; + bool split = 0; + for (int ii=left; ii<right-1; ++ii) + { + int arrayVal = image[ii*4+elt]; + if (arrayVal < pivotValue) + { + GifSwapPixels(image, ii, storeIndex); + ++storeIndex; + } + else if (arrayVal == pivotValue) + { + if (split) + { + GifSwapPixels(image, ii, storeIndex); + ++storeIndex; + } + split = !split; + } + } + GifSwapPixels(image, storeIndex, right-1); + return storeIndex; +} + +// Perform an incomplete sort, finding all elements above and below the desired median +static void GifPartitionByMedian(uint8_t *image, int left, int right, int com, int neededCenter) +{ + if (left < right-1) + { + int pivotIndex = left + (right-left)/2; + + pivotIndex = GifPartition(image, left, right, com, pivotIndex); + + // Only "sort" the section of the array that contains the median + if (pivotIndex > neededCenter) + GifPartitionByMedian(image, left, pivotIndex, com, neededCenter); + + if (pivotIndex < neededCenter) + GifPartitionByMedian(image, pivotIndex + 1, right, com, neededCenter); + } +} + +// Builds a palette by creating a balanced k-d tree of all pixels in the image +static void GifSplitPalette(uint8_t *image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, + int treeNode, bool buildForDither, GifPalette *pal) +{ + if (lastElt <= firstElt || numPixels == 0) + return; + + // base case, bottom of the tree + if (lastElt == firstElt + 1) + { + if (buildForDither) + { + // Dithering needs at least one color as dark as anything + // in the image and at least one brightest color - + // otherwise it builds up error and produces strange artifacts + if (firstElt == 1) + { + // special case: the darkest color in the image + uint32_t r=255, g=255, b=255; + for (int ii=0; ii<numPixels; ++ii) + { + r = GIFMIN(r, image[ii*4+0]); + g = GIFMIN(g, image[ii*4 + 1]); + b = GIFMIN(b, image[ii*4+2]); + } + + pal->r[firstElt] = r; + pal->g[firstElt] = g; + pal->b[firstElt] = b; + + return; + } + + if (firstElt == (1 << pal->bitDepth)-1) + { + // special case: the lightest color in the image + uint32_t r=0, g=0, b=0; + for (int ii=0; ii<numPixels; ++ii) + { + r = GIFMAX(r, image[ii*4+0]); + g = GIFMAX(g, image[ii*4 + 1]); + b = GIFMAX(b, image[ii*4+2]); + } + + pal->r[firstElt] = r; + pal->g[firstElt] = g; + pal->b[firstElt] = b; + + return; + } + } + + // otherwise, take the average of all colors in this subcube + uint64_t r=0, g=0, b=0; + for (int ii=0; ii<numPixels; ++ii) + { + r += image[ii*4+0]; + g += image[ii*4 + 1]; + b += image[ii*4+2]; + } + + r += numPixels / 2; // round to nearest + g += numPixels / 2; + b += numPixels / 2; + + r /= numPixels; + g /= numPixels; + b /= numPixels; + + pal->r[firstElt] = (uint8_t)r; + pal->g[firstElt] = (uint8_t)g; + pal->b[firstElt] = (uint8_t)b; + + return; + } + + // Find the axis with the largest range + int minR = 255, maxR = 0; + int minG = 255, maxG = 0; + int minB = 255, maxB = 0; + for (int ii=0; ii<numPixels; ++ii) + { + int r = image[ii*4+0]; + int g = image[ii*4 + 1]; + int b = image[ii*4+2]; + + if (r > maxR) maxR = r; + if (r < minR) minR = r; + + if (g > maxG) maxG = g; + if (g < minG) minG = g; + + if (b > maxB) maxB = b; + if (b < minB) minB = b; + } + + int rRange = maxR - minR; + int gRange = maxG - minG; + int bRange = maxB - minB; + + // and split along that axis. (incidentally, this means this isn't a "proper" k-d tree but I don't know what else to call it) + int splitCom = 1; + if (bRange > gRange) splitCom = 2; + if (rRange > bRange && rRange > gRange) splitCom = 0; + + int subPixelsA = numPixels *(splitElt - firstElt) / (lastElt - firstElt); + int subPixelsB = numPixels-subPixelsA; + + GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA); + + pal->treeSplitElt[treeNode] = splitCom; + pal->treeSplit[treeNode] = image[subPixelsA*4+splitCom]; + + GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt-splitDist, splitDist/2, treeNode*2, buildForDither, pal); + GifSplitPalette(image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2 + 1, buildForDither, pal); +} + +// Finds all pixels that have changed from the previous image and +// moves them to the fromt of th buffer. +// This allows us to build a palette optimized for the colors of the +// changed pixels only. +static int GifPickChangedPixels(const uint8_t *lastFrame, uint8_t *frame, int numPixels) +{ + int numChanged = 0; + uint8_t *writeIter = frame; + + for (int ii=0; ii<numPixels; ++ii) + { + if (lastFrame[0] != frame[0] || + lastFrame[1] != frame[1] || + lastFrame[2] != frame[2]) + { + writeIter[0] = frame[0]; + writeIter[1] = frame[1]; + writeIter[2] = frame[2]; + ++numChanged; + writeIter += 4; + } + lastFrame += 4; + frame += 4; + } + + return numChanged; +} + +// Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom. +// This is known as the "modified median split" technique +static void GifMakePalette(const uint8_t *lastFrame, const uint8_t *nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette *pPal) +{ + pPal->bitDepth = bitDepth; + + // SplitPalette is destructive (it sorts the pixels by color) so + // we must create a copy of the image for it to destroy + int imageSize = width*height*4*sizeof(uint8_t); + uint8_t *destroyableImage = (uint8_t*)GIF_TEMP_MALLOC(imageSize); + memcpy(destroyableImage, nextFrame, imageSize); + + int numPixels = width*height; + if (lastFrame) + numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels); + + const int lastElt = 1 << bitDepth; + const int splitElt = lastElt/2; + const int splitDist = splitElt/2; + + GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal); + + GIF_TEMP_FREE(destroyableImage); + + // add the bottom node for the transparency index + pPal->treeSplit[1 << (bitDepth-1)] = 0; + pPal->treeSplitElt[1 << (bitDepth-1)] = 0; + + pPal->r[0] = pPal->g[0] = pPal->b[0] = 0; +} + +// Implements Floyd-Steinberg dithering, writes palette value to alpha +static void GifDitherImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal) +{ + int numPixels = width*height; + + // quantPixels initially holds color*256 for all pixels + // The extra 8 bits of precision allow for sub-single-color error values + // to be propagated + int32_t *quantPixels = (int32_t*)GIF_TEMP_MALLOC(sizeof(int32_t)*numPixels*4); + + for (int ii=0; ii<numPixels*4; ++ii) + { + uint8_t pix = nextFrame[ii]; + int32_t pix16 = (int32_t)pix*256; + quantPixels[ii] = pix16; + } + + for (uint32_t yy=0; yy<height; ++yy) + { + for (uint32_t xx=0; xx<width; ++xx) + { + int32_t *nextPix = quantPixels + 4*(yy*width+xx); + const uint8_t *lastPix = lastFrame? lastFrame + 4*(yy*width+xx) : NULL; + + // Compute the colors we want (rounding to nearest) + int32_t rr = (nextPix[0] + 127) / 256; + int32_t gg = (nextPix[1] + 127) / 256; + int32_t bb = (nextPix[2] + 127) / 256; + + // if it happens that we want the color from last frame, then just write out + // a transparent pixel + if (lastFrame && + lastPix[0] == rr && + lastPix[1] == gg && + lastPix[2] == bb) + { + nextPix[0] = rr; + nextPix[1] = gg; + nextPix[2] = bb; + nextPix[3] = kGifTransIndex; + continue; + } + + int32_t bestDiff = 1000000; + int32_t bestInd = kGifTransIndex; + + // Search the palete + GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1); + + // Write the result to the temp buffer + int32_t r_err = nextPix[0] - (int32_t)(pPal->r[bestInd])*256; + int32_t g_err = nextPix[1] - (int32_t)(pPal->g[bestInd])*256; + int32_t b_err = nextPix[2] - (int32_t)(pPal->b[bestInd])*256; + + nextPix[0] = pPal->r[bestInd]; + nextPix[1] = pPal->g[bestInd]; + nextPix[2] = pPal->b[bestInd]; + nextPix[3] = bestInd; + + // Propagate the error to the four adjacent locations + // that we haven't touched yet + int quantloc_7 = (yy*width+xx + 1); + int quantloc_3 = (yy*width+width+xx-1); + int quantloc_5 = (yy*width+width+xx); + int quantloc_1 = (yy*width+width+xx + 1); + + if (quantloc_7 < numPixels) + { + int32_t *pix7 = quantPixels+4*quantloc_7; + pix7[0] += GIFMAX(-pix7[0], r_err*7 / 16); + pix7[1] += GIFMAX(-pix7[1], g_err*7 / 16); + pix7[2] += GIFMAX(-pix7[2], b_err*7 / 16); + } + + if (quantloc_3 < numPixels) + { + int32_t *pix3 = quantPixels+4*quantloc_3; + pix3[0] += GIFMAX(-pix3[0], r_err*3 / 16); + pix3[1] += GIFMAX(-pix3[1], g_err*3 / 16); + pix3[2] += GIFMAX(-pix3[2], b_err*3 / 16); + } + + if (quantloc_5 < numPixels) + { + int32_t *pix5 = quantPixels+4*quantloc_5; + pix5[0] += GIFMAX(-pix5[0], r_err*5 / 16); + pix5[1] += GIFMAX(-pix5[1], g_err*5 / 16); + pix5[2] += GIFMAX(-pix5[2], b_err*5 / 16); + } + + if (quantloc_1 < numPixels) + { + int32_t *pix1 = quantPixels+4*quantloc_1; + pix1[0] += GIFMAX(-pix1[0], r_err / 16); + pix1[1] += GIFMAX(-pix1[1], g_err / 16); + pix1[2] += GIFMAX(-pix1[2], b_err / 16); + } + } + } + + // Copy the palettized result to the output buffer + for (int ii=0; ii<numPixels*4; ++ii) + { + outFrame[ii] = quantPixels[ii]; + } + + GIF_TEMP_FREE(quantPixels); +} + +// Picks palette colors for the image using simple thresholding, no dithering +static void GifThresholdImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal) +{ + uint32_t numPixels = width*height; + for (uint32_t ii=0; ii<numPixels; ++ii) + { + // if a previous color is available, and it matches the current color, + // set the pixel to transparent + if (lastFrame && + lastFrame[0] == nextFrame[0] && + lastFrame[1] == nextFrame[1] && + lastFrame[2] == nextFrame[2]) + { + outFrame[0] = lastFrame[0]; + outFrame[1] = lastFrame[1]; + outFrame[2] = lastFrame[2]; + outFrame[3] = kGifTransIndex; + } + else + { + // palettize the pixel + int32_t bestDiff = 1000000; + int32_t bestInd = 1; + GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], &bestInd, &bestDiff, 1); + + // Write the resulting color to the output buffer + outFrame[0] = pPal->r[bestInd]; + outFrame[1] = pPal->g[bestInd]; + outFrame[2] = pPal->b[bestInd]; + outFrame[3] = bestInd; + } + + if (lastFrame) lastFrame += 4; + outFrame += 4; + nextFrame += 4; + } +} + + +// insert a single bit +static void GifWriteBit(GifBitStatus *stat, uint32_t bit) +{ + bit = bit & 1; + bit = bit << stat->bitIndex; + stat->byte |= bit; + + ++stat->bitIndex; + if (stat->bitIndex > 7) + { + // move the newly-finished byte to the chunk buffer + stat->chunk[stat->chunkIndex++] = stat->byte; + // and start a new byte + stat->bitIndex = 0; + stat->byte = 0; + } +} + +// write all bytes so far to the file +static void GifWriteChunk(FILE *f, GifBitStatus *stat) +{ + fputc(stat->chunkIndex, f); + fwrite(stat->chunk, 1, stat->chunkIndex, f); + + stat->bitIndex = 0; + stat->byte = 0; + stat->chunkIndex = 0; +} + +static void GifWriteCode(FILE *f, GifBitStatus *stat, uint32_t code, uint32_t length) +{ + for (uint32_t ii=0; ii<length; ++ii) + { + GifWriteBit(stat, code); + code = code >> 1; + + if (stat->chunkIndex == 255) + { + GifWriteChunk(f, stat); + } + } +} + +// write a 256-color (8-bit) image palette to the file +static void GifWritePalette(const GifPalette *pPal, FILE *f) +{ + fputc(0, f); // first color: transparency + fputc(0, f); + fputc(0, f); + + for (int ii=1; ii<(1 << pPal->bitDepth); ++ii) + { + uint32_t r = pPal->r[ii]; + uint32_t g = pPal->g[ii]; + uint32_t b = pPal->b[ii]; + + fputc(r, f); + fputc(g, f); + fputc(b, f); + } +} + +// write the image header, LZW-compress and write out the image +static void GifWriteLzwImage(FILE *f, uint8_t *image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette *pPal) +{ + // graphics control extension + fputc(0x21, f); + fputc(0xf9, f); + fputc(0x04, f); + fputc(0x05, f); // leave prev frame in place, this frame has transparency + fputc(delay & 0xff, f); + fputc((delay >> 8) & 0xff, f); + fputc(kGifTransIndex, f); // transparent color index + fputc(0, f); + + fputc(0x2c, f); // image descriptor block + + fputc(left & 0xff, f); // corner of image in canvas space + fputc((left >> 8) & 0xff, f); + fputc(top & 0xff, f); + fputc((top >> 8) & 0xff, f); + + fputc(width & 0xff, f); // width and height of image + fputc((width >> 8) & 0xff, f); + fputc(height & 0xff, f); + fputc((height >> 8) & 0xff, f); + + //fputc(0, f); // no local color table, no transparency + //fputc(0x80, f); // no local color table, but transparency + + fputc(0x80 + pPal->bitDepth-1, f); // local color table present, 2 ^ bitDepth entries + GifWritePalette(pPal, f); + + const int minCodeSize = pPal->bitDepth; + const uint32_t clearCode = 1 << pPal->bitDepth; + + fputc(minCodeSize, f); // min code size 8 bits + + GifLzwNode *codetree = (GifLzwNode *)GIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096); + + memset(codetree, 0, sizeof(GifLzwNode)*4096); + int32_t curCode = -1; + uint32_t codeSize = minCodeSize + 1; + uint32_t maxCode = clearCode + 1; + + GifBitStatus stat; + stat.byte = 0; + stat.bitIndex = 0; + stat.chunkIndex = 0; + + GifWriteCode(f, &stat, clearCode, codeSize); // start with a fresh LZW dictionary + + for (uint32_t yy=0; yy<height; ++yy) + { + for (uint32_t xx=0; xx<width; ++xx) + { + uint8_t nextValue = image[(yy*width+xx)*4+3]; + + // "loser mode" - no compression, every single code is followed immediately by a clear + //WriteCode(f, stat, nextValue, codeSize); + //WriteCode(f, stat, 256, codeSize); + + if (curCode < 0) + { + // first value in a new run + curCode = nextValue; + } + else if (codetree[curCode].m_next[nextValue]) + { + // current run already in the dictionary + curCode = codetree[curCode].m_next[nextValue]; + } + else + { + // finish the current run, write a code + GifWriteCode(f, &stat, curCode, codeSize); + + // insert the new run into the dictionary + codetree[curCode].m_next[nextValue] = ++maxCode; + + if (maxCode >= (1ul << codeSize)) + { + // dictionary entry count has broken a size barrier, + // we need more bits for codes + codeSize++; + } + if (maxCode == 4095) + { + // the dictionary is full, clear it out and begin anew + GifWriteCode(f, &stat, clearCode, codeSize); // clear tree + + memset(codetree, 0, sizeof(GifLzwNode)*4096); + curCode = -1; + codeSize = minCodeSize + 1; + maxCode = clearCode + 1; + } + + curCode = nextValue; + } + } + } + + // compression footer + GifWriteCode(f, &stat, curCode, codeSize); + GifWriteCode(f, &stat, clearCode, codeSize); + GifWriteCode(f, &stat, clearCode + 1, minCodeSize + 1); + + // write out the last partial chunk + while (stat.bitIndex) GifWriteBit(&stat, 0); + if (stat.chunkIndex) GifWriteChunk(f, &stat); + + fputc(0, f); // image block terminator + + GIF_TEMP_FREE(codetree); +} + +#endif // GIF_IMPLEMENTATION diff --git a/src/external/glfw3/lib/win32/glfw3.lib b/src/external/glfw3/lib/win32/glfw3.lib Binary files differnew file mode 100644 index 00000000..741756ab --- /dev/null +++ b/src/external/glfw3/lib/win32/glfw3.lib diff --git a/src/external/lua/include/lauxlib.h b/src/external/lua/include/lauxlib.h deleted file mode 100644 index ddb7c228..00000000 --- a/src/external/lua/include/lauxlib.h +++ /dev/null @@ -1,256 +0,0 @@ -/* -** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $ -** Auxiliary functions for building Lua libraries -** See Copyright Notice in lua.h -*/ - - -#ifndef lauxlib_h -#define lauxlib_h - - -#include <stddef.h> -#include <stdio.h> - -#include "lua.h" - - - -/* extra error code for 'luaL_load' */ -#define LUA_ERRFILE (LUA_ERRERR+1) - - -typedef struct luaL_Reg { - const char *name; - lua_CFunction func; -} luaL_Reg; - - -#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) - -LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); -#define luaL_checkversion(L) \ - luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) - -LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); -LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); -LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); -LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); -LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, - size_t *l); -LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, - const char *def, size_t *l); -LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); -LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); - -LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); -LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, - lua_Integer def); - -LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); -LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); -LUALIB_API void (luaL_checkany) (lua_State *L, int arg); - -LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); -LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); -LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); -LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); - -LUALIB_API void (luaL_where) (lua_State *L, int lvl); -LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); - -LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, - const char *const lst[]); - -LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); -LUALIB_API int (luaL_execresult) (lua_State *L, int stat); - -/* predefined references */ -#define LUA_NOREF (-2) -#define LUA_REFNIL (-1) - -LUALIB_API int (luaL_ref) (lua_State *L, int t); -LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); - -LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, - const char *mode); - -#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) - -LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, - const char *name, const char *mode); -LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); - -LUALIB_API lua_State *(luaL_newstate) (void); - -LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); - -LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, - const char *r); - -LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); - -LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); - -LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, - const char *msg, int level); - -LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, - lua_CFunction openf, int glb); - -/* -** =============================================================== -** some useful macros -** =============================================================== -*/ - - -#define luaL_newlibtable(L,l) \ - lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) - -#define luaL_newlib(L,l) \ - (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) - -#define luaL_argcheck(L, cond,arg,extramsg) \ - ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) -#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) -#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) - -#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) - -#define luaL_dofile(L, fn) \ - (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) - -#define luaL_dostring(L, s) \ - (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) - -#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) - -#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) - -#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) - - -/* -** {====================================================== -** Generic Buffer manipulation -** ======================================================= -*/ - -typedef struct luaL_Buffer { - char *b; /* buffer address */ - size_t size; /* buffer size */ - size_t n; /* number of characters in buffer */ - lua_State *L; - char initb[LUAL_BUFFERSIZE]; /* initial buffer */ -} luaL_Buffer; - - -#define luaL_addchar(B,c) \ - ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ - ((B)->b[(B)->n++] = (c))) - -#define luaL_addsize(B,s) ((B)->n += (s)) - -LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); -LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); -LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); -LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); -LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); -LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); -LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); -LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); - -#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) - -/* }====================================================== */ - - - -/* -** {====================================================== -** File handles for IO library -** ======================================================= -*/ - -/* -** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and -** initial structure 'luaL_Stream' (it may contain other fields -** after that initial structure). -*/ - -#define LUA_FILEHANDLE "FILE*" - - -typedef struct luaL_Stream { - FILE *f; /* stream (NULL for incompletely created streams) */ - lua_CFunction closef; /* to close stream (NULL for closed streams) */ -} luaL_Stream; - -/* }====================================================== */ - - - -/* compatibility with old module system */ -#if defined(LUA_COMPAT_MODULE) - -LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, - int sizehint); -LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, - const luaL_Reg *l, int nup); - -#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) - -#endif - - -/* -** {================================================================== -** "Abstraction Layer" for basic report of messages and errors -** =================================================================== -*/ - -/* print a string */ -#if !defined(lua_writestring) -#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) -#endif - -/* print a newline and flush the output */ -#if !defined(lua_writeline) -#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) -#endif - -/* print an error message */ -#if !defined(lua_writestringerror) -#define lua_writestringerror(s,p) \ - (fprintf(stderr, (s), (p)), fflush(stderr)) -#endif - -/* }================================================================== */ - - -/* -** {============================================================ -** Compatibility with deprecated conversions -** ============================================================= -*/ -#if defined(LUA_COMPAT_APIINTCASTS) - -#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) -#define luaL_optunsigned(L,a,d) \ - ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) - -#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) -#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) - -#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) -#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) - -#endif -/* }============================================================ */ - - - -#endif - - diff --git a/src/external/lua/include/lua.h b/src/external/lua/include/lua.h deleted file mode 100644 index f78899fc..00000000 --- a/src/external/lua/include/lua.h +++ /dev/null @@ -1,486 +0,0 @@ -/* -** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $ -** Lua - A Scripting Language -** Lua.org, PUC-Rio, Brazil (http://www.lua.org) -** See Copyright Notice at the end of this file -*/ - - -#ifndef lua_h -#define lua_h - -#include <stdarg.h> -#include <stddef.h> - - -#include "luaconf.h" - - -#define LUA_VERSION_MAJOR "5" -#define LUA_VERSION_MINOR "3" -#define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "3" - -#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR -#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" - - -/* mark for precompiled code ('<esc>Lua') */ -#define LUA_SIGNATURE "\x1bLua" - -/* option for multiple returns in 'lua_pcall' and 'lua_call' */ -#define LUA_MULTRET (-1) - - -/* -** Pseudo-indices -** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty -** space after that to help overflow detection) -*/ -#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) -#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) - - -/* thread status */ -#define LUA_OK 0 -#define LUA_YIELD 1 -#define LUA_ERRRUN 2 -#define LUA_ERRSYNTAX 3 -#define LUA_ERRMEM 4 -#define LUA_ERRGCMM 5 -#define LUA_ERRERR 6 - - -typedef struct lua_State lua_State; - - -/* -** basic types -*/ -#define LUA_TNONE (-1) - -#define LUA_TNIL 0 -#define LUA_TBOOLEAN 1 -#define LUA_TLIGHTUSERDATA 2 -#define LUA_TNUMBER 3 -#define LUA_TSTRING 4 -#define LUA_TTABLE 5 -#define LUA_TFUNCTION 6 -#define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 - -#define LUA_NUMTAGS 9 - - - -/* minimum Lua stack available to a C function */ -#define LUA_MINSTACK 20 - - -/* predefined values in the registry */ -#define LUA_RIDX_MAINTHREAD 1 -#define LUA_RIDX_GLOBALS 2 -#define LUA_RIDX_LAST LUA_RIDX_GLOBALS - - -/* type of numbers in Lua */ -typedef LUA_NUMBER lua_Number; - - -/* type for integer functions */ -typedef LUA_INTEGER lua_Integer; - -/* unsigned integer type */ -typedef LUA_UNSIGNED lua_Unsigned; - -/* type for continuation-function contexts */ -typedef LUA_KCONTEXT lua_KContext; - - -/* -** Type for C functions registered with Lua -*/ -typedef int (*lua_CFunction) (lua_State *L); - -/* -** Type for continuation functions -*/ -typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); - - -/* -** Type for functions that read/write blocks when loading/dumping Lua chunks -*/ -typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); - -typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); - - -/* -** Type for memory-allocation functions -*/ -typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); - - - -/* -** generic extra include file -*/ -#if defined(LUA_USER_H) -#include LUA_USER_H -#endif - - -/* -** RCS ident string -*/ -extern const char lua_ident[]; - - -/* -** state manipulation -*/ -LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); -LUA_API void (lua_close) (lua_State *L); -LUA_API lua_State *(lua_newthread) (lua_State *L); - -LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); - - -LUA_API const lua_Number *(lua_version) (lua_State *L); - - -/* -** basic stack manipulation -*/ -LUA_API int (lua_absindex) (lua_State *L, int idx); -LUA_API int (lua_gettop) (lua_State *L); -LUA_API void (lua_settop) (lua_State *L, int idx); -LUA_API void (lua_pushvalue) (lua_State *L, int idx); -LUA_API void (lua_rotate) (lua_State *L, int idx, int n); -LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); -LUA_API int (lua_checkstack) (lua_State *L, int n); - -LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); - - -/* -** access functions (stack -> C) -*/ - -LUA_API int (lua_isnumber) (lua_State *L, int idx); -LUA_API int (lua_isstring) (lua_State *L, int idx); -LUA_API int (lua_iscfunction) (lua_State *L, int idx); -LUA_API int (lua_isinteger) (lua_State *L, int idx); -LUA_API int (lua_isuserdata) (lua_State *L, int idx); -LUA_API int (lua_type) (lua_State *L, int idx); -LUA_API const char *(lua_typename) (lua_State *L, int tp); - -LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); -LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); -LUA_API int (lua_toboolean) (lua_State *L, int idx); -LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); -LUA_API size_t (lua_rawlen) (lua_State *L, int idx); -LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); -LUA_API void *(lua_touserdata) (lua_State *L, int idx); -LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); -LUA_API const void *(lua_topointer) (lua_State *L, int idx); - - -/* -** Comparison and arithmetic functions -*/ - -#define LUA_OPADD 0 /* ORDER TM, ORDER OP */ -#define LUA_OPSUB 1 -#define LUA_OPMUL 2 -#define LUA_OPMOD 3 -#define LUA_OPPOW 4 -#define LUA_OPDIV 5 -#define LUA_OPIDIV 6 -#define LUA_OPBAND 7 -#define LUA_OPBOR 8 -#define LUA_OPBXOR 9 -#define LUA_OPSHL 10 -#define LUA_OPSHR 11 -#define LUA_OPUNM 12 -#define LUA_OPBNOT 13 - -LUA_API void (lua_arith) (lua_State *L, int op); - -#define LUA_OPEQ 0 -#define LUA_OPLT 1 -#define LUA_OPLE 2 - -LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); -LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); - - -/* -** push functions (C -> stack) -*/ -LUA_API void (lua_pushnil) (lua_State *L); -LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); -LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); -LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); -LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); -LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, - va_list argp); -LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); -LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); -LUA_API void (lua_pushboolean) (lua_State *L, int b); -LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); -LUA_API int (lua_pushthread) (lua_State *L); - - -/* -** get functions (Lua -> stack) -*/ -LUA_API int (lua_getglobal) (lua_State *L, const char *name); -LUA_API int (lua_gettable) (lua_State *L, int idx); -LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); -LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n); -LUA_API int (lua_rawget) (lua_State *L, int idx); -LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); -LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); - -LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); -LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); -LUA_API int (lua_getmetatable) (lua_State *L, int objindex); -LUA_API int (lua_getuservalue) (lua_State *L, int idx); - - -/* -** set functions (stack -> Lua) -*/ -LUA_API void (lua_setglobal) (lua_State *L, const char *name); -LUA_API void (lua_settable) (lua_State *L, int idx); -LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); -LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n); -LUA_API void (lua_rawset) (lua_State *L, int idx); -LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); -LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); -LUA_API int (lua_setmetatable) (lua_State *L, int objindex); -LUA_API void (lua_setuservalue) (lua_State *L, int idx); - - -/* -** 'load' and 'call' functions (load and run Lua code) -*/ -LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, - lua_KContext ctx, lua_KFunction k); -#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) - -LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, - lua_KContext ctx, lua_KFunction k); -#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) - -LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, - const char *chunkname, const char *mode); - -LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); - - -/* -** coroutine functions -*/ -LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, - lua_KFunction k); -LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); -LUA_API int (lua_status) (lua_State *L); -LUA_API int (lua_isyieldable) (lua_State *L); - -#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) - - -/* -** garbage-collection function and options -*/ - -#define LUA_GCSTOP 0 -#define LUA_GCRESTART 1 -#define LUA_GCCOLLECT 2 -#define LUA_GCCOUNT 3 -#define LUA_GCCOUNTB 4 -#define LUA_GCSTEP 5 -#define LUA_GCSETPAUSE 6 -#define LUA_GCSETSTEPMUL 7 -#define LUA_GCISRUNNING 9 - -LUA_API int (lua_gc) (lua_State *L, int what, int data); - - -/* -** miscellaneous functions -*/ - -LUA_API int (lua_error) (lua_State *L); - -LUA_API int (lua_next) (lua_State *L, int idx); - -LUA_API void (lua_concat) (lua_State *L, int n); -LUA_API void (lua_len) (lua_State *L, int idx); - -LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); - -LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); -LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); - - - -/* -** {============================================================== -** some useful macros -** =============================================================== -*/ - -#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) - -#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) -#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) - -#define lua_pop(L,n) lua_settop(L, -(n)-1) - -#define lua_newtable(L) lua_createtable(L, 0, 0) - -#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) - -#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) - -#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) -#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) -#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) -#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) -#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) -#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) -#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) -#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) - -#define lua_pushliteral(L, s) lua_pushstring(L, "" s) - -#define lua_pushglobaltable(L) \ - ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) - -#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) - - -#define lua_insert(L,idx) lua_rotate(L, (idx), 1) - -#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) - -#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) - -/* }============================================================== */ - - -/* -** {============================================================== -** compatibility macros for unsigned conversions -** =============================================================== -*/ -#if defined(LUA_COMPAT_APIINTCASTS) - -#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) -#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) -#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) - -#endif -/* }============================================================== */ - -/* -** {====================================================================== -** Debug API -** ======================================================================= -*/ - - -/* -** Event codes -*/ -#define LUA_HOOKCALL 0 -#define LUA_HOOKRET 1 -#define LUA_HOOKLINE 2 -#define LUA_HOOKCOUNT 3 -#define LUA_HOOKTAILCALL 4 - - -/* -** Event masks -*/ -#define LUA_MASKCALL (1 << LUA_HOOKCALL) -#define LUA_MASKRET (1 << LUA_HOOKRET) -#define LUA_MASKLINE (1 << LUA_HOOKLINE) -#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) - -typedef struct lua_Debug lua_Debug; /* activation record */ - - -/* Functions to be called by the debugger in specific events */ -typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); - - -LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); -LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); -LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); -LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); - -LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); -LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, - int fidx2, int n2); - -LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); -LUA_API lua_Hook (lua_gethook) (lua_State *L); -LUA_API int (lua_gethookmask) (lua_State *L); -LUA_API int (lua_gethookcount) (lua_State *L); - - -struct lua_Debug { - int event; - const char *name; /* (n) */ - const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ - const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ - const char *source; /* (S) */ - int currentline; /* (l) */ - int linedefined; /* (S) */ - int lastlinedefined; /* (S) */ - unsigned char nups; /* (u) number of upvalues */ - unsigned char nparams;/* (u) number of parameters */ - char isvararg; /* (u) */ - char istailcall; /* (t) */ - char short_src[LUA_IDSIZE]; /* (S) */ - /* private part */ - struct CallInfo *i_ci; /* active function */ -}; - -/* }====================================================================== */ - - -/****************************************************************************** -* Copyright (C) 1994-2016 Lua.org, PUC-Rio. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be -* included in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -******************************************************************************/ - - -#endif diff --git a/src/external/lua/include/lua.hpp b/src/external/lua/include/lua.hpp deleted file mode 100644 index ec417f59..00000000 --- a/src/external/lua/include/lua.hpp +++ /dev/null @@ -1,9 +0,0 @@ -// lua.hpp -// Lua header files for C++ -// <<extern "C">> not supplied automatically because Lua also compiles as C++ - -extern "C" { -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" -} diff --git a/src/external/lua/include/luaconf.h b/src/external/lua/include/luaconf.h deleted file mode 100644 index 867e9cb1..00000000 --- a/src/external/lua/include/luaconf.h +++ /dev/null @@ -1,769 +0,0 @@ -/* -** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $ -** Configuration file for Lua -** See Copyright Notice in lua.h -*/ - - -#ifndef luaconf_h -#define luaconf_h - -#include <limits.h> -#include <stddef.h> - - -/* -** =================================================================== -** Search for "@@" to find all configurable definitions. -** =================================================================== -*/ - - -/* -** {==================================================================== -** System Configuration: macros to adapt (if needed) Lua to some -** particular platform, for instance compiling it with 32-bit numbers or -** restricting it to C89. -** ===================================================================== -*/ - -/* -@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You -** can also define LUA_32BITS in the make file, but changing here you -** ensure that all software connected to Lua will be compiled with the -** same configuration. -*/ -/* #define LUA_32BITS */ - - -/* -@@ LUA_USE_C89 controls the use of non-ISO-C89 features. -** Define it if you want Lua to avoid the use of a few C99 features -** or Windows-specific features on Windows. -*/ -/* #define LUA_USE_C89 */ - - -/* -** By default, Lua on Windows use (some) specific Windows features -*/ -#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) -#define LUA_USE_WINDOWS /* enable goodies for regular Windows */ -#endif - - -#if defined(LUA_USE_WINDOWS) -#define LUA_DL_DLL /* enable support for DLL */ -#define LUA_USE_C89 /* broadly, Windows is C89 */ -#endif - - -#if defined(LUA_USE_LINUX) -#define LUA_USE_POSIX -#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ -#define LUA_USE_READLINE /* needs some extra libraries */ -#endif - - -#if defined(LUA_USE_MACOSX) -#define LUA_USE_POSIX -#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ -#define LUA_USE_READLINE /* needs an extra library: -lreadline */ -#endif - - -/* -@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for -** C89 ('long' and 'double'); Windows always has '__int64', so it does -** not need to use this case. -*/ -#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) -#define LUA_C89_NUMBERS -#endif - - - -/* -@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'. -*/ -/* avoid undefined shifts */ -#if ((INT_MAX >> 15) >> 15) >= 1 -#define LUAI_BITSINT 32 -#else -/* 'int' always must have at least 16 bits */ -#define LUAI_BITSINT 16 -#endif - - -/* -@@ LUA_INT_TYPE defines the type for Lua integers. -@@ LUA_FLOAT_TYPE defines the type for Lua floats. -** Lua should work fine with any mix of these options (if supported -** by your C compiler). The usual configurations are 64-bit integers -** and 'double' (the default), 32-bit integers and 'float' (for -** restricted platforms), and 'long'/'double' (for C compilers not -** compliant with C99, which may not have support for 'long long'). -*/ - -/* predefined options for LUA_INT_TYPE */ -#define LUA_INT_INT 1 -#define LUA_INT_LONG 2 -#define LUA_INT_LONGLONG 3 - -/* predefined options for LUA_FLOAT_TYPE */ -#define LUA_FLOAT_FLOAT 1 -#define LUA_FLOAT_DOUBLE 2 -#define LUA_FLOAT_LONGDOUBLE 3 - -#if defined(LUA_32BITS) /* { */ -/* -** 32-bit integers and 'float' -*/ -#if LUAI_BITSINT >= 32 /* use 'int' if big enough */ -#define LUA_INT_TYPE LUA_INT_INT -#else /* otherwise use 'long' */ -#define LUA_INT_TYPE LUA_INT_LONG -#endif -#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT - -#elif defined(LUA_C89_NUMBERS) /* }{ */ -/* -** largest types available for C89 ('long' and 'double') -*/ -#define LUA_INT_TYPE LUA_INT_LONG -#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE - -#endif /* } */ - - -/* -** default configuration for 64-bit Lua ('long long' and 'double') -*/ -#if !defined(LUA_INT_TYPE) -#define LUA_INT_TYPE LUA_INT_LONGLONG -#endif - -#if !defined(LUA_FLOAT_TYPE) -#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE -#endif - -/* }================================================================== */ - - - - -/* -** {================================================================== -** Configuration for Paths. -** =================================================================== -*/ - -/* -@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for -** Lua libraries. -@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for -** C libraries. -** CHANGE them if your machine has a non-conventional directory -** hierarchy or if you want to install your libraries in -** non-conventional directories. -*/ -#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR -#if defined(_WIN32) /* { */ -/* -** In Windows, any exclamation mark ('!') in the path is replaced by the -** path of the directory of the executable file of the current process. -*/ -#define LUA_LDIR "!\\lua\\" -#define LUA_CDIR "!\\" -#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" -#define LUA_PATH_DEFAULT \ - LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ - LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ - ".\\?.lua;" ".\\?\\init.lua" -#define LUA_CPATH_DEFAULT \ - LUA_CDIR"?.dll;" \ - LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ - LUA_CDIR"loadall.dll;" ".\\?.dll;" \ - LUA_CDIR"?53.dll;" ".\\?53.dll" - -#else /* }{ */ - -#define LUA_ROOT "/usr/local/" -#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" -#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" -#define LUA_PATH_DEFAULT \ - LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ - "./?.lua;" "./?/init.lua" -#define LUA_CPATH_DEFAULT \ - LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so;" \ - LUA_CDIR"lib?53.so;" "./lib?53.so" -#endif /* } */ - - -/* -@@ LUA_DIRSEP is the directory separator (for submodules). -** CHANGE it if your machine does not use "/" as the directory separator -** and is not Windows. (On Windows Lua automatically uses "\".) -*/ -#if defined(_WIN32) -#define LUA_DIRSEP "\\" -#else -#define LUA_DIRSEP "/" -#endif - -/* }================================================================== */ - - -/* -** {================================================================== -** Marks for exported symbols in the C code -** =================================================================== -*/ - -/* -@@ LUA_API is a mark for all core API functions. -@@ LUALIB_API is a mark for all auxiliary library functions. -@@ LUAMOD_API is a mark for all standard library opening functions. -** CHANGE them if you need to define those functions in some special way. -** For instance, if you want to create one Windows DLL with the core and -** the libraries, you may want to use the following definition (define -** LUA_BUILD_AS_DLL to get it). -*/ -#if defined(LUA_BUILD_AS_DLL) /* { */ - -#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ -#define LUA_API __declspec(dllexport) -#else /* }{ */ -#define LUA_API __declspec(dllimport) -#endif /* } */ - -#else /* }{ */ - -#define LUA_API extern - -#endif /* } */ - - -/* more often than not the libs go together with the core */ -#define LUALIB_API LUA_API -#define LUAMOD_API LUALIB_API - - -/* -@@ LUAI_FUNC is a mark for all extern functions that are not to be -** exported to outside modules. -@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables -** that are not to be exported to outside modules (LUAI_DDEF for -** definitions and LUAI_DDEC for declarations). -** CHANGE them if you need to mark them in some special way. Elf/gcc -** (versions 3.2 and later) mark them as "hidden" to optimize access -** when Lua is compiled as a shared library. Not all elf targets support -** this attribute. Unfortunately, gcc does not offer a way to check -** whether the target offers that support, and those without support -** give a warning about it. To avoid these warnings, change to the -** default definition. -*/ -#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ - defined(__ELF__) /* { */ -#define LUAI_FUNC __attribute__((visibility("hidden"))) extern -#else /* }{ */ -#define LUAI_FUNC extern -#endif /* } */ - -#define LUAI_DDEC LUAI_FUNC -#define LUAI_DDEF /* empty */ - -/* }================================================================== */ - - -/* -** {================================================================== -** Compatibility with previous versions -** =================================================================== -*/ - -/* -@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2. -@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1. -** You can define it to get all options, or change specific options -** to fit your specific needs. -*/ -#if defined(LUA_COMPAT_5_2) /* { */ - -/* -@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated -** functions in the mathematical library. -*/ -#define LUA_COMPAT_MATHLIB - -/* -@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'. -*/ -#define LUA_COMPAT_BITLIB - -/* -@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod. -*/ -#define LUA_COMPAT_IPAIRS - -/* -@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for -** manipulating other integer types (lua_pushunsigned, lua_tounsigned, -** luaL_checkint, luaL_checklong, etc.) -*/ -#define LUA_COMPAT_APIINTCASTS - -#endif /* } */ - - -#if defined(LUA_COMPAT_5_1) /* { */ - -/* Incompatibilities from 5.2 -> 5.3 */ -#define LUA_COMPAT_MATHLIB -#define LUA_COMPAT_APIINTCASTS - -/* -@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. -** You can replace it with 'table.unpack'. -*/ -#define LUA_COMPAT_UNPACK - -/* -@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. -** You can replace it with 'package.searchers'. -*/ -#define LUA_COMPAT_LOADERS - -/* -@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. -** You can call your C function directly (with light C functions). -*/ -#define lua_cpcall(L,f,u) \ - (lua_pushcfunction(L, (f)), \ - lua_pushlightuserdata(L,(u)), \ - lua_pcall(L,1,0,0)) - - -/* -@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. -** You can rewrite 'log10(x)' as 'log(x, 10)'. -*/ -#define LUA_COMPAT_LOG10 - -/* -@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base -** library. You can rewrite 'loadstring(s)' as 'load(s)'. -*/ -#define LUA_COMPAT_LOADSTRING - -/* -@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. -*/ -#define LUA_COMPAT_MAXN - -/* -@@ The following macros supply trivial compatibility for some -** changes in the API. The macros themselves document how to -** change your code to avoid using them. -*/ -#define lua_strlen(L,i) lua_rawlen(L, (i)) - -#define lua_objlen(L,i) lua_rawlen(L, (i)) - -#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) -#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) - -/* -@@ LUA_COMPAT_MODULE controls compatibility with previous -** module functions 'module' (Lua) and 'luaL_register' (C). -*/ -#define LUA_COMPAT_MODULE - -#endif /* } */ - - -/* -@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a -@@ a float mark ('.0'). -** This macro is not on by default even in compatibility mode, -** because this is not really an incompatibility. -*/ -/* #define LUA_COMPAT_FLOATSTRING */ - -/* }================================================================== */ - - - -/* -** {================================================================== -** Configuration for Numbers. -** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* -** satisfy your needs. -** =================================================================== -*/ - -/* -@@ LUA_NUMBER is the floating-point type used by Lua. -@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' -@@ over a floating number. -@@ l_mathlim(x) corrects limit name 'x' to the proper float type -** by prefixing it with one of FLT/DBL/LDBL. -@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. -@@ LUA_NUMBER_FMT is the format for writing floats. -@@ lua_number2str converts a float to a string. -@@ l_mathop allows the addition of an 'l' or 'f' to all math operations. -@@ l_floor takes the floor of a float. -@@ lua_str2number converts a decimal numeric string to a number. -*/ - - -/* The following definitions are good for most cases here */ - -#define l_floor(x) (l_mathop(floor)(x)) - -#define lua_number2str(s,sz,n) l_sprintf((s), sz, LUA_NUMBER_FMT, (n)) - -/* -@@ lua_numbertointeger converts a float number to an integer, or -** returns 0 if float is not within the range of a lua_Integer. -** (The range comparisons are tricky because of rounding. The tests -** here assume a two-complement representation, where MININTEGER always -** has an exact representation as a float; MAXINTEGER may not have one, -** and therefore its conversion to float may have an ill-defined value.) -*/ -#define lua_numbertointeger(n,p) \ - ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ - (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ - (*(p) = (LUA_INTEGER)(n), 1)) - - -/* now the variable definitions */ - -#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ - -#define LUA_NUMBER float - -#define l_mathlim(n) (FLT_##n) - -#define LUAI_UACNUMBER double - -#define LUA_NUMBER_FRMLEN "" -#define LUA_NUMBER_FMT "%.7g" - -#define l_mathop(op) op##f - -#define lua_str2number(s,p) strtof((s), (p)) - - -#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ - -#define LUA_NUMBER long double - -#define l_mathlim(n) (LDBL_##n) - -#define LUAI_UACNUMBER long double - -#define LUA_NUMBER_FRMLEN "L" -#define LUA_NUMBER_FMT "%.19Lg" - -#define l_mathop(op) op##l - -#define lua_str2number(s,p) strtold((s), (p)) - -#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */ - -#define LUA_NUMBER double - -#define l_mathlim(n) (DBL_##n) - -#define LUAI_UACNUMBER double - -#define LUA_NUMBER_FRMLEN "" -#define LUA_NUMBER_FMT "%.14g" - -#define l_mathop(op) op - -#define lua_str2number(s,p) strtod((s), (p)) - -#else /* }{ */ - -#error "numeric float type not defined" - -#endif /* } */ - - - -/* -@@ LUA_INTEGER is the integer type used by Lua. -** -@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. -** -@@ LUAI_UACINT is the result of an 'usual argument conversion' -@@ over a lUA_INTEGER. -@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. -@@ LUA_INTEGER_FMT is the format for writing integers. -@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. -@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. -@@ lua_integer2str converts an integer to a string. -*/ - - -/* The following definitions are good for most cases here */ - -#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" -#define lua_integer2str(s,sz,n) l_sprintf((s), sz, LUA_INTEGER_FMT, (n)) - -#define LUAI_UACINT LUA_INTEGER - -/* -** use LUAI_UACINT here to avoid problems with promotions (which -** can turn a comparison between unsigneds into a signed comparison) -*/ -#define LUA_UNSIGNED unsigned LUAI_UACINT - - -/* now the variable definitions */ - -#if LUA_INT_TYPE == LUA_INT_INT /* { int */ - -#define LUA_INTEGER int -#define LUA_INTEGER_FRMLEN "" - -#define LUA_MAXINTEGER INT_MAX -#define LUA_MININTEGER INT_MIN - -#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ - -#define LUA_INTEGER long -#define LUA_INTEGER_FRMLEN "l" - -#define LUA_MAXINTEGER LONG_MAX -#define LUA_MININTEGER LONG_MIN - -#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ - -/* use presence of macro LLONG_MAX as proxy for C99 compliance */ -#if defined(LLONG_MAX) /* { */ -/* use ISO C99 stuff */ - -#define LUA_INTEGER long long -#define LUA_INTEGER_FRMLEN "ll" - -#define LUA_MAXINTEGER LLONG_MAX -#define LUA_MININTEGER LLONG_MIN - -#elif defined(LUA_USE_WINDOWS) /* }{ */ -/* in Windows, can use specific Windows types */ - -#define LUA_INTEGER __int64 -#define LUA_INTEGER_FRMLEN "I64" - -#define LUA_MAXINTEGER _I64_MAX -#define LUA_MININTEGER _I64_MIN - -#else /* }{ */ - -#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ - or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" - -#endif /* } */ - -#else /* }{ */ - -#error "numeric integer type not defined" - -#endif /* } */ - -/* }================================================================== */ - - -/* -** {================================================================== -** Dependencies with C99 and other C details -** =================================================================== -*/ - -/* -@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. -** (All uses in Lua have only one format item.) -*/ -#if !defined(LUA_USE_C89) -#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) -#else -#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) -#endif - - -/* -@@ lua_strx2number converts an hexadecimal numeric string to a number. -** In C99, 'strtod' does that conversion. Otherwise, you can -** leave 'lua_strx2number' undefined and Lua will provide its own -** implementation. -*/ -#if !defined(LUA_USE_C89) -#define lua_strx2number(s,p) lua_str2number(s,p) -#endif - - -/* -@@ lua_number2strx converts a float to an hexadecimal numeric string. -** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. -** Otherwise, you can leave 'lua_number2strx' undefined and Lua will -** provide its own implementation. -*/ -#if !defined(LUA_USE_C89) -#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n)) -#endif - - -/* -** 'strtof' and 'opf' variants for math functions are not valid in -** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the -** availability of these variants. ('math.h' is already included in -** all files that use these macros.) -*/ -#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) -#undef l_mathop /* variants not available */ -#undef lua_str2number -#define l_mathop(op) (lua_Number)op /* no variant */ -#define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) -#endif - - -/* -@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation -** functions. It must be a numerical type; Lua will use 'intptr_t' if -** available, otherwise it will use 'ptrdiff_t' (the nearest thing to -** 'intptr_t' in C89) -*/ -#define LUA_KCONTEXT ptrdiff_t - -#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ - __STDC_VERSION__ >= 199901L -#include <stdint.h> -#if defined(INTPTR_MAX) /* even in C99 this type is optional */ -#undef LUA_KCONTEXT -#define LUA_KCONTEXT intptr_t -#endif -#endif - - -/* -@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). -** Change that if you do not want to use C locales. (Code using this -** macro must include header 'locale.h'.) -*/ -#if !defined(lua_getlocaledecpoint) -#define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) -#endif - -/* }================================================================== */ - - -/* -** {================================================================== -** Language Variations -** ===================================================================== -*/ - -/* -@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some -** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from -** numbers to strings. Define LUA_NOCVTS2N to turn off automatic -** coercion from strings to numbers. -*/ -/* #define LUA_NOCVTN2S */ -/* #define LUA_NOCVTS2N */ - - -/* -@@ LUA_USE_APICHECK turns on several consistency checks on the C API. -** Define it as a help when debugging C code. -*/ -#if defined(LUA_USE_APICHECK) -#include <assert.h> -#define luai_apicheck(l,e) assert(e) -#endif - -/* }================================================================== */ - - -/* -** {================================================================== -** Macros that affect the API and must be stable (that is, must be the -** same when you compile Lua and when you compile code that links to -** Lua). You probably do not want/need to change them. -** ===================================================================== -*/ - -/* -@@ LUAI_MAXSTACK limits the size of the Lua stack. -** CHANGE it if you need a different limit. This limit is arbitrary; -** its only purpose is to stop Lua from consuming unlimited stack -** space (and to reserve some numbers for pseudo-indices). -*/ -#if LUAI_BITSINT >= 32 -#define LUAI_MAXSTACK 1000000 -#else -#define LUAI_MAXSTACK 15000 -#endif - - -/* -@@ LUA_EXTRASPACE defines the size of a raw memory area associated with -** a Lua state with very fast access. -** CHANGE it if you need a different size. -*/ -#define LUA_EXTRASPACE (sizeof(void *)) - - -/* -@@ LUA_IDSIZE gives the maximum size for the description of the source -@@ of a function in debug information. -** CHANGE it if you want a different size. -*/ -#define LUA_IDSIZE 60 - - -/* -@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. -** CHANGE it if it uses too much C-stack space. (For long double, -** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a -** smaller buffer would force a memory allocation for each call to -** 'string.format'.) -*/ -#if defined(LUA_FLOAT_LONGDOUBLE) -#define LUAL_BUFFERSIZE 8192 -#else -#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) -#endif - -/* }================================================================== */ - - -/* -@@ LUA_QL describes how error messages quote program elements. -** Lua does not use these macros anymore; they are here for -** compatibility only. -*/ -#define LUA_QL(x) "'" x "'" -#define LUA_QS LUA_QL("%s") - - - - -/* =================================================================== */ - -/* -** Local configuration. You can use this space to add your redefinitions -** without modifying the main part of the file. -*/ - - - - - -#endif - diff --git a/src/external/lua/include/lualib.h b/src/external/lua/include/lualib.h deleted file mode 100644 index 5165c0fb..00000000 --- a/src/external/lua/include/lualib.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ -** Lua standard libraries -** See Copyright Notice in lua.h -*/ - - -#ifndef lualib_h -#define lualib_h - -#include "lua.h" - - - -LUAMOD_API int (luaopen_base) (lua_State *L); - -#define LUA_COLIBNAME "coroutine" -LUAMOD_API int (luaopen_coroutine) (lua_State *L); - -#define LUA_TABLIBNAME "table" -LUAMOD_API int (luaopen_table) (lua_State *L); - -#define LUA_IOLIBNAME "io" -LUAMOD_API int (luaopen_io) (lua_State *L); - -#define LUA_OSLIBNAME "os" -LUAMOD_API int (luaopen_os) (lua_State *L); - -#define LUA_STRLIBNAME "string" -LUAMOD_API int (luaopen_string) (lua_State *L); - -#define LUA_UTF8LIBNAME "utf8" -LUAMOD_API int (luaopen_utf8) (lua_State *L); - -#define LUA_BITLIBNAME "bit32" -LUAMOD_API int (luaopen_bit32) (lua_State *L); - -#define LUA_MATHLIBNAME "math" -LUAMOD_API int (luaopen_math) (lua_State *L); - -#define LUA_DBLIBNAME "debug" -LUAMOD_API int (luaopen_debug) (lua_State *L); - -#define LUA_LOADLIBNAME "package" -LUAMOD_API int (luaopen_package) (lua_State *L); - - -/* open all previous libraries */ -LUALIB_API void (luaL_openlibs) (lua_State *L); - - - -#if !defined(lua_assert) -#define lua_assert(x) ((void)0) -#endif - - -#endif diff --git a/src/external/lua/lib/liblua53.a b/src/external/lua/lib/liblua53.a Binary files differdeleted file mode 100644 index e51c0c80..00000000 --- a/src/external/lua/lib/liblua53.a +++ /dev/null diff --git a/src/external/lua/lib/liblua53dll.a b/src/external/lua/lib/liblua53dll.a Binary files differdeleted file mode 100644 index 32646db3..00000000 --- a/src/external/lua/lib/liblua53dll.a +++ /dev/null diff --git a/src/external/openal_soft/include/AL/alext.h b/src/external/openal_soft/include/AL/alext.h index 0090c804..50ad10ec 100644 --- a/src/external/openal_soft/include/AL/alext.h +++ b/src/external/openal_soft/include/AL/alext.h @@ -436,6 +436,18 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi #define AL_GAIN_LIMIT_SOFT 0x200E #endif +#ifndef AL_SOFT_source_resampler +#define AL_SOFT_source_resampler +#define AL_NUM_RESAMPLERS_SOFT 0x1210 +#define AL_DEFAULT_RESAMPLER_SOFT 0x1211 +#define AL_SOURCE_RESAMPLER_SOFT 0x1212 +#define AL_RESAMPLER_NAME_SOFT 0x1213 +typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index); +#ifdef AL_ALEXT_PROTOTYPES +AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index); +#endif +#endif + #ifdef __cplusplus } #endif diff --git a/src/external/openal_soft/lib/android/libopenal.so b/src/external/openal_soft/lib/android/libopenal.so Binary files differnew file mode 100644 index 00000000..e384d9ad --- /dev/null +++ b/src/external/openal_soft/lib/android/libopenal.so diff --git a/src/external/pthread/COPYING b/src/external/pthread/COPYING deleted file mode 100644 index 5cfea0d0..00000000 --- a/src/external/pthread/COPYING +++ /dev/null @@ -1,150 +0,0 @@ - pthreads-win32 - a POSIX threads library for Microsoft Windows - - -This file is Copyrighted ------------------------- - - This file is covered under the following Copyright: - - Copyright (C) 2001,2006 Ross P. Johnson - All rights reserved. - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -Pthreads-win32 is covered by the GNU Lesser General Public License ------------------------------------------------------------------- - - Pthreads-win32 is open software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation version 2.1 of the - License. - - Pthreads-win32 is several binary link libraries, several modules, - associated interface definition files and scripts used to control - its compilation and installation. - - Pthreads-win32 is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - A copy of the GNU Lesser General Public License is distributed with - pthreads-win32 under the filename: - - COPYING.LIB - - You should have received a copy of the version 2.1 GNU Lesser General - Public License with pthreads-win32; if not, write to: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA - - The contact addresses for pthreads-win32 is as follows: - - Web: http://sources.redhat.com/pthreads-win32 - Email: Ross Johnson - Please use: Firstname.Lastname@homemail.com.au - - - -Pthreads-win32 copyrights and exception files ---------------------------------------------- - - With the exception of the files listed below, Pthreads-win32 - is covered under the following GNU Lesser General Public License - Copyrights: - - Pthreads-win32 - POSIX Threads Library for Win32 - Copyright(C) 1998 John E. Bossom - Copyright(C) 1999,2006 Pthreads-win32 contributors - - The current list of contributors is contained - in the file CONTRIBUTORS included with the source - code distribution. The current list of CONTRIBUTORS - can also be seen at the following WWW location: - http://sources.redhat.com/pthreads-win32/contributors.html - - Contact Email: Ross Johnson - Please use: Firstname.Lastname@homemail.com.au - - These files are not covered under one of the Copyrights listed above: - - COPYING - COPYING.LIB - tests/rwlock7.c - - This file, COPYING, is distributed under the Copyright found at the - top of this file. It is important to note that you may distribute - verbatim copies of this file but you may not modify this file. - - The file COPYING.LIB, which contains a copy of the version 2.1 - GNU Lesser General Public License, is itself copyrighted by the - Free Software Foundation, Inc. Please note that the Free Software - Foundation, Inc. does NOT have a copyright over Pthreads-win32, - only the COPYING.LIB that is supplied with pthreads-win32. - - The file tests/rwlock7.c is derived from code written by - Dave Butenhof for his book 'Programming With POSIX(R) Threads'. - The original code was obtained by free download from his website - http://home.earthlink.net/~anneart/family/Threads/source.html - and did not contain a copyright or author notice. It is assumed to - be freely distributable. - - In all cases one may use and distribute these exception files freely. - And because one may freely distribute the LGPL covered files, the - entire pthreads-win32 source may be freely used and distributed. - - - -General Copyleft and License info ---------------------------------- - - For general information on Copylefts, see: - - http://www.gnu.org/copyleft/ - - For information on GNU Lesser General Public Licenses, see: - - http://www.gnu.org/copyleft/lesser.html - http://www.gnu.org/copyleft/lesser.txt - - -Why pthreads-win32 did not use the GNU General Public License -------------------------------------------------------------- - - The goal of the pthreads-win32 project has been to - provide a quality and complete implementation of the POSIX - threads API for Microsoft Windows within the limits imposed - by virtue of it being a stand-alone library and not - linked directly to other POSIX compliant libraries. For - example, some functions and features, such as those based - on POSIX signals, are missing. - - Pthreads-win32 is a library, available in several different - versions depending on supported compilers, and may be used - as a dynamically linked module or a statically linked set of - binary modules. It is not an application on it's own. - - It was fully intended that pthreads-win32 be usable with - commercial software not covered by either the GPL or the LGPL - licenses. Pthreads-win32 has many contributors to it's - code base, many of whom have done so because they have - used the library in commercial or proprietry software - projects. - - Releasing pthreads-win32 under the LGPL ensures that the - library can be used widely, while at the same time ensures - that bug fixes and improvements to the pthreads-win32 code - itself is returned to benefit all current and future users - of the library. - - Although pthreads-win32 makes it possible for applications - that use POSIX threads to be ported to Win32 platforms, the - broader goal of the project is to encourage the use of open - standards, and in particular, to make it just a little easier - for developers writing Win32 applications to consider - widening the potential market for their products. diff --git a/src/external/pthread/include/pthread.h b/src/external/pthread/include/pthread.h deleted file mode 100644 index b4072f72..00000000 --- a/src/external/pthread/include/pthread.h +++ /dev/null @@ -1,1368 +0,0 @@ -/* This is an implementation of the threads API of POSIX 1003.1-2001. - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#if !defined( PTHREAD_H ) -#define PTHREAD_H - -/* - * See the README file for an explanation of the pthreads-win32 version - * numbering scheme and how the DLL is named etc. - */ -#define PTW32_VERSION 2,9,1,0 -#define PTW32_VERSION_STRING "2, 9, 1, 0\0" - -/* There are three implementations of cancel cleanup. - * Note that pthread.h is included in both application - * compilation units and also internally for the library. - * The code here and within the library aims to work - * for all reasonable combinations of environments. - * - * The three implementations are: - * - * WIN32 SEH - * C - * C++ - * - * Please note that exiting a push/pop block via - * "return", "exit", "break", or "continue" will - * lead to different behaviour amongst applications - * depending upon whether the library was built - * using SEH, C++, or C. For example, a library built - * with SEH will call the cleanup routine, while both - * C++ and C built versions will not. - */ - -/* - * Define defaults for cleanup code. - * Note: Unless the build explicitly defines one of the following, then - * we default to standard C style cleanup. This style uses setjmp/longjmp - * in the cancelation and thread exit implementations and therefore won't - * do stack unwinding if linked to applications that have it (e.g. - * C++ apps). This is currently consistent with most/all commercial Unix - * POSIX threads implementations. - */ -#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) -# define __CLEANUP_C -#endif - -#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) -#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. -#endif - -/* - * Stop here if we are being included by the resource compiler. - */ -#if !defined(RC_INVOKED) - -#undef PTW32_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_LEVEL -#define PTW32_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_LEVEL -#define PTW32_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) -#define PTW32_LEVEL PTW32_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(_UWIN) -# define HAVE_STRUCT_TIMESPEC 1 -# define HAVE_SIGNAL_H 1 -# undef HAVE_PTW32_CONFIG_H -# pragma comment(lib, "pthread") -#endif - -/* - * ------------------------------------------------------------- - * - * - * Module: pthread.h - * - * Purpose: - * Provides an implementation of PThreads based upon the - * standard: - * - * POSIX 1003.1-2001 - * and - * The Single Unix Specification version 3 - * - * (these two are equivalent) - * - * in order to enhance code portability between Windows, - * various commercial Unix implementations, and Linux. - * - * See the ANNOUNCE file for a full list of conforming - * routines and defined constants, and a list of missing - * routines and constants not defined in this implementation. - * - * Authors: - * There have been many contributors to this library. - * The initial implementation was contributed by - * John Bossom, and several others have provided major - * sections or revisions of parts of the implementation. - * Often significant effort has been contributed to - * find and fix important bugs and other problems to - * improve the reliability of the library, which sometimes - * is not reflected in the amount of code which changed as - * result. - * As much as possible, the contributors are acknowledged - * in the ChangeLog file in the source code distribution - * where their changes are noted in detail. - * - * Contributors are listed in the CONTRIBUTORS file. - * - * As usual, all bouquets go to the contributors, and all - * brickbats go to the project maintainer. - * - * Maintainer: - * The code base for this project is coordinated and - * eventually pre-tested, packaged, and made available by - * - * Ross Johnson <rpj@callisto.canberra.edu.au> - * - * QA Testers: - * Ultimately, the library is tested in the real world by - * a host of competent and demanding scientists and - * engineers who report bugs and/or provide solutions - * which are then fixed or incorporated into subsequent - * versions of the library. Each time a bug is fixed, a - * test case is written to prove the fix and ensure - * that later changes to the code don't reintroduce the - * same error. The number of test cases is slowly growing - * and therefore so is the code reliability. - * - * Compliance: - * See the file ANNOUNCE for the list of implemented - * and not-implemented routines and defined options. - * Of course, these are all defined is this file as well. - * - * Web site: - * The source code and other information about this library - * are available from - * - * http://sources.redhat.com/pthreads-win32/ - * - * ------------------------------------------------------------- - */ - -/* Try to avoid including windows.h */ -#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) -#define PTW32_INCLUDE_WINDOWS_H -#endif - -#if defined(PTW32_INCLUDE_WINDOWS_H) -#include <windows.h> -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) -/* - * VC++6.0 or early compiler's header has no DWORD_PTR type. - */ -typedef unsigned long DWORD_PTR; -typedef unsigned long ULONG_PTR; -#endif -/* - * ----------------- - * autoconf switches - * ----------------- - */ - -#if defined(HAVE_PTW32_CONFIG_H) -#include "config.h" -#endif /* HAVE_PTW32_CONFIG_H */ - -#if !defined(NEED_FTIME) -#include <time.h> -#else /* NEED_FTIME */ -/* use native WIN32 time API */ -#endif /* NEED_FTIME */ - -#if defined(HAVE_SIGNAL_H) -#include <signal.h> -#endif /* HAVE_SIGNAL_H */ - -#include <limits.h> - -/* - * Boolean values to make us independent of system includes. - */ -enum { - PTW32_FALSE = 0, - PTW32_TRUE = (! PTW32_FALSE) -}; - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include <errno.h> -#endif -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Several systems don't define some error numbers. - */ -#if !defined(ENOTSUP) -# define ENOTSUP 48 /* This is the value in Solaris. */ -#endif - -#if !defined(ETIMEDOUT) -# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ -#endif - -#if !defined(ENOSYS) -# define ENOSYS 140 /* Semi-arbitrary value */ -#endif - -#if !defined(EDEADLK) -# if defined(EDEADLOCK) -# define EDEADLK EDEADLOCK -# else -# define EDEADLK 36 /* This is the value in MSVC. */ -# endif -#endif - -/* POSIX 2008 - related to robust mutexes */ -#if !defined(EOWNERDEAD) -# define EOWNERDEAD 43 -#endif -#if !defined(ENOTRECOVERABLE) -# define ENOTRECOVERABLE 44 -#endif - -#include <sched.h> - -/* - * To avoid including windows.h we define only those things that we - * actually need from it. - */ -#if !defined(PTW32_INCLUDE_WINDOWS_H) -#if !defined(HANDLE) -# define PTW32__HANDLE_DEF -# define HANDLE void * -#endif -#if !defined(DWORD) -# define PTW32__DWORD_DEF -# define DWORD unsigned long -#endif -#endif - -#if !defined(HAVE_STRUCT_TIMESPEC) -#define HAVE_STRUCT_TIMESPEC -#if !defined(_TIMESPEC_DEFINED) -#define _TIMESPEC_DEFINED -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif /* _TIMESPEC_DEFINED */ -#endif /* HAVE_STRUCT_TIMESPEC */ - -#if !defined(SIG_BLOCK) -#define SIG_BLOCK 0 -#endif /* SIG_BLOCK */ - -#if !defined(SIG_UNBLOCK) -#define SIG_UNBLOCK 1 -#endif /* SIG_UNBLOCK */ - -#if !defined(SIG_SETMASK) -#define SIG_SETMASK 2 -#endif /* SIG_SETMASK */ - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -/* - * ------------------------------------------------------------- - * - * POSIX 1003.1-2001 Options - * ========================= - * - * Options are normally set in <unistd.h>, which is not provided - * with pthreads-win32. - * - * For conformance with the Single Unix Specification (version 3), all of the - * options below are defined, and have a value of either -1 (not supported) - * or 200112L (supported). - * - * These options can neither be left undefined nor have a value of 0, because - * either indicates that sysconf(), which is not implemented, may be used at - * runtime to check the status of the option. - * - * _POSIX_THREADS (== 200112L) - * If == 200112L, you can use threads - * - * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) - * If == 200112L, you can control the size of a thread's - * stack - * pthread_attr_getstacksize - * pthread_attr_setstacksize - * - * _POSIX_THREAD_ATTR_STACKADDR (== -1) - * If == 200112L, you can allocate and control a thread's - * stack. If not supported, the following functions - * will return ENOSYS, indicating they are not - * supported: - * pthread_attr_getstackaddr - * pthread_attr_setstackaddr - * - * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) - * If == 200112L, you can use realtime scheduling. - * This option indicates that the behaviour of some - * implemented functions conforms to the additional TPS - * requirements in the standard. E.g. rwlocks favour - * writers over readers when threads have equal priority. - * - * _POSIX_THREAD_PRIO_INHERIT (== -1) - * If == 200112L, you can create priority inheritance - * mutexes. - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PRIO_PROTECT (== -1) - * If == 200112L, you can create priority ceiling mutexes - * Indicates the availability of: - * pthread_mutex_getprioceiling - * pthread_mutex_setprioceiling - * pthread_mutexattr_getprioceiling - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprioceiling - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PROCESS_SHARED (== -1) - * If set, you can create mutexes and condition - * variables that can be shared with another - * process.If set, indicates the availability - * of: - * pthread_mutexattr_getpshared - * pthread_mutexattr_setpshared - * pthread_condattr_getpshared - * pthread_condattr_setpshared - * - * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) - * If == 200112L you can use the special *_r library - * functions that provide thread-safe behaviour - * - * _POSIX_READER_WRITER_LOCKS (== 200112L) - * If == 200112L, you can use read/write locks - * - * _POSIX_SPIN_LOCKS (== 200112L) - * If == 200112L, you can use spin locks - * - * _POSIX_BARRIERS (== 200112L) - * If == 200112L, you can use barriers - * - * + These functions provide both 'inherit' and/or - * 'protect' protocol, based upon these macro - * settings. - * - * ------------------------------------------------------------- - */ - -/* - * POSIX Options - */ -#undef _POSIX_THREADS -#define _POSIX_THREADS 200809L - -#undef _POSIX_READER_WRITER_LOCKS -#define _POSIX_READER_WRITER_LOCKS 200809L - -#undef _POSIX_SPIN_LOCKS -#define _POSIX_SPIN_LOCKS 200809L - -#undef _POSIX_BARRIERS -#define _POSIX_BARRIERS 200809L - -#undef _POSIX_THREAD_SAFE_FUNCTIONS -#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L - -#undef _POSIX_THREAD_ATTR_STACKSIZE -#define _POSIX_THREAD_ATTR_STACKSIZE 200809L - -/* - * The following options are not supported - */ -#undef _POSIX_THREAD_ATTR_STACKADDR -#define _POSIX_THREAD_ATTR_STACKADDR -1 - -#undef _POSIX_THREAD_PRIO_INHERIT -#define _POSIX_THREAD_PRIO_INHERIT -1 - -#undef _POSIX_THREAD_PRIO_PROTECT -#define _POSIX_THREAD_PRIO_PROTECT -1 - -/* TPS is not fully supported. */ -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 - -#undef _POSIX_THREAD_PROCESS_SHARED -#define _POSIX_THREAD_PROCESS_SHARED -1 - - -/* - * POSIX 1003.1-2001 Limits - * =========================== - * - * These limits are normally set in <limits.h>, which is not provided with - * pthreads-win32. - * - * PTHREAD_DESTRUCTOR_ITERATIONS - * Maximum number of attempts to destroy - * a thread's thread-specific data on - * termination (must be at least 4) - * - * PTHREAD_KEYS_MAX - * Maximum number of thread-specific data keys - * available per process (must be at least 128) - * - * PTHREAD_STACK_MIN - * Minimum supported stack size for a thread - * - * PTHREAD_THREADS_MAX - * Maximum number of threads supported per - * process (must be at least 64). - * - * SEM_NSEMS_MAX - * The maximum number of semaphores a process can have. - * (must be at least 256) - * - * SEM_VALUE_MAX - * The maximum value a semaphore can have. - * (must be at least 32767) - * - */ -#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 - -#undef PTHREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS - -#undef _POSIX_THREAD_KEYS_MAX -#define _POSIX_THREAD_KEYS_MAX 128 - -#undef PTHREAD_KEYS_MAX -#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX - -#undef PTHREAD_STACK_MIN -#define PTHREAD_STACK_MIN 0 - -#undef _POSIX_THREAD_THREADS_MAX -#define _POSIX_THREAD_THREADS_MAX 64 - - /* Arbitrary value */ -#undef PTHREAD_THREADS_MAX -#define PTHREAD_THREADS_MAX 2019 - -#undef _POSIX_SEM_NSEMS_MAX -#define _POSIX_SEM_NSEMS_MAX 256 - - /* Arbitrary value */ -#undef SEM_NSEMS_MAX -#define SEM_NSEMS_MAX 1024 - -#undef _POSIX_SEM_VALUE_MAX -#define _POSIX_SEM_VALUE_MAX 32767 - -#undef SEM_VALUE_MAX -#define SEM_VALUE_MAX INT_MAX - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * The Open Watcom C/C++ compiler uses a non-standard calling convention - * that passes function args in registers unless __cdecl is explicitly specified - * in exposed function prototypes. - * - * We force all calls to cdecl even though this could slow Watcom code down - * slightly. If you know that the Watcom compiler will be used to build both - * the DLL and application, then you can probably define this as a null string. - * Remember that pthread.h (this file) is used for both the DLL and application builds. - */ -#define PTW32_CDECL __cdecl - -#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX -# include <sys/types.h> -#else -/* - * Generic handle type - intended to extend uniqueness beyond - * that available with a simple pointer. It should scale for either - * IA-32 or IA-64. - */ -typedef struct { - void * p; /* Pointer to actual object */ - unsigned int x; /* Extra information - reuse count etc */ -} ptw32_handle_t; - -typedef ptw32_handle_t pthread_t; -typedef struct pthread_attr_t_ * pthread_attr_t; -typedef struct pthread_once_t_ pthread_once_t; -typedef struct pthread_key_t_ * pthread_key_t; -typedef struct pthread_mutex_t_ * pthread_mutex_t; -typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; -typedef struct pthread_cond_t_ * pthread_cond_t; -typedef struct pthread_condattr_t_ * pthread_condattr_t; -#endif -typedef struct pthread_rwlock_t_ * pthread_rwlock_t; -typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; -typedef struct pthread_spinlock_t_ * pthread_spinlock_t; -typedef struct pthread_barrier_t_ * pthread_barrier_t; -typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; - -/* - * ==================== - * ==================== - * POSIX Threads - * ==================== - * ==================== - */ - -enum { -/* - * pthread_attr_{get,set}detachstate - */ - PTHREAD_CREATE_JOINABLE = 0, /* Default */ - PTHREAD_CREATE_DETACHED = 1, - -/* - * pthread_attr_{get,set}inheritsched - */ - PTHREAD_INHERIT_SCHED = 0, - PTHREAD_EXPLICIT_SCHED = 1, /* Default */ - -/* - * pthread_{get,set}scope - */ - PTHREAD_SCOPE_PROCESS = 0, - PTHREAD_SCOPE_SYSTEM = 1, /* Default */ - -/* - * pthread_setcancelstate paramters - */ - PTHREAD_CANCEL_ENABLE = 0, /* Default */ - PTHREAD_CANCEL_DISABLE = 1, - -/* - * pthread_setcanceltype parameters - */ - PTHREAD_CANCEL_ASYNCHRONOUS = 0, - PTHREAD_CANCEL_DEFERRED = 1, /* Default */ - -/* - * pthread_mutexattr_{get,set}pshared - * pthread_condattr_{get,set}pshared - */ - PTHREAD_PROCESS_PRIVATE = 0, - PTHREAD_PROCESS_SHARED = 1, - -/* - * pthread_mutexattr_{get,set}robust - */ - PTHREAD_MUTEX_STALLED = 0, /* Default */ - PTHREAD_MUTEX_ROBUST = 1, - -/* - * pthread_barrier_wait - */ - PTHREAD_BARRIER_SERIAL_THREAD = -1 -}; - -/* - * ==================== - * ==================== - * Cancelation - * ==================== - * ==================== - */ -#define PTHREAD_CANCELED ((void *)(size_t) -1) - - -/* - * ==================== - * ==================== - * Once Key - * ==================== - * ==================== - */ -#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} - -struct pthread_once_t_ -{ - int done; /* indicates if user function has been executed */ - void * lock; - int reserved1; - int reserved2; -}; - - -/* - * ==================== - * ==================== - * Object initialisers - * ==================== - * ==================== - */ -#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) - -/* - * Compatibility with LinuxThreads - */ -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER - -#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) - -#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) - -#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) - - -/* - * Mutex types. - */ -enum -{ - /* Compatibility with LinuxThreads */ - PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, - /* For compatibility with POSIX */ - PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL -}; - - -typedef struct ptw32_cleanup_t ptw32_cleanup_t; - -#if defined(_MSC_VER) -/* Disable MSVC 'anachronism used' warning */ -#pragma warning( disable : 4229 ) -#endif - -typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); - -#if defined(_MSC_VER) -#pragma warning( default : 4229 ) -#endif - -struct ptw32_cleanup_t -{ - ptw32_cleanup_callback_t routine; - void *arg; - struct ptw32_cleanup_t *prev; -}; - -#if defined(__CLEANUP_SEH) - /* - * WIN32 SEH version of cancel cleanup. - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ - _cleanup.arg = (_arg); \ - __try \ - { \ - -#define pthread_cleanup_pop( _execute ) \ - } \ - __finally \ - { \ - if( _execute || AbnormalTermination()) \ - { \ - (*(_cleanup.routine))( _cleanup.arg ); \ - } \ - } \ - } - -#else /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_C) - - /* - * C implementation of PThreads cancel cleanup - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ - -#define pthread_cleanup_pop( _execute ) \ - (void) ptw32_pop_cleanup( _execute ); \ - } - -#else /* __CLEANUP_C */ - -#if defined(__CLEANUP_CXX) - - /* - * C++ version of cancel cleanup. - * - John E. Bossom. - */ - - class PThreadCleanup { - /* - * PThreadCleanup - * - * Purpose - * This class is a C++ helper class that is - * used to implement pthread_cleanup_push/ - * pthread_cleanup_pop. - * The destructor of this class automatically - * pops the pushed cleanup routine regardless - * of how the code exits the scope - * (i.e. such as by an exception) - */ - ptw32_cleanup_callback_t cleanUpRout; - void * obj; - int executeIt; - - public: - PThreadCleanup() : - cleanUpRout( 0 ), - obj( 0 ), - executeIt( 0 ) - /* - * No cleanup performed - */ - { - } - - PThreadCleanup( - ptw32_cleanup_callback_t routine, - void * arg ) : - cleanUpRout( routine ), - obj( arg ), - executeIt( 1 ) - /* - * Registers a cleanup routine for 'arg' - */ - { - } - - ~PThreadCleanup() - { - if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) - { - (void) (*cleanUpRout)( obj ); - } - } - - void execute( int exec ) - { - executeIt = exec; - } - }; - - /* - * C++ implementation of PThreads cancel cleanup; - * This implementation takes advantage of a helper - * class who's destructor automatically calls the - * cleanup routine if we exit our scope weirdly - */ -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ - (void *) (_arg) ); - -#define pthread_cleanup_pop( _execute ) \ - cleanup.execute( _execute ); \ - } - -#else - -#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. - -#endif /* __CLEANUP_CXX */ - -#endif /* __CLEANUP_C */ - -#endif /* __CLEANUP_SEH */ - -/* - * =============== - * =============== - * Methods - * =============== - * =============== - */ - -/* - * PThread Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, - int *detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, - void **stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, - size_t * stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, - int detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, - void *stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, - size_t stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, - int *); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, - int inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, - int * inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, - int *); - -/* - * PThread Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, - const pthread_attr_t * attr, - void *(PTW32_CDECL *start) (void *), - void *arg); - -PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); - -PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, - pthread_t t2); - -PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); - -PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, - void **value_ptr); - -PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, - int *oldstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, - int *oldtype); - -PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, - void (PTW32_CDECL *init_routine) (void)); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); - -PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, - ptw32_cleanup_callback_t routine, - void *arg); -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread Specific Data Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, - void (PTW32_CDECL *destructor) (void *)); - -PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); - -PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, - const void *value); - -PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); - - -/* - * Mutex Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, - int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( - pthread_mutexattr_t *attr, - int robust); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( - const pthread_mutexattr_t * attr, - int * robust); - -/* - * Barrier Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, - int pshared); - -/* - * Mutex Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, - const pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); - -/* - * Spinlock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); - -/* - * Barrier Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, - const pthread_barrierattr_t * attr, - unsigned int count); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); - -/* - * Condition Variable Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, - int pshared); - -/* - * Condition Variable Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, - const pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, - pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, - pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); - -/* - * Scheduling - */ -PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, - int policy, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, - int *policy, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); - -PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); - -/* - * Read-Write Lock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, - const pthread_rwlockattr_t *attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, - int pshared); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 - -/* - * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32 - * already have signal.h that don't define these. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); - -/* - * Non-portable functions - */ - -/* - * Compatibility with Linux. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, - int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, - int *kind); - -/* - * Possibly supported by other POSIX threads implementations - */ -PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); -PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); -PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); - -/* - * Useful if an application wants to statically link - * the lib rather than load the DLL at run-time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); - -/* - * Features that are auto-detected at load/run time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); -enum ptw32_features { - PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ - PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ -}; - -/* - * Register a system time change with the library. - * Causes the library to perform various functions - * in response to the change. Should be called whenever - * the application's top level window receives a - * WM_TIMECHANGE message. It can be passed directly to - * pthread_create() as a new thread if desired. - */ -PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); - -#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* - * Returns the Win32 HANDLE for the POSIX thread. - */ -PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); -/* - * Returns the win32 thread ID for POSIX thread. - */ -PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); - - -/* - * Protected Methods - * - * This function blocks until the given WIN32 handle - * is signaled or pthread_cancel had been called. - * This function allows the caller to hook into the - * PThreads cancel mechanism. It is implemented using - * - * WaitForMultipleObjects - * - * on 'waitHandle' and a manually reset WIN32 Event - * used to implement pthread_cancel. The 'timeout' - * argument to TimedWait is simply passed to - * WaitForMultipleObjects. - */ -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, - DWORD timeout); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread-Safe C Runtime Library Mappings. - */ -#if !defined(_UWIN) -# if defined(NEED_ERRNO) - PTW32_DLLPORT int * PTW32_CDECL _errno( void ); -# else -# if !defined(errno) -# if (defined(_MT) || defined(_DLL)) - __declspec(dllimport) extern int * __cdecl _errno(void); -# define errno (*_errno()) -# endif -# endif -# endif -#endif - -/* - * Some compiler environments don't define some things. - */ -#if defined(__BORLANDC__) -# define _ftime ftime -# define _timeb timeb -#endif - -#if defined(__cplusplus) - -/* - * Internal exceptions - */ -class ptw32_exception {}; -class ptw32_exception_cancel : public ptw32_exception {}; -class ptw32_exception_exit : public ptw32_exception {}; - -#endif - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* FIXME: This is only required if the library was built using SEH */ -/* - * Get internal SEH tag - */ -PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -#if !defined(PTW32_BUILD) - -#if defined(__CLEANUP_SEH) - -/* - * Redefine the SEH __except keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#define __except( E ) \ - __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ - ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) - -#endif /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_CXX) - -/* - * Redefine the C++ catch keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#if defined(_MSC_VER) - /* - * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' - * if you want Pthread-Win32 cancelation and pthread_exit to work. - */ - -#if !defined(PtW32NoCatchWarn) - -#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") -#pragma message("------------------------------------------------------------------") -#pragma message("When compiling applications with MSVC++ and C++ exception handling:") -#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") -#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") -#pragma message(" cancelation and pthread_exit to work. For example:") -#pragma message("") -#pragma message(" #if defined(PtW32CatchAll)") -#pragma message(" PtW32CatchAll") -#pragma message(" #else") -#pragma message(" catch(...)") -#pragma message(" #endif") -#pragma message(" {") -#pragma message(" /* Catchall block processing */") -#pragma message(" }") -#pragma message("------------------------------------------------------------------") - -#endif - -#define PtW32CatchAll \ - catch( ptw32_exception & ) { throw; } \ - catch( ... ) - -#else /* _MSC_VER */ - -#define catch( E ) \ - catch( ptw32_exception & ) { throw; } \ - catch( E ) - -#endif /* _MSC_VER */ - -#endif /* __CLEANUP_CXX */ - -#endif /* ! PTW32_BUILD */ - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#if defined(PTW32__HANDLE_DEF) -# undef HANDLE -#endif -#if defined(PTW32__DWORD_DEF) -# undef DWORD -#endif - -#undef PTW32_LEVEL -#undef PTW32_LEVEL_MAX - -#endif /* ! RC_INVOKED */ - -#endif /* PTHREAD_H */ diff --git a/src/external/pthread/include/sched.h b/src/external/pthread/include/sched.h deleted file mode 100644 index f36a97a6..00000000 --- a/src/external/pthread/include/sched.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Module: sched.h - * - * Purpose: - * Provides an implementation of POSIX realtime extensions - * as defined in - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined(_SCHED_H) -#define _SCHED_H - -#undef PTW32_SCHED_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SCHED_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SCHED_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) -#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX -/* Include everything */ -#endif - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include <errno.h> -#endif -#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ - -#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) -# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -/* For pid_t */ -# include <sys/types.h> -/* Required by Unix 98 */ -# include <time.h> -# else - typedef int pid_t; -# endif -#else - typedef int pid_t; -#endif - -/* Thread scheduling policies */ - -enum { - SCHED_OTHER = 0, - SCHED_FIFO, - SCHED_RR, - SCHED_MIN = SCHED_OTHER, - SCHED_MAX = SCHED_RR -}; - -struct sched_param { - int sched_priority; -}; - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -PTW32_DLLPORT int __cdecl sched_yield (void); - -PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); - -PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); - -PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); - -PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); - -/* - * Note that this macro returns ENOTSUP rather than - * ENOSYS as might be expected. However, returning ENOSYS - * should mean that sched_get_priority_{min,max} are - * not implemented as well as sched_rr_get_interval. - * This is not the case, since we just don't support - * round-robin scheduling. Therefore I have chosen to - * return the same value as sched_setscheduler when - * SCHED_RR is passed to it. - */ -#define sched_rr_get_interval(_pid, _interval) \ - ( errno = ENOTSUP, (int) -1 ) - - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SCHED_LEVEL -#undef PTW32_SCHED_LEVEL_MAX - -#endif /* !_SCHED_H */ - diff --git a/src/external/pthread/include/semaphore.h b/src/external/pthread/include/semaphore.h deleted file mode 100644 index c6e9407e..00000000 --- a/src/external/pthread/include/semaphore.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Module: semaphore.h - * - * Purpose: - * Semaphores aren't actually part of the PThreads standard. - * They are defined by the POSIX Standard: - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined( SEMAPHORE_H ) -#define SEMAPHORE_H - -#undef PTW32_SEMAPHORE_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SEMAPHORE_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SEMAPHORE_LEVEL -#define PTW32_SEMAPHORE_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SEMAPHORE_LEVEL -#define PTW32_SEMAPHORE_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SEMAPHORE_LEVEL_MAX 3 - -#if !defined(PTW32_SEMAPHORE_LEVEL) -#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(__GNUC__) && ! defined (__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include <errno.h> -#endif -#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ - -#define _POSIX_SEMAPHORES - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -#if !defined(HAVE_MODE_T) -typedef unsigned int mode_t; -#endif - - -typedef struct sem_t_ * sem_t; - -PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, - int pshared, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, - const struct timespec * abstime); - -PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, - int count); - -PTW32_DLLPORT int __cdecl sem_open (const char * name, - int oflag, - mode_t mode, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_unlink (const char * name); - -PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, - int * sval); - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SEMAPHORE_LEVEL -#undef PTW32_SEMAPHORE_LEVEL_MAX - -#endif /* !SEMAPHORE_H */ diff --git a/src/external/pthread/lib/libpthreadGC2.a b/src/external/pthread/lib/libpthreadGC2.a Binary files differdeleted file mode 100644 index df211759..00000000 --- a/src/external/pthread/lib/libpthreadGC2.a +++ /dev/null diff --git a/src/external/pthread/lib/pthreadGC2.dll b/src/external/pthread/lib/pthreadGC2.dll Binary files differdeleted file mode 100644 index 67b9289d..00000000 --- a/src/external/pthread/lib/pthreadGC2.dll +++ /dev/null diff --git a/src/external/stb_image.h b/src/external/stb_image.h index 4d8d0133..ae2ada6a 100644 --- a/src/external/stb_image.h +++ b/src/external/stb_image.h @@ -1,4 +1,4 @@ -/* stb_image - v2.14 - public domain image loader - http://nothings.org/stb_image.h +/* stb_image - v2.15 - public domain image loader - http://nothings.org/stb_image.h no warranty implied; use at your own risk Do this: @@ -21,7 +21,7 @@ avoid problematic images and only need the trivial interface JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) - PNG 1/2/4/8-bit-per-channel (16 bpc not supported) + PNG 1/2/4/8/16-bit-per-channel TGA (not sure what subset, if a subset) BMP non-1bpp, non-RLE @@ -42,115 +42,19 @@ Full documentation under "DOCUMENTATION" below. - Revision 2.00 release notes: - - - Progressive JPEG is now supported. - - - PPM and PGM binary formats are now supported, thanks to Ken Miller. - - - x86 platforms now make use of SSE2 SIMD instructions for - JPEG decoding, and ARM platforms can use NEON SIMD if requested. - This work was done by Fabian "ryg" Giesen. SSE2 is used by - default, but NEON must be enabled explicitly; see docs. - - With other JPEG optimizations included in this version, we see - 2x speedup on a JPEG on an x86 machine, and a 1.5x speedup - on a JPEG on an ARM machine, relative to previous versions of this - library. The same results will not obtain for all JPGs and for all - x86/ARM machines. (Note that progressive JPEGs are significantly - slower to decode than regular JPEGs.) This doesn't mean that this - is the fastest JPEG decoder in the land; rather, it brings it - closer to parity with standard libraries. If you want the fastest - decode, look elsewhere. (See "Philosophy" section of docs below.) - - See final bullet items below for more info on SIMD. - - - Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing - the memory allocator. Unlike other STBI libraries, these macros don't - support a context parameter, so if you need to pass a context in to - the allocator, you'll have to store it in a global or a thread-local - variable. - - - Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and - STBI_NO_LINEAR. - STBI_NO_HDR: suppress implementation of .hdr reader format - STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API - - - You can suppress implementation of any of the decoders to reduce - your code footprint by #defining one or more of the following - symbols before creating the implementation. - - STBI_NO_JPEG - STBI_NO_PNG - STBI_NO_BMP - STBI_NO_PSD - STBI_NO_TGA - STBI_NO_GIF - STBI_NO_HDR - STBI_NO_PIC - STBI_NO_PNM (.ppm and .pgm) - - - You can request *only* certain decoders and suppress all other ones - (this will be more forward-compatible, as addition of new decoders - doesn't require you to disable them explicitly): - - STBI_ONLY_JPEG - STBI_ONLY_PNG - STBI_ONLY_BMP - STBI_ONLY_PSD - STBI_ONLY_TGA - STBI_ONLY_GIF - STBI_ONLY_HDR - STBI_ONLY_PIC - STBI_ONLY_PNM (.ppm and .pgm) - - Note that you can define multiples of these, and you will get all - of them ("only x" and "only y" is interpreted to mean "only x&y"). - - - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still - want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB - - - Compilation of all SIMD code can be suppressed with - #define STBI_NO_SIMD - It should not be necessary to disable SIMD unless you have issues - compiling (e.g. using an x86 compiler which doesn't support SSE - intrinsics or that doesn't support the method used to detect - SSE2 support at run-time), and even those can be reported as - bugs so I can refine the built-in compile-time checking to be - smarter. - - - The old STBI_SIMD system which allowed installing a user-defined - IDCT etc. has been removed. If you need this, don't upgrade. My - assumption is that almost nobody was doing this, and those who - were will find the built-in SIMD more satisfactory anyway. - - - RGB values computed for JPEG images are slightly different from - previous versions of stb_image. (This is due to using less - integer precision in SIMD.) The C code has been adjusted so - that the same RGB values will be computed regardless of whether - SIMD support is available, so your app should always produce - consistent results. But these results are slightly different from - previous versions. (Specifically, about 3% of available YCbCr values - will compute different RGB results from pre-1.49 versions by +-1; - most of the deviating values are one smaller in the G channel.) - - - If you must produce consistent results with previous versions of - stb_image, #define STBI_JPEG_OLD and you will get the same results - you used to; however, you will not get the SIMD speedups for - the YCbCr-to-RGB conversion step (although you should still see - significant JPEG speedup from the other changes). - - Please note that STBI_JPEG_OLD is a temporary feature; it will be - removed in future versions of the library. It is only intended for - near-term back-compatibility use. - - - Latest revision history: +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 RGB-format JPEG; remove white matting in PSD; - allocate large structures on the stack; + allocate large structures on the stack; correct channel count for PNG & BMP 2.10 (2016-01-22) avoid warning introduced in 2.09 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED @@ -174,32 +78,26 @@ Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) github:urraka (animated gif) Junggon Kim (PNM comments) Daniel Gibson (16-bit TGA) - socks-the-fox (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) Optimizations & bugfixes Fabian "ryg" Giesen Arseny Kapoulkine Bug & warning fixes Marc LeBlanc David Woo Guillaume George Martins Mozeiko - Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson - Dave Moore Roy Eltham Hayaki Saito Phil Jordan - Won Chun Luke Graham Johan Duparc Nathan Reed - the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis - Janez Zemva John Bartholomew Michal Cichon github:svdijk - Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson - Laurent Gomila Cort Stratton Sergio Gonzalez github:romigrou - Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan - Ryamond Barbiero Paul Du Bois Engin Manap github:snagar - Michaelangel007@github Oriol Ferrer Mesia Dale Weiler github:Zelex - Philipp Wiesemann Josh Tobin github:rlyeh github:grim210@github - Blazej Dariusz Roszkowski github:sammyhw - - -LICENSE - -This software is dual-licensed to the public domain and under the following -license: you are granted a perpetual, irrevocable license to copy, modify, -publish, and distribute this file as you see fit. + Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan + Dave Moore Roy Eltham Hayaki Saito Nathan Reed + Won Chun Luke Graham Johan Duparc Nick Verigakis + the Horde3D community Thomas Ruf Ronny Chevalier Baldur Karlsson + Janez Zemva John Bartholomew Michal Cichon github:rlyeh + Jonathan Blow Ken Hamada Tero Hanninen github:romigrou + Laurent Gomila Cort Stratton Sergio Gonzalez github:svdijk + Aruelien Pocheville Thibault Reuille Cass Everitt github:snagar + Ryamond Barbiero Paul Du Bois Engin Manap github:Zelex + Michaelangel007@github Philipp Wiesemann Dale Weiler github:grim210 + Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:sammyhw + Blazej Dariusz Roszkowski Gregory Mullen github:phprus */ @@ -274,13 +172,13 @@ publish, and distribute this file as you see fit. // and for best performance I may provide less-easy-to-use APIs that give higher // performance, in addition to the easy to use ones. Nevertheless, it's important // to keep in mind that from the standpoint of you, a client of this library, -// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all. +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. // // Some secondary priorities arise directly from the first two, some of which // make more explicit reasons why performance can't be emphasized. // // - Portable ("ease of use") -// - Small footprint ("easy to maintain") +// - Small source code footprint ("easy to maintain") // - No dependencies ("ease of use") // // =========================================================================== @@ -312,13 +210,6 @@ publish, and distribute this file as you see fit. // (at least this is true for iOS and Android). Therefore, the NEON support is // toggled by a build flag: define STBI_NEON to get NEON loops. // -// The output of the JPEG decoder is slightly different from versions where -// SIMD support was introduced (that is, for versions before 1.49). The -// difference is only +-1 in the 8-bit RGB channels, and only on a small -// fraction of pixels. You can force the pre-1.49 behavior by defining -// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path -// and hence cost some performance. -// // If for some reason you do not want to use any of SIMD code, or if // you have issues compiling it, you can disable it entirely by // defining STBI_NO_SIMD. @@ -374,20 +265,47 @@ publish, and distribute this file as you see fit. // says there's premultiplied data (currently only happens in iPhone images, // and only if iPhone convert-to-rgb processing is on). // +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// #ifndef STBI_NO_STDIO #include <stdio.h> #endif // STBI_NO_STDIO -#define STBI_NO_HDR // RaySan: not required by raylib -//#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2 - -// NOTE: Added to work with raylib on Android -#if defined(PLATFORM_ANDROID) - #include "utils.h" // RaySan: Android fopen function map -#endif - #define STBI_VERSION 1 enum @@ -666,12 +584,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #define STBI__X86_TARGET #endif -#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) -// NOTE: not clear do we actually need this for the 64-bit path? +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) // gcc doesn't support sse2 intrinsics unless you compile with -msse2, -// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; -// this is just broken and gcc are jerks for not fixing it properly -// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. #define STBI_NO_SIMD #endif @@ -729,14 +649,10 @@ static int stbi__sse2_available() static int stbi__sse2_available() { -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later - // GCC 4.8+ has a nice way to do this - return __builtin_cpu_supports("sse2"); -#else - // portable way to do this, preferably without using GCC inline ASM? - // just bail for now. - return 0; -#endif + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; } #endif #endif @@ -1738,7 +1654,7 @@ typedef struct stbi__context *s; stbi__huffman huff_dc[4]; stbi__huffman huff_ac[4]; - stbi_uc dequant[4][64]; + stbi__uint16 dequant[4][64]; stbi__int16 fast_ac[4][1 << FAST_BITS]; // sizes for components, interleaved MCUs @@ -1774,6 +1690,8 @@ typedef struct int succ_high; int succ_low; int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag int rgb; int scan_n, order[4]; @@ -1844,7 +1762,7 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) // magnitude code followed by receive_extend code int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); int m = 1 << (magbits - 1); - if (k < m) k += (-1 << magbits) + 1; + if (k < m) k += (~0U << magbits) + 1; // if the result is small enough, we can fit it in fast_ac table if (k >= -128 && k <= 127) fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); @@ -1859,6 +1777,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j) int b = j->nomore ? 0 : stbi__get8(j->s); if (b == 0xff) { int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes if (c != 0) { j->marker = (unsigned char) c; j->nomore = 1; @@ -1983,7 +1902,7 @@ static stbi_uc stbi__jpeg_dezigzag[64+15] = }; // decode one 64-entry block-- -static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant) +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) { int diff,dc,k; int t; @@ -2692,7 +2611,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j) x = stbi__get8(j->s); if (x != 0xff) return STBI__MARKER_none; while (x == 0xff) - x = stbi__get8(j->s); + x = stbi__get8(j->s); // consume repeated 0xff fill bytes return x; } @@ -2707,7 +2626,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j) j->code_bits = 0; j->code_buffer = 0; j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; j->marker = STBI__MARKER_none; j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; j->eob_run = 0; @@ -2839,7 +2758,7 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z) } } -static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant) +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) { int i; for (i=0; i < 64; ++i) @@ -2881,13 +2800,14 @@ static int stbi__process_marker(stbi__jpeg *z, int m) L = stbi__get16be(z->s)-2; while (L > 0) { int q = stbi__get8(z->s); - int p = q >> 4; + int p = q >> 4, sixteen = (p != 0); int t = q & 15,i; - if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG"); + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s); - L -= 65; + z->dequant[t][stbi__jpeg_dezigzag[i]] = sixteen ? stbi__get16be(z->s) : stbi__get8(z->s); + L -= (sixteen ? 129 : 65); } return L==0; @@ -2920,12 +2840,50 @@ static int stbi__process_marker(stbi__jpeg *z, int m) } return L==0; } + // check for comment block or APP blocks if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - stbi__skip(z->s, stbi__get16be(z->s)-2); + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); return 1; } - return 0; + + return stbi__err("unknown marker","Corrupt JPEG"); } // after we see SOS @@ -2999,7 +2957,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires c = stbi__get8(s); - if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); s->img_n = c; for (i=0; i < c; ++i) { z->img_comp[i].data = NULL; @@ -3012,13 +2970,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) for (i=0; i < s->img_n; ++i) { static unsigned char rgb[3] = { 'R', 'G', 'B' }; z->img_comp[i].id = stbi__get8(s); - if (z->img_comp[i].id != i+1) // JFIF requires - if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files! - // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format) - if (z->img_comp[i].id != rgb[i]) - return stbi__err("bad component ID","Corrupt JPEG"); - ++z->rgb; - } + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; q = stbi__get8(s); z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); @@ -3090,6 +3043,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) { int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 z->marker = STBI__MARKER_none; // initialize cached marker to empty m = stbi__get_marker(z); if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); @@ -3131,12 +3086,15 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j) if (x == 255) { j->marker = stbi__get8(j->s); break; - } else if (x != 0) { - return stbi__err("junk before marker", "Corrupt JPEG"); } } // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 } + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) stbi__err("bad DNL height", "Corrupt JPEG"); } else { if (!stbi__process_marker(j, m)) return 0; } @@ -3355,38 +3313,9 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_ return out; } -#ifdef STBI_JPEG_OLD -// this is the same YCbCr-to-RGB calculation that stb_image has used -// historically before the algorithm changes in 1.49 -#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) -static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 16) + 32768; // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr*float2fixed(1.40200f); - g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); - b = y_fixed + cb*float2fixed(1.77200f); - r >>= 16; - g >>= 16; - b >>= 16; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#else // this is a reduced-precision calculation of YCbCr-to-RGB introduced // to make sure the code produces the same results in both SIMD and scalar -#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) { int i; @@ -3395,9 +3324,9 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc int r,g,b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; - r = y_fixed + cr* float2fixed(1.40200f); - g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* float2fixed(1.77200f); + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; @@ -3411,7 +3340,6 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc out += step; } } -#endif #if defined(STBI_SSE2) || defined(STBI_NEON) static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) @@ -3530,9 +3458,9 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons int r,g,b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; - r = y_fixed + cr* float2fixed(1.40200f); - g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* float2fixed(1.77200f); + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; @@ -3558,18 +3486,14 @@ static void stbi__setup_jpeg(stbi__jpeg *j) #ifdef STBI_SSE2 if (stbi__sse2_available()) { j->idct_block_kernel = stbi__idct_simd; - #ifndef STBI_JPEG_OLD j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - #endif j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; } #endif #ifdef STBI_NEON j->idct_block_kernel = stbi__idct_simd; - #ifndef STBI_JPEG_OLD j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - #endif j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; #endif } @@ -3590,9 +3514,16 @@ typedef struct int ypos; // which pre-expansion row we're on } stbi__resample; +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) { - int n, decode_n; + int n, decode_n, is_rgb; z->s->img_n = 0; // make stbi__cleanup_jpeg safe // validate req_comp @@ -3602,9 +3533,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n; + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; - if (z->s->img_n == 3 && n < 3) + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) decode_n = 1; else decode_n = z->s->img_n; @@ -3664,7 +3597,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp if (n >= 3) { stbi_uc *y = coutput[0]; if (z->s->img_n == 3) { - if (z->rgb == 3) { + if (is_rgb) { for (i=0; i < z->s->img_x; ++i) { out[0] = y[i]; out[1] = coutput[1][i]; @@ -3675,6 +3608,28 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp } else { z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc k = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], k); + out[1] = stbi__blinn_8x8(coutput[1][i], k); + out[2] = stbi__blinn_8x8(coutput[2][i], k); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc k = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], k); + out[1] = stbi__blinn_8x8(255 - out[1], k); + out[2] = stbi__blinn_8x8(255 - out[2], k); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } } else for (i=0; i < z->s->img_x; ++i) { out[0] = out[1] = out[2] = y[i]; @@ -3682,17 +3637,45 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp out += n; } } else { - stbi_uc *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc k = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], k); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], k); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], k); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } } } stbi__cleanup_jpeg(z); *out_x = z->s->img_x; *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n; // report original components, not output + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output return output; } } @@ -3701,6 +3684,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re { unsigned char* result; stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + STBI_NOTUSED(ri); j->s = s; stbi__setup_jpeg(j); result = load_jpeg_image(j, x,y,comp,req_comp); @@ -3711,11 +3695,12 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re static int stbi__jpeg_test(stbi__context *s) { int r; - stbi__jpeg j; - j.s = s; - stbi__setup_jpeg(&j); - r = stbi__decode_jpeg_header(&j, STBI__SCAN_type); + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); stbi__rewind(s); + STBI_FREE(j); return r; } @@ -3727,7 +3712,7 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) } if (x) *x = j->s->img_x; if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; return 1; } @@ -3784,7 +3769,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits) return stbi__bitreverse16(v) >> (16-bits); } -static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) { int i,k=0; int code, next_code[16], sizes[17]; @@ -4074,9 +4059,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a) return 1; } -// @TODO: should statically initialize these for optimal thread safety -static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; -static void stbi__init_zdefaults(void) +static const stbi_uc stbi__zdefault_length[288] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: { int i; // use <= to match clearly with spec for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; @@ -4086,6 +4086,7 @@ static void stbi__init_zdefaults(void) for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; } +*/ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) { @@ -4104,7 +4105,6 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) } else { if (type == 1) { // use fixed code lengths - if (!stbi__zdefault_distance[31]) stbi__init_zdefaults(); if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; } else { @@ -4305,7 +4305,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r for (j=0; j < y; ++j) { stbi_uc *cur = a->out + stride*j; - stbi_uc *prior = cur - stride; + stbi_uc *prior; int filter = *raw++; if (filter > 4) @@ -4317,6 +4317,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r filter_bytes = 1; width = img_width_bytes; } + prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above // if first row, use special filter that doesn't sample previous row if (j == 0) filter = first_row_filter[filter]; @@ -4709,7 +4710,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); @@ -4992,7 +4993,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) info->offset = stbi__get32le(s); info->hsz = hsz = stbi__get32le(s); info->mr = info->mg = info->mb = info->ma = 0; - + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); if (hsz == 12) { s->img_x = stbi__get16le(s); @@ -5077,7 +5078,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req stbi__bmp_data info; STBI_NOTUSED(ri); - info.all_a = 255; + info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == NULL) return NULL; // error code already set @@ -5196,7 +5197,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req stbi__skip(s, pad); } } - + // if alpha channel is all 0s, replace with all 255s if (target == 4 && all_a == 0) for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) @@ -5979,9 +5980,11 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) { stbi_uc *result; - int i, x,y; + int i, x,y, internal_comp; STBI_NOTUSED(ri); + if (!comp) comp = &internal_comp; + for (i=0; i<92; ++i) stbi__get8(s); @@ -6600,6 +6603,11 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) char buffer[STBI__HDR_BUFLEN]; char *token; int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; if (stbi__hdr_test(s) == 0) { stbi__rewind( s ); @@ -6641,14 +6649,14 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) void *p; stbi__bmp_data info; - info.all_a = 255; + info.all_a = 255; p = stbi__bmp_parse_header(s, &info); stbi__rewind( s ); if (p == NULL) return 0; - *x = s->img_x; - *y = s->img_y; - *comp = info.ma ? 4 : 3; + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) *comp = info.ma ? 4 : 3; return 1; } #endif @@ -6656,7 +6664,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_PSD static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) { - int channelCount; + int channelCount, dummy; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; if (stbi__get32be(s) != 0x38425053) { stbi__rewind( s ); return 0; @@ -6689,9 +6700,13 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_PIC static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) { - int act_comp=0,num_packets=0,chained; + int act_comp=0,num_packets=0,chained,dummy; stbi__pic_packet packets[10]; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { stbi__rewind(s); return 0; @@ -6777,7 +6792,7 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req *x = s->img_x; *y = s->img_y; - *comp = s->img_n; + if (comp) *comp = s->img_n; if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) return stbi__errpuc("too large", "PNM too large"); @@ -6831,16 +6846,20 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c) static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) { - int maxv; + int maxv, dummy; char c, p, t; - stbi__rewind( s ); + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); // Get identifier p = (char) stbi__get8(s); t = (char) stbi__get8(s); if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); + stbi__rewind(s); return 0; } @@ -6947,6 +6966,11 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int /* revision history: + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) allocate large structures on the stack @@ -7108,3 +7132,46 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int 0.50 (2006-11-19) first released version */ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/external/stb_image_resize.h b/src/external/stb_image_resize.h index 5214ad6e..b507e049 100644 --- a/src/external/stb_image_resize.h +++ b/src/external/stb_image_resize.h @@ -1,4 +1,4 @@ -/* stb_image_resize - v0.92 - public domain image resizing +/* stb_image_resize - v0.94 - public domain image resizing by Jorge L Rodriguez (@VinoBS) - 2014 http://github.com/nothings/stb @@ -107,8 +107,8 @@ industry, it is still uncommon in the videogame/real-time world. If you linearly filter non-premultiplied alpha, strange effects - occur. (For example, the average of 1% opaque bright green - and 99% opaque black produces 50% transparent dark green when + occur. (For example, the 50/50 average of 99% transparent bright green + and 1% transparent black produces 50% transparent dark green when non-premultiplied, whereas premultiplied it produces 50% transparent near-black. The former introduces green energy that doesn't exist in the source image.) @@ -152,20 +152,20 @@ (For example, graphics hardware does not apply sRGB conversion to the alpha channel.) - ADDITIONAL CONTRIBUTORS + CONTRIBUTORS + Jorge L Rodriguez: Implementation Sean Barrett: API design, optimizations Aras Pranckevicius: bugfix REVISIONS + 0.94 (2017-03-18) fixed warnings + 0.93 (2017-03-03) fixed bug with certain combinations of heights 0.92 (2017-01-02) fix integer overflow on large (>2GB) images 0.91 (2016-04-02) fix warnings; fix handling of subpixel regions 0.90 (2014-09-17) first released version LICENSE - - This software is dual-licensed to the public domain and under the following - license: you are granted a perpetual, irrevocable license to copy, modify, - publish, and distribute this file as you see fit. + See end of file for license information. TODO Don't decode all of the image data when only processing a partial tile @@ -533,10 +533,11 @@ typedef struct int horizontal_num_contributors; int vertical_num_contributors; - int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter) + int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter) + int ring_buffer_num_entries; // Total number of entries in the ring buffer. int ring_buffer_first_scanline; int ring_buffer_last_scanline; - int ring_buffer_begin_index; + int ring_buffer_begin_index; // first_scanline is at this index in the ring buffer float* ring_buffer; float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds. @@ -551,16 +552,17 @@ typedef struct int encode_buffer_size; } stbir__info; + +static const float stbir__max_uint8_as_float = 255.0f; +static const float stbir__max_uint16_as_float = 65535.0f; +static const double stbir__max_uint32_as_float = 4294967295.0; + + static stbir__inline int stbir__min(int a, int b) { return a < b ? a : b; } -static stbir__inline int stbir__max(int a, int b) -{ - return a > b ? a : b; -} - static stbir__inline float stbir__saturate(float x) { if (x < 0) @@ -1027,7 +1029,7 @@ static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radi *out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5)); } -static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group) +static void stbir__calculate_coefficients_upsample(stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group) { int i; float total_filter = 0; @@ -1077,7 +1079,7 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi } } -static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group) +static void stbir__calculate_coefficients_downsample(stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group) { int i; @@ -1107,7 +1109,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st } } -static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) +static void stbir__normalize_downsample_coefficients(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, int input_size, int output_size) { int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio); @@ -1184,7 +1186,7 @@ static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, st // Each scan line uses the same kernel values so we should calculate the kernel // values once and then we can use them for every scan line. -static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) +static void stbir__calculate_filters(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) { int n; int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); @@ -1201,7 +1203,7 @@ static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributor stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out); - stbir__calculate_coefficients_upsample(stbir_info, filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); + stbir__calculate_coefficients_upsample(filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); } } else @@ -1217,10 +1219,10 @@ static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributor stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in); - stbir__calculate_coefficients_downsample(stbir_info, filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); + stbir__calculate_coefficients_downsample(filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); } - stbir__normalize_downsample_coefficients(stbir_info, contributors, coefficients, filter, scale_ratio, shift, input_size, output_size); + stbir__normalize_downsample_coefficients(contributors, coefficients, filter, scale_ratio, input_size, output_size); } } @@ -1270,7 +1272,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) - decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / 255; + decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / stbir__max_uint8_as_float; } break; @@ -1283,7 +1285,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]]; if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) - decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / 255; + decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint8_as_float; } break; @@ -1293,7 +1295,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) - decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535; + decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float; } break; @@ -1303,10 +1305,10 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) - decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535); + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float); if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) - decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / 65535; + decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint16_as_float; } break; @@ -1316,7 +1318,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) - decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295); + decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float); } break; @@ -1326,10 +1328,10 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) - decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295)); + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float)); if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) - decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / 4294967295); + decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint32_as_float); } break; @@ -1411,6 +1413,8 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n) int ring_buffer_index; float* ring_buffer; + stbir_info->ring_buffer_last_scanline = n; + if (stbir_info->ring_buffer_begin_index < 0) { ring_buffer_index = stbir_info->ring_buffer_begin_index = 0; @@ -1418,24 +1422,21 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n) } else { - ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline) + 1) % stbir_info->vertical_filter_pixel_width; + ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline)) % stbir_info->ring_buffer_num_entries; STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index); } ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float)); memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes); - stbir_info->ring_buffer_last_scanline = n; - return ring_buffer; } -static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n, float* output_buffer) +static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, float* output_buffer) { int x, k; int output_w = stbir_info->output_w; - int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width; int channels = stbir_info->channels; float* decode_buffer = stbir__get_decode_buffer(stbir_info); stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; @@ -1515,12 +1516,10 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n, } } -static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n, float* output_buffer) +static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, float* output_buffer) { int x, k; int input_w = stbir_info->input_w; - int output_w = stbir_info->output_w; - int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width; int channels = stbir_info->channels; float* decode_buffer = stbir__get_decode_buffer(stbir_info); stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; @@ -1654,9 +1653,9 @@ static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n) // Now resample it into the ring buffer. if (stbir__use_width_upsampling(stbir_info)) - stbir__resample_horizontal_upsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n)); + stbir__resample_horizontal_upsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n)); else - stbir__resample_horizontal_downsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n)); + stbir__resample_horizontal_downsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n)); // Now it's sitting in the ring buffer ready to be used as source for the vertical sampling. } @@ -1670,17 +1669,17 @@ static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n // Now resample it into the horizontal buffer. if (stbir__use_width_upsampling(stbir_info)) - stbir__resample_horizontal_upsample(stbir_info, n, stbir_info->horizontal_buffer); + stbir__resample_horizontal_upsample(stbir_info, stbir_info->horizontal_buffer); else - stbir__resample_horizontal_downsample(stbir_info, n, stbir_info->horizontal_buffer); + stbir__resample_horizontal_downsample(stbir_info, stbir_info->horizontal_buffer); // Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers. } // Get the specified scan line from the ring buffer. -static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_size, int ring_buffer_length) +static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_num_entries, int ring_buffer_length) { - int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_size; + int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_num_entries; return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length); } @@ -1715,19 +1714,23 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void // build a table of all channels that need colorspace correction, so // we don't perform colorspace correction on channels that don't need it. - for (x=0, num_nonalpha=0; x < channels; ++x) + for (x = 0, num_nonalpha = 0; x < channels; ++x) + { if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) - nonalpha[num_nonalpha++] = x; + { + nonalpha[num_nonalpha++] = (stbir_uint16)x; + } + } #define STBIR__ROUND_INT(f) ((int) ((f)+0.5)) #define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5)) #ifdef STBIR__SATURATE_INT - #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * 255 )) - #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * 65535)) + #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * stbir__max_uint8_as_float )) + #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * stbir__max_uint16_as_float)) #else - #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * 255 ) - #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * 65535) + #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint8_as_float ) + #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint16_as_float) #endif switch (decode) @@ -1782,7 +1785,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void for (n = 0; n < num_nonalpha; n++) { int index = pixel_index + nonalpha[n]; - ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * 65535); + ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * stbir__max_uint16_as_float); } if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) @@ -1799,7 +1802,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void for (n = 0; n < channels; n++) { int index = pixel_index + n; - ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * 4294967295); + ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * stbir__max_uint32_as_float); } } break; @@ -1812,11 +1815,11 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void for (n = 0; n < num_nonalpha; n++) { int index = pixel_index + nonalpha[n]; - ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * 4294967295); + ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * stbir__max_uint32_as_float); } if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) - ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * 4294967295); + ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * stbir__max_uint32_as_float); } break; @@ -1855,7 +1858,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void } } -static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out) +static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n) { int x, k; int output_w = stbir_info->output_w; @@ -1865,7 +1868,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in int alpha_channel = stbir_info->alpha_channel; int type = stbir_info->type; int colorspace = stbir_info->colorspace; - int kernel_pixel_width = stbir_info->vertical_filter_pixel_width; + int ring_buffer_entries = stbir_info->ring_buffer_num_entries; void* output_data = stbir_info->output_data; float* encode_buffer = stbir_info->encode_buffer; int decode = STBIR__DECODE(type, colorspace); @@ -1876,7 +1879,6 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in float* ring_buffer = stbir_info->ring_buffer; int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; - int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline; int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); int n0,n1, output_row_start; @@ -1900,7 +1902,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; - float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { @@ -1913,7 +1915,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; - float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { @@ -1927,7 +1929,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; - float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { @@ -1942,7 +1944,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; - float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { @@ -1958,7 +1960,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; - float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { @@ -1973,16 +1975,14 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode); } -static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out) +static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n) { int x, k; int output_w = stbir_info->output_w; - int output_h = stbir_info->output_h; stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; float* vertical_coefficients = stbir_info->vertical_coefficients; int channels = stbir_info->channels; - int kernel_pixel_width = stbir_info->vertical_filter_pixel_width; - void* output_data = stbir_info->output_data; + int ring_buffer_entries = stbir_info->ring_buffer_num_entries; float* horizontal_buffer = stbir_info->horizontal_buffer; int coefficient_width = stbir_info->vertical_coefficient_width; int contributor = n + stbir_info->vertical_filter_pixel_margin; @@ -1990,7 +1990,6 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, float* ring_buffer = stbir_info->ring_buffer; int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; - int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline; int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); int n0,n1; @@ -2005,7 +2004,7 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, int coefficient_group = coefficient_width * contributor; float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; - float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); switch (channels) { case 1: @@ -2071,7 +2070,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info) stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out); - STBIR_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width); + STBIR_ASSERT(in_last_scanline - in_first_scanline + 1 <= stbir_info->ring_buffer_num_entries); if (stbir_info->ring_buffer_begin_index >= 0) { @@ -2090,7 +2089,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info) else { stbir_info->ring_buffer_first_scanline++; - stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width; + stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries; } } } @@ -2103,7 +2102,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info) stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1); // Now all buffers should be ready to write a row of vertical sampling. - stbir__resample_vertical_upsample(stbir_info, y, in_first_scanline, in_last_scanline, in_center_of_out); + stbir__resample_vertical_upsample(stbir_info, y); STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h); } @@ -2148,7 +2147,7 @@ static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessar else { stbir_info->ring_buffer_first_scanline++; - stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width; + stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries; } } } @@ -2172,7 +2171,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info) stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in); - STBIR_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width); + STBIR_ASSERT(out_last_scanline - out_first_scanline + 1 <= stbir_info->ring_buffer_num_entries); if (out_last_scanline < 0 || out_first_scanline >= output_h) continue; @@ -2189,7 +2188,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info) stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1); // Now the horizontal buffer is ready to write to all ring buffer rows. - stbir__resample_vertical_downsample(stbir_info, y, out_first_scanline, out_last_scanline, out_center_of_in); + stbir__resample_vertical_downsample(stbir_info, y); } stbir__empty_ring_buffer(stbir_info, stbir_info->output_h); @@ -2246,13 +2245,16 @@ static stbir_uint32 stbir__calculate_memory(stbir__info *info) info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w); info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h); + // One extra entry because floating point precision problems sometimes cause an extra to be necessary. + info->ring_buffer_num_entries = filter_height + 1; + info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors); info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float); info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors); info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float); info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float); info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float); - info->ring_buffer_size = info->output_w * info->channels * filter_height * sizeof(float); + info->ring_buffer_size = info->output_w * info->channels * info->ring_buffer_num_entries * sizeof(float); info->encode_buffer_size = info->output_w * info->channels * sizeof(float); STBIR_ASSERT(info->horizontal_filter != 0); @@ -2390,8 +2392,8 @@ static int stbir__resize_allocated(stbir__info *info, // This signals that the ring buffer is empty info->ring_buffer_begin_index = -1; - stbir__calculate_filters(info, info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w); - stbir__calculate_filters(info, info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h); + stbir__calculate_filters(info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w); + stbir__calculate_filters(info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h); STBIR_PROGRESS_REPORT(0); @@ -2578,3 +2580,45 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int } #endif // STB_IMAGE_RESIZE_IMPLEMENTATION + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/external/stb_image_write.h b/src/external/stb_image_write.h index ae9180b0..df623393 100644 --- a/src/external/stb_image_write.h +++ b/src/external/stb_image_write.h @@ -1,4 +1,4 @@ -/* stb_image_write - v1.03 - public domain - http://nothings.org/stb/stb_image_write.h +/* stb_image_write - v1.05 - public domain - http://nothings.org/stb/stb_image_write.h writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015 no warranty implied; use at your own risk @@ -104,12 +104,11 @@ CREDITS: Filip Wasil Thatcher Ulrich github:poppolopoppo + Patrick Boettcher LICENSE -This software is dual-licensed to the public domain and under the following -license: you are granted a perpetual, irrevocable license to copy, modify, -publish, and distribute this file as you see fit. + See end of file for license information. */ @@ -294,10 +293,8 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in s->func(s->context, &d[comp - 1], 1); switch (comp) { + case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case case 1: - s->func(s->context,d,1); - break; - case 2: if (expand_mono) stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp else @@ -897,6 +894,7 @@ static unsigned char stbiw__paeth(int a, int b, int c) return STBIW_UCHAR(c); } +// @OPTIMIZE: provide an option that always forces left-predict or paeth predict unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) { int ctype[5] = { -1, 0, 4, 2, 6 }; @@ -913,10 +911,10 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in for (j=0; j < y; ++j) { static int mapping[] = { 0,1,2,3,4 }; static int firstmap[] = { 0,1,0,5,6 }; - int *mymap = j ? mapping : firstmap; + int *mymap = (j != 0) ? mapping : firstmap; int best = 0, bestval = 0x7fffffff; for (p=0; p < 2; ++p) { - for (k= p?best:0; k < 5; ++k) { + for (k= p?best:0; k < 5; ++k) { // @TODO: clarity: rewrite this to go 0..5, and 'continue' the unwanted ones during 2nd pass int type = mymap[k],est=0; unsigned char *z = pixels + stride_bytes*j; for (i=0; i < n; ++i) @@ -1018,6 +1016,9 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, #endif // STB_IMAGE_WRITE_IMPLEMENTATION /* Revision history + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? 1.02 (2016-04-02) avoid allocating large structures on the stack 1.01 (2016-01-16) @@ -1047,3 +1048,45 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, first public release 0.90 first internal release */ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/external/stb_rect_pack.h b/src/external/stb_rect_pack.h index c75527da..f5eb8d33 100644 --- a/src/external/stb_rect_pack.h +++ b/src/external/stb_rect_pack.h @@ -1,4 +1,4 @@ -// stb_rect_pack.h - v0.10 - public domain - rectangle packing +// stb_rect_pack.h - v0.11 - public domain - rectangle packing // Sean Barrett 2014 // // Useful for e.g. packing rectangular textures into an atlas. @@ -27,11 +27,14 @@ // Sean Barrett // Minor features // Martins Mozeiko +// github:IntellectualKitty +// // Bugfixes / warning fixes // Jeremy Jaussaud // // Version history: // +// 0.11 (2017-03-03) return packing success/fail result // 0.10 (2016-10-25) remove cast-away-const to avoid warnings // 0.09 (2016-08-27) fix compiler warnings // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) @@ -43,9 +46,7 @@ // // LICENSE // -// This software is dual-licensed to the public domain and under the following -// license: you are granted a perpetual, irrevocable license to copy, modify, -// publish, and distribute this file as you see fit. +// See end of file for license information. ////////////////////////////////////////////////////////////////////////////// // @@ -77,7 +78,7 @@ typedef int stbrp_coord; typedef unsigned short stbrp_coord; #endif -STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); +STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); // Assign packed locations to rectangles. The rectangles are of type // 'stbrp_rect' defined below, stored in the array 'rects', and there // are 'num_rects' many of them. @@ -98,6 +99,9 @@ STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int // arrays will probably produce worse packing results than calling it // a single time with the full rectangle array, but the option is // available. +// +// The function returns 1 if all of the rectangles were successfully +// packed and 0 otherwise. struct stbrp_rect { @@ -544,9 +548,9 @@ static int rect_original_order(const void *a, const void *b) #define STBRP__MAXVAL 0xffff #endif -STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) +STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) { - int i; + int i, all_rects_packed = 1; // we use the 'was_packed' field internally to allow sorting/unsorting for (i=0; i < num_rects; ++i) { @@ -576,8 +580,56 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n // unsort STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); - // set was_packed flags - for (i=0; i < num_rects; ++i) + // set was_packed flags and all_rects_packed status + for (i=0; i < num_rects; ++i) { rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); + if (!rects[i].was_packed) + all_rects_packed = 0; + } + + // return the all_rects_packed status + return all_rects_packed; } #endif + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/external/stb_truetype.h b/src/external/stb_truetype.h index 92b9a875..fc5b9782 100644 --- a/src/external/stb_truetype.h +++ b/src/external/stb_truetype.h @@ -1,4 +1,4 @@ -// stb_truetype.h - v1.14 - public domain +// stb_truetype.h - v1.15 - public domain // authored from 2009-2016 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: @@ -50,10 +50,13 @@ // Higor Euripedes // Thomas Fields // Derek Vinyard +// Cort Stratton // // VERSION HISTORY // -// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts, num-fonts-in-TTC function +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts // 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.11 (2016-04-02) fix unused-variable warning // 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef @@ -69,9 +72,7 @@ // // LICENSE // -// This software is dual-licensed to the public domain and under the following -// license: you are granted a perpetual, irrevocable license to copy, modify, -// publish, and distribute this file as you see fit. +// See end of file for license information. // // USAGE // @@ -494,7 +495,7 @@ typedef struct float x1,y1,s1,t1; // bottom-right } stbtt_aligned_quad; -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above int char_index, // character to display float *xpos, float *ypos, // pointers to current position in screen pixel space stbtt_aligned_quad *q, // output: quad to draw @@ -594,7 +595,7 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h // To use with PackFontRangesGather etc., you must set it before calls // call to PackFontRangesGatherRects. -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above int char_index, // character to display float *xpos, float *ypos, // pointers to current position in screen pixel space stbtt_aligned_quad *q, // output: quad to draw @@ -3287,11 +3288,11 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo return bottom_y; } -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) { float d3d_bias = opengl_fillrule ? 0 : -0.5f; float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_bakedchar *b = chardata + char_index; + const stbtt_bakedchar *b = chardata + char_index; int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); @@ -3735,10 +3736,10 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); } -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) { float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_packedchar *b = chardata + char_index; + const stbtt_packedchar *b = chardata + char_index; if (align_to_integer) { float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); @@ -4016,3 +4017,45 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const // 0.2 (2009-03-11) Fix unsigned/signed char warnings // 0.1 (2009-03-09) First public release // + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/external/stb_vorbis.c b/src/external/stb_vorbis.c index 07d79318..21638bcd 100644 --- a/src/external/stb_vorbis.c +++ b/src/external/stb_vorbis.c @@ -162,21 +162,23 @@ #endif #ifndef STB_VORBIS_NO_CRT -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <math.h> -#if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)) -#include <malloc.h> -#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__) -#include <alloca.h> -#endif -#endif + #include <stdlib.h> + #include <string.h> + #include <assert.h> + #include <math.h> + + // find definition of alloca if it's not in stdlib.h: + #if defined(_MSC_VER) || defined(__MINGW32__) + #include <malloc.h> + #endif + #if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__) + #include <alloca.h> + #endif #else // STB_VORBIS_NO_CRT -#define NULL 0 -#define malloc(s) 0 -#define free(s) ((void) 0) -#define realloc(s) 0 + #define NULL 0 + #define malloc(s) 0 + #define free(s) ((void) 0) + #define realloc(s) 0 #endif // STB_VORBIS_NO_CRT #include <limits.h> @@ -597,17 +599,18 @@ static int ilog(int32 n) { static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; + if (n < 0) return 0; // signed n returns 0 + // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29) if (n < (1 << 14)) - if (n < (1 << 4)) return 0 + log2_4[n ]; - else if (n < (1 << 9)) return 5 + log2_4[n >> 5]; + if (n < (1 << 4)) return 0 + log2_4[n ]; + else if (n < (1 << 9)) return 5 + log2_4[n >> 5]; else return 10 + log2_4[n >> 10]; else if (n < (1 << 24)) - if (n < (1 << 19)) return 15 + log2_4[n >> 15]; + if (n < (1 << 19)) return 15 + log2_4[n >> 15]; else return 20 + log2_4[n >> 20]; - else if (n < (1 << 29)) return 25 + log2_4[n >> 25]; - else if (n < (1 << 31)) return 30 + log2_4[n >> 30]; - else return 0; // signed n returns 0 + else if (n < (1 << 29)) return 25 + log2_4[n >> 25]; + else return 30 + log2_4[n >> 30]; } #ifndef M_PI @@ -880,13 +883,13 @@ static void neighbors(uint16 *x, int n, int *plow, int *phigh) // this has been repurposed so y is now the original index instead of y typedef struct { - uint16 x,y; -} Point; + uint16 x,id; +} stbv__floor_ordering; static int STBV_CDECL point_compare(const void *p, const void *q) { - Point *a = (Point *) p; - Point *b = (Point *) q; + stbv__floor_ordering *a = (stbv__floor_ordering *) p; + stbv__floor_ordering *b = (stbv__floor_ordering *) q; return a->x < b->x ? -1 : a->x > b->x; } @@ -3095,11 +3098,13 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) return right - left; } -static void vorbis_pump_first_frame(stb_vorbis *f) +static int vorbis_pump_first_frame(stb_vorbis *f) { - int len, right, left; - if (vorbis_decode_packet(f, &len, &left, &right)) + int len, right, left, res; + res = vorbis_decode_packet(f, &len, &left, &right); + if (res) vorbis_finish_frame(f, len, left, right); + return res; } #ifndef STB_VORBIS_NO_PUSHDATA_API @@ -3482,7 +3487,7 @@ static int start_decoder(vorb *f) g->book_list[j] = get_bits(f,8); return error(f, VORBIS_feature_not_supported); } else { - Point p[31*8+2]; + stbv__floor_ordering p[31*8+2]; Floor1 *g = &f->floor_config[i].floor1; int max_class = -1; g->partitions = get_bits(f, 5); @@ -3518,11 +3523,11 @@ static int start_decoder(vorb *f) // precompute the sorting for (j=0; j < g->values; ++j) { p[j].x = g->Xlist[j]; - p[j].y = j; + p[j].id = j; } qsort(p, g->values, sizeof(p[0]), point_compare); for (j=0; j < g->values; ++j) - g->sorted_order[j] = (uint8) p[j].y; + g->sorted_order[j] = (uint8) p[j].id; // precompute the neighbors for (j=2; j < g->values; ++j) { int low,hi; @@ -4226,8 +4231,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) // starting from the start is handled differently if (sample_number <= left.last_decoded_sample) { - stb_vorbis_seek_start(f); - return 1; + if (stb_vorbis_seek_start(f)) + return 1; + return 0; } while (left.page_end != right.page_start) { @@ -4328,7 +4334,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) skip(f, f->segments[i]); // start decoding (optimizable - this frame is generally discarded) - vorbis_pump_first_frame(f); + if (!vorbis_pump_first_frame(f)) + return 0; + if (f->current_loc > sample_number) + return error(f, VORBIS_seek_failed); return 1; error: @@ -4419,14 +4428,14 @@ int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) return 1; } -void stb_vorbis_seek_start(stb_vorbis *f) +int stb_vorbis_seek_start(stb_vorbis *f) { - if (IS_PUSH_MODE(f)) { error(f, VORBIS_invalid_api_mixing); return; } + if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); } set_file_offset(f, f->first_audio_page_offset); f->previous_length = 0; f->first_decode = TRUE; f->next_seg = -1; - vorbis_pump_first_frame(f); + return vorbis_pump_first_frame(f); } unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) @@ -4591,6 +4600,7 @@ stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *err if (f) { *f = p; vorbis_pump_first_frame(f); + if (error) *error = VORBIS__no_error; return f; } } @@ -4956,6 +4966,7 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in #endif // STB_VORBIS_NO_PULLDATA_API /* Version history + 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory 1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version 1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks; avoid discarding last frame of audio data @@ -5008,3 +5019,46 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in */ #endif // STB_VORBIS_HEADER_ONLY + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/external/stb_vorbis.h b/src/external/stb_vorbis.h index 624ce4bc..9394e813 100644 --- a/src/external/stb_vorbis.h +++ b/src/external/stb_vorbis.h @@ -1,4 +1,4 @@ -// Ogg Vorbis audio decoder - v1.09 - public domain +// Ogg Vorbis audio decoder - v1.10 - public domain // http://nothings.org/stb_vorbis/ // // Original version written by Sean Barrett in 2007. @@ -9,12 +9,7 @@ // // LICENSE // -// This software is dual-licensed to the public domain and under the following -// license: you are granted a perpetual, irrevocable license to copy, modify, -// publish, and distribute this file as you see fit. -// -// No warranty for any purpose is expressed or implied by the author (nor -// by RAD Game Tools). Report bugs and send enhancements to the author. +// See end of file for license information. // // Limitations: // @@ -37,6 +32,7 @@ // manxorist@github saga musix // // Partial history: +// 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory // 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version // 1.08 - 2016/04/02 - warnings; setup memory leaks; truncation of last frame // 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const @@ -280,7 +276,7 @@ extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); // do not need to seek to EXACTLY the target sample when using get_samples_*, // you can also use seek_frame(). -extern void stb_vorbis_seek_start(stb_vorbis *f); +extern int stb_vorbis_seek_start(stb_vorbis *f); // this function is equivalent to stb_vorbis_seek(f,0) extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f); |
