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
@@ -59,7 +59,7 @@ interface JsonModel {
59
59
 
60
60
  export type CustomModelMetadata = {
61
61
  scale?: number
62
- offset?: { x?: number, y?: number, z?: number }
62
+ offset?: { x?: number; y?: number; z?: number }
63
63
  texture?: string
64
64
  textures?: Record<string, string>
65
65
  animation?: string
@@ -81,7 +81,7 @@ interface EntityOverrides {
81
81
  customModel?: EntityCustomModel
82
82
  }
83
83
 
84
- function normalizeCustomModelParts (custom: EntityCustomModel): CustomModelPart[] {
84
+ function normalizeCustomModelParts(custom: EntityCustomModel): CustomModelPart[] {
85
85
  if ('parts' in custom && Array.isArray(custom.parts)) return custom.parts
86
86
  return [custom as CustomModelPart]
87
87
  }
@@ -184,9 +184,9 @@ function addCube(
184
184
  ): void {
185
185
  const cubeRotation = new THREE.Euler(0, 0, 0)
186
186
  if (cube.rotation) {
187
- cubeRotation.x = -cube.rotation[0] * Math.PI / 180
188
- cubeRotation.y = -cube.rotation[1] * Math.PI / 180
189
- cubeRotation.z = -cube.rotation[2] * Math.PI / 180
187
+ cubeRotation.x = (-cube.rotation[0] * Math.PI) / 180
188
+ cubeRotation.y = (-cube.rotation[1] * Math.PI) / 180
189
+ cubeRotation.z = (-cube.rotation[2] * Math.PI) / 180
190
190
  }
191
191
  for (const { dir, corners, u0, v0, u1, v1 } of Object.values(elemFaces)) {
192
192
  const ndx = Math.floor(attr.positions.length / 3)
@@ -295,18 +295,18 @@ export function getMesh(
295
295
  bone.position.z = jsonBone.pivot[2]
296
296
  }
297
297
  if (jsonBone.bind_pose_rotation) {
298
- bone.rotation.x = -jsonBone.bind_pose_rotation[0] * Math.PI / 180
299
- bone.rotation.y = -jsonBone.bind_pose_rotation[1] * Math.PI / 180
300
- bone.rotation.z = -jsonBone.bind_pose_rotation[2] * Math.PI / 180
298
+ bone.rotation.x = (-jsonBone.bind_pose_rotation[0] * Math.PI) / 180
299
+ bone.rotation.y = (-jsonBone.bind_pose_rotation[1] * Math.PI) / 180
300
+ bone.rotation.z = (-jsonBone.bind_pose_rotation[2] * Math.PI) / 180
301
301
  } else if (jsonBone.rotation) {
302
- bone.rotation.x = -jsonBone.rotation[0] * Math.PI / 180
303
- bone.rotation.y = -jsonBone.rotation[1] * Math.PI / 180
304
- bone.rotation.z = -jsonBone.rotation[2] * Math.PI / 180
302
+ bone.rotation.x = (-jsonBone.rotation[0] * Math.PI) / 180
303
+ bone.rotation.y = (-jsonBone.rotation[1] * Math.PI) / 180
304
+ bone.rotation.z = (-jsonBone.rotation[2] * Math.PI) / 180
305
305
  }
306
306
  if (overrides.rotation?.[jsonBone.name]) {
307
- bone.rotation.x -= (overrides.rotation[jsonBone.name].x ?? 0) * Math.PI / 180
308
- bone.rotation.y -= (overrides.rotation[jsonBone.name].y ?? 0) * Math.PI / 180
309
- bone.rotation.z -= (overrides.rotation[jsonBone.name].z ?? 0) * Math.PI / 180
307
+ bone.rotation.x -= ((overrides.rotation[jsonBone.name].x ?? 0) * Math.PI) / 180
308
+ bone.rotation.y -= ((overrides.rotation[jsonBone.name].y ?? 0) * Math.PI) / 180
309
+ bone.rotation.z -= ((overrides.rotation[jsonBone.name].z ?? 0) * Math.PI) / 180
310
310
  }
311
311
  bone.name = `bone_${jsonBone.name}`
312
312
  bones[jsonBone.name] = bone
@@ -356,31 +356,35 @@ export function getMesh(
356
356
  loadedTexture.needsUpdate = true
357
357
  material.map = loadedTexture
358
358
  } else {
359
- void loadTexture(texture, loadedTexture => {
360
- if (material.map) {
361
- // texture is already loaded
362
- return
363
- }
364
- loadedTexture.magFilter = THREE.NearestFilter
365
- loadedTexture.minFilter = THREE.NearestFilter
366
- loadedTexture.flipY = false
367
- loadedTexture.wrapS = THREE.RepeatWrapping
368
- loadedTexture.wrapT = THREE.RepeatWrapping
369
- material.map = loadedTexture
370
- }, () => {
371
- // This callback runs after the texture is fully loaded
372
- const map = material.map as THREE.Texture<HTMLImageElement | ImageBitmap> | null
373
- if (!map) return
374
- const actualWidth = map.image.width
375
- if (actualWidth && textureWidth !== actualWidth) {
376
- map.repeat.x = textureWidth / actualWidth
377
- }
378
- const actualHeight = map.image.height
379
- if (actualHeight && textureHeight !== actualHeight) {
380
- map.repeat.y = textureHeight / actualHeight
359
+ void loadTexture(
360
+ texture,
361
+ loadedTexture => {
362
+ if (material.map) {
363
+ // texture is already loaded
364
+ return
365
+ }
366
+ loadedTexture.magFilter = THREE.NearestFilter
367
+ loadedTexture.minFilter = THREE.NearestFilter
368
+ loadedTexture.flipY = false
369
+ loadedTexture.wrapS = THREE.RepeatWrapping
370
+ loadedTexture.wrapT = THREE.RepeatWrapping
371
+ material.map = loadedTexture
372
+ },
373
+ () => {
374
+ // This callback runs after the texture is fully loaded
375
+ const map = material.map as THREE.Texture<HTMLImageElement | ImageBitmap> | null
376
+ if (!map) return
377
+ const actualWidth = map.image.width
378
+ if (actualWidth && textureWidth !== actualWidth) {
379
+ map.repeat.x = textureWidth / actualWidth
380
+ }
381
+ const actualHeight = map.image.height
382
+ if (actualHeight && textureHeight !== actualHeight) {
383
+ map.repeat.y = textureHeight / actualHeight
384
+ }
385
+ material.needsUpdate = true
381
386
  }
382
- material.needsUpdate = true
383
- })
387
+ )
384
388
  }
385
389
 
386
390
  return mesh
@@ -418,14 +422,16 @@ const temporaryMappings: EntityMapping[] = [
418
422
  { pattern: /_raft$/, target: 'boat' },
419
423
  { pattern: /_horse$/, target: 'horse' },
420
424
  { pattern: /_zombie$/, target: 'zombie' },
421
- { pattern: /_arrow$/, target: 'zombie' },
425
+ { pattern: /_arrow$/, target: 'zombie' }
422
426
  ]
423
427
 
424
428
  function getEntityMapping(type: string): string | undefined {
425
429
  for (const mapping of temporaryMappings) {
426
430
  if (typeof mapping.pattern === 'string') {
427
431
  if (mapping.pattern === type) return mapping.target
428
- } else if (mapping.pattern.test(type)) { return mapping.target }
432
+ } else if (mapping.pattern.test(type)) {
433
+ return mapping.target
434
+ }
429
435
  }
430
436
  return undefined
431
437
  }
@@ -449,9 +455,9 @@ const offsetEntity: Record<string, Vec3> = {
449
455
 
450
456
  interface EntityGeometry {
451
457
  geometry: Array<{
452
- name: string;
453
- [key: string]: any;
454
- }>;
458
+ name: string
459
+ [key: string]: any
460
+ }>
455
461
  }
456
462
 
457
463
  export type EntityModelType = 'obj' | 'bedrock' | 'gltf'
@@ -469,13 +475,7 @@ export class EntityMesh {
469
475
  animations?: THREE.AnimationClip[]
470
476
  private animationControllers: Array<ReturnType<typeof createAnimatedObject>> = []
471
477
 
472
- constructor(
473
- version: string,
474
- type: string,
475
- worldRenderer?: WorldRendererThree,
476
- overrides: EntityOverrides = {},
477
- debugFlags: EntityDebugFlags = {}
478
- ) {
478
+ constructor(version: string, type: string, worldRenderer?: WorldRendererThree, overrides: EntityOverrides = {}, debugFlags: EntityDebugFlags = {}) {
479
479
  const originalType = type
480
480
  const mappedValue = getEntityMapping(type)
481
481
  if (mappedValue) {
@@ -496,43 +496,46 @@ export class EntityMesh {
496
496
  switch (modelType) {
497
497
  case 'gltf': {
498
498
  const loader = new GLTFLoader()
499
- void loader.parseAsync(modelPath, '').then(gltf => {
500
- partRoot.add(gltf.scene)
501
- if (metadata?.scale) {
502
- const s = metadata.scale
503
- partRoot.scale.set(s, s, s)
504
- }
505
- if (metadata?.offset) {
506
- const { x = 0, y = 0, z = 0 } = metadata.offset
507
- partRoot.position.set(x, y, z)
508
- }
509
- if (metadata?.texture) {
510
- const texture = loadNearestFilterTexture(metadata.texture)
511
- partRoot.traverse((child) => {
512
- if (child instanceof THREE.Mesh) {
513
- child.material = new THREE.MeshBasicMaterial({
514
- map: texture,
515
- transparent: true,
516
- alphaTest: 0.1
517
- })
499
+ void loader
500
+ .parseAsync(modelPath, '')
501
+ .then(gltf => {
502
+ partRoot.add(gltf.scene)
503
+ if (metadata?.scale) {
504
+ const s = metadata.scale
505
+ partRoot.scale.set(s, s, s)
506
+ }
507
+ if (metadata?.offset) {
508
+ const { x = 0, y = 0, z = 0 } = metadata.offset
509
+ partRoot.position.set(x, y, z)
510
+ }
511
+ if (metadata?.texture) {
512
+ const texture = loadNearestFilterTexture(metadata.texture)
513
+ partRoot.traverse(child => {
514
+ if (child instanceof THREE.Mesh) {
515
+ child.material = new THREE.MeshBasicMaterial({
516
+ map: texture,
517
+ transparent: true,
518
+ alphaTest: 0.1
519
+ })
520
+ }
521
+ })
522
+ }
523
+ if (gltf.animations?.length) {
524
+ this.animations = [...(this.animations ?? []), ...gltf.animations]
525
+ const controller = createAnimatedObject(partRoot, gltf.animations)
526
+ this.animationControllers.push(controller)
527
+ const animationName = metadata?.animation
528
+ const loop = metadata?.animationLoop ?? true
529
+ if (animationName) {
530
+ controller.playAnimation(animationName, loop)
531
+ } else {
532
+ controller.playAnimation(gltf.animations[0].name, loop)
518
533
  }
519
- })
520
- }
521
- if (gltf.animations?.length) {
522
- this.animations = [...(this.animations ?? []), ...gltf.animations]
523
- const controller = createAnimatedObject(partRoot, gltf.animations)
524
- this.animationControllers.push(controller)
525
- const animationName = metadata?.animation
526
- const loop = metadata?.animationLoop ?? true
527
- if (animationName) {
528
- controller.playAnimation(animationName, loop)
529
- } else {
530
- controller.playAnimation(gltf.animations[0].name, loop)
531
534
  }
532
- }
533
- }).catch(err => {
534
- console.error('Failed to load GLTF model:', err)
535
- })
535
+ })
536
+ .catch(err => {
537
+ console.error('Failed to load GLTF model:', err)
538
+ })
536
539
  break
537
540
  }
538
541
  case 'obj': {
@@ -553,7 +556,7 @@ export class EntityMesh {
553
556
  transparent: true,
554
557
  alphaTest: 0.1
555
558
  })
556
- obj.traverse((child) => {
559
+ obj.traverse(child => {
557
560
  if (child instanceof THREE.Mesh) {
558
561
  child.material = material
559
562
  }
@@ -574,12 +577,13 @@ export class EntityMesh {
574
577
  for (const [name, jsonModel] of Object.entries(modelData.geometry)) {
575
578
  const texture = metadata?.textures?.[name] ?? modelData.textures?.[name]
576
579
  if (!texture) continue
577
- const mesh = getMesh(worldRenderer,
578
- texture.endsWith('.png') || texture.startsWith('data:image/') || texture.startsWith('block:')
579
- ? texture : texture + '.png',
580
+ const mesh = getMesh(
581
+ worldRenderer,
582
+ texture.endsWith('.png') || texture.startsWith('data:image/') || texture.startsWith('block:') ? texture : texture + '.png',
580
583
  jsonModel as JsonModel,
581
584
  overrides,
582
- debugFlags)
585
+ debugFlags
586
+ )
583
587
  mesh.name = `geometry_${name}`
584
588
  partRoot.add(mesh)
585
589
  }
@@ -595,15 +599,15 @@ export class EntityMesh {
595
599
  if (externalModels[type]) {
596
600
  const objLoader = new OBJLoader()
597
601
  const texturePathMap = {
598
- 'zombie_horse': `textures/${version}/entity/horse/horse_zombie.png`,
599
- 'husk': huskPng,
600
- 'skeleton_horse': `textures/${version}/entity/horse/horse_skeleton.png`,
601
- 'donkey': `textures/${version}/entity/horse/donkey.png`,
602
- 'mule': `textures/${version}/entity/horse/mule.png`,
603
- 'ocelot': ocelotPng,
604
- 'arrow': arrowTexture,
605
- 'spectral_arrow': spectralArrowTexture,
606
- 'tipped_arrow': tippedArrowTexture
602
+ zombie_horse: `textures/${version}/entity/horse/horse_zombie.png`,
603
+ husk: huskPng,
604
+ skeleton_horse: `textures/${version}/entity/horse/horse_skeleton.png`,
605
+ donkey: `textures/${version}/entity/horse/donkey.png`,
606
+ mule: `textures/${version}/entity/horse/mule.png`,
607
+ ocelot: ocelotPng,
608
+ arrow: arrowTexture,
609
+ spectral_arrow: spectralArrowTexture,
610
+ tipped_arrow: tippedArrowTexture
607
611
  }
608
612
  const tempTextureMap = texturePathMap[originalType] || texturePathMap[type]
609
613
  if (tempTextureMap) {
@@ -625,15 +629,16 @@ export class EntityMesh {
625
629
  if (scale) obj.scale.set(scale, scale, scale)
626
630
  const offset = offsetEntity[originalType]
627
631
  if (offset) obj.position.set(offset.x, offset.y, offset.z)
628
- obj.traverse((child) => {
632
+ obj.traverse(child => {
629
633
  if (child instanceof THREE.Mesh) {
630
634
  child.material = material
631
635
  // todo
632
636
  if (child.name === 'Head layer') child.visible = false
633
- if (child.name === 'Head' && overrides.rotation?.head) { // todo
634
- child.rotation.x -= (overrides.rotation.head.x ?? 0) * Math.PI / 180
635
- child.rotation.y -= (overrides.rotation.head.y ?? 0) * Math.PI / 180
636
- child.rotation.z -= (overrides.rotation.head.z ?? 0) * Math.PI / 180
637
+ if (child.name === 'Head' && overrides.rotation?.head) {
638
+ // todo
639
+ child.rotation.x -= ((overrides.rotation.head.x ?? 0) * Math.PI) / 180
640
+ child.rotation.y -= ((overrides.rotation.head.y ?? 0) * Math.PI) / 180
641
+ child.rotation.z -= ((overrides.rotation.head.z ?? 0) * Math.PI) / 180
637
642
  }
638
643
  }
639
644
  })
@@ -661,12 +666,13 @@ export class EntityMesh {
661
666
  const texture = overrides.textures?.[name] ?? e.textures[name]
662
667
  if (!texture) continue
663
668
  // console.log(JSON.stringify(jsonModel, null, 2))
664
- const mesh = getMesh(worldRenderer,
665
- texture.endsWith('.png') || texture.startsWith('data:image/') || texture.startsWith('block:')
666
- ? texture : texture + '.png',
669
+ const mesh = getMesh(
670
+ worldRenderer,
671
+ texture.endsWith('.png') || texture.startsWith('data:image/') || texture.startsWith('block:') ? texture : texture + '.png',
667
672
  jsonModel,
668
673
  overrides,
669
- debugFlags)
674
+ debugFlags
675
+ )
670
676
  mesh.name = `geometry_${name}`
671
677
  this.mesh.add(mesh)
672
678
  }
@@ -1,7 +1,7 @@
1
1
  //@ts-check
2
2
  import { PlayerAnimation } from 'skinview3d'
3
3
 
4
- const clamp01 = (v) => Math.max(0, Math.min(1, v))
4
+ const clamp01 = v => Math.max(0, Math.min(1, v))
5
5
  const mix = (a, b, t) => a + (b - a) * t
6
6
 
7
7
  function updateElytraRightWing(player) {
@@ -90,7 +90,7 @@ export class WalkingGeneralSwing extends PlayerAnimation {
90
90
  capeRot: player.cape.rotation.clone(),
91
91
 
92
92
  elytraPos: player.elytra.position.clone(),
93
- elytraRot: player.elytra.rotation.clone(),
93
+ elytraRot: player.elytra.rotation.clone()
94
94
  }
95
95
  }
96
96
 
@@ -213,7 +213,7 @@ const HitAnimation = {
213
213
  player.skin.leftArm.position.z = swing * 0.3
214
214
  player.skin.leftArm.position.x = 5 - swing * 0.05
215
215
  }
216
- },
216
+ }
217
217
  }
218
218
 
219
219
  function applyCrouchPose(player, crouchBlend) {
@@ -19,19 +19,19 @@ export { default as elytraTexture } from 'mc-assets/dist/other-textures/latest/e
19
19
  export { default as armorModel } from './armorModels.json'
20
20
 
21
21
  export const armorTextures = {
22
- 'leather_layer_1': leatherLayer1,
23
- 'leather_layer_1_overlay': leatherLayer1Overlay,
24
- 'leather_layer_2': leatherLayer2,
25
- 'leather_layer_2_overlay': leatherLayer2Overlay,
26
- 'chainmail_layer_1': chainmailLayer1,
27
- 'chainmail_layer_2': chainmailLayer2,
28
- 'iron_layer_1': ironLayer1,
29
- 'iron_layer_2': ironLayer2,
30
- 'diamond_layer_1': diamondLayer1,
31
- 'diamond_layer_2': diamondLayer2,
32
- 'golden_layer_1': goldenLayer1,
33
- 'golden_layer_2': goldenLayer2,
34
- 'netherite_layer_1': netheriteLayer1,
35
- 'netherite_layer_2': netheriteLayer2,
36
- 'turtle_layer_1': turtleLayer1
22
+ leather_layer_1: leatherLayer1,
23
+ leather_layer_1_overlay: leatherLayer1Overlay,
24
+ leather_layer_2: leatherLayer2,
25
+ leather_layer_2_overlay: leatherLayer2Overlay,
26
+ chainmail_layer_1: chainmailLayer1,
27
+ chainmail_layer_2: chainmailLayer2,
28
+ iron_layer_1: ironLayer1,
29
+ iron_layer_2: ironLayer2,
30
+ diamond_layer_1: diamondLayer1,
31
+ diamond_layer_2: diamondLayer2,
32
+ golden_layer_1: goldenLayer1,
33
+ golden_layer_2: goldenLayer2,
34
+ netherite_layer_1: netheriteLayer1,
35
+ netherite_layer_2: netheriteLayer2,
36
+ turtle_layer_1: turtleLayer1
37
37
  }
@@ -43,7 +43,7 @@ export class AnimationManager {
43
43
 
44
44
  // Set up onBeforeRender callback for renderable objects
45
45
  // onBeforeRender only works on renderable objects (Mesh, Line, Points, Sprite)
46
- this.object.traverse((child) => {
46
+ this.object.traverse(child => {
47
47
  if (child instanceof THREE.Mesh || child instanceof THREE.Line || child instanceof THREE.Points || child instanceof THREE.Sprite) {
48
48
  const originalOnBeforeRender = child.onBeforeRender
49
49
  child.onBeforeRender = (renderer, scene, camera, geometry, material, group) => {
@@ -132,10 +132,7 @@ export class AnimationManager {
132
132
  /**
133
133
  * Convenience function to create and manage animations for an object
134
134
  */
135
- export function createAnimatedObject(
136
- object: THREE.Object3D,
137
- animations: THREE.AnimationClip[]
138
- ) {
135
+ export function createAnimatedObject(object: THREE.Object3D, animations: THREE.AnimationClip[]) {
139
136
  const manager = new AnimationManager(object, animations)
140
137
  manager.createAnimationState()
141
138
 
@@ -62,7 +62,7 @@ export const FIREWORKS_CONFIG = {
62
62
  gravity: new THREE.Vector3(0, -0.005, 0),
63
63
  friction: 0.998,
64
64
  defaultParticleSize: 300,
65
- maxActiveFireworks: 5,
65
+ maxActiveFireworks: 5
66
66
  }
67
67
 
68
68
  // Utility functions
@@ -105,7 +105,13 @@ export const createFireworksTexture = () => {
105
105
  }
106
106
 
107
107
  // Point mesh creation
108
- const getPointMesh = (num: number, vels: THREE.Vector3[], type: 'seed' | 'trail' | 'default', texture: THREE.Texture, particleSize = FIREWORKS_CONFIG.defaultParticleSize) => {
108
+ const getPointMesh = (
109
+ num: number,
110
+ vels: THREE.Vector3[],
111
+ type: 'seed' | 'trail' | 'default',
112
+ texture: THREE.Texture,
113
+ particleSize = FIREWORKS_CONFIG.defaultParticleSize
114
+ ) => {
109
115
  const bufferGeometry = new THREE.BufferGeometry()
110
116
  const vertices: number[] = []
111
117
  const velocities: number[] = []
@@ -175,13 +181,13 @@ const getPointMesh = (num: number, vels: THREE.Vector3[], type: 'seed' | 'trail'
175
181
  const shaderMaterial = new THREE.RawShaderMaterial({
176
182
  uniforms: {
177
183
  size: { value: FIREWORKS_CONFIG.textureSize },
178
- texture: { value: texture },
184
+ texture: { value: texture }
179
185
  },
180
186
  transparent: true,
181
187
  depthWrite: false,
182
188
  blending: THREE.AdditiveBlending,
183
189
  vertexShader,
184
- fragmentShader,
190
+ fragmentShader
185
191
  })
186
192
 
187
193
  return new THREE.Points(bufferGeometry, shaderMaterial)
@@ -193,13 +199,13 @@ export class ParticleMesh {
193
199
  timerStartFading: number
194
200
  mesh: THREE.Points
195
201
 
196
- constructor (num: number, vels: THREE.Vector3[], type: 'seed' | 'trail' | 'default', texture: THREE.Texture, particleSize?: number) {
202
+ constructor(num: number, vels: THREE.Vector3[], type: 'seed' | 'trail' | 'default', texture: THREE.Texture, particleSize?: number) {
197
203
  this.particleNum = num
198
204
  this.timerStartFading = 10
199
205
  this.mesh = getPointMesh(num, vels, type, texture, particleSize)
200
206
  }
201
207
 
202
- update (gravity: THREE.Vector3) {
208
+ update(gravity: THREE.Vector3) {
203
209
  if (this.timerStartFading > 0) this.timerStartFading -= 0.3
204
210
 
205
211
  const position = this.mesh.geometry.attributes.position as THREE.BufferAttribute
@@ -234,18 +240,18 @@ export class ParticleMesh {
234
240
  color.needsUpdate = true
235
241
  }
236
242
 
237
- disposeAll () {
243
+ disposeAll() {
238
244
  this.mesh.geometry.dispose()
239
245
  ;(this.mesh.material as THREE.Material).dispose()
240
246
  }
241
247
  }
242
248
 
243
249
  export class ParticleSeedMesh extends ParticleMesh {
244
- constructor (num: number, vels: THREE.Vector3[], texture: THREE.Texture) {
250
+ constructor(num: number, vels: THREE.Vector3[], texture: THREE.Texture) {
245
251
  super(num, vels, 'seed', texture)
246
252
  }
247
253
 
248
- update (gravity: THREE.Vector3) {
254
+ update(gravity: THREE.Vector3) {
249
255
  const position = this.mesh.geometry.attributes.position as THREE.BufferAttribute
250
256
  const velocity = this.mesh.geometry.attributes.velocity as THREE.BufferAttribute
251
257
  const color = this.mesh.geometry.attributes.color as THREE.BufferAttribute
@@ -284,11 +290,11 @@ export class ParticleSeedMesh extends ParticleMesh {
284
290
  }
285
291
 
286
292
  export class ParticleTailMesh extends ParticleMesh {
287
- constructor (num: number, vels: THREE.Vector3[], texture: THREE.Texture) {
293
+ constructor(num: number, vels: THREE.Vector3[], texture: THREE.Texture) {
288
294
  super(num, vels, 'trail', texture)
289
295
  }
290
296
 
291
- update (gravity: THREE.Vector3) {
297
+ update(gravity: THREE.Vector3) {
292
298
  const position = this.mesh.geometry.attributes.position as THREE.BufferAttribute
293
299
  const velocity = this.mesh.geometry.attributes.velocity as THREE.BufferAttribute
294
300
  const color = this.mesh.geometry.attributes.color as THREE.BufferAttribute
@@ -336,7 +342,7 @@ export class BasicFireworks {
336
342
  texture: THREE.Texture
337
343
  particleSize: number
338
344
 
339
- constructor (texture: THREE.Texture, particleSize = FIREWORKS_CONFIG.defaultParticleSize, startPosition?: THREE.Vector3) {
345
+ constructor(texture: THREE.Texture, particleSize = FIREWORKS_CONFIG.defaultParticleSize, startPosition?: THREE.Vector3) {
340
346
  this.meshGroup = new THREE.Group()
341
347
  this.isExplode = false
342
348
  this.texture = texture
@@ -351,7 +357,7 @@ export class BasicFireworks {
351
357
  this.flowerSizeRate = THREE.MathUtils.mapLinear(this.petalsNum, min, max, 0.4, 0.7)
352
358
  }
353
359
 
354
- getSeed (startPosition?: THREE.Vector3): ParticleSeedMesh {
360
+ getSeed(startPosition?: THREE.Vector3): ParticleSeedMesh {
355
361
  const num = 40
356
362
  const vels: THREE.Vector3[] = []
357
363
 
@@ -376,7 +382,7 @@ export class BasicFireworks {
376
382
  return pm
377
383
  }
378
384
 
379
- explode (pos: THREE.Vector3) {
385
+ explode(pos: THREE.Vector3) {
380
386
  this.isExplode = true
381
387
  this.flower = this.getFlower(pos)
382
388
  this.meshGroup.add(this.flower.mesh)
@@ -384,7 +390,7 @@ export class BasicFireworks {
384
390
  this.seed.disposeAll()
385
391
  }
386
392
 
387
- getFlower (pos: THREE.Vector3): ParticleMesh {
393
+ getFlower(pos: THREE.Vector3): ParticleMesh {
388
394
  const num = this.petalsNum
389
395
  const vels: THREE.Vector3[] = []
390
396
  let radius: number
@@ -425,7 +431,7 @@ export class BasicFireworks {
425
431
  return particleMesh
426
432
  }
427
433
 
428
- update (gravity: THREE.Vector3) {
434
+ update(gravity: THREE.Vector3) {
429
435
  if (this.isExplode) {
430
436
  this.flower!.update(gravity)
431
437
  if (this.life > 0) this.life -= 1
@@ -434,7 +440,7 @@ export class BasicFireworks {
434
440
  }
435
441
  }
436
442
 
437
- drawTail () {
443
+ drawTail() {
438
444
  this.seed.update(FIREWORKS_CONFIG.gravity)
439
445
 
440
446
  const position = this.seed.mesh.geometry.attributes.position as THREE.BufferAttribute
@@ -479,7 +485,7 @@ export class RichFireworks extends BasicFireworks {
479
485
  tailMeshGroup: THREE.Group
480
486
  tails: ParticleTailMesh[]
481
487
 
482
- constructor (texture: THREE.Texture, particleSize = FIREWORKS_CONFIG.defaultParticleSize, startPosition?: THREE.Vector3) {
488
+ constructor(texture: THREE.Texture, particleSize = FIREWORKS_CONFIG.defaultParticleSize, startPosition?: THREE.Vector3) {
483
489
  super(texture, particleSize, startPosition)
484
490
 
485
491
  const max = 150
@@ -490,7 +496,7 @@ export class RichFireworks extends BasicFireworks {
490
496
  this.tails = []
491
497
  }
492
498
 
493
- explode (pos: THREE.Vector3) {
499
+ explode(pos: THREE.Vector3) {
494
500
  this.isExplode = true
495
501
  this.flower = this.getFlower(pos)
496
502
  this.tails = this.getTail()
@@ -498,7 +504,7 @@ export class RichFireworks extends BasicFireworks {
498
504
  this.meshGroup.add(this.tailMeshGroup)
499
505
  }
500
506
 
501
- getTail (): ParticleTailMesh[] {
507
+ getTail(): ParticleTailMesh[] {
502
508
  const tails: ParticleTailMesh[] = []
503
509
  const num = 20
504
510
  const petalColor = this.flower!.mesh.geometry.attributes.color as THREE.BufferAttribute
@@ -537,7 +543,7 @@ export class RichFireworks extends BasicFireworks {
537
543
  return tails
538
544
  }
539
545
 
540
- update (gravity: THREE.Vector3) {
546
+ update(gravity: THREE.Vector3) {
541
547
  if (this.isExplode) {
542
548
  this.flower!.update(gravity)
543
549
 
@@ -548,11 +554,7 @@ export class RichFireworks extends BasicFireworks {
548
554
  tail.update(gravity)
549
555
 
550
556
  const { x, y, z } = getOffsetXYZ(i)
551
- const flowerPos = new THREE.Vector3(
552
- flowerGeometry.array[x],
553
- flowerGeometry.array[y],
554
- flowerGeometry.array[z]
555
- )
557
+ const flowerPos = new THREE.Vector3(flowerGeometry.array[x], flowerGeometry.array[y], flowerGeometry.array[z])
556
558
 
557
559
  const position = tail.mesh.geometry.attributes.position as THREE.BufferAttribute
558
560
  const velocity = tail.mesh.geometry.attributes.velocity as THREE.BufferAttribute
@@ -589,7 +591,7 @@ export class FireworksManager {
589
591
  particleSize: number
590
592
  maxFireworks: number
591
593
 
592
- constructor (scene: THREE.Scene, sceneOrigin: SceneOrigin, config?: FireworksManagerConfig) {
594
+ constructor(scene: THREE.Scene, sceneOrigin: SceneOrigin, config?: FireworksManagerConfig) {
593
595
  this.fireworksInstances = []
594
596
  this.scene = scene
595
597
  this.sceneOrigin = sceneOrigin
@@ -598,7 +600,7 @@ export class FireworksManager {
598
600
  this.maxFireworks = config?.maxActiveFireworks ?? FIREWORKS_CONFIG.maxActiveFireworks
599
601
  }
600
602
 
601
- launchFirework (options?: FireworkLaunchOptions) {
603
+ launchFirework(options?: FireworkLaunchOptions) {
602
604
  if (this.fireworksInstances.length >= this.maxFireworks) return
603
605
 
604
606
  const particleSize = options?.particleSize ?? this.particleSize
@@ -622,11 +624,11 @@ export class FireworksManager {
622
624
  }
623
625
  }
624
626
 
625
- repositionAll (): void {
627
+ repositionAll(): void {
626
628
  // No-op: tracked objects are automatically repositioned by SceneOrigin
627
629
  }
628
630
 
629
- update () {
631
+ update() {
630
632
  const explodedIndexList: number[] = []
631
633
 
632
634
  for (let i = this.fireworksInstances.length - 1; i >= 0; i--) {
@@ -656,7 +658,7 @@ export class FireworksManager {
656
658
  }
657
659
  }
658
660
 
659
- clear () {
661
+ clear() {
660
662
  for (const instance of this.fireworksInstances) {
661
663
  this.sceneOrigin.removeAndUntrack(instance.meshGroup)
662
664
  instance.seed.disposeAll()
@@ -668,7 +670,7 @@ export class FireworksManager {
668
670
  this.fireworksInstances = []
669
671
  }
670
672
 
671
- dispose () {
673
+ dispose() {
672
674
  this.clear()
673
675
  this.texture.dispose()
674
676
  }