Implement BiomeNoiseVisualizer

This commit is contained in:
Misode
2020-08-07 00:45:31 +02:00
parent 0ffe97dda5
commit 88d6014dfa

View File

@@ -2,11 +2,14 @@ import SimplexNoise from 'simplex-noise'
import { DataModel, Path } from "@mcschema/core";
import { Visualizer } from './VisualizerView';
export class BiomeNoiseVisualizer implements Visualizer {
private noise: SimplexNoise
static readonly noiseMaps = ['altitude', 'temperature', 'humidity', 'weirdness']
private noise: SimplexNoise[]
private biomeSource: any
constructor() {
this.noise = new SimplexNoise()
this.noise = BiomeNoiseVisualizer.noiseMaps.map(e => new SimplexNoise())
}
path() {
@@ -20,17 +23,61 @@ export class BiomeNoiseVisualizer implements Visualizer {
}
draw(model: DataModel, img: ImageData) {
const biomeSource = model.get(new Path(['generator', 'biome_source']))
this.biomeSource = model.get(new Path(['generator', 'biome_source']))
const data = img.data
for (let x = 0; x < 200; x += 1) {
for (let y = 0; y < 100; y += 1) {
const i = (y * (img.width * 4)) + (x * 4)
const b = (this.noise.noise2D(x/50, y/50) > 0) ? 0 : 255
data[i] = b
data[i + 1] = b
data[i + 2] = b
const b = this.closestBiome(x, y)
const color = this.colorFromBiome(b)
data[i] = color[0]
data[i + 1] = color[1]
data[i + 2] = color[2]
data[i + 3] = 255
}
}
}
private closestBiome(x: number, y: number): string {
const noise = this.getNoise(x, y)
if (!this.biomeSource.biomes) return ''
return this.biomeSource.biomes
.map((b: any) => ({
biome: b.biome ?? '',
distance: this.distance([...noise, 0], [...BiomeNoiseVisualizer.noiseMaps.map(s => b.parameters[s]), b.parameters.offset])
}))
.sort((a: any, b: any) => a.distance - b.distance)
[0].biome
}
private distance(a: number[], b: number[]) {
let d = 0
for (let i = 0; i < a.length; i ++) {
d += (a[i]-b[i]) * (a[i]-b[i])
}
return d
}
private getNoise(x: number, y: number): number[] {
return BiomeNoiseVisualizer.noiseMaps.map((id, index) => {
const config = this.biomeSource[`${id}_noise`]
let n = 0
let scale = 2**config.firstOctave
for (let i = 0; i < config.amplitudes.length; i++) {
n += this.noise[index].noise2D(x*scale, y*scale + i) * config.amplitudes[i] * 128 / scale
scale *= 2
}
return n
})
}
private colorFromBiome(biome: string): number[] {
const h = Math.abs(this.hash(biome))
return [h % 256, (h >> 8) % 256, (h >> 16) % 256]
}
private hash(s: string) {
return s.split('').reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)
}
}