minecraft-renderer 0.1.78 → 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.
Files changed (200) hide show
  1. package/README.md +29 -25
  2. package/dist/mesher.js +36 -36
  3. package/dist/mesher.js.map +4 -4
  4. package/dist/mesherWasm.js +217 -217
  5. package/dist/minecraft-renderer.js +32 -32
  6. package/dist/minecraft-renderer.js.meta.json +1 -1
  7. package/dist/threeWorker.js +415 -415
  8. package/package.json +5 -2
  9. package/src/bundler/bundlePrepare.ts +3 -8
  10. package/src/graphicsBackend/appViewer.ts +10 -7
  11. package/src/graphicsBackend/config.ts +1 -5
  12. package/src/graphicsBackend/playerState.ts +35 -34
  13. package/src/graphicsBackend/preloadWorkers.ts +43 -41
  14. package/src/graphicsBackend/rendererDefaultOptions.ts +68 -70
  15. package/src/graphicsBackend/rendererOptionsSync.ts +24 -50
  16. package/src/graphicsBackend/types.ts +2 -2
  17. package/src/index.ts +6 -27
  18. package/src/lib/DebugGui.ts +34 -31
  19. package/src/lib/animationController.ts +9 -9
  20. package/src/lib/bakeLegacyLight.ts +1 -6
  21. package/src/lib/bindAbortableListener.test.ts +32 -12
  22. package/src/lib/bindAbortableListener.ts +14 -6
  23. package/src/lib/blockEntityLightRegistry.ts +11 -20
  24. package/src/lib/blockEntityLighting.test.ts +1 -6
  25. package/src/lib/blockEntityLighting.ts +5 -5
  26. package/src/lib/buildSharedConfig.mjs +4 -4
  27. package/src/lib/buildWorkerMcDataIndexes.test.ts +4 -4
  28. package/src/lib/buildWorkerMcDataIndexes.ts +11 -19
  29. package/src/lib/cameraBobbing.ts +1 -1
  30. package/src/lib/canvas2DOverlay.example.ts +13 -33
  31. package/src/lib/canvas2DOverlay.quickstart.ts +24 -54
  32. package/src/lib/canvas2DOverlay.ts +28 -47
  33. package/src/lib/cleanupDecorator.ts +2 -2
  34. package/src/lib/createPlayerObject.test.ts +2 -7
  35. package/src/lib/createPlayerObject.ts +18 -25
  36. package/src/lib/frameTimingCollector.ts +2 -5
  37. package/src/lib/guiRenderer.ts +57 -42
  38. package/src/lib/items.ts +15 -9
  39. package/src/lib/mesherlogReader.ts +5 -6
  40. package/src/lib/simpleUtils.ts +5 -5
  41. package/src/lib/skyLight.ts +3 -3
  42. package/src/lib/smoothSwitcher.ts +11 -18
  43. package/src/lib/ui/newStats.ts +10 -12
  44. package/src/lib/utils/proxy.ts +7 -1
  45. package/src/lib/utils/skins.ts +4 -4
  46. package/src/lib/utils.ts +1 -1
  47. package/src/lib/workerMessageSanitize.ts +5 -12
  48. package/src/lib/workerProxy.ts +52 -42
  49. package/src/lib/workerSyncOps.test.ts +58 -41
  50. package/src/lib/worldrendererCommon.reconfigure.test.ts +24 -21
  51. package/src/lib/worldrendererCommon.removeColumn.test.ts +11 -13
  52. package/src/lib/worldrendererCommon.ts +338 -211
  53. package/src/mesher-legacy/mesher.ts +9 -4
  54. package/src/mesher-legacy/test/a.ts +1 -1
  55. package/src/mesher-legacy/test/mesherTester.ts +2 -2
  56. package/src/mesher-legacy/test/playground.ts +1 -1
  57. package/src/mesher-legacy/test/run/test-js.ts +1 -1
  58. package/src/mesher-legacy/test/snapshotUtils.ts +3 -8
  59. package/src/mesher-legacy/test/test-perf.ts +1 -1
  60. package/src/mesher-legacy/test/tests.test.ts +2 -2
  61. package/src/mesher-shared/blockEntityMetadata.test.ts +7 -5
  62. package/src/mesher-shared/blockEntityMetadata.ts +28 -19
  63. package/src/mesher-shared/blockPropertiesForMeshing.ts +2 -2
  64. package/src/mesher-shared/computeHeightmap.ts +2 -4
  65. package/src/mesher-shared/exportedGeometryTypes.ts +3 -3
  66. package/src/mesher-shared/faceOcclusion.ts +324 -0
  67. package/src/mesher-shared/models.ts +80 -131
  68. package/src/mesher-shared/modelsGeometryCommon.ts +30 -15
  69. package/src/mesher-shared/shared.ts +46 -46
  70. package/src/mesher-shared/standaloneRenderer.ts +40 -44
  71. package/src/mesher-shared/tests/faceOcclusion.test.ts +179 -0
  72. package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +12 -8
  73. package/src/mesher-shared/vertexShading.ts +2 -11
  74. package/src/mesher-shared/world.ts +19 -19
  75. package/src/mesher-shared/worldLighting.test.ts +2 -2
  76. package/src/performanceMonitor/PerformanceMonitor.ts +4 -13
  77. package/src/performanceMonitor/formatPerformanceFactorsDebug.ts +2 -2
  78. package/src/performanceMonitor/index.ts +1 -5
  79. package/src/performanceMonitor/types.ts +1 -1
  80. package/src/playerState/playerState.ts +55 -50
  81. package/src/playerState/types.ts +2 -8
  82. package/src/playground/allEntitiesDebug.ts +19 -16
  83. package/src/playground/baseScene.ts +29 -32
  84. package/src/playground/mobileControls.tsx +133 -129
  85. package/src/playground/playground.html +76 -73
  86. package/src/playground/playground.ts +14 -1
  87. package/src/playground/playgroundUi.tsx +100 -74
  88. package/src/playground/reactUtils.ts +3 -7
  89. package/src/playground/scenes/entities.ts +10 -7
  90. package/src/playground/scenes/frequentUpdates.ts +5 -5
  91. package/src/playground/scenes/geometryExport.ts +6 -20
  92. package/src/playground/scenes/highPosEntityUpdates.ts +2 -10
  93. package/src/playground/scenes/index.ts +1 -1
  94. package/src/playground/scenes/lightingStarfield.ts +18 -12
  95. package/src/playground/scenes/main.ts +15 -11
  96. package/src/playground/scenes/partialBlockCulling.ts +31 -0
  97. package/src/playground/scenes/railsCobweb.ts +1 -1
  98. package/src/playground/scenes/rotationIssue.ts +1 -1
  99. package/src/playground/scenes/slabsOptimization.ts +1 -2
  100. package/src/playground/scenes/transparencyIssue.ts +1 -1
  101. package/src/playground/shared.ts +2 -2
  102. package/src/resourcesManager/resourcesManager.ts +29 -54
  103. package/src/resourcesManager/resourcesManager.worker.test.ts +6 -10
  104. package/src/shims/minecraftData.ts +70 -24
  105. package/src/sign-renderer/index.html +10 -12
  106. package/src/sign-renderer/index.ts +29 -29
  107. package/src/sign-renderer/playground.ts +22 -15
  108. package/src/sign-renderer/tests.test.ts +16 -13
  109. package/src/sign-renderer/vite.config.ts +2 -2
  110. package/src/three/appShared.ts +46 -25
  111. package/src/three/bannerRenderer.ts +33 -61
  112. package/src/three/cameraShake.ts +15 -6
  113. package/src/three/chunkMeshManager.ts +329 -301
  114. package/src/three/cinimaticScript.ts +26 -15
  115. package/src/three/cubeDrawSpans.ts +27 -37
  116. package/src/three/cubeMultiDraw.ts +9 -22
  117. package/src/three/documentRenderer.ts +15 -18
  118. package/src/three/entities.ts +175 -150
  119. package/src/three/entity/EntityMesh.ts +114 -108
  120. package/src/three/entity/animations.js +3 -3
  121. package/src/three/entity/armorModels.ts +15 -15
  122. package/src/three/entity/gltfAnimationUtils.ts +2 -5
  123. package/src/three/fireworks.ts +34 -32
  124. package/src/three/fireworksRenderer.ts +32 -29
  125. package/src/three/globalBlockBuffer.ts +174 -99
  126. package/src/three/globalLegacyBuffer.ts +465 -136
  127. package/src/three/graphicsBackendBase.ts +19 -25
  128. package/src/three/graphicsBackendOffThread.ts +12 -15
  129. package/src/three/hand.ts +21 -21
  130. package/src/three/handLegacy.ts +3 -13
  131. package/src/three/holdingBlock.ts +116 -79
  132. package/src/three/holdingBlockFactory.ts +1 -4
  133. package/src/three/holdingBlockItemIdentity.test.ts +25 -17
  134. package/src/three/holdingBlockItemIdentity.ts +9 -6
  135. package/src/three/holdingBlockLegacy.ts +113 -132
  136. package/src/three/itemMesh.ts +20 -29
  137. package/src/three/legacyMultiDraw.ts +93 -0
  138. package/src/three/legacySectionCull.ts +8 -14
  139. package/src/three/menuBackground/activeView.ts +1 -4
  140. package/src/three/menuBackground/assetUrl.ts +1 -1
  141. package/src/three/menuBackground/classic.ts +4 -12
  142. package/src/three/menuBackground/gpuPreference.ts +1 -3
  143. package/src/three/menuBackground/index.ts +2 -11
  144. package/src/three/menuBackground/renderer.ts +1 -5
  145. package/src/three/menuBackground/types.ts +1 -4
  146. package/src/three/menuBackground/v2.ts +196 -96
  147. package/src/three/menuBackground/v2Meta.ts +3 -3
  148. package/src/three/menuBackground/worldBlocks.ts +37 -35
  149. package/src/three/modules/blockBreakParticles.ts +59 -28
  150. package/src/three/modules/cameraBobbing.ts +3 -6
  151. package/src/three/modules/index.ts +1 -1
  152. package/src/three/modules/rain.ts +10 -23
  153. package/src/three/modules/sciFiWorldReveal.ts +11 -25
  154. package/src/three/modules/starfield.ts +7 -13
  155. package/src/three/renderSlot.ts +28 -16
  156. package/src/three/rendererModuleSystem.ts +1 -3
  157. package/src/three/sceneOrigin.ts +96 -33
  158. package/src/three/sectionRaycastAabb.ts +30 -18
  159. package/src/three/shaderCubeMesh.ts +6 -17
  160. package/src/three/shaders/cubeBlockShader.ts +85 -96
  161. package/src/three/shaders/legacyBlockShader.ts +21 -43
  162. package/src/three/shaders/textureIndexMapping.ts +89 -95
  163. package/src/three/shaders/tintPalette.ts +156 -170
  164. package/src/three/signTextureCache.ts +9 -12
  165. package/src/three/skyboxRenderer.ts +62 -70
  166. package/src/three/tests/chunkMeshManagerLegacy.test.ts +133 -25
  167. package/src/three/tests/cubeDrawSpans.test.ts +55 -25
  168. package/src/three/tests/globalBlockBuffer.test.ts +217 -0
  169. package/src/three/tests/globalLegacyBuffer.test.ts +460 -58
  170. package/src/three/tests/legacyMultiDraw.test.ts +88 -0
  171. package/src/three/tests/pr3PerFrameCpuCuts.test.ts +370 -0
  172. package/src/three/tests/signTextureCache.test.ts +4 -4
  173. package/src/three/threeJsMedia.ts +55 -72
  174. package/src/three/threeJsParticles.ts +32 -41
  175. package/src/three/threeJsSound.ts +3 -3
  176. package/src/three/threeJsUtils.ts +3 -3
  177. package/src/three/threeWorker.ts +2 -2
  178. package/src/three/waypointSprite.ts +55 -82
  179. package/src/three/waypoints.ts +20 -23
  180. package/src/three/world/cursorBlock.ts +25 -12
  181. package/src/three/world/vr.ts +11 -17
  182. package/src/three/worldGeometryExport.ts +15 -34
  183. package/src/three/worldRendererThree.ts +131 -133
  184. package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
  185. package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
  186. package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
  187. package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
  188. package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
  189. package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
  190. package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +17 -4
  191. package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
  192. package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
  193. package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
  194. package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
  195. package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
  196. package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
  197. package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
  198. package/src/worldView/worldView.spiral.test.ts +1 -1
  199. package/src/worldView/worldView.ts +34 -39
  200. package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
