#pragma once namespace Framework { template //! A 3D vector class Vec4 { public: T x; //! X component of the vector T y; //! Y component of the vector T z; //! Z component of the vector T w; //! W component of the vector //! Constructor inline Vec4() {} //! Constructor //! \param x The X component of the new vector //! \param y The Y component of the new vector //! \param z The Z component of the new vector //! \param w The W component of the new vector inline Vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {} //! Constructor //! \param vect A vector whose values should be copied inline Vec4(const Vec4& vect) : Vec4(vect.x, vect.y, vect.z, vect.w) {} //! Scales the vector so that it has length 1 inline Vec4& normalize() { const T length = getLength(); x /= length; y /= length; z /= length; w /= length; return *this; } //! Swaps the values of the vector with those of another vector //! \param vect The other vector inline Vec4& swap(Vec4& vect) { const Vec4 tmp = vect; vect = *this; *this = tmp; return *this; } //! Calculates an angle between this and another vector inline float angle(Vec4 vect) { return lowPrecisionACos( (float)(*this * vect) / ((float)getLength() * (float)vect.getLength())); } //! Copies the values of another vector //! \param r The other vector inline Vec4 operator=(const Vec4& r) { x = r.x; y = r.y; z = r.z; w = r.w; return *this; } //! Adds another vector to this one //! \param r The other vector inline Vec4 operator+=(const Vec4& r) { x += r.x; y += r.y; z += r.z; w += r.w; return *this; } //! Subtracts another vector from this one //! \param r The other vector inline Vec4 operator-=(const Vec4& r) { x -= r.x; y -= r.y; z -= r.z; w -= r.w; return *this; } //! Scales this vector //! \param r The factor inline Vec4 operator*=(const T& r) { x *= r; y *= r; z *= r; w *= r; return *this; } //! Scales this vector by 1/factor //! \param r The factor inline Vec4 operator/=(const T& r) { x /= r; y /= r; z /= r; w /= r; return *this; } //! Calculates the square of the distance between two vectors //! \param p The other vector inline T distanceSq(const Vec4& p) const { return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) + (z - p.z) * (z - p.z) + (w - p.w) * (w - p.w); } //! Calculates the distance between two vectors //! \param p The other vector inline T distance(const Vec4& p) const { return sqrt(distanceSq(p)); } //! Returns a new vector that is the negation of this one inline Vec4 operator-() const { return {-x, -y, -z, -w}; } template //! Converts the vector type to another inline operator Vec4() const { return {(T2)x, (T2)y, (T2)z, (T2)w}; } //! Calculates the square of the vector's length inline T getLengthSq() const { return *this * *this; } //! Calculates the length of the vector inline T getLength() const { return (T)sqrt(getLengthSq()); } //! Calculates the dot product between two vectors //! \param r The other vector inline T operator*(const Vec4& r) const { return x * r.x + y * r.y + z * r.z + w * r.w; } //! Calculates the sum of two vectors //! \param r The other vector inline Vec4 operator+(const Vec4& r) const { return Vec4(*this) += r; } //! Subtracts two vectors from each other //! \param r The other vector inline Vec4 operator-(const Vec4& r) const { return Vec4(*this) -= r; } //! Scales the vector without modifying it //! \param r The factor inline Vec4 operator*(const T& r) const { return Vec4(*this) *= r; } //! Scales the vector by 1/factor without modifying it //! \param r The factor inline Vec4 operator/(const T& r) const { return Vec4(*this) /= r; } //! Checks two vectors for equality //! \param r The other vector inline bool operator==(const Vec4& r) const { return x == r.x && y == r.y && z == r.z && w == r.w; } //! Checks two vectors for inequality //! \param r The other vector inline bool operator!=(const Vec4& r) const { return !(*this == r); } //! Returns the cross product between this and another vector //! \param b The other vector inline Vec4 crossProduct(const Vec4& b) const { return Vec4(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x, w * b.w - w * b.w); } }; } // namespace Framework