diff --git a/CMCore b/CMCore index df5189ed..0a0f885c 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit df5189ed09cab1197ddbb4e9f5a3d7959c961e3e +Subproject commit 0a0f885c75bc9342bb46d639a2174f8d8a44cf4c diff --git a/example/Gizmo/GizmoTest.cpp b/example/Gizmo/GizmoTest.cpp index f1d49524..c908228c 100644 --- a/example/Gizmo/GizmoTest.cpp +++ b/example/Gizmo/GizmoTest.cpp @@ -6,11 +6,65 @@ using namespace hgl; using namespace hgl::graph; const Vector3f GizmoPosition(0,0,0); -// + +/** +* 永远转向摄像机的变换节点 +*/ +class TransformFaceToCamera:public TransformBase +{ + CameraInfo *camera_info=nullptr; + + Matrix4f last_view_matrix; + +protected: + + void MakeNewestData(Matrix4f &mat) override + { + if(camera_info) + mat=ToMatrix(CalculateFacingRotationQuat(WorldPosition,camera_info->view,WorldNormal)); + else + mat=Identity4f; + } + +public: + + using TransformBase::TransformBase; + + constexpr const size_t GetTypeHash()const override { return hgl::GetTypeHash(); } + + TransformFaceToCamera(CameraInfo *ci):TransformBase() + { + camera_info=ci; + + last_view_matrix=Identity4f; + } + + TransformBase *CreateSelfCopy()const override + { + return(new TransformFaceToCamera(camera_info)); + } + + void SetCameraInfo(CameraInfo *ci) { camera_info=ci; } + + bool Update() override + { + if(!camera_info) + return(false); + + if(IsNearlyEqual(last_view_matrix,camera_info->view)) + return(false); + + last_view_matrix=camera_info->view; + + UpdateVersion(); + return(true); + } +};//class TransformFaceToCamera:public TransformBase + ///** -//* 一种永远转向正面的场景节点 +//* 一种永远转向正面的变换节点 //*/ -//class BillboardSceneNode:public SceneNode +//class TransformBillboard:public TransformBase //{ // CameraInfo *camera_info=nullptr; // bool face_to_camera=false; @@ -20,9 +74,6 @@ const Vector3f GizmoPosition(0,0,0); // //public: // -// using SceneNode::SceneNode; -// virtual ~BillboardSceneNode()=default; -// // virtual void SetCameraInfo (CameraInfo * ci ){camera_info =ci;} // virtual void SetViewportInfo(ViewportInfo * vi ){viewport_info =vi;} // @@ -57,7 +108,7 @@ const Vector3f GizmoPosition(0,0,0); class TestApp:public SceneAppFramework { SceneNode root; - //BillboardSceneNode *rotate_white_torus=nullptr; + SceneNode *rotate_white_torus=nullptr; StaticMesh *sm_move=nullptr; StaticMesh *sm_rotate=nullptr; @@ -92,18 +143,20 @@ private: root.CreateSubNode(sm_rotate->GetScene()); //root.CreateSubNode(sm_scale->GetScene()); - //{ - // Transform tm; + { + rotate_white_torus=new SceneNode(scale(13),face_torus); - // tm.SetScale(7.5); + rotate_white_torus->SetLocalNormal(AxisVector::X); - // rotate_white_torus=new BillboardSceneNode(tm,face_torus); + TransformFaceToCamera *rotate_white_torus_tfc=new TransformFaceToCamera(ci); - // rotate_white_torus->SetCameraInfo(ci); - // rotate_white_torus->SetFaceToCamera(true); + rotate_white_torus->GetTransform().AddTransform(rotate_white_torus_tfc); - // root.AddSubNode(rotate_white_torus); - //} + //rotate_white_torus->SetCameraInfo(ci); + //rotate_white_torus->SetFaceToCamera(true); + + root.AddSubNode(rotate_white_torus); + } root.RefreshMatrix(); render_list->SetCamera(ci); diff --git a/inc/hgl/graph/SceneMatrix.h b/inc/hgl/graph/SceneMatrix.h index 5e76ac3a..b964510d 100644 --- a/inc/hgl/graph/SceneMatrix.h +++ b/inc/hgl/graph/SceneMatrix.h @@ -26,11 +26,20 @@ namespace hgl Matrix4f parent_matrix; Matrix4f local_matrix; + bool local_is_identity; + + Vector3f local_normal; + TransformManager transform_manager; Matrix4f transform_matrix; - Vector3f OriginWorldPosition; //原始世界坐标 - Vector3f FinalWorldPosition; //最终世界坐标 + protected: + + Vector3f OriginWorldPosition; //变换前世界坐标 + Vector3f FinalWorldPosition; //变换后世界坐标 + + Vector3f OriginWorldNormal; //变换前世界法线 + Vector3f FinalWorldNormal; //变换后世界法线 protected: @@ -44,6 +53,7 @@ namespace hgl void Clear(); const Matrix4f &GetLocalMatrix()const{return local_matrix;} ///<取得本地矩阵 + const Vector3f &GetLocalNormal()const{return local_normal;} ///<取得本地法线 const Matrix4f &GetLocalToWorldMatrix(){return GetNewestVersionData();} ///<取得本地到世界矩阵 const Matrix4f &GetInverseLocalToWorldMatrix(){UpdateNewestData();return inverse_local_to_world_matrix;} ///<取得世界到本地矩阵 @@ -56,6 +66,7 @@ namespace hgl TransformManager &GetTransform(){return transform_manager;} ///<取得变换管理器 const Vector3f &GetWorldPosition()const{return FinalWorldPosition;} ///<取得世界坐标 + const Vector3f &GetWorldNormal()const { return FinalWorldNormal; } ///<取得世界法线 public: @@ -67,6 +78,16 @@ namespace hgl UpdateVersion(); } + void SetLocalNormal(const Vector3f &normal) + { + //if(IsNearlyEqual(local_normal,normal)) + if(!hgl_cmp(local_normal,normal)) + return; + + local_normal=normal; + UpdateVersion(); + } + void SetLocalMatrix(const Matrix4f &mat) { //if (IsNearlyEqual(local_matrix,mat)) @@ -74,6 +95,8 @@ namespace hgl return; local_matrix=mat; + local_is_identity=IsIdentityMatrix(mat); + UpdateVersion(); } @@ -86,6 +109,8 @@ namespace hgl parent_matrix=pm; UpdateVersion(); } + + virtual void Update(); };//class SceneMatrix }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/SceneOrient.h b/inc/hgl/graph/SceneOrient.h index 71f48068..b59be7c6 100644 --- a/inc/hgl/graph/SceneOrient.h +++ b/inc/hgl/graph/SceneOrient.h @@ -28,8 +28,9 @@ namespace hgl scene_matrix.Clear(); } - void SetLocalMatrix (const Matrix4f &mat){scene_matrix.SetLocalMatrix(mat);} ///<设置本地矩阵 - void SetParentMatrix (const Matrix4f &mat){scene_matrix.SetParentMatrix(mat);} ///<设置上级到世界空间变换矩阵 + void SetLocalNormal(const Vector3f &nor) {scene_matrix.SetLocalNormal(nor);} ///<设置本地法线 + void SetLocalMatrix (const Matrix4f &mat){scene_matrix.SetLocalMatrix(mat);} ///<设置本地矩阵 + void SetParentMatrix(const Matrix4f &mat){scene_matrix.SetParentMatrix(mat);} ///<设置上级到世界空间变换矩阵 public: diff --git a/src/SceneGraph/SceneMatrix.cpp b/src/SceneGraph/SceneMatrix.cpp index 386e9ace..46b8a2ae 100644 --- a/src/SceneGraph/SceneMatrix.cpp +++ b/src/SceneGraph/SceneMatrix.cpp @@ -8,6 +8,8 @@ namespace hgl { parent_matrix=so.parent_matrix; local_matrix=so.local_matrix; + local_is_identity=IsIdentityMatrix(local_matrix); + local_normal=AxisVector::Z; transform_manager=so.transform_manager; transform_matrix=so.transform_matrix; @@ -20,31 +22,57 @@ namespace hgl { parent_matrix=Identity4f; local_matrix=Identity4f; + local_is_identity=true; + local_normal=AxisVector::Z; transform_matrix=Identity4f; UpdateVersion(); } void SceneMatrix::MakeNewestData(Matrix4f &local_to_world_matrix) { - local_to_world_matrix=parent_matrix*local_matrix; + if(local_is_identity) + local_to_world_matrix=parent_matrix; + else + local_to_world_matrix=parent_matrix*local_matrix; OriginWorldPosition=TransformPosition(local_to_world_matrix,ZeroVector3f); + OriginWorldNormal=TransformNormal(local_to_world_matrix,local_normal); if(transform_manager.IsEmpty()) { FinalWorldPosition=OriginWorldPosition; + FinalWorldNormal=OriginWorldNormal; } else { - transform_manager.GetMatrix(transform_matrix,OriginWorldPosition); + transform_manager.GetMatrix(transform_matrix,OriginWorldPosition,OriginWorldNormal); local_to_world_matrix*=transform_matrix; FinalWorldPosition=TransformPosition(local_to_world_matrix,ZeroVector3f); + FinalWorldNormal=TransformNormal(local_to_world_matrix,local_normal); } inverse_local_to_world_matrix =inverse(local_to_world_matrix); inverse_transpose_local_to_world_matrix=transpose(inverse_local_to_world_matrix); } + + void SceneMatrix::Update() + { + if(transform_manager.IsEmpty()) + { + if(IsNewestVersion()) + return; + } + else + { + if(!transform_manager.Update()) + return; + + UpdateVersion(); + } + + UpdateNewestData(); + } }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/SceneOrient.cpp b/src/SceneGraph/SceneOrient.cpp index c7d49a07..7704de01 100644 --- a/src/SceneGraph/SceneOrient.cpp +++ b/src/SceneGraph/SceneOrient.cpp @@ -19,11 +19,7 @@ namespace hgl void SceneOrient::RefreshMatrix() { - if (scene_matrix.IsNewestVersion()) - { - //是最新版本,证明没有更新,那不用刷新了 - return; - } + scene_matrix.Update(); } }//namespace graph }//namespace hgl