// 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/. #pragma once extern "C" { /// <summary> /// 3-dimensional Vector representation /// </summary> /// This is a C-style implementation /// This uses the right-handed coordinate system. typedef struct Vec3 { /// <summary> /// The right axis of the vector /// </summary> float x; /// <summary> /// The upward axis of the vector /// </summary> float y; /// <summary> /// The forward axis of the vector /// </summary> float z; } Vec3; } /// <summary> /// A 3-dimensional vector /// </summary> /// This uses the right-handed coordinate system. struct Vector3 : Vec3 { public: /// <summary> /// Create a new 3-dimensinal zero vector /// </summary> Vector3(); /// <summary> /// Create a new 3-dimensional vector /// </summary> /// <param name="x">x axis value</param> /// <param name="y">y axis value</param> /// <param name="z">z axis value</param> Vector3(float x, float y, float z); /// <summary> /// Create a vector from C-style Vec3 /// </summary> /// <param name="v">The C-style Vec</param> Vector3(Vec3 v); ~Vector3(); /// <summary> /// A vector with zero for all axis /// </summary> const static Vector3 zero; /// <summary> /// A vector with values (1, 0, 0) /// </summary> const static Vector3 right; /// <summary> /// A vector3 with values (-1, 0, 0) /// </summary> const static Vector3 left; /// <summary> /// A vector with values (0, 1, 0) /// </summary> const static Vector3 up; /// <summary> /// A vector with values (0, -1, 0) /// </summary> const static Vector3 down; /// <summary> /// A vector with values (0, 0, 1) /// </summary> const static Vector3 forward; /// <summary> /// A vector with values (0, 0, -1) /// </summary> const static Vector3 back; /// <summary> /// The length of a vector /// </summary> /// <param name="vector">The vector for which you need the length</param> /// <returns>The length of the given vector</returns> static float Magnitude(const Vector3& vector); /// <summary> /// The length of this vector /// </summary> /// <returns>The length of this vector</returns> float magnitude() const; /// <summary> /// The squared length of a vector /// </summary> /// <param name="vector">The vector for which you need the squared length</param> /// <returns>The squatred length</returns> /// 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& vector); /// <summary> /// The squared length of this vector /// </summary> /// <returns>The squared length</returns> /// 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; /// <summary> /// Connvert a vector to a length of 1 /// </summary> /// <param name="vector">The vector to convert</param> /// <returns>The vector with length 1</returns> static Vector3 Normalize(Vector3 vector); /// <summary> /// Convert the vector to a length of a /// </summary> /// <returns>The vector with length 1</returns> Vector3 normalized() const; /// <summary> /// Negate the vector /// </summary> /// <returns>The negated vector</returns> /// This will result in a vector pointing in the opposite direction Vector3 operator -(); /// <summary> /// Subtract a vector from this vector /// </summary> /// <param name="vector">The vector to subtract from this vector</param> /// <returns>The result of the subtraction</returns> Vector3 operator -(const Vector3& vector) const; /// <summary> /// Add another vector to this vector /// </summary> /// <param name="vector2">The vector to add</param> /// <returns>The result of adding the vector</returns> Vector3 operator +(const Vector3& vector2) const; /// <summary> /// Scale a vector using another vector /// </summary> /// <param name="vector1">The vector to scale</param> /// <param name="vector2">A vector with scaling factors</param> /// <returns>The scaled vector</returns> /// Each component of the vector v1 will be multiplied with the /// component from the scaling vector v2. static Vector3 Scale(const Vector3& vector1, const Vector3& vector2); /// <summary> /// Scale a vector uniformly up /// </summary> /// <param name="factor">The scaling factor</param> /// <returns>The scaled vector</returns> /// Each component of the vector will be multipled with the same factor. Vector3 operator *(float factor) const; /// <summary> /// Scale a vector uniformy down /// </summary> /// <param name="factor">The scaling factor</param> /// <returns>The scaled vector</returns> /// Each componet of the vector will be divided by the same factor. Vector3 operator /(const float& factor); /// <summary> /// The dot product of two vectors /// </summary> /// <param name="vector1">The first vector</param> /// <param name="vector2">The second vector</param> /// <returns>The dot product of the two vectors</returns> static float Dot(const Vector3& vector1, const Vector3& vector2); /// <summary> /// Check is this vector is equal to the given vector /// </summary> /// <param name="vector">The vector to check against</param> /// <returns>True if it is identical to the given vector</returns> /// Note this uses float comparison to check equality which /// may have strange effects. Equality on float should be avoided. bool operator ==(const Vector3& vector); /// <summary> /// The distance between two vectors /// </summary> /// <param name="vector1">The first vector</param> /// <param name="vector2">The second vectors</param> /// <returns>The distance between the two vectors</returns> static float Distance(const Vector3& vector1, const Vector3& vector2); /// <summary> /// The cross product of two vectors /// </summary> /// <param name="vector1">The first vector</param> /// <param name="vector2">The second vector</param> /// <returns>The cross product of the two vectors</returns> static Vector3 Cross(const Vector3& vector1, const Vector3& vector2); // Projects a vector onto another vector. /// <summary> /// Project a vector on another vector /// </summary> /// <param name="vector">The vector to project</param> /// <param name="onNormal">The normal vector to project on</param> /// <returns>The projected vector</returns> static Vector3 Project(Vector3 vector, Vector3 onNormal); /// <summary> /// Projects a vector onto a plane defined by a normal orthogonal to the plane. /// </summary> /// <param name="vector">The vector to project</param> /// <param name="planeNormal">The normal of the plane to project on</param> /// <returns></returns> static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal); /// <summary> /// Calculate the angle between two vectors /// </summary> /// <param name="vector1">The first vector</param> /// <param name="vector2">The second vector</param> /// <returns></returns> /// This reterns an unsigned angle which is the shortest distance /// between the two vectors. Use Vector3::SignedAngle if a /// signed angle is needed. static float Angle(Vector3 vector1, Vector3 vector2); /// <summary> /// Calculate the angle between two vectors rotation around an axis. /// </summary> /// <param name="from">The starting vector</param> /// <param name="to">The ending vector</param> /// <param name="axis">The axis to rotate around</param> /// <returns>The signed angle</returns> static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis); };