stim::mesh_description struct

Initialization parameters for meshes.

Mesh data of just about any layout can be expressed using a mesh_description, from a simple list of vertices to complex Struct-Of-Array solutions.

Examples

Fixed-format meshes

A simple two-buffer mesh with POD vertices stored contiguously in one buffer and indices stored the other:

struct example_mesh
{
    struct vertex
    {
        vec3 position;
        vec3 normal;
        vec2 uv;
    };

    std::vector<unsigned> indices;
    std::vector<vertex> vertices;
};

example_mesh m{ /* ... */ };

stim::mesh_description desc{};
desc.flags              = stim::mesh_flags::forward_winding | stim::mesh_flags::triangle_list;
desc.indices            = { m.indices.data(), m.indices.size() };
desc.vertices.count     = m.vertices.size();
desc.vertices.positions = { &m.vertices[0].position.x, sizeof(example_mesh::vertex) };
desc.vertices.normals   = { &m.vertices[0].normal.x, sizeof(example_mesh::vertex) };
desc.vertices.uvs       = { &m.vertices[0].uv.x, sizeof(example_mesh::vertex) };

Mesh vertices stored separately (struct-of-arrays)

A slightly more complex multi-buffer mesh where each scalar component of each vertex is stored in its own buffer:

struct example_mesh
{
    struct soa_vec3
    {
        std::vector<float> x;
        std::vector<float> y;
        std::vector<float> z;
    };
    struct soa_uv
    {
        std::vector<float> u;
        std::vector<float> v;
    };

    std::vector<unsigned> indices;
    soa_vec3 positions;
    soa_vec3 normals;
    soa_uv uvs;
};

example_mesh m{ /* ... */ };

stim::mesh_description desc{};
desc.flags              = stim::mesh_flags::forward_winding | stim::mesh_flags::triangle_list;
desc.indices            = { m.indices.data(), m.indices.size() };
desc.vertices.count     = m.positions.size();
desc.vertices.positions = { m.positions.x.data(), m.positions.y.data(), m.positions.z.data() };
desc.vertices.normals   = { m.normals.x.data(), m.normals.y.data(), m.normals.z.data() };
desc.vertices.uvs       = { m.uvs.u.data(), m.uvs.v.data() };

Mixed-method vertex storage

A hybrid mesh where the positions data is stored in struct-of-arrays format, and all the other data associated with each vertex is stored in a separate POD type buffer:

struct example_mesh
{
    struct soa_vec3
    {
        std::vector<float> x;
        std::vector<float> y;
        std::vector<float> z;
    };
    struct vertex_metadata
    {
        vec3 normal;
        vec2 uv;
        vec4 tangent;
        vec2 lightmap;
        uint32_t debug_colour;
    };

    std::vector<unsigned> indices;
    soa_vec3 positions;
    std::vector<vertex_metadata> metadata;
};

example_mesh m{ /* ... */ };

stim::mesh_description desc{};
desc.flags              = stim::mesh_flags::forward_winding | stim::mesh_flags::triangle_list;
desc.indices            = { m.indices.data(), m.indices.size() };
desc.vertices.count     = m.positions.size();
desc.vertices.positions = { m.positions.x.data(), m.positions.y.data(), m.positions.z.data() };
desc.vertices.normals   = { &m.metadata[0].normal.x, sizeof(example_mesh::vertex_metadata) };
desc.vertices.uvs       = { &m.metadata[0].uv.x, sizeof(example_mesh::vertex_metadata) };

Note that the vertex_metadata type shown above contains more information than the bare minimums used by the library; this is OK, and works because the initializer for each vertex channel specifies the byte stride between the actual channel data, skipping any irrelevant data in between.

UE4 Static Meshes

Mesh descriptions can be directly initialized from an instance of UE4's UStaticMesh:

UStaticMesh& sm = /* ... */;

stim::mesh_description desc{ sm };

Constructors, destructors, conversion operators

mesh_description() defaulted noexcept
Default constructor. Does not initialize the members.
operator bool() const explicit constexpr noexcept
Returns true if the fields of this description are sufficient to describe a valid mesh.

Public functions

auto indexed() const -> bool constexpr noexcept
Returns true if the mesh is indexed.
auto topology() const -> mesh_flags constexpr noexcept
Returns the mesh's topology.
auto triangle_count() const -> size_t constexpr noexcept
Returns the number of triangles in the mesh.
auto winding_order() const -> mesh_flags constexpr noexcept
Returns the mesh's winding order.

Public variables

mesh_flags flags
Flags describing the mesh's topology, winding order, etc.
mesh_vertices_description vertices
A description of the mesh's vertices.
mesh_indices_description indices
A description of the mesh's indices.

Compatibility with UE4

mesh_description(const ::FStaticMeshLODResources& lod) noexcept
Initializes the description from a single LOD of a UE4 static mesh.
mesh_description(const ::UStaticMesh& mesh) noexcept
Initializes the description from the first LOD of a UE4 static mesh.

Friends

auto operator!=(const mesh_description& lhs, const mesh_description& rhs) -> bool noexcept
Returns true if two descriptions do not describe the same mesh.
auto operator==(const mesh_description& lhs, const mesh_description& rhs) -> bool noexcept
Returns true if two descriptions describe the same mesh.

Function documentation

stim::mesh_description::mesh_description() defaulted noexcept

Default constructor. Does not initialize the members.

stim::mesh_description::mesh_description(const ::FStaticMeshLODResources& lod) noexcept

Initializes the description from a single LOD of a UE4 static mesh.

stim::mesh_description::mesh_description(const ::UStaticMesh& mesh) noexcept

Initializes the description from the first LOD of a UE4 static mesh.

Variable documentation

mesh_flags stim::mesh_description::flags

Flags describing the mesh's topology, winding order, etc.

mesh_vertices_description stim::mesh_description::vertices

A description of the mesh's vertices.

mesh_indices_description stim::mesh_description::indices

A description of the mesh's indices.