Merge branch '0.9.1' into gtx_ulp

This commit is contained in:
Christophe Riccio 2011-03-11 00:41:09 +00:00
commit 06ee0b868b
12 changed files with 253 additions and 1588 deletions

View File

@ -44,7 +44,7 @@ PROJECT_BRIEF =
# exceed 55 pixels and the maximum width should not exceed 200 pixels. # exceed 55 pixels and the maximum width should not exceed 200 pixels.
# Doxygen will copy the logo to the output directory. # Doxygen will copy the logo to the output directory.
PROJECT_LOGO = G:/git/ogl-math/doc/image/logo-mini.png PROJECT_LOGO = ./image/logo-mini.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.
@ -80,7 +80,7 @@ OUTPUT_LANGUAGE = English
# the file and class documentation (similar to JavaDoc). # the file and class documentation (similar to JavaDoc).
# Set to NO to disable this. # Set to NO to disable this.
BRIEF_MEMBER_DESC = YES BRIEF_MEMBER_DESC = NO
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description. # the brief description of a member or function before the detailed description.

View File

@ -9,15 +9,15 @@
This library works perfectly with OpenGL but it also ensures interoperability with other third party libraries and SDK. It is a good candidate for software rendering (Raytracing / Rasterisation), image processing, physic simulations and any context that requires a simple and convenient mathematics library. This library works perfectly with OpenGL but it also ensures interoperability with other third party libraries and SDK. It is a good candidate for software rendering (Raytracing / Rasterisation), image processing, physic simulations and any context that requires a simple and convenient mathematics library.
\note The Doxygen-generated documentation will often state that a type or function
is defined in a namespace that is a child of the \link glm glm \endlink namespace.
Please ignore this; you can access all publicly available types as direct children
of the glm namespace.
GLM is written as a platform independent library with no dependence and officially supports the following compilers: GLM is written as a platform independent library with no dependence and officially supports the following compilers:
1. GCC 3.4 and higher 1. GCC 3.4 and higher
2. LLVM 2.3 through GCC 4.2 front-end and higher 2. LLVM 2.3 through GCC 4.2 front-end and higher
3. Visual Studio 2005 and higher 3. Visual Studio 2005 and higher
\note The Doxygen-generated documentation will often state that a type or function
is defined in a namespace that is a child of the \link glm glm \endlink namespace.
Please ignore this; All publicly available types and functions can be accessed as a direct children
of the glm namespace.
The source code is licenced under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT licence</a>. The source code is licenced under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT licence</a>.
@ -67,7 +67,7 @@ int foo()
The \ref core "GLM" represents only what GLSL's core provides in terms of types and functions The \ref core "GLM" represents only what GLSL's core provides in terms of types and functions
(to the best of GLM's ability to replicate them). All that is needed to use the core (to the best of GLM's ability to replicate them). All that is needed to use the core
is to <tt>#include <glm/glm.hpp></tt>. is to include <tt><glm/glm.hpp></tt>.
\ref gtc "GTC extensions" are functions and types that add onto the core. \ref gtc "GTC extensions" are functions and types that add onto the core.
These are considered reasonably stable, with their APIs not changing much between These are considered reasonably stable, with their APIs not changing much between
@ -79,7 +79,7 @@ int foo()
is why they are marked "experimental". Like GTC extensions, each experimental extension is included is why they are marked "experimental". Like GTC extensions, each experimental extension is included
with a separate header file. with a separate header file.
All the extensions can be included at once by default with <tt>#include <glm/ext.hpp></tt> All the extensions can be included at once by default by including <tt><glm/ext.hpp></tt>
but this is not recommanded as it will reduce compilation speed for many unused features. but this is not recommanded as it will reduce compilation speed for many unused features.
All of GLM is defined as direct children of the glm namespace, including extensions. All of GLM is defined as direct children of the glm namespace, including extensions.
@ -255,8 +255,8 @@ void foo()
GLM's functions are defined in headers, so they are defined with C++'s "inline" delcaration. GLM's functions are defined in headers, so they are defined with C++'s "inline" delcaration.
This does not require the compiler to inline them, however. This does not require the compiler to inline them, however.
If you want to force the compiler to inline the function, using whatever capabilities that the compiler provides to do so, To force the compiler to inline the function, using whatever capabilities that the compiler provides to do so,
you can define GLM_FORCE_INLINE before any inclusion of <glm/glm.hpp>. GLM_FORCE_INLINE can be defined before any inclusion of <glm/glm.hpp>.
\code \code
#define GLM_FORCE_INLINE #define GLM_FORCE_INLINE
@ -281,7 +281,7 @@ void foo()
\section advanced_compatibility Compatibility \section advanced_compatibility Compatibility
Compilers have some language extensions that GLM will automatically take advantage of them when they are enabled. Compilers have some language extensions that GLM will automatically take advantage of them when they are enabled.
The #define GLM_FORCE_CXX98 can switch off these extensions, forcing GLM to operate on pure C++98. GLM_FORCE_CXX98 can switch off these extensions, forcing GLM to operate on pure C++98.
\code \code
#define GLM_FORCE_CXX98 #define GLM_FORCE_CXX98
@ -394,9 +394,10 @@ void foo()
\section faq7 Should I use 'using namespace glm;'? \section faq7 Should I use 'using namespace glm;'?
This is unwise. There is every chance that are that if 'using namespace glm;' is called, name collisions will happen. GLSL names for functions are fairly generic, so it is entirely likely that there is another function called, for example, \link glm::sqrt sqrt \endlink. This is unwise. Chances are that if 'using namespace glm;' is called, name collisions will happen.
GLSL names for functions are fairly generic, so it is entirely likely that there is another function called, for example, \link glm::sqrt sqrt \endlink.
If you need frequent use of particular types, you can bring them into the global For frequent use of particular types, they can be brough into the global
namespace with a 'using' declaration like this: namespace with a 'using' declaration like this:
/code /code
@ -409,9 +410,11 @@ void foo()
GLM is mainly designed to be convenient; that's why it is written against GLSL specification. GLM is mainly designed to be convenient; that's why it is written against GLSL specification.
The <a href="http://en.wikipedia.org/wiki/Pareto_principle">80-20</a> rule suggests that 80% of a program's performance comes from 20% of its code. Therefore, one must first identify which 20% of the code is impacting the performance. The <a href="http://en.wikipedia.org/wiki/Pareto_principle">80-20 rule</a> suggests that 80% of a program's performance comes from 20% of its code.
Therefore, one should first identify which 20% of the code is impacting the performance.
In general, if one identifies certain math code to be a performance bottleneck, the only way to solve this is to write specialized code for those particular math needs. So no canned library solution would be suitable. In general, if one identifies certain math code to be a performance bottleneck, the only way to solve this is to write specialized code for those particular math needs.
So no canned library solution would be suitable.
That being said, GLM can provides some descent performances alternatives based on approximations or SIMD instructions. That being said, GLM can provides some descent performances alternatives based on approximations or SIMD instructions.
**/ **/
@ -603,27 +606,30 @@ glm::vec3 lighting(
\page pg_reference References \page pg_reference References
OpenGL 4.1 core specification: OpenGL 4.1 core specification:
http://www.opengl.org/registry/doc/glspec41.core.20100725.pdf http://www.opengl.org/registry/doc/glspec41.core.20100725.pdf
GLSL 4.10 specification: GLSL 4.10 specification:
http://www.opengl.org/registry/doc/GLSLangSpec.4.10.6.clean.pdf http://www.opengl.org/registry/doc/GLSLangSpec.4.10.6.clean.pdf
GLU 1.3 specification: GLU 1.3 specification:
http://www.opengl.org/documentation/specs/glu/glu1_3.pdf http://www.opengl.org/documentation/specs/glu/glu1_3.pdf
GLM HEAD snapshot: GLM HEAD snapshot:
http://ogl-math.git.sourceforge.net/git/gitweb.cgi?p=ogl-math/ogl-math;a=snapshot;h=HEAD;sf=tgz http://ogl-math.git.sourceforge.net/git/gitweb.cgi?p=ogl-math/ogl-math;a=snapshot;h=HEAD;sf=tgz
GLM Trac, for bug report and feature request: GLM bug tracker:
https://sourceforge.net/apps/trac/ogl-math https://sourceforge.net/apps/trac/ogl-math
GLM website: GLM website:
http://glm.g-truc.net http://glm.g-truc.net
GLM OpenGL SDK page:
http://www.opengl.org/sdk/libs/GLM/
G-Truc Creation page: G-Truc Creation page:
http://www.g-truc.net/project-0016.html http://www.g-truc.net/project-0016.html
The OpenGL Toolkits forum to ask questions about GLM: The OpenGL Toolkits forum to ask questions about GLM:
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=postlist&Board=10&page=1 http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=postlist&Board=10&page=1
**/ **/

File diff suppressed because it is too large Load Diff

View File

@ -1005,8 +1005,7 @@ inline void sse_inverse_fast_ps(__m128 const in[4], __m128 out[4])
out[3] = _mm_mul_ps(Inv3, Rcp0); out[3] = _mm_mul_ps(Inv3, Rcp0);
} }
inline void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out[4])
void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out[4])
{ {
float a = glm::radians(Angle); float a = glm::radians(Angle);
float c = cos(a); float c = cos(a);
@ -1076,7 +1075,7 @@ void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out
sse_mul_ps(in, Result, out); sse_mul_ps(in, Result, out);
} }
void sse_outer_ps(__m128 const & c, __m128 const & r, __m128 out[4]) inline void sse_outer_ps(__m128 const & c, __m128 const & r, __m128 out[4])
{ {
out[0] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(0, 0, 0, 0))); out[0] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(0, 0, 0, 0)));
out[1] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(1, 1, 1, 1))); out[1] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(1, 1, 1, 1)));

