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
@@ -6,12 +6,12 @@ test('hand item render key ignores live use state but keeps first-person display
6
6
  const getItemRenderData = vi.fn(() => ({ modelName: 'item/bow' }))
7
7
  const worldRenderer = {
8
8
  playerStateReactive: {
9
- itemUsageTicks: 20,
9
+ itemUsageTicks: 20
10
10
  },
11
11
  resourcesManager: {
12
- currentResources: {},
12
+ currentResources: {}
13
13
  },
14
- getItemRenderData,
14
+ getItemRenderData
15
15
  } as any
16
16
 
17
17
  const handItem = {
@@ -19,8 +19,8 @@ test('hand item render key ignores live use state but keeps first-person display
19
19
  id: 261,
20
20
  name: 'minecraft:bow',
21
21
  fullItem: {
22
- count: 1,
23
- },
22
+ count: 1
23
+ }
24
24
  } as const
25
25
 
26
26
  const activeKey = getHandItemRenderKey(worldRenderer, handItem)
@@ -28,16 +28,24 @@ test('hand item render key ignores live use state but keeps first-person display
28
28
  const idleKey = getHandItemRenderKey(worldRenderer, handItem)
29
29
 
30
30
  expect(activeKey).toBe(idleKey)
31
- expect(getItemRenderData).toHaveBeenNthCalledWith(1, {
32
- ...handItem.fullItem,
33
- itemId: handItem.id,
34
- }, {
35
- 'minecraft:display_context': 'firstperson',
36
- })
37
- expect(getItemRenderData).toHaveBeenNthCalledWith(2, {
38
- ...handItem.fullItem,
39
- itemId: handItem.id,
40
- }, {
41
- 'minecraft:display_context': 'firstperson',
42
- })
31
+ expect(getItemRenderData).toHaveBeenNthCalledWith(
32
+ 1,
33
+ {
34
+ ...handItem.fullItem,
35
+ itemId: handItem.id
36
+ },
37
+ {
38
+ 'minecraft:display_context': 'firstperson'
39
+ }
40
+ )
41
+ expect(getItemRenderData).toHaveBeenNthCalledWith(
42
+ 2,
43
+ {
44
+ ...handItem.fullItem,
45
+ itemId: handItem.id
46
+ },
47
+ {
48
+ 'minecraft:display_context': 'firstperson'
49
+ }
50
+ )
43
51
  })
@@ -5,11 +5,11 @@ import type { WorldRendererThree } from './worldRendererThree'
5
5
  export const getFirstPersonItemSpecificProps = (worldRenderer: WorldRendererThree): ItemSpecificContextProperties => ({
6
6
  'minecraft:display_context': 'firstperson',
7
7
  'minecraft:use_duration': worldRenderer.playerStateReactive.itemUsageTicks,
8
- 'minecraft:using_item': !!worldRenderer.playerStateReactive.itemUsageTicks,
8
+ 'minecraft:using_item': !!worldRenderer.playerStateReactive.itemUsageTicks
9
9
  })
10
10
 
11
11
  const getFirstPersonItemIdentityProps = (): ItemSpecificContextProperties => ({
12
- 'minecraft:display_context': 'firstperson',
12
+ 'minecraft:display_context': 'firstperson'
13
13
  })
14
14
 
15
15
  export const getHandItemRenderKey = (worldRenderer: WorldRendererThree, handItem?: HandItemBlock) => {
@@ -21,10 +21,13 @@ export const getHandItemRenderKey = (worldRenderer: WorldRendererThree, handItem
21
21
  return `${handItem.type}:${itemIdentifier}`
22
22
  }
23
23
 
24
- const renderData = worldRenderer.getItemRenderData({
25
- ...handItem.fullItem,
26
- itemId: handItem.id,
27
- }, getFirstPersonItemIdentityProps())
24
+ const renderData = worldRenderer.getItemRenderData(
25
+ {
26
+ ...handItem.fullItem,
27
+ itemId: handItem.id
28
+ },
29
+ getFirstPersonItemIdentityProps()
30
+ )
28
31
 
29
32
  return `${handItem.type}:${itemIdentifier}:${renderData.modelName}`
30
33
  }
