minecraft-renderer 0.1.63 → 0.1.65
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 +1 -1
- package/dist/mesherWasm.js +22 -22
- package/dist/minecraft-renderer.js +59 -59
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +415 -415
- package/package.json +1 -1
- package/src/graphicsBackend/rendererDefaultOptions.ts +41 -24
- package/src/graphicsBackend/rendererOptionsSync.ts +23 -23
- package/src/index.ts +8 -8
- package/src/lib/worldrendererCommon.removeColumn.test.ts +182 -0
- package/src/lib/worldrendererCommon.ts +16 -6
- package/src/three/entities.ts +54 -170
- package/src/three/entity/animations.js +92 -185
- package/src/three/menuBackground/activeView.ts +1 -1
- package/src/three/menuBackground/config.ts +9 -9
- package/src/three/menuBackground/index.ts +10 -10
- package/src/three/menuBackground/renderer.ts +12 -12
- package/src/three/menuBackground/types.ts +9 -9
- package/src/three/menuBackground/{futuristic.ts → v2.ts} +110 -59
- package/src/three/menuBackground/{futuristicMeta.ts → v2Meta.ts} +6 -6
- package/src/wasm-mesher/tests/mesherWasmRequestTracker.test.ts +29 -0
- package/src/wasm-mesher/worker/mesherWasm.ts +7 -0
- package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +10 -0
- package/src/worldView/worldView.spiral.test.ts +38 -0
- package/src/worldView/worldView.ts +2 -0
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
V2_CAMERA_IDS,
|
|
4
|
+
V2_CAMERA_LABELS,
|
|
5
|
+
V2_SCENE_IDS,
|
|
6
|
+
V2_SCENE_LABELS,
|
|
7
7
|
MINECRAFT_BLOCK_GROUP_IDS,
|
|
8
8
|
MINECRAFT_BLOCK_GROUP_LABELS
|
|
9
|
-
} from '../three/menuBackground/
|
|
9
|
+
} from '../three/menuBackground/v2Meta'
|
|
10
10
|
import { MENU_BACKGROUND_OPTION_DEFAULTS } from '../three/menuBackground/config'
|
|
11
11
|
import type { RendererGpuPreference } from '../three/menuBackground/gpuPreference'
|
|
12
12
|
|
|
@@ -54,11 +54,11 @@ export const RENDERER_DEFAULT_OPTIONS = {
|
|
|
54
54
|
defaultSkybox: true as boolean,
|
|
55
55
|
menuBackgroundMode: MB.mode,
|
|
56
56
|
menuBackgroundMinecraftTextures: MB.minecraftTextures as boolean,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
menuBackgroundV2Scene: MB.v2Scene,
|
|
58
|
+
menuBackgroundV2Camera: MB.v2Camera,
|
|
59
|
+
menuBackgroundV2BlockGroup: MB.v2BlockGroup,
|
|
60
|
+
menuBackgroundV2CameraSpeed: MB.v2CameraSpeedPercent,
|
|
61
|
+
menuBackgroundV2BlockSpeed: MB.v2BlockSpeedPercent,
|
|
62
62
|
rendererFuturisticReveal: false as boolean,
|
|
63
63
|
rendererPerfDebugOverlay: false as boolean,
|
|
64
64
|
disableBlockEntityTextures: false as boolean,
|
|
@@ -110,37 +110,54 @@ export function migrateRendererOptions(saved: Record<string, unknown>): void {
|
|
|
110
110
|
}
|
|
111
111
|
delete saved.wasmExperimentalMesher
|
|
112
112
|
delete saved.rendererWasmMesher
|
|
113
|
+
|
|
114
|
+
if (saved.menuBackgroundMode === 'futuristic') {
|
|
115
|
+
saved.menuBackgroundMode = 'v2'
|
|
116
|
+
}
|
|
117
|
+
const futuristicToV2: Array<[string, string]> = [
|
|
118
|
+
['menuBackgroundFuturisticScene', 'menuBackgroundV2Scene'],
|
|
119
|
+
['menuBackgroundFuturisticCamera', 'menuBackgroundV2Camera'],
|
|
120
|
+
['menuBackgroundFuturisticBlockGroup', 'menuBackgroundV2BlockGroup'],
|
|
121
|
+
['menuBackgroundFuturisticCameraSpeed', 'menuBackgroundV2CameraSpeed'],
|
|
122
|
+
['menuBackgroundFuturisticBlockSpeed', 'menuBackgroundV2BlockSpeed'],
|
|
123
|
+
]
|
|
124
|
+
for (const [oldKey, newKey] of futuristicToV2) {
|
|
125
|
+
if (saved[oldKey] !== undefined && saved[newKey] === undefined) {
|
|
126
|
+
saved[newKey] = saved[oldKey]
|
|
127
|
+
}
|
|
128
|
+
delete saved[oldKey]
|
|
129
|
+
}
|
|
113
130
|
}
|
|
114
131
|
|
|
115
132
|
/** Settings UI metadata for {@link RENDERER_DEFAULT_OPTIONS} keys. */
|
|
116
133
|
export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, RendererOptionMeta>> = {
|
|
117
134
|
menuBackgroundMode: {
|
|
118
|
-
possibleValues: [['classic', 'Classic'], ['
|
|
135
|
+
possibleValues: [['classic', 'Classic'], ['v2', 'V2']],
|
|
119
136
|
requiresRestart: true
|
|
120
137
|
},
|
|
121
138
|
menuBackgroundMinecraftTextures: {
|
|
122
139
|
text: 'Minecraft block textures',
|
|
123
|
-
tooltip: 'Use block atlas on
|
|
140
|
+
tooltip: 'Use block atlas on V2 menu cubes (loads assets on menu)'
|
|
124
141
|
},
|
|
125
|
-
|
|
126
|
-
possibleValues:
|
|
142
|
+
menuBackgroundV2Scene: {
|
|
143
|
+
possibleValues: V2_SCENE_IDS.map(id => [id, V2_SCENE_LABELS[id]] as [string, string])
|
|
127
144
|
},
|
|
128
|
-
|
|
129
|
-
possibleValues:
|
|
145
|
+
menuBackgroundV2Camera: {
|
|
146
|
+
possibleValues: V2_CAMERA_IDS.map(id => [id, V2_CAMERA_LABELS[id]] as [string, string])
|
|
130
147
|
},
|
|
131
|
-
|
|
148
|
+
menuBackgroundV2BlockGroup: {
|
|
132
149
|
possibleValues: MINECRAFT_BLOCK_GROUP_IDS.map(id => [id, MINECRAFT_BLOCK_GROUP_LABELS[id]] as [string, string]),
|
|
133
150
|
text: 'Block pool',
|
|
134
151
|
tooltip: 'Block set for textured menu cubes (requires Minecraft textures)'
|
|
135
152
|
},
|
|
136
|
-
|
|
153
|
+
menuBackgroundV2CameraSpeed: {
|
|
137
154
|
text: 'Camera speed',
|
|
138
155
|
tooltip: 'Orbit / fly-through camera path speed. 0 freezes the path; mouse parallax still works.',
|
|
139
156
|
min: 0,
|
|
140
157
|
max: 200,
|
|
141
158
|
unit: '%'
|
|
142
159
|
},
|
|
143
|
-
|
|
160
|
+
menuBackgroundV2BlockSpeed: {
|
|
144
161
|
text: 'Block speed',
|
|
145
162
|
tooltip: 'Floating blocks and sky rotation. Independent of camera path speed.',
|
|
146
163
|
min: 0,
|
|
@@ -315,11 +332,11 @@ export const RENDERER_RENDER_GUI_SECTIONS: ReadonlyArray<{
|
|
|
315
332
|
keys: [
|
|
316
333
|
'menuBackgroundMode',
|
|
317
334
|
'menuBackgroundMinecraftTextures',
|
|
318
|
-
'
|
|
319
|
-
'
|
|
320
|
-
'
|
|
321
|
-
'
|
|
322
|
-
'
|
|
335
|
+
'menuBackgroundV2Scene',
|
|
336
|
+
'menuBackgroundV2Camera',
|
|
337
|
+
'menuBackgroundV2BlockGroup',
|
|
338
|
+
'menuBackgroundV2CameraSpeed',
|
|
339
|
+
'menuBackgroundV2BlockSpeed'
|
|
323
340
|
]
|
|
324
341
|
},
|
|
325
342
|
{
|
|
@@ -11,7 +11,7 @@ import { rendererShaderCubeDebugModeToValue } from './rendererDefaultOptions'
|
|
|
11
11
|
import type { MenuBackgroundOptions } from '../three/menuBackground/types'
|
|
12
12
|
import type { MenuBackgroundRenderer } from '../three/menuBackground/renderer'
|
|
13
13
|
import { menuBackgroundSpeedToMultiplier } from '../three/menuBackground/config'
|
|
14
|
-
import type {
|
|
14
|
+
import type { V2CameraId, V2SceneId, MinecraftBlockGroupId } from '../three/menuBackground/v2'
|
|
15
15
|
import { setSkinsConfig } from '../lib/utils/skins'
|
|
16
16
|
|
|
17
17
|
export type { RendererStorageOptions } from './rendererDefaultOptions'
|
|
@@ -37,20 +37,20 @@ export function menuBackgroundOptionsFromStorage(o: Pick<
|
|
|
37
37
|
RendererStorageOptions,
|
|
38
38
|
| 'menuBackgroundMode'
|
|
39
39
|
| 'menuBackgroundMinecraftTextures'
|
|
40
|
-
| '
|
|
41
|
-
| '
|
|
42
|
-
| '
|
|
43
|
-
| '
|
|
44
|
-
| '
|
|
40
|
+
| 'menuBackgroundV2Scene'
|
|
41
|
+
| 'menuBackgroundV2Camera'
|
|
42
|
+
| 'menuBackgroundV2BlockGroup'
|
|
43
|
+
| 'menuBackgroundV2CameraSpeed'
|
|
44
|
+
| 'menuBackgroundV2BlockSpeed'
|
|
45
45
|
>): MenuBackgroundOptions {
|
|
46
46
|
return {
|
|
47
47
|
mode: o.menuBackgroundMode as MenuBackgroundOptions['mode'],
|
|
48
48
|
useMinecraftTextures: o.menuBackgroundMinecraftTextures,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
v2Scene: o.menuBackgroundV2Scene as V2SceneId,
|
|
50
|
+
v2Camera: o.menuBackgroundV2Camera as V2CameraId,
|
|
51
|
+
v2BlockGroup: o.menuBackgroundV2BlockGroup as MinecraftBlockGroupId,
|
|
52
|
+
v2CameraSpeed: menuBackgroundSpeedToMultiplier(o.menuBackgroundV2CameraSpeed),
|
|
53
|
+
v2BlockSpeed: menuBackgroundSpeedToMultiplier(o.menuBackgroundV2BlockSpeed),
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -58,20 +58,20 @@ export function applyMenuBackgroundLiveOptions(
|
|
|
58
58
|
menu: MenuBackgroundRenderer,
|
|
59
59
|
o: Pick<
|
|
60
60
|
RendererStorageOptions,
|
|
61
|
-
| '
|
|
62
|
-
| '
|
|
63
|
-
| '
|
|
64
|
-
| '
|
|
65
|
-
| '
|
|
61
|
+
| 'menuBackgroundV2Scene'
|
|
62
|
+
| 'menuBackgroundV2Camera'
|
|
63
|
+
| 'menuBackgroundV2BlockGroup'
|
|
64
|
+
| 'menuBackgroundV2CameraSpeed'
|
|
65
|
+
| 'menuBackgroundV2BlockSpeed'
|
|
66
66
|
>
|
|
67
67
|
): void {
|
|
68
|
-
const
|
|
69
|
-
if (!
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
void
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
const v2 = menu.v2
|
|
69
|
+
if (!v2) return
|
|
70
|
+
v2.setScene?.(o.menuBackgroundV2Scene)
|
|
71
|
+
v2.setCamera?.(o.menuBackgroundV2Camera)
|
|
72
|
+
void v2.setBlockGroup?.(o.menuBackgroundV2BlockGroup)
|
|
73
|
+
v2.setCameraSpeed?.(menuBackgroundSpeedToMultiplier(o.menuBackgroundV2CameraSpeed))
|
|
74
|
+
v2.setBlockSpeed?.(menuBackgroundSpeedToMultiplier(o.menuBackgroundV2BlockSpeed))
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function resolveWasmMesherActive(o: RendererStorageOptions): boolean {
|
package/src/index.ts
CHANGED
|
@@ -85,21 +85,21 @@ export type {
|
|
|
85
85
|
MenuBackgroundMode,
|
|
86
86
|
MenuBackgroundOptions,
|
|
87
87
|
MenuBackgroundView,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
V2SceneId,
|
|
89
|
+
V2CameraId,
|
|
90
|
+
V2MenuBackgroundOptions,
|
|
91
91
|
MinecraftBlockGroupId
|
|
92
92
|
} from './three/menuBackground'
|
|
93
93
|
export {
|
|
94
94
|
MenuBackgroundRenderer,
|
|
95
95
|
ClassicMenuBackground,
|
|
96
|
-
|
|
96
|
+
V2MenuBackground,
|
|
97
97
|
WorldBlocksMenuBackground,
|
|
98
98
|
MENU_BACKGROUND_MC_VERSION,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
V2_SCENE_IDS,
|
|
100
|
+
V2_CAMERA_IDS,
|
|
101
|
+
V2_SCENE_LABELS,
|
|
102
|
+
V2_CAMERA_LABELS,
|
|
103
103
|
MINECRAFT_BLOCK_GROUPS,
|
|
104
104
|
MINECRAFT_BLOCK_GROUP_IDS,
|
|
105
105
|
MINECRAFT_BLOCK_GROUP_LABELS,
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import { EventEmitter } from 'events'
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
|
|
4
|
+
import { Vec3 } from 'vec3'
|
|
5
|
+
import { proxy } from 'valtio'
|
|
6
|
+
import { WorldRendererCommon } from './worldrendererCommon'
|
|
7
|
+
import { defaultWorldRendererConfig } from '../graphicsBackend/config'
|
|
8
|
+
import { getInitialPlayerState } from '../playerState/playerState'
|
|
9
|
+
import type { DisplayWorldOptions, GraphicsInitOptions } from '../graphicsBackend/types'
|
|
10
|
+
|
|
11
|
+
vi.mock('./ui/newStats', () => ({
|
|
12
|
+
addNewStat: vi.fn(() => ({ updateText: vi.fn(), setVisibility: vi.fn() })),
|
|
13
|
+
updateStatText: vi.fn(),
|
|
14
|
+
removeAllStats: vi.fn(),
|
|
15
|
+
updatePanesVisibility: vi.fn(),
|
|
16
|
+
MC_RENDERER_DEBUG_OVERLAY_CLASS: 'mc-renderer-debug-overlay',
|
|
17
|
+
}))
|
|
18
|
+
|
|
19
|
+
vi.mock('./utils/skins', () => ({
|
|
20
|
+
setSkinsConfig: vi.fn(),
|
|
21
|
+
steveTexture: {},
|
|
22
|
+
stevePngUrl: '',
|
|
23
|
+
}))
|
|
24
|
+
|
|
25
|
+
function ensurePromiseWithResolvers() {
|
|
26
|
+
if (!Promise.withResolvers) {
|
|
27
|
+
Promise.withResolvers = function <T>() {
|
|
28
|
+
let resolve!: (value: T | PromiseLike<T>) => void
|
|
29
|
+
let reject!: (reason?: unknown) => void
|
|
30
|
+
const promise = new Promise<T>((res, rej) => {
|
|
31
|
+
resolve = res
|
|
32
|
+
reject = rej
|
|
33
|
+
})
|
|
34
|
+
return { promise, resolve, reject }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class TestWorldRenderer extends WorldRendererCommon {
|
|
40
|
+
outputFormat = 'threeJs' as const
|
|
41
|
+
|
|
42
|
+
changeBackgroundColor() {}
|
|
43
|
+
changeCardinalLight() {}
|
|
44
|
+
handleWorkerMessage() {}
|
|
45
|
+
updateCamera() {}
|
|
46
|
+
render() {}
|
|
47
|
+
updateShowChunksBorder() {}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function createRenderer() {
|
|
51
|
+
const rendererState = proxy({
|
|
52
|
+
world: {
|
|
53
|
+
chunksLoaded: new Set<string>(),
|
|
54
|
+
heightmaps: new Map<string, Int16Array>(),
|
|
55
|
+
allChunksLoaded: false,
|
|
56
|
+
mesherWork: false,
|
|
57
|
+
instabilityFactors: {},
|
|
58
|
+
intersectMedia: null,
|
|
59
|
+
},
|
|
60
|
+
renderer: '',
|
|
61
|
+
preventEscapeMenu: false,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const displayOptions = {
|
|
65
|
+
version: '1.21.1',
|
|
66
|
+
worldView: new EventEmitter() as DisplayWorldOptions['worldView'],
|
|
67
|
+
inWorldRenderingConfig: { ...defaultWorldRendererConfig },
|
|
68
|
+
playerStateReactive: getInitialPlayerState(),
|
|
69
|
+
rendererState,
|
|
70
|
+
nonReactiveState: {
|
|
71
|
+
fps: 0,
|
|
72
|
+
worstRenderTime: 0,
|
|
73
|
+
avgRenderTime: 0,
|
|
74
|
+
world: {
|
|
75
|
+
chunksLoaded: new Set<string>(),
|
|
76
|
+
chunksTotalNumber: 0,
|
|
77
|
+
chunksFullInfo: '',
|
|
78
|
+
},
|
|
79
|
+
renderer: {
|
|
80
|
+
timeline: { live: [], frozen: [], lastSecond: [] },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
resourcesManager: {} as DisplayWorldOptions['resourcesManager'],
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const initOptions: GraphicsInitOptions = {
|
|
87
|
+
config: { sceneBackground: '#000' },
|
|
88
|
+
rendererSpecificSettings: {},
|
|
89
|
+
callbacks: {
|
|
90
|
+
displayCriticalError: vi.fn(),
|
|
91
|
+
setRendererSpecificSettings: vi.fn(),
|
|
92
|
+
fireCustomEvent: vi.fn(),
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const renderer = new TestWorldRenderer(displayOptions.resourcesManager, displayOptions, initOptions)
|
|
97
|
+
renderer.active = true
|
|
98
|
+
renderer.workers = [{ postMessage: vi.fn() }, { postMessage: vi.fn() }]
|
|
99
|
+
renderer.viewDistance = 16
|
|
100
|
+
renderer.viewerChunkPosition = new Vec3(0, 64, 0)
|
|
101
|
+
renderer.worldSizeParams = { minY: 0, worldHeight: 256 }
|
|
102
|
+
renderer.loadedChunks['160,0'] = true
|
|
103
|
+
return renderer
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function sectionKeysForColumn(renderer: TestWorldRenderer, x: number, z: number): string[] {
|
|
107
|
+
const keys: string[] = []
|
|
108
|
+
const sectionHeight = renderer.getSectionHeight()
|
|
109
|
+
for (let y = renderer.worldMinYRender; y < renderer.worldSizeParams.worldHeight; y += sectionHeight) {
|
|
110
|
+
keys.push(`${x},${y},${z}`)
|
|
111
|
+
}
|
|
112
|
+
return keys
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
describe('WorldRendererCommon.removeColumn sectionsWaiting reconciliation', () => {
|
|
116
|
+
beforeEach(() => {
|
|
117
|
+
ensurePromiseWithResolvers()
|
|
118
|
+
vi.useFakeTimers()
|
|
119
|
+
vi.stubGlobal('location', { href: 'http://localhost/' })
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
afterEach(() => {
|
|
123
|
+
vi.useRealTimers()
|
|
124
|
+
vi.unstubAllGlobals()
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
test('clears sectionsWaiting when viewDistance gate blocks setSectionDirty(false)', () => {
|
|
128
|
+
const renderer = createRenderer()
|
|
129
|
+
const columnX = 160
|
|
130
|
+
const columnZ = 0
|
|
131
|
+
const sectionPos = new Vec3(columnX, 64, columnZ)
|
|
132
|
+
|
|
133
|
+
renderer.setSectionDirty(sectionPos, true)
|
|
134
|
+
expect(renderer.sectionsWaiting.get(`${columnX},64,${columnZ}`)).toBe(1)
|
|
135
|
+
|
|
136
|
+
renderer.viewDistance = 4
|
|
137
|
+
renderer.removeColumn(columnX, columnZ)
|
|
138
|
+
|
|
139
|
+
for (const key of sectionKeysForColumn(renderer, columnX, columnZ)) {
|
|
140
|
+
expect(renderer.sectionsWaiting.has(key)).toBe(false)
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
test('treats late sectionFinished as a no-op after removeColumn', () => {
|
|
145
|
+
const renderer = createRenderer()
|
|
146
|
+
const sectionKey = '160,64,0'
|
|
147
|
+
const debugSpy = vi.spyOn(console, 'debug').mockImplementation(() => {})
|
|
148
|
+
|
|
149
|
+
renderer.sectionsWaiting.set(sectionKey, 1)
|
|
150
|
+
renderer.viewDistance = 4
|
|
151
|
+
renderer.removeColumn(160, 0)
|
|
152
|
+
|
|
153
|
+
expect(() => {
|
|
154
|
+
renderer.handleMessage({ type: 'sectionFinished', key: sectionKey, workerIndex: 0 })
|
|
155
|
+
}).not.toThrow()
|
|
156
|
+
|
|
157
|
+
expect(renderer.sectionsWaiting.has(sectionKey)).toBe(false)
|
|
158
|
+
expect(debugSpy).toHaveBeenCalledWith(
|
|
159
|
+
expect.stringContaining('sectionFinished for non-outstanding section'),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
debugSpy.mockRestore()
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
test('clears sectionsWaiting when unload happens before batched dirty flush', () => {
|
|
166
|
+
const renderer = createRenderer()
|
|
167
|
+
renderer.forceCallFromMesherReplayer = false
|
|
168
|
+
const columnX = 160
|
|
169
|
+
const columnZ = 0
|
|
170
|
+
|
|
171
|
+
renderer.setSectionDirty(new Vec3(columnX, 64, columnZ), true)
|
|
172
|
+
expect(renderer.sectionsWaiting.get(`${columnX},64,${columnZ}`)).toBe(1)
|
|
173
|
+
|
|
174
|
+
renderer.viewDistance = 4
|
|
175
|
+
renderer.removeColumn(columnX, columnZ)
|
|
176
|
+
vi.advanceTimersByTime(0)
|
|
177
|
+
|
|
178
|
+
for (const key of sectionKeysForColumn(renderer, columnX, columnZ)) {
|
|
179
|
+
expect(renderer.sectionsWaiting.has(key)).toBe(false)
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
})
|
|
@@ -424,7 +424,10 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
424
424
|
}
|
|
425
425
|
if (data.type === 'sectionFinished') { // on after load & unload section
|
|
426
426
|
this.logWorkerWork(`<- ${data.workerIndex} sectionFinished ${data.key} ${JSON.stringify({ processTime: data.processTime })}`)
|
|
427
|
-
if (!this.sectionsWaiting.has(data.key))
|
|
427
|
+
if (!this.sectionsWaiting.has(data.key)) {
|
|
428
|
+
console.debug(`sectionFinished for non-outstanding section ${data.key} (viewDistance=${this.viewDistance})`)
|
|
429
|
+
return
|
|
430
|
+
}
|
|
428
431
|
this.sectionsWaiting.set(data.key, this.sectionsWaiting.get(data.key)! - 1)
|
|
429
432
|
if (this.sectionsWaiting.get(data.key) === 0) {
|
|
430
433
|
this.sectionsWaiting.delete(data.key)
|
|
@@ -787,9 +790,11 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
787
790
|
this.sectionDirtyPendingArgs.delete(key)
|
|
788
791
|
}
|
|
789
792
|
}
|
|
790
|
-
for (
|
|
791
|
-
|
|
793
|
+
for (let i = 0; i < this.workers.length; i++) {
|
|
794
|
+
this.toWorkerMessagesQueue[i] ??= []
|
|
795
|
+
this.toWorkerMessagesQueue[i].push({ type: 'unloadChunk', x, z })
|
|
792
796
|
}
|
|
797
|
+
this.dispatchMessages()
|
|
793
798
|
this.logWorkerWork(`-> unloadChunk ${JSON.stringify({ x, z })}`)
|
|
794
799
|
delete this.finishedChunks[`${x},${z}`]
|
|
795
800
|
this.allChunksFinished = Object.keys(this.finishedChunks).length === this.chunksLength
|
|
@@ -798,9 +803,14 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|
|
798
803
|
this.initialChunkLoadWasStartedIn = undefined
|
|
799
804
|
}
|
|
800
805
|
const sectionHeight = this.getSectionHeight()
|
|
801
|
-
for (let y = this.
|
|
802
|
-
|
|
803
|
-
|
|
806
|
+
for (let y = this.worldMinYRender; y < this.worldSizeParams.worldHeight; y += sectionHeight) {
|
|
807
|
+
const sectionKey = `${x},${y},${z}`
|
|
808
|
+
const waitingCount = this.sectionsWaiting.get(sectionKey)
|
|
809
|
+
if (waitingCount !== undefined && waitingCount > 0) {
|
|
810
|
+
console.debug(`[removeColumn] clearing non-zero sectionsWaiting for ${sectionKey}: ${waitingCount} (chunk ${x},${z}, viewDistance=${this.viewDistance})`)
|
|
811
|
+
}
|
|
812
|
+
this.sectionsWaiting.delete(sectionKey)
|
|
813
|
+
delete this.finishedSections[sectionKey]
|
|
804
814
|
}
|
|
805
815
|
this.highestBlocksByChunks.delete(`${x},${z}`)
|
|
806
816
|
const heightmapKey = `${Math.floor(x / 16)},${Math.floor(z / 16)}`
|