minerender 2.1.0-beta.5 → 2.1.0-beta.7

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 (102) hide show
  1. package/dist/browser/esm/Materials.mjs +6 -3
  2. package/dist/browser/esm/Materials.mjs.map +1 -1
  3. package/dist/browser/esm/Ticker.mjs +3 -1
  4. package/dist/browser/esm/Ticker.mjs.map +1 -1
  5. package/dist/browser/esm/UVMapper.mjs +9 -9
  6. package/dist/browser/esm/UVMapper.mjs.map +1 -1
  7. package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
  8. package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
  9. package/dist/browser/esm/assets/AssetKey.mjs +1 -1
  10. package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
  11. package/dist/browser/esm/assets/AssetLoader.mjs +5 -5
  12. package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
  13. package/dist/browser/esm/assets/Assets.mjs +1 -5
  14. package/dist/browser/esm/assets/Assets.mjs.map +1 -1
  15. package/dist/browser/esm/assets/BlockEntities.mjs +3 -1
  16. package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
  17. package/dist/browser/esm/assets/BlockStates.mjs +1 -1
  18. package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
  19. package/dist/browser/esm/assets/Entities.mjs +1 -1
  20. package/dist/browser/esm/assets/Entities.mjs.map +1 -1
  21. package/dist/browser/esm/assets/Fonts.mjs +31 -4
  22. package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
  23. package/dist/browser/esm/assets/Models.mjs +1 -1
  24. package/dist/browser/esm/assets/Models.mjs.map +1 -1
  25. package/dist/browser/esm/assets/_fonts/Unihex.mjs +168 -0
  26. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
  27. package/dist/browser/esm/assets/index.mjs +1 -0
  28. package/dist/browser/esm/assets/index.mjs.map +1 -1
  29. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +19 -9
  30. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  31. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
  32. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
  33. package/dist/browser/esm/cache/Caching.mjs +2 -0
  34. package/dist/browser/esm/cache/Caching.mjs.map +1 -1
  35. package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs +62 -11
  36. package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
  37. package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
  38. package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
  39. package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
  40. package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
  41. package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
  42. package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
  43. package/dist/browser/esm/gui/GuiText.mjs +4 -3
  44. package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
  45. package/dist/browser/esm/image/ImageLoader.mjs +3 -3
  46. package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
  47. package/dist/browser/esm/index.browser.d.mts +115 -20
  48. package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
  49. package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
  50. package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
  51. package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
  52. package/dist/browser/esm/model/block/scene/BlockObject.mjs +3 -1
  53. package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
  54. package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
  55. package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
  56. package/dist/browser/esm/model/scene/ModelObject.mjs +8 -4
  57. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  58. package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
  59. package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
  60. package/dist/browser/esm/renderer/Renderer.mjs +4 -2
  61. package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
  62. package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
  63. package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
  64. package/dist/browser/esm/request/Requests.mjs +3 -3
  65. package/dist/browser/esm/request/Requests.mjs.map +1 -1
  66. package/dist/browser/esm/skin/Skins.mjs +6 -4
  67. package/dist/browser/esm/skin/Skins.mjs.map +1 -1
  68. package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
  69. package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
  70. package/dist/browser/esm/util/log.mjs +75 -0
  71. package/dist/browser/esm/util/log.mjs.map +1 -1
  72. package/dist/browser/esm/util/model.mjs +7 -7
  73. package/dist/browser/esm/util/model.mjs.map +1 -1
  74. package/dist/browser/esm/util/performance.mjs.map +1 -1
  75. package/dist/browser/esm/world/Chunk.mjs +8 -5
  76. package/dist/browser/esm/world/Chunk.mjs.map +1 -1
  77. package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
  78. package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
  79. package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
  80. package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
  81. package/dist/browser/esm/world/SectionMesh.mjs +4 -0
  82. package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
  83. package/dist/browser/esm/world/SectionModels.mjs +2 -2
  84. package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
  85. package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
  86. package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
  87. package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
  88. package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
  89. package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
  90. package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
  91. package/dist/browser/index.d.ts +115 -20
  92. package/dist/browser/index.js +3449 -3025
  93. package/dist/browser/index.js.map +1 -1
  94. package/dist/bundle.js +13217 -12745
  95. package/dist/bundle.js.map +1 -1
  96. package/dist/node/index.d.mts +115 -20
  97. package/dist/node/index.d.ts +115 -20
  98. package/dist/node/index.js +3477 -3046
  99. package/dist/node/index.js.map +1 -1
  100. package/dist/node/index.mjs +3456 -3027
  101. package/dist/node/index.mjs.map +1 -1
  102. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/renderer/SceneObject.ts"],"sourcesContent":["import { BoxGeometry, Color, EdgesGeometry, Euler, InstancedBufferAttribute, InstancedMesh, LineBasicMaterial, LineSegments, Matrix4, Mesh, Object3D, Quaternion, Scene, Vector3 } from \"three\";\nimport { ModelElement, ModelFaces } from \"../model/ModelElement\";\nimport { Geometries } from \"../Geometries\";\nimport { facesToUvArray } from \"../util/_internal/cubeUv\";\nimport { DoubleArray, TripleArray } from \"../model/Model\";\nimport { Axis, axisToVec3 } from \"../Axis\";\nimport type { BufferGeometry, Material, Object3DEventMap } from \"three\";\nimport { SkinPart } from \"../skin/SkinPart\";\nimport { changeEvent, Maybe } from \"../util/util\";\nimport { InstanceReference } from \"../instance/InstanceReference\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport { isMesh } from \"../util/three\";\nimport { Disposable, isDisposable } from \"../Disposable\";\nimport { SceneObjectOptions } from \"./SceneObjectOptions\";\nimport { merge } from \"../util/_internal/merge\";\nimport { Instanceable } from \"../instance/Instanceable\";\nimport type { MineRenderScene } from \"./MineRenderScene\";\nimport { Transformable } from \"../Transformable\";\nimport { prefix } from \"../util/log\";\n\nconst p = prefix(\"SceneObject\");\n\n/**\n * Base for renderable Minecraft objects, with named parts and optional shared instances.\n * Use {@link notifyDirty} after changing a part directly so the renderer redraws it.\n */\nexport class SceneObject extends Object3D<Object3DEventMap & { change: {} }> implements Disposable, Instanceable, Transformable {\n\n public readonly isSceneObject: true = true;\n\n public static readonly DEFAULT_OPTIONS: SceneObjectOptions = merge({}, <SceneObjectOptions>{\n instanceMeshes: true,\n maxInstanceCount: 50,\n mergeMeshes: true,\n wireframe: false\n });\n public readonly options: SceneObjectOptions;\n\n private _scene: Maybe<MineRenderScene>;\n\n private materialCallbacks: { [key: string]: Array<(mat: Material, key: string) => void>; } = {};\n\n protected _isInstanced: boolean = false;\n _instanceCounter: number = 0;\n protected instanceMesh?: InstancedMesh;\n private readonly instanceReferences = new Map<number, InstanceReference<SceneObject>>();\n private readonly freeInstanceIndices: number[] = [];\n private readonly hiddenInstanceMatrices = new Map<number, Matrix4>();\n\n constructor(options?: Partial<SceneObjectOptions>) {\n super();\n this.options = merge({}, SceneObject.DEFAULT_OPTIONS, options ?? {});\n console.log(\"SceneObject options\", this.options);\n }\n\n public set scene(scene: MineRenderScene) {\n if (!!this._scene) throw new MineRenderError(\"Scene already set\");\n this._scene = scene;\n }\n\n public get scene(): MineRenderScene {\n if (!this._scene) throw new MineRenderError(\"Scene not set\");\n return this._scene;\n }\n\n async init(): Promise<void> {\n }\n\n /** Marks ancestor scenes for redraw and emits a `change` event. */\n public notifyDirty() {\n this.traverseAncestors(parent => {\n const scene = parent as MineRenderScene;\n if (scene.isMineRenderScene) scene.dirty = true;\n });\n this.dispatchEvent(changeEvent);\n }\n\n //<editor-fold desc=\"GROUPS\">\n\n protected createAndAddGroup(name?: string, x: number = 0, y: number = 0, z: number = 0, offsetAxis?: Axis, offset: number = 0): Object3D {\n const group = this.createGroup(name, x, y, z, offsetAxis, offset);\n\n if (name) {\n let existing = this.getObjectByName(group.name);\n if (existing) {\n this.remove(existing);\n }\n }\n\n console.log(\"add\", group, group.name);\n this.add(group);\n this.notifyDirty();\n return group;\n }\n\n protected createGroup(name?: string, x: number = 0, y: number = 0, z: number = 0, offsetAxis?: Axis, offset: number = 0): Object3D {\n const obj = new Object3D();\n if (name) {\n obj.name = `group:${name}`;\n }\n if (x > 0 || y > 0 || z > 0) {\n obj.position.set(x, y, z);\n }\n if (offsetAxis) {\n obj.translateOnAxis(axisToVec3(offsetAxis), offset);\n }\n return obj;\n }\n\n /**\n * Finds a named part, such as `head`, without the internal `group:` prefix.\n * Returns `undefined` when the group does not exist.\n */\n public getGroupByName(name: string): Maybe<Object3D> {\n return this.getObjectByName(`group:${name}`) as Object3D;\n }\n\n /**\n * Changes a named group's visibility and requests a redraw.\n * @param name - Part name without the `group:` prefix.\n * @param visible - Visibility to assign. Omit it to toggle the current value.\n * @returns The resulting visibility, or `false` if the group does not exist.\n */\n public toggleGroupVisibility(name: string, visible?: boolean): boolean {\n return this.toggleObjectVisibility(this.getGroupByName(name), visible);\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"MESHES\">\n\n protected addOrReplaceMesh(mesh: Mesh, parent: Object3D, name?: string) {\n if (name) {\n const existing = parent.getObjectByName(mesh.name);\n if (existing) {\n console.log(\"remove\", existing.name, existing);\n parent.remove(existing);\n }\n }\n console.log(\"add\", mesh, mesh.name);\n parent.add(mesh);\n }\n\n protected createAndAddMesh(name?: string, group?: Object3D, geometry?: BufferGeometry, material?: Material | Material[], offsetAxis?: Axis, offset: number = 0): Mesh {\n const mesh = this.createMesh(name, geometry, material, offsetAxis, offset);\n if (group) {\n this.addOrReplaceMesh(mesh, group, name);\n } else {\n this.addOrReplaceMesh(mesh, this, name);\n }\n this.notifyDirty();\n return mesh;\n }\n\n protected createMesh(name?: string, geometry?: BufferGeometry, material?: Material | Material[], offsetAxis?: Axis, offset: number = 0): Mesh {\n const mesh = new Mesh(geometry, material);\n if (name) {\n mesh.name = `mesh:${name}`;\n }\n\n //TODO\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n\n if (offsetAxis) {\n mesh.translateOnAxis(axisToVec3(offsetAxis), offset);\n }\n return mesh;\n }\n\n protected createInstancedMesh(name: Maybe<string>, geometry: BufferGeometry, material: Material | Material[], count: number): InstancedMesh {\n const mesh = new InstancedMesh(geometry, material, count);\n mesh.count = 0;\n this.instanceMesh = mesh;\n this._isInstanced = true;\n if (name) {\n mesh.name = `mesh:${name}`;\n }\n return mesh;\n }\n\n /**\n * Finds a named mesh without the internal `mesh:` prefix, or returns `undefined`.\n */\n public getMeshByName(name: string): Maybe<Mesh> {\n return this.getObjectByName(`mesh:${name}`) as Mesh;\n }\n\n /**\n * Changes a named mesh's visibility and requests a redraw.\n * @param name - Mesh name without the `mesh:` prefix.\n * @param visible - Visibility to assign. Omit it to toggle the current value.\n * @returns The resulting visibility, or `false` if the mesh does not exist.\n */\n public toggleMeshVisibility(name: string, visible?: boolean): boolean {\n return this.toggleObjectVisibility(this.getMeshByName(name), visible);\n }\n\n public iterateAllMeshes(cb: (mesh: Mesh) => void) {\n this.traverse(obj => {\n if (isMesh(obj)) cb(obj);\n });\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"GEOMETRIES\">\n\n protected _getBoxGeometryFromDimensions([width, height, depth]: TripleArray, faces: ModelFaces, originalTextureSize: DoubleArray, actualTextureSize: DoubleArray): BoxGeometry {\n const uv = facesToUvArray(faces, originalTextureSize, actualTextureSize);\n return Geometries.getBox({\n width,\n height,\n depth,\n uv\n });\n }\n\n protected _getBoxGeometryFromElement(element: ModelElement): BoxGeometry {\n const width = element.to[0] - element.from[0];\n const height = element.to[1] - element.from[1];\n const depth = element.to[2] - element.from[2];\n\n const uv = element.mappedUv;\n\n return Geometries.getBox({\n width,\n height,\n depth,\n uv\n });\n }\n\n protected _getBoxGeometryForDimensionsAndUv(width: number, height: number, depth: number, uv: number[]): BoxGeometry {\n return Geometries.getBox({\n width,\n height,\n depth,\n uv\n });\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"INSTANCING\">\n\n get isInstanced(): boolean {\n return this._isInstanced;\n }\n\n /** Number of live placements, excluding released instance slots. */\n get instanceCounter(): number {\n return this._instanceCounter;\n }\n\n protected constructInstanceReference(i: number): InstanceReference<SceneObject> {\n return new InstanceReference<this>(this, i);\n }\n\n /** Allocates a placement of this instanced object, reusing a released slot when available. */\n nextInstance(): InstanceReference<SceneObject> {\n const mesh = this.instanceMesh;\n if (!mesh) throw new MineRenderError(\"Object is not instanced\");\n const index = this.freeInstanceIndices.pop() ?? mesh.count;\n if (index >= mesh.instanceMatrix.count) this.growInstances(index + 1);\n const reference = this.constructInstanceReference(index);\n this.instanceReferences.set(index, reference);\n this._instanceCounter = this.instanceReferences.size;\n mesh.count = Math.max(mesh.count, index + 1);\n if (mesh.instanceColor) {\n mesh.setColorAt(index, new Color(0xffffff));\n mesh.instanceColor.needsUpdate = true;\n }\n if (this._scene) this._scene.stats.instanceCount++;\n this.setMatrixAt(index, new Matrix4());\n return reference;\n }\n\n /** Returns the live reference for a raycast hit on this object's instance mesh. */\n public getInstanceReference(mesh: Object3D, index: number): Maybe<InstanceReference<SceneObject>> {\n return mesh === this.instanceMesh ? this.instanceReferences.get(index) : undefined;\n }\n\n isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean {\n return this.instanceReferences.get(index) === reference;\n }\n\n removeInstanceAt(index: number): void {\n if (!this.instanceReferences.has(index)) return;\n const mesh = this.instanceMesh!;\n this.hiddenInstanceMatrices.delete(index);\n this.setMatrixAt(index, new Matrix4().makeScale(0, 0, 0));\n this.instanceReferences.delete(index);\n this.freeInstanceIndices.push(index);\n this._instanceCounter = this.instanceReferences.size;\n while (mesh.count > 0 && !this.instanceReferences.has(mesh.count - 1)) mesh.count--;\n if (this._scene) this._scene.stats.instanceCount--;\n }\n\n private growInstances(required: number): void {\n const mesh = this.instanceMesh!;\n const capacity = Math.max(required, mesh.instanceMatrix.count * 2);\n const grow = (attribute: InstancedBufferAttribute, fill: number) => {\n const array = new Float32Array(capacity * attribute.itemSize).fill(fill);\n array.set(attribute.array);\n return new InstancedBufferAttribute(array, attribute.itemSize, attribute.normalized, attribute.meshPerAttribute)\n .setUsage(attribute.usage);\n };\n const matrix = grow(mesh.instanceMatrix, 0);\n const color = mesh.instanceColor ? grow(mesh.instanceColor, 1) : null;\n // Release uploaded instance buffers before replacing their attributes.\n mesh.dispose();\n mesh.instanceMatrix = matrix;\n mesh.instanceColor = color;\n }\n\n protected *activeInstanceIndices(): Iterable<number> {\n if (this.instanceMesh) {\n yield* this.instanceReferences.keys();\n } else {\n for (let i = 0; i < this.instanceCounter; i++) yield i;\n }\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"TRANSFORMATION\">\n\n getMatrixAt(index: number, matrix: Matrix4 = new Matrix4()): Matrix4 {\n if (!this.instanceReferences.has(index)) throw new MineRenderError(\"Instance is not active\");\n const hidden = this.hiddenInstanceMatrices.get(index);\n if (hidden) {\n return matrix.copy(hidden);\n }\n this.instanceMesh!.getMatrixAt(index, matrix);\n return matrix;\n }\n\n setMatrixAt(index: number, matrix: Matrix4) {\n if (!this.instanceReferences.has(index)) throw new MineRenderError(\"Instance is not active\");\n const mesh = this.instanceMesh!;\n const hidden = this.hiddenInstanceMatrices.get(index);\n if (hidden) {\n hidden.copy(matrix);\n }\n mesh.setMatrixAt(index, hidden ? new Matrix4().makeScale(0, 0, 0) : matrix);\n mesh.instanceMatrix.needsUpdate = true;\n mesh.boundingBox = null;\n mesh.boundingSphere = null;\n this.notifyDirty();\n }\n\n setInstanceVisibleAt(index: number, visible: boolean): void {\n if (!this.instanceReferences.has(index)) {\n throw new MineRenderError(\"Instance is not active\");\n }\n const hidden = this.hiddenInstanceMatrices.get(index);\n if (visible) {\n if (!hidden) {\n return;\n }\n this.hiddenInstanceMatrices.delete(index);\n this.setMatrixAt(index, hidden);\n } else {\n if (hidden) {\n return;\n }\n const matrix = this.getMatrixAt(index);\n this.hiddenInstanceMatrices.set(index, matrix);\n this.setMatrixAt(index, matrix);\n }\n }\n\n setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n\n const oldPosition = new Vector3();\n const oldRotation = new Quaternion();\n const oldScale = new Vector3();\n\n const matrix = new Matrix4();\n if (!scale || !rotation || !position) {\n this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);\n }\n\n matrix.compose(\n position ? position : oldPosition,\n rotation ? new Quaternion().setFromEuler(rotation) : oldRotation,\n scale ? scale : oldScale\n );\n\n this.setMatrixAt(index, matrix);\n }\n\n setPositionAt(index: number, position: Vector3) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n this.setPositionRotationScaleAt(index, position);\n }\n\n getPositionAt(index: number, vector: Vector3 = new Vector3()): Vector3 {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const matrix = this.getMatrixAt(index)\n vector.setFromMatrixPosition(matrix);\n return vector;\n }\n\n setRotationAt(index: number, rotation: Euler) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n this.setPositionRotationScaleAt(index, undefined, rotation, undefined);\n }\n\n getRotationAt(index: number, euler: Euler = new Euler()): Euler {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const rotation = new Quaternion();\n this.getMatrixAt(index).decompose(new Vector3(), rotation, new Vector3());\n return euler.setFromQuaternion(rotation);\n }\n\n setScaleAt(index: number, scale: Vector3) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n this.setPositionRotationScaleAt(index, undefined, undefined, scale);\n }\n\n getScaleAt(index: number, vector: Vector3 = new Vector3()): Vector3 {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const matrix = this.getMatrixAt(index)\n vector.setFromMatrixScale(matrix);\n return vector;\n }\n\n /** Updates supplied transform components. For a shared model, affects every live instance. */\n setPositionRotationScale(position?: Vector3, rotation?: Euler, scale?: Vector3): void {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, position, rotation, scale);\n }\n } else {\n if (position) {\n this.position.set(position.x, position.y, position.z);\n }\n if (rotation) {\n this.rotation.set(rotation.x, rotation.y, rotation.z);\n }\n if (scale) {\n this.scale.set(scale.x, scale.y, scale.z);\n }\n }\n this.notifyDirty();\n }\n\n /** Sets position in scene units. For a shared model, updates every live instance. */\n setPosition(position: Vector3) {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, position);\n }\n } else {\n this.position.set(position.x, position.y, position.z);\n }\n this.notifyDirty();\n }\n\n getPosition(): Vector3 {\n if (this.isInstanced) {\n return this.getPositionAt(this.instanceReferences.keys().next().value ?? 0);\n } else {\n return this.position;\n }\n }\n\n /** Sets rotation in radians. For a shared model, updates every live instance. */\n setRotation(rotation: Euler) {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, undefined, rotation);\n }\n } else {\n this.rotation.set(rotation.x, rotation.y, rotation.z);\n }\n this.notifyDirty();\n }\n\n getRotation(): Euler {\n if (this.isInstanced) {\n return this.getRotationAt(this.instanceReferences.keys().next().value ?? 0);\n } else {\n return this.rotation;\n }\n }\n\n /** Sets scale factors. For a shared model, updates every live instance. */\n setScale(scale: Vector3) {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, undefined, undefined, scale);\n }\n } else {\n this.scale.set(scale.x, scale.y, scale.z);\n }\n this.notifyDirty();\n }\n\n getScale(): Vector3 {\n if (this.isInstanced) {\n return this.getScaleAt(this.instanceReferences.keys().next().value ?? 0);\n } else {\n return this.scale;\n }\n }\n\n //</editor-fold>\n\n protected toggleObjectVisibility(object?: Object3D, visible?: boolean): boolean {\n if (object) {\n if (typeof visible !== \"undefined\") {\n object.visible = visible;\n } else {\n object.visible = !object.visible;\n }\n this.notifyDirty();\n return object.visible;\n }\n this.notifyDirty();\n return false;\n }\n\n //<editor-fold desc=\"CLEANUP\">\n\n public dispose() {\n this.disposeAndRemoveAllChildren();\n this.notifyDirty();\n super.dispose();\n }\n\n /** Releases instance slots and removes children, disposing children that implement Disposable. */\n public disposeAndRemoveAllChildren() {\n if (this.instanceMesh) {\n if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;\n this.instanceReferences.clear();\n this.freeInstanceIndices.length = 0;\n this.hiddenInstanceMatrices.clear();\n this._instanceCounter = 0;\n this.instanceMesh.count = 0;\n this.instanceMesh.dispose();\n this.instanceMesh.removeFromParent();\n this.instanceMesh = undefined;\n this._isInstanced = false;\n }\n while (this.children.length > 0) {\n let c = this.children[0];\n if (isDisposable(c)) {\n c.dispose();\n }\n this.remove(c);\n }\n this.notifyDirty();\n }\n\n /** Detaches the object from its parent and requests a redraw. */\n public removeFromScene() {\n this.notifyDirty();\n this.removeFromParent();\n }\n\n //</editor-fold>\n\n}\n\nexport function isSceneObject(obj: any): obj is SceneObject {\n return (<SceneObject>obj).isSceneObject;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/renderer/SceneObject.ts"],"sourcesContent":["import { BoxGeometry, Color, EdgesGeometry, Euler, InstancedBufferAttribute, InstancedMesh, LineBasicMaterial, LineSegments, Matrix4, Mesh, Object3D, Quaternion, Scene, Vector3 } from \"three\";\nimport { ModelElement, ModelFaces } from \"../model/ModelElement\";\nimport { Geometries } from \"../Geometries\";\nimport { facesToUvArray } from \"../util/_internal/cubeUv\";\nimport { DoubleArray, TripleArray } from \"../model/Model\";\nimport { Axis, axisToVec3 } from \"../Axis\";\nimport type { BufferGeometry, Material, Object3DEventMap } from \"three\";\nimport { SkinPart } from \"../skin/SkinPart\";\nimport { changeEvent, Maybe } from \"../util/util\";\nimport { InstanceReference } from \"../instance/InstanceReference\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport { isMesh } from \"../util/three\";\nimport { Disposable, isDisposable } from \"../Disposable\";\nimport { SceneObjectOptions } from \"./SceneObjectOptions\";\nimport { merge } from \"../util/_internal/merge\";\nimport { Instanceable } from \"../instance/Instanceable\";\nimport type { MineRenderScene } from \"./MineRenderScene\";\nimport { Transformable } from \"../Transformable\";\n\n\n/**\n * Base for renderable Minecraft objects, with named parts and optional shared instances.\n * Use {@link notifyDirty} after changing a part directly so the renderer redraws it.\n */\nexport class SceneObject extends Object3D<Object3DEventMap & { change: {} }> implements Disposable, Instanceable, Transformable {\n\n public readonly isSceneObject: true = true;\n\n public static readonly DEFAULT_OPTIONS: SceneObjectOptions = merge({}, <SceneObjectOptions>{\n instanceMeshes: true,\n maxInstanceCount: 50,\n mergeMeshes: true,\n wireframe: false\n });\n public readonly options: SceneObjectOptions;\n\n private _scene: Maybe<MineRenderScene>;\n\n private materialCallbacks: { [key: string]: Array<(mat: Material, key: string) => void>; } = {};\n\n protected _isInstanced: boolean = false;\n _instanceCounter: number = 0;\n protected instanceMesh?: InstancedMesh;\n private readonly instanceReferences = new Map<number, InstanceReference<SceneObject>>();\n private readonly freeInstanceIndices: number[] = [];\n private readonly hiddenInstanceMatrices = new Map<number, Matrix4>();\n\n constructor(options?: Partial<SceneObjectOptions>) {\n super();\n this.options = merge({}, SceneObject.DEFAULT_OPTIONS, options ?? {});\n }\n\n public set scene(scene: MineRenderScene) {\n if (!!this._scene) throw new MineRenderError(\"Scene already set\");\n this._scene = scene;\n }\n\n public get scene(): MineRenderScene {\n if (!this._scene) throw new MineRenderError(\"Scene not set\");\n return this._scene;\n }\n\n async init(): Promise<void> {\n }\n\n /** Marks ancestor scenes for redraw and emits a `change` event. */\n public notifyDirty() {\n this.traverseAncestors(parent => {\n const scene = parent as MineRenderScene;\n if (scene.isMineRenderScene) scene.dirty = true;\n });\n this.dispatchEvent(changeEvent);\n }\n\n //<editor-fold desc=\"GROUPS\">\n\n protected createAndAddGroup(name?: string, x: number = 0, y: number = 0, z: number = 0, offsetAxis?: Axis, offset: number = 0): Object3D {\n const group = this.createGroup(name, x, y, z, offsetAxis, offset);\n\n if (name) {\n let existing = this.getObjectByName(group.name);\n if (existing) {\n this.remove(existing);\n }\n }\n\n this.add(group);\n this.notifyDirty();\n return group;\n }\n\n protected createGroup(name?: string, x: number = 0, y: number = 0, z: number = 0, offsetAxis?: Axis, offset: number = 0): Object3D {\n const obj = new Object3D();\n if (name) {\n obj.name = `group:${name}`;\n }\n if (x > 0 || y > 0 || z > 0) {\n obj.position.set(x, y, z);\n }\n if (offsetAxis) {\n obj.translateOnAxis(axisToVec3(offsetAxis), offset);\n }\n return obj;\n }\n\n /**\n * Finds a named part, such as `head`, without the internal `group:` prefix.\n * Returns `undefined` when the group does not exist.\n */\n public getGroupByName(name: string): Maybe<Object3D> {\n return this.getObjectByName(`group:${name}`) as Object3D;\n }\n\n /**\n * Changes a named group's visibility and requests a redraw.\n * @param name - Part name without the `group:` prefix.\n * @param visible - Visibility to assign. Omit it to toggle the current value.\n * @returns The resulting visibility, or `false` if the group does not exist.\n */\n public toggleGroupVisibility(name: string, visible?: boolean): boolean {\n return this.toggleObjectVisibility(this.getGroupByName(name), visible);\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"MESHES\">\n\n protected addOrReplaceMesh(mesh: Mesh, parent: Object3D, name?: string) {\n if (name) {\n const existing = parent.getObjectByName(mesh.name);\n if (existing) {\n parent.remove(existing);\n }\n }\n parent.add(mesh);\n }\n\n protected createAndAddMesh(name?: string, group?: Object3D, geometry?: BufferGeometry, material?: Material | Material[], offsetAxis?: Axis, offset: number = 0): Mesh {\n const mesh = this.createMesh(name, geometry, material, offsetAxis, offset);\n if (group) {\n this.addOrReplaceMesh(mesh, group, name);\n } else {\n this.addOrReplaceMesh(mesh, this, name);\n }\n this.notifyDirty();\n return mesh;\n }\n\n protected createMesh(name?: string, geometry?: BufferGeometry, material?: Material | Material[], offsetAxis?: Axis, offset: number = 0): Mesh {\n const mesh = new Mesh(geometry, material);\n if (name) {\n mesh.name = `mesh:${name}`;\n }\n\n //TODO\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n\n if (offsetAxis) {\n mesh.translateOnAxis(axisToVec3(offsetAxis), offset);\n }\n return mesh;\n }\n\n protected createInstancedMesh(name: Maybe<string>, geometry: BufferGeometry, material: Material | Material[], count: number): InstancedMesh {\n const mesh = new InstancedMesh(geometry, material, count);\n mesh.count = 0;\n this.instanceMesh = mesh;\n this._isInstanced = true;\n if (name) {\n mesh.name = `mesh:${name}`;\n }\n return mesh;\n }\n\n /**\n * Finds a named mesh without the internal `mesh:` prefix, or returns `undefined`.\n */\n public getMeshByName(name: string): Maybe<Mesh> {\n return this.getObjectByName(`mesh:${name}`) as Mesh;\n }\n\n /**\n * Changes a named mesh's visibility and requests a redraw.\n * @param name - Mesh name without the `mesh:` prefix.\n * @param visible - Visibility to assign. Omit it to toggle the current value.\n * @returns The resulting visibility, or `false` if the mesh does not exist.\n */\n public toggleMeshVisibility(name: string, visible?: boolean): boolean {\n return this.toggleObjectVisibility(this.getMeshByName(name), visible);\n }\n\n public iterateAllMeshes(cb: (mesh: Mesh) => void) {\n this.traverse(obj => {\n if (isMesh(obj)) cb(obj);\n });\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"GEOMETRIES\">\n\n protected _getBoxGeometryFromDimensions([width, height, depth]: TripleArray, faces: ModelFaces, originalTextureSize: DoubleArray, actualTextureSize: DoubleArray): BoxGeometry {\n const uv = facesToUvArray(faces, originalTextureSize, actualTextureSize);\n return Geometries.getBox({\n width,\n height,\n depth,\n uv\n });\n }\n\n protected _getBoxGeometryFromElement(element: ModelElement): BoxGeometry {\n const width = element.to[0] - element.from[0];\n const height = element.to[1] - element.from[1];\n const depth = element.to[2] - element.from[2];\n\n const uv = element.mappedUv;\n\n return Geometries.getBox({\n width,\n height,\n depth,\n uv\n });\n }\n\n protected _getBoxGeometryForDimensionsAndUv(width: number, height: number, depth: number, uv: number[]): BoxGeometry {\n return Geometries.getBox({\n width,\n height,\n depth,\n uv\n });\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"INSTANCING\">\n\n get isInstanced(): boolean {\n return this._isInstanced;\n }\n\n /** Number of live placements, excluding released instance slots. */\n get instanceCounter(): number {\n return this._instanceCounter;\n }\n\n protected constructInstanceReference(i: number): InstanceReference<SceneObject> {\n return new InstanceReference<this>(this, i);\n }\n\n /** Allocates a placement of this instanced object, reusing a released slot when available. */\n nextInstance(): InstanceReference<SceneObject> {\n const mesh = this.instanceMesh;\n if (!mesh) throw new MineRenderError(\"Object is not instanced\");\n const index = this.freeInstanceIndices.pop() ?? mesh.count;\n if (index >= mesh.instanceMatrix.count) this.growInstances(index + 1);\n const reference = this.constructInstanceReference(index);\n this.instanceReferences.set(index, reference);\n this._instanceCounter = this.instanceReferences.size;\n mesh.count = Math.max(mesh.count, index + 1);\n if (mesh.instanceColor) {\n mesh.setColorAt(index, new Color(0xffffff));\n mesh.instanceColor.needsUpdate = true;\n }\n if (this._scene) this._scene.stats.instanceCount++;\n this.setMatrixAt(index, new Matrix4());\n return reference;\n }\n\n /** Returns the live reference for a raycast hit on this object's instance mesh. */\n public getInstanceReference(mesh: Object3D, index: number): Maybe<InstanceReference<SceneObject>> {\n return mesh === this.instanceMesh ? this.instanceReferences.get(index) : undefined;\n }\n\n isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean {\n return this.instanceReferences.get(index) === reference;\n }\n\n removeInstanceAt(index: number): void {\n if (!this.instanceReferences.has(index)) return;\n const mesh = this.instanceMesh!;\n this.hiddenInstanceMatrices.delete(index);\n this.setMatrixAt(index, new Matrix4().makeScale(0, 0, 0));\n this.instanceReferences.delete(index);\n this.freeInstanceIndices.push(index);\n this._instanceCounter = this.instanceReferences.size;\n while (mesh.count > 0 && !this.instanceReferences.has(mesh.count - 1)) mesh.count--;\n if (this._scene) this._scene.stats.instanceCount--;\n }\n\n private growInstances(required: number): void {\n const mesh = this.instanceMesh!;\n const capacity = Math.max(required, mesh.instanceMatrix.count * 2);\n const grow = (attribute: InstancedBufferAttribute, fill: number) => {\n const array = new Float32Array(capacity * attribute.itemSize).fill(fill);\n array.set(attribute.array);\n return new InstancedBufferAttribute(array, attribute.itemSize, attribute.normalized, attribute.meshPerAttribute)\n .setUsage(attribute.usage);\n };\n const matrix = grow(mesh.instanceMatrix, 0);\n const color = mesh.instanceColor ? grow(mesh.instanceColor, 1) : null;\n // Release uploaded instance buffers before replacing their attributes.\n mesh.dispose();\n mesh.instanceMatrix = matrix;\n mesh.instanceColor = color;\n }\n\n protected *activeInstanceIndices(): Iterable<number> {\n if (this.instanceMesh) {\n yield* this.instanceReferences.keys();\n } else {\n for (let i = 0; i < this.instanceCounter; i++) yield i;\n }\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"TRANSFORMATION\">\n\n getMatrixAt(index: number, matrix: Matrix4 = new Matrix4()): Matrix4 {\n if (!this.instanceReferences.has(index)) throw new MineRenderError(\"Instance is not active\");\n const hidden = this.hiddenInstanceMatrices.get(index);\n if (hidden) {\n return matrix.copy(hidden);\n }\n this.instanceMesh!.getMatrixAt(index, matrix);\n return matrix;\n }\n\n setMatrixAt(index: number, matrix: Matrix4) {\n if (!this.instanceReferences.has(index)) throw new MineRenderError(\"Instance is not active\");\n const mesh = this.instanceMesh!;\n const hidden = this.hiddenInstanceMatrices.get(index);\n if (hidden) {\n hidden.copy(matrix);\n }\n mesh.setMatrixAt(index, hidden ? new Matrix4().makeScale(0, 0, 0) : matrix);\n mesh.instanceMatrix.needsUpdate = true;\n mesh.boundingBox = null;\n mesh.boundingSphere = null;\n this.notifyDirty();\n }\n\n setInstanceVisibleAt(index: number, visible: boolean): void {\n if (!this.instanceReferences.has(index)) {\n throw new MineRenderError(\"Instance is not active\");\n }\n const hidden = this.hiddenInstanceMatrices.get(index);\n if (visible) {\n if (!hidden) {\n return;\n }\n this.hiddenInstanceMatrices.delete(index);\n this.setMatrixAt(index, hidden);\n } else {\n if (hidden) {\n return;\n }\n const matrix = this.getMatrixAt(index);\n this.hiddenInstanceMatrices.set(index, matrix);\n this.setMatrixAt(index, matrix);\n }\n }\n\n setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n\n const oldPosition = new Vector3();\n const oldRotation = new Quaternion();\n const oldScale = new Vector3();\n\n const matrix = new Matrix4();\n if (!scale || !rotation || !position) {\n this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);\n }\n\n matrix.compose(\n position ? position : oldPosition,\n rotation ? new Quaternion().setFromEuler(rotation) : oldRotation,\n scale ? scale : oldScale\n );\n\n this.setMatrixAt(index, matrix);\n }\n\n setPositionAt(index: number, position: Vector3) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n this.setPositionRotationScaleAt(index, position);\n }\n\n getPositionAt(index: number, vector: Vector3 = new Vector3()): Vector3 {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const matrix = this.getMatrixAt(index)\n vector.setFromMatrixPosition(matrix);\n return vector;\n }\n\n setRotationAt(index: number, rotation: Euler) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n this.setPositionRotationScaleAt(index, undefined, rotation, undefined);\n }\n\n getRotationAt(index: number, euler: Euler = new Euler()): Euler {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const rotation = new Quaternion();\n this.getMatrixAt(index).decompose(new Vector3(), rotation, new Vector3());\n return euler.setFromQuaternion(rotation);\n }\n\n setScaleAt(index: number, scale: Vector3) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n this.setPositionRotationScaleAt(index, undefined, undefined, scale);\n }\n\n getScaleAt(index: number, vector: Vector3 = new Vector3()): Vector3 {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const matrix = this.getMatrixAt(index)\n vector.setFromMatrixScale(matrix);\n return vector;\n }\n\n /** Updates supplied transform components. For a shared model, affects every live instance. */\n setPositionRotationScale(position?: Vector3, rotation?: Euler, scale?: Vector3): void {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, position, rotation, scale);\n }\n } else {\n if (position) {\n this.position.set(position.x, position.y, position.z);\n }\n if (rotation) {\n this.rotation.set(rotation.x, rotation.y, rotation.z);\n }\n if (scale) {\n this.scale.set(scale.x, scale.y, scale.z);\n }\n }\n this.notifyDirty();\n }\n\n /** Sets position in scene units. For a shared model, updates every live instance. */\n setPosition(position: Vector3) {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, position);\n }\n } else {\n this.position.set(position.x, position.y, position.z);\n }\n this.notifyDirty();\n }\n\n getPosition(): Vector3 {\n if (this.isInstanced) {\n return this.getPositionAt(this.instanceReferences.keys().next().value ?? 0);\n } else {\n return this.position;\n }\n }\n\n /** Sets rotation in radians. For a shared model, updates every live instance. */\n setRotation(rotation: Euler) {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, undefined, rotation);\n }\n } else {\n this.rotation.set(rotation.x, rotation.y, rotation.z);\n }\n this.notifyDirty();\n }\n\n getRotation(): Euler {\n if (this.isInstanced) {\n return this.getRotationAt(this.instanceReferences.keys().next().value ?? 0);\n } else {\n return this.rotation;\n }\n }\n\n /** Sets scale factors. For a shared model, updates every live instance. */\n setScale(scale: Vector3) {\n if (this.isInstanced) {\n for (const i of this.activeInstanceIndices()) {\n this.setPositionRotationScaleAt(i, undefined, undefined, scale);\n }\n } else {\n this.scale.set(scale.x, scale.y, scale.z);\n }\n this.notifyDirty();\n }\n\n getScale(): Vector3 {\n if (this.isInstanced) {\n return this.getScaleAt(this.instanceReferences.keys().next().value ?? 0);\n } else {\n return this.scale;\n }\n }\n\n //</editor-fold>\n\n protected toggleObjectVisibility(object?: Object3D, visible?: boolean): boolean {\n if (object) {\n if (typeof visible !== \"undefined\") {\n object.visible = visible;\n } else {\n object.visible = !object.visible;\n }\n this.notifyDirty();\n return object.visible;\n }\n this.notifyDirty();\n return false;\n }\n\n //<editor-fold desc=\"CLEANUP\">\n\n public dispose() {\n this.disposeAndRemoveAllChildren();\n this.notifyDirty();\n super.dispose();\n }\n\n /** Releases instance slots and removes children, disposing children that implement Disposable. */\n public disposeAndRemoveAllChildren() {\n if (this.instanceMesh) {\n if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;\n this.instanceReferences.clear();\n this.freeInstanceIndices.length = 0;\n this.hiddenInstanceMatrices.clear();\n this._instanceCounter = 0;\n this.instanceMesh.count = 0;\n this.instanceMesh.dispose();\n this.instanceMesh.removeFromParent();\n this.instanceMesh = undefined;\n this._isInstanced = false;\n }\n while (this.children.length > 0) {\n let c = this.children[0];\n if (isDisposable(c)) {\n c.dispose();\n }\n this.remove(c);\n }\n this.notifyDirty();\n }\n\n /** Detaches the object from its parent and requests a redraw. */\n public removeFromScene() {\n this.notifyDirty();\n this.removeFromParent();\n }\n\n //</editor-fold>\n\n}\n\nexport function isSceneObject(obj: any): obj is SceneObject {\n return (<SceneObject>obj).isSceneObject;\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  // src/request/Requests.ts
2
2
  import { JobCancelledError, JobQueue } from "jobqu";
3
- import { prefix } from "../util/log.mjs";
4
- var p = prefix("Requests");
3
+ import { logger } from "../util/log.mjs";
4
+ var log = logger("Requests");
5
5
  var RequestError = class extends Error {
6
6
  constructor(message, response, cause) {
7
7
  super(message);
@@ -80,7 +80,7 @@ var RequestQueue = class {
80
80
  try {
81
81
  return await abortable(this.queue.add(request), signal);
82
82
  } catch (error) {
83
- console.debug(p, "Request failed", error);
83
+ log.debug("Request failed", error);
84
84
  const delay = this.retryDelay(error, request, retries);
85
85
  if (delay === void 0) {
86
86
  throw error;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/request/Requests.ts"],"sourcesContent":["import { JobCancelledError, JobQueue } from \"jobqu\";\nimport { prefix } from \"../util/log\";\n\nconst p = prefix(\"Requests\");\n\n/** Fetch settings passed to {@link Requests.genericRequest} or {@link Requests.mcAssetRequest}. */\nexport interface RequestConfig extends RequestInit {\n url: string;\n /** Prepended to relative URLs, preserving any path in the base URL. */\n baseURL?: string;\n /** Timeout per attempt in milliseconds, including body reading. Defaults to 5000; 0 disables it. */\n timeout?: number;\n /** Response-body decoding. Defaults to `json`. */\n responseType?: \"json\" | \"arraybuffer\";\n}\n\n/** A decoded response body with the HTTP status, native headers, and final URL. */\nexport interface RequestResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Headers;\n /** Final URL after redirects. */\n url: string;\n}\n\n/** An HTTP or network failure, with response details or an underlying cause when available. */\nexport class RequestError extends Error {\n constructor(message: string, readonly response?: RequestResponse<undefined>, readonly cause?: unknown) {\n super(message);\n this.name = \"RequestError\";\n }\n}\n\nasync function fetchRequest(config: RequestConfig, defaultBaseURL?: string): Promise<RequestResponse> {\n const { url, baseURL = defaultBaseURL, timeout = 5000, responseType = \"json\", signal, ...options } = config;\n const target = baseURL && !/^([a-z][a-z\\d+.-]*:|\\/\\/)/i.test(url)\n ? `${baseURL.replace(/\\/+$/, \"\")}/${url.replace(/^\\/+/, \"\")}` : url;\n const headers = new Headers(options.headers);\n if (typeof window === \"undefined\" && !headers.has(\"User-Agent\")) {\n headers.set(\"User-Agent\", \"MineRender\");\n }\n const attemptSignal = AbortSignal.any([\n ...(signal ? [signal] : []), ...(timeout === 0 ? [] : [AbortSignal.timeout(timeout)])\n ]);\n // Validate configuration before classifying Fetch TypeErrors as network failures.\n const request = new Request(target, { ...options, headers, signal: attemptSignal });\n attemptSignal.throwIfAborted();\n try {\n const response = await fetch(request);\n const result: RequestResponse<undefined> = {\n data: undefined,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n url: response.url\n };\n if (!response.ok) {\n // Release error bodies without letting cleanup hide the HTTP status.\n await response.body?.cancel().catch(() => {});\n throw new RequestError(`Request failed with status ${response.status}`, result);\n }\n const emptyBody = request.method === \"HEAD\" || response.status === 204 || response.status === 205;\n const data = responseType === \"arraybuffer\" ? await response.arrayBuffer()\n : emptyBody || response.body === null ? undefined : await response.json();\n return { ...result, data };\n } catch (error) {\n attemptSignal.throwIfAborted();\n if (/^https?:/.test(request.url) && request.redirect !== \"error\" && error instanceof TypeError) {\n throw new RequestError(\"Network request failed\", undefined, error);\n }\n throw error;\n }\n}\n\nasync function abortable<T>(promise: Promise<T>, signal?: AbortSignal | null): Promise<T> {\n if (!signal) return promise;\n let abort: () => void;\n const cancelled = new Promise<never>((_, reject) => {\n abort = () => reject(signal.reason);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n });\n try {\n return await Promise.race([promise, cancelled]);\n } finally {\n signal.removeEventListener(\"abort\", abort!);\n }\n}\n\nclass RequestQueue {\n\n public baseURL?: string;\n private pendingRequests = 0;\n private readonly stopped = new AbortController();\n private readonly queue = new JobQueue<RequestConfig, RequestResponse>(\n request => fetchRequest(request, this.baseURL), { interval: 10, maxPerRun: 1, maxActive: 8 });\n\n public async request(request: RequestConfig): Promise<RequestResponse> {\n this.pendingRequests++;\n const signal = request.signal;\n try {\n for (let retries = 0; ; retries++) {\n signal?.throwIfAborted();\n try {\n return await abortable(this.queue.add(request), signal);\n } catch (error) {\n console.debug(p, \"Request failed\", error);\n const delay = this.retryDelay(error, request, retries);\n if (delay === undefined) {\n throw error;\n }\n await this.waitForRetry(delay, signal);\n }\n }\n } finally {\n if (signal?.aborted) {\n this.queue.remove(request);\n }\n this.pendingRequests--;\n }\n }\n\n private retryDelay(error: unknown, request: RequestConfig, retries: number): number | undefined {\n if (this.stopped.signal.aborted || retries >= 3 ||\n (request.method ?? \"get\").toLowerCase() !== \"get\" || request.signal?.aborted) {\n return undefined;\n }\n if (error instanceof RequestError) {\n const status = error.response?.status;\n if (status !== undefined && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return undefined;\n } else if (!(error instanceof DOMException && error.name === \"TimeoutError\")) {\n return undefined;\n }\n\n let delay = 100 * (2 ** retries);\n const retryAfter = error instanceof RequestError ? error.response?.headers.get(\"Retry-After\") : undefined;\n if (retryAfter !== undefined && retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {\n return undefined;\n }\n delay = Math.max(delay, seconds * 1000);\n }\n return delay;\n }\n\n private async waitForRetry(delay: number, signal?: AbortSignal | null): Promise<void> {\n let timer: ReturnType<typeof setTimeout>;\n const waiting = new Promise<void>(resolve => { timer = setTimeout(resolve, delay); });\n try {\n await abortable(waiting, AbortSignal.any([this.stopped.signal, ...(signal ? [signal] : [])]));\n } finally {\n clearTimeout(timer!);\n }\n }\n\n public get pendingSize(): number {\n return this.pendingRequests;\n }\n\n public end(): void {\n this.queue.end();\n this.stopped.abort(new JobCancelledError(\"ended\"));\n }\n}\n\n/** Shared Fetch queues with concurrency limits, cancellation, timeouts, and bounded retries for GET requests. */\nexport class Requests {\n\n private static genericQueue = new RequestQueue();\n private static mcAssetRequestQueue = new RequestQueue();\n\n /** Queues a general request. Set `request.signal` to cancel it and `request.timeout` to limit each attempt. */\n public static genericRequest(request: RequestConfig): Promise<RequestResponse> {\n return this.genericQueue.request(request);\n }\n\n /** Queues a request separately from general traffic, using the configured asset base URL for relative paths. */\n public static mcAssetRequest(request: RequestConfig): Promise<RequestResponse> {\n return this.mcAssetRequestQueue.request(request);\n }\n\n /** Sets the base URL for relative asset requests. Use {@link AssetLoader.setVersion} to change Minecraft versions. */\n public static setMcAssetRoot(root: string) {\n this.mcAssetRequestQueue.baseURL = root;\n }\n\n /** Counts unsettled calls, including retry delays and requests still running after shutdown. */\n public static get queueSizes() {\n return {\n generic: this.genericQueue.pendingSize,\n mcAsset: this.mcAssetRequestQueue.pendingSize\n }\n }\n\n /**\n * Permanently stops both queues and rejects waiting, retrying, and future requests.\n * Requests already running can finish. Idle queues hold no timer, so Node can exit without\n * this cleanup. See {@link shutdown}.\n */\n public static end() {\n this.genericQueue.end();\n this.mcAssetRequestQueue.end();\n }\n\n}\n"],"mappings":";AAAA,SAAS,mBAAmB,gBAAgB;AAC5C,SAAS,cAAc;AAEvB,IAAM,IAAI,OAAO,UAAU;AAwBpB,IAAM,eAAN,cAA2B,MAAM;AAAA,EACpC,YAAY,SAA0B,UAAgD,OAAiB;AACnG,UAAM,OAAO;AADqB;AAAgD;AAElF,SAAK,OAAO;AAAA,EAChB;AACJ;AAEA,eAAe,aAAa,QAAuB,gBAAmD;AAClG,QAAM,EAAE,KAAK,UAAU,gBAAgB,UAAU,KAAM,eAAe,QAAQ,QAAQ,GAAG,QAAQ,IAAI;AACrG,QAAM,SAAS,WAAW,CAAC,6BAA6B,KAAK,GAAG,IAC1D,GAAG,QAAQ,QAAQ,QAAQ,EAAE,CAAC,IAAI,IAAI,QAAQ,QAAQ,EAAE,CAAC,KAAK;AACpE,QAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,MAAI,OAAO,WAAW,eAAe,CAAC,QAAQ,IAAI,YAAY,GAAG;AAC7D,YAAQ,IAAI,cAAc,YAAY;AAAA,EAC1C;AACA,QAAM,gBAAgB,YAAY,IAAI;AAAA,IAClC,GAAI,SAAS,CAAC,MAAM,IAAI,CAAC;AAAA,IAAI,GAAI,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,QAAQ,OAAO,CAAC;AAAA,EACvF,CAAC;AAED,QAAM,UAAU,IAAI,QAAQ,QAAQ,EAAE,GAAG,SAAS,SAAS,QAAQ,cAAc,CAAC;AAClF,gBAAc,eAAe;AAC7B,MAAI;AACA,UAAM,WAAW,MAAM,MAAM,OAAO;AACpC,UAAM,SAAqC;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,MACrB,SAAS,SAAS;AAAA,MAClB,KAAK,SAAS;AAAA,IAClB;AACA,QAAI,CAAC,SAAS,IAAI;AAEd,YAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAC5C,YAAM,IAAI,aAAa,8BAA8B,SAAS,MAAM,IAAI,MAAM;AAAA,IAClF;AACA,UAAM,YAAY,QAAQ,WAAW,UAAU,SAAS,WAAW,OAAO,SAAS,WAAW;AAC9F,UAAM,OAAO,iBAAiB,gBAAgB,MAAM,SAAS,YAAY,IACnE,aAAa,SAAS,SAAS,OAAO,SAAY,MAAM,SAAS,KAAK;AAC5E,WAAO,EAAE,GAAG,QAAQ,KAAK;AAAA,EAC7B,SAAS,OAAO;AACZ,kBAAc,eAAe;AAC7B,QAAI,WAAW,KAAK,QAAQ,GAAG,KAAK,QAAQ,aAAa,WAAW,iBAAiB,WAAW;AAC5F,YAAM,IAAI,aAAa,0BAA0B,QAAW,KAAK;AAAA,IACrE;AACA,UAAM;AAAA,EACV;AACJ;AAEA,eAAe,UAAa,SAAqB,QAAyC;AACtF,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI;AACJ,QAAM,YAAY,IAAI,QAAe,CAAC,GAAG,WAAW;AAChD,YAAQ,MAAM,OAAO,OAAO,MAAM;AAClC,WAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;AACtD,QAAI,OAAO,QAAS,OAAM;AAAA,EAC9B,CAAC;AACD,MAAI;AACA,WAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,SAAS,CAAC;AAAA,EAClD,UAAE;AACE,WAAO,oBAAoB,SAAS,KAAM;AAAA,EAC9C;AACJ;AAEA,IAAM,eAAN,MAAmB;AAAA,EAAnB;AAGI,SAAQ,kBAAkB;AAC1B,SAAiB,UAAU,IAAI,gBAAgB;AAC/C,SAAiB,QAAQ,IAAI;AAAA,MACzB,aAAW,aAAa,SAAS,KAAK,OAAO;AAAA,MAAG,EAAE,UAAU,IAAI,WAAW,GAAG,WAAW,EAAE;AAAA,IAAC;AAAA;AAAA,EAEhG,MAAa,QAAQ,SAAkD;AACnE,SAAK;AACL,UAAM,SAAS,QAAQ;AACvB,QAAI;AACA,eAAS,UAAU,KAAK,WAAW;AAC/B,gBAAQ,eAAe;AACvB,YAAI;AACA,iBAAO,MAAM,UAAU,KAAK,MAAM,IAAI,OAAO,GAAG,MAAM;AAAA,QAC1D,SAAS,OAAO;AACZ,kBAAQ,MAAM,GAAG,kBAAkB,KAAK;AACxC,gBAAM,QAAQ,KAAK,WAAW,OAAO,SAAS,OAAO;AACrD,cAAI,UAAU,QAAW;AACrB,kBAAM;AAAA,UACV;AACA,gBAAM,KAAK,aAAa,OAAO,MAAM;AAAA,QACzC;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,UAAI,QAAQ,SAAS;AACjB,aAAK,MAAM,OAAO,OAAO;AAAA,MAC7B;AACA,WAAK;AAAA,IACT;AAAA,EACJ;AAAA,EAEQ,WAAW,OAAgB,SAAwB,SAAqC;AAC5F,QAAI,KAAK,QAAQ,OAAO,WAAW,WAAW,MACzC,QAAQ,UAAU,OAAO,YAAY,MAAM,SAAS,QAAQ,QAAQ,SAAS;AAC9E,aAAO;AAAA,IACX;AACA,QAAI,iBAAiB,cAAc;AAC/B,YAAM,SAAS,MAAM,UAAU;AAC/B,UAAI,WAAW,UAAa,WAAW,OAAO,WAAW,OAAO,EAAE,UAAU,OAAO,SAAS,KAAM,QAAO;AAAA,IAC7G,WAAW,EAAE,iBAAiB,gBAAgB,MAAM,SAAS,iBAAiB;AAC1E,aAAO;AAAA,IACX;AAEA,QAAI,QAAQ,MAAO,KAAK;AACxB,UAAM,aAAa,iBAAiB,eAAe,MAAM,UAAU,QAAQ,IAAI,aAAa,IAAI;AAChG,QAAI,eAAe,UAAa,eAAe,MAAM;AACjD,YAAM,UAAU,OAAO,UAAU;AACjC,UAAI,CAAC,WAAW,KAAK,KAAK,CAAC,OAAO,SAAS,OAAO,KAAK,UAAU,GAAG;AAChE,eAAO;AAAA,MACX;AACA,cAAQ,KAAK,IAAI,OAAO,UAAU,GAAI;AAAA,IAC1C;AACA,WAAO;AAAA,EACX;AAAA,EAEA,MAAc,aAAa,OAAe,QAA4C;AAClF,QAAI;AACJ,UAAM,UAAU,IAAI,QAAc,aAAW;AAAE,cAAQ,WAAW,SAAS,KAAK;AAAA,IAAG,CAAC;AACpF,QAAI;AACA,YAAM,UAAU,SAAS,YAAY,IAAI,CAAC,KAAK,QAAQ,QAAQ,GAAI,SAAS,CAAC,MAAM,IAAI,CAAC,CAAE,CAAC,CAAC;AAAA,IAChG,UAAE;AACE,mBAAa,KAAM;AAAA,IACvB;AAAA,EACJ;AAAA,EAEA,IAAW,cAAsB;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,MAAY;AACf,SAAK,MAAM,IAAI;AACf,SAAK,QAAQ,MAAM,IAAI,kBAAkB,OAAO,CAAC;AAAA,EACrD;AACJ;AAGO,IAAM,WAAN,MAAe;AAAA;AAAA,EAMlB,OAAc,eAAe,SAAkD;AAC3E,WAAO,KAAK,aAAa,QAAQ,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,OAAc,eAAe,SAAkD;AAC3E,WAAO,KAAK,oBAAoB,QAAQ,OAAO;AAAA,EACnD;AAAA;AAAA,EAGA,OAAc,eAAe,MAAc;AACvC,SAAK,oBAAoB,UAAU;AAAA,EACvC;AAAA;AAAA,EAGA,WAAkB,aAAa;AAC3B,WAAO;AAAA,MACH,SAAS,KAAK,aAAa;AAAA,MAC3B,SAAS,KAAK,oBAAoB;AAAA,IACtC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAc,MAAM;AAChB,SAAK,aAAa,IAAI;AACtB,SAAK,oBAAoB,IAAI;AAAA,EACjC;AAEJ;AAtCa,SAEM,eAAe,IAAI,aAAa;AAFtC,SAGM,sBAAsB,IAAI,aAAa;","names":[]}
1
+ {"version":3,"sources":["../../../../src/request/Requests.ts"],"sourcesContent":["import { JobCancelledError, JobQueue } from \"jobqu\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"Requests\");\n\n/** Fetch settings passed to {@link Requests.genericRequest} or {@link Requests.mcAssetRequest}. */\nexport interface RequestConfig extends RequestInit {\n url: string;\n /** Prepended to relative URLs, preserving any path in the base URL. */\n baseURL?: string;\n /** Timeout per attempt in milliseconds, including body reading. Defaults to 5000; 0 disables it. */\n timeout?: number;\n /** Response-body decoding. Defaults to `json`. */\n responseType?: \"json\" | \"arraybuffer\";\n}\n\n/** A decoded response body with the HTTP status, native headers, and final URL. */\nexport interface RequestResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Headers;\n /** Final URL after redirects. */\n url: string;\n}\n\n/** An HTTP or network failure, with response details or an underlying cause when available. */\nexport class RequestError extends Error {\n constructor(message: string, readonly response?: RequestResponse<undefined>, readonly cause?: unknown) {\n super(message);\n this.name = \"RequestError\";\n }\n}\n\nasync function fetchRequest(config: RequestConfig, defaultBaseURL?: string): Promise<RequestResponse> {\n const { url, baseURL = defaultBaseURL, timeout = 5000, responseType = \"json\", signal, ...options } = config;\n const target = baseURL && !/^([a-z][a-z\\d+.-]*:|\\/\\/)/i.test(url)\n ? `${baseURL.replace(/\\/+$/, \"\")}/${url.replace(/^\\/+/, \"\")}` : url;\n const headers = new Headers(options.headers);\n if (typeof window === \"undefined\" && !headers.has(\"User-Agent\")) {\n headers.set(\"User-Agent\", \"MineRender\");\n }\n const attemptSignal = AbortSignal.any([\n ...(signal ? [signal] : []), ...(timeout === 0 ? [] : [AbortSignal.timeout(timeout)])\n ]);\n // Validate configuration before classifying Fetch TypeErrors as network failures.\n const request = new Request(target, { ...options, headers, signal: attemptSignal });\n attemptSignal.throwIfAborted();\n try {\n const response = await fetch(request);\n const result: RequestResponse<undefined> = {\n data: undefined,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n url: response.url\n };\n if (!response.ok) {\n // Release error bodies without letting cleanup hide the HTTP status.\n await response.body?.cancel().catch(() => {});\n throw new RequestError(`Request failed with status ${response.status}`, result);\n }\n const emptyBody = request.method === \"HEAD\" || response.status === 204 || response.status === 205;\n const data = responseType === \"arraybuffer\" ? await response.arrayBuffer()\n : emptyBody || response.body === null ? undefined : await response.json();\n return { ...result, data };\n } catch (error) {\n attemptSignal.throwIfAborted();\n if (/^https?:/.test(request.url) && request.redirect !== \"error\" && error instanceof TypeError) {\n throw new RequestError(\"Network request failed\", undefined, error);\n }\n throw error;\n }\n}\n\nasync function abortable<T>(promise: Promise<T>, signal?: AbortSignal | null): Promise<T> {\n if (!signal) return promise;\n let abort: () => void;\n const cancelled = new Promise<never>((_, reject) => {\n abort = () => reject(signal.reason);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n });\n try {\n return await Promise.race([promise, cancelled]);\n } finally {\n signal.removeEventListener(\"abort\", abort!);\n }\n}\n\nclass RequestQueue {\n\n public baseURL?: string;\n private pendingRequests = 0;\n private readonly stopped = new AbortController();\n private readonly queue = new JobQueue<RequestConfig, RequestResponse>(\n request => fetchRequest(request, this.baseURL), { interval: 10, maxPerRun: 1, maxActive: 8 });\n\n public async request(request: RequestConfig): Promise<RequestResponse> {\n this.pendingRequests++;\n const signal = request.signal;\n try {\n for (let retries = 0; ; retries++) {\n signal?.throwIfAborted();\n try {\n return await abortable(this.queue.add(request), signal);\n } catch (error) {\n log.debug(\"Request failed\", error);\n const delay = this.retryDelay(error, request, retries);\n if (delay === undefined) {\n throw error;\n }\n await this.waitForRetry(delay, signal);\n }\n }\n } finally {\n if (signal?.aborted) {\n this.queue.remove(request);\n }\n this.pendingRequests--;\n }\n }\n\n private retryDelay(error: unknown, request: RequestConfig, retries: number): number | undefined {\n if (this.stopped.signal.aborted || retries >= 3 ||\n (request.method ?? \"get\").toLowerCase() !== \"get\" || request.signal?.aborted) {\n return undefined;\n }\n if (error instanceof RequestError) {\n const status = error.response?.status;\n if (status !== undefined && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return undefined;\n } else if (!(error instanceof DOMException && error.name === \"TimeoutError\")) {\n return undefined;\n }\n\n let delay = 100 * (2 ** retries);\n const retryAfter = error instanceof RequestError ? error.response?.headers.get(\"Retry-After\") : undefined;\n if (retryAfter !== undefined && retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {\n return undefined;\n }\n delay = Math.max(delay, seconds * 1000);\n }\n return delay;\n }\n\n private async waitForRetry(delay: number, signal?: AbortSignal | null): Promise<void> {\n let timer: ReturnType<typeof setTimeout>;\n const waiting = new Promise<void>(resolve => { timer = setTimeout(resolve, delay); });\n try {\n await abortable(waiting, AbortSignal.any([this.stopped.signal, ...(signal ? [signal] : [])]));\n } finally {\n clearTimeout(timer!);\n }\n }\n\n public get pendingSize(): number {\n return this.pendingRequests;\n }\n\n public end(): void {\n this.queue.end();\n this.stopped.abort(new JobCancelledError(\"ended\"));\n }\n}\n\n/** Shared Fetch queues with concurrency limits, cancellation, timeouts, and bounded retries for GET requests. */\nexport class Requests {\n\n private static genericQueue = new RequestQueue();\n private static mcAssetRequestQueue = new RequestQueue();\n\n /** Queues a general request. Set `request.signal` to cancel it and `request.timeout` to limit each attempt. */\n public static genericRequest(request: RequestConfig): Promise<RequestResponse> {\n return this.genericQueue.request(request);\n }\n\n /** Queues a request separately from general traffic, using the configured asset base URL for relative paths. */\n public static mcAssetRequest(request: RequestConfig): Promise<RequestResponse> {\n return this.mcAssetRequestQueue.request(request);\n }\n\n /** Sets the base URL for relative asset requests. Use {@link AssetLoader.setVersion} to change Minecraft versions. */\n public static setMcAssetRoot(root: string) {\n this.mcAssetRequestQueue.baseURL = root;\n }\n\n /** Counts unsettled calls, including retry delays and requests still running after shutdown. */\n public static get queueSizes() {\n return {\n generic: this.genericQueue.pendingSize,\n mcAsset: this.mcAssetRequestQueue.pendingSize\n }\n }\n\n /**\n * Permanently stops both queues and rejects waiting, retrying, and future requests.\n * Requests already running can finish. Idle queues hold no timer, so Node can exit without\n * this cleanup. See {@link shutdown}.\n */\n public static end() {\n this.genericQueue.end();\n this.mcAssetRequestQueue.end();\n }\n\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,8 @@
1
1
  // src/skin/Skins.ts
2
2
  import { Requests } from "../request/Requests.mjs";
3
3
  import { Caching } from "../cache/Caching.mjs";
4
+ import { logger } from "../util/log.mjs";
5
+ var log = logger("Skins");
4
6
  var Skins = class {
5
7
  //<editor-fold desc="Skins">
6
8
  /** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */
@@ -72,7 +74,7 @@ var Skins = class {
72
74
  }
73
75
  return void 0;
74
76
  }).catch((err) => {
75
- console.warn(err);
77
+ log.warn(err);
76
78
  return void 0;
77
79
  });
78
80
  }
@@ -87,7 +89,7 @@ var Skins = class {
87
89
  }
88
90
  return void 0;
89
91
  }).catch((err) => {
90
- console.warn(err);
92
+ log.warn(err);
91
93
  return void 0;
92
94
  });
93
95
  }
@@ -101,7 +103,7 @@ var Skins = class {
101
103
  }
102
104
  return void 0;
103
105
  }).catch((err) => {
104
- console.warn(err);
106
+ log.warn(err);
105
107
  return void 0;
106
108
  });
