Projects
zig-gamedev/zmesh has 37 GitHub stars and 20 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-14 19:57 UTC. Last push 2026-10-23.
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
Zig library for loading, generating, processing and optimising triangle meshes.
Creative & MediaREADME.md
Original
zmesh
Zig library for loading, generating, processing and optimising triangle meshes.
Under the hood this library uses below C/C++ libraries:
All memory allocations go through user-supplied, Zig allocator.
As an example program please see procedural mesh (wgpu).
Getting started
Example build.zig:
pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{ ... });
const zmesh = b.dependency("zmesh", .{});
exe.root_module.addImport("zmesh", zmesh.module("root"));
exe.linkLibrary(zmesh.artifact("zmesh"));
}
Now in your code you may import and use zmesh:
const zmesh = @import("zmesh");
pub fn main() !void {
...
zmesh.init(allocator);
defer zmesh.deinit();
var custom = zmesh.Shape.init(indices, positions, normals, texcoords);
defer custom.deinit();
var disk = zmesh.Shape.initParametricDisk(10, 2);
defer disk.deinit();
disk.invert(0, 0);
var cylinder = zmesh.Shape.initCylinder(10, 4);
defer cylinder.deinit();
cylinder.merge(disk);
cylinder.translate(0, 0, -1);
disk.invert(0, 0);
cylinder.merge(disk);
cylinder.scale(0.5, 0.5, 2);
cylinder.rotate(math.pi * 0.5, 1.0, 0.0, 0.0);
cylinder.unweld();
cylinder.computeNormals();
...
}
const zmesh = @import("zmesh");
pub fn main() !void {
zmesh.init(allocator);
defer zmesh.deinit();
//
// Load mesh
//
const data = try zmesh.io.zcgltf.parseAndLoadFile(content_dir ++ "cube.gltf");
defer zmesh.io.zcgltf.freeData(data);
var mesh_indices = std.ArrayListUnmanaged(u32){};
var mesh_positions = std.ArrayListUnmanaged([3]f32){};
var mesh_normals = std.ArrayListUnmanaged([3]f32){};
try zmesh.io.zcgltf.appendMeshPrimitive(
allocator,
data,
0, // mesh index
0, // gltf primitive index (submesh index)
&mesh_indices,
&mesh_positions,
&mesh_normals, // normals (optional)
null, // texcoords (optional)
null, // tangents (optional)
);
...
//
// Optimize mesh
//
const Vertex = struct {
position: [3]f32,
normal: [3]f32,
};
var remap = std.ArrayListUnmanaged(u32){};
try remap.resize(allocator, src_indices.items.len);
const num_unique_vertices = zmesh.opt.generateVertexRemap(
remap.items, // 'vertex remap' (destination)
src_indices.items, // non-optimized indices
Vertex, // Zig type describing your vertex
src_vertices.items, // non-optimized vertices
);
var optimized_vertices = std.ArrayListUnmanaged(Vertex){};
try optimized_vertices.resize(allocator, num_unique_vertices);
zmesh.opt.remapVertexBuffer(
Vertex, // Zig type describing your vertex
optimized_vertices.items, // optimized vertices (destination)
src_vertices.items, // non-optimized vertices (source)
remap.items, // 'vertex remap' generated by generateVertexRemap()
);
// More optimization steps are available - see `zmeshoptimizer.zig` file.
}