diff options
Diffstat (limited to 'src/rtw/perlin.zig')
| -rw-r--r-- | src/rtw/perlin.zig | 59 |
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; + } + } +}; |