107
109
  }
@@ -125,7 +127,7 @@ var Skins = class {
125
127
  }
126
128
  return void 0;
127
129
  }).catch((err) => {
128
- console.warn(err);
130
+ log.warn(err);
129
131
  return void 0;
130
132
  });
131
133
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/skin/Skins.ts"],"sourcesContent":["import { Requests } from \"../request/Requests\";\nimport { Maybe } from \"../util/util\";\nimport { Caching } from \"../cache/Caching\";\n\n//TODO: cache stuff\n/** Resolves player names, UUIDs, and service IDs to skin or cape texture URLs. */\nexport class Skins {\n\n\n //<editor-fold desc=\"Skins\">\n\n /** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */\n static async fromUuidOrUsername(uuidOrUsername: string): Promise<Maybe<string>> {\n if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {\n return this.fromUuid(uuidOrUsername);\n }\n return this.fromUsername(uuidOrUsername);\n }\n\n /** Builds a proxy URL for a UUID without downloading or checking the skin. */\n static async fromUuid(uuid: string): Promise<Maybe<string>> {\n return this.getMcProxySkinUrl(uuid);\n }\n\n static async fromUsername(username: string): Promise<Maybe<string>> {\n return this.usernameToUuid(username).then(uuid => {\n if (uuid) {\n return this.fromUuid(uuid);\n }\n return undefined;\n })\n }\n\n /** Looks up a saved MineSkin skin and returns its texture URL, or `undefined` on lookup failure. */\n static async fromMineSkin(mineskinId: string): Promise<Maybe<string>> {\n return this.getMineSkin(mineskinId).then(mineskin => {\n if (mineskin) {\n return mineskin[\"data\"][\"texture\"][\"value\"][\"urls\"][\"skins\"];\n }\n return undefined;\n })\n }\n\n //</editor-fold>\n\n\n //<editor-fold desc=\"Capes\">\n\n /** Resolves a player's Minecraft cape URL for {@link SkinObject.setCapeTexture}. */\n static async capeFromUuidOrUsername(uuidOrUsername: string): Promise<Maybe<string>> {\n if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {\n return this.capeFromUuid(uuidOrUsername);\n }\n return this.capeFromUsername(uuidOrUsername);\n }\n\n /** Builds a proxy URL without checking whether the player has a cape. */\n static async capeFromUuid(uuid: string): Promise<Maybe<string>> {\n return this.getMcProxyCapeUrl(uuid);\n }\n\n static async capeFromUsername(username: string): Promise<Maybe<string>> {\n return this.usernameToUuid(username).then(uuid => {\n if (uuid) {\n return this.capeFromUuid(uuid);\n }\n return undefined;\n })\n }\n\n /** Returns a full static cape texture for a username or UUID. */\n static async capeFromCapesDev(player: string, capeType: string = \"minecraft\"): Promise<Maybe<string>> {\n const cape = await this.getCapesDev(player, capeType);\n return cape?.exists ? cape.imageUrls?.still?.full : undefined;\n }\n\n //</editor-fold>\n\n\n //<editor-fold desc=\"Helpers\">\n\n private static async usernameToUuid(username: string): Promise<Maybe<string>> {\n return Caching.usernameUuidCache.get(username, () => this.usernameToUuidMcProxy(username));\n }\n\n private static async usernameToUuidMcProxy(username: string): Promise<Maybe<string>> {\n return Requests.genericRequest({\n baseURL: 'https://mcproxy.dev',\n url: '/uuid/' + username\n }).then(res => {\n if (res.status === 200) {\n return res.data[\"data\"][\"id\"];\n }\n return undefined;\n }).catch(err => {\n console.warn(err);\n return undefined;\n })\n }\n\n /** @deprecated **/\n private static async usernameToUuidSkinProxy(username: string): Promise<Maybe<string>> {\n return Requests.genericRequest({\n baseURL: 'https://minecraft-skin-proxy.inventive.workers.dev',\n url: '/uuid/' + username\n }).then(res => {\n if (res.status === 200) {\n return res.data[\"id\"];\n }\n return undefined;\n }).catch(err => {\n console.warn(err);\n return undefined;\n })\n }\n\n private static async usernameToUuidMineTools(username: string): Promise<Maybe<string>> {\n return Requests.genericRequest({\n baseURL: 'https://api.minetools.eu',\n url: '/uuid/' + username\n }).then(res => {\n if (res.status === 200) {\n return res.data[\"id\"];\n }\n return undefined;\n }).catch(err => {\n console.warn(err);\n return undefined;\n })\n }\n\n private static async getProfileFromMinetools(uuid: string): Promise<Maybe<any>> {\n return Requests.genericRequest({\n baseURL: 'https://api.minetools.eu',\n url: '/profile/' + uuid\n }).then(res => {\n if (res.status === 200) {\n return res.data;\n }\n })\n }\n\n private static async getMineSkin(mineskinId: string): Promise<Maybe<any>> {\n return Requests.genericRequest({\n baseURL: 'https://api.mineskin.org',\n url: '/get/uuid/' + mineskinId\n }).then(res => {\n if (res.status === 200) {\n return res.data;\n }\n return undefined;\n }).catch(err => {\n console.warn(err);\n return undefined;\n })\n }\n\n private static async getCapesDev(player: string, type: string = 'all'): Promise<Maybe<any>> {\n return Requests.genericRequest({\n baseURL: 'https://api.capes.dev',\n url: '/load/' + encodeURIComponent(player) + '/' + encodeURIComponent(type)\n }).then(res => {\n if (res.status === 200) {\n return res.data;\n }\n return undefined;\n })\n }\n\n private static getCrafatarSkinUrl(uuid: string): string {\n return \"https://crafatar.com/skins/\" + uuid;\n }\n\n private static getCrafatarCapeUrl(uuid: string): string {\n return \"https://crafatar.com/capes/\" + uuid;\n }\n\n private static getMcHeadsSkinUrl(uuid: string): string {\n return \"https://mc-heads.net/skin/\" + uuid;\n }\n\n private static getMineSkinPlayerSkinUrl(uuid: string): string {\n return \"https://mineskin.org/skin/player/\" + uuid;\n }\n\n /** @deprecated **/\n private static getSkinProxySkinUrl(uuid: string): string {\n return \"https://minecraft-skin-proxy.inventive.workers.dev/skin/\" + uuid;\n }\n\n /** @deprecated **/\n private static getSkinProxyCapeUrl(uuid: string): string {\n return \"https://minecraft-skin-proxy.inventive.workers.dev/cape/\" + uuid;\n }\n\n private static getMcProxySkinUrl(uuid: string): string {\n return \"https://mcproxy.dev/skin/\" + uuid;\n }\n\n private static getMcProxyCapeUrl(uuid: string): string {\n return \"https://mcproxy.dev/cape/\" + uuid;\n }\n\n //</editor-fold>\n\n\n}\n"],"mappings":";AAAA,SAAS,gBAAgB;AAEzB,SAAS,eAAe;AAIjB,IAAM,QAAN,MAAY;AAAA;AAAA;AAAA,EAMf,aAAa,mBAAmB,gBAAgD;AAC5E,QAAI,eAAe,WAAW,MAAM,eAAe,WAAW,IAAI;AAC9D,aAAO,KAAK,SAAS,cAAc;AAAA,IACvC;AACA,WAAO,KAAK,aAAa,cAAc;AAAA,EAC3C;AAAA;AAAA,EAGA,aAAa,SAAS,MAAsC;AACxD,WAAO,KAAK,kBAAkB,IAAI;AAAA,EACtC;AAAA,EAEA,aAAa,aAAa,UAA0C;AAChE,WAAO,KAAK,eAAe,QAAQ,EAAE,KAAK,UAAQ;AAC9C,UAAI,MAAM;AACN,eAAO,KAAK,SAAS,IAAI;AAAA,MAC7B;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,aAAa,aAAa,YAA4C;AAClE,WAAO,KAAK,YAAY,UAAU,EAAE,KAAK,cAAY;AACjD,UAAI,UAAU;AACV,eAAO,SAAS,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;AAAA,MAC/D;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,uBAAuB,gBAAgD;AAChF,QAAI,eAAe,WAAW,MAAM,eAAe,WAAW,IAAI;AAC9D,aAAO,KAAK,aAAa,cAAc;AAAA,IAC3C;AACA,WAAO,KAAK,iBAAiB,cAAc;AAAA,EAC/C;AAAA;AAAA,EAGA,aAAa,aAAa,MAAsC;AAC5D,WAAO,KAAK,kBAAkB,IAAI;AAAA,EACtC;AAAA,EAEA,aAAa,iBAAiB,UAA0C;AACpE,WAAO,KAAK,eAAe,QAAQ,EAAE,KAAK,UAAQ;AAC9C,UAAI,MAAM;AACN,eAAO,KAAK,aAAa,IAAI;AAAA,MACjC;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,aAAa,iBAAiB,QAAgB,WAAmB,aAAqC;AAClG,UAAM,OAAO,MAAM,KAAK,YAAY,QAAQ,QAAQ;AACpD,WAAO,MAAM,SAAS,KAAK,WAAW,OAAO,OAAO;AAAA,EACxD;AAAA;AAAA;AAAA,EAOA,aAAqB,eAAe,UAA0C;AAC1E,WAAO,QAAQ,kBAAkB,IAAI,UAAU,MAAM,KAAK,sBAAsB,QAAQ,CAAC;AAAA,EAC7F;AAAA,EAEA,aAAqB,sBAAsB,UAA0C;AACjF,WAAO,SAAS,eAAe;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK,WAAW;AAAA,IACpB,CAAC,EAAE,KAAK,SAAO;AACX,UAAI,IAAI,WAAW,KAAK;AACpB,eAAO,IAAI,KAAK,MAAM,EAAE,IAAI;AAAA,MAChC;AACA,aAAO;AAAA,IACX,CAAC,EAAE,MAAM,SAAO;AACZ,cAAQ,KAAK,GAAG;AAChB,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,aAAqB,wBAAwB,UAA0C;AACnF,WAAO,SAAS,eAAe;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK,WAAW;AAAA,IACpB,CAAC,EAAE,KAAK,SAAO;AACX,UAAI,IAAI,WAAW,KAAK;AACpB,eAAO,IAAI,KAAK,IAAI;AAAA,MACxB;AACA,aAAO;AAAA,IACX,CAAC,EAAE,MAAM,SAAO;AACZ,cAAQ,KAAK,GAAG;AAChB,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,aAAqB,wBAAwB,UAA0C;AACnF,WAAO,SAAS,eAAe;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK,WAAW;AAAA,IACpB,CAAC,EAAE,KAAK,SAAO;AACX,UAAI,IAAI,WAAW,KAAK;AACpB,eAAO,IAAI,KAAK,IAAI;AAAA,MACxB;AACA,aAAO;AAAA,IACX,CAAC,EAAE,MAAM,SAAO;AACZ,cAAQ,KAAK,GAAG;AAChB,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,aAAqB,wBAAwB,MAAmC;AAC5E,WAAO,SAAS,eAAe;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK,cAAc;AAAA,IACvB,CAAC,EAAE,KAAK,SAAO;AACX,UAAI,IAAI,WAAW,KAAK;AACpB,eAAO,IAAI;AAAA,MACf;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,aAAqB,YAAY,YAAyC;AACtE,WAAO,SAAS,eAAe;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK,eAAe;AAAA,IACxB,CAAC,EAAE,KAAK,SAAO;AACX,UAAI,IAAI,WAAW,KAAK;AACpB,eAAO,IAAI;AAAA,MACf;AACA,aAAO;AAAA,IACX,CAAC,EAAE,MAAM,SAAO;AACZ,cAAQ,KAAK,GAAG;AAChB,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,aAAqB,YAAY,QAAgB,OAAe,OAA4B;AACxF,WAAO,SAAS,eAAe;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK,WAAW,mBAAmB,MAAM,IAAI,MAAM,mBAAmB,IAAI;AAAA,IAC9E,CAAC,EAAE,KAAK,SAAO;AACX,UAAI,IAAI,WAAW,KAAK;AACpB,eAAO,IAAI;AAAA,MACf;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,OAAe,mBAAmB,MAAsB;AACpD,WAAO,gCAAgC;AAAA,EAC3C;AAAA,EAEA,OAAe,mBAAmB,MAAsB;AACpD,WAAO,gCAAgC;AAAA,EAC3C;AAAA,EAEA,OAAe,kBAAkB,MAAsB;AACnD,WAAO,+BAA+B;AAAA,EAC1C;AAAA,EAEA,OAAe,yBAAyB,MAAsB;AAC1D,WAAO,sCAAsC;AAAA,EACjD;AAAA;AAAA,EAGA,OAAe,oBAAoB,MAAsB;AACrD,WAAO,6DAA6D;AAAA,EACxE;AAAA;AAAA,EAGA,OAAe,oBAAoB,MAAsB;AACrD,WAAO,6DAA6D;AAAA,EACxE;AAAA,EAEA,OAAe,kBAAkB,MAAsB;AACnD,WAAO,8BAA8B;AAAA,EACzC;AAAA,EAEA,OAAe,kBAAkB,MAAsB;AACnD,WAAO,8BAA8B;AAAA,EACzC;AAAA;AAKJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/skin/Skins.ts"],"sourcesContent":["import { Requests } from \"../request/Requests\";\nimport { Maybe } from \"../util/util\";\nimport { Caching } from \"../cache/Caching\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"Skins\");\n\n//TODO: cache stuff\n/** Resolves player names, UUIDs, and service IDs to skin or cape texture URLs. */\nexport class Skins {\n\n\n //<editor-fold desc=\"Skins\">\n\n /** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */\n static async fromUuidOrUsername(uuidOrUsername: string): Promise<Maybe<string>> {\n if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {\n return this.fromUuid(uuidOrUsername);\n }\n return this.fromUsername(uuidOrUsername);\n }\n\n /** Builds a proxy URL for a UUID without downloading or checking the skin. */\n static async fromUuid(uuid: string): Promise<Maybe<string>> {\n return this.getMcProxySkinUrl(uuid);\n }\n\n static async fromUsername(username: string): Promise<Maybe<string>> {\n return this.usernameToUuid(username).then(uuid => {\n if (uuid) {\n return this.fromUuid(uuid);\n }\n return undefined;\n })\n }\n\n /** Looks up a saved MineSkin skin and returns its texture URL, or `undefined` on lookup failure. */\n static async fromMineSkin(mineskinId: string): Promise<Maybe<string>> {\n return this.getMineSkin(mineskinId).then(mineskin => {\n if (mineskin) {\n return mineskin[\"data\"][\"texture\"][\"value\"][\"urls\"][\"skins\"];\n }\n return undefined;\n })\n }\n\n //</editor-fold>\n\n\n //<editor-fold desc=\"Capes\">\n\n /** Resolves a player's Minecraft cape URL for {@link SkinObject.setCapeTexture}. */\n static async capeFromUuidOrUsername(uuidOrUsername: string): Promise<Maybe<string>> {\n if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {\n return this.capeFromUuid(uuidOrUsername);\n }\n return this.capeFromUsername(uuidOrUsername);\n }\n\n /** Builds a proxy URL without checking whether the player has a cape. */\n static async capeFromUuid(uuid: string): Promise<Maybe<string>> {\n return this.getMcProxyCapeUrl(uuid);\n }\n\n static async capeFromUsername(username: string): Promise<Maybe<string>> {\n return this.usernameToUuid(username).then(uuid => {\n if (uuid) {\n return this.capeFromUuid(uuid);\n }\n return undefined;\n })\n }\n\n /** Returns a full static cape texture for a username or UUID. */\n static async capeFromCapesDev(player: string, capeType: string = \"minecraft\"): Promise<Maybe<string>> {\n const cape = await this.getCapesDev(player, capeType);\n return cape?.exists ? cape.imageUrls?.still?.full : undefined;\n }\n\n //</editor-fold>\n\n\n //<editor-fold desc=\"Helpers\">\n\n private static async usernameToUuid(username: string): Promise<Maybe<string>> {\n return Caching.usernameUuidCache.get(username, () => this.usernameToUuidMcProxy(username));\n }\n\n private static async usernameToUuidMcProxy(username: string): Promise<Maybe<string>> {\n return Requests.genericRequest({\n baseURL: 'https://mcproxy.dev',\n url: '/uuid/' + username\n }).then(res => {\n if (res.status === 200) {\n return res.data[\"data\"][\"id\"];\n }\n return undefined;\n }).catch(err => {\n log.warn(err);\n return undefined;\n })\n }\n\n /** @deprecated **/\n private static async usernameToUuidSkinProxy(username: string): Promise<Maybe<string>> {\n return Requests.genericRequest({\n baseURL: 'https://minecraft-skin-proxy.inventive.workers.dev',\n url: '/uuid/' + username\n }).then(res => {\n if (res.status === 200) {\n return res.data[\"id\"];\n }\n return undefined;\n }).catch(err => {\n log.warn(err);\n return undefined;\n })\n }\n\n private static async usernameToUuidMineTools(username: string): Promise<Maybe<string>> {\n return Requests.genericRequest({\n baseURL: 'https://api.minetools.eu',\n url: '/uuid/' + username\n }).then(res => {\n if (res.status === 200) {\n return res.data[\"id\"];\n }\n return undefined;\n }).catch(err => {\n log.warn(err);\n return undefined;\n })\n }\n\n private static async getProfileFromMinetools(uuid: string): Promise<Maybe<any>> {\n return Requests.genericRequest({\n baseURL: 'https://api.minetools.eu',\n url: '/profile/' + uuid\n }).then(res => {\n if (res.status === 200) {\n return res.data;\n }\n })\n }\n\n private static async getMineSkin(mineskinId: string): Promise<Maybe<any>> {\n return Requests.genericRequest({\n baseURL: 'https://api.mineskin.org',\n url: '/get/uuid/' + mineskinId\n }).then(res => {\n if (res.status === 200) {\n return res.data;\n }\n return undefined;\n }).catch(err => {\n log.warn(err);\n return undefined;\n })\n }\n\n private static async getCapesDev(player: string, type: string = 'all'): Promise<Maybe<any>> {\n return Requests.genericRequest({\n baseURL: 'https://api.capes.dev',\n url: '/load/' + encodeURIComponent(player) + '/' + encodeURIComponent(type)\n }).then(res => {\n if (res.status === 200) {\n return res.data;\n }\n return undefined;\n })\n }\n\n private static getCrafatarSkinUrl(uuid: string): string {\n return \"https://crafatar.com/skins/\" + uuid;\n }\n\n private static getCrafatarCapeUrl(uuid: string): string {\n return \"https://crafatar.com/capes/\" + uuid;\n }\n\n private static getMcHeadsSkinUrl(uuid: string): string {\n return \"https://mc-heads.net/skin/\" + uuid;\n }\n\n private static getMineSkinPlayerSkinUrl(uuid: string): string {\n return \"https://mineskin.org/skin/player/\" + uuid;\n }\n\n /** @deprecated **/\n private static getSkinProxySkinUrl(uuid: string): string {\n return \"https://minecraft-skin-proxy.inventive.workers.dev/skin/\" + uuid;\n }\n\n /** @deprecated **/\n private static getSkinProxyCapeUrl(uuid: string): string {\n return \"https://minecraft-skin-proxy.inventive.workers.dev/cape/\" + uuid;\n }\n\n private static getMcProxySkinUrl(uuid: string): string {\n return \"https://mcproxy.dev/skin/\" + uuid;\n }\n\n private static getMcProxyCapeUrl(uuid: string): string {\n return \"https://mcproxy.dev/cape/\" + uuid;\n }\n\n //</editor-fold>\n\n\n}\n"],"mappings":"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","names":[]}
@@ -3,6 +3,8 @@ import { RGBAFormat, Texture } from "three";
3
3
  import * as THREE from "three";
