mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-25 16:16:50 +00:00
Implement BiomeNoiseVisualizer
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user