Skip to content

Latest commit

 

History

History
128 lines (98 loc) · 3.44 KB

README.md

File metadata and controls

128 lines (98 loc) · 3.44 KB

image

zmesh

Load, generate, process and optimize triangle meshes in Zig.

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

Copy zmesh to a subdirectory of your project and add the following to your build.zig.zon .dependencies:

    .zmesh = .{ .path = "libs/zmesh" },

Then in your build.zig add:

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