View File

@ -88,7 +88,7 @@ namespace glm
#elif(GLM_PRECISION & GLM_PRECISION_LOWP_INT) #elif(GLM_PRECISION & GLM_PRECISION_LOWP_INT)
typedef precision::lowp_int int_t; typedef precision::lowp_int int_t;
#else #else
typedef mediump_int int_t; typedef precision::mediump_int int_t;
# pragma message("GLM message: Precisson undefined for signed integer number."); # pragma message("GLM message: Precisson undefined for signed integer number.");
#endif//GLM_PRECISION #endif//GLM_PRECISION

View File

@ -15,7 +15,6 @@
#include "type_int.hpp" #include "type_int.hpp"
#include "type_size.hpp" #include "type_size.hpp"
#include "_swizzle.hpp" #include "_swizzle.hpp"
#include "_detail.hpp"
namespace glm namespace glm
{ {

View File

@ -12,9 +12,6 @@
#ifndef glm_glm #ifndef glm_glm
#define glm_glm #define glm_glm
//! TODO: to delete
#define GLMvalType typename genType::value_type
#include <cmath> #include <cmath>
#include <climits> #include <climits>
#include <cfloat> #include <cfloat>

View File

@ -144,13 +144,15 @@ namespace matrix_transform
} }
template <typename valType> template <typename valType>
inline detail::tmat4x4<valType> ortho( inline detail::tmat4x4<valType> ortho
(
valType const & left, valType const & left,
valType const & right, valType const & right,
valType const & bottom, valType const & bottom,
valType const & top, valType const & top,
valType const & zNear, valType const & zNear,
valType const & zFar) valType const & zFar
)
{ {
detail::tmat4x4<valType> Result(1); detail::tmat4x4<valType> Result(1);
Result[0][0] = valType(2) / (right - left); Result[0][0] = valType(2) / (right - left);
@ -179,13 +181,15 @@ namespace matrix_transform
} }
template <typename valType> template <typename valType>
inline detail::tmat4x4<valType> frustum( inline detail::tmat4x4<valType> frustum
(
valType const & left, valType const & left,
valType const & right, valType const & right,
valType const & bottom, valType const & bottom,
valType const & top, valType const & top,
valType const & nearVal, valType const & nearVal,
valType const & farVal) valType const & farVal
)
{ {
detail::tmat4x4<valType> Result(0); detail::tmat4x4<valType> Result(0);
Result[0][0] = (valType(2) * nearVal) / (right - left); Result[0][0] = (valType(2) * nearVal) / (right - left);
@ -199,11 +203,13 @@ namespace matrix_transform
} }
template <typename valType> template <typename valType>
inline detail::tmat4x4<valType> perspective( inline detail::tmat4x4<valType> perspective
(
valType const & fovy, valType const & fovy,
valType const & aspect, valType const & aspect,
valType const & zNear, valType const & zNear,
valType const & zFar) valType const & zFar
)
{ {
valType range = tan(radians(fovy / valType(2))) * zNear; valType range = tan(radians(fovy / valType(2))) * zNear;
valType left = -range * aspect; valType left = -range * aspect;
@ -244,10 +250,12 @@ namespace matrix_transform
} }
template <typename T> template <typename T>
inline detail::tmat4x4<T> infinitePerspective( inline detail::tmat4x4<T> infinitePerspective
(
T fovy, T fovy,
T aspect, T aspect,
T zNear) T zNear
)
{ {
T range = tan(radians(fovy / T(2))) * zNear; T range = tan(radians(fovy / T(2))) * zNear;
T left = -range * aspect; T left = -range * aspect;
@ -265,10 +273,12 @@ namespace matrix_transform
} }
template <typename T> template <typename T>
inline detail::tmat4x4<T> tweakedInfinitePerspective( inline detail::tmat4x4<T> tweakedInfinitePerspective
(
T fovy, T fovy,
T aspect, T aspect,
T zNear) T zNear
)
{ {
T range = tan(radians(fovy / T(2))) * zNear; T range = tan(radians(fovy / T(2))) * zNear;
T left = -range * aspect; T left = -range * aspect;
@ -286,11 +296,13 @@ namespace matrix_transform
} }
template <typename T, typename U> template <typename T, typename U>
inline detail::tvec3<T> project( inline detail::tvec3<T> project
(
detail::tvec3<T> const & obj, detail::tvec3<T> const & obj,
detail::tmat4x4<T> const & model, detail::tmat4x4<T> const & model,
detail::tmat4x4<T> const & proj, detail::tmat4x4<T> const & proj,
detail::tvec4<U> const & viewport) detail::tvec4<U> const & viewport
)
{ {
detail::tvec4<T> tmp = detail::tvec4<T>(obj, T(1)); detail::tvec4<T> tmp = detail::tvec4<T>(obj, T(1));
tmp = model * tmp; tmp = model * tmp;
@ -305,11 +317,13 @@ namespace matrix_transform
} }
template <typename T, typename U> template <typename T, typename U>
inline detail::tvec3<T> unProject( inline detail::tvec3<T> unProject
(
detail::tvec3<T> const & win, detail::tvec3<T> const & win,
detail::tmat4x4<T> const & model, detail::tmat4x4<T> const & model,
detail::tmat4x4<T> const & proj, detail::tmat4x4<T> const & proj,
detail::tvec4<U> const & viewport) detail::tvec4<U> const & viewport
)
{ {
detail::tmat4x4<T> inverse = glm::inverse(proj * model); detail::tmat4x4<T> inverse = glm::inverse(proj * model);
@ -338,16 +352,23 @@ namespace matrix_transform
if(!(delta.x > T(0) && delta.y > T(0))) if(!(delta.x > T(0) && delta.y > T(0)))
return Result; // Error return Result; // Error
detail::tvec3<T> Temp(
(T(viewport[2]) - T(2) * (center.x - T(viewport[0]))) / delta.x,
(T(viewport[3]) - T(2) * (center.y - T(viewport[1]))) / delta.y,
T(0));
// Translate and scale the picked region to the entire window // Translate and scale the picked region to the entire window
Result = translate(Result, (T(viewport[2]) - T(2) * (center.x - T(viewport[0]))) / delta.x, (T(viewport[3]) - T(2) * (center.y - T(viewport[1]))) / delta.y, T(0)); Result = translate(Result, Temp);
return scale(Result, T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1)); return scale(Result, T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1));
} }
template <typename T> template <typename T>
inline detail::tmat4x4<T> lookAt( inline detail::tmat4x4<T> lookAt
const detail::tvec3<T>& eye, (
const detail::tvec3<T>& center, detail::tvec3<T> const & eye,
const detail::tvec3<T>& up) detail::tvec3<T> const & center,
detail::tvec3<T> const & up
)
{ {
detail::tvec3<T> f = normalize(center - eye); detail::tvec3<T> f = normalize(center - eye);
detail::tvec3<T> u = normalize(up); detail::tvec3<T> u = normalize(up);

View File

@ -36,31 +36,31 @@ namespace glm
//! From GLM_GTX_spline extension. //! From GLM_GTX_spline extension.
template <typename genType> template <typename genType>
genType catmullRom( genType catmullRom(
const genType& v1, genType const & v1,
const genType& v2, genType const & v2,
const genType& v3, genType const & v3,
const genType& v4, genType const & v4,
const GLMvalType& s); typename genType::value_type const & s);
//! Return a point from a hermite curve. //! Return a point from a hermite curve.
//! From GLM_GTX_spline extension. //! From GLM_GTX_spline extension.
template <typename genType> template <typename genType>
genType hermite( genType hermite(
const genType& v1, genType const & v1,
const genType& t1, genType const & t1,
const genType& v2, genType const & v2,
const genType& t2, genType const & t2,
const GLMvalType& s); typename genType::value_type const & s);
//! Return a point from a cubic curve. //! Return a point from a cubic curve.
//! From GLM_GTX_spline extension. //! From GLM_GTX_spline extension.
template <typename genType> template <typename genType>
genType cubic( genType cubic(
const genType& v1, genType const & v1,
const genType& v2, genType const & v2,
const genType& v3, genType const & v3,
const genType& v4, genType const & v4,
const GLMvalType& s); typename genType::value_type const & s);
///@} ///@}

View File

@ -12,53 +12,59 @@ namespace gtx{
namespace spline namespace spline
{ {
template <typename genType> template <typename genType>
inline genType catmullRom( inline genType catmullRom
const genType& v1, (
const genType& v2, genType const & v1,
const genType& v3, genType const & v2,
const genType& v4, genType const & v3,
const GLMvalType& s) genType const & v4,
typename genType::value_type const & s
)
{ {
GLMvalType s1 = s; typename genType::value_type s1 = s;
GLMvalType s2 = optimum_pow::pow2(s); typename genType::value_type s2 = optimum_pow::pow2(s);
GLMvalType s3 = optimum_pow::pow3(s); typename genType::value_type s3 = optimum_pow::pow3(s);
GLMvalType f1 = -s3 + GLMvalType(2) * s2 - s; typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s;
GLMvalType f2 = GLMvalType(3) * s3 - GLMvalType(5) * s2 + GLMvalType(2); typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2);
GLMvalType f3 = GLMvalType(-3) * s3 + GLMvalType(4) * s2 + s; typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s;
GLMvalType f4 = s3 - s2; typename genType::value_type f4 = s3 - s2;
return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / GLMvalType(2); return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2);
} }
template <typename genType> template <typename genType>
inline genType hermite( inline genType hermite
const genType& v1, (
const genType& t1, genType const & v1,
const genType& v2, genType const & t1,
const genType& t2, genType const & v2,
const GLMvalType& s) genType const & t2,
typename genType::value_type const & s
)
{ {
GLMvalType s1 = s; typename genType::value_type s1 = s;
GLMvalType s2 = optimum_pow::pow2(s); typename genType::value_type s2 = optimum_pow::pow2(s);
GLMvalType s3 = optimum_pow::pow3(s); typename genType::value_type s3 = optimum_pow::pow3(s);
GLMvalType f1 = GLMvalType(2) * s3 - GLMvalType(3) * s2 + GLMvalType(1); typename genType::value_type f1 = typename genType::value_type(2) * s3 - typename genType::value_type(3) * s2 + typename genType::value_type(1);
GLMvalType f2 = GLMvalType(-2) * s3 + GLMvalType(3) * s2; typename genType::value_type f2 = typename genType::value_type(-2) * s3 + typename genType::value_type(3) * s2;
GLMvalType f3 = s3 - GLMvalType(2) * s2 + s; typename genType::value_type f3 = s3 - typename genType::value_type(2) * s2 + s;
GLMvalType f4 = s3 - s2; typename genType::value_type f4 = s3 - s2;
return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2; return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2;
} }
template <typename genType> template <typename genType>
inline genType cubic( inline genType cubic
const genType& v1, (
const genType& v2, genType const & v1,
const genType& v3, genType const & v2,
const genType& v4, genType const & v3,
const GLMvalType& s) genType const & v4,
typename genType::value_type const & s
)
{ {
return ((v1 * s + v2) * s + v3) * s + v4; return ((v1 * s + v2) * s + v3) * s + v4;
} }

View File

@ -39,55 +39,55 @@ namespace glm
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool areCollinear( bool areCollinear(
const genType & v0, genType const & v0,
const genType & v1, genType const & v1,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
//! Check if two vectors are opposites. //! Check if two vectors are opposites.
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool areOpposite( bool areOpposite(
const genType & v0, genType const & v0,
const genType & v1, genType const & v1,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
//! Check if two vectors are orthogonals. //! Check if two vectors are orthogonals.
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool areOrthogonal( bool areOrthogonal(
const genType & v0, genType const & v0,
const genType & v1, genType const & v1,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
//! Check if a vector is normalized. //! Check if a vector is normalized.
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool isNormalized( bool isNormalized(
const genType & v, genType const & v,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
//! Check if a vector is null. //! Check if a vector is null.
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool isNull( bool isNull(
const genType& v, genType const & v,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
//! Check if two vectors are orthonormal. //! Check if two vectors are orthonormal.
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool areOrthonormal( bool areOrthonormal(
const genType & v0, genType const & v0,
const genType & v1, genType const & v1,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
//! Check if two vectors are similar. //! Check if two vectors are similar.
//! From GLM_GTX_vector_query extensions. //! From GLM_GTX_vector_query extensions.
template <typename genType> template <typename genType>
bool areSimilar( bool areSimilar(
const genType& v0, genType const & v0,
const genType& v1, genType const & v1,
const GLMvalType epsilon = std::numeric_limits<GLMvalType>::epsilon()); typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
///@} ///@}

View File

@ -17,77 +17,100 @@ namespace gtx{
namespace vector_query namespace vector_query
{ {
template <typename T> template <typename T>
inline bool areCollinear( inline bool areCollinear
const detail::tvec2<T>& v0, (
const detail::tvec2<T>& v1, detail::tvec2<T> const & v0,
const T epsilon) detail::tvec2<T> const & v1,
T const & epsilon
)
{ {
return length(cross(detail::tvec3<T>(v0, T(0)), detail::tvec3<T>(v1, T(0)))) < epsilon; return length(cross(detail::tvec3<T>(v0, T(0)), detail::tvec3<T>(v1, T(0)))) < epsilon;
} }
template <typename T> template <typename T>
inline bool areCollinear( inline bool areCollinear
const detail::tvec3<T>& v0, (
const detail::tvec3<T>& v1, detail::tvec3<T> const & v0,
const T epsilon) detail::tvec3<T> const & v1,
T const & epsilon
)
{ {
return length(cross(v0, v1)) < epsilon; return length(cross(v0, v1)) < epsilon;
} }
template <typename T> template <typename T>
inline bool areCollinear( inline bool areCollinear
const detail::tvec4<T>& v0, (
const detail::tvec4<T>& v1, detail::tvec4<T> const & v0,
const T epsilon) detail::tvec4<T> const & v1,
T const & epsilon
)
{ {
return length(cross(detail::tvec3<T>(v0), detail::tvec3<T>(v1))) < epsilon; return length(cross(detail::tvec3<T>(v0), detail::tvec3<T>(v1))) < epsilon;
} }
template <typename genType> template <typename genType>
inline bool areOpposite( inline bool areOpposite
const genType& v0, (
const genType& v1, genType const & v0,
const GLMvalType epsilon) genType const & v1,
typename genType::value_type const & epsilon
)
{ {
assert(isNormalized(v0) && isNormalized(v1)); assert(isNormalized(v0) && isNormalized(v1));
return((genType::value_type(1) + dot(v0, v1)) <= epsilon); return((typename genType::value_type(1) + dot(v0, v1)) <= epsilon);
} }
template <typename genType> template <typename genType>
inline bool areOrthogonal( inline bool areOrthogonal
const genType& v0, (
const genType& v1, genType const & v0,
const GLMvalType epsilon) genType const & v1,
typename genType::value_type const & epsilon
)
{ {
return abs(dot(v0, v1)) <= max(GLMvalType(1), length(v0)) * max(GLMvalType(1), length(v1)) * epsilon; return abs(dot(v0, v1)) <= max(
typename genType::value_type(1),
length(v0)) * max(
typename genType::value_type(1),
length(v1)) * epsilon;
} }
template <typename genType> template <typename genType>
inline bool isNormalized( inline bool isNormalized
const genType& v, (
const GLMvalType epsilon) genType const & v,
typename genType::value_type const & epsilon
)
{ {
return abs(length(v) - GLMvalType(1)) <= GLMvalType(2) * epsilon; return abs(length(v) - GLMvalType(1)) <= GLMvalType(2) * epsilon;
} }
template <typename genType> template <typename genType>
inline bool isNull(const genType& v, const GLMvalType epsilon) inline bool isNull
(
genType const & v,
typename genType::value_type const & epsilon
)
{ {
return length(v) <= epsilon; return length(v) <= epsilon;
} }
template <typename T> template <typename T>
inline bool isCompNull( inline bool isCompNull
const T s, (
const T epsilon) T const & s,
T const & epsilon
)
{ {
return abs(s) < epsilon; return abs(s) < epsilon;
} }
template <typename T> template <typename T>
inline detail::tvec2<bool> isCompNull( inline detail::tvec2<bool> isCompNull
const detail::tvec2<T>& v, (
const T epsilon) detail::tvec2<T> const & v,
T const & epsilon)
{ {
return detail::tvec2<bool>( return detail::tvec2<bool>(
(abs(v.x) < epsilon), (abs(v.x) < epsilon),
@ -95,9 +118,11 @@ namespace vector_query
} }
template <typename T> template <typename T>
inline detail::tvec3<bool> isCompNull( inline detail::tvec3<bool> isCompNull
const detail::tvec3<T>& v, (
const T epsilon) detail::tvec3<T> const & v,
T const & epsilon
)
{ {
return detail::tvec3<bool>( return detail::tvec3<bool>(
abs(v.x) < epsilon, abs(v.x) < epsilon,
@ -106,9 +131,11 @@ namespace vector_query
} }
template <typename T> template <typename T>
inline detail::tvec4<bool> isCompNull( inline detail::tvec4<bool> isCompNull
const detail::tvec4<T>& v, (
const T epsilon) detail::tvec4<T> const & v,
T const & epsilon
)
{ {
return detail::tvec4<bool>( return detail::tvec4<bool>(
abs(v.x) < epsilon, abs(v.x) < epsilon,
@ -118,19 +145,23 @@ namespace vector_query
} }
template <typename genType> template <typename genType>
inline bool areOrthonormal( inline bool areOrthonormal
const genType& v0, (
const genType& v1, genType const & v0,
const GLMvalType epsilon) genType const & v1,
typename genType::value_type const & epsilon
)
{ {
return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon); return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon);
} }
template <typename genType> template <typename genType>
inline bool areSimilar( inline bool areSimilar
const genType& v0, (
const genType& v1, genType const & v0,
const GLMvalType epsilon) genType const & v1,
typename genType::value_type const & epsilon
)
{ {
bool similar = true; bool similar = true;
for(typename genType::size_type i = 0; similar && i < genType::value_size(); i++) for(typename genType::size_type i = 0; similar && i < genType::value_size(); i++)