diff --git a/prismarine-viewer/viewer/lib/mesher/shared.ts b/prismarine-viewer/viewer/lib/mesher/shared.ts index 07b667471..11988db22 100644 --- a/prismarine-viewer/viewer/lib/mesher/shared.ts +++ b/prismarine-viewer/viewer/lib/mesher/shared.ts @@ -7,7 +7,8 @@ export const defaultMesherConfig = { smoothLighting: true, outputFormat: 'threeJs' as 'threeJs' | 'webgpu', textureSize: 1024, // for testing - debugModelVariant: undefined as undefined | number[] + debugModelVariant: undefined as undefined | number[], + clipWorldBelowY: undefined as undefined | number } export type MesherConfig = typeof defaultMesherConfig diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index ea90da372..65546de4f 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -321,6 +321,10 @@ export abstract class WorldRendererCommon console.log('texture loaded') } + get worldMinYRender () { + return Math.floor(Math.max(this.worldConfig.minY, this.mesherConfig.clipWorldBelowY ?? -Infinity) / 16) * 16 + } + addColumn (x: number, z: number, chunk: any, isLightUpdate: boolean) { if (!this.active) return if (this.workers.length === 0) throw new Error('workers not initialized yet') @@ -330,7 +334,7 @@ export abstract class WorldRendererCommon // todo optimize worker.postMessage({ type: 'chunk', x, z, chunk }) } - for (let y = this.worldConfig.minY; y < this.worldConfig.worldHeight; y += 16) { + for (let y = this.worldMinYRender; y < this.worldConfig.worldHeight; y += 16) { const loc = new Vec3(x, y, z) this.setSectionDirty(loc) if (this.neighborChunkUpdates && (!isLightUpdate || this.mesherConfig.smoothLighting)) { diff --git a/src/optionsStorage.ts b/src/optionsStorage.ts index 01610cf2f..c97dadc17 100644 --- a/src/optionsStorage.ts +++ b/src/optionsStorage.ts @@ -52,6 +52,7 @@ const defaultOptions = { // antiAliasing: false, + clipWorldBelowY: undefined as undefined | number, // will be removed showChunkBorders: false, // todo rename option frameLimit: false as number | false, alwaysBackupWorldBeforeLoading: undefined as boolean | undefined | null, @@ -157,7 +158,7 @@ subscribe(options, () => { localStorage.options = JSON.stringify(saveOptions) }) -type WatchValue = >(proxy: T, callback: (p: T) => void) => void +type WatchValue = >(proxy: T, callback: (p: T, isChanged: boolean) => void) => void export const watchValue: WatchValue = (proxy, callback) => { const watchedProps = new Set() @@ -166,10 +167,10 @@ export const watchValue: WatchValue = (proxy, callback) => { watchedProps.add(p.toString()) return Reflect.get(target, p, receiver) }, - })) + }), false) for (const prop of watchedProps) { subscribeKey(proxy, prop, () => { - callback(proxy) + callback(proxy, true) }) } } diff --git a/src/watchOptions.ts b/src/watchOptions.ts index 3ea170636..2996a2e1c 100644 --- a/src/watchOptions.ts +++ b/src/watchOptions.ts @@ -58,6 +58,12 @@ export const watchOptionsAfterViewerInit = () => { watchValue(options, o => { viewer.world.displayStats = o.renderDebug === 'advanced' }) + watchValue(options, (o, isChanged) => { + viewer.world.mesherConfig.clipWorldBelowY = o.clipWorldBelowY + if (isChanged) { + (viewer.world as WorldRendererThree).rerenderAllChunks() + } + }) viewer.world.mesherConfig.smoothLighting = options.smoothLighting subscribeKey(options, 'smoothLighting', () => {