minecraft-renderer 0.1.34 → 0.1.36
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/dist/mesher.js +64 -64
- package/dist/mesher.js.map +3 -3
- package/dist/mesherWasm.js +1 -1
- package/dist/minecraft-renderer.js +55 -55
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +363 -363
- package/package.json +1 -1
- package/src/graphicsBackend/config.ts +6 -1
- package/src/graphicsBackend/playerState.ts +1 -0
- package/src/lib/worldrendererCommon.ts +8 -0
- package/src/mesher/models.ts +15 -6
- package/src/mesher/shared.ts +3 -1
- package/src/playerState/playerState.ts +2 -0
- package/src/playground/scenes/main.ts +1 -1
- package/src/three/chunkMeshManager.ts +808 -0
- package/src/three/entities.ts +42 -36
- package/src/three/graphicsBackendBase.ts +1 -1
- package/src/three/modules/sciFiWorldReveal.ts +10 -21
- package/src/three/panorama.ts +1 -1
- package/src/three/worldRendererThree.ts +65 -40
- package/src/three/worldBlockGeometry.ts +0 -355
package/src/three/entities.ts
CHANGED
|
@@ -149,43 +149,49 @@ const addNametag = (entity, options: { fontFamily: string }, mesh, version: stri
|
|
|
149
149
|
c.removeFromParent()
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
if (entity.username
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
nameTag.
|
|
171
|
-
nameTag.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
nameTag.name = 'nametag'
|
|
185
|
-
|
|
186
|
-
mesh.add(nameTag)
|
|
187
|
-
return nameTag
|
|
152
|
+
if (entity.username === undefined || entity.username === null) return
|
|
153
|
+
|
|
154
|
+
const plainUsername =
|
|
155
|
+
typeof entity.username === 'string'
|
|
156
|
+
? entity.username
|
|
157
|
+
: new (PrismarineChatLoader(version))(entity.username).toString()
|
|
158
|
+
if (plainUsername.startsWith('EMPTY')) return
|
|
159
|
+
|
|
160
|
+
const canvas = getUsernameTexture(entity, options, version)
|
|
161
|
+
if (!canvas) return
|
|
162
|
+
const tex = new THREE.Texture(canvas)
|
|
163
|
+
tex.needsUpdate = true
|
|
164
|
+
let nameTag: THREE.Object3D
|
|
165
|
+
if (entity.nameTagFixed) {
|
|
166
|
+
const geometry = new THREE.PlaneGeometry()
|
|
167
|
+
const material = new THREE.MeshBasicMaterial({ map: tex })
|
|
168
|
+
material.transparent = true
|
|
169
|
+
nameTag = new THREE.Mesh(geometry, material)
|
|
170
|
+
nameTag.rotation.set(entity.pitch, THREE.MathUtils.degToRad(entity.yaw + 180), 0)
|
|
171
|
+
nameTag.position.y += entity.height + 0.3
|
|
172
|
+
} else {
|
|
173
|
+
const spriteMat = new THREE.SpriteMaterial({ map: tex })
|
|
174
|
+
nameTag = new THREE.Sprite(spriteMat)
|
|
175
|
+
nameTag.position.y += entity.height + 0.6
|
|
176
|
+
}
|
|
177
|
+
nameTag.renderOrder = 1000
|
|
178
|
+
nameTag.scale.set(canvas.width * 0.005, canvas.height * 0.005, 1)
|
|
179
|
+
if (entity.nameTagRotationRight) {
|
|
180
|
+
nameTag.applyQuaternion(entity.nameTagRotationRight)
|
|
181
|
+
}
|
|
182
|
+
if (entity.nameTagScale) {
|
|
183
|
+
nameTag.scale.multiply(entity.nameTagScale)
|
|
188
184
|
}
|
|
185
|
+
if (entity.nameTagRotationLeft) {
|
|
186
|
+
nameTag.applyQuaternion(entity.nameTagRotationLeft)
|
|
187
|
+
}
|
|
188
|
+
if (entity.nameTagTranslation) {
|
|
189
|
+
nameTag.position.add(entity.nameTagTranslation)
|
|
190
|
+
}
|
|
191
|
+
nameTag.name = 'nametag'
|
|
192
|
+
|
|
193
|
+
mesh.add(nameTag)
|
|
194
|
+
return nameTag
|
|
189
195
|
}
|
|
190
196
|
|
|
191
197
|
// todo cleanup
|
|
@@ -225,7 +225,7 @@ export const createGraphicsBackendBase = () => {
|
|
|
225
225
|
},
|
|
226
226
|
get left() {
|
|
227
227
|
return {
|
|
228
|
-
'Geo Memory': worldRenderer?.
|
|
228
|
+
'Geo Memory': worldRenderer?.chunkMeshManager.getEstimatedMemoryUsage().total ?? '-'
|
|
229
229
|
}
|
|
230
230
|
},
|
|
231
231
|
}),
|
|
@@ -58,11 +58,9 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
58
58
|
// Store original methods for patching
|
|
59
59
|
private originalFinishChunk: ((chunkKey: string) => void) | null = null
|
|
60
60
|
private originalDestroy: (() => void) | null = null
|
|
61
|
-
private originalSceneAdd: ((...object: THREE.Object3D[]) => THREE.
|
|
61
|
+
private originalSceneAdd: ((...object: THREE.Object3D[]) => THREE.Group) | null = null
|
|
62
62
|
private originalHandleWorkerMessage: ((data: { geometry: MesherGeometryOutput; key: string; type: string }) => void) | null = null
|
|
63
63
|
|
|
64
|
-
private originalWbgHandle: ((data: any) => void) | null = null
|
|
65
|
-
|
|
66
64
|
private configEnabled = true
|
|
67
65
|
|
|
68
66
|
constructor(private readonly worldRenderer: WorldRendererThree) {
|
|
@@ -146,12 +144,10 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
146
144
|
this.originalDestroy!()
|
|
147
145
|
}
|
|
148
146
|
|
|
149
|
-
// Patch handleWorkerMessage
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
wbg.handleWorkerGeometryMessage = (data: any) => {
|
|
154
|
-
const result = this.originalWbgHandle!(data)
|
|
147
|
+
// Patch handleWorkerMessage to intercept geometry
|
|
148
|
+
this.originalHandleWorkerMessage = wr.handleWorkerMessage.bind(wr)
|
|
149
|
+
wr.handleWorkerMessage = (data: any) => {
|
|
150
|
+
this.originalHandleWorkerMessage!(data)
|
|
155
151
|
|
|
156
152
|
if (this.enabled && data?.type === 'geometry') {
|
|
157
153
|
Promise.resolve().then(() => {
|
|
@@ -162,14 +158,12 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
162
158
|
}
|
|
163
159
|
})
|
|
164
160
|
}
|
|
165
|
-
|
|
166
|
-
return result
|
|
167
161
|
}
|
|
168
162
|
|
|
169
163
|
|
|
170
164
|
// Patch scene.add to intercept mesh additions
|
|
171
165
|
this.originalSceneAdd = wr.scene.add.bind(wr.scene)
|
|
172
|
-
wr.scene.add = (...objects: THREE.Object3D[]): THREE.
|
|
166
|
+
wr.scene.add = (...objects: THREE.Object3D[]): THREE.Group => {
|
|
173
167
|
// Call original add first
|
|
174
168
|
const result = this.originalSceneAdd!(...objects)
|
|
175
169
|
|
|
@@ -208,11 +202,6 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
208
202
|
this.originalSceneAdd = null
|
|
209
203
|
}
|
|
210
204
|
|
|
211
|
-
if (this.originalWbgHandle) {
|
|
212
|
-
wr.worldBlockGeometry.handleWorkerGeometryMessage = this.originalWbgHandle as any
|
|
213
|
-
this.originalWbgHandle = null
|
|
214
|
-
}
|
|
215
|
-
|
|
216
205
|
if (this.onWorldSwitchedCb) {
|
|
217
206
|
const i = wr.onWorldSwitched.indexOf(this.onWorldSwitchedCb)
|
|
218
207
|
if (i !== -1) wr.onWorldSwitched.splice(i, 1)
|
|
@@ -249,7 +238,7 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
249
238
|
let current: THREE.Object3D | null = mesh
|
|
250
239
|
while (current) {
|
|
251
240
|
const { sectionKey } = (current as any)
|
|
252
|
-
if (sectionKey && this.worldRenderer.
|
|
241
|
+
if (sectionKey && this.worldRenderer.chunkMeshManager.sectionObjects[sectionKey] === current) {
|
|
253
242
|
return sectionKey
|
|
254
243
|
}
|
|
255
244
|
current = current.parent
|
|
@@ -270,7 +259,7 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
270
259
|
const derivedKey = `${sectionX},${sectionY},${sectionZ}`
|
|
271
260
|
|
|
272
261
|
// Verify this key exists in sectionObjects
|
|
273
|
-
if (this.worldRenderer.
|
|
262
|
+
if (this.worldRenderer.chunkMeshManager.sectionObjects[derivedKey]) {
|
|
274
263
|
return derivedKey
|
|
275
264
|
}
|
|
276
265
|
|
|
@@ -281,7 +270,7 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
281
270
|
* Get the scene from world renderer
|
|
282
271
|
*/
|
|
283
272
|
private get scene(): THREE.Scene {
|
|
284
|
-
return this.worldRenderer.
|
|
273
|
+
return this.worldRenderer.realScene
|
|
285
274
|
}
|
|
286
275
|
|
|
287
276
|
/**
|
|
@@ -295,7 +284,7 @@ export class SciFiWorldRevealModule implements RendererModuleController {
|
|
|
295
284
|
* Get original mesh for a section key
|
|
296
285
|
*/
|
|
297
286
|
private getOriginalMesh(key: string): THREE.Mesh | null {
|
|
298
|
-
const sectionObject = this.worldRenderer.
|
|
287
|
+
const sectionObject = this.worldRenderer.chunkMeshManager.sectionObjects[key]
|
|
299
288
|
if (!sectionObject) return null
|
|
300
289
|
return sectionObject.children.find(child => child.name === 'mesh') as THREE.Mesh | null
|
|
301
290
|
}
|
package/src/three/panorama.ts
CHANGED
|
@@ -13,7 +13,6 @@ import { addNewStat } from '../lib/ui/newStats'
|
|
|
13
13
|
import { MesherGeometryOutput } from '../mesher/shared'
|
|
14
14
|
import { ItemSpecificContextProperties } from '../playerState/types'
|
|
15
15
|
import { setBlockPosition } from '../mesher/standaloneRenderer'
|
|
16
|
-
import { getBannerTexture, createBannerMesh, releaseBannerTexture } from './bannerRenderer'
|
|
17
16
|
import { getMyHand } from './hand'
|
|
18
17
|
import { createHoldingBlock } from './holdingBlockFactory'
|
|
19
18
|
import type { IHoldingBlock } from './holdingBlockTypes'
|
|
@@ -34,7 +33,7 @@ import { DEFAULT_TEMPERATURE, SkyboxRenderer } from './skyboxRenderer'
|
|
|
34
33
|
import { FireworksManager } from './fireworks'
|
|
35
34
|
import { SceneOrigin } from './sceneOrigin'
|
|
36
35
|
import { downloadWorldGeometry } from './worldGeometryExport'
|
|
37
|
-
import {
|
|
36
|
+
import { ChunkMeshManager } from './chunkMeshManager'
|
|
38
37
|
import type { RendererModuleManifest, RegisteredModule, RendererModuleController } from './rendererModuleSystem'
|
|
39
38
|
import { BUILTIN_MODULES } from './modules/index'
|
|
40
39
|
|
|
@@ -42,21 +41,22 @@ type SectionKey = string
|
|
|
42
41
|
|
|
43
42
|
export class WorldRendererThree extends WorldRendererCommon {
|
|
44
43
|
outputFormat = 'threeJs' as const
|
|
45
|
-
|
|
44
|
+
chunkMeshManager: ChunkMeshManager
|
|
46
45
|
get sectionObjects() {
|
|
47
|
-
return this.
|
|
46
|
+
return this.chunkMeshManager.sectionObjects
|
|
48
47
|
}
|
|
49
48
|
chunkTextures = new Map<string, { [pos: string]: THREE.Texture }>()
|
|
50
49
|
signsCache = new Map<string, any>()
|
|
51
50
|
cameraSectionPos: Vec3 = new Vec3(0, 0, 0)
|
|
52
51
|
holdingBlock: IHoldingBlock
|
|
53
52
|
holdingBlockLeft: IHoldingBlock
|
|
54
|
-
|
|
53
|
+
realScene = new THREE.Scene()
|
|
54
|
+
scene = new THREE.Group()
|
|
55
55
|
ambientLight = new THREE.AmbientLight(0xcc_cc_cc)
|
|
56
56
|
directionalLight = new THREE.DirectionalLight(0xff_ff_ff, 0.5)
|
|
57
57
|
entities = new Entities(this, (globalThis as any).mcData)
|
|
58
58
|
cameraGroupVr?: THREE.Object3D
|
|
59
|
-
material = new THREE.
|
|
59
|
+
material = new THREE.MeshBasicMaterial({ vertexColors: true, transparent: true, alphaTest: 0.1 })
|
|
60
60
|
itemsTexture!: THREE.Texture
|
|
61
61
|
cursorBlock: CursorBlock
|
|
62
62
|
onRender: Array<(deltaTime: number) => void> = []
|
|
@@ -65,7 +65,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
65
65
|
cameraContainer!: THREE.Object3D
|
|
66
66
|
media: ThreeJsMedia
|
|
67
67
|
get waitingChunksToDisplay() {
|
|
68
|
-
return
|
|
68
|
+
return {} as { [chunkKey: string]: string[] }
|
|
69
69
|
}
|
|
70
70
|
waypoints: WaypointsRenderer
|
|
71
71
|
cinimaticScript: CinimaticScriptRunner
|
|
@@ -81,7 +81,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
81
81
|
renderTimeAvg = 0
|
|
82
82
|
// Memory usage tracking (in bytes)
|
|
83
83
|
get estimatedMemoryUsage() {
|
|
84
|
-
return this.
|
|
84
|
+
return this.chunkMeshManager.getEstimatedMemoryUsage().total
|
|
85
85
|
}
|
|
86
86
|
// Module system
|
|
87
87
|
private modules = {} as Record<string, RegisteredModule>
|
|
@@ -107,7 +107,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
107
107
|
DEBUG_RAYCAST = false
|
|
108
108
|
skyboxRenderer: SkyboxRenderer
|
|
109
109
|
fireworks: FireworksManager
|
|
110
|
-
sceneOrigin = new SceneOrigin(this.
|
|
110
|
+
sceneOrigin = new SceneOrigin(this.realScene)
|
|
111
111
|
/** Camera world position stored in float64 (JS number) for precision */
|
|
112
112
|
cameraWorldPos = { x: 0, y: 0, z: 0 }
|
|
113
113
|
|
|
@@ -131,11 +131,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
131
131
|
private readonly _tpChunkWorldPos = new THREE.Vector3()
|
|
132
132
|
|
|
133
133
|
get tilesRendered() {
|
|
134
|
-
return
|
|
134
|
+
return this.chunkMeshManager.getTotalTiles()
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
get blocksRendered() {
|
|
138
|
-
return
|
|
138
|
+
return this.chunkMeshManager.getTotalBlocks()
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
constructor(public renderer: THREE.WebGLRenderer, public initOptions: GraphicsInitOptions, public displayOptions: DisplayWorldOptions) {
|
|
@@ -145,8 +145,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
145
145
|
this.renderer = renderer
|
|
146
146
|
displayOptions.rendererState.renderer = WorldRendererThree.getRendererInfo(renderer) ?? '...'
|
|
147
147
|
|
|
148
|
-
// Initialize
|
|
149
|
-
this.
|
|
148
|
+
// Initialize chunk mesh manager
|
|
149
|
+
this.chunkMeshManager = new ChunkMeshManager(this, this.scene, this.material, this.worldSizeParams.worldHeight, this.viewDistance)
|
|
150
|
+
this.onRenderDistanceChanged = (viewDistance) => {
|
|
151
|
+
this.chunkMeshManager.updateViewDistance(viewDistance)
|
|
152
|
+
}
|
|
150
153
|
|
|
151
154
|
this.cursorBlock = new CursorBlock(this)
|
|
152
155
|
this.holdingBlock = createHoldingBlock(this)
|
|
@@ -158,7 +161,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
// Initialize skybox renderer
|
|
161
|
-
this.skyboxRenderer = new SkyboxRenderer(this.
|
|
164
|
+
this.skyboxRenderer = new SkyboxRenderer(this.realScene, false, null)
|
|
162
165
|
void this.skyboxRenderer.init()
|
|
163
166
|
|
|
164
167
|
this.addDebugOverlay()
|
|
@@ -181,7 +184,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
181
184
|
fov: this.camera.fov
|
|
182
185
|
})
|
|
183
186
|
)
|
|
184
|
-
this.fireworks = new FireworksManager(this.
|
|
187
|
+
this.fireworks = new FireworksManager(this.realScene, this.sceneOrigin)
|
|
185
188
|
|
|
186
189
|
// this.fountain = new Fountain(this.scene, this.scene, {
|
|
187
190
|
// position: new THREE.Vector3(0, 10, 0),
|
|
@@ -447,19 +450,20 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
447
450
|
this.cameraWorldPos.y = 0
|
|
448
451
|
this.cameraWorldPos.z = 0
|
|
449
452
|
|
|
450
|
-
this.
|
|
451
|
-
this.
|
|
452
|
-
this.
|
|
453
|
+
this.realScene.matrixAutoUpdate = false // for perf
|
|
454
|
+
this.realScene.background = new THREE.Color(this.initOptions.config.sceneBackground)
|
|
455
|
+
this.realScene.add(this.ambientLight)
|
|
453
456
|
this.directionalLight.position.set(1, 1, 0.5).normalize()
|
|
454
457
|
this.directionalLight.castShadow = true
|
|
455
|
-
this.
|
|
458
|
+
this.realScene.add(this.directionalLight)
|
|
456
459
|
|
|
457
460
|
const size = this.renderer.getSize(new THREE.Vector2())
|
|
458
461
|
this.camera = new THREE.PerspectiveCamera(75, size.x / size.y, 0.1, 1000)
|
|
459
462
|
this._wrapCameraPositionWithWarning()
|
|
460
463
|
this.cameraContainer = new THREE.Object3D()
|
|
461
464
|
this.cameraContainer.add(this.camera)
|
|
462
|
-
this.
|
|
465
|
+
this.realScene.add(this.cameraContainer)
|
|
466
|
+
this.realScene.add(this.scene)
|
|
463
467
|
}
|
|
464
468
|
|
|
465
469
|
override watchReactivePlayerState() {
|
|
@@ -625,7 +629,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
625
629
|
}
|
|
626
630
|
|
|
627
631
|
changeBackgroundColor(color: [number, number, number]): void {
|
|
628
|
-
this.
|
|
632
|
+
this.realScene.background = new THREE.Color(color[0], color[1], color[2])
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
changeCardinalLight(cardinalLight: string): void {
|
|
636
|
+
this.worldRendererConfig.cardinalLight = cardinalLight
|
|
629
637
|
}
|
|
630
638
|
|
|
631
639
|
timeUpdated(newTime: number): void {
|
|
@@ -662,7 +670,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
662
670
|
setBlockPosition(mesh, pos)
|
|
663
671
|
const helper = new THREE.BoxHelper(mesh, 0xff_ff_00)
|
|
664
672
|
mesh.add(helper)
|
|
665
|
-
this.
|
|
673
|
+
this.realScene.add(mesh)
|
|
666
674
|
}
|
|
667
675
|
|
|
668
676
|
demoItem() {
|
|
@@ -675,7 +683,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
675
683
|
// mesh.scale.set(0.5, 0.5, 0.5)
|
|
676
684
|
const helper = new THREE.BoxHelper(mesh, 0xff_ff_00)
|
|
677
685
|
mesh.add(helper)
|
|
678
|
-
this.
|
|
686
|
+
this.realScene.add(mesh)
|
|
679
687
|
}
|
|
680
688
|
|
|
681
689
|
debugOverlayAdded = false
|
|
@@ -695,7 +703,9 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
695
703
|
text += `TE: ${formatBigNumber(this.renderer.info.memory.textures)} `
|
|
696
704
|
text += `F: ${formatBigNumber(this.tilesRendered)} `
|
|
697
705
|
text += `B: ${formatBigNumber(this.blocksRendered)} `
|
|
698
|
-
text += `MEM: ${this.
|
|
706
|
+
text += `MEM: ${this.chunkMeshManager.getEstimatedMemoryUsage().total} `
|
|
707
|
+
const poolStats = this.chunkMeshManager.getStats()
|
|
708
|
+
text += `POOL: ${poolStats.activeCount}/${poolStats.poolSize} HR: ${poolStats.hitRate}`
|
|
699
709
|
pane.updateText(text)
|
|
700
710
|
this.backendInfoReport = text
|
|
701
711
|
}
|
|
@@ -709,7 +719,8 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
709
719
|
const [x, y, z] = key.split(',').map(x => Math.floor(+x / 16))
|
|
710
720
|
// sum of distances: x + y + z
|
|
711
721
|
const chunkDistance = Math.abs(x - this.cameraSectionPos.x) + Math.abs(y - this.cameraSectionPos.y) + Math.abs(z - this.cameraSectionPos.z)
|
|
712
|
-
const
|
|
722
|
+
const sectionObj = this.sectionObjects[key]
|
|
723
|
+
const section = (sectionObj as any).mesh ?? sectionObj.children.find(child => child.name === 'mesh')!
|
|
713
724
|
section.renderOrder = 500 - chunkDistance
|
|
714
725
|
}
|
|
715
726
|
|
|
@@ -732,12 +743,15 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
732
743
|
}
|
|
733
744
|
|
|
734
745
|
finishChunk(chunkKey: string) {
|
|
735
|
-
|
|
746
|
+
// ChunkMeshManager applies updates immediately, no buffering needed
|
|
736
747
|
}
|
|
737
748
|
|
|
738
749
|
handleWorkerMessage(data: { geometry: MesherGeometryOutput, key, type }): void {
|
|
739
750
|
if (data.type === 'geometry') {
|
|
740
|
-
|
|
751
|
+
const chunkCoords = data.key.split(',')
|
|
752
|
+
if (!this.loadedChunks[chunkCoords[0] + ',' + chunkCoords[2]] || !data.geometry.positions.length || !this.active) return
|
|
753
|
+
this.chunkMeshManager.updateSection(data.key, data.geometry)
|
|
754
|
+
this.updatePosDataChunk(data.key)
|
|
741
755
|
}
|
|
742
756
|
}
|
|
743
757
|
|
|
@@ -883,11 +897,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
883
897
|
private debugRaycast(pos: THREE.Vector3, direction: THREE.Vector3, distance: number) {
|
|
884
898
|
// Remove existing debug objects
|
|
885
899
|
if (this.debugRaycastHelper) {
|
|
886
|
-
this.
|
|
900
|
+
this.realScene.remove(this.debugRaycastHelper)
|
|
887
901
|
this.debugRaycastHelper = undefined
|
|
888
902
|
}
|
|
889
903
|
if (this.debugHitPoint) {
|
|
890
|
-
this.
|
|
904
|
+
this.realScene.remove(this.debugHitPoint)
|
|
891
905
|
this.debugHitPoint = undefined
|
|
892
906
|
}
|
|
893
907
|
|
|
@@ -907,14 +921,14 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
907
921
|
distance * 0.1,
|
|
908
922
|
distance * 0.05
|
|
909
923
|
)
|
|
910
|
-
this.
|
|
924
|
+
this.realScene.add(this.debugRaycastHelper)
|
|
911
925
|
|
|
912
926
|
// Create hit point indicator
|
|
913
927
|
const hitGeometry = new THREE.SphereGeometry(0.2, 8, 8)
|
|
914
928
|
const hitMaterial = new THREE.MeshBasicMaterial({ color: 0x00_ff_00 })
|
|
915
929
|
this.debugHitPoint = new THREE.Mesh(hitGeometry, hitMaterial)
|
|
916
930
|
this.debugHitPoint.position.copy(scenePos).add(direction.clone().multiplyScalar(distance))
|
|
917
|
-
this.
|
|
931
|
+
this.realScene.add(this.debugHitPoint)
|
|
918
932
|
}
|
|
919
933
|
|
|
920
934
|
prevFramePerspective = null as string | null
|
|
@@ -1012,11 +1026,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1012
1026
|
|
|
1013
1027
|
// remove any debug raycasting
|
|
1014
1028
|
if (this.debugRaycastHelper) {
|
|
1015
|
-
this.
|
|
1029
|
+
this.realScene.remove(this.debugRaycastHelper)
|
|
1016
1030
|
this.debugRaycastHelper = undefined
|
|
1017
1031
|
}
|
|
1018
1032
|
if (this.debugHitPoint) {
|
|
1019
|
-
this.
|
|
1033
|
+
this.realScene.remove(this.debugHitPoint)
|
|
1020
1034
|
this.debugHitPoint = undefined
|
|
1021
1035
|
}
|
|
1022
1036
|
}
|
|
@@ -1087,9 +1101,8 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1087
1101
|
|
|
1088
1102
|
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
|
|
1089
1103
|
const cam = this.cameraGroupVr instanceof THREE.Group ? this.cameraGroupVr.children.find(child => child instanceof THREE.PerspectiveCamera) as THREE.PerspectiveCamera : this.camera
|
|
1090
|
-
//
|
|
1091
|
-
this.
|
|
1092
|
-
this.renderer.render(this.scene, cam)
|
|
1104
|
+
// ChunkMeshManager applies updates immediately, no pending updates to flush
|
|
1105
|
+
this.renderer.render(this.realScene, cam)
|
|
1093
1106
|
|
|
1094
1107
|
if (
|
|
1095
1108
|
this.displayOptions.inWorldRenderingConfig.showHand &&
|
|
@@ -1118,6 +1131,9 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1118
1131
|
}
|
|
1119
1132
|
const end = performance.now()
|
|
1120
1133
|
const totalTime = end - start
|
|
1134
|
+
if (this.worldRendererConfig.autoLowerRenderDistance) {
|
|
1135
|
+
this.chunkMeshManager.recordRenderTime(totalTime)
|
|
1136
|
+
}
|
|
1121
1137
|
this.renderTimeAvgCount++
|
|
1122
1138
|
this.renderTimeAvg = ((this.renderTimeAvg * (this.renderTimeAvgCount - 1)) + totalTime) / this.renderTimeAvgCount
|
|
1123
1139
|
this.renderTimeMax = Math.max(this.renderTimeMax, totalTime)
|
|
@@ -1233,15 +1249,16 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1233
1249
|
resetWorld() {
|
|
1234
1250
|
super.resetWorld()
|
|
1235
1251
|
|
|
1236
|
-
this.
|
|
1252
|
+
this.chunkMeshManager.dispose()
|
|
1253
|
+
this.chunkMeshManager = new ChunkMeshManager(this, this.scene, this.material, this.worldSizeParams.worldHeight, this.viewDistance)
|
|
1237
1254
|
|
|
1238
1255
|
// Clean up debug objects
|
|
1239
1256
|
if (this.debugRaycastHelper) {
|
|
1240
|
-
this.
|
|
1257
|
+
this.realScene.remove(this.debugRaycastHelper)
|
|
1241
1258
|
this.debugRaycastHelper = undefined
|
|
1242
1259
|
}
|
|
1243
1260
|
if (this.debugHitPoint) {
|
|
1244
|
-
this.
|
|
1261
|
+
this.realScene.remove(this.debugHitPoint)
|
|
1245
1262
|
this.debugHitPoint = undefined
|
|
1246
1263
|
}
|
|
1247
1264
|
}
|
|
@@ -1286,7 +1303,14 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1286
1303
|
super.removeColumn(x, z)
|
|
1287
1304
|
|
|
1288
1305
|
this.cleanChunkTextures(x, z)
|
|
1289
|
-
this.
|
|
1306
|
+
const sectionHeight = this.getSectionHeight()
|
|
1307
|
+
const worldMinY = this.worldMinYRender
|
|
1308
|
+
for (let y = worldMinY; y < this.worldSizeParams.worldHeight; y += sectionHeight) {
|
|
1309
|
+
const key = `${x},${y},${z}`
|
|
1310
|
+
if (this.chunkMeshManager.sectionObjects[key]) {
|
|
1311
|
+
this.chunkMeshManager.releaseSection(key)
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1290
1314
|
}
|
|
1291
1315
|
|
|
1292
1316
|
setSectionDirty(...args: Parameters<WorldRendererCommon['setSectionDirty']>) {
|
|
@@ -1309,6 +1333,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1309
1333
|
}
|
|
1310
1334
|
|
|
1311
1335
|
destroy(): void {
|
|
1336
|
+
this.chunkMeshManager.dispose()
|
|
1312
1337
|
this.disposeModules()
|
|
1313
1338
|
this.fireworksLegacy.destroy()
|
|
1314
1339
|
super.destroy()
|