CnaEngine::Graphics::MeshBuilder

CPU-side mesh builder for faced boxes, plates, crossed plates and billboards — replaced Easy3D::CubeMesh.

Replaced Easy3D::CubeMesh on 2026-10-20 This page used to document easy-3d's CubeMesh (BuildCubeMesh over a CubeBatch). easy-3d was removed on 2026-10-20 and replaced by the strict modules of cna-engine; the game now builds every mesh with MeshBuilder. The page keeps its old file name so existing links keep working.

Overview

Lives in the sibling ../cna-engine repository (CMake target CnaEngine::Graphics, namespace CnaEngine::Graphics; XNA 4.0 types only), not in galaxy-eggbert itself. Galaxy Eggbert uses it with positions plus one texture coordinate per vertex. It is a helper beside CNA, not a scene graph: the game still calls CNA directly.

The builder is the batch — easy-3d's separate CPU batches (CubeBatch, BillboardBatch) and its CubeVertex/BillboardVertex plus index vectors were not taken over. The meshes come out with the same vertices and indices as easy-3d produced, bit for bit (verified by cna-engine's Easy3DEquivalenceTests).

Header: include/CnaEngine/Graphics/MeshBuilder.hpp (in ../cna-engine).

API (as used by GalaxyEggbertCNA)

namespace CnaEngine::Graphics {

struct UvRect { float u0, v0, u1, v1; };          // was Easy3D::UvRect { U0, V0, U1, V1 }

enum class BoxFace { PositiveZ, NegativeZ, PositiveX, NegativeX, PositiveY, NegativeY };
struct BoxFaceStyle { bool visible; UvRect uv; };
using BoxFaces = std::array<BoxFaceStyle, 6>;      // indexed by BoxFace

enum class PlateAxis { Z, X, Y };

class MeshBuilder {
public:
    std::uint32_t AddVertex(const BuilderVertex& vertex);
    void AddTriangle(std::uint32_t a, std::uint32_t b, std::uint32_t c);
    void AddQuad(std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t d);

    void AddBox(const Vector3& min, const Vector3& max, const BoxFaces& faces);
    void AddPlate(const Vector3& center, float width, float height, PlateAxis axis, const UvRect& uv);
    void AddCrossedPlates(const Vector3& center, float width, float height, int planes, const UvRect& uv);
    void AddBillboard(const Vector3& position, const Vector2& size,
                      const Vector3& cameraRight, const Vector3& cameraUp,
                      const UvRect& uv, const Vector2& origin, float rotation);

    const MeshData& Mesh() const;   // the mesh built so far
    MeshData Take();                 // moves the mesh out and resets the builder
};

}

What Replaced What

easy-3d (until 2026-10-20)Now
CubeVertex/BillboardVertex vectors + index vectors, CubeBatch, BillboardBatchOne MeshBuilder (positions + one texture coordinate)
BuildCubeMesh, AppendCubeMeshAddBox(min, max, BoxFaces)
AppendDirectionalCubeMesh (DirectionalCubeItem, DirectionalCubeFace, CubeFace)AddBox with one BoxFaceStyle{visible, uv} per BoxFace
AppendPlateMesh (PlateItem, PlateAxis)AddPlate(center, width, height, PlateAxis::{Z,X,Y}, uv)
AppendTripleCrossMesh (TripleCrossItem)AddCrossedPlates(center, width, height, 3, uv)
AppendBillboardMesh (BillboardItem)AddBillboard(position, size, cameraRight, cameraUp, uv, origin, rotation)
AppendPyramidTipMesh (PyramidTipItem, the teleporter's tip)The game's own AddPyramidTip() in src/GalaxyEggbert/Game/TerrainRenderer.cpp (built with AddVertex/AddTriangle/AddQuad, same vertices)

Galaxy Eggbert's Helpers — TexturedMesh.hpp

The small game header src/GalaxyEggbert/Game/TexturedMesh.hpp wraps the builder for the game's one vertex format:

HelperDoes
MakeTexturedMeshBuilder()A MeshBuilder with positions + one texture coordinate
TexturedVertex(position, uv)A builder vertex for AddVertex
AddCenteredBox(mesh, center, size, faces)
AddCenteredBox(mesh, center, size, uv)
A box of size centred on center, with a style per face or one texture region on all six
UploadTexturedMesh(device, meshData)Uploads the built mesh as a GpuMesh

Used By

GETerrainRenderer builds its terrain meshes from non-air world blocks with a MeshBuilder (AddCenteredBox, AddPlate, AddCrossedPlates, AddPyramidTip) and hands the result to UploadTexturedMesh, which uploads it as a CnaEngine::Graphics::GpuMesh for drawing. Cube objects, billboards (AddBillboard), the HUD and the editor's quads are built the same way.

Modification Policy

Requires approval Modifying ../cna-engine (including this class) requires the user to explicitly scope that repository into the task — it is not blanket-authorized just because galaxy-eggbert depends on it.