minerender 2.1.0-alpha.30 → 2.1.0-alpha.32

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.
@@ -288,7 +288,7 @@ function isDisposable(obj) {
288
288
  import { BoxGeometry, Float32BufferAttribute } from "three";
289
289
 
290
290
  // src/util/util.ts
291
- import * as CryptoJS from "crypto-js";
291
+ import CryptoJS from "crypto-js";
292
292
  var changeEvent = { type: "change" };
293
293
  function md5(str) {
294
294
  return CryptoJS.MD5(str).toString(CryptoJS.enc.Hex);
@@ -5479,17 +5479,17 @@ var baseSkinCoordinates = {
5479
5479
  },
5480
5480
  up: {
5481
5481
  uv: [
5482
- 4,
5483
- 36,
5484
5482
  8,
5483
+ 36,
5484
+ 4,
5485
5485
  32
5486
5486
  ]
5487
5487
  },
5488
5488
  down: {
5489
5489
  uv: [
5490
- 8,
5491
- 32,
5492
5490
  12,
5491
+ 32,
5492
+ 8,
5493
5493
  36
5494
5494
  ],
5495
5495
  rotation: 180
@@ -5545,13 +5545,13 @@ var slimSkinTextureCoordinates = {
5545
5545
 
5546
5546
  // src/skin/SkinGeometries.ts
5547
5547
  var box8inner = [8, 8, 8];
5548
- var box8outer = [8.504, 8.504, 8.504];
5548
+ var box8outer = [9, 9, 9];
5549
5549
  var box8_12_4inner = [8, 12, 4];
5550
- var box8_12_4outer = [8.504, 12.504, 4.504];
5550
+ var box8_12_4outer = [8.5, 12.5, 4.5];
5551
5551
  var box4_12_4inner = [4, 12, 4];
5552
- var box4_12_4outer = [4.504, 12.504, 4.504];
5552
+ var box4_12_4outer = [4.5, 12.5, 4.5];
5553
5553
  var box3_12_4inner = [3, 12, 4];
5554
- var box3_12_4outer = [3.504, 12.504, 4.504];
5554
+ var box3_12_4outer = [3.5, 12.5, 4.5];
5555
5555
  var box10_16_1 = [10, 16, 1];
5556
5556
  var baseSkinGeometries = {
5557
5557
  head: box8inner,
@@ -5585,9 +5585,54 @@ var import_ts_deepmerge7 = __toESM(require_dist());
5585
5585
 
5586
5586
  // src/skin/SkinTextures.ts
5587
5587
  import { DataTexture, DoubleSide as DoubleSide2, FrontSide as FrontSide2, MeshBasicMaterial as MeshBasicMaterial3, SRGBColorSpace as SRGBColorSpace3 } from "three";
5588
+
5589
+ // src/skin/SkinImage.ts
5590
+ var SkinImage = class {
5591
+ static async getData(src) {
5592
+ const key = serializeImageKey({ src });
5593
+ return await Caching.imageDataCache.get(`skin:${key}`, async () => {
5594
+ const info = await ImageLoader.getInfo(src);
5595
+ if (info.type !== "png") return ImageLoader.getData(src);
5596
+ try {
5597
+ return await this.decodePng(info.data);
5598
+ } catch (error) {
5599
+ Caching.rawImageCache.invalidate(key);
5600
+ throw error;
5601
+ }
5602
+ });
5603
+ }
5604
+ static async decodePng(bytes) {
5605
+ const { decode, convertIndexedToRgb } = await import("fast-png");
5606
+ const png = decode(bytes);
5607
+ let { data, channels, depth } = png;
5608
+ if (channels === 1 && (png.palette || depth < 8)) {
5609
+ const max = (1 << depth) - 1;
5610
+ const palette = png.palette ?? Array.from({ length: max + 1 }, (_, value) => {
5611
+ const gray = value * 255 / max;
5612
+ return [gray, gray, gray, png.transparency?.[0] === value ? 0 : 255];
5613
+ });
5614
+ data = convertIndexedToRgb({ ...png, palette });
5615
+ channels = palette[0].length;
5616
+ depth = 8;
5617
+ }
5618
+ const pixels = new Uint8ClampedArray(png.width * png.height * 4);
5619
+ for (let pixel = 0; pixel < png.width * png.height; pixel++) {
5620
+ const source = pixel * channels;
5621
+ const target = pixel * 4;
5622
+ const sample = (channel) => depth === 16 ? data[source + channel] >>> 8 : data[source + channel];
5623
+ pixels[target] = sample(0);
5624
+ pixels[target + 1] = sample(channels < 3 ? 0 : 1);
5625
+ pixels[target + 2] = sample(channels < 3 ? 0 : 2);
5626
+ pixels[target + 3] = channels % 2 === 0 ? sample(channels - 1) : png.transparency?.every((value, channel) => data[source + channel] === value) ? 0 : 255;
5627
+ }
5628
+ return { width: png.width, height: png.height, data: pixels, colorSpace: "srgb" };
5629
+ }
5630
+ };
5631
+
5632
+ // src/skin/SkinTextures.ts
5588
5633
  var SkinTextures = class {
5589
5634
  static async get(src, legacy) {
5590
- const image = await ImageLoader.getData(src);
5635
+ const image = await SkinImage.getData(src);
5591
5636
  const scale = image.width / 64;
5592
5637
  if (!Number.isInteger(scale) || scale < 1 || image.height !== image.width && image.height !== image.width / 2) {
5593
5638
  throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; expected 64x64 or 64x32, or an integer-scaled equivalent`);
@@ -5600,12 +5645,13 @@ var SkinTextures = class {
5600
5645
  const key = `skin:${serializeImageKey({ src })}:${isLegacy}`;
5601
5646
  const material = Caching.materialCache.get(key, () => {
5602
5647
  const pixels = isLegacy ? this.normalizeLegacy(image, scale) : new Uint8Array(image.data);
5648
+ this.makeBaseOpaque(pixels, image.width, scale);
5603
5649
  return this.createMaterial(pixels, image.width, image.width);
5604
5650
  });
5605
5651
  return { material, slim, legacy: isLegacy };
5606
5652
  }
5607
5653
  static async getCape(src, layout = "minecraft") {
5608
- const image = await ImageLoader.getData(src);
5654
+ const image = await SkinImage.getData(src);
5609
5655
  const scale = image.width / 64;
5610
5656
  if (layout === "minecraft" && (!Number.isInteger(scale) || scale < 1 || image.height !== image.width / 2)) {
5611
5657
  throw new MineRenderError(`Invalid cape dimensions ${image.width}x${image.height}; expected 64x32 or an integer-scaled equivalent`);
@@ -5619,7 +5665,7 @@ var SkinTextures = class {
5619
5665
  texture.colorSpace = SRGBColorSpace3;
5620
5666
  texture.flipY = true;
5621
5667
  texture.needsUpdate = true;
5622
- return new MeshBasicMaterial3({ map: texture, transparent, side: transparent ? DoubleSide2 : FrontSide2, alphaTest: transparent ? 0.5 : 0 });
5668
+ return new MeshBasicMaterial3({ map: texture, transparent, side: transparent ? DoubleSide2 : FrontSide2, alphaTest: transparent ? 0.1 : 0 });
5623
5669
  }
5624
5670
  static isSlim(image, scale) {
5625
5671
  for (const [x, y] of [[46, 52], [54, 20]]) {
@@ -5662,18 +5708,22 @@ var SkinTextures = class {
5662
5708
  if (pixels[(y * image.width + x) * 4 + 3] < 128) clearHat = false;
5663
5709
  }
5664
5710
  }
5665
- for (let y = 0; y < image.width; y++) {
5666
- for (let x = 0; x < image.width; x++) {
5667
- const alpha = (y * image.width + x) * 4 + 3;
5668
- if (x < 32 * scale && y < 16 * scale || y >= 16 * scale && y < 32 * scale || x >= 16 * scale && x < 48 * scale && y >= 48 * scale) {
5669
- pixels[alpha] = 255;
5670
- } else if (clearHat && x >= 32 * scale && y < 32 * scale) {
5671
- pixels[alpha] = 0;
5711
+ if (clearHat) {
5712
+ for (let y = 0; y < 32 * scale; y++) {
5713
+ for (let x = 32 * scale; x < image.width; x++) {
5714
+ pixels[(y * image.width + x) * 4 + 3] = 0;
5672
5715
  }
5673
5716
  }
5674
5717
  }
5675
5718
  return pixels;
5676
5719
  }
5720
+ static makeBaseOpaque(pixels, width, scale) {
5721
+ for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64]]) {
5722
+ for (let y = y0 * scale; y < y1 * scale; y++) {
5723
+ for (let x = x0 * scale; x < x1 * scale; x++) pixels[(y * width + x) * 4 + 3] = 255;
5724
+ }
5725
+ }
5726
+ }
5677
5727
  };
5678
5728
 
5679
5729
  // src/skin/CapeLayout.ts
@@ -5695,12 +5745,13 @@ var SkinObject = class extends SceneObject {
5695
5745
  this.slim = this.options.slim ?? false;
5696
5746
  }
5697
5747
  async init() {
5748
+ const cape = this.getGroupByName("cape" /* CAPE */);
5698
5749
  this.createMeshes();
5750
+ if (cape) this.getGroupByName("body" /* BODY */).attach(cape);
5699
5751
  }
5700
5752
  removeMeshes() {
5701
5753
  }
5702
5754
  createMeshes() {
5703
- console.log("#createMeshes");
5704
5755
  const mat = this.skinMaterial ?? Materials.MISSING_TEXTURE;
5705
5756
  {
5706
5757
  const headGroup = this.createAndAddGroup("head", 0, 28, 0, "y" /* Y */, -4);
@@ -5710,45 +5761,48 @@ var SkinObject = class extends SceneObject {
5710
5761
  const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
5711
5762
  }
5712
5763
  {
5713
- const bodyGroup = this.createAndAddGroup("body", 0, 18, 0);
5764
+ const bodyGroup = this.createAndAddGroup("body", 0, 24, 0);
5714
5765
  const bodyGeo = this.getBoxGeometry("body" /* BODY */);
5715
- const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat);
5766
+ const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat, "y" /* Y */, -6);
5716
5767
  const jacketGeo = this.getBoxGeometry("jacket" /* JACKET */);
5717
- const jacket = this.createAndAddMesh("jacket", bodyGroup, jacketGeo, mat);
5768
+ const jacket = this.createAndAddMesh("jacket", bodyGroup, jacketGeo, mat, "y" /* Y */, -6);
5718
5769
  }
5719
5770
  {
5720
5771
  {
5721
- const leftArmGroup = this.createAndAddGroup("leftArm", this.slim ? -5.5 : -6, 18, 0, "y" /* Y */, 4);
5772
+ const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
5722
5773
  const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
5723
5774
  const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
5775
+ leftArm.position.x = this.slim ? -0.5 : -1;
5724
5776
  const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
5725
5777
  const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
5778
+ leftSleeve.position.x = this.slim ? -0.5 : -1;
5726
5779
  }
5727
5780
  {
5728
- const rightArmGroup = this.createAndAddGroup("rightArm", this.slim ? 5.5 : 6, 18, 0, "y" /* Y */, 4);
5781
+ const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
5729
5782
  const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
5730
5783
  const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
5784
+ rightArm.position.x = this.slim ? 0.5 : 1;
5731
5785
  const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
5732
5786
  const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
5787
+ rightSleeve.position.x = this.slim ? 0.5 : 1;
5733
5788
  }
5734
5789
  }
5735
5790
  {
5736
5791
  {
5737
- const leftLegGroup = this.createAndAddGroup("leftLeg", -2, 6, 0, "y" /* Y */, 4);
5792
+ const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
5738
5793
  const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
5739
- const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -4);
5794
+ const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
5740
5795
  const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
5741
- const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -4);
5796
+ const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
5742
5797
  }
5743
5798
  {
5744
- const rightLegGroup = this.createAndAddGroup("rightLeg", 2, 6, 0, "y" /* Y */, 4);
5799
+ const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
5745
5800
  const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
5746
- const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -4);
5801
+ const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
5747
5802
  const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
5748
- const rightTrousers = this.createAndAddMesh("rightTrousers", rightLegGroup, rightTrousersGeo, mat, "y" /* Y */, -4);
5803
+ const rightTrousers = this.createAndAddMesh("rightTrousers", rightLegGroup, rightTrousersGeo, mat, "y" /* Y */, -6);
5749
5804
  }
5750
5805
  }
5751
- console.log("#createMeshes done");
5752
5806
  }
5753
5807
  async setSkinTexture(src) {
5754
5808
  if (typeof src === "undefined") return;
@@ -5773,7 +5827,7 @@ var SkinObject = class extends SceneObject {
5773
5827
  const load = ++this.capeLoad;
5774
5828
  if (src === void 0) {
5775
5829
  const group = this.getGroupByName("cape" /* CAPE */);
5776
- if (group) this.remove(group);
5830
+ group?.removeFromParent();
5777
5831
  this.notifyDirty();
5778
5832
  return;
5779
5833
  }
@@ -5791,7 +5845,9 @@ var SkinObject = class extends SceneObject {
5791
5845
  mesh.material = material;
5792
5846
  mesh.geometry = geometry;
5793
5847
  } else {
5794
- const group = this.createAndAddGroup("cape" /* CAPE */, 0, 24, 2);
5848
+ const body = this.getGroupByName("body" /* BODY */);
5849
+ const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
5850
+ (body ?? this).add(group);
5795
5851
  group.rotation.set(toRadians(-6), Math.PI, 0);
5796
5852
  const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
5797
5853
  cape.position.set(0, -8, -0.5);
@@ -5806,15 +5862,14 @@ var SkinObject = class extends SceneObject {
5806
5862
  updateSlim(slim) {
5807
5863
  if (slim === this.slim) return;
5808
5864
  this.slim = slim;
5865
+ const offset = slim ? 0.5 : -0.5;
5809
5866
  for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
5810
5867
  const mesh = this.getMeshByName(part);
5811
- if (mesh) mesh.geometry = this.getBoxGeometry(part);
5868
+ if (mesh) {
5869
+ mesh.geometry = this.getBoxGeometry(part);
5870
+ mesh.position.x += part === "leftArm" /* LEFT_ARM */ || part === "leftSleeve" /* LEFT_SLEEVE */ ? offset : -offset;
5871
+ }
5812
5872
  }
5813
- const offset = slim ? 0.5 : -0.5;
5814
- const leftArm = this.getGroupByName("leftArm" /* LEFT_ARM */);
5815
- const rightArm = this.getGroupByName("rightArm" /* RIGHT_ARM */);
5816
- if (leftArm) leftArm.position.x += offset;
5817
- if (rightArm) rightArm.position.x -= offset;
5818
5873
  this.notifyDirty();
5819
5874
  }
5820
5875
  /** Select the texture layout, or pass undefined to detect it from image dimensions. */
@@ -5830,7 +5885,6 @@ var SkinObject = class extends SceneObject {
5830
5885
  }
5831
5886
  //TODO: layer toggles
5832
5887
  getBoxGeometry(part) {
5833
- console.log("slim", this.slim);
5834
5888
  const coordinates = this.slim ? slimSkinTextureCoordinates : classicSkinTextureCoordinates;
5835
5889
  const geometries = this.slim ? slimSkinGeometries : classicSkinGeometries;
5836
5890
  return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [64, 64]);
@@ -7415,6 +7469,7 @@ export {
7415
7469
  SceneStats,
7416
7470
  SceneStatsDisplay,
7417
7471
  SchematicParser,
7472
+ SkinImage,
7418
7473
  SkinObject,
7419
7474
  SkinPart,
7420
7475
  SkinTextures,