SceneComponent增加了SceneOrient父类,所有SceneComponent增加变换属性

This commit is contained in:
hyzboy 2025-06-14 23:42:50 +08:00
parent f9675fc1e5
commit c1420e257d
14 changed files with 182 additions and 70 deletions

@ -1 +1 @@
Subproject commit 5009069a3081d458f41f21f30236e3afebf1fd8a
Subproject commit 74e33b497274e51c35a5ee19a274b12dc86deecb

View File

@ -5,6 +5,7 @@
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/component/StaticMeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
@ -79,10 +80,10 @@ private:
for(uint i=0;i<TRIANGLE_NUMBER;i++)
{
rad=deg2rad<double>((360.0f/double(TRIANGLE_NUMBER))*i); //这里一定要加<float>或<float>否则结果用int保存会出现问题
rad=deg2rad<double>((360.0f/double(TRIANGLE_NUMBER))*i); //这里一定要加<double>或<float>否则结果用int保存会出现问题
mat=rotate(rad,Vector3f(0,0,1));
scene_root->Add(new SceneNode(mat,render_obj));
CreateComponent<StaticMeshComponent>(mat,scene_root,render_obj);
}
return(true);

View File

@ -160,6 +160,30 @@ namespace hgl
return c;
}
template<typename C,typename ...ARGS>
inline C *CreateComponent(const graph::Matrix4f &mat,graph::SceneNode *parent_node,ARGS...args)
{
if(!parent_node)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, parent node is null!"));
return(nullptr);
}
C *c=this->CreateComponent<C>(args...); //创建组件
if(!c)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, create component failed!"));
return(nullptr);
}
parent_node->AttachComponent(c); //将组件附加到父节点
c->graph::SceneOrient::SetLocalMatrix(mat);
return c;
}
};//class WorkObject
/**

View File

@ -23,14 +23,15 @@
*
* Component是组件的基类
*
* SceneComponent是场景组件基类
*
* RenderComponent是可渲染组件的基类Component
*
* PrimitiveComponent是图元组件的基类RenderComponent
* PrimitiveComponent是图元组件的基类
* Component都必须是一个有3D空间的几何图元
* PrimitiveComponent提供数据进行计算
* RenderComponent是可渲染组件的基类
*
* StaticMeshComponent是静态网格组件PrimitiveComponent实现
* StaticMeshComponent是静态网格组件RenderComponent实现
*
*/
@ -89,6 +90,7 @@ public: //事件
};//class Component
using ComponentSet=SortedSet<Component *>;
using ComponentList=ArrayList<Component *>;
class ComponentManager
{

View File

@ -1,6 +1,7 @@
#pragma once
#include<hgl/component/Component.h>
#include<hgl/graph/SceneOrient.h>
COMPONENT_NAMESPACE_BEGIN
@ -8,12 +9,11 @@ COMPONENT_NAMESPACE_BEGIN
* <br>
*
*/
class SceneComponent:public Component
class SceneComponent:public Component,public SceneOrient
{
public:
using Component::Component;
virtual ~SceneComponent()=default;
};//class SceneComponent

View File

@ -63,11 +63,7 @@ class StaticMeshComponent:public RenderComponent
public:
StaticMeshComponent(StaticMeshComponentData *cd,StaticMeshComponentManager *cm)
:RenderComponent(cd,cm)
{
sm_data=cd;
}
StaticMeshComponent(StaticMeshComponentData *cd,StaticMeshComponentManager *cm):RenderComponent(cd,cm){sm_data=cd;}
virtual ~StaticMeshComponent()=default;

View File

@ -19,33 +19,33 @@ namespace hgl::graph
*/
class SceneNode:public SceneOrient ///场景节点类
{
SceneNode *ParentNode=nullptr; ///<上级节点
SceneNode *parent_node=nullptr; ///<上级节点
SceneNodeID NodeID=-1; ///<节点ID
SceneNodeName NodeName; ///<节点名称
SceneNodeID node_id=-1; ///<节点ID
SceneNodeName node_name; ///<节点名称
protected:
AABB BoundingBox; ///<绑定盒
AABB LocalBoundingBox; ///<本地坐标绑定盒
AABB bounding_box; ///<绑定盒
AABB local_bounding_box; ///<本地坐标绑定盒
//AABB WorldBoundingBox; ///<世界坐标绑定盒
protected:
ObjectList<SceneNode> ChildNode; ///<子节点
ObjectList<SceneNode> child_nodes; ///<子节点
/**
* SceneNode下可能会包含多个组件SceneNode使用
* ComponentManager管理
*/
SortedSet<Component *> ComponentSet; ///<组件合集
ComponentSet component_set; ///<组件合集
public:
const SceneNodeID & GetNodeID ()const { return NodeID; } ///<取得节点ID
const SceneNodeName & GetNodeName ()const { return NodeName; } ///<取得节点名称
const SceneNodeID & GetNodeID ()const { return node_id; } ///<取得节点ID
const SceneNodeName & GetNodeName ()const { return node_name; } ///<取得节点名称
const ObjectList<SceneNode> &GetChildNode()const { return ChildNode; } ///<取得子节点列表
const ObjectList<SceneNode> &GetChildNode()const { return child_nodes; } ///<取得子节点列表
public:
@ -63,56 +63,56 @@ namespace hgl::graph
{
SceneOrient::Clear();
ParentNode=nullptr;
parent_node=nullptr;
BoundingBox.SetZero();
LocalBoundingBox.SetZero();
bounding_box.SetZero();
local_bounding_box.SetZero();
ChildNode.Clear();
ComponentSet.Clear();
child_nodes.Clear();
component_set.Clear();
}
const bool ChildNodeIsEmpty()const
{
if(ChildNode.GetCount())return(false);
if(child_nodes.GetCount())return(false);
return(true);
}
void SetParent(SceneNode *sn) {ParentNode=sn;}
SceneNode * GetParent() noexcept{return ParentNode;}
const SceneNode * GetParent()const noexcept{return ParentNode;}
void SetParent(SceneNode *sn) {parent_node=sn;}
SceneNode * GetParent() noexcept{return parent_node;}
const SceneNode * GetParent()const noexcept{return parent_node;}
SceneNode *Add(SceneNode *sn)
{
if(!sn)
return(nullptr);
ChildNode.Add(sn);
child_nodes.Add(sn);
sn->SetParent(this);
return sn;
}
public: //坐标相关方法
virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒
virtual void SetBoundingBox (const AABB &bb){bounding_box=bb;} ///<设置绑定盒
virtual void RefreshMatrix () override; ///<刷新世界变换
virtual void RefreshBoundingBox (); ///<刷新绑定盒
virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒
virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒
virtual const AABB & GetBoundingBox ()const{return bounding_box;} ///<取得绑定盒
virtual const AABB & GetLocalBoundingBox ()const{return local_bounding_box;} ///<取得本地坐标绑定盒
// virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒
public: //组件相关方法
bool ComponentIsEmpty ()const{return ComponentSet.GetCount()==0;} ///<是否没有组件
virtual int GetComponentCount ()const{return ComponentSet.GetCount();} ///<取得组件数量
bool ComponentIsEmpty ()const{return component_set.GetCount()==0;} ///<是否没有组件
virtual int GetComponentCount ()const{return component_set.GetCount();} ///<取得组件数量
virtual bool AttachComponent (Component *comp) ///<添加一个组件
{
if(!comp)return(false);
if(ComponentSet.Add(comp)<0)
if(component_set.Add(comp)<0)
return(false);
comp->OnAttach(this); //调用组件的OnAttach方法
@ -123,17 +123,17 @@ namespace hgl::graph
{
if (!comp)return;
ComponentSet.Delete(comp);
component_set.Delete(comp);
comp->OnDetach(this); //调用组件的OnDetach方法
}
bool Contains (Component *comp){return ComponentSet.Contains(comp);} ///<是否包含指定组件
bool Contains (Component *comp){return component_set.Contains(comp);} ///<是否包含指定组件
bool HasComponent (const ComponentManager *); ///<是否有指定组件管理器的组件
virtual int GetComponents (ArrayList<Component *> &comp_list,const ComponentManager *); ///<取得所有组件
virtual int GetComponents (ComponentList &comp_list,const ComponentManager *); ///<取得所有组件
const SortedSet<Component *> & GetComponents ()const{return ComponentSet;}
const ComponentSet &GetComponents ()const{return component_set;}
};//class SceneNode
SceneNode *Duplication(SceneNode *); ///<复制一个场景节点

View File

@ -21,7 +21,7 @@ protected:
protected:
AABB BoundingBox;
AABB bounding_box;
public:
@ -48,6 +48,6 @@ public:
VertexDataManager * GetVDM (); ///<取得顶点数据管理器
const AABB & GetBoundingBox ()const{return BoundingBox;}
const AABB & GetBoundingBox ()const{return bounding_box;}
};//class Primitive
VK_NAMESPACE_END

View File

@ -304,6 +304,7 @@ SET(COMPONENT_FILES ${COMPONENT_INCLUDE_PATH}/Component.h
${COMPONENT_INCLUDE_PATH}/StaticMeshComponent.h
component/Component.cpp
component/ComponentManager.cpp
component/SceneComponent.cpp
component/StaticMeshComponentManager.cpp
)

View File

@ -0,0 +1,5 @@
#include<hgl/component/SceneComponent.h>
COMPONENT_NAMESPACE_BEGIN
COMPONENT_NAMESPACE_END

View File

@ -56,12 +56,10 @@ void MaterialRenderList::Add(StaticMeshComponent *smc)
rn.sm_component =smc;
SceneNode *sn=smc->GetOwnerNode(); //目前先这样处理未来改成每个Component有自己的再一次的变换矩阵
rn.l2w_version =sn->GetLocalToWorldMatrixVersion();
rn.l2w_version =smc->GetLocalToWorldMatrixVersion();
rn.l2w_index =0;
rn.world_position =sn->GetWorldPosition();
rn.world_position =smc->GetWorldPosition();
if(camera_info)
rn.to_camera_distance=length(camera_info->pos,rn.world_position);
@ -104,7 +102,7 @@ void MaterialRenderList::UpdateLocalToWorld()
for(int i=0;i<node_count;i++)
{
l2w_version=rn->sm_component->GetOwnerNode()->GetLocalToWorldMatrixVersion();
l2w_version=rn->sm_component->GetLocalToWorldMatrixVersion();
if(rn->l2w_version!=l2w_version) //版本不对,需要更新
{

View File

@ -74,7 +74,7 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list)
for(int i=0;i<rn_list.GetCount();i++)
{
*l2wp=rn->sm_component->GetOwnerNode()->GetLocalToWorldMatrix();
*l2wp=rn->sm_component->GetLocalToWorldMatrix();
++l2wp;
++rn;
}
@ -98,7 +98,7 @@ void RenderAssignBuffer::UpdateLocalToWorld(const RenderNodePointerList &rnp_lis
for(uint i=0;i<count;i++)
{
l2wp[(*rn)->l2w_index-first]=(*rn)->sm_component->GetOwnerNode()->GetLocalToWorldMatrix();
l2wp[(*rn)->l2w_index-first]=(*rn)->sm_component->GetLocalToWorldMatrix();
++rn;
}

View File

@ -0,0 +1,79 @@
#include<hgl/graph/RenderNode.h>
#include<hgl/graph/VertexDataManager.h>
#include<hgl/component/StaticMeshComponent.h>
VK_NAMESPACE_BEGIN
/**
*
*
*
* for(material)
* for(pipeline)
* for(material_instance)
* for(vab)
*
*
* Indirect Command Buffer
IndirectCommandBuffer使Indirect渲染的
VBOINDIRECT缓冲区便
*/
const int RenderNode::compare(const RenderNode &other)const
{
hgl::int64 off;
hgl::graph::Mesh *ri_one=other.sm_component->GetMesh();
hgl::graph::Mesh *ri_two=sm_component->GetMesh();
auto *prim_one=ri_one->GetPrimitive();
auto *prim_two=ri_two->GetPrimitive();
//比较VDM
if(prim_one->GetVDM()) //有VDM
{
off=prim_one->GetVDM()
-prim_two->GetVDM();
if(off)
return off;
//比较模型
{
off=prim_one
-prim_two;
if(off)
{
off=prim_one->GetVertexOffset()-prim_two->GetVertexOffset(); //保证vertex offset小的在前面
return off;
}
}
}
//比较距离。。。。。。。。。。。。。。。。。。。。。还不知道这个是正了还是反了,等测出来确认后修改下面的返回值和这里的注释
float foff=other.to_camera_distance
-to_camera_distance;
if(foff>0)
return 1;
else
return -1;
}
Mesh *RenderNode::GetMesh()const
{
return sm_component?sm_component->GetMesh():nullptr;
}
MaterialInstance *RenderNode::GetMaterialInstance()const
{
if(!sm_component)return(nullptr);
if(!sm_component->GetMesh())return(nullptr);
return sm_component->GetMesh()->GetMaterialInstance();
}
VK_NAMESPACE_END

View File

@ -1,4 +1,5 @@
#include<hgl/graph/SceneNode.h>
#include<hgl/component/SceneComponent.h>
#include<hgl/graph/Mesh.h>
namespace hgl::graph
@ -30,10 +31,10 @@ namespace hgl::graph
// }
// else
// {
// BoundingBox.SetZero();
// bounding_box.SetZero();
// //WorldBoundingBox=
// LocalBoundingBox=BoundingBox;
// local_bounding_box=bounding_box;
// }
//}
@ -49,16 +50,21 @@ namespace hgl::graph
const Matrix4f &l2w=scene_matrix.GetLocalToWorldMatrix();
const int count=ChildNode.GetCount();
SceneNode **sub=ChildNode.GetData();
for(int i=0;i<count;i++)
for(SceneNode *sub:child_nodes)
{
(*sub)->SetParentMatrix(l2w);
(*sub)->RefreshMatrix();
sub->SetParentMatrix(l2w);
sub->RefreshMatrix();
}
sub++;
for(Component *com:component_set)
{
SceneComponent *sc=reinterpret_cast<SceneComponent *>(com);
if(!sc)
continue;
sc->SetParentMatrix(l2w);
sc->RefreshMatrix();
}
}
@ -67,8 +73,8 @@ namespace hgl::graph
*/
void SceneNode::RefreshBoundingBox()
{
int count=ChildNode.GetCount();
SceneNode **sub=ChildNode.GetData();
int count=child_nodes.GetCount();
SceneNode **sub=child_nodes.GetData();
AABB local,world;
@ -85,17 +91,17 @@ namespace hgl::graph
++sub;
}
LocalBoundingBox=local;
local_bounding_box=local;
}
int SceneNode::GetComponents(ArrayList<Component *> &comp_list,const ComponentManager *mgr)
int SceneNode::GetComponents(ComponentList &comp_list,const ComponentManager *mgr)
{
if(!mgr)return(-1);
if(ComponentIsEmpty())return(0);
int result=0;
for(Component *c:ComponentSet)
for(Component *c:component_set)
{
if(c->GetManager()==mgr)
{
@ -112,7 +118,7 @@ namespace hgl::graph
if(!mgr)return(false);
if(ComponentIsEmpty())return(false);
for(Component *c:ComponentSet)
for(Component *c:component_set)
{
if(c->GetManager()==mgr)
return(true);