Cogs.Core
SceneSystem.cpp
1#include "SceneSystem.h"
2#include "Components/Core/RenderComponent.h"
3
4#include "Foundation/ComponentModel/Entity.h"
5
6#include <functional>
7
9{
11 bool updateHierarchy = false;
12
13 needsPost = false;
14
15 for (const auto & sceneComponent : pool) {
16 if (!sceneComponent.isActive()) continue;
17 if (!sceneComponent.hasChanged()) continue;
18
19 needsPost = true;
20
21 sceneComponent.getContainer()->getComponents(renderComponents);
22
23 for (auto & renderComponent : renderComponents) {
24 renderComponent.setRenderFlag(RenderFlags::SelfVisibility, sceneComponent.visible);
25 renderComponent.setRenderFlag(RenderFlags::SelfPickable, sceneComponent.pickable);
26 }
27
28 if (!sceneComponent.children.empty()) {
29 // If component has children, we must propagate properties down the hierarchy. Since
30 // we don't have current parent-flags, we defer the traversal until we have plowed
31 // through all components and start at the roots.
32 updateHierarchy = true;
33 }
34 }
35
36 if (updateHierarchy) {
37 for (auto & sceneComponent : pool) {
38 if (sceneComponent.parent || sceneComponent.children.empty()) {
39 // Neither a root nor a parent node, skip
40 continue;
41 }
42
43 std::function<void(SceneComponent &, bool, bool)> updateChildren = [&](SceneComponent & component, bool parentVisible, bool parentPickable)
44 {
45 for (const auto & child : component.children) {
46 child->getComponents(renderComponents);
47
48 for (auto & childComponent : renderComponents) {
49 childComponent.setRenderFlag(RenderFlags::ParentVisibility, parentVisible);
50 childComponent.setRenderFlag(RenderFlags::ParentPickable, parentPickable);
51 }
52
53 auto childSceneComponent = child->getComponent<SceneComponent>();
54
55 if (childSceneComponent) {
56 childSceneComponent->parent = getHandle(&component);
57 updateChildren(*childSceneComponent, parentVisible && childSceneComponent->visible, parentPickable && childSceneComponent->pickable);
58 }
59 }
60 };
61
62 updateChildren(sceneComponent, sceneComponent.visible, sceneComponent.pickable);
63 }
64 }
65}
66
68{
69 if (!needsPost) return;
70
72}
73
74Cogs::Core::SceneState Cogs::Core::SceneSystem::getSceneState(const SceneComponent & sceneComponent)
75{
76 if (sceneComponent.parent) {
77 auto parentSceneComponent = sceneComponent.parent.resolveComponent<SceneComponent>();
78 auto parentState = getSceneState(*parentSceneComponent);
79
80 return SceneState{ parentState.visible && sceneComponent.visible, parentState.pickable && sceneComponent.pickable };
81 } else {
82 return SceneState{ sceneComponent.visible, sceneComponent.pickable };
83 }
84}
85
86void Cogs::Core::SceneSystem::updateState(SceneComponent & sceneComponent)
87{
88 auto parentState = sceneComponent.parent ? getSceneState(*sceneComponent.parent.resolveComponent<SceneComponent>()) : SceneState{ true, true };
89
90 ComponentModel::ComponentCollection<RenderComponent> collection;
91 sceneComponent.getContainer()->getComponents(collection);
92
93 for (auto & component : collection) {
94 component.setRenderFlag(RenderFlags::ParentVisibility, parentState.visible);
95 component.setRenderFlag(RenderFlags::ParentPickable, parentState.pickable);
96 component.setRenderFlag(RenderFlags::SelfVisibility, sceneComponent.visible);
97 component.setRenderFlag(RenderFlags::SelfPickable, sceneComponent.pickable);
98 }
99}
void postUpdate()
Perform post update logic in the system.
void update()
Updates the system state to that of the current frame.
ComponentPool< SceneComponent > pool
Pool of components managed by the system.
ComponentHandle getHandle(const SceneComponent *component)
Get a handle to the given Component instance.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Contains information on how the entity behaves in the scene.
std::vector< EntityPtr > children
Contains all child entities owned by this component.
bool visible
If the entity this component is a member of should be visible.
ComponentModel::ComponentHandle parent
Handle to the scene component of the parent entity.
bool pickable
If the entity this component is a member of should be pickable.
@ ParentVisibility
Parent visibility, used by the SceneSystem to toggle child entity visibility on/off.
@ ParentPickable
Parent pickable, used by the SceneSystem to toggle child entity pickable on/off.
@ SelfVisibility
Self visibility, used by the SceneSystem to toggle entity visibility on/off.
@ SelfPickable
Self pickable, used by the SceneSystem to toggle entity pickable on/off.
ComponentType * resolveComponent() const
Definition: Component.h:90