diff --git a/glm/core/func_exponential.inl b/glm/core/func_exponential.inl new file mode 100644 index 00000000..e8ff4cfe --- /dev/null +++ b/glm/core/func_exponential.inl @@ -0,0 +1,224 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net) +/// 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. +/// +/// @ref core +/// @file glm/core/func_exponential.inl +/// @date 2008-08-03 / 2011-06-15 +/// @author Christophe Riccio +/////////////////////////////////////////////////////////////////////////////////// + +#include "func_vector_relational.hpp" +#include "_vectorize.hpp" +#include +#include + +namespace glm +{ + // pow + template + GLM_FUNC_QUALIFIER genType pow + ( + genType const & x, + genType const & y + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'pow' only accept floating-point inputs"); + + return std::pow(x, y); + } + + VECTORIZE_VEC_VEC(pow) + + // exp + template + GLM_FUNC_QUALIFIER genType exp + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'exp' only accept floating-point inputs"); + + return std::exp(x); + } + + VECTORIZE_VEC(exp) + + // log + template + GLM_FUNC_QUALIFIER genType log + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'log' only accept floating-point inputs"); + + return std::log(x); + } + + VECTORIZE_VEC(log) + + //exp2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType exp2 + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'exp2' only accept floating-point inputs"); + + return std::exp(static_cast(0.69314718055994530941723212145818) * x); + } + + VECTORIZE_VEC(exp2) + +namespace detail +{ + template + struct compute_log2 + { + template + T operator() (T const & Value) const; + }; + + template <> + struct compute_log2 + { + template + T operator() (T const & Value) const + { + return static_cast(::std::log(Value)) * static_cast(1.4426950408889634073599246810019); + } + }; + +}//namespace detail + + // log2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType log2 + ( + genType const & x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, + "GLM core 'log2' only accept floating-point inputs. Include for additional integer support."); + + assert(x > genType(0)); // log2 is only defined on the range (0, inf] + return detail::compute_log2::is_iec559>()(x); + } + + VECTORIZE_VEC(log2) + + // sqrt + template + GLM_FUNC_QUALIFIER genType sqrt + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'sqrt' only accept floating-point inputs"); + + assert(x >= genType(0)); + + return std::sqrt(x); + } + + VECTORIZE_VEC(sqrt) + + template + GLM_FUNC_QUALIFIER genType inversesqrt + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'inversesqrt' only accept floating-point inputs"); + + assert(x > genType(0)); + + return genType(1) / std::sqrt(x); + } + + VECTORIZE_VEC(inversesqrt) + + namespace detail + { + template + genType fastInversesqrt(genType const & v) + { + genType tmp(v); + genType xhalf(tmp * genType(0.5f)); + genUType i = *reinterpret_cast(const_cast(&v)); + i = genUType(0x5f375a86) - (i >> genUType(1)); + // tmp = *reinterpret_cast(&i); + { + genType* ptr(reinterpret_cast(&i)); + tmp = *ptr; + } + tmp = tmp * (genType(1.5f) - xhalf * tmp * tmp); + return tmp; + } + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec1 inversesqrt(lowp_vec1 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec1(0)))); + + return detail::fastInversesqrt(v); + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec2 inversesqrt(lowp_vec2 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec2(0)))); + + return detail::fastInversesqrt(v); + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec3 inversesqrt(lowp_vec3 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec3(0)))); + + return detail::fastInversesqrt(v); + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec4 inversesqrt(lowp_vec4 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec4(0)))); + + return detail::fastInversesqrt(v); + } + +}//namespace glm diff --git a/glm/detail/func_common.inl b/glm/detail/func_common.inl index a788eb4c..4026e0c8 100644 --- a/glm/detail/func_common.inl +++ b/glm/detail/func_common.inl @@ -716,7 +716,7 @@ namespace detail # if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_INTEL)) return _isnan(x) != 0; # elif(GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG)) -# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID) +# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L) return _isnan(x) != 0; # else return std::isnan(x); @@ -787,7 +787,7 @@ namespace detail # if(GLM_COMPILER & (GLM_COMPILER_INTEL | GLM_COMPILER_VC)) return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF; # elif(GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG)) -# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID) +# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L) return _isinf(x) != 0; # else return std::isinf(x); diff --git a/glm/detail/func_geometric.inl b/glm/detail/func_geometric.inl index 2f8691dd..1e8cd633 100644 --- a/glm/detail/func_geometric.inl +++ b/glm/detail/func_geometric.inl @@ -92,8 +92,7 @@ namespace detail { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length' only accept floating-point inputs"); - genType sqr = x * x; - return sqrt(sqr); + return abs(x); } template diff --git a/glm/detail/func_packing.inl b/glm/detail/func_packing.inl index e5eb0933..60dfc63b 100644 --- a/glm/detail/func_packing.inl +++ b/glm/detail/func_packing.inl @@ -35,7 +35,9 @@ namespace glm GLM_FUNC_QUALIFIER uint packUnorm2x16(vec2 const & v) { u16vec2 Topack(round(clamp(v, 0.0f, 1.0f) * 65535.0f)); - return reinterpret_cast(Topack); + // return reinterpret_cast(Topack); + uint* ptr(reinterpret_cast(&Topack)); + return *ptr; } GLM_FUNC_QUALIFIER vec2 unpackUnorm2x16(uint const & p) @@ -47,7 +49,9 @@ namespace glm GLM_FUNC_QUALIFIER uint packSnorm2x16(vec2 const & v) { i16vec2 Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); - return reinterpret_cast(Topack); + // return reinterpret_cast(Topack); + uint* ptr(reinterpret_cast(&Topack)); + return *ptr; } GLM_FUNC_QUALIFIER vec2 unpackSnorm2x16(uint const & p) diff --git a/glm/detail/setup.hpp b/glm/detail/setup.hpp index 34188c66..62b3e2cb 100644 --- a/glm/detail/setup.hpp +++ b/glm/detail/setup.hpp @@ -578,16 +578,19 @@ #define GLM_ARCH_PURE 0x0000 #define GLM_ARCH_SSE2 0x0001 -#define GLM_ARCH_SSE3 0x0002// | GLM_ARCH_SSE2 -#define GLM_ARCH_AVX 0x0008// | GLM_ARCH_SSE3 | GLM_ARCH_SSE2 -#define GLM_ARCH_AVX2 0x0010// | GLM_ARCH_AVX | GLM_ARCH_SSE3 | GLM_ARCH_SSE2 +#define GLM_ARCH_SSE3 0x0002 +#define GLM_ARCH_SSE4 0x0004 +#define GLM_ARCH_AVX 0x0008 +#define GLM_ARCH_AVX2 0x0010 #if(defined(GLM_FORCE_PURE)) # define GLM_ARCH GLM_ARCH_PURE #elif(defined(GLM_FORCE_AVX2)) -# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) #elif(defined(GLM_FORCE_AVX)) -# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +#elif(defined(GLM_FORCE_SSE4)) +# define GLM_ARCH (GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) #elif(defined(GLM_FORCE_SSE3)) # define GLM_ARCH (GLM_ARCH_SSE3 | GLM_ARCH_SSE2) #elif(defined(GLM_FORCE_SSE2)) @@ -606,14 +609,26 @@ # endif #elif(GLM_COMPILER & GLM_COMPILER_VC) # if _M_IX86_FP == 2 && defined(__AVX__) -# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) # elif _M_IX86_FP == 2 # define GLM_ARCH (GLM_ARCH_SSE2) # else # define GLM_ARCH (GLM_ARCH_PURE) # endif -#elif((GLM_PLATFORM & GLM_PLATFORM_APPLE) && (GLM_COMPILER & GLM_COMPILER_GCC)) -# define GLM_ARCH GLM_ARCH_PURE +#elif(((GLM_COMPILER & GLM_COMPILER_GCC) && (defined(__i386__) || defined(__x86_64__))) || (GLM_COMPILER & GLM_COMPILER_LLVM_GCC) || (GLM_COMPILER & GLM_COMPILER_CLANG)) +# if defined(__AVX2__) +# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# elif defined(__AVX__) +# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# elif defined(__SSE4_1__ ) +# define GLM_ARCH (GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# elif defined(__SSE3__) +# define GLM_ARCH (GLM_ARCH_SSE3 | GLM_ARCH_SSE2) +# elif defined(__SSE2__) +# define GLM_ARCH (GLM_ARCH_SSE2) +# else +# define GLM_ARCH (GLM_ARCH_PURE) +# endif #else # define GLM_ARCH GLM_ARCH_PURE #endif diff --git a/glm/detail/type_mat4x4.hpp b/glm/detail/type_mat4x4.hpp index 30e0a548..d5f652bf 100644 --- a/glm/detail/type_mat4x4.hpp +++ b/glm/detail/type_mat4x4.hpp @@ -59,6 +59,7 @@ namespace detail private: /// @cond DETAIL col_type value[4]; + /// @endcond public: // Constructors diff --git a/glm/gtc/quaternion.hpp b/glm/gtc/quaternion.hpp index 44474573..1470a85d 100644 --- a/glm/gtc/quaternion.hpp +++ b/glm/gtc/quaternion.hpp @@ -59,6 +59,7 @@ namespace detail { enum ctor{null}; + typedef T value_type; typedef tvec4 bool_type; public: diff --git a/glm/gtc/quaternion.inl b/glm/gtc/quaternion.inl index 951b62c4..a9d5ac52 100644 --- a/glm/gtc/quaternion.inl +++ b/glm/gtc/quaternion.inl @@ -255,7 +255,7 @@ namespace detail template struct compute_dot { - static T call(tquat const & x, tquat const & y) + static GLM_FUNC_QUALIFIER T call(tquat const & x, tquat const & y) { tvec4 tmp(x.x * y.x, x.y * y.y, x.z * y.z, x.w * y.w); return (tmp.x + tmp.y) + (tmp.z + tmp.w); @@ -302,16 +302,11 @@ namespace detail detail::tvec3 const & v ) { - T Two(2); + detail::tvec3 const QuatVector(q.x, q.y, q.z); + detail::tvec3 const uv(glm::cross(QuatVector, v)); + detail::tvec3 const uuv(glm::cross(QuatVector, uv)); - detail::tvec3 uv, uuv; - detail::tvec3 QuatVector(q.x, q.y, q.z); - uv = glm::cross(QuatVector, v); - uuv = glm::cross(QuatVector, uv); - uv *= (Two * q.w); - uuv *= Two; - - return v + uv + uuv; + return v + ((uv * q.w) + uuv) * static_cast(2); } template @@ -587,10 +582,10 @@ namespace detail { // Linear interpolation return detail::tquat( - mix(x.w, y.w, a), - mix(x.x, y.x, a), - mix(x.y, y.y, a), - mix(x.z, y.z, a)); + mix(x.w, z.w, a), + mix(x.x, z.x, a), + mix(x.y, z.y, a), + mix(x.z, z.z, a)); } else { diff --git a/glm/gtx/bit.inl b/glm/gtx/bit.inl index e8ef509f..f34a9833 100644 --- a/glm/gtx/bit.inl +++ b/glm/gtx/bit.inl @@ -287,7 +287,7 @@ namespace glm assert(ToBit <= sizeof(genIUType) * std::size_t(8)); genIUType Result = Value; - for(std::size_t i = 0; i <= ToBit; ++i) + for(signed i = 0; i <= ToBit; ++i) Result |= (1 << i); return Result; } @@ -304,7 +304,7 @@ namespace glm assert(ToBit <= sizeof(genIUType) * std::size_t(8)); genIUType Result = Value; - for(std::size_t i = 0; i <= ToBit; ++i) + for(signed i = 0; i <= ToBit; ++i) Result &= ~(1 << i); return Result; } diff --git a/glm/gtx/euler_angles.inl b/glm/gtx/euler_angles.inl index b3102242..a1afcf3a 100644 --- a/glm/gtx/euler_angles.inl +++ b/glm/gtx/euler_angles.inl @@ -250,7 +250,7 @@ namespace glm detail::tvec3 const & angles ) { - return detail::tmat3x3(yawPitchRoll(angles.x, angles.y, angles.z)); + return detail::tmat3x3(yawPitchRoll(angles.z, angles.x, angles.y)); } template diff --git a/glm/gtx/fast_square_root.inl b/glm/gtx/fast_square_root.inl index a08bdbf2..198e03ab 100644 --- a/glm/gtx/fast_square_root.inl +++ b/glm/gtx/fast_square_root.inl @@ -101,13 +101,43 @@ namespace glm template GLM_FUNC_QUALIFIER genType fastDistance ( - genType const & x, + genType const & x, genType const & y ) { return fastLength(y - x); } + template + GLM_FUNC_QUALIFIER valType fastDistance + ( + detail::tvec2 const & x, + detail::tvec2 const & y + ) + { + return fastLength(y - x); + } + + template + GLM_FUNC_QUALIFIER valType fastDistance + ( + detail::tvec3 const & x, + detail::tvec3 const & y + ) + { + return fastLength(y - x); + } + + template + GLM_FUNC_QUALIFIER valType fastDistance + ( + detail::tvec4 const & x, + detail::tvec4 const & y + ) + { + return fastLength(y - x); + } + // fastNormalize template GLM_FUNC_QUALIFIER genType fastNormalize diff --git a/glm/gtx/io.hpp b/glm/gtx/io.hpp index e97d27fb..25e9d74b 100644 --- a/glm/gtx/io.hpp +++ b/glm/gtx/io.hpp @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////////// /// OpenGL Mathematics (glm.g-truc.net) /// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) +/// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net) /// 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 @@ -26,94 +26,174 @@ /// @author Jan P Springer (regnirpsj@gmail.com) /// /// @see core (dependence) -/// @see gtx_quaternion (dependence) +/// @see gtc_quaternion (dependence) /// /// @defgroup gtx_io GLM_GTX_io /// @ingroup gtx /// /// @brief std::[w]ostream support for glm types /// +/// std::[w]ostream support for glm types + precision/width/etc. manipulators +/// based on howard hinnant's std::chrono io proposal +/// [http://home.roadrunner.com/~hinnant/bloomington/chrono_io.html] +/// /// needs to be included to use these functionalities. /////////////////////////////////////////////////////////////////////////////////// #ifndef GLM_GTX_io -#define GLM_GTX_io +#define GLM_GTX_io GLM_VERSION // Dependency: -#include "../detail/setup.hpp" -#include "../gtc/quaternion.hpp" +#include "../glm.hpp" +#include "../gtx/quaternion.hpp" -#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) -# pragma message("GLM: GLM_GTX_io extension included") +#if(defined(GLM_MESSAGES) && !defined(glm_ext)) +# pragma message("GLM: GLM_GTX_io extension included") #endif #include // std::basic_ostream<> (fwd) +#include // std::locale, std::locale::facet, std::locale::id #include // std::pair<> namespace glm { - /// @addtogroup gtx_io - /// @{ + /// @addtogroup gtx_io + /// @{ namespace io { - class precision_guard { + enum order_type { column_major, row_major, }; + + template + class format_punct : public std::locale::facet { + typedef CTy char_type; + public: + + static std::locale::id id; + + bool formatted; + unsigned precision; + unsigned width; + char_type separator; + char_type delim_left; + char_type delim_right; + char_type space; + char_type newline; + order_type order; + + explicit format_punct(size_t a = 0); + explicit format_punct(format_punct const&); - GLM_FUNC_DECL explicit precision_guard(); - GLM_FUNC_DECL ~precision_guard(); - + }; + + template > + class basic_state_saver { + + public: + + explicit basic_state_saver(std::basic_ios&); + ~basic_state_saver(); + private: - unsigned precision_; - unsigned value_width_; + typedef ::std::basic_ios state_type; + typedef typename state_type::char_type char_type; + typedef ::std::ios_base::fmtflags flags_type; + typedef ::std::streamsize streamsize_type; + typedef ::std::locale const locale_type; + + state_type& state_; + flags_type flags_; + streamsize_type precision_; + streamsize_type width_; + char_type fill_; + locale_type locale_; + + basic_state_saver& operator=(basic_state_saver const&); }; - class format_guard - { - public: - enum order_t { column_major, row_major, }; + typedef basic_state_saver state_saver; + typedef basic_state_saver wstate_saver; + + template > + class basic_format_saver { - GLM_FUNC_DECL explicit format_guard(); - GLM_FUNC_DECL ~format_guard(); + public: - private: + explicit basic_format_saver(std::basic_ios&); + ~basic_format_saver(); - order_t order_; - char cr_; - }; + private: - // decimal places (dflt: 3) - GLM_FUNC_DECL unsigned& precision(); + basic_state_saver const bss_; - // sign + value + '.' + decimals (dflt: 1 + 4 + 1 + precision()) - GLM_FUNC_DECL unsigned& value_width(); + basic_format_saver& operator=(basic_format_saver const&); + + }; - // matrix output order (dflt: row_major) - GLM_FUNC_DECL format_guard::order_t& order(); + typedef basic_format_saver format_saver; + typedef basic_format_saver wformat_saver; + + struct precision { - // carriage/return char (dflt: '\n') - GLM_FUNC_DECL char& cr(); + unsigned value; + + explicit precision(unsigned); + + }; + + struct width { - // matrix output order -> column_major - GLM_FUNC_DECL std::ios_base& column_major(std::ios_base&); + unsigned value; + + explicit width(unsigned); + + }; - // matrix output order -> row_major - GLM_FUNC_DECL std::ios_base& row_major (std::ios_base&); + template + struct delimeter { - // carriage/return char -> '\n' - GLM_FUNC_DECL std::ios_base& formatted (std::ios_base&); + CTy value[3]; + + explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ','); + + }; - // carriage/return char -> ' ' - GLM_FUNC_DECL std::ios_base& unformatted (std::ios_base&); + struct order { + order_type value; + + explicit order(order_type); + + }; + + // functions, inlined (inline) + + template + FTy const& get_facet(std::basic_ios&); + template + std::basic_ios& formatted(std::basic_ios&); + template + std::basic_ios& unformattet(std::basic_ios&); + + template + std::basic_ostream& operator<<(std::basic_ostream&, precision const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, width const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, delimeter const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, order const&); + }//namespace io namespace detail { + template GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tquat const&); template @@ -140,9 +220,15 @@ namespace glm GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x3 const&); template GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x4 const&); - - /// @} -}//namespace detail + + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, + std::pair const, + tmat4x4 const> const&); + + }//namespace detail + + /// @} }//namespace glm #include "io.inl" diff --git a/glm/gtx/io.inl b/glm/gtx/io.inl index 2329ffd8..3132a88e 100644 --- a/glm/gtx/io.inl +++ b/glm/gtx/io.inl @@ -1,328 +1,579 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// -// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) +// OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net) /////////////////////////////////////////////////////////////////////////////////////////////////// // Created : 2013-11-22 -// Updated : 2013-11-22 +// Updated : 2013-12-18 // Licence : This source is under MIT License // File : glm/gtx/inl.inl /////////////////////////////////////////////////////////////////////////////////////////////////// -#include "../matrix.hpp" -// #include // boost::io::ios_all_saver -#include // std::setfill<>, std::fixed, std::setprecision, std::right, - // std::setw -#include // std::basic_ostream<> +#include // std::setfill<>, std::fixed, std::setprecision, std::right, std::setw +#include // std::basic_ostream<> -namespace glm{ -namespace io +namespace glm { + namespace io + { + template /* explicit */ GLM_FUNC_QUALIFIER - precision_guard::precision_guard() - : precision_ (precision()), - value_width_(value_width()) + format_punct::format_punct(size_t a) + : std::locale::facet(a), + formatted (true), + precision (3), + width (1 + 4 + 1 + precision), + separator (','), + delim_left ('['), + delim_right (']'), + space (' '), + newline ('\n'), + order (row_major) {} + template + /* explicit */ GLM_FUNC_QUALIFIER + format_punct::format_punct(format_punct const& a) + : std::locale::facet(0), + formatted (a.formatted), + precision (a.precision), + width (a.width), + separator (a.separator), + delim_left (a.delim_left), + delim_right (a.delim_right), + space (a.space), + newline (a.newline), + order (a.order) + {} + + template std::locale::id format_punct::id; + + template + /* explicit */ GLM_FUNC_QUALIFIER + basic_state_saver::basic_state_saver(std::basic_ios& a) + : state_ (a), + flags_ (a.flags()), + precision_(a.precision()), + width_ (a.width()), + fill_ (a.fill()), + locale_ (a.getloc()) + {} + + template GLM_FUNC_QUALIFIER - precision_guard::~precision_guard() + basic_state_saver::~basic_state_saver() { - value_width() = value_width_; - precision() = precision_; + state_.imbue(locale_); + state_.fill(fill_); + state_.width(width_); + state_.precision(precision_); + state_.flags(flags_); + } + + template + /* explicit */ GLM_FUNC_QUALIFIER + basic_format_saver::basic_format_saver(std::basic_ios& a) + : bss_(a) + { + a.imbue(std::locale(a.getloc(), new format_punct(get_facet >(a)))); } + template + GLM_FUNC_QUALIFIER + basic_format_saver::~basic_format_saver() + {} + /* explicit */ GLM_FUNC_QUALIFIER - format_guard::format_guard() - : order_(order()), - cr_ (cr()) + precision::precision(unsigned a) + : value(a) {} - GLM_FUNC_QUALIFIER - format_guard::~format_guard() + /* explicit */ GLM_FUNC_QUALIFIER + width::width(unsigned a) + : value(a) + {} + + template + /* explicit */ GLM_FUNC_QUALIFIER + delimeter::delimeter(CTy a, CTy b, CTy c) + : value() { - cr() = cr_; - order() = order_; + value[0] = a; + value[1] = b; + value[2] = c; } - GLM_FUNC_QUALIFIER unsigned& precision() + /* explicit */ GLM_FUNC_QUALIFIER + order::order(order_type a) + : value(a) + {} + + template + GLM_FUNC_QUALIFIER FTy const& + get_facet(std::basic_ios& ios) { - static unsigned p(3); + if (!std::has_facet(ios.getloc())) { + ios.imbue(std::locale(ios.getloc(), new FTy)); + } - return p; + return std::use_facet(ios.getloc()); } - - GLM_FUNC_QUALIFIER unsigned& value_width() + + template + GLM_FUNC_QUALIFIER std::basic_ios& + formatted(std::basic_ios& ios) { - static unsigned p(9); + const_cast&>(get_facet >(ios)).formatted = true; - return p; + return ios; } - GLM_FUNC_QUALIFIER format_guard::order_t& order() + template + GLM_FUNC_QUALIFIER std::basic_ios& + unformatted(std::basic_ios& ios) { - static format_guard::order_t p(format_guard::row_major); + const_cast&>(get_facet >(ios)).formatted = false; - return p; + return ios; } - GLM_FUNC_QUALIFIER char& - cr() + template + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, precision const& a) { - static char p('\n'); return p; + const_cast&>(get_facet >(os)).precision = a.value; + + return os; } - - GLM_FUNC_QUALIFIER std::ios_base& column_major(std::ios_base& os) + + template + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, width const& a) { - order() = format_guard::column_major; - + const_cast&>(get_facet >(os)).width = a.value; + return os; } - - GLM_FUNC_QUALIFIER std::ios_base& row_major(std::ios_base& os) + + template + std::basic_ostream& operator<<(std::basic_ostream& os, + delimeter const& a) { - order() = format_guard::row_major; + format_punct& fmt(const_cast&>(get_facet >(os))); + + fmt.delim_left = a.value[0]; + fmt.delim_right = a.value[1]; + fmt.separator = a.value[2]; return os; } - GLM_FUNC_QUALIFIER std::ios_base& formatted(std::ios_base& os) + template + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, order const& a) { - cr() = '\n'; - + const_cast&>(get_facet >(os)).order = a.value; + return os; } - GLM_FUNC_QUALIFIER std::ios_base& unformatted(std::ios_base& os) + } // namespace io + + namespace detail { + + template + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tquat const& a) { - cr() = ' '; + typename std::basic_ostream::sentry const cerberus(os); + + if (cerberus) { + io::format_punct const& fmt(io::get_facet >(os)); + + if (fmt.formatted) { + io::basic_state_saver const bss(os); + + os << std::fixed + << std::right + << std::setprecision(fmt.precision) + << std::setfill(fmt.space) + << fmt.delim_left + << std::setw(fmt.width) << a.w << fmt.separator + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y << fmt.separator + << std::setw(fmt.width) << a.z + << fmt.delim_right; + } else { + os << a.w << fmt.space << a.x << fmt.space << a.y << fmt.space << a.z; + } + } return os; } -} // namespace io -namespace detail -{ - // functions, inlined (inline) - template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tquat const& a) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tvec2 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.w << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.z - << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + + if (fmt.formatted) { + io::basic_state_saver const bss(os); + + os << std::fixed + << std::right + << std::setprecision(fmt.precision) + << std::setfill(fmt.space) + << fmt.delim_left + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y + << fmt.delim_right; + } else { + os << a.x << fmt.space << a.y; + } } return os; } - + template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec2 const& a) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tvec3 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y - << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + + if (fmt.formatted) { + io::basic_state_saver const bss(os); + + os << std::fixed + << std::right + << std::setprecision(fmt.precision) + << std::setfill(fmt.space) + << fmt.delim_left + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y << fmt.separator + << std::setw(fmt.width) << a.z + << fmt.delim_right; + } else { + os << a.x << fmt.space << a.y << fmt.space << a.z; + } } - + return os; } - + template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec3 const& a) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tvec4 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.z - << ']'; - } + io::format_punct const& fmt(io::get_facet >(os)); + if (fmt.formatted) { + io::basic_state_saver const bss(os); + + os << std::fixed + << std::right + << std::setprecision(fmt.precision) + << std::setfill(fmt.space) + << fmt.delim_left + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y << fmt.separator + << std::setw(fmt.width) << a.z << fmt.separator + << std::setw(fmt.width) << a.w + << fmt.delim_right; + } else { + os << a.x << fmt.space << a.y << fmt.space << a.z << fmt.space << a.w; + } + } + return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec4 const& a) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat2x2 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.z << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.w - << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat2x2 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x2 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat2x3 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat3x2 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1] << fmt.space << m[2]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x3 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat2x4 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat4x2 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.newline + << fmt.space << m[3] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x4 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat3x2 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat2x3 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x2 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat3x3 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat3x3 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1] << fmt.space << m[2]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x3 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat3x4 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat4x3 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.newline + << fmt.space << m[3] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x4 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat4x2 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat2x4 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat4x2 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat4x3 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << io::cr() - << ' ' << m[3] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat3x4 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1] << fmt.space << m[2]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat4x3 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tmat4x4 const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << io::cr() - << ' ' << m[3] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat4x4 m(a); + + if (io::row_major == fmt.order) { + m = transpose(a); + } + + if (fmt.formatted) { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.newline + << fmt.space << m[3] << fmt.delim_right; + } else { + os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; + } } return os; } template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat4x4 const& m) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, + std::pair const, tmat4x4 const> const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << io::cr() - << ' ' << m[3] << ']'; + io::format_punct const& fmt(io::get_facet >(os)); + tmat4x4 ml(a.first); + tmat4x4 mr(a.second); + + if (io::row_major == fmt.order) { + ml = transpose(a.first); + mr = transpose(a.second); + } + + if (fmt.formatted) { + CTy const& l(fmt.delim_left); + CTy const& r(fmt.delim_right); + CTy const& s(fmt.space); + + os << fmt.newline + << l << ml[0] << s << s << l << mr[0] << fmt.newline + << s << ml[1] << s << s << s << mr[1] << fmt.newline + << s << ml[2] << s << s << s << mr[2] << fmt.newline + << s << ml[3] << r << s << s << mr[3] << r; + } else { + os << ml << fmt.space << mr; + } } return os; } - -}//namespace detail + + }//namespace detail }//namespace glm diff --git a/readme.txt b/readme.txt index 5d77323e..8016adc5 100644 --- a/readme.txt +++ b/readme.txt @@ -50,6 +50,15 @@ GLM 0.9.5.4: 2014-0X-XX - Fixed non-utf8 character #196 - Added FindGLM install for CMake #189 - Fixed GTX_color_space - saturation #195 +- Fixed glm::isinf and glm::isnan for with Android NDK 9d #191 +- Fixed builtin GLM_ARCH_SSE4 #204 +- Optimized Quaternion vector rotation #205 +- Fixed missing doxygen @endcond tag #211 +- Fixed instruction set detection with Clang #158 +- Fixed orientate3 function #207 +- Fixed lerp when cosTheta is close to 1 in quaternion slerp #210 +- Added GTX_io for io with #144 +- Fixed fastDistance ambiguity #215 ================================================================================ GLM 0.9.5.3: 2014-04-02 diff --git a/test/core/core_type_cast.cpp b/test/core/core_type_cast.cpp index 7c002886..f33972c6 100644 --- a/test/core/core_type_cast.cpp +++ b/test/core/core_type_cast.cpp @@ -9,6 +9,9 @@ #define GLM_FORCE_RADIANS #include +#include +#include +#include struct my_vec2 { @@ -86,10 +89,50 @@ int test_vec4_cast() return Error; } +int test_std_copy() +{ + int Error = 0; + + { + std::vector High4; + std::vector Medium4(High4.size()); + + std::copy(&High4.begin()[0], &High4.end()[0], Medium4.begin()); + + *Medium4.begin() = *High4.begin(); + } + + { + std::vector High3; + std::vector Medium3(High3.size()); + + std::copy(&High3.begin()[0], &High3.end()[0], Medium3.begin()); + + *Medium3.begin() = *High3.begin(); + } + + { + std::vector High2; + std::vector Medium2(High2.size()); + + std::copy(&High2.begin()[0], &High2.end()[0], Medium2.begin()); + + *Medium2.begin() = *High2.begin(); + } + + glm::dvec4 v1; + glm::vec4 v2; + + v2 = v1; + + return Error; +} + int main() { int Error = 0; + Error += test_std_copy(); Error += test_vec2_cast(); Error += test_vec3_cast(); Error += test_vec4_cast(); diff --git a/test/gtc/gtc_quaternion.cpp b/test/gtc/gtc_quaternion.cpp index 4346e8fc..fab238af 100644 --- a/test/gtc/gtc_quaternion.cpp +++ b/test/gtc/gtc_quaternion.cpp @@ -196,6 +196,15 @@ int test_quat_slerp() // Must be 0 0.00X 0 0.99999 glm::quat almostid = glm::slerp(id, glm::angleAxis(0.1f, glm::vec3(0.0f, 1.0f, 0.0f)), 0.5f); + // Testing quaternions with opposite sign + { + glm::quat a(-1, 0, 0, 0); + + glm::quat result = glm::slerp(a, id, 0.5f); + + Error += glm::epsilonEqual(glm::pow(glm::dot(id, result), 2.f), 1.f, 0.01f) ? 0 : 1; + } + return Error; } @@ -247,6 +256,20 @@ int test_quat_type() return 0; } +int test_quat_mul_vec() +{ + int Error(0); + + glm::quat q = glm::angleAxis(glm::pi() * 0.5f, glm::vec3(0, 0, 1)); + glm::vec3 v(1, 0, 0); + glm::vec3 u(q * v); + glm::vec3 w(u * q); + + Error += glm::all(glm::epsilonEqual(v, w, 0.01f)) ? 0 : 1; + + return Error; +} + int test_quat_ctr() { int Error(0); @@ -269,6 +292,7 @@ int main() int Error(0); Error += test_quat_ctr(); + Error += test_quat_mul_vec(); Error += test_quat_two_axis_ctr(); Error += test_quat_mul(); Error += test_quat_precision(); diff --git a/test/gtx/gtx_fast_square_root.cpp b/test/gtx/gtx_fast_square_root.cpp index 788b341c..b9d41dcd 100644 --- a/test/gtx/gtx_fast_square_root.cpp +++ b/test/gtx/gtx_fast_square_root.cpp @@ -27,11 +27,29 @@ int test_fastInverseSqrt() return 0; } +int test_fastDistance() +{ + int Error(0); + + glm::mediump_f32 A = glm::fastDistance(glm::mediump_f32(0.0f), glm::mediump_f32(1.0f)); + glm::mediump_f32 B = glm::fastDistance(glm::mediump_f32vec2(0.0f), glm::mediump_f32vec2(1.0f, 0.0f)); + glm::mediump_f32 C = glm::fastDistance(glm::mediump_f32vec3(0.0f), glm::mediump_f32vec3(1.0f, 0.0f, 0.0f)); + glm::mediump_f32 D = glm::fastDistance(glm::mediump_f32vec4(0.0f), glm::mediump_f32vec4(1.0f, 0.0f, 0.0f, 0.0f)); + + Error += glm::epsilonEqual(A, glm::mediump_f32(1.0f), glm::mediump_f32(0.01f)) ? 0 : 1; + Error += glm::epsilonEqual(B, glm::mediump_f32(1.0f), glm::mediump_f32(0.01f)) ? 0 : 1; + Error += glm::epsilonEqual(C, glm::mediump_f32(1.0f), glm::mediump_f32(0.01f)) ? 0 : 1; + Error += glm::epsilonEqual(D, glm::mediump_f32(1.0f), glm::mediump_f32(0.01f)) ? 0 : 1; + + return Error; +} + int main() { int Error(0); Error += test_fastInverseSqrt(); + Error += test_fastDistance(); return Error; } diff --git a/test/gtx/gtx_io.cpp b/test/gtx/gtx_io.cpp index 05ba8e9b..6fcaa60e 100644 --- a/test/gtx/gtx_io.cpp +++ b/test/gtx/gtx_io.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace { @@ -32,8 +33,60 @@ namespace { return os; } + template + std::basic_string + type_name(std::basic_ostream& os, T const&) + { + std::basic_ostringstream ostr; + + if (typeid(T) == typeid(glm::detail::tquat)) { ostr << "quat"; } + else if (typeid(T) == typeid(glm::detail::tvec2)) { ostr << "vec2"; } + else if (typeid(T) == typeid(glm::detail::tvec3)) { ostr << "vec3"; } + else if (typeid(T) == typeid(glm::detail::tvec4)) { ostr << "vec4"; } + else if (typeid(T) == typeid(glm::detail::tmat2x2)) { ostr << "mat2x2"; } + else if (typeid(T) == typeid(glm::detail::tmat2x3)) { ostr << "mat2x3"; } + else if (typeid(T) == typeid(glm::detail::tmat2x4)) { ostr << "mat2x4"; } + else if (typeid(T) == typeid(glm::detail::tmat3x2)) { ostr << "mat3x2"; } + else if (typeid(T) == typeid(glm::detail::tmat3x3)) { ostr << "mat3x3"; } + else if (typeid(T) == typeid(glm::detail::tmat3x4)) { ostr << "mat3x4"; } + else if (typeid(T) == typeid(glm::detail::tmat4x2)) { ostr << "mat4x2"; } + else if (typeid(T) == typeid(glm::detail::tmat4x3)) { ostr << "mat4x3"; } + else if (typeid(T) == typeid(glm::detail::tmat4x4)) { ostr << "mat4x4"; } + else { ostr << "unknown"; } + + ostr << '<' << typeid(U).name() << ',' << P << '>'; + + return ostr.str(); + } + } // namespace { +template +int test_io_quat(OS& os) +{ + os << '\n' + << typeid(OS).name() + << '\n'; + + glm::detail::tquat const q(1, 0, 0, 0); + + { + glm::io::basic_format_saver const iofs(os); + + os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2) + << type_name(os, q) << ": " << q << '\n'; + } + + { + glm::io::basic_format_saver const iofs(os); + + os << glm::io::unformatted + << type_name(os, q) << ": " << q << '\n'; + } + + return 0; +} + template int test_io_vec(OS& os) { @@ -45,18 +98,16 @@ int test_io_vec(OS& os) glm::detail::tvec3 const v3(2, 3, 4); glm::detail::tvec4 const v4(5, 6, 7, 8); - os << "vec2<" << typeid(T).name() << ',' << P << ">: " << v2 << '\n' - << "vec3<" << typeid(T).name() << ',' << P << ">: " << v3 << '\n' - << "vec4<" << typeid(T).name() << ',' << P << ">: " << v4 << '\n'; + os << type_name(os, v2) << ": " << v2 << '\n' + << type_name(os, v3) << ": " << v3 << '\n' + << type_name(os, v4) << ": " << v4 << '\n'; - glm::io::precision_guard const iopg; - - glm::io::precision() = 2; - glm::io::value_width() = 1 + 2 + 1 + glm::io::precision(); + glm::io::basic_format_saver const iofs(os); - os << "vec2<" << typeid(T).name() << ',' << P << ">: " << v2 << '\n' - << "vec3<" << typeid(T).name() << ',' << P << ">: " << v3 << '\n' - << "vec4<" << typeid(T).name() << ',' << P << ">: " << v4 << '\n'; + os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2) + << type_name(os, v2) << ": " << v2 << '\n' + << type_name(os, v3) << ": " << v3 << '\n' + << type_name(os, v4) << ": " << v4 << '\n'; return 0; } @@ -93,12 +144,10 @@ int test_io_mat(OS& os) << "mat4x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat4x4(v4_1, v4_2, v4_3, v4_4) << '\n'; #endif - glm::io::precision_guard const iopg; - - glm::io::precision() = 2; - glm::io::value_width() = 1 + 2 + 1 + glm::io::precision(); + glm::io::basic_format_saver const iofs(os); - os << "mat2x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x2(v2_1, v2_2) << '\n' + os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2) + << "mat2x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x2(v2_1, v2_2) << '\n' << "mat2x3<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x3(v3_1, v3_2) << '\n' << "mat2x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x4(v4_1, v4_2) << '\n' << "mat3x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat3x2(v2_1, v2_2, v2_3) << '\n' @@ -108,7 +157,8 @@ int test_io_mat(OS& os) << "mat4x3<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat4x3(v3_1, v3_2, v3_3, v3_4) << '\n' << "mat4x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat4x4(v4_1, v4_2, v4_3, v4_4) << '\n'; - os << glm::io::column_major + os << glm::io::unformatted + << glm::io::order(glm::io::column_major) << "mat2x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x2(v2_1, v2_2) << '\n' << "mat2x3<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x3(v3_1, v3_2) << '\n' << "mat2x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x4(v4_1, v4_2) << '\n' @@ -126,6 +176,13 @@ int main() { int Error(0); + Error += test_io_quat(std::cout); + Error += test_io_quat(std::wcout); + Error += test_io_quat(std::cout); + Error += test_io_quat(std::wcout); + Error += test_io_quat(std::cout); + Error += test_io_quat(std::wcout); + Error += test_io_vec(std::cout); Error += test_io_vec(std::wcout); Error += test_io_vec(std::cout);