minecraft-renderer 0.1.79 → 0.1.81

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 (205) hide show
  1. package/README.md +66 -26
  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 +66 -66
  6. package/dist/minecraft-renderer.js.meta.json +1 -1
  7. package/dist/threeWorker.js +450 -450
  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 +349 -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/cameraCollisionBlockCache.ts +156 -0
  113. package/src/three/cameraCollisionSolidity.ts +50 -0
  114. package/src/three/cameraShake.ts +15 -6
  115. package/src/three/chunkMeshManager.ts +223 -390
  116. package/src/three/cinimaticScript.ts +26 -15
  117. package/src/three/cubeDrawSpans.ts +27 -37
  118. package/src/three/cubeMultiDraw.ts +9 -22
  119. package/src/three/documentRenderer.ts +15 -18
  120. package/src/three/entities.ts +175 -150
  121. package/src/three/entity/EntityMesh.ts +114 -108
  122. package/src/three/entity/animations.js +3 -3
  123. package/src/three/entity/armorModels.ts +15 -15
  124. package/src/three/entity/gltfAnimationUtils.ts +2 -5
  125. package/src/three/fireworks.ts +34 -32
  126. package/src/three/fireworksRenderer.ts +32 -29
  127. package/src/three/globalBlockBuffer.ts +167 -100
  128. package/src/three/globalLegacyBuffer.ts +248 -264
  129. package/src/three/graphicsBackendBase.ts +19 -25
  130. package/src/three/graphicsBackendOffThread.ts +12 -15
  131. package/src/three/hand.ts +21 -21
  132. package/src/three/handLegacy.ts +3 -13
  133. package/src/three/holdingBlock.ts +116 -79
  134. package/src/three/holdingBlockFactory.ts +1 -4
  135. package/src/three/holdingBlockItemIdentity.test.ts +25 -17
  136. package/src/three/holdingBlockItemIdentity.ts +9 -6
  137. package/src/three/holdingBlockLegacy.ts +113 -132
  138. package/src/three/itemMesh.ts +20 -29
  139. package/src/three/legacyMultiDraw.ts +10 -16
  140. package/src/three/legacySectionCull.ts +8 -14
  141. package/src/three/menuBackground/activeView.ts +1 -4
  142. package/src/three/menuBackground/assetUrl.ts +1 -1
  143. package/src/three/menuBackground/classic.ts +4 -12
  144. package/src/three/menuBackground/gpuPreference.ts +1 -3
  145. package/src/three/menuBackground/index.ts +2 -11
  146. package/src/three/menuBackground/renderer.ts +1 -5
  147. package/src/three/menuBackground/types.ts +1 -4
  148. package/src/three/menuBackground/v2.ts +196 -96
  149. package/src/three/menuBackground/v2Meta.ts +3 -3
  150. package/src/three/menuBackground/worldBlocks.ts +37 -35
  151. package/src/three/modules/blockBreakParticles.ts +59 -28
  152. package/src/three/modules/cameraBobbing.ts +3 -6
  153. package/src/three/modules/index.ts +1 -1
  154. package/src/three/modules/rain.ts +10 -23
  155. package/src/three/modules/sciFiWorldReveal.ts +11 -25
  156. package/src/three/modules/starfield.ts +7 -13
  157. package/src/three/renderSlot.ts +28 -16
  158. package/src/three/rendererModuleSystem.ts +1 -3
  159. package/src/three/sceneOrigin.ts +96 -33
  160. package/src/three/sectionRaycastAabb.ts +24 -110
  161. package/src/three/shaderCubeMesh.ts +6 -17
  162. package/src/three/shaders/cubeBlockShader.ts +85 -96
  163. package/src/three/shaders/legacyBlockShader.ts +21 -43
  164. package/src/three/shaders/textureIndexMapping.ts +89 -95
  165. package/src/three/shaders/tintPalette.ts +156 -170
  166. package/src/three/signTextureCache.ts +9 -12
  167. package/src/three/skyboxRenderer.ts +62 -70
  168. package/src/three/tests/chunkMeshManagerLegacy.test.ts +34 -64
  169. package/src/three/tests/cubeDrawSpans.test.ts +55 -25
  170. package/src/three/tests/globalBlockBuffer.test.ts +217 -0
  171. package/src/three/tests/globalLegacyBuffer.test.ts +300 -41
  172. package/src/three/tests/legacyMultiDraw.test.ts +8 -29
  173. package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
  174. package/src/three/tests/signTextureCache.test.ts +4 -4
  175. package/src/three/thirdPersonVoxelRaycast.ts +120 -0
  176. package/src/three/threeJsMedia.ts +55 -72
  177. package/src/three/threeJsParticles.ts +32 -41
  178. package/src/three/threeJsSound.ts +3 -3
  179. package/src/three/threeJsUtils.ts +3 -3
  180. package/src/three/threeWorker.ts +2 -2
  181. package/src/three/waypointSprite.ts +55 -82
  182. package/src/three/waypoints.ts +20 -23
  183. package/src/three/world/cursorBlock.ts +25 -12
  184. package/src/three/world/vr.ts +11 -17
  185. package/src/three/worldGeometryExport.ts +15 -34
  186. package/src/three/worldRendererThree.ts +144 -166
  187. package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
  188. package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
  189. package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
  190. package/src/wasm-mesher/tests/cameraCollisionBlockCache.test.ts +82 -0
  191. package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
  192. package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
  193. package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
  194. package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +1 -93
  195. package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
  196. package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
  197. package/src/wasm-mesher/tests/thirdPersonVoxelRaycast.test.ts +63 -0
  198. package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
  199. package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
  200. package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
  201. package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
  202. package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
  203. package/src/worldView/worldView.spiral.test.ts +1 -1
  204. package/src/worldView/worldView.ts +34 -39
  205. package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
