Refactored outerProduct code

This commit is contained in:
Christophe Riccio 2013-12-25 07:11:52 +01:00
parent c03ebcc688
commit 590c2780d9
2 changed files with 191 additions and 187 deletions

View File

@ -69,8 +69,8 @@ namespace glm
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a> /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>
/// ///
/// @todo Clarify the declaration to specify that matType doesn't have to be provided when used. /// @todo Clarify the declaration to specify that matType doesn't have to be provided when used.
template <typename vecType, typename matType> template <typename T, precision P, template <typename, precision> class vecTypeA, template <typename, precision> class vecTypeB>
GLM_FUNC_DECL matType outerProduct(vecType const & c, vecType const & r); GLM_FUNC_DECL void outerProduct(vecTypeA<T, P> const & c, vecTypeB<T, P> const & r);
/// Returns the transposed matrix of x /// Returns the transposed matrix of x
/// ///
@ -78,8 +78,8 @@ namespace glm
/// ///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/transpose.xml">GLSL transpose man page</a> /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/transpose.xml">GLSL transpose man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a> /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>
template <typename matType> template <typename T, precision P, template <typename, precision> class matType>
GLM_FUNC_DECL typename matType::transpose_type transpose(matType const & x); GLM_FUNC_DECL typename matType<T, P>::transpose_type transpose(matType<T, P> const & x);
/// Return the determinant of a squared matrix. /// Return the determinant of a squared matrix.
/// ///

View File

