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
@@ -3,196 +3,182 @@ import * as THREE from 'three'
3
3
 
4
4
  // ---- Palette entry ----
5
5
  export interface TintPaletteEntry {
6
- r: number // 0-1
7
- g: number
8
- b: number
6
+ r: number // 0-1
7
+ g: number
8
+ b: number
9
9
  }
10
10
 
11
11
  // ---- Palette manager ----
12
12
  export class TintPalette {
13
- private entries: TintPaletteEntry[] = [{ r: 1, g: 1, b: 1 }] // index 0 = white (no tint)
14
- private colorToIndex: Map<number, number> = new Map() // packed color -> index
15
- private categoryBiomeToIndex: Map<string, number> = new Map()
16
- private texture: THREE.DataTexture | null = null
17
- private ready = false
18
-
19
- /** Pack [r,g,b] (0-1 floats) into a 24-bit integer for fast lookup */
20
- private packColor(r: number, g: number, b: number): number {
21
- const ri = Math.round(r * 255)
22
- const gi = Math.round(g * 255)
23
- const bi = Math.round(b * 255)
24
- return (ri << 16) | (gi << 8) | bi
13
+ private entries: TintPaletteEntry[] = [{ r: 1, g: 1, b: 1 }] // index 0 = white (no tint)
14
+ private colorToIndex: Map<number, number> = new Map() // packed color -> index
15
+ private categoryBiomeToIndex: Map<string, number> = new Map()
16
+ private texture: THREE.DataTexture | null = null
17
+ private ready = false
18
+
19
+ /** Pack [r,g,b] (0-1 floats) into a 24-bit integer for fast lookup */
20
+ private packColor(r: number, g: number, b: number): number {
21
+ const ri = Math.round(r * 255)
22
+ const gi = Math.round(g * 255)
23
+ const bi = Math.round(b * 255)
24
+ return (ri << 16) | (gi << 8) | bi
25
+ }
26
+
27
+ /** Add a tint entry, returns its palette index (reuses duplicates) */
28
+ add(r: number, g: number, b: number, category: string, key: string): number {
29
+ const packed = this.packColor(r, g, b)
30
+
31
+ // Try categorical lookup first (faster and preserves semantic grouping)
32
+ const catKey = `${category}:${key}`
33
+ const existing = this.categoryBiomeToIndex.get(catKey)
34
+ if (existing !== undefined) return existing
35
+
36
+ // Deduplicate by exact color
37
+ const colorIdx = this.colorToIndex.get(packed)
38
+ if (colorIdx !== undefined) {
39
+ this.categoryBiomeToIndex.set(catKey, colorIdx)
40
+ return colorIdx
25
41
  }
26
42
 
27
- /** Add a tint entry, returns its palette index (reuses duplicates) */
28
- add(r: number, g: number, b: number, category: string, key: string): number {
29
- const packed = this.packColor(r, g, b)
30
-
31
- // Try categorical lookup first (faster and preserves semantic grouping)
32
- const catKey = `${category}:${key}`
33
- const existing = this.categoryBiomeToIndex.get(catKey)
34
- if (existing !== undefined) return existing
35
-
36
- // Deduplicate by exact color
37
- const colorIdx = this.colorToIndex.get(packed)
38
- if (colorIdx !== undefined) {
39
- this.categoryBiomeToIndex.set(catKey, colorIdx)
40
- return colorIdx
41
- }
42
-
43
- const idx = this.entries.length
44
- this.entries.push({ r, g, b })
45
- this.colorToIndex.set(packed, idx)
46
- this.categoryBiomeToIndex.set(catKey, idx)
47
- return idx
43
+ const idx = this.entries.length
44
+ this.entries.push({ r, g, b })
45
+ this.colorToIndex.set(packed, idx)
46
+ this.categoryBiomeToIndex.set(catKey, idx)
47
+ return idx
48
+ }
49
+
50
+ /** Look up tint index for a specific block face */
51
+ getTintIndex(faceTintIndex: number | undefined, blockName: string, blockProps: Record<string, any>, biome: string): number {
52
+ if (faceTintIndex === undefined) return 0 // white
53
+
54
+ if (faceTintIndex === 0) {
55
+ if (blockName === 'redstone_wire') {
56
+ return this.categoryBiomeToIndex.get(`redstone:${blockProps.power}`) ?? this.categoryBiomeToIndex.get('redstone:0') ?? 0
57
+ }
58
+ if (blockName === 'birch_leaves' || blockName === 'spruce_leaves' || blockName === 'lily_pad') {
59
+ return this.categoryBiomeToIndex.get(`constant:${blockName}`) ?? this.categoryBiomeToIndex.get('constant:default') ?? 0
60
+ }
61
+ if (blockName.includes('leaves') || blockName === 'vine') {
62
+ return this.categoryBiomeToIndex.get(`foliage:${biome}`) ?? this.categoryBiomeToIndex.get('foliage:plains') ?? 0
63
+ }
64
+ // Default: grass tint
65
+ return this.categoryBiomeToIndex.get(`grass:${biome}`) ?? this.categoryBiomeToIndex.get('grass:plains') ?? 0
48
66
  }
49
67
 
50
- /** Look up tint index for a specific block face */
51
- getTintIndex(
52
- faceTintIndex: number | undefined,
53
- blockName: string,
54
- blockProps: Record<string, any>,
55
- biome: string,
56
- ): number {
57
- if (faceTintIndex === undefined) return 0 // white
58
-
59
- if (faceTintIndex === 0) {
60
- if (blockName === 'redstone_wire') {
61
- return this.categoryBiomeToIndex.get(`redstone:${blockProps.power}`)
62
- ?? this.categoryBiomeToIndex.get('redstone:0')
63
- ?? 0
64
- }
65
- if (blockName === 'birch_leaves' || blockName === 'spruce_leaves' || blockName === 'lily_pad') {
66
- return this.categoryBiomeToIndex.get(`constant:${blockName}`)
67
- ?? this.categoryBiomeToIndex.get('constant:default')
68
- ?? 0
69
- }
70
- if (blockName.includes('leaves') || blockName === 'vine') {
71
- return this.categoryBiomeToIndex.get(`foliage:${biome}`) ?? this.categoryBiomeToIndex.get('foliage:plains') ?? 0
72
- }
73
- // Default: grass tint
74
- return this.categoryBiomeToIndex.get(`grass:${biome}`) ?? this.categoryBiomeToIndex.get('grass:plains') ?? 0
75
- }
76
-
77
- return 0 // unknown tint index -> white
68
+ return 0 // unknown tint index -> white
69
+ }
70
+
71
+ /** Get the palette entry at a given index */
72
+ getEntry(index: number): TintPaletteEntry {
73
+ return this.entries[index] ?? this.entries[0]
74
+ }
75
+
76
+ /** Total number of palette entries */
77
+ get size(): number {
78
+ return this.entries.length
79
+ }
80
+
81
+ /** Build RGBA Float32Array from palette entries (for DataTexture) */
82
+ private buildTextureData(): Float32Array {
83
+ // RGBA × 256 entries
84
+ const data = new Float32Array(256 * 4)
85
+ for (let i = 0; i < this.entries.length && i < 256; i++) {
86
+ const e = this.entries[i]
87
+ data[i * 4] = e.r
88
+ data[i * 4 + 1] = e.g
89
+ data[i * 4 + 2] = e.b
90
+ data[i * 4 + 3] = 1.0
78
91
  }
79
-
80
- /** Get the palette entry at a given index */
81
- getEntry(index: number): TintPaletteEntry {
82
- return this.entries[index] ?? this.entries[0]
92
+ return data
93
+ }
94
+
95
+ /** Create or update the Three.js DataTexture */
96
+ createTexture(): THREE.DataTexture {
97
+ if (this.texture) {
98
+ this.texture.dispose()
99
+ this.texture = null
100
+ this.ready = false
83
101
  }
84
-
85
- /** Total number of palette entries */
86
- get size(): number {
87
- return this.entries.length
102
+ const data = this.buildTextureData()
103
+ const texture = new THREE.DataTexture(data as any, 256, 1, THREE.RGBAFormat, THREE.FloatType) as THREE.DataTexture
104
+ texture.minFilter = THREE.NearestFilter
105
+ texture.magFilter = THREE.NearestFilter
106
+ texture.wrapS = THREE.ClampToEdgeWrapping
107
+ texture.wrapT = THREE.ClampToEdgeWrapping
108
+ texture.needsUpdate = true
109
+ this.texture = texture
110
+ this.ready = true
111
+ return texture
112
+ }
113
+
114
+ getTexture(): THREE.DataTexture | null {
115
+ return this.texture
116
+ }
117
+
118
+ isReady(): boolean {
119
+ return this.ready
120
+ }
121
+
122
+ /** Precompute the full palette using tints data */
123
+ static fromTintsData(tintsData: Record<string, any>): TintPalette {
124
+ const palette = new TintPalette()
125
+ // Offsets to avoid collision with categorical keys — already handled by packColor dedup
126
+
127
+ function tintToGl(tint: number): [number, number, number] {
128
+ const r = ((tint >> 16) & 0xff) / 255
129
+ const g = ((tint >> 8) & 0xff) / 255
130
+ const b = (tint & 0xff) / 255
131
+ return [r, g, b]
88
132
  }
89
133
 
90
- /** Build RGBA Float32Array from palette entries (for DataTexture) */
91
- private buildTextureData(): Float32Array {
92
- // RGBA × 256 entries
93
- const data = new Float32Array(256 * 4)
94
- for (let i = 0; i < this.entries.length && i < 256; i++) {
95
- const e = this.entries[i]
96
- data[i * 4] = e.r
97
- data[i * 4 + 1] = e.g
98
- data[i * 4 + 2] = e.b
99
- data[i * 4 + 3] = 1.0
134
+ // --- grass tint (per biome) ---
135
+ if (tintsData.grass) {
136
+ const grassDefault = tintToGl(tintsData.grass.default)
137
+ for (const { keys, color } of tintsData.grass.data ?? []) {
138
+ const c = tintToGl(color as number)
139
+ for (const biome of keys as string[]) {
140
+ palette.add(c[0], c[1], c[2], 'grass', biome)
100
141
  }
101
- return data
142
+ }
143
+ palette.add(grassDefault[0], grassDefault[1], grassDefault[2], 'grass', 'plains')
102
144
  }
103
145
 
104
- /** Create or update the Three.js DataTexture */
105
- createTexture(): THREE.DataTexture {
106
- if (this.texture) {
107
- this.texture.dispose()
108
- this.texture = null
109
- this.ready = false
146
+ // --- foliage tint (per biome) ---
147
+ if (tintsData.foliage) {
148
+ const foliageDefault = tintToGl(tintsData.foliage.default)
149
+ for (const { keys, color } of tintsData.foliage.data ?? []) {
150
+ const c = tintToGl(color as number)
151
+ for (const biome of keys as string[]) {
152
+ palette.add(c[0], c[1], c[2], 'foliage', biome)
110
153
  }
111
- const data = this.buildTextureData()
112
- const texture = new THREE.DataTexture(
113
- data as any,
114
- 256, 1,
115
- THREE.RGBAFormat,
116
- THREE.FloatType,
117
- ) as THREE.DataTexture
118
- texture.minFilter = THREE.NearestFilter
119
- texture.magFilter = THREE.NearestFilter
120
- texture.wrapS = THREE.ClampToEdgeWrapping
121
- texture.wrapT = THREE.ClampToEdgeWrapping
122
- texture.needsUpdate = true
123
- this.texture = texture
124
- this.ready = true
125
- return texture
126
- }
127
-
128
- getTexture(): THREE.DataTexture | null {
129
- return this.texture
130
- }
131
-
132
- isReady(): boolean {
133
- return this.ready
154
+ }
155
+ palette.add(foliageDefault[0], foliageDefault[1], foliageDefault[2], 'foliage', 'plains')
134
156
  }
135
157
 
136
- /** Precompute the full palette using tints data */
137
- static fromTintsData(tintsData: Record<string, any>): TintPalette {
138
- const palette = new TintPalette()
139
- // Offsets to avoid collision with categorical keys already handled by packColor dedup
140
-
141
- function tintToGl(tint: number): [number, number, number] {
142
- const r = ((tint >> 16) & 0xff) / 255
143
- const g = ((tint >> 8) & 0xff) / 255
144
- const b = (tint & 0xff) / 255
145
- return [r, g, b]
146
- }
147
-
148
- // --- grass tint (per biome) ---
149
- if (tintsData.grass) {
150
- const grassDefault = tintToGl(tintsData.grass.default)
151
- for (const { keys, color } of tintsData.grass.data ?? []) {
152
- const c = tintToGl(color as number)
153
- for (const biome of keys as string[]) {
154
- palette.add(c[0], c[1], c[2], 'grass', biome)
155
- }
156
- }
157
- palette.add(grassDefault[0], grassDefault[1], grassDefault[2], 'grass', 'plains')
158
- }
159
-
160
- // --- foliage tint (per biome) ---
161
- if (tintsData.foliage) {
162
- const foliageDefault = tintToGl(tintsData.foliage.default)
163
- for (const { keys, color } of tintsData.foliage.data ?? []) {
164
- const c = tintToGl(color as number)
165
- for (const biome of keys as string[]) {
166
- palette.add(c[0], c[1], c[2], 'foliage', biome)
167
- }
168
- }
169
- palette.add(foliageDefault[0], foliageDefault[1], foliageDefault[2], 'foliage', 'plains')
170
- }
171
-
172
- // --- redstone tint (per power level 0-15) ---
173
- if (tintsData.redstone) {
174
- const rsDefault = tintToGl(tintsData.redstone.default)
175
- for (const { keys, color } of tintsData.redstone.data ?? []) {
176
- const c = tintToGl(color as number)
177
- for (const key of keys as string[]) {
178
- palette.add(c[0], c[1], c[2], 'redstone', key)
179
- }
180
- }
181
- palette.add(rsDefault[0], rsDefault[1], rsDefault[2], 'redstone', '0')
158
+ // --- redstone tint (per power level 0-15) ---
159
+ if (tintsData.redstone) {
160
+ const rsDefault = tintToGl(tintsData.redstone.default)
161
+ for (const { keys, color } of tintsData.redstone.data ?? []) {
162
+ const c = tintToGl(color as number)
163
+ for (const key of keys as string[]) {
164
+ palette.add(c[0], c[1], c[2], 'redstone', key)
182
165
  }
166
+ }
167
+ palette.add(rsDefault[0], rsDefault[1], rsDefault[2], 'redstone', '0')
168
+ }
183
169
 
184
- // --- constant tints (birch leaves, spruce leaves, lily pad) ---
185
- if (tintsData.constant) {
186
- const constDefault = tintToGl(tintsData.constant.default)
187
- for (const { keys, color } of tintsData.constant.data ?? []) {
188
- const c = tintToGl(color as number)
189
- for (const key of keys as string[]) {
190
- palette.add(c[0], c[1], c[2], 'constant', key)
191
- }
192
- }
193
- palette.add(constDefault[0], constDefault[1], constDefault[2], 'constant', 'default')
170
+ // --- constant tints (birch leaves, spruce leaves, lily pad) ---
171
+ if (tintsData.constant) {
172
+ const constDefault = tintToGl(tintsData.constant.default)
173
+ for (const { keys, color } of tintsData.constant.data ?? []) {
174
+ const c = tintToGl(color as number)
175
+ for (const key of keys as string[]) {
176
+ palette.add(c[0], c[1], c[2], 'constant', key)
194
177
  }
195
-
196
- return palette
178
+ }
179
+ palette.add(constDefault[0], constDefault[1], constDefault[2], 'constant', 'default')
197
180
  }
181
+
182
+ return palette
183
+ }
198
184
  }
@@ -4,17 +4,19 @@ import PrismarineChatLoader from 'prismarine-chat'
4
4
  import { renderSign } from '../sign-renderer'
5
5
  import type { WorldRendererThree } from './worldRendererThree'
6
6
 
7
- const signTextureCache = new Map<string, { texture: THREE.Texture, refCount: number }>()
7
+ const signTextureCache = new Map<string, { texture: THREE.Texture; refCount: number }>()
8
8
 
9
9
  // Build the key ONLY from fields that change rendered pixels, so two signs
10
10
  // with identical visible text share a texture even if other NBT differs.
11
- function createSignCacheKey (blockEntity: any, isHanging: boolean, backSide: boolean): string {
11
+ function createSignCacheKey(blockEntity: any, isHanging: boolean, backSide: boolean): string {
12
12
  let lines: string[]
13
13
  let color: string
14
- if (blockEntity && 'front_text' in blockEntity) { // 1.20+
14
+ if (blockEntity && 'front_text' in blockEntity) {
15
+ // 1.20+
15
16
  lines = blockEntity.front_text?.messages ?? []
16
17
  color = blockEntity.front_text?.color || 'black'
17
- } else { // legacy
18
+ } else {
19
+ // legacy
18
20
  lines = [blockEntity?.Text1, blockEntity?.Text2, blockEntity?.Text3, blockEntity?.Text4]
19
21
  color = blockEntity?.Color || 'black'
20
22
  }
@@ -22,12 +24,7 @@ function createSignCacheKey (blockEntity: any, isHanging: boolean, backSide: boo
22
24
  return `${isHanging ? 1 : 0}|${backSide ? 1 : 0}|${color}|${lines.join('\0')}`
23
25
  }
24
26
 
25
- export function getSignTexture (
26
- worldRenderer: WorldRendererThree,
27
- blockEntity: any,
28
- isHanging: boolean,
29
- backSide = false
30
- ): THREE.Texture | undefined {
27
+ export function getSignTexture(worldRenderer: WorldRendererThree, blockEntity: any, isHanging: boolean, backSide = false): THREE.Texture | undefined {
31
28
  const cacheKey = createSignCacheKey(blockEntity, isHanging, backSide)
32
29
  const cached = signTextureCache.get(cacheKey)
33
30
  if (cached) {
@@ -45,7 +42,7 @@ export function getSignTexture (
45
42
  return tex
46
43
  }
47
44
 
48
- export function releaseSignTexture (texture: THREE.Texture): void {
45
+ export function releaseSignTexture(texture: THREE.Texture): void {
49
46
  for (const [key, cached] of signTextureCache.entries()) {
50
47
  if (cached.texture === texture) {
51
48
  cached.refCount--
@@ -58,7 +55,7 @@ export function releaseSignTexture (texture: THREE.Texture): void {
58
55
  }
59
56
  }
60
57
 
61
- export function disposeAllSignTextures (): void {
58
+ export function disposeAllSignTextures(): void {
62
59
  for (const [, cached] of signTextureCache) cached.texture.dispose()
63
60
  signTextureCache.clear()
64
61
  }