#ifndef Vec3_H #define Vec3_H #include "FrameworkMath.h" namespace Framework { template //! A 3D vector class Vec3 { public: T x; //! X component of the vector T y; //! Y component of the vector T z; //! Z component of the vector //! Constructor inline Vec3() {} //! 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 inline Vec3(T x, T y, T z) : x(x), y(y), z(z) {} //! Constructor //! \param vect A vector whose values should be copied inline Vec3(const Vec3& vect) : Vec3(vect.x, vect.y, vect.z) {} //! Scales the vector so that it has length 1 inline Vec3& normalize() { const T length = getLength(); x /= length; y /= length; z /= length; return *this; } //! Swaps the values of the vector with those of another vector //! \param vect The other vector inline Vec3& swap(Vec3& vect) { const Vec3 tmp = vect; vect = *this; *this = tmp; return *this; } //! Calculates an angle between this and another vector inline float angle(Vec3 vect) { return lowPrecisionACos( (float)(*this * vect) / ((float)getLength() * (float)vect.getLength())); } //! Copies the values of another vector //! \param r The other vector inline Vec3 operator=(const Vec3& r) { x = r.x; y = r.y; z = r.z; return *this; } //! Adds another vector to this one //! \param r The other vector inline Vec3 operator+=(const Vec3& r) { x += r.x; y += r.y; z += r.z; return *this; } //! Subtracts another vector from this one //! \param r The other vector inline Vec3 operator-=(const Vec3& r) { x -= r.x; y -= r.y; z -= r.z; return *this; } //! Scales this vector //! \param r The factor inline Vec3 operator*=(const T& r) { x *= r; y *= r; z *= r; return *this; } //! Scales this vector by 1/factor //! \param r The factor inline Vec3 operator/=(const T& r) { x /= r; y /= r; z /= r; return *this; } //! Calculates the square of the distance between two vectors //! \param p The other vector inline T abstandSq(const Vec3& p) const { return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) + (z - p.z) * (z - p.z); } //! Calculates the distance between two vectors //! \param p The other vector inline T abstand(const Vec3& p) const { return sqrt(abstandSq(p)); } //! Returns a new vector that is the negation of this one inline Vec3 operator-() const { return {-x, -y, -z}; } template //! Converts the vector type to another inline operator Vec3() const { return {(T2)x, (T2)y, (T2)z}; } //! 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 Vec3& r) const { return x * r.x + y * r.y + z * r.z; } //! Calculates the sum of two vectors //! \param r The other vector inline Vec3 operator+(const Vec3& r) const { return Vec3(*this) += r; } //! Subtracts two vectors from each other //! \param r The other vector inline Vec3 operator-(const Vec3& r) const { return Vec3(*this) -= r; } //! Scales the vector without modifying it //! \param r The factor inline Vec3 operator*(const T& r) const { return Vec3(*this) *= r; } //! Scales the vector by 1/factor without modifying it //! \param r The factor inline Vec3 operator/(const T& r) const { return Vec3(*this) /= r; } //! Checks two vectors for equality //! \param r The other vector inline bool operator==(const Vec3& r) const { return x == r.x && y == r.y && z == r.z; } //! Checks two vectors for inequality //! \param r The other vector inline bool operator!=(const Vec3& r) const { return !(*this == r); } //! Returns the cross product between this and another vector //! \param b The other vector inline Vec3 crossProduct(const Vec3& b) const { return Vec3( y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); } inline Vec3& rotateY(float radian) { const float cosTheta = lowPrecisionCos(radian); const float sinTheta = lowPrecisionSin(radian); float x = cosTheta * this->x + sinTheta * this->z; float z = -sinTheta * this->x + cosTheta * this->z; this->x = (T)x; this->z = (T)z; return *this; } inline Vec3& rotateX(float radian) { const float cosTheta = lowPrecisionCos(radian); const float sinTheta = lowPrecisionSin(radian); float y = cosTheta * this->y + -sinTheta * this->z; float z = sinTheta * this->y + cosTheta * this->z; this->y = (T)y; this->z = (T)z; return *this; } inline Vec3& rotateZ(float radian) { const float cosTheta = lowPrecisionCos(radian); const float sinTheta = lowPrecisionSin(radian); float x = cosTheta * this->x + -sinTheta * this->y; float y = sinTheta * this->x + cosTheta * this->y; this->x = (T)x; this->y = (T)y; return *this; } }; } // namespace Framework #endif