Fixed vector and matrix queries

This commit is contained in:
Christophe Riccio 2014-01-04 14:57:59 +01:00
parent 06ac77dad4
commit 6f096fbb31
7 changed files with 226 additions and 214 deletions

View File

@ -92,14 +92,26 @@
# pragma message("GLM: Core library included")
#endif//GLM_MESSAGE
#include "./detail/func_trigonometric.hpp"
#include "./detail/func_exponential.hpp"
#include "./detail/func_common.hpp"
#include "./detail/func_packing.hpp"
#include "./detail/func_geometric.hpp"
#include "./detail/func_matrix.hpp"
#include "./detail/func_vector_relational.hpp"
#include "./detail/func_integer.hpp"
#include "./detail/func_noise.hpp"
#include "vec2.hpp"
#include "vec3.hpp"
#include "vec4.hpp"
#include "mat2x2.hpp"
#include "mat2x3.hpp"
#include "mat2x4.hpp"
#include "mat3x2.hpp"
#include "mat3x3.hpp"
#include "mat3x4.hpp"
#include "mat4x2.hpp"
#include "mat4x3.hpp"
#include "mat4x4.hpp"
#include "trigonometric.hpp"
#include "exponential.hpp"
#include "common.hpp"
#include "packing.hpp"
#include "geometric.hpp"
#include "matrix.hpp"
#include "vector_relational.hpp"
#include "integer.hpp"
#endif//GLM_INCLUDED

View File

