Cogs.Core
HighlightRegionSystem.cpp
1#include "Foundation/Logging/Logger.h"
2
3#include "Systems/Core/TransformSystem.h"
4
5#include "Resources/MaterialManager.h"
6
7#include "Context.h"
8
9#include "HighlightRegionSystem.h"
10#include "HighlightRegionBounds.h"
11#include "HighlightRegionPicker.h"
12#include "HighlightRegionRenderer.h"
13
14namespace {
15 using namespace Cogs::Core;
16 Cogs::Logging::Log logger = Cogs::Logging::getLogger("HighlightRegion");
17
18}
19
21{
22 if (!material || !material->isActive()) return;
23
24
25 for (HighlightRegionComponent& regionComp : pool) {
26 HighlightRegionData& data = getData(&regionComp);
27 bool update = regionComp.hasChanged();
28
29 if (!data.materialInstance) {
30 data.materialInstance = context->materialInstanceManager->createMaterialInstance(material);
31 if (VariableKey key = material->getTextureKey("offscreenDepth"); key != NoProperty) {
32 data.materialInstance->setTextureFilterMode(key, SamplerState::FilterMode::MinMagMipPoint);
33 }
34 update = true;
35 }
36
37 if (TransformComponent* trComp = regionComp.getComponent<TransformComponent>(); trComp) {
38 data.worldMatrix = context->transformSystem->getLocalToWorld(trComp);
39 }
40
41 if (update) {
42 data.materialInstance->setVariant("DebugForceVisible", regionComp.debugForceVisible);
43 data.materialInstance->setVariant("DebugShowTriangles", regionComp.debugShowTriangles);
44 data.materialInstance->setVariant("DebugDiscardBehindNearNotEye", regionComp.debugDiscardBehindNearNotEye);
45
46 data.debugForceNoSplit = regionComp.debugForceNoSplit;
47 data.materialInstance->setVariant("SplitCube", !data.debugForceNoSplit);
48
49 size_t instanceCount = std::min(regionComp.id.size(),
50 std::min(std::min(regionComp.position.size(),
51 regionComp.rotation.size()),
52 std::min(regionComp.scale.size(),
53 regionComp.color.size())));
54 const float alpha = regionComp.alpha;
55 constexpr float sqrt3 = 1.74f;
56 data.instanceData.resize(instanceCount);
57 glm::vec3 boundsMin = glm::vec3(std::numeric_limits<float>::max());
58 glm::vec3 boundsMax = glm::vec3(-std::numeric_limits<float>::max());
59 for (size_t i = 0; i < instanceCount; i++) {
60 const glm::quat& r = regionComp.rotation[i];
61 const glm::vec3& p = regionComp.position[i];
62 const glm::vec3& s = regionComp.scale[i];
63 const glm::vec4& c = regionComp.color[i];
64
65 float radius = sqrt3 * std::max(s.x, std::max(s.y, s.z));
66 boundsMin = glm::min(boundsMin, p - glm::vec3(radius));
67 boundsMax = glm::max(boundsMax, p + glm::vec3(radius));
68
69 // R[row][col]
70 const glm::mat3 R = glm::mat3_cast(r);
71
72 data.instanceData[i].data0 = glm::mat4(R[0][0], R[1][0], R[2][0], p.x,
73 R[0][1], R[1][1], R[2][1], p.y,
74 R[0][2], R[1][2], R[2][2], p.z,
75 c.r, c.g, c.b, c.a * alpha);
76
77 data.instanceData[i].data1 = glm::mat4(s.x, s.y, s.z, 0.f,
78 0.f, 0.f, 0.f, 0.f,
79 0.f, 0.f, 0.f, 0.f,
80 0.f, 0.f, 0.f, 0.f);
81 }
82 data.boundsMin = boundsMin;
83 data.boundsMax = boundsMax;
84 data.instanceDataUpdated = true;
85 }
86
87 }
88}
89
91{
92 if (pool.size() == 0) {
93 if (!material) {
94 material = context->materialManager->loadMaterial("HighlightRegionMaterial.material");
95 }
96
97 assert(bounds == nullptr);
98 bounds = new HighlightRegionBounds(this);
99 context->bounds->addBoundsExtension(bounds);
100
101 assert(picker == nullptr);
102 picker = new HighlightRegionPicker(this);
103 context->rayPicking->addPickable(picker);
104
105 renderer = new HighlightRegionRenderer(this);
106 context->renderer->registerExtension(renderer);
107
108 LOG_DEBUG(logger, "Registered bounds, picker, and renderer extensions");
109 }
111 return handle;
112}
113
115{
117 if (pool.size() == 0) {
118 assert(bounds);
119 context->bounds->removeBoundsExtension(bounds);
120 delete bounds;
121 bounds = nullptr;
122
123 assert(picker);
124 context->rayPicking->removePickable(picker);
125 delete picker;
126 picker = nullptr;
127
128 assert(renderer);
129 context->renderer->unregisterExtension(renderer);
130 delete renderer;
131 renderer = nullptr;
132
133 LOG_DEBUG(logger, "Unregistered bounds, picker, and renderer extensions");
134 }
135}
ComponentType * getComponent() const
Definition: Component.h:159
virtual ComponentHandle createComponent()
Create a new component instance.
Context * context
Pointer to the Context instance the system lives in.
virtual void destroyComponent(ComponentHandle)
Destroy the component held by the given handle.
void update()
Updates the system state to that of the current frame.
ComponentPool< ComponentType > pool
Pool of components managed by the system.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
Log implementation class.
Definition: LogManager.h:140
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
uint16_t VariableKey
Used to lookup material properties.
Definition: Resources.h:46
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Handle to a Component instance.
Definition: Component.h:67
void destroyComponent(ComponentHandle component) override
ComponentHandle createComponent() override
@ MinMagMipPoint
Point sampling for both minification and magnification.
Definition: SamplerState.h:33