minecraft-renderer 0.1.79 → 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 +27 -27
  6. package/dist/minecraft-renderer.js.meta.json +1 -1
  7. package/dist/threeWorker.js +133 -133
  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 +239 -282
  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 +167 -100
  126. package/src/three/globalLegacyBuffer.ts +257 -166
  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 +10 -16
  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 +34 -34
  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 +300 -41
  170. package/src/three/tests/legacyMultiDraw.test.ts +8 -29
  171. package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
  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 +117 -129
  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
@@ -12,7 +12,7 @@ export type BlockLightmapParams = {
12
12
  export const DEFAULT_LIGHTMAP_PARAMS: Required<BlockLightmapParams> = {
13
13
  curve: 0,
14
14
  minBrightness: 0.12,
15
- gamma: 1,
15
+ gamma: 1
16
16
  }
17
17
 
18
18
  /** GLSL body for applyLightmap — requires u_lightCurve, u_minBrightness, u_lightGamma uniforms. */
@@ -25,7 +25,7 @@ float applyLightmap(float L) {
25
25
  }
26
26
  `
27
27
 
28
- export function applyLightmap (L: number, params: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS): number {
28
+ export function applyLightmap(L: number, params: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS): number {
29
29
  const curve = params.curve ?? DEFAULT_LIGHTMAP_PARAMS.curve
30
30
  const minBrightness = params.minBrightness ?? DEFAULT_LIGHTMAP_PARAMS.minBrightness
31
31
  const gamma = params.gamma ?? DEFAULT_LIGHTMAP_PARAMS.gamma
@@ -37,16 +37,16 @@ export function applyLightmap (L: number, params: BlockLightmapParams = DEFAULT_
37
37
  }
38
38
 
39
39
  /** Same cap as block shaders: max(block, min(sky, skyLevel)). */
40
- export function combinedBlockLight (block: number, sky: number, skyLevel: number): number {
40
+ export function combinedBlockLight(block: number, sky: number, skyLevel: number): number {
41
41
  return Math.max(block, Math.min(sky, skyLevel))
42
42
  }
43
43
 
44
44
  /** 0..1 brightness for MeshBasicMaterial.color.setScalar on block-entity overlays. */
45
- export function blockEntityBrightness (
45
+ export function blockEntityBrightness(
46
46
  blockNorm: number,
47
47
  skyNorm: number,
48
48
  skyLevel: number,
49
- lightmapParams: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS,
49
+ lightmapParams: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS
50
50
  ): number {
51
51
  const L = combinedBlockLight(blockNorm, skyNorm, skyLevel)
52
52
  return applyLightmap(L, lightmapParams)
@@ -1,6 +1,6 @@
1
1
  export const dynamicMcDataFiles = {
2
- 'blocks': 'blocksArray',
3
- 'blockCollisionShapes': 'blockCollisionShapes',
4
- 'biomes': 'biomesArray',
5
- 'tints': 'tints',
2
+ blocks: 'blocksArray',
3
+ blockCollisionShapes: 'blockCollisionShapes',
4
+ biomes: 'biomesArray',
5
+ tints: 'tints'
6
6
  }
@@ -6,7 +6,7 @@ describe('augmentWorkerMcData', () => {
6
6
  it('is idempotent when mcData is augmented twice (menu then world)', () => {
7
7
  const mcData: Record<string, unknown> = {
8
8
  entities: [{ name: 'bat', id: 1, type: 'mob' }],
9
- blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }],
9
+ blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
10
10
  }
11
11
  augmentWorkerMcData(mcData)
12
12
  expect(() => augmentWorkerMcData(mcData)).not.toThrow()
@@ -16,7 +16,7 @@ describe('augmentWorkerMcData', () => {
16
16
 
17
17
  it('keeps *Array sources after indexing (esbuild mc-data plugin reads blocksArray)', () => {
18
18
  const mcData: Record<string, unknown> = {
19
- blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }],
19
+ blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
20
20
  }
21
21
  augmentWorkerMcData(mcData)
22
22
  expect(Array.isArray(mcData.blocksArray)).toBe(true)
@@ -26,7 +26,7 @@ describe('augmentWorkerMcData', () => {
26
26
 
27
27
  it('coerces valtio-style dense objects into arrays', () => {
28
28
  const mcData: Record<string, unknown> = {
29
- entities: { 0: { name: 'bat', id: 1, type: 'mob' } },
29
+ entities: { 0: { name: 'bat', id: 1, type: 'mob' } }
30
30
  }
31
31
  augmentWorkerMcData(mcData)
32
32
  expect((mcData.entitiesByName as Record<string, { name: string }>).bat?.name).toBe('bat')
@@ -36,7 +36,7 @@ describe('augmentWorkerMcData', () => {
36
36
  const mcData: Record<string, unknown> = {
37
37
  entities: [{ name: 'bat', id: 1, type: 'mob' }],
38
38
  items: [{ name: 'dirt', id: 2 }],
39
- blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }],
39
+ blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
40
40
  }
41
41
  augmentWorkerMcData(mcData)
42
42
  expect((mcData.entitiesByName as Record<string, { name: string }>).bat?.name).toBe('bat')
@@ -1,7 +1,7 @@
1
1
  //@ts-nocheck
2
2
  type McElement = Record<string, unknown>
3
3
 
4
- function coerceDenseArray (value: unknown): McElement[] | undefined {
4
+ function coerceDenseArray(value: unknown): McElement[] | undefined {
5
5
  if (Array.isArray(value)) {
6
6
  return value as McElement[]
7
7
  }
@@ -9,7 +9,10 @@ function coerceDenseArray (value: unknown): McElement[] | undefined {
9
9
  return undefined
10
10
  }
11
11
  const record = value as Record<string, McElement>
12
- const keys = Object.keys(record).filter((k) => /^\d+$/.test(k)).map(Number).sort((a, b) => a - b)
12
+ const keys = Object.keys(record)
13
+ .filter(k => /^\d+$/.test(k))
14
+ .map(Number)
15
+ .sort((a, b) => a - b)
13
16
  if (!keys.length || keys[0] !== 0) {
14
17
  return undefined
15
18
  }
@@ -18,13 +21,10 @@ function coerceDenseArray (value: unknown): McElement[] | undefined {
18
21
  return undefined
19
22
  }
20
23
  }
21
- return keys.map((k) => record[String(k)])
24
+ return keys.map(k => record[String(k)])
22
25
  }
23
26
 
24
- function buildIndexFromArray<T extends McElement> (
25
- array: T[],
26
- field: keyof T
27
- ): Record<string | number, T> {
27
+ function buildIndexFromArray<T extends McElement>(array: T[], field: keyof T): Record<string | number, T> {
28
28
  if (!Array.isArray(array)) {
29
29
  console.warn('[augmentWorkerMcData] buildIndexFromArray expected array, got', typeof array)
30
30
  return {}
@@ -35,11 +35,7 @@ function buildIndexFromArray<T extends McElement> (
35
35
  }, {})
36
36
  }
37
37
 
38
- function buildIndexFromArrayWithRanges<T extends McElement> (
39
- array: T[],
40
- minField: keyof T,
41
- maxField: keyof T
42
- ): Record<number, T> {
38
+ function buildIndexFromArrayWithRanges<T extends McElement>(array: T[], minField: keyof T, maxField: keyof T): Record<number, T> {
43
39
  if (!Array.isArray(array)) {
44
40
  console.warn('[augmentWorkerMcData] buildIndexFromArrayWithRanges expected array, got', typeof array)
45
41
  return {}
@@ -54,7 +50,7 @@ function buildIndexFromArrayWithRanges<T extends McElement> (
54
50
  }, {})
55
51
  }
56
52
 
57
- function ensureBlockStateIds (blocks: McElement[]) {
53
+ function ensureBlockStateIds(blocks: McElement[]) {
58
54
  if (!blocks.length) return
59
55
  if ('minStateId' in blocks[0] && 'defaultState' in blocks[0]) return
60
56
  for (const block of blocks) {
@@ -65,11 +61,7 @@ function ensureBlockStateIds (blocks: McElement[]) {
65
61
  }
66
62
  }
67
63
 
68
- function getSourceArray (
69
- mcData: Record<string, unknown>,
70
- arrayKey: string,
71
- rawKey: string
72
- ): McElement[] | undefined {
64
+ function getSourceArray(mcData: Record<string, unknown>, arrayKey: string, rawKey: string): McElement[] | undefined {
73
65
  const fromArrayKey = coerceDenseArray(mcData[arrayKey])
74
66
  if (fromArrayKey?.length) {
75
67
  return fromArrayKey
@@ -81,7 +73,7 @@ function getSourceArray (
81
73
  return undefined
82
74
  }
83
75
 
84
- export function augmentWorkerMcData (mcData: Record<string, unknown>) {
76
+ export function augmentWorkerMcData(mcData: Record<string, unknown>) {
85
77
  if (mcData.__workerIndexesBuilt) {
86
78
  return mcData
87
79
  }
@@ -14,7 +14,7 @@ export interface CameraBobInput {
14
14
 
15
15
  const DEG_TO_RAD = Math.PI / 180
16
16
 
17
- export function computeCameraBob (input: CameraBobInput): CameraBobResult {
17
+ export function computeCameraBob(input: CameraBobInput): CameraBobResult {
18
18
  const { walkDist, prevWalkDist, bob, prevBob, partialTick } = input
19
19
 
20
20
  // Vanilla uses "backwards interpolation": -(walkDist + delta * partialTick)
@@ -15,7 +15,7 @@ export function example1_SimpleBlackBox(documentRenderer: DocumentRenderer) {
15
15
  const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
16
16
 
17
17
  // Register to render overlay after main scene
18
- documentRenderer.onRender.push((sizeChanged) => {
18
+ documentRenderer.onRender.push(sizeChanged => {
19
19
  if (sizeChanged) {
20
20
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
21
21
  }
@@ -46,7 +46,7 @@ export function example2_FPSCounter(documentRenderer: DocumentRenderer) {
46
46
  let lastTime = performance.now()
47
47
  let frameCount = 0
48
48
 
49
- documentRenderer.onRender.push((sizeChanged) => {
49
+ documentRenderer.onRender.push(sizeChanged => {
50
50
  if (sizeChanged) {
51
51
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
52
52
  }
@@ -82,13 +82,10 @@ export function example2_FPSCounter(documentRenderer: DocumentRenderer) {
82
82
  // ============================================
83
83
  // EXAMPLE 3: Coordinate Display (Bottom-Left)
84
84
  // ============================================
85
- export function example3_CoordinateDisplay(
86
- documentRenderer: DocumentRenderer,
87
- getPosition: () => { x: number; y: number; z: number }
88
- ) {
85
+ export function example3_CoordinateDisplay(documentRenderer: DocumentRenderer, getPosition: () => { x: number; y: number; z: number }) {
89
86
  const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
90
87
 
91
- documentRenderer.onRender.push((sizeChanged) => {
88
+ documentRenderer.onRender.push(sizeChanged => {
92
89
  if (sizeChanged) {
93
90
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
94
91
  }
@@ -130,13 +127,10 @@ export function example3_CoordinateDisplay(
130
127
  // ============================================
131
128
  // EXAMPLE 4: Mini-map (Top-Right Corner)
132
129
  // ============================================
133
- export function example4_MiniMap(
134
- documentRenderer: DocumentRenderer,
135
- playerPos: { x: number; z: number }
136
- ) {
130
+ export function example4_MiniMap(documentRenderer: DocumentRenderer, playerPos: { x: number; z: number }) {
137
131
  const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
138
132
 
139
- documentRenderer.onRender.push((sizeChanged) => {
133
+ documentRenderer.onRender.push(sizeChanged => {
140
134
  if (sizeChanged) {
141
135
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
142
136
  }
@@ -197,13 +191,10 @@ export function example5_DirectWebGL(documentRenderer: DocumentRenderer) {
197
191
  // ============================================
198
192
  // EXAMPLE 6: Health/Status Bar
199
193
  // ============================================
200
- export function example6_HealthBar(
201
- documentRenderer: DocumentRenderer,
202
- getHealth: () => { current: number; max: number }
203
- ) {
194
+ export function example6_HealthBar(documentRenderer: DocumentRenderer, getHealth: () => { current: number; max: number }) {
204
195
  const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
205
196
 
206
- documentRenderer.onRender.push((sizeChanged) => {
197
+ documentRenderer.onRender.push(sizeChanged => {
207
198
  if (sizeChanged) {
208
199
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
209
200
  }
@@ -249,7 +240,7 @@ export function example6_HealthBar(
249
240
  export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
250
241
  const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
251
242
 
252
- documentRenderer.onRender.push((sizeChanged) => {
243
+ documentRenderer.onRender.push(sizeChanged => {
253
244
  if (sizeChanged) {
254
245
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
255
246
  }
@@ -262,10 +253,7 @@ export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
262
253
 
263
254
  // Draw vertical lines
264
255
  for (let x = 0; x < width; x += gridSize) {
265
- const points = [
266
- new THREE.Vector3(x, 0, 0),
267
- new THREE.Vector3(x, height, 0)
268
- ]
256
+ const points = [new THREE.Vector3(x, 0, 0), new THREE.Vector3(x, height, 0)]
269
257
  const geometry = new THREE.BufferGeometry().setFromPoints(points)
270
258
  const material = new THREE.LineBasicMaterial({ color: 0x333333, opacity: 0.3, transparent: true })
271
259
  const line = new THREE.Line(geometry, material)
@@ -275,10 +263,7 @@ export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
275
263
 
276
264
  // Draw horizontal lines
277
265
  for (let y = 0; y < height; y += gridSize) {
278
- const points = [
279
- new THREE.Vector3(0, y, 0),
280
- new THREE.Vector3(width, y, 0)
281
- ]
266
+ const points = [new THREE.Vector3(0, y, 0), new THREE.Vector3(width, y, 0)]
282
267
  const geometry = new THREE.BufferGeometry().setFromPoints(points)
283
268
  const material = new THREE.LineBasicMaterial({ color: 0x333333, opacity: 0.3, transparent: true })
284
269
  const line = new THREE.Line(geometry, material)
@@ -301,7 +286,7 @@ export function integrateWithDocumentRenderer(documentRenderer: DocumentRenderer
301
286
 
302
287
  // Add to render loop
303
288
  const originalRender = documentRenderer.render
304
- documentRenderer.render = (sizeChanged) => {
289
+ documentRenderer.render = sizeChanged => {
305
290
  // Call original render
306
291
  originalRender.call(documentRenderer, sizeChanged)
307
292
 
@@ -333,7 +318,7 @@ export function workerCompatibleOverlay(documentRenderer: DocumentRenderer) {
333
318
  // This works the same in both main thread and worker!
334
319
  const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
335
320
 
336
- documentRenderer.onRender.push((sizeChanged) => {
321
+ documentRenderer.onRender.push(sizeChanged => {
337
322
  if (sizeChanged) {
338
323
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
339
324
  }
@@ -355,8 +340,3 @@ export function workerCompatibleOverlay(documentRenderer: DocumentRenderer) {
355
340
 
356
341
  return overlay
357
342
  }
358
-
359
-
360
-
361
-
362
-
@@ -13,21 +13,15 @@ import { Canvas2DOverlay } from './canvas2DOverlay'
13
13
  // STEP 1: Create the overlay
14
14
  // ============================================
15
15
  export function addBlackBoxOverlay(documentRenderer: DocumentRenderer) {
16
- const overlay = new Canvas2DOverlay(
17
- documentRenderer.renderer,
18
- documentRenderer.canvas
19
- )
16
+ const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
20
17
 
21
18
  // ============================================
22
19
  // STEP 2: Hook into the render loop
23
20
  // ============================================
24
- documentRenderer.onRender.push((sizeChanged) => {
21
+ documentRenderer.onRender.push(sizeChanged => {
25
22
  // Update overlay camera when canvas size changes
26
23
  if (sizeChanged) {
27
- overlay.updateSize(
28
- documentRenderer.canvas.width,
29
- documentRenderer.canvas.height
30
- )
24
+ overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
31
25
  }
32
26
 
33
27
  // Clear previous frame's overlay
@@ -43,12 +37,12 @@ export function addBlackBoxOverlay(documentRenderer: DocumentRenderer) {
43
37
  const y = documentRenderer.canvas.height - boxSize - 10 // 10px from bottom
44
38
 
45
39
  overlay.drawRect(
46
- x, // x position
47
- y, // y position
48
- boxSize, // width
49
- boxSize, // height
40
+ x, // x position
41
+ y, // y position
42
+ boxSize, // width
43
+ boxSize, // height
50
44
  0x000000, // color (black)
51
- 0.8 // opacity (80%)
45
+ 0.8 // opacity (80%)
52
46
  )
53
47
 
54
48
  // ============================================
@@ -82,12 +76,9 @@ const overlay = addBlackBoxOverlay(documentRenderer)
82
76
  // Add More Elements
83
77
  // ============================================
84
78
  export function addMultipleElements(documentRenderer: DocumentRenderer) {
85
- const overlay = new Canvas2DOverlay(
86
- documentRenderer.renderer,
87
- documentRenderer.canvas
88
- )
79
+ const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
89
80
 
90
- documentRenderer.onRender.push((sizeChanged) => {
81
+ documentRenderer.onRender.push(sizeChanged => {
91
82
  if (sizeChanged) {
92
83
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
93
84
  }
@@ -96,14 +87,7 @@ export function addMultipleElements(documentRenderer: DocumentRenderer) {
96
87
 
97
88
  // Bottom-left black box
98
89
  const boxSize = 100
99
- overlay.drawRect(
100
- 10,
101
- documentRenderer.canvas.height - boxSize - 10,
102
- boxSize,
103
- boxSize,
104
- 0x000000,
105
- 0.8
106
- )
90
+ overlay.drawRect(10, documentRenderer.canvas.height - boxSize - 10, boxSize, boxSize, 0x000000, 0.8)
107
91
 
108
92
  // Add label inside the box
109
93
  overlay.drawText('Info', 15, documentRenderer.canvas.height - boxSize, {
@@ -144,16 +128,10 @@ export function addMultipleElements(documentRenderer: DocumentRenderer) {
144
128
  // ============================================
145
129
  // Dynamic Data Example
146
130
  // ============================================
147
- export function addDynamicOverlay(
148
- documentRenderer: DocumentRenderer,
149
- getData: () => { fps: number; x: number; y: number; z: number }
150
- ) {
151
- const overlay = new Canvas2DOverlay(
152
- documentRenderer.renderer,
153
- documentRenderer.canvas
154
- )
155
-
156
- documentRenderer.onRender.push((sizeChanged) => {
131
+ export function addDynamicOverlay(documentRenderer: DocumentRenderer, getData: () => { fps: number; x: number; y: number; z: number }) {
132
+ const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
133
+
134
+ documentRenderer.onRender.push(sizeChanged => {
157
135
  if (sizeChanged) {
158
136
  overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
159
137
  }
@@ -208,10 +186,7 @@ export function addDynamicOverlay(
208
186
  import { WebGLDirect2DOverlay } from './canvas2DOverlay'
209
187
 
210
188
  export function addHighPerformanceOverlay(documentRenderer: DocumentRenderer) {
211
- const overlay = new WebGLDirect2DOverlay(
212
- documentRenderer.renderer,
213
- documentRenderer.canvas
214
- )
189
+ const overlay = new WebGLDirect2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
215
190
 
216
191
  documentRenderer.onRender.push(() => {
217
192
  // Direct WebGL rendering - very fast!
@@ -223,21 +198,16 @@ export function addHighPerformanceOverlay(documentRenderer: DocumentRenderer) {
223
198
  const y = documentRenderer.canvas.height - boxSize - 10
224
199
 
225
200
  overlay.drawRect(
226
- x, // x
227
- y, // y
228
- boxSize, // width
229
- boxSize, // height
230
- 0, // red (0-1)
231
- 0, // green (0-1)
232
- 0, // blue (0-1)
233
- 0.8 // alpha (0-1)
201
+ x, // x
202
+ y, // y
203
+ boxSize, // width
204
+ boxSize, // height
205
+ 0, // red (0-1)
206
+ 0, // green (0-1)
207
+ 0, // blue (0-1)
208
+ 0.8 // alpha (0-1)
234
209
  )
235
210
  })
236
211
 
237
212
  return overlay
238
213
  }
239
-
240
-
241
-
242
-
243
-
@@ -123,22 +123,20 @@ export class Canvas2DOverlay {
123
123
  /**
124
124
  * Draw text using canvas texture (works in worker with OffscreenCanvas)
125
125
  */
126
- drawText(text: string, x: number, y: number, options: {
127
- fontSize?: number
128
- fontFamily?: string
129
- color?: string
130
- backgroundColor?: string
131
- padding?: number
132
- opacity?: number
133
- } = {}) {
134
- const {
135
- fontSize = 16,
136
- fontFamily = 'Arial',
137
- color = '#ffffff',
138
- backgroundColor = '#000000',
139
- padding = 4,
140
- opacity = 1
141
- } = options
126
+ drawText(
127
+ text: string,
128
+ x: number,
129
+ y: number,
130
+ options: {
131
+ fontSize?: number
132
+ fontFamily?: string
133
+ color?: string
134
+ backgroundColor?: string
135
+ padding?: number
136
+ opacity?: number
137
+ } = {}
138
+ ) {
139
+ const { fontSize = 16, fontFamily = 'Arial', color = '#ffffff', backgroundColor = '#000000', padding = 4, opacity = 1 } = options
142
140
 
143
141
  // Create a temporary canvas for text rendering
144
142
  // OffscreenCanvas works in workers!
@@ -178,11 +176,7 @@ export class Canvas2DOverlay {
178
176
  const geometry = new THREE.PlaneGeometry(textCanvas.width, textCanvas.height)
179
177
  const mesh = new THREE.Mesh(geometry, material)
180
178
 
181
- mesh.position.set(
182
- x + textCanvas.width / 2,
183
- y + textCanvas.height / 2,
184
- 0
185
- )
179
+ mesh.position.set(x + textCanvas.width / 2, y + textCanvas.height / 2, 0)
186
180
 
187
181
  this.overlayScene.add(mesh)
188
182
  this.overlayObjects.push(mesh)
@@ -252,7 +246,9 @@ export class WebGLDirect2DOverlay {
252
246
  this.gl = this.renderer.getContext()
253
247
 
254
248
  // Create shader program for 2D rendering
255
- const vertexShader = this.createShader(this.gl.VERTEX_SHADER, `
249
+ const vertexShader = this.createShader(
250
+ this.gl.VERTEX_SHADER,
251
+ `
256
252
  attribute vec2 position;
257
253
  attribute vec4 color;
258
254
  varying vec4 vColor;
@@ -264,16 +260,20 @@ export class WebGLDirect2DOverlay {
264
260
  gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
265
261
  vColor = color;
266
262
  }
267
- `)
263
+ `
264
+ )
268
265
 
269
- const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `
266
+ const fragmentShader = this.createShader(
267
+ this.gl.FRAGMENT_SHADER,
268
+ `
270
269
  precision mediump float;
271
270
  varying vec4 vColor;
272
271
 
273
272
  void main() {
274
273
  gl_FragColor = vColor;
275
274
  }
276
- `)
275
+ `
276
+ )
277
277
 
278
278
  this.program = this.createProgram(vertexShader, fragmentShader)
279
279
 
@@ -318,23 +318,9 @@ export class WebGLDirect2DOverlay {
318
318
  const x2 = x + width
319
319
  const y2 = y + height
320
320
 
321
- const positions = new Float32Array([
322
- x1, y1,
323
- x2, y1,
324
- x1, y2,
325
- x1, y2,
326
- x2, y1,
327
- x2, y2
328
- ])
329
-
330
- const colors = new Float32Array([
331
- r, g, b, a,
332
- r, g, b, a,
333
- r, g, b, a,
334
- r, g, b, a,
335
- r, g, b, a,
336
- r, g, b, a
337
- ])
321
+ const positions = new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2])
322
+
323
+ const colors = new Float32Array([r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a])
338
324
 
339
325
  this.gl.useProgram(this.program)
340
326
 
@@ -375,8 +361,3 @@ export class WebGLDirect2DOverlay {
375
361
  this.gl.deleteProgram(this.program)
376
362
  }
377
363
  }
378
-
379
-
380
-
381
-
382
-
@@ -1,5 +1,5 @@
1
1
  //@ts-nocheck
2
- export function buildCleanupDecorator (cleanupMethod: string) {
2
+ export function buildCleanupDecorator(cleanupMethod: string) {
3
3
  return function () {
4
4
  return function (_target: { snapshotInitialValues }, propertyKey: string) {
5
5
  const target = _target as any
@@ -13,7 +13,7 @@ export function buildCleanupDecorator (cleanupMethod: string) {
13
13
  }
14
14
  target._snapshotMethodPatched = true
15
15
  }
16
- (target._toCleanup ??= []).push(propertyKey)
16
+ ;(target._toCleanup ??= []).push(propertyKey)
17
17
  if (!target._cleanupPatched) {
18
18
  const originalMethod = target[cleanupMethod]
19
19
  target[cleanupMethod] = function () {
@@ -3,7 +3,7 @@ import { describe, expect, it, vi } from 'vitest'
3
3
 
4
4
  vi.mock('./utils/skins', () => ({
5
5
  stevePngUrl: '',
6
- loadSkinImage: vi.fn(),
6
+ loadSkinImage: vi.fn()
7
7
  }))
8
8
 
9
9
  import { PlayerObject } from 'skinview3d'
@@ -16,12 +16,7 @@ describe('configurePlayerSkinMaterials', () => {
16
16
 
17
17
  configurePlayerSkinMaterials(playerObject)
18
18
 
19
- const allMaterials = [
20
- skin.layer1Material,
21
- skin.layer1MaterialBiased,
22
- skin.layer2Material,
23
- skin.layer2MaterialBiased,
24
- ]
19
+ const allMaterials = [skin.layer1Material, skin.layer1MaterialBiased, skin.layer2Material, skin.layer2MaterialBiased]
25
20
  for (const mat of allMaterials) {
26
21
  expect(mat.transparent).toBe(false)
27
22
  expect(mat.alphaTest).toBe(0.1)
@@ -12,7 +12,7 @@ export type PlayerObjectType = PlayerObject & {
12
12
 
13
13
  const LOG_DEPTH_BIAS = -2e-4 // tune visually; negative ≈ polygonOffset “closer”
14
14
 
15
- function patchLogDepthBiasShader (shader: THREE.WebGLProgramParametersWithUniforms): void {
15
+ function patchLogDepthBiasShader(shader: THREE.WebGLProgramParametersWithUniforms): void {
16
16
  shader.uniforms.uLogDepthBias = { value: LOG_DEPTH_BIAS }
17
17
  shader.fragmentShader = shader.fragmentShader.replace(
18
18
  '#include <logdepthbuf_pars_fragment>',
@@ -26,7 +26,7 @@ function patchLogDepthBiasShader (shader: THREE.WebGLProgramParametersWithUnifor
26
26
  )
27
27
  }
28
28
 
29
- function applyLogDepthBias (material: THREE.Material): void {
29
+ function applyLogDepthBias(material: THREE.Material): void {
30
30
  if (material.userData.logDepthBiasApplied) return
31
31
  material.userData.logDepthBiasApplied = true
32
32
  material.onBeforeCompile = patchLogDepthBiasShader
@@ -34,14 +34,9 @@ function applyLogDepthBias (material: THREE.Material): void {
34
34
  }
35
35
 
36
36
  /** Log-depth world: opaque cutout mats (alphaTest + depthWrite, not transparent sort). */
37
- export function configurePlayerSkinMaterials (playerObject: PlayerObject): void {
37
+ export function configurePlayerSkinMaterials(playerObject: PlayerObject): void {
38
38
  const skin = playerObject.skin as any
39
- const materials = [
40
- skin.layer1Material,
41
- skin.layer1MaterialBiased,
42
- skin.layer2Material,
43
- skin.layer2MaterialBiased,
44
- ]
39
+ const materials = [skin.layer1Material, skin.layer1MaterialBiased, skin.layer2Material, skin.layer2MaterialBiased]
45
40
  for (const mat of materials) {
46
41
  mat.transparent = false
47
42
  mat.alphaTest = 0.1
@@ -51,14 +46,10 @@ export function configurePlayerSkinMaterials (playerObject: PlayerObject): void
51
46
  applyLogDepthBias(skin.layer2MaterialBiased)
52
47
  }
53
48
 
54
- export function createPlayerObject (options: {
55
- username?: string
56
- uuid?: string
57
- scale?: number
58
- }): {
59
- playerObject: PlayerObjectType
60
- wrapper: THREE.Group
61
- } {
49
+ export function createPlayerObject(options: { username?: string; uuid?: string; scale?: number }): {
50
+ playerObject: PlayerObjectType
51
+ wrapper: THREE.Group
52
+ } {
62
53
  const wrapper = new THREE.Group()
63
54
  const playerObject = new PlayerObject() as PlayerObjectType
64
55
 
@@ -69,7 +60,7 @@ export function createPlayerObject (options: {
69
60
  configurePlayerSkinMaterials(playerObject)
70
61
 
71
62
  wrapper.add(playerObject as any)
72
- const scale = options.scale ?? (1 / 16)
63
+ const scale = options.scale ?? 1 / 16
73
64
  wrapper.scale.set(scale, scale, scale)
74
65
  wrapper.rotation.set(0, Math.PI, 0)
75
66
 
@@ -82,11 +73,13 @@ export function createPlayerObject (options: {
82
73
  }
83
74
 
84
75
  export const applySkinToPlayerObject = async (playerObject: PlayerObjectType, skinUrl: string) => {
85
- return loadSkinImage(skinUrl || stevePngUrl).then(({ canvas }) => {
86
- const skinTexture = new THREE.CanvasTexture(canvas)
87
- skinTexture.magFilter = THREE.NearestFilter
88
- skinTexture.minFilter = THREE.NearestFilter
89
- skinTexture.needsUpdate = true
90
- playerObject.skin.map = skinTexture as any
91
- }).catch(console.error)
76
+ return loadSkinImage(skinUrl || stevePngUrl)
77
+ .then(({ canvas }) => {
78
+ const skinTexture = new THREE.CanvasTexture(canvas)
79
+ skinTexture.magFilter = THREE.NearestFilter
80
+ skinTexture.minFilter = THREE.NearestFilter
81
+ skinTexture.needsUpdate = true
82
+ playerObject.skin.map = skinTexture as any
83
+ })
84
+ .catch(console.error)
92
85
  }