diff --git a/include/vsg/all.h b/include/vsg/all.h index 8b0c27e796..ecadb1994d 100644 --- a/include/vsg/all.h +++ b/include/vsg/all.h @@ -48,6 +48,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include diff --git a/include/vsg/maths/common.h b/include/vsg/maths/common.h index eb72b54740..2cf89c9ff3 100644 --- a/include/vsg/maths/common.h +++ b/include/vsg/maths/common.h @@ -23,16 +23,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI namespace vsg { - constexpr float PIf = 3.14159265358979323846f; - constexpr double PI = 3.14159265358979323846; + + constexpr float PIf = numbers::PI(); + constexpr double PI = numbers::PI(); /// convert degrees to radians - constexpr float radians(float degrees) noexcept { return degrees * (PIf / 180.0f); } - constexpr double radians(double degrees) noexcept { return degrees * (PI / 180.0); } + constexpr float radians(float degrees) noexcept { return degrees * numbers::degrees_to_radians(); } + constexpr double radians(double degrees) noexcept { return degrees * numbers::degrees_to_radians(); } /// convert radians to degrees - constexpr float degrees(float radians) noexcept { return radians * (180.0f / PIf); } - constexpr double degrees(double radians) noexcept { return radians * (180.0 / PI); } + constexpr float degrees(float radians) noexcept { return radians * numbers::radians_to_degrees(); } + constexpr double degrees(double radians) noexcept { return radians * numbers::radians_to_degrees(); } /// compute value^2 constexpr float square(float v) noexcept { return v * v; }; @@ -46,26 +47,26 @@ namespace vsg return edge0; else if (x >= edge1) return edge1; - double r = (x - edge0) / (edge1 - edge0); - return edge0 + (r * r * (3.0 - 2.0 * r)) * (edge1 - edge0); + T r = (x - edge0) / (edge1 - edge0); + return edge0 + (r * r * (numbers::three() - numbers::two() * r)) * (edge1 - edge0); } /// Hermite interpolation between 0.0 and 1.0 template T smoothstep(T r) { - if (r <= 0.0) - return 0.0; - else if (r >= 1.0) - return 1.0; - return r * r * (3.0 - 2.0 * r); + if (r <= numbers::zero()) + return numbers::zero(); + else if (r >= numbers::one()) + return numbers::one(); + return r * r * (numbers::three() - numbers::two() * r); } /// interpolate between two values template T mix(T start, T end, T r) { - T one_minus_r = 1.0 - r; + T one_minus_r = numbers::one() - r; return start * one_minus_r + end * r; } diff --git a/include/vsg/maths/mat2.h b/include/vsg/maths/mat2.h index 90de397d00..dd011a9781 100644 --- a/include/vsg/maths/mat2.h +++ b/include/vsg/maths/mat2.h @@ -28,12 +28,12 @@ namespace vsg column_type value[2]; constexpr t_mat2() : - value{{1, 0}, - {0, 1}} {} + value{{numbers::one(), numbers::zero()}, + {numbers::zero(), numbers::one()}} {} constexpr explicit t_mat2(value_type v) : - value{{v, 0}, - {0, v}} {} + value{{v, numbers::zero()}, + {numbers::zero(), v}} {} constexpr t_mat2(value_type v0, value_type v1, /* column 0 */ value_type v2, value_type v3) /* column 1 */ : diff --git a/include/vsg/maths/mat3.h b/include/vsg/maths/mat3.h index eadc63d983..95a9020513 100644 --- a/include/vsg/maths/mat3.h +++ b/include/vsg/maths/mat3.h @@ -28,14 +28,14 @@ namespace vsg column_type value[3]; constexpr t_mat3() : - value{{1, 0, 0}, - {0, 1, 0}, - {0, 0, 1}} {} + value{{numbers::one(), numbers::zero(), numbers::zero()}, + {numbers::zero(), numbers::one(), numbers::zero()}, + {numbers::zero(), numbers::zero(), numbers::one()}} {} constexpr explicit t_mat3(value_type v) : - value{{v, 0, 0}, - {0, v, 0}, - {0, 0, v}} {} + value{{v, numbers::zero(), numbers::zero()}, + {numbers::zero(), v, numbers::zero()}, + {numbers::zero(), numbers::zero(), v}} {} constexpr t_mat3(value_type v0, value_type v1, value_type v2, /* column 0 */ value_type v3, value_type v4, value_type v5, /* column 1 */ diff --git a/include/vsg/maths/mat4.h b/include/vsg/maths/mat4.h index ee8d9a870f..8174d094b2 100644 --- a/include/vsg/maths/mat4.h +++ b/include/vsg/maths/mat4.h @@ -30,16 +30,16 @@ namespace vsg column_type value[4]; constexpr t_mat4() : - value{{1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}} {} + value{{numbers::one(), numbers::zero(), numbers::zero(), numbers::zero()}, + {numbers::zero(), numbers::one(), numbers::zero(), numbers::zero()}, + {numbers::zero(), numbers::zero(), numbers::one(), numbers::zero()}, + {numbers::zero(), numbers::zero(), numbers::zero(), numbers::one()}} {} constexpr explicit t_mat4(value_type v) : - value{{v, 0, 0, 0}, - {0, v, 0, 0}, - {0, 0, v, 0}, - {0, 0, 0, v}} {} + value{{v, numbers::zero(), numbers::zero(), numbers::zero()}, + {numbers::zero(), v, numbers::zero(), numbers::zero()}, + {numbers::zero(), numbers::zero(), v, numbers::zero()}, + {numbers::zero(), numbers::zero(), numbers::zero(), v}} {} constexpr t_mat4(value_type v0, value_type v1, value_type v2, value_type v3, /* column 0 */ value_type v4, value_type v5, value_type v6, value_type v7, /* column 1 */ @@ -219,14 +219,14 @@ namespace vsg lhs[0] * rhs[1][0] + lhs[1] * rhs[1][1] + lhs[2] * rhs[1][2] + lhs[3] * rhs[1][3], lhs[0] * rhs[2][0] + lhs[1] * rhs[2][1] + lhs[2] * rhs[2][2] + lhs[3] * rhs[2][3], lhs[0] * rhs[3][0] + lhs[1] * rhs[3][1] + lhs[2] * rhs[3][2] + lhs[3] * rhs[3][3]); - T inv = static_cast(1.0) / length(transformed.n); + T inv = numbers::one() / length(transformed.n); return t_plane(transformed[0] * inv, transformed[1] * inv, transformed[2] * inv, transformed[3] * inv); } template t_vec3 operator*(const t_mat4& lhs, const t_vec3& rhs) { - T inv = static_cast(1.0) / (lhs[0][3] * rhs[0] + lhs[1][3] * rhs[1] + lhs[2][3] * rhs[2] + lhs[3][3]); + T inv = numbers::one() / (lhs[0][3] * rhs[0] + lhs[1][3] * rhs[1] + lhs[2][3] * rhs[2] + lhs[3][3]); return t_vec3((lhs[0][0] * rhs[0] + lhs[1][0] * rhs[1] + lhs[2][0] * rhs[2] + lhs[3][0]) * inv, (lhs[0][1] * rhs[0] + lhs[1][1] * rhs[1] + lhs[2][1] * rhs[2] + lhs[3][1]) * inv, (lhs[0][2] * rhs[0] + lhs[1][2] * rhs[1] + lhs[2][2] * rhs[2] + lhs[3][2]) * inv); @@ -235,7 +235,7 @@ namespace vsg template t_vec3 operator*(const t_vec3& lhs, const t_mat4& rhs) { - T inv = static_cast(1.0) / (lhs[0] * rhs[3][0] + lhs[1] * rhs[3][1] + lhs[2] * rhs[3][2] + rhs[3][3]); + T inv = numbers::one() / (lhs[0] * rhs[3][0] + lhs[1] * rhs[3][1] + lhs[2] * rhs[3][2] + rhs[3][3]); return t_vec3(lhs[0] * rhs[0][0] + lhs[1] * rhs[0][1] + lhs[2] * rhs[0][2] + rhs[0][3] * inv, lhs[0] * rhs[1][0] + lhs[1] * rhs[1][1] + lhs[2] * rhs[1][2] + rhs[1][3] * inv, lhs[0] * rhs[2][0] + lhs[1] * rhs[2][1] + lhs[2] * rhs[2][2] + rhs[2][3] * inv); diff --git a/include/vsg/maths/numbers.h b/include/vsg/maths/numbers.h new file mode 100644 index 0000000000..f1da50a8c6 --- /dev/null +++ b/include/vsg/maths/numbers.h @@ -0,0 +1,37 @@ +#pragma once + +/* + +Copyright(c) 2018 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include + +namespace vsg +{ + template + struct numbers + { + static constexpr T zero() { return static_cast(0.0); } + static constexpr T half() { return static_cast(0.5); } + static constexpr T one() { return static_cast(1.0); } + static constexpr T two() { return static_cast(2.0); } + static constexpr T three() { return static_cast(3.0); } + + static constexpr T minus_one() { return static_cast(-1.0); } + + static constexpr T epsilon() { return std::numeric_limits::epsilon(); } + + static constexpr T PI() { return static_cast(3.14159265358979323846); } + static constexpr T degrees_to_radians() { return PI() / static_cast(180.0); } + static constexpr T radians_to_degrees() { return static_cast(180.0) / PI(); } + }; + +} // namespace vsg diff --git a/include/vsg/maths/plane.h b/include/vsg/maths/plane.h index 89456a0b3d..1130ea928a 100644 --- a/include/vsg/maths/plane.h +++ b/include/vsg/maths/plane.h @@ -50,7 +50,7 @@ namespace vsg }; constexpr t_plane() : - value{0.0, 0.0, 0.0, 0.0} {} + value{numbers::zero(), numbers::zero(), numbers::zero(), numbers::zero()} {} constexpr t_plane(const t_plane& pl) : value{pl[0], pl[1], pl[2], pl[3]} {} @@ -100,7 +100,7 @@ namespace vsg value[3] = in_d; } - bool valid() const { return n.x != 0.0 && n.y != 0.0 && n.z != 0.0; } + bool valid() const { return n.x != numbers::zero() && n.y != numbers::zero() && n.z != numbers::zero(); } explicit operator bool() const noexcept { return valid(); } diff --git a/include/vsg/maths/quat.h b/include/vsg/maths/quat.h index 726097b3d2..a4a3aad531 100644 --- a/include/vsg/maths/quat.h +++ b/include/vsg/maths/quat.h @@ -45,7 +45,7 @@ namespace vsg }; constexpr t_quat() : - value{0.0, 0.0, 0.0, 1.0} {} + value{numbers::zero(), numbers::zero(), numbers::zero(), numbers::one()} {} constexpr t_quat(const t_quat& v) : value{v.x, v.y, v.z, v.w} {} constexpr t_quat(value_type in_x, value_type in_y, value_type in_z, value_type in_w) : @@ -93,18 +93,17 @@ namespace vsg void set(value_type angle_radians, const t_vec3& axis) { - const value_type epsilon = 1e-7; value_type len = length(axis); - if (len < epsilon) + if (len < numbers::epsilon()) { // ~zero length axis, so reset rotation to zero. *this = {}; return; } - value_type inversenorm = 1.0 / len; - value_type coshalfangle = cos(0.5 * angle_radians); - value_type sinhalfangle = sin(0.5 * angle_radians); + value_type inversenorm = numbers::one() / len; + value_type coshalfangle = cos(numbers::half() * angle_radians); + value_type sinhalfangle = sin(numbers::half() * angle_radians); x = axis.x * sinhalfangle * inversenorm; y = axis.y * sinhalfangle * inversenorm; @@ -114,12 +113,10 @@ namespace vsg void set(const t_vec3& from, const t_vec3& to) { - const value_type epsilon = 1e-7; - value_type dot_pd = vsg::dot(from, to); value_type div = std::sqrt(length2(from) * length2(to)); vsg::dvec3 axis; - if (div - std::abs(dot_pd) < epsilon) + if (div - std::abs(dot_pd) < numbers::epsilon()) { axis = orthogonal(from); } @@ -132,9 +129,9 @@ namespace vsg double angle_radians = acos(dot_pd / div); - value_type inversenorm = 1.0 / len; - value_type coshalfangle = cos(0.5 * angle_radians); - value_type sinhalfangle = sin(0.5 * angle_radians); + value_type inversenorm = numbers::one() / len; + value_type coshalfangle = cos(numbers::half() * angle_radians); + value_type sinhalfangle = sin(numbers::half() * angle_radians); x = axis.x * sinhalfangle * inversenorm; y = axis.y * sinhalfangle * inversenorm; @@ -142,7 +139,7 @@ namespace vsg w = coshalfangle; } - explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; } + explicit operator bool() const noexcept { return value[0] != numbers::zero() || value[1] != numbers::zero() || value[2] != numbers::zero() || value[3] != numbers::zero(); } }; using quat = t_quat; /// float quaternion @@ -222,9 +219,8 @@ namespace vsg t_vec3 qvec(q[0], q[1], q[2]); uv = cross(qvec, v); uuv = cross(qvec, uv); - T two(2.0); - uv *= (two * q[3]); - uuv *= two; + uv *= (numbers::two() * q[3]); + uuv *= numbers::two(); return v + uv + uuv; } @@ -237,7 +233,7 @@ namespace vsg template constexpr t_quat operator/(const t_quat& lhs, T rhs) { - T inv = static_cast(1.0) / rhs; + T inv = numbers::one() / rhs; return t_quat(lhs[0] * inv, lhs[1] * inv, lhs[2] * inv, lhs[3] * inv); } @@ -250,7 +246,7 @@ namespace vsg template constexpr t_quat normalize(const t_quat& v) { - T inverse_len = static_cast(1.0) / length(v); + T inverse_len = numbers::one() / length(v); return t_quat(v[0] * inverse_len, v[1] * inverse_len, v[2] * inverse_len, v[3] * inverse_len); } @@ -264,18 +260,15 @@ namespace vsg constexpr t_quat inverse(const t_quat& v) { t_quat c = conjugate(v); - T inverse_len = static_cast(1.0) / length(v); + T inverse_len = numbers::one() / length(v); return t_quat(c[0] * inverse_len, c[1] * inverse_len, c[2] * inverse_len, c[3] * inverse_len); } template constexpr t_quat mix(const t_quat& from, t_quat to, T r) { - T epsilon = std::numeric_limits::epsilon(); - T one(1.0); - T cosomega = dot(from, to); - if (cosomega < 0.0) + if (cosomega < numbers::zero()) { cosomega = -cosomega; to.x = -to.x; @@ -284,18 +277,18 @@ namespace vsg to.w = -to.w; } - if ((one - cosomega) > epsilon) + if ((numbers::one() - cosomega) > numbers::epsilon()) { T omega = acos(cosomega); T sinomega = sin(omega); - T scale_from = sin((one - r) * omega) / sinomega; + T scale_from = sin((numbers::one() - r) * omega) / sinomega; T scale_to = sin(r * omega) / sinomega; return (from * scale_from) + (to * scale_to); } else { // quaternions are very close so just linearly interpolate - return (from * (one - r)) + (to * r); + return (from * (numbers::one() - r)) + (to * r); } } diff --git a/include/vsg/maths/sphere.h b/include/vsg/maths/sphere.h index 587972d6b5..7de13c45c3 100644 --- a/include/vsg/maths/sphere.h +++ b/include/vsg/maths/sphere.h @@ -55,7 +55,7 @@ namespace vsg }; constexpr t_sphere() : - value{0.0, 0.0, 0.0, -1.0} {} + value{numbers::zero(), numbers::zero(), numbers::zero(), numbers::minus_one()} {} constexpr t_sphere(const t_sphere& s) : value{s[0], s[1], s[2], s[3]} {} @@ -106,7 +106,7 @@ namespace vsg r = rad; } - bool valid() const { return radius >= 0.0; } + bool valid() const { return radius >= numbers::zero(); } explicit operator bool() const noexcept { return valid(); } @@ -115,8 +115,8 @@ namespace vsg void reset() { - center.set(0.0, 0.0, 0.0); - radius = -1.0; + center.set(numbers::zero(), numbers::zero(), numbers::zero()); + radius = numbers::minus_one(); } }; diff --git a/include/vsg/maths/transform.h b/include/vsg/maths/transform.h index a07b1a131c..e01111a199 100644 --- a/include/vsg/maths/transform.h +++ b/include/vsg/maths/transform.h @@ -30,27 +30,29 @@ namespace vsg T qwy(q.w * q.y); T qwz(q.w * q.z); - T zero(0.0); - T one(1.0); - T two(2.0); + const T zero(numbers::zero()); + const T one(numbers::one()); + const T two(numbers::two()); return t_mat4(one - two * (qyy + qzz), two * (qxy + qwz), two * (qxz - qwy), zero, two * (qxy - qwz), one - two * (qxx + qzz), two * (qyz + qwx), zero, two * (qxz + qwy), two * (qyz - qwx), one - two * (qxx + qyy), zero, - zero, zero, zero, 1.0); + zero, zero, zero, one); } /// create a 4x4 matrix that represents the rotation by a radian angle around an x, y, z axis template t_mat4 rotate(T angle_radians, T x, T y, T z) { + const T zero(numbers::zero()); + const T one(numbers::one()); const T c = std::cos(angle_radians); const T s = std::sin(angle_radians); - const T one_minus_c = 1 - c; - return t_mat4(x * x * one_minus_c + c, y * x * one_minus_c + z * s, x * z * one_minus_c - y * s, 0, - x * y * one_minus_c - z * s, y * y * one_minus_c + c, y * z * one_minus_c + x * s, 0, - x * z * one_minus_c + y * s, y * z * one_minus_c - x * s, z * z * one_minus_c + c, 0, - 0, 0, 0, 1); + const T one_minus_c = one - c; + return t_mat4(x * x * one_minus_c + c, y * x * one_minus_c + z * s, x * z * one_minus_c - y * s, zero, + x * y * one_minus_c - z * s, y * y * one_minus_c + c, y * z * one_minus_c + x * s, zero, + x * z * one_minus_c + y * s, y * z * one_minus_c - x * s, z * z * one_minus_c + c, zero, + zero, zero, zero, one); } /// create a 4x4 matrix that represents the rotation by a radian angle around a vec3 axis @@ -64,10 +66,12 @@ namespace vsg template constexpr t_mat4 translate(T x, T y, T z) { - return t_mat4(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - x, y, z, 1); + const T zero(numbers::zero()); + const T one(numbers::one()); + return t_mat4(one, zero, zero, zero, + zero, one, zero, zero, + zero, zero, one, zero, + x, y, z, one); } /// create a 4x4 matrix that represents the translation by vec3 @@ -81,20 +85,24 @@ namespace vsg template constexpr t_mat4 scale(T s) { - return t_mat4(s, 0, 0, 0, - 0, s, 0, 0, - 0, 0, s, 0, - 0, 0, 0, 1); + const T zero(numbers::zero()); + const T one(numbers::one()); + return t_mat4(s, zero, zero, zero, + zero, s, zero, zero, + zero, zero, s, zero, + zero, zero, zero, one); } /// create a 4x4 matrix that represents the scale by sx, sy, zz template constexpr t_mat4 scale(T sx, T sy, T sz) { - return t_mat4(sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, 0, 1); + const T zero(numbers::zero()); + const T one(numbers::one()); + return t_mat4(sx, zero, zero, zero, + zero, sy, zero, zero, + zero, zero, sz, zero, + zero, zero, zero, one); } /// create a 4x4 matrix that represents the scale by vec3 @@ -131,32 +139,40 @@ namespace vsg template constexpr t_mat4 perspective(T fovy_radians, T aspectRatio, T zNear, T zFar) { - T f = static_cast(1.0 / std::tan(fovy_radians * 0.5)); - T r = static_cast(1.0 / (zFar - zNear)); - return t_mat4(f / aspectRatio, 0, 0, 0, - 0, -f, 0, 0, - 0, 0, zNear * r, -1, - 0, 0, (zFar * zNear) * r, 0); + const T zero(numbers::zero()); + const T one(numbers::one()); + T f = static_cast(one / std::tan(fovy_radians * numbers::half())); + T r = static_cast(one / (zFar - zNear)); + return t_mat4(f / aspectRatio, zero, zero, zero, + zero, -f, zero, zero, + zero, zero, zNear * r, -one, + zero, zero, (zFar * zNear) * r, zero); } /// create a 4x4 matrix for a Reverse depth perspective matrix, convention: 1 to 0 depth range. Y NDC coordinates are inverted in Vulkan. template constexpr t_mat4 perspective(T left, T right, T bottom, T top, T zNear, T zFar) { - return t_mat4(2.0 * zNear / (right - left), 0.0, 0.0, 0.0, - 0.0, 2.0 * zNear / (bottom - top), 0.0, 0.0, - (right + left) / (right - left), (bottom + top) / (bottom - top), zNear / (zFar - zNear), -1.0, - 0.0, 0.0, zNear * zFar / (zFar - zNear), 0.0); + const T zero(numbers::zero()); + const T one(numbers::one()); + const T two(numbers::two()); + return t_mat4(two * zNear / (right - left), zero, zero, zero, + zero, two * zNear / (bottom - top), zero, zero, + (right + left) / (right - left), (bottom + top) / (bottom - top), zNear / (zFar - zNear), -one, + zero, zero, zNear * zFar / (zFar - zNear), zero); } /// create a 4x4 matrix for an orthographic projection, from vulkan cookbook with reverse depth template constexpr t_mat4 orthographic(T left, T right, T bottom, T top, T zNear, T zFar) { - return t_mat4(2.0 / (right - left), 0.0, 0.0, 0.0, - 0.0, 2.0 / (bottom - top), 0.0, 0.0, - 0.0, 0.0, 1.0 / (zFar - zNear), 0.0, - -(right + left) / (right - left), -(bottom + top) / (bottom - top), zFar / (zFar - zNear), 1.0); + const T zero(numbers::zero()); + const T one(numbers::one()); + const T two(numbers::two()); + return t_mat4(two / (right - left), zero, zero, zero, + zero, two / (bottom - top), zero, zero, + zero, zero, one / (zFar - zNear), zero, + -(right + left) / (right - left), -(bottom + top) / (bottom - top), zFar / (zFar - zNear), one); } template @@ -164,33 +180,38 @@ namespace vsg { using vec_type = t_vec3; + const T zero(numbers::zero()); + const T one(numbers::one()); + vec_type forward = normalize(center - eye); vec_type up_normal = normalize(up); vec_type side = normalize(cross(forward, up_normal)); vec_type u = normalize(cross(side, forward)); - return t_mat4(side[0], u[0], -forward[0], 0, - side[1], u[1], -forward[1], 0, - side[2], u[2], -forward[2], 0, - 0, 0, 0, 1) * + return t_mat4(side[0], u[0], -forward[0], zero, + side[1], u[1], -forward[1], zero, + side[2], u[2], -forward[2], zero, + zero, zero, zero, one) * vsg::translate(-eye.x, -eye.y, -eye.z); } template constexpr t_mat4 computeBillboardMatrix(const t_vec3& centerEye, T autoscaleDistance) { - auto distance = -centerEye.z; + const T zero(numbers::zero()); + const T one(numbers::one()); - auto scale = (distance < autoscaleDistance) ? distance / autoscaleDistance : 1.0; - t_mat4 mS(scale, 0.0, 0.0, 0.0, - 0.0, scale, 0.0, 0.0, - 0.0, 0.0, scale, 0.0, - 0.0, 0.0, 0.0, 1.0); - - t_mat4 mT(1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - centerEye.x, centerEye.y, centerEye.z, 1.0); + auto distance = -centerEye.z; + auto scale = (distance < autoscaleDistance) ? distance / autoscaleDistance : one; + t_mat4 mS(scale, zero, zero, zero, + zero, scale, zero, zero, + zero, zero, scale, zero, + zero, zero, zero, one); + + t_mat4 mT(one, zero, zero, zero, + zero, one, zero, zero, + zero, zero, one, zero, + centerEye.x, centerEye.y, centerEye.z, one); return mT * mS; } diff --git a/include/vsg/maths/vec2.h b/include/vsg/maths/vec2.h index 899ed2bd41..de514bdf3c 100644 --- a/include/vsg/maths/vec2.h +++ b/include/vsg/maths/vec2.h @@ -24,6 +24,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #endif #include +#include #include #include @@ -121,7 +122,7 @@ namespace vsg { if constexpr (std::is_floating_point_v) { - value_type inv = static_cast(1.0) / rhs; + value_type inv = numbers::one() / rhs; value[0] *= inv; value[1] *= inv; } @@ -133,7 +134,7 @@ namespace vsg return *this; } - explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0; } + explicit operator bool() const noexcept { return value[0] != numbers::zero() || value[1] != numbers::zero(); } }; using vec2 = t_vec2; // float 2D vector @@ -210,7 +211,7 @@ namespace vsg { if constexpr (std::is_floating_point_v) { - T inv = static_cast(1.0) / rhs; + T inv = numbers::one() / rhs; return t_vec2(lhs[0] * inv, lhs[1] * inv); } else @@ -254,7 +255,7 @@ namespace vsg template constexpr t_vec2 mix(const t_vec2& start, const t_vec2& end, T r) { - T one_minus_r = 1 - r; + T one_minus_r = numbers::one() - r; return t_vec2(start[0] * one_minus_r + end[0] * r, start[1] * one_minus_r + end[1] * r); } diff --git a/include/vsg/maths/vec3.h b/include/vsg/maths/vec3.h index 27d27a7ef9..c3c779cc56 100644 --- a/include/vsg/maths/vec3.h +++ b/include/vsg/maths/vec3.h @@ -52,7 +52,7 @@ namespace vsg }; constexpr t_vec3() : - value{0, 0, 0} {} + value{} {} constexpr t_vec3(const t_vec3& v) : value{v.x, v.y, v.z} {} constexpr t_vec3& operator=(const t_vec3&) = default; @@ -127,7 +127,7 @@ namespace vsg { if constexpr (std::is_floating_point_v) { - value_type inv = static_cast(1.0) / rhs; + value_type inv = numbers::one() / rhs; value[0] *= inv; value[1] *= inv; value[2] *= inv; @@ -141,7 +141,7 @@ namespace vsg return *this; } - explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0; } + explicit operator bool() const noexcept { return value[0] != numbers::zero() || value[1] != numbers::zero() || value[2] != numbers::zero(); } }; using vec3 = t_vec3; // float 3D vector @@ -221,7 +221,7 @@ namespace vsg { if constexpr (std::is_floating_point_v) { - T inv = static_cast(1.0) / rhs; + T inv = numbers::one() / rhs; return t_vec3(lhs[0] * inv, lhs[1] * inv, lhs[2] * inv); } else @@ -265,7 +265,7 @@ namespace vsg template constexpr t_vec3 mix(const t_vec3& start, const t_vec3& end, T r) { - T one_minus_r = 1 - r; + T one_minus_r = numbers::one() - r; return t_vec3(start[0] * one_minus_r + end[0] * r, start[1] * one_minus_r + end[1] * r, start[2] * one_minus_r + end[2] * r); @@ -280,13 +280,13 @@ namespace vsg auto abs_z = fabs(v.z); if (abs_x < abs_y) { - if (abs_x < abs_z) return {0.0, v.z, -v.y}; // v.x shortest, use cross with x axis + if (abs_x < abs_z) return {numbers::zero(), v.z, -v.y}; // v.x shortest, use cross with x axis } else if (abs_y < abs_z) { - return {-v.z, 0.0, v.x}; // v.y shortest, use cross with y axis + return {-v.z, numbers::zero(), v.x}; // v.y shortest, use cross with y axis } - return {v.y, -v.x, 0.0}; // v.z shortest, use cross with z axis + return {v.y, -v.x, numbers::zero()}; // v.z shortest, use cross with z axis } } // namespace vsg diff --git a/include/vsg/maths/vec4.h b/include/vsg/maths/vec4.h index 4ed3eb08cd..13a15906ed 100644 --- a/include/vsg/maths/vec4.h +++ b/include/vsg/maths/vec4.h @@ -153,7 +153,7 @@ namespace vsg { if constexpr (std::is_floating_point_v) { - value_type inv = static_cast(1.0) / rhs; + value_type inv = numbers::one() / rhs; value[0] *= inv; value[1] *= inv; value[2] *= inv; @@ -171,7 +171,7 @@ namespace vsg operator VkClearColorValue() const noexcept { return VkClearColorValue{{r, g, b, a}}; } - explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; } + explicit operator bool() const noexcept { return value[0] != numbers::zero() || value[1] != numbers::zero() || value[2] != numbers::zero() || value[3] != numbers::zero(); } }; using vec4 = t_vec4; // float 4D vector @@ -253,7 +253,7 @@ namespace vsg { if constexpr (std::is_floating_point_v) { - T inv = static_cast(1.0) / rhs; + T inv = numbers::one() / rhs; return t_vec4(lhs[0] * inv, lhs[1] * inv, lhs[2] * inv, lhs[3] * inv); } else @@ -283,7 +283,7 @@ namespace vsg template constexpr t_vec4 mix(const t_vec4& start, const t_vec4& end, T r) { - T one_minus_r = 1 - r; + T one_minus_r = numbers::one() - r; return t_vec4(start[0] * one_minus_r + end[0] * r, start[1] * one_minus_r + end[1] * r, start[2] * one_minus_r + end[2] * r,