aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/rtw/perlin.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtw/perlin.zig')
-rw-r--r--src/rtw/perlin.zig59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/rtw/perlin.zig b/src/rtw/perlin.zig
new file mode 100644
index 0000000..df5de76
--- /dev/null
+++ b/src/rtw/perlin.zig
@@ -0,0 +1,59 @@
+const rand = @import("rand.zig");
+const Random = rand.Random;
+const randomReal01 = rand.randomReal01;
+const randomInt = rand.randomInt;
+const Point3 = @import("vec.zig").Point3;
+
+pub const Perlin = struct {
+ const POINT_COUNT = 256;
+
+ randomNoise: [POINT_COUNT]f64,
+ permX: [POINT_COUNT]usize,
+ permY: [POINT_COUNT]usize,
+ permZ: [POINT_COUNT]usize,
+
+ pub fn init(rng: Random) Perlin {
+ var perlin = Perlin{
+ .randomNoise = undefined,
+ .permX = undefined,
+ .permY = undefined,
+ .permZ = undefined,
+ };
+
+ var i: usize = 0;
+ while (i < POINT_COUNT) : (i += 1) {
+ perlin.randomNoise[i] = randomReal01(rng);
+ }
+ perlinGeneratePerm(rng, &perlin.permX);
+ perlinGeneratePerm(rng, &perlin.permY);
+ perlinGeneratePerm(rng, &perlin.permZ);
+
+ return perlin;
+ }
+
+ pub fn noise(perlin: Perlin, p: Point3) f64 {
+ const i = @intCast(usize, @floatToInt(i32, 4.0 * p.x) & 255);
+ const j = @intCast(usize, @floatToInt(i32, 4.0 * p.y) & 255);
+ const k = @intCast(usize, @floatToInt(i32, 4.0 * p.z) & 255);
+
+ return perlin.randomNoise[perlin.permX[i] ^ perlin.permY[j] ^ perlin.permZ[k]];
+ }
+
+ fn perlinGeneratePerm(rng: Random, p: []usize) void {
+ var i: usize = 0;
+ while (i < POINT_COUNT) : (i += 1) {
+ p[i] = i;
+ }
+ permute(rng, p, POINT_COUNT);
+ }
+
+ fn permute(rng: Random, p: []usize, n: usize) void {
+ var i = n - 1;
+ while (i > 0) : (i -= 1) {
+ const target = randomInt(usize, rng, 0, i);
+ const tmp = p[i];
+ p[i] = p[target];
+ p[target] = tmp;
+ }
+ }
+};