Skip to content

Commit

Permalink
Merge pull request g-truc#1116 from Thibaulltt/master
Browse files Browse the repository at this point in the history
GLM_EXT_matrix_common : add glm::mat<> support to glm::abs() g-truc#1116
  • Loading branch information
christophe-lunarg authored Oct 24, 2022
2 parents af97257 + 48e1ff3 commit 7b9d310
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 1 deletion.
128 changes: 128 additions & 0 deletions glm/ext/_matrix_vectorize.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#pragma once

namespace glm {

namespace detail {

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, length_t C, length_t R, typename Ret, typename T, qualifier Q>
struct matrix_functor_1 {
};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 2, 2, Ret, T, Q> {
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 2, T, Q> call(Ret (*Func)(T x), mat<2, 2, T, Q> const &x) {
return mat<2, 2, Ret, Q>(
Func(x[0][0]), Func(x[0][1]),
Func(x[1][0]), Func(x[1][1])
);
}
};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 2, 3, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 3, T, Q> call(Ret (*Func)(T x), mat<2, 3, T, Q> const &x) {
return mat<2, 3, Ret, Q>(
Func(x[0][0]), Func(x[0][1]),
Func(x[1][0]), Func(x[1][1]),
Func(x[2][0]), Func(x[2][1])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 2, 4, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 4, T, Q> call(Ret (*Func)(T x), mat<2, 4, T, Q> const &x) {
return mat<2, 4, Ret, Q>(
Func(x[0][0]), Func(x[0][1]),
Func(x[1][0]), Func(x[1][1]),
Func(x[2][0]), Func(x[2][1]),
Func(x[3][0]), Func(x[3][1])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 3, 2, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 2, T, Q> call(Ret (*Func)(T x), mat<3, 2, T, Q> const &x) {
return mat<3, 2, Ret, Q>(
Func(x[0][0]), Func(x[0][1]), Func(x[0][2]),
Func(x[1][0]), Func(x[1][1]), Func(x[1][2])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 3, 3, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 3, T, Q> call(Ret (*Func)(T x), mat<3, 3, T, Q> const &x) {
return mat<3, 3, Ret, Q>(
Func(x[0][0]), Func(x[0][1]), Func(x[0][2]),
Func(x[1][0]), Func(x[1][1]), Func(x[1][2]),
Func(x[2][0]), Func(x[2][1]), Func(x[2][2])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 3, 4, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 4, T, Q> call(Ret (*Func)(T x), mat<3, 4, T, Q> const &x) {
return mat<3, 4, Ret, Q>(
Func(x[0][0]), Func(x[0][1]), Func(x[0][2]),
Func(x[1][0]), Func(x[1][1]), Func(x[1][2]),
Func(x[2][0]), Func(x[2][1]), Func(x[2][2]),
Func(x[3][0]), Func(x[3][1]), Func(x[3][2])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 4, 2, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 2, T, Q> call(Ret (*Func)(T x), mat<4, 2, T, Q> const &x) {
return mat<4, 2, Ret, Q>(
Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]),
Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 4, 3, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 3, T, Q> call(Ret (*Func)(T x), mat<4, 3, T, Q> const &x) {
return mat<4, 3, Ret, Q>(
Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]),
Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]),
Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), Func(x[2][3])
);
}

};

template<template<length_t C, length_t R, typename T, qualifier Q> class mat, typename Ret, typename T, qualifier Q>
struct matrix_functor_1<mat, 4, 4, Ret, T, Q> {

GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(Ret (*Func)(T x), mat<4, 4, T, Q> const &x) {
return mat<4, 4, Ret, Q>(
Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]),
Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]),
Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), Func(x[2][3]),
Func(x[3][0]), Func(x[3][1]), Func(x[3][2]), Func(x[3][3])
);
}

};

}

}// namespace glm
5 changes: 4 additions & 1 deletion glm/ext/matrix_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "../detail/_fixes.hpp"

#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_transform extension included")
# pragma message("GLM: GLM_EXT_matrix_common extension included")
#endif

namespace glm
Expand All @@ -30,6 +30,9 @@ namespace glm
template<length_t C, length_t R, typename T, typename U, qualifier Q>
GLM_FUNC_DECL mat<C, R, T, Q> mix(mat<C, R, T, Q> const& x, mat<C, R, T, Q> const& y, U a);

template <length_t C, length_t R, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR mat<C, R, T, Q> abs(mat<C, R, T, Q> const& x);

/// @}
}//namespace glm

Expand Down
18 changes: 18 additions & 0 deletions glm/ext/matrix_common.inl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "../matrix.hpp"

#include "_matrix_vectorize.hpp"

namespace glm
{
template<length_t C, length_t R, typename T, typename U, qualifier Q>
Expand All @@ -13,4 +15,20 @@ namespace glm
{
return matrixCompMult(mat<C, R, U, Q>(x), static_cast<U>(1) - a) + matrixCompMult(mat<C, R, U, Q>(y), a);
}

template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
struct compute_abs_matrix
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<C, R, T, Q> call(mat<C, R, T, Q> const& x)
{
return detail::matrix_functor_1<mat, C, R, T, T, Q>::call(abs, x);
}
};

template<length_t C, length_t R, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR mat<C, R, T, Q> abs(mat<C, R, T, Q> const& x)
{
return compute_abs_matrix<C, R, T, Q, detail::is_aligned<Q>::value>::call(x);
}

}//namespace glm
30 changes: 30 additions & 0 deletions test/ext/ext_matrix_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,41 @@ static int test_mix()
return Error;
}

static int test_abs()
{
int Error = 0;

{
glm::mat4 A(
3.0f, 1.0f, 5.2f, 4.9f,
1.4f, 0.5f, 9.3f, 3.7f,
6.8f, 8.4f, 4.3f, 3.9f,
5.6f, 7.2f, 1.1f, 4.4f
);
glm::mat4 B(
1.0,-1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,-1.0,
1.0,-1.0,-1.0,-1.0,
-1.0,-1.0, 1.0, 1.0
);
glm::mat4 C = glm::matrixCompMult(A, B); // Not * to avoid matrix product.
glm::mat4 D = glm::abs(C);
glm::bvec4 const row1 = glm::equal(D[0], A[0]);
glm::bvec4 const row2 = glm::equal(D[1], A[1]);
glm::bvec4 const row3 = glm::equal(D[2], A[2]);
glm::bvec4 const row4 = glm::equal(D[3], A[3]);
Error += glm::all(glm::bvec4{glm::all(row1), glm::all(row2), glm::all(row3), glm::all(row4)}) ? 0 : 1;

return Error;
}
}

int main()
{
int Error = 0;

Error += test_mix();
Error += test_abs();

return Error;
}

0 comments on commit 7b9d310

Please sign in to comment.