// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0.If a copy of the MPL was not distributed with this // file, You can obtain one at https ://mozilla.org/MPL/2.0/. #ifndef VECTOR3_H #define VECTOR3_H #include "Vector2.h" extern "C" { /// /// 3-dimensional Vector representation (C-style) /// /// This is a C-style implementation /// This uses the right-handed coordinate system. typedef struct Vec3 { protected: /// /// The right axis of the vector /// float x; /// /// The upward axis of the vector /// float y; /// /// The forward axis of the vector /// float z; } Vec3; } namespace Passer { namespace LinearAlgebra { template class SphericalOf; /// @brief A 3-dimensional vector /// @remark This uses a right-handed carthesian coordinate system. /// @note This implementation intentionally avoids the use of x, y and z values. struct Vector3 : Vec3 { friend struct Vec3; public: /// @brief A new 3-dimensional zero vector Vector3(); /// @brief A new 3-dimensional vector /// @param right The distance in the right direction in meters /// @param up The distance in the upward direction in meters /// @param forward The distance in the forward direction in meters Vector3(float right, float up, float forward); /// @brief Convert a 2-dimenstional vector to a 3-dimensional vector /// @param v The vector to convert Vector3(Vector2 v); /// @brief Convert vector in spherical coordinates to 3d carthesian /// coordinates /// @param v The vector to convert Vector3(SphericalOf v); /// @brief Vector3 destructor ~Vector3(); /// @brief A vector with zero for all axis const static Vector3 zero; /// @brief A vector with one for all axis const static Vector3 one; /// @brief A normalized forward-oriented vector const static Vector3 forward; /// @brief A normalized back-oriented vector const static Vector3 back; /// @brief A normalized right-oriented vector const static Vector3 right; /// @brief A normalized left-oriented vector const static Vector3 left; /// @brief A normalized up-oriented vector const static Vector3 up; /// @brief A normalized down-oriented vector const static Vector3 down; // Access functions which are intended to replace the use of XYZ inline float Forward() const { return z; }; inline float Up() const { return y; }; inline float Right() const { return x; }; /// @brief Check if this vector to the given vector /// @param v The vector to check against /// @return true if it is identical to the given vector /// @note This uses float comparison to check equality which may have strange /// effects. Equality on floats should be avoided. bool operator==(const Vector3 &v) const; /// @brief The vector length /// @param v The vector for which you need the length /// @return The vector length static float Magnitude(const Vector3 &v); /// @brief The vector length /// @return The vector length float magnitude() const; /// @brief The squared vector length /// @param v The vector for which you need the length /// @return The squared vector length /// @remark The squared length is computationally simpler than the real /// length. Think of Pythagoras A^2 + B^2 = C^2. This leaves out the /// calculation of the squared root of C. static float SqrMagnitude(const Vector3 &v); /// @brief The squared vector length /// @return The squared vector length /// @remark The squared length is computationally simpler than the real /// length. Think of Pythagoras A^2 + B^2 = C^2. This leaves out the /// calculation of the squared root of C. float sqrMagnitude() const; /// @brief Convert the vector to a length of 1 /// @param v The vector to convert /// @return The vector normalized to a length of 1 static Vector3 Normalize(const Vector3 &v); /// @brief Convert the vector to a length of 1 /// @return The vector normalized to a length of 1 Vector3 normalized() const; /// @brief Negate te vector such that it points in the opposite direction /// @return The negated vector Vector3 operator-() const; /// @brief Subtract a vector from this vector /// @param v The vector to subtract from this vector /// @return The result of this subtraction Vector3 operator-(const Vector3 &v) const; Vector3 operator-=(const Vector3 &v); /// @brief Add a vector to this vector /// @param v The vector to add to this vector /// @return The result of the addition Vector3 operator+(const Vector3 &v) const; Vector3 operator+=(const Vector3 &v); /// @brief Scale the vector using another vector /// @param v1 The vector to scale /// @param v2 A vector with the scaling factors /// @return The scaled vector /// @remark Each component of the vector v1 will be multiplied with the /// matching component from the scaling vector v2. static Vector3 Scale(const Vector3 &v1, const Vector3 &v2); /// @brief Scale the vector uniformly up /// @param f The scaling factor /// @return The scaled vector /// @remark Each component of the vector will be multipled with the same /// factor f. friend Vector3 operator*(const Vector3 &v, float f) { return Vector3(v.x * f, v.y * f, v.z * f); } friend Vector3 operator*(float f, const Vector3 &v) { // return Vector3(f * v.x, f * v.y, f * v.z); return Vector3(v.x * f, v.y * f, v.z * f); } Vector3 operator*=(float f); /// @brief Scale the vector uniformly down /// @param f The scaling factor /// @return The scaled vector /// @remark Each componet of the vector will be divided by the same factor. friend Vector3 operator/(const Vector3 &v, float f) { return Vector3(v.x / f, v.y / f, v.z / f); } friend Vector3 operator/(float f, const Vector3 &v) { // return Vector3(f / v.x, f / v.y, f / v.z); return Vector3(v.x / f, v.y / f, v.z / f); } Vector3 operator/=(float f); /// @brief The distance between two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The distance between the two vectors static float Distance(const Vector3 &v1, const Vector3 &v2); /// @brief The dot product of two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The dot product of the two vectors static float Dot(const Vector3 &v1, const Vector3 &v2); /// @brief The cross product of two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The cross product of the two vectors static Vector3 Cross(const Vector3 &v1, const Vector3 &v2); /// @brief Project the vector on another vector /// @param v The vector to project /// @param n The normal vecto to project on /// @return The projected vector static Vector3 Project(const Vector3 &v, const Vector3 &n); /// @brief Project the vector on a plane defined by a normal orthogonal to the /// plane. /// @param v The vector to project /// @param n The normal of the plane to project on /// @return Teh projected vector static Vector3 ProjectOnPlane(const Vector3 &v, const Vector3 &n); /// @brief The angle between two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The angle between the two vectors /// @remark This reterns an unsigned angle which is the shortest distance /// between the two vectors. Use Vector3::SignedAngle if a signed angle is /// needed. static AngleOf Angle(const Vector3 &v1, const Vector3 &v2); /// @brief The signed angle between two vectors /// @param v1 The starting vector /// @param v2 The ending vector /// @param axis The axis to rotate around /// @return The signed angle between the two vectors static AngleOf SignedAngle(const Vector3 &v1, const Vector3 &v2, const Vector3 &axis); /// @brief Lerp (linear interpolation) between two vectors /// @param v1 The starting vector /// @param v2 The ending vector /// @param f The interpolation distance /// @return The lerped vector /// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value /// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference /// between *v1* and *v2* etc. static Vector3 Lerp(const Vector3 &v1, const Vector3 &v2, float f); }; } // namespace LinearAlgebra } // namespace Passer using namespace Passer::LinearAlgebra; #include "Spherical.h" #endif