123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- // Description : Common vector class
- #pragma once
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- // class Vec4
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- struct Vec4
- {
- using value_type = f32;
- enum
- {
- component_count = 4
- };
- f32 x, y, z, w;
- #if defined(_DEBUG)
- ILINE Vec4()
- {
- if constexpr (sizeof(f32) == 4)
- {
- uint32* p = alias_cast<uint32*>(&x);
- p[0] = F32NAN;
- p[1] = F32NAN;
- p[2] = F32NAN;
- p[3] = F32NAN;
- }
- }
- #else
- ILINE Vec4() {}
- #endif
- ILINE Vec4(f32 vx, f32 vy, f32 vz, f32 vw) { x = vx; y = vy; z = vz; w = vw; }
- ILINE Vec4(const Vec3_tpl<f32>& v, f32 vw) { x = v.x; y = v.y; z = v.z; w = vw; }
- explicit ILINE Vec4(f32 m) { x = y = z = w = m; }
- ILINE Vec4(type_zero) { x = y = z = w = f32(0); }
- ILINE void operator () (f32 vx, f32 vy, f32 vz, f32 vw) { x = vx; y = vy; z = vz; w = vw; }
- ILINE void operator () (const Vec3_tpl<f32>& v, f32 vw) { x = v.x; y = v.y; z = v.z; w = vw; }
- ILINE f32& operator [] (int index) { assert(index >= 0 && index <= 3); return ((f32*)this)[index]; }
- ILINE f32 operator [] (int index) const { assert(index >= 0 && index <= 3); return ((f32*)this)[index]; }
- ILINE Vec4& zero() { x = y = z = w = 0; return *this; }
- ILINE bool IsEquivalent(const Vec4& v1, f32 epsilon = VEC_EPSILON) const
- {
- assert(v1.IsValid());
- assert(this->IsValid());
- return ((fabs_tpl(x - v1.x) <= epsilon) && (fabs_tpl(y - v1.y) <= epsilon) && (fabs_tpl(z - v1.z) <= epsilon) && (fabs_tpl(w - v1.w) <= epsilon));
- }
- ILINE Vec4& operator=(const Vec4& src)
- {
- x = src.x;
- y = src.y;
- z = src.z;
- w = src.w;
- return *this;
- }
- ILINE Vec4 operator * (f32 k) const
- {
- return Vec4(x * k, y * k, z * k, w * k);
- }
- ILINE Vec4 operator / (f32 k) const
- {
- k = (f32)1.0 / k;
- return Vec4(x * k, y * k, z * k, w * k);
- }
- ILINE Vec4& operator *= (f32 k)
- {
- x *= k;
- y *= k;
- z *= k;
- w *= k;
- return *this;
- }
- ILINE Vec4& operator /= (f32 k)
- {
- k = (f32)1.0 / k;
- x *= k;
- y *= k;
- z *= k;
- w *= k;
- return *this;
- }
- ILINE void operator += (const Vec4& v)
- {
- x += v.x;
- y += v.y;
- z += v.z;
- w += v.w;
- }
- ILINE void operator -= (const Vec4& v)
- {
- x -= v.x;
- y -= v.y;
- z -= v.z;
- w -= v.w;
- }
- ILINE f32 Dot (const Vec4& vec2) const
- {
- return x * vec2.x + y * vec2.y + z * vec2.z + w * vec2.w;
- }
- ILINE f32 GetLength() const
- {
- return sqrt_tpl(Dot(*this));
- }
- ILINE f32 GetLengthSquared() const
- {
- return Dot(*this);
- }
- bool IsValid() const
- {
- if (!NumberValid(x))
- {
- return false;
- }
- if (!NumberValid(y))
- {
- return false;
- }
- if (!NumberValid(z))
- {
- return false;
- }
- if (!NumberValid(w))
- {
- return false;
- }
- return true;
- }
- /*!
- * functions and operators to compare vector
- *
- * Example:
- * if (v0==v1) dosomething;
- */
- ILINE bool operator==(const Vec4& vec)
- {
- return x == vec.x && y == vec.y && z == vec.z && w == vec.w;
- }
- ILINE bool operator!=(const Vec4& vec) { return !(*this == vec); }
- ILINE friend bool operator ==(const Vec4& v0, const Vec4& v1)
- {
- return ((v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z) && (v0.w == v1.w));
- }
- ILINE friend bool operator !=(const Vec4& v0, const Vec4& v1) { return !(v0 == v1); }
- //! normalize the vector
- // The default Normalize function is in fact "safe". 0 vectors remain unchanged.
- ILINE void Normalize()
- {
- assert(this->IsValid());
- f32 fInvLen = isqrt_safe_tpl(x * x + y * y + z * z + w * w);
- x *= fInvLen;
- y *= fInvLen;
- z *= fInvLen;
- w *= fInvLen;
- }
- //! may be faster and less accurate
- ILINE void NormalizeFast()
- {
- assert(this->IsValid());
- f32 fInvLen = isqrt_fast_tpl(x * x + y * y + z * z + w * w);
- x *= fInvLen;
- y *= fInvLen;
- z *= fInvLen;
- w *= fInvLen;
- }
- };
- //vector addition
- ILINE Vec4 operator + (const Vec4& v0, const Vec4& v1)
- {
- return Vec4(v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w);
- }
- //vector subtraction
- ILINE Vec4 operator - (const Vec4& v0, const Vec4& v1)
- {
- return Vec4(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w);
- }
|