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"
20 constexpr uint32_t cColours[] = {
43 mVertexFormatHandle = Cogs::VertexFormats::createVertexFormat(elements, std::size(elements));
46 mArrowMesh =
context->meshManager->create();
48 std::vector<glm::vec3> vertices = {
50 { 0.2f, 0.15f, 0.0f },
51 { 0.1f, 0.15f, 0.0f },
53 { 0.1f, 0.15f, 0.0f },
54 { -0.1f, 0.15f, 0.0f },
57 { -0.1f, 0.15f, 0.0f },
58 { -0.2f, 0.15f, 0.0f },
61 { 0.1f, 0.15f, 0.0f },
62 { 0.0f, -0.15f, 0.0f },
63 { -0.1f, 0.15f, 0.0f },
65 { 0.1f, 0.15f, 0.0f },
66 { 0.05f, -0.5f, 0.0f },
67 { 0.0f, -0.15f, 0.0f },
69 { 0.0f, -0.15f, 0.0f },
70 { 0.05f, -0.5f, 0.0f },
71 { -0.05f, -0.5f, 0.0f },
73 { -0.1f, 0.15f, 0.0f },
74 { 0.0f, -0.15f, 0.0f },
75 { -0.05f, -0.5f, 0.0f },
80 std::vector<glm::vec4> baricentricCoords = {
83 { 1.0f, 100.0f, 0.0f, 1.0f },
84 { 0.0f, 1.0f, 0.0f, 1.0f },
85 { 0.0f, 100.0f, 1.0f, 1.0f },
87 { 1.0f, 100.0f, 100.0f, 1.0f },
88 { 100.0f, 1.0f, 100.0f, 1.0f },
89 { 100.0f, 100.0f, 1.0f, 1.0f },
91 { 1.0f, 100.0f, 0.0f, 1.0f },
92 { 0.0f, 1.0f, 0.0f, 1.0f },
93 { 0.0f, 100.0f, 1.0f, 1.0f },
95 { 2.0f, 100.0f, 100.0f, 1.0f },
96 { 100.0f, 10.0f, 100.0f, 1.0f },
97 { 100.0f, 100.0f, 2.0f, 1.0f },
99 { 1.0f, 100.0f, 0.0f, 1.0f },
100 { 100.0f, 1.0f, 0.0f, 1.0f },
101 { 100.0f, 100.0f, 1.0f, 1.0f },
103 { 1.0f, 100.0f, 100.0f, 1.0f },
104 { 0.0f, 1.0f, 100.0f, 1.0f },
105 { 0.0f, 100.0f, 1.0f, 1.0f },
107 { 1.0f, 0.0f, 100.0f, 1.0f },
108 { 100.0f, 1.0f, 100.0f, 1.0f },
109 { 100.0f, 0.0f, 1.0f, 1.0f },
112 mesh->
setName(
"Sea Currents Arrow");
114 mesh->setColors(baricentricCoords);
115 mesh->
setBounds({ { -0.5f, -0.5f, -0.1f}, {0.5f, 0.5f, 0.1f} });
119 arrowInstancesStreamsLayout = mesh->getStreamsLayout();
130 if (seaCurrentsComp.positions.size() == 0)
continue;
132 constexpr float cSpeedBandMax[] = { 0.5f, 1.0f, 2.0f, 3.0f, 5.0f, 7.0f, 10.0f, 13.0f, 99.0f };
133 constexpr float cSpeedBandMin[] = { 0.0f, 0.5f, 1.0f, 2.0f, 3.0f, 5.0f, 7.0f, 10.0f, 13.0f };
134 constexpr float cSpeedBandWidth[] = { 0.5f, 0.5f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 86.0f };
136 if (!seaCurrentsComp.isValid()) {
140 if (!mMaterial->isActive()) {
142 context->materialManager->processLoading();
143 mMaterial = context->materialInstanceManager->createMaterialInstance(material);
146 if (seaCurrentsComp.hasChanged()) {
148 lowestSpeed = context->variables->get(
"seacurrents.lowestSpeed", 0.01f);
149 highestSpeed = context->variables->get(
"seacurrents.highestSpeed", 13.0f);
150 minScale = context->variables->get(
"seacurrents.minScale", 0.2f);
151 maxScale = context->variables->get(
"seacurrents.maxScale", 1.0f);
154 glm::vec2 minPos(std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
155 glm::vec2 maxPos(std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest());
158 for (
const glm::vec2& position : seaCurrentsComp.positions) {
159 minPos = glm::min(minPos, position);
160 maxPos = glm::max(maxPos, position);
163 data.mBounds = {{minPos, -0.01f}, {maxPos, 0.01f}};
166 size_t relevantDataPoints = seaCurrentsComp.positions.size();
168 if (!seaCurrentsComp.ignorePriorities) {
170 auto it = std::upper_bound(seaCurrentsComp.priorities.begin(), seaCurrentsComp.priorities.end(), seaCurrentsComp.priorityLevel);
172 relevantDataPoints = std::distance(seaCurrentsComp.priorities.begin(), it);
176 data.mData.resize(relevantDataPoints);
178 for (
size_t idx = 0, pointCount = relevantDataPoints; idx < pointCount; ++idx) {
179 float angle = glm::radians(seaCurrentsComp.angles[idx]);
180 float speed = seaCurrentsComp.speeds[idx];
182 uint32_t colouridx = 0;
183 glm::vec2 pos = seaCurrentsComp.positions[idx];
185 for (; colouridx < 8; ++colouridx) {
186 if (speed < cSpeedBandMax[colouridx]) {
190 float scalingFactor = 1.0f;
193 scalingFactor = std::min(std::max(lowestSpeed, speed), highestSpeed) / highestSpeed;
196 scalingFactor = (speed - cSpeedBandMin[colouridx]) / cSpeedBandWidth[colouridx];
199 float scale = std::lerp(minScale, maxScale, scalingFactor);
201 data.mData[idx].pos = glm::vec4(pos, scale * seaCurrentsComp.scale, angle);
202 data.mData[idx].colour = cColours[colouridx];
221 context->materialManager->processLoading();
223 mMaterial = context->materialInstanceManager->createMaterialInstance(material);
225 if (pool.size() == 1u) {
226 assert(bounds ==
nullptr);
227 bounds = std::make_unique<SeaCurrentsBounds>(
this);
228 context->bounds->addBoundsExtension(bounds.get());
235 base_type::destroyComponent(component);
237 if (pool.size() == 0u && bounds) {
238 context->bounds->removeBoundsExtension(bounds.get());
245 if (!ignoreVisibility) {
247 if (sc && !sc->visible)
248 return Geometry::makeEmptyBoundingBox<Geometry::BoundingBox>();
252 return data.mTransformedBounds;
258 const Cogs::Geometry::BoundingBox bbox = seaCurrentSystem->getWorldBounds(seaCurrentsComponent,
false);
267 if (!seaCurrentsComponent)
return false;
269 const Cogs::Geometry::BoundingBox bbox = seaCurrentSystem->getWorldBounds(*seaCurrentsComponent, ignoreVisibility);
270 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.