4
4
  import { ImageLoader } from "../image/ImageLoader.mjs";
5
5
  import { Textures } from "./Textures.mjs";
6
+ import { logger } from "../util/log.mjs";
7
+ var log = logger("TextureLoader");
6
8
  var TextureLoader = class {
7
9
  /** Reports whether image loading failed, so cached textures can be retried. */
8
10
  static hasFailed(texture) {
@@ -18,7 +20,7 @@ var TextureLoader = class {
18
20
  texture.needsUpdate = true;
19
21
  }, (error) => {
20
22
  this.failedTextures.add(texture);
21
- console.warn("Failed to load texture", src, error);
23
+ log.warn("Failed to load texture", src, error);
22
24
  });
23
25
  texture.image = image;
24
26
  texture.format = format;
@@ -34,7 +36,7 @@ var TextureLoader = class {
34
36
  texture.needsUpdate = true;
35
37
  }).catch((error) => {
36
38
  this.failedTextures.add(texture);
37
- console.warn("Failed to load texture", src, error);
39
+ log.warn("Failed to load texture", src, error);
38
40
  });
39
41
  texture.format = format;
40
42
  texture.rotation = rotation;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/texture/TextureLoader.ts"],"sourcesContent":["import { PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Caching } from \"../cache/Caching\";\nimport * as THREE from \"three\";\nimport { ImageLoader } from \"../image/ImageLoader\";\nimport { createCanvas } from \"../canvas/CanvasCompat\";\nimport type { CanvasRenderingContext2D } from \"canvas\";\nimport { Textures } from \"./Textures\";\n\n/** Creates sRGB textures immediately and fills their pixels after asynchronous image loading. */\nexport class TextureLoader {\n\n private static readonly failedTextures = new WeakSet<Texture>();\n\n /** Reports whether image loading failed, so cached textures can be retried. */\n public static hasFailed(texture: Texture): boolean {\n return this.failedTextures.has(texture);\n }\n\n protected static createTexture(): Texture {\n return new Texture();\n }\n\n public static loadInBackground(src: string, format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = this.createTexture();\n texture.colorSpace = THREE.SRGBColorSpace;\n const image = ImageLoader.loadElement(src, () => {\n texture.needsUpdate = true;\n }, error => {\n this.failedTextures.add(texture);\n console.warn(\"Failed to load texture\", src, error);\n });\n texture.image = image;\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n /** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */\n public static load(src: string,format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = new Texture();\n texture.colorSpace = THREE.SRGBColorSpace;\n ImageLoader.getData(src).then(image=>{\n texture.image = image;\n texture.needsUpdate = true;\n }).catch(error => {\n this.failedTextures.add(texture);\n console.warn(\"Failed to load texture\", src, error);\n });\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n\n}\n"],"mappings":";AAAA,SAAsB,YAAY,eAAe;AAEjD,YAAY,WAAW;AACvB,SAAS,mBAAmB;AAG5B,SAAS,gBAAgB;AAGlB,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAKvB,OAAc,UAAU,SAA2B;AAC/C,WAAO,KAAK,eAAe,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,OAAiB,gBAAyB;AACtC,WAAO,IAAI,QAAQ;AAAA,EACvB;AAAA,EAEA,OAAc,iBAAiB,KAAa,SAAsB,YAAY,WAAmB,GAAY;AACzG,UAAM,UAAU,KAAK,cAAc;AACnC,YAAQ,aAAmB;AAC3B,UAAM,QAAQ,YAAY,YAAY,KAAK,MAAM;AAC7C,cAAQ,cAAc;AAAA,IAC1B,GAAG,WAAS;AACR,WAAK,eAAe,IAAI,OAAO;AAC/B,cAAQ,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACrD,CAAC;AACD,YAAQ,QAAQ;AAChB,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,OAAc,KAAK,KAAY,SAAsB,YAAY,WAAmB,GAAY;AAC5F,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,aAAmB;AAC3B,gBAAY,QAAQ,GAAG,EAAE,KAAK,WAAO;AACjC,cAAQ,QAAQ;AAChB,cAAQ,cAAc;AAAA,IAC1B,CAAC,EAAE,MAAM,WAAS;AACd,WAAK,eAAe,IAAI,OAAO;AAC/B,cAAQ,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACrD,CAAC;AACD,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAGJ;AA/Ca,cAEe,iBAAiB,oBAAI,QAAiB;","names":[]}
