Fixed undefined reference to fastInverseSqrt (#161)

This commit is contained in:
Christophe Riccio 2014-02-08 13:34:40 +01:00
parent 1d981dd344
commit a310855d23
6 changed files with 109 additions and 61 deletions

View File

@ -29,10 +29,20 @@
#ifndef GLM_CORE_DETAIL_INCLUDED
#define GLM_CORE_DETAIL_INCLUDED
#include "type_vec1.hpp"
#include "type_vec2.hpp"
#include "type_vec3.hpp"
#include "type_vec4.hpp"
#define VECTORIZE1_VEC(func) \
template <typename T, precision P> \
GLM_FUNC_QUALIFIER detail::tvec1<T, P> func( \
detail::tvec1<T, P> const & v) \
{ \
return detail::tvec1<T, P>( \
func(v.x)); \
}
#define VECTORIZE2_VEC(func) \
template <typename T, precision P> \
GLM_FUNC_QUALIFIER detail::tvec2<T, P> func( \
@ -67,10 +77,23 @@
}
#define VECTORIZE_VEC(func) \
VECTORIZE1_VEC(func) \
VECTORIZE2_VEC(func) \
VECTORIZE3_VEC(func) \
VECTORIZE4_VEC(func)
#define VECTORIZE1_VEC_SCA(func) \
template <typename T, precision P> \
GLM_FUNC_QUALIFIER detail::tvec1<T, P> func \
( \
detail::tvec1<T, P> const & x, \
T const & y \
) \
{ \
return detail::tvec1<T, P>( \
func(x.x, y)); \
}
#define VECTORIZE2_VEC_SCA(func) \
template <typename T, precision P> \
GLM_FUNC_QUALIFIER detail::tvec2<T, P> func \
@ -114,6 +137,7 @@
}
#define VECTORIZE_VEC_SCA(func) \
VECTORIZE1_VEC_SCA(func) \
VECTORIZE2_VEC_SCA(func) \
VECTORIZE3_VEC_SCA(func) \
VECTORIZE4_VEC_SCA(func)

View File

