Cogs.Core
DensityFieldSystem.cpp
1#include "ExtensionRegistry.h"
2#include "Resources/MeshManager.h"
3#include "Resources/MaterialManager.h"
4#include "Components/Core/MeshComponent.h"
5#include "Components/Core/SubMeshRenderComponent.h"
6#include "Components/Core/SceneComponent.h"
7#include "Context.h"
8
9#include "Components/PointDataComponent.h"
10
11#include "../Tasks/DensityFieldTask.h"
12#include "DensityFieldSystem.h"
13
14#include "Foundation/ComponentModel/Entity.h"
15
17{
18 for (auto & fieldComp : pool) {
19 if(!fieldComp.pointData) continue;
20
21 auto & fieldData = getData(&fieldComp);
22
23 if (!fieldData.persistentData) fieldData.persistentData = std::make_shared<DensityFieldTaskData>();
24
25 auto pointComp = fieldComp.pointData->getComponent<PointDataComponent>();
26 if (!pointComp) continue;
27
28 auto sceneComp = fieldComp.getComponent<SceneComponent>();
29 auto meshComp = fieldComp.getComponent<MeshComponent>();
30
31 if (pointComp->hasChanged()
32 || (fieldData.pointPositionGeneration != pointComp->positions.getGeneration())
33 || (fieldData.pointDataGeneration != pointComp->data.getGeneration())
34 || sceneComp->hasFieldChanged(&SceneComponent::visible))
35 {
36 fieldData.needsUpdate = true;
37 }
38
39 if (fieldComp.hasChanged()) {
40 if (glm::any(glm::notEqual(fieldData.resolution, fieldComp.resolution))) {
41 fieldData.resolution = fieldComp.resolution;
42 fieldData.needsUpdate = true;
43 }
44 }
45
46 if (!pointComp->positions) {
47 meshComp->meshHandle = {};
48 meshComp->setChanged();
49 continue;
50 }
51
52 // If we have the singular reference, no tasks are working.
53 if (fieldData.persistentData.use_count() == 1) {
54
55 // If context is set, a task has been triggered.
56 if (fieldData.persistentData->context != nullptr) {
57 fieldData.persistentData->context = nullptr;
58
59 meshComp->meshHandle = fieldData.persistentData->mesh;
60 meshComp->setChanged();
61
62 auto meshRenderComp = fieldComp.getComponent<SubMeshRenderComponent>();
63 meshRenderComp->materials.resize(fieldData.persistentData->thresholds.size());
64
65 for (size_t i = 0; i < fieldData.persistentData->thresholds.size(); i++) {
66 if (!meshRenderComp->materials[i]) {
67 meshRenderComp->materials[i] = context->materialInstanceManager->createMaterialInstance(context->materialManager->getDefaultMaterial());
68 }
69
70 if (fieldComp.innerLayerOpaque && i == 0) {
71 meshRenderComp->materials[i]->setOpaque();
72 } else {
73 meshRenderComp->materials[i]->setTransparent();
74 }
75 meshRenderComp->materials[i]->clone(fieldComp.material.resolve());
76
77 if (meshRenderComp->materials[i]->isDefaultMaterial()) {
78 meshRenderComp->materials[i]->setPermutation("Default");
79 meshRenderComp->materials[i]->setVariant("Textured", true);
80 meshRenderComp->materials[i]->setVariant("EnableLighting", true);
81 }
82
83 meshRenderComp->materials[i]->setTransparent();
84 meshRenderComp->materials[i]->options.depthBiasEnabled = true;
85 meshRenderComp->materials[i]->options.depthBias.slope = 0.f;
86 meshRenderComp->materials[i]->options.depthBias.constant = i*fieldComp.layerDepthBiasStep;
87 meshRenderComp->materials[i]->options.depthBias.clamp = 100000.f;
88 }
89 meshRenderComp->setChanged();
90 }
91
92 // Check if it is time to regenerate mesh.
93 if (fieldData.needsUpdate) {
94 auto r = fieldData.resolution;
95
96 fieldData.pointPositionGeneration = pointComp->positions.getGeneration();
97 if (pointComp->data) {
98 fieldData.pointDataGeneration = pointComp->data.getGeneration();
99 }
100
101 if (fieldComp.thresholds.empty()
102 || pointComp->positions.empty()
103 || (std::min(std::min(r.x, r.y), r.z) == 0)
104 || !sceneComp->visible)
105 {
106 // Invalid setup, just set an empty mesh.
107 meshComp->meshHandle = MeshHandle::NoHandle;
108 meshComp->setChanged();
109 continue;
110 } else {
111 // Set up for a new task
112 fieldData.persistentData->update(context,
113 fieldComp,
114 fieldData,
115 pointComp->positions,
116 pointComp->data);
117 // and fire and forget.
118 DensityFieldTask task{ fieldData.persistentData };
119 context->taskManager->enqueue(context->taskManager->create(context->taskManager->ResourceQueue, task));
120 }
121 }
122 }
123 }
124}
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
Context * context
Pointer to the Context instance the system lives in.
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
std::unique_ptr< class TaskManager > taskManager
TaskManager service instance.
Definition: Context.h:186
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
Definition: MeshComponent.h:15
Contains information on how the entity behaves in the scene.
bool visible
If the entity this component is a member of should be visible.
Renders a mesh with flexible submesh usage.
std::vector< MaterialInstanceHandle > materials
Materials used to render individual sub-meshes.
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.