Used Transform instead of Matrix4f in SceneOrient, MaterialRenderList/RenderAssignBuffer supports updating the L2WMatrix of only the changed objects

This commit is contained in:
hyzboy 2024-08-04 22:35:31 +08:00
parent 3768507169
commit 5213651054
14 changed files with 196 additions and 81 deletions

2
CMCore

@ -1 +1 @@
Subproject commit 0dd89d78abd3cb24c6ce36d57fd9d8ccac3ec983 Subproject commit 8e471259d2ecfa9c9f293ac45a6e9e119ec31fc9

View File

@ -5,6 +5,8 @@
using namespace hgl; using namespace hgl;
using namespace hgl::graph; 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 class TestApp:public SceneAppFramework
{ {
SceneNode root; SceneNode root;
SceneNode *rotate_white_torus=nullptr;
StaticMesh *sm_move=nullptr; StaticMesh *sm_move=nullptr;
StaticMesh *sm_rotate=nullptr; StaticMesh *sm_rotate=nullptr;
@ -41,6 +44,23 @@ private:
return(true); 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: public:
bool Init(uint w,uint h) bool Init(uint w,uint h)
@ -50,6 +70,8 @@ public:
if(!InitGizmo()) if(!InitGizmo())
return(false); return(false);
InitGizmoSceneTree();
camera->pos=Vector3f(32,32,32); camera->pos=Vector3f(32,32,32);
camera_control->SetTarget(Vector3f(0,0,0)); camera_control->SetTarget(Vector3f(0,0,0));
@ -71,29 +93,27 @@ public:
const float screen_height=vi.GetViewportHeight(); const float screen_height=vi.GetViewportHeight();
root.Clear();
const Vector3f GizmoPosition(0,0,0);
const Vector4f pos=ci.Project(GizmoPosition); 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; Transform tm;
tm.SetRotation(CalculateFacingRotationQuat(GizmoPosition,ci.view,AxisVector::X)); tm.SetRotation(CalculateFacingRotationQuat(GizmoPosition,ci.view,AxisVector::X));
tm.SetScale(15); tm.SetScale(15);
root.CreateSubNode(tm,face_torus); rotate_white_torus->SetLocalTransform(tm);
} }
root.RefreshMatrix(); {
render_list->SetCamera(&(camera_control->GetCameraInfo())); Transform tm;
render_list->Expend(&root);
tm.SetScale(pos.w*16.0f/screen_height);
root.SetLocalTransform(tm);
}
root.RefreshTransform();
render_list->UpdateTransform();
SceneAppFramework::BuildCommandBuffer(index); SceneAppFramework::BuildCommandBuffer(index);
} }

View File

@ -23,6 +23,8 @@ class MaterialRenderList
RenderNodeList rn_list; RenderNodeList rn_list;
RenderNodePointerList rn_update_l2w_list;
private: private:
RenderAssignBuffer *assign_buffer; RenderAssignBuffer *assign_buffer;
@ -92,5 +94,7 @@ public:
void End(); void End();
void Render(RenderCmdBuffer *); void Render(RenderCmdBuffer *);
void UpdateTransform(); //刷新所有对象的LocalToWorld矩阵
};//class MaterialRenderList };//class MaterialRenderList
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -31,5 +31,11 @@ public:
for(auto *it:data_list) for(auto *it:data_list)
it->value->Render(rcb); it->value->Render(rcb);
} }
void UpdateTransform()
{
for(auto *it:data_list)
it->value->UpdateTransform();
}
};//class MaterialRenderMap };//class MaterialRenderMap
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -39,6 +39,8 @@ namespace hgl
virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象 virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象
virtual void UpdateTransform(); ///<更新所有对象的变换数据
virtual void Clear(); ///<彻底清理 virtual void Clear(); ///<彻底清理
};//class RenderList };//class RenderList
}//namespace graph }//namespace graph

View File

@ -15,11 +15,15 @@ namespace hgl
{ {
SceneNode *scene_node; SceneNode *scene_node;
uint32 l2w_transform_version;
uint32 l2w_index;
Vector3f world_position; Vector3f world_position;
float to_camera_distance; float to_camera_distance;
}; };
using RenderNodeList=List<RenderNode>; using RenderNodeList=List<RenderNode>;
using RenderNodePointerList=List<RenderNode *>;
using MaterialInstanceSets=SortedSets<MaterialInstance *>; ///<材质实例集合 using MaterialInstanceSets=SortedSets<MaterialInstance *>; ///<材质实例集合
}//namespace graph }//namespace graph

View File

@ -33,8 +33,8 @@ namespace hgl
SceneNode()=default; SceneNode()=default;
SceneNode(SceneNode *); SceneNode(SceneNode *);
SceneNode( Renderable *ri ) {render_obj=ri;} SceneNode( Renderable *ri ) {render_obj=ri;}
SceneNode(const Matrix4f &mat ):SceneOrient(mat) {} SceneNode(const Transform &tf ):SceneOrient(tf) {}
SceneNode(const Matrix4f &mat, Renderable *ri ):SceneOrient(mat) {render_obj=ri;} SceneNode(const Transform &tf, Renderable *ri ):SceneOrient(tf) {render_obj=ri;}
virtual ~SceneNode()=default; virtual ~SceneNode()=default;
@ -120,7 +120,7 @@ namespace hgl
virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒 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 void RefreshBoundingBox (); ///<刷新绑定盒
virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒 virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒

