1#include "EchoSounderExtension.h"
3#include "Bridge/Bridge.h"
6#include "ViewContext.h"
8#include "EntityDefinitions.h"
9#include "EntityStore.h"
10#include "ExtensionRegistry.h"
11#include "Components/DataRefComponent.h"
12#include "Components/DataSetComponent.h"
13#include "Components/WindowComponent.h"
14#include "Components/LocationComponent.h"
15#include "Components/PingOutlineComponent.h"
16#include "Components/BeamGroupComponent.h"
17#include "Components/PingIsoComponent.h"
18#include "Components/SwathBottomComponent.h"
19#include "Components/SwathIsoComponent.h"
20#include "Components/OctProviderComponent.h"
21#include "Components/UniformGridComponent.h"
22#include "Components/UniformGridIsoComponent.h"
23#include "Resources/ResourceStore.h"
24#include "Renderer/IRenderer.h"
25#include "Serialization/EntityReader.h"
26#include "Services/Variables.h"
27#include "Systems/DataSetSystem.h"
28#include "Systems/PingIsoSystem.h"
29#include "Systems/SwathBottomSystem.h"
30#include "Systems/SwathIsoSystem.h"
31#include "Systems/OctProviderSystem.h"
32#include "Systems/UniformGridSystem.h"
34#include "Rendering/ICapabilities.h"
35#include "Rendering/IGraphicsDevice.h"
37#include "Foundation/Logging/Logger.h"
38#include "Foundation/Platform/IO.h"
43#include <glm/gtc/type_ptr.hpp>
75int echosounderSetConfig(
void * ctx,
85 const float* transducerAlpha,
86 const float* transducerOffset,
87 const float* directionX,
88 const float* directionY,
89 const float* beamWidthX,
90 const float* beamWidthY)
92 auto context =
reinterpret_cast<Context *
>(ctx);
93 auto component = getComponent(context, entityId);
97 if (1000 < component->messages.size()) {
102 configMessage->config.coordSys = coordSys;
103 configMessage->config.capacity = capacity;
104 configMessage->config.beamCount = beamCount;
105 configMessage->config.sampleCount = sampleCount;
106 configMessage->config.depthOffset = depthOffset;
107 configMessage->config.depthStep = depthStep;
108 configMessage->config.useDecibel = (useDecibel != 0);
109 configMessage->config.tryPreserve = (tryPreserve != 0);
110 configMessage->config.transducerAlpha = glm::make_vec3(transducerAlpha);
111 configMessage->config.transducerOffset = glm::make_vec3(transducerOffset);
113 configMessage->config.directionX.resize(beamCount);
114 std::memcpy(configMessage->config.directionX.data(), directionX,
sizeof(
float)*beamCount);
116 configMessage->config.directionY.resize(beamCount);
117 std::memcpy(configMessage->config.directionY.data(), directionY,
sizeof(
float)*beamCount);
119 configMessage->config.beamWidthX.resize(beamCount);
120 std::memcpy(configMessage->config.beamWidthX.data(), beamWidthX,
sizeof(
float)*beamCount);
122 configMessage->config.beamWidthY.resize(beamCount);
123 std::memcpy(configMessage->config.beamWidthY.data(), beamWidthY,
sizeof(
float)*beamCount);
125 component->messages.push_back(configMessage);
130int echosounderClearPings(
void * ctx, EntityId entityId)
132 auto context =
reinterpret_cast<Context *
>(ctx);
133 auto component = getComponent(context, entityId);
137 if (1000 < component->messages.size()) {
147int echosounderAddPing(
void * ctx,
150 uint32_t sampleCount,
152 const float* position,
153 const float* orientation,
154 const float* samples,
155 const float* bottomDepths,
156 const float* bottomReflectivities)
158 auto context =
reinterpret_cast<Context *
>(ctx);
159 auto component = getComponent(context, entityId);
163 if (1000 < component->messages.size()) {
169 auto & p = pingMessage->ping;
171 p.beamCount = beamCount;
172 p.sampleCount = sampleCount;
173 p.timestamp = timestamp;
174 p.position = glm::make_vec3(position);
175 p.orientation = glm::make_quat(orientation);
177 p.storage.resize(p.storageSize(),
false);
178 std::memcpy(p.values(), samples, p.valuesSize());
180 std::memcpy(p.bottomDepths(), bottomDepths, p.bottomDepthsSize());
183 std::memset(p.bottomDepths(), ~0u, p.bottomDepthsSize());
186 if (bottomReflectivities) {
187 std::memcpy(p.bottomReflectivities(), bottomReflectivities, p.bottomReflectivitiesSize());
190 std::memset(p.bottomReflectivities(), ~0u, p.bottomReflectivitiesSize());
193 component->messages.push_back(pingMessage);
198int uniformGridAddConfig(
void * ctx,
204 uint32_t sampleCount,
207 const float* transducerAlpha,
208 const float* transducerOffset,
209 const float* directionX,
210 const float* directionY,
211 const float* beamWidthX,
212 const float* beamWidthY)
215 auto component = getUniformGridComponent(context, entityId);
216 auto system = ExtensionRegistry::getExtensionSystem<EchoSounder::UniformGridSystem>(context);
217 if(component && system){
219 config.configId = configId;
220 config.coordSys = coordSys;
221 config.majorCount = majorCount;
222 config.minorCount = minorCount;
223 config.sampleCount = sampleCount;
224 config.depthOffset = depthOffset;
225 config.depthStep = depthStep;
226 config.transducerAlpha = glm::make_vec3(transducerAlpha);
227 config.transducerOffset = glm::make_vec3(transducerOffset);
229 uint32_t beamCount = minorCount*majorCount;
230 config.directionX.resize(beamCount);
231 std::memcpy(config.directionX.data(), directionX,
sizeof(
float)*beamCount);
232 config.directionY.resize(beamCount);
233 std::memcpy(config.directionY.data(), directionY,
sizeof(
float)*beamCount);
234 config.beamWidthX.resize(beamCount);
235 std::memcpy(config.beamWidthX.data(), beamWidthX,
sizeof(
float)*beamCount);
236 config.beamWidthY.resize(beamCount);
237 std::memcpy(config.beamWidthY.data(), beamWidthY,
sizeof(
float)*beamCount);
239 system->config(component, config);
244int uniformGridClearPings(
void * ctx, EntityId entityId)
247 auto component = getUniformGridComponent(context, entityId);
248 auto system = ExtensionRegistry::getExtensionSystem<EchoSounder::UniformGridSystem>(context);
249 if(component && system) system->clear(component);
253int uniformGridAddPing(
void * ctx,
257 uint32_t sampleCount,
259 const float* position,
260 const float* orientation,
261 const float* samples,
266 auto component = getUniformGridComponent(context, entityId);
267 auto system = ExtensionRegistry::getExtensionSystem<EchoSounder::UniformGridSystem>(context);
268 if(component && system){
270 p.configId = configId;
271 p.timestamp = timestamp;
272 p.position = glm::make_vec3(position);
273 p.orientation = glm::make_quat(orientation);
274 size_t size =
sizeof(float)*beamCount*sampleCount;
275 p.storage.resize(size,
false);
276 std::memcpy(p.storage.data(), samples, size);
277 system->addPing(context, component, p);
284 Cogs::Core::EchoSounder::SetConfigPtr setConfigPtr = echosounderSetConfig;
285 Cogs::Core::EchoSounder::ClearPingsPtr clearPingsPtr = echosounderClearPings;
286 Cogs::Core::EchoSounder::AddPingPtr addPingPtr = echosounderAddPing;
293 namespace EchoSounder
306 if (strcmp(
"setConfig", symbol) == 0) {
309 else if (strcmp(
"clearPings", symbol) == 0) {
310 return clearPingsPtr;
312 else if (strcmp(
"addPing", symbol) == 0) {
315 else if (strcmp(
"uniformGridAddConfig", symbol) == 0) {
316 return uniformGridAddConfig;
318 else if (strcmp(
"uniformGridClearPings", symbol) == 0) {
319 return uniformGridClearPings;
321 else if (strcmp(
"uniformGridAddPing", symbol) == 0) {
322 return uniformGridAddPing;
330 } multiBeamExtension;
335static void EchoSounderResize(
ViewContext* view,
int x,
int y)
337 Context* context = view->getContext();
339 if(!context->
variables->get(
"renderer.oit.EchoSounderOITResize",
true))
return;
342 auto device = context->device;
344 auto capabilites = device->getCapabilities();
345 if(!capabilites)
return;
346 auto vendor = capabilites-> getVendor();
347 size_t max_oit_memory = 256;
349 size_t vRam = capabilites->getDeviceCapabilities().DedicatedVideoMemory;
350 size_t sRam = capabilites->getDeviceCapabilities().DedicatedSystemMemory;
351 size_t shRam = capabilites->getDeviceCapabilities().SharedSystemMemory;
352 max_oit_memory = std::max((
size_t)1024*1024*1024, std::max(vRam, std::max(sRam, shRam)));
355 max_oit_memory = std::max((
size_t)1024*1024*1024, capabilites->getDeviceCapabilities().DedicatedVideoMemory);
358 size_t app_memory = 500*1024*1024;
359 size_t oit_memory = (size_t)ceil((max_oit_memory*factor-app_memory));
361 float upscaleWidth = 1.0f;
362 float upscaleHeight = 1.0f;
363 int temporalUpscaleWidth = context->
variables->get(
"renderer.oit.TemporalUpscaleWidth", 1);
364 int temporalUpscaleHeight = context->
variables->get(
"renderer.oit.TemporalUpscaleHeight", 1);
365 size_t nodeBufferFactor = context->
variables->get(
"renderer.oit.bufferFactor", 1);
367 size_t maxWidth = context->
variables->get(
"renderer.oit.MaxWidth", 1920);
368 size_t maxHeight = context->
variables->get(
"renderer.oit.MaxHeight", 1200);
375 size_t width_s = (size_t)ceil(width/(upscaleWidth*temporalUpscaleWidth));
376 size_t height_s = (size_t)ceil(height/(upscaleHeight*temporalUpscaleHeight));
377 if(width_s > maxWidth){
381 if(height_s > maxHeight){
386 size_t res = width_s * height_s;
388 size_t listBuffer = res * 4;
389 size_t nodeBuffer = res * nodeBufferFactor * 8;
390 size_t dataBuffer = res * nodeBufferFactor * 16;
392 size_t DepthSubRes = res*4;
393 size_t OITColorSubRes = res*4;
394 size_t OITDepth = (size_t)ceil(width/upscaleWidth)*(size_t)ceil(height/upscaleHeight)*4;
395 size_t ColorTemporalA = (size_t)ceil(width/upscaleWidth)*(size_t)ceil(height/upscaleHeight)*4;
396 size_t ColorTemporalB = (size_t)ceil(width/upscaleWidth)*(size_t)ceil(height/upscaleHeight)*4;
398 total_size = listBuffer+nodeBuffer+dataBuffer +
399 DepthSubRes+OITColorSubRes+OITDepth+ColorTemporalA+ColorTemporalB;
400 if(total_size < oit_memory)
break;
401 if(upscaleWidth <= upscaleHeight) upscaleWidth*=2;
402 else upscaleHeight*=2;
405 LOG_INFO(logger,
"Resize %d %d upscale (%.1f, %.1f) temporalUpscale (%d, %d) factor %zu",
406 x, y, upscaleWidth, upscaleHeight, temporalUpscaleWidth, temporalUpscaleHeight, nodeBufferFactor);
408 context->
variables->set(
"renderer.oit.UpscaleWidth", upscaleWidth);
409 context->
variables->set(
"renderer.oit.UpscaleHeight", upscaleHeight);
410 context->
variables->set(
"renderer.oit.TemporalUpscaleWidth", temporalUpscaleWidth);
411 context->
variables->set(
"renderer.oit.TemporalUpscaleHeight", temporalUpscaleHeight);
416 DataSetComponent::registerType();
417 DataRefComponent::registerType();
418 WindowComponent::registerType();
419 LocationComponent::registerType();
420 PingOutlineComponent::registerType();
421 BeamGroupComponent::registerType();
422 SwathBottomComponent::registerType();
423 SwathIsoComponent::registerType();
424 PingIsoComponent::registerType();
425 OctProviderComponent::registerType();
426 UniformGridComponent::registerType();
427 UniformGridIsoComponent::registerType();
434 context->
variables->set(
"echo.maxNewChunks", 8);
437 context->
variables->set(
"echo.maxPathUpsample", 3);
440 context->
variables->set(
"echo.maxDepthUpsample", 2);
443 context->
variables->set(
"echo.maxBeamUpsample", 5);
446 context->
variables->set(
"echo.minSliceDistance", 0.01);
448 context->
variables->set(
"echo.remap.printQueues",
false);
451 context->
variables->set(
"echo.remap.maxTileUpdates", 8);
454 context->
variables->set(
"echo.remap.maxPingAdd", 4);
456 context->
variables->set(
"echo.remap.dump",
false);
458 context->
resourceStore->addResourceArchive(
"Cogs.Core.Extensions.EchoSounder.zip");
460 context->
resourceStore->addSearchPath(
"../Extensions/EchoSounder/Data/");
461 context->
resourceStore->addSearchPath(
"../Extensions/EchoSounder/Data/Materials/");
462 context->
resourceStore->addSearchPath(
"../Extensions/EchoSounder/Data/Shaders/");
464 const auto dependencyDir = IO::expandEnvironmentVariable(
"CoinDir");
467 context->
resourceStore->addSearchPath(dependencyDir +
"/Materials/");
468 context->
resourceStore->addSearchPath(dependencyDir +
"/shaders/");
470 loadPermutations(context,
"Permutations/EchoBizarreLighting.permutations");
479 readEntityDefinition(R
"(
480{ "name": "EchoDataSet",
482 "EchoDataSetComponent",
483 "TransformComponent",
489 readEntityDefinition(R"(
490{ "name": "EchoUniformGrid",
492 "EchoUniformGridComponent",
493 "EchoUniformGridIsoComponent",
494 "TransformComponent",
498 { "EchoUniformGridIsoComponent": { "material": "MultibeamIsoMaterial" }},
503 readEntityDefinition(R"(
504{ "name": "EchoUniformGridIsoVisualizer",
506 "TransformComponent",
509 "SubMeshRenderComponent",
514 readEntityDefinition(R"(
515{ "name": "EchoUniformGridPointVisualizer",
517 "TransformComponent",
520 "MeshRenderComponent",
525 readEntityDefinition(R"(
526{ "name": "EchoSwathBottom",
528 "EchoDataRefComponent",
529 "EchoWindowComponent",
530 "EchoBeamGroupComponent",
531 "EchoSwathBottomComponent",
532 "TransformComponent",
539 readEntityDefinition(R"(
540{ "name": "EchoSwathIso",
542 "EchoDataRefComponent",
543 "EchoWindowComponent",
544 "EchoBeamGroupComponent",
545 "EchoSwathIsoComponent",
546 "TransformComponent",
550 { "EchoSwathIsoComponent": { "material": "MultibeamIsoMaterial" }},
555 readEntityDefinition(R"(
556{ "name": "EchoPingIso",
558 "EchoDataRefComponent",
559 "EchoLocationComponent",
560 "EchoBeamGroupComponent",
561 "EchoPingIsoComponent",
562 "TransformComponent",
565 "SubMeshRenderComponent"
568 { "EchoPingIsoComponent": { "material": "ParametricGridMaterial" }},
569 { "EchoLocationComponent": { "updateTransform": false }},
574 readEntityDefinition(R"(
575{ "name": "EchoChunkSurface",
577 "TransformComponent",
580 "SubMeshRenderComponent"
585 readEntityDefinition(R"(
586{ "name": "EchoPingOutline",
588 "EchoDataRefComponent",
589 "EchoLocationComponent",
590 "EchoBeamGroupComponent",
591 "EchoPingOutlineComponent",
592 "TransformComponent",
595 "MeshRenderComponent",
599 { "MaterialComponent": { "enableLighting": false }},
604 readEntityDefinition(R"(
605{ "name": "EchoConfigAnnotation",
607 "TransformComponent",
609 "AnnotationAxisComponent",
611 "SpriteRenderComponent",
616 readEntityDefinition(R"(
617{ "name": "EchoOctReference",
619 "EchoDataRefComponent",
620 "EchoBeamGroupComponent",
626 readEntityDefinition(R"(
627{ "name": "EchoOctVolume",
630 "EchoOctProviderComponent",
631 "TransformComponent",
642 auto swathSeabedSystem = ExtensionRegistry::registerExtensionSystem<SwathBottomSystem>(context,
SystemPriority::Geometry, 16);
643 swathSeabedSystem->setDataSystem(dataSetSystem);
645 auto swathIsoSystem = ExtensionRegistry::registerExtensionSystem<SwathIsoSystem>(context,
SystemPriority::Geometry, 16);
646 swathIsoSystem->setDataSystem(dataSetSystem);
648 auto singlePingIsoSystem = ExtensionRegistry::registerExtensionSystem<PingIsoSystem>(context,
SystemPriority::Geometry, 16);
649 singlePingIsoSystem->setDataSystem(dataSetSystem);
654 ViewContext* defaultView = context->getDefaultView();
655 glm::vec2 size = defaultView->getSize();
657 EchoSounderResize(defaultView, (
int)size.x, (
int)size.y);
658 defaultView->addResizeCallback(&EchoSounderResize);
665 ViewContext* defaultView = context->getDefaultView();
668 defaultView->removeResizeCallback(&EchoSounderResize);
T * getComponent() const
Get a pointer to the first component implementing the given type in the entity.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
void registerDynamicComponentType(const StringView &typeName)
Register a dynamic component type with the given typeName.
class EntityStore * store
Entity store.
std::unique_ptr< class Variables > variables
Variables service instance.
std::unique_ptr< class ResourceStore > resourceStore
ResourceStore service instance.
ComponentModel::Entity * getEntityPtr(const EntityId entityId)
Get a raw pointer to the entity with the given id.
static void add(Extension *extension, StringView version)
Adds the given extension to the registry, ensuring the initialization methods are called at appropria...
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
void * getSymbolPointer(const char *symbol) const override
Get pointer to symbol defined by extension.
const char * getExtensionKey() const override
Get the extensions unique key, used to check for extension presence and retrieve extension specific d...
bool initializeStatic() override
Initialize extension statically.
bool initialize(Context *context) override
Initialize extension for the given context.
void cleanup(Context *context) override
Cleanup context bound extension content.
Defines an extension to Cogs.Core and provides methods to override in order to initialize extension c...
@ PreDynamicComponents
Run before the dynamic components.
@ Geometry
Run at the time geometry data is updated.
@ PreGeometry
Run before geometry updates are performed.