@ -41,18 +41,24 @@
#include "type_mat4x4.hpp" #include "type_mat4x4.hpp"
#include <limits> #include <limits>
namespace glm namespace glm{
namespace detail
{ {
// outerProduct template
template <typename T, precision P> <
GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> outerProduct template <class, precision> class vecTypeA,
( template <class, precision> class vecTypeB,
detail::tvec2<T, P> const & c, typename T, precision P
detail::tvec2<T, P> const & r >
) struct compute_outerProduct{};
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs");
template <typename T, precision P>
struct compute_outerProduct<detail::tvec2, detail::tvec2, T, P>
{
typedef detail::tmat2x2 return_type;
static return_type call(detail::tvec2<T, P> const & c, detail::tvec2<T, P> const & r)
{
detail::tmat2x2<T, P> m(detail::tmat2x2<T, P>::null); detail::tmat2x2<T, P> m(detail::tmat2x2<T, P>::null);
m[0][0] = c[0] * r[0]; m[0][0] = c[0] * r[0];
m[0][1] = c[1] * r[0]; m[0][1] = c[1] * r[0];
@ -60,46 +66,43 @@ namespace glm
m[1][1] = c[1] * r[1]; m[1][1] = c[1] * r[1];
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> outerProduct struct compute_outerProduct<detail::tvec3, detail::tvec3, T, P>
(
detail::tvec3<T, P> const & c,
detail::tvec3<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat3x3 return_type;
static return_type call(detail::tvec3<T, P> const & c, detail::tvec3<T, P> const & r)
{
detail::tmat3x3<T, P> m(detail::tmat3x3<T, P>::null); detail::tmat3x3<T, P> m(detail::tmat3x3<T, P>::null);
for(length_t i(0); i < m.length(); ++i) for(length_t i(0); i < m.length(); ++i)
m[i] = c * r[i]; m[i] = c * r[i];
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> outerProduct struct compute_outerProduct<detail::tvec4, detail::tvec4, T, P>
(
detail::tvec4<T, P> const & c,
detail::tvec4<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat4x4 return_type;
static return_type call(detail::tvec4<T, P> const & c, detail::tvec4<T, P> const & r)
{
detail::tmat4x4<T, P> m(detail::tmat4x4<T, P>::null); detail::tmat4x4<T, P> m(detail::tmat4x4<T, P>::null);
for(length_t i(0); i < m.length(); ++i) for(length_t i(0); i < m.length(); ++i)
m[i] = c * r[i]; m[i] = c * r[i];
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat2x3<T, P> outerProduct struct compute_outerProduct<detail::tvec3, detail::tvec2, T, P>
(
detail::tvec3<T, P> const & c,
detail::tvec2<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat2x3 return_type;
static return_type call(detail::tvec3<T, P> const & c, detail::tvec2<T, P> const & r)
{
detail::tmat2x3<T, P> m(detail::tmat2x3<T, P>::null); detail::tmat2x3<T, P> m(detail::tmat2x3<T, P>::null);
m[0][0] = c.x * r.x; m[0][0] = c.x * r.x;
m[0][1] = c.y * r.x; m[0][1] = c.y * r.x;
@ -109,16 +112,15 @@ namespace glm
m[1][2] = c.z * r.y; m[1][2] = c.z * r.y;
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat3x2<T, P> outerProduct struct compute_outerProduct<detail::tvec2, detail::tvec3, T, P>
(
detail::tvec2<T, P> const & c,
detail::tvec3<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat3x2 return_type;
static return_type call(detail::tvec2<T, P> const & c, detail::tvec3<T, P> const & r)
{
detail::tmat3x2<T, P> m(detail::tmat3x2<T, P>::null); detail::tmat3x2<T, P> m(detail::tmat3x2<T, P>::null);
m[0][0] = c.x * r.x; m[0][0] = c.x * r.x;
m[0][1] = c.y * r.x; m[0][1] = c.y * r.x;
@ -128,16 +130,15 @@ namespace glm
m[2][1] = c.y * r.z; m[2][1] = c.y * r.z;
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat2x4<T, P> outerProduct struct compute_outerProduct<detail::tvec4, detail::tvec2, T, P>
(
detail::tvec4<T, P> const & c,
detail::tvec2<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat2x4 return_type;
static return_type call(detail::tvec4<T, P> const & c, detail::tvec2<T, P> const & r)
{
detail::tmat2x4<T, P> m(detail::tmat2x4<T, P>::null); detail::tmat2x4<T, P> m(detail::tmat2x4<T, P>::null);
m[0][0] = c.x * r.x; m[0][0] = c.x * r.x;
m[0][1] = c.y * r.x; m[0][1] = c.y * r.x;
@ -149,16 +150,15 @@ namespace glm
m[1][3] = c.w * r.y; m[1][3] = c.w * r.y;
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat4x2<T, P> outerProduct struct compute_outerProduct<detail::tvec2, detail::tvec4, T, P>
(
detail::tvec2<T, P> const & c,
detail::tvec4<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat4x2 return_type;
static return_type call(detail::tvec2<T, P> const & c, detail::tvec4<T, P> const & r)
{
detail::tmat4x2<T, P> m(detail::tmat4x2<T, P>::null); detail::tmat4x2<T, P> m(detail::tmat4x2<T, P>::null);
m[0][0] = c.x * r.x; m[0][0] = c.x * r.x;
m[0][1] = c.y * r.x; m[0][1] = c.y * r.x;
@ -170,16 +170,15 @@ namespace glm
m[3][1] = c.y * r.w; m[3][1] = c.y * r.w;
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat3x4<T, P> outerProduct struct compute_outerProduct<detail::tvec4, detail::tvec3, T, P>
(
detail::tvec4<T, P> const & c,
detail::tvec3<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat3x4 return_type;
static return_type call(detail::tvec4<T, P> const & c, detail::tvec3<T, P> const & r)
{
detail::tmat3x4<T, P> m(detail::tmat3x4<T, P>::null); detail::tmat3x4<T, P> m(detail::tmat3x4<T, P>::null);
m[0][0] = c.x * r.x; m[0][0] = c.x * r.x;
m[0][1] = c.y * r.x; m[0][1] = c.y * r.x;
@ -195,16 +194,15 @@ namespace glm
m[2][3] = c.w * r.z; m[2][3] = c.w * r.z;
return m; return m;
} }
};
template <typename T, precision P> template <typename T, precision P>
GLM_FUNC_QUALIFIER detail::tmat4x3<T, P> outerProduct struct compute_outerProduct<detail::tvec3, detail::tvec4, T, P>
(
detail::tvec3<T, P> const & c,
detail::tvec4<T, P> const & r
)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs"); typedef detail::tmat4x3 return_type;
static return_type call(detail::tvec3<T, P> const & c, detail::tvec4<T, P> const & r)
{
detail::tmat4x3<T, P> m(detail::tmat4x3<T, P>::null); detail::tmat4x3<T, P> m(detail::tmat4x3<T, P>::null);
m[0][0] = c.x * r.x; m[0][0] = c.x * r.x;
m[0][1] = c.y * r.x; m[0][1] = c.y * r.x;
@ -220,9 +218,8 @@ namespace glm
m[3][2] = c.z * r.w; m[3][2] = c.z * r.w;
return m; return m;
} }
};
namespace detail
{
template <template <class, precision> class matType, typename T, precision P> template <template <class, precision> class matType, typename T, precision P>
struct compute_transpose{}; struct compute_transpose{};
@ -567,22 +564,29 @@ namespace detail
return result; return result;
} }
template<template <class, precision> class vecTypeA, template <class, precision> class vecTypeB, typename T, precision P>
GLM_FUNC_QUALIFIER typename detail::compute_outerProduct<vecTypeA, vecTypeB, T, P>::return_type outerProduct(vecTypeA<T, P> const & c, vecTypeB<T, P> const & r)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'outerProduct' only accept floating-point inputs");
return detail::compute_outerProduct<vecTypeA, vecTypeB, T, P>::call(c, r);
}
template <typename T, precision P, template <typename, precision> class matType> template <typename T, precision P, template <typename, precision> class matType>
GLM_FUNC_DECL typename matType::transpose_type transpose(matType<T, P> const & m) GLM_FUNC_QUALIFIER typename matType<T, P>::transpose_type transpose(matType<T, P> const & m)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'transpose' only accept floating-point inputs"); GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'transpose' only accept floating-point inputs");
return detail::compute_transpose<matType, T, P>::call(m); return detail::compute_transpose<matType, T, P>::call(m);
} }
template <typename T, precision P, template <typename, precision> class matType> template <typename T, precision P, template <typename, precision> class matType>
GLM_FUNC_DECL T determinant(matType<T, P> const & m) GLM_FUNC_QUALIFIER T determinant(matType<T, P> const & m)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'determinant' only accept floating-point inputs"); GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'determinant' only accept floating-point inputs");
return detail::compute_determinant<matType, T, P>::call(m); return detail::compute_determinant<matType, T, P>::call(m);
} }
template <typename T, precision P, template <typename, precision> class matType> template <typename T, precision P, template <typename, precision> class matType>
GLM_FUNC_DECL matType<T, P> inverse(matType<T, P> const & m) GLM_FUNC_QUALIFIER matType<T, P> inverse(matType<T, P> const & m)
{ {
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'inverse' only accept floating-point inputs"); GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'inverse' only accept floating-point inputs");
return detail::compute_inverse<matType, T, P>::call(m); return detail::compute_inverse<matType, T, P>::call(m);