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