MeshLib C++ Docs
Loading...
Searching...
No Matches
MRVector4.h
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include "MRPch/MRBindingMacros.h"
5#include "MRVector3.h"
6
7namespace MR
8{
9
10#ifdef _MSC_VER
11#pragma warning(push)
12#pragma warning(disable: 4804) // unsafe use of type 'bool' in operation
13#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
14#endif
15
18template <typename T>
19struct Vector4
20{
21 using ValueType = T;
24 static constexpr int elements = 4;
25
26 T x, y, z, w;
27
28 constexpr Vector4() noexcept : x( 0 ), y( 0 ), z( 0 ), w( 0 ) { }
29 explicit Vector4( NoInit ) noexcept { }
30 constexpr Vector4( T x, T y, T z, T w ) noexcept : x( x ), y( y ), z( z ), w( w ) { }
31 static constexpr Vector4 diagonal( T a ) noexcept
32 {
33 return Vector4( a, a, a, a );
34 }
35 template <typename U>
36 constexpr explicit Vector4( const Vector4<U> & v ) noexcept : x( T( v.x ) ), y( T( v.y ) ), z( T( v.z ) ), w( T( v.w ) )
37 {
38 }
39
40 constexpr const T & operator []( int e ) const noexcept { return *( &x + e ); }
41 constexpr T & operator []( int e ) noexcept { return *( &x + e ); }
42
43 T lengthSq() const
44 {
45 return x * x + y * y + z * z + w * w;
46 }
47 auto length() const
48 {
49 // Calling `sqrt` this way to hopefully support boost.multiprecision numbers.
50 // Returning `auto` to not break on integral types.
51 using std::sqrt;
52 return sqrt( lengthSq() );
53 }
54
55 Vector4 normalized() const MR_REQUIRES_IF_SUPPORTED( !std::is_integral_v<T> )
56 {
57 auto len = length();
58 if ( len <= 0 )
59 return {};
60 return ( 1 / len ) * ( *this );
61 }
62
64 Vector3<T> proj3d() const MR_REQUIRES_IF_SUPPORTED( !std::is_integral_v<T> )
65 {
66 return { x / w, y / w, z / w };
67 }
68
69 [[nodiscard]] bool isFinite() const MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
70 {
71 return std::isfinite( x ) && std::isfinite( y ) && std::isfinite( z ) && std::isfinite( w );
72 }
73
74 [[nodiscard]] friend constexpr bool operator ==( const Vector4<T> & a, const Vector4<T> & b ) { return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; }
75 [[nodiscard]] friend constexpr bool operator !=( const Vector4<T> & a, const Vector4<T> & b ) { return !( a == b ); }
76
77 // NOTE: We use `std::declval()` in the operators below because libclang 18 in our binding generator is bugged and chokes on decltyping `a.x` and such. TODO fix this when we update libclang.
78
79 [[nodiscard]] friend constexpr const Vector4<T> & operator +( const Vector4<T> & a ) { return a; }
80 [[nodiscard]] friend constexpr auto operator -( const Vector4<T> & a ) -> Vector4<decltype( -std::declval<T>() )> { return { -a.x, -a.y, -a.z, -a.w }; }
81
82 [[nodiscard]] friend constexpr auto operator +( const Vector4<T> & a, const Vector4<T> & b ) -> Vector4<decltype( std::declval<T>() + std::declval<T>() )> { return { a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w }; }
83 [[nodiscard]] friend constexpr auto operator -( const Vector4<T> & a, const Vector4<T> & b ) -> Vector4<decltype( std::declval<T>() - std::declval<T>() )> { return { a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w }; }
84 [[nodiscard]] friend constexpr auto operator *( T a, const Vector4<T> & b ) -> Vector4<decltype( std::declval<T>() * std::declval<T>() )> { return { a * b.x, a * b.y, a * b.z, a * b.w }; }
85 [[nodiscard]] friend constexpr auto operator *( const Vector4<T> & b, T a ) -> Vector4<decltype( std::declval<T>() * std::declval<T>() )> { return { a * b.x, a * b.y, a * b.z, a * b.w }; }
86 [[nodiscard]] friend constexpr auto operator /( Vector4<T> b, T a ) -> Vector4<decltype( std::declval<T>() / std::declval<T>() )>
87 {
88 if constexpr ( std::is_integral_v<T> )
89 return { b.x / a, b.y / a, b.z / a, b.w / a };
90 else
91 return b * ( 1 / a );
92 }
93
94 friend constexpr Vector4<T> & operator +=( Vector4<T> & a, const Vector4<T> & b ) MR_REQUIRES_IF_SUPPORTED( requires{ a + b; } ) { a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; return a; }
95 friend constexpr Vector4<T> & operator -=( Vector4<T> & a, const Vector4<T> & b ) MR_REQUIRES_IF_SUPPORTED( requires{ a - b; } ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; return a; }
96 friend constexpr Vector4<T> & operator *=( Vector4<T> & a, T b ) MR_REQUIRES_IF_SUPPORTED( requires{ a * b; } ) { a.x *= b; a.y *= b; a.z *= b; a.w *= b; return a; }
97 friend constexpr Vector4<T> & operator /=( Vector4<T> & a, T b ) MR_REQUIRES_IF_SUPPORTED( requires{ a / b; } )
98 {
99 if constexpr ( std::is_integral_v<T> )
100 { a.x /= b; a.y /= b; a.z /= b; a.w /= b; return a; }
101 else
102 return a *= ( 1 / b );
103 }
104};
105
108
110template <typename T>
111inline T distanceSq( const Vector4<T> & a, const Vector4<T> & b )
112{
113 return ( a - b ).lengthSq();
114}
115
117template <typename T>
118inline T distance( const Vector4<T> & a, const Vector4<T> & b )
119{
120 return ( a - b ).length();
121}
122
124template <typename T>
125inline auto dot( const Vector4<T> & a, const Vector4<T> & b ) -> decltype( a.x * b.x )
126{
127 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
128}
129
131template <typename T>
132inline T sqr( const Vector4<T> & a )
133{
134 return a.lengthSq();
135}
136
138template <typename T>
139inline Vector4<T> mult( const Vector4<T>& a, const Vector4<T>& b )
140{
141 return { a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w };
142}
143
145template <typename T>
146inline Vector4<T> div( const Vector4<T>& a, const Vector4<T>& b )
147{
148 return { a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w };
149}
150
151
152// We don't need to bind those functions themselves. This doesn't prevent `__iter__` from being generated for the type.
153
154template <typename T>
155MR_BIND_IGNORE auto begin( const Vector4<T> & v ) { return &v[0]; }
156template <typename T>
157MR_BIND_IGNORE auto begin( Vector4<T> & v ) { return &v[0]; }
158
159template <typename T>
160MR_BIND_IGNORE auto end( const Vector4<T> & v ) { return &v[4]; }
161template <typename T>
162MR_BIND_IGNORE auto end( Vector4<T> & v ) { return &v[4]; }
163
165
166#ifdef _MSC_VER
167#pragma warning(pop)
168#endif
169
170} // namespace MR
#define MR_REQUIRES_IF_SUPPORTED(...)
Definition MRMacros.h:31
MR_BIND_IGNORE auto begin(const BitSet &a)
Definition MRMesh/MRBitSet.h:295
MR_BIND_IGNORE auto end(const BitSet &)
Definition MRMesh/MRBitSet.h:297
Definition MRMatrix4.h:20
Definition MRMesh/MRMeshFwd.h:89
Definition MRSymMatrix4.h:13
Definition MRMesh/MRVector3.h:26
Definition MRVector4.h:20
Vector4 normalized() const
Definition MRVector4.h:55
friend constexpr Vector4< T > & operator*=(Vector4< T > &a, T b)
Definition MRVector4.h:96
friend constexpr bool operator!=(const Vector4< T > &a, const Vector4< T > &b)
Definition MRVector4.h:75
T y
Definition MRVector4.h:26
T z
Definition MRVector4.h:26
T x
Definition MRVector4.h:26
friend constexpr Vector4< T > & operator-=(Vector4< T > &a, const Vector4< T > &b)
Definition MRVector4.h:95
T sqr(const Vector4< T > &a)
squared length
Definition MRVector4.h:132
T w
Definition MRVector4.h:26
T lengthSq() const
Definition MRVector4.h:43
Vector4(NoInit) noexcept
Definition MRVector4.h:29
friend constexpr const Vector4< T > & operator+(const Vector4< T > &a)
Definition MRVector4.h:79
friend constexpr auto operator-(const Vector4< T > &a) -> Vector4< decltype(-std::declval< T >())>
Definition MRVector4.h:80
T ValueType
Definition MRVector4.h:21
Vector3< T > proj3d() const
assuming this is a point represented in homogeneous 4D coordinates, returns the point as 3D-vector
Definition MRVector4.h:64
Vector4< T > div(const Vector4< T > &a, const Vector4< T > &b)
per component division
Definition MRVector4.h:146
T distanceSq(const Vector4< T > &a, const Vector4< T > &b)
squared distance between two points, which is faster to compute than just distance
Definition MRVector4.h:111
constexpr Vector4(T x, T y, T z, T w) noexcept
Definition MRVector4.h:30
constexpr Vector4(const Vector4< U > &v) noexcept
Definition MRVector4.h:36
auto dot(const Vector4< T > &a, const Vector4< T > &b) -> decltype(a.x *b.x)
dot product
Definition MRVector4.h:125
Vector4< T > mult(const Vector4< T > &a, const Vector4< T > &b)
per component multiplication
Definition MRVector4.h:139
friend constexpr bool operator==(const Vector4< T > &a, const Vector4< T > &b)
Definition MRVector4.h:74
auto length() const
Definition MRVector4.h:47
constexpr const T & operator[](int e) const noexcept
Definition MRVector4.h:40
static constexpr Vector4 diagonal(T a) noexcept
Definition MRVector4.h:31
bool isFinite() const
Definition MRVector4.h:69
friend constexpr auto operator/(Vector4< T > b, T a) -> Vector4< decltype(std::declval< T >()/std::declval< T >())>
Definition MRVector4.h:86
friend constexpr Vector4< T > & operator/=(Vector4< T > &a, T b)
Definition MRVector4.h:97
static constexpr int elements
Definition MRVector4.h:24
friend constexpr Vector4< T > & operator+=(Vector4< T > &a, const Vector4< T > &b)
Definition MRVector4.h:94
constexpr Vector4() noexcept
Definition MRVector4.h:28
friend constexpr auto operator*(T a, const Vector4< T > &b) -> Vector4< decltype(std::declval< T >() *std::declval< T >())>
Definition MRVector4.h:84
T distance(const Vector4< T > &a, const Vector4< T > &b)
distance between two points, better use distanceSq for higher performance
Definition MRVector4.h:118