mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-26 00:16:51 +00:00
Register project noises and DFs to use in previews
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale } from '../../contexts/index.js'
|
||||
import { useLocale, useProject } from '../../contexts/index.js'
|
||||
import { useCanvas } from '../../hooks/index.js'
|
||||
import { densityFunction } from '../../previews/index.js'
|
||||
import { randomSeed } from '../../Utils.js'
|
||||
@@ -8,6 +8,7 @@ import type { PreviewProps } from './index.js'
|
||||
|
||||
export const DensityFunctionPreview = ({ data, shown, version }: PreviewProps) => {
|
||||
const { locale } = useLocale()
|
||||
const { project } = useProject()
|
||||
const [seed, setSeed] = useState(randomSeed())
|
||||
const [autoScroll, setAutoScroll] = useState(false)
|
||||
const [focused, setFocused] = useState<string | undefined>(undefined)
|
||||
@@ -21,7 +22,7 @@ export const DensityFunctionPreview = ({ data, shown, version }: PreviewProps) =
|
||||
return [size, size]
|
||||
},
|
||||
async draw(img) {
|
||||
const options = { offset: offset.current, width: img.width, seed, version }
|
||||
const options = { offset: offset.current, width: img.width, seed, version, project }
|
||||
await densityFunction(data, img, options)
|
||||
},
|
||||
async onDrag(dx) {
|
||||
@@ -36,7 +37,7 @@ export const DensityFunctionPreview = ({ data, shown, version }: PreviewProps) =
|
||||
onLeave() {
|
||||
setFocused(undefined)
|
||||
},
|
||||
}, [version, state, seed])
|
||||
}, [version, state, seed, project])
|
||||
|
||||
useEffect(() => {
|
||||
if (scrollInterval.current) {
|
||||
@@ -51,7 +52,7 @@ export const DensityFunctionPreview = ({ data, shown, version }: PreviewProps) =
|
||||
}, 100) as any
|
||||
}
|
||||
}
|
||||
}, [version, state, seed, shown, autoScroll])
|
||||
}, [version, state, seed, project, shown, autoScroll])
|
||||
|
||||
return <>
|
||||
<div class="controls preview-controls">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale } from '../../contexts/index.js'
|
||||
import { useLocale, useProject } from '../../contexts/index.js'
|
||||
import { useCanvas } from '../../hooks/index.js'
|
||||
import { getNoiseBlock, noiseSettings } from '../../previews/index.js'
|
||||
import { CachedCollections, checkVersion } from '../../services/index.js'
|
||||
@@ -9,6 +9,7 @@ import type { PreviewProps } from './index.js'
|
||||
|
||||
export const NoiseSettingsPreview = ({ data, shown, version }: PreviewProps) => {
|
||||
const { locale } = useLocale()
|
||||
const { project } = useProject()
|
||||
const [seed, setSeed] = useState(randomSeed())
|
||||
const [biome, setBiome] = useState('minecraft:plains')
|
||||
const [biomeScale, setBiomeScale] = useState(0.2)
|
||||
@@ -25,7 +26,7 @@ export const NoiseSettingsPreview = ({ data, shown, version }: PreviewProps) =>
|
||||
return [size, size]
|
||||
},
|
||||
async draw(img) {
|
||||
const options = { biome, biomeDepth, biomeScale, offset: offset.current, width: img.width, seed, version }
|
||||
const options = { biome, biomeDepth, biomeScale, offset: offset.current, width: img.width, seed, version, project }
|
||||
await noiseSettings(data, img, options)
|
||||
},
|
||||
async onDrag(dx) {
|
||||
@@ -41,7 +42,7 @@ export const NoiseSettingsPreview = ({ data, shown, version }: PreviewProps) =>
|
||||
onLeave() {
|
||||
setFocused(undefined)
|
||||
},
|
||||
}, [state, seed])
|
||||
}, [state, seed, project])
|
||||
|
||||
useEffect(() => {
|
||||
if (scrollInterval.current) {
|
||||
@@ -62,7 +63,7 @@ export const NoiseSettingsPreview = ({ data, shown, version }: PreviewProps) =>
|
||||
}
|
||||
})()
|
||||
}
|
||||
}, [version, state, seed, shown, biome, biomeScale, biomeDepth, autoScroll])
|
||||
}, [version, state, seed, project, shown, biome, biomeScale, biomeDepth, autoScroll])
|
||||
|
||||
const allBiomes = useMemo(() => CachedCollections?.get('worldgen/biome') ?? [], [version])
|
||||
|
||||
|
||||
@@ -4,6 +4,13 @@ import type { VersionId } from '../services/index.js'
|
||||
import { checkVersion, fetchAllPresets } from '../services/index.js'
|
||||
import { deepClone, deepEqual } from '../Utils.js'
|
||||
|
||||
export type ProjectData = Record<string, Record<string, unknown>>
|
||||
|
||||
const DYNAMIC_REGISTRIES = new Set([
|
||||
'minecraft:worldgen/noise',
|
||||
'minecraft:worldgen/density_function',
|
||||
])
|
||||
|
||||
export class Deepslate {
|
||||
private d = deepslate19
|
||||
private loadedVersion: VersionId | undefined
|
||||
@@ -17,18 +24,19 @@ export class Deepslate {
|
||||
private generatorCache: ChunkGenerator | undefined
|
||||
private chunksCache: Chunk[] = []
|
||||
|
||||
public async loadVersion(version: VersionId) {
|
||||
public async loadVersion(version: VersionId, project?: ProjectData) {
|
||||
if (this.loadedVersion === version) {
|
||||
this.applyProjectData(version, project)
|
||||
return
|
||||
}
|
||||
if (this.loadingVersion !== version || !this.loadingPromise) {
|
||||
this.loadingVersion = version
|
||||
this.loadingPromise = this.doLoadVersion(version)
|
||||
this.loadingPromise = this.doLoadVersion(version, project)
|
||||
}
|
||||
return this.loadingPromise
|
||||
}
|
||||
|
||||
private async doLoadVersion(version: VersionId) {
|
||||
private async doLoadVersion(version: VersionId, project?: ProjectData) {
|
||||
const cachedDeepslate = this.deepslateCache.get(version)
|
||||
if (cachedDeepslate) {
|
||||
this.d = cachedDeepslate
|
||||
@@ -40,26 +48,47 @@ export class Deepslate {
|
||||
} else {
|
||||
this.d = await import('deepslate-1.18') as any
|
||||
}
|
||||
if (this.d.WorldgenRegistries) {
|
||||
if (checkVersion(version, '1.19')) {
|
||||
await Promise.all(this.d.Registry.REGISTRY.map(async (id, registry) => {
|
||||
if (DYNAMIC_REGISTRIES.has(id.toString())) {
|
||||
const entries = await fetchAllPresets(version, id.path)
|
||||
for (const [key, value] of entries.entries()) {
|
||||
registry.register(this.d.Identifier.parse(key), registry.parse(value), true)
|
||||
}
|
||||
}
|
||||
}))
|
||||
} else if (checkVersion(version, '1.18.2')) {
|
||||
const REGISTRIES: [string, keyof typeof deepslate19.WorldgenRegistries, { fromJson(obj: unknown): any}][] = [
|
||||
['worldgen/noise', 'NOISE', this.d.NoiseParameters],
|
||||
['worldgen/density_function', 'DENSITY_FUNCTION', this.d.DensityFunction],
|
||||
]
|
||||
await Promise.all(REGISTRIES.map(async ([id, name, parser]) => {
|
||||
const entries = await fetchAllPresets(version, id)
|
||||
const registry = new this.d.Registry<typeof parser>(this.d.Identifier.create(id))
|
||||
for (const [key, value] of entries.entries()) {
|
||||
registry.register(this.d.Identifier.parse(key), parser.fromJson(value))
|
||||
this.d.WorldgenRegistries[name].register(this.d.Identifier.parse(key), parser.fromJson(value), true)
|
||||
}
|
||||
this.d.WorldgenRegistries[name].assign(registry as any)
|
||||
}))
|
||||
}
|
||||
this.deepslateCache.set(version, this.d)
|
||||
}
|
||||
this.applyProjectData(version, project)
|
||||
this.loadedVersion = version
|
||||
this.loadingVersion = undefined
|
||||
}
|
||||
|
||||
private applyProjectData(version: VersionId, project?: ProjectData) {
|
||||
if (checkVersion(version, '1.19')) {
|
||||
this.d.Registry.REGISTRY.forEach((id, registry) => {
|
||||
if (DYNAMIC_REGISTRIES.has(id.toString())) {
|
||||
registry.clear()
|
||||
for (const [key, value] of Object.entries(project?.[id.path] ?? {})) {
|
||||
registry.register(this.d.Identifier.parse(key), registry.parse(value))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public loadChunkGenerator(settings: unknown, seed: bigint, biome = 'unknown') {
|
||||
if (!this.loadedVersion) {
|
||||
throw new Error('No deepslate version loaded')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BlockState, clampedMap, DensityFunction } from 'deepslate/worldgen'
|
||||
import type { Project } from '../contexts/Project.jsx'
|
||||
import type { VersionId } from '../services/index.js'
|
||||
import { checkVersion } from '../services/index.js'
|
||||
import { Deepslate } from './Deepslate.js'
|
||||
@@ -12,6 +13,7 @@ export type NoiseSettingsOptions = {
|
||||
width: number,
|
||||
seed: bigint,
|
||||
version: VersionId,
|
||||
project: Project,
|
||||
}
|
||||
|
||||
const colors: Record<string, [number, number, number]> = {
|
||||
@@ -37,8 +39,7 @@ const DEEPSLATE = new Deepslate()
|
||||
|
||||
export async function noiseSettings(state: any, img: ImageData, options: NoiseSettingsOptions) {
|
||||
if (checkVersion(options.version, '1.18')) {
|
||||
|
||||
await DEEPSLATE.loadVersion(options.version)
|
||||
await DEEPSLATE.loadVersion(options.version, getProjectData(options.project))
|
||||
DEEPSLATE.loadChunkGenerator(state, options.seed, options.biome)
|
||||
DEEPSLATE.generateChunks(-options.offset, options.width, options.biome)
|
||||
const noise = DEEPSLATE.getNoiseSettings()
|
||||
@@ -80,7 +81,7 @@ export function getNoiseBlock(x: number, y: number) {
|
||||
}
|
||||
|
||||
export async function densityFunction(state: any, img: ImageData, options: NoiseSettingsOptions) {
|
||||
await DEEPSLATE.loadVersion(options.version)
|
||||
await DEEPSLATE.loadVersion(options.version, getProjectData(options.project))
|
||||
const fn = DEEPSLATE.loadDensityFunction(state, options.seed)
|
||||
const noise = DEEPSLATE.getNoiseSettings()
|
||||
|
||||
@@ -107,6 +108,16 @@ export async function densityFunction(state: any, img: ImageData, options: Noise
|
||||
}
|
||||
}
|
||||
|
||||
function getProjectData(project: Project) {
|
||||
return Object.fromEntries(['worldgen/noise', 'worldgen/density_function'].map(type => {
|
||||
const resources = Object.fromEntries(
|
||||
project.files.filter(file => file.type === type)
|
||||
.map<[string, unknown]>(file => [file.id, file.data])
|
||||
)
|
||||
return [type, resources]
|
||||
}))
|
||||
}
|
||||
|
||||
function getColor(noise: number[], y: number): number {
|
||||
if (noise[y] > 0) {
|
||||
return 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DataModel } from '@mcschema/core'
|
||||
import { LegacyRandom, NoiseParameters, NormalNoise } from 'deepslate/worldgen'
|
||||
import { NoiseParameters, NormalNoise, XoroshiroRandom } from 'deepslate/worldgen'
|
||||
import type { VersionId } from '../services/index.js'
|
||||
|
||||
export type NoiseOptions = {
|
||||
@@ -10,7 +10,7 @@ export type NoiseOptions = {
|
||||
}
|
||||
|
||||
export function normalNoise(state: any, img: ImageData, options: NoiseOptions) {
|
||||
const random = new LegacyRandom(options.seed)
|
||||
const random = XoroshiroRandom.create(options.seed)
|
||||
const params = NoiseParameters.fromJson(DataModel.unwrapLists(state))
|
||||
const noise = new NormalNoise(random, params)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user