TypedMesh is a templated data structure for creating meshes with a custom amount of vertex buffers. It uses a variadic set of BufferTraits to define its interface. For example, a Mesh with a position and color per vertex would be defined as TypedMesh<PositionsBufferTrait,ColorsBufferTrait>
. Depending on the Traits specified in the declaration the interface towards the class is updated.
Simple Usage
using MyMesh = TypedMesh<buffertraits::PositionsBuffer,buffertraits::ColorsBuffer>;
MyMesh mesh;
mesh.addVertex(vec3(0.0f), vec4(1,0,0,1) );
mesh.addVertex(vec3(1.0f), vec4(0,1,0,1) );
If texture coordinates are also needed for each vertex in the mesh then one could instead use:
using MyMesh = TypedMesh<buffertraits::PositionsBuffer, buffertraits::TexCoordBuffer,
buffertraits::ColorsBuffer>;
MyMesh mesh;
mesh.addVertex(vec3(0.0f), vec3(0.0f), vec4(1,0,0,1) );
mesh.addVertex(vec3(1.0f), vec3(1.0f), vec4(0,1,0,1) );
For meshes with more than a couple of vertices, it is more efficient to add all vertices to the mesh at the same time. This can be done by using a std::vector containing TypedMesh::Vertex instead, as described by the following example:
using MyMesh = TypedMesh<PositionsBufferTrait,ColorsBufferTrait>;
std::vector<MyMesh::Vertex> vertices;
vertices.emplace_back(vec3(0.0f), vec4(1,0,0,1));
vertices.emplace_back(vec3(1.0f), vec4(0,1,0,1));
MyMesh mesh;
mesh.addVertices(vertices);
When creating meshes it is very common to also have Index buffers, in addition to the vertex buffers. To add a index buffer to the mesh you can use the function addIndexBuffer as demonstrated by the following example.
using MyMesh = TypedMesh<buffertraits::PositionsBuffer, buffertraits::ColorsBuffer>;
MyMesh mesh;
auto ib = mesh.addIndexBuffer(DrawType::Lines, ConnectivityType::None);
ib->add({0,1});
ib->add({1,2});
Examples
Creating a bounding box with Adjacency information
The following code snippet uses a SimpleMesh2 to create bounding box for a given basisandoffset matrix. It is the code used in meshutil::boundingBoxAdjacency
std::shared_ptr<PosTexColorMesh> boundingBoxAdjacency(const mat4& basisandoffset,
const vec4& color) {
auto mesh = std::make_shared<PosTexColorMesh>();
mesh->setModelMatrix(basisandoffset);
mesh->addVertices({{vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), color},
{vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), color},
{vec3(1.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0), color},
{vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), color},
{vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0), color},
{vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), color},
{vec3(1.0, 1.0, 1.0), vec3(1.0, 1.0, 1.0), color},
{vec3(0.0, 1.0, 1.0), vec3(0.0, 1.0, 1.0), color}});
auto inds1 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds1->add({3, 0, 1, 2, 3, 0, 1});
auto inds2 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds2->add({7, 4, 5, 6, 7, 4, 5});
auto inds3 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds3->add({3, 0, 4, 7, 3, 0, 4});
auto inds4 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds4->add({2, 1, 5, 6, 2, 1, 2});
return mesh;
}
Creating camera frustum
The following code snippet is another example where we create a camera frustum mesh for a given camera. It is the code used in meshutil::cameraFrustum
std::shared_ptr<ColoredMesh> cameraFrustum(const Camera& camera, vec4 color,
std::shared_ptr<ColoredMesh> mesh) {
const static std::vector<vec3> vertices{vec3(-1, -1, -1), vec3(-1, 1, -1), vec3(1, -1, -1),
vec3(1, 1, -1), vec3(-1, -1, 1), vec3(-1, 1, 1),
vec3(1, -1, 1), vec3(1, 1, 1)};
auto& vertVector = mesh->getTypedDataContainer<buffertraits::PositionsBuffer>();
auto& colorVector = mesh->getTypedDataContainer<buffertraits::ColorsBuffer>();
auto off = static_cast<unsigned int>(vertVector.size());
vertVector.insert(vertVector.end(), vertices.begin(), vertices.end());
colorVector.insert(colorVector.end(), 8, color);
mesh->setModelMatrix(glm::inverse(camera.getProjectionMatrix() * camera.getViewMatrix()));
auto ib = std::make_shared<IndexBufferRAM>();
auto indices = std::make_shared<IndexBuffer>(ib);
ib->add({off + 0, off + 1, off + 1, off + 3, off + 3, off + 2, off + 2, off + 0});
ib->add({off + 4, off + 5, off + 5, off + 7, off + 7, off + 6, off + 6, off + 4});
ib->add({off + 0, off + 4, off + 1, off + 5, off + 2, off + 6, off + 3, off + 7});
mesh->addIndices(Mesh::MeshInfo(DrawType::Lines, ConnectivityType::None), indices);
return mesh;
}
◆ BasicMesh
Initial value: TypedMesh<buffertraits::PositionsBuffer, buffertraits::NormalBuffer,
buffertraits::TexCoordBuffer<3>, buffertraits::ColorsBuffer>
Type definition of a TypedMesh having positions(vec3), normals(vec3), texture coordinates(vec3) and colors(vec4).
◆ ColoredMesh
Type definition of a TypedMesh having only positions(vec3) and colors(vec4). Example usage:
std::shared_ptr<ColoredMesh> cameraFrustum(const Camera& camera, vec4 color,
std::shared_ptr<ColoredMesh> mesh) {
const static std::vector<vec3> vertices{vec3(-1, -1, -1), vec3(-1, 1, -1), vec3(1, -1, -1),
vec3(1, 1, -1), vec3(-1, -1, 1), vec3(-1, 1, 1),
vec3(1, -1, 1), vec3(1, 1, 1)};
auto& vertVector = mesh->getTypedDataContainer<buffertraits::PositionsBuffer>();
auto& colorVector = mesh->getTypedDataContainer<buffertraits::ColorsBuffer>();
auto off = static_cast<unsigned int>(vertVector.size());
vertVector.insert(vertVector.end(), vertices.begin(), vertices.end());
colorVector.insert(colorVector.end(), 8, color);
mesh->setModelMatrix(glm::inverse(camera.getProjectionMatrix() * camera.getViewMatrix()));
auto ib = std::make_shared<IndexBufferRAM>();
auto indices = std::make_shared<IndexBuffer>(ib);
ib->add({off + 0, off + 1, off + 1, off + 3, off + 3, off + 2, off + 2, off + 0});
ib->add({off + 4, off + 5, off + 5, off + 7, off + 7, off + 6, off + 6, off + 4});
ib->add({off + 0, off + 4, off + 1, off + 5, off + 2, off + 6, off + 3, off + 7});
mesh->addIndices(Mesh::MeshInfo(DrawType::Lines, ConnectivityType::None), indices);
return mesh;
}
◆ PosTexColorMesh
Initial value: TypedMesh<buffertraits::PositionsBuffer, buffertraits::TexCoordBuffer<3>,
buffertraits::ColorsBuffer>
Type definition of a TypedMesh having positions(vec3), texture coordinates(vec3) and colors(vec4). Example usage:
std::shared_ptr<PosTexColorMesh> boundingBoxAdjacency(const mat4& basisandoffset,
const vec4& color) {
auto mesh = std::make_shared<PosTexColorMesh>();
mesh->setModelMatrix(basisandoffset);
mesh->addVertices({{vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), color},
{vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), color},
{vec3(1.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0), color},
{vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), color},
{vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0), color},
{vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), color},
{vec3(1.0, 1.0, 1.0), vec3(1.0, 1.0, 1.0), color},
{vec3(0.0, 1.0, 1.0), vec3(0.0, 1.0, 1.0), color}});
auto inds1 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds1->add({3, 0, 1, 2, 3, 0, 1});
auto inds2 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds2->add({7, 4, 5, 6, 7, 4, 5});
auto inds3 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds3->add({3, 0, 4, 7, 3, 0, 4});
auto inds4 = mesh->addIndexBuffer(DrawType::Lines, ConnectivityType::StripAdjacency);
inds4->add({2, 1, 5, 6, 2, 1, 2});
return mesh;
}
◆ SphereMesh
Initial value:
TypedMesh<buffertraits::PositionsBuffer, buffertraits::RadiiBuffer, buffertraits::ColorsBuffer>
Type definition of a TypedMesh useful for Spheres, consists of a vec3-buffer for position, a float-buffer for radii and vec4 for colors.