Path: blob/master/thirdparty/jolt_physics/Jolt/Math/DVec3.h
9913 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Math/Double3.h>78JPH_NAMESPACE_BEGIN910/// 3 component vector of doubles (stored as 4 vectors).11/// Note that we keep the 4th component the same as the 3rd component to avoid divisions by zero when JPH_FLOATING_POINT_EXCEPTIONS_ENABLED defined12class [[nodiscard]] alignas(JPH_DVECTOR_ALIGNMENT) DVec313{14public:15JPH_OVERRIDE_NEW_DELETE1617// Underlying vector type18#if defined(JPH_USE_AVX)19using Type = __m256d;20using TypeArg = __m256d;21#elif defined(JPH_USE_SSE)22using Type = struct { __m128d mLow, mHigh; };23using TypeArg = const Type &;24#elif defined(JPH_USE_NEON)25using Type = float64x2x2_t;26using TypeArg = const Type &;27#else28using Type = struct { double mData[4]; };29using TypeArg = const Type &;30#endif3132// Argument type33using ArgType = DVec3Arg;3435/// Constructor36DVec3() = default; ///< Intentionally not initialized for performance reasons37DVec3(const DVec3 &inRHS) = default;38DVec3 & operator = (const DVec3 &inRHS) = default;39JPH_INLINE explicit DVec3(Vec3Arg inRHS);40JPH_INLINE explicit DVec3(Vec4Arg inRHS);41JPH_INLINE DVec3(TypeArg inRHS) : mValue(inRHS) { CheckW(); }4243/// Create a vector from 3 components44JPH_INLINE DVec3(double inX, double inY, double inZ);4546/// Load 3 doubles from memory47explicit JPH_INLINE DVec3(const Double3 &inV);4849/// Vector with all zeros50static JPH_INLINE DVec3 sZero();5152/// Vector with all ones53static JPH_INLINE DVec3 sOne();5455/// Vectors with the principal axis56static JPH_INLINE DVec3 sAxisX() { return DVec3(1, 0, 0); }57static JPH_INLINE DVec3 sAxisY() { return DVec3(0, 1, 0); }58static JPH_INLINE DVec3 sAxisZ() { return DVec3(0, 0, 1); }5960/// Replicate inV across all components61static JPH_INLINE DVec3 sReplicate(double inV);6263/// Vector with all NaN's64static JPH_INLINE DVec3 sNaN();6566/// Load 3 doubles from memory (reads 64 bits extra which it doesn't use)67static JPH_INLINE DVec3 sLoadDouble3Unsafe(const Double3 &inV);6869/// Store 3 doubles to memory70JPH_INLINE void StoreDouble3(Double3 *outV) const;7172/// Convert to float vector 3 rounding to nearest73JPH_INLINE explicit operator Vec3() const;7475/// Prepare to convert to float vector 3 rounding towards zero (returns DVec3 that can be converted to a Vec3 to get the rounding)76JPH_INLINE DVec3 PrepareRoundToZero() const;7778/// 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)79JPH_INLINE DVec3 PrepareRoundToInf() const;8081/// Convert to float vector 3 rounding down82JPH_INLINE Vec3 ToVec3RoundDown() const;8384/// Convert to float vector 3 rounding up85JPH_INLINE Vec3 ToVec3RoundUp() const;8687/// Return the minimum value of each of the components88static JPH_INLINE DVec3 sMin(DVec3Arg inV1, DVec3Arg inV2);8990/// Return the maximum of each of the components91static JPH_INLINE DVec3 sMax(DVec3Arg inV1, DVec3Arg inV2);9293/// Clamp a vector between min and max (component wise)94static JPH_INLINE DVec3 sClamp(DVec3Arg inV, DVec3Arg inMin, DVec3Arg inMax);9596/// Equals (component wise)97static JPH_INLINE DVec3 sEquals(DVec3Arg inV1, DVec3Arg inV2);9899/// Less than (component wise)100static JPH_INLINE DVec3 sLess(DVec3Arg inV1, DVec3Arg inV2);101102/// Less than or equal (component wise)103static JPH_INLINE DVec3 sLessOrEqual(DVec3Arg inV1, DVec3Arg inV2);104105/// Greater than (component wise)106static JPH_INLINE DVec3 sGreater(DVec3Arg inV1, DVec3Arg inV2);107108/// Greater than or equal (component wise)109static JPH_INLINE DVec3 sGreaterOrEqual(DVec3Arg inV1, DVec3Arg inV2);110111/// Calculates inMul1 * inMul2 + inAdd112static JPH_INLINE DVec3 sFusedMultiplyAdd(DVec3Arg inMul1, DVec3Arg inMul2, DVec3Arg inAdd);113114/// Component wise select, returns inNotSet when highest bit of inControl = 0 and inSet when highest bit of inControl = 1115static JPH_INLINE DVec3 sSelect(DVec3Arg inNotSet, DVec3Arg inSet, DVec3Arg inControl);116117/// Logical or (component wise)118static JPH_INLINE DVec3 sOr(DVec3Arg inV1, DVec3Arg inV2);119120/// Logical xor (component wise)121static JPH_INLINE DVec3 sXor(DVec3Arg inV1, DVec3Arg inV2);122123/// Logical and (component wise)124static JPH_INLINE DVec3 sAnd(DVec3Arg inV1, DVec3Arg inV2);125126/// 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)127JPH_INLINE int GetTrues() const;128129/// Test if any of the components are true (true is when highest bit of component is set)130JPH_INLINE bool TestAnyTrue() const;131132/// Test if all components are true (true is when highest bit of component is set)133JPH_INLINE bool TestAllTrue() const;134135/// Get individual components136#if defined(JPH_USE_AVX)137JPH_INLINE double GetX() const { return _mm_cvtsd_f64(_mm256_castpd256_pd128(mValue)); }138JPH_INLINE double GetY() const { return mF64[1]; }139JPH_INLINE double GetZ() const { return mF64[2]; }140#elif defined(JPH_USE_SSE)141JPH_INLINE double GetX() const { return _mm_cvtsd_f64(mValue.mLow); }142JPH_INLINE double GetY() const { return mF64[1]; }143JPH_INLINE double GetZ() const { return _mm_cvtsd_f64(mValue.mHigh); }144#elif defined(JPH_USE_NEON)145JPH_INLINE double GetX() const { return vgetq_lane_f64(mValue.val[0], 0); }146JPH_INLINE double GetY() const { return vgetq_lane_f64(mValue.val[0], 1); }147JPH_INLINE double GetZ() const { return vgetq_lane_f64(mValue.val[1], 0); }148#else149JPH_INLINE double GetX() const { return mF64[0]; }150JPH_INLINE double GetY() const { return mF64[1]; }151JPH_INLINE double GetZ() const { return mF64[2]; }152#endif153154/// Set individual components155JPH_INLINE void SetX(double inX) { mF64[0] = inX; }156JPH_INLINE void SetY(double inY) { mF64[1] = inY; }157JPH_INLINE void SetZ(double inZ) { mF64[2] = mF64[3] = inZ; } // Assure Z and W are the same158159/// Set all components160JPH_INLINE void Set(double inX, double inY, double inZ) { *this = DVec3(inX, inY, inZ); }161162/// Get double component by index163JPH_INLINE double operator [] (uint inCoordinate) const { JPH_ASSERT(inCoordinate < 3); return mF64[inCoordinate]; }164165/// Set double component by index166JPH_INLINE void SetComponent(uint inCoordinate, double inValue) { JPH_ASSERT(inCoordinate < 3); mF64[inCoordinate] = inValue; mValue = sFixW(mValue); } // Assure Z and W are the same167168/// Comparison169JPH_INLINE bool operator == (DVec3Arg inV2) const;170JPH_INLINE bool operator != (DVec3Arg inV2) const { return !(*this == inV2); }171172/// Test if two vectors are close173JPH_INLINE bool IsClose(DVec3Arg inV2, double inMaxDistSq = 1.0e-24) const;174175/// Test if vector is near zero176JPH_INLINE bool IsNearZero(double inMaxDistSq = 1.0e-24) const;177178/// Test if vector is normalized179JPH_INLINE bool IsNormalized(double inTolerance = 1.0e-12) const;180181/// Test if vector contains NaN elements182JPH_INLINE bool IsNaN() const;183184/// Multiply two double vectors (component wise)185JPH_INLINE DVec3 operator * (DVec3Arg inV2) const;186187/// Multiply vector with double188JPH_INLINE DVec3 operator * (double inV2) const;189190/// Multiply vector with double191friend JPH_INLINE DVec3 operator * (double inV1, DVec3Arg inV2);192193/// Divide vector by double194JPH_INLINE DVec3 operator / (double inV2) const;195196/// Multiply vector with double197JPH_INLINE DVec3 & operator *= (double inV2);198199/// Multiply vector with vector200JPH_INLINE DVec3 & operator *= (DVec3Arg inV2);201202/// Divide vector by double203JPH_INLINE DVec3 & operator /= (double inV2);204205/// Add two vectors (component wise)206JPH_INLINE DVec3 operator + (Vec3Arg inV2) const;207208/// Add two double vectors (component wise)209JPH_INLINE DVec3 operator + (DVec3Arg inV2) const;210211/// Add two vectors (component wise)212JPH_INLINE DVec3 & operator += (Vec3Arg inV2);213214/// Add two double vectors (component wise)215JPH_INLINE DVec3 & operator += (DVec3Arg inV2);216217/// Negate218JPH_INLINE DVec3 operator - () const;219220/// Subtract two vectors (component wise)221JPH_INLINE DVec3 operator - (Vec3Arg inV2) const;222223/// Subtract two double vectors (component wise)224JPH_INLINE DVec3 operator - (DVec3Arg inV2) const;225226/// Subtract two vectors (component wise)227JPH_INLINE DVec3 & operator -= (Vec3Arg inV2);228229/// Subtract two vectors (component wise)230JPH_INLINE DVec3 & operator -= (DVec3Arg inV2);231232/// Divide (component wise)233JPH_INLINE DVec3 operator / (DVec3Arg inV2) const;234235/// Return the absolute value of each of the components236JPH_INLINE DVec3 Abs() const;237238/// Reciprocal vector (1 / value) for each of the components239JPH_INLINE DVec3 Reciprocal() const;240241/// Cross product242JPH_INLINE DVec3 Cross(DVec3Arg inV2) const;243244/// Dot product245JPH_INLINE double Dot(DVec3Arg inV2) const;246247/// Squared length of vector248JPH_INLINE double LengthSq() const;249250/// Length of vector251JPH_INLINE double Length() const;252253/// Normalize vector254JPH_INLINE DVec3 Normalized() const;255256/// Component wise square root257JPH_INLINE DVec3 Sqrt() const;258259/// Get vector that contains the sign of each element (returns 1 if positive, -1 if negative)260JPH_INLINE DVec3 GetSign() const;261262/// To String263friend ostream & operator << (ostream &inStream, DVec3Arg inV)264{265inStream << inV.mF64[0] << ", " << inV.mF64[1] << ", " << inV.mF64[2];266return inStream;267}268269/// Internal helper function that checks that W is equal to Z, so e.g. dividing by it should not generate div by 0270JPH_INLINE void CheckW() const;271272/// Internal helper function that ensures that the Z component is replicated to the W component to prevent divisions by zero273static JPH_INLINE Type sFixW(TypeArg inValue);274275/// Representations of true and false for boolean operations276inline static const double cTrue = BitCast<double>(~uint64(0));277inline static const double cFalse = 0.0;278279union280{281Type mValue;282double mF64[4];283};284};285286static_assert(std::is_trivial<DVec3>(), "Is supposed to be a trivial type!");287288JPH_NAMESPACE_END289290#include "DVec3.inl"291292293