diff --git a/inc/hgl/math/Math.h b/inc/hgl/math/Math.h index f664e93..bd501f4 100644 --- a/inc/hgl/math/Math.h +++ b/inc/hgl/math/Math.h @@ -2,9 +2,7 @@ #define HGL_ALGORITHM_MATH_INCLUDE #include -#include #include -#include // Game Math and Geometry Library -#include +#include #endif//HGL_ALGORITHM_MATH_INCLUDE diff --git a/inc/hgl/math/Matrix.h b/inc/hgl/math/Matrix.h index ecd5250..f21f457 100644 --- a/inc/hgl/math/Matrix.h +++ b/inc/hgl/math/Matrix.h @@ -18,7 +18,7 @@ namespace hgl #define DEFINE_MATRIX(num) using Matrix##num##f=glm::mat##num; \ constexpr const Matrix##num##f Identity##num##f=Matrix##num##f(1.0f); \ - inline bool IsIdentity(const Matrix##num##f &m){return(hgl_cmp(m,Identity##num##f)==0);} \ + inline bool IsIdentityMatrix(const Matrix##num##f &m){return(hgl_cmp(m,Identity##num##f)==0);} \ inline int FastMatrixComp(const Matrix##num##f &m1,const Matrix##num##f &m2){return hgl_cmp(m1,m2);} DEFINE_MATRIX(2) @@ -29,7 +29,7 @@ namespace hgl DEFINE_MATRIX(4x2) DEFINE_MATRIX(4x3) -#undef DEFINE_MATRIX +//#undef DEFINE_MATRIX inline Matrix4f inverse(const Matrix4f &m) { @@ -218,232 +218,7 @@ namespace hgl const Matrix4f GetRotateMatrix(const Vector3f &world_position,const Vector3f &old_direction,const Vector3f &new_direction); const Quatf GetRotateQuat(const Vector3f &world_position,const Vector3f &old_direction,const Vector3f &new_direction); - /** - * 带误差的比较两个浮点矩阵是否相等 - * @param m1 矩阵1 - * @param m2 矩阵2 - * @param deviation 允许的误差值 - */ - template - inline float DeviationMatrixComp(const M &m1,const M &m2,const float deviation=HGL_FLOAT_SMALL) - { - float *f1=(float *)&m1; - float *f2=(float *)&m2; - float gap; - - for(int i=0;i - * 便于分散管理平移、旋转、缩放等数值 - */ - class Transform - { - protected: - - Matrix4f matrix; - Matrix4f inverse_matrix; - Matrix4f transpose_inverse_matrix; - - bool matrix_dirty; - - Vector3f translation_vector; - - Quatf rotation_quat; - Vector3f rotation_axis; - float rotate_angle; - - Vector3f scale_vector; - - protected: - - void UpdateMatrix() - { - if(!matrix_dirty) - return; - - matrix=translate(translation_vector)*ToMatrix(rotation_quat)*scale(scale_vector); - inverse_matrix=inverse(matrix); - transpose_inverse_matrix=transpose(inverse_matrix); - - matrix_dirty=false; - } - - void UpdateQuat() - { - rotation_quat=RotationQuat(rotate_angle,rotation_axis); - matrix_dirty=true; - } - - public: - - const Matrix4f &GetMatrix() - { - UpdateMatrix(); - return matrix; - } - - operator const Matrix4f &(){return GetMatrix();} - - const Matrix4f &GetInverseMatrix() - { - UpdateMatrix(); - return inverse_matrix; - } - - const Vector3f &GetTranslation ()const{return translation_vector;} - const Vector3f &GetScale ()const{return scale_vector;} - - const Quatf & GetRotationQuat ()const{return rotation_quat;} - const Vector3f &GetRotationAxis ()const{return rotation_axis;} - const float GetRotateAngle ()const{return rotate_angle;} - - void SetTranslation(const float x,const float y,const float z) - { - translation_vector.x=x; - translation_vector.y=y; - translation_vector.z=z; - matrix_dirty=true; - } - - void SetTranslation(const Vector3f &v) - { - translation_vector=v; - matrix_dirty=true; - } - - void ClearRotation() - { - rotation_quat=IdentityQuatf; - rotation_axis=Vector3f(0,0,0); - rotate_angle=0; - matrix_dirty=true; - } - - void SetRotation(const Quatf &q) - { - rotation_quat=q; - ExtractedQuat(q,rotation_axis,rotate_angle); - matrix_dirty=true; - } - - void SetRotation(const Vector3f &axis,const float angle) - { - rotation_axis=axis; - rotate_angle=angle; - UpdateQuat(); - } - - void SetRotationAxis(const Vector3f &axis) - { - rotation_axis=axis; - UpdateQuat(); - } - - void SetRotation(const AXIS &axis,const float angle) - { - rotation_axis=GetAxisVector(axis); - rotate_angle=angle; - UpdateQuat(); - } - - void SetRotationAxis(const AXIS &axis) - { - rotation_axis=GetAxisVector(axis); - UpdateQuat(); - } - - void SetRotateAngle(float angle) - { - rotate_angle=angle; - UpdateQuat(); - } - - void SetScale(const float &v) - { - scale_vector=Vector3f(v,v,v); - matrix_dirty=true; - } - - void SetScale(const Vector3f &v) - { - scale_vector=v; - matrix_dirty=true; - } - - public: - - Transform() - { - matrix=Identity4f; - inverse_matrix=Identity4f; - - matrix_dirty=false; - - translation_vector=Vector3f(0,0,0); - rotation_quat=Quatf(1,0,0,0); - rotation_axis=Vector3f(0,0,0); - rotate_angle=0; - scale_vector=Vector3f(1,1,1); - } - - Transform(const Matrix4f &m) - { - SetFromMatrix4f(m); - } - - void SetFromMatrix4f(const Matrix4f &m) - { - matrix=m; - inverse_matrix=inverse(m); - - matrix_dirty=false; - - DecomposeTransform(m,translation_vector,rotation_quat,scale_vector); - - ExtractedQuat(rotation_quat,rotation_axis,rotate_angle); - } - - inline Vector3f TransformPosition(const Vector3f &v) - { - return Vector3f(matrix*Vector4f(v,1.0f)); - } - - inline Vector3f TransformDirection(const Vector3f &v) - { - return Vector3f(matrix*Vector4f(v,0.0f)); - } - - inline Vector3f TransformNormal(const Vector3f &v) - { - return normalize(Vector3f(transpose_inverse_matrix*Vector4f(v,0.0f))); - } - - inline Matrix3f TransformMatrix(const Matrix3f &child) - { - return Matrix3f(matrix*Matrix4f(child)); - } - - inline Matrix4f TransformMatrix(const Matrix4f &child) - { - return matrix*child; - } - };//Transform - - constexpr const size_t TransformMatrix4fLength=sizeof(Transform); - - Transform Blend(const Transform &from,const Transform &to,const float t); }//namespace hgl #endif//HGL_ALGORITHM_MATH_VECTOR_MATRIX_INCLUDE diff --git a/inc/hgl/math/Transform.h b/inc/hgl/math/Transform.h new file mode 100644 index 0000000..c12a96b --- /dev/null +++ b/inc/hgl/math/Transform.h @@ -0,0 +1,334 @@ +#pragma once +#include + +namespace hgl +{ + /** + * 变换矩阵
+ * 便于分散管理平移、旋转、缩放等数值 + */ + class Transform + { + protected: + + uint32 version; + + bool is_identity; + bool is_zero_rotate; + bool matrix_dirty; + + Matrix4f matrix; + Matrix4f inverse_matrix; + Matrix4f transpose_inverse_matrix; + + Vector3f translation_vector; + + Quatf rotation_quat; + Vector3f rotation_axis; + float rotate_angle; + + Vector3f scale_vector; + + protected: + + void UpdateQuat() + { + if(IsNearlyZero(rotate_angle)) + { + if(is_zero_rotate) + return; + + is_zero_rotate=true; + rotation_quat=IdentityQuatf; + return; + } + else + { + is_zero_rotate=false; + rotation_quat=RotationQuat(rotate_angle,rotation_axis); + } + + matrix_dirty=true; + } + + public: + + void UpdateMatrix() + { + if(!matrix_dirty) + return; + + if(translation_vector==ZeroVector3f + &&rotation_quat==IdentityQuatf + &&scale_vector==OneVector3f) + { + if(is_identity) //如果之前就是空的,那不更新版本号 + { + matrix_dirty=false; + return; + } + + SetToIdentity(); + } + else + { + matrix=translate(translation_vector)*ToMatrix(rotation_quat)*scale(scale_vector); + inverse_matrix=inverse(matrix); + transpose_inverse_matrix=transpose(inverse_matrix); + + is_identity=false; + } + + matrix_dirty=false; + + if(version>0xF0000000) + version=0; + else + ++version; + } + + const uint32 GetVersion() + { + UpdateMatrix(); + return version; + } + + const bool IsIdentity() + { + UpdateMatrix(); + return is_identity; + } + + const Matrix4f &GetMatrix() + { + UpdateMatrix(); + return matrix; + } + + const Matrix4f GetMatrix()const //不能执行UpdateMatrix时的获取 + { + if(matrix_dirty) + return translate(translation_vector)*ToMatrix(rotation_quat)*scale(scale_vector); + else + return matrix; + } + + operator const Matrix4f &(){return GetMatrix();} + + const Matrix4f &GetInverseMatrix() + { + UpdateMatrix(); + return inverse_matrix; + } + + const Vector3f &GetTranslation ()const{return translation_vector;} + const Vector3f &GetScale ()const{return scale_vector;} + + const Quatf & GetRotationQuat ()const{return rotation_quat;} + const Vector3f &GetRotationAxis ()const{return rotation_axis;} + const float GetRotateAngle ()const{return rotate_angle;} + + void SetTranslation(const float x,const float y,const float z) + { + translation_vector.x=x; + translation_vector.y=y; + translation_vector.z=z; + matrix_dirty=true; + } + + void SetTranslation(const Vector3f &v) + { + translation_vector=v; + matrix_dirty=true; + } + + void ClearRotation() + { + rotation_quat=IdentityQuatf; + rotation_axis=ZeroVector3f; + rotate_angle=0; + matrix_dirty=true; + } + + void SetRotation(const Quatf &q) + { + rotation_quat=q; + ExtractedQuat(q,rotation_axis,rotate_angle); + matrix_dirty=true; + } + + void SetRotation(const Vector3f &axis,const float angle) + { + rotation_axis=axis; + rotate_angle=angle; + UpdateQuat(); + } + + void SetRotation(const AXIS &axis,const float angle) + { + rotation_axis=GetAxisVector(axis); + rotate_angle=angle; + UpdateQuat(); + } + + void SetRotateAngle(float angle) + { + rotate_angle=angle; + UpdateQuat(); + } + + void SetScale(const float &v) + { + scale_vector=Vector3f(v,v,v); + matrix_dirty=true; + } + + void SetScale(const float x,const float y,const float z) + { + scale_vector.x=x; + scale_vector.y=y; + scale_vector.z=z; + + matrix_dirty=true; + } + + void SetScale(const Vector3f &v) + { + scale_vector=v; + matrix_dirty=true; + } + + public: + + Transform() + { + SetToIdentity(); + } + + Transform(const Matrix4f &m) + { + SetFromMatrix4f(m); + } + + Transform(const Transform &t) + { + hgl_cpy(*this,t); + } + + void SetToIdentity() + { + is_identity=true; + is_zero_rotate=true; + + matrix=Identity4f; + inverse_matrix=Identity4f; + + matrix_dirty=false; + + translation_vector=ZeroVector3f; + rotation_quat=IdentityQuatf; + rotation_axis=ZeroVector3f; + rotate_angle=0; + scale_vector=OneVector3f; + } + + const bool operator == (const Transform &t) + { + UpdateMatrix(); + + if(is_identity) + { + if(t.is_identity) + return(true); + else + return(false); + } + else + { + if(t.is_identity) + return(false); + } + + const Matrix4f tm=t.GetMatrix(); + + return matrix==tm; + } + + void operator = (const Transform &t) + { + hgl_cpy(*this,t); + + UpdateMatrix(); + } + + void SetFromMatrix4f(const Matrix4f &m) + { + is_identity=IsIdentityMatrix(m); + + if(is_identity) + { + SetToIdentity(); + return; + } + + matrix=m; + inverse_matrix=inverse(m); + + matrix_dirty=false; + + DecomposeTransform(m,translation_vector,rotation_quat,scale_vector); + + ExtractedQuat(rotation_quat,rotation_axis,rotate_angle); + } + + inline Vector3f TransformPosition(const Vector3f &v) + { + UpdateMatrix(); + return Vector3f(matrix*Vector4f(v,1.0f)); + } + + inline Vector3f TransformDirection(const Vector3f &v) + { + UpdateMatrix(); + return Vector3f(matrix*Vector4f(v,0.0f)); + } + + inline Vector3f TransformNormal(const Vector3f &v) + { + UpdateMatrix(); + return normalize(Vector3f(transpose_inverse_matrix*Vector4f(v,0.0f))); + } + + inline Matrix3f TransformMatrix(const Matrix3f &child) + { + UpdateMatrix(); + return Matrix3f(matrix*Matrix4f(child)); + } + + inline Matrix4f TransformMatrix(const Matrix4f &child) + { + UpdateMatrix(); + return matrix*child; + } + + inline Transform TransformTransform(const Transform &child) + { + UpdateMatrix(); + const Matrix4f &child_matrix=child.GetMatrix(); + + return Transform(matrix*child_matrix); + } + + inline Transform TransformTransform(const Transform &child)const + { + const Matrix4f &cur_matrix=GetMatrix(); + const Matrix4f &child_matrix=child.GetMatrix(); + + return Transform(cur_matrix*child_matrix); + } + };//Transform + + constexpr const size_t TransformMatrix4fLength=sizeof(Transform); + + Transform Lerp(const Transform &from,const Transform &to,const float t); +}//namespace hgl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f625404..a87dd1b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,6 +56,7 @@ SET(MATH_HEADER_FILES ${MATH_INCLUDE_PATH}/bvec.h ${MATH_INCLUDE_PATH}/Math.h ${MATH_INCLUDE_PATH}/MathConst.h ${MATH_INCLUDE_PATH}/Matrix.h + ${MATH_INCLUDE_PATH}/Transform.h ${MATH_INCLUDE_PATH}/Vector.h ${MATH_INCLUDE_PATH}/PrimaryMathematics.h ${MATH_INCLUDE_PATH}/PhysicsConst.h @@ -68,7 +69,8 @@ SET(MATH_HEADER_FILES ${MATH_INCLUDE_PATH}/bvec.h SET(MATH_SOURCE_FILES Math/LAtan.cpp Math/LSinCos.cpp Math/Matrix4f.cpp - Math/HalfFloat.cpp) + Math/HalfFloat.cpp + Math/Transform.cpp) SOURCE_GROUP("Math\\Header Files" FILES ${MATH_HEADER_FILES}) SOURCE_GROUP("Math\\Source Files" FILES ${MATH_SOURCE_FILES}) diff --git a/src/Math/Matrix4f.cpp b/src/Math/Matrix4f.cpp index 9952a72..0fce0a6 100644 --- a/src/Math/Matrix4f.cpp +++ b/src/Math/Matrix4f.cpp @@ -168,17 +168,6 @@ namespace hgl return true; } - Transform Blend(const Transform &from,const Transform &to,const float t) - { - Transform result; - - result.SetTranslation( from.GetTranslation()*(1.0f-t) + to.GetTranslation() *t); - result.SetRotation( SLerpQuat(from.GetRotationQuat(),to.GetRotationQuat(),t)); - result.SetScale( from.GetScale() *(1.0f-t) + to.GetScale() *t); - - return result; - } - /** * 计算一个方向旋转成另一个方向的变换矩阵 */ diff --git a/src/Math/Transform.cpp b/src/Math/Transform.cpp new file mode 100644 index 0000000..b11942b --- /dev/null +++ b/src/Math/Transform.cpp @@ -0,0 +1,15 @@ +#include + +namespace hgl +{ + Transform Lerp(const Transform &from,const Transform &to,const float t) + { + Transform result; + + result.SetTranslation( from.GetTranslation()*(1.0f-t) + to.GetTranslation() *t); + result.SetRotation( SLerpQuat(from.GetRotationQuat(),to.GetRotationQuat(),t)); + result.SetScale( from.GetScale() *(1.0f-t) + to.GetScale() *t); + + return result; + } +}//namespace hgl