31#ifndef DVD_CORE_MATH_MATH_VECTORS_INL_
32#define DVD_CORE_MATH_MATH_VECTORS_INL_
44 return _mm_movemask_ps( _mm_cmpeq_ps( a, b ) ) != 0xF;
50 const auto eps = _mm_set1_ps( epsilon );
52 const auto abd = _mm_andnot_ps( _mm_set1_ps( -0.0f ), _mm_sub_ps( a, b ) );
55 return _mm_movemask_ps( _mm_cmplt_ps( abd, eps ) ) != 0xF;
61 __m128 r = _mm_mul_ps( a, b );
62 r = _mm_add_ps( _mm_movehl_ps( r, r ), r );
63 r = _mm_add_ss( _mm_shuffle_ps( r, r, 1 ), r );
70 a = _mm_mul_ps( a, b );
71 b = _mm_hadd_ps( a, a );
72 return _mm_hadd_ps( b, b );
82 return v1.x * v2.y - v1.y * v2.x;
104 template <
typename T>
111 template <
typename T>
114 return a.x * b.x + a.y * b.y;
117 template <
typename T>
124 template <
typename T>
134 template <
typename T>
137 return vector.normalize();
140 template <
typename T>
147 template <
typename T>
154 template <
typename T>
157 return a.x * b.x + a.y * b.y + a.z * b.z;
161 template <
typename T>
164 return vec3<T>( v1.y * v2.z - v1.z * v2.y,
165 v1.z * v2.x - v1.x * v2.z,
166 v1.x * v2.y - v1.y * v2.x );
169 template <
typename T>
172 constexpr F32 tolerance = 1e-6f;
173 return SQUARED(
Dot( v1, v2 ) ) <
Dot( v1, v1 ) *
Dot( v2, v2 ) * tolerance;
176 template <
typename T>
179 return vec3<T>( v.z, v.y, v.x );
182 template <
typename T>
185 T min = std::abs( v.x );
188 if ( std::abs( v.y ) < min )
190 min = std::abs( v.y );
194 if ( std::abs( v.z ) < min )
199 return Cross( v, cardinalAxis );
205 return direction *
Dot( in, direction );
208 template <
typename T>
215 template <
typename T>
219 v2 -= v2.projectToNorm( v1 );
221 v3 -= v3.projectToNorm( v1 );
222 v3 -= v3.projectToNorm( v2 );
226 template <
typename T>
237 template <
typename T>
244 template <
typename T>
247 return vec4<T>( std::min( v1.x, v2.x ), std::min( v1.y, v2.y ),
248 std::min( v1.z, v2.z ), std::min( v1.w, v2.w ) );
251 template <
typename T>
254 return vec4<T>( std::max( v1.x, v2.x ), std::max( v1.y, v2.y ),
255 std::max( v1.z, v2.z ), std::max( v1.w, v2.w ) );
258 template <
typename T>
261 return vector.normalize();
264 template <
typename T>
270 template <
typename T>
277 template <
typename T>
288 template <
typename T>
300 template <
typename T>
313 template <
typename T>
323 template <
typename T>
330 template <
typename T>
337 template <
typename T>
340 const vec2 d = v - *
this;
345 template <
typename T>
348 const T l = this->length();
359 template <
typename T>
362 return std::min( x, y );
365 template <
typename T>
368 return std::max( x, y );
372 template <
typename T>
373 template <
typename U>
requires std::is_pod_v<U>
376 return COMPARE( this->x, v.x ) &&
381 template <
typename T>
382 template <
typename U>
requires std::is_pod_v<U>
391 template <
typename T>
394 const vec2 v( vB - vA );
399 template <
typename T>
402 return this->x * v.
x + this->y * v.
y;
406 template <
typename T>
409 set(
static_cast<T
>(std::roundf( this->x )),
static_cast<T
>(std::roundf( this->y )) );
414 template <
typename T>
417 v[0] =
static_cast<T
>(this->_v[0]);
418 v[1] =
static_cast<T
>(this->_v[1]);
423 template <
typename T>
426 return (vB - vA) * this->projectionOnLine( vA, vB ) + vA;
431 template <
typename T>
434 const T factor = this->projectionOnLine( vA, vB );
436 if ( factor <= 0 )
return vA;
437 if ( factor >= 1 )
return vB;
439 return (vB - vA) * factor + vA;
443 template <
typename T>
446 set(
Lerp( *
this, v, factor ) );
450 template <
typename T>
453 set(
Lerp( *
this, v, factor ) );
457 template <
typename T,
typename U>
requires std::is_pod_v<U>
460 return {
Lerp( u.x, v.
x, factor ),
Lerp( u.y, v.
y, factor ) };
464 template <
typename T>
467 return {
Lerp( u.x, v.
x, factor.x ),
Lerp( u.y, v.
y, factor.y ) };
475 template <
typename T>
476 template <
typename U>
requires std::is_pod_v<U>
485 template <
typename T>
486 template <
typename U>
requires std::is_pod_v<U>
495 template <
typename T>
501 template <
typename T>
502 template <
typename U>
requires std::is_pod_v<U>
505 return SQUARED( dot( other ) ) <=
SQUARED( epsilon ) * lengthSquared() * other.lengthSquared();
508 template <
typename T>
515 template <
typename T>
518 const T l = this->length();
530 template <
typename T>
533 return std::min( x, std::min( y, z ) );
537 template <
typename T>
540 return std::max( x, std::max( y, z ) );
544 template <
typename T>
547 this->x = v1.y * v2.z - v1.z * v2.y;
548 this->y = v1.z * v2.x - v1.x * v2.z;
549 this->z = v1.x * v2.y - v1.y * v2.x;
553 template <
typename T>
556 this->cross( *
this, v2 );
560 template <
typename T>
567 template <
typename T>
574 template <
typename T>
577 const vec3 d{ v.
x - this->x, v.
y - this->y, v.z - this->z };
582 template <
typename T>
585 const T angle =
static_cast<T
>(std::abs( std::acos( this->dot( v ) / (this->length() * v.
length()) ) ));
590 template <
typename T>
593 return Normalized(
vec3( u.x - this->x, u.y - this->y, u.z - this->z ) );
596 template <
typename T>
599 return direction * dot( direction );
603 template <
typename T>
611 template <
typename T>
614 set(
Lerp( *
this, v, factor ) );
619 template <
typename T>
622 set(
Lerp( *
this, v, factor ) );
626 template <
typename T>
629 this->y =
static_cast<T
>(std::cos( radians ) * this->y +
630 std::sin( radians ) * this->z);
631 this->z =
static_cast<T
>(-std::sin( radians ) * this->y +
632 std::cos( radians ) * this->z);
636 template <
typename T>
639 this->x =
static_cast<T
>(std::cos( radians ) * this->x -
640 std::sin( radians ) * this->z);
641 this->z =
static_cast<T
>(std::sin( radians ) * this->x +
642 std::cos( radians ) * this->z);
646 template <
typename T>
649 this->x =
static_cast<T
>(std::cos( radians ) * this->x +
650 std::sin( radians ) * this->y);
651 this->y =
static_cast<T
>(-std::sin( radians ) * this->x +
652 std::cos( radians ) * this->y);
656 template <
typename T>
659 set(
static_cast<T
>(std::roundf( this->x )),
660 static_cast<T
>(std::roundf( this->y )),
661 static_cast<T
>(std::roundf( this->z )) );
665 template <
typename T>
668 std::swap( this->x, iv.x );
669 std::swap( this->y, iv.y );
670 std::swap( this->z, iv.z );
674 template <
typename T>
677 std::swap( this->x, iv->x );
678 std::swap( this->y, iv->y );
679 std::swap( this->z, iv->z );
684 template <
typename T>
687 v[0] =
static_cast<T
>(this->_v[0]);
688 v[1] =
static_cast<T
>(this->_v[1]);
689 v[2] =
static_cast<T
>(this->_v[2]);
694 template <
typename T>
697 return vec3( vp1.x - vp2.x, vp1.y - vp2.y, vp1.z - vp2.z );
702 template <
typename T>
705 return (vB - vA) * this->projectionOnLine( vA, vB ) + vA;
710 template <
typename T>
713 const T factor = this->projectionOnLine( vA, vB );
715 if ( factor <= 0.0f )
return vA;
717 if ( factor >= 1.0f )
return vB;
719 return (vB - vA) * factor + vA;
723 template <
typename T,
typename U>
requires std::is_pod_v<U>
726 return {
Lerp( u.x, v.
x, factor ),
Lerp( u.y, v.
y, factor ),
Lerp( u.z, v.z, factor ) };
730 template <
typename T>
733 return {
Lerp( u.x, v.
x, factor.x ),
Lerp( u.y, v.
y, factor.y ),
Lerp( u.z, v.z, factor.z ) };
736 template <
typename T>
742 template <
typename T>
745 return vec3<T>( std::min( v1.x, v2.x ), std::min( v1.y, v2.y ), std::min( v1.z, v2.z ) );
748 template <
typename T>
751 return vec3<T>( std::max( v1.x, v2.x ), std::max( v1.y, v2.y ), std::max( v1.z, v2.z ) );
761 return vec4<F32>( _mm_sub_ps( _reg._reg, _mm_set1_ps( _f ) ) );
768 _reg.
_reg = _mm_sub_ps( _reg._reg, _mm_set1_ps( _f ) );
776 return vec4<F32>( _mm_add_ps( _reg._reg, _mm_set1_ps( _f ) ) );
783 _reg.
_reg = _mm_add_ps( _reg._reg, _mm_set1_ps( _f ) );
791 return vec4<F32>( _mm_mul_ps( _reg._reg, _mm_set1_ps( _f ) ) );
798 _reg.
_reg = _mm_mul_ps( _reg._reg, _mm_set1_ps( _f ) );
806 return vec4<F32>( _mm_div_ps( _reg._reg, _mm_set1_ps( _f ) ) );
813 _reg.
_reg = _mm_div_ps( _reg._reg, _mm_set1_ps( _f ) );
821 return vec4<F32>( _mm_add_ps( _reg._reg, v._reg._reg ) );
828 _reg.
_reg = _mm_add_ps( _reg._reg, v._reg._reg );
836 return vec4<F32>( _mm_sub_ps( _reg._reg, v._reg._reg ) );
843 _reg.
_reg = _mm_sub_ps( _reg._reg, v._reg._reg );
851 return vec4<F32>( _mm_div_ps( _reg._reg, v._reg._reg ) );
858 _reg.
_reg = _mm_div_ps( _reg._reg, v._reg._reg );
866 return vec4<F32>( _mm_mul_ps( _reg._reg, v._reg._reg ) );
873 _reg.
_reg = _mm_mul_ps( _reg._reg, v._reg._reg );
878 template <
typename T>
879 template <
typename U>
requires std::is_pod_v<U>
898 template <
typename T>
899 template <
typename U>
requires std::is_pod_v<U>
902 if constexpr ( std::is_same<T, U>::value && std::is_same<U, F32>::value )
916 template <
typename T>
919 set(
static_cast<T
>(std::roundf( this->x )),
static_cast<T
>(std::roundf( this->y )),
920 static_cast<T
>(std::roundf( this->z )),
static_cast<T
>(std::roundf( this->w )) );
924 template <
typename T>
927 std::swap( this->x, iv->x );
928 std::swap( this->y, iv->y );
929 std::swap( this->z, iv->z );
930 std::swap( this->w, iv->w );
936 std::swap( _reg._reg, iv->_reg._reg );
940 template <
typename T>
947 template <
typename T>
950 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
956 return _mm_cvtss_f32(
AVX::DotSimd( a._reg._reg, b._reg._reg ) );
960 template <
typename T>
969 return Divide::Sqrt<F32>(
AVX::DotSimd( _reg._reg, _reg._reg ) );
973 template <
typename T>
976 return Dot( *
this, *
this );
980 template <
typename T>
983 return direction * dot( direction );
987 template <
typename T>
990 const T l = this->length();
1004 _reg.
_reg = _mm_mul_ps( _reg._reg, _mm_rsqrt_ps(
AVX::SimpleDot( _reg._reg, _reg._reg ) ) );
1009 template <
typename T>
1010 template <
typename U>
requires std::is_pod_v<U>
1013 return SQUARED( dot( other ) ) <=
SQUARED( epsilon ) * lengthSquared() * other.lengthSquared();
1017 template <
typename T>
1020 return std::min( x, std::min( y, std::min( z, w ) ) );
1024 template <
typename T>
1027 return std::max( x, std::max( y, std::min( z, w ) ) );
1031 template <
typename T>
1034 set(
Lerp( *
this, v, factor ) );
1039 template <
typename T>
1042 set(
Lerp( *
this, v, factor ) );
1045 template <
typename T>
1048 return {
Lerp( u.x, v.
x, factor ),
Lerp( u.y, v.
y, factor ),
Lerp( u.z, v.z, factor ),
Lerp( u.w, v.w, factor ) };
1052 template <
typename T>
1055 return {
Lerp( u.x, v.
x, factor.x ),
Lerp( u.y, v.
y, factor.y ),
Lerp( u.z, v.z, factor.z ),
Lerp( u.w, v.w, factor.w ) };
1058 template <
typename Type>
1064 template <
typename Type>
1071 template <
typename Type>
bool compare(vec2< U > v) const noexcept
compare 2 vectors
void lerp(const vec2 &v, T factor) noexcept
lerp between this and the specified vector by the specified amount
T minComponent() const noexcept
get the smallest value of X or Y
vec2 closestPointOnSegment(const vec2 &vA, const vec2 &vB)
return the closest point on the line segment defined between the 2 points (A, B) and this vector
vec2 & normalize() noexcept
convert the vector to unit length
T distance(const vec2 &v) const
compute the vector's distance to another specified vector
T maxComponent() const noexcept
get the largest value of X or Y
T distanceSquared(const vec2 &v) const noexcept
compute the vector's squared distance to another specified vector
vec2 closestPointOnLine(const vec2 &vA, const vec2 &vB)
return the closest point on the line defined by the 2 points (A, B) and this vector
T lengthSquared() const noexcept
return the squared distance of the vector
void round()
round both values
void get(T *v) const
export the vector's components in the first 2 positions of the specified array
T projectionOnLine(const vec2 &vA, const vec2 &vB) const
project this vector on the line defined by the 2 points(A, B)
T dot(const vec2 &v) const noexcept
calculate the dot product between this vector and the specified one
T angle(vec3 &v) const
returns the angle in radians between '*this' and 'v'
T dot(const vec3 &v) const noexcept
calculate the dot product between this vector and the specified one
vec3 & normalize() noexcept
transform the vector to unit length
void lerp(const vec3 &v, T factor) noexcept
lerp between this and the specified vector by the specified amount
T length() const noexcept
return the vector's length
T maxComponent() const noexcept
get the largest value of X,Y or Z
T projectionOnLine(const vec3 &vA, const vec3 &vB) const
project this vector on the line defined by the 2 points(A, B)
vec3 closestPointOnLine(const vec3 &vA, const vec3 &vB)
void swap(vec3 &iv) noexcept
swap the components of this vector with that of the specified one
T minComponent() const noexcept
get the smallest value of X,Y or Z
void rotateX(D64 radians)
rotate this vector on the X axis
T lengthSquared() const noexcept
return the squared distance of the vector
vec3 direction(const vec3 &u) const noexcept
get the direction vector to the specified point
void cross(const vec3 &v1, const vec3 &v2) noexcept
set this vector to be equal to the cross of the 2 specified vectors
vec3 closestPointOnSegment(const vec3 &vA, const vec3 &vB)
void rotateZ(D64 radians)
rotate this vector on the Z axis
void get(T *v) const noexcept
bool isUniform(F32 tolerance=0.0001f) const noexcept
uniform vector: x = y = z
void rotateY(D64 radians)
rotate this vector on the Y axis
T distanceSquared(const vec3 &v) const noexcept
compute the vector's squared distance to another specified vector
vec3 projectToNorm(const vec3< T > &direction) noexcept
project this vector onto the given direction
bool compare(const vec3< U > &v) const noexcept
compare 2 vectors
vec3 vector(const vec3 &vp1, const vec3 &vp2) const noexcept
bool isPerpendicular(const vec3< U > &other, F32 epsilon=EPSILON_F32) const noexcept
The current vector is perpendicular to the specified one within epsilon.
T distance(const vec3 &v) const noexcept
compute the vector's distance to another specified vector
void round()
round all three values
vec4 & operator+=(U _f) noexcept
void set(const T *v) noexcept
set the 4 components of the vector manually using a source pointer to a (large enough) array
vec4 operator-() const noexcept
vec4 projectToNorm(const vec4< T > &direction)
project this vector onto the given direction
vec4 operator+(U _f) const noexcept
T maxComponent() const noexcept
get the largest value of X,Y,Z or W
vec4 & operator-=(U _f) noexcept
vec4 operator*(U _f) const noexcept
vec4 & operator*=(U _f) noexcept
T lengthSquared() const noexcept
return the squared distance of the vector
void round() noexcept
round all four values
void swap(vec4 *iv) noexcept
swap the components of this vector with that of the specified one
vec4 & operator/=(U _f) noexcept
T minComponent() const noexcept
get the smallest value of X,Y,Z or W
void lerp(const vec4 &v, T factor) noexcept
lerp between this and the specified vector by the specified amount
bool compare(const vec4< U > &v) const noexcept
compare 2 vectors
T length() const noexcept
return the vector's length
vec4 & normalize() noexcept
transform the vector to unit length
bool isPerpendicular(const vec4< U > &other, F32 epsilon=EPSILON_F32) const noexcept
The current vector is perpendicular to the specified one within epsilon.
T dot(const vec4 &v) const noexcept
calculate the dot product between this vector and the specified one
vec4 operator/(U _f) const noexcept
__m128 SimpleDot(__m128 a, __m128 b) noexcept
__m128 DotSimd(const __m128 &a, const __m128 &b) noexcept
bool Fneq128(__m128 const &a, __m128 const &b) noexcept
Handle console commands that start with a forward slash.
vec2< T > Normalized(vec2< T > vector) noexcept
vec3< T > Abs(const vec3< T > &vector) noexcept
bool IS_ZERO(const T X) noexcept
T Lerp(T v1, T v2, U t) noexcept
vec2< T > operator*(T fl, vec2< T > v) noexcept
multiply a vector by a value
constexpr T SQUARED(T input) noexcept
static const vec3< F32 > WORLD_X_AXIS
vec3< T > Min(const vec3< T > &v1, const vec3< T > &v2) noexcept
static const vec3< F32 > WORLD_Z_AXIS
vec2< T > Inverse(vec2< T > v) noexcept
vec3< T > Perpendicular(const vec3< T > &v) noexcept
T Dot(vec2< T > a, vec2< T > b) noexcept
general vec2 dot product
constexpr F32 EPSILON_F32
eastl::vector< Type > vector
vec3< T > AreOrthogonal(const vec3< T > &v1, const vec3< T > &v2) noexcept
vec3< T > Max(const vec3< T > &v1, const vec3< T > &v2) noexcept
vec2< T > Normalize(vec2< T > &vector) noexcept
void OrthoNormalize(vec2< T > &n, vec2< T > &u) noexcept
bool COMPARE_TOLERANCE(const T X, const U Y, const T TOLERANCE) noexcept
::value constexpr T CLAMPED(T n, T min, T max) noexcept
vec2< T > Cross(vec2< T > v1, vec2< T > v2) noexcept
general vec2 cross function
bool COMPARE(T X, U Y) noexcept
vec3< T > ProjectToNorm(const vec3< T > &in, const vec3< T > &direction)
vec2< T > Clamped(vec2< T > v, vec2< T > min, vec2< T > max) noexcept
static const vec3< F32 > WORLD_Y_AXIS