package worldgen import ( "sync" packworld "edgaru089.ink/go/gl01/internal/world" "edgaru089.ink/go/gl01/internal/world/blocks" "github.com/aquilax/go-perlin" ) const ( Alpha = 5 // Weight forming the noise sum Beta = 2 // harmonic scaling/spacing N = 3 // iterations AltitudeDensity = 20 // Density of the noise in altitude Sealevel = 63 // Space with Y=63 and lower should be the sea Highest = 74 // Highest part of the terrain Lowest = 54 // Lowest part of the terrain ) var perlins map[int64]*perlin.Perlin var perlinsLock sync.RWMutex func init() { perlins = make(map[int64]*perlin.Perlin) } func fractal(p *perlin.Perlin, x, y float64, levels int) float64 { ans := 0.0 amp := 1.0 for i := 0; i < levels; i++ { ans += amp * p.Noise2D(x, y) amp /= 3 x *= 2 y *= 2 } return ans } // Chunk generates the chunk (must with chunkID set!!) with seed. func Chunk(chunk *packworld.Chunk, world *packworld.World, seed int64) { perlinsLock.RLock() p, ok := perlins[seed] if !ok { perlinsLock.RUnlock() perlinsLock.Lock() p = perlin.NewPerlin(Alpha, Beta, N, seed) perlins[seed] = p perlinsLock.Unlock() } else { perlinsLock.RUnlock() } //log.Printf("noise=%.5f", p.Noise2D(0.1, 0.1)) offX := packworld.ChunkSizeX * chunk.X offZ := packworld.ChunkSizeZ * chunk.Z for x := 0; x < packworld.ChunkSizeX; x++ { for z := 0; z < packworld.ChunkSizeZ; z++ { height := Lowest + int(float64(Highest-Lowest)*(fractal( p, float64(offX+x)/AltitudeDensity, float64(offZ+z)/AltitudeDensity, 6)/2+0.5)) //log.Printf("height = %d (noise=%.5f)", height, p.Noise2D(float64(offX+x)/AltitudeDensity, float64(offZ+z)/AltitudeDensity)/2+0.5) // water for y := Sealevel; y > height; y-- { chunk.Id[x][y][z] = blocks.Water } // covering dirt if height >= Sealevel { chunk.Id[x][height][z] = blocks.Grass } else { chunk.Id[x][height][z] = blocks.Dirt } //chunk.Id[x][height][z] = blocks.DebugDir chunk.Id[x][height-1][z] = blocks.Dirt chunk.Id[x][height-2][z] = blocks.Dirt chunk.Id[x][height-3][z] = blocks.Dirt height -= 4 // stone in the middle for y := height; y >= 1; y-- { chunk.Id[x][y][z] = blocks.Stone } // bedrock at the bottom chunk.Id[x][0][z] = blocks.Bedrock // plant trees if height >= 50 && height <= 70 { if p.Noise2D(float64(offX+x), float64(offZ+z)) > 0.9 { } } } } chunk.InvalidateRender() }