1
+ {"version":3,"sources":["../../../../src/texture/TextureLoader.ts"],"sourcesContent":["import { PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Caching } from \"../cache/Caching\";\nimport * as THREE from \"three\";\nimport { ImageLoader } from \"../image/ImageLoader\";\nimport { createCanvas } from \"../canvas/CanvasCompat\";\nimport type { CanvasRenderingContext2D } from \"canvas\";\nimport { Textures } from \"./Textures\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"TextureLoader\");\n\n/** Creates sRGB textures immediately and fills their pixels after asynchronous image loading. */\nexport class TextureLoader {\n\n private static readonly failedTextures = new WeakSet<Texture>();\n\n /** Reports whether image loading failed, so cached textures can be retried. */\n public static hasFailed(texture: Texture): boolean {\n return this.failedTextures.has(texture);\n }\n\n protected static createTexture(): Texture {\n return new Texture();\n }\n\n public static loadInBackground(src: string, format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = this.createTexture();\n texture.colorSpace = THREE.SRGBColorSpace;\n const image = ImageLoader.loadElement(src, () => {\n texture.needsUpdate = true;\n }, error => {\n this.failedTextures.add(texture);\n log.warn(\"Failed to load texture\", src, error);\n });\n texture.image = image;\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n /** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */\n public static load(src: string,format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = new Texture();\n texture.colorSpace = THREE.SRGBColorSpace;\n ImageLoader.getData(src).then(image=>{\n texture.image = image;\n texture.needsUpdate = true;\n }).catch(error => {\n this.failedTextures.add(texture);\n log.warn(\"Failed to load texture\", src, error);\n });\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n\n}\n"],"mappings":";AAAA,SAAsB,YAAY,eAAe;AAEjD,YAAY,WAAW;AACvB,SAAS,mBAAmB;AAG5B,SAAS,gBAAgB;AACzB,SAAS,cAAc;AAEvB,IAAM,MAAM,OAAO,eAAe;AAG3B,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAKvB,OAAc,UAAU,SAA2B;AAC/C,WAAO,KAAK,eAAe,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,OAAiB,gBAAyB;AACtC,WAAO,IAAI,QAAQ;AAAA,EACvB;AAAA,EAEA,OAAc,iBAAiB,KAAa,SAAsB,YAAY,WAAmB,GAAY;AACzG,UAAM,UAAU,KAAK,cAAc;AACnC,YAAQ,aAAmB;AAC3B,UAAM,QAAQ,YAAY,YAAY,KAAK,MAAM;AAC7C,cAAQ,cAAc;AAAA,IAC1B,GAAG,WAAS;AACR,WAAK,eAAe,IAAI,OAAO;AAC/B,UAAI,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,YAAQ,QAAQ;AAChB,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,OAAc,KAAK,KAAY,SAAsB,YAAY,WAAmB,GAAY;AAC5F,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,aAAmB;AAC3B,gBAAY,QAAQ,GAAG,EAAE,KAAK,WAAO;AACjC,cAAQ,QAAQ;AAChB,cAAQ,cAAc;AAAA,IAC1B,CAAC,EAAE,MAAM,WAAS;AACd,WAAK,eAAe,IAAI,OAAO;AAC/B,UAAI,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAGJ;AA/Ca,cAEe,iBAAiB,oBAAI,QAAiB;","names":[]}
@@ -1,4 +1,77 @@
1
1
  // src/util/log.ts