@@ -11,14 +11,14 @@ type ControlModeConfig = {
11
11
  }
12
12
 
13
13
  interface MediaProperties {
14
- position: { x: number, y: number, z: number }
15
- size: { width: number, height: number }
14
+ position: { x: number; y: number; z: number }
15
+ size: { width: number; height: number }
16
16
  src: string
17
17
  rotation?: 0 | 1 | 2 | 3 // 0-3 for 0°, 90°, 180°, 270°
18
18
  doubleSide?: boolean
19
19
  background?: number // Hexadecimal color (e.g., 0x000000 for black)
20
20
  opacity?: number // 0-1 value for transparency
21
- uvMapping?: { startU: number, endU: number, startV: number, endV: number }
21
+ uvMapping?: { startU: number; endU: number; startV: number; endV: number }
22
22
  allowOrigins?: string[] | boolean
23
23
  loop?: boolean
24
24
  volume?: number
@@ -34,12 +34,7 @@ interface MediaData {
34
34
  video: HTMLVideoElement | undefined
35
35
  pausedBecuaseHidden: boolean
36
36
  texture: THREE.Texture
37
- updateUVMapping: (config: {
38
- startU: number
39
- endU: number
40
- startV: number
41
- endV: number
42
- }) => void
37
+ updateUVMapping: (config: { startU: number; endU: number; startV: number; endV: number }) => void
43
38
  positionalAudio?: THREE.PositionalAudio
44
39
  hadAutoPlayError?: boolean
45
40
  ended?: boolean
@@ -95,7 +90,7 @@ export class ThreeJsMedia {
95
90
  ctx.clearRect(0, 0, canvas.width, canvas.height)
96
91
 
97
92
  // Add background color
98
- ctx.fillStyle = `rgba(${background >> 16 & 255}, ${background >> 8 & 255}, ${background & 255}, 1)`
93
+ ctx.fillStyle = `rgba(${(background >> 16) & 255}, ${(background >> 8) & 255}, ${background & 255}, 1)`
99
94
  ctx.fillRect(0, 0, canvas.width, canvas.height)
100
95
 
101
96
  // Add red text with size relative to canvas dimensions
@@ -167,7 +162,13 @@ export class ThreeJsMedia {
167
162
 
168
163
  const originSecurityError = props.allowOrigins !== undefined && !this.validateOrigin(props.src, props.allowOrigins)
169
164
  if (originSecurityError) {
170
- console.warn('Remote resource blocked due to security policy', props.src, 'allowed origins:', props.allowOrigins, 'you can control it with `remoteContentNotSameOrigin` option')
165
+ console.warn(
166
+ 'Remote resource blocked due to security policy',
167
+ props.src,
168
+ 'allowed origins:',
169
+ props.allowOrigins,
170
+ 'you can control it with `remoteContentNotSameOrigin` option'
171
+ )
171
172
  props.src = ''
172
173
  }
173
174
 
@@ -247,12 +248,11 @@ export class ThreeJsMedia {
247
248
  })
248
249
  }
249
250
 
250
-
251
251
  // Create background texture first
252
252
  const backgroundTexture = this.createBackgroundTexture(
253
253
  props.size.width,
254
254
  props.size.height,
255
- props.background,
255
+ props.background
256
256
  // props.opacity ?? 1
257
257
  )
258
258
 
@@ -278,30 +278,32 @@ export class ThreeJsMedia {
278
278
  if (video) {
279
279
  texture = new THREE.VideoTexture(video)
280
280
  } else if (workerVideoUnsupported) {
281
- texture = this.createErrorTexture(
282
- props.size.width,
283
- props.size.height,
284
- props.background,
285
- 'Video unavailable (multi-thread)',
286
- )
281
+ texture = this.createErrorTexture(props.size.width, props.size.height, props.background, 'Video unavailable (multi-thread)')
287
282
  } else if (isWebWorker) {
288
283
  const loaded = loadThreeJsTextureFromUrlSync(props.src)
289
284
  texture = loaded.texture
290
285
  texture.minFilter = THREE.NearestFilter
291
286
  texture.magFilter = THREE.NearestFilter
292
- void loaded.promise.then(() => {
293
- if (this.customMedia.get(id)?.texture === texture) {
294
- material.map = texture
295
- material.needsUpdate = true
296
- }
297
- }).catch(() => handleError())
287
+ void loaded.promise
288
+ .then(() => {
289
+ if (this.customMedia.get(id)?.texture === texture) {
290
+ material.map = texture
291
+ material.needsUpdate = true
292
+ }
293
+ })
294
+ .catch(() => handleError())
298
295
  } else {
299
- texture = new THREE.TextureLoader().load(props.src, () => {
300
- if (this.customMedia.get(id)?.texture === texture) {
301
- material.map = texture
302
- material.needsUpdate = true
303
- }
304
- }, undefined, () => handleError()) // todo cache
296
+ texture = new THREE.TextureLoader().load(
297
+ props.src,
298
+ () => {
299
+ if (this.customMedia.get(id)?.texture === texture) {
300
+ material.map = texture
301
+ material.needsUpdate = true
302
+ }
303
+ },
304
+ undefined,
305
+ () => handleError()
306
+ ) // todo cache
305
307
  }
306
308
  texture.minFilter = THREE.NearestFilter
307
309
  texture.magFilter = THREE.NearestFilter
@@ -312,7 +314,13 @@ export class ThreeJsMedia {
312
314
  // Create inner mesh for offsets
313
315
  const mesh = new THREE.Mesh(geometry, material)
314
316
 
315
- const { mesh: panel } = this.positionMeshExact(mesh, THREE.MathUtils.degToRad((props.rotation ?? 0) * 90), props.position, props.size.width, props.size.height)
317
+ const { mesh: panel } = this.positionMeshExact(
318
+ mesh,
319
+ THREE.MathUtils.degToRad((props.rotation ?? 0) * 90),
320
+ props.position,
321
+ props.size.width,
322
+ props.size.height
323
+ )
316
324
 
317
325
  scene.add(panel)
318
326
 
@@ -336,7 +344,7 @@ export class ThreeJsMedia {
336
344
  }
337
345
 
338
346
  // UV mapping configuration
339
- const updateUVMapping = (config: { startU: number, endU: number, startV: number, endV: number }) => {
347
+ const updateUVMapping = (config: { startU: number; endU: number; startV: number; endV: number }) => {
340
348
  const uvs = geometry.attributes.uv.array as Float32Array
341
349
  uvs[0] = config.startU
342
350
  uvs[1] = config.startV
@@ -368,7 +376,7 @@ export class ThreeJsMedia {
368
376
  if (videoData.destroyed) return
369
377
  console.error(`Failed to play video ${id}:`, err)
370
378
  // TODO!
371
- const t = /* translate ?? */(txt => txt)
379
+ const t = /* translate ?? */ txt => txt
372
380
  handleError(err.name === 'NotAllowedError' || err.name === 'AbortError' ? t('Waiting for user interaction') : t('Failed to auto play'))
373
381
  }
374
382
  }
@@ -398,14 +406,15 @@ export class ThreeJsMedia {
398
406
  return
399
407
  }
400
408
 
401
- void videoData.video.play()
409
+ void videoData.video
410
+ .play()
402
411
  .then(() => {
403
412
  videoData.hadAutoPlayError = false
404
413
  console.log(`Playing video ${id}`)
405
414
  })
406
415
  .catch(err => {
407
416
  if (videoData.pausedBecuaseHidden) return
408
- if (err.name === 'NotAllowedError' || err.name === 'AbortError' || err.message?.includes('not allowed') && !videoData.pausedBecuaseHidden) {
417
+ if (err.name === 'NotAllowedError' || err.name === 'AbortError' || (err.message?.includes('not allowed') && !videoData.pausedBecuaseHidden)) {
409
418
  videoData.hadAutoPlayError = true
410
419
  }
411
420
  videoData.handleError(err)
@@ -518,14 +527,7 @@ export class ThreeJsMedia {
518
527
  * @param depth Depth of the mesh (default: 1)
519
528
  * @returns The positioned mesh for chaining
520
529
  */
521
- positionMeshExact(
522
- mesh: THREE.Mesh,
523
- rotation: number,
524
- startPosition: { x: number, y: number, z: number },
525
- width: number,
526
- height: number,
527
- depth = 1
528
- ) {
530
+ positionMeshExact(mesh: THREE.Mesh, rotation: number, startPosition: { x: number; y: number; z: number }, width: number, height: number, depth = 1) {
529
531
  // avoid z-fighting with the ground plane
530
532
  if (rotation === 0) {
531
533
  startPosition.z += 0.001
@@ -536,7 +538,7 @@ export class ThreeJsMedia {
536
538
  if (rotation === Math.PI) {
537
539
  startPosition.z -= 0.001
538
540
  }
539
- if (rotation === 3 * Math.PI / 2) {
541
+ if (rotation === (3 * Math.PI) / 2) {
540
542
  startPosition.x += 0.001
541
543
  }
542
544
 
@@ -547,12 +549,11 @@ export class ThreeJsMedia {
547
549
  if (rotation === Math.PI) {
548
550
  startPosition.x += 1
549
551
  }
550
- if (rotation === 3 * Math.PI / 2) {
552
+ if (rotation === (3 * Math.PI) / 2) {
551
553
  startPosition.z += 1
552
554
  startPosition.x += 1
553
555
  }
554
556
 
555
-
556
557
  // First, clean up any previous transformations
557
558
  mesh.matrix.identity()
558
559
  mesh.position.set(0, 0, 0)
@@ -563,7 +564,7 @@ export class ThreeJsMedia {
563
564
  // We need to set up the proper orientation for our use case
564
565
  // Rotate the plane to face the correct direction based on the rotation parameter
565
566
  mesh.rotateY(rotation)
566
- if (rotation === Math.PI / 2 || rotation === 3 * Math.PI / 2) {
567
+ if (rotation === Math.PI / 2 || rotation === (3 * Math.PI) / 2) {
567
568
  mesh.rotateZ(-Math.PI)
568
569
  mesh.rotateX(-Math.PI)
569
570
  }
@@ -585,36 +586,24 @@ export class ThreeJsMedia {
585
586
  debugGroup.add(mesh)
586
587
 
587
588
  // Add a marker at the starting position (should be exactly at pos)
588
- const startMarker = new THREE.Mesh(
589
- new THREE.BoxGeometry(0.1, 0.1, 0.1),
590
- new THREE.MeshBasicMaterial({ color: 0xff_00_00 })
591
- )
589
+ const startMarker = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial({ color: 0xff_00_00 }))
592
590
  startMarker.position.set(startPosition.x, startPosition.y, startPosition.z)
593
591
  debugGroup.add(startMarker)
594
592
 
595
593
  // Add a marker at the end position (width units away in the rotated direction)
596
594
  const endX = startPosition.x + Math.cos(rotation) * width
597
595
  const endZ = startPosition.z + Math.sin(rotation) * width
598
- const endYMarker = new THREE.Mesh(
599
- new THREE.BoxGeometry(0.1, 0.1, 0.1),
600
- new THREE.MeshBasicMaterial({ color: 0x00_00_ff })
601
- )
596
+ const endYMarker = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial({ color: 0x00_00_ff }))
602
597
  endYMarker.position.set(startPosition.x, startPosition.y + height, startPosition.z)
603
598
  debugGroup.add(endYMarker)
604
599
 
605
600
  // Add a marker at the width endpoint
606
- const endWidthMarker = new THREE.Mesh(
607
- new THREE.BoxGeometry(0.1, 0.1, 0.1),
608
- new THREE.MeshBasicMaterial({ color: 0xff_ff_00 })
609
- )
601
+ const endWidthMarker = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial({ color: 0xff_ff_00 }))
610
602
  endWidthMarker.position.set(endX, startPosition.y, endZ)
611
603
  debugGroup.add(endWidthMarker)
612
604
 
613
605
  // Add a marker at the corner diagonal endpoint (both width and height)
614
- const endCornerMarker = new THREE.Mesh(
615
- new THREE.BoxGeometry(0.1, 0.1, 0.1),
616
- new THREE.MeshBasicMaterial({ color: 0xff_00_ff })
617
- )
606
+ const endCornerMarker = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial({ color: 0xff_00_ff }))
618
607
  endCornerMarker.position.set(endX, startPosition.y + height, endZ)
619
608
  debugGroup.add(endCornerMarker)
620
609
 
@@ -624,12 +613,7 @@ export class ThreeJsMedia {
624
613
  this.worldRenderer.sceneOrigin.toSceneY(startPosition.y),
625
614
  this.worldRenderer.sceneOrigin.toSceneZ(startPosition.z)
626
615
  )
627
- const directionHelper = new THREE.ArrowHelper(
628
- new THREE.Vector3(Math.cos(rotation), 0, Math.sin(rotation)),
629
- sceneStartPos,
630
- 1,
631
- 0xff_00_00
632
- )
616
+ const directionHelper = new THREE.ArrowHelper(new THREE.Vector3(Math.cos(rotation), 0, Math.sin(rotation)), sceneStartPos, 1, 0xff_00_00)
633
617
  debugGroup.add(directionHelper)
634
618
 
635
619
  return {
@@ -708,8 +692,7 @@ export class ThreeJsMedia {
708
692
  // Find if this object belongs to any media
709
693
  for (const [id, videoData] of this.customMedia.entries()) {
710
694
  // Check if the intersected object is part of our media mesh
711
- if (intersectedObject === videoData.mesh ||
712
- videoData.mesh.children.includes(intersectedObject)) {
695
+ if (intersectedObject === videoData.mesh || videoData.mesh.children.includes(intersectedObject)) {
713
696
  const { uv } = intersection
714
697
  if (uv) {
715
698
  const result = {
@@ -3,23 +3,23 @@ import * as THREE from 'three'
3
3
  import type { SceneOrigin } from './sceneOrigin'
4
4
 
5
5
  interface ParticleMesh extends THREE.Mesh {
6
- velocity: THREE.Vector3;
7
- worldPos: THREE.Vector3;
6
+ velocity: THREE.Vector3
7
+ worldPos: THREE.Vector3
8
8
  }
9
9
 
10
10
  interface ParticleConfig {
11
- fountainHeight: number;
12
- resetHeight: number;
13
- xVelocityRange: number;
14
- zVelocityRange: number;
15
- particleCount: number;
16
- particleRadiusRange: { min: number; max: number };
17
- yVelocityRange: { min: number; max: number };
11
+ fountainHeight: number
12
+ resetHeight: number
13
+ xVelocityRange: number
14
+ zVelocityRange: number
15
+ particleCount: number
16
+ particleRadiusRange: { min: number; max: number }
17
+ yVelocityRange: { min: number; max: number }
18
18
  }
19
19
 
20
20
  export interface FountainOptions {
21
- position?: { x: number, y: number, z: number }
22
- particleConfig?: Partial<ParticleConfig>;
21
+ position?: { x: number; y: number; z: number }
22
+ particleConfig?: Partial<ParticleConfig>
23
23
  }
24
24
 
25
25
  export class Fountain {
@@ -29,15 +29,17 @@ export class Fountain {
29
29
  private readonly sceneOrigin: SceneOrigin | undefined
30
30
  container: THREE.Object3D | undefined
31
31
 
32
- constructor (public sectionId: string, options: FountainOptions = {}, sceneOrigin?: SceneOrigin) {
32
+ constructor(
33
+ public sectionId: string,
34
+ options: FountainOptions = {},
35
+ sceneOrigin?: SceneOrigin
36
+ ) {
33
37
  this.position = options.position ? new THREE.Vector3(options.position.x, options.position.y, options.position.z) : new THREE.Vector3(0, 0, 0)
34
38
  this.config = this.createConfig(options.particleConfig)
35
39
  this.sceneOrigin = sceneOrigin
36
40
  }
37
41
 
38
- private createConfig (
39
- particleConfigOverride?: Partial<ParticleConfig>
40
- ): { particleConfig: ParticleConfig } {
42
+ private createConfig(particleConfigOverride?: Partial<ParticleConfig>): { particleConfig: ParticleConfig } {
41
43
  const particleConfig: ParticleConfig = {
42
44
  fountainHeight: 10,
43
45
  resetHeight: 0,
@@ -52,27 +54,26 @@ export class Fountain {
52
54
  return { particleConfig }
53
55
  }
54
56
 
55
- private toSceneX (worldX: number): number {
57
+ private toSceneX(worldX: number): number {
56
58
  return this.sceneOrigin ? this.sceneOrigin.toSceneX(worldX) : worldX
57
59
  }
58
60
 
59
- private toSceneY (worldY: number): number {
61
+ private toSceneY(worldY: number): number {
60
62
  return this.sceneOrigin ? this.sceneOrigin.toSceneY(worldY) : worldY
61
63
  }
62
64
 
63
- private toSceneZ (worldZ: number): number {
65
+ private toSceneZ(worldZ: number): number {
64
66
  return this.sceneOrigin ? this.sceneOrigin.toSceneZ(worldZ) : worldZ
65
67
  }
66
68
 
67
-
68
- createParticles (container: THREE.Object3D): void {
69
+ createParticles(container: THREE.Object3D): void {
69
70
  this.container = container
70
71
  const colorStart = new THREE.Color(0xff_ff_00)
71
72
  const colorEnd = new THREE.Color(0xff_a5_00)
72
73
 
73
74
  for (let i = 0; i < this.config.particleConfig.particleCount; i++) {
74
- const radius = Math.random() *
75
- (this.config.particleConfig.particleRadiusRange.max - this.config.particleConfig.particleRadiusRange.min) +
75
+ const radius =
76
+ Math.random() * (this.config.particleConfig.particleRadiusRange.max - this.config.particleConfig.particleRadiusRange.min) +
76
77
  this.config.particleConfig.particleRadiusRange.min
77
78
  const geometry = new THREE.SphereGeometry(radius)
78
79
  const material = new THREE.MeshBasicMaterial({
@@ -103,7 +104,7 @@ export class Fountain {
103
104
  }
104
105
  }
105
106
 
106
- render (): void {
107
+ render(): void {
107
108
  for (const particle of this.particles) {
108
109
  particle.velocity.y -= 0.01 + Math.random() * 0.1
109
110
  particle.worldPos.add(particle.velocity)
@@ -121,15 +122,11 @@ export class Fountain {
121
122
  )
122
123
  }
123
124
 
124
- particle.position.set(
125
- this.toSceneX(particle.worldPos.x),
126
- this.toSceneY(particle.worldPos.y),
127
- this.toSceneZ(particle.worldPos.z)
128
- )
125
+ particle.position.set(this.toSceneX(particle.worldPos.x), this.toSceneY(particle.worldPos.y), this.toSceneZ(particle.worldPos.z))
129
126
  }
130
127
  }
131
128
 
132
- private updateParticleCount (newCount: number): void {
129
+ private updateParticleCount(newCount: number): void {
133
130
  if (newCount !== this.config.particleConfig.particleCount) {
134
131
  this.config.particleConfig.particleCount = newCount
135
132
  const currentCount = this.particles.length
@@ -142,7 +139,7 @@ export class Fountain {
142
139
  }
143
140
  }
144
141
 
145
- private addParticles (count: number): void {
142
+ private addParticles(count: number): void {
146
143
  const geometry = new THREE.SphereGeometry(0.1)
147
144
  const material = new THREE.MeshBasicMaterial({ color: 0x00_ff_00 })
148
145
 
@@ -150,24 +147,18 @@ export class Fountain {
150
147
  const mesh = new THREE.Mesh(geometry, material)
151
148
  const particle = mesh as unknown as ParticleMesh
152
149
  particle.worldPos = this.position.clone()
153
- particle.position.set(
154
- this.toSceneX(this.position.x),
155
- this.toSceneY(this.position.y),
156
- this.toSceneZ(this.position.z)
157
- )
150
+ particle.position.set(this.toSceneX(this.position.x), this.toSceneY(this.position.y), this.toSceneZ(this.position.z))
158
151
  particle.velocity = new THREE.Vector3(
159
- Math.random() * this.config.particleConfig.xVelocityRange -
160
- this.config.particleConfig.xVelocityRange / 2,
152
+ Math.random() * this.config.particleConfig.xVelocityRange - this.config.particleConfig.xVelocityRange / 2,
161
153
  Math.random() * 2,
162
- Math.random() * this.config.particleConfig.zVelocityRange -
163
- this.config.particleConfig.zVelocityRange / 2
154
+ Math.random() * this.config.particleConfig.zVelocityRange - this.config.particleConfig.zVelocityRange / 2
164
155
  )
165
156
  this.particles.push(particle)
166
157
  this.container!.add(particle)
167
158
  }
168
159
  }
169
160
 
170
- private removeParticles (count: number): void {
161
+ private removeParticles(count: number): void {
171
162
  for (let i = 0; i < count; i++) {
172
163
  const particle = this.particles.pop()
173
164
  if (particle) {
@@ -176,7 +167,7 @@ export class Fountain {
176
167
  }
177
168
  }
178
169
 
179
- public dispose (): void {
170
+ public dispose(): void {
180
171
  for (const particle of this.particles) {
181
172
  particle.geometry.dispose()
182
173
  if (Array.isArray(particle.material)) {
@@ -15,7 +15,7 @@ export class ThreeJsSound implements SoundSystem {
15
15
  this.stopAll()
16
16
  })
17
17
 
18
- worldRenderer.onReactiveConfigUpdated('volume', (volume) => {
18
+ worldRenderer.onReactiveConfigUpdated('volume', volume => {
19
19
  this.changeVolume(volume)
20
20
  })
21
21
  }
@@ -26,7 +26,7 @@ export class ThreeJsSound implements SoundSystem {
26
26
  this.worldRenderer.camera.add(this.audioListener)
27
27
  }
28
28
 
29
- playSound(position: { x: number, y: number, z: number }, path: string, volume = 1, pitch = 1, timeout = 500) {
29
+ playSound(position: { x: number; y: number; z: number }, path: string, volume = 1, pitch = 1, timeout = 500) {
30
30
  this.initAudioListener()
31
31
 
32
32
  const sound = new THREE.PositionalAudio(this.audioListener!)
@@ -35,7 +35,7 @@ export class ThreeJsSound implements SoundSystem {
35
35
 
36
36
  const audioLoader = new THREE.AudioLoader()
37
37
  const start = Date.now()
38
- void audioLoader.loadAsync(path).then((buffer) => {
38
+ void audioLoader.loadAsync(path).then(buffer => {
39
39
  if (Date.now() - start > timeout) {
40
40
  console.warn('Ignored playing sound', path, 'due to timeout:', timeout, 'ms <', Date.now() - start, 'ms')
41
41
  return
@@ -70,17 +70,17 @@ export const loadThreeJsTextureFromBitmap = (image: ImageBitmap) => {
70
70
  }
71
71
 
72
72
  /** Worker-safe sync handle; image loads via fetch + OffscreenCanvas (not TextureLoader). */
73
- export function loadNearestFilterTexture (imageUrl: string): THREE.Texture {
73
+ export function loadNearestFilterTexture(imageUrl: string): THREE.Texture {
74
74
  const { texture, promise } = loadThreeJsTextureFromUrlSync(imageUrl)
75
75
  texture.magFilter = THREE.NearestFilter
76
76
  texture.minFilter = THREE.NearestFilter
77
- void promise.catch((err) => {
77
+ void promise.catch(err => {
78
78
  console.error('[texture] failed to load', imageUrl, err)
79
79
  })
80
80
  return texture
81
81
  }
82
82
 
83
- export async function loadTexture (texture: string, cb: (texture: THREE.Texture) => void, onLoad?: () => void): Promise<void> {
83
+ export async function loadTexture(texture: string, cb: (texture: THREE.Texture) => void, onLoad?: () => void): Promise<void> {
84
84
  const cached = textureCache[texture]
85
85
  if (!cached) {
86
86
  const { promise, resolve } = Promise.withResolvers<THREE.Texture>()
@@ -1,7 +1,7 @@
1
1
  //@ts-nocheck
2
2
  import { augmentWorkerMcData } from '../lib/buildWorkerMcDataIndexes'
3
3
 
4
- globalThis.structuredClone ??= (value) => JSON.parse(JSON.stringify(value))
4
+ globalThis.structuredClone ??= value => JSON.parse(JSON.stringify(value))
5
5
 
6
6
  const applyWorkerMcData = (raw: Record<string, unknown>) => {
7
7
  augmentWorkerMcData(raw)
@@ -23,7 +23,7 @@ self.addEventListener('message', (event: MessageEvent) => {
23
23
 
24
24
  if (Array.isArray(data)) {
25
25
  // eslint-disable-next-line unicorn/no-array-for-each
26
- data.forEach((msg) => {
26
+ data.forEach(msg => {
27
27
  if (msg.type === 'mcData') {
28
28
  applyWorkerMcData(msg.mcData)
29
29
  }