Used Transform instead of Matrix4f in SceneOrient, MaterialRenderList/RenderAssignBuffer supports updating the L2WMatrix of only the changed objects
This commit is contained in:
parent
3768507169
commit
5213651054
2
CMCore
2
CMCore
@ -1 +1 @@
|
||||
Subproject commit 0dd89d78abd3cb24c6ce36d57fd9d8ccac3ec983
|
||||
Subproject commit 8e471259d2ecfa9c9f293ac45a6e9e119ec31fc9
|
@ -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)
|
||||
@ -51,6 +71,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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -39,6 +39,8 @@ namespace hgl
|
||||
|
||||
virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象
|
||||
|
||||
virtual void UpdateTransform(); ///<更新所有对象的变换数据
|
||||
|
||||
virtual void Clear(); ///<彻底清理
|
||||
};//class RenderList
|
||||
}//namespace graph
|
||||
|
@ -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<RenderNode>;
|
||||
using RenderNodePointerList=List<RenderNode *>;
|
||||
|
||||
using MaterialInstanceSets=SortedSets<MaterialInstance *>; ///<材质实例集合
|
||||
}//namespace graph
|
||||
|
@ -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;} ///<取得绑定盒
|
||||
|
@ -4,7 +4,6 @@
|
||||
//#include<hgl/type/List.h>
|
||||
#include<hgl/math/Math.h>
|
||||
#include<hgl/graph/VK.h>
|
||||
//#include<hgl/graph/Transform.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
@ -16,24 +15,21 @@ namespace hgl
|
||||
{
|
||||
protected:
|
||||
|
||||
//ObjectList<Transform> TransformList;
|
||||
|
||||
Vector3f Position; ///<坐标
|
||||
Vector3f Direction; ///<方向
|
||||
|
||||
bool IdentityLocalMatrix; ///<是否为空矩阵
|
||||
Transform LocalTransform; ///<当前变换(指相对上一级的变换)
|
||||
Transform WorldTransform; ///<当前到世界变换
|
||||
|
||||
Matrix4f LocalMatrix; ///<当前矩阵(指相对上一级的变换矩阵)
|
||||
Matrix4f LocalToWorldMatrix; ///<当前到世界矩阵
|
||||
protected:
|
||||
|
||||
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;}
|
||||
@ -41,25 +37,22 @@ namespace hgl
|
||||
|
||||
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 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 Transform & GetLocalTransform ()const {return LocalTransform;} ///<取得当前节点矩阵
|
||||
const Transform & GetWorldTransform ()const {return WorldTransform;} ///<取得当前节点到世界矩阵
|
||||
|
||||
const Matrix4f & GetLocalMatrix ()const {return LocalMatrix;}
|
||||
const Matrix4f & GetLocalToWorldMatrix ()const {return LocalToWorldMatrix;}
|
||||
|
||||
const Matrix4f & GetInverseLocalMatrix ()const {return InverseLocalMatrix;}
|
||||
const Matrix4f & GetInverseLocalToWorldMatrix()const {return InverseLocalToWorldMatrix;}
|
||||
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
|
||||
|
@ -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;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)
|
||||
{
|
||||
pipeline=ri->GetPipeline();
|
||||
|
@ -73,7 +73,7 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list)
|
||||
|
||||
for(uint i=0;i<rn_list.GetCount();i++)
|
||||
{
|
||||
*l2wp=rn->scene_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;i<count;i++)
|
||||
{
|
||||
l2wp[(*rn)->l2w_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;i<rn_list.GetCount();i++)
|
||||
{
|
||||
rn->l2w_index=i;
|
||||
|
||||
adp->l2w=i;
|
||||
adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance());
|
||||
++adp;
|
||||
|
@ -92,5 +92,6 @@ public:
|
||||
|
||||
void WriteNode(const RenderNodeList &);
|
||||
|
||||
void UpdateTransform(const RenderNodePointerList &,const int first,const int last);
|
||||
};//struct RenderAssignBuffer
|
||||
VK_NAMESPACE_END
|
||||
|
@ -77,5 +77,13 @@ namespace hgl
|
||||
{
|
||||
mrl_map.Clear();
|
||||
}
|
||||
|
||||
void RenderList::UpdateTransform()
|
||||
{
|
||||
if(renderable_count<=0)
|
||||
return;
|
||||
|
||||
mrl_map.UpdateTransform();
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
|
@ -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;i<count;i++)
|
||||
{
|
||||
(*sub)->RefreshMatrix(&LocalToWorldMatrix);
|
||||
if(!(*sub)->RefreshTransform(WorldTransform))
|
||||
return(false);
|
||||
|
||||
sub++;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user