View File

@ -4,7 +4,6 @@
//#include<hgl/type/List.h> //#include<hgl/type/List.h>
#include<hgl/math/Math.h> #include<hgl/math/Math.h>
#include<hgl/graph/VK.h> #include<hgl/graph/VK.h>
//#include<hgl/graph/Transform.h>
namespace hgl namespace hgl
{ {
namespace graph namespace graph
@ -12,54 +11,48 @@ namespace hgl
/** /**
* *
*/ */
class SceneOrient ///场景定位类 class SceneOrient ///场景定位类
{ {
protected: protected:
//ObjectList<Transform> TransformList; Vector3f Position; ///<坐标
Vector3f Direction; ///<方向
Vector3f Position; ///<坐标 Transform LocalTransform; ///<当前变换(指相对上一级的变换)
Vector3f Direction; ///<方向 Transform WorldTransform; ///<当前到世界变换
bool IdentityLocalMatrix; ///<是否为空矩阵 protected:
Matrix4f LocalMatrix; ///<当前矩阵(指相对上一级的变换矩阵) void SetWorldTransform (const Transform &); ///<设定当前节点到世界矩阵
Matrix4f LocalToWorldMatrix; ///<当前到世界矩阵
Matrix4f InverseLocalMatrix; ///<反向当前矩阵
Matrix4f InverseLocalToWorldMatrix; ///<反向当前到世界矩阵
public: public:
SceneOrient(); SceneOrient();
SceneOrient(const SceneOrient &); SceneOrient(const SceneOrient &);
SceneOrient(const Matrix4f &mat); SceneOrient(const Transform &);
virtual ~SceneOrient()=default; virtual ~SceneOrient()=default;
void SetPosition (const Vector3f &pos){Position=pos;} void SetPosition (const Vector3f &pos){Position=pos;}
void SetDirection (const Vector3f &dir){Direction=dir;} void SetDirection (const Vector3f &dir){Direction=dir;}
const Vector3f & GetLocalPosition ()const{return Position;} const Vector3f & GetLocalPosition ()const {return Position;}
const Vector3f & GetLocalDirection ()const{return Direction;} const Vector3f & GetLocalDirection ()const {return Direction;}
const Vector3f & GetWorldPosition ()const{return TransformPosition(LocalToWorldMatrix,Position);} const Vector3f GetWorldPosition () {return WorldTransform.TransformPosition(Position);}
const Vector3f & GetWorldDirection ()const{return TransformDirection(LocalToWorldMatrix,Direction);} const Vector3f GetWorldDirection () {return WorldTransform.TransformDirection(Direction);}
public: public:
const bool IsIdentityLocalMatrix ()const{return IdentityLocalMatrix;} ///<是否为空矩阵(相对上一级没变化) void SetLocalTransform (const Transform &); ///<设定当前节点矩阵
Matrix4f & SetLocalMatrix (const Matrix4f &); ///<设定当前节点矩阵 const Transform & GetLocalTransform ()const {return LocalTransform;} ///<取得当前节点矩阵
Matrix4f & SetLocalToWorldMatrix (const Matrix4f &); ///<设定当前节点到世界矩阵 const Transform & GetWorldTransform ()const {return WorldTransform;} ///<取得当前节点到世界矩阵
const Matrix4f & GetLocalMatrix ()const {return LocalMatrix;} Transform & GetLocalTransform () {LocalTransform.UpdateMatrix();return LocalTransform;} ///<取得当前节点矩阵
const Matrix4f & GetLocalToWorldMatrix ()const {return LocalToWorldMatrix;} Transform & GetWorldTransform () {WorldTransform.UpdateMatrix();return WorldTransform;} ///<取得当前节点到世界矩阵
const Matrix4f & GetInverseLocalMatrix ()const {return InverseLocalMatrix;}
const Matrix4f & GetInverseLocalToWorldMatrix()const {return InverseLocalToWorldMatrix;}
public: public:
virtual void RefreshLocalToWorldMatrix (const Matrix4f *); ///<刷新到世界空间矩阵 virtual bool RefreshTransform (const Transform &); ///<刷新到世界空间变换
};//class SceneOrient };//class SceneOrient
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl

View File

@ -113,6 +113,9 @@ void MaterialRenderList::Add(SceneNode *sn)
rn.scene_node =sn; rn.scene_node =sn;
rn.l2w_transform_version=sn->GetWorldTransform().GetVersion();
rn.l2w_index=0;
rn.world_position =sn->GetWorldPosition(); rn.world_position =sn->GetWorldPosition();
if(camera_info) if(camera_info)
@ -138,6 +141,51 @@ void MaterialRenderList::End()
assign_buffer->WriteNode(rn_list); 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;i<node_count;i++)
{
Transform &tf=rn->scene_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) void MaterialRenderList::RenderItem::Set(Renderable *ri)
{ {
pipeline=ri->GetPipeline(); pipeline=ri->GetPipeline();

View File

@ -73,7 +73,7 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list)
for(uint i=0;i<rn_list.GetCount();i++) for(uint i=0;i<rn_list.GetCount();i++)
{ {
*l2wp=rn->scene_node->GetLocalToWorldMatrix(); *l2wp=rn->scene_node->GetWorldTransform().GetMatrix();
++l2wp; ++l2wp;
++rn; ++rn;
} }
@ -81,6 +81,30 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list)
l2w_buffer->Unmap(); 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;i<count;i++)
{
l2wp[(*rn)->l2w_index-first]=(*rn)->scene_node->GetWorldTransform().GetMatrix();
++rn;
}
l2w_buffer->Unmap();
}
void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list) void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list)
{ {
mi_set.Clear(); mi_set.Clear();
@ -181,6 +205,8 @@ void RenderAssignBuffer::WriteNode(const RenderNodeList &rn_list)
for(uint i=0;i<rn_list.GetCount();i++) for(uint i=0;i<rn_list.GetCount();i++)
{ {
rn->l2w_index=i;
adp->l2w=i; adp->l2w=i;
adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance()); adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance());
++adp; ++adp;

View File

@ -92,5 +92,6 @@ public:
void WriteNode(const RenderNodeList &); void WriteNode(const RenderNodeList &);
void UpdateTransform(const RenderNodePointerList &,const int first,const int last);
};//struct RenderAssignBuffer };//struct RenderAssignBuffer
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -77,5 +77,13 @@ namespace hgl
{ {
mrl_map.Clear(); mrl_map.Clear();
} }
void RenderList::UpdateTransform()
{
if(renderable_count<=0)
return;
mrl_map.UpdateTransform();
}
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl

View File

@ -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) if(!parent_transform.IsLastVersion())
RefreshLocalToWorldMatrix(root_matrix); return(false);
if(!parent_transform.IsIdentity())
SceneOrient::RefreshTransform(parent_transform);
else else
SetLocalToWorldMatrix(LocalMatrix); SetWorldTransform(LocalTransform);
const int count=SubNode.GetCount(); const int count=SubNode.GetCount();
@ -56,10 +59,13 @@ namespace hgl
for(int i=0;i<count;i++) for(int i=0;i<count;i++)
{ {
(*sub)->RefreshMatrix(&LocalToWorldMatrix); if(!(*sub)->RefreshTransform(WorldTransform))
return(false);
sub++; sub++;
} }
return(true);
} }
/** /**

View File

@ -7,13 +7,6 @@ namespace hgl
{ {
Position=Vector3f(0.0f); Position=Vector3f(0.0f);
Direction=Vector3f(0.0f); Direction=Vector3f(0.0f);
IdentityLocalMatrix=true;
LocalMatrix =Identity4f;
LocalToWorldMatrix =Identity4f;
InverseLocalMatrix =Identity4f;
InverseLocalToWorldMatrix =Identity4f;
} }
SceneOrient::SceneOrient(const SceneOrient &so) SceneOrient::SceneOrient(const SceneOrient &so)
@ -21,44 +14,48 @@ namespace hgl
hgl_cpy(*this,so); hgl_cpy(*this,so);
} }
SceneOrient::SceneOrient(const Matrix4f &mat) SceneOrient::SceneOrient(const Transform &t)
{ {
SetLocalMatrix(mat); SetLocalTransform(t);
LocalToWorldMatrix =Identity4f;
InverseLocalToWorldMatrix =Identity4f;
} }
Matrix4f &SceneOrient::SetLocalMatrix(const Matrix4f &m) void SceneOrient::SetLocalTransform(const Transform &t)
{ {
LocalMatrix=m; if(LocalTransform==t)
return;
IdentityLocalMatrix=IsIdentity(m); LocalTransform=t;
InverseLocalMatrix=inverse(LocalMatrix);
return LocalMatrix;
} }
Matrix4f &SceneOrient::SetLocalToWorldMatrix(const Matrix4f &m) void SceneOrient::SetWorldTransform(const Transform &t)
{ {
LocalToWorldMatrix=m; if(WorldTransform==t)
return;
InverseLocalToWorldMatrix=inverse(LocalToWorldMatrix); WorldTransform=t;
return LocalToWorldMatrix;
} }
/** /**
* *
* @param m local to world矩阵 * @param m local to world变换
*/ */
void SceneOrient::RefreshLocalToWorldMatrix(const Matrix4f *m) bool SceneOrient::RefreshTransform(const Transform &t)
{ {
if(IdentityLocalMatrix) if(!t.IsLastVersion()) //都不是最新版本
SetLocalToWorldMatrix(*m); return(false);
//理论上讲Transform在正常转const的情况下就已经做了UpdateMatrix()的操作,这个需要测试一下
if(LocalTransform.IsIdentity())
{
SetWorldTransform(t);
}
else else
SetLocalToWorldMatrix(TransformMatrix(*m,LocalMatrix)); {
SetWorldTransform(t.TransformTransform(LocalTransform));
}
return(true);
} }
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl