Skip to content

Commit 7d7a30c

Browse files
committed
files from monorepo @ 613d847104a072fc1d4442f58d5f50b3f9c3f27c
0 parents  commit 7d7a30c

File tree

9 files changed

+5477
-0
lines changed

9 files changed

+5477
-0
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Ignore some special directories
2+
*zig-cache
3+
*zig-out
4+
5+
# Ignore some special OS files
6+
*.DS_Store

LICENSE

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Michal Ziulek
4+
Copyright (c) 2024 zig-gamedev contributors
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

README.md

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# [zmath](https://github.com/michal-z/zig-gamedev/zmath)
2+
3+
SIMD math library for game developers
4+
5+
Tested on x86_64 and AArch64.
6+
7+
Provides ~140 optimized routines and ~70 extensive tests.
8+
9+
Can be used with any graphics API.
10+
11+
Documentation can be found [here](https://github.com/michal-z/zig-gamedev/zmath/src/zmath.zig).
12+
13+
Benchamrks can be found [here](https://github.com/michal-z/zig-gamedev/zmath/src/benchmark.zig).
14+
15+
An intro article can be found [here](https://zig.news/michalz/fast-multi-platform-simd-math-library-in-zig-2adn).
16+
17+
## Getting started
18+
19+
Copy `zmath` into a subdirectory of your project and add the following to your `build.zig.zon` .dependencies:
20+
```zig
21+
.zmath = .{ .path = "libs/zmath" },
22+
```
23+
24+
Then in your `build.zig` add:
25+
26+
```zig
27+
pub fn build(b: *std.Build) void {
28+
const exe = b.addExecutable(.{ ... });
29+
30+
const zmath = b.dependency("zmath", .{});
31+
exe.root_module.addImport("zmath", zmath.module("root"));
32+
}
33+
```
34+
35+
Now in your code you may import and use zmath:
36+
37+
```zig
38+
const zm = @import("zmath");
39+
40+
pub fn main() !void {
41+
//
42+
// OpenGL/Vulkan example
43+
//
44+
const object_to_world = zm.rotationY(..);
45+
const world_to_view = zm.lookAtRh(
46+
zm.f32x4(3.0, 3.0, 3.0, 1.0), // eye position
47+
zm.f32x4(0.0, 0.0, 0.0, 1.0), // focus point
48+
zm.f32x4(0.0, 1.0, 0.0, 0.0), // up direction ('w' coord is zero because this is a vector not a point)
49+
);
50+
// `perspectiveFovRhGl` produces Z values in [-1.0, 1.0] range (Vulkan app should use `perspectiveFovRh`)
51+
const view_to_clip = zm.perspectiveFovRhGl(0.25 * math.pi, aspect_ratio, 0.1, 20.0);
52+
53+
const object_to_view = zm.mul(object_to_world, world_to_view);
54+
const object_to_clip = zm.mul(object_to_view, view_to_clip);
55+
56+
// Transposition is needed because GLSL uses column-major matrices by default
57+
gl.uniformMatrix4fv(0, 1, gl.TRUE, zm.arrNPtr(&object_to_clip));
58+
59+
// In GLSL: gl_Position = vec4(in_position, 1.0) * object_to_clip;
60+
61+
//
62+
// DirectX example
63+
//
64+
const object_to_world = zm.rotationY(..);
65+
const world_to_view = zm.lookAtLh(
66+
zm.f32x4(3.0, 3.0, -3.0, 1.0), // eye position
67+
zm.f32x4(0.0, 0.0, 0.0, 1.0), // focus point
68+
zm.f32x4(0.0, 1.0, 0.0, 0.0), // up direction ('w' coord is zero because this is a vector not a point)
69+
);
70+
const view_to_clip = zm.perspectiveFovLh(0.25 * math.pi, aspect_ratio, 0.1, 20.0);
71+
72+
const object_to_view = zm.mul(object_to_world, world_to_view);
73+
const object_to_clip = zm.mul(object_to_view, view_to_clip);
74+
75+
// Transposition is needed because HLSL uses column-major matrices by default
76+
const mem = allocateUploadMemory(...);
77+
zm.storeMat(mem, zm.transpose(object_to_clip));
78+
79+
// In HLSL: out_position_sv = mul(float4(in_position, 1.0), object_to_clip);
80+
81+
//
82+
// 'WASD' camera movement example
83+
//
84+
{
85+
const speed = zm.f32x4s(10.0);
86+
const delta_time = zm.f32x4s(demo.frame_stats.delta_time);
87+
const transform = zm.mul(zm.rotationX(demo.camera.pitch), zm.rotationY(demo.camera.yaw));
88+
var forward = zm.normalize3(zm.mul(zm.f32x4(0.0, 0.0, 1.0, 0.0), transform));
89+
90+
zm.storeArr3(&demo.camera.forward, forward);
91+
92+
const right = speed * delta_time * zm.normalize3(zm.cross3(zm.f32x4(0.0, 1.0, 0.0, 0.0), forward));
93+
forward = speed * delta_time * forward;
94+
95+
var cam_pos = zm.loadArr3(demo.camera.position);
96+
97+
if (keyDown('W')) {
98+
cam_pos += forward;
99+
} else if (keyDown('S')) {
100+
cam_pos -= forward;
101+
}
102+
if (keyDown('D')) {
103+
cam_pos += right;
104+
} else if (keyDown('A')) {
105+
cam_pos -= right;
106+
}
107+
108+
zm.storeArr3(&demo.camera.position, cam_pos);
109+
}
110+
111+
//
112+
// SIMD wave equation solver example (works with vector width 4, 8 and 16)
113+
// 'T' can be F32x4, F32x8 or F32x16
114+
//
115+
var z_index: i32 = 0;
116+
while (z_index < grid_size) : (z_index += 1) {
117+
const z = scale * @intToFloat(f32, z_index - grid_size / 2);
118+
const vz = zm.splat(T, z);
119+
120+
var x_index: i32 = 0;
121+
while (x_index < grid_size) : (x_index += zm.veclen(T)) {
122+
const x = scale * @intToFloat(f32, x_index - grid_size / 2);
123+
const vx = zm.splat(T, x) + voffset * zm.splat(T, scale);
124+
125+
const d = zm.sqrt(vx * vx + vz * vz);
126+
const vy = zm.sin(d - vtime);
127+
128+
const index = @intCast(usize, x_index + z_index * grid_size);
129+
zm.store(xslice[index..], vx, 0);
130+
zm.store(yslice[index..], vy, 0);
131+
zm.store(zslice[index..], vz, 0);
132+
}
133+
}
134+
}
135+
```

build.zig

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) void {
4+
const target = b.standardTargetOptions(.{});
5+
6+
const options = .{
7+
.optimize = b.option(
8+
std.builtin.OptimizeMode,
9+
"optimize",
10+
"Select optimization mode",
11+
) orelse b.standardOptimizeOption(.{
12+
.preferred_optimize_mode = .ReleaseFast,
13+
}),
14+
.enable_cross_platform_determinism = b.option(
15+
bool,
16+
"enable_cross_platform_determinism",
17+
"Enable cross-platform determinism",
18+
) orelse true,
19+
};
20+
21+
const options_step = b.addOptions();
22+
inline for (std.meta.fields(@TypeOf(options))) |field| {
23+
options_step.addOption(field.type, field.name, @field(options, field.name));
24+
}
25+
26+
const options_module = options_step.createModule();
27+
28+
const zmath = b.addModule("root", .{
29+
.root_source_file = b.path("src/main.zig"),
30+
.imports = &.{
31+
.{ .name = "zmath_options", .module = options_module },
32+
},
33+
});
34+
35+
const test_step = b.step("test", "Run zmath tests");
36+
37+
const tests = b.addTest(.{
38+
.name = "zmath-tests",
39+
.root_source_file = b.path("src/main.zig"),
40+
.target = target,
41+
.optimize = options.optimize,
42+
});
43+
b.installArtifact(tests);
44+
45+
tests.root_module.addImport("zmath_options", options_module);
46+
47+
test_step.dependOn(&b.addRunArtifact(tests).step);
48+
49+
const benchmark_step = b.step("benchmark", "Run zmath benchmarks");
50+
51+
const benchmarks = b.addExecutable(.{
52+
.name = "zmath-benchmarks",
53+
.root_source_file = b.path("src/benchmark.zig"),
54+
.target = target,
55+
.optimize = options.optimize,
56+
});
57+
b.installArtifact(benchmarks);
58+
59+
benchmarks.root_module.addImport("zmath", zmath);
60+
61+
benchmark_step.dependOn(&b.addRunArtifact(benchmarks).step);
62+
}

build.zig.zon

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.{
2+
.name = "zmath",
3+
.version = "0.11.0-dev",
4+
.paths = .{
5+
"build.zig",
6+
"build.zig.zon",
7+
"src",
8+
"README.md",
9+
"LICENSE",
10+
},
11+
}

0 commit comments

Comments
 (0)