@@ -20,82 +20,36 @@ import { getFirstPersonItemSpecificProps, getHandItemRenderKey } from './holding
20
20
 
21
21
  const rotationPositionData = {
22
22
  itemRight: {
23
- 'rotation': [
24
- 0,
25
- -90,
26
- 25
27
- ],
28
- 'translation': [
29
- 1.13,
30
- 3.2,
31
- 1.13
32
- ],
33
- 'scale': [
34
- 0.68,
35
- 0.68,
36
- 0.68
37
- ]
23
+ rotation: [0, -90, 25],
24
+ translation: [1.13, 3.2, 1.13],
25
+ scale: [0.68, 0.68, 0.68]
38
26
  },
39
27
  itemLeft: {
40
- 'rotation': [
41
- 0,
42
- 90,
43
- -25
44
- ],
45
- 'translation': [
46
- 1.13,
47
- 3.2,
48
- 1.13
49
- ],
50
- 'scale': [
51
- 0.68,
52
- 0.68,
53
- 0.68
54
- ]
28
+ rotation: [0, 90, -25],
29
+ translation: [1.13, 3.2, 1.13],
30
+ scale: [0.68, 0.68, 0.68]
55
31
  },
56
32
  blockRight: {
57
- 'rotation': [
58
- 0,
59
- 45,
60
- 0
61
- ],
62
- 'translation': [
63
- 0,
64
- 0,
65
- 0
66
- ],
67
- 'scale': [
68
- 0.4,
69
- 0.4,
70
- 0.4
71
- ]
33
+ rotation: [0, 45, 0],
34
+ translation: [0, 0, 0],
35
+ scale: [0.4, 0.4, 0.4]
72
36
  },
73
37
  blockLeft: {
74
- 'rotation': [
75
- 0,
76
- 225,
77
- 0
78
- ],
79
- 'translation': [
80
- 0,
81
- 0,
82
- 0
83
- ],
84
- 'scale': [
85
- 0.4,
86
- 0.4,
87
- 0.4
88
- ]
38
+ rotation: [0, 225, 0],
39
+ translation: [0, 0, 0],
40
+ scale: [0.4, 0.4, 0.4]
89
41
  }
90
42
  }
91
43
 