@@ -33,6 +33,7 @@ import { FireworksManager } from './fireworks'
33
33
  import { SceneOrigin } from './sceneOrigin'
34
34
  import { downloadWorldGeometry } from './worldGeometryExport'
35
35
  import { ChunkMeshManager } from './chunkMeshManager'
36
+ import { raycastVoxelSolid } from './thirdPersonVoxelRaycast'
36
37
  import type { RendererModuleManifest, RegisteredModule, RendererModuleController } from './rendererModuleSystem'
37
38
  import { BUILTIN_MODULES } from './modules/index'
38
39
  import { formatPerformanceFactorsDebug, PerformanceMonitor } from '../performanceMonitor'
@@ -46,8 +47,7 @@ export class WorldRendererThree extends WorldRendererCommon {
46
47
  private static readonly LEGACY_TO_PHYSICAL_LIGHT = Math.PI
47
48
 
48
49
  protected override isShaderCubeBlocksEnabled(): boolean {
49
- return this.worldRendererConfig.shaderCubeBlocks === true
50
- && !!this.renderer?.capabilities?.isWebGL2
50
+ return this.worldRendererConfig.shaderCubeBlocks === true && !!this.renderer?.capabilities?.isWebGL2
51
51
  }
52
52
  chunkMeshManager: ChunkMeshManager
53
53
  get sectionObjects() {
@@ -92,7 +92,7 @@ export class WorldRendererThree extends WorldRendererCommon {
92
92
  */
93
93
  camera!: THREE.PerspectiveCamera
94
94
  renderTimeAvg = 0
95
- private pendingSectionUpdates = new Map<string, { geometry: MesherGeometryOutput, key: string, type: string }>()
95
+ private pendingSectionUpdates = new Map<string, { geometry: MesherGeometryOutput; key: string; type: string }>()
96
96
  /**
97
97
  * Per-section buffering timestamps for `applyPendingSectionUpdates`.
98
98
  * Each section gets its own deadline so a continuous stream of updates
@@ -110,19 +110,19 @@ export class WorldRendererThree extends WorldRendererCommon {
110
110
  private modules = {} as Record<string, RegisteredModule>
111
111
  sectionsOffsetsAnimations = {} as {
112
112
  [chunkKey: string]: {
113
- time: number,
113
+ time: number
114
114
  // also specifies direction
115
- speedX: number,
116
- speedY: number,
117
- speedZ: number,
115
+ speedX: number
116
+ speedY: number
117
+ speedZ: number
118
118
 
119
- currentOffsetX: number,
120
- currentOffsetY: number,
121
- currentOffsetZ: number,
119
+ currentOffsetX: number
120
+ currentOffsetY: number
121
+ currentOffsetZ: number
122
122
 
123
- limitX?: number,
124
- limitY?: number,
125
- limitZ?: number,
123
+ limitX?: number
124
+ limitY?: number
125
+ limitZ?: number
126
126
  }
127
127
  }
128
128
  fountains: Fountain[] = []
@@ -139,8 +139,8 @@ export class WorldRendererThree extends WorldRendererCommon {
139
139
 
140
140
  private readonly _tmpCameraPos = new THREE.Vector3()
141
141
 
142
- private currentPosTween?: tweenJs.Tween<{ x: number, y: number, z: number }>
143
- private currentRotTween?: tweenJs.Tween<{ pitch: number, yaw: number }>
142
+ private currentPosTween?: tweenJs.Tween<{ x: number; y: number; z: number }>
143
+ private currentRotTween?: tweenJs.Tween<{ pitch: number; yaw: number }>
144
144
 
145
145
  // Pre-allocated objects for getThirdPersonCamera (avoid per-frame allocs)
146
146
  private readonly _tpDirection = new THREE.Vector3()
@@ -150,7 +150,6 @@ export class WorldRendererThree extends WorldRendererCommon {
150
150
  private readonly _tpScenePos = new THREE.Vector3()
151
151
  private readonly _tpAxisX = new THREE.Vector3(1, 0, 0)
152
152
  private readonly _tpAxisY = new THREE.Vector3(0, 1, 0)
153
- private readonly _tpRaycaster = new THREE.Raycaster()
154
153
  private readonly _tpChunkWorldPos = new THREE.Vector3()
155
154
 
156
155
  get tilesRendered() {
@@ -161,7 +160,11 @@ export class WorldRendererThree extends WorldRendererCommon {
161
160
  return this.chunkMeshManager.getTotalBlocks()
162
161
  }
163
162
 
164
- constructor(public renderer: THREE.WebGLRenderer, public initOptions: GraphicsInitOptions, public displayOptions: DisplayWorldOptions) {
163
+ constructor(
164
+ public renderer: THREE.WebGLRenderer,
165
+ public initOptions: GraphicsInitOptions,
166
+ public displayOptions: DisplayWorldOptions
167
+ ) {
165
168
  if (!displayOptions.resourcesManager) throw new Error('resourcesManager is required in displayOptions')
166
169
  super(displayOptions.resourcesManager, displayOptions, initOptions)
167
170
 
@@ -173,13 +176,13 @@ export class WorldRendererThree extends WorldRendererCommon {
173
176
 
174
177
  // Initialize chunk mesh manager
175
178
  this.chunkMeshManager = new ChunkMeshManager(this, this.scene, this.material, this.worldSizeParams.worldHeight, this.viewDistance)
176
- this.onRenderDistanceChanged = (viewDistance) => {
179
+ this.onRenderDistanceChanged = viewDistance => {
177
180
  this.chunkMeshManager.updateViewDistance(viewDistance)
178
181
  }
179
182
 
180
183
  // Final lightmap values TBD — compare against https://v99.mcraft.fun/
181
184
  if (typeof window !== 'undefined') {
182
- (window as any).setBlockLightmap = (params: { curve?: number, minBrightness?: number, gamma?: number }) => {
185
+ ;(window as any).setBlockLightmap = (params: { curve?: number; minBrightness?: number; gamma?: number }) => {
183
186
  this.chunkMeshManager.setBlockLightmapParams(params)
184
187
  }
185
188
  }
@@ -211,7 +214,7 @@ export class WorldRendererThree extends WorldRendererCommon {
211
214
  this.cinimaticScript = new CinimaticScriptRunner(
212
215
  this,
213
216
  (pos, yaw, pitch) => this.setCinimaticCamera(pos, yaw, pitch),
214
- (fov) => this.setCinimaticFov(fov),
217
+ fov => this.setCinimaticFov(fov),
215
218
  () => ({
216
219
  position: new Vec3(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z),
217
220
  yaw: this.cameraShake.getBaseRotation().yaw,
@@ -249,7 +252,7 @@ export class WorldRendererThree extends WorldRendererCommon {
249
252
  manifest,
250
253
  controller,
251
254
  enabled: false,
252
- toggle: () => this.toggleModule(manifest.id),
255
+ toggle: () => this.toggleModule(manifest.id)
253
256
  }
254
257
 
255
258
  this.modules[manifest.id] = registered
@@ -259,7 +262,6 @@ export class WorldRendererThree extends WorldRendererCommon {
259
262
  }
260
263
  }
261
264
 
262
-
263
265
  /**
264
266
  * Enable a module
265
267
  */
@@ -406,7 +408,7 @@ export class WorldRendererThree extends WorldRendererCommon {
406
408
  self._cameraPositionAccessWarned = true
407
409
  console.warn(
408
410
  '[WorldRendererThree] Do not set camera.position to world coordinates — it is scene-local. ' +
409
- 'Use cameraWorldPos and sceneOrigin.update() to move the camera.'
411
+ 'Use cameraWorldPos and sceneOrigin.update() to move the camera.'
410
412
  )
411
413
  }
412
414
  }
@@ -415,7 +417,7 @@ export class WorldRendererThree extends WorldRendererCommon {
415
417
  if ((prop === 'x' || prop === 'y' || prop === 'z') && typeof value === 'number' && Math.abs(value) > WORLD_COORD_THRESHOLD) {
416
418
  warnOnce()
417
419
  }
418
- ; (target as any)[prop] = value
420
+ ;(target as any)[prop] = value
419
421
  return true
420
422
  },
421
423
  get(target, prop, receiver) {
@@ -462,7 +464,12 @@ export class WorldRendererThree extends WorldRendererCommon {
462
464
  }
463
465
 
464
466
  downloadWorldGeometry() {
465
- downloadWorldGeometry(this, new THREE.Vector3(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z), this.cameraShake.getBaseRotation(), 'world-geometry.json')
467
+ downloadWorldGeometry(
468
+ this,
469
+ new THREE.Vector3(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z),
470
+ this.cameraShake.getBaseRotation(),
471
+ 'world-geometry.json'
472
+ )
466
473
  }
467
474
 
468
475
  updateEntity(e, isPosUpdate = false) {
@@ -509,27 +516,27 @@ export class WorldRendererThree extends WorldRendererCommon {
509
516
 
510
517
  override watchReactivePlayerState() {
511
518
  super.watchReactivePlayerState()
512
- this.onReactivePlayerStateUpdated('inWater', (value) => {
519
+ this.onReactivePlayerStateUpdated('inWater', value => {
513
520
  this.skyboxRenderer.updateWaterState(value, this.playerStateReactive.waterBreathing)
514
521
  })
515
- this.onReactivePlayerStateUpdated('waterBreathing', (value) => {
522
+ this.onReactivePlayerStateUpdated('waterBreathing', value => {
516
523
  this.skyboxRenderer.updateWaterState(this.playerStateReactive.inWater, value)
517
524
  })
518
- this.onReactivePlayerStateUpdated('ambientLight', (value) => {
525
+ this.onReactivePlayerStateUpdated('ambientLight', value => {
519
526
  if (!value) return
520
527
  this.ambientLight.intensity = value * WorldRendererThree.LEGACY_TO_PHYSICAL_LIGHT
521
528
  })
522
- this.onReactivePlayerStateUpdated('directionalLight', (value) => {
529
+ this.onReactivePlayerStateUpdated('directionalLight', value => {
523
530
  if (!value) return
524
531
  this.directionalLight.intensity = value * WorldRendererThree.LEGACY_TO_PHYSICAL_LIGHT
525
532
  })
526
- this.onReactivePlayerStateUpdated('lookingAtBlock', (value) => {
533
+ this.onReactivePlayerStateUpdated('lookingAtBlock', value => {
527
534
  this.cursorBlock.setHighlightCursorBlock(value ? new Vec3(value.x, value.y, value.z) : null, value?.shapes)
528
535
  })
529
- this.onReactivePlayerStateUpdated('diggingBlock', (value) => {
536
+ this.onReactivePlayerStateUpdated('diggingBlock', value => {
530
537
  this.cursorBlock.updateBreakAnimation(value ? { x: value.x, y: value.y, z: value.z } : undefined, value?.stage ?? null, value?.mergedShape)
531
538
  })
532
- this.onReactivePlayerStateUpdated('perspective', (value) => {
539
+ this.onReactivePlayerStateUpdated('perspective', value => {
533
540
  // Update camera perspective when it changes
534
541
  const vecPos = new Vec3(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z)
535
542
  this.updateCamera(vecPos, this.cameraShake.getBaseRotation().yaw, this.cameraShake.getBaseRotation().pitch)
@@ -539,10 +546,10 @@ export class WorldRendererThree extends WorldRendererCommon {
539
546
 
540
547
  override watchReactiveConfig() {
541
548
  super.watchReactiveConfig()
542
- this.onReactiveConfigUpdated('showChunkBorders', (value) => {
549
+ this.onReactiveConfigUpdated('showChunkBorders', value => {
543
550
  this.updateShowChunksBorder(value)
544
551
  })
545
- this.onReactiveConfigUpdated('defaultSkybox', (value) => {
552
+ this.onReactiveConfigUpdated('defaultSkybox', value => {
546
553
  this.skyboxRenderer.updateDefaultSkybox(value)
547
554
  })
548
555
  this.onReactiveConfigUpdated('shaderCubeDebugMode', () => {
@@ -560,7 +567,7 @@ export class WorldRendererThree extends WorldRendererCommon {
560
567
  })
561
568
 
562
569
  let currentHandRenderer = this.displayOptions.inWorldRenderingConfig.handRenderer
563
- this.onReactiveConfigUpdated('handRenderer', (value) => {
570
+ this.onReactiveConfigUpdated('handRenderer', value => {
564
571
  if (value === currentHandRenderer) return
565
572
  currentHandRenderer = value
566
573
  const wasReady = this.holdingBlock.ready
@@ -742,9 +749,12 @@ export class WorldRendererThree extends WorldRendererCommon {
742
749
  demoItem() {
743
750
  //@ts-expect-error
744
751
  const pos = cursorBlockRel(0, 1, 0).position
745
- const { mesh } = this.entities.getItemMesh({
746
- itemId: 541,
747
- }, {})!
752
+ const { mesh } = this.entities.getItemMesh(
753
+ {
754
+ itemId: 541
755
+ },
756
+ {}
757
+ )!
748
758
  mesh.position.set(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5)
749
759
  // mesh.scale.set(0.5, 0.5, 0.5)
750
760
  const helper = new THREE.BoxHelper(mesh, 0xff_ff_00)
@@ -778,6 +788,10 @@ export class WorldRendererThree extends WorldRendererCommon {
778
788
  text += `LEG-B: ${formatCompact(s.used)}/${formatCompact(s.capacity)}q `
779
789
  }
780
790
  text += `MEM: ${this.chunkMeshManager.getEstimatedMemoryUsage().total} `
791
+ const camCollisionBytes = this.cameraCollisionBlockCache.getAllocatedBytes()
792
+ if (camCollisionBytes > 0) {
793
+ text += `CAM: ${formatCompact(camCollisionBytes)}b `
794
+ }
781
795
  const pf = formatPerformanceFactorsDebug(this.reactiveState.world.instabilityFactors)
782
796
  if (pf) text += `PF: ${pf} `
783
797
  // entities can be seen in F3
@@ -800,9 +814,7 @@ export class WorldRendererThree extends WorldRendererCommon {
800
814
  const renderOrder = 500 - chunkDistance
801
815
 
802
816
  // Cubes in globalBlockBuffer may leave sectionObj.mesh unset.
803
- const drawable = sectionObj.mesh
804
- ?? sectionObj.shaderMesh
805
- ?? sectionObj.children.find(child => child.name === 'mesh' || child.name === 'shaderMesh')
817
+ const drawable = sectionObj.mesh ?? sectionObj.shaderMesh ?? sectionObj.children.find(child => child.name === 'mesh' || child.name === 'shaderMesh')
806
818
  if (drawable) {
807
819
  drawable.renderOrder = renderOrder
808
820
  }
@@ -847,17 +859,16 @@ export class WorldRendererThree extends WorldRendererCommon {
847
859
  // the just-updated section and a stale neighbor (sky-flicker bug).
848
860
  const [sx, sy, sz] = key.split(',').map(Number)
849
861
  const neighborKeys = [
850
- `${sx - 16},${sy},${sz}`, `${sx + 16},${sy},${sz}`,
851
- `${sx},${sy - sectionHeight},${sz}`, `${sx},${sy + sectionHeight},${sz}`,
852
- `${sx},${sy},${sz - 16}`, `${sx},${sy},${sz + 16}`,
862
+ `${sx - 16},${sy},${sz}`,
863
+ `${sx + 16},${sy},${sz}`,
864
+ `${sx},${sy - sectionHeight},${sz}`,
865
+ `${sx},${sy + sectionHeight},${sz}`,
866
+ `${sx},${sy},${sz - 16}`,
867
+ `${sx},${sy},${sz + 16}`
853
868
  ]
854
869
  let neighborBusy = false
855
870
  for (const neighborKey of neighborKeys) {
856
- if (
857
- this.sectionsWaiting.has(neighborKey) &&
858
- !this.pendingSectionUpdates.has(neighborKey) &&
859
- this.sectionObjects[neighborKey]
860
- ) {
871
+ if (this.sectionsWaiting.has(neighborKey) && !this.pendingSectionUpdates.has(neighborKey) && this.sectionObjects[neighborKey]) {
861
872
  neighborBusy = true
862
873
  break
863
874
  }
@@ -891,8 +902,9 @@ export class WorldRendererThree extends WorldRendererCommon {
891
902
  const sectionObject = this.chunkMeshManager.updateSection(update.key, update.geometry)
892
903
  this.updatePosDataChunk(update.key)
893
904
  if (sectionObject) {
894
- this.getModule<{ onSectionMeshed?: (key: string, geometry: MesherGeometryOutput, section: typeof sectionObject) => void }>('futuristicReveal')
895
- ?.onSectionMeshed?.(update.key, update.geometry, sectionObject)
905
+ this.getModule<{ onSectionMeshed?: (key: string, geometry: MesherGeometryOutput, section: typeof sectionObject) => void }>(
906
+ 'futuristicReveal'
907
+ )?.onSectionMeshed?.(update.key, update.geometry, sectionObject)
896
908
  }
897
909
  }
898
910
  }
@@ -906,7 +918,7 @@ export class WorldRendererThree extends WorldRendererCommon {
906
918
  }
907
919
  }
908
920
 
909
- handleWorkerMessage(data: { geometry: MesherGeometryOutput, key, type }): void {
921
+ handleWorkerMessage(data: { geometry: MesherGeometryOutput; key; type }): void {
910
922
  if (data.type === 'geometry') {
911
923
  const chunkCoords = data.key.split(',')
912
924
  const chunkKey = `${chunkCoords[0]},${chunkCoords[2]}`
@@ -933,24 +945,20 @@ export class WorldRendererThree extends WorldRendererCommon {
933
945
  const sectionObject = this.chunkMeshManager.updateSection(data.key, data.geometry)
934
946
  this.updatePosDataChunk(data.key)
935
947
  if (sectionObject) {
936
- this.getModule<{ onSectionMeshed?: (key: string, geometry: MesherGeometryOutput, section: typeof sectionObject) => void }>('futuristicReveal')
937
- ?.onSectionMeshed?.(data.key, data.geometry, sectionObject)
948
+ this.getModule<{ onSectionMeshed?: (key: string, geometry: MesherGeometryOutput, section: typeof sectionObject) => void }>(
949
+ 'futuristicReveal'
950
+ )?.onSectionMeshed?.(data.key, data.geometry, sectionObject)
938
951
  }
939
952
  }
940
953
  }
941
954
 
942
-
943
955
  getCameraPosition(target?: THREE.Vector3): THREE.Vector3 {
944
956
  return (target ?? this._tmpCameraPos).set(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z)
945
957
  }
946
958
 
947
959
  getSectionCameraPosition() {
948
960
  const pos = this.getCameraPosition()
949
- return new Vec3(
950
- Math.floor(pos.x / 16),
951
- Math.floor(pos.y / 16),
952
- Math.floor(pos.z / 16)
953
- )
961
+ return new Vec3(Math.floor(pos.x / 16), Math.floor(pos.y / 16), Math.floor(pos.z / 16))
954
962
  }
955
963
 
956
964
  updateCameraSectionPos() {
@@ -1002,63 +1010,36 @@ export class WorldRendererThree extends WorldRendererCommon {
1002
1010
  this.debugRaycast(pos, direction, distance)
1003
1011
  }
1004
1012
 
1005
- const raycaster = this._tpRaycaster
1006
- raycaster.set(pos, direction)
1007
- raycaster.far = distance
1008
-
1009
- const maxCenterDistance = 80
1010
- const maxCenterDistSq = maxCenterDistance * maxCenterDistance
1011
- const ox = pos.x
1012
- const oy = pos.y
1013
- const oz = pos.z
1014
-
1015
- // Legacy section meshes: world-space raycast (static mesh.matrix translation).
1016
- const legacyMeshes: THREE.Object3D[] = []
1017
- for (const obj of Object.values(this.sectionObjects)) {
1018
- if (obj.name !== 'chunk' || !obj.visible) continue
1019
- if (obj.worldX === undefined) continue
1020
- const dcx = obj.worldX - ox
1021
- const dcy = obj.worldY! - oy
1022
- const dcz = obj.worldZ! - oz
1023
- if (dcx * dcx + dcy * dcy + dcz * dcz > maxCenterDistSq) continue
1024
- const mesh = obj.children.find(child => child.name === 'mesh')
1025
- if (mesh) legacyMeshes.push(mesh)
1026
- }
1027
-
1028
- const intersects = raycaster.intersectObjects(legacyMeshes, false)
1013
+ /** Swept-sphere radius for third-person camera collision (baked into voxel AABB expansion). */
1014
+ const CAMERA_COLLISION_RADIUS = 0.25
1015
+ /** Hard floor only guards zero/negative; never clamp up past a hit distance. */
1016
+ const MIN_CAMERA_DISTANCE = 0.05
1017
+ /** Eye→camera minimum so the lens stays outside the player head when a wall squeeze would pull closer. */
1018
+ const MIN_THIRD_PERSON_BODY_CLEARANCE = 0.4
1019
+
1020
+ const blockCache = this.cameraCollisionBlockCache
1021
+ const voxelHit = raycastVoxelSolid(
1022
+ pos.x,
1023
+ pos.y,
1024
+ pos.z,
1025
+ direction.x,
1026
+ direction.y,
1027
+ direction.z,
1028
+ distance,
1029
+ CAMERA_COLLISION_RADIUS,
1030
+ MIN_CAMERA_DISTANCE,
1031
+ (bx, by, bz) => blockCache.isSolidBlock(bx, by, bz)
1032
+ )
1029
1033
 
1030
1034
  let finalDistance = distance
1031
- if (intersects.length > 0) {
1032
- finalDistance = Math.max(0.5, intersects[0].distance - 0.2)
1035
+ if (voxelHit !== undefined) {
1036
+ finalDistance = Math.min(finalDistance, voxelHit.distance)
1033
1037
  }
1034
-
1035
- // Shader cubes in global buffer: tight per-section AABBs (no mesh raycast).
1036
- const boxHit = this.chunkMeshManager.raycastShaderSectionAABBs(
1037
- pos,
1038
- direction,
1039
- finalDistance,
1040
- maxCenterDistance,
1041
- )
1042
- if (boxHit !== undefined) {
1043
- finalDistance = Math.max(0.5, boxHit - 0.2)
1038
+ if (finalDistance < MIN_THIRD_PERSON_BODY_CLEARANCE) {
1039
+ finalDistance = MIN_THIRD_PERSON_BODY_CLEARANCE
1044
1040
  }
1045
1041
 
1046
- const legacyGlobalHit = this.chunkMeshManager.raycastGlobalLegacySections(
1047
- raycaster,
1048
- pos,
1049
- maxCenterDistance,
1050
- )
1051
- if (legacyGlobalHit !== undefined) {
1052
- finalDistance = Math.max(0.5, legacyGlobalHit - 0.2)
1053
- }
1054
-
1055
- const finalPos = new Vec3(
1056
- pos.x + direction.x * finalDistance,
1057
- pos.y + direction.y * finalDistance,
1058
- pos.z + direction.z * finalDistance
1059
- )
1060
-
1061
- return finalPos
1042
+ return new Vec3(pos.x + direction.x * finalDistance, pos.y + direction.y * finalDistance, pos.z + direction.z * finalDistance)
1062
1043
  }
1063
1044
 
1064
1045
  private debugRaycastHelper?: THREE.ArrowHelper
@@ -1076,11 +1057,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1076
1057
  }
1077
1058
 
1078
1059
  // Convert world position to scene-relative coordinates
1079
- const scenePos = new THREE.Vector3(
1080
- this.sceneOrigin.toSceneX(pos.x),
1081
- this.sceneOrigin.toSceneY(pos.y),
1082
- this.sceneOrigin.toSceneZ(pos.z)
1083
- )
1060
+ const scenePos = new THREE.Vector3(this.sceneOrigin.toSceneX(pos.x), this.sceneOrigin.toSceneY(pos.y), this.sceneOrigin.toSceneZ(pos.z))
1084
1061
 
1085
1062
  // Create raycast arrow
1086
1063
  this.debugRaycastHelper = new THREE.ArrowHelper(
@@ -1170,9 +1147,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1170
1147
 
1171
1148
  this.currentPosTween?.stop()
1172
1149
  // Use instant camera updates (0 delay) in playground mode when camera controls are enabled
1173
- const tweenDelay = this.displayOptions.inWorldRenderingConfig.instantCameraUpdate
1174
- ? 0
1175
- : (this.playerStateUtils.isSpectatingEntity() ? 150 : 50)
1150
+ const tweenDelay = this.displayOptions.inWorldRenderingConfig.instantCameraUpdate ? 0 : this.playerStateUtils.isSpectatingEntity() ? 150 : 50
1176
1151
  this.currentPosTween = new tweenJs.Tween(this.cameraWorldPos)
1177
1152
  .to({ x: pos.x, y: pos.y, z: pos.z }, tweenDelay)
1178
1153
  .onUpdate(() => {
@@ -1194,8 +1169,10 @@ export class WorldRendererThree extends WorldRendererCommon {
1194
1169
  yawOffset = Math.PI * 2
1195
1170
  }
1196
1171
  this.currentRotTween?.stop()
1197
- this.currentRotTween = new tweenJs.Tween(rotation).to({ pitch, yaw: yaw + yawOffset }, 100)
1198
- .onUpdate(params => this.cameraShake.setBaseRotation(params.pitch, params.yaw - yawOffset)).start()
1172
+ this.currentRotTween = new tweenJs.Tween(rotation)
1173
+ .to({ pitch, yaw: yaw + yawOffset }, 100)
1174
+ .onUpdate(params => this.cameraShake.setBaseRotation(params.pitch, params.yaw - yawOffset))
1175
+ .start()
1199
1176
  } else {
1200
1177
  this.currentRotTween?.stop()
1201
1178
  this.cameraShake.setBaseRotation(pitch, yaw)
@@ -1204,11 +1181,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1204
1181
  if (perspective === 'third_person_back' || perspective === 'third_person_front') {
1205
1182
  // Use getThirdPersonCamera for proper raycasting with max distance of 4
1206
1183
  const currentWorldPos = new THREE.Vector3(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z)
1207
- const thirdPersonPos = this.getThirdPersonCamera(
1208
- currentWorldPos,
1209
- yaw,
1210
- pitch
1211
- )
1184
+ const thirdPersonPos = this.getThirdPersonCamera(currentWorldPos, yaw, pitch)
1212
1185
 
1213
1186
  const distance = currentWorldPos.distanceTo(new THREE.Vector3(thirdPersonPos.x, thirdPersonPos.y, thirdPersonPos.z))
1214
1187
  // Apply Z offset based on perspective and calculated distance
@@ -1242,14 +1215,20 @@ export class WorldRendererThree extends WorldRendererCommon {
1242
1215
  }
1243
1216
 
1244
1217
  debugChunksVisibilityOverride() {
1245
- const { chunksRenderAboveOverride, chunksRenderBelowOverride, chunksRenderDistanceOverride, chunksRenderAboveEnabled, chunksRenderBelowEnabled, chunksRenderDistanceEnabled } = this.reactiveDebugParams
1218
+ const {
1219
+ chunksRenderAboveOverride,
1220
+ chunksRenderBelowOverride,
1221
+ chunksRenderDistanceOverride,
1222
+ chunksRenderAboveEnabled,
1223
+ chunksRenderBelowEnabled,
1224
+ chunksRenderDistanceEnabled
1225
+ } = this.reactiveDebugParams
1246
1226
 
1247
1227
  const sectionHeight = this.getSectionHeight()
1248
1228
  const baseY = this.cameraSectionPos.y * sectionHeight
1249
1229
 
1250
1230
  if (
1251
- this.displayOptions.inWorldRenderingConfig.enableDebugOverlay &&
1252
- chunksRenderAboveOverride !== undefined ||
1231
+ (this.displayOptions.inWorldRenderingConfig.enableDebugOverlay && chunksRenderAboveOverride !== undefined) ||
1253
1232
  chunksRenderBelowOverride !== undefined ||
1254
1233
  chunksRenderDistanceOverride !== undefined
1255
1234
  ) {
@@ -1258,11 +1237,19 @@ export class WorldRendererThree extends WorldRendererCommon {
1258
1237
  const [x, y, z] = key.split(',').map(Number)
1259
1238
  const isVisible =
1260
1239
  // eslint-disable-next-line no-constant-binary-expression, sonarjs/no-redundant-boolean
1261
- (chunksRenderAboveEnabled && chunksRenderAboveOverride !== undefined) ? y <= (baseY + chunksRenderAboveOverride) : true &&
1262
- // eslint-disable-next-line @stylistic/indent-binary-ops, no-constant-binary-expression, sonarjs/no-redundant-boolean
1263
- (chunksRenderBelowEnabled && chunksRenderBelowOverride !== undefined) ? y >= (baseY - chunksRenderBelowOverride) : true &&
1264
- // eslint-disable-next-line @stylistic/indent-binary-ops
1265
- (chunksRenderDistanceEnabled && chunksRenderDistanceOverride !== undefined) ? Math.abs(y - baseY) <= chunksRenderDistanceOverride : true
1240
+ chunksRenderAboveEnabled && chunksRenderAboveOverride !== undefined
1241
+ ? y <= baseY + chunksRenderAboveOverride
1242
+ : true &&
1243
+ // eslint-disable-next-line @stylistic/indent-binary-ops, no-constant-binary-expression, sonarjs/no-redundant-boolean
1244
+ chunksRenderBelowEnabled &&
1245
+ chunksRenderBelowOverride !== undefined
1246
+ ? y >= baseY - chunksRenderBelowOverride
1247
+ : true &&
1248
+ // eslint-disable-next-line @stylistic/indent-binary-ops
1249
+ chunksRenderDistanceEnabled &&
1250
+ chunksRenderDistanceOverride !== undefined
1251
+ ? Math.abs(y - baseY) <= chunksRenderDistanceOverride
1252
+ : true
1266
1253
 
1267
1254
  object.visible = isVisible
1268
1255
  }
@@ -1281,9 +1268,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1281
1268
  this.debugChunksVisibilityOverride()
1282
1269
  const start = performance.now()
1283
1270
  this.lastRendered = performance.now()
1284
- const deltaTime = this.lastRenderTime > 0
1285
- ? Math.min(Math.max((start - this.lastRenderTime) / 1000, 0), 0.1)
1286
- : 1 / 60
1271
+ const deltaTime = this.lastRenderTime > 0 ? Math.min(Math.max((start - this.lastRenderTime) / 1000, 0), 0.1) : 1 / 60
1287
1272
  this.lastRenderTime = start
1288
1273
  this.cursorBlock.render()
1289
1274
  this.updateSectionOffsets()
@@ -1307,7 +1292,10 @@ export class WorldRendererThree extends WorldRendererCommon {
1307
1292
  }
1308
1293
 
1309
1294
  // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
1310
- const cam = this.cameraGroupVr instanceof THREE.Group ? this.cameraGroupVr.children.find(child => child instanceof THREE.PerspectiveCamera) as THREE.PerspectiveCamera : this.camera
1295
+ const cam =
1296
+ this.cameraGroupVr instanceof THREE.Group
1297
+ ? (this.cameraGroupVr.children.find(child => child instanceof THREE.PerspectiveCamera) as THREE.PerspectiveCamera)
1298
+ : this.camera
1311
1299
  // Flush buffered section geometry before reveal tick (calls onSectionMeshed synchronously in handleWorkerMessage).
1312
1300
  this.applyPendingSectionUpdates()
1313
1301
  const sciFiNow = performance.now()
@@ -1347,15 +1335,11 @@ export class WorldRendererThree extends WorldRendererCommon {
1347
1335
  }
1348
1336
  globalLegacyBlendBuffer.suppressThreeDraw()
1349
1337
  }
1338
+ this.chunkMeshManager.markCullDirtyIfBufferStateChanged()
1350
1339
  this.chunkMeshManager.setLegacyCameraOrigin(camX, camY, camZ)
1351
1340
  this.chunkMeshManager.updateCullDirtyFromCamera(cam, camX, camY, camZ)
1352
1341
  if (this.chunkMeshManager.cullDirty) {
1353
- this.chunkMeshManager.updateSectionCullAndSort(
1354
- cam,
1355
- this.cameraWorldPos.x,
1356
- this.cameraWorldPos.y,
1357
- this.cameraWorldPos.z,
1358
- )
1342
+ this.chunkMeshManager.updateSectionCullAndSort(cam, this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z)
1359
1343
  this.chunkMeshManager.clearCullDirty()
1360
1344
  }
1361
1345
  this.renderer.render(this.scene, cam)
@@ -1391,14 +1375,14 @@ export class WorldRendererThree extends WorldRendererCommon {
1391
1375
  this.chunkMeshManager.recordRenderTime(totalTime)
1392
1376
  }
1393
1377
  this.renderTimeAvgCount++
1394
- this.renderTimeAvg = ((this.renderTimeAvg * (this.renderTimeAvgCount - 1)) + totalTime) / this.renderTimeAvgCount
1378
+ this.renderTimeAvg = (this.renderTimeAvg * (this.renderTimeAvgCount - 1) + totalTime) / this.renderTimeAvgCount
1395
1379
  this.renderTimeMax = Math.max(this.renderTimeMax, totalTime)
1396
1380
 
1397
1381
  this.performanceMonitor.onFrame({
1398
1382
  totalMs: totalTime,
1399
1383
  entitiesMs: entitiesRenderMs,
1400
1384
  loadedTextureCount: this.renderer.info.memory.textures,
1401
- fps: this.lastFps,
1385
+ fps: this.lastFps
1402
1386
  })
1403
1387
  }
1404
1388
 
@@ -1416,8 +1400,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1416
1400
  let skinUrl = decodedData.textures?.SKIN?.url
1417
1401
  const { skinTexturesProxy } = this.worldRendererConfig
1418
1402
  if (skinTexturesProxy) {
1419
- skinUrl = skinUrl?.replace('http://textures.minecraft.net/', skinTexturesProxy)
1420
- .replace('https://textures.minecraft.net/', skinTexturesProxy)
1403
+ skinUrl = skinUrl?.replace('http://textures.minecraft.net/', skinTexturesProxy).replace('https://textures.minecraft.net/', skinTexturesProxy)
1421
1404
  }
1422
1405
 
1423
1406
  const mesh = getMesh(this, skinUrl, armorModel.head as any)
@@ -1430,11 +1413,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1430
1413
  group.add(mesh)
1431
1414
  this.sceneOrigin.track(group)
1432
1415
  group.position.set(position.x + 0.5, position.y + 0.045, position.z + 0.5)
1433
- group.rotation.set(
1434
- 0,
1435
- -THREE.MathUtils.degToRad(rotation * (isWall ? 90 : 45 / 2)),
1436
- 0
1437
- )
1416
+ group.rotation.set(0, -THREE.MathUtils.degToRad(rotation * (isWall ? 90 : 45 / 2)), 0)
1438
1417
  group.scale.set(0.8, 0.8, 0.8)
1439
1418
  return group
1440
1419
  } catch (err) {
@@ -1449,7 +1428,8 @@ export class WorldRendererThree extends WorldRendererCommon {
1449
1428
  }
1450
1429
  }
1451
1430
 
1452
- rerenderAllChunks() { // todo not clear what to do with loading chunks
1431
+ rerenderAllChunks() {
1432
+ // todo not clear what to do with loading chunks
1453
1433
  for (const key of Object.keys(this.sectionObjects)) {
1454
1434
  const [x, y, z] = key.split(',').map(Number)
1455
1435
  this.setSectionDirty(new Vec3(x, y, z))
@@ -1483,12 +1463,14 @@ export class WorldRendererThree extends WorldRendererCommon {
1483
1463
 
1484
1464
  getLoadedChunksRelative(pos: Vec3, includeY = false) {
1485
1465
  const [currentX, currentY, currentZ] = sectionPos(pos)
1486
- return Object.fromEntries(Object.entries(this.sectionObjects).map(([key, o]) => {
1487
- const [xRaw, yRaw, zRaw] = key.split(',').map(Number)
1488
- const [x, y, z] = sectionPos({ x: xRaw, y: yRaw, z: zRaw })
1489
- const setKey = includeY ? `${x - currentX},${y - currentY},${z - currentZ}` : `${x - currentX},${z - currentZ}`
1490
- return [setKey, o]
1491
- }))
1466
+ return Object.fromEntries(
1467
+ Object.entries(this.sectionObjects).map(([key, o]) => {
1468
+ const [xRaw, yRaw, zRaw] = key.split(',').map(Number)
1469
+ const [x, y, z] = sectionPos({ x: xRaw, y: yRaw, z: zRaw })
1470
+ const setKey = includeY ? `${x - currentX},${y - currentY},${z - currentZ}` : `${x - currentX},${z - currentZ}`
1471
+ return [setKey, o]
1472
+ })
1473
+ )
1492
1474
  }
1493
1475
 
1494
1476
  readdChunks() {
@@ -1633,11 +1615,7 @@ export class WorldRendererThree extends WorldRendererCommon {
1633
1615
  // Apply the offset to the section object (compose with camera-relative base position)
1634
1616
  const section = this.sectionObjects[key]
1635
1617
  if (section) {
1636
- section.position.set(
1637
- anim.currentOffsetX,
1638
- anim.currentOffsetY,
1639
- anim.currentOffsetZ
1640
- )
1618
+ section.position.set(anim.currentOffsetX, anim.currentOffsetY, anim.currentOffsetZ)
1641
1619
  section.updateMatrix()
1642
1620
  }
1643
1621
  }
@@ -14,7 +14,7 @@ type BlockMeta = {
14
14
 
15
15
  const metaCache = new Map<string, BlockMeta>()
16
16
 
17
- const blockToIds = (block: { minStateId: number, maxStateId: number }) => {
17
+ const blockToIds = (block: { minStateId: number; maxStateId: number }) => {
18
18
  const ids: number[] = []
19
19
  for (let i = block.minStateId; i <= block.maxStateId; i++) {
20
20
  ids.push(i)
@@ -169,13 +169,7 @@ export function convertChunkToWasm(
169
169
  }
170
170
  }
171
171
 
172
- const {
173
- invisibleBlocks,
174
- transparentBlocks,
175
- noAoBlocks,
176
- cullIdenticalBlocks,
177
- occludingBlocks
178
- } = getBlockMeta(version)
172
+ const { invisibleBlocks, transparentBlocks, noAoBlocks, cullIdenticalBlocks, occludingBlocks } = getBlockMeta(version)
179
173
 
180
174
  return {
181
175
  blockStates,
@@ -187,6 +181,6 @@ export function convertChunkToWasm(
187
181
  noAoBlocks,
188
182
  cullIdenticalBlocks,
189
183
  occludingBlocks,
190
- blockCount,
184
+ blockCount
191
185
  }
192
186
  }