An open API service indexing awesome lists of open source software.

https://github.com/zig-gamedev/zmesh

Zig library for loading, generating, processing and optimising triangle meshes.
https://github.com/zig-gamedev/zmesh

3d gamedev mesh-generation mesh-optimization mesh-processing zig

Last synced: 11 months ago
JSON representation

Zig library for loading, generating, processing and optimising triangle meshes.

Awesome Lists containing this project

README

          

![image](logo.jpg)

# [zmesh](https://github.com/zig-gamedev/zmesh)

Zig library for loading, generating, processing and optimising triangle meshes.

Under the hood this library uses below C/C++ libraries:

* [par shapes](https://github.com/prideout/par/blob/master/par_shapes.h)
* [meshoptimizer](https://github.com/zeux/meshoptimizer)
* [cgltf](https://github.com/jkuhlmann/cgltf)

All memory allocations go through user-supplied, Zig allocator.

As an example program please see [procedural mesh (wgpu)](https://github.com/michal-z/zig-gamedev/tree/main/samples/procedural_mesh_wgpu).

## Getting started

Example `build.zig`:
```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`:

```zig
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();
...
}
```

```zig
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.ArrayList(u32).init(allocator);
var mesh_positions = std.ArrayList([3]f32).init(allocator);
var mesh_normals = std.ArrayList([3]f32).init(allocator);

zmesh.io.zcgltf.appendMeshPrimitive(
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.ArrayList(u32).init(allocator);
remap.resize(src_indices.items.len) catch unreachable;

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.ArrayList(Vertex).init(allocator);
optimized_vertices.resize(num_unique_vertices) catch unreachable;

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.
}
```