@ -384,14 +384,14 @@ namespace glm
detail::tvec4<U, P> const & viewport
)
{
detail::tmat4x4<T, P> inverse = glm::inverse(proj * model);
detail::tmat4x4<T, P> Inverse = inverse(proj * model);
detail::tvec4<T, P> tmp = detail::tvec4<T, P>(win, T(1));
tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
tmp = tmp * T(2) - T(1);
detail::tvec4<T, P> obj = inverse * tmp;
detail::tvec4<T, P> obj = Inverse * tmp;
obj /= obj.w;
return detail::tvec3<T, P>(obj);

View File

@ -56,58 +56,42 @@ namespace glm
/// Return whether a matrix a null matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P>
bool isNull(
detail::tmat2x2<T, P> const & m,
T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
bool isNull(detail::tmat2x2<T, P> const & m, T const & epsilon);
/// Return whether a matrix a null matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P>
bool isNull(
detail::tmat3x3<T, P> const & m,
T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
bool isNull(detail::tmat3x3<T, P> const & m, T const & epsilon);
/// Return whether a matrix is a null matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P>
bool isNull(
detail::tmat4x4<T, P> const & m,
T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
bool isNull(detail::tmat4x4<T, P> const & m, T const & epsilon);
/// Return whether a matrix is an identity matrix.
/// From GLM_GTX_matrix_query extension.
template<typename genType>
bool isIdentity(
genType const & m,
typename genType::value_type const & epsilon/* = std::numeric_limits<typename genType::value_type>::epsilon()*/);
template<typename T, precision P, template <typename, precision> class matType>
bool isIdentity(matType<T, P> const & m, T const & epsilon);
/// Return whether a matrix is a normalized matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P>
bool isNormalized(
detail::tmat2x2<T, P> const & m,
T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
bool isNormalized(detail::tmat2x2<T, P> const & m, T const & epsilon);
/// Return whether a matrix is a normalized matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P>
bool isNormalized(
detail::tmat3x3<T, P> const & m,
T const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
bool isNormalized(detail::tmat3x3<T, P> const & m, T const & epsilon);
/// Return whether a matrix is a normalized matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P>
bool isNormalized(
detail::tmat4x4<T, P> const & m,
T const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
bool isNormalized(detail::tmat4x4<T, P> const & m, T const & epsilon);
/// Return whether a matrix is an orthonormalized matrix.
/// From GLM_GTX_matrix_query extension.
template<typename T, precision P, template <typename, precision> class matType>
bool isOrthogonal(
matType<T, P> const & m,
T const & epsilon/* = std::numeric_limits<genType>::epsilon()*/);
bool isOrthogonal(matType<T, P> const & m, T const & epsilon);
/// @}
}//namespace glm

View File

@ -54,55 +54,33 @@ namespace glm
//! Check whether two vectors are collinears.
/// @see gtx_vector_query extensions.
template <typename genType>
bool areCollinear(
genType const & v0,
genType const & v1,
typename genType::value_type const & epsilon);
template <typename T, precision P, template <typename, precision> class vecType>
bool areCollinear(vecType<T, P> const & v0, vecType<T, P> const & v1, T const & epsilon);
//! Check whether two vectors are orthogonals.
/// @see gtx_vector_query extensions.
template <typename genType>
bool areOrthogonal(
genType const & v0,
genType const & v1,
typename genType::value_type const & epsilon);
template <typename T, precision P, template <typename, precision> class vecType>
bool areOrthogonal(vecType<T, P> const & v0, vecType<T, P> const & v1, T const & epsilon);
//! Check whether a vector is normalized.
/// @see gtx_vector_query extensions.
template <typename genType, precision P, template <typename, precision> class vecType>
bool isNormalized(
vecType<genType, P> const & v,
genType const & epsilon);
template <typename T, precision P, template <typename, precision> class vecType>
bool isNormalized(vecType<T, P> const & v, T const & epsilon);
//! Check whether a vector is null.
/// @see gtx_vector_query extensions.
template <typename T, precision P>
bool isNull(
detail::tvec2<T, P> const & v,
T const & epsilon);
template <typename T, precision P, template <typename, precision> class vecType>
bool isNull(vecType<T, P> const & v, T const & epsilon);
//! Check whether a vector is null.
//! Check whether a each component of a vector is null.
/// @see gtx_vector_query extensions.
template <typename T, precision P>
bool isNull(
detail::tvec3<T, P> const & v,
T const & epsilon);
//! Check whether a vector is null.
/// @see gtx_vector_query extensions.
template <typename T, precision P>
bool isNull(
detail::tvec4<T, P> const & v,
T const & epsilon);
template <typename T, precision P, template <typename, precision> class vecType>
vecType<bool, P> isCompNull(vecType<T, P> const & v, T const & epsilon);
//! Check whether two vectors are orthonormal.
/// @see gtx_vector_query extensions.
template <typename genType>
bool areOrthonormal(
genType const & v0,
genType const & v1,
typename genType::value_type const & epsilon);
template <typename T, precision P, template <typename, precision> class vecType>
bool areOrthonormal(vecType<T, P> const & v0, vecType<T, P> const & v1, T const & epsilon);
/// @}
}// namespace glm

View File

@ -12,39 +12,91 @@
#include <cassert>
namespace glm
namespace glm{
namespace detail
{
template <typename T, precision P>
GLM_FUNC_QUALIFIER bool areCollinear
(
detail::tvec2<T, P> const & v0,
detail::tvec2<T, P> const & v1,
T const & epsilon
)
{
return length(cross(detail::tvec3<T, P>(v0, T(0)), detail::tvec3<T, P>(v1, T(0)))) < epsilon;
}
template <typename T, precision P, template <typename, precision> class vecType>
struct compute_areCollinear{};
template <typename T, precision P>
GLM_FUNC_QUALIFIER bool areCollinear
(
detail::tvec3<T, P> const & v0,
detail::tvec3<T, P> const & v1,
T const & epsilon
)
struct compute_areCollinear<T, P, tvec2>
{
return length(cross(v0, v1)) < epsilon;
}
static bool call(detail::tvec2<T, P> const & v0, detail::tvec2<T, P> const & v1, T const & epsilon)
{
return length(cross(detail::tvec3<T, P>(v0, static_cast<T>(0)), detail::tvec3<T, P>(v1, static_cast<T>(0)))) < epsilon;
}
};
template <typename T, precision P>
struct compute_areCollinear<T, P, tvec3>
{
static bool call(detail::tvec3<T, P> const & v0, detail::tvec3<T, P> const & v1, T const & epsilon)
{
return length(cross(v0, v1)) < epsilon;
}
};
template <typename T, precision P>
struct compute_areCollinear<T, P, tvec4>
{
static bool call(detail::tvec4<T, P> const & v0, detail::tvec4<T, P> const & v1, T const & epsilon)
{
return length(cross(detail::tvec3<T, P>(v0), detail::tvec3<T, P>(v1))) < epsilon;
}
};
template <typename T, precision P, template <typename, precision> class vecType>
struct compute_isCompNull{};
template <typename T, precision P>
struct compute_isCompNull<T, P, tvec2>
{
static detail::tvec2<bool, P> call(detail::tvec2<T, P> const & v, T const & epsilon)
{
return detail::tvec2<bool, P>(
(abs(v.x) < epsilon),
(abs(v.y) < epsilon));
}
};
template <typename T, precision P>
struct compute_isCompNull<T, P, tvec3>
{
static detail::tvec3<bool, P> call(detail::tvec3<T, P> const & v, T const & epsilon)
{
return detail::tvec3<bool, P>(
(abs(v.x) < epsilon),
(abs(v.y) < epsilon),
(abs(v.z) < epsilon));
}
};
template <typename T, precision P>
struct compute_isCompNull<T, P, tvec4>
{
static detail::tvec4<bool, P> call(detail::tvec4<T, P> const & v, T const & epsilon)
{
return detail::tvec4<bool, P>(
(abs(v.x) < epsilon),
(abs(v.y) < epsilon),
(abs(v.z) < epsilon),
(abs(v.w) < epsilon));
}
};
}//namespace detail
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER bool areCollinear
(
detail::tvec4<T, P> const & v0,
detail::tvec4<T, P> const & v1,
vecType<T, P> const & v0,
vecType<T, P> const & v1,
T const & epsilon
)
{
return length(cross(detail::tvec3<T, P>(v0), detail::tvec3<T, P>(v1))) < epsilon;
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'areCollinear' only accept floating-point inputs");
return detail::compute_areCollinear<T, P, vecType>::call(v0, v1, epsilon);
}
template <typename T, precision P, template <typename, precision> class vecType>
@ -55,11 +107,11 @@ namespace glm
T const & epsilon
)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'areOrthogonal' only accept floating-point inputs");
return abs(dot(v0, v1)) <= max(
T(1),
length(v0)) * max(
T(1),
length(v1)) * epsilon;
static_cast<T>(1),
length(v0)) * max(static_cast<T>(1), length(v1)) * epsilon;
}
template <typename T, precision P, template <typename, precision> class vecType>
@ -69,47 +121,33 @@ namespace glm
T const & epsilon
)
{
return abs(length(v) - T(1)) <= T(2) * epsilon;
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isNormalized' only accept floating-point inputs");
return abs(length(v) - static_cast<T>(1)) <= static_cast<T>(2) * epsilon;
}
template <typename T, precision P>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER bool isNull
(
detail::tvec2<T, P> const & v,
vecType<T, P> const & v,
T const & epsilon
)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isNull' only accept floating-point inputs");
return length(v) <= epsilon;
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER bool isNull
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<bool, P> isCompNull
(
detail::tvec3<T, P> const & v,
vecType<T, P> const & v,
T const & epsilon
)
{
return length(v) <= epsilon;
}
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isCompNull' only accept floating-point inputs");
template <typename T, precision P>
GLM_FUNC_QUALIFIER bool isNull
(
detail::tvec4<T, P> const & v,
T const & epsilon
)
{
return length(v) <= epsilon;
}
template <typename T>
GLM_FUNC_QUALIFIER bool isCompNull
(
T const & s,
T const & epsilon
)
{
return abs(s) < epsilon;
return detail::compute_isCompNull<T, P, vecType>::call(v, epsilon);
}
template <typename T, precision P>
@ -118,9 +156,7 @@ namespace glm
detail::tvec2<T, P> const & v,
T const & epsilon)
{
return detail::tvec2<bool, P>(
(abs(v.x) < epsilon),
(abs(v.y) < epsilon));
}
template <typename T, precision P>