@ -31,8 +31,51 @@
#include <limits>
#include <cassert>
namespace glm
namespace glm{
namespace detail
{
template <bool isFloat>
struct compute_log2
{
template <typename T>
T operator() (T const & Value) const;
};
template <>
struct compute_log2<true>
{
template <typename T>
T operator() (T const & Value) const
{
return static_cast<T>(::std::log(Value)) * static_cast<T>(1.4426950408889634073599246810019);
}
};
template <template <class, precision> class vecType, typename T, precision P>
struct compute_inversesqrt
{
static vecType<T, P> call(vecType<T, P> const & x)
{
return static_cast<T>(1) / sqrt(x);
}
};
template <template <class, precision> class vecType>
struct compute_inversesqrt<vecType, float, lowp>
{
static vecType<float, lowp> call(vecType<float, lowp> const & x)
{
vecType<float, lowp> tmp(x);
vecType<float, lowp> xhalf(tmp * 0.5f);
vecType<uint, lowp> i = *reinterpret_cast<vecType<uint, lowp>*>(const_cast<vecType<float, lowp>*>(&x));
i = vecType<uint, lowp>(0x5f375a86) - (i >> vecType<uint, lowp>(1));
tmp = *reinterpret_cast<vecType<float, lowp>*>(&i);
tmp = tmp * (1.5f - xhalf * tmp * tmp);
return tmp;
}
};
}//namespace detail
// pow
template <typename genType>
GLM_FUNC_QUALIFIER genType pow
@ -98,27 +141,6 @@ namespace glm
VECTORIZE_VEC(exp2)
namespace detail
{
template <bool isFloat>
struct compute_log2
{
template <typename T>
T operator() (T const & Value) const;
};
template <>
struct compute_log2<true>
{
template <typename T>
T operator() (T const & Value) const
{
return static_cast<T>(::std::log(Value)) * static_cast<T>(1.4426950408889634073599246810019);
}
};
}//namespace detail
// log2, ln2 = 0.69314718055994530941723212145818f
template <typename genType>
GLM_FUNC_QUALIFIER genType log2
@ -142,9 +164,7 @@ namespace detail
genType const & x
)
{
GLM_STATIC_ASSERT(
std::numeric_limits<genType>::is_iec559,
"'sqrt' only accept floating-point inputs");
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'sqrt' only accept floating-point inputs");
assert(x >= genType(0));
@ -153,33 +173,6 @@ namespace detail
VECTORIZE_VEC(sqrt)
namespace detail
{
template <template <class, precision> class vecType, typename T, precision P>
struct compute_inversesqrt
{
static vecType<T, P> call(vecType<T, P> const & x)
{
return static_cast<T>(1) / sqrt(x);
}
};
template <template <class, precision> class vecType>
struct compute_inversesqrt<vecType, float, lowp>
{
static vecType<float, lowp> call(vecType<float, lowp> const & x)
{
vecType<float, lowp> tmp(x);
vecType<float, lowp> xhalf(tmp * 0.5f);
vecType<uint, lowp> i = *reinterpret_cast<vecType<uint, lowp>*>(const_cast<vecType<float, lowp>*>(&x));
i = vecType<uint, lowp>(0x5f375a86) - (i >> vecType<uint, lowp>(1));
tmp = *reinterpret_cast<vecType<float, lowp>*>(&i);
tmp = tmp * (1.5f - xhalf * tmp * tmp);
return tmp;
}
};
}//namespace detail
// inversesqrt
GLM_FUNC_QUALIFIER float inversesqrt(float const & x)
{

View File

@ -55,27 +55,32 @@ namespace glm
//! Faster than the common sqrt function but less accurate.
//! From GLM_GTX_fast_square_root extension.
template <typename genType>
genType fastSqrt(genType const & x);
GLM_FUNC_DECL genType fastSqrt(genType const & x);
//! Faster than the common inversesqrt function but less accurate.
//! From GLM_GTX_fast_square_root extension.
template <typename genType>
genType fastInverseSqrt(genType const & x);
GLM_FUNC_DECL genType fastInverseSqrt(genType const & x);
//! Faster than the common inversesqrt function but less accurate.
//! From GLM_GTX_fast_square_root extension.
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> fastInverseSqrt(vecType<T, P> const & x);
//! Faster than the common length function but less accurate.
//! From GLM_GTX_fast_square_root extension.
template <typename genType>
typename genType::value_type fastLength(genType const & x);
GLM_FUNC_DECL typename genType::value_type fastLength(genType const & x);
//! Faster than the common distance function but less accurate.
//! From GLM_GTX_fast_square_root extension.
template <typename genType>
typename genType::value_type fastDistance(genType const & x, genType const & y);
GLM_FUNC_DECL typename genType::value_type fastDistance(genType const & x, genType const & y);
//! Faster than the common normalize function but less accurate.
//! From GLM_GTX_fast_square_root extension.
template <typename genType>
genType fastNormalize(genType const & x);
GLM_FUNC_DECL genType fastNormalize(genType const & x);
/// @}
}// namespace glm

View File

@ -24,11 +24,18 @@ namespace glm
VECTORIZE_VEC(fastSqrt)
// fastInversesqrt
GLM_FUNC_QUALIFIER float fastInverseSqrt(float x)
template <>
GLM_FUNC_QUALIFIER float fastInverseSqrt<float>(float const & x)
{
return detail::compute_inversesqrt<detail::tvec1, float, lowp>::call(detail::tvec1<float, lowp>(x)).x;
}
template <>
GLM_FUNC_QUALIFIER double fastInverseSqrt<double>(double const & x)
{
return detail::compute_inversesqrt<detail::tvec1, double, lowp>::call(detail::tvec1<double, lowp>(x)).x;
}
template <template <class, precision> class vecType, typename T, precision P>
GLM_FUNC_QUALIFIER vecType<T, P> fastInverseSqrt
(

View File

@ -44,6 +44,7 @@ GLM 0.9.5.2: 2014-02-08
- Fixed non power of two matrix products
- Fixed mix function link error
- Fixed SSE code included in GLM tests on "pure" platforms
- Fixed undefined reference to fastInverseSqrt (#161)
================================================================================
GLM 0.9.5.1: 2014-01-11

View File

@ -8,12 +8,30 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
#define GLM_FORCE_RADIANS
#include <glm/gtc/type_precision.hpp>
#include <glm/gtx/fast_square_root.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/vector_relational.hpp>
int test_fastInverseSqrt()
{
int Error(0);
Error += glm::epsilonEqual(glm::fastInverseSqrt(1.0f), 1.0f, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(glm::fastInverseSqrt(1.0), 1.0, 0.01) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::vec2(1.0f)), glm::vec2(1.0f), 0.01f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec3(1.0)), glm::dvec3(1.0), 0.01)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec4(1.0)), glm::dvec4(1.0), 0.01)) ? 0 : 1;
return 0;
}
int main()
{
int Error(0);
Error += test_fastInverseSqrt();
return Error;
}