diff --git a/glm/core/intrinsic_matrix.inl b/glm/core/intrinsic_matrix.inl index 6f0fdb7f..3891b80d 100644 --- a/glm/core/intrinsic_matrix.inl +++ b/glm/core/intrinsic_matrix.inl @@ -46,7 +46,7 @@ GLM_FUNC_QUALIFIER matType sse_comp_mul_ps out[3] = _mm_mul_ps(in1[3], in2[3]); } -GLM_FUNC_QUALIFIER void sse_add_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]) +GLM_FUNC_QUALIFIER void sse_add_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4]) { { out[0] = _mm_add_ps(in1[0], in2[0]); @@ -56,7 +56,7 @@ GLM_FUNC_QUALIFIER void sse_add_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]) } } -GLM_FUNC_QUALIFIER void sse_sub_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]) +GLM_FUNC_QUALIFIER void sse_sub_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4]) { { out[0] = _mm_sub_ps(in1[0], in2[0]); @@ -66,7 +66,7 @@ GLM_FUNC_QUALIFIER void sse_sub_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]) } } -GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 m[4], __m128 v) +GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 const m[4], __m128 v) { __m128 v0 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); __m128 v1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); @@ -85,7 +85,7 @@ GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 m[4], __m128 v) return a2; } -GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 v, __m128 m[4]) +GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 v, __m128 const m[4]) { __m128 i0 = m[0]; __m128 i1 = m[1]; diff --git a/glm/gtx/simd_mat4.hpp b/glm/gtx/simd_mat4.hpp index 22f28279..2a1b9ff4 100644 --- a/glm/gtx/simd_mat4.hpp +++ b/glm/gtx/simd_mat4.hpp @@ -91,6 +91,8 @@ namespace detail fvec4SIMD const & v3); explicit fmat4x4SIMD( tmat4x4 const & m); + explicit fmat4x4SIMD( + __m128 const in[4]); // Conversions //template diff --git a/glm/gtx/simd_mat4.inl b/glm/gtx/simd_mat4.inl index 4592d0f6..54d12425 100644 --- a/glm/gtx/simd_mat4.inl +++ b/glm/gtx/simd_mat4.inl @@ -26,7 +26,14 @@ GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::row_size() } GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD() -{} +{ +#ifndef GLM_SIMD_ENABLE_DEFAULT_INIT + this->Data[0] = fvec4SIMD(1.0f, 0, 0, 0); + this->Data[1] = fvec4SIMD(0, 1.0f, 0, 0); + this->Data[2] = fvec4SIMD(0, 0, 1.0f, 0); + this->Data[3] = fvec4SIMD(0, 0, 0, 1.0f); +#endif +} GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s) { @@ -75,6 +82,17 @@ GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD this->Data[3] = fvec4SIMD(m[3]); } +GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD +( + __m128 const in[4] +) +{ + this->Data[0] = in[0]; + this->Data[1] = in[1]; + this->Data[2] = in[2]; + this->Data[3] = in[3]; +} + ////////////////////////////////////// // Accesses @@ -232,6 +250,274 @@ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- () return *this; } + +////////////////////////////////////////////////////////////// +// Binary operators + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator+ +( + const fmat4x4SIMD &m, + float const & s +) +{ + return detail::fmat4x4SIMD + ( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator+ +( + float const & s, + const fmat4x4SIMD &m +) +{ + return detail::fmat4x4SIMD + ( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator+ +( + const fmat4x4SIMD &m1, + const fmat4x4SIMD &m2 +) +{ + return detail::fmat4x4SIMD + ( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3] + ); +} + + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator- +( + const fmat4x4SIMD &m, + float const & s +) +{ + return detail::fmat4x4SIMD + ( + m[0] - s, + m[1] - s, + m[2] - s, + m[3] - s + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator- +( + float const & s, + const fmat4x4SIMD &m +) +{ + return detail::fmat4x4SIMD + ( + s - m[0], + s - m[1], + s - m[2], + s - m[3] + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator- +( + const fmat4x4SIMD &m1, + const fmat4x4SIMD &m2 +) +{ + return detail::fmat4x4SIMD + ( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3] + ); +} + + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator* +( + const fmat4x4SIMD &m, + float const & s +) +{ + return detail::fmat4x4SIMD + ( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator* +( + float const & s, + const fmat4x4SIMD &m +) +{ + return detail::fmat4x4SIMD + ( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s + ); +} + +GLM_FUNC_QUALIFIER fvec4SIMD operator* +( + const fmat4x4SIMD &m, + fvec4SIMD const & v +) +{ + return sse_mul_ps(&m.Data[0].Data, v.Data); +} + +GLM_FUNC_QUALIFIER fvec4SIMD operator* +( + fvec4SIMD const & v, + const fmat4x4SIMD &m +) +{ + return sse_mul_ps(v.Data, &m.Data[0].Data); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator* +( + const fmat4x4SIMD &m1, + const fmat4x4SIMD &m2 +) +{ + fmat4x4SIMD result; + sse_mul_ps(&m1.Data[0].Data, &m2.Data[0].Data, &result.Data[0].Data); + + return result; +} + + + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator/ +( + const fmat4x4SIMD &m, + float const & s +) +{ + return detail::fmat4x4SIMD + ( + m[0] / s, + m[1] / s, + m[2] / s, + m[3] / s + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator/ +( + float const & s, + const fmat4x4SIMD &m +) +{ + return detail::fmat4x4SIMD + ( + s / m[0], + s / m[1], + s / m[2], + s / m[3] + ); +} + +GLM_FUNC_QUALIFIER fvec4SIMD operator/ +( + const fmat4x4SIMD &m, + fvec4SIMD const & v +) +{ + return inverse(m) * v; +} + +GLM_FUNC_QUALIFIER fvec4SIMD operator/ +( + fvec4SIMD const & v, + const fmat4x4SIMD &m +) +{ + return v * inverse(m); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD operator/ +( + const fmat4x4SIMD &m1, + const fmat4x4SIMD &m2 +) +{ + __m128 result[4]; + __m128 inv[4]; + + sse_inverse_ps(&m2.Data[0].Data, inv); + sse_mul_ps(&m1.Data[0].Data, inv, result); + + return fmat4x4SIMD(result); +} + + +////////////////////////////////////////////////////////////// +// Unary constant operators +GLM_FUNC_QUALIFIER fmat4x4SIMD const operator- +( + fmat4x4SIMD const & m +) +{ + return detail::fmat4x4SIMD + ( + -m[0], + -m[1], + -m[2], + -m[3] + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD const operator-- +( + fmat4x4SIMD const & m, + int +) +{ + return detail::fmat4x4SIMD + ( + m[0] - 1.0f, + m[1] - 1.0f, + m[2] - 1.0f, + m[3] - 1.0f + ); +} + +GLM_FUNC_QUALIFIER fmat4x4SIMD const operator++ +( + fmat4x4SIMD const & m, + int +) +{ + return detail::fmat4x4SIMD + ( + m[0] + 1.0f, + m[1] + 1.0f, + m[2] + 1.0f, + m[3] + 1.0f + ); +} + }//namespace detail GLM_FUNC_QUALIFIER detail::tmat4x4 mat4_cast diff --git a/glm/gtx/simd_vec4.hpp b/glm/gtx/simd_vec4.hpp index d18fbb8e..3e36cc91 100644 --- a/glm/gtx/simd_vec4.hpp +++ b/glm/gtx/simd_vec4.hpp @@ -54,6 +54,14 @@ # pragma message("GLM: GLM_GTX_simd_vec4 extension included") #endif + +// Warning silencer for nameless struct/union. +#if (GLM_COMPILER & GLM_COMPILER_VC) +# pragma warning(push) +# pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union +#endif + + namespace glm{ namespace detail { @@ -69,7 +77,15 @@ namespace detail typedef fvec4SIMD type; typedef tvec4 bool_type; - __m128 Data; +#ifdef GLM_SIMD_ENABLE_XYZW_UNION + union + { + __m128 Data; + struct {float x, y, z, w;}; + }; +#else + __m128 Data; +#endif ////////////////////////////////////// // Implicit basic constructors @@ -490,6 +506,12 @@ namespace detail #include "simd_vec4.inl" + +#if (GLM_COMPILER & GLM_COMPILER_VC) +# pragma warning(pop) +#endif + + #endif//(GLM_ARCH != GLM_ARCH_PURE) #endif//GLM_GTX_simd_vec4 diff --git a/glm/gtx/simd_vec4.inl b/glm/gtx/simd_vec4.inl index 321ce4f4..005aa7dd 100644 --- a/glm/gtx/simd_vec4.inl +++ b/glm/gtx/simd_vec4.inl @@ -20,6 +20,9 @@ struct mask // Implicit basic constructors GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD() +#ifdef GLM_SIMD_ENABLE_DEFAULT_INIT + : Data(_mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f)) +#endif {} GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(__m128 const & Data) :