No description
  • C++ 90.1%
  • C 5.3%
  • Zig 4.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Krist Ponpairin 9797d7bd08
Some checks are pending
ci / lint-and-build-and-test (macos-latest) (push) Waiting to run
ci / lint-and-build-and-test (ubuntu-latest) (push) Waiting to run
ci / lint-and-build-and-test (windows-latest) (push) Waiting to run
Merge pull request #24 from krist7599555/patch-1
Fix: make AllowedDOFs non-exhaustive to support bitmasking
2026-02-11 19:27:05 +00:00
.github/workflows upgrade setup-zig 2025-07-20 23:06:03 +01:00
libs - Fixup const-ness of DestroyBodies in_body_ids 2026-01-04 11:19:24 -05:00
src Merge pull request #24 from krist7599555/patch-1 2026-02-11 19:27:05 +00:00
.gitignore files from monorepo @ bde42aaeec763c1bd8781d26285b0f4dc65b1a4c 2024-11-04 21:14:19 +00:00
build.zig - Fixup usage of deprecated std.Build APIs 2026-01-03 17:26:41 -05:00
build.zig.zon Bump minimum_zig_version to 0.15.1 2025-09-14 01:59:54 +01:00
LICENSE files from monorepo @ bde42aaeec763c1bd8781d26285b0f4dc65b1a4c 2024-11-04 21:14:19 +00:00
README.md files from monorepo @ bde42aaeec763c1bd8781d26285b0f4dc65b1a4c 2024-11-04 21:14:19 +00:00

zphysics

Zig build package, bindings and C API for Jolt Physics.

For a simple sample applications please see here.

Getting started

Example build.zig:

pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{ ... });

    const zphysics = b.dependency("zphysics", .{
        .use_double_precision = false,
        .enable_cross_platform_determinism = true,
    });
    exe.root_module.addImport("zphysics", zphysics.module("root"));
    exe.linkLibrary(zphysics.artifact("joltc"));
}

Now in your code you may import and use zphysics:

const zphy = @import("zphysics");

pub fn main() !void {
    try zphy.init(allocator, .{});
    defer zphy.deinit();

    // Create physics system
    const physics_system = try zphy.PhysicsSystem.create(
        ... // layer interfaces - please see sample application
        .{
            .max_bodies = 1024,
            .num_body_mutexes = 0,
            .max_body_pairs = 1024,
            .max_contact_constraints = 1024,
        },
    );
    defer physics_system.destroy();

    // Create shape
    const body_interface = physics_system.getBodyInterfaceMut();

    const shape_settings = try zphy.BoxShapeSettings.create(.{ 1.0, 1.0, 1.0 });
    defer shape_settings.release();

    const shape = try shape_settings.createShape();
    defer shape.release();

    // Create body
    const body_id = try body_interface.createAndAddBody(.{
        .position = .{ 0.0, -1.0, 0.0, 1.0 },
        .rotation = .{ 0.0, 0.0, 0.0, 1.0 },
        .shape = shape,
        .motion_type = .dynamic,
        .object_layer = object_layers.non_moving,
    }, .activate);
    defer body_interface.removeAndDestroyBody(body_id);

    physics_system.optimizeBroadPhase();

    // Perform ray cast
    {
        const query = physics_system.getNarrowPhaseQuery();

        var result = query.castRay(.{ .origin = .{ 0, 10, 0, 1 }, .direction = .{ 0, -20, 0, 0 } }, .{});
        if (result.has_hit) {
            // result.hit.body_id
            // result.hit.fraction
            // result.hit.sub_shape_id
            ...
        }
    }

    // Main loop
    while (...) {
        physics_system.update(1.0 / 60.0, .{});

        // Draw all bodies
        const bodies = physics_system.getBodiesUnsafe();
        for (bodies) |body| {
            if (!zphy.isValidBodyPointer(body)) continue;

            const object_to_world = object_to_world: {
                const position = zm.loadArr4(body.position);
                const rotation = zm.loadArr4(body.rotation);
                var xform = zm.matFromQuat(rotation);
                xform[3] = position;
                xform[3][3] = 1.0;
                break :object_to_world xform;
            };

            // Issue a draw call
            ...
        }
    }
}

Usage in a shared library

The joltc artifact can be built as a shared library by specifying the shared build option:

    const zphysics = b.dependency("zphysics", .{
        .shared = true,
    });

If your zig module uses zphysics and is itself part of a shared library that is reloaded at runtime, then some additional steps are required:

  • Before unloading the shared library, call preUnload to export the internal global state
  • After reloading the shared library, call postReload to import the internal state and update allocator vtables

If you use registerTrace or registerAssertFailed, these must also be called again to update their function pointers.