diff --git a/glm/detail/func_matrix.hpp b/glm/detail/func_matrix.hpp
index e4adc5ba..f75d17bd 100644
--- a/glm/detail/func_matrix.hpp
+++ b/glm/detail/func_matrix.hpp
@@ -69,8 +69,8 @@ namespace glm
/// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions
///
/// @todo Clarify the declaration to specify that matType doesn't have to be provided when used.
- template
- GLM_FUNC_DECL matType outerProduct(vecType const & c, vecType const & r);
+ template class vecTypeA, template class vecTypeB>
+ GLM_FUNC_DECL void outerProduct(vecTypeA const & c, vecTypeB const & r);
/// Returns the transposed matrix of x
///
@@ -78,8 +78,8 @@ namespace glm
///
/// @see GLSL transpose man page
/// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions
- template
- GLM_FUNC_DECL typename matType::transpose_type transpose(matType const & x);
+ template class matType>
+ GLM_FUNC_DECL typename matType::transpose_type transpose(matType const & x);
/// Return the determinant of a squared matrix.
///
diff --git a/glm/detail/func_matrix.inl b/glm/detail/func_matrix.inl
index a3e668bd..16ed8bbc 100644
--- a/glm/detail/func_matrix.inl
+++ b/glm/detail/func_matrix.inl
@@ -41,188 +41,185 @@
#include "type_mat4x4.hpp"
#include
-namespace glm
-{
- // outerProduct
- template
- GLM_FUNC_QUALIFIER detail::tmat2x2 outerProduct
- (
- detail::tvec2 const & c,
- detail::tvec2 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat2x2 m(detail::tmat2x2::null);
- m[0][0] = c[0] * r[0];
- m[0][1] = c[1] * r[0];
- m[1][0] = c[0] * r[1];
- m[1][1] = c[1] * r[1];
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat3x3 outerProduct
- (
- detail::tvec3 const & c,
- detail::tvec3 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat3x3 m(detail::tmat3x3::null);
- for(length_t i(0); i < m.length(); ++i)
- m[i] = c * r[i];
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat4x4 outerProduct
- (
- detail::tvec4 const & c,
- detail::tvec4 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat4x4 m(detail::tmat4x4::null);
- for(length_t i(0); i < m.length(); ++i)
- m[i] = c * r[i];
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat2x3 outerProduct
- (
- detail::tvec3 const & c,
- detail::tvec2 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat2x3 m(detail::tmat2x3::null);
- m[0][0] = c.x * r.x;
- m[0][1] = c.y * r.x;
- m[0][2] = c.z * r.x;
- m[1][0] = c.x * r.y;
- m[1][1] = c.y * r.y;
- m[1][2] = c.z * r.y;
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat3x2 outerProduct
- (
- detail::tvec2 const & c,
- detail::tvec3 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat3x2 m(detail::tmat3x2::null);
- m[0][0] = c.x * r.x;
- m[0][1] = c.y * r.x;
- m[1][0] = c.x * r.y;
- m[1][1] = c.y * r.y;
- m[2][0] = c.x * r.z;
- m[2][1] = c.y * r.z;
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat2x4 outerProduct
- (
- detail::tvec4 const & c,
- detail::tvec2 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat2x4 m(detail::tmat2x4::null);
- m[0][0] = c.x * r.x;
- m[0][1] = c.y * r.x;
- m[0][2] = c.z * r.x;
- m[0][3] = c.w * r.x;
- m[1][0] = c.x * r.y;
- m[1][1] = c.y * r.y;
- m[1][2] = c.z * r.y;
- m[1][3] = c.w * r.y;
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat4x2 outerProduct
- (
- detail::tvec2 const & c,
- detail::tvec4 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat4x2 m(detail::tmat4x2::null);
- m[0][0] = c.x * r.x;
- m[0][1] = c.y * r.x;
- m[1][0] = c.x * r.y;
- m[1][1] = c.y * r.y;
- m[2][0] = c.x * r.z;
- m[2][1] = c.y * r.z;
- m[3][0] = c.x * r.w;
- m[3][1] = c.y * r.w;
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat3x4 outerProduct
- (
- detail::tvec4 const & c,
- detail::tvec3 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat3x4 m(detail::tmat3x4::null);
- m[0][0] = c.x * r.x;
- m[0][1] = c.y * r.x;
- m[0][2] = c.z * r.x;
- m[0][3] = c.w * r.x;
- m[1][0] = c.x * r.y;
- m[1][1] = c.y * r.y;
- m[1][2] = c.z * r.y;
- m[1][3] = c.w * r.y;
- m[2][0] = c.x * r.z;
- m[2][1] = c.y * r.z;
- m[2][2] = c.z * r.z;
- m[2][3] = c.w * r.z;
- return m;
- }
-
- template
- GLM_FUNC_QUALIFIER detail::tmat4x3 outerProduct
- (
- detail::tvec3 const & c,
- detail::tvec4 const & r
- )
- {
- GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
-
- detail::tmat4x3 m(detail::tmat4x3::null);
- m[0][0] = c.x * r.x;
- m[0][1] = c.y * r.x;
- m[0][2] = c.z * r.x;
- m[1][0] = c.x * r.y;
- m[1][1] = c.y * r.y;
- m[1][2] = c.z * r.y;
- m[2][0] = c.x * r.z;
- m[2][1] = c.y * r.z;
- m[2][2] = c.z * r.z;
- m[3][0] = c.x * r.w;
- m[3][1] = c.y * r.w;
- m[3][2] = c.z * r.w;
- return m;
- }
-
+namespace glm{
namespace detail
{
+ template
+ <
+ template class vecTypeA,
+ template class vecTypeB,
+ typename T, precision P
+ >
+ struct compute_outerProduct{};
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat2x2 return_type;
+
+ static return_type call(detail::tvec2 const & c, detail::tvec2 const & r)
+ {
+ detail::tmat2x2 m(detail::tmat2x2::null);
+ m[0][0] = c[0] * r[0];
+ m[0][1] = c[1] * r[0];
+ m[1][0] = c[0] * r[1];
+ m[1][1] = c[1] * r[1];
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat3x3 return_type;
+
+ static return_type call(detail::tvec3 const & c, detail::tvec3 const & r)
+ {
+ detail::tmat3x3 m(detail::tmat3x3::null);
+ for(length_t i(0); i < m.length(); ++i)
+ m[i] = c * r[i];
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat4x4 return_type;
+
+ static return_type call(detail::tvec4 const & c, detail::tvec4 const & r)
+ {
+ detail::tmat4x4 m(detail::tmat4x4::null);
+ for(length_t i(0); i < m.length(); ++i)
+ m[i] = c * r[i];
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat2x3 return_type;
+
+ static return_type call(detail::tvec3 const & c, detail::tvec2 const & r)
+ {
+ detail::tmat2x3 m(detail::tmat2x3::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat3x2 return_type;
+
+ static return_type call(detail::tvec2 const & c, detail::tvec3 const & r)
+ {
+ detail::tmat3x2 m(detail::tmat3x2::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat2x4 return_type;
+
+ static return_type call(detail::tvec4 const & c, detail::tvec2 const & r)
+ {
+ detail::tmat2x4 m(detail::tmat2x4::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[0][3] = c.w * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ m[1][3] = c.w * r.y;
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat4x2 return_type;
+
+ static return_type call(detail::tvec2 const & c, detail::tvec4 const & r)
+ {
+ detail::tmat4x2 m(detail::tmat4x2::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ m[3][0] = c.x * r.w;
+ m[3][1] = c.y * r.w;
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat3x4 return_type;
+
+ static return_type call(detail::tvec4 const & c, detail::tvec3 const & r)
+ {
+ detail::tmat3x4 m(detail::tmat3x4::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[0][3] = c.w * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ m[1][3] = c.w * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ m[2][2] = c.z * r.z;
+ m[2][3] = c.w * r.z;
+ return m;
+ }
+ };
+
+ template
+ struct compute_outerProduct
+ {
+ typedef detail::tmat4x3 return_type;
+
+ static return_type call(detail::tvec3 const & c, detail::tvec4 const & r)
+ {
+ detail::tmat4x3 m(detail::tmat4x3::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ m[2][2] = c.z * r.z;
+ m[3][0] = c.x * r.w;
+ m[3][1] = c.y * r.w;
+ m[3][2] = c.z * r.w;
+ return m;
+ }
+ };
+
template class matType, typename T, precision P>
struct compute_transpose{};
@@ -567,22 +564,29 @@ namespace detail
return result;
}
+ template class vecTypeA, template class vecTypeB, typename T, precision P>
+ GLM_FUNC_QUALIFIER typename detail::compute_outerProduct::return_type outerProduct(vecTypeA const & c, vecTypeB const & r)
+ {
+ GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'outerProduct' only accept floating-point inputs");
+ return detail::compute_outerProduct::call(c, r);
+ }
+
template class matType>
- GLM_FUNC_DECL typename matType::transpose_type transpose(matType const & m)
+ GLM_FUNC_QUALIFIER typename matType::transpose_type transpose(matType const & m)
{
GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'transpose' only accept floating-point inputs");
return detail::compute_transpose::call(m);
}
template class matType>
- GLM_FUNC_DECL T determinant(matType const & m)
+ GLM_FUNC_QUALIFIER T determinant(matType const & m)
{
GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'determinant' only accept floating-point inputs");
return detail::compute_determinant::call(m);
}
template class matType>
- GLM_FUNC_DECL matType inverse(matType const & m)
+ GLM_FUNC_QUALIFIER matType inverse(matType const & m)
{
GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'inverse' only accept floating-point inputs");
return detail::compute_inverse::call(m);