diff --git a/inc/hgl/WorkObject.h b/inc/hgl/WorkObject.h index c870ff32..653e51f0 100644 --- a/inc/hgl/WorkObject.h +++ b/inc/hgl/WorkObject.h @@ -32,10 +32,10 @@ namespace hgl //以下数据均取自RenderFramework - graph::RenderResource *db=nullptr; //暂时的,未来会被更好的机制替代 + graph::RenderResource * db =nullptr; //暂时的,未来会被更好的机制替代 - graph::Scene * scene=nullptr; //场景 - graph::Renderer * renderer=nullptr; //渲染器 + graph::Scene * scene =nullptr; //场景 + graph::Renderer * renderer=nullptr; //渲染器 public: diff --git a/inc/hgl/graph/Scene.h b/inc/hgl/graph/Scene.h index 56f6d631..7b3df7ae 100644 --- a/inc/hgl/graph/Scene.h +++ b/inc/hgl/graph/Scene.h @@ -2,6 +2,7 @@ #include #include +#include namespace hgl::graph { @@ -17,6 +18,10 @@ namespace hgl::graph SceneNode *root_node; ///<场景根节点 + protected: // event dispatcher + + io::EventDispatcher event_dispatcher; ///<事件分发器 + public: const U8String & GetSceneName()const{return SceneName;} ///<获取场景名称 @@ -27,13 +32,18 @@ namespace hgl::graph Scene() { - root_node=new SceneNode; + root_node=new SceneNode(this); } virtual ~Scene() { SAFE_CLEAR(root_node); } + + io::EventDispatcher *GetEventDispatcher() ///<获取事件分发器 + { + return &event_dispatcher; + } };//class Scene bool RegisterScene(Scene *sw); ///<注册场景 diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index b566559f..0674ef63 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -13,6 +13,10 @@ namespace hgl::io namespace hgl::graph { + class Scene; //场景主类 + //每个SceneNode都要记录Scene来区分自己属于那个场景 + //这个场景可能是一个确实是一个场景,也有可能只是一个StaticMesh + using SceneNodeID =int64; using SceneNodeList =ObjectList; @@ -26,11 +30,17 @@ namespace hgl::graph */ class SceneNode:public SceneOrient ///场景节点类 { + friend class Scene; + + Scene *main_scene=nullptr; ///<主场景 + SceneNode *parent_node=nullptr; ///<上级节点 SceneNodeID node_id=-1; ///<节点ID SceneNodeName node_name; ///<节点名称 + void OnChangeScene(Scene *); + protected: AABB bounding_box; ///<绑定盒 @@ -49,22 +59,30 @@ namespace hgl::graph public: + Scene *GetScene()const{ return main_scene; } ///<取得主场景 + const SceneNodeID & GetNodeID ()const { return node_id; } ///<取得节点ID const SceneNodeName & GetNodeName ()const { return node_name; } ///<取得节点名称 const SceneNodeList & GetChildNode()const { return child_nodes; } ///<取得子节点列表 - public: + protected: SceneNode(const SceneNode &)=delete; SceneNode(const SceneNode *)=delete; - using SceneOrient::SceneOrient; ///<继承构造函数 + SceneNode():SceneOrient(){} + SceneNode(Scene *s):SceneOrient(),main_scene(s){} ///<从Scene构造 + SceneNode(Scene *s,const SceneOrient &so):SceneOrient(so),main_scene(s){} ///<从SceneOrient复制构造 + SceneNode(Scene *s,const Matrix4f &mat):SceneOrient(mat),main_scene(s){} ///<从Matrix4f复制构造 + + public: + virtual ~SceneNode(); public: - virtual SceneNode * CreateNode()const{return(new SceneNode);} ///<创建一个同类的节点对象 + virtual SceneNode * CreateNode()const{return(new SceneNode(GetScene()));} ///<创建一个同类的节点对象 virtual void DuplicationChildNodes(SceneNode *node) const ///<复制子节点到指定节点 { @@ -97,7 +115,7 @@ namespace hgl::graph { SceneOrient::Clear(); - parent_node=nullptr; + SetParent(nullptr); //清除父节点 bounding_box.SetZero(); local_bounding_box.SetZero(); @@ -113,7 +131,16 @@ namespace hgl::graph return(true); } - void SetParent(SceneNode *sn) {parent_node=sn;} + virtual void SetParent(SceneNode *sn) + { + if(parent_node==sn) + return; //如果父节点没有变化,则不需要处理 + + parent_node=sn; + + OnChangeScene(sn?sn->GetScene():nullptr); + } + SceneNode * GetParent() noexcept{return parent_node;} const SceneNode * GetParent()const noexcept{return parent_node;} diff --git a/src/SceneGraph/scene/SceneNode.cpp b/src/SceneGraph/scene/SceneNode.cpp index 182e750a..a12f298f 100644 --- a/src/SceneGraph/scene/SceneNode.cpp +++ b/src/SceneGraph/scene/SceneNode.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace hgl::graph { @@ -117,4 +118,27 @@ namespace hgl::graph c->OnDetach(this); } } + + void SceneNode::OnChangeScene(Scene *new_scene) + { + if(main_scene==new_scene) + return; + + auto self_ep=GetEventDispatcher(); + + if(self_ep) + { + if(main_scene) + { + main_scene->GetEventDispatcher()->RemoveChildDispatcher(self_ep); //从旧的场景中移除事件分发器 + } + + if(new_scene) + { + new_scene->GetEventDispatcher()->AddChildDispatcher(self_ep); //添加到新的场景中 + } + } + + main_scene=new_scene; + } }//namespace hgl::graph