Cogs.Core
SwathIsoSystem.cpp
1#include "SwathIsoSystem.h"
2
3#include "Context.h"
4#include "EntityStore.h"
5#include "Components/Core/SubMeshRenderComponent.h"
6#include "Components/Core/SceneComponent.h"
7#include "Components/Appearance/MaterialComponent.h"
8#include "Systems/Core/TransformSystem.h"
9#include "Resources/MeshManager.h"
10#include "Resources/MaterialManager.h"
11#include "Services/TaskManager.h"
12
13#include "../Components/DataSetComponent.h"
14#include "../Components/WindowComponent.h"
15#include "../Components/BeamGroupComponent.h"
16#include "../Components/DataRefComponent.h"
17#include "../Systems/DataSetSystem.h"
18
19#include "Foundation/Logging/Logger.h"
20
22using namespace Cogs::Core::EchoSounder;
23
24#include "../Tasks/SwathIsoSurfacesBuildMeshTask.h"
25
27{
29
30 surfaceMaterial = context->materialManager->loadMaterial("MultibeamIsoMaterial.material");
31
32 context->materialManager->processLoading();
33
34 rangeKey = surfaceMaterial->getVec4Key("range");
35}
36
38{
39 surfaceMaterial = {};
40}
41
43{
44 bool activateMeshes = false;
45 for (auto & isoComp : pool) {
46 auto & isoData = getData(&isoComp);
47
48 const auto * winComp = isoComp.getComponent<WindowComponent>();
49 const auto * groupComp = isoComp.getComponent<BeamGroupComponent>();
50
51 if (!winComp || !groupComp || !groupComp->sane || groupComp->majorCount != 1) {
52 isoComp.setChanged();
53 continue;
54 }
55
56 // beamGroup->sane makes sure that we have data (and that it is sane).
57 const auto * dataRefComp = isoComp.getComponent<DataRefComponent>();
58 const auto * dataComp = dataRefComp->data->getComponent<DataSetComponent>();
59 const auto & dataData = dataSetSystem->getData(dataComp);
60
61 if (isoComp.hasChanged()) {
62
63 const auto layers = isoComp.thresholds.size();
64 isoComp.material->setVec4Property(rangeKey, glm::vec4(isoComp.uTextureRange.x,
65 1.f / std::max(std::numeric_limits<float>::min(), isoComp.uTextureRange.y - isoComp.uTextureRange.x),
66 isoComp.vTextureRange.x,
67 1.f / std::max(std::numeric_limits<float>::min(), isoComp.vTextureRange.y - isoComp.vTextureRange.x)));
68
69 const size_t o = isoData.layerMaterialInstances.size();
70 isoData.layerMaterialInstances.resize(layers);
71 for (size_t i = 0; i < layers; i++) {
72 if (o <= i) {
73 isoData.layerMaterialInstances[i] = context->materialInstanceManager->createMaterialInstance(surfaceMaterial);
74 }
75
76 isoData.layerMaterialInstances[i]->clone(isoComp.material.resolve());
77 if (isoComp.innerLayerOpaque && ((i + 1) == layers)) {
78 isoData.layerMaterialInstances[i]->setOpaque();
79 }
80 else {
81 isoData.layerMaterialInstances[i]->setTransparent();
82 }
83 if (isoComp.layerDepthBiasStep != 0.f) {
84 isoData.layerMaterialInstances[i]->options.depthBiasEnabled = true;
85 isoData.layerMaterialInstances[i]->options.depthBias.slope = 0.f;
86 isoData.layerMaterialInstances[i]->options.depthBias.constant = i*isoComp.layerDepthBiasStep;
87 isoData.layerMaterialInstances[i]->options.depthBias.clamp = 100000.f;
88 }
89 }
90 }
91
92 bool updateParams = isoData.thresholds != isoComp.thresholds ||
93 (isoData.capSeparation != isoComp.capSeparation) ||
94 (isoData.flipOrientation != isoComp.flipOrientation) ||
95 (isoData.innerLayerOpaque != isoComp.innerLayerOpaque) ||
96 (isoData.seabedClipOffset != isoComp.seabedClipOffset) ||
97 ((isoData.overflowThreshold != isoComp.overflowThreshold) && !(std::isnan(isoData.overflowThreshold) && std::isnan(isoComp.overflowThreshold))) ||
98 ((isoData.minVerticalDepth != isoComp.minVerticalDepth) && !(std::isnan(isoData.minVerticalDepth) && std::isnan(isoComp.minVerticalDepth))) ||
99 ((isoData.maxVerticalDepth != isoComp.maxVerticalDepth) && !(std::isnan(isoData.maxVerticalDepth) && std::isnan(isoComp.maxVerticalDepth))) ||
100 (isoData.beamGroupGen != groupComp->gen) ||
101 (isoData.beamSpacing != winComp->beamSpacing) ||
102 (isoData.depthSpacing != winComp->depthSpacing);
103
104 if (isoData.pathSpacing != winComp->pathSpacing)
105 {
106 //clears old data immediately, view will be empty until new data is ready
107 isoData.pathSpacing = winComp->pathSpacing;
108 isoData.resamplingPositions.clear(isoData.pathSpacing, context->variables->get("echo.maxPathUpsample")->getFloat());
109 isoData.chunks.clear();
110 isoData.meshManager.clear();
111 updateParams = true;
112 }
113 if (updateParams)
114 {
115 //keeps old data until new data is ready
116 isoData.thresholds = isoComp.thresholds;
117 isoData.capSeparation = isoComp.capSeparation;
118 isoData.flipOrientation = isoComp.flipOrientation;
119 isoData.innerLayerOpaque = isoComp.innerLayerOpaque;
120 isoData.seabedClipOffset = isoComp.seabedClipOffset;
121 isoData.overflowThreshold = isoComp.overflowThreshold;
122 isoData.minVerticalDepth = isoComp.minVerticalDepth;
123 isoData.maxVerticalDepth = isoComp.maxVerticalDepth;
124 isoData.beamSpacing = winComp->beamSpacing;
125 isoData.depthSpacing = winComp->depthSpacing;
126 isoData.beamGroupGen = groupComp->gen;
127 isoData.meshManager.updateCurrent();
128 isoData.runMeshManager = true;
129 }
130
131 bool resampleSitesChanged;
132 const auto * sceneComp = isoComp.getComponent<SceneComponent>();
133 if (sceneComp->visible) {
134 resampleSitesChanged = isoData.resamplingPositions.update(winComp, dataComp, &dataData);
135 }
136 else {
137 resampleSitesChanged = isoData.resamplingPositions.clear(isoData.pathSpacing, context->variables->get("echo.maxPathUpsample")->getFloat());
138 }
139 if (resampleSitesChanged) {
140 if (isoData.chunks.update(isoData.resamplingPositions)) {
141 isoData.runMeshManager = true;
142 }
143 }
144
145 if (isoData.meshManager.ready() && isoData.runMeshManager) {
146 auto * containerPtr = isoComp.getContainer();
147
148
149 SwathPathMeshManager::CreateBuildFunc createBuildFunc =
150 [context, groupComp, &isoComp, &isoData, &dataData](MeshHandle& mesh, uint32_t chunkIndex) -> TaskFunction
151 {
152 return SwathIsoSurfacesBuildMeshTask(context, mesh, chunkIndex, *groupComp, isoComp, isoData, dataData);
153 };
154
155 SwathPathMeshManager::CreateEntity createEntity =
156 [context, containerPtr]() -> EntityPtr
157 {
158 return context->store->createChildEntity("EchoChunkSurface", containerPtr);
159 };
160
161 SwathPathMeshManager::ActivateEntity activateEntity =
162 [&isoData](EntityPtr e, uint32_t /*ix*/)
163 {
164 auto mshRndCmp = e->getComponent<SubMeshRenderComponent>();
165
166 mshRndCmp->materials.resize(isoData.layerMaterialInstances.size());
167
168 for (size_t i = 0; i < isoData.layerMaterialInstances.size(); i++) {
169 mshRndCmp->materials[i] = isoData.layerMaterialInstances[i];
170 }
171
172 mshRndCmp->setChanged();
173 };
174
175 isoData.runMeshManager = isoData.meshManager.update(context,
176 isoData.chunks,
177 createBuildFunc,
178 createEntity,
179 activateEntity);
180 activateMeshes = true;
181 }
182 if (!isoData.meshManager.ready()) {
183 context->engine->triggerUpdate();
184 }
185 }
186
187 // Swap meshes so that they participate when creating building boxes.
188 if(activateMeshes) {
189 context->engine->swapResources();
190 }
191}
192
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
class Entity * getContainer() const
Get the container currently owning this component instance.
Definition: Component.h:151
Context * context
Pointer to the Context instance the system lives in.
virtual void initialize(Context *context)
Initialize the system.
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
class EntityStore * store
Entity store.
Definition: Context.h:231
std::unique_ptr< class Variables > variables
Variables service instance.
Definition: Context.h:180
std::unique_ptr< class Engine > engine
Engine instance.
Definition: Context.h:222
EntityPtr createChildEntity(const StringView &type, ComponentModel::Entity *parent, const StringView &name=StringView())
Create a new Entity, parenting it to the given parent.
Contains information on how the entity behaves in the scene.
Renders a mesh with flexible submesh usage.
std::vector< MaterialInstanceHandle > materials
Materials used to render individual sub-meshes.
std::function< void()> TaskFunction
Type of task function used by the task manager.
Definition: TaskManager.h:38
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
void cleanup(Context *context) override
Provided for custom cleanup logic in derived systems.
void initialize(Context *context) override
Initialize the system.