diff --git a/src/naive/naive_vec4.h b/src/naive/naive_vec4.h index 1e37c52..8b53440 100644 --- a/src/naive/naive_vec4.h +++ b/src/naive/naive_vec4.h @@ -74,6 +74,11 @@ private: return std::sqrt(dot3(v, v)); } +[[nodiscard]] inline float magnitude3_sq(vec4 v) noexcept +{ + return dot3(v, v); +} + [[nodiscard]] inline vec4 norm3(vec4 v) noexcept { const float inv = 1.0f / magnitude3(v); // normalize xyz, keep w diff --git a/src/tenvex/expressions/core.h b/src/tenvex/expressions/core.h index 69c44f2..3d22d6f 100644 --- a/src/tenvex/expressions/core.h +++ b/src/tenvex/expressions/core.h @@ -101,6 +101,12 @@ vf4 magnitude3(vf4 v) noexcept return _mm_sqrt_ps(dot3(v, v)); } +[[nodiscard]] TNVX_INLINE +vf4 magnitude3_sq(vf4 v) noexcept +{ + return dot3(v, v); +} + [[nodiscard]] TNVX_INLINE vf4 norm3(vf4 v) noexcept { diff --git a/src/tenvex/expressions/magnitude3_sq.h b/src/tenvex/expressions/magnitude3_sq.h new file mode 100644 index 0000000..f1505d3 --- /dev/null +++ b/src/tenvex/expressions/magnitude3_sq.h @@ -0,0 +1,35 @@ +#pragma once + +#include "core.h" +#include "expression.h" +#include "traits.h" +#include "concepts.h" + +namespace tnvx +{ + +template +struct Magn3Sq : Expr> +{ + TNVX_INLINE + explicit Magn3Sq(const E& e) noexcept; + + [[nodiscard]] TNVX_INLINE + vf4 eval() const noexcept; + + [[nodiscard]] TNVX_INLINE + operator float() const noexcept; + +private: + tnvx_ref_or_value_t _e; +}; + +template inline constexpr bool is_scalar_expr> = true; + +template +[[nodiscard]] TNVX_INLINE +Magn3Sq magnitude3_sq(const E& e) noexcept; + +} + +#include "magnitude3_sq_impl.hpp" diff --git a/src/tenvex/expressions/magnitude3_sq_impl.hpp b/src/tenvex/expressions/magnitude3_sq_impl.hpp new file mode 100644 index 0000000..088bbab --- /dev/null +++ b/src/tenvex/expressions/magnitude3_sq_impl.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "magnitude3_sq.h" + +namespace tnvx +{ + +template +TNVX_INLINE +Magn3Sq::Magn3Sq(const E& e) noexcept + : _e(e) +{ +} + +template +TNVX_INLINE +vf4 Magn3Sq::eval() const noexcept +{ + return detail::magnitude3_sq(_e.eval()); +} + +template +TNVX_INLINE +Magn3Sq::operator float() const noexcept +{ + return detail::to_float(eval()); +} + +template +TNVX_INLINE +Magn3Sq magnitude3_sq(const E& e) noexcept +{ + return Magn3Sq(e); +} + + +} diff --git a/src/tenvex/tenvex.h b/src/tenvex/tenvex.h index c9e9162..92b4268 100644 --- a/src/tenvex/tenvex.h +++ b/src/tenvex/tenvex.h @@ -9,6 +9,7 @@ #include "expressions/dot3.h" #include "expressions/dot4.h" #include "expressions/magnitude3.h" +#include "expressions/magnitude3_sq.h" #include "expressions/norm3.h" #include "expressions/cross3.h" #include "expressions/vec4.h" diff --git a/src/tests/naive_tests.cpp b/src/tests/naive_tests.cpp index 8378006..26caae5 100644 --- a/src/tests/naive_tests.cpp +++ b/src/tests/naive_tests.cpp @@ -123,6 +123,24 @@ TEST(naive_vec4, magnitude_b) EXPECT_FLOAT_EQ(check, result); } +TEST(naive_vec4, magnitude3_sq_a) +{ + vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f }; + float check = 1.0f; + float result = magnitude3_sq(a); + + EXPECT_FLOAT_EQ(check, result); +} + +TEST(naive_vec4, magnitude3_sq_b) +{ + vec4 a = { 1.0f, 0.0f, 1.0f, 1.0f }; + float check = 2.0f; + float result = magnitude3_sq(a); + + EXPECT_FLOAT_EQ(check, result); +} + TEST(naive_vec4, expression_a) { vec4 a = { 1.0f, 1.0f, 1.0f, 1.0f }; diff --git a/src/tests/vec4_tests.cpp b/src/tests/vec4_tests.cpp index 98f83a8..6b1b8b7 100644 --- a/src/tests/vec4_tests.cpp +++ b/src/tests/vec4_tests.cpp @@ -121,6 +121,24 @@ TEST(vec4, magnitude_b) EXPECT_FLOAT_EQ(check, result); } +TEST(vec4, magnitude3_sq_a) +{ + vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f }; + float check = 1.0f; + float result = magnitude3_sq(a); + + EXPECT_FLOAT_EQ(check, result); +} + +TEST(vec4, magnitude3_sq_b) +{ + vec4 a = { 1.0f, 0.0f, 1.0f, 1.0f }; + float check = 2.0f; + float result = magnitude3_sq(a); + + EXPECT_FLOAT_EQ(check, result); +} + TEST(vec4, expression_a) { vec4 a = { 1.0f, 1.0f, 1.0f, 1.0f };