View File

@ -9,62 +9,64 @@
#include <glm/matrix.hpp>
using namespace glm;
int test_matrixCompMult()
{
int Error(0);
{
glm::mat2 m(0, 1, 2, 3);
glm::mat2 n = glm::matrixCompMult(m, m);
Error += n == glm::mat2(0, 1, 4, 9) ? 0 : 1;
mat2 m(0, 1, 2, 3);
mat2 n = matrixCompMult(m, m);
Error += n == mat2(0, 1, 4, 9) ? 0 : 1;
}
{
glm::mat2x3 m(0, 1, 2, 3, 4, 5);
glm::mat2x3 n = glm::matrixCompMult(m, m);
Error += n == glm::mat2x3(0, 1, 4, 9, 16, 25) ? 0 : 1;
mat2x3 m(0, 1, 2, 3, 4, 5);
mat2x3 n = matrixCompMult(m, m);
Error += n == mat2x3(0, 1, 4, 9, 16, 25) ? 0 : 1;
}
{
glm::mat2x4 m(0, 1, 2, 3, 4, 5, 6, 7);
glm::mat2x4 n = glm::matrixCompMult(m, m);
Error += n == glm::mat2x4(0, 1, 4, 9, 16, 25, 36, 49) ? 0 : 1;
mat2x4 m(0, 1, 2, 3, 4, 5, 6, 7);
mat2x4 n = matrixCompMult(m, m);
Error += n == mat2x4(0, 1, 4, 9, 16, 25, 36, 49) ? 0 : 1;
}
{
glm::mat3 m(0, 1, 2, 3, 4, 5, 6, 7, 8);
glm::mat3 n = glm::matrixCompMult(m, m);
Error += n == glm::mat3(0, 1, 4, 9, 16, 25, 36, 49, 64) ? 0 : 1;
mat3 m(0, 1, 2, 3, 4, 5, 6, 7, 8);
mat3 n = matrixCompMult(m, m);
Error += n == mat3(0, 1, 4, 9, 16, 25, 36, 49, 64) ? 0 : 1;
}
{
glm::mat3x2 m(0, 1, 2, 3, 4, 5);
glm::mat3x2 n = glm::matrixCompMult(m, m);
Error += n == glm::mat3x2(0, 1, 4, 9, 16, 25) ? 0 : 1;
mat3x2 m(0, 1, 2, 3, 4, 5);
mat3x2 n = matrixCompMult(m, m);
Error += n == mat3x2(0, 1, 4, 9, 16, 25) ? 0 : 1;
}
{
glm::mat3x4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
glm::mat3x4 n = glm::matrixCompMult(m, m);
Error += n == glm::mat3x4(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121) ? 0 : 1;
mat3x4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
mat3x4 n = matrixCompMult(m, m);
Error += n == mat3x4(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121) ? 0 : 1;
}
{
glm::mat4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
glm::mat4 n = glm::matrixCompMult(m, m);
Error += n == glm::mat4(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225) ? 0 : 1;
mat4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
mat4 n = matrixCompMult(m, m);
Error += n == mat4(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225) ? 0 : 1;
}
{
glm::mat4x2 m(0, 1, 2, 3, 4, 5, 6, 7);
glm::mat4x2 n = glm::matrixCompMult(m, m);
Error += n == glm::mat4x2(0, 1, 4, 9, 16, 25, 36, 49) ? 0 : 1;
mat4x2 m(0, 1, 2, 3, 4, 5, 6, 7);
mat4x2 n = matrixCompMult(m, m);
Error += n == mat4x2(0, 1, 4, 9, 16, 25, 36, 49) ? 0 : 1;
}
{
glm::mat4x3 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
glm::mat4x3 n = glm::matrixCompMult(m, m);
Error += n == glm::mat4x3(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121) ? 0 : 1;
mat4x3 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
mat4x3 n = matrixCompMult(m, m);
Error += n == mat4x3(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121) ? 0 : 1;
}
return Error;
@ -79,62 +81,62 @@ int test_outerProduct()
int test_transpose()
{
int Error(0);
{
glm::mat2 m(0, 1, 2, 3);
glm::mat2 t = glm::transpose(m);
Error += t == glm::mat2(0, 2, 1, 3) ? 0 : 1;
}
int Error(0);
{
glm::mat2x3 m(0, 1, 2, 3, 4, 5);
glm::mat3x2 t = glm::transpose(m);
Error += t == glm::mat3x2(0, 3, 1, 4, 2, 5) ? 0 : 1;
}
{
mat2 m(0, 1, 2, 3);
mat2 t = transpose(m);
Error += t == mat2(0, 2, 1, 3) ? 0 : 1;
}
{
mat2x3 m(0, 1, 2, 3, 4, 5);
mat3x2 t = transpose(m);
Error += t == mat3x2(0, 3, 1, 4, 2, 5) ? 0 : 1;
}
{
mat2x4 m(0, 1, 2, 3, 4, 5, 6, 7);
mat4x2 t = transpose(m);
Error += t == mat4x2(0, 4, 1, 5, 2, 6, 3, 7) ? 0 : 1;
}
{
mat3 m(0, 1, 2, 3, 4, 5, 6, 7, 8);
mat3 t = transpose(m);
Error += t == mat3(0, 3, 6, 1, 4, 7, 2, 5, 8) ? 0 : 1;
}
{
mat3x2 m(0, 1, 2, 3, 4, 5);
mat2x3 t = transpose(m);
Error += t == mat2x3(0, 2, 4, 1, 3, 5) ? 0 : 1;
}
{
mat3x4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
mat4x3 t = transpose(m);
Error += t == mat4x3(0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11) ? 0 : 1;
}
{
mat4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
mat4 t = transpose(m);
Error += t == mat4(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15) ? 0 : 1;
}
{
mat4x2 m(0, 1, 2, 3, 4, 5, 6, 7);
mat2x4 t = transpose(m);
Error += t == mat2x4(0, 2, 4, 6, 1, 3, 5, 7) ? 0 : 1;
}
{
mat4x3 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
mat3x4 t = transpose(m);
Error += t == mat3x4(0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11) ? 0 : 1;
}
{
glm::mat2x4 m(0, 1, 2, 3, 4, 5, 6, 7);
glm::mat4x2 t = glm::transpose(m);
Error += t == glm::mat4x2(0, 4, 1, 5, 2, 6, 3, 7) ? 0 : 1;
}
{
glm::mat3 m(0, 1, 2, 3, 4, 5, 6, 7, 8);
glm::mat3 t = glm::transpose(m);
Error += t == glm::mat3(0, 3, 6, 1, 4, 7, 2, 5, 8) ? 0 : 1;
}
{
glm::mat3x2 m(0, 1, 2, 3, 4, 5);
glm::mat2x3 t = glm::transpose(m);
Error += t == glm::mat2x3(0, 2, 4, 1, 3, 5) ? 0 : 1;
}
{
glm::mat3x4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
glm::mat4x3 t = glm::transpose(m);
Error += t == glm::mat4x3(0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11) ? 0 : 1;
}
{
glm::mat4 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
glm::mat4 t = glm::transpose(m);
Error += t == glm::mat4(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15) ? 0 : 1;
}
{
glm::mat4x2 m(0, 1, 2, 3, 4, 5, 6, 7);
glm::mat2x4 t = glm::transpose(m);
Error += t == glm::mat2x4(0, 2, 4, 6, 1, 3, 5, 7) ? 0 : 1;
}
{
glm::mat4x3 m(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
glm::mat3x4 t = glm::transpose(m);
Error += t == glm::mat3x4(0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11) ? 0 : 1;
}
return Error;
}
@ -154,7 +156,7 @@ int test_inverse()
glm::vec4(0, 1, 0, 0),
glm::vec4(0, 0, 1, 0),
glm::vec4(0, 0, 0, 1));
glm::mat4x4 B4x4 = glm::inverse(A4x4);
glm::mat4x4 B4x4 = inverse(A4x4);
glm::mat4x4 I4x4 = A4x4 * B4x4;
Failed += I4x4 == glm::mat4x4(1) ? 0 : 1;

View File

@ -184,12 +184,12 @@ int test_Snorm3x10_1x2()
int Error = 0;
std::vector<glm::vec4> Tests;
Tests.push_back(glm::vec4(1.0));
Tests.push_back(glm::vec4(0.0));
Tests.push_back(glm::vec4(2.0));
Tests.push_back(glm::vec4(0.1));
Tests.push_back(glm::vec4(0.5));
Tests.push_back(glm::vec4(0.9));
Tests.push_back(glm::vec4(1.0f));
Tests.push_back(glm::vec4(0.0f));
Tests.push_back(glm::vec4(2.0f));
Tests.push_back(glm::vec4(0.1f));
Tests.push_back(glm::vec4(0.5f));
Tests.push_back(glm::vec4(0.9f));
for(std::size_t i = 0; i < Tests.size(); ++i)
{