Update currenct expressions list
This commit is contained in:
parent
df718217d2
commit
bf74d7163f
@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
#include "core.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "concepts.h"
|
#include "concepts.h"
|
||||||
#include "traits.h"
|
#include "traits.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -17,7 +15,7 @@ struct Add : Expr<Add<L, R>>
|
|||||||
Add(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
Add(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
__m128 eval() const noexcept;
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tnvx_ref_or_value_t<L> _l;
|
tnvx_ref_or_value_t<L> _l;
|
||||||
@ -26,7 +24,7 @@ private:
|
|||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
Add<L, R> operator+(const L& l, const R& r) noexcept;
|
Add<L, R> operator+(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
inline constexpr bool is_vec_expr<Add<L, R>> = true;
|
inline constexpr bool is_vec_expr<Add<L, R>> = true;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
#include "add.h"
|
#include "add.h"
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
@ -16,14 +15,14 @@ Add<L, R>::Add(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
|||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
__m128 Add<L, R>::eval() const noexcept
|
vf4 Add<L, R>::eval() const noexcept
|
||||||
{
|
{
|
||||||
return _mm_add_ps(_l.eval(), _r.eval());
|
return detail::add(_l.eval(), _r.eval());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
Add<L, R> operator+(const L& l, const R& r) noexcept
|
Add<L, R> operator+(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
{
|
{
|
||||||
return { l, r };
|
return { l, r };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace tnvx
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept expression = requires (T t)
|
concept expression = requires (T t)
|
||||||
{
|
{
|
||||||
{ t.eval() } -> std::same_as<__m128>;
|
{ t.eval() } -> std::same_as<vf4>;
|
||||||
{ t.self() } -> std::same_as<const T&>;
|
{ t.self() } -> std::same_as<const T&>;
|
||||||
}
|
}
|
||||||
&& std::is_base_of_v<Expr<T>, T>;
|
&& std::is_base_of_v<Expr<T>, T>;
|
||||||
|
|||||||
3
src/tenvex/expressions/config.h
Normal file
3
src/tenvex/expressions/config.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define HAS_SSE42 1
|
||||||
88
src/tenvex/expressions/core.h
Normal file
88
src/tenvex/expressions/core.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
|
#if defined(HAS_SSE42)
|
||||||
|
#include <smmintrin.h>
|
||||||
|
using vf4 = __m128;
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tnvx::detail
|
||||||
|
{
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
bool eq(vf4 a, vf4 b)
|
||||||
|
{
|
||||||
|
return _mm_movemask_ps(_mm_cmpeq_ps(a, b)) == 0b1111;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
bool approx_eq(vf4 a, vf4 b, float eps) noexcept
|
||||||
|
{
|
||||||
|
vf4 abs_diff = _mm_andnot_ps(_mm_set1_ps(-0.0f), _mm_sub_ps(a, b));
|
||||||
|
return _mm_movemask_ps(_mm_cmple_ps(abs_diff, _mm_set1_ps(eps))) == 0b1111;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 scalar(float value) noexcept
|
||||||
|
{
|
||||||
|
return _mm_set_ps1(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 add(vf4 l, vf4 r) noexcept
|
||||||
|
{
|
||||||
|
return _mm_add_ps(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 sub(vf4 l, vf4 r) noexcept
|
||||||
|
{
|
||||||
|
return _mm_sub_ps(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 mul(vf4 l, vf4 r) noexcept
|
||||||
|
{
|
||||||
|
return _mm_mul_ps(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 div(vf4 l, vf4 r) noexcept
|
||||||
|
{
|
||||||
|
return _mm_div_ps(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 dot3(vf4 l, vf4 r) noexcept
|
||||||
|
{
|
||||||
|
return _mm_dp_ps(l, r, 0b01111111);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 magnitude3(vf4 v) noexcept
|
||||||
|
{
|
||||||
|
return _mm_sqrt_ps(_mm_dp_ps(v, v, 0b01111111));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 norm3(vf4 v) noexcept
|
||||||
|
{
|
||||||
|
return _mm_blend_ps(_mm_div_ps(v, magnitude3(v)), v, 0b1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 cross3(vf4 l, vf4 r) noexcept
|
||||||
|
{
|
||||||
|
vf4 a_yzx = _mm_shuffle_ps(l, l, _MM_SHUFFLE(3, 0, 2, 1));
|
||||||
|
vf4 b_yzx = _mm_shuffle_ps(r, r, _MM_SHUFFLE(3, 0, 2, 1));
|
||||||
|
|
||||||
|
vf4 t = _mm_sub_ps(_mm_mul_ps(l, b_yzx),
|
||||||
|
_mm_mul_ps(a_yzx, r));
|
||||||
|
|
||||||
|
return _mm_shuffle_ps(t, t, _MM_SHUFFLE(3, 0, 2, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
33
src/tenvex/expressions/cross3.h
Normal file
33
src/tenvex/expressions/cross3.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "traits.h"
|
||||||
|
#include "concepts.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
struct Cross3 : Expr<Cross3<L, R>>
|
||||||
|
{
|
||||||
|
TNVX_INLINE
|
||||||
|
Cross3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tnvx_ref_or_value_t<L> _l;
|
||||||
|
tnvx_ref_or_value_t<R> _r;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
Cross3<L, R> cross3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R> inline constexpr bool is_vec_expr<Cross3<L, R>> = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "cross3_impl.hpp"
|
||||||
30
src/tenvex/expressions/cross3_impl.hpp
Normal file
30
src/tenvex/expressions/cross3_impl.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cross3.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
Cross3<L, R>::Cross3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
|
: _l(l)
|
||||||
|
, _r(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
vf4 Cross3<L, R>::eval() const noexcept
|
||||||
|
{
|
||||||
|
return detail::cross3(_l.eval(), _r.eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
Cross3<L, R> cross3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
|
{
|
||||||
|
return { l, r };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -9,4 +9,4 @@
|
|||||||
#else
|
#else
|
||||||
#define TNVX_INLINE inline
|
#define TNVX_INLINE inline
|
||||||
#define TNVX_RESTRICT
|
#define TNVX_RESTRICT
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
35
src/tenvex/expressions/div.h
Normal file
35
src/tenvex/expressions/div.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "traits.h"
|
||||||
|
#include "concepts.h"
|
||||||
|
|
||||||
|
#include "scalar.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr L, scalar_expr R>
|
||||||
|
struct Div : Expr<Div<L, R>>
|
||||||
|
{
|
||||||
|
TNVX_INLINE
|
||||||
|
Div(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tnvx_ref_or_value_t<L> _l;
|
||||||
|
tnvx_ref_or_value_t<R> _r;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
Div<E, Scalar> operator/(const E& TNVX_RESTRICT l, float r) noexcept;
|
||||||
|
|
||||||
|
template<vec_expr L, scalar_expr R> inline constexpr bool is_vec_expr<Div<L, R>> = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "div_impl.hpp"
|
||||||
30
src/tenvex/expressions/div_impl.hpp
Normal file
30
src/tenvex/expressions/div_impl.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "div.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr L, scalar_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
tnvx::Div<L, R>::Div(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
|
: _l(l)
|
||||||
|
, _r(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr L, scalar_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
vf4 Div<L, R>::eval() const noexcept
|
||||||
|
{
|
||||||
|
return detail::div(_l.eval(), _r.eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Div<E, Scalar> operator/(const E& TNVX_RESTRICT l, float r) noexcept
|
||||||
|
{
|
||||||
|
return { l, Scalar(r) };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
36
src/tenvex/expressions/dot3.h
Normal file
36
src/tenvex/expressions/dot3.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "traits.h"
|
||||||
|
#include "concepts.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
struct Dot3 : Expr<Dot3<L, R>>
|
||||||
|
{
|
||||||
|
TNVX_INLINE
|
||||||
|
Dot3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
operator float() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tnvx_ref_or_value_t<L> _l;
|
||||||
|
tnvx_ref_or_value_t<R> _r;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
Dot3<L, R> dot3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R> inline constexpr bool is_scalar_expr<Dot3<L, R>> = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "dot3_impl.h"
|
||||||
37
src/tenvex/expressions/dot3_impl.h
Normal file
37
src/tenvex/expressions/dot3_impl.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dot3.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
Dot3<L, R>::Dot3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
|
: _l(l)
|
||||||
|
, _r(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
vf4 Dot3<L, R>::eval() const noexcept
|
||||||
|
{
|
||||||
|
return detail::dot3(_l.eval(), _r.eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
Dot3<L, R>::operator float() const noexcept
|
||||||
|
{
|
||||||
|
return _mm_cvtss_f32(eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr L, vec_expr R>
|
||||||
|
TNVX_INLINE
|
||||||
|
Dot3<L, R> dot3(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
|
{
|
||||||
|
return { l, r };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
#include "core.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
{
|
{
|
||||||
|
|||||||
35
src/tenvex/expressions/magnitude3.h
Normal file
35
src/tenvex/expressions/magnitude3.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "traits.h"
|
||||||
|
#include "concepts.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
struct Magn3 : Expr<Magn3<E>>
|
||||||
|
{
|
||||||
|
TNVX_INLINE
|
||||||
|
explicit Magn3(const E& TNVX_RESTRICT e) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
operator float() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tnvx_ref_or_value_t<E> _e;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Magn3<E> magnitude3(const E& TNVX_RESTRICT e) noexcept;
|
||||||
|
|
||||||
|
template<vec_expr E> inline constexpr bool is_scalar_expr<Magn3<E>> = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "magnitude3_impl.hpp"
|
||||||
37
src/tenvex/expressions/magnitude3_impl.hpp
Normal file
37
src/tenvex/expressions/magnitude3_impl.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "magnitude3.h"
|
||||||
|
#include "dot3.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Magn3<E>::Magn3(const E& TNVX_RESTRICT e) noexcept
|
||||||
|
: _e(e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
vf4 Magn3<E>::eval() const noexcept
|
||||||
|
{
|
||||||
|
return detail::magnitude3(_e.eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Magn3<E>::operator float() const noexcept
|
||||||
|
{
|
||||||
|
return _mm_cvtss_f32(eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Magn3<E> magnitude3(const E& TNVX_RESTRICT e) noexcept
|
||||||
|
{
|
||||||
|
return Magn3<E>(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,14 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
#include "core.h"
|
||||||
#include "traits.h"
|
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
|
#include "traits.h"
|
||||||
#include "concepts.h"
|
#include "concepts.h"
|
||||||
|
|
||||||
#include "scalar.h"
|
#include "scalar.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -16,10 +14,10 @@ template<expression L, expression R>
|
|||||||
struct Mul : Expr<Mul<L, R>>
|
struct Mul : Expr<Mul<L, R>>
|
||||||
{
|
{
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Mul(const L& l, const R& r) noexcept;
|
Mul(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
__m128 eval() const noexcept;
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tnvx_ref_or_value_t<L> _l;
|
tnvx_ref_or_value_t<L> _l;
|
||||||
@ -28,15 +26,15 @@ private:
|
|||||||
|
|
||||||
template<vec_expr E>
|
template<vec_expr E>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
Mul<E, Scalar> operator*(const E& l, float r) noexcept;
|
Mul<E, Scalar> operator*(const E& TNVX_RESTRICT l, float r) noexcept;
|
||||||
|
|
||||||
template<vec_expr E>
|
template<vec_expr E>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
Mul<Scalar, E> operator*(float l, const E& r) noexcept;
|
Mul<Scalar, E> operator*(float l, const E& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
template<scalar_expr L, scalar_expr R>
|
template<scalar_expr L, scalar_expr R>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
Mul<L, R> operator*(const L& l, const R& r) noexcept;
|
Mul<L, R> operator*(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
template<vec_expr L, scalar_expr R> inline constexpr bool is_vec_expr<Mul<L, R>> = true;
|
template<vec_expr L, scalar_expr R> inline constexpr bool is_vec_expr<Mul<L, R>> = true;
|
||||||
template<scalar_expr L, vec_expr R> inline constexpr bool is_vec_expr<Mul<L, R>> = true;
|
template<scalar_expr L, vec_expr R> inline constexpr bool is_vec_expr<Mul<L, R>> = true;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace tnvx
|
|||||||
|
|
||||||
template<expression L, expression R>
|
template<expression L, expression R>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Mul<L, R>::Mul(const L& l, const R& r) noexcept
|
Mul<L, R>::Mul(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
: _l(l)
|
: _l(l)
|
||||||
, _r(r)
|
, _r(r)
|
||||||
{
|
{
|
||||||
@ -15,28 +15,28 @@ Mul<L, R>::Mul(const L& l, const R& r) noexcept
|
|||||||
|
|
||||||
template<expression L, expression R>
|
template<expression L, expression R>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
__m128 Mul<L, R>::eval() const noexcept
|
vf4 Mul<L, R>::eval() const noexcept
|
||||||
{
|
{
|
||||||
return _mm_mul_ps(_l.eval(), _r.eval());
|
return _mm_mul_ps(_l.eval(), _r.eval());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<vec_expr E>
|
template<vec_expr E>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Mul<E, Scalar> operator*(const E& l, float r) noexcept
|
Mul<E, Scalar> operator*(const E& TNVX_RESTRICT l, float r) noexcept
|
||||||
{
|
{
|
||||||
return { l, Scalar(r) };
|
return { l, Scalar(r) };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<vec_expr E>
|
template<vec_expr E>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Mul<Scalar, E> operator*(float l, const E& r) noexcept
|
Mul<Scalar, E> operator*(float l, const E& TNVX_RESTRICT r) noexcept
|
||||||
{
|
{
|
||||||
return { Scalar(l), r };
|
return { Scalar(l), r };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<scalar_expr L, scalar_expr R>
|
template<scalar_expr L, scalar_expr R>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Mul<L, R> operator*(const L& l, const R& r) noexcept
|
Mul<L, R> operator*(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
{
|
{
|
||||||
return { l, r };
|
return { l, r };
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/tenvex/expressions/norm3.h
Normal file
31
src/tenvex/expressions/norm3.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "traits.h"
|
||||||
|
#include "concepts.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
struct Norm3 : Expr<Norm3<E>>
|
||||||
|
{
|
||||||
|
TNVX_INLINE
|
||||||
|
explicit Norm3(const E& TNVX_RESTRICT e) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tnvx_ref_or_value_t<E> _e;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
[[nodiscard]] TNVX_INLINE
|
||||||
|
Norm3<E> norm3(const E& TNVX_RESTRICT e) noexcept;
|
||||||
|
|
||||||
|
template<vec_expr E> inline constexpr bool is_vec_expr<Norm3<E>> = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
#include "norm3_impl.hpp"
|
||||||
29
src/tenvex/expressions/norm3_impl.hpp
Normal file
29
src/tenvex/expressions/norm3_impl.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "norm3.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Norm3<E>::Norm3(const E& TNVX_RESTRICT e) noexcept
|
||||||
|
: _e(e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
vf4 Norm3<E>::eval() const noexcept
|
||||||
|
{
|
||||||
|
return detail::norm3(_e.eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
Norm3<E> norm3(const E& TNVX_RESTRICT e) noexcept
|
||||||
|
{
|
||||||
|
return Norm3<E>(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
#include "core.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "traits.h"
|
#include "traits.h"
|
||||||
#include "concepts.h"
|
#include "concepts.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -16,10 +14,10 @@ struct Scalar : Expr<Scalar>
|
|||||||
explicit Scalar(float value) noexcept;
|
explicit Scalar(float value) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
__m128 eval() const noexcept;
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
__m128 _value;
|
vf4 _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|||||||
@ -8,11 +8,11 @@ namespace tnvx
|
|||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Scalar::Scalar(float value) noexcept
|
Scalar::Scalar(float value) noexcept
|
||||||
{
|
{
|
||||||
_value = _mm_set1_ps(value);
|
_value = detail::scalar(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
__m128 Scalar::eval() const noexcept
|
vf4 Scalar::eval() const noexcept
|
||||||
{
|
{
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
#include "core.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "concepts.h"
|
#include "concepts.h"
|
||||||
#include "traits.h"
|
#include "traits.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -17,7 +15,7 @@ struct Sub : Expr<Sub<L, R>>
|
|||||||
Sub(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
Sub(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
__m128 eval() const noexcept;
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tnvx_ref_or_value_t<L> _l;
|
tnvx_ref_or_value_t<L> _l;
|
||||||
@ -26,10 +24,9 @@ private:
|
|||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
[[nodiscard]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
Sub<L, R> operator-(const L& l, const R& r) noexcept;
|
Sub<L, R> operator-(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept;
|
||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R> inline constexpr bool is_vec_expr<Sub<L, R>> = true;
|
||||||
inline constexpr bool is_vec_expr<Sub<L, R>> = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,14 +15,14 @@ Sub<L, R>::Sub(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
|||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
__m128 Sub<L, R>::eval() const noexcept
|
vf4 Sub<L, R>::eval() const noexcept
|
||||||
{
|
{
|
||||||
return _mm_sub_ps(_l.eval(), _r.eval());
|
return detail::sub(_l.eval(), _r.eval());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<vec_expr L, vec_expr R>
|
template<vec_expr L, vec_expr R>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
Sub<L, R> operator-(const L& l, const R& r) noexcept
|
Sub<L, R> operator-(const L& TNVX_RESTRICT l, const R& TNVX_RESTRICT r) noexcept
|
||||||
{
|
{
|
||||||
return { l, r };
|
return { l, r };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.h"
|
#include "core.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "traits.h"
|
#include "traits.h"
|
||||||
#include "concepts.h"
|
#include "concepts.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
|
||||||
|
|
||||||
namespace tnvx
|
namespace tnvx
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -20,17 +18,16 @@ struct alignas(16) vec4 : Expr<vec4>
|
|||||||
|
|
||||||
template<vec_expr E>
|
template<vec_expr E>
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
vec4(const E& e) noexcept;
|
vec4(const E& TNVX_RESTRICT e) noexcept;
|
||||||
|
|
||||||
[[nodiscaed]] TNVX_INLINE
|
[[nodiscard]] TNVX_INLINE
|
||||||
__m128 eval() const noexcept;
|
vf4 eval() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
__m128 _data;
|
vf4 _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<> inline constexpr bool is_vec_expr<vec4> = true;
|
||||||
inline constexpr bool is_vec_expr<vec4> = true;
|
|
||||||
|
|
||||||
TNVX_INLINE
|
TNVX_INLINE
|
||||||
bool approx_eq(const vec4& lhs, const vec4& rhs, float eps = 1e-6f) noexcept;
|
bool approx_eq(const vec4& lhs, const vec4& rhs, float eps = 1e-6f) noexcept;
|
||||||
@ -39,3 +36,5 @@ TNVX_INLINE
|
|||||||
bool operator==(const vec4& lhs, const vec4& rhs) noexcept;
|
bool operator==(const vec4& lhs, const vec4& rhs) noexcept;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "vec4_impl.hpp"
|
||||||
|
|||||||
@ -1 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "vec4.h"
|
||||||
|
|
||||||
|
namespace tnvx
|
||||||
|
{
|
||||||
|
|
||||||
|
TNVX_INLINE
|
||||||
|
vec4::vec4(float x, float y, float z, float w) noexcept
|
||||||
|
: _data(_mm_set_ps(w, z, y, x))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TNVX_INLINE
|
||||||
|
__m128 vec4::eval() const noexcept
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<vec_expr E>
|
||||||
|
TNVX_INLINE
|
||||||
|
vec4::vec4(const E& TNVX_RESTRICT e) noexcept
|
||||||
|
: _data(e.eval())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TNVX_INLINE
|
||||||
|
bool approx_eq(const vec4& lhs, const vec4& rhs, float eps) noexcept
|
||||||
|
{
|
||||||
|
return detail::approx_eq(lhs.eval(), rhs.eval(), eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
TNVX_INLINE
|
||||||
|
bool tnvx::operator==(const vec4& lhs, const vec4& rhs) noexcept
|
||||||
|
{
|
||||||
|
return detail::eq(lhs.eval(), rhs.eval());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "expressions/defines.h"
|
|
||||||
#include "expressions/traits.h"
|
|
||||||
#include "expressions/expression.h"
|
|
||||||
#include "expressions/concepts.h"
|
|
||||||
#include "expressions/add.h"
|
#include "expressions/add.h"
|
||||||
#include "expressions/sub.h"
|
#include "expressions/sub.h"
|
||||||
#include "expressions/scalar.h"
|
#include "expressions/scalar.h"
|
||||||
#include "expressions/mul.h"
|
#include "expressions/mul.h"
|
||||||
|
#include "expressions/div.h"
|
||||||
|
#include "expressions/dot3.h"
|
||||||
|
#include "expressions/magnitude3.h"
|
||||||
|
#include "expressions/norm3.h"
|
||||||
|
#include "expressions/cross3.h"
|
||||||
#include "expressions/vec4.h"
|
#include "expressions/vec4.h"
|
||||||
|
|||||||
@ -45,12 +45,21 @@ TEST(vec4, mult_b)
|
|||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, dot)
|
TEST(vec4, div)
|
||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 3.0f, 0.0f };
|
vec4 a = { 3.0f, 6.0f, 0.0f, 0.0f };
|
||||||
vec4 b = { 1.0f, 2.0f, 3.0f, 1.0f };
|
float b = 3.0f;
|
||||||
|
vec4 check = { 1.0f, 2.0f, 0.0f, 0.0f };
|
||||||
|
vec4 result = a / b;
|
||||||
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(vec4, dot3)
|
||||||
|
{
|
||||||
|
vec4 a = { 1.0f, 0.0f, 3.0f, 1.0f };
|
||||||
|
vec4 b = { 1.0f, 2.0f, 3.0f, 4.0f };
|
||||||
float check = 10.0f;
|
float check = 10.0f;
|
||||||
float result = dot(a, b);
|
float result = dot3(a, b);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(check, result);
|
EXPECT_FLOAT_EQ(check, result);
|
||||||
}
|
}
|
||||||
@ -60,25 +69,25 @@ TEST(vec4, cross)
|
|||||||
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||||
vec4 check = { 0.0f, 0.0f, 1.0f, 0.0f };
|
vec4 check = { 0.0f, 0.0f, 1.0f, 0.0f };
|
||||||
vec4 result = cross(a, b);
|
vec4 result = cross3(a, b);
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, norm_a)
|
TEST(vec4, norm_a)
|
||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||||
vec4 check = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 check = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||||
vec4 result = norm(a);
|
vec4 result = norm3(a);
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, norm_b)
|
TEST(vec4, norm_b)
|
||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 1.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 1.0f, 1.0f };
|
||||||
vec4 check = { 0.707106f, 0.0f, 0.707106f, 0.0f };
|
vec4 check = { 0.707106f, 0.0f, 0.707106f, 1.0f };
|
||||||
vec4 result = norm(a);
|
vec4 result = norm3(a);
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
@ -87,7 +96,7 @@ TEST(vec4, magnitude_a)
|
|||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
float check = 1.0f;
|
float check = 1.0f;
|
||||||
float result = magnitude(a);
|
float result = magnitude3(a);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(check, result);
|
EXPECT_FLOAT_EQ(check, result);
|
||||||
}
|
}
|
||||||
@ -96,20 +105,20 @@ TEST(vec4, magnitude_b)
|
|||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 1.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 1.0f, 0.0f };
|
||||||
float check = 1.4142135f;
|
float check = 1.4142135f;
|
||||||
float result = magnitude(a);
|
float result = magnitude3(a);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(check, result);
|
EXPECT_FLOAT_EQ(check, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, expression_a)
|
TEST(vec4, expression_a)
|
||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 1.0f, 1.0f, 0.0f };
|
vec4 a = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
vec4 b = { 0.0f, 1.0f, 0.0f, 3.0f };
|
||||||
vec4 c = { 1.15f, 0.0f, 11.0f, 0.0f };
|
vec4 c = { 1.15f, 0.0f, 11.0f, 0.0f };
|
||||||
|
|
||||||
vec4 check = { 3.45f, 0.0f, 33.0f, 0.0f };
|
vec4 check = { 3.45f, 0.0f, 33.0f, 0.0f };
|
||||||
|
|
||||||
vec4 result = dot(a, b) * 3.0f * c;
|
vec4 result = dot3(a, b) * 3.0f * c;
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
@ -122,7 +131,7 @@ TEST(vec4, expression_b)
|
|||||||
|
|
||||||
vec4 check = { 33.0f, 0.0f, -3.45f, 0.0f };
|
vec4 check = { 33.0f, 0.0f, -3.45f, 0.0f };
|
||||||
|
|
||||||
vec4 result = dot(a, b) * 3.0f * cross(b, c);
|
vec4 result = dot3(a, b) * 3.0f * cross3(b, c);
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
@ -133,22 +142,12 @@ TEST(vec4, expression_c)
|
|||||||
vec4 b = { 4.0f, 5.0f, 6.0f, 0.0f };
|
vec4 b = { 4.0f, 5.0f, 6.0f, 0.0f };
|
||||||
vec4 c = { 1.0f, 0.0f, 1.0f, 0.0f };
|
vec4 c = { 1.0f, 0.0f, 1.0f, 0.0f };
|
||||||
|
|
||||||
vec4 check = { 7.243f, 5.657f, 10.071f, 0.0f };
|
vec4 check = { 7.24264050f, 5.65685463f, 10.0710678f, 0.0f };
|
||||||
|
|
||||||
vec4 result = norm(a + b * 2.0f) * dot(b, c) + c * 3.0f;
|
vec4 tmp1 = norm3(a + b * 2.0f) * dot3(b, c);
|
||||||
|
vec4 tmp2 = c * 3.0f;
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
vec4 result = tmp1 + tmp2;
|
||||||
}
|
|
||||||
|
|
||||||
TEST(vec4, expression_d)
|
|
||||||
{
|
|
||||||
vec4 a = { 1.0f, 2.0f, 3.0f, 0.0f };
|
|
||||||
vec4 b = { 4.0f, 5.0f, 6.0f, 0.0f };
|
|
||||||
vec4 c = { 1.0f, 0.0f, 1.0f, 0.0f };
|
|
||||||
|
|
||||||
vec4 check = { 7.243f, 5.657f, 10.071f, 0.0f };
|
|
||||||
|
|
||||||
vec4 result = magnitude(a) * dot(b, c) + c * 3.0f;
|
|
||||||
|
|
||||||
EXPECT_TRUE(approx_eq(check, result));
|
EXPECT_TRUE(approx_eq(check, result));
|
||||||
}
|
}
|
||||||
@ -157,27 +156,27 @@ TEST(vec4, cross_anticommutative)
|
|||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||||
EXPECT_TRUE(approx_eq(cross(a, b), cross(b, a) * -1.0f));
|
EXPECT_TRUE(approx_eq(cross3(a, b), cross3(b, a) * -1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, dot_commutative)
|
TEST(vec4, dot_commutative)
|
||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 2.0f, 3.0f, 0.0f };
|
vec4 a = { 1.0f, 2.0f, 3.0f, 0.0f };
|
||||||
vec4 b = { 4.0f, 5.0f, 6.0f, 0.0f };
|
vec4 b = { 4.0f, 5.0f, 6.0f, 0.0f };
|
||||||
EXPECT_FLOAT_EQ(dot(a, b), dot(b, a));
|
EXPECT_FLOAT_EQ(dot3(a, b), dot3(b, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, norm_magnitude)
|
TEST(vec4, norm_magnitude)
|
||||||
{
|
{
|
||||||
vec4 a = { 3.0f, 1.0f, 4.0f, 0.0f };
|
vec4 a = { 3.0f, 1.0f, 4.0f, 0.0f };
|
||||||
EXPECT_NEAR(magnitude(norm(a)), 1.0f, 1e-5f);
|
EXPECT_NEAR(magnitude3(norm3(a)), 1.0f, 1e-5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, dot_perpendicular)
|
TEST(vec4, dot_perpendicular)
|
||||||
{
|
{
|
||||||
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
vec4 b = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||||
EXPECT_FLOAT_EQ(dot(a, b), 0.0f);
|
EXPECT_FLOAT_EQ(dot3(a, b), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vec4, cross_parallel)
|
TEST(vec4, cross_parallel)
|
||||||
@ -185,7 +184,7 @@ TEST(vec4, cross_parallel)
|
|||||||
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
vec4 a = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
vec4 b = { 2.0f, 0.0f, 0.0f, 0.0f };
|
vec4 b = { 2.0f, 0.0f, 0.0f, 0.0f };
|
||||||
vec4 check = { 0.0f, 0.0f, 0.0f, 0.0f };
|
vec4 check = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
EXPECT_TRUE(approx_eq(cross(a, b), check));
|
EXPECT_TRUE(approx_eq(cross3(a, b), check));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user