diff --git a/inc/hgl/math/MathConst.h b/inc/hgl/math/MathConst.h index 60cf3ee..53d2b4b 100644 --- a/inc/hgl/math/MathConst.h +++ b/inc/hgl/math/MathConst.h @@ -2,24 +2,24 @@ #define HGL_MATH_CONST_INCLUDE #include +#include namespace hgl { constexpr const float HGL_FLOAT_MIN =1.175494351e-38f; ///<最小浮点数 constexpr const float HGL_FLOAT_MAX =3.402823466e+38f; ///<最大浮点数 - constexpr const float HGL_FLOAT_EPSILON =1.192092896e-07f; ///<浮点数精度 - constexpr const float HGL_FLOAT_ZERO =0.000001f; ///<浮点数零值 - constexpr const float HGL_FLOAT_SMALL =1.e-6f; ///<浮点数小值 + constexpr const float HGL_FLOAT_EPSILON =std::numeric_limits::epsilon(); ///<浮点数精度最小值 + constexpr const double HGL_DOUBLE_EPSILON =std::numeric_limits::epsilon(); ///<双精度浮点数精度最小值 - template bool IsNearlyZero(const T value) - { - return(abs(value)<=HGL_FLOAT_SMALL); - } + template bool IsNearlyZero(const T value); - template bool IsNearlyEqual(const T a,const T b) - { - return(abs(a-b)<=HGL_FLOAT_SMALL); - } + template<> inline bool IsNearlyZero(const float value){return(fabsf(value) <= HGL_FLOAT_EPSILON);} + template<> inline bool IsNearlyZero(const double value){return(fabs(value) <= HGL_DOUBLE_EPSILON);} + + template bool IsNearlyEqual(const T a,const T b); + + template<> inline bool IsNearlyEqual(const float a,const float b){return(fabsf(a - b) <= HGL_FLOAT_EPSILON);} + template<> inline bool IsNearlyEqual(const double a,const double b){return(fabs(a - b) <= HGL_DOUBLE_EPSILON); } constexpr const double HGL_E =2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274; //欧拉数(自然对数的底数) constexpr const double HGL_LOG2E =1.44269504088896340736; diff --git a/inc/hgl/math/Matrix.h b/inc/hgl/math/Matrix.h index 15cf168..9b41199 100644 --- a/inc/hgl/math/Matrix.h +++ b/inc/hgl/math/Matrix.h @@ -32,6 +32,11 @@ namespace hgl //#undef DEFINE_MATRIX + inline const bool IsNearlyEqual(const Quatf &q1,const Quatf &q2) + { + return glm::all(glm::epsilonEqual(q1,q2,glm::epsilon())); + } + inline Matrix4f inverse(const Matrix4f &m) { return glm::inverse(m); diff --git a/inc/hgl/math/Transform.h b/inc/hgl/math/Transform.h index d00fa62..4ccb25b 100644 --- a/inc/hgl/math/Transform.h +++ b/inc/hgl/math/Transform.h @@ -122,7 +122,7 @@ namespace hgl const Quatf &GetQuat()const { return quat; } void SetQuat(const Quatf &q) { - if (IsNearlyEqual(quat,q)) + if(IsNearlyEqual(quat,q)) return; quat=q; diff --git a/inc/hgl/math/Vector.h b/inc/hgl/math/Vector.h index a2a3bf0..766a01e 100644 --- a/inc/hgl/math/Vector.h +++ b/inc/hgl/math/Vector.h @@ -7,6 +7,8 @@ #include #include +#include +#include namespace hgl { @@ -261,19 +263,52 @@ namespace hgl return from + (to - from) * alpha; } - inline bool is_nearly_equal(const float v1,const float v2,const float deviation=HGL_FLOAT_SMALL) + inline bool IsNearlyEqual(const float v1,const float v2,const float epsilon=HGL_FLOAT_EPSILON) { - return fabsf(v1-v2)<=deviation; + return glm::epsilonEqual(v1,v2,epsilon); } - inline bool is_nearly_equal(const Vector2f &v1,const Vector2f &v2,const float deviation=HGL_FLOAT_SMALL) + inline bool IsNearlyEqual(const Vector2f &v1,const Vector2f &v2,const float epsilon=HGL_FLOAT_EPSILON) { - return length_squared_2d(v1,v2)<=deviation; + glm::bvec2 result=glm::epsilonEqual(v1,v2,epsilon); + + return result.x && result.y; } - inline bool is_nearly_equal(const Vector3f &v1,const Vector3f &v2,const float deviation=HGL_FLOAT_SMALL) + inline bool IsNearlyEqual(const Vector2d &v1,const Vector2d &v2,const double epsilon=HGL_DOUBLE_EPSILON) { - return length_squared(v1,v2)<=deviation; + glm::bvec2 result=glm::epsilonEqual(v1,v2,epsilon); + + return result.x && result.y; + } + + inline bool IsNearlyEqual(const Vector3f &v1,const Vector3f &v2,const float epsilon=HGL_FLOAT_EPSILON) + { + glm::bvec3 result=glm::epsilonEqual(v1,v2,epsilon); + + return result.x && result.y && result.z; + } + + inline bool IsNearlyEqual(const Vector3d &v1,const Vector3d &v2,const double epsilon=HGL_DOUBLE_EPSILON) + { + glm::bvec3 result=glm::epsilonEqual(v1,v2,epsilon); + + return result.x && result.y && result.z; + } + + template + inline const bool IsNearlyZero(const glm::vec<2,T,Q> &v) + { + return IsNearlyZero(v.x) + &&IsNearlyZero(v.y); + } + + template + inline const bool IsNearlyZero(const glm::vec<3,T,Q> &v) + { + return IsNearlyZero(v.x) + &&IsNearlyZero(v.y) + &&IsNearlyZero(v.z); } /** @@ -384,36 +419,6 @@ namespace hgl hgl_max(v1.w,v2.w)); } - template - inline const bool IsNearlyZero(const glm::vec<2,T,Q> &v) - { - return IsNearlyZero(v.x) - &&IsNearlyZero(v.y); - } - - template - inline const bool IsNearlyZero(const glm::vec<3,T,Q> &v) - { - return IsNearlyZero(v.x) - &&IsNearlyZero(v.y) - &&IsNearlyZero(v.z); - } - - template - inline const bool IsNearlyEqual(const glm::vec<2,T,Q> &a,const glm::vec<2,T,Q> &b) - { - return IsNearlyEqual(a.x,b.x) - &&IsNearlyEqual(a.y,b.y); - } - - template - inline const bool IsNearlyEqual(const glm::vec<3,T,Q> &a,const glm::vec<3,T,Q> &b) - { - return IsNearlyEqual(a.x,b.x) - &&IsNearlyEqual(a.y,b.y) - &&IsNearlyEqual(a.z,b.z); - } - inline const Vector3f LerpDirection(const Vector3f &old_direction,const Vector3f &new_direction,const float alpha) { return glm::normalize(old_direction*(1.0f-alpha)+new_direction*alpha);