diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 5f14f8be7..0ab620406 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -73,8 +73,8 @@ namespace Nz String ToString() const; - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; const Vector3& operator+() const; Vector3 operator-() const; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 9a04ad97b..a1807c902 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -13,36 +13,83 @@ namespace Nz { + /*! + * \class Nz::Vector2 + * \brief Math class that represents an element of the three dimensional vector space + * + * \remark The basis is said to be "right-hand". It means that with your right hand, the thumb is X positive, the index finger Y positive and the middle finger (pointing to you) Z positive + */ + + /*! + * \brief Constructs a Vector3 object from its coordinates + * + * \param X X component + * \param Y Y component + * \param Z Z component + */ + template Vector3::Vector3(T X, T Y, T Z) { Set(X, Y, Z); } + /*! + * \brief Constructs a Vector3 object from a component and a Vector2 + * + * \param X X component + * \param vec vec.X = Y component and vec.y = Z component + */ + template Vector3::Vector3(T X, const Vector2& vec) { Set(X, vec); } + /*! + * \brief Constructs explicitely a Vector3 object from its "scale" + * + * \param scale X component = Y component = Z component + */ + template Vector3::Vector3(T scale) { Set(scale); } + /*! + * \brief Constructs a Vector3 object from an array of three elements + * + * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component + */ + template Vector3::Vector3(const T vec[3]) { Set(vec); } + /*! + * \brief Constructs a Vector3 object from a Vector2 and a component + * + * \param vec vec.X = X component and vec.y = Y component + * \param Z Z component + */ + template Vector3::Vector3(const Vector2& vec, T Z) { Set(vec, Z); } + /*! + * \brief Constructs a Vector3 object from another type of Vector3 + * + * \param vec Vector of type U to convert to type T + */ + template template Vector3::Vector3(const Vector3& vec) @@ -50,18 +97,46 @@ namespace Nz Set(vec); } + /*! + * \brief Constructs a Vector3 object from a Vector4 + * + * \param vec Vector4 where only the first three components are taken + */ + template Vector3::Vector3(const Vector4& vec) { Set(vec); } + /*! + * \brief Calculates the absolute dot (scalar) product with two vectors + * \return The dot product with absolutes values on each component + * + * \param vec The other vector to calculate the absolute dot product with + * + * \see DotProduct + */ + template T Vector3::AbsDotProduct(const Vector3& vec) const { return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z); } + /*! + * \brief Calculates the angle between two vectors in orthonormal basis + * \return The angle unit depends of NAZARA_MATH_ANGLE_RADIAN in the range 0..pi + * + * \param vec The other vector to measure the angle with + * + * \remark The vectors do not need to be normalised + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + * + * \see NormalizeAngle + */ + template T Vector3::AngleBetween(const Vector3& vec) const { @@ -78,46 +153,103 @@ namespace Nz } #endif - T alpha = DotProduct(vec)/divisor; + T alpha = DotProduct(vec) / divisor; return FromRadians(std::acos(Clamp(alpha, F(-1.0), F(1.0)))); } + /*! + * \brief Calculates the cross (scalar) product with two vectors + * \return The vector of the cross product according to "right-hand" rule + * + * \param vec The other vector to calculate the cross product with + * + * \see CrossProduct + */ + template Vector3 Vector3::CrossProduct(const Vector3& vec) const { return Vector3(y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see SquaredDistance + */ + template T Vector3::Distance(const Vector3& vec) const { return std::sqrt(SquaredDistance(vec)); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance in float between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + */ + template float Vector3::Distancef(const Vector3& vec) const { return std::sqrt(static_cast(SquaredDistance(vec))); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec The other vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector3::DotProduct(const Vector3& vec) const { - return x*vec.x + y*vec.y + z*vec.z; + return x * vec.x + y * vec.y + z * vec.z; } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length of the vector + * + * \see GetSquaredLength + */ + template T Vector3::GetLength() const { return static_cast(std::sqrt(GetSquaredLength())); } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length in float of the vector + */ + template float Vector3::GetLengthf() const { return std::sqrt(static_cast(GetSquaredLength())); } + /*! + * \brief Gets a copy normalized of the vector + * \return A new vector which is the vector normalized + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If ths vector is (0, 0, 0), then it returns (0, 0, 0) and length is 0 + * + * \see Normalize + */ + template Vector3 Vector3::GetNormal(T* length) const { @@ -127,78 +259,171 @@ namespace Nz return vec; } + /*! + * \brief Calculates the squared length (magnitude) of the vector + * \return The squared length of the vector + * + * \see GetLength + */ + template T Vector3::GetSquaredLength() const { return x*x + y*y + z*z; } + /*! + * \brief Makes the vector (0, 0, 1) + * \return A reference to this vector with components (0, 0, 1) + * + * \see Backward + */ + template Vector3& Vector3::MakeBackward() { return Set(F(0.0), F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, -1, 0) + * \return A reference to this vector with components (0, -1, 0) + * + * \see Down + */ + template Vector3& Vector3::MakeDown() { return Set(F(0.0), F(-1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 0, -1) + * \return A reference to this vector with components (0, 0, -1) + * + * \see Forward + */ + template Vector3& Vector3::MakeForward() { return Set(F(0.0), F(0.0), F(-1.0)); } + /*! + * \brief Makes the vector (-1, 0, 0) + * \return A reference to this vector with components (-1, 0, 0) + * + * \see Left + */ + template Vector3& Vector3::MakeLeft() { return Set(F(-1.0), F(0.0), F(0.0)); } + /*! + * \brief Makes the vector (1, 0, 0) + * \return A reference to this vector with components (1, 0, 0) + * + * \see Right + */ + template Vector3& Vector3::MakeRight() { return Set(F(1.0), F(0.0), F(0.0)); } + /*! + * \brief Makes the vector (1, 1, 1) + * \return A reference to this vector with components (1, 1, 1) + * + * \see Unit + */ + template Vector3& Vector3::MakeUnit() { return Set(F(1.0), F(1.0), F(1.0)); } + /*! + * \brief Makes the vector (1, 0, 0) + * \return A reference to this vector with components (1, 0, 0) + * + * \see UnitX + */ + template Vector3& Vector3::MakeUnitX() { return Set(F(1.0), F(0.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 1, 0) + * \return A reference to this vector with components (0, 1, 0) + * + * \see UnitY + */ + template Vector3& Vector3::MakeUnitY() { return Set(F(0.0), F(1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 0, 1) + * \return A reference to this vector with components (0, 0, 1) + * + * \see UnitZ + */ + template Vector3& Vector3::MakeUnitZ() { return Set(F(0.0), F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 1, 0) + * \return A reference to this vector with components (0, 1, 0) + * + * \see Up + */ + template Vector3& Vector3::MakeUp() { return Set(F(0.0), F(1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 0, 0) + * \return A reference to this vector with components (0, 0, 0) + * + * \see Zero + */ + template Vector3& Vector3::MakeZero() { return Set(F(0.0), F(0.0), F(0.0)); } + /*! + * \brief Sets this vector's components to the maximum of its own and other components + * \return A reference to this vector with replaced values with the corresponding max value + * + * \param vec Other vector to compare the components with + * + * \see Minimize + */ + template Vector3& Vector3::Maximize(const Vector3& vec) { @@ -214,6 +439,15 @@ namespace Nz return *this; } + /*! + * \brief Sets this vector's components to the minimum of its own and other components + * \return A reference to this vector with replaced values with the corresponding min value + * + * \param vec Other vector to compare the components with + * + * \see Maximize + */ + template Vector3& Vector3::Minimize(const Vector3& vec) { @@ -229,6 +463,17 @@ namespace Nz return *this; } + /*! + * \brief Normalizes the current vector + * \return A reference to this vector + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If the vector is (0, 0, 0), then it returns (0, 0, 0) and length is 0 + * + * \see GetNormal + */ + template Vector3& Vector3::Normalize(T* length) { @@ -247,6 +492,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector + * \return A reference to this vector + * + * \param X X component + * \param Y Y component + * \param Z Z component + */ + template Vector3& Vector3::Set(T X, T Y, T Z) { @@ -257,6 +511,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a component and a Vector2 + * + * \param X X component + * \param vec vec.X = Y component and vec.y = Z component + */ + template Vector3& Vector3::Set(T X, const Vector2& vec) { @@ -267,6 +528,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a "scale" + * \return A reference to this vector + * + * \param scale X component = Y component = Z component + */ + template Vector3& Vector3::Set(T scale) { @@ -277,6 +545,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from an array of three elements + * \return A reference to this vector + * + * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component + */ + template Vector3& Vector3::Set(const T vec[3]) { @@ -285,6 +560,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector2 and a component + * + * \param vec vec.X = X component and vec.y = Y component + * \param Z Z component + */ + template Vector3& Vector3::Set(const Vector2& vec, T Z) { @@ -295,6 +577,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another vector + * \return A reference to this vector + * + * \param vec The other vector + */ + template Vector3& Vector3::Set(const Vector3& vec) { @@ -303,6 +592,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another type of Vector3 + * \return A reference to this vector + * + * \param vec Vector of type U to convert its components + */ + template template Vector3& Vector3::Set(const Vector3& vec) @@ -314,6 +610,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector4 + * \return A reference to this vector + * + * \param vec Vector4 where only the first three components are taken + */ + template Vector3& Vector3::Set(const Vector4& vec) { @@ -324,12 +627,26 @@ namespace Nz return *this; } + /*! + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see Distance + */ + template T Vector3::SquaredDistance(const Vector3& vec) const { return (*this - vec).GetSquaredLength(); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Vector3(x, y, z)" + */ + template String Vector3::ToString() const { @@ -338,54 +655,116 @@ namespace Nz return ss << "Vector3(" << x << ", " << y << ", " << z <<')'; } + /*! + * \brief Converts vector to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 2 is undefined behavior + */ + template - Vector3::operator T*() + Vector3::operator T* () { return &x; } + /*! + * \brief Converts vector to const pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 2 is undefined behavior + */ + template - Vector3::operator const T*() const + Vector3::operator const T* () const { return &x; } + /*! + * \brief Helps to represent the sign of the vector + * \return A constant reference to this vector + */ + template const Vector3& Vector3::operator+() const { return *this; } + /*! + * \brief Negates the components of the vector + * \return A constant reference to this vector with negate components + */ + template Vector3 Vector3::operator-() const { return Vector3(-x, -y, -z); } + /*! + * \brief Adds the components of the vector with other vector + * \return A vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector3 Vector3::operator+(const Vector3& vec) const { return Vector3(x + vec.x, y + vec.y, z + vec.z); } + /*! + * \brief Substracts the components of the vector with other vector + * \return A vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector3 Vector3::operator-(const Vector3& vec) const { return Vector3(x - vec.x, y - vec.y, z - vec.z); } + /*! + * \brief Multiplies the components of the vector with other vector + * \return A vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector3 Vector3::operator*(const Vector3& vec) const { return Vector3(x * vec.x, y * vec.y, z * vec.z); } + /*! + * \brief Multiplies the components of the vector with a scalar + * \return A vector where components are the product of this vector and the scalar + * + * \param scale The scalar to multiply components with + */ + template Vector3 Vector3::operator*(T scale) const { return Vector3(x * scale, y * scale, z * scale); } + /*! + * \brief Divides the components of the vector with other vector + * \return A vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector3 Vector3::operator/(const Vector3& vec) const { @@ -402,6 +781,16 @@ namespace Nz return Vector3(x / vec.x, y / vec.y, z / vec.z); } + /*! + * \brief Divides the components of the vector with a scalar + * \return A vector where components are the quotient of this vector and the scalar + * + * \param scale The scalar to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector3 Vector3::operator/(T scale) const { @@ -418,6 +807,13 @@ namespace Nz return Vector3(x / scale, y / scale, z / scale); } + /*! + * \brief Adds the components of other vector to this vector + * \return A reference to this vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector3& Vector3::operator+=(const Vector3& vec) { @@ -428,6 +824,13 @@ namespace Nz return *this; } + /*! + * \brief Substracts the components of other vector to this vector + * \return A reference to this vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector3& Vector3::operator-=(const Vector3& vec) { @@ -438,6 +841,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector3& Vector3::operator*=(const Vector3& vec) { @@ -448,6 +858,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector with a scalar + * \return A reference to this vector where components are the product of this vector and the scalar + * + * \param vec The other vector to multiply components with + */ + template Vector3& Vector3::operator*=(T scale) { @@ -458,6 +875,16 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to multiply components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector3& Vector3::operator/=(const Vector3& vec) { @@ -476,6 +903,16 @@ namespace Nz return *this; } + /*! + * \brief Divides the components of other vector with a scalar + * \return A reference to this vector where components are the quotient of this vector and the scalar + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector3& Vector3::operator/=(T scale) { @@ -494,20 +931,41 @@ namespace Nz return *this; } + /*! + * \brief Compares the vector to other one + * \return true if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator==(const Vector3& vec) const { return NumberEquals(x, vec.x) && - NumberEquals(y, vec.y) && - NumberEquals(z, vec.z); + NumberEquals(y, vec.y) && + NumberEquals(z, vec.z); } + /*! + * \brief Compares the vector to other one + * \return false if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator!=(const Vector3& vec) const { return !operator==(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator<(const Vector3& vec) const { @@ -522,6 +980,13 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator<=(const Vector3& vec) const { @@ -536,30 +1001,71 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator>(const Vector3& vec) const { return !operator<=(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator>=(const Vector3& vec) const { return !operator<(vec); } + /*! + * \brief Calculates the cross product with two vectors + * \return A vector which is the cross product according to "right-hand" rule + * + * \param vec1 The first vector to calculate the cross product with + * \param vec2 The second vector to calculate the cross product with + * + * \see CrossProduct + */ + template Vector3 Vector3::CrossProduct(const Vector3& vec1, const Vector3& vec2) { return vec1.CrossProduct(vec2); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec1 The first vector to calculate the dot product with + * \param vec2 The second vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector3::DotProduct(const Vector3& vec1, const Vector3& vec2) { return vec1.DotProduct(vec2); } + /*! + * \brief Shorthand for the vector (0, 0, 1) + * \return A vector with components (0, 0, 1) + * + * \see MakeBackward + */ + template Vector3 Vector3::Backward() { @@ -569,6 +1075,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, -1, 0) + * \return A vector with components (0, -1, 0) + * + * \see MakeDown + */ + template Vector3 Vector3::Down() { @@ -578,6 +1091,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, -1) + * \return A vector with components (0, 0, -1) + * + * \see Forward + */ + template Vector3 Vector3::Forward() { @@ -587,6 +1107,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (-1, 0, 0) + * \return A vector with components (-1, 0, 0) + * + * \see MakeLeft + */ + template Vector3 Vector3::Left() { @@ -596,18 +1123,54 @@ namespace Nz return vector; } + /*! + * \brief Interpolates the vector to other one with a factor of interpolation + * \return A new vector which is the interpolation of two vectors + * + * \param from Initial vector + * \param to Target vector + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * + * \see Lerp + */ + template Vector3 Vector3::Lerp(const Vector3& from, const Vector3& to, T interpolation) { - return Nz::Lerp(from, to, interpolation); + Vector3 dummy; + dummy.x = Nz::Lerp(from.x, to.x, interpolation); + dummy.y = Nz::Lerp(from.y, to.y, interpolation); + dummy.z = Nz::Lerp(from.z, to.z, interpolation); + + return dummy; } + /*! + * \brief Gives the normalized vector + * \return A normalized vector from the vec + * + * \param vec Vector to normalize + * + * \remark If the vector is (0, 0, 0), then it returns (0, 0, 0) + * + * \see GetNormal + */ + template Vector3 Vector3::Normalize(const Vector3& vec) { return vec.GetNormal(); } + /*! + * \brief Shorthand for the vector (1, 0, 0) + * \return A vector with components (1, 0, 0) + * + * \see MakeRight + */ + template Vector3 Vector3::Right() { @@ -617,6 +1180,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (1, 1, 1) + * \return A vector with components (1, 1, 1) + * + * \see MakeUnit + */ + template Vector3 Vector3::Unit() { @@ -626,6 +1196,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (1, 0, 0) + * \return A vector with components (1, 0, 0) + * + * \see MakeUnitX + */ + template Vector3 Vector3::UnitX() { @@ -635,6 +1212,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1, 0) + * \return A vector with components (0, 1, 0) + * + * \see MakeUnitY + */ + template Vector3 Vector3::UnitY() { @@ -644,6 +1228,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, 1) + * \return A vector with components (0, 0, 1) + * + * \see MakeUnitZ + */ + template Vector3 Vector3::UnitZ() { @@ -653,6 +1244,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1, 0) + * \return A vector with components (0, 1, 0) + * + * \see MakeUp + */ + template Vector3 Vector3::Up() { @@ -662,6 +1260,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, 0) + * \return A vector with components (0, 0, 0) + * + * \see MakeZero + */ + template Vector3 Vector3::Zero() { @@ -672,18 +1277,43 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param vec The vector to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec) { return out << vec.ToString(); } +/*! +* \brief Multiplies the components of the vector with a scalar +* \return A vector where components are the product of this vector and the scalar +* +* \param scale The scalar to multiply components with +*/ + template Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) { return Nz::Vector3(scale * vec.x, scale * vec.y, scale * vec.z); } +/*! +* \brief Divides the components of the vector with a scalar +* \return A vector where components are the quotient of this vector and the scalar +* +* \param scale The scalar to divide components with +* +* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined +* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null +*/ + template Nz::Vector3 operator/(T scale, const Nz::Vector3& vec) {