Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Math/DVec3.h
9913 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Math/Double3.h>
8
9
JPH_NAMESPACE_BEGIN
10
11
/// 3 component vector of doubles (stored as 4 vectors).
12
/// Note that we keep the 4th component the same as the 3rd component to avoid divisions by zero when JPH_FLOATING_POINT_EXCEPTIONS_ENABLED defined
13
class [[nodiscard]] alignas(JPH_DVECTOR_ALIGNMENT) DVec3
14
{
15
public:
16
JPH_OVERRIDE_NEW_DELETE
17
18
// Underlying vector type
19
#if defined(JPH_USE_AVX)
20
using Type = __m256d;
21
using TypeArg = __m256d;
22
#elif defined(JPH_USE_SSE)
23
using Type = struct { __m128d mLow, mHigh; };
24
using TypeArg = const Type &;
25
#elif defined(JPH_USE_NEON)
26
using Type = float64x2x2_t;
27
using TypeArg = const Type &;
28
#else
29
using Type = struct { double mData[4]; };
30
using TypeArg = const Type &;
31
#endif
32
33
// Argument type
34
using ArgType = DVec3Arg;
35
36
/// Constructor
37
DVec3() = default; ///< Intentionally not initialized for performance reasons
38
DVec3(const DVec3 &inRHS) = default;
39
DVec3 & operator = (const DVec3 &inRHS) = default;
40
JPH_INLINE explicit DVec3(Vec3Arg inRHS);
41
JPH_INLINE explicit DVec3(Vec4Arg inRHS);
42
JPH_INLINE DVec3(TypeArg inRHS) : mValue(inRHS) { CheckW(); }
43
44
/// Create a vector from 3 components
45
JPH_INLINE DVec3(double inX, double inY, double inZ);
46
47
/// Load 3 doubles from memory
48
explicit JPH_INLINE DVec3(const Double3 &inV);
49
50
/// Vector with all zeros
51
static JPH_INLINE DVec3 sZero();
52
53
/// Vector with all ones
54
static JPH_INLINE DVec3 sOne();
55
56
/// Vectors with the principal axis
57
static JPH_INLINE DVec3 sAxisX() { return DVec3(1, 0, 0); }
58
static JPH_INLINE DVec3 sAxisY() { return DVec3(0, 1, 0); }
59
static JPH_INLINE DVec3 sAxisZ() { return DVec3(0, 0, 1); }
60
61
/// Replicate inV across all components
62
static JPH_INLINE DVec3 sReplicate(double inV);
63
64
/// Vector with all NaN's
65
static JPH_INLINE DVec3 sNaN();
66
67
/// Load 3 doubles from memory (reads 64 bits extra which it doesn't use)
68
static JPH_INLINE DVec3 sLoadDouble3Unsafe(const Double3 &inV);
69
70
/// Store 3 doubles to memory
71
JPH_INLINE void StoreDouble3(Double3 *outV) const;
72
73
/// Convert to float vector 3 rounding to nearest
74
JPH_INLINE explicit operator Vec3() const;
75
76
/// Prepare to convert to float vector 3 rounding towards zero (returns DVec3 that can be converted to a Vec3 to get the rounding)
77
JPH_INLINE DVec3 PrepareRoundToZero() const;
78
79
/// Prepare to convert to float vector 3 rounding towards positive/negative inf (returns DVec3 that can be converted to a Vec3 to get the rounding)
80
JPH_INLINE DVec3 PrepareRoundToInf() const;
81
82
/// Convert to float vector 3 rounding down
83
JPH_INLINE Vec3 ToVec3RoundDown() const;
84
85
/// Convert to float vector 3 rounding up
86
JPH_INLINE Vec3 ToVec3RoundUp() const;
87
88
/// Return the minimum value of each of the components
89
static JPH_INLINE DVec3 sMin(DVec3Arg inV1, DVec3Arg inV2);
90
91
/// Return the maximum of each of the components
92
static JPH_INLINE DVec3 sMax(DVec3Arg inV1, DVec3Arg inV2);
93
94
/// Clamp a vector between min and max (component wise)
95
static JPH_INLINE DVec3 sClamp(DVec3Arg inV, DVec3Arg inMin, DVec3Arg inMax);
96
97
/// Equals (component wise)
98
static JPH_INLINE DVec3 sEquals(DVec3Arg inV1, DVec3Arg inV2);
99
100
/// Less than (component wise)
101
static JPH_INLINE DVec3 sLess(DVec3Arg inV1, DVec3Arg inV2);
102
103
/// Less than or equal (component wise)
104
static JPH_INLINE DVec3 sLessOrEqual(DVec3Arg inV1, DVec3Arg inV2);
105
106
/// Greater than (component wise)
107
static JPH_INLINE DVec3 sGreater(DVec3Arg inV1, DVec3Arg inV2);
108
109
/// Greater than or equal (component wise)
110
static JPH_INLINE DVec3 sGreaterOrEqual(DVec3Arg inV1, DVec3Arg inV2);
111
112
/// Calculates inMul1 * inMul2 + inAdd
113
static JPH_INLINE DVec3 sFusedMultiplyAdd(DVec3Arg inMul1, DVec3Arg inMul2, DVec3Arg inAdd);
114
115
/// Component wise select, returns inNotSet when highest bit of inControl = 0 and inSet when highest bit of inControl = 1
116
static JPH_INLINE DVec3 sSelect(DVec3Arg inNotSet, DVec3Arg inSet, DVec3Arg inControl);
117
118
/// Logical or (component wise)
119
static JPH_INLINE DVec3 sOr(DVec3Arg inV1, DVec3Arg inV2);
120
121
/// Logical xor (component wise)
122
static JPH_INLINE DVec3 sXor(DVec3Arg inV1, DVec3Arg inV2);
123
124
/// Logical and (component wise)
125
static JPH_INLINE DVec3 sAnd(DVec3Arg inV1, DVec3Arg inV2);
126
127
/// Store if X is true in bit 0, Y in bit 1, Z in bit 2 and W in bit 3 (true is when highest bit of component is set)
128
JPH_INLINE int GetTrues() const;
129
130
/// Test if any of the components are true (true is when highest bit of component is set)
131
JPH_INLINE bool TestAnyTrue() const;
132
133
/// Test if all components are true (true is when highest bit of component is set)
134
JPH_INLINE bool TestAllTrue() const;
135
136
/// Get individual components
137
#if defined(JPH_USE_AVX)
138
JPH_INLINE double GetX() const { return _mm_cvtsd_f64(_mm256_castpd256_pd128(mValue)); }
139
JPH_INLINE double GetY() const { return mF64[1]; }
140
JPH_INLINE double GetZ() const { return mF64[2]; }
141
#elif defined(JPH_USE_SSE)
142
JPH_INLINE double GetX() const { return _mm_cvtsd_f64(mValue.mLow); }
143
JPH_INLINE double GetY() const { return mF64[1]; }
144
JPH_INLINE double GetZ() const { return _mm_cvtsd_f64(mValue.mHigh); }
145
#elif defined(JPH_USE_NEON)
146
JPH_INLINE double GetX() const { return vgetq_lane_f64(mValue.val[0], 0); }
147
JPH_INLINE double GetY() const { return vgetq_lane_f64(mValue.val[0], 1); }
148
JPH_INLINE double GetZ() const { return vgetq_lane_f64(mValue.val[1], 0); }
149
#else
150
JPH_INLINE double GetX() const { return mF64[0]; }
151
JPH_INLINE double GetY() const { return mF64[1]; }
152
JPH_INLINE double GetZ() const { return mF64[2]; }
153
#endif
154
155
/// Set individual components
156
JPH_INLINE void SetX(double inX) { mF64[0] = inX; }
157
JPH_INLINE void SetY(double inY) { mF64[1] = inY; }
158
JPH_INLINE void SetZ(double inZ) { mF64[2] = mF64[3] = inZ; } // Assure Z and W are the same
159
160
/// Set all components
161
JPH_INLINE void Set(double inX, double inY, double inZ) { *this = DVec3(inX, inY, inZ); }
162
163
/// Get double component by index
164
JPH_INLINE double operator [] (uint inCoordinate) const { JPH_ASSERT(inCoordinate < 3); return mF64[inCoordinate]; }
165
166
/// Set double component by index
167
JPH_INLINE void SetComponent(uint inCoordinate, double inValue) { JPH_ASSERT(inCoordinate < 3); mF64[inCoordinate] = inValue; mValue = sFixW(mValue); } // Assure Z and W are the same
168
169
/// Comparison
170
JPH_INLINE bool operator == (DVec3Arg inV2) const;
171
JPH_INLINE bool operator != (DVec3Arg inV2) const { return !(*this == inV2); }
172
173
/// Test if two vectors are close
174
JPH_INLINE bool IsClose(DVec3Arg inV2, double inMaxDistSq = 1.0e-24) const;
175
176
/// Test if vector is near zero
177
JPH_INLINE bool IsNearZero(double inMaxDistSq = 1.0e-24) const;
178
179
/// Test if vector is normalized
180
JPH_INLINE bool IsNormalized(double inTolerance = 1.0e-12) const;
181
182
/// Test if vector contains NaN elements
183
JPH_INLINE bool IsNaN() const;
184
185
/// Multiply two double vectors (component wise)
186
JPH_INLINE DVec3 operator * (DVec3Arg inV2) const;
187
188
/// Multiply vector with double
189
JPH_INLINE DVec3 operator * (double inV2) const;
190
191
/// Multiply vector with double
192
friend JPH_INLINE DVec3 operator * (double inV1, DVec3Arg inV2);
193
194
/// Divide vector by double
195
JPH_INLINE DVec3 operator / (double inV2) const;
196
197
/// Multiply vector with double
198
JPH_INLINE DVec3 & operator *= (double inV2);
199
200
/// Multiply vector with vector
201
JPH_INLINE DVec3 & operator *= (DVec3Arg inV2);
202
203
/// Divide vector by double
204
JPH_INLINE DVec3 & operator /= (double inV2);
205
206
/// Add two vectors (component wise)
207
JPH_INLINE DVec3 operator + (Vec3Arg inV2) const;
208
209
/// Add two double vectors (component wise)
210
JPH_INLINE DVec3 operator + (DVec3Arg inV2) const;
211
212
/// Add two vectors (component wise)
213
JPH_INLINE DVec3 & operator += (Vec3Arg inV2);
214
215
/// Add two double vectors (component wise)
216
JPH_INLINE DVec3 & operator += (DVec3Arg inV2);
217
218
/// Negate
219
JPH_INLINE DVec3 operator - () const;
220
221
/// Subtract two vectors (component wise)
222
JPH_INLINE DVec3 operator - (Vec3Arg inV2) const;
223
224
/// Subtract two double vectors (component wise)
225
JPH_INLINE DVec3 operator - (DVec3Arg inV2) const;
226
227
/// Subtract two vectors (component wise)
228
JPH_INLINE DVec3 & operator -= (Vec3Arg inV2);
229
230
/// Subtract two vectors (component wise)
231
JPH_INLINE DVec3 & operator -= (DVec3Arg inV2);
232
233
/// Divide (component wise)
234
JPH_INLINE DVec3 operator / (DVec3Arg inV2) const;
235
236
/// Return the absolute value of each of the components
237
JPH_INLINE DVec3 Abs() const;
238
239
/// Reciprocal vector (1 / value) for each of the components
240
JPH_INLINE DVec3 Reciprocal() const;
241
242
/// Cross product
243
JPH_INLINE DVec3 Cross(DVec3Arg inV2) const;
244
245
/// Dot product
246
JPH_INLINE double Dot(DVec3Arg inV2) const;
247
248
/// Squared length of vector
249
JPH_INLINE double LengthSq() const;
250
251
/// Length of vector
252
JPH_INLINE double Length() const;
253
254
/// Normalize vector
255
JPH_INLINE DVec3 Normalized() const;
256
257
/// Component wise square root
258
JPH_INLINE DVec3 Sqrt() const;
259
260
/// Get vector that contains the sign of each element (returns 1 if positive, -1 if negative)
261
JPH_INLINE DVec3 GetSign() const;
262
263
/// To String
264
friend ostream & operator << (ostream &inStream, DVec3Arg inV)
265
{
266
inStream << inV.mF64[0] << ", " << inV.mF64[1] << ", " << inV.mF64[2];
267
return inStream;
268
}
269
270
/// Internal helper function that checks that W is equal to Z, so e.g. dividing by it should not generate div by 0
271
JPH_INLINE void CheckW() const;
272
273
/// Internal helper function that ensures that the Z component is replicated to the W component to prevent divisions by zero
274
static JPH_INLINE Type sFixW(TypeArg inValue);
275
276
/// Representations of true and false for boolean operations
277
inline static const double cTrue = BitCast<double>(~uint64(0));
278
inline static const double cFalse = 0.0;
279
280
union
281
{
282
Type mValue;
283
double mF64[4];
284
};
285
};
286
287
static_assert(std::is_trivial<DVec3>(), "Is supposed to be a trivial type!");
288
289
JPH_NAMESPACE_END
290
291
#include "DVec3.inl"
292
293