Cogs.Core
BadgeSetSystem.cpp
1#include "BadgeSetSystem.h"
2#include "Context.h"
3
4#include "Systems/Core/CameraSystem.h"
5#include "ViewContext.h"
6#include "Services/DPIService.h"
7
8#include "Components/Core/MeshComponent.h"
9#include "Components/Core/SceneComponent.h"
10#include "Components/Core/TransformComponent.h"
11#include "Components/Core/InstancedMeshRenderComponent.h"
12#include "Resources/MaterialManager.h"
13#include "Resources/MeshManager.h"
14#include "Resources/VertexFormats.h"
15#include "Systems/Core/TransformSystem.h"
16#include "Resources/TextureManager.h"
17
18#include "Foundation/Logging/Logger.h"
19
20using namespace Cogs::Geometry;
21
22namespace {
23 Cogs::Logging::Log gLogger = Cogs::Logging::getLogger("BadgeSetSystem");
24}
25
26Cogs::Core::BadgeSetSystem::~BadgeSetSystem()
27{
28}
29
32 generateMesh(context);
33}
34
35void Cogs::Core::BadgeSetSystem::generateMesh(Context* context)
36{
37 quadMesh = context->meshManager->create();
38
39 std::vector<glm::vec3> points = {
40 { 0, 0, 0 },
41 { 1, 0, 0 },
42 { 1, 1, 0 },
43 { 0, 1, 0 },
44 };
45
46 std::vector<glm::vec2> texCoords = {
47 { 0, 0 },
48 { 1, 0 },
49 { 1, 1 },
50 { 0, 1 }
51 };
52
53 std::vector<uint32_t> indices = { 0,1,2,2,3,0 };
54
55 quadMesh->primitiveType = Cogs::PrimitiveType::TriangleList;
56 quadMesh->setPositions(points);
57 quadMesh->setIndexes(indices);
58 quadMesh->setTexCoords(texCoords);
59
60 instMaterial = context->materialManager->loadMaterial("BadgeMaterial.material");
61 context->materialManager->processLoading();
62
63 Material* mat = instMaterial.resolve();
64 viewPlaneLocalKey = mat->getFloatKey("viewPlaneLocal");
65 viewXLocalKey = mat->getFloatKey("viewXLocal");
66 viewYLocalKey = mat->getFloatKey("viewYLocal");
67 pointSizeKey = mat->getVec2Key("pointSize");
68 anchorPointOffsetKey = mat->getVec2Key("anchorPointOffset");
69 nearCutoffKey = mat->getVec2Key("nearCutoff");
70 farCutoffKey = mat->getVec2Key("farCutoff");
71 nearVisibilityLimitKey = mat->getFloatKey("nearVisibilityLimit");
72 farVisibilityLimitKey = mat->getFloatKey("farVisibilityLimit");
73 outputAlphaValueKey = mat->getFloatKey("outputAlphaValue");
74
75 iconTextureKey = mat->getTextureKey("iconMap");
76 styleTextureKey = mat->getTextureKey("styleMap");
77 digitTextureKey = mat->getTextureKey("digitMap");
78
79 if (!picker) {
80 picker = std::make_unique<BadgeSetPicker>(this);
81 if (picker) {
82 LOG_DEBUG(gLogger, "Registered badge set picker extension");
83 context->rayPicking->addPickable(picker.get());
84 }
85 else {
86 LOG_ERROR(gLogger, "Badge set picker extension could not be initialized!");
87 }
88 }
89}
90
92{
93 //Get refs here as it will be the same for all comps in the system pool
94 const CameraData& mainCamData = context->cameraSystem->getMainCameraData();
95
96 for (BadgeSetComponent& badgeSetComp : pool) {
97 if (!badgeSetComp.isActive()) {
98 continue;
99 }
100
101 InstancedMeshRenderComponent* instancedMeshRenderComponent = badgeSetComp.getComponent<InstancedMeshRenderComponent>();
102 if (!instancedMeshRenderComponent) {
103 LOG_WARNING_ONCE(gLogger, "Missing InstancedMeshRendererComponent, skipping Entity update on this system");
104 continue;
105 }
106
107 BadgeSetData& data = getData(&badgeSetComp);
108
109 if (!data.texturesLoaded) {
110 if ((badgeSetComp.styleTexture && badgeSetComp.iconTexture && badgeSetComp.digitTexture)) {
111 SceneComponent* sceneComponent = badgeSetComp.getComponent<SceneComponent>();
112 if (!badgeSetComp.styleTexture->isActive() ||
113 !badgeSetComp.iconTexture->isActive() ||
114 !badgeSetComp.digitTexture->isActive()) {
115 sceneComponent->visible = false;
116 instancedMeshRenderComponent->unsetRenderFlag(Cogs::Core::RenderFlags::SelfVisibility);
117 }
118 else {
119 data.texturesLoaded = true;
120 sceneComponent->visible = true;
121 instancedMeshRenderComponent->setRenderFlag(Cogs::Core::RenderFlags::SelfVisibility);
122 }
123 }
124 }
125
126 if (!data.initialized) {
127
128 MeshComponent* meshComponent = badgeSetComp.getComponent<MeshComponent>();
129 if (!meshComponent) {
130 LOG_WARNING_ONCE(gLogger, "Missing MeshComponent, skipping Entity update on this system");
131 continue;
132 }
133
134 meshComponent->meshHandle = quadMesh;
135 meshComponent->setChanged();
136
138
139 if (!HandleIsValid(badgeSetComp.iconTexture)) {
140 LOG_WARNING_ONCE(gLogger, "icon texture provided is not a valid texture handle");
141 continue;
142 }
143 if (!HandleIsValid(badgeSetComp.digitTexture)) {
144 LOG_WARNING_ONCE(gLogger, "digit texture provided is not a valid texture handle");
145 continue;
146 }
147
148 if (badgeSetComp.positions.size() != badgeSetComp.icons.size() || badgeSetComp.positions.size() != badgeSetComp.styles.size())
149 {
150 LOG_WARNING_ONCE(gLogger, "Positions, icons and styles must contain the same number of elements");
151 continue;
152 }
153
154 std::vector<glm::vec4> interleavedData;
155 interleavedData.resize(badgeSetComp.positions.size());
156 for (size_t i = 0; i < badgeSetComp.positions.size(); i++) {
157 interleavedData[i] = glm::vec4(badgeSetComp.numbers[i], badgeSetComp.styles[i], 0, badgeSetComp.icons[i]);
158 }
159
160 instancedMeshRenderComponent->instanceMesh = context->meshManager->create();
161 instancedMeshRenderComponent->instanceMesh->setInstancePositions(badgeSetComp.positions);
162
163 instancedMeshRenderComponent->instanceMesh->setInstanceColors(interleavedData);
164
165 instancedMeshRenderComponent->startInstance = 0;
166 instancedMeshRenderComponent->instanceCount = static_cast<uint32_t>(-1);
167 instancedMeshRenderComponent->startIndex = 0;
168
169 data.materialInstance = instancedMeshRenderComponent->material ? instancedMeshRenderComponent->material : context->materialInstanceManager->createMaterialInstance(instMaterial);
170 data.materialInstance->setOption("CullMode", "None");
171 data.materialInstance->setVariant("AlphaTest", "None");
172
173 instancedMeshRenderComponent->material = data.materialInstance;
174 instancedMeshRenderComponent->setChanged();
175 data.initialized = true;
176 }
177
178 TransformComponent* trComp = badgeSetComp.getComponent<TransformComponent>();
179
180 // We use the main cam to determine view-dependent orientation etc. This is usually the camera that is used
181 // for rendering. In VR applications, we have a camera per eye, and what they see have to agree, so by using
182 // the main camera to define orientation (and not the the camera used for rendering) they agree.
183 // NOTE: The vec/matrix multiplications here simplify the expansion
184 // ( ([0,1,0,0] M^-1) )^t = (M^-1)^t [0,1,0,0]^t of a more traditional space transformation
185 glm::mat4 viewFromLocal = mainCamData.viewMatrix * context->transformSystem->getLocalToWorld(trComp);
186 data.viewPlaneLocal = glm::vec4(0.f, 0.f, -1.f, 0.f) * viewFromLocal;
187 data.viewXLocal = glm::vec3(1.f, 0.f, 0.f) * glm::mat3(viewFromLocal);
188 data.viewYLocal = glm::vec3(0.f, 1.f, 0.f) * glm::mat3(viewFromLocal);
189 //Equivalent to doing, we just grab the key representing the literal string value.
190 //data.materialInstance->setVec4Property("viewPlaneLocal", data.viewPlaneLocal);
191 data.materialInstance->setVec4Property(viewPlaneLocalKey, data.viewPlaneLocal);
192
193 data.materialInstance->setVec4Property(viewXLocalKey, glm::vec4(data.viewXLocal, 1.f));
194 data.materialInstance->setVec4Property(viewYLocalKey, glm::vec4(data.viewYLocal, 1.f));
195 // Near and far distances are relative to the main camera (distance from viewPLaneLocal)
196 data.materialInstance->setFloatProperty(nearVisibilityLimitKey, badgeSetComp.nearVisibilityLimit);
197 data.materialInstance->setFloatProperty(farVisibilityLimitKey, badgeSetComp.farVisibilityLimit);
198 data.materialInstance->setFloatProperty(outputAlphaValueKey, badgeSetComp.outputAlphaValue);
199
200 // Near and far cutoff points are relative to the main camera (distance from viewPlaneLocal)
201 data.materialInstance->setFloatProperty(nearCutoffKey, badgeSetComp.nearScalingCutoff);
202 data.materialInstance->setFloatProperty(farCutoffKey, badgeSetComp.farScalingCutoff);
203 // Point size is in object space units.
204 data.materialInstance->setVec2Property(pointSizeKey, glm::vec2(badgeSetComp.badgeSize));
205
206 data.materialInstance->setVec2Property(anchorPointOffsetKey, glm::vec2(-badgeSetComp.anchorPoint.x, -badgeSetComp.anchorPoint.y));
207
208 data.materialInstance->setVariant("Textured", true);
209
210 data.materialInstance->setTextureAddressMode(iconTextureKey, SamplerState::Clamp);
211 data.materialInstance->setTextureProperty(iconTextureKey, badgeSetComp.iconTexture);
212
213 data.materialInstance->setTextureAddressMode(styleTextureKey, SamplerState::Clamp);
214 data.materialInstance->setTextureProperty(styleTextureKey, badgeSetComp.styleTexture);
215
216 data.materialInstance->setTextureAddressMode(digitTextureKey, SamplerState::Clamp);
217 data.materialInstance->setTextureProperty(digitTextureKey, badgeSetComp.digitTexture);
218
219 if (badgeSetComp.hasFieldChanged(&BadgeSetComponent::positions) || badgeSetComp.hasFieldChanged(&BadgeSetComponent::icons) || badgeSetComp.hasFieldChanged(&BadgeSetComponent::styles)) {
220 if (badgeSetComp.positions.size() != badgeSetComp.icons.size() || badgeSetComp.positions.size() != badgeSetComp.styles.size())
221 {
222 LOG_WARNING_ONCE(gLogger, "Positions, icons and styles must contain the same number of elements");
223 continue;
224 }
225
226 if (!instancedMeshRenderComponent->instanceMesh) {
227 instancedMeshRenderComponent->instanceMesh = context->meshManager->create();
228 }
229 instancedMeshRenderComponent->instanceMesh->clear();
230 instancedMeshRenderComponent->instanceMesh->setInstancePositions(badgeSetComp.positions);
231
232 std::vector<glm::vec4> interleavedData;
233 interleavedData.resize(badgeSetComp.positions.size());
234 for (size_t i = 0; i < badgeSetComp.positions.size(); i++) {
235 interleavedData[i] = glm::vec4(badgeSetComp.numbers[i], badgeSetComp.styles[i], 0, badgeSetComp.icons[i]);
236 }
237
238 instancedMeshRenderComponent->instanceMesh->setInstanceColors(interleavedData);
239 }
240 }
241}
242
244{
245
246}
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
virtual void initialize(Context *context) override
Initialize the system.
virtual void cleanup(Context *context) override
Provided for custom cleanup logic in derived systems.
virtual void initialize(Context *context)
Initialize the system.
void update()
Updates the system state to that of the current frame.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
std::unique_ptr< class RayPicking > rayPicking
RayPicking service instance.
Definition: Context.h:213
uint32_t startIndex
Start vertex index to render from.
uint32_t instanceCount
Instance count. uint32_t(-1) to draw all remaining instances.
MaterialInstanceHandle material
Material instance used to render the mesh.
MeshHandle instanceMesh
Mesh containing instancing data.
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
Definition: MeshComponent.h:15
MeshHandle meshHandle
Handle to a Mesh resource to use when rendering.
Definition: MeshComponent.h:29
constexpr void unsetRenderFlag(RenderFlags flag)
Unset the given flag.
constexpr void setRenderFlag(RenderFlags flag)
Sets the given flag.
Contains information on how the entity behaves in the scene.
bool visible
If the entity this component is a member of should be visible.
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
Log implementation class.
Definition: LogManager.h:140
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ 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.
Contains geometry calculations and generation.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
@ TriangleList
List of triangles.
Component for showing lots of badges.
std::vector< glm::vec3 > positions
Badge positions.
std::vector< int > icons
Icon (index) to be rendered on top of style.
std::vector< int > styles
Style (index) used for background behind icon.
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Definition: CameraSystem.h:67
void clear()
Clear all data from the Mesh, returning it to its initial non-indexed state with no streams and no su...
Definition: Mesh.cpp:27
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
Definition: SamplerState.h:17