diff --git a/include/bx/inline/math.inl b/include/bx/inline/math.inl index 1da6b2d..cbb77a2 100644 --- a/include/bx/inline/math.inl +++ b/include/bx/inline/math.inl @@ -286,9 +286,24 @@ namespace bx return _c - _a * _b; } + inline BX_CONSTEXPR_FUNC float add(float _a, float _b) + { + return _a + _b; + } + + inline BX_CONSTEXPR_FUNC float sub(float _a, float _b) + { + return _a - _b; + } + + inline BX_CONSTEXPR_FUNC float mul(float _a, float _b) + { + return _a * _b; + } + inline BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c) { - return _a * _b + _c; + return add(mul(_a, _b), _c); } inline BX_CONSTEXPR_FUNC float rcp(float _a) @@ -383,7 +398,7 @@ namespace bx template inline Ty load(const void* _ptr) { - Ty result; + Ty result(init::None); memCopy(&result, _ptr, sizeof(Ty) ); return result; } @@ -394,7 +409,21 @@ namespace bx memCopy(_ptr, &_a, sizeof(Ty) ); } - inline Vec3::Vec3() + inline Vec3::Vec3(init::NoneType) + { + } + + constexpr Vec3::Vec3(init::ZeroType) + : x(0.0f) + , y(0.0f) + , z(0.0f) + { + } + + constexpr Vec3::Vec3(init::IdentityType) + : x(0.0f) + , y(0.0f) + , z(0.0f) { } @@ -412,6 +441,57 @@ namespace bx { } + inline Plane::Plane(init::NoneType) + : normal(init::None) + { + } + + constexpr Plane::Plane(init::ZeroType) + : normal(init::Zero) + , dist(0.0f) + { + } + + constexpr Plane::Plane(init::IdentityType) + : normal(0.0f, 1.0f, 0.0f) + , dist(0.0f) + { + } + + constexpr Plane::Plane(Vec3 _normal, float _dist) + : normal(_normal) + , dist(_dist) + { + } + + inline Quaternion::Quaternion(init::NoneType) + { + } + + constexpr Quaternion::Quaternion(init::ZeroType) + : x(0.0f) + , y(0.0f) + , z(0.0f) + , w(0.0f) + { + } + + constexpr Quaternion::Quaternion(init::IdentityType) + : x(0.0f) + , y(0.0f) + , z(0.0f) + , w(1.0f) + { + } + + constexpr Quaternion::Quaternion(float _x, float _y, float _z, float _w) + : x(_x) + , y(_y) + , z(_z) + , w(_w) + { + } + inline BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a) { return @@ -650,7 +730,7 @@ namespace bx inline BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v) { - Vec3 result; + Vec3 result(init::None); const float phi = _u * kPi2; const float theta = _v * kPi; @@ -705,6 +785,39 @@ namespace bx }; } + inline BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b) + { + return + { + _a.x + _b.x, + _a.y + _b.y, + _a.z + _b.z, + _a.w + _b.w, + }; + } + + inline BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b) + { + return + { + _a.x - _b.x, + _a.y - _b.y, + _a.z - _b.z, + _a.w - _b.w, + }; + } + + inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b) + { + return + { + _a.x * _b, + _a.y * _b, + _a.z * _b, + _a.w * _b, + }; + } + inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b) { const float ax = _a.x; @@ -751,15 +864,9 @@ namespace bx const float norm = dot(_a, _a); if (0.0f < norm) { - const float invNorm = 1.0f / sqrt(norm); + const float invNorm = rsqrt(norm); - return - { - _a.x * invNorm, - _a.y * invNorm, - _a.z * invNorm, - _a.w * invNorm, - }; + return mul(_a, invNorm); } return @@ -771,6 +878,19 @@ namespace bx }; } + inline BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t) + { + const float sa = 1.0f - _t; + const float adotb = dot(_a, _b); + const float sb = sign(adotb) * _t; + + const Quaternion aa = mul(_a, sa); + const Quaternion bb = mul(_b, sb); + const Quaternion qq = add(aa, bb); + + return normalize(qq); + } + inline BX_CONST_FUNC Vec3 toEuler(const Quaternion _a) { const float xx = _a.x; @@ -872,8 +992,8 @@ namespace bx inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos) { - Vec3 tangent; - Vec3 bitangent; + Vec3 tangent(init::None); + Vec3 bitangent(init::None); calcTangentFrame(tangent, bitangent, _normal); store(&_result[ 0], mul(bitangent, _scale) ); @@ -891,8 +1011,8 @@ namespace bx inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos, float _angle) { - Vec3 tangent; - Vec3 bitangent; + Vec3 tangent(init::None); + Vec3 bitangent(init::None); calcTangentFrame(tangent, bitangent, _normal, _angle); store(&_result[0], mul(bitangent, _scale) ); @@ -969,7 +1089,7 @@ namespace bx inline Vec3 mul(const Vec3& _vec, const float* _mat) { - Vec3 result; + Vec3 result(init::None); result.x = _vec.x * _mat[0] + _vec.y * _mat[4] + _vec.z * _mat[ 8] + _mat[12]; result.y = _vec.x * _mat[1] + _vec.y * _mat[5] + _vec.z * _mat[ 9] + _mat[13]; result.z = _vec.x * _mat[2] + _vec.y * _mat[6] + _vec.z * _mat[10] + _mat[14]; @@ -978,7 +1098,7 @@ namespace bx inline Vec3 mulXyz0(const Vec3& _vec, const float* _mat) { - Vec3 result; + Vec3 result(init::None); result.x = _vec.x * _mat[0] + _vec.y * _mat[4] + _vec.z * _mat[ 8]; result.y = _vec.x * _mat[1] + _vec.y * _mat[5] + _vec.z * _mat[ 9]; result.z = _vec.x * _mat[2] + _vec.y * _mat[6] + _vec.z * _mat[10]; diff --git a/include/bx/math.h b/include/bx/math.h index bd05e84..f5f6248 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -50,11 +50,38 @@ namespace bx }; }; + /// Structure initializer types. + namespace init + { + /// Fields are left uninitialized. + /// + struct NoneType {}; + constexpr NoneType None; + + /// Fields are initialized to zero. + /// + struct ZeroType {}; + constexpr ZeroType Zero; + + /// Fields are initialized to identity value. + /// + struct IdentityType {}; + constexpr IdentityType Identity; + } + /// struct Vec3 { + Vec3() = delete; + /// - Vec3(); + Vec3(init::NoneType); + + /// + constexpr Vec3(init::ZeroType); + + /// + constexpr Vec3(init::IdentityType); /// explicit constexpr Vec3(float _v); @@ -68,6 +95,20 @@ namespace bx /// struct Plane { + Plane() = delete; + + /// + Plane(init::NoneType); + + /// + constexpr Plane(init::ZeroType); + + /// + constexpr Plane(init::IdentityType); + + /// + constexpr Plane(Vec3 _normal, float _dist); + Vec3 normal; float dist; }; @@ -75,6 +116,20 @@ namespace bx /// struct Quaternion { + Quaternion() = delete; + + /// + Quaternion(init::NoneType); + + /// + constexpr Quaternion(init::ZeroType); + + /// + constexpr Quaternion(init::IdentityType); + + /// + constexpr Quaternion(float _x, float _y, float _z, float _w); + float x, y, z, w; }; @@ -253,11 +308,24 @@ namespace bx /// BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c); - /// Returns result of multipla and add (_a * _b + _c). + /// Returns resul of addition (_a + _b). + /// + BX_CONSTEXPR_FUNC float add(float _a, float _b); + + /// Returns resul of subtracion (_a - _b). + /// + BX_CONSTEXPR_FUNC float sub(float _a, float _b); + + /// Returns result of multiply (_a * _b). + /// + BX_CONSTEXPR_FUNC float mul(float _a, float _b); + + /// Returns result of multiply and add (_a * _b + _c). /// BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c); /// Returns reciprocal of _a. + /// BX_CONSTEXPR_FUNC float rcp(float _a); /// Returns the floating-point remainder of the division operation _a/_b. @@ -376,6 +444,7 @@ namespace bx BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b); /// Returns component wise reciprocal of _a. + /// BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a); /// @@ -396,6 +465,15 @@ namespace bx /// BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b); + /// + BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b); + + /// + BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b); + + /// + BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b); + /// BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b); @@ -408,6 +486,9 @@ namespace bx /// BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a); + /// + BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t); + /// BX_CONST_FUNC Vec3 toEuler(const Quaternion _a); diff --git a/tests/math_test.cpp b/tests/math_test.cpp index d2a3642..fa3a00d 100644 --- a/tests/math_test.cpp +++ b/tests/math_test.cpp @@ -237,7 +237,7 @@ TEST_CASE("quaternion", "") float mtxQ[16]; float mtx[16]; - bx::Quaternion quat = { 0.0f, 0.0f, 0.0f, 1.0f }; + bx::Quaternion quat = bx::init::Identity; bx::mtxQuat(mtxQ, quat); bx::mtxIdentity(mtx); mtxCheck(mtxQ, mtx);