1#include "SeaCurrentsSystem.h"
3#include "SeaCurrentsRenderer.h"
5#include "Components/Core/MeshComponent.h"
6#include "Components/Core/SceneComponent.h"
7#include "Components/Core/TransformComponent.h"
8#include "Components/Core/InstancedMeshRenderComponent.h"
9#include "Resources/MaterialManager.h"
10#include "Resources/MeshManager.h"
11#include "Resources/VertexFormats.h"
12#include "Systems/Core/TransformSystem.h"
19 constexpr uint32_t cColours[] = {
42 mVertexFormatHandle = Cogs::VertexFormats::createVertexFormat(elements, glm::countof(elements));
45 mArrowMesh =
context->meshManager->create();
47 std::vector<glm::vec3> vertices = {
49 { 0.2f, 0.15f, 0.0f },
50 { 0.1f, 0.15f, 0.0f },
52 { 0.1f, 0.15f, 0.0f },
53 { -0.1f, 0.15f, 0.0f },
56 { -0.1f, 0.15f, 0.0f },
57 { -0.2f, 0.15f, 0.0f },
60 { 0.1f, 0.15f, 0.0f },
61 { 0.0f, -0.15f, 0.0f },
62 { -0.1f, 0.15f, 0.0f },
64 { 0.1f, 0.15f, 0.0f },
65 { 0.05f, -0.5f, 0.0f },
66 { 0.0f, -0.15f, 0.0f },
68 { 0.0f, -0.15f, 0.0f },
69 { 0.05f, -0.5f, 0.0f },
70 { -0.05f, -0.5f, 0.0f },
72 { -0.1f, 0.15f, 0.0f },
73 { 0.0f, -0.15f, 0.0f },
74 { -0.05f, -0.5f, 0.0f },
79 std::vector<glm::vec4> baricentricCoords = {
82 { 1.0f, 100.0f, 0.0f, 1.0f },
83 { 0.0f, 1.0f, 0.0f, 1.0f },
84 { 0.0f, 100.0f, 1.0f, 1.0f },
86 { 1.0f, 100.0f, 100.0f, 1.0f },
87 { 100.0f, 1.0f, 100.0f, 1.0f },
88 { 100.0f, 100.0f, 1.0f, 1.0f },
90 { 1.0f, 100.0f, 0.0f, 1.0f },
91 { 0.0f, 1.0f, 0.0f, 1.0f },
92 { 0.0f, 100.0f, 1.0f, 1.0f },
94 { 2.0f, 100.0f, 100.0f, 1.0f },
95 { 100.0f, 10.0f, 100.0f, 1.0f },
96 { 100.0f, 100.0f, 2.0f, 1.0f },
98 { 1.0f, 100.0f, 0.0f, 1.0f },
99 { 100.0f, 1.0f, 0.0f, 1.0f },
100 { 100.0f, 100.0f, 1.0f, 1.0f },
102 { 1.0f, 100.0f, 100.0f, 1.0f },
103 { 0.0f, 1.0f, 100.0f, 1.0f },
104 { 0.0f, 100.0f, 1.0f, 1.0f },
106 { 1.0f, 0.0f, 100.0f, 1.0f },
107 { 100.0f, 1.0f, 100.0f, 1.0f },
108 { 100.0f, 0.0f, 1.0f, 1.0f },
111 mesh->
setName(
"Sea Currents Arrow");
113 mesh->setColors(baricentricCoords);
114 mesh->
setBounds({ { -0.5f, -0.5f, -0.1f}, {0.5f, 0.5f, 0.1f} });
118 arrowInstancesStreamsLayout = mesh->getStreamsLayout();
129 if (seaCurrentsComp.positions.size() == 0)
continue;
131 constexpr float cSpeedBandMax[] = { 0.5f, 1.0f, 2.0f, 3.0f, 5.0f, 7.0f, 10.0f, 13.0f, 99.0f };
132 constexpr float cSpeedBandMin[] = { 0.0f, 0.5f, 1.0f, 2.0f, 3.0f, 5.0f, 7.0f, 10.0f, 13.0f };
133 constexpr float cSpeedBandWidth[] = { 0.5f, 0.5f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 86.0f };
135 if (!seaCurrentsComp.isValid()) {
139 if (!mMaterial->isActive()) {
141 context->materialManager->processLoading();
142 mMaterial = context->materialInstanceManager->createMaterialInstance(material);
145 if (seaCurrentsComp.hasChanged()) {
147 lowestSpeed = context->variables->get(
"seacurrents.lowestSpeed", 0.01f);
148 highestSpeed = context->variables->get(
"seacurrents.highestSpeed", 13.0f);
149 minScale = context->variables->get(
"seacurrents.minScale", 0.2f);
150 maxScale = context->variables->get(
"seacurrents.maxScale", 1.0f);
153 glm::vec2 minPos(std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
154 glm::vec2 maxPos(std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest());
157 for (
const glm::vec2& position : seaCurrentsComp.positions) {
158 minPos = glm::min(minPos, position);
159 maxPos = glm::max(maxPos, position);
162 data.mBounds = {{minPos, -0.01f}, {maxPos, 0.01f}};
165 size_t relevantDataPoints = seaCurrentsComp.positions.size();
167 if (!seaCurrentsComp.ignorePriorities) {
169 auto it = std::upper_bound(seaCurrentsComp.priorities.begin(), seaCurrentsComp.priorities.end(), seaCurrentsComp.priorityLevel);
171 relevantDataPoints = std::distance(seaCurrentsComp.priorities.begin(), it);
175 data.mData.resize(relevantDataPoints);
177 for (
size_t idx = 0, pointCount = relevantDataPoints; idx < pointCount; ++idx) {
178 float angle = glm::radians(seaCurrentsComp.angles[idx]);
179 float speed = seaCurrentsComp.speeds[idx];
181 uint32_t colouridx = 0;
182 glm::vec2 pos = seaCurrentsComp.positions[idx];
184 for (; colouridx < 8; ++colouridx) {
185 if (speed < cSpeedBandMax[colouridx]) {
189 float scalingFactor = 1.0f;
192 scalingFactor = std::min(std::max(lowestSpeed, speed), highestSpeed) / highestSpeed;
195 scalingFactor = (speed - cSpeedBandMin[colouridx]) / cSpeedBandWidth[colouridx];
198 float scale = std::lerp(minScale, maxScale, scalingFactor);
200 data.mData[idx].pos = glm::vec4(pos, scale * seaCurrentsComp.scale, angle);
201 data.mData[idx].colour = cColours[colouridx];
220 context->materialManager->processLoading();
222 mMaterial = context->materialInstanceManager->createMaterialInstance(material);
224 if (pool.size() == 1u) {
225 assert(bounds ==
nullptr);
226 bounds = std::make_unique<SeaCurrentsBounds>(
this);
227 context->bounds->addBoundsExtension(bounds.get());
234 base_type::destroyComponent(component);
236 if (pool.size() == 0u && bounds) {
237 context->bounds->removeBoundsExtension(bounds.get());
244 if (!ignoreVisibility) {
246 if (sc && !sc->visible)
247 return Geometry::makeEmptyBoundingBox<Geometry::BoundingBox>();
251 return data.mTransformedBounds;
257 const Cogs::Geometry::BoundingBox bbox = seaCurrentSystem->getWorldBounds(seaCurrentsComponent,
false);
266 if (!seaCurrentsComponent)
return false;
268 const Cogs::Geometry::BoundingBox bbox = seaCurrentSystem->getWorldBounds(*seaCurrentsComponent, ignoreVisibility);
269 if (!isEmpty(bbox)) {
ComponentType * getComponent() const
Container for components, providing composition of dynamic entities.
T * getComponent() const
Get a pointer to the first component implementing the given type in the entity.
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.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
class IRenderer * renderer
Renderer.
virtual void registerExtension(IRendererExtension *extension)=0
Register an extension with the renderer.
virtual void unregisterExtension(IRendererExtension *extension)=0
Unregister an extension with the renderer.
Contains information on how the entity behaves in the scene.
virtual void getBounds(Context *context, Cogs::Geometry::BoundingBox &bounds) override
Expand bounds including bounds of all entities in this system in world coordinates.
virtual void destroyComponent(ComponentHandle component) override
Cogs::Geometry::BoundingBox getWorldBounds(const SeaCurrentsComponent &seaCurrentsComponent, bool ignoreVisibility) const
Used by SeaCurrentsBounds::getBounds.
virtual void initialize(Context *context) override
Initialize the system.
virtual void cleanup(Context *context) override
Provided for custom cleanup logic in derived systems.
virtual ComponentHandle createComponent() override
@ PerBand
Arrows scale with the speed of the current within each band.
@ Normal
Arrows scale with the speed of the current from min speed to max speed.
Contains geometry calculations and generation.
@ InstanceData
Per instance data.
@ InstanceVector
Instance vector semantic.
Handle to a Component instance.
VertexFormatHandle vertexFormats[maxStreams]
COGSCORE_DLL_API void updateHash()
static constexpr size_t maxStreams
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
void setBounds(Geometry::BoundingBox box)
Set custom bounds for the mesh.
void setPositions(std::span< const glm::vec3 > positions)
Set the position data of the Mesh.
void setName(const StringView &name)
Set the user friendly name of the resource.
ResourceType * resolve() const
Resolve the handle, returning a pointer to the actual resource.
Component for displaying surface currents based on the IHO S111 standard.
Vertex element structure used to describe a single data element in a vertex for the input assembler.