3#include "VertexFormats.h"
4#include "MeshStreamsLayout.h"
5#include "ResourceBase.h"
8#include "Rendering/Common.h"
9#include "Rendering/VertexFormat.h"
11#include "Foundation/Geometry/BoundingBox.hpp"
12#include "Foundation/Memory/MemoryBuffer.h"
42 Indexes = LastVertexType,
90 COGSCORE_DLL_API
void * data();
91 COGSCORE_DLL_API
const void * data()
const;
93 COGSCORE_DLL_API
size_t size()
const;
124 template<
typename Element>
136 : data(data), mesh(mesh), type(type) {}
143 : data(other.data), mesh(other.mesh), type(other.type)
145 other.data =
nullptr;
146 other.mesh =
nullptr;
164 [[nodiscard]]
constexpr Element &
operator[](
const size_t index)
169 [[nodiscard]]
constexpr const Element & operator[](
const size_t index)
const
175 [[nodiscard]]
constexpr bool isValid()
const {
return data !=
nullptr; }
195 template<
typename Element>
209 : data(data), mesh(mesh), type(type) {}
212 [[nodiscard]]
bool isValid()
const {
return data !=
nullptr; }
222 [[nodiscard]]
constexpr const Element&
operator[](
const size_t index)
const
230 const Element* data =
nullptr;
301 setMeshFlag(MeshFlags::BoundingBoxSet);
305 static constexpr size_t MaxStreams = 16;
308 static constexpr int NoStream = -1;
317 set(VertexDataType::Positions, VertexFormats::Pos3f, positions);
320 void setColors(std::span<const glm::vec4> colors)
322 set(VertexDataType::Colors0, VertexFormats::Color4f, colors);
325 void setInstancePositions(std::span<const glm::vec3> positions)
327 set(VertexDataType::Positions, VertexFormats::InstancePos3f, positions);
330 void setInstanceColors(std::span<const glm::vec4> colors)
332 set(VertexDataType::Colors0, VertexFormats::InstanceColor4f, colors);
345 template<
typename Iterator>
348 set(VertexDataType::Positions, VertexFormats::Pos3f, begin, end);
366 return map<glm::vec3>(VertexDataType::Positions, VertexFormats::Pos3f, start, end-start);
384 return mapReadOnly<glm::vec3>(VertexDataType::Positions, VertexFormats::Pos3f, start, end - start);
394 set(VertexDataType::Normals, VertexFormats::Norm3f, normals);
407 template<
typename Iterator>
410 set(VertexDataType::Normals, VertexFormats::Norm3f, begin, end);
425 return map<glm::vec3>(VertexDataType::Normals, VertexFormats::Norm3f, start, end-start);
440 return mapReadOnly<glm::vec3>(VertexDataType::Normals, VertexFormats::Norm3f, start, end - start);
450 set(VertexDataType::Tangents, VertexFormats::Tang3f, tangents);
463 template<
typename Iterator>
466 set(VertexDataType::Tangents, VertexFormats::Tang3f, begin, end);
481 return map<glm::vec3>(VertexDataType::Tangents, VertexFormats::Tang3f, start, end-start);
496 return mapReadOnly<glm::vec3>(VertexDataType::Tangents, VertexFormats::Tang3f, start, end - start);
506 set(VertexDataType::TexCoords0, VertexFormats::Tex2f, texCoords);
519 template<
typename Iterator>
522 set(VertexDataType::TexCoords0, VertexFormats::Tex2f, begin, end);
537 return map<glm::vec2>(VertexDataType::TexCoords0, VertexFormats::Tex2f, start, end-start);
552 return mapReadOnly<glm::vec2>(VertexDataType::TexCoords0, VertexFormats::Tex2f, start, end - start);
566 template<
typename Element>
569 return map<Element>(type, format, 0, count);
579 return (0x1 << type);
598 setIndexData(collection.data(), collection.size());
610 auto & stream = getStream(VertexDataType::Indexes);
612 setMeshFlag(MeshFlags::IndexesChanged);
613 unsetMeshFlag(MeshFlags::Indexed);
615 if (hasStream(VertexDataType::SubMeshes)) {
616 DataStream& subMeshes = getStream(VertexDataType::SubMeshes);
617 clearStream(subMeshes);
642 uint32_t numElements,
685 return (meshFlags & flag) == flag;
694 return (isMeshFlagSet(MeshFlags::IndexesChanged) || isMeshFlagSet(MeshFlags::StreamsChanged)) && !isMeshFlagSet(MeshFlags::BoundingBoxSet);
709 auto streamData = mapStream(VertexDataType::Indexes, 0, count,
sizeof(uint32_t),
true);
710 memcpy(streamData, data,
sizeof(uint32_t) * count);
712 this->count =
static_cast<uint32_t
>(count);
714 setMeshFlag(MeshFlags::Indexed);
715 setMeshFlag(MeshFlags::IndexesChanged);
718 void setIndexData(
const uint16_t * data,
size_t count)
722 auto streamData = mapStream(VertexDataType::Indexes, 0, count,
sizeof(uint16_t),
true);
723 memcpy(streamData, data,
sizeof(uint16_t) * count);
725 this->count =
static_cast<uint32_t
>(count);
727 setMeshFlag(MeshFlags::Indexed);
728 setMeshFlag(MeshFlags::IndexesChanged);
740 setIndexData(data.data(), data.size());
753 template<
typename Element>
756 setVertexData(elements, count, Element::getVertexFormat());
770 template<
typename Element>
773 this->count =
static_cast<uint32_t
>(count);
775 set(VertexDataType::Interleaved0, format, elements, elements + count);
791 template<
typename Element>
794 const size_t count = end - begin;
795 auto mapped = map<typename std::remove_const<Element>::type>(type, format, 0, end - begin,
true);
797 for (
size_t i = 0; i < count; ++i) {
798 mapped[i] = *begin++;
800 setMeshFlag(MeshFlags::StreamsChanged);
812 template<
typename Collection>
815 set(type, format, collection.data(), collection.data() + collection.size());
835 template<
typename Element>
838 void* stream = mapStream(type, format, start, count,
sizeof(Element), resize);
856 template<
typename Element>
862 if (!hasStream(type))
867 if (stream.size() < (start + count))
871 void* streamData = mapStream(type, format, start, count,
sizeof(Element), resize);
883 const size_t elementSize,
884 bool resize =
false);
893 bool resize =
false);
902 markStreamChanged(type);
910 streamsUpdated |= Mesh::toFlag(type);
911 setMeshFlag(MeshFlags::StreamsChanged);
935 return streamIndexes[type] != NoStream;
945 return !isMeshFlagSet(MeshFlags::ClockwiseWinding);
955 return isMeshFlagSet(MeshFlags::Indexed);
965 return *
reinterpret_cast<T*
>(ptr + index * stride);
972 return *
reinterpret_cast<const T*
>(ptr + index * stride);
977 constexpr bool isValid()
const {
return ptr !=
nullptr; }
979 uint8_t* ptr =
nullptr;
992 [[nodiscard]] StreamReference getPositionStream();
1001 [[nodiscard]] StreamReference getSemanticStream(
ElementSemantic semantic, DataFormat format);
1012 [[nodiscard]] uint32_t
getCount()
const {
return count; }
1019 void setCount(
size_t count) { this->count =
static_cast<uint32_t
>(count); setMeshFlag(MeshFlags::StreamsChanged); setMeshFlag(MeshFlags::IndexesChanged); }
1033 void setInstanceCount(
size_t count) { instanceCount =
static_cast<uint16_t
>(count); setMeshFlag(MeshFlags::StreamsChanged); setMeshFlag(MeshFlags::IndexesChanged); }
1044 template<
typename Datatype>
1049 copyData(output, semantic, format);
1054 template<
typename Datatype>
1057 if (streams.size()) {
1058 auto[rawData, count, stride] = getSemanticStream(semantic, format);
1060 output.resize(count,
false);
1062 for (
size_t i = 0; i < count; ++i) {
1063 output[i] = *
reinterpret_cast<const Datatype *
>(rawData + i * stride);
1071 class MeshManager * getManager()
const;
1074 std::span<uint32_t> mapPoseIndexes(uint32_t count);
1076 std::span<const uint32_t> getPoseIndexes()
const;
1078 std::span<SubMesh> mapSubMeshes(uint32_t count);
1080 std::span<SubMesh> getSubMeshes();
1083 std::span<const uint32_t> getIndexes()
const;
1085 std::span<const uint16_t> getIndexesU16()
const;
1088 bool hasIndexesU16()
const;
1091 std::vector<DataStream> streams;
1094 std::array<int8_t, static_cast<size_t>(VertexDataType::Reserved)> streamIndexes;
1096 Geometry::BoundingBox boundingBox;
1098 uint16_t streamsUpdated = 0;
1099 uint16_t submeshCount = 0;
1100 uint16_t meshFlags = MeshFlags::None;
1101 PrimitiveType::EPrimitiveType primitiveType = PrimitiveType::TriangleList;
1105 uint16_t instanceCount = 0;
1109 template<
typename Element>
1118#include "MeshHelper.h"
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
@ Normals
Render world-space surface normals.
bool isLine(PrimitiveType::EPrimitiveType primitiveType)
Check if the given primitive type represents lines.
void setChanged(Cogs::Core::Context *context, Cogs::ComponentModel::Component *component, Reflection::FieldId fieldId)
Must be Called after changing a Component field. Mark field changed. Request engine update.
ElementSemantic
Element semantics used to map data to the shader stage.
Contains a stream of data used by Mesh resources.
uint32_t numElements
Number of elements of the type given by format contained in data.
uint32_t offset
Byte offset from the start of the buffer.
VertexFormatHandle format
A pointer to the format describing the contents of the byte buffer.
DataStream()=default
Construct a default data stream.
VertexDataType::EVertexDataType type
Type index used to index streams in a Mesh resource.
uint32_t stride
Element stride.
Cogs::Core::ResourceBufferHandle buffer
Data buffer.
DataStream(DataStream &&other)=default
Move construct the data stream from other.
DataStream(const DataStream &other)=delete
Disable copy constructing data streams.
Wrapper for read-only access to mapped stream data.
bool isValid() const
Returns true if stream mapping successful.
MappedStreamReadOnly(struct Mesh *mesh, const Element *data, VertexDataType::EVertexDataType type)
Constructs a MappedStreamReadOnly from the given mesh for readonly access to the mesh stream.
constexpr const Element & operator[](const size_t index) const
Access the Element at the given index.
Wrapper for mapped stream data automatically updating the Mesh resource mapped from when destructed.
constexpr bool isValid() const
Returns true if stream mapping successful.
MappedStream(MappedStream &&other)
Move construct the wrapper from other.
Element * data
Pointer to the element data mapped from the Mesh data stream.
~MappedStream()
Destructs the mapped stream wrapper.
VertexDataType::EVertexDataType type
Type index of the mesh data stream.
MappedStream(struct Mesh *mesh, Element *data, VertexDataType::EVertexDataType type)
Constructs a MappedStream from the given mesh for updating the mesh.
constexpr Element & operator[](const size_t index)
Access the Element at the given index.
MappedStream(MappedStream &other)=delete
Disabled copy constructor.
struct Mesh * mesh
Pointer to the mapped mesh.
Defines mesh flags controlling the behavior of Mesh resources.
@ Instanced
Mesh contains instance data.
@ StreamsChanged
One or more of the data streams in the mesh changed.
@ IndexesChanged
The index data of the mesh changed.
@ Indexed
The mesh should be drawn indexed, using index data to order the triangle vertexes.
@ BoundingBoxSet
Custom bounding box set, no automatic calculation of bounds should be performed.
@ ClockwiseWinding
The mesh uses clockwise winding order for it's triangles as opposed to the counter-clockwise default.
Utility structure containing reference to a data stream in a mesh.
const T & getDataAt(const size_t index) const
Gets const reference to data at given index. No index or data type checking.
T & getDataAt(uint32_t index)
Gets reference to data at given index. No index or data type checking.
constexpr bool isValid() const
Checks if the stream is valid.
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
MappedStream< glm::vec3 > mapTangents(const size_t start, const size_t end)
Map the tangent stream for write access, range between start and end.
void setTangents(Iterator begin, Iterator end)
Set the tangent data of the mesh.
void setVertexData(Element *elements, size_t count, VertexFormatHandle format)
Set vertex data.
MappedStream< glm::vec2 > mapTexCoords(const size_t start, const size_t end)
Map the texture coordinate stream for write access, range between start and end.
void unmap(VertexDataType::EVertexDataType type)
Unmap the stream with the given vertex data type index.
void markStreamChanged(VertexDataType::EVertexDataType type)
Mark stream with the given vertex data type index as changed.
Mesh & operator=(Mesh &&other) noexcept=default
Move assign from other.
Mesh & operator=(const Mesh &other) noexcept=delete
Disabled copy assign since copying Mesh resources naively might incur a performance penalty.
void setTangents(std::span< const glm::vec3 > tangents)
Set the tangent data of the Mesh.
void setIndexes(std::span< const uint32_t > collection)
Set the index data to the collection given.
MappedStreamReadOnly< Element > mapReadOnly(const VertexDataType::EVertexDataType type, VertexFormatHandle format, const size_t start, const size_t count)
Maps the data stream corresponding to the given type for read-only access.
bool isCCW() const
If triangles in the mesh are specified counter-clockwise, which is the default.
void setTexCoords(std::span< const glm::vec2 > texCoords)
Set the texture coordinate data of the Mesh.
Mesh(Mesh &&other) noexcept=default
Move construct a Mesh from other.
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 set(const VertexDataType::EVertexDataType type, VertexFormatHandle format, const Collection &collection)
Convenience method for setting vertex data to the stream given by type.
void setBounds(Geometry::BoundingBox box)
Set custom bounds for the mesh.
uint32_t getInstanceCount() const
Get the number of instances in this mesh.
Cogs::Memory::TypedBuffer< Datatype > copyData(Cogs::ElementSemantic semantic, DataFormat format)
Return a vector with all elements of the given semantic data as a continous buffer.
void setPositions(Iterator begin, Iterator end)
Set the position data of the mesh.
bool isIndexed() const
If the mesh uses indexed geometry.
constexpr bool isMeshFlagSet(MeshFlags::EMeshFlags flag) const
Check if the given mesh flag(s) is set.
void clearIndexes()
Clear all index data, also clearing all sub-meshes.
void set(const VertexDataType::EVertexDataType type, VertexFormatHandle format, Element *begin, Element *end)
Set the data of the vertex stream indexed by type.
bool hasStream(VertexDataType::EVertexDataType type) const
Check if the Mesh has a DataStream for the given type.
void setTexCoords(Iterator begin, Iterator end)
Set the texture coordinate data of the mesh.
MappedStream< glm::vec3 > mapPositions(const size_t start, const size_t end)
Map the position stream for write access, range between start and end.
MappedStreamReadOnly< glm::vec3 > mapNormalsReadOnly(const size_t start, const size_t end)
Map the normal stream for read access, range between start and end.
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.
MappedStream< Element > map(const VertexDataType::EVertexDataType type, VertexFormatHandle format, const size_t start, const size_t count, bool resize=false)
Maps the data stream corresponding to the given type.
void unsetMeshFlag(MeshFlags::EMeshFlags flag)
Unset the given mesh flag.
void setIndexData(std::span< const uint32_t > data)
Convenience method for setting index data from a vector of source data.
MappedStream< glm::vec3 > mapNormals(const size_t start, const size_t end)
Map the normal stream for write access, range between start and end.
bool boundsDirty() const
Gets if the mesh bounds need to be updated before use.
void setMeshFlag(MeshFlags::EMeshFlags flag)
Set the given mesh flag.
void setVertexData(Element *elements, size_t count)
Set vertex data.
MappedStreamReadOnly< glm::vec3 > mapTangentsReadOnly(const size_t start, const size_t end)
Map the tangent stream for read access, range between start and end.
void setNormals(Iterator begin, Iterator end)
Set the normal data of the mesh.
void setCount(size_t count)
Explicitly set the vertex count of the mesh.
MappedStreamReadOnly< glm::vec3 > mapPositionsReadOnly(const size_t start, const size_t end)
Map the position stream for read access, range between start and end.
uint32_t getCount() const
Get the vertex count of the mesh.
MappedStreamReadOnly< glm::vec2 > mapTexCoordsReadOnly(const size_t start, const size_t end)
Map the texture coordinate stream for read access, range between start and end.
void setPositions(std::span< const glm::vec3 > positions)
Set the position data of the Mesh.
static constexpr uint16_t toFlag(VertexDataType::EVertexDataType type)
Convert the given type index to a flag.
MappedStream< Element > map(const VertexDataType::EVertexDataType type, VertexFormatHandle format, const size_t count)
Maps the data stream corresponding to the given type with the given format and count.
Mesh(const Mesh &other)=delete
Disabled copy constructor since copying Mesh resources naively might incur a performance penalty.
Base class for engine resources.
Defines a sub-mesh of a Mesh resource.
PrimitiveType::EPrimitiveType primitiveType
Primitive type to use when drawing the sub-mesh.
uint32_t startIndex
Start index of the sub-mesh in the index array of the Mesh.
uint32_t numIndexes
Number of indexes to draw for the sub-mesh.
Defines vertex data types used to track streams in Mesh instances.
EVertexDataType
Contains data types.
EPrimitiveType
Primitive type enumeration.