Cogs.Core
MeshGeneratorSystem.cpp
1#include "MeshGeneratorSystem.h"
2
3#include "Foundation/Logging/Logger.h"
4
5#include "Components/Core/MeshComponent.h"
6#include "Components/Core/CameraComponent.h"
7#include "Components/Core/TransformComponent.h"
8#include "Components/Core/LodComponent.h"
9
10#include "Systems/Core/TransformSystem.h"
11#include "Systems/Core/CameraSystem.h"
12#include "Systems/Core/LodSystem.h"
13
14#include "Context.h"
15
16#include "Utilities/TessellationPredicates.h"
17
18#include "Services/Services.h"
19
20#include "Generators/MeshGenerator.h"
21
22using namespace Cogs::Core;
23
24namespace
25{
26 Cogs::Logging::Log logger = Cogs::Logging::getLogger("MeshGeneratorSystem");
27}
28
30{
31 auto meshGenerator = context->services->getService<MeshGenerator>();
32
33 auto camComp = context->cameraSystem->getMainCamera();
34 for (auto & component : pool) {
35 auto & data = getData(&component);
36
37 auto lodComp = component.getComponent<LodComponent>();
38
39 if (lodComp && lodComp->policy == LodPolicy::GeometricTolerance) {
40 const auto & lodData = context->lodSystem->getData<LodData>(lodComp);
41
42 // --- Get reference position and screen space radius ------------------
43 glm::vec4 screenReferencePoint = lodData.localToClip * glm::vec4(0.f, 0.f, 0.f, 1.f);
44
45 float minSamples = 3.f;
46 float maxSamples = 4.f * float(component.samples);
47 float epsilon = lodComp->geometricTolerance;
48 glm::vec2 rr = localSphereRadiusInScreenSpace(lodData.localToClip, lodData.clipToLocal,
49 screenReferencePoint, 1.f);
50
51 // --- Determine LoD ---------------------------------------------------
52 float nonIntegerSamples = 0.f;
53 switch (context->lodSystem->geometricErrorKind) {
54 case GeometricErrorKind::AreaBased:
55 nonIntegerSamples = sphereSectorGeometricAreaPredicate(rr, camComp->viewportSize,
56 epsilon*epsilon, minSamples, maxSamples);
57 break;
58 case GeometricErrorKind::DistanceBased:
59 nonIntegerSamples = sphereSectorGeometricDistancePredicate(rr, camComp->viewportSize,
60 epsilon, minSamples, maxSamples);
61 break;
62 }
63 int samples = static_cast<int>(std::ceil(nonIntegerSamples));
64 if (samples == data.currentSamples && !component.hasChanged()) {
65 continue;
66 }
67 data.currentSamples = samples;
68
69 } else {
70 if (!component.hasChanged() ||
71 (data.currentType == component.shape && // Make sure that spec has really changed since creating a new mesh costs a bit.
72 data.currentSamples == component.samples &&
73 data.currentSize == component.size &&
74 data.arcStart == component.arcStart &&
75 data.arcEnd == component.arcEnd)) {
76 continue;
77 }
78
79 data.currentSamples = component.samples;
80 data.currentSize = component.size;
81 }
82
83 data.currentType = component.shape;
84 data.arcStart = component.arcStart;
85 data.arcEnd = component.arcEnd;
86
87 auto meshComponent = component.getComponent<MeshComponent>();
88
89 assert(meshComponent && "No mesh component found to assign generated mesh.");
90
91 meshComponent->meshHandle = meshGenerator->getMesh(data.currentType, data.currentSamples, component.size, data.arcStart, data.arcEnd);
92 meshComponent->setChanged();
93 }
94}
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 Services > services
Services.
Definition: Context.h:174
Contains data describing level of detail behavior for the entity the component belongs to.
Definition: LodComponent.h:43
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
Definition: MeshComponent.h:15
Log implementation class.
Definition: LogManager.h:139
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
COGSCORE_DLL_API glm::vec2 localSphereRadiusInScreenSpace(const glm::mat4 &localToClip, const glm::mat4 &clipToLocal, const glm::vec4 &clipPosition, const float localRadius)
Given a screen space reference position and a local space radius, find the corresponding screen space...
@ GeometricTolerance
Use a geometric error bound to determine how refined geometry needs to be at its current position.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Defines level of detail data calculated by the LodSystem.
Definition: LodSystem.h:15