4#include "Systems/Core/CameraSystem.h"
5#include "Systems/Core/TransformSystem.h"
6#include "Components/Core/MeshComponent.h"
7#include "Components/Core/MeshRenderComponent.h"
9#include "Resources/MeshManager.h"
11#include "LoftedCrossSectionsSystem.h"
12#include "LoftedCrossSectionsSystem_tables.h"
14#include "Foundation/Logging/Logger.h"
30bool Cogs::Core::LoftedCrossSectionsSystem::process(
Context* context,
31 glm::vec4 viewer_world,
43 glm::mat4 worldToLocal = glm::inverse(context->transformSystem->getLocalToWorld(transform));
44 glm::vec4 t = worldToLocal * viewer_world;
45 glm::vec3 viewpoint = (1.f / t.w)*glm::vec3(t.x, t.y, t.z);
47 if (glm::distance(viewpoint, data.viewpoint) > std::numeric_limits<float>::epsilon()) {
48 data.viewpoint = viewpoint;
49 reconsiderView =
true;
55 const float* pos =
nullptr;
56 size_t pos_stride = 0;
58 if (!component.vertices_vn.empty()) {
59 pos = (
const float*)((
const uint8_t*)component.vertices_vn.data() + offsetof(PositionNormalVertex, position));
60 pos_stride =
sizeof(PositionNormalVertex) /
sizeof(
float);
61 }
else if (!component.vertices_vnt.empty()) {
62 pos = (
const float*)((
const uint8_t*)component.vertices_vnt.data() + offsetof(PositionNormalTexVertex, position));
63 pos_stride =
sizeof(PositionNormalTexVertex) /
sizeof(
float);
71 switch (component.shape) {
72 case LoftedCrossSectionsComponent::Shape::Hollow:
73 hollowOpenAlignedClassifySamples(data.inside, pos, pos_stride, component.spine, data.viewpoint, component.
crossSections, component.
samples);
76 case LoftedCrossSectionsComponent::Shape::Solid:
77 solidOpenAlignedClassifySamples(data.inside, pos, pos_stride, component.spine, data.viewpoint, component.
crossSections, component.
samples);
80 case LoftedCrossSectionsComponent::Shape::Shell:
81 shellOpenAlignedClassifySamples(data.inside, pos, pos_stride, component.spine, data.viewpoint, component.
crossSections, component.
samples);
92 size_t newVertices = 0;
93 size_t outIndices = 0;
94 size_t cutIndices = 0;
95 switch (component.shape) {
96 case LoftedCrossSectionsComponent::Shape::Hollow:
98 hollowOpenAlignedCountCellResources(newVertices, outIndices, cutIndices, data.classification,
99 component.spine, data.inside, data.viewpoint,
101 }
else if (component.
open) {
102 hollowOpenCountCellResources(newVertices, outIndices, cutIndices,
105 hollowClosedCountCellResources(newVertices, outIndices, cutIndices,
112 case LoftedCrossSectionsComponent::Shape::Solid:
114 solidOpenAlignedCountCellResources(newVertices, outIndices, cutIndices, data.classification,
115 component.spine, data.inside, data.viewpoint,
117 }
else if (component.
open) {
118 solidOpenCountCellResources(newVertices, outIndices, cutIndices,
121 solidClosedCountCellResources(newVertices, outIndices,
128 case LoftedCrossSectionsComponent::Shape::Shell:
130 shellOpenAlignedCountCellResources(newVertices, outIndices, data.classification,
131 component.spine, data.inside, data.viewpoint,
133 }
else if (component.
open) {
134 shellOpenCountCellResources(outIndices,
136 component.doubleSeamVertices);
138 shellClosedCountCellResources(outIndices,
140 component.doubleSeamVertices);
148 std::vector<unsigned int> surface(outIndices);
149 std::vector<unsigned int> cut(cutIndices);
152 float *tex =
nullptr;
153 size_t pos_stride, nrm_stride, tex_stride;
155 if (!component.vertices_vn.empty()) {
156 component.vertices_vn.resize(newVertices);
157 pos = (
float*)((uint8_t*)component.vertices_vn.data() + offsetof(PositionNormalVertex, position));
158 nrm = (
float*)((uint8_t*)component.vertices_vn.data() + offsetof(PositionNormalVertex, normal));
159 pos_stride =
sizeof(PositionNormalVertex) /
sizeof(
float);
160 nrm_stride =
sizeof(PositionNormalVertex) /
sizeof(
float);
163 component.vertices_vnt.resize(newVertices);
164 pos = (
float*)((uint8_t*)component.vertices_vnt.data() + offsetof(PositionNormalTexVertex, position));
165 nrm = (
float*)((uint8_t*)component.vertices_vnt.data() + offsetof(PositionNormalTexVertex, normal));
166 tex = (
float*)((uint8_t*)component.vertices_vnt.data() + offsetof(PositionNormalTexVertex, tex));
167 pos_stride =
sizeof(PositionNormalTexVertex) /
sizeof(
float);
168 nrm_stride =
sizeof(PositionNormalTexVertex) /
sizeof(
float);
169 tex_stride =
sizeof(PositionNormalTexVertex) /
sizeof(
float);
174 switch (component.shape) {
175 case LoftedCrossSectionsComponent::Shape::Hollow:
177 hollowOpenAlignedSkin(surface, cut, pos, pos_stride, tex, tex_stride, nrm, nrm_stride,
178 data.classification, component.spine, data.viewpoint,
180 }
else if (component.
open) {
181 hollowOpenSkin(surface, cut, pos, pos_stride, tex, tex_stride, nrm, nrm_stride,
184 hollowClosedSkin(surface, component.
crossSections, component.
samples, component.doubleSeamVertices);
188 case LoftedCrossSectionsComponent::Shape::Solid:
190 solidOpenAlignedSkin(surface, cut, pos, pos_stride, tex, tex_stride, nrm, nrm_stride,
191 data.classification, component.spine, data.viewpoint,
193 }
else if (component.
open) {
194 solidOpenSkin(surface, cut, pos, pos_stride, tex, tex_stride, nrm, nrm_stride,
198 solidClosedSkin(surface, pos, pos_stride, tex, tex_stride, nrm, nrm_stride,
204 case LoftedCrossSectionsComponent::Shape::Shell:
206 shellOpenAlignedSkin(surface, pos, pos_stride, tex, tex_stride, nrm, nrm_stride,
207 data.classification, component.spine, data.viewpoint,
209 }
else if (component.
open) {
210 shellOpenSkin(surface,
212 component.doubleSeamVertices);
214 shellClosedSkin(surface,
216 component.doubleSeamVertices);
222 surface.reserve(surface.size() + cut.size());
223 surface.insert(surface.end(), cut.begin(), cut.end());
225 if (!component.vertices_vn.empty()) {
226 mesh->
setVertexData(component.vertices_vn.data(), component.vertices_vn.size());
228 mesh->
setVertexData(component.vertices_vnt.data(), component.vertices_vnt.size());
243 auto & meshManager = context->meshManager;
244 const auto & cameraComponent = context->cameraSystem->getMainCamera();
245 const auto & cameraData = context->cameraSystem->getData(cameraComponent);
247 glm::vec4 viewerWorld = cameraData.inverseViewMatrix * glm::vec4(0.f, 0.f, 0.f, 1.f);
249 for (
auto& component : pool) {
250 auto& data = getData(&component);
254 meshComponent->
meshHandle = context->meshManager->create();
257 auto mesh = meshManager->get(meshComponent->meshHandle);
263 meshComponent->setChanged();
267 if (!component.visibility || !component.
hasData) {
268 if (data.visibilityProcessed) {
269 data.visibilityProcessed =
false;
272 meshComponent->setChanged();
276 data.visibilityProcessed =
true;
279 process(context, viewerWorld, component, data, mesh);
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
ComponentType * getComponent() const
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.
void initialize(Context *context) override
Initialize the system.
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
MeshHandle meshHandle
Handle to a Mesh resource to use when rendering.
Log implementation class.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
bool boundingBoxSet
True when bounding box info is set but not yet forwarded to mesh.
int crossSections
Number of cross sections (inner & outer cross sections count as one).
bool screenAligned
Let open geometry be screen-aligned.
int samples
Number of sample points in each of the cross sections.
bool open
If true, cull the front of the shape such that the inside is visible.
bool hasData
True if we have (sane) data.
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
void setIndexes(std::span< const uint32_t > collection)
Set the index data to the collection given.
void setBounds(Geometry::BoundingBox box)
Set custom bounds for the mesh.
void clearIndexes()
Clear all index data, also clearing all sub-meshes.
void clear()
Clear all data from the Mesh, returning it to its initial non-indexed state with no streams and no su...
void setVertexData(Element *elements, size_t count)
Set vertex data.
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
@ TriangleList
List of triangles.