MeshLib C++ Docs
Loading...
Searching...
No Matches
MRVector3.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMacros.h"
4#include "MRMesh/MRUnsigned.h"
5#include "MRMeshFwd.h"
6#include "MRConstants.h"
7#include "MRPch/MRBindingMacros.h"
8#include <algorithm>
9#include <cmath>
10#include <cstring>
11#include <iosfwd>
12#include <utility>
13#if MR_HAS_REQUIRES
14#include <concepts>
15#endif
16
17namespace MR
18{
21
22
23#ifdef _MSC_VER
24#pragma warning(push)
25#pragma warning(disable: 4804)
26#pragma warning(disable: 4146)
27#endif
28
31template <typename T>
32struct Vector3
33{
34 using ValueType = T;
37 static constexpr int elements = 3;
38
39 T x, y, z;
40
41 constexpr Vector3() noexcept : x( 0 ), y( 0 ), z( 0 )
42 {
43 static_assert( sizeof( Vector3<ValueType> ) == elements * sizeof( ValueType ), "Struct size invalid" );
44 static_assert( elements == 3, "Invalid number of elements" );
45 }
46 explicit Vector3( NoInit ) noexcept { }
47 constexpr Vector3( T x, T y, T z ) noexcept : x( x ), y( y ), z( z ) { }
48
49 template <typename U> MR_REQUIRES_IF_SUPPORTED( std::constructible_from<T, U> )
50 explicit constexpr Vector3( const Vector2<U> & v ) noexcept : x( v.x ), y( v.y ), z( 0 ) { }
51
52 static constexpr Vector3 diagonal( T a ) noexcept { return Vector3( a, a, a ); }
53 static constexpr Vector3 plusX() noexcept { return Vector3( 1, 0, 0 ); }
54 static constexpr Vector3 plusY() noexcept { return Vector3( 0, 1, 0 ); }
55 static constexpr Vector3 plusZ() noexcept { return Vector3( 0, 0, 1 ); }
56 static constexpr Vector3 minusX() noexcept MR_REQUIRES_IF_SUPPORTED( !std::is_unsigned_v<T> ) { return Vector3( -1, 0, 0 ); }
57 static constexpr Vector3 minusY() noexcept MR_REQUIRES_IF_SUPPORTED( !std::is_unsigned_v<T> ) { return Vector3( 0, -1, 0 ); }
58 static constexpr Vector3 minusZ() noexcept MR_REQUIRES_IF_SUPPORTED( !std::is_unsigned_v<T> ) { return Vector3( 0, 0, -1 ); }
59
62 template <typename U> MR_REQUIRES_IF_SUPPORTED( !std::is_same_v<T, U> )
63 constexpr explicit Vector3( const Vector3<U> & v ) noexcept : x( T( v.x ) ), y( T( v.y ) ), z( T( v.z ) ) { }
64
65 constexpr const T & operator []( int e ) const noexcept { return *( ( ValueType *)this + e ); }
66 constexpr T & operator []( int e ) noexcept { return *( ( ValueType *)this + e ); }
67
68 T lengthSq() const { return x * x + y * y + z * z; }
69 auto length() const
70 {
73 using std::sqrt;
74 return sqrt( lengthSq() );
75 }
76
77 [[nodiscard]] Vector3 normalized() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
78 {
79 auto len = length();
80 if ( len <= 0 )
81 return {};
82 return ( 1 / len ) * (*this);
83 }
84
86 Vector3 furthestBasisVector() const MR_REQUIRES_IF_SUPPORTED( !std::is_same_v<T, bool> );
87
90 std::pair<Vector3, Vector3> perpendicular() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> );
91
93 template <MR_SAME_TYPE_TEMPLATE_PARAM(T, TT)>
94 Vector3 transformed( const AffineXf3<TT>* xf ) const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
95 {
96 return xf ? ( *xf )( *this ) : *this;
97 }
98
100 void unsignZeroValues() MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
101 {
102 for ( auto i = 0; i < elements; ++i )
103 if ( (*this)[i] == 0.f && std::signbit( (*this)[i] ) )
104 (*this)[i] = 0.f;
105 }
106
107 [[nodiscard]] bool isFinite() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
108 {
109 return std::isfinite( x ) && std::isfinite( y ) && std::isfinite( z );
110 }
111
112 [[nodiscard]] friend constexpr bool operator ==( const Vector3<T> & a, const Vector3<T> & b ) { return a.x == b.x && a.y == b.y && a.z == b.z; }
113 [[nodiscard]] friend constexpr bool operator !=( const Vector3<T> & a, const Vector3<T> & b ) { return !( a == b ); }
114
116
117 [[nodiscard]] friend constexpr const Vector3<T> & operator +( const Vector3<T> & a ) { return a; }
118 [[nodiscard]] friend constexpr auto operator -( const Vector3<T> & a ) -> Vector3<decltype( -std::declval<T>() )> { return { -a.x, -a.y, -a.z }; }
119
120 [[nodiscard]] friend constexpr auto operator +( const Vector3<T> & a, const Vector3<T> & b ) -> Vector3<decltype( std::declval<T>() + std::declval<T>() )> { return { a.x + b.x, a.y + b.y, a.z + b.z }; }
121 [[nodiscard]] friend constexpr auto operator -( const Vector3<T> & a, const Vector3<T> & b ) -> Vector3<decltype( std::declval<T>() - std::declval<T>() )> { return { a.x - b.x, a.y - b.y, a.z - b.z }; }
122 [[nodiscard]] friend constexpr auto operator *( T a, const Vector3<T> & b ) -> Vector3<decltype( std::declval<T>() * std::declval<T>() )> { return { a * b.x, a * b.y, a * b.z }; }
123 [[nodiscard]] friend constexpr auto operator *( const Vector3<T> & b, T a ) -> Vector3<decltype( std::declval<T>() * std::declval<T>() )> { return { a * b.x, a * b.y, a * b.z }; }
124 [[nodiscard]] friend constexpr auto operator /( Vector3<T> b, T a ) -> Vector3<decltype( std::declval<T>() / std::declval<T>() )>
125 {
126 if constexpr ( std::is_integral_v<T> )
127 return { b.x / a, b.y / a, b.z / a };
128 else
129 return b * ( 1 / a );
130 }
131
132 friend constexpr Vector3<T> & operator +=( Vector3<T> & a, const Vector3<T> & b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; }
133 friend constexpr Vector3<T> & operator -=( Vector3<T> & a, const Vector3<T> & b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; }
134 friend constexpr Vector3<T> & operator *=( Vector3<T> & a, T b ) { a.x *= b; a.y *= b; a.z *= b; return a; }
135 friend constexpr Vector3<T> & operator /=( Vector3<T> & a, T b )
136 {
137 if constexpr ( std::is_integral_v<T> )
138 { a.x /= b; a.y /= b; a.z /= b; return a; }
139 else
140 return a *= ( 1 / b );
141 }
142
143 friend std::ostream& operator<<( std::ostream& s, const Vector3& vec )
144 {
145 return s << vec.x << ' ' << vec.y << ' ' << vec.z;
146 }
147
148 friend std::istream& operator>>( std::istream& s, Vector3& vec )
149 {
150 return s >> vec.x >> vec.y >> vec.z;
151 }
152
153
156
157 MR_BIND_IGNORE friend auto begin( const Vector3& v ) { return &v[0]; }
158 MR_BIND_IGNORE friend auto begin( Vector3& v ) { return &v[0]; }
159 MR_BIND_IGNORE friend auto end( const Vector3& v ) { return &v[3]; }
160 MR_BIND_IGNORE friend auto end( Vector3& v ) { return &v[3]; }
161};
162
165
166
168template <typename T>
169inline T distanceSq( const Vector3<T> & a, const Vector3<T> & b )
170{
171 return ( a - b ).lengthSq();
172}
173
175template <typename T>
176inline T distance( const Vector3<T> & a, const Vector3<T> & b )
177{
178 return ( a - b ).length();
179}
180
182template <typename T>
183inline Vector3<T> cross( const Vector3<T> & a, const Vector3<T> & b )
184{
185 return {
186 a.y * b.z - a.z * b.y,
187 a.z * b.x - a.x * b.z,
188 a.x * b.y - a.y * b.x
189 };
190}
191
193template <typename T>
194inline auto dot( const Vector3<T> & a, const Vector3<T> & b ) -> decltype( a.x * b.x )
195{
196 return a.x * b.x + a.y * b.y + a.z * b.z;
197}
198
200template <typename T>
201inline T sqr( const Vector3<T> & a )
202{
203 return a.lengthSq();
204}
205
207template <typename T>
208inline T mixed( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
209{
210 return dot( a, cross( b, c ) );
211}
212
214template <typename T>
215inline Vector3<T> mult( const Vector3<T>& a, const Vector3<T>& b )
216{
217 return { a.x * b.x,a.y * b.y,a.z * b.z };
218}
219
221template <typename T>
222inline Vector3<T> div( const Vector3<T>& a, const Vector3<T>& b )
223{
224 return { a.x / b.x, a.y / b.y, a.z / b.z };
225}
226
227
230template <typename T>
231inline T angle( const Vector3<T> & a, const Vector3<T> & b )
232{
233 return std::atan2( cross( a, b ).length(), dot( a, b ) );
236}
237
238template <typename T>
239inline Vector3<T> Vector3<T>::furthestBasisVector() const MR_REQUIRES_IF_SUPPORTED( !std::is_same_v<T, bool> )
240{
241 using std::abs;
242 using Unsigned::abs;
243 if ( abs( x ) < abs( y ) )
244 return ( abs( x ) < abs( z ) ) ? Vector3( 1, 0, 0 ) : Vector3( 0, 0, 1 );
245 else
246 return ( abs( y ) < abs( z ) ) ? Vector3( 0, 1, 0 ) : Vector3( 0, 0, 1 );
247}
248
249template <typename T>
250inline std::pair<Vector3<T>, Vector3<T>> Vector3<T>::perpendicular() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
251{
252 std::pair<Vector3<T>, Vector3<T>> res;
253 auto c1 = furthestBasisVector();
254 res.first = cross( *this, c1 ).normalized();
255 res.second = cross( *this, res.first ).normalized();
256 return res;
257}
258
260template <typename T>
261Vector3<T> unitVector3( T azimuth, T altitude )
262{
263 const auto zenithAngle = T( PI2 ) - altitude;
264 return
265 {
266 std::sin( zenithAngle ) * std::cos( azimuth ),
267 std::sin( zenithAngle ) * std::sin( azimuth ),
268 std::cos( zenithAngle )
269 };
270}
271
273
274#ifdef _MSC_VER
275#pragma warning(pop)
276#endif
277
278}
279
280template<>
281struct std::hash<MR::Vector3f>
282{
283 size_t operator()( MR::Vector3f const& p ) const noexcept
284 {
287 std::uint64_t xy;
288 std::uint32_t z;
289 static_assert( sizeof( float ) == sizeof( std::uint32_t ) );
290 std::memcpy( &xy, &p.x, sizeof( std::uint64_t ) );
291 std::memcpy( &z, &p.z, sizeof( std::uint32_t ) );
292 return size_t( xy ) ^ ( size_t( z ) << 16 );
293 }
294};
#define MR_SAME_TYPE_TEMPLATE_PARAM(target_, name_)
Definition MRMacros.h:35
#define MR_REQUIRES_IF_SUPPORTED(...)
Definition MRMacros.h:34
MR_REQUIRES_IF_SUPPORTED(std::is_function_v< T >) inline size_t heapBytes(const std
Definition MRHeapBytes.h:69
static constexpr Vector3 plusX() noexcept
Definition MRVector3.h:53
void unsignZeroValues() MR_REQUIRES_IF_SUPPORTED(std
get rid of signed zero values to be sure that equal vectors have identical binary representation
Definition MRVector3.h:100
static constexpr Vector3 minusX() noexcept MR_REQUIRES_IF_SUPPORTED(!std
Definition MRVector3.h:56
auto dot(const Vector3< T > &a, const Vector3< T > &b) -> decltype(a.x *b.x)
dot product
Definition MRVector3.h:194
Vector3< T > unitVector3(T azimuth, T altitude)
returns a point on unit sphere given two angles
Definition MRVector3.h:261
T distanceSq(const Vector3< T > &a, const Vector3< T > &b)
squared distance between two points, which is faster to compute than just distance
Definition MRVector3.h:169
SymMatrix3< Int128 > SymMatrixType
Definition MRVector3.h:36
friend constexpr bool operator!=(const Vector3< T > &a, const Vector3< T > &b)
Definition MRVector3.h:113
MR_BIND_IGNORE friend auto end(const Vector3 &v)
Definition MRVector3.h:159
static constexpr Vector3 minusY() noexcept MR_REQUIRES_IF_SUPPORTED(!std
Definition MRVector3.h:57
static constexpr Vector3 minusZ() noexcept MR_REQUIRES_IF_SUPPORTED(!std
Definition MRVector3.h:58
MR_BIND_IGNORE friend auto begin(const Vector3 &v)
Definition MRVector3.h:157
Vector3< T > div(const Vector3< T > &a, const Vector3< T > &b)
per component division
Definition MRVector3.h:222
friend constexpr auto operator*(T a, const Vector3< T > &b) -> Vector3< decltype(std::declval< T >() *std::declval< T >())>
Definition MRVector3.h:122
auto dot(const Matrix2< T > &a, const Matrix2< T > &b) -> decltype(dot(a.x, b.x))
double-dot product: x = a : b
Definition MRMatrix2.h:142
friend constexpr auto operator-(const Vector3< T > &a) -> Vector3< decltype(-std::declval< T >())>
Definition MRVector3.h:118
Int128 x
Definition MRVector3.h:39
Vector3 furthestBasisVector() const MR_REQUIRES_IF_SUPPORTED(!std std::pair< Vector3, Vector3 > perpendicular() const MR_REQUIRES_IF_SUPPORTED(std Vector3 transformed(const AffineXf3< TT > *xf) const MR_REQUIRES_IF_SUPPORTED(std
Definition MRVector3.h:94
Int128 y
Definition MRVector3.h:39
static constexpr int elements
Definition MRVector3.h:37
friend std::istream & operator>>(std::istream &s, Vector3 &vec)
Definition MRVector3.h:148
friend std::ostream & operator<<(std::ostream &s, const Vector3 &vec)
Definition MRVector3.h:143
MR_BIND_IGNORE friend auto end(Vector3 &v)
Definition MRVector3.h:160
friend constexpr const Vector3< T > & operator+(const Vector3< T > &a)
NOTE: We use std::declval() in the operators below because libclang 18 in our binding generator is bu...
Definition MRVector3.h:117
Matrix3< Int128 > MatrixType
Definition MRVector3.h:35
friend constexpr Vector3< T > & operator/=(Vector3< T > &a, T b)
Definition MRVector3.h:135
MR_REQUIRES_IF_SUPPORTED(!std::is_same_v< T, U >) const expr explicit Vector3(const Vector3< U > &v) noexcept
Definition MRVector3.h:62
Vector3(NoInit) noexcept
Definition MRVector3.h:46
Int128 ValueType
Definition MRVector3.h:34
constexpr const T & operator[](int e) const noexcept
Definition MRVector3.h:65
auto length() const
Definition MRVector3.h:69
MR_REQUIRES_IF_SUPPORTED(std::constructible_from< T, U >) explicit const expr Vector3(const Vector2< U > &v) noexcept
Definition MRVector3.h:49
constexpr Vector3(T x, T y, T z) noexcept
Definition MRVector3.h:47
friend constexpr bool operator==(const Vector3< T > &a, const Vector3< T > &b)
Definition MRVector3.h:112
friend constexpr Vector3< T > & operator*=(Vector3< T > &a, T b)
Definition MRVector3.h:134
T distance(const Vector3< T > &a, const Vector3< T > &b)
distance between two points, better use distanceSq for higher performance
Definition MRVector3.h:176
T mixed(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
mixed product
Definition MRVector3.h:208
static constexpr Vector3 plusZ() noexcept
Definition MRVector3.h:55
Vector3 normalized() const MR_REQUIRES_IF_SUPPORTED(std
Definition MRVector3.h:77
friend constexpr auto operator/(Vector3< T > b, T a) -> Vector3< decltype(std::declval< T >()/std::declval< T >())>
Definition MRVector3.h:124
T sqr(const Vector3< T > &a)
squared length
Definition MRVector3.h:201
MR_BIND_IGNORE friend auto begin(Vector3 &v)
Definition MRVector3.h:158
MRMESH_CLASS Vector3
Definition MRMeshFwd.h:218
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:13
T angle(const Vector3< T > &a, const Vector3< T > &b)
Definition MRVector3.h:231
AffineXf< Vector3< T > > AffineXf3
Definition MRMeshFwd.h:313
constexpr Vector3() noexcept
Definition MRVector3.h:41
Vector3< T > mult(const Vector3< T > &a, const Vector3< T > &b)
per component multiplication
Definition MRVector3.h:215
Int128 z
Definition MRVector3.h:39
friend constexpr Vector3< T > & operator-=(Vector3< T > &a, const Vector3< T > &b)
Definition MRVector3.h:133
T lengthSq() const
Definition MRVector3.h:68
static constexpr Vector3 plusY() noexcept
Definition MRVector3.h:54
bool isFinite() const MR_REQUIRES_IF_SUPPORTED(std
Definition MRVector3.h:107
static constexpr Vector3 diagonal(T a) noexcept
Definition MRVector3.h:52
Vector3< T > cross(const Vector3< T > &a, const Vector3< T > &b)
cross product
Definition MRVector3.h:183
length
Definition MRObjectDimensionsEnum.h:17
friend constexpr Vector3< T > & operator+=(Vector3< T > &a, const Vector3< T > &b)
Definition MRVector3.h:132
constexpr T abs(T value)
Definition MRUnsigned.h:18
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
Definition MRMatrix3.h:24
Definition MRMeshFwd.h:97
Definition MRSymMatrix3.h:18
Definition MRVector2.h:29
T cross(const Vector2< T > &a, const Vector2< T > &b)
cross product
Definition MRVector2.h:160
Definition MRVector3.h:33