diff --git a/inc/hgl/component/Component.h b/inc/hgl/component/Component.h index 51fff872..aa150d24 100644 --- a/inc/hgl/component/Component.h +++ b/inc/hgl/component/Component.h @@ -58,17 +58,8 @@ class Component public: Component()=delete; - Component(SceneNode *sn,ComponentData *cd,ComponentManager *cm) - { - OwnerNode=sn; - Data=cd; - Manager=cm; - } - - virtual ~Component() - { - SAFE_CLEAR(Data); - } + Component(ComponentData *,ComponentManager *); + virtual ~Component(); virtual const size_t GetHashCode()const=0; @@ -84,6 +75,9 @@ public: public: //事件 + virtual void OnAttach(SceneNode *node){if(node)OwnerNode=node;} ///<附加到节点事件 + virtual void OnDetach(){OwnerNode=nullptr;} ///<从节点分离事件 + virtual void OnFocusLost(){} ///<焦点丢失事件 virtual void OnFocusGained(){} ///<焦点获得事件 };//class Component @@ -94,6 +88,13 @@ class ComponentManager { ComponentSet component_set; +protected: + + friend class Component; //Component可以直接访问ComponentManager的成员 + + virtual void AttachComponent(Component *c){if(!c)return;component_set.Add(c);} + virtual void DetachComponent(Component *c){if(!c)return;component_set.Delete(c);} + public: virtual const size_t GetComponentHashCode()const=0; @@ -113,9 +114,6 @@ public: virtual void UpdateComponents(const double delta_time); - virtual void AttachComponent(Component *c){if(!c)return;component_set.Add(c);} - virtual void DetachComponent(Component *c){if(!c)return;component_set.Delete(c);} - public: //事件 virtual void OnFocusLost(){} ///<焦点丢失事件 diff --git a/inc/hgl/component/PrimitiveComponent.h b/inc/hgl/component/PrimitiveComponent.h index 870b35ad..fd42f0dd 100644 --- a/inc/hgl/component/PrimitiveComponent.h +++ b/inc/hgl/component/PrimitiveComponent.h @@ -12,8 +12,8 @@ class PrimitiveComponent:public RenderComponent { public: - PrimitiveComponent(SceneNode *psn,ComponentData *cd,ComponentManager *cm) - :RenderComponent(psn,cd,cm){} + using RenderComponent::RenderComponent; + virtual ~PrimitiveComponent()=default; };//class PrimitiveComponent diff --git a/inc/hgl/component/RenderComponent.h b/inc/hgl/component/RenderComponent.h index d58b2f95..a94d6380 100644 --- a/inc/hgl/component/RenderComponent.h +++ b/inc/hgl/component/RenderComponent.h @@ -11,8 +11,7 @@ class RenderComponent: public Component { public: - RenderComponent(SceneNode *psn,ComponentData *cd,ComponentManager *cm) - :Component(psn,cd,cm){} + using Component::Component; virtual ~RenderComponent()=default; };//class RenderComponent diff --git a/inc/hgl/component/StaticMeshComponent.h b/inc/hgl/component/StaticMeshComponent.h index 77c226af..cb9a51a6 100644 --- a/inc/hgl/component/StaticMeshComponent.h +++ b/inc/hgl/component/StaticMeshComponent.h @@ -20,6 +20,8 @@ public: { mesh=m; } + + virtual ~StaticMeshComponentData(); };//struct StaticMeshComponentData class StaticMeshComponent; @@ -43,24 +45,14 @@ public: StaticMeshComponentManager()=default; - StaticMeshComponent *CreateStaticMeshComponent(StaticMeshComponentData *data) - { - if(!data)return(nullptr); - - return(new StaticMeshComponent(data)); - } + StaticMeshComponent *CreateStaticMeshComponent(StaticMeshComponentData *data); StaticMeshComponent *CreateStaticMeshComponent(Mesh *m) { return CreateStaticMeshComponent(new StaticMeshComponentData(m)); } - virtual Component *CreateComponent(ComponentData *data) override - { - if(!data)return(nullptr); - - return CreateStaticMeshComponent(reinterpret_cast(data)); - } + virtual Component *CreateComponent(ComponentData *data) override; };//class StaticMeshComponentManager class StaticMeshComponent:public PrimitiveComponent @@ -69,8 +61,8 @@ class StaticMeshComponent:public PrimitiveComponent public: - StaticMeshComponent(SceneNode *psn,StaticMeshComponentData *cd,StaticMeshComponentManager *cm) - :PrimitiveComponent(psn,cd,cm) + StaticMeshComponent(StaticMeshComponentData *cd,StaticMeshComponentManager *cm) + :PrimitiveComponent(cd,cm) { sm_data=cd; } @@ -90,6 +82,7 @@ public: StaticMeshComponentData &GetData() {return *sm_data;} const StaticMeshComponentData &GetData()const {return *sm_data;} + Mesh *GetMesh() const{return sm_data->mesh;} };//class StaticMeshComponent COMPONENT_NAMESPACE_END diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index e248184c..9fc6fd6d 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -8,7 +8,7 @@ namespace hgl::graph { - using SceneNodeID =uint64; + using SceneNodeID =int64; HGL_DEFINE_U16_IDNAME(SceneNodeName) @@ -19,9 +19,9 @@ namespace hgl::graph */ class SceneNode:public SceneOrient ///场景节点类 { - SceneNode *ParentNode; ///<上级节点 + SceneNode *ParentNode=nullptr; ///<上级节点 - SceneNodeID NodeID; ///<节点ID + SceneNodeID NodeID=-1; ///<节点ID SceneNodeName NodeName; ///<节点名称 protected: @@ -35,7 +35,12 @@ namespace hgl::graph protected: ObjectList ChildNode; ///<子节点 - ObjectList ComponentList; ///<组件列表 + + /** + * 组件合集,一个SceneNode下可能会包含多个组件,同时一个组件也可能被多个SceneNode使用。 + * 所以这里只保留一个指针,不拥有组件的生命周期,组件的生命周期由其对应的ComponentManager管理。 + */ + SortedSet ComponentSet; ///<组件合集 public: @@ -68,7 +73,7 @@ namespace hgl::graph LocalBoundingBox.SetZero(); ChildNode.Clear(); - ComponentList.Clear(); + ComponentSet.Clear(); render_obj=nullptr; } @@ -111,11 +116,11 @@ namespace hgl::graph public: //组件相关方法 - bool ComponentIsEmpty ()const {return ComponentList.GetCount()==0;} ///<是否没有组件 - virtual int GetComponentCount ()const {return ComponentList.GetCount();} ///<取得组件数量 - virtual void AddComponent (Component *comp) {ComponentList.Add(comp);} ///<添加一个组件 - virtual void RemoveComponent (Component *comp) {ComponentList.DeleteByValue(comp);} ///<删除一个组件 - bool Contains (Component *comp) {return ComponentList.Contains(comp);} ///<是否包含指定组件 + bool ComponentIsEmpty ()const{return ComponentSet.GetCount()==0;} ///<是否没有组件 + virtual int GetComponentCount ()const{return ComponentSet.GetCount();} ///<取得组件数量 + virtual void AttachComponent (Component *comp){ComponentSet.Add(comp);} ///<添加一个组件 + virtual void DetachComponent (Component *comp){ComponentSet.Delete(comp);} ///<删除一个组件 + bool Contains (Component *comp){return ComponentSet.Contains(comp);} ///<是否包含指定组件 bool HasComponent (const ComponentManager *); ///<是否有指定组件管理器的组件 virtual int GetComponents (ArrayList &comp_list,const ComponentManager *); ///<取得所有组件 diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 02839419..196a780a 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -300,6 +300,7 @@ SET(COMPONENT_FILES ${COMPONENT_INCLUDE_PATH}/Component.h ${COMPONENT_INCLUDE_PATH}/RenderComponent.h ${COMPONENT_INCLUDE_PATH}/PrimitiveComponent.h ${COMPONENT_INCLUDE_PATH}/StaticMeshComponent.h + component/Component.cpp component/ComponentManager.cpp component/StaticMeshComponentManager.cpp ) diff --git a/src/SceneGraph/component/Component.cpp b/src/SceneGraph/component/Component.cpp new file mode 100644 index 00000000..c7106cc3 --- /dev/null +++ b/src/SceneGraph/component/Component.cpp @@ -0,0 +1,27 @@ +#include +#include + +namespace hgl::graph +{ + Component::Component(ComponentData *cd,ComponentManager *cm) + { + OwnerNode=nullptr; + Data=cd; + Manager=cm; + + Manager->AttachComponent(this); + } + + Component::~Component() + { + if(OwnerNode) + { + OwnerNode->DetachComponent(this); + OwnerNode=nullptr; + } + + Manager->DetachComponent(this); + + SAFE_CLEAR(Data); + } +}//namespace hgl::graph diff --git a/src/SceneGraph/component/StaticMeshComponentManager.cpp b/src/SceneGraph/component/StaticMeshComponentManager.cpp index 4e8cb526..5e6cd57b 100644 --- a/src/SceneGraph/component/StaticMeshComponentManager.cpp +++ b/src/SceneGraph/component/StaticMeshComponentManager.cpp @@ -1,7 +1,26 @@ #include #include +#include COMPONENT_NAMESPACE_BEGIN +StaticMeshComponentData::~StaticMeshComponentData() +{ + SAFE_CLEAR(mesh); +} + +Component *StaticMeshComponentManager::CreateComponent(ComponentData *data) +{ + if(!data)return(nullptr); + + return CreateStaticMeshComponent(reinterpret_cast(data)); +} + +StaticMeshComponent *StaticMeshComponentManager::CreateStaticMeshComponent(StaticMeshComponentData *data) +{ + if(!data)return(nullptr); + + return(new StaticMeshComponent(data,this)); +} COMPONENT_NAMESPACE_END diff --git a/src/SceneGraph/scene/SceneNode.cpp b/src/SceneGraph/scene/SceneNode.cpp index 82b9eb5f..613252d6 100644 --- a/src/SceneGraph/scene/SceneNode.cpp +++ b/src/SceneGraph/scene/SceneNode.cpp @@ -1,125 +1,123 @@ #include #include -namespace hgl + +namespace hgl::graph { - namespace graph + SceneNode *Duplication(SceneNode *src_node) { - SceneNode *Duplication(SceneNode *src_node) + if(!src_node) + return nullptr; + + SceneNode *node=new SceneNode(*(SceneOrient *)src_node); + + node->SetRenderable(src_node->GetRenderable()); + + for(SceneNode *sn:src_node->GetChildNode()) { - if(!src_node) - return nullptr; - - SceneNode *node=new SceneNode(*(SceneOrient *)src_node); - - node->SetRenderable(src_node->GetRenderable()); - - for(SceneNode *sn:src_node->GetChildNode()) - { - node->Add(Duplication(sn)); - } - - return node; + node->Add(Duplication(sn)); } - void SceneNode::SetRenderable(Mesh *ri) + return node; + } + + void SceneNode::SetRenderable(Mesh *ri) + { + render_obj=ri; + + if(render_obj) { - render_obj=ri; - - if(render_obj) - { - SetBoundingBox(render_obj->GetBoundingBox()); - } - else - { - BoundingBox.SetZero(); - - //WorldBoundingBox= - LocalBoundingBox=BoundingBox; - } + SetBoundingBox(render_obj->GetBoundingBox()); } - - /** - * 刷新矩阵变换 - */ - void SceneNode::RefreshMatrix() + else { - SceneOrient::RefreshMatrix(); + BoundingBox.SetZero(); + + //WorldBoundingBox= + LocalBoundingBox=BoundingBox; + } + } + + /** + * 刷新矩阵变换 + */ + void SceneNode::RefreshMatrix() + { + SceneOrient::RefreshMatrix(); // if (scene_matrix.IsNewestVersion()) //自己不变,不代表下面不变 - //return; + //return; - const Matrix4f &l2w=scene_matrix.GetLocalToWorldMatrix(); + const Matrix4f &l2w=scene_matrix.GetLocalToWorldMatrix(); - const int count=ChildNode.GetCount(); + const int count=ChildNode.GetCount(); - SceneNode **sub=ChildNode.GetData(); + SceneNode **sub=ChildNode.GetData(); - for(int i=0;iSetParentMatrix(l2w); - (*sub)->RefreshMatrix(); - - sub++; - } - } - - /** - * 刷新绑定盒 - */ - void SceneNode::RefreshBoundingBox() + for(int i=0;iSetParentMatrix(l2w); + (*sub)->RefreshMatrix(); - AABB local,world; + sub++; + } + } + /** + * 刷新绑定盒 + */ + void SceneNode::RefreshBoundingBox() + { + int count=ChildNode.GetCount(); + SceneNode **sub=ChildNode.GetData(); + + AABB local,world; + + (*sub)->RefreshBoundingBox(); + local=(*sub)->GetLocalBoundingBox(); + + ++sub; + for(int i=1;iRefreshBoundingBox(); - local=(*sub)->GetLocalBoundingBox(); + + local.Enclose((*sub)->GetLocalBoundingBox()); ++sub; - for(int i=1;iRefreshBoundingBox(); - - local.Enclose((*sub)->GetLocalBoundingBox()); - - ++sub; - } - - LocalBoundingBox=local; } - int SceneNode::GetComponents(ArrayList &comp_list,const ComponentManager *mgr) + LocalBoundingBox=local; + } + + int SceneNode::GetComponents(ArrayList &comp_list,const ComponentManager *mgr) + { + if(!mgr)return(-1); + if(ComponentIsEmpty())return(0); + + int result=0; + + for(Component *c:ComponentSet) { - if(!mgr)return(-1); - if(ComponentIsEmpty())return(0); - - int result=0; - - for(Component *c:ComponentList) + if(c->GetManager()==mgr) { - if(c->GetManager()==mgr) - { - comp_list.Add(c); - ++result; - } + comp_list.Add(c); + ++result; } - - return result; } - bool SceneNode::HasComponent(const ComponentManager *mgr) + return result; + } + + bool SceneNode::HasComponent(const ComponentManager *mgr) + { + if(!mgr)return(false); + if(ComponentIsEmpty())return(false); + + for(Component *c:ComponentSet) { - if(!mgr)return(false); - if(ComponentIsEmpty())return(false); - - for(Component *c:ComponentList) - { - if(c->GetManager()==mgr) - return(true); - } - - return(false); + if(c->GetManager()==mgr) + return(true); } - }//namespace graph -}//namespace hgl + + return(false); + } +}//namespace hgl::graph