Skip to content

Latest commit

 

History

History
157 lines (122 loc) · 4.4 KB

File metadata and controls

157 lines (122 loc) · 4.4 KB

image

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"));
}

Zemscripten build.zig example:

pub fn build(b: *std.Build) void {
    const target = b.resolveTargetQuery(.{
        .cpu_arch = .wasm32,
        .os_tag = .emscripten,
    });

    const wasm = b.addLibrary(.{ .name = "zemscripten-build", .linkage = .static, .root_module = b.createModule(.{
        .root_source_file = b.path("main.zig"),
        .target = target,
        .optimize = optimize,
    }) });

    // Add Emscripten include paths for @cImport
    const emsdk_path = b.dependency("emsdk", .{}).path("").getPath(b);
    const emscripten_include_path = b.pathJoin(&.{ emsdk_path, "upstream", "emscripten", "cache", "sysroot", "include" });
    wasm.root_module.addSystemIncludePath(.{ .cwd_relative = emscripten_include_path });

    const zemscripten = b.dependency("zemscripten", .{});
    const zmesh = b.dependency("zmesh", .{
        .target = target,
        .optimize = optimize,
        .emscripten_include_path = emscripten_include_path,
    });

    wasm.root_module.addImport("zmesh", zmesh.module("root"));
    wasm.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.
}