From 3ead8d3d3447b31dcfb000781260f7875ec8d78f Mon Sep 17 00:00:00 2001 From: hyzboy Date: Mon, 26 Aug 2024 23:01:22 +0800 Subject: [PATCH] revert Transform class --- inc/hgl/math/Transform.h | 299 +++++++++++++++++++++++++++++++++++++++ src/Math/Transform.cpp | 126 +++++++++++++++++ 2 files changed, 425 insertions(+) diff --git a/inc/hgl/math/Transform.h b/inc/hgl/math/Transform.h index 32a9d57..d54e074 100644 --- a/inc/hgl/math/Transform.h +++ b/inc/hgl/math/Transform.h @@ -593,4 +593,303 @@ namespace hgl UpdateVersion(); } };//class TransformManager + + + /** + * 变换矩阵
+ * 便于分散管理平移、旋转、缩放等数值 + */ + class Transform + { + uint32 version; ///<版本号(注:用于记录任何变化,而不是matrix) + + void UpdateVersion() + { + if(version>=0x70000000) + version=0; + else + ++version; + } + + protected: + + bool is_identity; + bool is_zero_rotate; + bool matrix_dirty; + + //matrix其实用的少,所以在不取matrix时,并不会计算。 + 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(); + + public: + + void UpdateMatrix(); + + 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();} + operator const Transform & (){UpdateMatrix();return *this;} + + 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) + { + if(is_identity) + { + if(IsNearlyZero(x) + &&IsNearlyZero(y) + &&IsNearlyZero(z)) + return; + } + + is_identity=false; + + translation_vector.x=x; + translation_vector.y=y; + translation_vector.z=z; + matrix_dirty=true; + } + + void SetTranslation(const Vector3f &v) + { + if(is_identity) + { + if(IsNearlyZero(v.x) + &&IsNearlyZero(v.y) + &&IsNearlyZero(v.z)) + return; + } + + is_identity=false; + + 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) + { + if(is_identity) + { + if(q==IdentityQuatf) + return; + } + + is_identity=false; + + rotation_quat=q; + ExtractedQuat(q,rotation_axis,rotate_angle); + matrix_dirty=true; + } + + void SetRotation(const Vector3f &axis,const float angle) + { + if(is_identity) + { + if(IsNearlyZero(angle)==0) + return; + } + + is_identity=false; + + rotation_axis=axis; + rotate_angle=angle; + UpdateQuat(); + } + + void SetRotation(const AXIS &axis,const float angle) + { + if(is_identity) + { + if(IsNearlyZero(angle)==0) + return; + } + + is_identity=false; + + rotation_axis=GetAxisVector(axis); + rotate_angle=angle; + UpdateQuat(); + } + + void SetRotateAngle(float angle) + { + if(is_identity) + { + if(IsNearlyZero(angle)==0) + return; + } + + is_identity=false; + + rotate_angle=angle; + UpdateQuat(); + } + + void SetScale(const float &v) + { + if(is_identity) + { + if(IsNearlyEqual(v,1.0f)) + return; + } + is_identity=false; + + scale_vector=Vector3f(v,v,v); + matrix_dirty=true; + } + + void SetScale(const float x,const float y,const float z) + { + if(is_identity) + { + if(IsNearlyEqual(x,1.0f) + &&IsNearlyEqual(y,1.0f) + &&IsNearlyEqual(z,1.0f)) + return; + } + + is_identity=false; + + scale_vector.x=x; + scale_vector.y=y; + scale_vector.z=z; + + matrix_dirty=true; + } + + void SetScale(const Vector3f &v) + { + if(is_identity) + { + if(IsNearlyEqual(v.x,1.0f) + &&IsNearlyEqual(v.y,1.0f) + &&IsNearlyEqual(v.z,1.0f)) + return; + } + + is_identity=false; + + scale_vector=v; + matrix_dirty=true; + } + + public: + + Transform() + { + SetToIdentity(); + version=0; + } + + Transform(const Matrix4f &m) + { + SetFromMatrix4f(m); + version=0; + } + + Transform(const Transform &t) + { + hgl_cpy(*this,t); + version=0; + } + + void SetToIdentity(); + + const bool operator == (const Transform &t); + + void operator = (const Transform &t) + { + if(operator==(t)) + return; + + uint32 old_version=version; + + hgl_cpy(*this,t); + + version=++old_version; + UpdateMatrix(); + } + + void SetFromMatrix4f(const Matrix4f &m); + + const bool IsIdentity()const{return is_identity;} + + const bool IsLastVersion()const{return !matrix_dirty;} + + 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 Vector3f InverseTransformPosition (const Vector3f &v){UpdateMatrix();return Vector3f(inverse_matrix*Vector4f(v,1.0f));} + inline Vector3f InverseTransformDirection (const Vector3f &v){UpdateMatrix();return Vector3f(inverse_matrix*Vector4f(v,0.0f));} + inline Vector3f InverseTransformNormal (const Vector3f &v){UpdateMatrix();return normalize(Vector3f(transpose_inverse_matrix*Vector4f(v,0.0f)));} + inline Matrix3f InverseTransformMatrix (const Matrix3f &child){UpdateMatrix();return Matrix3f(inverse_matrix*Matrix4f(child));} + inline Matrix4f InverseTransformMatrix (const Matrix4f &child){UpdateMatrix();return inverse_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 + + const Transform IdentityTransform; + + constexpr const size_t TransformMatrix4fLength=sizeof(Transform); + + Transform Lerp(const Transform &from,const Transform &to,const float t); }//namespace hgl diff --git a/src/Math/Transform.cpp b/src/Math/Transform.cpp index c21d8f9..101e1dd 100644 --- a/src/Math/Transform.cpp +++ b/src/Math/Transform.cpp @@ -2,5 +2,131 @@ 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; + } + + void Transform::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; + } + + void Transform::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; + + UpdateVersion(); + } + + void Transform::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 Transform::operator == (const Transform &t) + { + if(is_identity) + { + if(t.is_identity) + return(true); + else + return(false); + } + else + { + if(t.is_identity) + return(false); + } + + if(translation_vector!=t.translation_vector)return(false); + if(rotation_quat!=t.rotation_quat)return(false); + if(scale_vector!=t.scale_vector)return(false); + + return(true); + } + + void Transform::SetFromMatrix4f(const Matrix4f &m) + { + if(is_identity) + { + if(IsIdentityMatrix(m)) + return; + } + + is_identity=IsIdentityMatrix(m); + + if(is_identity) + { + SetToIdentity(); + UpdateVersion(); + 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); + } }//namespace hgl