diff --git a/CMCore b/CMCore index 0dd89d78..8e471259 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 0dd89d78abd3cb24c6ce36d57fd9d8ccac3ec983 +Subproject commit 8e471259d2ecfa9c9f293ac45a6e9e119ec31fc9 diff --git a/example/Gizmo/GizmoTest.cpp b/example/Gizmo/GizmoTest.cpp index 1f319360..58dbdd2c 100644 --- a/example/Gizmo/GizmoTest.cpp +++ b/example/Gizmo/GizmoTest.cpp @@ -5,6 +5,8 @@ using namespace hgl; using namespace hgl::graph; +const Vector3f GizmoPosition(0,0,0); + /** * 求一个世界坐标在屏幕上的位置 */ @@ -20,6 +22,7 @@ Vector2f WorldToScreen(const Vector3f &world_pos,const CameraInfo &ci,const View class TestApp:public SceneAppFramework { SceneNode root; + SceneNode *rotate_white_torus=nullptr; StaticMesh *sm_move=nullptr; StaticMesh *sm_rotate=nullptr; @@ -41,6 +44,23 @@ private: return(true); } + void InitGizmoSceneTree() + { + camera_control->Refresh(); + const CameraInfo &ci=camera_control->GetCameraInfo(); + + root.Clear(); + + root.CreateSubNode(sm_move->GetScene()); + root.CreateSubNode(sm_rotate->GetScene()); + + rotate_white_torus=root.CreateSubNode(face_torus); + + root.RefreshTransform(); + render_list->SetCamera(&(camera_control->GetCameraInfo())); + render_list->Expend(&root); + } + public: bool Init(uint w,uint h) @@ -50,6 +70,8 @@ public: if(!InitGizmo()) return(false); + + InitGizmoSceneTree(); camera->pos=Vector3f(32,32,32); camera_control->SetTarget(Vector3f(0,0,0)); @@ -71,29 +93,27 @@ public: const float screen_height=vi.GetViewportHeight(); - root.Clear(); - - const Vector3f GizmoPosition(0,0,0); - const Vector4f pos=ci.Project(GizmoPosition); - root.SetLocalMatrix(scale(pos.w*16.0f/screen_height)); - - root.CreateSubNode(sm_move->GetScene()); - root.CreateSubNode(sm_rotate->GetScene()); - { Transform tm; tm.SetRotation(CalculateFacingRotationQuat(GizmoPosition,ci.view,AxisVector::X)); tm.SetScale(15); - root.CreateSubNode(tm,face_torus); + rotate_white_torus->SetLocalTransform(tm); } - root.RefreshMatrix(); - render_list->SetCamera(&(camera_control->GetCameraInfo())); - render_list->Expend(&root); + { + Transform tm; + + tm.SetScale(pos.w*16.0f/screen_height); + + root.SetLocalTransform(tm); + } + + root.RefreshTransform(); + render_list->UpdateTransform(); SceneAppFramework::BuildCommandBuffer(index); } diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index 240ae21c..64ced46e 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -23,6 +23,8 @@ class MaterialRenderList RenderNodeList rn_list; + RenderNodePointerList rn_update_l2w_list; + private: RenderAssignBuffer *assign_buffer; @@ -92,5 +94,7 @@ public: void End(); void Render(RenderCmdBuffer *); + + void UpdateTransform(); //刷新所有对象的LocalToWorld矩阵 };//class MaterialRenderList VK_NAMESPACE_END diff --git a/inc/hgl/graph/MaterialRenderMap.h b/inc/hgl/graph/MaterialRenderMap.h index 21400632..334659d2 100644 --- a/inc/hgl/graph/MaterialRenderMap.h +++ b/inc/hgl/graph/MaterialRenderMap.h @@ -31,5 +31,11 @@ public: for(auto *it:data_list) it->value->Render(rcb); } + + void UpdateTransform() + { + for(auto *it:data_list) + it->value->UpdateTransform(); + } };//class MaterialRenderMap VK_NAMESPACE_END diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index 8f7f3eb9..aa86e98f 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -39,6 +39,8 @@ namespace hgl virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象 + virtual void UpdateTransform(); ///<更新所有对象的变换数据 + virtual void Clear(); ///<彻底清理 };//class RenderList }//namespace graph diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h index 6d09ad13..b3d916f6 100644 --- a/inc/hgl/graph/RenderNode.h +++ b/inc/hgl/graph/RenderNode.h @@ -15,11 +15,15 @@ namespace hgl { SceneNode *scene_node; + uint32 l2w_transform_version; + uint32 l2w_index; + Vector3f world_position; float to_camera_distance; }; using RenderNodeList=List; + using RenderNodePointerList=List; using MaterialInstanceSets=SortedSets; ///<材质实例集合 }//namespace graph diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index ba5d9b26..02fe4ae9 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -33,8 +33,8 @@ namespace hgl SceneNode()=default; SceneNode(SceneNode *); SceneNode( Renderable *ri ) {render_obj=ri;} - SceneNode(const Matrix4f &mat ):SceneOrient(mat) {} - SceneNode(const Matrix4f &mat, Renderable *ri ):SceneOrient(mat) {render_obj=ri;} + SceneNode(const Transform &tf ):SceneOrient(tf) {} + SceneNode(const Transform &tf, Renderable *ri ):SceneOrient(tf) {render_obj=ri;} virtual ~SceneNode()=default; @@ -120,7 +120,7 @@ namespace hgl virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒 - virtual void RefreshMatrix (const Matrix4f *mat=nullptr); ///<刷新世界变换矩阵 + virtual bool RefreshTransform (const Transform &tf=IdentityTransform) override; ///<刷新世界变换 virtual void RefreshBoundingBox (); ///<刷新绑定盒 virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒 diff --git a/inc/hgl/graph/SceneOrient.h b/inc/hgl/graph/SceneOrient.h index c2963932..c0309bdc 100644 --- a/inc/hgl/graph/SceneOrient.h +++ b/inc/hgl/graph/SceneOrient.h @@ -4,7 +4,6 @@ //#include #include #include -//#include namespace hgl { namespace graph @@ -12,54 +11,48 @@ namespace hgl /** * 方向定位数据基类 */ - class SceneOrient ///场景定位类 + class SceneOrient ///场景定位类 { protected: - //ObjectList TransformList; + Vector3f Position; ///<坐标 + Vector3f Direction; ///<方向 - Vector3f Position; ///<坐标 - Vector3f Direction; ///<方向 + Transform LocalTransform; ///<当前变换(指相对上一级的变换) + Transform WorldTransform; ///<当前到世界变换 - bool IdentityLocalMatrix; ///<是否为空矩阵 + protected: - Matrix4f LocalMatrix; ///<当前矩阵(指相对上一级的变换矩阵) - Matrix4f LocalToWorldMatrix; ///<当前到世界矩阵 - - Matrix4f InverseLocalMatrix; ///<反向当前矩阵 - Matrix4f InverseLocalToWorldMatrix; ///<反向当前到世界矩阵 + void SetWorldTransform (const Transform &); ///<设定当前节点到世界矩阵 public: SceneOrient(); SceneOrient(const SceneOrient &); - SceneOrient(const Matrix4f &mat); + SceneOrient(const Transform &); virtual ~SceneOrient()=default; void SetPosition (const Vector3f &pos){Position=pos;} void SetDirection (const Vector3f &dir){Direction=dir;} - const Vector3f & GetLocalPosition ()const{return Position;} - const Vector3f & GetLocalDirection ()const{return Direction;} - const Vector3f & GetWorldPosition ()const{return TransformPosition(LocalToWorldMatrix,Position);} - const Vector3f & GetWorldDirection ()const{return TransformDirection(LocalToWorldMatrix,Direction);} + const Vector3f & GetLocalPosition ()const {return Position;} + const Vector3f & GetLocalDirection ()const {return Direction;} + const Vector3f GetWorldPosition () {return WorldTransform.TransformPosition(Position);} + const Vector3f GetWorldDirection () {return WorldTransform.TransformDirection(Direction);} public: - const bool IsIdentityLocalMatrix ()const{return IdentityLocalMatrix;} ///<是否为空矩阵(相对上一级没变化) + void SetLocalTransform (const Transform &); ///<设定当前节点矩阵 - Matrix4f & SetLocalMatrix (const Matrix4f &); ///<设定当前节点矩阵 - Matrix4f & SetLocalToWorldMatrix (const Matrix4f &); ///<设定当前节点到世界矩阵 - - const Matrix4f & GetLocalMatrix ()const {return LocalMatrix;} - const Matrix4f & GetLocalToWorldMatrix ()const {return LocalToWorldMatrix;} - - const Matrix4f & GetInverseLocalMatrix ()const {return InverseLocalMatrix;} - const Matrix4f & GetInverseLocalToWorldMatrix()const {return InverseLocalToWorldMatrix;} + const Transform & GetLocalTransform ()const {return LocalTransform;} ///<取得当前节点矩阵 + const Transform & GetWorldTransform ()const {return WorldTransform;} ///<取得当前节点到世界矩阵 + + Transform & GetLocalTransform () {LocalTransform.UpdateMatrix();return LocalTransform;} ///<取得当前节点矩阵 + Transform & GetWorldTransform () {WorldTransform.UpdateMatrix();return WorldTransform;} ///<取得当前节点到世界矩阵 public: - virtual void RefreshLocalToWorldMatrix (const Matrix4f *); ///<刷新到世界空间矩阵 + virtual bool RefreshTransform (const Transform &); ///<刷新到世界空间变换 };//class SceneOrient }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/MaterialRenderList.cpp b/src/SceneGraph/MaterialRenderList.cpp index 853f5af4..7f3f5686 100644 --- a/src/SceneGraph/MaterialRenderList.cpp +++ b/src/SceneGraph/MaterialRenderList.cpp @@ -113,6 +113,9 @@ void MaterialRenderList::Add(SceneNode *sn) rn.scene_node =sn; + rn.l2w_transform_version=sn->GetWorldTransform().GetVersion(); + rn.l2w_index=0; + rn.world_position =sn->GetWorldPosition(); if(camera_info) @@ -138,6 +141,51 @@ void MaterialRenderList::End() assign_buffer->WriteNode(rn_list); } +void MaterialRenderList::UpdateTransform() +{ + if(!assign_buffer) + return; + + rn_update_l2w_list.Clear(); + + const int node_count=rn_list.GetCount(); + + if(node_count<=0)return; + + int first=-1,last=-1; + int update_count=0; + RenderNode *rn=rn_list.GetData(); + + for(int i=0;iscene_node->GetWorldTransform(); + + if(rn->l2w_transform_version!=tf.GetVersion()) //版本不对,需要更新 + { + if(first==-1) + { + first=rn->l2w_index; + } + + last=rn->l2w_index; + + rn->l2w_transform_version=tf.GetVersion(); + + rn_update_l2w_list.Add(rn); + + ++update_count; + } + + ++rn; + } + + if(update_count>0) + { + assign_buffer->UpdateTransform(rn_update_l2w_list,first,last); + rn_update_l2w_list.Clear(); + } +} + void MaterialRenderList::RenderItem::Set(Renderable *ri) { pipeline=ri->GetPipeline(); diff --git a/src/SceneGraph/RenderAssignBuffer.cpp b/src/SceneGraph/RenderAssignBuffer.cpp index 4770f803..67938df2 100644 --- a/src/SceneGraph/RenderAssignBuffer.cpp +++ b/src/SceneGraph/RenderAssignBuffer.cpp @@ -73,7 +73,7 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list) for(uint i=0;iscene_node->GetLocalToWorldMatrix(); + *l2wp=rn->scene_node->GetWorldTransform().GetMatrix(); ++l2wp; ++rn; } @@ -81,6 +81,30 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list) l2w_buffer->Unmap(); } +void RenderAssignBuffer::UpdateTransform(const RenderNodePointerList &rnp_list,const int first,const int last) +{ + if(!l2w_buffer) + return; + + if(rnp_list.IsEmpty()) + return; + + const uint count=rnp_list.GetCount(); + + RenderNode **rn=rnp_list.GetData(); + Matrix4f *l2wp=(Matrix4f *)(l2w_buffer->DeviceBuffer::Map( sizeof(Matrix4f)*first, + sizeof(Matrix4f)*(last-first+1))); + + for(uint i=0;il2w_index-first]=(*rn)->scene_node->GetWorldTransform().GetMatrix(); + + ++rn; + } + + l2w_buffer->Unmap(); +} + void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list) { mi_set.Clear(); @@ -181,6 +205,8 @@ void RenderAssignBuffer::WriteNode(const RenderNodeList &rn_list) for(uint i=0;il2w_index=i; + adp->l2w=i; adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance()); ++adp; diff --git a/src/SceneGraph/RenderAssignBuffer.h b/src/SceneGraph/RenderAssignBuffer.h index ad8e7a01..dcd2e6f8 100644 --- a/src/SceneGraph/RenderAssignBuffer.h +++ b/src/SceneGraph/RenderAssignBuffer.h @@ -92,5 +92,6 @@ public: void WriteNode(const RenderNodeList &); + void UpdateTransform(const RenderNodePointerList &,const int first,const int last); };//struct RenderAssignBuffer VK_NAMESPACE_END diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index 72009c61..3435e250 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -77,5 +77,13 @@ namespace hgl { mrl_map.Clear(); } + + void RenderList::UpdateTransform() + { + if(renderable_count<=0) + return; + + mrl_map.UpdateTransform(); + } }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/SceneNode.cpp b/src/SceneGraph/SceneNode.cpp index 417b14ef..8cd0d362 100644 --- a/src/SceneGraph/SceneNode.cpp +++ b/src/SceneGraph/SceneNode.cpp @@ -40,15 +40,18 @@ namespace hgl } /** - * 刷新矩阵 - * @param root_matrix 根矩阵 + * 刷新变换 + * @param parent_transform 上级节点变换 */ - void SceneNode::RefreshMatrix(const Matrix4f *root_matrix) + bool SceneNode::RefreshTransform(const Transform &parent_transform) { - if(root_matrix) - RefreshLocalToWorldMatrix(root_matrix); + if(!parent_transform.IsLastVersion()) + return(false); + + if(!parent_transform.IsIdentity()) + SceneOrient::RefreshTransform(parent_transform); else - SetLocalToWorldMatrix(LocalMatrix); + SetWorldTransform(LocalTransform); const int count=SubNode.GetCount(); @@ -56,10 +59,13 @@ namespace hgl for(int i=0;iRefreshMatrix(&LocalToWorldMatrix); + if(!(*sub)->RefreshTransform(WorldTransform)) + return(false); sub++; } + + return(true); } /** diff --git a/src/SceneGraph/SceneOrient.cpp b/src/SceneGraph/SceneOrient.cpp index 85834542..121a576f 100644 --- a/src/SceneGraph/SceneOrient.cpp +++ b/src/SceneGraph/SceneOrient.cpp @@ -7,13 +7,6 @@ namespace hgl { Position=Vector3f(0.0f); Direction=Vector3f(0.0f); - - IdentityLocalMatrix=true; - - LocalMatrix =Identity4f; - LocalToWorldMatrix =Identity4f; - InverseLocalMatrix =Identity4f; - InverseLocalToWorldMatrix =Identity4f; } SceneOrient::SceneOrient(const SceneOrient &so) @@ -21,44 +14,48 @@ namespace hgl hgl_cpy(*this,so); } - SceneOrient::SceneOrient(const Matrix4f &mat) + SceneOrient::SceneOrient(const Transform &t) { - SetLocalMatrix(mat); - - LocalToWorldMatrix =Identity4f; - InverseLocalToWorldMatrix =Identity4f; + SetLocalTransform(t); } - Matrix4f &SceneOrient::SetLocalMatrix(const Matrix4f &m) + void SceneOrient::SetLocalTransform(const Transform &t) { - LocalMatrix=m; + if(LocalTransform==t) + return; - IdentityLocalMatrix=IsIdentity(m); - - InverseLocalMatrix=inverse(LocalMatrix); - - return LocalMatrix; + LocalTransform=t; } - Matrix4f &SceneOrient::SetLocalToWorldMatrix(const Matrix4f &m) + void SceneOrient::SetWorldTransform(const Transform &t) { - LocalToWorldMatrix=m; + if(WorldTransform==t) + return; - InverseLocalToWorldMatrix=inverse(LocalToWorldMatrix); - - return LocalToWorldMatrix; + WorldTransform=t; } /** - * 刷新世界矩阵 - * @param m 上一级local to world矩阵 + * 刷新世界变换 + * @param m 上一级local to world变换 */ - void SceneOrient::RefreshLocalToWorldMatrix(const Matrix4f *m) + bool SceneOrient::RefreshTransform(const Transform &t) { - if(IdentityLocalMatrix) - SetLocalToWorldMatrix(*m); + if(!t.IsLastVersion()) //都不是最新版本 + return(false); + + //理论上讲,Transform在正常转const的情况下,就已经做了UpdateMatrix()的操作,这个需要测试一下 + + if(LocalTransform.IsIdentity()) + { + SetWorldTransform(t); + } else - SetLocalToWorldMatrix(TransformMatrix(*m,LocalMatrix)); + { + SetWorldTransform(t.TransformTransform(LocalTransform)); + } + + return(true); } }//namespace graph }//namespace hgl