1#include "ShapeSystem.h"
5#include "Components/Core/MeshComponent.h"
6#include "Components/Appearance/MaterialComponent.h"
8#include "Foundation/Logging/Logger.h"
10#include "Resources/Mesh.h"
11#include "Resources/MeshManager.h"
12#include "Resources/ModelManager.h"
14#include "Services/Variables.h"
16#include "Math/IndexConversion.h"
17#include "Math/NormalGenerator.h"
19#include "Foundation/Geometry/Glm.hpp"
21#include "Rendering/ICapabilities.h"
28 const Cogs::StringView instancedLinesSettingName =
"shapeSystem.instancedLine";
32 size_t vn = shapeComponent.indexes.empty() ? shapeComponent.positions.size() : shapeComponent.indexes.size();
35 size_t instanceCount = 0;
36 switch (shapeComponent.primitiveType) {
38 case ShapePrimitiveType::LineList:
40 instanceCount = vn / 2;
43 case ShapePrimitiveType::LineStrip:
45 instanceCount = std::max(
size_t(1), vn) - 1;
56 .format = Cogs::DataFormat::X32Y32Z32_FLOAT,
63 .
offset = 3 *
sizeof(float),
64 .format = Cogs::DataFormat::X32Y32Z32_FLOAT,
74 glm::vec3 hi(-std::numeric_limits<float>::max());
75 glm::vec3 lo(std::numeric_limits<float>::max());
76 if (glm::vec3* ptr = (glm::vec3*)mesh->
mapStream(VertexDataType::Positions, formatHandle, 0, (vn + stride - 1) / stride, stride *
sizeof(glm::vec3),
true); ptr !=
nullptr) {
77 if (shapeComponent.indexes.empty()) {
78 for (
size_t i = 0; i < vn; i++) {
79 const glm::vec3 p = shapeComponent.positions[i];
86 for (
size_t i = 0; i < vn; i++) {
87 const glm::vec3 p = shapeComponent.positions[shapeComponent.indexes[i]];
93 mesh->
unmap(VertexDataType::Positions);
94 mesh->
setBounds(Cogs::Geometry::BoundingBox{ lo, hi });
124 bool forceUpdate =
false;
125 if (supportsInstancing) {
126 Variable* instancedLinesVar = context->
variables->get(instancedLinesSettingName);
127 if (instancedLinesVar->isEmpty()) {
128 instancedLinesVar->setBool(
false);
131 instancedLines = instancedLinesVar->getBool();
134 for (
const auto & shapeComponent : pool) {
138 if (forceUpdate || shapeComponent.
hasChanged()) {
140 meshComponent->
meshHandle = context->meshManager->create();
144 auto mesh = context->meshManager->get(meshComponent->
meshHandle);
148 if (!shapeComponent.positions.size()) {
152 if (instancedLines) {
153 switch (shapeComponent.primitiveType) {
155 case ShapePrimitiveType::LineList:
156 case ShapePrimitiveType::LineStrip:
157 if (buildInstancedLineList(mesh, materialComponent, shapeComponent)) {
167 if (materialComponent) {
170 switch (shapeComponent.primitiveType) {
171 case ShapePrimitiveType::Default:
173 if (shapeComponent.positions.size() == shapeComponent.normals.size()) {
176 if (shapeComponent.normals.size()) {
180 if (shapeComponent.texCoords.size()) {
184 reindex(shapeComponent.indexes, mesh,
false);
185 }
else if (shapeComponent.positions.size() && !shapeComponent.normals.size()) {
186 const auto & idx = shapeComponent.indexes;
188 bool quads = idx.size() >= 5 && (idx.size() % 5) == 0 && idx[4] == -1;
190 std::vector<glm::vec3> positions;
191 std::vector<glm::vec3> normals;
192 std::vector<int32_t> indexes;
193 std::vector<glm::vec2> texCoords;
195 Cogs::Geometry::generateFacetNormals(
196 shapeComponent.positions.data(),
197 shapeComponent.positions.size(),
198 shapeComponent.indexes.data(),
199 shapeComponent.indexes.size(),
200 shapeComponent.texCoords.data(),
215 if (texCoords.size()) {
219 reindex(indexes, mesh,
false);
223 case ShapePrimitiveType::DefaultLine:
225 if (materialComponent) {
231 if (shapeComponent.normals.size()) {
235 if (shapeComponent.texCoords.size()) {
239 reindex(shapeComponent.indexes, mesh,
true);
241 if (!shapeComponent.normals.size() && materialComponent) {
242 materialComponent->enableLighting =
false;
247 case ShapePrimitiveType::LineListAdjacency:
248 case ShapePrimitiveType::LineStripAdjacency:
249 case ShapePrimitiveType::LineList:
250 case ShapePrimitiveType::LineStrip:
251 case ShapePrimitiveType::PointList:
253 if (materialComponent) {
254 materialComponent->enableLighting = shapeComponent.normals.size() > 0;
258 case ShapePrimitiveType::TriangleList:
259 case ShapePrimitiveType::TriangleStrip:
263 if (shapeComponent.normals.size()) {
267 if (shapeComponent.texCoords.size()) {
271 if (shapeComponent.indexes.size()) {
272 mesh->
setIndexData(
reinterpret_cast<const uint32_t *
>(shapeComponent.indexes.data()), shapeComponent.indexes.size());
289 static_assert(
sizeof(typeMap) /
sizeof(typeMap[0]) == (size_t)ShapePrimitiveType::ShapePrimitiveType_Size,
"Type map wrong size.");
291 mesh->primitiveType = typeMap[
static_cast<int>(shapeComponent.primitiveType)];
293 if (materialComponent) {
294 materialComponent->primitiveType = mesh->primitiveType;
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
ComponentType * getComponent() const
class Entity * getContainer() const
Get the container currently owning this component instance.
const std::string & getName() const noexcept
Get the name of this 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.
std::unique_ptr< class Variables > variables
Variables service instance.
virtual IGraphicsDevice * getDevice()=0
Get the graphics device used by the renderer.
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.
void initialize(Context *context) override
Initialize the system.
virtual ICapabilities * getCapabilities()=0
Get a pointer to the capability management interface used to query the graphics device capability fla...
Log implementation class.
Provides a weakly referenced view over the contents of a string.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
Contains geometry calculations and generation.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
@ InstanceData
Per instance data.
@ Position
Position semantic.
Exposes material properties for legacy entities and code.
bool instancedLine
Lines rendered with instancing.
@ Instanced
Mesh contains instance data.
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
void unmap(VertexDataType::EVertexDataType type)
Unmap the stream with the given vertex data type index.
uint8_t * mapStream(const VertexDataType::EVertexDataType type, VertexFormatHandle format, const size_t start, const size_t count, const size_t elementSize, bool resize=false)
Raw stream mapping method.
void setTexCoords(std::span< const glm::vec2 > texCoords)
Set the texture coordinate data of the Mesh.
void setIndexData(const uint32_t *data, size_t count)
Convenience method for setting index data from a raw pointer to data and count number of elements.
void setBounds(Geometry::BoundingBox box)
Set custom bounds for the mesh.
void setInstanceCount(size_t count)
Set the number of instances in this mesh.
void setNormals(std::span< const glm::vec3 > normals)
Set the normal data of the Mesh.
void clear()
Clear all data from the Mesh, returning it to its initial non-indexed state with no streams and no su...
void setMeshFlag(MeshFlags::EMeshFlags flag)
Set the given mesh flag.
void setCount(size_t count)
Explicitly set the vertex count of the mesh.
void setPositions(std::span< const glm::vec3 > positions)
Set the position data of the Mesh.
Runtime control variable.
virtual bool supportsInstancing() const
Check if the graphics device supports instancing.
EPrimitiveType
Primitive type enumeration.
@ LineStripAdjacency
Line strip with adjacency.
@ TriangleStrip
Triangle strip.
@ TriangleListAdjacency
List of triangles with adjacency.
@ PointList
List of points.
@ TriangleStripAdjacency
Triangle strip with adjacency.
@ LineListAdjacency
List of lines with adjacency.
@ TriangleList
List of triangles.
Vertex element structure used to describe a single data element in a vertex for the input assembler.
uint16_t offset
Offset in bytes from the vertex position in memory.