Converted all unit tests to template form
All checks were successful
Build and Run C++ Unit Tests / build-and-test (push) Successful in 2m2s
All checks were successful
Build and Run C++ Unit Tests / build-and-test (push) Successful in 2m2s
This commit is contained in:
parent
679471f748
commit
b555fb5d6a
@ -43,24 +43,22 @@ const DirectionOf<T> DirectionOf<T>::right =
|
|||||||
DirectionOf<T>(AngleOf<T>::Degrees(90), AngleOf<T>());
|
DirectionOf<T>(AngleOf<T>::Degrees(90), AngleOf<T>());
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3 DirectionOf<T>::ToVector3() const {
|
Vector3Of<float> DirectionOf<T>::ToVector3() const {
|
||||||
Quaternion q = Quaternion::Euler(-this->vertical.InDegrees(),
|
Quaternion q = Quaternion::Euler(-this->vertical.InDegrees(),
|
||||||
this->horizontal.InDegrees(), 0);
|
this->horizontal.InDegrees(), 0);
|
||||||
Vector3 v = q * Vector3::forward;
|
Vector3Of<float> v = q * Vector3Of<float>::forward;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DirectionOf<T> DirectionOf<T>::FromVector3(Vector3 vector) {
|
DirectionOf<T> DirectionOf<T>::FromVector3(Vector3Of<float> vector) {
|
||||||
DirectionOf<T> d;
|
DirectionOf<T> d;
|
||||||
d.horizontal = AngleOf<T>::Atan2(
|
d.horizontal = AngleOf<T>::Atan2(
|
||||||
vector.Right(),
|
vector.horizontal,
|
||||||
vector
|
vector.depth); // AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
|
||||||
.Forward()); // AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
|
d.vertical = AngleOf<T>::Degrees(-90) -
|
||||||
d.vertical =
|
AngleOf<T>::Acos(vector.vertical); // AngleOf<T>::Radians(-(0.5f
|
||||||
AngleOf<T>::Degrees(-90) -
|
// * pi) - acosf(v.Up()));
|
||||||
AngleOf<T>::Acos(
|
|
||||||
vector.Up()); // AngleOf<T>::Radians(-(0.5f * pi) - acosf(v.Up()));
|
|
||||||
d.Normalize();
|
d.Normalize();
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -101,4 +99,4 @@ void DirectionOf<T>::Normalize() {
|
|||||||
|
|
||||||
template class LinearAlgebra::DirectionOf<float>;
|
template class LinearAlgebra::DirectionOf<float>;
|
||||||
template class LinearAlgebra::DirectionOf<signed short>;
|
template class LinearAlgebra::DirectionOf<signed short>;
|
||||||
}
|
} // namespace LinearAlgebra
|
||||||
@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
struct Vector3;
|
//struct Vector3;
|
||||||
|
template <typename T>
|
||||||
|
class Vector3Of;
|
||||||
|
|
||||||
/// @brief A direction using angles in various representations
|
/// @brief A direction using angles in various representations
|
||||||
/// @tparam T The implementation type used for the representation of the angles
|
/// @tparam T The implementation type used for the representation of the angles
|
||||||
@ -38,13 +40,13 @@ class DirectionOf {
|
|||||||
|
|
||||||
/// @brief Convert the direction into a carthesian vector
|
/// @brief Convert the direction into a carthesian vector
|
||||||
/// @return The carthesian vector corresponding to this direction.
|
/// @return The carthesian vector corresponding to this direction.
|
||||||
Vector3 ToVector3() const;
|
Vector3Of<float> ToVector3() const;
|
||||||
/// @brief Convert a carthesian vector into a direction
|
/// @brief Convert a carthesian vector into a direction
|
||||||
/// @param v The carthesian vector
|
/// @param v The carthesian vector
|
||||||
/// @return The direction.
|
/// @return The direction.
|
||||||
/// @note Information about the length of the carthesian vector is not
|
/// @note Information about the length of the carthesian vector is not
|
||||||
/// included in this transformation.
|
/// included in this transformation.
|
||||||
static DirectionOf<T> FromVector3(Vector3 vector);
|
static DirectionOf<T> FromVector3(Vector3Of<float> vector);
|
||||||
|
|
||||||
/// @brief Create a direction using angle values in degrees
|
/// @brief Create a direction using angle values in degrees
|
||||||
/// @param horizontal The horizontal angle in degrees
|
/// @param horizontal The horizontal angle in degrees
|
||||||
|
|||||||
@ -36,11 +36,11 @@ PolarOf<T> PolarOf<T>::Radians(float distance, float radians) {
|
|||||||
return PolarOf<T>(distance, AngleOf<T>::Radians(radians));
|
return PolarOf<T>(distance, AngleOf<T>::Radians(radians));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <>
|
||||||
PolarOf<T> PolarOf<T>::FromVector2(Vector2Of<T> v) {
|
PolarOf<float> PolarOf<float>::FromVector2(Vector2Of<float> v) {
|
||||||
float distance = v.Magnitude();
|
float distance = v.Magnitude();
|
||||||
AngleOf<T> angle = Vector2Of<T>::SignedAngle(Vector2Of<T>::forward, v);
|
AngleOf<float> angle = Vector2Of<float>::SignedAngle(Vector2Of<float>::forward, v);
|
||||||
PolarOf<T> p = PolarOf(distance, angle);
|
PolarOf<float> p = PolarOf(distance, angle);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
2
Polar.h
2
Polar.h
@ -56,7 +56,7 @@ class PolarOf {
|
|||||||
/// @brief Convert a vector from 2D carthesian coordinates to polar
|
/// @brief Convert a vector from 2D carthesian coordinates to polar
|
||||||
/// coordinates
|
/// coordinates
|
||||||
/// @param v The vector to convert
|
/// @param v The vector to convert
|
||||||
static PolarOf<T> FromVector2(Vector2Of<T> v);
|
static PolarOf<float> FromVector2(Vector2Of<float> v);
|
||||||
/// @brief Convert a vector from spherical coordinates to polar coordinates
|
/// @brief Convert a vector from spherical coordinates to polar coordinates
|
||||||
/// @param s The vector to convert
|
/// @param s The vector to convert
|
||||||
/// @note The resulting vector will be projected on the horizontal plane
|
/// @note The resulting vector will be projected on the horizontal plane
|
||||||
|
|||||||
132
Quaternion.cpp
132
Quaternion.cpp
@ -44,8 +44,8 @@ Quaternion::~Quaternion() {}
|
|||||||
|
|
||||||
const Quaternion Quaternion::identity = Quaternion(0, 0, 0, 1);
|
const Quaternion Quaternion::identity = Quaternion(0, 0, 0, 1);
|
||||||
|
|
||||||
Vector3 Quaternion::xyz() const {
|
Vector3Of<float> Quaternion::xyz() const {
|
||||||
return Vector3(x, y, z);
|
return Vector3Of<float>(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Quaternion::GetLength() const {
|
float Quaternion::GetLength() const {
|
||||||
@ -78,18 +78,18 @@ float Quaternion::Dot(Quaternion a, Quaternion b) {
|
|||||||
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Quaternion::ToAngles(const Quaternion& q1) {
|
Vector3Of<float> Quaternion::ToAngles(const Quaternion& q1) {
|
||||||
float test = q1.x * q1.y + q1.z * q1.w;
|
float test = q1.x * q1.y + q1.z * q1.w;
|
||||||
if (test > 0.499f) { // singularity at north pole
|
if (test > 0.499f) { // singularity at north pole
|
||||||
return Vector3(0, 2 * (float)atan2(q1.x, q1.w) * Rad2Deg, 90);
|
return Vector3Of<float>(0, 2 * (float)atan2(q1.x, q1.w) * Rad2Deg, 90);
|
||||||
} else if (test < -0.499f) { // singularity at south pole
|
} else if (test < -0.499f) { // singularity at south pole
|
||||||
return Vector3(0, -2 * (float)atan2(q1.x, q1.w) * Rad2Deg, -90);
|
return Vector3Of<float>(0, -2 * (float)atan2(q1.x, q1.w) * Rad2Deg, -90);
|
||||||
} else {
|
} else {
|
||||||
float sqx = q1.x * q1.x;
|
float sqx = q1.x * q1.x;
|
||||||
float sqy = q1.y * q1.y;
|
float sqy = q1.y * q1.y;
|
||||||
float sqz = q1.z * q1.z;
|
float sqz = q1.z * q1.z;
|
||||||
|
|
||||||
return Vector3(
|
return Vector3Of<float>(
|
||||||
atan2f(2 * q1.x * q1.w - 2 * q1.y * q1.z, 1 - 2 * sqx - 2 * sqz) *
|
atan2f(2 * q1.x * q1.w - 2 * q1.y * q1.z, 1 - 2 * sqx - 2 * sqz) *
|
||||||
Rad2Deg,
|
Rad2Deg,
|
||||||
atan2f(2 * q1.y * q1.w - 2 * q1.x * q1.z, 1 - 2 * sqy - 2 * sqz) *
|
atan2f(2 * q1.y * q1.w - 2 * q1.x * q1.z, 1 - 2 * sqy - 2 * sqz) *
|
||||||
@ -128,7 +128,7 @@ Quaternion Quaternion::operator*(const Quaternion& r2) const {
|
|||||||
-this->x * r2.x - this->y * r2.y - this->z * r2.z + this->w * r2.w);
|
-this->x * r2.x - this->y * r2.y - this->z * r2.z + this->w * r2.w);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector3 Quaternion::operator*(const Vector3& p) const {
|
Vector3Of<float> Quaternion::operator*(const Vector3Of<float>& p) const {
|
||||||
float num = this->x * 2;
|
float num = this->x * 2;
|
||||||
float num2 = this->y * 2;
|
float num2 = this->y * 2;
|
||||||
float num3 = this->z * 2;
|
float num3 = this->z * 2;
|
||||||
@ -142,9 +142,9 @@ Vector3 Quaternion::operator*(const Vector3& p) const {
|
|||||||
float num11 = this->w * num2;
|
float num11 = this->w * num2;
|
||||||
float num12 = this->w * num3;
|
float num12 = this->w * num3;
|
||||||
|
|
||||||
float px = p.Right();
|
float px = p.horizontal;
|
||||||
float py = p.Up();
|
float py = p.vertical;
|
||||||
float pz = p.Forward();
|
float pz = p.depth;
|
||||||
// Vector3 result = Vector3::zero;
|
// Vector3 result = Vector3::zero;
|
||||||
// result.x =
|
// result.x =
|
||||||
float rx =
|
float rx =
|
||||||
@ -155,7 +155,7 @@ Vector3 Quaternion::operator*(const Vector3& p) const {
|
|||||||
// result.z =
|
// result.z =
|
||||||
float rz =
|
float rz =
|
||||||
(num8 - num11) * px + (num9 + num10) * py + (1 - (num4 + num5)) * pz;
|
(num8 - num11) * px + (num9 + num10) * py + (1 - (num4 + num5)) * pz;
|
||||||
Vector3 result = Vector3(rx, ry, rz);
|
Vector3Of<float> result = Vector3Of<float>(rx, ry, rz);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,23 +168,23 @@ Quaternion Quaternion::Inverse(Quaternion r) {
|
|||||||
return Quaternion(-r.x / n, -r.y / n, -r.z / n, r.w / n);
|
return Quaternion(-r.x / n, -r.y / n, -r.z / n, r.w / n);
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::LookRotation(const Vector3& forward) {
|
Quaternion Quaternion::LookRotation(const Vector3Of<float>& forward) {
|
||||||
Vector3 up = Vector3(0, 1, 0);
|
Vector3Of<float> up = Vector3Of<float>(0, 1, 0);
|
||||||
return LookRotation(forward, up);
|
return LookRotation(forward, up);
|
||||||
}
|
}
|
||||||
Quaternion Quaternion::LookRotation(const Vector3& forward, const Vector3& up) {
|
Quaternion Quaternion::LookRotation(const Vector3Of<float>& forward, const Vector3Of<float>& up) {
|
||||||
Vector3 nForward = Vector3::Normalize(forward);
|
Vector3Of<float> nForward = Vector3Of<float>::Normalize(forward);
|
||||||
Vector3 nRight = Vector3::Normalize(Vector3::Cross(up, nForward));
|
Vector3Of<float> nRight = Vector3Of<float>::Normalize(Vector3Of<float>::Cross(up, nForward));
|
||||||
Vector3 nUp = Vector3::Cross(nForward, nRight);
|
Vector3Of<float> nUp = Vector3Of<float>::Cross(nForward, nRight);
|
||||||
float m00 = nRight.Right(); // x;
|
float m00 = nRight.horizontal; // x;
|
||||||
float m01 = nRight.Up(); // y;
|
float m01 = nRight.vertical; // y;
|
||||||
float m02 = nRight.Forward(); // z;
|
float m02 = nRight.depth; // z;
|
||||||
float m10 = nUp.Right(); // x;
|
float m10 = nUp.horizontal; // x;
|
||||||
float m11 = nUp.Up(); // y;
|
float m11 = nUp.vertical; // y;
|
||||||
float m12 = nUp.Forward(); // z;
|
float m12 = nUp.depth; // z;
|
||||||
float m20 = nForward.Right(); // x;
|
float m20 = nForward.horizontal; // x;
|
||||||
float m21 = nForward.Up(); // y;
|
float m21 = nForward.vertical; // y;
|
||||||
float m22 = nForward.Forward(); // z;
|
float m22 = nForward.depth; // z;
|
||||||
|
|
||||||
float num8 = (m00 + m11) + m22;
|
float num8 = (m00 + m11) + m22;
|
||||||
Quaternion quaternion = Quaternion();
|
Quaternion quaternion = Quaternion();
|
||||||
@ -224,11 +224,11 @@ Quaternion Quaternion::LookRotation(const Vector3& forward, const Vector3& up) {
|
|||||||
return quaternion;
|
return quaternion;
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::FromToRotation(Vector3 fromDirection,
|
Quaternion Quaternion::FromToRotation(Vector3Of<float> fromDirection,
|
||||||
Vector3 toDirection) {
|
Vector3Of<float> toDirection) {
|
||||||
Vector3 axis = Vector3::Cross(fromDirection, toDirection);
|
Vector3Of<float> axis = Vector3Of<float>::Cross(fromDirection, toDirection);
|
||||||
axis = Vector3::Normalize(axis);
|
axis = Vector3Of<float>::Normalize(axis);
|
||||||
AngleOf<float> angle = Vector3::SignedAngle(fromDirection, toDirection, axis);
|
AngleOf<float> angle = Vector3Of<float>::SignedAngle(fromDirection, toDirection, axis);
|
||||||
Quaternion rotation = Quaternion::AngleAxis(angle.InDegrees(), axis);
|
Quaternion rotation = Quaternion::AngleAxis(angle.InDegrees(), axis);
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
@ -244,18 +244,18 @@ Quaternion Quaternion::RotateTowards(const Quaternion& from,
|
|||||||
return SlerpUnclamped(from, to, t);
|
return SlerpUnclamped(from, to, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::AngleAxis(float angle, const Vector3& axis) {
|
Quaternion Quaternion::AngleAxis(float angle, const Vector3Of<float>& axis) {
|
||||||
if (Vector3::SqrMagnitude(axis) == 0.0f)
|
if (Vector3Of<float>::SqrMagnitudeOf(axis) == 0.0f)
|
||||||
return Quaternion();
|
return Quaternion();
|
||||||
|
|
||||||
Quaternion result = Quaternion();
|
Quaternion result = Quaternion();
|
||||||
float radians = angle * Deg2Rad;
|
float radians = angle * Deg2Rad;
|
||||||
radians *= 0.5f;
|
radians *= 0.5f;
|
||||||
|
|
||||||
Vector3 axis2 = axis * (float)sin(radians);
|
Vector3Of<float> axis2 = axis * (float)sin(radians);
|
||||||
result.x = axis2.Right(); // x;
|
result.x = axis2.horizontal; // x;
|
||||||
result.y = axis2.Up(); // y;
|
result.y = axis2.vertical; // y;
|
||||||
result.z = axis2.Forward(); // z;
|
result.z = axis2.depth; // z;
|
||||||
result.w = (float)cos(radians);
|
result.w = (float)cos(radians);
|
||||||
|
|
||||||
return Quaternion::Normalize(result);
|
return Quaternion::Normalize(result);
|
||||||
@ -266,23 +266,23 @@ float Quaternion::Angle(Quaternion a, Quaternion b) {
|
|||||||
return (float)acos(fmin(fabs(f), 1)) * 2 * Rad2Deg;
|
return (float)acos(fmin(fabs(f), 1)) * 2 * Rad2Deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quaternion::ToAngleAxis(float* angle, Vector3* axis) {
|
void Quaternion::ToAngleAxis(float* angle, Vector3Of<float>* axis) {
|
||||||
Quaternion::ToAxisAngleRad(*this, axis, angle);
|
Quaternion::ToAxisAngleRad(*this, axis, angle);
|
||||||
*angle *= Rad2Deg;
|
*angle *= Rad2Deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quaternion::ToAxisAngleRad(const Quaternion& q,
|
void Quaternion::ToAxisAngleRad(const Quaternion& q,
|
||||||
Vector3* const axis,
|
Vector3Of<float>* const axis,
|
||||||
float* angle) {
|
float* angle) {
|
||||||
Quaternion q1 = (fabs(q.w) > 1.0f) ? Quaternion::Normalize(q) : q;
|
Quaternion q1 = (fabs(q.w) > 1.0f) ? Quaternion::Normalize(q) : q;
|
||||||
*angle = 2.0f * acosf(q1.w); // angle
|
*angle = 2.0f * acosf(q1.w); // angle
|
||||||
float den = sqrtf(1.0F - q1.w * q1.w);
|
float den = sqrtf(1.0F - q1.w * q1.w);
|
||||||
if (den > 0.0001f) {
|
if (den > 0.0001f) {
|
||||||
*axis = Vector3::Normalize(q1.xyz() / den);
|
*axis = Vector3Of<float>::Normalize(q1.xyz() / den);
|
||||||
} else {
|
} else {
|
||||||
// This occurs when the angle is zero.
|
// This occurs when the angle is zero.
|
||||||
// Not a problem: just set an arbitrary normalized axis.
|
// Not a problem: just set an arbitrary normalized axis.
|
||||||
*axis = Vector3(1, 0, 0);
|
*axis = Vector3Of<float>(1, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Quaternion Quaternion::SlerpUnclamped(const Quaternion& a,
|
Quaternion Quaternion::SlerpUnclamped(const Quaternion& a,
|
||||||
@ -298,9 +298,9 @@ Quaternion Quaternion::SlerpUnclamped(const Quaternion& a,
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector3 axyz = a.xyz();
|
const Vector3Of<float> axyz = a.xyz();
|
||||||
const Vector3 bxyz = b.xyz();
|
const Vector3Of<float> bxyz = b.xyz();
|
||||||
float cosHalfAngle = a.w * b.w + Vector3::Dot(axyz, bxyz);
|
float cosHalfAngle = a.w * b.w + Vector3Of<float>::Dot(axyz, bxyz);
|
||||||
|
|
||||||
Quaternion b2 = b;
|
Quaternion b2 = b;
|
||||||
if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) {
|
if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) {
|
||||||
@ -328,9 +328,9 @@ Quaternion Quaternion::SlerpUnclamped(const Quaternion& a,
|
|||||||
blendA = 1.0f - t;
|
blendA = 1.0f - t;
|
||||||
blendB = t;
|
blendB = t;
|
||||||
}
|
}
|
||||||
Vector3 v = axyz * blendA + b2.xyz() * blendB;
|
Vector3Of<float> v = axyz * blendA + b2.xyz() * blendB;
|
||||||
Quaternion result =
|
Quaternion result =
|
||||||
Quaternion(v.Right(), v.Up(), v.Forward(), blendA * a.w + blendB * b2.w);
|
Quaternion(v.horizontal, v.vertical, v.depth, blendA * a.w + blendB * b2.w);
|
||||||
if (result.GetLengthSquared() > 0.0f)
|
if (result.GetLengthSquared() > 0.0f)
|
||||||
return Quaternion::Normalize(result);
|
return Quaternion::Normalize(result);
|
||||||
else
|
else
|
||||||
@ -348,16 +348,16 @@ Quaternion Quaternion::Slerp(const Quaternion& a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::Euler(float x, float y, float z) {
|
Quaternion Quaternion::Euler(float x, float y, float z) {
|
||||||
return Quaternion::Euler(Vector3(x, y, z));
|
return Quaternion::Euler(Vector3Of<float>(x, y, z));
|
||||||
}
|
}
|
||||||
Quaternion Quaternion::Euler(Vector3 euler) {
|
Quaternion Quaternion::Euler(Vector3Of<float> euler) {
|
||||||
return Quaternion::FromEulerRad(euler * Deg2Rad);
|
return Quaternion::FromEulerRad(euler * Deg2Rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::FromEulerRad(Vector3 euler) {
|
Quaternion Quaternion::FromEulerRad(Vector3Of<float> euler) {
|
||||||
float yaw = euler.Right();
|
float yaw = euler.horizontal;
|
||||||
float pitch = euler.Up();
|
float pitch = euler.vertical;
|
||||||
float roll = euler.Forward();
|
float roll = euler.depth;
|
||||||
float rollOver2 = roll * 0.5f;
|
float rollOver2 = roll * 0.5f;
|
||||||
float sinRollOver2 = (float)sin((float)rollOver2);
|
float sinRollOver2 = (float)sin((float)rollOver2);
|
||||||
float cosRollOver2 = (float)cos((float)rollOver2);
|
float cosRollOver2 = (float)cos((float)rollOver2);
|
||||||
@ -380,15 +380,15 @@ Quaternion Quaternion::FromEulerRad(Vector3 euler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::EulerXYZ(float x, float y, float z) {
|
Quaternion Quaternion::EulerXYZ(float x, float y, float z) {
|
||||||
return Quaternion::EulerXYZ(Vector3(x, y, z));
|
return Quaternion::EulerXYZ(Vector3Of<float>(x, y, z));
|
||||||
}
|
}
|
||||||
Quaternion Quaternion::EulerXYZ(Vector3 euler) {
|
Quaternion Quaternion::EulerXYZ(Vector3Of<float> euler) {
|
||||||
return Quaternion::FromEulerRadXYZ(euler * Deg2Rad);
|
return Quaternion::FromEulerRadXYZ(euler * Deg2Rad);
|
||||||
}
|
}
|
||||||
Quaternion Quaternion::FromEulerRadXYZ(Vector3 euler) {
|
Quaternion Quaternion::FromEulerRadXYZ(Vector3Of<float> euler) {
|
||||||
float yaw = euler.Right(); // x;
|
float yaw = euler.horizontal; // x;
|
||||||
float pitch = euler.Up(); // y;
|
float pitch = euler.vertical; // y;
|
||||||
float roll = euler.Forward(); // z;
|
float roll = euler.depth; // z;
|
||||||
float rollOver2 = roll * 0.5f;
|
float rollOver2 = roll * 0.5f;
|
||||||
float sinRollOver2 = (float)sin((float)rollOver2);
|
float sinRollOver2 = (float)sin((float)rollOver2);
|
||||||
float cosRollOver2 = (float)cos((float)rollOver2);
|
float cosRollOver2 = (float)cos((float)rollOver2);
|
||||||
@ -410,29 +410,29 @@ Quaternion Quaternion::FromEulerRadXYZ(Vector3 euler) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Quaternion::GetAngleAround(Vector3 axis, Quaternion rotation) {
|
float Quaternion::GetAngleAround(Vector3Of<float> axis, Quaternion rotation) {
|
||||||
Quaternion secondaryRotation = GetRotationAround(axis, rotation);
|
Quaternion secondaryRotation = GetRotationAround(axis, rotation);
|
||||||
float rotationAngle;
|
float rotationAngle;
|
||||||
Vector3 rotationAxis;
|
Vector3Of<float> rotationAxis;
|
||||||
secondaryRotation.ToAngleAxis(&rotationAngle, &rotationAxis);
|
secondaryRotation.ToAngleAxis(&rotationAngle, &rotationAxis);
|
||||||
|
|
||||||
// Do the axis point in opposite directions?
|
// Do the axis point in opposite directions?
|
||||||
if (Vector3::Dot(axis, rotationAxis) < 0)
|
if (Vector3Of<float>::Dot(axis, rotationAxis) < 0)
|
||||||
rotationAngle = -rotationAngle;
|
rotationAngle = -rotationAngle;
|
||||||
|
|
||||||
return rotationAngle;
|
return rotationAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::GetRotationAround(Vector3 axis, Quaternion rotation) {
|
Quaternion Quaternion::GetRotationAround(Vector3Of<float> axis, Quaternion rotation) {
|
||||||
Vector3 ra = Vector3(rotation.x, rotation.y, rotation.z); // rotation axis
|
Vector3Of<float> ra = Vector3Of<float>(rotation.x, rotation.y, rotation.z); // rotation axis
|
||||||
Vector3 p = Vector3::Project(
|
Vector3Of<float> p = Vector3Of<float>::Project(
|
||||||
ra, axis); // return projection ra on to axis (parallel component)
|
ra, axis); // return projection ra on to axis (parallel component)
|
||||||
Quaternion twist = Quaternion(p.Right(), p.Up(), p.Forward(), rotation.w);
|
Quaternion twist = Quaternion(p.horizontal, p.vertical, p.depth, rotation.w);
|
||||||
twist = Quaternion::Normalize(twist);
|
twist = Quaternion::Normalize(twist);
|
||||||
return twist;
|
return twist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quaternion::GetSwingTwist(Vector3 axis,
|
void Quaternion::GetSwingTwist(Vector3Of<float> axis,
|
||||||
Quaternion rotation,
|
Quaternion rotation,
|
||||||
Quaternion* swing,
|
Quaternion* swing,
|
||||||
Quaternion* twist) {
|
Quaternion* twist) {
|
||||||
|
|||||||
34
Quaternion.h
34
Quaternion.h
@ -89,7 +89,7 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="q">The quaternion to convert</param>
|
/// <param name="q">The quaternion to convert</param>
|
||||||
/// <returns>A vector containing euler angles</returns>
|
/// <returns>A vector containing euler angles</returns>
|
||||||
/// The euler angles performed in the order: Z, X, Y
|
/// The euler angles performed in the order: Z, X, Y
|
||||||
static Vector3 ToAngles(const Quaternion& q);
|
static Vector3Of<float> ToAngles(const Quaternion& q);
|
||||||
|
|
||||||
Matrix2 ToRotationMatrix();
|
Matrix2 ToRotationMatrix();
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ struct Quaternion : Quat {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">The vector to rotate</param>
|
/// <param name="vector">The vector to rotate</param>
|
||||||
/// <returns>The rotated vector</returns>
|
/// <returns>The rotated vector</returns>
|
||||||
Vector3 operator*(const Vector3& vector) const;
|
Vector3Of<float> operator*(const Vector3Of<float>& vector) const;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiply this quaternion with another quaternion
|
/// Multiply this quaternion with another quaternion
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -132,8 +132,8 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="forward">The look direction</param>
|
/// <param name="forward">The look direction</param>
|
||||||
/// <param name="upwards">The up direction</param>
|
/// <param name="upwards">The up direction</param>
|
||||||
/// <returns>The look rotation</returns>
|
/// <returns>The look rotation</returns>
|
||||||
static Quaternion LookRotation(const Vector3& forward,
|
static Quaternion LookRotation(const Vector3Of<float>& forward,
|
||||||
const Vector3& upwards);
|
const Vector3Of<float>& upwards);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a quaternion with the given forward direction with up =
|
/// Creates a quaternion with the given forward direction with up =
|
||||||
/// Vector3::up
|
/// Vector3::up
|
||||||
@ -143,7 +143,7 @@ struct Quaternion : Quat {
|
|||||||
/// For the rotation, Vector::up is used for the up direction.
|
/// For the rotation, Vector::up is used for the up direction.
|
||||||
/// Note: if the forward direction == Vector3::up, the result is
|
/// Note: if the forward direction == Vector3::up, the result is
|
||||||
/// Quaternion::identity
|
/// Quaternion::identity
|
||||||
static Quaternion LookRotation(const Vector3& forward);
|
static Quaternion LookRotation(const Vector3Of<float>& forward);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculat the rotation from on vector to another
|
/// Calculat the rotation from on vector to another
|
||||||
@ -151,7 +151,7 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="fromDirection">The from direction</param>
|
/// <param name="fromDirection">The from direction</param>
|
||||||
/// <param name="toDirection">The to direction</param>
|
/// <param name="toDirection">The to direction</param>
|
||||||
/// <returns>The rotation from the first to the second vector</returns>
|
/// <returns>The rotation from the first to the second vector</returns>
|
||||||
static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection);
|
static Quaternion FromToRotation(Vector3Of<float> fromDirection, Vector3Of<float> toDirection);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotate form one orientation to anther with a maximum amount of degrees
|
/// Rotate form one orientation to anther with a maximum amount of degrees
|
||||||
@ -170,13 +170,13 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="angle">The angle</param>
|
/// <param name="angle">The angle</param>
|
||||||
/// <param name="axis">The axis</param>
|
/// <param name="axis">The axis</param>
|
||||||
/// <returns>The resulting quaternion</returns>
|
/// <returns>The resulting quaternion</returns>
|
||||||
static Quaternion AngleAxis(float angle, const Vector3& axis);
|
static Quaternion AngleAxis(float angle, const Vector3Of<float>& axis);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert this quaternion to angle/axis representation
|
/// Convert this quaternion to angle/axis representation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="angle">A pointer to the angle for the result</param>
|
/// <param name="angle">A pointer to the angle for the result</param>
|
||||||
/// <param name="axis">A pointer to the axis for the result</param>
|
/// <param name="axis">A pointer to the axis for the result</param>
|
||||||
void ToAngleAxis(float* angle, Vector3* axis);
|
void ToAngleAxis(float* angle, Vector3Of<float>* axis);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the angle between two orientations
|
/// Get the angle between two orientations
|
||||||
@ -225,7 +225,7 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="eulerAngles">Vector with the euler angles</param>
|
/// <param name="eulerAngles">Vector with the euler angles</param>
|
||||||
/// <returns>The resulting quaternion</returns>
|
/// <returns>The resulting quaternion</returns>
|
||||||
/// Rotation are appied in the order Z, X, Y.
|
/// Rotation are appied in the order Z, X, Y.
|
||||||
static Quaternion Euler(Vector3 eulerAngles);
|
static Quaternion Euler(Vector3Of<float> eulerAngles);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a rotation from euler angles
|
/// Create a rotation from euler angles
|
||||||
@ -242,7 +242,7 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="eulerAngles">Vector with the euler angles</param>
|
/// <param name="eulerAngles">Vector with the euler angles</param>
|
||||||
/// <returns>The resulting quaternion</returns>
|
/// <returns>The resulting quaternion</returns>
|
||||||
/// Rotation are appied in the order X, Y, Z.
|
/// Rotation are appied in the order X, Y, Z.
|
||||||
static Quaternion EulerXYZ(Vector3 eulerAngles);
|
static Quaternion EulerXYZ(Vector3Of<float> eulerAngles);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the angle of around the give axis for a rotation
|
/// Returns the angle of around the give axis for a rotation
|
||||||
@ -250,14 +250,14 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="axis">The axis around which the angle should be
|
/// <param name="axis">The axis around which the angle should be
|
||||||
/// computed</param> <param name="rotation">The source rotation</param>
|
/// computed</param> <param name="rotation">The source rotation</param>
|
||||||
/// <returns>The signed angle around the axis</returns>
|
/// <returns>The signed angle around the axis</returns>
|
||||||
static float GetAngleAround(Vector3 axis, Quaternion rotation);
|
static float GetAngleAround(Vector3Of<float> axis, Quaternion rotation);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the rotation limited around the given axis
|
/// Returns the rotation limited around the given axis
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="axis">The axis which which the rotation should be
|
/// <param name="axis">The axis which which the rotation should be
|
||||||
/// limited</param> <param name="rotation">The source rotation</param>
|
/// limited</param> <param name="rotation">The source rotation</param>
|
||||||
/// <returns>The rotation around the given axis</returns>
|
/// <returns>The rotation around the given axis</returns>
|
||||||
static Quaternion GetRotationAround(Vector3 axis, Quaternion rotation);
|
static Quaternion GetRotationAround(Vector3Of<float> axis, Quaternion rotation);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Swing-twist decomposition of a rotation
|
/// Swing-twist decomposition of a rotation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -266,7 +266,7 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="swing">A pointer to the quaternion for the swing
|
/// <param name="swing">A pointer to the quaternion for the swing
|
||||||
/// result</param> <param name="twist">A pointer to the quaternion for the
|
/// result</param> <param name="twist">A pointer to the quaternion for the
|
||||||
/// twist result</param>
|
/// twist result</param>
|
||||||
static void GetSwingTwist(Vector3 axis,
|
static void GetSwingTwist(Vector3Of<float> axis,
|
||||||
Quaternion rotation,
|
Quaternion rotation,
|
||||||
Quaternion* swing,
|
Quaternion* swing,
|
||||||
Quaternion* twist);
|
Quaternion* twist);
|
||||||
@ -284,11 +284,11 @@ struct Quaternion : Quat {
|
|||||||
float GetLengthSquared() const;
|
float GetLengthSquared() const;
|
||||||
static float GetLengthSquared(const Quaternion& q);
|
static float GetLengthSquared(const Quaternion& q);
|
||||||
|
|
||||||
void ToAxisAngleRad(const Quaternion& q, Vector3* const axis, float* angle);
|
void ToAxisAngleRad(const Quaternion& q, Vector3Of<float>* const axis, float* angle);
|
||||||
static Quaternion FromEulerRad(Vector3 euler);
|
static Quaternion FromEulerRad(Vector3Of<float> euler);
|
||||||
static Quaternion FromEulerRadXYZ(Vector3 euler);
|
static Quaternion FromEulerRadXYZ(Vector3Of<float> euler);
|
||||||
|
|
||||||
Vector3 xyz() const;
|
Vector3Of<float> xyz() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
|
|||||||
@ -64,15 +64,15 @@ SphericalOf<T> SphericalOf<T>::FromPolar(PolarOf<T> polar) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SphericalOf<T> SphericalOf<T>::FromVector3(Vector3 v) {
|
SphericalOf<T> SphericalOf<T>::FromVector3(Vector3Of<float> v) {
|
||||||
float distance = v.magnitude();
|
float distance = v.Magnitude();
|
||||||
if (distance == 0.0f) {
|
if (distance == 0.0f) {
|
||||||
return SphericalOf(distance, AngleOf<T>(), AngleOf<T>());
|
return SphericalOf(distance, AngleOf<T>(), AngleOf<T>());
|
||||||
} else {
|
} else {
|
||||||
AngleOf<T> verticalAngle =
|
AngleOf<T> verticalAngle =
|
||||||
AngleOf<T>::Radians((pi / 2 - acosf(v.Up() / distance)));
|
AngleOf<T>::Radians((pi / 2 - acosf(v.vertical / distance)));
|
||||||
AngleOf<T> horizontalAngle =
|
AngleOf<T> horizontalAngle =
|
||||||
AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
|
AngleOf<T>::Radians(atan2f(v.horizontal, v.depth));
|
||||||
return SphericalOf(distance, horizontalAngle, verticalAngle);
|
return SphericalOf(distance, horizontalAngle, verticalAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ SphericalOf<T> SphericalOf<T>::FromVector3(Vector3 v) {
|
|||||||
* @return Vector3 The 3D vector representation of the spherical coordinates.
|
* @return Vector3 The 3D vector representation of the spherical coordinates.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3 SphericalOf<T>::ToVector3() const {
|
Vector3Of<float> SphericalOf<T>::ToVector3() const {
|
||||||
float verticalRad = (pi / 2) - this->direction.vertical.InRadians();
|
float verticalRad = (pi / 2) - this->direction.vertical.InRadians();
|
||||||
float horizontalRad = this->direction.horizontal.InRadians();
|
float horizontalRad = this->direction.horizontal.InRadians();
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ Vector3 SphericalOf<T>::ToVector3() const {
|
|||||||
float y = this->distance * cosVertical;
|
float y = this->distance * cosVertical;
|
||||||
float z = this->distance * sinVertical * cosHorizontal;
|
float z = this->distance * sinVertical * cosHorizontal;
|
||||||
|
|
||||||
Vector3 v = Vector3(x, y, z);
|
Vector3Of<float> v = Vector3Of<float>(x, y, z);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,9 +145,9 @@ SphericalOf<T> SphericalOf<T>::operator-() const {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
SphericalOf<T> SphericalOf<T>::operator-(const SphericalOf<T>& s2) const {
|
SphericalOf<T> SphericalOf<T>::operator-(const SphericalOf<T>& s2) const {
|
||||||
// let's do it the easy way...
|
// let's do it the easy way...
|
||||||
Vector3 v1 = this->ToVector3();
|
Vector3Of<float> v1 = this->ToVector3();
|
||||||
Vector3 v2 = s2.ToVector3();
|
Vector3Of<float> v2 = s2.ToVector3();
|
||||||
Vector3 v = v1 - v2;
|
Vector3Of<float> v = v1 - v2;
|
||||||
SphericalOf<T> r = SphericalOf<T>::FromVector3(v);
|
SphericalOf<T> r = SphericalOf<T>::FromVector3(v);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -160,9 +160,9 @@ SphericalOf<T> SphericalOf<T>::operator-=(const SphericalOf<T>& v) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
SphericalOf<T> SphericalOf<T>::operator+(const SphericalOf<T>& s2) const {
|
SphericalOf<T> SphericalOf<T>::operator+(const SphericalOf<T>& s2) const {
|
||||||
// let's do it the easy way...
|
// let's do it the easy way...
|
||||||
Vector3 v1 = this->ToVector3();
|
Vector3Of<float> v1 = this->ToVector3();
|
||||||
Vector3 v2 = s2.ToVector3();
|
Vector3Of<float> v2 = s2.ToVector3();
|
||||||
Vector3 v = v1 + v2;
|
Vector3Of<float> v = v1 + v2;
|
||||||
SphericalOf<T> r = SphericalOf<T>::FromVector3(v);
|
SphericalOf<T> r = SphericalOf<T>::FromVector3(v);
|
||||||
return r;
|
return r;
|
||||||
/*
|
/*
|
||||||
@ -240,9 +240,9 @@ float SphericalOf<T>::DistanceBetween(const SphericalOf<T>& v1,
|
|||||||
const SphericalOf<T>& v2) {
|
const SphericalOf<T>& v2) {
|
||||||
// SphericalOf<T> difference = v1 - v2;
|
// SphericalOf<T> difference = v1 - v2;
|
||||||
// return difference.distance;
|
// return difference.distance;
|
||||||
Vector3 vec1 = v1.ToVector3();
|
Vector3Of<float> vec1 = v1.ToVector3();
|
||||||
Vector3 vec2 = v2.ToVector3();
|
Vector3Of<float> vec2 = v2.ToVector3();
|
||||||
float distance = Vector3::Distance(vec1, vec2);
|
float distance = Vector3Of<float>::Distance(vec1, vec2);
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,8 +253,8 @@ AngleOf<T> SphericalOf<T>::AngleBetween(const SphericalOf& v1,
|
|||||||
// if (denominator < epsilon)
|
// if (denominator < epsilon)
|
||||||
// return 0.0f;
|
// return 0.0f;
|
||||||
|
|
||||||
Vector3 v1_3 = v1.ToVector3();
|
Vector3Of<float> v1_3 = v1.ToVector3();
|
||||||
Vector3 v2_3 = v2.ToVector3();
|
Vector3Of<float> v2_3 = v2.ToVector3();
|
||||||
// float dot = Vector3::Dot(v1_3, v2_3);
|
// float dot = Vector3::Dot(v1_3, v2_3);
|
||||||
// float fraction = dot / denominator;
|
// float fraction = dot / denominator;
|
||||||
// if (isnan(fraction))
|
// if (isnan(fraction))
|
||||||
@ -262,7 +262,7 @@ AngleOf<T> SphericalOf<T>::AngleBetween(const SphericalOf& v1,
|
|||||||
|
|
||||||
// float cdot = Float::Clamp(fraction, -1.0, 1.0);
|
// float cdot = Float::Clamp(fraction, -1.0, 1.0);
|
||||||
// float r = ((float)acos(cdot)) * Rad2Deg;
|
// float r = ((float)acos(cdot)) * Rad2Deg;
|
||||||
AngleSingle r = Vector3::Angle(v1_3, v2_3);
|
AngleSingle r = Vector3Of<float>::UnsignedAngle(v1_3, v2_3);
|
||||||
return AngleOf<T>::Degrees(r.InDegrees());
|
return AngleOf<T>::Degrees(r.InDegrees());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,10 +270,10 @@ template <typename T>
|
|||||||
AngleOf<T> SphericalOf<T>::SignedAngleBetween(const SphericalOf<T>& v1,
|
AngleOf<T> SphericalOf<T>::SignedAngleBetween(const SphericalOf<T>& v1,
|
||||||
const SphericalOf<T>& v2,
|
const SphericalOf<T>& v2,
|
||||||
const SphericalOf<T>& axis) {
|
const SphericalOf<T>& axis) {
|
||||||
Vector3 v1_vector = v1.ToVector3();
|
Vector3Of<float> v1_vector = v1.ToVector3();
|
||||||
Vector3 v2_vector = v2.ToVector3();
|
Vector3Of<float> v2_vector = v2.ToVector3();
|
||||||
Vector3 axis_vector = axis.ToVector3();
|
Vector3Of<float> axis_vector = axis.ToVector3();
|
||||||
AngleSingle r = Vector3::SignedAngle(v1_vector, v2_vector, axis_vector);
|
AngleSingle r = Vector3Of<float>::SignedAngle(v1_vector, v2_vector, axis_vector);
|
||||||
return AngleOf<T>::Degrees(r.InDegrees());
|
return AngleOf<T>::Degrees(r.InDegrees());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,10 +59,10 @@ class SphericalOf {
|
|||||||
/// @brief Create a Spherical coordinate from a Vector3 coordinate
|
/// @brief Create a Spherical coordinate from a Vector3 coordinate
|
||||||
/// @param v The vector coordinate
|
/// @param v The vector coordinate
|
||||||
/// @return The spherical coordinate
|
/// @return The spherical coordinate
|
||||||
static SphericalOf<T> FromVector3(Vector3 v);
|
static SphericalOf<T> FromVector3(Vector3Of<float> v);
|
||||||
/// @brief Convert the spherical coordinate to a Vector3 coordinate
|
/// @brief Convert the spherical coordinate to a Vector3 coordinate
|
||||||
/// @return The vector coordinate
|
/// @return The vector coordinate
|
||||||
Vector3 ToVector3() const;
|
Vector3Of<float> ToVector3() const;
|
||||||
|
|
||||||
/// @brief A spherical vector with zero degree angles and distance
|
/// @brief A spherical vector with zero degree angles and distance
|
||||||
const static SphericalOf<T> zero;
|
const static SphericalOf<T> zero;
|
||||||
|
|||||||
@ -69,9 +69,9 @@ Quaternion SwingTwistOf<T>::ToQuaternion() const {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SwingTwistOf<T> SwingTwistOf<T>::FromQuaternion(Quaternion q) {
|
SwingTwistOf<T> SwingTwistOf<T>::FromQuaternion(Quaternion q) {
|
||||||
Vector3 angles = Quaternion::ToAngles(q);
|
Vector3Of<float> angles = Quaternion::ToAngles(q);
|
||||||
SwingTwistOf<T> r =
|
SwingTwistOf<T> r =
|
||||||
SwingTwistOf<T>::Degrees(angles.Up(), angles.Right(), angles.Forward());
|
SwingTwistOf<T>::Degrees(angles.vertical, angles.horizontal, angles.depth);
|
||||||
r.Normalize();
|
r.Normalize();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ template <typename T>
|
|||||||
SphericalOf<T> SwingTwistOf<T>::ToAngleAxis() const {
|
SphericalOf<T> SwingTwistOf<T>::ToAngleAxis() const {
|
||||||
Quaternion q = this->ToQuaternion();
|
Quaternion q = this->ToQuaternion();
|
||||||
float angle;
|
float angle;
|
||||||
Vector3 axis;
|
Vector3Of<float> axis;
|
||||||
q.ToAngleAxis(&angle, &axis);
|
q.ToAngleAxis(&angle, &axis);
|
||||||
DirectionOf<T> direction = DirectionOf<T>::FromVector3(axis);
|
DirectionOf<T> direction = DirectionOf<T>::FromVector3(axis);
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ SphericalOf<T> SwingTwistOf<T>::ToAngleAxis() const {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SwingTwistOf<T> SwingTwistOf<T>::FromAngleAxis(SphericalOf<T> aa) {
|
SwingTwistOf<T> SwingTwistOf<T>::FromAngleAxis(SphericalOf<T> aa) {
|
||||||
Vector3 vectorAxis = aa.direction.ToVector3();
|
Vector3Of<float> vectorAxis = aa.direction.ToVector3();
|
||||||
Quaternion q = Quaternion::AngleAxis(aa.distance, vectorAxis);
|
Quaternion q = Quaternion::AngleAxis(aa.distance, vectorAxis);
|
||||||
return SwingTwistOf<T>();
|
return SwingTwistOf<T>();
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ SwingTwistOf<T> SwingTwistOf<T>::Inverse(SwingTwistOf<T> rotation) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
SwingTwistOf<T> SwingTwistOf<T>::AngleAxis(float angle,
|
SwingTwistOf<T> SwingTwistOf<T>::AngleAxis(float angle,
|
||||||
const DirectionOf<T>& axis) {
|
const DirectionOf<T>& axis) {
|
||||||
Vector3 axis_vector = axis.ToVector3();
|
Vector3Of<float> axis_vector = axis.ToVector3();
|
||||||
Quaternion q = Quaternion::AngleAxis(angle, axis_vector);
|
Quaternion q = Quaternion::AngleAxis(angle, axis_vector);
|
||||||
SwingTwistOf<T> r = SwingTwistOf<T>::FromQuaternion(q);
|
SwingTwistOf<T> r = SwingTwistOf<T>::FromQuaternion(q);
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
257
Vector2.cpp
257
Vector2.cpp
@ -7,181 +7,7 @@
|
|||||||
#include "FloatSingle.h"
|
#include "FloatSingle.h"
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
// #if defined(AVR)
|
|
||||||
// #include <Arduino.h>
|
|
||||||
// #else
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
// #endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
Vector2::Vector2() {
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
Vector2::Vector2(float _x, float _y) {
|
|
||||||
x = _x;
|
|
||||||
y = _y;
|
|
||||||
}
|
|
||||||
// Vector2::Vector2(Vec2 v) {
|
|
||||||
// x = v.x;
|
|
||||||
// y = v.y;
|
|
||||||
// }
|
|
||||||
Vector2::Vector2(Vector3 v) {
|
|
||||||
x = v.Right(); // x;
|
|
||||||
y = v.Forward(); // z;
|
|
||||||
}
|
|
||||||
Vector2::Vector2(PolarSingle p) {
|
|
||||||
float horizontalRad = p.angle.InDegrees() * Deg2Rad;
|
|
||||||
float cosHorizontal = cosf(horizontalRad);
|
|
||||||
float sinHorizontal = sinf(horizontalRad);
|
|
||||||
|
|
||||||
x = p.distance * sinHorizontal;
|
|
||||||
y = p.distance * cosHorizontal;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2::~Vector2() {}
|
|
||||||
|
|
||||||
const Vector2 Vector2::zero = Vector2(0, 0);
|
|
||||||
const Vector2 Vector2::one = Vector2(1, 1);
|
|
||||||
const Vector2 Vector2::right = Vector2(1, 0);
|
|
||||||
const Vector2 Vector2::left = Vector2(-1, 0);
|
|
||||||
const Vector2 Vector2::up = Vector2(0, 1);
|
|
||||||
const Vector2 Vector2::down = Vector2(0, -1);
|
|
||||||
const Vector2 Vector2::forward = Vector2(0, 1);
|
|
||||||
const Vector2 Vector2::back = Vector2(0, -1);
|
|
||||||
|
|
||||||
bool Vector2::operator==(const Vector2& v) {
|
|
||||||
return (this->x == v.x && this->y == v.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Vector2::Magnitude(const Vector2& v) {
|
|
||||||
return sqrtf(v.x * v.x + v.y * v.y);
|
|
||||||
}
|
|
||||||
float Vector2::magnitude() const {
|
|
||||||
return (float)sqrtf(x * x + y * y);
|
|
||||||
}
|
|
||||||
float Vector2::SqrMagnitude(const Vector2& v) {
|
|
||||||
return v.x * v.x + v.y * v.y;
|
|
||||||
}
|
|
||||||
float Vector2::sqrMagnitude() const {
|
|
||||||
return (x * x + y * y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::Normalize(const Vector2& v) {
|
|
||||||
float num = Vector2::Magnitude(v);
|
|
||||||
Vector2 result = Vector2::zero;
|
|
||||||
if (num > Float::epsilon) {
|
|
||||||
result = v / num;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
Vector2 Vector2::normalized() const {
|
|
||||||
float num = this->magnitude();
|
|
||||||
Vector2 result = Vector2::zero;
|
|
||||||
if (num > Float::epsilon) {
|
|
||||||
result = ((Vector2) * this) / num;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator-() {
|
|
||||||
return Vector2(-this->x, -this->y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator-(const Vector2& v) const {
|
|
||||||
return Vector2(this->x - v.x, this->y - v.y);
|
|
||||||
}
|
|
||||||
Vector2 Vector2::operator-=(const Vector2& v) {
|
|
||||||
this->x -= v.x;
|
|
||||||
this->y -= v.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Vector2 Vector2::operator+(const Vector2& v) const {
|
|
||||||
return Vector2(this->x + v.x, this->y + v.y);
|
|
||||||
}
|
|
||||||
Vector2 Vector2::operator+=(const Vector2& v) {
|
|
||||||
this->x += v.x;
|
|
||||||
this->y += v.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::Scale(const Vector2& v1, const Vector2& v2) {
|
|
||||||
return Vector2(v1.x * v2.x, v1.y * v2.y);
|
|
||||||
}
|
|
||||||
// Vector2 Passer::LinearAlgebra::operator*(const Vector2 &v, float f) {
|
|
||||||
// return Vector2(v.x * f, v.y * f);
|
|
||||||
// }
|
|
||||||
// Vector2 Passer::LinearAlgebra::operator*(float f, const Vector2 &v) {
|
|
||||||
// return Vector2(v.x * f, v.y * f);
|
|
||||||
// }
|
|
||||||
Vector2 Vector2::operator*=(float f) {
|
|
||||||
this->x *= f;
|
|
||||||
this->y *= f;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
// Vector2 Passer::LinearAlgebra::operator/(const Vector2 &v, float f) {
|
|
||||||
// return Vector2(v.x / f, v.y / f);
|
|
||||||
// }
|
|
||||||
// Vector2 Passer::LinearAlgebra::operator/(float f, const Vector2 &v) {
|
|
||||||
// return Vector2(v.x / f, v.y / f);
|
|
||||||
// }
|
|
||||||
Vector2 Vector2::operator/=(float f) {
|
|
||||||
this->x /= f;
|
|
||||||
this->y /= f;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Vector2::Dot(const Vector2& v1, const Vector2& v2) {
|
|
||||||
return v1.x * v2.x + v1.y * v2.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Vector2::Distance(const Vector2& v1, const Vector2& v2) {
|
|
||||||
return Magnitude(v1 - v2);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Vector2::Angle(const Vector2& v1, const Vector2& v2) {
|
|
||||||
return (float)fabs(SignedAngle(v1, v2));
|
|
||||||
}
|
|
||||||
float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) {
|
|
||||||
float sqrMagFrom = v1.sqrMagnitude();
|
|
||||||
float sqrMagTo = v2.sqrMagnitude();
|
|
||||||
|
|
||||||
if (sqrMagFrom == 0 || sqrMagTo == 0)
|
|
||||||
return 0;
|
|
||||||
if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo))
|
|
||||||
#if defined(AVR)
|
|
||||||
return NAN;
|
|
||||||
#else
|
|
||||||
return nanf("");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float angleFrom = atan2f(v1.y, v1.x);
|
|
||||||
float angleTo = atan2f(v2.y, v2.x);
|
|
||||||
return -(angleTo - angleFrom) * Rad2Deg;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::Rotate(const Vector2& v, AngleSingle a) {
|
|
||||||
float angleRad = a.InDegrees() * Deg2Rad;
|
|
||||||
#if defined(AVR)
|
|
||||||
float sinValue = sin(angleRad);
|
|
||||||
float cosValue = cos(angleRad); // * Angle::Deg2Rad);
|
|
||||||
#else
|
|
||||||
float sinValue = (float)sinf(angleRad);
|
|
||||||
float cosValue = (float)cosf(angleRad);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float tx = v.x;
|
|
||||||
float ty = v.y;
|
|
||||||
Vector2 r = Vector2((cosValue * tx) - (sinValue * ty),
|
|
||||||
(sinValue * tx) + (cosValue * ty));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float f) {
|
|
||||||
Vector2 v = v1 + (v2 - v1) * f;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma region Vector2Of
|
#pragma region Vector2Of
|
||||||
|
|
||||||
@ -193,10 +19,9 @@ Vector2Of<T>::Vector2Of(T horizontal, T vertical)
|
|||||||
: horizontal(horizontal), vertical(vertical) {}
|
: horizontal(horizontal), vertical(vertical) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2Of<float> Vector2Of<T>::FromPolar(PolarOf<T> p) {
|
Vector2Of<float> Vector2Of<T>::FromPolar(PolarOf<float> p) {
|
||||||
float horizontalRad = p.angle.InDegrees() * Deg2Rad;
|
float cosHorizontal = AngleOf<float>::Cos(p.angle);
|
||||||
float cosHorizontal = cosf(horizontalRad);
|
float sinHorizontal = AngleOf<float>::Sin(p.angle);
|
||||||
float sinHorizontal = sinf(horizontalRad);
|
|
||||||
|
|
||||||
Vector2Of<float> v;
|
Vector2Of<float> v;
|
||||||
v.horizontal = p.distance * sinHorizontal;
|
v.horizontal = p.distance * sinHorizontal;
|
||||||
@ -226,7 +51,8 @@ template <typename T>
|
|||||||
float Vector2Of<T>::Magnitude() const {
|
float Vector2Of<T>::Magnitude() const {
|
||||||
T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical;
|
T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical;
|
||||||
float sqrFloat = static_cast<float>(sqr);
|
float sqrFloat = static_cast<float>(sqr);
|
||||||
return sqrtf(sqrFloat);
|
float r = sqrtf(sqrFloat);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -241,6 +67,13 @@ float Vector2Of<T>::SqrMagnitude() const {
|
|||||||
return static_cast<float>(sqr);
|
return static_cast<float>(sqr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
float Vector2Of<T>::Distance(const Vector2Of& v1, const Vector2Of& v2) {
|
||||||
|
Vector2Of<float> delta = v1 - v2;
|
||||||
|
float r = MagnitudeOf(delta);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2Of<T> Vector2Of<T>::operator-() {
|
Vector2Of<T> Vector2Of<T>::operator-() {
|
||||||
return Vector2Of<T>(-this->horizontal, -this->vertical);
|
return Vector2Of<T>(-this->horizontal, -this->vertical);
|
||||||
@ -289,11 +122,6 @@ T Vector2Of<T>::Dot(const Vector2Of& v1, const Vector2Of& v2) {
|
|||||||
return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical;
|
return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
float Vector2Of<T>::Distance(const Vector2Of& v1, const Vector2Of& v2) {
|
|
||||||
return MagnitudeOf(v1 - v2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2Of<float> Vector2Of<T>::Normalize(const Vector2Of<T>& v) {
|
Vector2Of<float> Vector2Of<T>::Normalize(const Vector2Of<T>& v) {
|
||||||
float num = Vector2Of<T>::MagnitudeOf(v);
|
float num = Vector2Of<T>::MagnitudeOf(v);
|
||||||
@ -305,68 +133,50 @@ Vector2Of<float> Vector2Of<T>::Normalize(const Vector2Of<T>& v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<T> Vector2Of<T>::UnsignedAngle(const Vector2Of& v1,
|
AngleOf<float> Vector2Of<T>::UnsignedAngle(const Vector2Of& v1,
|
||||||
const Vector2Of& v2) {
|
const Vector2Of& v2) {
|
||||||
return AngleOf<T>::Abs(SignedAngle(v1, v2));
|
return AngleOf<float>::Abs(SignedAngle(v1, v2));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<T> Vector2Of<T>::SignedAngle(const Vector2Of& v1, const Vector2Of& v2) {
|
AngleOf<float> Vector2Of<T>::SignedAngle(const Vector2Of& v1,
|
||||||
|
const Vector2Of& v2) {
|
||||||
float sqrMagFrom = v1.SqrMagnitude();
|
float sqrMagFrom = v1.SqrMagnitude();
|
||||||
float sqrMagTo = v2.SqrMagnitude();
|
float sqrMagTo = v2.SqrMagnitude();
|
||||||
|
|
||||||
if (sqrMagFrom == 0 || sqrMagTo == 0)
|
if (sqrMagFrom == 0 || sqrMagTo == 0)
|
||||||
return AngleOf<T>::zero;
|
return AngleOf<float>::zero;
|
||||||
if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo))
|
if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo))
|
||||||
return AngleOf<T>::zero; // Angle does not support NaN...
|
return AngleOf<float>::zero; // Angle does not support NaN...
|
||||||
|
|
||||||
AngleOf<T> angleFrom = AngleOf<T>::Atan2(static_cast<float>(v1.vertical),
|
AngleOf<float> angleFrom = AngleOf<float>::Atan2(
|
||||||
static_cast<float>(v1.horizontal));
|
static_cast<float>(v1.vertical), static_cast<float>(v1.horizontal));
|
||||||
AngleOf<T> angleTo = AngleOf<T>::Atan2(static_cast<float>(v2.vertical),
|
AngleOf<float> angleTo = AngleOf<float>::Atan2(
|
||||||
static_cast<float>(v2.horizontal));
|
static_cast<float>(v2.vertical), static_cast<float>(v2.horizontal));
|
||||||
return -(angleTo - angleFrom);
|
return -(angleTo - angleFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2Of<float> Vector2Of<T>::Rotate(const Vector2Of& v, AngleOf<T> a) {
|
Vector2Of<float> Vector2Of<T>::Rotate(const Vector2Of& v, AngleOf<float> a) {
|
||||||
float sinValue = AngleOf<T>::Sin(a);
|
float sinValue = AngleOf<float>::Sin(a);
|
||||||
float cosValue = AngleOf<T>::Cos(a);
|
float cosValue = AngleOf<float>::Cos(a);
|
||||||
float tx = static_cast<float>(v.horizontal);
|
float tx = static_cast<float>(v.horizontal);
|
||||||
float ty = static_cast<float>(v.vertical);
|
float ty = static_cast<float>(v.vertical);
|
||||||
Vector2Of<float> r = Vector2Of<float>((cosValue * tx) - (sinValue * ty),
|
Vector2Of<float> r = Vector2Of<float>((cosValue * tx) - (sinValue * ty),
|
||||||
(sinValue * tx) + (cosValue * ty));
|
(sinValue * tx) + (cosValue * ty));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2Of<float> Vector2Of<T>::Lerp(const Vector2Of& v1,
|
Vector2Of<float> Vector2Of<T>::Lerp(const Vector2Of& v1,
|
||||||
const Vector2Of& v2,
|
const Vector2Of& v2,
|
||||||
float f) {
|
float f) {
|
||||||
Vector2Of<float> v = v1 + static_cast<Vector2Of<float>>(v2 - v1) * f;
|
Vector2Of<float> v1f = (Vector2Of<float>)v1;
|
||||||
return v;
|
Vector2Of<float> delta = v2 - v1;
|
||||||
|
Vector2Of<float> r = v1f + delta * f;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// float Vector2::Angle(const Vector2& v1, const Vector2& v2) {
|
|
||||||
// return (float)fabs(SignedAngle(v1, v2));
|
|
||||||
// }
|
|
||||||
// float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) {
|
|
||||||
// float sqrMagFrom = v1.sqrMagnitude();
|
|
||||||
// float sqrMagTo = v2.sqrMagnitude();
|
|
||||||
|
|
||||||
// if (sqrMagFrom == 0 || sqrMagTo == 0)
|
|
||||||
// return 0;
|
|
||||||
// if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo))
|
|
||||||
// #if defined(AVR)
|
|
||||||
// return NAN;
|
|
||||||
// #else
|
|
||||||
// return nanf("");
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// float angleFrom = atan2f(v1.y, v1.x);
|
|
||||||
// float angleTo = atan2f(v2.y, v2.x);
|
|
||||||
// return -(angleTo - angleFrom) * Rad2Deg;
|
|
||||||
// }
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2Of<float> Vector2Of<T>::Normalized() const {
|
Vector2Of<float> Vector2Of<T>::Normalized() const {
|
||||||
float num = Vector2Of<T>::MagnitudeOf(*this);
|
float num = Vector2Of<T>::MagnitudeOf(*this);
|
||||||
@ -379,6 +189,7 @@ Vector2Of<float> Vector2Of<T>::Normalized() const {
|
|||||||
|
|
||||||
// Explicit instantiation for int
|
// Explicit instantiation for int
|
||||||
template class Vector2Of<signed short>;
|
template class Vector2Of<signed short>;
|
||||||
|
template class Vector2Of<int>;
|
||||||
template class Vector2Of<float>;
|
template class Vector2Of<float>;
|
||||||
|
|
||||||
#pragma endregion Vector2Of
|
#pragma endregion Vector2Of
|
||||||
31
Vector2.h
31
Vector2.h
@ -216,8 +216,6 @@ class Vector2Of {
|
|||||||
/// up = positive
|
/// up = positive
|
||||||
Vector2Of(T horizontal, T vertical);
|
Vector2Of(T horizontal, T vertical);
|
||||||
|
|
||||||
static Vector2Of<float> FromPolar(PolarOf<T> v);
|
|
||||||
|
|
||||||
/// @brief Converting constructor: allow Vector2Of<U> -> Vector2Of<T>
|
/// @brief Converting constructor: allow Vector2Of<U> -> Vector2Of<T>
|
||||||
/// @tparam U
|
/// @tparam U
|
||||||
/// @param other
|
/// @param other
|
||||||
@ -226,10 +224,13 @@ class Vector2Of {
|
|||||||
: horizontal(static_cast<T>(other.horizontal)),
|
: horizontal(static_cast<T>(other.horizontal)),
|
||||||
vertical(static_cast<T>(other.vertical)) {}
|
vertical(static_cast<T>(other.vertical)) {}
|
||||||
|
|
||||||
|
static Vector2Of<float> FromPolar(PolarOf<float> v);
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
constexpr Vector2Of& operator=(const Vector2Of<U>& other) noexcept {
|
constexpr Vector2Of& operator=(const Vector2Of<U>& other) noexcept {
|
||||||
this.horizontal = static_cast<T>(other.horizontal);
|
this->horizontal = static_cast<T>(other.horizontal);
|
||||||
this.vertical = static_cast<T>(other.vertical);
|
this->vertical = static_cast<T>(other.vertical);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief A vector with zero for all axis
|
/// @brief A vector with zero for all axis
|
||||||
@ -266,6 +267,12 @@ class Vector2Of {
|
|||||||
/// of the squared root of C.
|
/// of the squared root of C.
|
||||||
float SqrMagnitude() const;
|
float SqrMagnitude() const;
|
||||||
|
|
||||||
|
/// @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 Vector2Of& v1, const Vector2Of& v2);
|
||||||
|
|
||||||
/// @brief Negate the vector such that it points in the opposite direction
|
/// @brief Negate the vector such that it points in the opposite direction
|
||||||
/// @return The negated vector
|
/// @return The negated vector
|
||||||
Vector2Of operator-();
|
Vector2Of operator-();
|
||||||
@ -315,12 +322,6 @@ class Vector2Of {
|
|||||||
/// @return The dot product of the two vectors
|
/// @return The dot product of the two vectors
|
||||||
static T Dot(const Vector2Of& v1, const Vector2Of& v2);
|
static T Dot(const Vector2Of& v1, const Vector2Of& v2);
|
||||||
|
|
||||||
/// @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 Vector2Of& v1, const Vector2Of& v2);
|
|
||||||
|
|
||||||
static Vector2Of<float> Normalize(const Vector2Of& v);
|
static Vector2Of<float> Normalize(const Vector2Of& v);
|
||||||
/// @brief Convert the vector to a length 1
|
/// @brief Convert the vector to a length 1
|
||||||
/// @return The vector normalized to a length of 1
|
/// @return The vector normalized to a length of 1
|
||||||
@ -333,18 +334,18 @@ class Vector2Of {
|
|||||||
/// @remark This reterns an unsigned angle which is the shortest distance
|
/// @remark This reterns an unsigned angle which is the shortest distance
|
||||||
/// between the two vectors. Use Vector2::SignedAngle if a signed angle is
|
/// between the two vectors. Use Vector2::SignedAngle if a signed angle is
|
||||||
/// needed.
|
/// needed.
|
||||||
static AngleOf<T> UnsignedAngle(const Vector2Of& v1, const Vector2Of& v2);
|
static AngleOf<float> UnsignedAngle(const Vector2Of& v1, const Vector2Of& v2);
|
||||||
/// @brief The signed angle between two vectors
|
/// @brief The signed angle between two vectors
|
||||||
/// @param v1 The starting vector
|
/// @param v1 The starting vector
|
||||||
/// @param v2 The ending vector
|
/// @param v2 The ending vector
|
||||||
/// @return The signed angle between the two vectors
|
/// @return The signed angle between the two vectors
|
||||||
static AngleOf<T> SignedAngle(const Vector2Of& v1, const Vector2Of& v2);
|
static AngleOf<float> SignedAngle(const Vector2Of& v1, const Vector2Of& v2);
|
||||||
|
|
||||||
/// @brief Rotate the vector
|
/// @brief Rotate the vector
|
||||||
/// @param v The vector to rotate
|
/// @param v The vector to rotate
|
||||||
/// @param a The angle in degrees to rotate
|
/// @param a The angle in degrees to rotate
|
||||||
/// @return The rotated vector
|
/// @return The rotated vector
|
||||||
static Vector2Of<float> Rotate(const Vector2Of& v, AngleOf<T> a);
|
static Vector2Of<float> Rotate(const Vector2Of& v, AngleOf<float> a);
|
||||||
|
|
||||||
/// @brief Lerp (linear interpolation) between two vectors
|
/// @brief Lerp (linear interpolation) between two vectors
|
||||||
/// @param v1 The starting vector
|
/// @param v1 The starting vector
|
||||||
@ -354,7 +355,9 @@ class Vector2Of {
|
|||||||
/// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value
|
/// @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
|
/// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference
|
||||||
/// between *v1* and *v2* etc.
|
/// between *v1* and *v2* etc.
|
||||||
static Vector2Of<float> Lerp(const Vector2Of& v1, const Vector2Of& v2, float f);
|
static Vector2Of<float> Lerp(const Vector2Of& v1,
|
||||||
|
const Vector2Of& v2,
|
||||||
|
float f);
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma region friend functions
|
#pragma region friend functions
|
||||||
|
|||||||
179
Vector3.cpp
179
Vector3.cpp
@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
#include "FloatSingle.h"
|
||||||
#include "Spherical.h"
|
#include "Spherical.h"
|
||||||
//#include "TypeTraits.h"
|
// #include "TypeTraits.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ const float Deg2Rad = 0.0174532924F;
|
|||||||
const float Rad2Deg = 57.29578F;
|
const float Rad2Deg = 57.29578F;
|
||||||
const float epsilon = 1E-05f;
|
const float epsilon = 1E-05f;
|
||||||
|
|
||||||
|
/*
|
||||||
Vector3::Vector3() {
|
Vector3::Vector3() {
|
||||||
this->x = 0;
|
this->x = 0;
|
||||||
this->y = 0;
|
this->y = 0;
|
||||||
@ -161,7 +163,8 @@ float Vector3::Distance(const Vector3& v1, const Vector3& v2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::Cross(const Vector3& v1, const Vector3& v2) {
|
Vector3 Vector3::Cross(const Vector3& v1, const Vector3& v2) {
|
||||||
return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x);
|
return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x *
|
||||||
|
v2.y - v1.y * v2.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::Project(const Vector3& v, const Vector3& n) {
|
Vector3 Vector3::Project(const Vector3& v, const Vector3& n) {
|
||||||
@ -194,14 +197,16 @@ AngleOf<float> Vector3::Angle(const Vector3& v1, const Vector3& v2) {
|
|||||||
float dot = Vector3::Dot(v1, v2);
|
float dot = Vector3::Dot(v1, v2);
|
||||||
float fraction = dot / denominator;
|
float fraction = dot / denominator;
|
||||||
if (isnan(fraction))
|
if (isnan(fraction))
|
||||||
return AngleOf<float>::Degrees(fraction); // short cut to returning NaN universally
|
return AngleOf<float>::Degrees(fraction); // short cut to returning NaN
|
||||||
|
universally
|
||||||
|
|
||||||
float cdot = clamp(fraction, -1.0, 1.0);
|
float cdot = clamp(fraction, -1.0, 1.0);
|
||||||
float r = ((float)acos(cdot));
|
float r = ((float)acos(cdot));
|
||||||
return AngleOf<float>::Radians(r);
|
return AngleOf<float>::Radians(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
AngleOf<float> Vector3::SignedAngle(const Vector3& v1, const Vector3& v2, const Vector3& axis) {
|
AngleOf<float> Vector3::SignedAngle(const Vector3& v1, const Vector3& v2, const
|
||||||
|
Vector3& axis) {
|
||||||
// angle in [0,180]
|
// angle in [0,180]
|
||||||
AngleOf<float> angle = Vector3::Angle(v1, v2);
|
AngleOf<float> angle = Vector3::Angle(v1, v2);
|
||||||
|
|
||||||
@ -219,6 +224,7 @@ Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float f) {
|
|||||||
Vector3 v = v1 + (v2 - v1) * f;
|
Vector3 v = v1 + (v2 - v1) * f;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#pragma region Vector3Of
|
#pragma region Vector3Of
|
||||||
|
|
||||||
@ -232,44 +238,47 @@ Vector3Of<T>::Vector3Of(T horizontal, T vertical, T depth)
|
|||||||
: horizontal(horizontal), vertical(vertical), depth(depth) {}
|
: horizontal(horizontal), vertical(vertical), depth(depth) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3Of<T>::Vector3Of(Vector2Of<T> v) : horizontal(v.horizontal), vertical(v.vertical) {}
|
Vector3Of<T>::Vector3Of(Vector2Of<T> v)
|
||||||
|
: horizontal(v.horizontal), vertical(v.vertical) {}
|
||||||
template <typename T>
|
|
||||||
Vector3Of<T>::Vector3Of(SphericalOf<T> v) {
|
|
||||||
float cosVertical = AngleOf<T>::Cos(v.direction.vertical);
|
|
||||||
float sinVertical = AngleOf<T>::Sin(v.direction.vertical);
|
|
||||||
float cosHorizontal = AngleOf<T>::Cos(v.direction.horizontal);
|
|
||||||
float sinHorizontal = AngleOf<T>::Sin(v.direction.horizontal);
|
|
||||||
|
|
||||||
horizontal = v.distance * sinVertical * sinHorizontal;
|
|
||||||
vertical = v.distance * cosVertical;
|
|
||||||
depth = v.distance * sinVertical * cosHorizontal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Vector3Of<T>::Vector3Of(Vector3 v) : horizontal(v.x), vertical(v.y), depth(v.z) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Vector3 Vector3Of<T>::ToVector3() {
|
|
||||||
return Vector3(this->horizontal, this->vertical, this->depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3Of<T>::~Vector3Of() {}
|
Vector3Of<T>::~Vector3Of() {}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
Vector3Of<float> Vector3Of<float>::FromSpherical(SphericalOf<float> v) {
|
||||||
|
AngleOf<float> vertical = AngleOf<float>::Degrees(90) - v.direction.vertical;
|
||||||
|
AngleOf<float> horizontal = v.direction.horizontal;
|
||||||
|
float cosVertical = AngleOf<float>::Cos(vertical);
|
||||||
|
float sinVertical = AngleOf<float>::Sin(vertical);
|
||||||
|
float cosHorizontal = AngleOf<float>::Cos(horizontal);
|
||||||
|
float sinHorizontal = AngleOf<float>::Sin(horizontal);
|
||||||
|
|
||||||
|
Vector3Of<float> r = Vector3Of<float>();
|
||||||
|
r.horizontal = v.distance * sinVertical * sinHorizontal;
|
||||||
|
r.vertical = v.distance * cosVertical;
|
||||||
|
r.depth = v.distance * sinVertical * cosHorizontal;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const Vector3Of<T> Vector3Of<T>::zero = Vector3Of(T{}, T{}, T{});
|
const Vector3Of<T> Vector3Of<T>::zero = Vector3Of(T{}, T{}, T{});
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const Vector3Of<int> Vector3Of<int>::unit = Vector3Of<int>(1, 1, 1);
|
const Vector3Of<int> Vector3Of<int>::unit = Vector3Of<int>(1, 1, 1);
|
||||||
template <>
|
template <>
|
||||||
const Vector3Of<float> Vector3Of<float>::unit = Vector3Of<float>(1.0f, 1.0f, 1.0f);
|
const Vector3Of<float> Vector3Of<float>::unit =
|
||||||
|
Vector3Of<float>(1.0f, 1.0f, 1.0f);
|
||||||
template <>
|
template <>
|
||||||
const Vector3Of<double> Vector3Of<double>::unit = Vector3Of<double>(1.0f, 1.0f, 1.0f);
|
const Vector3Of<double> Vector3Of<double>::unit =
|
||||||
|
Vector3Of<double>(1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const Vector3Of<T> Vector3Of<T>::forward = Vector3Of(T{}, T{}, 1);
|
||||||
|
|
||||||
// template <typename T>
|
// template <typename T>
|
||||||
// const Vector3Of<T> Vector3Of<T>::unit =
|
// const Vector3Of<T> Vector3Of<T>::unit =
|
||||||
// Vector3Of(TypeTraits<T>::unit(), TypeTraits<T>::unit(), TypeTraits<T>::unit());
|
// Vector3Of(TypeTraits<T>::unit(), TypeTraits<T>::unit(),
|
||||||
|
// TypeTraits<T>::unit());
|
||||||
// const Vector3Of Vector3Of::right = Vector3Of(1, 0, 0);
|
// const Vector3Of Vector3Of::right = Vector3Of(1, 0, 0);
|
||||||
// const Vector3Of Vector3Of::left = Vector3Of(-1, 0, 0);
|
// const Vector3Of Vector3Of::left = Vector3Of(-1, 0, 0);
|
||||||
// const Vector3Of Vector3Of::up = Vector3Of(0, 1, 0);
|
// const Vector3Of Vector3Of::up = Vector3Of(0, 1, 0);
|
||||||
@ -278,18 +287,26 @@ const Vector3Of<double> Vector3Of<double>::unit = Vector3Of<double>(1.0f, 1.0f,
|
|||||||
// const Vector3Of Vector3Of::back = Vector3Of(0, 0, -1);
|
// const Vector3Of Vector3Of::back = Vector3Of(0, 0, -1);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Vector3Of<T>::MagnitudeOf(const Vector3Of& v) {
|
bool Vector3Of<T>::operator==(const Vector3Of& v) const {
|
||||||
return sqrtf(v.horizontal * v.horizontal + v.vertical * v.vertical + v.depth * v.depth);
|
return (this->horizontal == v.horizontal && this->vertical == v.vertical &&
|
||||||
|
this->depth == v.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
float Vector3Of<T>::MagnitudeOf(const Vector3Of& v) {
|
||||||
|
return sqrtf(v.horizontal * v.horizontal + v.vertical * v.vertical +
|
||||||
|
v.depth * v.depth);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Vector3Of<T>::Magnitude() const {
|
float Vector3Of<T>::Magnitude() const {
|
||||||
return (T)sqrtf(this->horizontal * this->horizontal + this->vertical * this->vertical +
|
return sqrtf(this->horizontal * this->horizontal +
|
||||||
this->depth * this->depth);
|
this->vertical * this->vertical + this->depth * this->depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
float Vector3Of<T>::SqrMagnitudeOf(const Vector3Of& v) {
|
float Vector3Of<T>::SqrMagnitudeOf(const Vector3Of& v) {
|
||||||
return v.horizontal * v.horizontal + v.vertical * v.vertical + v.depth * v.depth;
|
return v.horizontal * v.horizontal + v.vertical * v.vertical +
|
||||||
|
v.depth * v.depth;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
float Vector3Of<T>::SqrMagnitude() const {
|
float Vector3Of<T>::SqrMagnitude() const {
|
||||||
@ -311,14 +328,18 @@ Vector3Of<T> Vector3Of<T>::Normalized() const {
|
|||||||
float num = this->Magnitude();
|
float num = this->Magnitude();
|
||||||
Vector3Of<T> result = Vector3Of<T>::zero;
|
Vector3Of<T> result = Vector3Of<T>::zero;
|
||||||
if (num > epsilon) {
|
if (num > epsilon) {
|
||||||
result = ((Vector3Of<T>) * this) / num;
|
result = ((Vector3Of<T>)*this) / num;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Vector3Of<T> Vector3Of<T>::operator-() const {
|
||||||
|
return Vector3Of<T>(-this->horizontal, -this->vertical, -this->depth);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
Vector3Of<T> Vector3Of<T>::operator-(const Vector3Of& v) const {
|
Vector3Of<T> Vector3Of<T>::operator-(const Vector3Of& v) const {
|
||||||
return Vector3(this->horizontal - v.horizontal, this->vertical - v.vertical,
|
return Vector3Of<T>(this->horizontal - v.horizontal,
|
||||||
this->depth - v.depth);
|
this->vertical - v.vertical, this->depth - v.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -331,8 +352,8 @@ Vector3Of<T> Vector3Of<T>::operator-=(const Vector3Of& v) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3Of<T> Vector3Of<T>::operator+(const Vector3Of& v) const {
|
Vector3Of<T> Vector3Of<T>::operator+(const Vector3Of& v) const {
|
||||||
return Vector3(this->horizontal + v.horizontal, this->vertical + v.vertical,
|
return Vector3Of<T>(this->horizontal + v.horizontal,
|
||||||
this->depth + v.depth);
|
this->vertical + v.vertical, this->depth + v.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -343,6 +364,12 @@ Vector3Of<T> Vector3Of<T>::operator+=(const Vector3Of& v) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Vector3Of<T> Vector3Of<T>::Scale(const Vector3Of& v1, const Vector3Of& v2) {
|
||||||
|
return Vector3Of<T>(v1.horizontal * v2.horizontal, v1.vertical * v2.vertical,
|
||||||
|
v1.depth * v2.depth);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3Of<T> Vector3Of<T>::operator*=(float f) {
|
Vector3Of<T> Vector3Of<T>::operator*=(float f) {
|
||||||
this->horizontal *= f;
|
this->horizontal *= f;
|
||||||
@ -360,12 +387,64 @@ Vector3Of<T> Vector3Of<T>::operator/=(float f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
float Vector3Of<T>::Dot(const Vector3Of& v1, const Vector3Of& v2) {
|
float Vector3Of<T>::Distance(const Vector3Of& v1, const Vector3Of& v2) {
|
||||||
return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical + v1.depth * v2.depth;
|
return MagnitudeOf(v1 - v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<float> Vector3Of<T>::UnsignedAngle(const Vector3Of& v1, const Vector3Of& v2) {
|
T Vector3Of<T>::Dot(const Vector3Of& v1, const Vector3Of& v2) {
|
||||||
|
return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical +
|
||||||
|
v1.depth * v2.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Vector3Of<T> Vector3Of<T>::Cross(const Vector3Of& v1, const Vector3Of& v2) {
|
||||||
|
return Vector3Of<T>(
|
||||||
|
v1.vertical * v2.depth - v1.depth * v2.vertical,
|
||||||
|
v1.depth * v2.horizontal - v1.horizontal * v2.depth,
|
||||||
|
v1.horizontal * v2.vertical - v1.vertical * v2.horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Vector3Of<float> Vector3Of<T>::Project(const Vector3Of& v, const Vector3Of& n) {
|
||||||
|
T sqrMagnitude = Dot(n, n);
|
||||||
|
if (sqrMagnitude < epsilon)
|
||||||
|
return Vector3Of<float>::zero;
|
||||||
|
else {
|
||||||
|
T dot = Dot(v, n);
|
||||||
|
Vector3Of<float> r = n * dot;
|
||||||
|
r /= sqrMagnitude;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Vector3Of<float> Vector3Of<T>::ProjectOnPlane(const Vector3Of& v,
|
||||||
|
const Vector3Of& n) {
|
||||||
|
Vector3Of<float> r = (Vector3Of<float>)v - Project(v, n);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AngleOf<float> Vector3Of<T>::SignedAngle(const Vector3Of& v1,
|
||||||
|
const Vector3Of& v2,
|
||||||
|
const Vector3Of& axis) {
|
||||||
|
// angle in [0,180]
|
||||||
|
AngleOf<float> angle = Vector3Of<T>::UnsignedAngle(v1, v2);
|
||||||
|
|
||||||
|
Vector3Of<T> cross = Vector3Of<T>::Cross(v1, v2);
|
||||||
|
float b = Vector3Of<T>::Dot(axis, cross);
|
||||||
|
float signd = b < 0 ? -1.0F : (b > 0 ? 1.0F : 0.0F);
|
||||||
|
|
||||||
|
// angle in [-179,180]
|
||||||
|
AngleOf<float> signed_angle = angle * signd;
|
||||||
|
|
||||||
|
return AngleOf<float>(signed_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AngleOf<float> Vector3Of<T>::UnsignedAngle(const Vector3Of& v1,
|
||||||
|
const Vector3Of& v2) {
|
||||||
float denominator = sqrtf(v1.SqrMagnitude() * v2.SqrMagnitude());
|
float denominator = sqrtf(v1.SqrMagnitude() * v2.SqrMagnitude());
|
||||||
if (denominator < epsilon)
|
if (denominator < epsilon)
|
||||||
return AngleOf<float>();
|
return AngleOf<float>();
|
||||||
@ -373,14 +452,26 @@ AngleOf<float> Vector3Of<T>::UnsignedAngle(const Vector3Of& v1, const Vector3Of&
|
|||||||
float dot = Vector3Of::Dot(v1, v2);
|
float dot = Vector3Of::Dot(v1, v2);
|
||||||
float fraction = dot / denominator;
|
float fraction = dot / denominator;
|
||||||
if (isnan(fraction))
|
if (isnan(fraction))
|
||||||
return AngleOf<float>::Degrees(fraction); // short cut to returning NaN universally
|
return AngleOf<float>::Degrees(
|
||||||
|
fraction); // short cut to returning NaN universally
|
||||||
|
|
||||||
float cdot = clamp(fraction, -1.0, 1.0);
|
float cdot = Float::Clamp(fraction, -1.0, 1.0);
|
||||||
float r = ((float)acos(cdot));
|
float r = ((float)acos(cdot));
|
||||||
return AngleOf<float>::Radians(r);
|
return AngleOf<float>::Radians(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Vector3Of<float> Vector3Of<T>::Lerp(const Vector3Of& v1,
|
||||||
|
const Vector3Of& v2,
|
||||||
|
float f) {
|
||||||
|
Vector3Of<float> v1f = v1;
|
||||||
|
Vector3Of<float> delta = v2 - v1;
|
||||||
|
Vector3Of<float> r = v1f + delta * f;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
template class Vector3Of<float>;
|
template class Vector3Of<float>;
|
||||||
|
template class Vector3Of<int>;
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
|
|
||||||
|
|||||||
144
Vector3.h
144
Vector3.h
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "Vector2.h"
|
#include "Vector2.h"
|
||||||
|
|
||||||
|
/*
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 3-dimensional Vector representation (C-style)
|
/// 3-dimensional Vector representation (C-style)
|
||||||
@ -31,12 +31,14 @@ typedef struct Vec3 {
|
|||||||
|
|
||||||
} Vec3;
|
} Vec3;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SphericalOf;
|
class SphericalOf;
|
||||||
|
|
||||||
|
/*
|
||||||
/// @brief A 3-dimensional vector
|
/// @brief A 3-dimensional vector
|
||||||
/// @remark This uses a right-handed carthesian coordinate system.
|
/// @remark This uses a right-handed carthesian coordinate system.
|
||||||
/// @note This implementation intentionally avoids the use of x, y and z values.
|
/// @note This implementation intentionally avoids the use of x, y and z values.
|
||||||
@ -147,8 +149,8 @@ struct Vector3 : Vec3 {
|
|||||||
/// @return The scaled vector
|
/// @return The scaled vector
|
||||||
/// @remark Each component of the vector will be multipled with the same
|
/// @remark Each component of the vector will be multipled with the same
|
||||||
/// factor f.
|
/// factor f.
|
||||||
friend Vector3 operator*(const Vector3& v, float f) { return Vector3(v.x * f, v.y * f, v.z * f); }
|
friend Vector3 operator*(const Vector3& v, float f) { return Vector3(v.x * f,
|
||||||
friend Vector3 operator*(float f, const Vector3& v) {
|
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(f * v.x, f * v.y, f * v.z);
|
||||||
return Vector3(v.x * f, v.y * f, v.z * f);
|
return Vector3(v.x * f, v.y * f, v.z * f);
|
||||||
}
|
}
|
||||||
@ -157,8 +159,8 @@ struct Vector3 : Vec3 {
|
|||||||
/// @param f The scaling factor
|
/// @param f The scaling factor
|
||||||
/// @return The scaled vector
|
/// @return The scaled vector
|
||||||
/// @remark Each componet of the vector will be divided by the same factor.
|
/// @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/(const Vector3& v, float f) { return Vector3(v.x / f,
|
||||||
friend Vector3 operator/(float f, const Vector3& v) {
|
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(f / v.x, f / v.y, f / v.z);
|
||||||
return Vector3(v.x / f, v.y / f, v.z / f);
|
return Vector3(v.x / f, v.y / f, v.z / f);
|
||||||
}
|
}
|
||||||
@ -207,7 +209,8 @@ struct Vector3 : Vec3 {
|
|||||||
/// @param v2 The ending vector
|
/// @param v2 The ending vector
|
||||||
/// @param axis The axis to rotate around
|
/// @param axis The axis to rotate around
|
||||||
/// @return The signed angle between the two vectors
|
/// @return The signed angle between the two vectors
|
||||||
static AngleOf<float> SignedAngle(const Vector3& v1, const Vector3& v2, const Vector3& axis);
|
static AngleOf<float> SignedAngle(const Vector3& v1, const Vector3& v2, const
|
||||||
|
Vector3& axis);
|
||||||
|
|
||||||
/// @brief Lerp (linear interpolation) between two vectors
|
/// @brief Lerp (linear interpolation) between two vectors
|
||||||
/// @param v1 The starting vector
|
/// @param v1 The starting vector
|
||||||
@ -219,57 +222,86 @@ struct Vector3 : Vec3 {
|
|||||||
/// between *v1* and *v2* etc.
|
/// between *v1* and *v2* etc.
|
||||||
static Vector3 Lerp(const Vector3& v1, const Vector3& v2, float f);
|
static Vector3 Lerp(const Vector3& v1, const Vector3& v2, float f);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
/// @brief A 3-dimensional vector
|
/// @brief A 3-dimensional vector
|
||||||
/// @remark This uses a right-handed carthesian coordinate system.
|
/// @remark This uses a right-handed carthesian coordinate system.
|
||||||
/// @remark No default unit (for instance, meters) is specified
|
/// @remark No default unit (for instance, meters) is specified
|
||||||
/// @note This implementation intentionally avoids the use of x, y and z values.
|
/// @note This implementation intentionally avoids the use of x, y and z values.
|
||||||
/// @tparam T The type of the paramters used to measure distance. Typical values are float and int
|
/// @tparam T The type of the paramters used to measure distance. Typical values
|
||||||
|
/// are float and int
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Vector3Of {
|
class Vector3Of {
|
||||||
public:
|
public:
|
||||||
/// @brief The distance in the horizontal direction, left = negative, right = positive
|
/// @brief The distance in the horizontal direction, left = negative, right =
|
||||||
|
/// positive
|
||||||
T horizontal = T{};
|
T horizontal = T{};
|
||||||
/// @brief The distance in the vertical direction, down = negative, up = positive
|
/// @brief The distance in the vertical direction, down = negative, up =
|
||||||
|
/// positive
|
||||||
T vertical = T{};
|
T vertical = T{};
|
||||||
/// @brief The distance in the depth direction, backward = negative, forward = positive
|
/// @brief The distance in the depth direction, backward = negative, forward =
|
||||||
|
/// positive
|
||||||
T depth = T{};
|
T depth = T{};
|
||||||
|
|
||||||
/// @brief A new 3-dimensional zero vector
|
/// @brief A new 3-dimensional zero vector
|
||||||
Vector3Of();
|
Vector3Of();
|
||||||
/// @brief A new 3-dimensional vector
|
/// @brief A new 3-dimensional vector
|
||||||
/// @param horizontal The distance in the horizontal direction, left = negative, right =
|
/// @param horizontal The distance in the horizontal direction, left =
|
||||||
/// positive
|
/// negative, right = positive
|
||||||
/// @param vertical The distance in the vertical direction, down = negative, up =
|
/// @param vertical The distance in the vertical direction, down = negative,
|
||||||
/// positive
|
/// up = positive
|
||||||
/// @param depth The distance in the depth direction, backward = negative, forward =
|
/// @param depth The distance in the depth direction, backward = negative,
|
||||||
/// positive
|
/// forward = positive
|
||||||
Vector3Of(T horizontal, T vertical, T depth);
|
Vector3Of(T horizontal, T vertical, T depth);
|
||||||
Vector3Of(Vector2Of<T> v);
|
Vector3Of(Vector2Of<T> v);
|
||||||
Vector3Of(SphericalOf<T> v);
|
// Vector3Of(SphericalOf<T> v);
|
||||||
Vector3Of(Vector3 v);
|
|
||||||
|
|
||||||
Vector3 ToVector3();
|
|
||||||
|
|
||||||
/// @brief Vector3 destructor
|
/// @brief Vector3 destructor
|
||||||
~Vector3Of();
|
~Vector3Of();
|
||||||
|
|
||||||
|
/// @brief Converting constructor: allow Vector2Of<U> -> Vector2Of<T>
|
||||||
|
/// @tparam U
|
||||||
|
/// @param other
|
||||||
|
template <typename U>
|
||||||
|
constexpr Vector3Of(const Vector3Of<U>& other) noexcept
|
||||||
|
: horizontal(static_cast<T>(other.horizontal)),
|
||||||
|
vertical(static_cast<T>(other.vertical)),
|
||||||
|
depth(static_cast<T>(other.depth)) {}
|
||||||
|
|
||||||
|
static Vector3Of<float> FromSpherical(SphericalOf<float> v);
|
||||||
|
|
||||||
/// @brief A vector with zero for all axis
|
/// @brief A vector with zero for all axis
|
||||||
const static Vector3Of zero;
|
const static Vector3Of zero;
|
||||||
/// @brief A vector with unit for all axis
|
/// @brief A vector with unit for all axis
|
||||||
const static Vector3Of unit;
|
const static Vector3Of unit;
|
||||||
// const Vector3Of<int> Vector3Of<int>::unit(1, 1, 1); // Hardcoded unit vector for int
|
/// @brief A normalized forward-oriented vector
|
||||||
// const Vector3Of<float> Vector3Of<float>::unit(1.0f, 1.0f, 1.0f); // Hardcoded unit vector for
|
const static Vector3Of forward;
|
||||||
// float
|
/// @brief A normalized back-oriented vector
|
||||||
|
const static Vector3Of back;
|
||||||
|
/// @brief A normalized right-oriented vector
|
||||||
|
const static Vector3Of right;
|
||||||
|
/// @brief A normalized left-oriented vector
|
||||||
|
const static Vector3Of left;
|
||||||
|
/// @brief A normalized up-oriented vector
|
||||||
|
const static Vector3Of up;
|
||||||
|
/// @brief A normalized down-oriented vector
|
||||||
|
const static Vector3Of down;
|
||||||
|
|
||||||
|
/// @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 Vector3Of& v) const;
|
||||||
|
|
||||||
/// @brief The vector length
|
/// @brief The vector length
|
||||||
/// @param v The vector for which you need the length
|
/// @param v The vector for which you need the length
|
||||||
/// @return The vector length
|
/// @return The vector length
|
||||||
static T MagnitudeOf(const Vector3Of& v);
|
static float MagnitudeOf(const Vector3Of& v);
|
||||||
|
|
||||||
/// @brief The vector length
|
/// @brief The vector length
|
||||||
/// @return The vector length
|
/// @return The vector length
|
||||||
T Magnitude() const;
|
float Magnitude() const;
|
||||||
|
|
||||||
/// @brief The squared vector length
|
/// @brief The squared vector length
|
||||||
/// @param v The vector for which you need the length
|
/// @param v The vector for which you need the length
|
||||||
@ -293,6 +325,10 @@ class Vector3Of {
|
|||||||
/// @return The vector normalized to a length of 1
|
/// @return The vector normalized to a length of 1
|
||||||
Vector3Of<T> Normalized() const;
|
Vector3Of<T> Normalized() const;
|
||||||
|
|
||||||
|
/// @brief Negate te vector such that it points in the opposite direction
|
||||||
|
/// @return The negated vector
|
||||||
|
Vector3Of<T> operator-() const;
|
||||||
|
|
||||||
/// @brief Subtract a vector from this vector
|
/// @brief Subtract a vector from this vector
|
||||||
/// @param v The vector to subtract from this vector
|
/// @param v The vector to subtract from this vector
|
||||||
/// @return The result of this subtraction
|
/// @return The result of this subtraction
|
||||||
@ -305,6 +341,14 @@ class Vector3Of {
|
|||||||
Vector3Of<T> operator+(const Vector3Of& v) const;
|
Vector3Of<T> operator+(const Vector3Of& v) const;
|
||||||
Vector3Of<T> operator+=(const Vector3Of& v);
|
Vector3Of<T> operator+=(const Vector3Of& 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 Vector3Of<T> Scale(const Vector3Of& v1, const Vector3Of& v2);
|
||||||
|
|
||||||
/// @brief Scale the vector uniformly up
|
/// @brief Scale the vector uniformly up
|
||||||
/// @param f The scaling factor
|
/// @param f The scaling factor
|
||||||
/// @return The scaled vector
|
/// @return The scaled vector
|
||||||
@ -315,7 +359,7 @@ class Vector3Of {
|
|||||||
}
|
}
|
||||||
friend Vector3Of<T> operator*(float f, const Vector3Of& v) {
|
friend Vector3Of<T> operator*(float f, const Vector3Of& v) {
|
||||||
return Vector3Of<T>(f * v.horizontal, f * v.vertical, f * v.depth);
|
return Vector3Of<T>(f * v.horizontal, f * v.vertical, f * v.depth);
|
||||||
// return Vector3Of<T>(v.horizontal * f, v.vertical * f, v.depth * f);
|
// return Vector3Of<T>(v.horizontal * f, v.vertical * f, v.depth * f);
|
||||||
}
|
}
|
||||||
Vector3Of<T> operator*=(float f);
|
Vector3Of<T> operator*=(float f);
|
||||||
|
|
||||||
@ -328,15 +372,39 @@ class Vector3Of {
|
|||||||
}
|
}
|
||||||
friend Vector3Of<T> operator/(float f, const Vector3Of& v) {
|
friend Vector3Of<T> operator/(float f, const Vector3Of& v) {
|
||||||
return Vector3Of<T>(f / v.horizontal, f / v.vertical, f / v.depth);
|
return Vector3Of<T>(f / v.horizontal, f / v.vertical, f / v.depth);
|
||||||
// return Vector3Of<T>(v.horizontal / f, v.vertical / f, v.depth / f);
|
// return Vector3Of<T>(v.horizontal / f, v.vertical / f, v.depth / f);
|
||||||
}
|
}
|
||||||
Vector3Of<T> operator/=(float f);
|
Vector3Of<T> 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 Vector3Of& v1, const Vector3Of& v2);
|
||||||
|
|
||||||
/// @brief The dot product of two vectors
|
/// @brief The dot product of two vectors
|
||||||
/// @param v1 The first vector
|
/// @param v1 The first vector
|
||||||
/// @param v2 The second vector
|
/// @param v2 The second vector
|
||||||
/// @return The dot product of the two vectors
|
/// @return The dot product of the two vectors
|
||||||
static float Dot(const Vector3Of& v1, const Vector3Of& v2);
|
static T Dot(const Vector3Of& v1, const Vector3Of& 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 Vector3Of<T> Cross(const Vector3Of& v1, const Vector3Of& 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 Vector3Of<float> Project(const Vector3Of& v, const Vector3Of& 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 Vector3Of<float> ProjectOnPlane(const Vector3Of& v, const Vector3Of& n);
|
||||||
|
|
||||||
/// @brief The angle between two vectors
|
/// @brief The angle between two vectors
|
||||||
/// @param v1 The first vector
|
/// @param v1 The first vector
|
||||||
@ -346,6 +414,26 @@ class Vector3Of {
|
|||||||
/// between the two vectors. Use Vector3::SignedAngle if a signed angle is
|
/// between the two vectors. Use Vector3::SignedAngle if a signed angle is
|
||||||
/// needed.
|
/// needed.
|
||||||
static AngleOf<float> UnsignedAngle(const Vector3Of& v1, const Vector3Of& v2);
|
static AngleOf<float> UnsignedAngle(const Vector3Of& v1, const Vector3Of& 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<float> SignedAngle(const Vector3Of& v1,
|
||||||
|
const Vector3Of& v2,
|
||||||
|
const Vector3Of& 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 Vector3Of<float> Lerp(const Vector3Of& v1,
|
||||||
|
const Vector3Of& v2,
|
||||||
|
float f);
|
||||||
};
|
};
|
||||||
|
|
||||||
using Vector3Int = Vector3Of<int>;
|
using Vector3Int = Vector3Of<int>;
|
||||||
|
|||||||
@ -10,7 +10,6 @@ using namespace LinearAlgebra;
|
|||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
//using AngleTypes = ::testing::Types<AngleOf<float>, AngleOf<signed short>, AngleOf<signed char>>;
|
|
||||||
using BaseTypes = ::testing::Types<float, signed short, signed char>;
|
using BaseTypes = ::testing::Types<float, signed short, signed char>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@ -1,128 +1,151 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <limits>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "Polar.h"
|
#include "Polar.h"
|
||||||
#include "Spherical.h"
|
#include "Spherical.h"
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
using Vector2 = Vector2Of<float>;
|
using BaseTypes = ::testing::Types<float, signed short>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class PolarTests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(PolarTests, BaseTypes);
|
||||||
|
|
||||||
|
TYPED_TEST(PolarTests, FromVector2) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
using Polar = PolarOf<float>;
|
||||||
|
|
||||||
TEST(Polar, FromVector2) {
|
|
||||||
Vector2 v = Vector2(0, 1);
|
Vector2 v = Vector2(0, 1);
|
||||||
PolarSingle p = PolarSingle::FromVector2(v);
|
Polar p = Polar::FromVector2(v);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 0 1";
|
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 0 1";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "s.angle 0 0 1";
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "s.angle 0 0 1";
|
||||||
|
|
||||||
v = Vector2(1, 0);
|
v = Vector2(1, 0);
|
||||||
p = PolarSingle::FromVector2(v);
|
p = Polar::FromVector2(v);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 1 0";
|
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 1 0";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 90.0F) << "s.angle 1 0";
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 90.0F) << "s.angle 1 0";
|
||||||
|
|
||||||
v = Vector2(-1, 1);
|
v = Vector2(-1, 1);
|
||||||
p = PolarSingle::FromVector2(v);
|
p = Polar::FromVector2(v);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, sqrt(2.0F)) << "p.distance -1 1";
|
EXPECT_FLOAT_EQ(p.distance, sqrt(2.0F)) << "p.distance -1 1";
|
||||||
EXPECT_NEAR(p.angle.InDegrees(), -45.0F, 1.0e-05) << "s.angle -1 1";
|
EXPECT_NEAR(p.angle.InDegrees(), -45.0F, 1.0e-05) << "s.angle -1 1";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, FromSpherical) {
|
TYPED_TEST(PolarTests, FromSpherical) {
|
||||||
SphericalSingle s;
|
using T = TypeParam;
|
||||||
PolarSingle p;
|
using Spherical = SphericalOf<T>;
|
||||||
|
using Polar = PolarOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
s = SphericalSingle(1, DirectionSingle::forward);
|
Spherical s;
|
||||||
p = PolarSingle::FromSpherical(s);
|
Polar p;
|
||||||
|
|
||||||
|
s = Spherical(1, DirectionOf<T>::forward);
|
||||||
|
p = Polar::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 0 0)";
|
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 0 0)";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(1 0 0)";
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(1 0 0)";
|
||||||
|
|
||||||
s = SphericalSingle(1, AngleSingle::Degrees(45), AngleSingle::Degrees(0));
|
s = Spherical(1, AngleOf<T>::Degrees(45), AngleOf<T>::Degrees(0));
|
||||||
p = PolarSingle::FromSpherical(s);
|
p = Polar::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 45 0)";
|
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 45 0)";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 45.0F)
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 45.0F)
|
||||||
<< "p.angle FromSpherical(1 45 0)";
|
<< "p.angle FromSpherical(1 45 0)";
|
||||||
|
|
||||||
s = SphericalSingle(1, AngleSingle::Degrees(-45), AngleSingle::Degrees(0));
|
s = Spherical(1, Angle::Degrees(-45), Angle::Degrees(0));
|
||||||
p = PolarSingle::FromSpherical(s);
|
p = Polar::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 -45 0)";
|
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 -45 0)";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), -45.0F)
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), -45.0F)
|
||||||
<< "p.angle FromSpherical(1 -45 0)";
|
<< "p.angle FromSpherical(1 -45 0)";
|
||||||
|
|
||||||
s = SphericalSingle(0, AngleSingle::Degrees(0), AngleSingle::Degrees(0));
|
s = Spherical(0, Angle::Degrees(0), Angle::Degrees(0));
|
||||||
p = PolarSingle::FromSpherical(s);
|
p = Polar::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 0.0F) << "p.distance FromSpherical(0 0 0)";
|
EXPECT_FLOAT_EQ(p.distance, 0.0F) << "p.distance FromSpherical(0 0 0)";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(0 0 0)";
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(0 0 0)";
|
||||||
|
|
||||||
s = SphericalSingle(-1, AngleSingle::Degrees(0), AngleSingle::Degrees(0));
|
s = Spherical(-1, Angle::Degrees(0), Angle::Degrees(0));
|
||||||
p = PolarSingle::FromSpherical(s);
|
p = Polar::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(-1 0 0)";
|
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(-1 0 0)";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), -180.0F)
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), -180.0F)
|
||||||
<< "p.angle FromSpherical(-1 0 0)";
|
<< "p.angle FromSpherical(-1 0 0)";
|
||||||
|
|
||||||
s = SphericalSingle(0, AngleSingle::Degrees(0), AngleSingle::Degrees(90));
|
s = Spherical(0, Angle::Degrees(0), Angle::Degrees(90));
|
||||||
p = PolarSingle::FromSpherical(s);
|
p = Polar::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(p.distance, 0.0F) << "p.distance FromSpherical(0 0 90)";
|
EXPECT_FLOAT_EQ(p.distance, 0.0F) << "p.distance FromSpherical(0 0 90)";
|
||||||
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(0 0 90)";
|
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(0 0 90)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Negation) {
|
TYPED_TEST(PolarTests, Negation) {
|
||||||
PolarSingle v = PolarSingle(2, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle r = PolarSingle::zero;
|
using Polar = PolarOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Polar v = Polar(2, Angle::Degrees(45));
|
||||||
|
Polar r = Polar::zero;
|
||||||
|
|
||||||
r = -v;
|
r = -v;
|
||||||
EXPECT_FLOAT_EQ(r.distance, 2);
|
EXPECT_FLOAT_EQ(r.distance, 2);
|
||||||
EXPECT_FLOAT_EQ(r.angle.InDegrees(), -135);
|
EXPECT_FLOAT_EQ(r.angle.InDegrees(), -135);
|
||||||
EXPECT_TRUE(r == PolarSingle(2, AngleSingle::Degrees(-135)))
|
EXPECT_TRUE(r == Polar(2, Angle::Degrees(-135))) << "Negate(2 45)";
|
||||||
<< "Negate(2 45)";
|
|
||||||
|
|
||||||
v = PolarSingle::Deg(2, -45);
|
v = Polar::Deg(2, -45);
|
||||||
r = -v;
|
r = -v;
|
||||||
EXPECT_TRUE(r == PolarSingle(2, AngleSingle::Degrees(135)))
|
EXPECT_TRUE(r == Polar(2, Angle::Degrees(135))) << "Negate(2 -45)";
|
||||||
<< "Negate(2 -45)";
|
|
||||||
|
|
||||||
v = PolarSingle::Degrees(2, 0);
|
v = Polar::Degrees(2, 0);
|
||||||
r = -v;
|
r = -v;
|
||||||
EXPECT_TRUE(r == PolarSingle(2, AngleSingle::Degrees(180))) << "Negate(2 0)";
|
EXPECT_TRUE(r == Polar(2, Angle::Degrees(180))) << "Negate(2 0)";
|
||||||
|
|
||||||
v = PolarSingle(0, AngleSingle::Degrees(0));
|
v = Polar(0, Angle::Degrees(0));
|
||||||
r = -v;
|
r = -v;
|
||||||
EXPECT_FLOAT_EQ(r.distance, 0.0f);
|
EXPECT_FLOAT_EQ(r.distance, 0.0f);
|
||||||
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 0.0f);
|
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 0.0f);
|
||||||
EXPECT_TRUE(r == PolarSingle(0, AngleSingle::Degrees(0))) << "Negate(0 0)";
|
EXPECT_TRUE(r == Polar(0, Angle::Degrees(0))) << "Negate(0 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Subtraction) {
|
TYPED_TEST(PolarTests, Subtraction) {
|
||||||
PolarSingle v1 = PolarSingle(4, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle v2 = PolarSingle(1, AngleSingle::Degrees(-90));
|
using Polar = PolarOf<T>;
|
||||||
PolarSingle r = PolarSingle::zero;
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Polar v1 = Polar(4, Angle::Degrees(45));
|
||||||
|
Polar v2 = Polar(1, Angle::Degrees(-90));
|
||||||
|
Polar r = Polar::zero;
|
||||||
|
|
||||||
r = v1 - v2;
|
r = v1 - v2;
|
||||||
// don't know what to expect yet
|
// don't know what to expect yet
|
||||||
|
|
||||||
v2 = PolarSingle::zero;
|
v2 = Polar::zero;
|
||||||
r = v1 - v2;
|
r = v1 - v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Subtraction(0 0)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Subtraction(0 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Addition) {
|
TYPED_TEST(PolarTests, Addition) {
|
||||||
PolarSingle v1 = PolarSingle(1, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle v2 = PolarSingle(1, AngleSingle::Degrees(-90));
|
using Polar = PolarOf<T>;
|
||||||
PolarSingle r = PolarSingle::zero;
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Polar v1 = Polar(1, Angle::Degrees(45));
|
||||||
|
Polar v2 = Polar(1, Angle::Degrees(-90));
|
||||||
|
Polar r = Polar::zero;
|
||||||
|
|
||||||
r = v1 - v2;
|
r = v1 - v2;
|
||||||
// don't know what to expect yet
|
// don't know what to expect yet
|
||||||
|
|
||||||
v2 = PolarSingle::zero;
|
v2 = Polar::zero;
|
||||||
r = v1 + v2;
|
r = v1 + v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0)";
|
||||||
|
|
||||||
@ -130,15 +153,19 @@ TEST(Polar, Addition) {
|
|||||||
r += v2;
|
r += v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0)";
|
||||||
|
|
||||||
v2 = PolarSingle(1, AngleSingle::Degrees(-45));
|
v2 = Polar(1, Angle::Degrees(-45));
|
||||||
r = v1 + v2;
|
r = v1 + v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(0 0 0)";
|
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(0 0 0)";
|
||||||
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 0) << "Addition(0 0 0)";
|
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 0) << "Addition(0 0 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Scale_Multiply) {
|
TYPED_TEST(PolarTests, Scale_Multiply) {
|
||||||
PolarSingle v1 = PolarSingle(4, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle r = PolarSingle::zero;
|
using Polar = PolarOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Polar v1 = Polar(4, Angle::Degrees(45));
|
||||||
|
Polar r = Polar::zero;
|
||||||
|
|
||||||
r = v1 * 2.0f;
|
r = v1 * 2.0f;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance * 2) << "ScaleMult(4 45, 2)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance * 2) << "ScaleMult(4 45, 2)";
|
||||||
@ -146,9 +173,13 @@ TEST(Polar, Scale_Multiply) {
|
|||||||
<< "ScaleMult(4 45, 2)";
|
<< "ScaleMult(4 45, 2)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Scale_Divide) {
|
TYPED_TEST(PolarTests, Scale_Divide) {
|
||||||
PolarSingle v1 = PolarSingle(4, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle r = PolarSingle::zero;
|
using Polar = PolarOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Polar v1 = Polar(4, Angle::Degrees(45));
|
||||||
|
Polar r = Polar::zero;
|
||||||
|
|
||||||
r = v1 / 2.0f;
|
r = v1 / 2.0f;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance / 2) << "ScaleDiv(4 45, 2)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance / 2) << "ScaleDiv(4 45, 2)";
|
||||||
@ -156,31 +187,39 @@ TEST(Polar, Scale_Divide) {
|
|||||||
<< "ScaleDiv(4 45, 2)";
|
<< "ScaleDiv(4 45, 2)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Distance) {
|
TYPED_TEST(PolarTests, Distance) {
|
||||||
PolarSingle v1 = PolarSingle(4, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle v2 = PolarSingle(1, AngleSingle::Degrees(-90));
|
using Polar = PolarOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Polar v1 = Polar(4, Angle::Degrees(45));
|
||||||
|
Polar v2 = Polar(1, Angle::Degrees(-90));
|
||||||
float d = 0;
|
float d = 0;
|
||||||
|
|
||||||
d = PolarSingle::Distance(v1, v2);
|
d = Polar::Distance(v1, v2);
|
||||||
// don't know what to expect yet
|
// don't know what to expect yet
|
||||||
|
|
||||||
v2 = PolarSingle::zero;
|
v2 = Polar::zero;
|
||||||
d = PolarSingle::Distance(v1, v2);
|
d = Polar::Distance(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(d, v1.distance) << "Distance(4 45, zero)";
|
EXPECT_FLOAT_EQ(d, v1.distance) << "Distance(4 45, zero)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Polar, Rotate) {
|
TYPED_TEST(PolarTests, Rotate) {
|
||||||
PolarSingle v = PolarSingle(4, AngleSingle::Degrees(45));
|
using T = TypeParam;
|
||||||
PolarSingle r = PolarSingle::zero;
|
using Polar = PolarOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
r = PolarSingle::Rotate(v, AngleSingle::Degrees(45));
|
Polar v = Polar(4, Angle::Degrees(45));
|
||||||
|
Polar r = Polar::zero;
|
||||||
|
|
||||||
|
r = Polar::Rotate(v, Angle::Degrees(45));
|
||||||
EXPECT_FLOAT_EQ(r.distance, v.distance) << "Rotate(4 45, 45)";
|
EXPECT_FLOAT_EQ(r.distance, v.distance) << "Rotate(4 45, 45)";
|
||||||
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 90.0f) << "Rotate(4 45, 45)";
|
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 90.0f) << "Rotate(4 45, 45)";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performance Test
|
// Performance Test
|
||||||
TEST(PolarOfTest, PerformanceTest) {
|
TYPED_TEST(PolarTests, PerformanceTest) {
|
||||||
const int numIterations = 1000000; // Number of instances to test
|
const int numIterations = 1000000; // Number of instances to test
|
||||||
std::vector<PolarOf<float>> polarObjects;
|
std::vector<PolarOf<float>> polarObjects;
|
||||||
|
|
||||||
// Measure time for creating a large number of PolarOf objects
|
// Measure time for creating a large number of PolarOf objects
|
||||||
@ -188,11 +227,11 @@ TEST(PolarOfTest, PerformanceTest) {
|
|||||||
|
|
||||||
for (int i = 0; i < numIterations; ++i) {
|
for (int i = 0; i < numIterations; ++i) {
|
||||||
float distance =
|
float distance =
|
||||||
static_cast<float>(rand() % 100); // Random distance from 0 to 100
|
static_cast<float>(rand() % 100); // Random distance from 0 to 100
|
||||||
AngleOf<float> angle = AngleOf<float>::Degrees(
|
AngleOf<float> angle = AngleOf<float>::Degrees(static_cast<float>(
|
||||||
static_cast<float>(rand() % 360)); // Random angle from 0 to 360 degrees
|
rand() % 360)); // Random angle from 0 to 360 degrees
|
||||||
PolarOf<float> p = PolarOf<float>(distance, angle);
|
PolarOf<float> p = PolarOf<float>(distance, angle);
|
||||||
polarObjects.emplace_back(p); // Create and store the object
|
polarObjects.emplace_back(p); // Create and store the object
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
@ -202,7 +241,7 @@ TEST(PolarOfTest, PerformanceTest) {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
// Test completion with a message
|
// Test completion with a message
|
||||||
ASSERT_GE(duration.count(), 0); // Ensure duration is non-negative
|
ASSERT_GE(duration.count(), 0); // Ensure duration is non-negative
|
||||||
|
|
||||||
// Assert that the duration is less than or equal to 1 second
|
// Assert that the duration is less than or equal to 1 second
|
||||||
ASSERT_LE(duration.count(), 1.0)
|
ASSERT_LE(duration.count(), 1.0)
|
||||||
@ -210,26 +249,27 @@ TEST(PolarOfTest, PerformanceTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Edge Case 1: Testing with distance = 0 and angle = 45
|
// Edge Case 1: Testing with distance = 0 and angle = 45
|
||||||
TEST(PolarOfTest, TestDistanceZero) {
|
TYPED_TEST(PolarTests, TestDistanceZero) {
|
||||||
PolarOf<float> p1(0.0f, AngleOf<float>::Degrees(45.0f));
|
PolarOf<float> p1(0.0f, AngleOf<float>::Degrees(45.0f));
|
||||||
EXPECT_EQ(p1.distance, 0.0f); // Ensure distance is 0
|
EXPECT_EQ(p1.distance, 0.0f); // Ensure distance is 0
|
||||||
EXPECT_EQ(p1.angle.InDegrees(), 0.0f); // Ensure angle is 0 when distance is 0
|
EXPECT_EQ(p1.angle.InDegrees(),
|
||||||
|
0.0f); // Ensure angle is 0 when distance is 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edge Case 2: Testing with negative distance, angle should be adjusted
|
// Edge Case 2: Testing with negative distance, angle should be adjusted
|
||||||
TEST(PolarOfTest, TestNegativeDistance) {
|
TYPED_TEST(PolarTests, TestNegativeDistance) {
|
||||||
PolarOf<float> p2(-10.0f, AngleOf<float>::Degrees(90.0f));
|
PolarOf<float> p2(-10.0f, AngleOf<float>::Degrees(90.0f));
|
||||||
EXPECT_EQ(p2.distance, 10.0f); // Ensure distance is positive
|
EXPECT_EQ(p2.distance, 10.0f); // Ensure distance is positive
|
||||||
EXPECT_NEAR(p2.angle.InDegrees(), -90.0f,
|
EXPECT_NEAR(p2.angle.InDegrees(), -90.0f,
|
||||||
0.0001f); // Ensure angle is normalized to 270 degrees (180 + 90)
|
0.0001f); // Ensure angle is normalized to 270 degrees (180 + 90)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edge Case 3: Testing with positive distance and angle = 180
|
// Edge Case 3: Testing with positive distance and angle = 180
|
||||||
TEST(PolarOfTest, TestPositiveDistance) {
|
TYPED_TEST(PolarTests, TestPositiveDistance) {
|
||||||
PolarOf<float> p3(100.0f, AngleOf<float>::Degrees(180.0f));
|
PolarOf<float> p3(100.0f, AngleOf<float>::Degrees(180.0f));
|
||||||
EXPECT_EQ(p3.distance, 100.0f); // Ensure distance is correct
|
EXPECT_EQ(p3.distance, 100.0f); // Ensure distance is correct
|
||||||
EXPECT_NEAR(p3.angle.InDegrees(), -180.0f,
|
EXPECT_NEAR(p3.angle.InDegrees(), -180.0f,
|
||||||
0.0001f); // Ensure angle is correct
|
0.0001f); // Ensure angle is correct
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -27,15 +27,15 @@ TEST(Quaternion, ToAngles) {
|
|||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3Of<float> v = Vector3Of<float>::zero;
|
||||||
|
|
||||||
v = Quaternion::ToAngles(q1);
|
v = Quaternion::ToAngles(q1);
|
||||||
r = v == Vector3(0, 0, 0);
|
r = v == Vector3Of<float>(0, 0, 0);
|
||||||
EXPECT_TRUE(r) << "Quaternion::ToAngles 0 0 0 1";
|
EXPECT_TRUE(r) << "Quaternion::ToAngles 0 0 0 1";
|
||||||
|
|
||||||
q1 = Quaternion(1, 0, 0, 0);
|
q1 = Quaternion(1, 0, 0, 0);
|
||||||
v = Quaternion::ToAngles(q1);
|
v = Quaternion::ToAngles(q1);
|
||||||
r = v == Vector3(180, 0, 0);
|
r = v == Vector3Of<float>(180, 0, 0);
|
||||||
// EXPECT_TRUE(r) << "Quaternion::ToAngles 1 0 0 0";
|
// EXPECT_TRUE(r) << "Quaternion::ToAngles 1 0 0 0";
|
||||||
// fails on MacOS?
|
// fails on MacOS?
|
||||||
}
|
}
|
||||||
@ -56,16 +56,16 @@ TEST(Quaternion, MultiplicationVector) {
|
|||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
||||||
Vector3 v1 = Vector3(0, 1, 0);
|
Vector3Of<float> v1 = Vector3Of<float>(0, 1, 0);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3Of<float> v = Vector3Of<float>::zero;
|
||||||
|
|
||||||
v = q1 * v1;
|
v = q1 * v1;
|
||||||
r = v == Vector3(0, 1, 0);
|
r = v == Vector3Of<float>(0, 1, 0);
|
||||||
EXPECT_TRUE(r) << "0 0 0 1 * Vector 0 1 0";
|
EXPECT_TRUE(r) << "0 0 0 1 * Vector 0 1 0";
|
||||||
|
|
||||||
q1 = Quaternion(1, 0, 0, 0);
|
q1 = Quaternion(1, 0, 0, 0);
|
||||||
v = q1 * v1;
|
v = q1 * v1;
|
||||||
r = v == Vector3(0, -1, 0);
|
r = v == Vector3Of<float>(0, -1, 0);
|
||||||
EXPECT_TRUE(r) << "1 0 0 0 * Vector 0 1 0";
|
EXPECT_TRUE(r) << "1 0 0 0 * Vector 0 1 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ TEST(Quaternion, SlerpUnclamped) {
|
|||||||
TEST(Quaternion, Euler) {
|
TEST(Quaternion, Euler) {
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(0, 0, 0);
|
Vector3Of<float> v1 = Vector3Of<float>(0, 0, 0);
|
||||||
Quaternion q = Quaternion::identity;
|
Quaternion q = Quaternion::identity;
|
||||||
|
|
||||||
q = Quaternion::Euler(v1);
|
q = Quaternion::Euler(v1);
|
||||||
@ -129,7 +129,7 @@ TEST(Quaternion, Euler) {
|
|||||||
r = q == Quaternion::identity;
|
r = q == Quaternion::identity;
|
||||||
EXPECT_TRUE(r) << "Euler 0 0 0";
|
EXPECT_TRUE(r) << "Euler 0 0 0";
|
||||||
|
|
||||||
v1 = Vector3(90, 90, -90);
|
v1 = Vector3Of<float>(90, 90, -90);
|
||||||
q = Quaternion::Euler(v1);
|
q = Quaternion::Euler(v1);
|
||||||
r = q == Quaternion(0, 0.707106709F, -0.707106709F, 0);
|
r = q == Quaternion(0, 0.707106709F, -0.707106709F, 0);
|
||||||
EXPECT_TRUE(r) << "Euler Vector 90 90 -90";
|
EXPECT_TRUE(r) << "Euler Vector 90 90 -90";
|
||||||
@ -142,7 +142,7 @@ TEST(Quaternion, Euler) {
|
|||||||
TEST(Quaternion, GetAngleAround) {
|
TEST(Quaternion, GetAngleAround) {
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(0, 1, 0);
|
Vector3Of<float> v1 = Vector3Of<float>(0, 1, 0);
|
||||||
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
||||||
float f;
|
float f;
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ TEST(Quaternion, GetAngleAround) {
|
|||||||
f = Quaternion::GetAngleAround(v1, q1);
|
f = Quaternion::GetAngleAround(v1, q1);
|
||||||
EXPECT_FLOAT_EQ(f, 180) << "GetAngleAround 0 1 0 , 0 0.7 -0.7 0";
|
EXPECT_FLOAT_EQ(f, 180) << "GetAngleAround 0 1 0 , 0 0.7 -0.7 0";
|
||||||
|
|
||||||
v1 = Vector3(0, 0, 0);
|
v1 = Vector3Of<float>(0, 0, 0);
|
||||||
f = Quaternion::GetAngleAround(v1, q1);
|
f = Quaternion::GetAngleAround(v1, q1);
|
||||||
r = isnan(f);
|
r = isnan(f);
|
||||||
EXPECT_TRUE(r) << "GetAngleAround 0 0 0 , 0 0.7 -0.7 0";
|
EXPECT_TRUE(r) << "GetAngleAround 0 0 0 , 0 0.7 -0.7 0";
|
||||||
@ -162,7 +162,7 @@ TEST(Quaternion, GetAngleAround) {
|
|||||||
TEST(Quaternion, GetRotationAround) {
|
TEST(Quaternion, GetRotationAround) {
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(0, 1, 0);
|
Vector3Of<float> v1 = Vector3Of<float>(0, 1, 0);
|
||||||
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
Quaternion q1 = Quaternion(0, 0, 0, 1);
|
||||||
Quaternion q = Quaternion::identity;
|
Quaternion q = Quaternion::identity;
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ TEST(Quaternion, GetRotationAround) {
|
|||||||
r = q == Quaternion(0, 1, 0, 0);
|
r = q == Quaternion(0, 1, 0, 0);
|
||||||
EXPECT_TRUE(r) << "GetRotationAround 0 1 0 , 0 0.7 -0.7 0";
|
EXPECT_TRUE(r) << "GetRotationAround 0 1 0 , 0 0.7 -0.7 0";
|
||||||
|
|
||||||
v1 = Vector3(0, 0, 0);
|
v1 = Vector3Of<float>(0, 0, 0);
|
||||||
q = Quaternion::GetRotationAround(v1, q1);
|
q = Quaternion::GetRotationAround(v1, q1);
|
||||||
r = isnan(q.x) && isnan(q.y) && isnan(q.z) && isnan(q.w);
|
r = isnan(q.x) && isnan(q.y) && isnan(q.z) && isnan(q.w);
|
||||||
EXPECT_TRUE(r) << "GetRotationAround 0 0 0 , 0 0.7 -0.7 0";
|
EXPECT_TRUE(r) << "GetRotationAround 0 0 0 , 0 0.7 -0.7 0";
|
||||||
|
|||||||
@ -1,214 +0,0 @@
|
|||||||
#if GTEST
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <limits>
|
|
||||||
#include <math.h>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
#include "Spherical.h"
|
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
|
||||||
|
|
||||||
TEST(SphericalSingle, FromVector3) {
|
|
||||||
Vector3 v = Vector3(0, 0, 1);
|
|
||||||
SphericalSingle s = SphericalSingle ::FromVector3(v);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 0 1";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F) << "s.hor 0 0 1";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F) << "s.vert 0 0 1";
|
|
||||||
|
|
||||||
v = Vector3(0, 1, 0);
|
|
||||||
s = SphericalSingle ::FromVector3(v);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 1 0";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F) << "s.hor 0 1 0";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 90.0F) << "s.vert 0 1 0";
|
|
||||||
|
|
||||||
v = Vector3(1, 0, 0);
|
|
||||||
s = SphericalSingle ::FromVector3(v);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 1 0 0";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 90.0F) << "s.hor 1 0 0";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F) << "s.vert 1 0 0";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SphericalSingle, FromPolar) {
|
|
||||||
PolarSingle p = PolarSingle(1, AngleSingle::Degrees(0));
|
|
||||||
SphericalSingle s = SphericalSingle ::FromPolar(p);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 0)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F)
|
|
||||||
<< "s.hor Polar(1 0)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F)
|
|
||||||
<< "s.vert Polar(1 0)";
|
|
||||||
|
|
||||||
p = PolarSingle(1, AngleSingle::Degrees(45));
|
|
||||||
s = SphericalSingle ::FromPolar(p);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 45)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 45.0F)
|
|
||||||
<< "s.hor Polar(1 45)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F)
|
|
||||||
<< "s.vert Polar(1 45)";
|
|
||||||
|
|
||||||
p = PolarSingle(1, AngleSingle::Degrees(-45));
|
|
||||||
s = SphericalSingle ::FromPolar(p);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 -45)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), -45.0F)
|
|
||||||
<< "s.hor Polar(1 -45)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F)
|
|
||||||
<< "s.vert Polar(1 -45)";
|
|
||||||
|
|
||||||
p = PolarSingle(0, AngleSingle::Degrees(0));
|
|
||||||
s = SphericalSingle ::FromPolar(p);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 0.0F) << "s.distance Polar(0 0)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F)
|
|
||||||
<< "s.hor Polar(0 0)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F)
|
|
||||||
<< "s.vert Polar(0 0)";
|
|
||||||
|
|
||||||
p = PolarSingle(-1, AngleSingle::Degrees(0));
|
|
||||||
s = SphericalSingle ::FromPolar(p);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(-1 0)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), -180.0F)
|
|
||||||
<< "s.hor Polar(-1 0)";
|
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F)
|
|
||||||
<< "s.vert Polar(-1 0)";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SphericalSingle, Incident1) {
|
|
||||||
Vector3 v = Vector3(2.242557f, 1.027884f, -0.322347f);
|
|
||||||
SphericalSingle s = SphericalSingle ::FromVector3(v);
|
|
||||||
|
|
||||||
SphericalSingle sr = SphericalSingle(2.49F, AngleSingle::Degrees(98.18f),
|
|
||||||
AngleSingle::Degrees(24.4F));
|
|
||||||
EXPECT_NEAR(s.distance, sr.distance, 1.0e-01);
|
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
|
||||||
sr.direction.horizontal.InDegrees(), 1.0e-02);
|
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
|
||||||
sr.direction.vertical.InDegrees(), 1.0e-02);
|
|
||||||
|
|
||||||
Vector3 r = Vector3(sr);
|
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-02) << "toVector3.x 1 0 0";
|
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-02) << "toVector3.y 1 0 0";
|
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-02) << "toVector3.z 1 0 0";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SphericalSingle, Incident2) {
|
|
||||||
Vector3 v = Vector3(1.0f, 0.0f, 1.0f);
|
|
||||||
SphericalSingle s = SphericalSingle ::FromVector3(v);
|
|
||||||
|
|
||||||
SphericalSingle sr = SphericalSingle(
|
|
||||||
1.4142135623F, AngleSingle::Degrees(45.0f), AngleSingle::Degrees(0.0F));
|
|
||||||
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
|
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
|
||||||
sr.direction.horizontal.InDegrees(), 1.0e-05);
|
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
|
||||||
sr.direction.vertical.InDegrees(), 1.0e-05);
|
|
||||||
|
|
||||||
Vector3 r = Vector3(sr);
|
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
|
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-06);
|
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-06);
|
|
||||||
|
|
||||||
v = Vector3(0.0f, 1.0f, 1.0f);
|
|
||||||
s = SphericalSingle ::FromVector3(v);
|
|
||||||
|
|
||||||
sr = SphericalSingle(1.4142135623F, AngleSingle::Degrees(0.0f),
|
|
||||||
AngleSingle::Degrees(45.0F));
|
|
||||||
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
|
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
|
||||||
sr.direction.horizontal.InDegrees(), 1.0e-05);
|
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
|
||||||
sr.direction.vertical.InDegrees(), 1.0e-05);
|
|
||||||
|
|
||||||
r = Vector3(sr);
|
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
|
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-06);
|
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-06);
|
|
||||||
|
|
||||||
v = Vector3(1.0f, 1.0f, 1.0f);
|
|
||||||
s = SphericalSingle ::FromVector3(v);
|
|
||||||
r = Vector3(s);
|
|
||||||
|
|
||||||
EXPECT_NEAR(s.distance, 1.73205080F, 1.0e-02);
|
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(), 45.0F, 1.0e-02);
|
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(), 35.26F, 1.0e-02);
|
|
||||||
|
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
|
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-06);
|
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-06);
|
|
||||||
|
|
||||||
// s = SphericalSingle(10, 45, 45);
|
|
||||||
// r = s.ToVector3();
|
|
||||||
// EXPECT_NEAR(r.x, 5, 1.0e-06);
|
|
||||||
// EXPECT_NEAR(r.y, 7.07, 1.0e-06);
|
|
||||||
// EXPECT_NEAR(r.z, 5, 1.0e-06);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SphericalSingle, Addition) {
|
|
||||||
SphericalSingle v1 =
|
|
||||||
SphericalSingle(1, AngleSingle::Degrees(45), AngleSingle::Degrees(0));
|
|
||||||
SphericalSingle v2 = SphericalSingle ::zero;
|
|
||||||
SphericalSingle r = SphericalSingle ::zero;
|
|
||||||
|
|
||||||
r = v1 + v2;
|
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
|
|
||||||
|
|
||||||
r = v1;
|
|
||||||
r += v2;
|
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
|
|
||||||
|
|
||||||
v2 = SphericalSingle(1, AngleSingle::Degrees(-45), AngleSingle::Degrees(0));
|
|
||||||
r = v1 + v2;
|
|
||||||
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 -45 0)";
|
|
||||||
EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 0) << "Addition(1 -45 0)";
|
|
||||||
EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 0) << "Addition(1 -45 0)";
|
|
||||||
|
|
||||||
v2 = SphericalSingle(1, AngleSingle::Degrees(0), AngleSingle::Degrees(90));
|
|
||||||
r = v1 + v2;
|
|
||||||
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 0 90)";
|
|
||||||
EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 45) << "Addition(1 0 90)";
|
|
||||||
EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 45) << "Addition(1 0 90)";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SphericalSingle, AdditionPerformance) {
|
|
||||||
const int numIterations = 1000000; // Number of additions to test
|
|
||||||
std::vector<SphericalSingle> sphericalObjects;
|
|
||||||
|
|
||||||
// Populate the vector with random SphericalOf objects
|
|
||||||
for (int i = 0; i < numIterations; ++i) {
|
|
||||||
float distance = (float)(rand() % 100);
|
|
||||||
float horizontal = (float)(rand() % 180);
|
|
||||||
float vertical = (float)(rand() % 360);
|
|
||||||
SphericalSingle s = SphericalSingle::Deg(distance, horizontal, vertical);
|
|
||||||
sphericalObjects.push_back(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Measure the time to perform multiple additions
|
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
|
||||||
|
|
||||||
SphericalSingle result = SphericalSingle::zero; // Start with a
|
|
||||||
// zero-initialized object
|
|
||||||
|
|
||||||
for (int i = 0; i < numIterations - 1; ++i) {
|
|
||||||
result = result + sphericalObjects[i]; // Add objects
|
|
||||||
// together
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
|
||||||
std::chrono::duration<double> duration = end - start;
|
|
||||||
std::cout << "Time to perform " << numIterations - 1
|
|
||||||
<< " additions: " << duration.count() << " seconds." << std::endl;
|
|
||||||
|
|
||||||
// Assert that the time taken is less than
|
|
||||||
// 1 second (or any other performance
|
|
||||||
// requirement)
|
|
||||||
ASSERT_LE(duration.count(), 1.0) << "Performance test failed: "
|
|
||||||
"Additions took longer than 1 "
|
|
||||||
"second.";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,17 +1,26 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <limits>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "Spherical.h"
|
#include "Spherical.h"
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(Spherical16, FromVector3) {
|
using BaseTypes = ::testing::Types<float, signed short>;
|
||||||
Vector3 v = Vector3(0, 0, 1);
|
|
||||||
Spherical16 s = Spherical16::FromVector3(v);
|
template <typename T>
|
||||||
|
class SphericalTests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(SphericalTests, BaseTypes);
|
||||||
|
|
||||||
|
TYPED_TEST(SphericalTests, FromVector3) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Spherical = SphericalOf<T>;
|
||||||
|
|
||||||
|
Vector3Of<float> v = Vector3Of<float>(0, 0, 1);
|
||||||
|
Spherical s = Spherical::FromVector3(v);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 0 1";
|
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 0 1";
|
||||||
EXPECT_FLOAT_EQ((float)s.direction.horizontal.InDegrees(), 0.0F)
|
EXPECT_FLOAT_EQ((float)s.direction.horizontal.InDegrees(), 0.0F)
|
||||||
@ -19,149 +28,167 @@ TEST(Spherical16, FromVector3) {
|
|||||||
EXPECT_FLOAT_EQ((float)s.direction.vertical.InDegrees(), 0.0F)
|
EXPECT_FLOAT_EQ((float)s.direction.vertical.InDegrees(), 0.0F)
|
||||||
<< "s.vert 0 0 1";
|
<< "s.vert 0 0 1";
|
||||||
|
|
||||||
v = Vector3(0, 1, 0);
|
v = Vector3Of<float>(0, 1, 0);
|
||||||
s = Spherical16::FromVector3(v);
|
s = Spherical::FromVector3(v);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 1 0";
|
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 1 0";
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F) << "s.hor 0 1 0";
|
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F) << "s.hor 0 1 0";
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 90.0F) << "s.vert 0 1 0";
|
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 90.0F) << "s.vert 0 1 0";
|
||||||
|
|
||||||
v = Vector3(1, 0, 0);
|
v = Vector3Of<float>(1, 0, 0);
|
||||||
s = Spherical16::FromVector3(v);
|
s = Spherical::FromVector3(v);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 1 0 0";
|
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 1 0 0";
|
||||||
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 90.0F) << "s.hor 1 0 0";
|
EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 90.0F) << "s.hor 1 0 0";
|
||||||
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F) << "s.vert 1 0 0";
|
EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F) << "s.vert 1 0 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Spherical16, Vector3) {
|
TYPED_TEST(SphericalTests, Vector3) {
|
||||||
Vector3 v = Vector3(1, 2, 3);
|
using T = TypeParam;
|
||||||
Spherical16 rd = Spherical16::FromVector3(v);
|
using Spherical = SphericalOf<T>;
|
||||||
Vector3 rv = rd.ToVector3();
|
|
||||||
EXPECT_LT(Vector3::Distance(v, rv), 10e-4) << " 1 2 3 <-> spherical";
|
|
||||||
|
|
||||||
v = Vector3(1, 2, -3);
|
Vector3Of<float> v = Vector3Of<float>(1, 2, 3);
|
||||||
rd = Spherical16::FromVector3(v);
|
Spherical rd = Spherical::FromVector3(v);
|
||||||
|
Vector3Of<float> rv = rd.ToVector3();
|
||||||
|
EXPECT_LT(Vector3Of<float>::Distance(v, rv), 10e-4) << " 1 2 3 <-> spherical";
|
||||||
|
|
||||||
|
v = Vector3Of<float>(1, 2, -3);
|
||||||
|
rd = Spherical::FromVector3(v);
|
||||||
rv = rd.ToVector3();
|
rv = rd.ToVector3();
|
||||||
EXPECT_LT(Vector3::Distance(v, rv), 10e-4) << " 1 2 3 <-> spherical";
|
EXPECT_LT(Vector3Of<float>::Distance(v, rv), 10e-4) << " 1 2 3 <-> spherical";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEST(Spherical16, FromPolar) {
|
// TYPED_TEST(SphericalTests, FromPolar) {
|
||||||
|
// using T = TypeParam;
|
||||||
|
// using Spherical = SphericalOf<T>;
|
||||||
|
|
||||||
// Polar p = Polar(1, 0);
|
// Polar p = Polar(1, 0);
|
||||||
// Spherical16 s = Spherical16::FromPolar(p);
|
// Spherical s = Spherical::FromPolar(p);
|
||||||
|
|
||||||
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 0)";
|
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 0)";
|
||||||
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(1 0)";
|
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(1 0)";
|
||||||
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 0)";
|
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 0)";
|
||||||
|
|
||||||
// p = Polar(1, 45);
|
// p = Polar(1, 45);
|
||||||
// s = Spherical16::FromPolar(p);
|
// s = Spherical::FromPolar(p);
|
||||||
|
|
||||||
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 45)";
|
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 45)";
|
||||||
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 45.0F) << "s.hor Polar(1 45)";
|
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 45.0F) << "s.hor Polar(1 45)";
|
||||||
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 45)";
|
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 45)";
|
||||||
|
|
||||||
// p = Polar(1, -45);
|
// p = Polar(1, -45);
|
||||||
// s = Spherical16::FromPolar(p);
|
// s = Spherical::FromPolar(p);
|
||||||
|
|
||||||
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 -45)";
|
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 -45)";
|
||||||
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -45.0F) << "s.hor Polar(1 -45)";
|
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -45.0F) << "s.hor Polar(1 -45)";
|
||||||
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 -45)";
|
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 -45)";
|
||||||
|
|
||||||
// p = Polar(0, 0);
|
// p = Polar(0, 0);
|
||||||
// s = Spherical16::FromPolar(p);
|
// s = Spherical::FromPolar(p);
|
||||||
|
|
||||||
// EXPECT_FLOAT_EQ(s.distance, 0.0F) << "s.distance Polar(0 0)";
|
// EXPECT_FLOAT_EQ(s.distance, 0.0F) << "s.distance Polar(0 0)";
|
||||||
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(0 0)";
|
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(0 0)";
|
||||||
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(0 0)";
|
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(0 0)";
|
||||||
|
|
||||||
// p = Polar(-1, 0);
|
// p = Polar(-1, 0);
|
||||||
// s = Spherical16::FromPolar(p);
|
// s = Spherical::FromPolar(p);
|
||||||
|
|
||||||
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(-1 0)";
|
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(-1 0)";
|
||||||
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -180.0F) << "s.hor Polar(-1 0)";
|
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -180.0F) << "s.hor Polar(-1 0)";
|
||||||
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(-1 0)";
|
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(-1 0)";
|
||||||
// }
|
// }
|
||||||
|
|
||||||
TEST(Spherical16, Incident1) {
|
TYPED_TEST(SphericalTests, Incident1) {
|
||||||
Vector3 v = Vector3(2.242557f, 1.027884f, -0.322347f);
|
using T = TypeParam;
|
||||||
Spherical16 s = Spherical16::FromVector3(v);
|
using Spherical = SphericalOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
Spherical16 sr =
|
Vector3Of<float> v = Vector3Of<float>(2.242557f, 1.027884f, -0.322347f);
|
||||||
Spherical16(2.49F, Angle16::Degrees(98.18f), Angle16::Degrees(24.4F));
|
Spherical s = Spherical::FromVector3(v);
|
||||||
|
|
||||||
|
Spherical sr =
|
||||||
|
Spherical(2.49F, Angle::Degrees(98.18f), Angle::Degrees(24.4F));
|
||||||
EXPECT_NEAR(s.distance, sr.distance, 1.0e-01);
|
EXPECT_NEAR(s.distance, sr.distance, 1.0e-01);
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
||||||
sr.direction.horizontal.InDegrees(), 1.0e-02);
|
sr.direction.horizontal.InDegrees(), 1.0e-02);
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
||||||
sr.direction.vertical.InDegrees(), 1.0e-02);
|
sr.direction.vertical.InDegrees(), 1.0e-02);
|
||||||
|
|
||||||
Vector3 r =
|
Vector3Of<float> r =
|
||||||
Spherical16(sr.distance, sr.direction.horizontal, sr.direction.vertical)
|
Spherical(sr.distance, sr.direction.horizontal, sr.direction.vertical)
|
||||||
.ToVector3();
|
.ToVector3();
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-02) << "toVector3.x 1 0 0";
|
EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-02) << "toVector3.x 1 0 0";
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-02) << "toVector3.y 1 0 0";
|
EXPECT_NEAR(r.vertical, v.vertical, 1.0e-02) << "toVector3.y 1 0 0";
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-02) << "toVector3.z 1 0 0";
|
EXPECT_NEAR(r.depth, v.depth, 1.0e-02) << "toVector3.z 1 0 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Spherical16, Incident2) {
|
TYPED_TEST(SphericalTests, Incident2) {
|
||||||
Vector3 v = Vector3(1.0f, 0.0f, 1.0f);
|
using T = TypeParam;
|
||||||
Spherical16 s = Spherical16::FromVector3(v);
|
using Spherical = SphericalOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
Spherical16 sr = Spherical16(1.4142135623F, Angle16::Degrees(45.0f),
|
Vector3Of<float> v = Vector3Of<float>(1.0f, 0.0f, 1.0f);
|
||||||
Angle16::Degrees(0.0F));
|
Spherical s = Spherical::FromVector3(v);
|
||||||
|
|
||||||
|
Spherical sr =
|
||||||
|
Spherical(1.4142135623F, Angle::Degrees(45.0f), Angle::Degrees(0.0F));
|
||||||
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
|
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
||||||
sr.direction.horizontal.InDegrees(), 1.0e-05);
|
sr.direction.horizontal.InDegrees(), 1.0e-05);
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
||||||
sr.direction.vertical.InDegrees(), 1.0e-05);
|
sr.direction.vertical.InDegrees(), 1.0e-05);
|
||||||
|
|
||||||
Vector3 r =
|
Vector3Of<float> r =
|
||||||
Spherical16(sr.distance, sr.direction.horizontal, sr.direction.vertical)
|
Spherical(sr.distance, sr.direction.horizontal, sr.direction.vertical)
|
||||||
.ToVector3();
|
.ToVector3();
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
|
EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-06);
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-06);
|
EXPECT_NEAR(r.vertical, v.vertical, 1.0e-06);
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-06);
|
EXPECT_NEAR(r.depth, v.depth, 1.0e-06);
|
||||||
|
|
||||||
v = Vector3(0.0f, 1.0f, 1.0f);
|
v = Vector3Of<float>(0.0f, 1.0f, 1.0f);
|
||||||
s = Spherical16::FromVector3(v);
|
s = Spherical::FromVector3(v);
|
||||||
|
|
||||||
sr = Spherical16(1.4142135623F, Angle16::Degrees(0), Angle16::Degrees(45));
|
sr = Spherical(1.4142135623F, Angle::Degrees(0), Angle::Degrees(45));
|
||||||
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
|
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
EXPECT_NEAR(s.direction.horizontal.InDegrees(),
|
||||||
sr.direction.horizontal.InDegrees(), 1.0e-05);
|
sr.direction.horizontal.InDegrees(), 1.0e-05);
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
EXPECT_NEAR(s.direction.vertical.InDegrees(),
|
||||||
sr.direction.vertical.InDegrees(), 1.0e-05);
|
sr.direction.vertical.InDegrees(), 1.0e-05);
|
||||||
|
|
||||||
r = Spherical16(sr.distance, sr.direction.horizontal, sr.direction.vertical)
|
r = Spherical(sr.distance, sr.direction.horizontal, sr.direction.vertical)
|
||||||
.ToVector3();
|
.ToVector3();
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
|
EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-06);
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-06);
|
EXPECT_NEAR(r.vertical, v.vertical, 1.0e-06);
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-06);
|
EXPECT_NEAR(r.depth, v.depth, 1.0e-06);
|
||||||
|
|
||||||
v = Vector3(1.0f, 1.0f, 1.0f);
|
v = Vector3Of<float>(1.0f, 1.0f, 1.0f);
|
||||||
s = Spherical16::FromVector3(v);
|
s = Spherical::FromVector3(v);
|
||||||
r = Spherical16(s.distance, s.direction.horizontal, s.direction.vertical)
|
r = Spherical(s.distance, s.direction.horizontal, s.direction.vertical)
|
||||||
.ToVector3();
|
.ToVector3();
|
||||||
|
|
||||||
EXPECT_NEAR(s.distance, 1.73205080F, 1.0e-02);
|
EXPECT_NEAR(s.distance, 1.73205080F, 1.0e-02);
|
||||||
EXPECT_NEAR(s.direction.horizontal.InDegrees(), 45.0F, 1.0e-02);
|
EXPECT_NEAR(s.direction.horizontal.InDegrees(), 45.0F, 1.0e-02);
|
||||||
EXPECT_NEAR(s.direction.vertical.InDegrees(), 35.26F, 1.0e-02);
|
EXPECT_NEAR(s.direction.vertical.InDegrees(), 35.26F, 1.0e-02);
|
||||||
|
|
||||||
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-04);
|
EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-04);
|
||||||
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-04);
|
EXPECT_NEAR(r.vertical, v.vertical, 1.0e-04);
|
||||||
EXPECT_NEAR(r.Forward(), v.Forward(), 1.0e-04);
|
EXPECT_NEAR(r.depth, v.depth, 1.0e-04);
|
||||||
|
|
||||||
// s = Spherical16(10, 45, 45);
|
// s = Spherical(10, 45, 45);
|
||||||
// r = s.ToVector3();
|
// r = s.ToVector3();
|
||||||
// EXPECT_NEAR(r.x, 5, 1.0e-06);
|
// EXPECT_NEAR(r.x, 5, 1.0e-06);
|
||||||
// EXPECT_NEAR(r.y, 7.07, 1.0e-06);
|
// EXPECT_NEAR(r.y, 7.07, 1.0e-06);
|
||||||
// EXPECT_NEAR(r.z, 5, 1.0e-06);
|
// EXPECT_NEAR(r.z, 5, 1.0e-06);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Spherical16, Addition) {
|
TYPED_TEST(SphericalTests, Addition) {
|
||||||
Spherical16 v1 = Spherical16(1, Angle16::Degrees(45), Angle16::Degrees(0));
|
using T = TypeParam;
|
||||||
Spherical16 v2 = Spherical16::zero;
|
using Spherical = SphericalOf<T>;
|
||||||
Spherical16 r = Spherical16::zero;
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
|
Spherical v1 = Spherical(1, Angle::Degrees(45), Angle::Degrees(0));
|
||||||
|
Spherical v2 = Spherical::zero;
|
||||||
|
Spherical r = Spherical::zero;
|
||||||
|
|
||||||
r = v1 + v2;
|
r = v1 + v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
|
||||||
@ -170,41 +197,44 @@ TEST(Spherical16, Addition) {
|
|||||||
r += v2;
|
r += v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
|
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
|
||||||
|
|
||||||
v2 = Spherical16(1, Angle16::Degrees(-45), Angle16::Degrees(0));
|
v2 = Spherical(1, Angle::Degrees(-45), Angle::Degrees(0));
|
||||||
r = v1 + v2;
|
r = v1 + v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 -45 0)";
|
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 -45 0)";
|
||||||
EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 0) << "Addition(1 -45 0)";
|
EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 0) << "Addition(1 -45 0)";
|
||||||
EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 0) << "Addition(1 -45 0)";
|
EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 0) << "Addition(1 -45 0)";
|
||||||
|
|
||||||
v2 = Spherical16(1, Angle16::Degrees(0), Angle16::Degrees(90));
|
v2 = Spherical(1, Angle::Degrees(0), Angle::Degrees(90));
|
||||||
r = v1 + v2;
|
r = v1 + v2;
|
||||||
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 0 90)";
|
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 0 90)";
|
||||||
EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 45) << "Addition(1 0 90)";
|
EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 45) << "Addition(1 0 90)";
|
||||||
EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 45) << "Addition(1 0 90)";
|
EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 45) << "Addition(1 0 90)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Spherical16, AdditionPerformance) {
|
TYPED_TEST(SphericalTests, AdditionPerformance) {
|
||||||
const int numIterations = 1000000; // Number of additions to test
|
using T = TypeParam;
|
||||||
std::vector<Spherical16> sphericalObjects;
|
using Spherical = SphericalOf<T>;
|
||||||
|
|
||||||
|
const int numIterations = 1000000; // Number of additions to test
|
||||||
|
std::vector<Spherical> sphericalObjects;
|
||||||
|
|
||||||
// Populate the vector with random SphericalOf objects
|
// Populate the vector with random SphericalOf objects
|
||||||
for (int i = 0; i < numIterations; ++i) {
|
for (int i = 0; i < numIterations; ++i) {
|
||||||
float distance = (float)(rand() % 100);
|
float distance = (float)(rand() % 100);
|
||||||
float horizontal = (float)(rand() % 180);
|
float horizontal = (float)(rand() % 180);
|
||||||
float vertical = (float)(rand() % 360);
|
float vertical = (float)(rand() % 360);
|
||||||
Spherical16 s = Spherical16::Deg(distance, horizontal, vertical);
|
Spherical s = Spherical::Deg(distance, horizontal, vertical);
|
||||||
sphericalObjects.push_back(s);
|
sphericalObjects.push_back(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Measure the time to perform multiple additions
|
// Measure the time to perform multiple additions
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
Spherical16 result = Spherical16::zero; // Start with a
|
Spherical result = Spherical::zero; // Start with a
|
||||||
// zero-initialized object
|
// zero-initialized object
|
||||||
|
|
||||||
for (int i = 0; i < numIterations - 1; ++i) {
|
for (int i = 0; i < numIterations - 1; ++i) {
|
||||||
result = result + sphericalObjects[i]; // Add objects
|
result = result + sphericalObjects[i]; // Add objects
|
||||||
// together
|
// together
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
@ -7,125 +7,133 @@
|
|||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(SwingTwistSingle, Quaternion) {
|
using BaseTypes = ::testing::Types<float, signed short>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SwingTwistTests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(SwingTwistTests, BaseTypes);
|
||||||
|
|
||||||
|
TYPED_TEST(SwingTwistTests, Quaternion) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using SwingTwist = SwingTwistOf<T>;
|
||||||
|
|
||||||
Quaternion q;
|
Quaternion q;
|
||||||
SwingTwistSingle s;
|
SwingTwist s;
|
||||||
Quaternion rq;
|
Quaternion rq;
|
||||||
|
|
||||||
q = Quaternion::identity;
|
q = Quaternion::identity;
|
||||||
s = SwingTwistSingle::FromQuaternion(q);
|
s = SwingTwist::FromQuaternion(q);
|
||||||
rq = s.ToQuaternion();
|
rq = s.ToQuaternion();
|
||||||
EXPECT_EQ(q, rq) << " 0 0 0 1 <-> SwingTwist";
|
EXPECT_EQ(q, rq) << " 0 0 0 1 <-> SwingTwist";
|
||||||
|
|
||||||
q = Quaternion::Euler(90, 0, 0);
|
q = Quaternion::Euler(90, 0, 0);
|
||||||
s = SwingTwistSingle::FromQuaternion(q);
|
s = SwingTwist::FromQuaternion(q);
|
||||||
rq = s.ToQuaternion();
|
rq = s.ToQuaternion();
|
||||||
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 90 0 0 <-> SwingTwist";
|
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 90 0 0 <-> SwingTwist";
|
||||||
|
|
||||||
q = Quaternion::Euler(0, 90, 0);
|
q = Quaternion::Euler(0, 90, 0);
|
||||||
s = SwingTwistSingle::FromQuaternion(q);
|
s = SwingTwist::FromQuaternion(q);
|
||||||
rq = s.ToQuaternion();
|
rq = s.ToQuaternion();
|
||||||
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 0 90 0 <-> SwingTwist";
|
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 0 90 0 <-> SwingTwist";
|
||||||
|
|
||||||
q = Quaternion::Euler(0, 0, 90);
|
q = Quaternion::Euler(0, 0, 90);
|
||||||
s = SwingTwistSingle::FromQuaternion(q);
|
s = SwingTwist::FromQuaternion(q);
|
||||||
rq = s.ToQuaternion();
|
rq = s.ToQuaternion();
|
||||||
EXPECT_EQ(q, rq) << " Euler 0 0 90 <-> SwingTwist";
|
EXPECT_EQ(q, rq) << " Euler 0 0 90 <-> SwingTwist";
|
||||||
|
|
||||||
q = Quaternion::Euler(0, 180, 0); // ==> spherical S(180 0)T0
|
q = Quaternion::Euler(0, 180, 0); // ==> spherical S(180 0)T0
|
||||||
s = SwingTwistSingle::FromQuaternion(q);
|
s = SwingTwist::FromQuaternion(q);
|
||||||
rq = s.ToQuaternion();
|
rq = s.ToQuaternion();
|
||||||
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 0 90 0 <-> SwingTwist";
|
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 0 90 0 <-> SwingTwist";
|
||||||
|
|
||||||
q = Quaternion::Euler(0, 135, 0); // ==> spherical S(180 45)T0
|
q = Quaternion::Euler(0, 135, 0); // ==> spherical S(180 45)T0
|
||||||
s = SwingTwistSingle::FromQuaternion(q);
|
s = SwingTwist::FromQuaternion(q);
|
||||||
rq = s.ToQuaternion();
|
rq = s.ToQuaternion();
|
||||||
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 0 90 0 <-> SwingTwist";
|
EXPECT_LT(Quaternion::Angle(q, rq), 10e-2) << " Euler 0 90 0 <-> SwingTwist";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SwingTwistSingle, AngleAxis) {
|
TYPED_TEST(SwingTwistTests, AngleAxis) {
|
||||||
SwingTwistSingle s;
|
using T = TypeParam;
|
||||||
SwingTwistSingle r;
|
using SwingTwist = SwingTwistOf<T>;
|
||||||
|
using Direction = DirectionOf<T>;
|
||||||
|
using Angle = AngleOf<T>;
|
||||||
|
|
||||||
s = SwingTwistSingle::AngleAxis(0, DirectionSingle::up);
|
SwingTwist s;
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(0, 0, 0)) << "0 up";
|
SwingTwist r;
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(90, DirectionSingle::up);
|
s = SwingTwist::AngleAxis(0, Direction::up);
|
||||||
s = SwingTwistSingle::Degrees(90, 0, 0);
|
EXPECT_EQ(s, SwingTwist::Degrees(0, 0, 0)) << "0 up";
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
|
||||||
<< "90 up";
|
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(180, DirectionSingle::up);
|
r = SwingTwist::AngleAxis(90, Direction::up);
|
||||||
s = SwingTwistSingle::Degrees(180, 0, 0);
|
s = SwingTwist::Degrees(90, 0, 0);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f)) << "90 up";
|
||||||
<< "180 up";
|
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(270, DirectionSingle::up);
|
r = SwingTwist::AngleAxis(180, Direction::up);
|
||||||
s = SwingTwistSingle::Degrees(-90, 0, 0);
|
s = SwingTwist::Degrees(180, 0, 0);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f)) << "180 up";
|
||||||
<< "270 up";
|
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(90, DirectionSingle::right);
|
r = SwingTwist::AngleAxis(270, Direction::up);
|
||||||
s = SwingTwistSingle::Degrees(0, 90, 0);
|
s = SwingTwist::Degrees(-90, 0, 0);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f)) << "270 up";
|
||||||
|
|
||||||
|
r = SwingTwist::AngleAxis(90, Direction::right);
|
||||||
|
s = SwingTwist::Degrees(0, 90, 0);
|
||||||
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f))
|
||||||
<< "90 right";
|
<< "90 right";
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(180, DirectionSingle::right);
|
r = SwingTwist::AngleAxis(180, Direction::right);
|
||||||
s = SwingTwistSingle::Degrees(0, 180, 0);
|
s = SwingTwist::Degrees(0, 180, 0);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f))
|
||||||
<< "180 right";
|
<< "180 right";
|
||||||
r = SwingTwistSingle::AngleAxis(270, DirectionSingle::right);
|
r = SwingTwist::AngleAxis(270, Direction::right);
|
||||||
s = SwingTwistSingle::Degrees(0, -90, 0);
|
s = SwingTwist::Degrees(0, -90, 0);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f))
|
||||||
<< "270 right";
|
<< "270 right";
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(90, DirectionSingle::forward);
|
r = SwingTwist::AngleAxis(90, Direction::forward);
|
||||||
s = SwingTwistSingle::Degrees(0, 0, 90);
|
s = SwingTwist::Degrees(0, 0, 90);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f)) << "90 up";
|
||||||
<< "90 up";
|
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(180, DirectionSingle::forward);
|
r = SwingTwist::AngleAxis(180, Direction::forward);
|
||||||
s = SwingTwistSingle::Degrees(0, 0, 180);
|
s = SwingTwist::Degrees(0, 0, 180);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f)) << "180 up";
|
||||||
<< "180 up";
|
|
||||||
|
|
||||||
r = SwingTwistSingle::AngleAxis(270, DirectionSingle::forward);
|
r = SwingTwist::AngleAxis(270, Direction::forward);
|
||||||
s = SwingTwistSingle::Degrees(0, 0, -90);
|
s = SwingTwist::Degrees(0, 0, -90);
|
||||||
EXPECT_LT(SwingTwistSingle::Angle(r, s), AngleSingle::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r, s), Angle::Degrees(10e-2f)) << "270 up";
|
||||||
<< "270 up";
|
|
||||||
|
|
||||||
auto r16 = SwingTwist16::AngleAxis(13, Direction16::down);
|
auto r16 = SwingTwist::AngleAxis(13, Direction::down);
|
||||||
auto s16 = SwingTwist16::Degrees(-13, 0, 0);
|
auto s16 = SwingTwist::Degrees(-13, 0, 0);
|
||||||
EXPECT_LT(SwingTwist16::Angle(r16, s16), Angle16::Degrees(10e-2f))
|
EXPECT_LT(SwingTwist::Angle(r16, s16), Angle::Degrees(10e-2f))
|
||||||
<< "270 up";
|
<< "270 up";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SwingTwistSingle, Normalize) {
|
TYPED_TEST(SwingTwistTests, Normalize) {
|
||||||
SwingTwistSingle s;
|
using T = TypeParam;
|
||||||
|
using SwingTwist = SwingTwistOf<T>;
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(0, 0, 0);
|
SwingTwist s;
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(0, 0, 0)) << "0 0 0 Normalized";
|
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(0, 180, 0);
|
s = SwingTwist::Degrees(0, 0, 0);
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(180, 0, 180)) << "0 180 0 Normalized";
|
EXPECT_EQ(s, SwingTwist::Degrees(0, 0, 0)) << "0 0 0 Normalized";
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(0, 180, 180);
|
s = SwingTwist::Degrees(0, 180, 0);
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(180, 0, 0)) << "0 180 180 Normalized";
|
EXPECT_EQ(s, SwingTwist::Degrees(180, 0, 180)) << "0 180 0 Normalized";
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(270, 90, 0);
|
s = SwingTwist::Degrees(0, 180, 180);
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(-90, 90, 0)) << "270 90 0 Normalized";
|
EXPECT_EQ(s, SwingTwist::Degrees(180, 0, 0)) << "0 180 180 Normalized";
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(270, 270, 0);
|
s = SwingTwist::Degrees(270, 90, 0);
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(-90, -90, 0))
|
EXPECT_EQ(s, SwingTwist::Degrees(-90, 90, 0)) << "270 90 0 Normalized";
|
||||||
<< "270 270 0 Normalized";
|
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(270, 225, 0);
|
s = SwingTwist::Degrees(270, 270, 0);
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(90, -45, -180))
|
EXPECT_EQ(s, SwingTwist::Degrees(-90, -90, 0)) << "270 270 0 Normalized";
|
||||||
<< "270 225 0 Normalized";
|
|
||||||
|
|
||||||
s = SwingTwistSingle::Degrees(270, 0, 225);
|
s = SwingTwist::Degrees(270, 225, 0);
|
||||||
EXPECT_EQ(s, SwingTwistSingle::Degrees(-90, 0, -135))
|
EXPECT_EQ(s, SwingTwist::Degrees(90, -45, -180)) << "270 225 0 Normalized";
|
||||||
<< "270 0 225 Normalized";
|
|
||||||
|
s = SwingTwist::Degrees(270, 0, 225);
|
||||||
|
EXPECT_EQ(s, SwingTwist::Degrees(-90, 0, -135)) << "270 0 225 Normalized";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -8,9 +8,21 @@
|
|||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
using Vector2 = Vector2Of<float>;
|
using BaseTypes = ::testing::Types<float, int>;
|
||||||
|
using FpTypes = ::testing::Types<float>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Vector2Tests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(Vector2Tests, BaseTypes);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Vector2FpTests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(Vector2FpTests, FpTypes);
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2Tests, FromPolar) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
TEST(Vector2, FromPolar) {
|
|
||||||
Vector2 v;
|
Vector2 v;
|
||||||
PolarSingle p;
|
PolarSingle p;
|
||||||
Vector2Float r;
|
Vector2Float r;
|
||||||
@ -37,7 +49,10 @@ TEST(Vector2, FromPolar) {
|
|||||||
EXPECT_FLOAT_EQ(r.vertical, 0.0F) << "FromPolar(0 0)";
|
EXPECT_FLOAT_EQ(r.vertical, 0.0F) << "FromPolar(0 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Magnitude) {
|
TYPED_TEST(Vector2Tests, Magnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v = Vector2(1, 2);
|
Vector2 v = Vector2(1, 2);
|
||||||
float m = 0;
|
float m = 0;
|
||||||
|
|
||||||
@ -54,6 +69,14 @@ TEST(Vector2, Magnitude) {
|
|||||||
v = Vector2(0, 0);
|
v = Vector2(0, 0);
|
||||||
m = v.Magnitude();
|
m = v.Magnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 ";
|
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Magnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
float m = 0;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -66,7 +89,10 @@ TEST(Vector2, Magnitude) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, SqrMagnitude) {
|
TYPED_TEST(Vector2Tests, SqrMagnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v = Vector2(1, 2);
|
Vector2 v = Vector2(1, 2);
|
||||||
float m = 0;
|
float m = 0;
|
||||||
|
|
||||||
@ -83,6 +109,14 @@ TEST(Vector2, SqrMagnitude) {
|
|||||||
v = Vector2(0, 0);
|
v = Vector2(0, 0);
|
||||||
m = v.SqrMagnitude();
|
m = v.SqrMagnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 0) << "v.sqrMagnitude 0 0 ";
|
EXPECT_FLOAT_EQ(m, 0) << "v.sqrMagnitude 0 0 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, SqrMagnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
float m;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -95,7 +129,10 @@ TEST(Vector2, SqrMagnitude) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Normalize) {
|
TYPED_TEST(Vector2Tests, Normalize) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(0, 2);
|
Vector2 v1 = Vector2(0, 2);
|
||||||
@ -114,6 +151,15 @@ TEST(Vector2, Normalize) {
|
|||||||
v1 = Vector2(0, 0);
|
v1 = Vector2(0, 0);
|
||||||
v = v1.Normalized();
|
v = v1.Normalized();
|
||||||
EXPECT_TRUE(v == Vector2(0, 0)) << "v.normalized 0 0";
|
EXPECT_TRUE(v == Vector2(0, 0)) << "v.normalized 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Normalize) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1;
|
||||||
|
float r;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v1 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v1 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -128,7 +174,10 @@ TEST(Vector2, Normalize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Negate) {
|
TYPED_TEST(Vector2Tests, Negate) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v = Vector2::zero;
|
Vector2 v = Vector2::zero;
|
||||||
|
|
||||||
@ -142,6 +191,14 @@ TEST(Vector2, Negate) {
|
|||||||
v1 = Vector2(0, 0);
|
v1 = Vector2(0, 0);
|
||||||
v = -v1;
|
v = -v1;
|
||||||
EXPECT_TRUE(v == Vector2(0, 0)) << "- 0 0";
|
EXPECT_TRUE(v == Vector2(0, 0)) << "- 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Negate) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v1 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v1 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -156,7 +213,10 @@ TEST(Vector2, Negate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Subtract) {
|
TYPED_TEST(Vector2Tests, Subtract) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
Vector2 v = Vector2::zero;
|
Vector2 v = Vector2::zero;
|
||||||
@ -181,6 +241,15 @@ TEST(Vector2, Subtract) {
|
|||||||
|
|
||||||
v -= v2;
|
v -= v2;
|
||||||
EXPECT_TRUE(v == Vector2(4, 5)) << "4 5 - 0 0";
|
EXPECT_TRUE(v == Vector2(4, 5)) << "4 5 - 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Subtract) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -195,7 +264,10 @@ TEST(Vector2, Subtract) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Addition) {
|
TYPED_TEST(Vector2Tests, Addition) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
Vector2 v = Vector2::zero;
|
Vector2 v = Vector2::zero;
|
||||||
@ -215,6 +287,15 @@ TEST(Vector2, Addition) {
|
|||||||
EXPECT_TRUE(v == Vector2(4, 5)) << "4 5 + 0 0";
|
EXPECT_TRUE(v == Vector2(4, 5)) << "4 5 + 0 0";
|
||||||
v += v2;
|
v += v2;
|
||||||
EXPECT_TRUE(v == Vector2(4, 5)) << "4 5 + 0 0";
|
EXPECT_TRUE(v == Vector2(4, 5)) << "4 5 + 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Addition) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2 = Vector2(0, 0);
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -229,7 +310,10 @@ TEST(Vector2, Addition) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Scale) {
|
TYPED_TEST(Vector2Tests, Scale) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
Vector2 v = Vector2::zero;
|
Vector2 v = Vector2::zero;
|
||||||
@ -244,6 +328,15 @@ TEST(Vector2, Scale) {
|
|||||||
v2 = Vector2(0, 0);
|
v2 = Vector2(0, 0);
|
||||||
v = Vector2::Scale(v1, v2);
|
v = Vector2::Scale(v1, v2);
|
||||||
EXPECT_TRUE(v == Vector2(0, 0)) << "Scale 4 5 , 0 0";
|
EXPECT_TRUE(v == Vector2(0, 0)) << "Scale 4 5 , 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Scale) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -258,9 +351,12 @@ TEST(Vector2, Scale) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Multiply) {
|
TYPED_TEST(Vector2Tests, Multiply) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
float f = 3;
|
T f = 3;
|
||||||
Vector2 v = Vector2::zero;
|
Vector2 v = Vector2::zero;
|
||||||
|
|
||||||
v = v1 * f;
|
v = v1 * f;
|
||||||
@ -273,6 +369,15 @@ TEST(Vector2, Multiply) {
|
|||||||
f = 0;
|
f = 0;
|
||||||
v = v1 * f;
|
v = v1 * f;
|
||||||
EXPECT_TRUE(v == Vector2(0, 0)) << "4 5 * 0";
|
EXPECT_TRUE(v == Vector2(0, 0)) << "4 5 * 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Multiply) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
T f;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
f = FLOAT_INFINITY;
|
f = FLOAT_INFINITY;
|
||||||
@ -287,9 +392,12 @@ TEST(Vector2, Multiply) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Divide) {
|
TYPED_TEST(Vector2Tests, Divide) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
float f = 2;
|
T f = 2;
|
||||||
Vector2 v = Vector2::zero;
|
Vector2 v = Vector2::zero;
|
||||||
|
|
||||||
v = v1 / f;
|
v = v1 / f;
|
||||||
@ -298,6 +406,15 @@ TEST(Vector2, Divide) {
|
|||||||
f = -2;
|
f = -2;
|
||||||
v = v1 / f;
|
v = v1 / f;
|
||||||
EXPECT_TRUE(v == Vector2(-2, -2.5F)) << "4 5 / -3";
|
EXPECT_TRUE(v == Vector2(-2, -2.5F)) << "4 5 / -3";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Divide) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v;
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
T f;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
f = 0;
|
f = 0;
|
||||||
@ -314,7 +431,10 @@ TEST(Vector2, Divide) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Dot) {
|
TYPED_TEST(Vector2Tests, Dot) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
float f = 0;
|
float f = 0;
|
||||||
@ -329,6 +449,15 @@ TEST(Vector2, Dot) {
|
|||||||
v2 = Vector2(0, 0);
|
v2 = Vector2(0, 0);
|
||||||
f = Vector2::Dot(v1, v2);
|
f = Vector2::Dot(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5, 0 0)";
|
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5, 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Dot) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v2;
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
float f;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -341,7 +470,10 @@ TEST(Vector2, Dot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Equality) {
|
TYPED_TEST(Vector2Tests, Equality) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
bool r = false;
|
bool r = false;
|
||||||
@ -352,6 +484,15 @@ TEST(Vector2, Equality) {
|
|||||||
v2 = Vector2(4, 5);
|
v2 = Vector2(4, 5);
|
||||||
r = v1 == v2;
|
r = v1 == v2;
|
||||||
EXPECT_TRUE(r) << "4 5 == 1 2";
|
EXPECT_TRUE(r) << "4 5 == 1 2";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Equality) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2;
|
||||||
|
bool r;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -364,7 +505,10 @@ TEST(Vector2, Equality) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Distance) {
|
TYPED_TEST(Vector2Tests, Distance) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
float f = 0;
|
float f = 0;
|
||||||
@ -379,6 +523,15 @@ TEST(Vector2, Distance) {
|
|||||||
v2 = Vector2(0, 0);
|
v2 = Vector2(0, 0);
|
||||||
f = Vector2::Distance(v1, v2);
|
f = Vector2::Distance(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 6.403124F) << "Distance(4 5, 0 0)";
|
EXPECT_FLOAT_EQ(f, 6.403124F) << "Distance(4 5, 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Distance) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2;
|
||||||
|
float f;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -391,10 +544,14 @@ TEST(Vector2, Distance) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Angle) {
|
TYPED_TEST(Vector2Tests, Angle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
using Angle = AngleOf<float>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
AngleSingle f = AngleSingle::zero;
|
Angle f = Angle::zero;
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
f = Vector2::UnsignedAngle(v1, v2);
|
f = Vector2::UnsignedAngle(v1, v2);
|
||||||
@ -407,26 +564,40 @@ TEST(Vector2, Angle) {
|
|||||||
v2 = Vector2(0, 0);
|
v2 = Vector2(0, 0);
|
||||||
f = Vector2::UnsignedAngle(v1, v2);
|
f = Vector2::UnsignedAngle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "Angle(4 5, 0 0)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "Angle(4 5, 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2FpTests, Angle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2;
|
||||||
|
AngleOf<float> f;
|
||||||
|
float r;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
f = Vector2::UnsignedAngle(v1, v2);
|
f = Vector2::UnsignedAngle(v1, v2);
|
||||||
//r = isnan(f.InDegrees());
|
// r = isnan(f.InDegrees());
|
||||||
r = f.InDegrees() == 0;
|
r = f.InDegrees() == 0;
|
||||||
EXPECT_TRUE(r) << "Angle(4 5, INFINITY INFINITY)";
|
EXPECT_TRUE(r) << "Angle(4 5, INFINITY INFINITY)";
|
||||||
|
|
||||||
v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
f = Vector2::UnsignedAngle(v1, v2);
|
f = Vector2::UnsignedAngle(v1, v2);
|
||||||
//r = isnan(f.InDegrees());
|
// r = isnan(f.InDegrees());
|
||||||
r = f.InDegrees() == 0;
|
r = f.InDegrees() == 0;
|
||||||
EXPECT_TRUE(r) << "Angle(4 5, -INFINITY -INFINITY)";
|
EXPECT_TRUE(r) << "Angle(4 5, -INFINITY -INFINITY)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, SignedAngle) {
|
TYPED_TEST(Vector2Tests, SignedAngle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
using Angle = AngleOf<float>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
AngleSingle f = AngleSingle::zero;
|
Angle f = Angle::zero;
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
f = Vector2::SignedAngle(v1, v2);
|
f = Vector2::SignedAngle(v1, v2);
|
||||||
@ -440,20 +611,6 @@ TEST(Vector2, SignedAngle) {
|
|||||||
f = Vector2::SignedAngle(v1, v2);
|
f = Vector2::SignedAngle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5, 0 0)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5, 0 0)";
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
|
||||||
f = Vector2::SignedAngle(v1, v2);
|
|
||||||
//r = isnan(f.InDegrees());
|
|
||||||
r = f.InDegrees() == 0;
|
|
||||||
EXPECT_TRUE(r) << "SignedAngle(4 5, INFINITY INFINITY)";
|
|
||||||
|
|
||||||
v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
|
||||||
f = Vector2::SignedAngle(v1, v2);
|
|
||||||
//r = isnan(f.InDegrees());
|
|
||||||
r = f.InDegrees() == 0;
|
|
||||||
EXPECT_TRUE(r) << "SignedAngle(4 5, -INFINITY -INFINITY)";
|
|
||||||
}
|
|
||||||
|
|
||||||
v1 = Vector2(0, 1);
|
v1 = Vector2(0, 1);
|
||||||
v2 = Vector2(1, 0);
|
v2 = Vector2(1, 0);
|
||||||
f = Vector2::SignedAngle(v1, v2);
|
f = Vector2::SignedAngle(v1, v2);
|
||||||
@ -465,24 +622,55 @@ TEST(Vector2, SignedAngle) {
|
|||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 180.0F) << "SignedAngle(0 1, 1 0)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 180.0F) << "SignedAngle(0 1, 1 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Rotate) {
|
TYPED_TEST(Vector2FpTests, SignedAngle) {
|
||||||
Vector2 v1 = Vector2(1, 2);
|
using T = TypeParam;
|
||||||
Vector2 r = Vector2(0, 0);
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
r = Vector2::Rotate(v1, AngleSingle::Degrees(0));
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2;
|
||||||
|
AngleOf<float> f;
|
||||||
|
float r;
|
||||||
|
|
||||||
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
|
f = Vector2::SignedAngle(v1, v2);
|
||||||
|
// r = isnan(f.InDegrees());
|
||||||
|
r = f.InDegrees() == 0;
|
||||||
|
EXPECT_TRUE(r) << "SignedAngle(4 5, INFINITY INFINITY)";
|
||||||
|
|
||||||
|
v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
|
f = Vector2::SignedAngle(v1, v2);
|
||||||
|
// r = isnan(f.InDegrees());
|
||||||
|
r = f.InDegrees() == 0;
|
||||||
|
EXPECT_TRUE(r) << "SignedAngle(4 5, -INFINITY -INFINITY)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector2Tests, Rotate) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
using Angle = AngleOf<float>;
|
||||||
|
|
||||||
|
Vector2 v1 = Vector2(1, 2);
|
||||||
|
Vector2Of<float> r = Vector2(0, 0);
|
||||||
|
|
||||||
|
r = Vector2::Rotate(v1, Angle::Degrees(0));
|
||||||
EXPECT_FLOAT_EQ(Vector2::Distance(r, v1), 0);
|
EXPECT_FLOAT_EQ(Vector2::Distance(r, v1), 0);
|
||||||
|
|
||||||
r = Vector2::Rotate(v1, AngleSingle::Degrees(180));
|
r = Vector2::Rotate(v1, Angle::Degrees(180));
|
||||||
EXPECT_NEAR(Vector2::Distance(r, Vector2(-1, -2)), 0, 1.0e-06);
|
EXPECT_NEAR(Vector2Of<float>::Distance(r, Vector2(-1, -2)), 0, 1.0e-06);
|
||||||
|
|
||||||
r = Vector2::Rotate(v1, AngleSingle::Degrees(-90));
|
r = Vector2::Rotate(v1, Angle::Degrees(-90));
|
||||||
EXPECT_NEAR(Vector2::Distance(r, Vector2(2, -1)), 0, 1.0e-06);
|
EXPECT_NEAR(Vector2::Distance(r, Vector2(2, -1)), 0, 1.0e-06);
|
||||||
|
|
||||||
r = Vector2::Rotate(v1, AngleSingle::Degrees(270));
|
r = Vector2::Rotate(v1, Angle::Degrees(270));
|
||||||
EXPECT_NEAR(Vector2::Distance(r, Vector2(2, -1)), 0, 1.0e-06);
|
EXPECT_NEAR(Vector2::Distance(r, Vector2(2, -1)), 0, 1.0e-06);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Lerp) {
|
TYPED_TEST(Vector2Tests, Lerp) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector2 = Vector2Of<T>;
|
||||||
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
Vector2 r = Vector2(0, 0);
|
Vector2 r = Vector2(0, 0);
|
||||||
|
|||||||
@ -1,134 +1,186 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <limits>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(Vector3, FromSpherical) {
|
using BaseTypes = ::testing::Types<float, int>;
|
||||||
|
using FpTypes = ::testing::Types<float>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Vector3Tests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(Vector3Tests, BaseTypes);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Vector3FpTests : public ::testing::Test {};
|
||||||
|
TYPED_TEST_SUITE(Vector3FpTests, FpTypes);
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, FromSpherical) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v = Vector3(0, 0, 1);
|
Vector3 v = Vector3(0, 0, 1);
|
||||||
SphericalOf<float> s = SphericalOf<float>::FromVector3(v);
|
SphericalOf<float> s = SphericalOf<float>::FromVector3(v);
|
||||||
Vector3 r = Vector3(s);
|
Vector3 r = Vector3::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(r.Right(), 0.0F) << "toVector3.x 0 0 1";
|
EXPECT_FLOAT_EQ(r.horizontal, 0.0F) << "toVector3.x 0 0 1";
|
||||||
EXPECT_NEAR(r.Up(), 0.0F, 1.0e-06) << "toVector3.y 0 0 1";
|
EXPECT_NEAR(r.vertical, 0.0F, 1.0e-06) << "toVector3.y 0 0 1";
|
||||||
EXPECT_FLOAT_EQ(r.Forward(), 1.0F) << "toVector3.z 0 0 1";
|
EXPECT_FLOAT_EQ(r.depth, 1.0F) << "toVector3.z 0 0 1";
|
||||||
|
|
||||||
v = Vector3(0, 1, 0);
|
v = Vector3(0, 1, 0);
|
||||||
s = SphericalOf<float>::FromVector3(v);
|
s = SphericalOf<float>::FromVector3(v);
|
||||||
r = Vector3(s);
|
r = Vector3::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(r.Right(), 0.0F) << "toVector3.x 0 1 0";
|
EXPECT_FLOAT_EQ(r.horizontal, 0.0F) << "toVector3.x 0 1 0";
|
||||||
EXPECT_FLOAT_EQ(r.Up(), 1.0F) << "toVector3.y 0 1 0";
|
EXPECT_FLOAT_EQ(r.vertical, 1.0F) << "toVector3.y 0 1 0";
|
||||||
EXPECT_NEAR(r.Forward(), 0.0F, 1.0e-06) << "toVector3.z 0 1 0";
|
EXPECT_NEAR(r.depth, 0.0F, 1.0e-06) << "toVector3.z 0 1 0";
|
||||||
|
|
||||||
v = Vector3(1, 0, 0);
|
v = Vector3(1, 0, 0);
|
||||||
s = SphericalOf<float>::FromVector3(v);
|
s = SphericalOf<float>::FromVector3(v);
|
||||||
r = Vector3(s);
|
r = Vector3::FromSpherical(s);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(r.Right(), 1.0F) << "toVector3.x 1 0 0";
|
EXPECT_FLOAT_EQ(r.horizontal, 1.0F) << "toVector3.x 1 0 0";
|
||||||
EXPECT_NEAR(r.Up(), 0.0F, 1.0e-06) << "toVector3.y 1 0 0";
|
EXPECT_NEAR(r.vertical, 0.0F, 1.0e-06) << "toVector3.y 1 0 0";
|
||||||
EXPECT_NEAR(r.Forward(), 0.0F, 1.0e-06) << "toVector3.z 1 0 0";
|
EXPECT_NEAR(r.depth, 0.0F, 1.0e-06) << "toVector3.z 1 0 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Magnitude) {
|
TYPED_TEST(Vector3Tests, Magnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v = Vector3(1, 2, 3);
|
Vector3 v = Vector3(1, 2, 3);
|
||||||
float m = 0;
|
float m = 0;
|
||||||
|
|
||||||
m = v.magnitude();
|
m = v.Magnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 3.741657F) << "v.magnitude 1 2 3";
|
EXPECT_FLOAT_EQ(m, 3.741657F) << "v.magnitude 1 2 3";
|
||||||
|
|
||||||
m = Vector3::Magnitude(v);
|
m = Vector3::MagnitudeOf(v);
|
||||||
EXPECT_FLOAT_EQ(m, 3.741657F) << "Vector3::Magnitude 1 2 3";
|
EXPECT_FLOAT_EQ(m, 3.741657F) << "Vector3::Magnitude 1 2 3";
|
||||||
|
|
||||||
v = Vector3(-1, -2, -3);
|
v = Vector3(-1, -2, -3);
|
||||||
m = v.magnitude();
|
m = v.Magnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 3.741657F) << "v.magnitude -1 -2 -3";
|
EXPECT_FLOAT_EQ(m, 3.741657F) << "v.magnitude -1 -2 -3";
|
||||||
|
|
||||||
v = Vector3(0, 0, 0);
|
v = Vector3(0, 0, 0);
|
||||||
m = v.magnitude();
|
m = v.Magnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 0 ";
|
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 0 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Magnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v;
|
||||||
|
float m;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
m = v.magnitude();
|
m = v.Magnitude();
|
||||||
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
||||||
<< "v.magnitude INFINITY INFINITY INFINITY ";
|
<< "v.magnitude INFINITY INFINITY INFINITY ";
|
||||||
|
|
||||||
v = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
m = v.magnitude();
|
m = v.Magnitude();
|
||||||
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
||||||
<< "v.magnitude -INFINITY -INFINITY -INFINITY ";
|
<< "v.magnitude -INFINITY -INFINITY -INFINITY ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, SqrMagnitude) {
|
TYPED_TEST(Vector3Tests, SqrMagnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v = Vector3(1, 2, 3);
|
Vector3 v = Vector3(1, 2, 3);
|
||||||
float m = 0;
|
float m = 0;
|
||||||
|
|
||||||
m = v.sqrMagnitude();
|
m = v.SqrMagnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 14) << "v.sqrMagnitude 1 2 3";
|
EXPECT_FLOAT_EQ(m, 14) << "v.sqrMagnitude 1 2 3";
|
||||||
|
|
||||||
m = Vector3::SqrMagnitude(v);
|
m = Vector3::SqrMagnitudeOf(v);
|
||||||
EXPECT_FLOAT_EQ(m, 14) << "Vector3::SqrMagnitude 1 2 3";
|
EXPECT_FLOAT_EQ(m, 14) << "Vector3::SqrMagnitude 1 2 3";
|
||||||
|
|
||||||
v = Vector3(-1, -2, -3);
|
v = Vector3(-1, -2, -3);
|
||||||
m = v.sqrMagnitude();
|
m = v.SqrMagnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 14) << "v.sqrMagnitude -1 -2 -3";
|
EXPECT_FLOAT_EQ(m, 14) << "v.sqrMagnitude -1 -2 -3";
|
||||||
|
|
||||||
v = Vector3(0, 0, 0);
|
v = Vector3(0, 0, 0);
|
||||||
m = v.sqrMagnitude();
|
m = v.SqrMagnitude();
|
||||||
EXPECT_FLOAT_EQ(m, 0) << "v.sqrMagnitude 0 0 0 ";
|
EXPECT_FLOAT_EQ(m, 0) << "v.sqrMagnitude 0 0 0 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, SqrMagnitude) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v;
|
||||||
|
float m;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
m = v.sqrMagnitude();
|
m = v.SqrMagnitude();
|
||||||
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
||||||
<< "v.sqrMagnitude INFINITY INFINITY INFINITY ";
|
<< "v.sqrMagnitude INFINITY INFINITY INFINITY ";
|
||||||
|
|
||||||
v = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
m = v.sqrMagnitude();
|
m = v.SqrMagnitude();
|
||||||
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
|
||||||
<< "v.sqrMagnitude -INFINITY -INFINITY -INFINITY ";
|
<< "v.sqrMagnitude -INFINITY -INFINITY -INFINITY ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Normalize) {
|
TYPED_TEST(Vector3Tests, Normalize) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(0, 2, 0);
|
Vector3 v1 = Vector3(0, 2, 0);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
v = v1.normalized();
|
v = v1.Normalized();
|
||||||
EXPECT_TRUE(v == Vector3(0, 1, 0)) << "v.normalized 0 2 0";
|
EXPECT_TRUE(v == Vector3(0, 1, 0)) << "v.normalized 0 2 0";
|
||||||
|
|
||||||
v = Vector3::Normalize(v1);
|
v = Vector3::Normalize(v1);
|
||||||
EXPECT_TRUE(v == Vector3(0, 1, 0)) << "Vector3::Normalize 0 2 0";
|
EXPECT_TRUE(v == Vector3(0, 1, 0)) << "Vector3::Normalize 0 2 0";
|
||||||
|
|
||||||
v1 = Vector3(0, -2, 0);
|
v1 = Vector3(0, -2, 0);
|
||||||
v = v1.normalized();
|
v = v1.Normalized();
|
||||||
EXPECT_TRUE(v == Vector3(0, -1, 0)) << "v.normalized 0 -2 0";
|
EXPECT_TRUE(v == Vector3(0, -1, 0)) << "v.normalized 0 -2 0";
|
||||||
|
|
||||||
v1 = Vector3(0, 0, 0);
|
v1 = Vector3(0, 0, 0);
|
||||||
v = v1.normalized();
|
v = v1.Normalized();
|
||||||
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "v.normalized 0 0 0";
|
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "v.normalized 0 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Normalize) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(0, 2, 0);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v1 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v1 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
v = v1.normalized();
|
v = v1.Normalized();
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
EXPECT_TRUE(r) << "v.normalized INFINITY INFINITY INFINITY";
|
EXPECT_TRUE(r) << "v.normalized INFINITY INFINITY INFINITY";
|
||||||
|
|
||||||
v1 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v1 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
v = v1.normalized();
|
v = v1.Normalized();
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
EXPECT_TRUE(r) << "v.normalized -INFINITY -INFINITY -INFINITY";
|
EXPECT_TRUE(r) << "v.normalized -INFINITY -INFINITY -INFINITY";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Negate) {
|
TYPED_TEST(Vector3Tests, Negate) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
@ -142,6 +194,14 @@ TEST(Vector3, Negate) {
|
|||||||
v1 = Vector3(0, 0, 0);
|
v1 = Vector3(0, 0, 0);
|
||||||
v = -v1;
|
v = -v1;
|
||||||
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "- 0 0 0";
|
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "- 0 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Negate) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v1 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v1 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -156,7 +216,11 @@ TEST(Vector3, Negate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Subtract) {
|
TYPED_TEST(Vector3Tests, Subtract) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -175,6 +239,15 @@ TEST(Vector3, Subtract) {
|
|||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
v = v1 - v2;
|
v = v1 - v2;
|
||||||
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "4 5 6 - 0 0 0";
|
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "4 5 6 - 0 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Subtract) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -189,7 +262,10 @@ TEST(Vector3, Subtract) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Addition) {
|
TYPED_TEST(Vector3Tests, Addition) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -204,6 +280,15 @@ TEST(Vector3, Addition) {
|
|||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
v = v1 + v2;
|
v = v1 + v2;
|
||||||
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "4 5 6 + 0 0 0";
|
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "4 5 6 + 0 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Addition) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -218,7 +303,11 @@ TEST(Vector3, Addition) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Scale) {
|
TYPED_TEST(Vector3Tests, Scale) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -233,6 +322,15 @@ TEST(Vector3, Scale) {
|
|||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
v = Vector3::Scale(v1, v2);
|
v = Vector3::Scale(v1, v2);
|
||||||
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "Scale 4 5 6 , 0 0 0";
|
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "Scale 4 5 6 , 0 0 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Scale) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -247,7 +345,10 @@ TEST(Vector3, Scale) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Multiply) {
|
TYPED_TEST(Vector3Tests, Multiply) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
float f = 3;
|
float f = 3;
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -262,6 +363,15 @@ TEST(Vector3, Multiply) {
|
|||||||
f = 0;
|
f = 0;
|
||||||
v = v1 * f;
|
v = v1 * f;
|
||||||
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "4 5 6 * 0";
|
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "4 5 6 * 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Multiply) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
float f = 3;
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
f = FLOAT_INFINITY;
|
f = FLOAT_INFINITY;
|
||||||
@ -276,7 +386,10 @@ TEST(Vector3, Multiply) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Divide) {
|
TYPED_TEST(Vector3Tests, Divide) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
float f = 2;
|
float f = 2;
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -287,6 +400,16 @@ TEST(Vector3, Divide) {
|
|||||||
f = -2;
|
f = -2;
|
||||||
v = v1 / f;
|
v = v1 / f;
|
||||||
EXPECT_TRUE(v == Vector3(-2, -2.5F, -3)) << "4 5 6 / -3";
|
EXPECT_TRUE(v == Vector3(-2, -2.5F, -3)) << "4 5 6 / -3";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Divide) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
float f = 2;
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
f = 0;
|
f = 0;
|
||||||
@ -304,7 +427,10 @@ TEST(Vector3, Divide) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Dot) {
|
TYPED_TEST(Vector3Tests, Dot) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
float f = 0;
|
float f = 0;
|
||||||
@ -319,6 +445,15 @@ TEST(Vector3, Dot) {
|
|||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
f = Vector3::Dot(v1, v2);
|
f = Vector3::Dot(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5 6, 0 0 0)";
|
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5 6, 0 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Dot) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
float f = 0;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -333,7 +468,10 @@ TEST(Vector3, Dot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Equality) {
|
TYPED_TEST(Vector3Tests, Equality) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
bool r = false;
|
bool r = false;
|
||||||
@ -344,6 +482,15 @@ TEST(Vector3, Equality) {
|
|||||||
v2 = Vector3(4, 5, 6);
|
v2 = Vector3(4, 5, 6);
|
||||||
r = v1 == v2;
|
r = v1 == v2;
|
||||||
EXPECT_TRUE(r) << "4 5 6 == 1 2 3";
|
EXPECT_TRUE(r) << "4 5 6 == 1 2 3";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Equality) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -357,7 +504,10 @@ TEST(Vector3, Equality) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Distance) {
|
TYPED_TEST(Vector3Tests, Distance) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
float f = 0;
|
float f = 0;
|
||||||
@ -372,6 +522,15 @@ TEST(Vector3, Distance) {
|
|||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
f = Vector3::Distance(v1, v2);
|
f = Vector3::Distance(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 8.77496433F) << "Distance(4 5 6, 0 0 0)";
|
EXPECT_FLOAT_EQ(f, 8.77496433F) << "Distance(4 5 6, 0 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Distance) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
float f = 0;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -386,7 +545,10 @@ TEST(Vector3, Distance) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Cross) {
|
TYPED_TEST(Vector3Tests, Cross) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -405,21 +567,34 @@ TEST(Vector3, Cross) {
|
|||||||
v = Vector3::Cross(v1, v2);
|
v = Vector3::Cross(v1, v2);
|
||||||
r = v == Vector3(0, 0, 0);
|
r = v == Vector3(0, 0, 0);
|
||||||
EXPECT_TRUE(r) << "Cross(4 5 6, 0 0 0)";
|
EXPECT_TRUE(r) << "Cross(4 5 6, 0 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Cross) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
v = Vector3::Cross(v1, v2);
|
v = Vector3::Cross(v1, v2);
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
EXPECT_TRUE(r) << "Cross(4 5 6, INFINITY INFINITY INFINITY)";
|
EXPECT_TRUE(r) << "Cross(4 5 6, INFINITY INFINITY INFINITY)";
|
||||||
|
|
||||||
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
v = Vector3::Cross(v1, v2);
|
v = Vector3::Cross(v1, v2);
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
EXPECT_TRUE(r) << "Cross(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
EXPECT_TRUE(r) << "Cross(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Project) {
|
TYPED_TEST(Vector3Tests, Project) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
@ -438,84 +613,124 @@ TEST(Vector3, Project) {
|
|||||||
v = Vector3::Project(v1, v2);
|
v = Vector3::Project(v1, v2);
|
||||||
r = v == Vector3(0, 0, 0);
|
r = v == Vector3(0, 0, 0);
|
||||||
EXPECT_TRUE(r) << "Project(4 5 6, 0 0 0)";
|
EXPECT_TRUE(r) << "Project(4 5 6, 0 0 0)";
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
|
||||||
v = Vector3::Project(v1, v2);
|
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
|
||||||
EXPECT_TRUE(r) << "Project(4 5 6, INFINITY INFINITY INFINITY)";
|
|
||||||
|
|
||||||
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
|
||||||
v = Vector3::Project(v1, v2);
|
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
|
||||||
EXPECT_TRUE(r) << "Project(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, ProjectOnPlane) {
|
TYPED_TEST(Vector3FpTests, Project) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v = Vector3::zero;
|
Vector3 v = Vector3::zero;
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
|
v = Vector3::Project(v1, v2);
|
||||||
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
|
EXPECT_TRUE(r) << "Project(4 5 6, INFINITY INFINITY INFINITY)";
|
||||||
|
|
||||||
|
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
|
v = Vector3::Project(v1, v2);
|
||||||
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
|
EXPECT_TRUE(r) << "Project(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3Tests, ProjectOnPlane) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3Of<float> v = Vector3Of<float>::zero;
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
v = Vector3::ProjectOnPlane(v1, v2);
|
v = Vector3::ProjectOnPlane(v1, v2);
|
||||||
r = v == Vector3(1.71428561F, 0.428571224F, -0.857142925F);
|
r = v == Vector3Of<float>(1.71428561F, 0.428571224F, -0.857142925F);
|
||||||
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, 1 2 3)";
|
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, 1 2 3)";
|
||||||
|
//EXPECT_EQ(v, Vector3(1.71428561F, 0.428571224F, -0.857142925F));
|
||||||
|
|
||||||
v2 = Vector3(-1, -2, -3);
|
v2 = Vector3(-1, -2, -3);
|
||||||
v = Vector3::ProjectOnPlane(v1, v2);
|
v = Vector3::ProjectOnPlane(v1, v2);
|
||||||
r = v == Vector3(1.71428561F, 0.428571224F, -0.857142925F);
|
r = v == Vector3Of<float>(1.71428561F, 0.428571224F, -0.857142925F);
|
||||||
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, -1 -2 -3)";
|
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, -1 -2 -3)";
|
||||||
|
|
||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
v = Vector3::ProjectOnPlane(v1, v2);
|
v = Vector3::ProjectOnPlane(v1, v2);
|
||||||
r = v == Vector3(4, 5, 6);
|
r = v == Vector3(4, 5, 6);
|
||||||
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, 0 0 0)";
|
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, 0 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, ProjectOnPlane) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3 v = Vector3::zero;
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
v = Vector3::ProjectOnPlane(v1, v2);
|
v = Vector3::ProjectOnPlane(v1, v2);
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, INFINITY INFINITY INFINITY)";
|
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, INFINITY INFINITY INFINITY)";
|
||||||
|
|
||||||
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
v = Vector3::ProjectOnPlane(v1, v2);
|
v = Vector3::ProjectOnPlane(v1, v2);
|
||||||
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
|
r = isnan(v.horizontal) && isnan(v.vertical) && isnan(v.depth);
|
||||||
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Angle) {
|
TYPED_TEST(Vector3Tests, Angle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
AngleOf<float> f = AngleOf<float>::Degrees(0);
|
AngleOf<float> f = AngleOf<float>::Degrees(0);
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::UnsignedAngle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 12.9331388F) << "Angle(4 5 6, 1 2 3)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 12.9331388F) << "Angle(4 5 6, 1 2 3)";
|
||||||
|
|
||||||
v2 = Vector3(-1, -2, -3);
|
v2 = Vector3(-1, -2, -3);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::UnsignedAngle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
|
||||||
|
|
||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::UnsignedAngle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "Angle(4 5 6, 0 0 0)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "Angle(4 5 6, 0 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, Angle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
AngleOf<float> f = AngleOf<float>::Degrees(0);
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::UnsignedAngle(v1, v2);
|
||||||
r = isnan(f.InDegrees());
|
r = isnan(f.InDegrees());
|
||||||
EXPECT_TRUE(r) << "Angle(4 5 6, INFINITY INFINITY INFINITY)";
|
EXPECT_TRUE(r) << "Angle(4 5 6, INFINITY INFINITY INFINITY)";
|
||||||
|
|
||||||
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::UnsignedAngle(v1, v2);
|
||||||
r = isnan(f.InDegrees());
|
r = isnan(f.InDegrees());
|
||||||
EXPECT_TRUE(r) << "Angle(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
EXPECT_TRUE(r) << "Angle(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, SignedAngle) {
|
TYPED_TEST(Vector3Tests, SignedAngle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v3 = Vector3(7, 8, -9);
|
Vector3 v3 = Vector3(7, 8, -9);
|
||||||
@ -545,6 +760,17 @@ TEST(Vector3, SignedAngle) {
|
|||||||
v3 = Vector3(0, 0, 0);
|
v3 = Vector3(0, 0, 0);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5 6, 1 2 3, 0 0 0)";
|
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5 6, 1 2 3, 0 0 0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(Vector3FpTests, SignedAngle) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
|
Vector3 v3 = Vector3(7, 8, -9);
|
||||||
|
AngleOf<float> f = AngleOf<float>::Degrees(0);
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
@ -559,7 +785,11 @@ TEST(Vector3, SignedAngle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector3, Lerp) {
|
TYPED_TEST(Vector3Tests, Lerp) {
|
||||||
|
using T = TypeParam;
|
||||||
|
using Vector3 = Vector3Of<T>;
|
||||||
|
;
|
||||||
|
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 r = Vector3(0, 0, 0);
|
Vector3 r = Vector3(0, 0, 0);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user