2
+ var runtime = globalThis;
3
+ var levels = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
4
+ var colors = { debug: 90, info: 36, warn: 33, error: 31 };
5
+ var threshold = "warn";
6
+ var namespaces;
7
+ var logHandler;
8
+ var tagStyle;
9
+ var switchRead = false;
10
+ var switchThreshold;
11
+ var switchNamespaces;
12
+ function readSwitch() {
13
+ switchRead = true;
14
+ let value;
15
+ if (typeof runtime.process?.versions?.node === "string") {
16
+ value = runtime.process.env?.MINERENDER_LOG;
17
+ } else {
18
+ try {
19
+ value = runtime.localStorage?.getItem("minerender:log");
20
+ } catch {
21
+ }
22
+ }
23
+ if (value) {
24
+ for (const entry of value.split(",")) {
25
+ const separator = entry.indexOf("=");
26
+ const name = separator < 0 ? void 0 : entry.slice(0, separator).trim();
27
+ const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();
28
+ if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === "") continue;
29
+ if (name === void 0) {
30
+ switchThreshold = setting;
31
+ } else {
32
+ switchNamespaces ?? (switchNamespaces = /* @__PURE__ */ new Map());
33
+ switchNamespaces.set(name, setting);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ var Logging = class {
39
+ /** Updates the given settings and keeps the others. */
40
+ static configure(options) {
41
+ if (options.level !== void 0) threshold = options.level;
42
+ if (options.namespaces !== void 0) namespaces = new Map(Object.entries(options.namespaces));
43
+ }
44
+ /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */
45
+ static setHandler(handler) {
46
+ logHandler = handler;
47
+ }
48
+ };
49
+ function logger(namespace) {
50
+ const write = (level, args) => {
51
+ if (!switchRead) readSwitch();
52
+ if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;
53
+ if (logHandler) {
54
+ logHandler(level, namespace, args);
55
+ return;
56
+ }
57
+ if (tagStyle === void 0) {
58
+ tagStyle = typeof runtime.process?.versions?.node === "string" ? runtime.process.stdout?.isTTY === true ? "ansi" : "plain" : "browser";
59
+ }
60
+ if (tagStyle === "browser") {
61
+ console[level](`%cMineRender%c ${namespace}`, "background:#3c8527;color:#fff;border-radius:3px;padding:0 4px", "font-weight:bold", ...args);
62
+ } else {
63
+ const color = colors[level];
64
+ const tag = `[minerender:${namespace}]`;
65
+ console[level](tagStyle === "ansi" ? `\x1B[${color}m${tag}\x1B[0m` : tag, ...args);
66
+ }
67
+ };
68
+ return {
69
+ debug: (...args) => write("debug", args),
70
+ info: (...args) => write("info", args),
71
+ warn: (...args) => write("warn", args),
72
+ error: (...args) => write("error", args)
73
+ };
74
+ }
2
75
  var Reset = "\x1B[0m";
3
76
  var FgGreen = "\x1B[32m";
4
77
  var BgBlack = "\x1B[40m";
@@ -6,6 +79,8 @@ function prefix(prefix2) {
6
79
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
7
80
  }
8
81
  export {
82
+ Logging,
83
+ logger,
9
84
  prefix
10
85
  };
11
86
  //# sourceMappingURL=log.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/util/log.ts"],"sourcesContent":["// https://stackoverflow.com/a/41407246/6257838\nconst Reset = \"\\x1b[0m\"\nconst Bright = \"\\x1b[1m\"\nconst Dim = \"\\x1b[2m\"\nconst Underscore = \"\\x1b[4m\"\nconst Blink = \"\\x1b[5m\"\nconst Reverse = \"\\x1b[7m\"\nconst Hidden = \"\\x1b[8m\"\n\nconst FgBlack = \"\\x1b[30m\"\nconst FgRed = \"\\x1b[31m\"\nconst FgGreen = \"\\x1b[32m\"\nconst FgYellow = \"\\x1b[33m\"\nconst FgBlue = \"\\x1b[34m\"\nconst FgMagenta = \"\\x1b[35m\"\nconst FgCyan = \"\\x1b[36m\"\nconst FgWhite = \"\\x1b[37m\"\n\nconst BgBlack = \"\\x1b[40m\"\nconst BgRed = \"\\x1b[41m\"\nconst BgGreen = \"\\x1b[42m\"\nconst BgYellow = \"\\x1b[43m\"\nconst BgBlue = \"\\x1b[44m\"\nconst BgMagenta = \"\\x1b[45m\"\nconst BgCyan = \"\\x1b[46m\"\nconst BgWhite = \"\\x1b[47m\"\n\nexport function prefix(prefix?: string): string {\n return `${ FgGreen }MR${ BgBlack }${ prefix ?? '' }${ Reset }`\n}\n"],"mappings":";AACA,IAAM,QAAQ;AAUd,IAAM,UAAU;AAOhB,IAAM,UAAU;AAST,SAAS,OAAOA,SAAyB;AAC5C,SAAO,GAAI,OAAQ,KAAM,OAAQ,GAAIA,WAAU,EAAG,GAAI,KAAM;AAChE;","names":["prefix"]}
1
+ {"version":3,"sources":["../../../../src/util/log.ts"],"sourcesContent":["/** Severity of a log message, from most to least verbose. */\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/** The lowest level that is printed, or `\"silent\"` to print nothing. */\nexport type LogThreshold = LogLevel | \"silent\";\n\n/** Receives each message that passes the threshold. `args` are the logger call's arguments, without a tag. */\nexport type LogHandler = (level: LogLevel, namespace: string, args: unknown[]) => void;\n\nexport interface LoggingOptions {\n /** Threshold for namespaces without an override. Starts at `\"warn\"`. */\n level?: LogThreshold;\n /** Thresholds by logger name, such as `{ UVMapper: \"debug\" }`. Replaces earlier overrides. */\n namespaces?: Record<string, LogThreshold>;\n}\n\nexport interface Logger {\n debug(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\ntype Runtime = {\n process?: { versions?: { node?: string }; stdout?: { isTTY?: boolean }; env?: Record<string, string | undefined> };\n localStorage?: { getItem(key: string): string | null };\n};\n\nconst runtime = globalThis as Runtime;\nconst levels: Record<LogThreshold, number> = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };\nconst colors: Record<LogLevel, number> = { debug: 90, info: 36, warn: 33, error: 31 };\n\nlet threshold: LogThreshold = \"warn\";\nlet namespaces: Map<string, LogThreshold> | undefined;\nlet logHandler: LogHandler | undefined;\nlet tagStyle: \"plain\" | \"ansi\" | \"browser\" | undefined;\nlet switchRead = false;\nlet switchThreshold: LogThreshold | undefined;\nlet switchNamespaces: Map<string, LogThreshold> | undefined;\n\nfunction readSwitch(): void {\n switchRead = true;\n let value: string | null | undefined;\n if (typeof runtime.process?.versions?.node === \"string\") {\n value = runtime.process.env?.MINERENDER_LOG;\n } else {\n try {\n value = runtime.localStorage?.getItem(\"minerender:log\");\n } catch {\n // Sandboxed pages can deny access to storage.\n }\n }\n if (value) {\n for (const entry of value.split(\",\")) {\n const separator = entry.indexOf(\"=\");\n const name = separator < 0 ? undefined : entry.slice(0, separator).trim();\n const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();\n if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === \"\") continue;\n if (name === undefined) {\n switchThreshold = setting as LogThreshold;\n } else {\n switchNamespaces ??= new Map();\n switchNamespaces.set(name, setting as LogThreshold);\n }\n }\n }\n}\n\n/** Global log settings for every MineRender logger. */\nexport class Logging {\n /** Updates the given settings and keeps the others. */\n static configure(options: LoggingOptions): void {\n if (options.level !== undefined) threshold = options.level;\n if (options.namespaces !== undefined) namespaces = new Map(Object.entries(options.namespaces));\n }\n\n /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */\n static setHandler(handler?: LogHandler): void {\n logHandler = handler;\n }\n}\n\n/** Creates a logger whose messages are tagged and filtered as `namespace`. */\nexport function logger(namespace: string): Logger {\n const write = (level: LogLevel, args: unknown[]): void => {\n if (!switchRead) readSwitch();\n if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;\n if (logHandler) {\n logHandler(level, namespace, args);\n return;\n }\n if (tagStyle === undefined) {\n tagStyle = typeof runtime.process?.versions?.node === \"string\"\n ? runtime.process.stdout?.isTTY === true ? \"ansi\" : \"plain\"\n : \"browser\";\n }\n if (tagStyle === \"browser\") {\n console[level](`%cMineRender%c ${namespace}`, \"background:#3c8527;color:#fff;border-radius:3px;padding:0 4px\", \"font-weight:bold\", ...args);\n } else {\n const color = colors[level];\n const tag = `[minerender:${namespace}]`;\n console[level](tagStyle === \"ansi\" ? `\\x1b[${color}m${tag}\\x1b[0m` : tag, ...args);\n }\n };\n return {\n debug: (...args) => write(\"debug\", args),\n info: (...args) => write(\"info\", args),\n warn: (...args) => write(\"warn\", args),\n error: (...args) => write(\"error\", args),\n };\n}\n\nconst Reset = \"\\x1b[0m\"\nconst FgGreen = \"\\x1b[32m\"\nconst BgBlack = \"\\x1b[40m\"\n\n/** @deprecated Use {@link logger}. */\nexport function prefix(prefix?: string): string {\n return `${ FgGreen }MR${ BgBlack }${ prefix ?? '' }${ Reset }`\n}\n"],"mappings":";AA4BA,IAAM,UAAU;AAChB,IAAM,SAAuC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,EAAE;AAC/F,IAAM,SAAmC,EAAE,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,GAAG;AAEpF,IAAI,YAA0B;AAC9B,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI,aAAa;AACjB,IAAI;AACJ,IAAI;AAEJ,SAAS,aAAmB;AACxB,eAAa;AACb,MAAI;AACJ,MAAI,OAAO,QAAQ,SAAS,UAAU,SAAS,UAAU;AACrD,YAAQ,QAAQ,QAAQ,KAAK;AAAA,EACjC,OAAO;AACH,QAAI;AACA,cAAQ,QAAQ,cAAc,QAAQ,gBAAgB;AAAA,IAC1D,QAAQ;AAAA,IAER;AAAA,EACJ;AACA,MAAI,OAAO;AACP,eAAW,SAAS,MAAM,MAAM,GAAG,GAAG;AAClC,YAAM,YAAY,MAAM,QAAQ,GAAG;AACnC,YAAM,OAAO,YAAY,IAAI,SAAY,MAAM,MAAM,GAAG,SAAS,EAAE,KAAK;AACxE,YAAM,WAAW,YAAY,IAAI,QAAQ,MAAM,MAAM,YAAY,CAAC,GAAG,KAAK;AAC1E,UAAI,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,OAAO,KAAK,SAAS,GAAI;AAC3E,UAAI,SAAS,QAAW;AACpB,0BAAkB;AAAA,MACtB,OAAO;AACH,gDAAqB,oBAAI,IAAI;AAC7B,yBAAiB,IAAI,MAAM,OAAuB;AAAA,MACtD;AAAA,IACJ;AAAA,EACJ;AACJ;AAGO,IAAM,UAAN,MAAc;AAAA;AAAA,EAEjB,OAAO,UAAU,SAA+B;AAC5C,QAAI,QAAQ,UAAU,OAAW,aAAY,QAAQ;AACrD,QAAI,QAAQ,eAAe,OAAW,cAAa,IAAI,IAAI,OAAO,QAAQ,QAAQ,UAAU,CAAC;AAAA,EACjG;AAAA;AAAA,EAGA,OAAO,WAAW,SAA4B;AAC1C,iBAAa;AAAA,EACjB;AACJ;AAGO,SAAS,OAAO,WAA2B;AAC9C,QAAM,QAAQ,CAAC,OAAiB,SAA0B;AACtD,QAAI,CAAC,WAAY,YAAW;AAC5B,QAAI,OAAO,KAAK,IAAI,OAAO,kBAAkB,IAAI,SAAS,KAAK,mBAAmB,YAAY,IAAI,SAAS,KAAK,SAAS,EAAG;AAC5H,QAAI,YAAY;AACZ,iBAAW,OAAO,WAAW,IAAI;AACjC;AAAA,IACJ;AACA,QAAI,aAAa,QAAW;AACxB,iBAAW,OAAO,QAAQ,SAAS,UAAU,SAAS,WAChD,QAAQ,QAAQ,QAAQ,UAAU,OAAO,SAAS,UAClD;AAAA,IACV;AACA,QAAI,aAAa,WAAW;AACxB,cAAQ,KAAK,EAAE,kBAAkB,SAAS,IAAI,iEAAiE,oBAAoB,GAAG,IAAI;AAAA,IAC9I,OAAO;AACH,YAAM,QAAQ,OAAO,KAAK;AAC1B,YAAM,MAAM,eAAe,SAAS;AACpC,cAAQ,KAAK,EAAE,aAAa,SAAS,QAAQ,KAAK,IAAI,GAAG,YAAY,KAAK,GAAG,IAAI;AAAA,IACrF;AAAA,EACJ;AACA,SAAO;AAAA,IACH,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI;AAAA,IACvC,MAAM,IAAI,SAAS,MAAM,QAAQ,IAAI;AAAA,IACrC,MAAM,IAAI,SAAS,MAAM,QAAQ,IAAI;AAAA,IACrC,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI;AAAA,EAC3C;AACJ;AAEA,IAAM,QAAQ;AACd,IAAM,UAAU;AAChB,IAAM,UAAU;AAGT,SAAS,OAAOA,SAAyB;AAC5C,SAAO,GAAI,OAAQ,KAAM,OAAQ,GAAIA,WAAU,EAAG,GAAI,KAAM;AAChE;","names":["prefix"]}
@@ -17,13 +17,13 @@ function applyElementRotation(rotation, geometry) {
17
17
  break;
18
18
  }
19
19
  if (rotation.rescale) {
20
- if (Math.abs(rotation.angle) === 22.5) {
21
- const s = 1 / Math.cos(0.39269909262657166);
22
- geometry.scale(s, 1, s);
23
- } else {
24
- const s = 1 / Math.cos(0.7853981852531433);
25
- geometry.scale(s, 1, s);
26
- }
20
+ const angle = toRadians(rotation.angle);
21
+ const s = 1 / Math.max(Math.abs(Math.cos(angle)), Math.abs(Math.sin(angle)));
22
+ geometry.scale(
23
+ rotation.axis === Axis.X ? 1 : s,
24
+ rotation.axis === Axis.Y ? 1 : s,
25
+ rotation.axis === Axis.Z ? 1 : s
26
+ );
27
27
  }
28
28
  geometry.translate(origin.x, origin.y, origin.z);
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/util/model.ts"],"sourcesContent":["/// https://stackoverflow.com/questions/42812861/three-js-pivot-point/42866733#42866733\n// obj - your object (THREE.Object3D or derived)\n// point - the point of rotation (THREE.Vector3)\n// axis - the axis of rotation (normalized THREE.Vector3)\n// theta - radian value of rotation\nimport { ElementRotation } from \"../model/ModelElement\";\nimport type { BufferGeometry } from \"three\";\nimport { Axis } from \"../Axis\";\nimport { toRadians } from \"./util\";\nimport { AxesHelper, Box3, BoxGeometry, EdgesGeometry, LineBasicMaterial, LineSegments, Matrix4, Mesh, Object3D, Quaternion, Vector3, Vector4 } from \"three\";\n\nfunction rotateAboutPoint(obj: Object3D, point: Vector3, axis: Vector3, theta: number) {\n obj.position.sub(point); // remove the offset\n obj.position.applyAxisAngle(axis, theta); // rotate the POSITION\n obj.position.add(point); // re-add the offset\n\n obj.rotateOnAxis(axis, theta); // rotate the OBJECT\n}\n\n/** Rotates geometry in place around the element's origin. The supplied angle is in degrees. */\nexport function applyElementRotation(rotation: ElementRotation, geometry: BufferGeometry) {\n const origin = new Vector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]);\n // origin.multiplyScalar(0.0625);\n\n\n // let axisVector: Vector3;\n // let inverseAxisVector: Vector3;\n // switch (rotation.axis) {\n // case Axis.X:\n // axisVector = new Vector3(1, 0, 0);\n // inverseAxisVector = new Vector3(0, 1, 1);\n // break;\n // case Axis.Y:\n // axisVector = new Vector3(0, 1, 0);\n // inverseAxisVector = new Vector3(1, 0, 1);\n // break;\n // case Axis.Z:\n // axisVector = new Vector3(0, 0, 1);\n // inverseAxisVector = new Vector3(1, 1, 0);\n // break;\n // }\n // const quat = new Quaternion().setFromAxisAngle(axisVector, (rotation.angle*0.017453292));\n // if (rotation.rescale) {\n // if (Math.abs(rotation.angle) === 22.5) {\n // inverseAxisVector.multiplyScalar(1.0 / Math.cos(0.39269909262657166) - 1.0)\n // }else {\n // inverseAxisVector.multiplyScalar(1.0 / Math.cos(0.7853981852531433) - 1.0)\n // }\n //\n // inverseAxisVector.add(new Vector3(1, 1, 1));\n // }else{\n // inverseAxisVector.set(1, 1, 1);\n // }\n\n // Vector4 vec4 = new Vector4(geometry.getAttribute(\"position\").)\n\n\n // subtract origin\n geometry.translate(-origin.x, -origin.y, -origin.z);\n // apply rotation\n switch (rotation.axis) {\n case Axis.X:\n geometry.rotateX(toRadians(rotation.angle));\n break;\n case Axis.Y:\n geometry.rotateY(toRadians(rotation.angle));\n break;\n case Axis.Z:\n geometry.rotateZ(toRadians(rotation.angle));\n break;\n }\n\n\n // if (rotation.rescale) {\n // console.log(\"angle\", Math.abs(rotation.angle) )\n // if (Math.abs(rotation.angle) === 22.5) {\n // const s = 2;\n // geometry.scale(s, s, s);\n // }else{\n // const s = 2;\n // geometry.scale(s, s, s);\n // }\n // }\n if (rotation.rescale) {\n //TODO: y height seems a bit too tall (1 pixel)\n if (Math.abs(rotation.angle) === 22.5) {\n const s = 1.0 / Math.cos(0.39269909262657166);\n geometry.scale(s, 1, s);\n }else {\n const s = 1.0 / Math.cos(0.7853981852531433);\n geometry.scale(s, 1, s);\n }\n }\n\n // add back origin\n geometry.translate(origin.x, origin.y, origin.z);\n\n\n}\n\n/** Rotates an object around a local axis by an angle in degrees. */\nexport function applyGenericRotation(axis: Axis, rotation: number, obj: Object3D) {\n\n\n // obj.position.sub(new Vector3(8,8,8).add(obj.position))\n //\n // switch (axis) {\n // case Axis.X:\n // obj.position.applyAxisAngle(new Vector3(1, 0, 0), toRadians(rotation));\n // break;\n // case Axis.Y:\n // obj.position.applyAxisAngle(new Vector3(0, 1, 0), toRadians(rotation));\n // break;\n // case Axis.Z:\n // obj.position.applyAxisAngle(new Vector3(0, 0, 1), toRadians(rotation));\n // break;\n // }\n //\n // obj.position.add(new Vector3(8,8,8).add(obj.position))\n\n switch (axis) {\n case Axis.X:\n obj.rotateOnAxis(new Vector3(1, 0, 0), toRadians(rotation));\n break;\n case Axis.Y:\n obj.rotateOnAxis(new Vector3(0, 1, 0), toRadians(rotation));\n break;\n case Axis.Z:\n obj.rotateOnAxis(new Vector3(0, 0, 1), toRadians(rotation));\n break;\n }\n\n // subtract origin\n // obj.translateX(-8);\n // obj.translateZ(-8);\n // obj.translateY(-8);\n // // apply rotation\n // switch (axis) {\n // case Axis.X:\n // obj.rotateX(toRadians(rotation));\n // // matrix.makeRotationX(toRadians(rotation));\n // break;\n // case Axis.Y:\n // obj.rotateY(toRadians(rotation));\n // // matrix.makeRotationY(toRadians(rotation));\n // break;\n // case Axis.Z:\n // obj.rotateZ(toRadians(rotation));\n // // matrix.makeRotationZ(toRadians(rotation));\n // break;\n // }\n // // add back origin\n // obj.translateX(8);\n // obj.translateZ(8);\n // obj.translateY(8);\n\n // obj.applyMatrix4(matrix);\n}\n\nexport function addBox3WireframeToObject(box: Box3, obj: Object3D, color: number = 0xffffff, w: number = 2) {\n let size = new Vector3();\n box.getSize(size);\n\n let boxGeo = new BoxGeometry(size.x, size.y, size.z, 1, 1, 1);\n // boxGeo.translate(box.min.x, box.min.y, box.min.z);\n let wireGeo = new EdgesGeometry(boxGeo);\n let wireMat = new LineBasicMaterial({ color: color, linewidth: w, })\n let wireframe = new LineSegments(wireGeo, wireMat);\n obj.add(wireframe);\n\n let axes = new AxesHelper(1);\n obj.add(axes);\n}\n\n\nexport function addWireframeToObject(obj: Object3D, color: number = 0xffffff, w: number = 2) {\n let boxGeo = new BoxGeometry(16, 16, 16, 1, 1, 1);\n let wireGeo = new EdgesGeometry(boxGeo);\n let wireMat = new LineBasicMaterial({ color: color, linewidth: w, })\n let wireframe = new LineSegments(wireGeo, wireMat);\n obj.add(wireframe);\n\n let axes = new AxesHelper(1);\n obj.add(axes);\n}\n\n/** Adds edge and axis helpers to a mesh and returns a function that disposes their resources. */\nexport function addWireframeToMesh(geo: BufferGeometry, mesh: Mesh, color: number = 0xffffff, w: number = 2) {\n let wireGeo = new EdgesGeometry(geo);\n let wireMat = new LineBasicMaterial({ color: color, linewidth: w, })\n let wireframe = new LineSegments(wireGeo, wireMat);\n mesh.add(wireframe);\n\n let axes = new AxesHelper(1);\n mesh.add(axes);\n\n return () => {\n wireGeo.dispose();\n wireMat.dispose();\n axes.dispose();\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/util/model.ts"],"sourcesContent":["/// https://stackoverflow.com/questions/42812861/three-js-pivot-point/42866733#42866733\n// obj - your object (THREE.Object3D or derived)\n// point - the point of rotation (THREE.Vector3)\n// axis - the axis of rotation (normalized THREE.Vector3)\n// theta - radian value of rotation\nimport { ElementRotation } from \"../model/ModelElement\";\nimport type { BufferGeometry } from \"three\";\nimport { Axis } from \"../Axis\";\nimport { toRadians } from \"./util\";\nimport { AxesHelper, Box3, BoxGeometry, EdgesGeometry, LineBasicMaterial, LineSegments, Matrix4, Mesh, Object3D, Quaternion, Vector3, Vector4 } from \"three\";\n\nfunction rotateAboutPoint(obj: Object3D, point: Vector3, axis: Vector3, theta: number) {\n obj.position.sub(point); // remove the offset\n obj.position.applyAxisAngle(axis, theta); // rotate the POSITION\n obj.position.add(point); // re-add the offset\n\n obj.rotateOnAxis(axis, theta); // rotate the OBJECT\n}\n\n/** Rotates geometry in place around the element's origin. The supplied angle is in degrees. */\nexport function applyElementRotation(rotation: ElementRotation, geometry: BufferGeometry) {\n const origin = new Vector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]);\n // origin.multiplyScalar(0.0625);\n\n\n // let axisVector: Vector3;\n // let inverseAxisVector: Vector3;\n // switch (rotation.axis) {\n // case Axis.X:\n // axisVector = new Vector3(1, 0, 0);\n // inverseAxisVector = new Vector3(0, 1, 1);\n // break;\n // case Axis.Y:\n // axisVector = new Vector3(0, 1, 0);\n // inverseAxisVector = new Vector3(1, 0, 1);\n // break;\n // case Axis.Z:\n // axisVector = new Vector3(0, 0, 1);\n // inverseAxisVector = new Vector3(1, 1, 0);\n // break;\n // }\n // const quat = new Quaternion().setFromAxisAngle(axisVector, (rotation.angle*0.017453292));\n // if (rotation.rescale) {\n // if (Math.abs(rotation.angle) === 22.5) {\n // inverseAxisVector.multiplyScalar(1.0 / Math.cos(0.39269909262657166) - 1.0)\n // }else {\n // inverseAxisVector.multiplyScalar(1.0 / Math.cos(0.7853981852531433) - 1.0)\n // }\n //\n // inverseAxisVector.add(new Vector3(1, 1, 1));\n // }else{\n // inverseAxisVector.set(1, 1, 1);\n // }\n\n // Vector4 vec4 = new Vector4(geometry.getAttribute(\"position\").)\n\n\n // subtract origin\n geometry.translate(-origin.x, -origin.y, -origin.z);\n // apply rotation\n switch (rotation.axis) {\n case Axis.X:\n geometry.rotateX(toRadians(rotation.angle));\n break;\n case Axis.Y:\n geometry.rotateY(toRadians(rotation.angle));\n break;\n case Axis.Z:\n geometry.rotateZ(toRadians(rotation.angle));\n break;\n }\n\n\n // if (rotation.rescale) {\n // console.log(\"angle\", Math.abs(rotation.angle) )\n // if (Math.abs(rotation.angle) === 22.5) {\n // const s = 2;\n // geometry.scale(s, s, s);\n // }else{\n // const s = 2;\n // geometry.scale(s, s, s);\n // }\n // }\n if (rotation.rescale) {\n // As in vanilla 1.21.6+, the element keeps its unrotated size along the nearest grid axis.\n const angle = toRadians(rotation.angle);\n const s = 1 / Math.max(Math.abs(Math.cos(angle)), Math.abs(Math.sin(angle)));\n geometry.scale(\n rotation.axis === Axis.X ? 1 : s,\n rotation.axis === Axis.Y ? 1 : s,\n rotation.axis === Axis.Z ? 1 : s\n );\n }\n\n // add back origin\n geometry.translate(origin.x, origin.y, origin.z);\n\n\n}\n\n/** Rotates an object around a local axis by an angle in degrees. */\nexport function applyGenericRotation(axis: Axis, rotation: number, obj: Object3D) {\n\n\n // obj.position.sub(new Vector3(8,8,8).add(obj.position))\n //\n // switch (axis) {\n // case Axis.X:\n // obj.position.applyAxisAngle(new Vector3(1, 0, 0), toRadians(rotation));\n // break;\n // case Axis.Y:\n // obj.position.applyAxisAngle(new Vector3(0, 1, 0), toRadians(rotation));\n // break;\n // case Axis.Z:\n // obj.position.applyAxisAngle(new Vector3(0, 0, 1), toRadians(rotation));\n // break;\n // }\n //\n // obj.position.add(new Vector3(8,8,8).add(obj.position))\n\n switch (axis) {\n case Axis.X:\n obj.rotateOnAxis(new Vector3(1, 0, 0), toRadians(rotation));\n break;\n case Axis.Y:\n obj.rotateOnAxis(new Vector3(0, 1, 0), toRadians(rotation));\n break;\n case Axis.Z:\n obj.rotateOnAxis(new Vector3(0, 0, 1), toRadians(rotation));\n break;\n }\n\n // subtract origin\n // obj.translateX(-8);\n // obj.translateZ(-8);\n // obj.translateY(-8);\n // // apply rotation\n // switch (axis) {\n // case Axis.X:\n // obj.rotateX(toRadians(rotation));\n // // matrix.makeRotationX(toRadians(rotation));\n // break;\n // case Axis.Y:\n // obj.rotateY(toRadians(rotation));\n // // matrix.makeRotationY(toRadians(rotation));\n // break;\n // case Axis.Z:\n // obj.rotateZ(toRadians(rotation));\n // // matrix.makeRotationZ(toRadians(rotation));\n // break;\n // }\n // // add back origin\n // obj.translateX(8);\n // obj.translateZ(8);\n // obj.translateY(8);\n\n // obj.applyMatrix4(matrix);\n}\n\nexport function addBox3WireframeToObject(box: Box3, obj: Object3D, color: number = 0xffffff, w: number = 2) {\n let size = new Vector3();\n box.getSize(size);\n\n let boxGeo = new BoxGeometry(size.x, size.y, size.z, 1, 1, 1);\n // boxGeo.translate(box.min.x, box.min.y, box.min.z);\n let wireGeo = new EdgesGeometry(boxGeo);\n let wireMat = new LineBasicMaterial({ color: color, linewidth: w, })\n let wireframe = new LineSegments(wireGeo, wireMat);\n obj.add(wireframe);\n\n let axes = new AxesHelper(1);\n obj.add(axes);\n}\n\n\nexport function addWireframeToObject(obj: Object3D, color: number = 0xffffff, w: number = 2) {\n let boxGeo = new BoxGeometry(16, 16, 16, 1, 1, 1);\n let wireGeo = new EdgesGeometry(boxGeo);\n let wireMat = new LineBasicMaterial({ color: color, linewidth: w, })\n let wireframe = new LineSegments(wireGeo, wireMat);\n obj.add(wireframe);\n\n let axes = new AxesHelper(1);\n obj.add(axes);\n}\n\n/** Adds edge and axis helpers to a mesh and returns a function that disposes their resources. */\nexport function addWireframeToMesh(geo: BufferGeometry, mesh: Mesh, color: number = 0xffffff, w: number = 2) {\n let wireGeo = new EdgesGeometry(geo);\n let wireMat = new LineBasicMaterial({ color: color, linewidth: w, })\n let wireframe = new LineSegments(wireGeo, wireMat);\n mesh.add(wireframe);\n\n let axes = new AxesHelper(1);\n mesh.add(axes);\n\n return () => {\n wireGeo.dispose();\n wireMat.dispose();\n axes.dispose();\n };\n}\n"],"mappings":";AAOA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,YAAkB,aAAa,eAAe,mBAAmB,cAAmD,eAAwB;AAW9I,SAAS,qBAAqB,UAA2B,UAA0B;AACtF,QAAM,SAAS,IAAI,QAAQ,SAAS,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC;AAqCrF,WAAS,UAAU,CAAC,OAAO,GAAG,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC;AAElD,UAAQ,SAAS,MAAM;AAAA,IACnB,KAAK,KAAK;AACN,eAAS,QAAQ,UAAU,SAAS,KAAK,CAAC;AAC1C;AAAA,IACJ,KAAK,KAAK;AACN,eAAS,QAAQ,UAAU,SAAS,KAAK,CAAC;AAC1C;AAAA,IACJ,KAAK,KAAK;AACN,eAAS,QAAQ,UAAU,SAAS,KAAK,CAAC;AAC1C;AAAA,EACR;AAaA,MAAI,SAAS,SAAS;AAElB,UAAM,QAAQ,UAAU,SAAS,KAAK;AACtC,UAAM,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC;AAC3E,aAAS;AAAA,MACL,SAAS,SAAS,KAAK,IAAI,IAAI;AAAA,MAC/B,SAAS,SAAS,KAAK,IAAI,IAAI;AAAA,MAC/B,SAAS,SAAS,KAAK,IAAI,IAAI;AAAA,IACnC;AAAA,EACJ;AAGA,WAAS,UAAU,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAGnD;AAGO,SAAS,qBAAqB,MAAY,UAAkB,KAAe;AAmB9E,UAAQ,MAAM;AAAA,IACV,KAAK,KAAK;AACN,UAAI,aAAa,IAAI,QAAQ,GAAG,GAAG,CAAC,GAAG,UAAU,QAAQ,CAAC;AAC1D;AAAA,IACJ,KAAK,KAAK;AACN,UAAI,aAAa,IAAI,QAAQ,GAAG,GAAG,CAAC,GAAG,UAAU,QAAQ,CAAC;AAC1D;AAAA,IACJ,KAAK,KAAK;AACN,UAAI,aAAa,IAAI,QAAQ,GAAG,GAAG,CAAC,GAAG,UAAU,QAAQ,CAAC;AAC1D;AAAA,EACR;AA2BJ;AAEO,SAAS,yBAAyB,KAAW,KAAe,QAAgB,UAAU,IAAY,GAAG;AACxG,MAAI,OAAO,IAAI,QAAQ;AACvB,MAAI,QAAQ,IAAI;AAEhB,MAAI,SAAS,IAAI,YAAY,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,CAAC;AAE5D,MAAI,UAAU,IAAI,cAAc,MAAM;AACtC,MAAI,UAAU,IAAI,kBAAkB,EAAE,OAAc,WAAW,EAAG,CAAC;AACnE,MAAI,YAAY,IAAI,aAAa,SAAS,OAAO;AACjD,MAAI,IAAI,SAAS;AAEjB,MAAI,OAAO,IAAI,WAAW,CAAC;AAC3B,MAAI,IAAI,IAAI;AAChB;AAGO,SAAS,qBAAqB,KAAe,QAAgB,UAAU,IAAY,GAAG;AACzF,MAAI,SAAS,IAAI,YAAY,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC;AAChD,MAAI,UAAU,IAAI,cAAc,MAAM;AACtC,MAAI,UAAU,IAAI,kBAAkB,EAAE,OAAc,WAAW,EAAG,CAAC;AACnE,MAAI,YAAY,IAAI,aAAa,SAAS,OAAO;AACjD,MAAI,IAAI,SAAS;AAEjB,MAAI,OAAO,IAAI,WAAW,CAAC;AAC3B,MAAI,IAAI,IAAI;AAChB;AAGO,SAAS,mBAAmB,KAAqB,MAAY,QAAgB,UAAU,IAAY,GAAG;AACzG,MAAI,UAAU,IAAI,cAAc,GAAG;AACnC,MAAI,UAAU,IAAI,kBAAkB,EAAE,OAAc,WAAW,EAAG,CAAC;AACnE,MAAI,YAAY,IAAI,aAAa,SAAS,OAAO;AACjD,OAAK,IAAI,SAAS;AAElB,MAAI,OAAO,IAAI,WAAW,CAAC;AAC3B,OAAK,IAAI,IAAI;AAEb,SAAO,MAAM;AACT,YAAQ,QAAQ;AAChB,YAAQ,QAAQ;AAChB,SAAK,QAAQ;AAAA,EACjB;AACJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/util/performance.ts"],"sourcesContent":["export function captureException(e: any, ...extra: any[]) {\n console.error(e, extra);\n //TODO\n}\n\nexport function timingStart(marker: string) {\n console.time(marker);\n //TODO\n}\n\nexport function timingEnd(marker: string) {\n console.timeEnd(marker);\n //TODO\n}\n"],"mappings":";AAAO,SAAS,iBAAiB,MAAW,OAAc;AACtD,UAAQ,MAAM,GAAG,KAAK;AAE1B;AAEO,SAAS,YAAY,QAAgB;AACxC,UAAQ,KAAK,MAAM;AAEvB;AAEO,SAAS,UAAU,QAAgB;AACtC,UAAQ,QAAQ,MAAM;AAE1B;","names":[]}
1
+ {"version":3,"sources":["../../../../src/util/performance.ts"],"sourcesContent":["/** @deprecated Unused by MineRender. */\nexport function captureException(e: any, ...extra: any[]) {\n console.error(e, extra);\n //TODO\n}\n\n/** @deprecated Unused by MineRender. */\nexport function timingStart(marker: string) {\n console.time(marker);\n //TODO\n}\n\n/** @deprecated Unused by MineRender. */\nexport function timingEnd(marker: string) {\n console.timeEnd(marker);\n //TODO\n}\n"],"mappings":";AACO,SAAS,iBAAiB,MAAW,OAAc;AACtD,UAAQ,MAAM,GAAG,KAAK;AAE1B;AAGO,SAAS,YAAY,QAAgB;AACxC,UAAQ,KAAK,MAAM;AAEvB;AAGO,SAAS,UAAU,QAAgB;AACtC,UAAQ,QAAQ,MAAM;AAE1B;","names":[]}
@@ -134,11 +134,14 @@ var Chunk = class _Chunk {
134
134
  this.biomes = copy;
135
135
  return this.refreshBiomes();
136
136
  }
137
- /** Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects. */
138
- refreshBiomes(columns) {
139
- return this.changeBlocks(() => this.refreshBiomeBlocks(columns), true);
137
+ /**
138
+ * Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
139
+ * The owning world can defer neighbor culling until all affected chunks are refreshed.
140
+ */
141
+ refreshBiomes(columns, deferCulling = false) {
142
+ return this.changeBlocks(() => this.refreshBiomeBlocks(columns, deferCulling), true);
140
143
  }
141
- async refreshBiomeBlocks(columns) {
144
+ async refreshBiomeBlocks(columns, deferCulling = false) {
142
145
  const blend = columns && this.biomeBlend?.();
143
146
  const ownColumn = columns?.some((column) => column.x === this.x && column.z === this.z);
144
147
  const affected = /* @__PURE__ */ new Map();
@@ -195,7 +198,7 @@ var Chunk = class _Chunk {
195
198
  this.renderedBlocks.get(index)?.object?.setVisible(false);
196
199
  }
197
200
  const positions = blocks.map(({ index }) => new Vector3(...this.positionAt(index)));
198
- if (this.onBlocksChanged) await this.onBlocksChanged(positions);
201
+ if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
199
202
  else await this.rebuildSectionMesh();
200
203
  }
201
204
  }