minecraft-renderer 0.1.79 → 0.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -25
- package/dist/mesher.js +36 -36
- package/dist/mesher.js.map +4 -4
- package/dist/mesherWasm.js +217 -217
- package/dist/minecraft-renderer.js +27 -27
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +133 -133
- package/package.json +5 -2
- package/src/bundler/bundlePrepare.ts +3 -8
- package/src/graphicsBackend/appViewer.ts +10 -7
- package/src/graphicsBackend/config.ts +1 -5
- package/src/graphicsBackend/playerState.ts +35 -34
- package/src/graphicsBackend/preloadWorkers.ts +43 -41
- package/src/graphicsBackend/rendererDefaultOptions.ts +68 -70
- package/src/graphicsBackend/rendererOptionsSync.ts +24 -50
- package/src/graphicsBackend/types.ts +2 -2
- package/src/index.ts +6 -27
- package/src/lib/DebugGui.ts +34 -31
- package/src/lib/animationController.ts +9 -9
- package/src/lib/bakeLegacyLight.ts +1 -6
- package/src/lib/bindAbortableListener.test.ts +32 -12
- package/src/lib/bindAbortableListener.ts +14 -6
- package/src/lib/blockEntityLightRegistry.ts +11 -20
- package/src/lib/blockEntityLighting.test.ts +1 -6
- package/src/lib/blockEntityLighting.ts +5 -5
- package/src/lib/buildSharedConfig.mjs +4 -4
- package/src/lib/buildWorkerMcDataIndexes.test.ts +4 -4
- package/src/lib/buildWorkerMcDataIndexes.ts +11 -19
- package/src/lib/cameraBobbing.ts +1 -1
- package/src/lib/canvas2DOverlay.example.ts +13 -33
- package/src/lib/canvas2DOverlay.quickstart.ts +24 -54
- package/src/lib/canvas2DOverlay.ts +28 -47
- package/src/lib/cleanupDecorator.ts +2 -2
- package/src/lib/createPlayerObject.test.ts +2 -7
- package/src/lib/createPlayerObject.ts +18 -25
- package/src/lib/frameTimingCollector.ts +2 -5
- package/src/lib/guiRenderer.ts +57 -42
- package/src/lib/items.ts +15 -9
- package/src/lib/mesherlogReader.ts +5 -6
- package/src/lib/simpleUtils.ts +5 -5
- package/src/lib/skyLight.ts +3 -3
- package/src/lib/smoothSwitcher.ts +11 -18
- package/src/lib/ui/newStats.ts +10 -12
- package/src/lib/utils/proxy.ts +7 -1
- package/src/lib/utils/skins.ts +4 -4
- package/src/lib/utils.ts +1 -1
- package/src/lib/workerMessageSanitize.ts +5 -12
- package/src/lib/workerProxy.ts +52 -42
- package/src/lib/workerSyncOps.test.ts +58 -41
- package/src/lib/worldrendererCommon.reconfigure.test.ts +24 -21
- package/src/lib/worldrendererCommon.removeColumn.test.ts +11 -13
- package/src/lib/worldrendererCommon.ts +338 -211
- package/src/mesher-legacy/mesher.ts +9 -4
- package/src/mesher-legacy/test/a.ts +1 -1
- package/src/mesher-legacy/test/mesherTester.ts +2 -2
- package/src/mesher-legacy/test/playground.ts +1 -1
- package/src/mesher-legacy/test/run/test-js.ts +1 -1
- package/src/mesher-legacy/test/snapshotUtils.ts +3 -8
- package/src/mesher-legacy/test/test-perf.ts +1 -1
- package/src/mesher-legacy/test/tests.test.ts +2 -2
- package/src/mesher-shared/blockEntityMetadata.test.ts +7 -5
- package/src/mesher-shared/blockEntityMetadata.ts +28 -19
- package/src/mesher-shared/blockPropertiesForMeshing.ts +2 -2
- package/src/mesher-shared/computeHeightmap.ts +2 -4
- package/src/mesher-shared/exportedGeometryTypes.ts +3 -3
- package/src/mesher-shared/faceOcclusion.ts +324 -0
- package/src/mesher-shared/models.ts +80 -131
- package/src/mesher-shared/modelsGeometryCommon.ts +30 -15
- package/src/mesher-shared/shared.ts +46 -46
- package/src/mesher-shared/standaloneRenderer.ts +40 -44
- package/src/mesher-shared/tests/faceOcclusion.test.ts +179 -0
- package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +12 -8
- package/src/mesher-shared/vertexShading.ts +2 -11
- package/src/mesher-shared/world.ts +19 -19
- package/src/mesher-shared/worldLighting.test.ts +2 -2
- package/src/performanceMonitor/PerformanceMonitor.ts +4 -13
- package/src/performanceMonitor/formatPerformanceFactorsDebug.ts +2 -2
- package/src/performanceMonitor/index.ts +1 -5
- package/src/performanceMonitor/types.ts +1 -1
- package/src/playerState/playerState.ts +55 -50
- package/src/playerState/types.ts +2 -8
- package/src/playground/allEntitiesDebug.ts +19 -16
- package/src/playground/baseScene.ts +29 -32
- package/src/playground/mobileControls.tsx +133 -129
- package/src/playground/playground.html +76 -73
- package/src/playground/playground.ts +14 -1
- package/src/playground/playgroundUi.tsx +100 -74
- package/src/playground/reactUtils.ts +3 -7
- package/src/playground/scenes/entities.ts +10 -7
- package/src/playground/scenes/frequentUpdates.ts +5 -5
- package/src/playground/scenes/geometryExport.ts +6 -20
- package/src/playground/scenes/highPosEntityUpdates.ts +2 -10
- package/src/playground/scenes/index.ts +1 -1
- package/src/playground/scenes/lightingStarfield.ts +18 -12
- package/src/playground/scenes/main.ts +15 -11
- package/src/playground/scenes/partialBlockCulling.ts +31 -0
- package/src/playground/scenes/railsCobweb.ts +1 -1
- package/src/playground/scenes/rotationIssue.ts +1 -1
- package/src/playground/scenes/slabsOptimization.ts +1 -2
- package/src/playground/scenes/transparencyIssue.ts +1 -1
- package/src/playground/shared.ts +2 -2
- package/src/resourcesManager/resourcesManager.ts +29 -54
- package/src/resourcesManager/resourcesManager.worker.test.ts +6 -10
- package/src/shims/minecraftData.ts +70 -24
- package/src/sign-renderer/index.html +10 -12
- package/src/sign-renderer/index.ts +29 -29
- package/src/sign-renderer/playground.ts +22 -15
- package/src/sign-renderer/tests.test.ts +16 -13
- package/src/sign-renderer/vite.config.ts +2 -2
- package/src/three/appShared.ts +46 -25
- package/src/three/bannerRenderer.ts +33 -61
- package/src/three/cameraShake.ts +15 -6
- package/src/three/chunkMeshManager.ts +239 -282
- package/src/three/cinimaticScript.ts +26 -15
- package/src/three/cubeDrawSpans.ts +27 -37
- package/src/three/cubeMultiDraw.ts +9 -22
- package/src/three/documentRenderer.ts +15 -18
- package/src/three/entities.ts +175 -150
- package/src/three/entity/EntityMesh.ts +114 -108
- package/src/three/entity/animations.js +3 -3
- package/src/three/entity/armorModels.ts +15 -15
- package/src/three/entity/gltfAnimationUtils.ts +2 -5
- package/src/three/fireworks.ts +34 -32
- package/src/three/fireworksRenderer.ts +32 -29
- package/src/three/globalBlockBuffer.ts +167 -100
- package/src/three/globalLegacyBuffer.ts +257 -166
- package/src/three/graphicsBackendBase.ts +19 -25
- package/src/three/graphicsBackendOffThread.ts +12 -15
- package/src/three/hand.ts +21 -21
- package/src/three/handLegacy.ts +3 -13
- package/src/three/holdingBlock.ts +116 -79
- package/src/three/holdingBlockFactory.ts +1 -4
- package/src/three/holdingBlockItemIdentity.test.ts +25 -17
- package/src/three/holdingBlockItemIdentity.ts +9 -6
- package/src/three/holdingBlockLegacy.ts +113 -132
- package/src/three/itemMesh.ts +20 -29
- package/src/three/legacyMultiDraw.ts +10 -16
- package/src/three/legacySectionCull.ts +8 -14
- package/src/three/menuBackground/activeView.ts +1 -4
- package/src/three/menuBackground/assetUrl.ts +1 -1
- package/src/three/menuBackground/classic.ts +4 -12
- package/src/three/menuBackground/gpuPreference.ts +1 -3
- package/src/three/menuBackground/index.ts +2 -11
- package/src/three/menuBackground/renderer.ts +1 -5
- package/src/three/menuBackground/types.ts +1 -4
- package/src/three/menuBackground/v2.ts +196 -96
- package/src/three/menuBackground/v2Meta.ts +3 -3
- package/src/three/menuBackground/worldBlocks.ts +37 -35
- package/src/three/modules/blockBreakParticles.ts +59 -28
- package/src/three/modules/cameraBobbing.ts +3 -6
- package/src/three/modules/index.ts +1 -1
- package/src/three/modules/rain.ts +10 -23
- package/src/three/modules/sciFiWorldReveal.ts +11 -25
- package/src/three/modules/starfield.ts +7 -13
- package/src/three/renderSlot.ts +28 -16
- package/src/three/rendererModuleSystem.ts +1 -3
- package/src/three/sceneOrigin.ts +96 -33
- package/src/three/sectionRaycastAabb.ts +30 -18
- package/src/three/shaderCubeMesh.ts +6 -17
- package/src/three/shaders/cubeBlockShader.ts +85 -96
- package/src/three/shaders/legacyBlockShader.ts +21 -43
- package/src/three/shaders/textureIndexMapping.ts +89 -95
- package/src/three/shaders/tintPalette.ts +156 -170
- package/src/three/signTextureCache.ts +9 -12
- package/src/three/skyboxRenderer.ts +62 -70
- package/src/three/tests/chunkMeshManagerLegacy.test.ts +34 -34
- package/src/three/tests/cubeDrawSpans.test.ts +55 -25
- package/src/three/tests/globalBlockBuffer.test.ts +217 -0
- package/src/three/tests/globalLegacyBuffer.test.ts +300 -41
- package/src/three/tests/legacyMultiDraw.test.ts +8 -29
- package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
- package/src/three/tests/signTextureCache.test.ts +4 -4
- package/src/three/threeJsMedia.ts +55 -72
- package/src/three/threeJsParticles.ts +32 -41
- package/src/three/threeJsSound.ts +3 -3
- package/src/three/threeJsUtils.ts +3 -3
- package/src/three/threeWorker.ts +2 -2
- package/src/three/waypointSprite.ts +55 -82
- package/src/three/waypoints.ts +20 -23
- package/src/three/world/cursorBlock.ts +25 -12
- package/src/three/world/vr.ts +11 -17
- package/src/three/worldGeometryExport.ts +15 -34
- package/src/three/worldRendererThree.ts +117 -129
- package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
- package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
- package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
- package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
- package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
- package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
- package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +17 -4
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
- package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
- package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
- package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
- package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
- package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
- package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
- package/src/worldView/worldView.spiral.test.ts +1 -1
- package/src/worldView/worldView.ts +34 -39
- package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
|
@@ -9,7 +9,15 @@ import { proxy, subscribe } from 'valtio'
|
|
|
9
9
|
import type { ResourcesManagerTransferred } from '../resourcesManager/resourcesManager'
|
|
10
10
|
import { dynamicMcDataFiles } from './buildSharedConfig.mjs'
|
|
11
11
|
import { DisplayWorldOptions, GraphicsInitOptions, RendererReactiveState, SoundSystem } from '../graphicsBackend/types'
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
HighestBlockInfo,
|
|
14
|
+
CustomBlockModels,
|
|
15
|
+
BlockStateModelInfo,
|
|
16
|
+
getBlockAssetsCacheKey,
|
|
17
|
+
MesherConfig,
|
|
18
|
+
MesherMainEvent,
|
|
19
|
+
SECTION_HEIGHT
|
|
20
|
+
} from '../mesher-shared/shared'
|
|
13
21
|
import { chunkPos } from './simpleUtils'
|
|
14
22
|
import { addNewStat, MC_RENDERER_DEBUG_OVERLAY_CLASS, removeAllStats, updatePanesVisibility, updateStatText } from './ui/newStats'
|
|
15
23
|
import { getPlayerStateUtils } from '../graphicsBackend/playerState'
|
|
@@ -43,7 +51,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
43
51
|
chunksRenderBelowEnabled: false,
|
|
44
52
|
chunksRenderDistanceOverride: undefined as number | undefined,
|
|
45
53
|
chunksRenderDistanceEnabled: false,
|
|
46
|
-
disableEntities: false
|
|
54
|
+
disableEntities: false
|
|
47
55
|
// disableParticles: false
|
|
48
56
|
})
|
|
49
57
|
|
|
@@ -90,7 +98,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
90
98
|
isProcessingQueue = false
|
|
91
99
|
ONMESSAGE_TIME_LIMIT = 30 // ms
|
|
92
100
|
|
|
93
|
-
handleResize = () => {
|
|
101
|
+
handleResize = () => {}
|
|
94
102
|
highestBlocksByChunks = new Map<string, { [chunkKey: string]: HighestBlockInfo }>()
|
|
95
103
|
blockEntities = {}
|
|
96
104
|
|
|
@@ -131,7 +139,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
131
139
|
private mesherPoolSnapshot = {
|
|
132
140
|
mesherWorkers: -1,
|
|
133
141
|
wasmMesher: false,
|
|
134
|
-
dedicatedChangeWorker: false
|
|
142
|
+
dedicatedChangeWorker: false
|
|
135
143
|
}
|
|
136
144
|
private mesherReconfigureQueue: Promise<void> = Promise.resolve()
|
|
137
145
|
private heightmapDebounceTimers = new Map<string, ReturnType<typeof setTimeout>>()
|
|
@@ -203,7 +211,11 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
203
211
|
return (this.initOptions.config.statsVisible ?? 0) > 1
|
|
204
212
|
}
|
|
205
213
|
|
|
206
|
-
constructor(
|
|
214
|
+
constructor(
|
|
215
|
+
public readonly resourcesManager: ResourcesManagerTransferred,
|
|
216
|
+
public displayOptions: DisplayWorldOptions,
|
|
217
|
+
public initOptions: GraphicsInitOptions
|
|
218
|
+
) {
|
|
207
219
|
this.snapshotInitialValues()
|
|
208
220
|
this.worldRendererConfig = displayOptions.inWorldRenderingConfig
|
|
209
221
|
this.playerStateReactive = displayOptions.playerStateReactive!
|
|
@@ -270,12 +282,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
270
282
|
if (!this.active) return
|
|
271
283
|
await this.updateAssetsData()
|
|
272
284
|
}
|
|
273
|
-
bindAbortableEmitterListener(
|
|
274
|
-
this.resourcesManager,
|
|
275
|
-
'assetsTexturesUpdated',
|
|
276
|
-
onAssetsTexturesUpdated,
|
|
277
|
-
this.abortController.signal
|
|
278
|
-
)
|
|
285
|
+
bindAbortableEmitterListener(this.resourcesManager, 'assetsTexturesUpdated', onAssetsTexturesUpdated, this.abortController.signal)
|
|
279
286
|
|
|
280
287
|
this.watchReactivePlayerState()
|
|
281
288
|
this.watchReactiveConfig()
|
|
@@ -283,7 +290,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
283
290
|
this.worldReadyResolvers.resolve()
|
|
284
291
|
}
|
|
285
292
|
|
|
286
|
-
snapshotInitialValues() {
|
|
293
|
+
snapshotInitialValues() {}
|
|
287
294
|
|
|
288
295
|
wasChunkSentToWorker(chunkKey: string) {
|
|
289
296
|
return this.loadedChunks[chunkKey]
|
|
@@ -305,7 +312,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
305
312
|
}
|
|
306
313
|
}
|
|
307
314
|
|
|
308
|
-
async getBlockInfo(blockPos: { x: number
|
|
315
|
+
async getBlockInfo(blockPos: { x: number; y: number; z: number }, stateId: number) {
|
|
309
316
|
const CHUNK_SIZE = 16
|
|
310
317
|
const chunkKey = `${Math.floor(blockPos.x / CHUNK_SIZE) * CHUNK_SIZE},${Math.floor(blockPos.z / CHUNK_SIZE) * CHUNK_SIZE}`
|
|
311
318
|
const customBlockName = this.protocolCustomBlocks.get(chunkKey)?.[`${blockPos.x},${blockPos.y},${blockPos.z}`]
|
|
@@ -323,14 +330,17 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
323
330
|
|
|
324
331
|
private createMesherWorker() {
|
|
325
332
|
const script = this.getMesherWorkerScript()
|
|
326
|
-
return initMesherWorker(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
333
|
+
return initMesherWorker(
|
|
334
|
+
data => {
|
|
335
|
+
if (Array.isArray(data)) {
|
|
336
|
+
this.messageQueue.push(...data)
|
|
337
|
+
} else {
|
|
338
|
+
this.messageQueue.push(data)
|
|
339
|
+
}
|
|
340
|
+
void this.processMessageQueue('worker')
|
|
341
|
+
},
|
|
342
|
+
script === 'wasm' ? 'mesherWasm.js' : 'mesher.js'
|
|
343
|
+
)
|
|
334
344
|
}
|
|
335
345
|
|
|
336
346
|
initWorkers(numWorkers = this.worldRendererConfig.mesherWorkers) {
|
|
@@ -343,7 +353,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
343
353
|
this.mesherPoolSnapshot = {
|
|
344
354
|
mesherWorkers: this.worldRendererConfig.mesherWorkers,
|
|
345
355
|
wasmMesher: this.worldRendererConfig.wasmMesher,
|
|
346
|
-
dedicatedChangeWorker: this.worldRendererConfig.dedicatedChangeWorker
|
|
356
|
+
dedicatedChangeWorker: this.worldRendererConfig.dedicatedChangeWorker
|
|
347
357
|
}
|
|
348
358
|
}
|
|
349
359
|
|
|
@@ -353,11 +363,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
353
363
|
const tryReconfigure = () => {
|
|
354
364
|
const cfg = this.worldRendererConfig
|
|
355
365
|
const snap = this.mesherPoolSnapshot
|
|
356
|
-
if (
|
|
357
|
-
cfg.mesherWorkers === snap.mesherWorkers &&
|
|
358
|
-
cfg.wasmMesher === snap.wasmMesher &&
|
|
359
|
-
cfg.dedicatedChangeWorker === snap.dedicatedChangeWorker
|
|
360
|
-
) {
|
|
366
|
+
if (cfg.mesherWorkers === snap.mesherWorkers && cfg.wasmMesher === snap.wasmMesher && cfg.dedicatedChangeWorker === snap.dedicatedChangeWorker) {
|
|
361
367
|
return
|
|
362
368
|
}
|
|
363
369
|
this.syncMesherPoolSnapshot()
|
|
@@ -365,16 +371,14 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
365
371
|
}
|
|
366
372
|
|
|
367
373
|
for (const key of ['mesherWorkers', 'wasmMesher', 'dedicatedChangeWorker'] as const) {
|
|
368
|
-
this.valtioUnsubs.push(
|
|
369
|
-
this.onReactiveConfigUpdated(key, tryReconfigure, false)
|
|
370
|
-
)
|
|
374
|
+
this.valtioUnsubs.push(this.onReactiveConfigUpdated(key, tryReconfigure, false))
|
|
371
375
|
}
|
|
372
376
|
}
|
|
373
377
|
|
|
374
378
|
private enqueueMesherWorkersReconfigure() {
|
|
375
379
|
this.mesherReconfigureQueue = this.mesherReconfigureQueue
|
|
376
380
|
.then(() => this.reconfigureMesherWorkers())
|
|
377
|
-
.catch(
|
|
381
|
+
.catch(err => {
|
|
378
382
|
console.error('[Mesher] Failed to reconfigure workers:', err)
|
|
379
383
|
})
|
|
380
384
|
}
|
|
@@ -450,7 +454,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
450
454
|
|
|
451
455
|
onReactiveConfigUpdated<T extends keyof typeof this.worldRendererConfig>(
|
|
452
456
|
key: T,
|
|
453
|
-
callback: (value: typeof this.worldRendererConfig[T]) => void,
|
|
457
|
+
callback: (value: (typeof this.worldRendererConfig)[T]) => void,
|
|
454
458
|
initial = true
|
|
455
459
|
) {
|
|
456
460
|
if (initial) {
|
|
@@ -462,19 +466,19 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
462
466
|
return subscribeKey(this.worldRendererConfig, key, callback)
|
|
463
467
|
}
|
|
464
468
|
|
|
465
|
-
onReactiveDebugUpdated<T extends keyof typeof this.reactiveDebugParams>(key: T, callback: (value: typeof this.reactiveDebugParams[T]) => void) {
|
|
469
|
+
onReactiveDebugUpdated<T extends keyof typeof this.reactiveDebugParams>(key: T, callback: (value: (typeof this.reactiveDebugParams)[T]) => void) {
|
|
466
470
|
callback(this.reactiveDebugParams[key])
|
|
467
471
|
subscribeKey(this.reactiveDebugParams, key, callback)
|
|
468
472
|
}
|
|
469
473
|
|
|
470
474
|
watchReactivePlayerState() {
|
|
471
475
|
this.valtioUnsubs.push(
|
|
472
|
-
this.onReactivePlayerStateUpdated('backgroundColor',
|
|
476
|
+
this.onReactivePlayerStateUpdated('backgroundColor', value => {
|
|
473
477
|
this.changeBackgroundColor(value)
|
|
474
478
|
})
|
|
475
479
|
)
|
|
476
480
|
this.valtioUnsubs.push(
|
|
477
|
-
this.onReactivePlayerStateUpdated('cardinalLight',
|
|
481
|
+
this.onReactivePlayerStateUpdated('cardinalLight', value => {
|
|
478
482
|
this.changeCardinalLight(value)
|
|
479
483
|
})
|
|
480
484
|
)
|
|
@@ -482,7 +486,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
482
486
|
|
|
483
487
|
watchReactiveConfig() {
|
|
484
488
|
this.valtioUnsubs.push(
|
|
485
|
-
this.onReactiveConfigUpdated('fetchPlayerSkins',
|
|
489
|
+
this.onReactiveConfigUpdated('fetchPlayerSkins', value => {
|
|
486
490
|
setSkinsConfig({ apiEnabled: value })
|
|
487
491
|
})
|
|
488
492
|
)
|
|
@@ -491,7 +495,12 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
491
495
|
async processMessageQueue(source: string) {
|
|
492
496
|
if (this.isProcessingQueue || this.messageQueue.length === 0) return
|
|
493
497
|
this.logWorkerWork(`# ${source} processing queue`)
|
|
494
|
-
if (
|
|
498
|
+
if (
|
|
499
|
+
this.lastRendered &&
|
|
500
|
+
performance.now() - this.lastRendered > this.ONMESSAGE_TIME_LIMIT &&
|
|
501
|
+
this.worldRendererConfig._experimentalSmoothChunkLoading &&
|
|
502
|
+
this.renderingActive
|
|
503
|
+
) {
|
|
495
504
|
const start = performance.now()
|
|
496
505
|
await new Promise(resolve => {
|
|
497
506
|
requestAnimationFrame(resolve)
|
|
@@ -512,7 +521,10 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
512
521
|
}
|
|
513
522
|
|
|
514
523
|
// Check if we've exceeded the time limit
|
|
515
|
-
if (
|
|
524
|
+
if (
|
|
525
|
+
processingStopped ||
|
|
526
|
+
(performance.now() - startTime > this.ONMESSAGE_TIME_LIMIT && this.renderingActive && this.worldRendererConfig._experimentalSmoothChunkLoading)
|
|
527
|
+
) {
|
|
516
528
|
// If we have more messages and exceeded time limit, schedule next batch
|
|
517
529
|
if (this.messageQueue.length > 0) {
|
|
518
530
|
requestAnimationFrame(async () => {
|
|
@@ -544,7 +556,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
544
556
|
const chunkCoords = data.key.split(',').map(Number)
|
|
545
557
|
this.lastChunkDistance = Math.max(...this.getDistance(new Vec3(chunkCoords[0], 0, chunkCoords[2])))
|
|
546
558
|
}
|
|
547
|
-
if (data.type === 'sectionFinished') {
|
|
559
|
+
if (data.type === 'sectionFinished') {
|
|
560
|
+
// on after load & unload section
|
|
548
561
|
this.logWorkerWork(`<- ${data.workerIndex} sectionFinished ${data.key} ${JSON.stringify({ processTime: data.processTime })}`)
|
|
549
562
|
if (!this.sectionsWaiting.has(data.key)) {
|
|
550
563
|
console.debug(`sectionFinished for non-outstanding section ${data.key} (viewDistance=${this.viewDistance})`)
|
|
@@ -558,7 +571,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
558
571
|
|
|
559
572
|
const chunkCoords = data.key.split(',').map(Number)
|
|
560
573
|
const chunkKey = `${chunkCoords[0]},${chunkCoords[2]}`
|
|
561
|
-
if (this.loadedChunks[chunkKey]) {
|
|
574
|
+
if (this.loadedChunks[chunkKey]) {
|
|
575
|
+
// ensure chunk data was added, not a neighbor chunk update
|
|
562
576
|
let loaded = true
|
|
563
577
|
const sectionHeight = this.getSectionHeight()
|
|
564
578
|
for (let y = this.worldMinYRender; y < this.worldSizeParams.worldHeight; y += sectionHeight) {
|
|
@@ -601,15 +615,15 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
601
615
|
this.renderUpdateEmitter.emit('update')
|
|
602
616
|
if (data.processTime) {
|
|
603
617
|
this.workersProcessAverageTimeCount++
|
|
604
|
-
this.workersProcessAverageTime =
|
|
618
|
+
this.workersProcessAverageTime =
|
|
619
|
+
(this.workersProcessAverageTime * (this.workersProcessAverageTimeCount - 1) + data.processTime) / this.workersProcessAverageTimeCount
|
|
605
620
|
this.maxWorkersProcessTime = Math.max(this.maxWorkersProcessTime, data.processTime)
|
|
606
621
|
}
|
|
607
|
-
if (typeof data.pre === 'number' && typeof data.wasm === 'number' && typeof data.post === 'number'
|
|
608
|
-
&& (data.pre > 0 || data.wasm > 0 || data.post > 0)) {
|
|
622
|
+
if (typeof data.pre === 'number' && typeof data.wasm === 'number' && typeof data.post === 'number' && (data.pre > 0 || data.wasm > 0 || data.post > 0)) {
|
|
609
623
|
const n = ++this.workersPhaseSampleCount
|
|
610
|
-
this.workersPreAverageTime = (
|
|
611
|
-
this.workersWasmAverageTime = (
|
|
612
|
-
this.workersPostAverageTime = (
|
|
624
|
+
this.workersPreAverageTime = (this.workersPreAverageTime * (n - 1) + data.pre) / n
|
|
625
|
+
this.workersWasmAverageTime = (this.workersWasmAverageTime * (n - 1) + data.wasm) / n
|
|
626
|
+
this.workersPostAverageTime = (this.workersPostAverageTime * (n - 1) + data.post) / n
|
|
613
627
|
// Pre-stage substages — additive schema; treat undefined as 0 so
|
|
614
628
|
// events from older mesher builds don't poison the running mean.
|
|
615
629
|
const ptc = typeof data.preTargetConvert === 'number' ? data.preTargetConvert : 0
|
|
@@ -619,11 +633,11 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
619
633
|
const po = typeof data.preOther === 'number' ? data.preOther : 0
|
|
620
634
|
const pch = typeof data.preCacheHits === 'number' ? data.preCacheHits : 0
|
|
621
635
|
const pcm = typeof data.preCacheMisses === 'number' ? data.preCacheMisses : 0
|
|
622
|
-
this.workersPreTargetConvertAverageTime = (
|
|
623
|
-
this.workersPreNeighborConvertAverageTime = (
|
|
624
|
-
this.workersPreNeighborCountAverage = (
|
|
625
|
-
this.workersPreTypedArrayBuildAverageTime = (
|
|
626
|
-
this.workersPreOtherAverageTime = (
|
|
636
|
+
this.workersPreTargetConvertAverageTime = (this.workersPreTargetConvertAverageTime * (n - 1) + ptc) / n
|
|
637
|
+
this.workersPreNeighborConvertAverageTime = (this.workersPreNeighborConvertAverageTime * (n - 1) + pnc) / n
|
|
638
|
+
this.workersPreNeighborCountAverage = (this.workersPreNeighborCountAverage * (n - 1) + pncn) / n
|
|
639
|
+
this.workersPreTypedArrayBuildAverageTime = (this.workersPreTypedArrayBuildAverageTime * (n - 1) + ptab) / n
|
|
640
|
+
this.workersPreOtherAverageTime = (this.workersPreOtherAverageTime * (n - 1) + po) / n
|
|
627
641
|
this.workersPreCacheHitsTotal += pch
|
|
628
642
|
this.workersPreCacheMissesTotal += pcm
|
|
629
643
|
if (this.worldRendererConfig.debugWasmPerf && n % WorldRendererCommon.PHASE_PERF_LOG_INTERVAL === 0) {
|
|
@@ -641,7 +655,9 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
641
655
|
const cacheTotal = this.workersPreCacheHitsTotal + this.workersPreCacheMissesTotal
|
|
642
656
|
const cacheHitPct = cacheTotal > 0 ? (this.workersPreCacheHitsTotal / cacheTotal) * 100 : 0
|
|
643
657
|
// eslint-disable-next-line no-console
|
|
644
|
-
console.log(
|
|
658
|
+
console.log(
|
|
659
|
+
`[wasm-mesher perf] n=${n} pre=${this.workersPreAverageTime.toFixed(2)}ms (${prePct.toFixed(1)}%) wasm=${this.workersWasmAverageTime.toFixed(2)}ms (${wasmPct.toFixed(1)}%) post=${this.workersPostAverageTime.toFixed(2)}ms (${postPct.toFixed(1)}%) | pre.targetConvert=${this.workersPreTargetConvertAverageTime.toFixed(2)}ms (${tgtPct.toFixed(1)}%) pre.neighborConvert=${this.workersPreNeighborConvertAverageTime.toFixed(2)}ms (${nbrPct.toFixed(1)}%) [n̄=${nbrCnt.toFixed(2)}, per-nbr=${nbrPerAvg.toFixed(2)}ms] pre.typedArrayBuild=${this.workersPreTypedArrayBuildAverageTime.toFixed(2)}ms (${tabPct.toFixed(1)}%) pre.other=${this.workersPreOtherAverageTime.toFixed(2)}ms (${othPct.toFixed(1)}%) | pre.cache hits=${this.workersPreCacheHitsTotal} misses=${this.workersPreCacheMissesTotal} (${cacheHitPct.toFixed(1)}% hit)`
|
|
660
|
+
)
|
|
645
661
|
}
|
|
646
662
|
}
|
|
647
663
|
}
|
|
@@ -679,7 +695,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
679
695
|
this.updateChunksStats()
|
|
680
696
|
}
|
|
681
697
|
|
|
682
|
-
changeHandSwingingState(isAnimationPlaying: boolean, isLeftHand: boolean): void {
|
|
698
|
+
changeHandSwingingState(isAnimationPlaying: boolean, isLeftHand: boolean): void {}
|
|
683
699
|
|
|
684
700
|
abstract handleWorkerMessage(data: WorkerReceive): void
|
|
685
701
|
|
|
@@ -769,7 +785,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
769
785
|
|
|
770
786
|
getMesherConfig(): MesherConfig {
|
|
771
787
|
const timeOfDay = this.timeOfTheDay
|
|
772
|
-
const skyLight =
|
|
788
|
+
const skyLight = timeOfDay < 0 || timeOfDay > 24_000 ? 15 : calculateSkyLightSimple(timeOfDay)
|
|
773
789
|
return {
|
|
774
790
|
version: this.version,
|
|
775
791
|
enableLighting: this.worldRendererConfig.enableLighting,
|
|
@@ -786,7 +802,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
786
802
|
worldMaxY: this.worldMinYRender + this.worldSizeParams.worldHeight,
|
|
787
803
|
disableConversionCache: this.worldRendererConfig.disableMesherConversionCache,
|
|
788
804
|
computeWireframeEdges: this.worldRendererConfig.futuristicReveal === true,
|
|
789
|
-
shaderCubeBlocks: this.isShaderCubeBlocksEnabled()
|
|
805
|
+
shaderCubeBlocks: this.isShaderCubeBlocksEnabled()
|
|
790
806
|
}
|
|
791
807
|
}
|
|
792
808
|
|
|
@@ -810,7 +826,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
810
826
|
latest: resources.blocksAtlasJson
|
|
811
827
|
},
|
|
812
828
|
blockstatesModels,
|
|
813
|
-
config: this.getMesherConfig()
|
|
829
|
+
config: this.getMesherConfig()
|
|
814
830
|
})
|
|
815
831
|
}
|
|
816
832
|
|
|
@@ -868,10 +884,13 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
868
884
|
this.workers[0].postMessage({
|
|
869
885
|
type: 'getHeightmap',
|
|
870
886
|
x,
|
|
871
|
-
z
|
|
887
|
+
z
|
|
872
888
|
})
|
|
873
889
|
}
|
|
874
|
-
this.logWorkerWork(
|
|
890
|
+
this.logWorkerWork(
|
|
891
|
+
() =>
|
|
892
|
+
`-> chunk ${JSON.stringify({ x, z, chunkLength: chunk.length, customBlockModelsLength: customBlockModels ? Object.keys(customBlockModels).length : 0 })}`
|
|
893
|
+
)
|
|
875
894
|
this.mesherLogReader?.chunkReceived(x, z, chunk.length)
|
|
876
895
|
const sectionHeight = this.getSectionHeight()
|
|
877
896
|
const CHUNK_SIZE = 16
|
|
@@ -933,7 +952,9 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
933
952
|
const sectionKey = `${x},${y},${z}`
|
|
934
953
|
const waitingCount = this.sectionsWaiting.get(sectionKey)
|
|
935
954
|
if (waitingCount !== undefined && waitingCount > 0) {
|
|
936
|
-
console.debug(
|
|
955
|
+
console.debug(
|
|
956
|
+
`[removeColumn] clearing non-zero sectionsWaiting for ${sectionKey}: ${waitingCount} (chunk ${x},${z}, viewDistance=${this.viewDistance})`
|
|
957
|
+
)
|
|
937
958
|
}
|
|
938
959
|
this.sectionsWaiting.delete(sectionKey)
|
|
939
960
|
delete this.finishedSections[sectionKey]
|
|
@@ -971,126 +992,206 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
971
992
|
void set()
|
|
972
993
|
}
|
|
973
994
|
|
|
974
|
-
updateEntity(e: any, isUpdate = false) {
|
|
995
|
+
updateEntity(e: any, isUpdate = false) {}
|
|
975
996
|
|
|
976
997
|
abstract updatePlayerEntity?(e: any): void
|
|
977
998
|
|
|
978
|
-
lightUpdate(chunkX: number, chunkZ: number) {
|
|
999
|
+
lightUpdate(chunkX: number, chunkZ: number) {}
|
|
979
1000
|
|
|
980
1001
|
connect(worldView: WorldViewWorker) {
|
|
981
1002
|
const worldEmitter = worldView
|
|
982
1003
|
const signal = this.abortController.signal
|
|
983
1004
|
|
|
984
|
-
bindAbortableListener(
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1005
|
+
bindAbortableListener(
|
|
1006
|
+
worldEmitter,
|
|
1007
|
+
'entity',
|
|
1008
|
+
e => {
|
|
1009
|
+
this.updateEntity(e, false)
|
|
1010
|
+
},
|
|
1011
|
+
signal
|
|
1012
|
+
)
|
|
1013
|
+
bindAbortableListener(
|
|
1014
|
+
worldEmitter,
|
|
1015
|
+
'entityMoved',
|
|
1016
|
+
e => {
|
|
1017
|
+
this.updateEntity(e, true)
|
|
1018
|
+
},
|
|
1019
|
+
signal
|
|
1020
|
+
)
|
|
1021
|
+
bindAbortableListener(
|
|
1022
|
+
worldEmitter,
|
|
1023
|
+
'playerEntity',
|
|
1024
|
+
e => {
|
|
1025
|
+
this.updatePlayerEntity?.(e)
|
|
1026
|
+
},
|
|
1027
|
+
signal
|
|
1028
|
+
)
|
|
993
1029
|
|
|
994
1030
|
let currentLoadChunkBatch = null as {
|
|
995
1031
|
timeout
|
|
996
1032
|
data
|
|
997
1033
|
} | null
|
|
998
|
-
bindAbortableListener(
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1034
|
+
bindAbortableListener(
|
|
1035
|
+
worldEmitter,
|
|
1036
|
+
'loadChunk',
|
|
1037
|
+
({ x, z, chunk, worldConfig, isLightUpdate }) => {
|
|
1038
|
+
this.worldSizeParams = worldConfig
|
|
1039
|
+
this.queuedChunks.add(`${x},${z}`)
|
|
1040
|
+
const args = [x, z, chunk, isLightUpdate]
|
|
1041
|
+
if (!currentLoadChunkBatch) {
|
|
1042
|
+
// add a setting to use debounce instead
|
|
1043
|
+
currentLoadChunkBatch = {
|
|
1044
|
+
data: [],
|
|
1045
|
+
timeout: setTimeout(() => {
|
|
1046
|
+
for (const args of currentLoadChunkBatch!.data) {
|
|
1047
|
+
this.queuedChunks.delete(`${args[0]},${args[1]}`)
|
|
1048
|
+
this.addColumn(...(args as Parameters<typeof this.addColumn>))
|
|
1049
|
+
}
|
|
1050
|
+
for (const fn of this.queuedFunctions) {
|
|
1051
|
+
fn()
|
|
1052
|
+
}
|
|
1053
|
+
this.queuedFunctions = []
|
|
1054
|
+
currentLoadChunkBatch = null
|
|
1055
|
+
}, this.worldRendererConfig.addChunksBatchWaitTime)
|
|
1056
|
+
}
|
|
1017
1057
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1058
|
+
currentLoadChunkBatch.data.push(args)
|
|
1059
|
+
},
|
|
1060
|
+
signal
|
|
1061
|
+
)
|
|
1021
1062
|
// todo remove and use other architecture instead so data flow is clear
|
|
1022
|
-
bindAbortableListener(
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
bindAbortableListener(
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1063
|
+
bindAbortableListener(
|
|
1064
|
+
worldEmitter,
|
|
1065
|
+
'blockEntities',
|
|
1066
|
+
blockEntities => {
|
|
1067
|
+
this.blockEntities = blockEntities
|
|
1068
|
+
},
|
|
1069
|
+
signal
|
|
1070
|
+
)
|
|
1071
|
+
|
|
1072
|
+
bindAbortableListener(
|
|
1073
|
+
worldEmitter,
|
|
1074
|
+
'unloadChunk',
|
|
1075
|
+
({ x, z }) => {
|
|
1076
|
+
this.removeColumn(x, z)
|
|
1077
|
+
},
|
|
1078
|
+
signal
|
|
1079
|
+
)
|
|
1080
|
+
|
|
1081
|
+
bindAbortableListener(
|
|
1082
|
+
worldEmitter,
|
|
1083
|
+
'blockUpdate',
|
|
1084
|
+
({ pos, stateId }) => {
|
|
1085
|
+
this.setBlockStateId(new Vec3(pos.x, pos.y, pos.z), stateId)
|
|
1086
|
+
},
|
|
1087
|
+
signal
|
|
1088
|
+
)
|
|
1089
|
+
|
|
1090
|
+
bindAbortableListener(
|
|
1091
|
+
worldEmitter,
|
|
1092
|
+
'chunkPosUpdate',
|
|
1093
|
+
({ pos }) => {
|
|
1094
|
+
this.updateViewerPosition(pos)
|
|
1095
|
+
},
|
|
1096
|
+
signal
|
|
1097
|
+
)
|
|
1098
|
+
|
|
1099
|
+
bindAbortableListener(
|
|
1100
|
+
worldEmitter,
|
|
1101
|
+
'end',
|
|
1102
|
+
() => {
|
|
1103
|
+
this.worldStop?.()
|
|
1104
|
+
},
|
|
1105
|
+
signal
|
|
1106
|
+
)
|
|
1107
|
+
|
|
1108
|
+
bindAbortableListener(
|
|
1109
|
+
worldEmitter,
|
|
1110
|
+
'renderDistance',
|
|
1111
|
+
d => {
|
|
1112
|
+
this.viewDistance = d
|
|
1113
|
+
this.chunksLength = d === 0 ? 1 : generateSpiralMatrix(d).length
|
|
1114
|
+
this.allChunksFinished = Object.keys(this.finishedChunks).length === this.chunksLength
|
|
1115
|
+
this.onRenderDistanceChanged?.(d)
|
|
1116
|
+
},
|
|
1117
|
+
signal
|
|
1118
|
+
)
|
|
1119
|
+
|
|
1120
|
+
bindAbortableListener(
|
|
1121
|
+
worldEmitter,
|
|
1122
|
+
'markAsLoaded',
|
|
1123
|
+
({ x, z }) => {
|
|
1124
|
+
this.markAsLoaded(x, z)
|
|
1125
|
+
},
|
|
1126
|
+
signal
|
|
1127
|
+
)
|
|
1128
|
+
|
|
1129
|
+
bindAbortableListener(
|
|
1130
|
+
worldEmitter,
|
|
1131
|
+
'updateLight',
|
|
1132
|
+
({ pos }) => {
|
|
1133
|
+
this.lightUpdate(pos.x, pos.z)
|
|
1134
|
+
},
|
|
1135
|
+
signal
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
bindAbortableListener(
|
|
1139
|
+
worldEmitter,
|
|
1140
|
+
'onWorldSwitch',
|
|
1141
|
+
() => {
|
|
1142
|
+
for (const fn of this.onWorldSwitched) {
|
|
1143
|
+
try {
|
|
1144
|
+
fn()
|
|
1145
|
+
} catch (e) {
|
|
1146
|
+
setTimeout(() => {
|
|
1147
|
+
console.log('[Renderer Backend] Error in onWorldSwitched:')
|
|
1148
|
+
throw e
|
|
1149
|
+
}, 0)
|
|
1150
|
+
}
|
|
1066
1151
|
}
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1152
|
+
},
|
|
1153
|
+
signal
|
|
1154
|
+
)
|
|
1069
1155
|
|
|
1070
|
-
bindAbortableListener(
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1156
|
+
bindAbortableListener(
|
|
1157
|
+
worldEmitter,
|
|
1158
|
+
'time',
|
|
1159
|
+
timeOfDay => {
|
|
1160
|
+
if (!this.worldRendererConfig.dayCycle) {
|
|
1161
|
+
return
|
|
1162
|
+
}
|
|
1163
|
+
this.timeUpdated?.(timeOfDay)
|
|
1075
1164
|
|
|
1076
|
-
|
|
1165
|
+
this.timeOfTheDay = timeOfDay
|
|
1077
1166
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1167
|
+
const skyLight = timeOfDay < 0 || timeOfDay > 24_000 ? 15 : calculateSkyLightSimple(timeOfDay)
|
|
1168
|
+
if (this.lastMesherSkyLight === skyLight) return
|
|
1169
|
+
this.lastMesherSkyLight = skyLight
|
|
1170
|
+
if (this.workers.length > 0) {
|
|
1171
|
+
this.sendWorkers({ config: { skyLight } } as WorkerSend)
|
|
1172
|
+
}
|
|
1173
|
+
this.onDayCycleSkyLightChanged?.(skyLight)
|
|
1174
|
+
},
|
|
1175
|
+
signal
|
|
1176
|
+
)
|
|
1086
1177
|
|
|
1087
|
-
bindAbortableListener(
|
|
1088
|
-
|
|
1089
|
-
|
|
1178
|
+
bindAbortableListener(
|
|
1179
|
+
worldEmitter,
|
|
1180
|
+
'biomeUpdate',
|
|
1181
|
+
({ biome }) => {
|
|
1182
|
+
this.biomeUpdated?.(biome)
|
|
1183
|
+
},
|
|
1184
|
+
signal
|
|
1185
|
+
)
|
|
1090
1186
|
|
|
1091
|
-
bindAbortableListener(
|
|
1092
|
-
|
|
1093
|
-
|
|
1187
|
+
bindAbortableListener(
|
|
1188
|
+
worldEmitter,
|
|
1189
|
+
'biomeReset',
|
|
1190
|
+
() => {
|
|
1191
|
+
this.biomeReset?.()
|
|
1192
|
+
},
|
|
1193
|
+
signal
|
|
1194
|
+
)
|
|
1094
1195
|
}
|
|
1095
1196
|
|
|
1096
1197
|
setBlockStateIdInner(pos: Vec3, stateId: number | undefined, needAoRecalculation = true) {
|
|
@@ -1118,10 +1219,13 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1118
1219
|
if (!this.worldRendererConfig.wasmMesher) {
|
|
1119
1220
|
const existing = this.heightmapDebounceTimers.get(chunkKey2)
|
|
1120
1221
|
if (existing) clearTimeout(existing)
|
|
1121
|
-
this.heightmapDebounceTimers.set(
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1222
|
+
this.heightmapDebounceTimers.set(
|
|
1223
|
+
chunkKey2,
|
|
1224
|
+
setTimeout(() => {
|
|
1225
|
+
this.heightmapDebounceTimers.delete(chunkKey2)
|
|
1226
|
+
this.workers[0]?.postMessage({ type: 'getHeightmap', x: chunkCornerX, z: chunkCornerZ })
|
|
1227
|
+
}, 100)
|
|
1228
|
+
)
|
|
1125
1229
|
}
|
|
1126
1230
|
}
|
|
1127
1231
|
this.logWorkerWork(`-> blockUpdate ${JSON.stringify({ pos, stateId, customBlockModels })}`)
|
|
@@ -1132,7 +1236,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1132
1236
|
if ((pos.x & 15) === 0) this.setSectionDirty(pos.offset(-CHUNK_SIZE, 0, 0), true, true)
|
|
1133
1237
|
if ((pos.x & 15) === 15) this.setSectionDirty(pos.offset(CHUNK_SIZE, 0, 0), true, true)
|
|
1134
1238
|
if ((pos.y & (sectionHeight - 1)) === 0) this.setSectionDirty(pos.offset(0, -sectionHeight, 0), true, true)
|
|
1135
|
-
if ((pos.y & (sectionHeight - 1)) ===
|
|
1239
|
+
if ((pos.y & (sectionHeight - 1)) === sectionHeight - 1) this.setSectionDirty(pos.offset(0, sectionHeight, 0), true, true)
|
|
1136
1240
|
if ((pos.z & 15) === 0) this.setSectionDirty(pos.offset(0, 0, -CHUNK_SIZE), true, true)
|
|
1137
1241
|
if ((pos.z & 15) === 15) this.setSectionDirty(pos.offset(0, 0, CHUNK_SIZE), true, true)
|
|
1138
1242
|
|
|
@@ -1153,10 +1257,14 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1153
1257
|
if ((pos.z & 15) === 15 && (pos.y & (sectionHeight - 1)) === 0) this.setSectionDirty(pos.offset(0, -sectionHeight, CHUNK_SIZE), true, true)
|
|
1154
1258
|
|
|
1155
1259
|
// x & z neighbors
|
|
1156
|
-
if ((pos.y & (sectionHeight - 1)) === 0 && (pos.x & 15) === 0 && (pos.z & 15) === 0)
|
|
1157
|
-
|
|
1158
|
-
if ((pos.y & (sectionHeight - 1)) === 0 && (pos.x & 15) ===
|
|
1159
|
-
|
|
1260
|
+
if ((pos.y & (sectionHeight - 1)) === 0 && (pos.x & 15) === 0 && (pos.z & 15) === 0)
|
|
1261
|
+
this.setSectionDirty(pos.offset(-CHUNK_SIZE, -sectionHeight, -CHUNK_SIZE), true, true)
|
|
1262
|
+
if ((pos.y & (sectionHeight - 1)) === 0 && (pos.x & 15) === 15 && (pos.z & 15) === 0)
|
|
1263
|
+
this.setSectionDirty(pos.offset(CHUNK_SIZE, -sectionHeight, -CHUNK_SIZE), true, true)
|
|
1264
|
+
if ((pos.y & (sectionHeight - 1)) === 0 && (pos.x & 15) === 0 && (pos.z & 15) === 15)
|
|
1265
|
+
this.setSectionDirty(pos.offset(-CHUNK_SIZE, -sectionHeight, CHUNK_SIZE), true, true)
|
|
1266
|
+
if ((pos.y & (sectionHeight - 1)) === 0 && (pos.x & 15) === 15 && (pos.z & 15) === 15)
|
|
1267
|
+
this.setSectionDirty(pos.offset(CHUNK_SIZE, -sectionHeight, CHUNK_SIZE), true, true)
|
|
1160
1268
|
}
|
|
1161
1269
|
}
|
|
1162
1270
|
}
|
|
@@ -1211,13 +1319,15 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1211
1319
|
async debugGetWorkerCustomBlockModel(pos: Vec3) {
|
|
1212
1320
|
const data = [] as Array<Promise<string>>
|
|
1213
1321
|
for (const worker of this.workers) {
|
|
1214
|
-
data.push(
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1322
|
+
data.push(
|
|
1323
|
+
new Promise(resolve => {
|
|
1324
|
+
worker.addEventListener('message', e => {
|
|
1325
|
+
if (e.data.type === 'customBlockModel') {
|
|
1326
|
+
resolve(e.data.customBlockModel)
|
|
1327
|
+
}
|
|
1328
|
+
})
|
|
1219
1329
|
})
|
|
1220
|
-
|
|
1330
|
+
)
|
|
1221
1331
|
worker.postMessage({
|
|
1222
1332
|
type: 'getCustomBlockModel',
|
|
1223
1333
|
pos
|
|
@@ -1226,7 +1336,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1226
1336
|
return Promise.all(data)
|
|
1227
1337
|
}
|
|
1228
1338
|
|
|
1229
|
-
setSectionDirty(pos: Vec3, value = true, useChangeWorker = false) {
|
|
1339
|
+
setSectionDirty(pos: Vec3, value = true, useChangeWorker = false) {
|
|
1340
|
+
// value false is used for unloading chunks
|
|
1230
1341
|
if (!this.forceCallFromMesherReplayer && this.mesherLogReader) return
|
|
1231
1342
|
|
|
1232
1343
|
if (this.viewDistance === -1) throw new Error('viewDistance not set')
|
|
@@ -1254,30 +1365,36 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1254
1365
|
|
|
1255
1366
|
// Schedule trailing dispatch after throttle window
|
|
1256
1367
|
if (!this.sectionDirtyTimers.has(key)) {
|
|
1257
|
-
this.sectionDirtyTimers.set(
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
this.
|
|
1264
|
-
|
|
1265
|
-
|
|
1368
|
+
this.sectionDirtyTimers.set(
|
|
1369
|
+
key,
|
|
1370
|
+
setTimeout(() => {
|
|
1371
|
+
const args = this.sectionDirtyPendingArgs.get(key)
|
|
1372
|
+
this.sectionDirtyCount.delete(key)
|
|
1373
|
+
this.sectionDirtyTimers.delete(key)
|
|
1374
|
+
this.sectionDirtyPendingArgs.delete(key)
|
|
1375
|
+
if (args) {
|
|
1376
|
+
this._dispatchDirtyImmediate(args.pos, args.value, args.useChangeWorker)
|
|
1377
|
+
}
|
|
1378
|
+
}, WorldRendererCommon.GEOMETRY_THROTTLE_DELAY)
|
|
1379
|
+
)
|
|
1266
1380
|
}
|
|
1267
1381
|
} else {
|
|
1268
1382
|
// Subsequent requests — throttle: store latest args, existing timer will dispatch
|
|
1269
1383
|
this.sectionDirtyPendingArgs.set(key, { pos, value, useChangeWorker })
|
|
1270
1384
|
|
|
1271
1385
|
if (!this.sectionDirtyTimers.has(key)) {
|
|
1272
|
-
this.sectionDirtyTimers.set(
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
this.
|
|
1279
|
-
|
|
1280
|
-
|
|
1386
|
+
this.sectionDirtyTimers.set(
|
|
1387
|
+
key,
|
|
1388
|
+
setTimeout(() => {
|
|
1389
|
+
const args = this.sectionDirtyPendingArgs.get(key)
|
|
1390
|
+
this.sectionDirtyCount.delete(key)
|
|
1391
|
+
this.sectionDirtyTimers.delete(key)
|
|
1392
|
+
this.sectionDirtyPendingArgs.delete(key)
|
|
1393
|
+
if (args) {
|
|
1394
|
+
this._dispatchDirtyImmediate(args.pos, args.value, args.useChangeWorker)
|
|
1395
|
+
}
|
|
1396
|
+
}, WorldRendererCommon.GEOMETRY_THROTTLE_DELAY)
|
|
1397
|
+
)
|
|
1281
1398
|
}
|
|
1282
1399
|
}
|
|
1283
1400
|
}
|
|
@@ -1302,7 +1419,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1302
1419
|
y: pos.y,
|
|
1303
1420
|
z: pos.z,
|
|
1304
1421
|
value,
|
|
1305
|
-
config: this.getMesherConfig()
|
|
1422
|
+
config: this.getMesherConfig()
|
|
1306
1423
|
})
|
|
1307
1424
|
} else {
|
|
1308
1425
|
this.toWorkerMessagesQueue[hash] ??= []
|
|
@@ -1312,7 +1429,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1312
1429
|
y: pos.y,
|
|
1313
1430
|
z: pos.z,
|
|
1314
1431
|
value,
|
|
1315
|
-
config: this.getMesherConfig()
|
|
1432
|
+
config: this.getMesherConfig()
|
|
1316
1433
|
})
|
|
1317
1434
|
this.dispatchMessages()
|
|
1318
1435
|
}
|
|
@@ -1328,7 +1445,9 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
1328
1445
|
const messages = this.toWorkerMessagesQueue[workerIndex]
|
|
1329
1446
|
worker.postMessage(messages)
|
|
1330
1447
|
for (const message of messages) {
|
|
1331
|
-
this.logWorkerWork(
|
|
1448
|
+
this.logWorkerWork(
|
|
1449
|
+
`-> ${workerIndex} dispatchMessages ${message.type} ${JSON.stringify({ x: message.x, y: message.y, z: message.z, value: message.value })}`
|
|
1450
|
+
)
|
|
1332
1451
|
}
|
|
1333
1452
|
}
|
|
1334
1453
|
this.toWorkerMessagesQueue = {}
|
|
@@ -1436,7 +1555,10 @@ export const initMesherWorker = (onGotMessage: (data: any) => void, workerName =
|
|
|
1436
1555
|
worker.onmessage = ({ data }) => {
|
|
1437
1556
|
onGotMessage(data)
|
|
1438
1557
|
}
|
|
1439
|
-
if (worker.on)
|
|
1558
|
+
if (worker.on)
|
|
1559
|
+
worker.on('message', data => {
|
|
1560
|
+
worker.onmessage({ data })
|
|
1561
|
+
})
|
|
1440
1562
|
return worker
|
|
1441
1563
|
}
|
|
1442
1564
|
|
|
@@ -1467,19 +1589,24 @@ export const meshersSendMcDataAwait = (
|
|
|
1467
1589
|
mcDataFull: IndexedData,
|
|
1468
1590
|
timeoutMs = 10_000
|
|
1469
1591
|
): Promise<void> => {
|
|
1470
|
-
return Promise.all(
|
|
1471
|
-
|
|
1472
|
-
worker
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1592
|
+
return Promise.all(
|
|
1593
|
+
workers.map(
|
|
1594
|
+
worker =>
|
|
1595
|
+
new Promise<void>((resolve, reject) => {
|
|
1596
|
+
const timeout = setTimeout(() => {
|
|
1597
|
+
worker.removeEventListener('message', handler as EventListener)
|
|
1598
|
+
reject(new Error(`mcData transfer timeout (${timeoutMs}ms)`))
|
|
1599
|
+
}, timeoutMs)
|
|
1600
|
+
const handler = ({ data }: MessageEvent) => {
|
|
1601
|
+
if (data?.type === 'mcDataApplied') {
|
|
1602
|
+
clearTimeout(timeout)
|
|
1603
|
+
worker.removeEventListener('message', handler as EventListener)
|
|
1604
|
+
resolve()
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
worker.addEventListener('message', handler as EventListener)
|
|
1608
|
+
meshersSendMcData([worker], version, mcDataKeys, mcDataFull)
|
|
1609
|
+
})
|
|
1610
|
+
)
|
|
1611
|
+
).then(() => undefined)
|
|
1485
1612
|
}
|