From c99155fb47f784b8aab54e3da65e0c1cf2a86a85 Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Fri, 30 Aug 2024 21:56:39 +1000 Subject: [PATCH] split worldgen --- Sources/Voxelotl/CMakeLists.txt | 1 + Sources/Voxelotl/Game.swift | 16 +++-------- Sources/Voxelotl/World.swift | 39 +++++++------------------- Sources/Voxelotl/WorldGenerator.swift | 40 +++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 41 deletions(-) create mode 100644 Sources/Voxelotl/WorldGenerator.swift diff --git a/Sources/Voxelotl/CMakeLists.txt b/Sources/Voxelotl/CMakeLists.txt index 5b00820..2628f77 100644 --- a/Sources/Voxelotl/CMakeLists.txt +++ b/Sources/Voxelotl/CMakeLists.txt @@ -51,6 +51,7 @@ add_executable(Voxelotl MACOSX_BUNDLE # Game logic classes Chunk.swift + WorldGenerator.swift World.swift Raycast.swift Player.swift diff --git a/Sources/Voxelotl/Game.swift b/Sources/Voxelotl/Game.swift index 7bf0bbc..8671526 100644 --- a/Sources/Voxelotl/Game.swift +++ b/Sources/Voxelotl/Game.swift @@ -40,20 +40,12 @@ class Game: GameDelegate { } private func generateWorld() { - var random: any RandomProvider -#if true - let newSeed = UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32 - printErr(newSeed) - random = Xoroshiro128PlusPlus(seed: newSeed) -#else - random = PCG32Random(state: ( - UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32, - UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32)) -#endif + let seed = UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32 + printErr(seed) #if DEBUG - self.world.generate(width: 2, height: 1, depth: 1, random: &random) + self.world.generate(width: 2, height: 1, depth: 1, seed: seed) #else - self.world.generate(width: 5, height: 3, depth: 5, random: &random) + self.world.generate(width: 5, height: 3, depth: 5, seed: seed) #endif } diff --git a/Sources/Voxelotl/World.swift b/Sources/Voxelotl/World.swift index 63e0d79..7bff672 100644 --- a/Sources/Voxelotl/World.swift +++ b/Sources/Voxelotl/World.swift @@ -2,11 +2,11 @@ import Foundation public class World { private var _chunks: Dictionary, Chunk> - private var noise: ImprovedPerlin! - private var noise2: SimplexNoise! + private var _generator: WorldGenerator public init() { self._chunks = [:] + self._generator = WorldGenerator() } func getBlock(at position: SIMD3) -> Block { @@ -19,40 +19,21 @@ public class World { self._chunks[position &>> Chunk.shift]?.setBlock(at: position, type: type) } - func generate(width: Int, height: Int, depth: Int, random: inout any RandomProvider) { - self.noise = ImprovedPerlin(random: &random) - self.noise2 = SimplexNoise(random: &random) - - for x in 0..) { - let chunkOrigin = chunkID &<< Chunk.shift - var chunk = Chunk(position: chunkOrigin) - chunk.fill(allBy: { position in - let fpos = SIMD3(position) - let threshold: Float = 0.6 - let value = fpos.y / Float(Chunk.size) - + self.noise.get(fpos * 0.05) * 1.1 - + self.noise.get(fpos * 0.10) * 0.5 - + self.noise.get(fpos * 0.30) * 0.23 - return if value < threshold { - .solid(.init( - hue: Float16(180 + self.noise2.get(fpos * 0.05) * 180), - saturation: Float16(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 4)) * 0.5), - value: Float16(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 9)) * 0.5).lerp(0.5, 1)).linear) - } else { - .air - } - }) - self._chunks[chunkID] = chunk + self._chunks[chunkID] = self._generator.makeChunk(id: chunkID) } var instances: [Instance] { diff --git a/Sources/Voxelotl/WorldGenerator.swift b/Sources/Voxelotl/WorldGenerator.swift new file mode 100644 index 0000000..2fe5142 --- /dev/null +++ b/Sources/Voxelotl/WorldGenerator.swift @@ -0,0 +1,40 @@ +struct WorldGenerator { + var noise: ImprovedPerlin!, noise2: SimplexNoise! + + public mutating func reset(seed: UInt64) { + var random: any RandomProvider +#if true + random = Xoroshiro128PlusPlus(seed: seed) +#else + //TODO: Fill seed with a hash + random = PCG32Random(state: ( + UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32, + UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32)) +#endif + + self.noise = ImprovedPerlin(random: &random) + self.noise2 = SimplexNoise(random: &random) + } + + public func makeChunk(id chunkID: SIMD3) -> Chunk { + let chunkOrigin = chunkID &<< Chunk.shift + var chunk = Chunk(position: chunkOrigin) + chunk.fill(allBy: { position in + let fpos = SIMD3(position) + let threshold: Float = 0.6 + let value = fpos.y / Float(Chunk.size) + + self.noise.get(fpos * 0.05) * 1.1 + + self.noise.get(fpos * 0.10) * 0.5 + + self.noise.get(fpos * 0.30) * 0.23 + return if value < threshold { + .solid(.init( + hue: Float16(180 + self.noise2.get(fpos * 0.05) * 180), + saturation: Float16(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 4)) * 0.5), + value: Float16(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 9)) * 0.5).lerp(0.5, 1)).linear) + } else { + .air + } + }) + return chunk + } +}