92
44
  export default class HoldingBlockLegacy implements IHoldingBlock {
93
45
  // TODO refactor with the tree builder for better visual understanding
94
46
  holdingBlock: THREE.Object3D | undefined = undefined
95
- blockSwapAnimation: {
96
- switcher: SmoothSwitcher
97
- // hidden: boolean
98
- } | undefined = undefined
47
+ blockSwapAnimation:
48
+ | {
49
+ switcher: SmoothSwitcher
50
+ // hidden: boolean
51
+ }
52
+ | undefined = undefined
99
53
  cameraGroup = new THREE.Mesh()
100
54
  objectOuterGroup = new THREE.Group() // 3
101
55
  objectInnerGroup = new THREE.Group() // 4
@@ -118,51 +72,63 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
118
72
  private disposed = false
119
73
  unsubs: Array<() => void> = []
120
74
 
121
- constructor(public worldRenderer: WorldRendererThree, public offHand = false) {
75
+ constructor(
76
+ public worldRenderer: WorldRendererThree,
77
+ public offHand = false
78
+ ) {
122
79
  this.initCameraGroup()
123
- this.unsubs.push(subscribeKey(this.worldRenderer.playerStateReactive, 'heldItemMain', () => {
124
- if (!this.offHand) {
125
- this.updateItem()
126
- }
127
- }))
128
- this.unsubs.push(subscribeKey(this.worldRenderer.playerStateReactive, 'heldItemOff', () => {
129
- if (this.offHand) {
130
- this.updateItem()
131
- }
132
- }))
80
+ this.unsubs.push(
81
+ subscribeKey(this.worldRenderer.playerStateReactive, 'heldItemMain', () => {
82
+ if (!this.offHand) {
83
+ this.updateItem()
84
+ }
85
+ })
86
+ )
87
+ this.unsubs.push(
88
+ subscribeKey(this.worldRenderer.playerStateReactive, 'heldItemOff', () => {
89
+ if (this.offHand) {
90
+ this.updateItem()
91
+ }
92
+ })
93
+ )
133
94
  this.config = worldRenderer.displayOptions.inWorldRenderingConfig
134
95
 
135
96
  this.offHandDisplay = this.offHand
136
97
  // this.offHandDisplay = true
137
98
  if (!this.offHand) {
138
99
  // load default hand
139
- void getMyHand().then((hand) => {
140
- if (this.disposed) return
141
- this.playerHand = hand
142
- // trigger update
143
- this.updateItem()
144
- }).then(() => {
145
- if (this.disposed) return
146
- // now watch over the player skin
147
- const unsub = watchProperty(
148
- async () => {
149
- return getMyHand(this.worldRenderer.playerStateReactive.playerSkin, this.worldRenderer.playerStateReactive.onlineMode ? this.worldRenderer.playerStateReactive.username : undefined)
150
- },
151
- this.worldRenderer.playerStateReactive,
152
- 'playerSkin',
153
- (newHand) => {
154
- if (newHand) {
155
- this.playerHand = newHand
156
- // trigger update
157
- this.updateItem()
100
+ void getMyHand()
101
+ .then(hand => {
102
+ if (this.disposed) return
103
+ this.playerHand = hand
104
+ // trigger update
105
+ this.updateItem()
106
+ })
107
+ .then(() => {
108
+ if (this.disposed) return
109
+ // now watch over the player skin
110
+ const unsub = watchProperty(
111
+ async () => {
112
+ return getMyHand(
113
+ this.worldRenderer.playerStateReactive.playerSkin,
114
+ this.worldRenderer.playerStateReactive.onlineMode ? this.worldRenderer.playerStateReactive.username : undefined
115
+ )
116
+ },
117
+ this.worldRenderer.playerStateReactive,
118
+ 'playerSkin',
119
+ newHand => {
120
+ if (newHand) {
121
+ this.playerHand = newHand
122
+ // trigger update
123
+ this.updateItem()
124
+ }
125
+ },
126
+ oldHand => {
127
+ disposeObject(oldHand!, true)
158
128
  }
159
- },
160
- (oldHand) => {
161
- disposeObject(oldHand!, true)
162
- }
163
- )
164
- this.unsubs.push(unsub)
165
- })
129
+ )
130
+ this.unsubs.push(unsub)
131
+ })
166
132
  }
167
133
  }
168
134
 
@@ -175,7 +141,7 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
175
141
  void this.setNewItem()
176
142
  } else {
177
143
  void this.setNewItem({
178
- type: 'hand',
144
+ type: 'hand'
179
145
  })
180
146
  }
181
147
  }
@@ -195,7 +161,8 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
195
161
  render(originalCamera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, ambientLight: THREE.AmbientLight, directionalLight: THREE.DirectionalLight) {
196
162
  if (!this.lastHeldItem) return
197
163
  const now = performance.now()
198
- if (this.lastUpdate && now - this.lastUpdate > 50) { // one tick
164
+ if (this.lastUpdate && now - this.lastUpdate > 50) {
165
+ // one tick
199
166
  void this.replaceItemModel(this.lastHeldItem)
200
167
  }
201
168
 
@@ -280,14 +247,14 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
280
247
  // throw new Error(`forceState does not match current state ${forceState} !== ${newState}`)
281
248
  // }
282
249
 
283
- const targetY = this.objectInnerGroup.position.y + (this.objectInnerGroup.scale.y * 1.5 * (newState === 'appeared' ? 1 : -1))
250
+ const targetY = this.objectInnerGroup.position.y + this.objectInnerGroup.scale.y * 1.5 * (newState === 'appeared' ? 1 : -1)
284
251
 
285
252
  // if (newState === this.blockSwapAnimation.switcher.transitioningToStateName) {
286
253
  // return false
287
254
  // }
288
255
 
289
256
  let cancelled = false
290
- return new Promise<boolean>((resolve) => {
257
+ return new Promise<boolean>(resolve => {
291
258
  this.blockSwapAnimation!.switcher.transitionTo(
292
259
  { y: targetY },
293
260
  newState,
@@ -318,16 +285,11 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
318
285
  // const aspect = viewerSize.width / viewerSize.height
319
286
  const aspect = 1
320
287
 
321
-
322
288
  // Adjust the position based on the aspect ratio
323
289
  const { position, scale: scaleData } = this.getHandHeld3d()
324
290
  const distance = -position.z
325
291
  const side = this.offHandModeLegacy ? -1 : 1
326
- this.objectOuterGroup.position.set(
327
- distance * position.x * aspect * side,
328
- distance * position.y,
329
- -distance
330
- )
292
+ this.objectOuterGroup.position.set(distance * position.x * aspect * side, distance * position.y, -distance)
331
293
 
332
294
  // const scale = Math.min(0.8, Math.max(1, 1 * aspect))
333
295
  const scale = scaleData * 2.22 * 0.2
@@ -341,10 +303,15 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
341
303
 
342
304
  let blockInner: THREE.Object3D | undefined
343
305
  if (handItem.type === 'item' || handItem.type === 'block') {
344
- const result = this.worldRenderer.entities.getItemMesh({
345
- ...handItem.fullItem,
346
- itemId: handItem.id,
347
- }, getFirstPersonItemSpecificProps(this.worldRenderer), false, this.lastItemModelName)
306
+ const result = this.worldRenderer.entities.getItemMesh(
307
+ {
308
+ ...handItem.fullItem,
309
+ itemId: handItem.id
310
+ },
311
+ getFirstPersonItemSpecificProps(this.worldRenderer),
312
+ false,
313
+ this.lastItemModelName
314
+ )
348
315
  if (result) {
349
316
  const { mesh: itemMesh, isBlock, modelName } = result
350
317
  if (isBlock) {
@@ -391,8 +358,6 @@ export default class HoldingBlockLegacy implements IHoldingBlock {
391
358
  this.holdingBlock?.removeFromParent()
392
359
  this.holdingBlock = result.model
393
360
  this.holdingBlockInnerGroup.add(result.model)
394
-
395
-
396
361
  }
397
362
 
398
363
  testUnknownBlockSwitch() {
@@ -568,7 +533,10 @@ class HandIdleAnimator {
568
533
 
569
534
  private readonly debugGui: DebugGui
570
535
 
571
- constructor(public handMesh: THREE.Object3D, public playerState: PlayerStateRenderer) {
536
+ constructor(
537
+ public handMesh: THREE.Object3D,
538
+ public playerState: PlayerStateRenderer
539
+ ) {
572
540
  this.handMesh = handMesh
573
541
  this.globalTime = 0
574
542
  this.currentState = 'NOT_MOVING'
@@ -597,12 +565,24 @@ class HandIdleAnimator {
597
565
  },
598
566
  (property, value) => {
599
567
  switch (property) {
600
- case 'x': this.handMesh.position.x = value; break
601
- case 'y': this.handMesh.position.y = value; break
602
- case 'z': this.handMesh.position.z = value; break
603
- case 'rotationX': this.handMesh.rotation.x = value; break
604
- case 'rotationY': this.handMesh.rotation.y = value; break
605
- case 'rotationZ': this.handMesh.rotation.z = value; break
568
+ case 'x':
569
+ this.handMesh.position.x = value
570
+ break
571
+ case 'y':
572
+ this.handMesh.position.y = value
573
+ break
574
+ case 'z':
575
+ this.handMesh.position.z = value
576
+ break
577
+ case 'rotationX':
578
+ this.handMesh.rotation.x = value
579
+ break
580
+ case 'rotationY':
581
+ this.handMesh.rotation.y = value
582
+ break
583
+ case 'rotationZ':
584
+ this.handMesh.rotation.z = value
585
+ break
606
586
  }
607
587
  },
608
588
  {
@@ -628,10 +608,13 @@ class HandIdleAnimator {
628
608
  this.idleOffset.rotationZ = this.handMesh.rotation.z - this.defaultPosition.rotationZ
629
609
 
630
610
  this.idleTween = new tweenJs.Tween(this.idleOffset, this.tween)
631
- .to({
632
- y: 0.05,
633
- rotationZ: 0.05
634
- }, 3000)
611
+ .to(
612
+ {
613
+ y: 0.05,
614
+ rotationZ: 0.05
615
+ },
616
+ 3000
617
+ )
635
618
  .easing(tweenJs.Easing.Sinusoidal.InOut)
636
619
  .yoyo(true)
637
620
  .repeat(Infinity)
@@ -729,8 +712,7 @@ class HandIdleAnimator {
729
712
  }
730
713
 
731
714
  // If we're not transitioning between states and in a stable state that should have idle animation
732
- if (!this.stateSwitcher.isTransitioning &&
733
- (this.currentState === 'NOT_MOVING' || this.currentState === 'SNEAKING')) {
715
+ if (!this.stateSwitcher.isTransitioning && (this.currentState === 'NOT_MOVING' || this.currentState === 'SNEAKING')) {
734
716
  // Start idle animation if not already running
735
717
  if (!this.idleTween?.isPlaying()) {
736
718
  this.startIdleAnimation()
@@ -744,8 +726,7 @@ class HandIdleAnimator {
744
726
  }
745
727
 
746
728
  // If we're in a movement state and not transitioning, update the movement animation
747
- if (!this.stateSwitcher.isTransitioning &&
748
- (this.currentState === 'WALKING' || this.currentState === 'SPRINTING')) {
729
+ if (!this.stateSwitcher.isTransitioning && (this.currentState === 'WALKING' || this.currentState === 'SPRINTING')) {
749
730
  const stateTransform = this.getStateTransform(this.currentState, this.globalTime)
750
731
  Object.assign(this.handMesh.position, stateTransform)
751
732
  Object.assign(this.handMesh.rotation, {
@@ -4,7 +4,7 @@ import * as THREE from 'three'
4
4
  /** Canvas used for item texture extraction (main thread or worker). */
5
5
  export type ItemTextureCanvas = HTMLCanvasElement | OffscreenCanvas
6
6
 
7
- function createItemTextureCanvas (width: number, height: number): ItemTextureCanvas {
7
+ function createItemTextureCanvas(width: number, height: number): ItemTextureCanvas {
8
8
  if (typeof document !== 'undefined') {
9
9
  const canvas = document.createElement('canvas')
10
10
  canvas.width = width
@@ -29,10 +29,7 @@ export interface Create3DItemMeshResult {
29
29
  * Creates a 3D item geometry with front/back faces and connecting edges
30
30
  * from a canvas containing the item texture
31
31
  */
32
- export function create3DItemMesh (
33
- canvas: ItemTextureCanvas,
34
- options: Create3DItemMeshOptions
35
- ): Create3DItemMeshResult {
32
+ export function create3DItemMesh(canvas: ItemTextureCanvas, options: Create3DItemMeshOptions): Create3DItemMeshResult {
36
33
  const { depth, pixelSize } = options
37
34
 
38
35
  // Validate canvas dimensions
@@ -47,7 +44,7 @@ export function create3DItemMesh (
47
44
  const w = canvas.width
48
45
  const h = canvas.height
49
46
  const halfDepth = depth / 2
50
- const actualPixelSize = pixelSize ?? (1 / Math.max(w, h))
47
+ const actualPixelSize = pixelSize ?? 1 / Math.max(w, h)
51
48
 
52
49
  // Find opaque pixels
53
50
  const isOpaque = (x: number, y: number) => {
@@ -256,10 +253,7 @@ export interface ItemMeshResult {
256
253
  /**
257
254
  * Extracts item texture region to a canvas
258
255
  */
259
- export function extractItemTextureToCanvas (
260
- sourceTexture: THREE.Texture<HTMLImageElement | ImageBitmap>,
261
- textureInfo: ItemTextureInfo
262
- ): ItemTextureCanvas {
256
+ export function extractItemTextureToCanvas(sourceTexture: THREE.Texture<HTMLImageElement | ImageBitmap>, textureInfo: ItemTextureInfo): ItemTextureCanvas {
263
257
  const { u, v, sizeX, sizeY } = textureInfo
264
258
 
265
259
  // Calculate canvas size - fix the calculation
@@ -292,7 +286,7 @@ export function extractItemTextureToCanvas (
292
286
  /**
293
287
  * Creates either a 2D or 3D item mesh based on parameters
294
288
  */
295
- export function createItemMesh (
289
+ export function createItemMesh(
296
290
  sourceTexture: THREE.Texture,
297
291
  textureInfo: ItemTextureInfo,
298
292
  options: {
@@ -317,14 +311,14 @@ export function createItemMesh (
317
311
  const spriteMat = new THREE.SpriteMaterial({
318
312
  map: itemsTexture,
319
313
  transparent: true,
320
- alphaTest: 0.1,
314
+ alphaTest: 0.1
321
315
  })
322
316
  const mesh = new THREE.Sprite(spriteMat)
323
317
 
324
318
  return {
325
319
  mesh,
326
320
  itemsTexture,
327
- cleanup () {
321
+ cleanup() {
328
322
  itemsTexture.dispose()
329
323
  }
330
324
  }
@@ -333,10 +327,7 @@ export function createItemMesh (
333
327
  if (use3D) {
334
328
  // Try to create 3D mesh
335
329
  try {
336
- const canvas = extractItemTextureToCanvas(
337
- sourceTexture as THREE.Texture<HTMLImageElement | ImageBitmap>,
338
- textureInfo
339
- )
330
+ const canvas = extractItemTextureToCanvas(sourceTexture as THREE.Texture<HTMLImageElement | ImageBitmap>, textureInfo)
340
331
  const { geometry } = create3DItemMesh(canvas, { depth })
341
332
 
342
333
  // Create texture from canvas for the 3D mesh
@@ -351,7 +342,7 @@ export function createItemMesh (
351
342
  map: itemsTexture,
352
343
  side: THREE.DoubleSide,
353
344
  transparent: true,
354
- alphaTest: 0.1,
345
+ alphaTest: 0.1
355
346
  })
356
347
 
357
348
  const mesh = new THREE.Mesh(geometry, material)
@@ -359,7 +350,7 @@ export function createItemMesh (
359
350
  return {
360
351
  mesh,
361
352
  itemsTexture,
362
- cleanup () {
353
+ cleanup() {
363
354
  itemsTexture.dispose()
364
355
  geometry.dispose()
365
356
  if (material.map) material.map.dispose()
@@ -389,24 +380,27 @@ export function createItemMesh (
389
380
  const material = new THREE.MeshStandardMaterial({
390
381
  map: itemsTexture,
391
382
  transparent: true,
392
- alphaTest: 0.1,
383
+ alphaTest: 0.1
393
384
  })
394
385
  const materialFlipped = new THREE.MeshStandardMaterial({
395
386
  map: itemsTextureFlipped,
396
387
  transparent: true,
397
- alphaTest: 0.1,
388
+ alphaTest: 0.1
398
389
  })
399
390
  const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0), [
400
- new THREE.MeshBasicMaterial({ color: 0x00_00_00 }), new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
401
- new THREE.MeshBasicMaterial({ color: 0x00_00_00 }), new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
402
- material, materialFlipped,
391
+ new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
392
+ new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
393
+ new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
394
+ new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
395
+ material,
396
+ materialFlipped
403
397
  ])
404
398
 
405
399
  return {
406
400
  mesh,
407
401
  itemsTexture,
408
402
  itemsTextureFlipped,
409
- cleanup () {
403
+ cleanup() {
410
404
  itemsTexture.dispose()
411
405
  itemsTextureFlipped.dispose()
412
406
  material.dispose()
@@ -418,10 +412,7 @@ export function createItemMesh (
418
412
  /**
419
413
  * Creates a complete 3D item mesh from a canvas texture
420
414
  */
421
- export function createItemMeshFromCanvas (
422
- canvas: HTMLCanvasElement,
423
- options: Create3DItemMeshOptions
424
- ): THREE.Mesh {
415
+ export function createItemMeshFromCanvas(canvas: HTMLCanvasElement, options: Create3DItemMeshOptions): THREE.Mesh {
425
416
  const { geometry } = create3DItemMesh(canvas, options)
426
417
 
427
418
  // Base color texture for the item
@@ -0,0 +1,93 @@
1
+ //@ts-nocheck
2
+ import { MAX_OPAQUE_SPANS } from './globalLegacyBuffer'
3
+
4
+ export type LegacyMultiDrawTier = 'A' | 'B' | 'C'
5
+
6
+ export type LegacyDrawSpan = { indexStart: number; indexCount: number }
7
+
8
+ export type LegacyMultiDrawCaps = {
9
+ tier: LegacyMultiDrawTier
10
+ ext: MultiDrawElementsExt | null
11
+ }
12
+
13
+ type MultiDrawElementsExt = {
14
+ multiDrawElementsWEBGL: (
15
+ mode: number,
16
+ counts: Int32Array,
17
+ countsOffset: number,
18
+ type: number,
19
+ offsets: Int32Array,
20
+ offsetsOffset: number,
21
+ drawCount: number
22
+ ) => void
23
+ }
24
+
25
+ export type LegacyMultiDrawScratch = {
26
+ counts: Int32Array
27
+ offsets: Int32Array
28
+ }
29
+
30
+ export function createLegacyMultiDrawScratch(): LegacyMultiDrawScratch {
31
+ return {
32
+ counts: new Int32Array(MAX_OPAQUE_SPANS),
33
+ offsets: new Int32Array(MAX_OPAQUE_SPANS)
34
+ }
35
+ }
36
+
37
+ /** Grow scratch arrays when blend (uncapped) span count exceeds opaque cap. */
38
+ function ensureScratchCapacity(scratch: LegacyMultiDrawScratch, minLength: number): void {
39
+ if (scratch.counts.length >= minLength) return
40
+ let newLen = scratch.counts.length
41
+ while (newLen < minLength) newLen *= 2
42
+ scratch.counts = new Int32Array(newLen)
43
+ scratch.offsets = new Int32Array(newLen)
44
+ }
45
+
46
+ export function detectLegacyMultiDrawCaps(gl: WebGL2RenderingContext): LegacyMultiDrawCaps {
47
+ const ext = gl.getExtension('WEBGL_multi_draw')
48
+ if (ext) {
49
+ return { tier: 'A', ext: ext as MultiDrawElementsExt }
50
+ }
51
+ return { tier: 'B', ext: null }
52
+ }
53
+
54
+ let tierLogged = false
55
+
56
+ export function logLegacyMultiDrawTierOnce(tier: LegacyMultiDrawTier, debug: boolean): void {
57
+ if (tierLogged || !debug) return
58
+ tierLogged = true
59
+ console.info('[globalLegacyBuffer] legacy multi_draw tier', tier)
60
+ }
61
+
62
+ /**
63
+ * Issue indexed legacy draws for visible spans. Tier B/C loop drawElements.
64
+ */
65
+ export function drawLegacySpans(
66
+ gl: WebGL2RenderingContext,
67
+ caps: LegacyMultiDrawCaps,
68
+ spans: readonly LegacyDrawSpan[],
69
+ scratch: LegacyMultiDrawScratch
70
+ ): void {
71
+ const drawCount = spans.length
72
+ if (drawCount === 0) return
73
+
74
+ ensureScratchCapacity(scratch, drawCount)
75
+
76
+ const mode = gl.TRIANGLES
77
+ const type = gl.UNSIGNED_INT
78
+
79
+ for (let i = 0; i < drawCount; i++) {
80
+ const span = spans[i]!
81
+ scratch.counts[i] = span.indexCount
82
+ scratch.offsets[i] = span.indexStart * 4
83
+ }
84
+
85
+ if (caps.tier === 'A' && caps.ext) {
86
+ caps.ext.multiDrawElementsWEBGL(mode, scratch.counts, 0, type, scratch.offsets, 0, drawCount)
87
+ return
88
+ }
89
+
90
+ for (let i = 0; i < drawCount; i++) {
91
+ gl.drawElements(mode, scratch.counts[i]!, type, scratch.offsets[i]!)
92
+ }
93
+ }