minerender 2.1.0-alpha.50 → 2.1.0-alpha.52

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.
@@ -2498,30 +2498,69 @@ var init_TextureAtlas = __esm({
2498
2498
  var ModelGenerator;
2499
2499
  var init_ModelGenerator = __esm({
2500
2500
  "src/model/ModelGenerator.ts"() {
2501
+ init_CubeFace();
2501
2502
  ModelGenerator = class {
2502
2503
  static {
2503
2504
  this.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2504
2505
  }
2506
+ /**
2507
+ * Front and back faces plus one zero-thickness side face per run of texels that border a transparent texel,
2508
+ * like vanilla's ItemModelGenerator. Pass the pixels of a single (first) animation frame.
2509
+ */
2505
2510
  static generateItemModel(imageData, layer) {
2506
2511
  const tintindex = this.ITEM_LAYERS.indexOf(layer);
2512
+ const texture = `#${layer}`;
2507
2513
  const mainElement = {
2508
2514
  from: [0, 0, 7.5],
2509
2515
  to: [16, 16, 8.5],
2510
2516
  faces: {
2511
2517
  "south": {
2512
2518
  uv: [0, 0, 16, 16],
2513
- texture: `#${layer}`,
2519
+ texture,
2514
2520
  tintindex
2515
2521
  },
2516
2522
  "north": {
2517
2523
  uv: [16, 0, 0, 16],
2518
- texture: `#${layer}`,
2524
+ texture,
2519
2525
  tintindex
2520
2526
  }
2521
2527
  },
2522
2528
  shade: true
2523
2529
  };
2524
- return [mainElement];
2530
+ const elements = [mainElement];
2531
+ const { width, height, data } = imageData;
2532
+ const opaque = (x, y) => x >= 0 && y >= 0 && x < width && y < height && data[(y * width + x) * 4 + 3] !== 0;
2533
+ const sx = 16 / width;
2534
+ const sy = 16 / height;
2535
+ const sides = [["up" /* UP */, 0, -1], ["down" /* DOWN */, 0, 1], ["west" /* WEST */, -1, 0], ["east" /* EAST */, 1, 0]];
2536
+ for (const [face, dx, dy] of sides) {
2537
+ const horizontal = dx === 0;
2538
+ const lines = horizontal ? height : width;
2539
+ const length = horizontal ? width : height;
2540
+ for (let line = 0; line < lines; line++) {
2541
+ for (let start = 0; start < length; start++) {
2542
+ const exposed = (i) => horizontal ? opaque(i, line) && !opaque(i, line + dy) : opaque(line, i) && !opaque(line + dx, i);
2543
+ if (!exposed(start)) continue;
2544
+ let end = start + 1;
2545
+ while (end < length && exposed(end)) end++;
2546
+ let uv, from, to;
2547
+ if (horizontal) {
2548
+ const y = 16 - (line + (dy > 0 ? 1 : 0)) * sy;
2549
+ uv = [start * sx, line * sy, end * sx, (line + 1) * sy];
2550
+ from = [start * sx, y, 7.5];
2551
+ to = [end * sx, y, 8.5];
2552
+ } else {
2553
+ const x = (line + (dx > 0 ? 1 : 0)) * sx;
2554
+ uv = [line * sx, start * sy, (line + 1) * sx, end * sy];
2555
+ from = [x, 16 - end * sy, 7.5];
2556
+ to = [x, 16 - start * sy, 8.5];
2557
+ }
2558
+ elements.push({ from, to, faces: { [face]: { uv, texture, tintindex } }, shade: true });
2559
+ start = end;
2560
+ }
2561
+ }
2562
+ }
2563
+ return elements;
2525
2564
  }
2526
2565
  };
2527
2566
  }
@@ -2888,7 +2927,15 @@ var init_UVMapper = __esm({
2888
2927
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2889
2928
  const textureImage = textureMap[layerName];
2890
2929
  if (textureImage) {
2891
- model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2930
+ const [width, height] = sizes[layerName];
2931
+ const frame = frames[layerName]?.[0].index ?? 0;
2932
+ const columns = textureImage.width / width;
2933
+ model.elements.push(...ModelGenerator.generateItemModel(textureImage.getSectionData(
2934
+ frame % columns * width,
2935
+ Math.floor(frame / columns) * height,
2936
+ width,
2937
+ height
2938
+ ), layerName));
2892
2939
  }
2893
2940
  }
2894
2941
  console.debug(p5, "Item model elements", model.elements);
@@ -4096,7 +4143,6 @@ var init_ModelObject = __esm({
4096
4143
  if (this.options.tints) this.options.tints = { ...this.options.tints };
4097
4144
  this.addEventListener("added", () => this.updateAnimationSubscription());
4098
4145
  this.addEventListener("removed", () => this.updateAnimationSubscription());
4099
- console.log("ModelObject options", this.options);
4100
4146
  }
4101
4147
  static {
4102
4148
  this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
@@ -5113,6 +5159,10 @@ var EntityObject = class _EntityObject extends SceneObject {
5113
5159
  uv
5114
5160
  ).clone();
5115
5161
  geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
5162
+ if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
5163
+ const index = Array.from(geometry.getIndex().array);
5164
+ geometry.setIndex(index.concat(index.slice().reverse()));
5165
+ }
5116
5166
  const mesh = this.createMesh(name, geometry, material);
5117
5167
  mesh.renderOrder = renderOrder;
5118
5168
  anchor.add(mesh);
@@ -8083,7 +8133,7 @@ var SceneStatsDisplay = class {
8083
8133
  }
8084
8134
  init() {
8085
8135
  this.statsContainer.classList.add("minerender-stats");
8086
- setInterval(() => {
8136
+ this.interval = setInterval(() => {
8087
8137
  for (let line of this.lines) {
8088
8138
  line.update();
8089
8139
  }
@@ -8092,6 +8142,13 @@ var SceneStatsDisplay = class {
8092
8142
  appendTo(el) {
8093
8143
  el.append(this.statsContainer);
8094
8144
  }
8145
+ dispose() {
8146
+ clearInterval(this.interval);
8147
+ this.interval = void 0;
8148
+ this.lines.length = 0;
8149
+ this.statsContainer.replaceChildren();
8150
+ this.statsContainer.remove();
8151
+ }
8095
8152
  add(line) {
8096
8153
  if (typeof line !== "undefined") {
8097
8154
  this.lines.push(line);
@@ -10530,7 +10587,7 @@ var SKIN_PARTS = Object.values(SkinPart);
10530
10587
  // src/skin/SkinTextureCoordinates.ts
10531
10588
  var baseSkinCoordinates = {
10532
10589
  head: {
10533
- east: {
10590
+ west: {
10534
10591
  // left
10535
10592
  uv: [
10536
10593
  0,
@@ -10539,7 +10596,7 @@ var baseSkinCoordinates = {
10539
10596
  16
10540
10597
  ]
10541
10598
  },
10542
- west: {
10599
+ east: {
10543
10600
  // right
10544
10601
  uv: [
10545
10602
  16,
@@ -10548,7 +10605,7 @@ var baseSkinCoordinates = {
10548
10605
  16
10549
10606
  ]
10550
10607
  },
10551
- north: {
10608
+ south: {
10552
10609
  // front
10553
10610
  uv: [
10554
10611
  8,
@@ -10557,7 +10614,7 @@ var baseSkinCoordinates = {
10557
10614
  16
10558
10615
  ]
10559
10616
  },
10560
- south: {
10617
+ north: {
10561
10618
  // back
10562
10619
  uv: [
10563
10620
  24,
@@ -10569,24 +10626,24 @@ var baseSkinCoordinates = {
10569
10626
  up: {
10570
10627
  // top
10571
10628
  uv: [
10572
- 16,
10573
10629
  8,
10574
- 8,
10575
- 0
10630
+ 0,
10631
+ 16,
10632
+ 8
10576
10633
  ]
10577
10634
  },
10578
10635
  down: {
10579
10636
  // bottom
10580
10637
  uv: [
10581
- 24,
10582
- 0,
10583
10638
  16,
10584
- 8
10639
+ 8,
10640
+ 24,
10641
+ 0
10585
10642
  ]
10586
10643
  }
10587
10644
  },
10588
10645
  body: {
10589
- east: {
10646
+ west: {
10590
10647
  uv: [
10591
10648
  16,
10592
10649
  20,
@@ -10594,7 +10651,7 @@ var baseSkinCoordinates = {
10594
10651
  32
10595
10652
  ]
10596
10653
  },
10597
- west: {
10654
+ east: {
10598
10655
  uv: [
10599
10656
  28,
10600
10657
  20,
@@ -10602,7 +10659,7 @@ var baseSkinCoordinates = {
10602
10659
  32
10603
10660
  ]
10604
10661
  },
10605
- north: {
10662
+ south: {
10606
10663
  uv: [
10607
10664
  20,
10608
10665
  20,
@@ -10610,7 +10667,7 @@ var baseSkinCoordinates = {
10610
10667
  32
10611
10668
  ]
10612
10669
  },
10613
- south: {
10670
+ north: {
10614
10671
  uv: [
10615
10672
  32,
10616
10673
  20,
@@ -10620,23 +10677,23 @@ var baseSkinCoordinates = {
10620
10677
  },
10621
10678
  up: {
10622
10679
  uv: [
10623
- 28,
10624
- 20,
10625
10680
  20,
10626
- 16
10681
+ 16,
10682
+ 28,
10683
+ 20
10627
10684
  ]
10628
10685
  },
10629
10686
  down: {
10630
10687
  uv: [
10631
- 36,
10632
- 16,
10633
10688
  28,
10634
- 20
10689
+ 20,
10690
+ 36,
10691
+ 16
10635
10692
  ]
10636
10693
  }
10637
10694
  },
10638
10695
  leftArm: {
10639
- east: {
10696
+ west: {
10640
10697
  uv: [
10641
10698
  32,
10642
10699
  52,
@@ -10644,7 +10701,7 @@ var baseSkinCoordinates = {
10644
10701
  64
10645
10702
  ]
10646
10703
  },
10647
- west: {
10704
+ east: {
10648
10705
  uv: [
10649
10706
  40,
10650
10707
  52,
@@ -10652,7 +10709,7 @@ var baseSkinCoordinates = {
10652
10709
  64
10653
10710
  ]
10654
10711
  },
10655
- north: {
10712
+ south: {
10656
10713
  uv: [
10657
10714
  36,
10658
10715
  52,
@@ -10660,7 +10717,7 @@ var baseSkinCoordinates = {
10660
10717
  64
10661
10718
  ]
10662
10719
  },
10663
- south: {
10720
+ north: {
10664
10721
  uv: [
10665
10722
  44,
10666
10723
  52,
@@ -10670,23 +10727,23 @@ var baseSkinCoordinates = {
10670
10727
  },
10671
10728
  up: {
10672
10729
  uv: [
10673
- 40,
10674
- 52,
10675
10730
  36,
10676
- 48
10731
+ 48,
10732
+ 40,
10733
+ 52
10677
10734
  ]
10678
10735
  },
10679
10736
  down: {
10680
10737
  uv: [
10681
- 44,
10682
- 48,
10683
10738
  40,
10684
- 52
10739
+ 52,
10740
+ 44,
10741
+ 48
10685
10742
  ]
10686
10743
  }
10687
10744
  },
10688
10745
  rightArm: {
10689
- east: {
10746
+ west: {
10690
10747
  uv: [
10691
10748
  40,
10692
10749
  20,
@@ -10694,7 +10751,7 @@ var baseSkinCoordinates = {
10694
10751
  32
10695
10752
  ]
10696
10753
  },
10697
- west: {
10754
+ east: {
10698
10755
  uv: [
10699
10756
  48,
10700
10757
  20,
@@ -10702,7 +10759,7 @@ var baseSkinCoordinates = {
10702
10759
  32
10703
10760
  ]
10704
10761
  },
10705
- north: {
10762
+ south: {
10706
10763
  uv: [
10707
10764
  44,
10708
10765
  20,
@@ -10710,7 +10767,7 @@ var baseSkinCoordinates = {
10710
10767
  32
10711
10768
  ]
10712
10769
  },
10713
- south: {
10770
+ north: {
10714
10771
  uv: [
10715
10772
  52,
10716
10773
  20,
@@ -10720,23 +10777,23 @@ var baseSkinCoordinates = {
10720
10777
  },
10721
10778
  up: {
10722
10779
  uv: [
10723
- 48,
10724
- 20,
10725
10780
  44,
10726
- 16
10781
+ 16,
10782
+ 48,
10783
+ 20
10727
10784
  ]
10728
10785
  },
10729
10786
  down: {
10730
10787
  uv: [
10731
- 52,
10732
- 16,
10733
10788
  48,
10734
- 20
10789
+ 20,
10790
+ 52,
10791
+ 16
10735
10792
  ]
10736
10793
  }
10737
10794
  },
10738
10795
  leftLeg: {
10739
- east: {
10796
+ west: {
10740
10797
  uv: [
10741
10798
  16,
10742
10799
  52,
@@ -10744,7 +10801,7 @@ var baseSkinCoordinates = {
10744
10801
  64
10745
10802
  ]
10746
10803
  },
10747
- west: {
10804
+ east: {
10748
10805
  uv: [
10749
10806
  24,
10750
10807
  52,
@@ -10752,7 +10809,7 @@ var baseSkinCoordinates = {
10752
10809
  64
10753
10810
  ]
10754
10811
  },
10755
- north: {
10812
+ south: {
10756
10813
  uv: [
10757
10814
  20,
10758
10815
  52,
@@ -10760,7 +10817,7 @@ var baseSkinCoordinates = {
10760
10817
  64
10761
10818
  ]
10762
10819
  },
10763
- south: {
10820
+ north: {
10764
10821
  uv: [
10765
10822
  28,
10766
10823
  52,
@@ -10770,24 +10827,24 @@ var baseSkinCoordinates = {
10770
10827
  },
10771
10828
  up: {
10772
10829
  uv: [
10773
- 24,
10774
- 52,
10775
10830
  20,
10776
- 48
10831
+ 48,
10832
+ 24,
10833
+ 52
10777
10834
  ]
10778
10835
  },
10779
10836
  down: {
10780
10837
  uv: [
10781
- 28,
10782
- 48,
10783
10838
  24,
10784
- 52
10839
+ 52,
10840
+ 28,
10841
+ 48
10785
10842
  ],
10786
10843
  rotation: 180
10787
10844
  }
10788
10845
  },
10789
10846
  rightLeg: {
10790
- east: {
10847
+ west: {
10791
10848
  uv: [
10792
10849
  0,
10793
10850
  20,
@@ -10795,7 +10852,7 @@ var baseSkinCoordinates = {
10795
10852
  32
10796
10853
  ]
10797
10854
  },
10798
- west: {
10855
+ east: {
10799
10856
  uv: [
10800
10857
  8,
10801
10858
  20,
@@ -10803,7 +10860,7 @@ var baseSkinCoordinates = {
10803
10860
  32
10804
10861
  ]
10805
10862
  },
10806
- north: {
10863
+ south: {
10807
10864
  uv: [
10808
10865
  4,
10809
10866
  20,
@@ -10811,7 +10868,7 @@ var baseSkinCoordinates = {
10811
10868
  32
10812
10869
  ]
10813
10870
  },
10814
- south: {
10871
+ north: {
10815
10872
  uv: [
10816
10873
  12,
10817
10874
  20,
@@ -10821,23 +10878,23 @@ var baseSkinCoordinates = {
10821
10878
  },
10822
10879
  up: {
10823
10880
  uv: [
10824
- 8,
10825
- 20,
10826
10881
  4,
10827
- 16
10882
+ 16,
10883
+ 8,
10884
+ 20
10828
10885
  ]
10829
10886
  },
10830
10887
  down: {
10831
10888
  uv: [
10832
- 12,
10833
- 16,
10834
10889
  8,
10835
- 20
10890
+ 20,
10891
+ 12,
10892
+ 16
10836
10893
  ]
10837
10894
  }
10838
10895
  },
10839
10896
  hat: {
10840
- east: {
10897
+ west: {
10841
10898
  uv: [
10842
10899
  32,
10843
10900
  8,
@@ -10845,7 +10902,7 @@ var baseSkinCoordinates = {
10845
10902
  16
10846
10903
  ]
10847
10904
  },
10848
- west: {
10905
+ east: {
10849
10906
  uv: [
10850
10907
  48,
10851
10908
  8,
@@ -10853,7 +10910,7 @@ var baseSkinCoordinates = {
10853
10910
  16
10854
10911
  ]
10855
10912
  },
10856
- north: {
10913
+ south: {
10857
10914
  uv: [
10858
10915
  40,
10859
10916
  8,
@@ -10861,7 +10918,7 @@ var baseSkinCoordinates = {
10861
10918
  16
10862
10919
  ]
10863
10920
  },
10864
- south: {
10921
+ north: {
10865
10922
  uv: [
10866
10923
  56,
10867
10924
  8,
@@ -10871,24 +10928,24 @@ var baseSkinCoordinates = {
10871
10928
  },
10872
10929
  up: {
10873
10930
  uv: [
10874
- 48,
10875
- 8,
10876
10931
  40,
10877
- 0
10932
+ 0,
10933
+ 48,
10934
+ 8
10878
10935
  ]
10879
10936
  },
10880
10937
  down: {
10881
10938
  uv: [
10882
- 56,
10883
- 0,
10884
10939
  48,
10885
- 8
10940
+ 8,
10941
+ 56,
10942
+ 0
10886
10943
  ],
10887
10944
  rotation: 180
10888
10945
  }
10889
10946
  },
10890
10947
  jacket: {
10891
- east: {
10948
+ west: {
10892
10949
  uv: [
10893
10950
  16,
10894
10951
  36,
@@ -10896,7 +10953,7 @@ var baseSkinCoordinates = {
10896
10953
  48
10897
10954
  ]
10898
10955
  },
10899
- west: {
10956
+ east: {
10900
10957
  uv: [
10901
10958
  28,
10902
10959
  36,
@@ -10904,7 +10961,7 @@ var baseSkinCoordinates = {
10904
10961
  48
10905
10962
  ]
10906
10963
  },
10907
- north: {
10964
+ south: {
10908
10965
  uv: [
10909
10966
  20,
10910
10967
  36,
@@ -10912,7 +10969,7 @@ var baseSkinCoordinates = {
10912
10969
  48
10913
10970
  ]
10914
10971
  },
10915
- south: {
10972
+ north: {
10916
10973
  uv: [
10917
10974
  32,
10918
10975
  36,
@@ -10922,24 +10979,24 @@ var baseSkinCoordinates = {
10922
10979
  },
10923
10980
  up: {
10924
10981
  uv: [
10925
- 28,
10926
- 36,
10927
10982
  20,
10928
- 32
10983
+ 32,
10984
+ 28,
10985
+ 36
10929
10986
  ]
10930
10987
  },
10931
10988
  down: {
10932
10989
  uv: [
10933
- 36,
10934
- 32,
10935
10990
  28,
10936
- 36
10991
+ 36,
10992
+ 36,
10993
+ 32
10937
10994
  ],
10938
10995
  rotation: 180
10939
10996
  }
10940
10997
  },
10941
10998
  leftSleeve: {
10942
- east: {
10999
+ west: {
10943
11000
  uv: [
10944
11001
  48,
10945
11002
  52,
@@ -10947,7 +11004,7 @@ var baseSkinCoordinates = {
10947
11004
  64
10948
11005
  ]
10949
11006
  },
10950
- west: {
11007
+ east: {
10951
11008
  uv: [
10952
11009
  56,
10953
11010
  52,
@@ -10955,7 +11012,7 @@ var baseSkinCoordinates = {
10955
11012
  64
10956
11013
  ]
10957
11014
  },
10958
- north: {
11015
+ south: {
10959
11016
  uv: [
10960
11017
  52,
10961
11018
  52,
@@ -10963,7 +11020,7 @@ var baseSkinCoordinates = {
10963
11020
  64
10964
11021
  ]
10965
11022
  },
10966
- south: {
11023
+ north: {
10967
11024
  uv: [
10968
11025
  60,
10969
11026
  52,
@@ -10973,24 +11030,24 @@ var baseSkinCoordinates = {
10973
11030
  },
10974
11031
  up: {
10975
11032
  uv: [
10976
- 56,
10977
- 52,
10978
11033
  52,
10979
- 48
11034
+ 48,
11035
+ 56,
11036
+ 52
10980
11037
  ]
10981
11038
  },
10982
11039
  down: {
10983
11040
  uv: [
10984
- 60,
10985
- 48,
10986
11041
  56,
10987
- 52
11042
+ 52,
11043
+ 60,
11044
+ 48
10988
11045
  ],
10989
11046
  rotation: 180
10990
11047
  }
10991
11048
  },
10992
11049
  rightSleeve: {
10993
- east: {
11050
+ west: {
10994
11051
  uv: [
10995
11052
  40,
10996
11053
  36,
@@ -10998,7 +11055,7 @@ var baseSkinCoordinates = {
10998
11055
  48
10999
11056
  ]
11000
11057
  },
11001
- west: {
11058
+ east: {
11002
11059
  uv: [
11003
11060
  48,
11004
11061
  36,
@@ -11006,7 +11063,7 @@ var baseSkinCoordinates = {
11006
11063
  48
11007
11064
  ]
11008
11065
  },
11009
- north: {
11066
+ south: {
11010
11067
  uv: [
11011
11068
  44,
11012
11069
  36,
@@ -11014,7 +11071,7 @@ var baseSkinCoordinates = {
11014
11071
  48
11015
11072
  ]
11016
11073
  },
11017
- south: {
11074
+ north: {
11018
11075
  uv: [
11019
11076
  52,
11020
11077
  36,
@@ -11024,24 +11081,24 @@ var baseSkinCoordinates = {
11024
11081
  },
11025
11082
  up: {
11026
11083
  uv: [
11027
- 48,
11028
- 36,
11029
11084
  44,
11030
- 32
11085
+ 32,
11086
+ 48,
11087
+ 36
11031
11088
  ]
11032
11089
  },
11033
11090
  down: {
11034
11091
  uv: [
11035
- 52,
11036
- 32,
11037
11092
  48,
11038
- 36
11093
+ 36,
11094
+ 52,
11095
+ 32
11039
11096
  ],
11040
11097
  rotation: 180
11041
11098
  }
11042
11099
  },
11043
11100
  leftTrousers: {
11044
- east: {
11101
+ west: {
11045
11102
  uv: [
11046
11103
  0,
11047
11104
  52,
@@ -11049,7 +11106,7 @@ var baseSkinCoordinates = {
11049
11106
  64
11050
11107
  ]
11051
11108
  },
11052
- west: {
11109
+ east: {
11053
11110
  uv: [
11054
11111
  8,
11055
11112
  52,
@@ -11057,7 +11114,7 @@ var baseSkinCoordinates = {
11057
11114
  64
11058
11115
  ]
11059
11116
  },
11060
- north: {
11117
+ south: {
11061
11118
  uv: [
11062
11119
  4,
11063
11120
  52,
@@ -11065,7 +11122,7 @@ var baseSkinCoordinates = {
11065
11122
  64
11066
11123
  ]
11067
11124
  },
11068
- south: {
11125
+ north: {
11069
11126
  uv: [
11070
11127
  12,
11071
11128
  52,
@@ -11075,23 +11132,23 @@ var baseSkinCoordinates = {
11075
11132
  },
11076
11133
  up: {
11077
11134
  uv: [
11078
- 8,
11079
- 52,
11080
11135
  4,
11081
- 48
11136
+ 48,
11137
+ 8,
11138
+ 52
11082
11139
  ]
11083
11140
  },
11084
11141
  down: {
11085
11142
  uv: [
11086
- 12,
11087
- 48,
11088
11143
  8,
11089
- 52
11144
+ 52,
11145
+ 12,
11146
+ 48
11090
11147
  ]
11091
11148
  }
11092
11149
  },
11093
11150
  rightTrousers: {
11094
- east: {
11151
+ west: {
11095
11152
  uv: [
11096
11153
  0,
11097
11154
  36,
@@ -11099,7 +11156,7 @@ var baseSkinCoordinates = {
11099
11156
  48
11100
11157
  ]
11101
11158
  },
11102
- west: {
11159
+ east: {
11103
11160
  uv: [
11104
11161
  8,
11105
11162
  36,
@@ -11107,7 +11164,7 @@ var baseSkinCoordinates = {
11107
11164
  48
11108
11165
  ]
11109
11166
  },
11110
- north: {
11167
+ south: {
11111
11168
  uv: [
11112
11169
  4,
11113
11170
  36,
@@ -11115,7 +11172,7 @@ var baseSkinCoordinates = {
11115
11172
  48
11116
11173
  ]
11117
11174
  },
11118
- south: {
11175
+ north: {
11119
11176
  uv: [
11120
11177
  12,
11121
11178
  36,
@@ -11125,18 +11182,18 @@ var baseSkinCoordinates = {
11125
11182
  },
11126
11183
  up: {
11127
11184
  uv: [
11128
- 8,
11129
- 36,
11130
11185
  4,
11131
- 32
11186
+ 32,
11187
+ 8,
11188
+ 36
11132
11189
  ]
11133
11190
  },
11134
11191
  down: {
11135
11192
  uv: [
11136
- 12,
11137
- 32,
11138
11193
  8,
11139
- 36
11194
+ 36,
11195
+ 12,
11196
+ 32
11140
11197
  ],
11141
11198
  rotation: 180
11142
11199
  }
@@ -11157,35 +11214,35 @@ var slimSkinTextureCoordinates = {
11157
11214
  ...baseSkinCoordinates,
11158
11215
  leftArm: {
11159
11216
  ...baseSkinCoordinates.leftArm,
11160
- west: { uv: [39, 52, 43, 64] },
11161
- north: { uv: [36, 52, 39, 64] },
11162
- south: { uv: [43, 52, 46, 64] },
11163
- up: { uv: [39, 52, 36, 48] },
11164
- down: { uv: [42, 48, 39, 52] }
11217
+ east: { uv: [39, 52, 43, 64] },
11218
+ south: { uv: [36, 52, 39, 64] },
11219
+ north: { uv: [43, 52, 46, 64] },
11220
+ up: { uv: [36, 48, 39, 52] },
11221
+ down: { uv: [39, 52, 42, 48] }
11165
11222
  },
11166
11223
  rightArm: {
11167
11224
  ...baseSkinCoordinates.rightArm,
11168
- west: { uv: [47, 20, 51, 32] },
11169
- north: { uv: [44, 20, 47, 32] },
11170
- south: { uv: [51, 20, 54, 32] },
11171
- up: { uv: [47, 20, 44, 16] },
11172
- down: { uv: [50, 16, 47, 20] }
11225
+ east: { uv: [47, 20, 51, 32] },
11226
+ south: { uv: [44, 20, 47, 32] },
11227
+ north: { uv: [51, 20, 54, 32] },
11228
+ up: { uv: [44, 16, 47, 20] },
11229
+ down: { uv: [47, 20, 50, 16] }
11173
11230
  },
11174
11231
  leftSleeve: {
11175
11232
  ...baseSkinCoordinates.leftSleeve,
11176
- west: { uv: [55, 52, 59, 64] },
11177
- north: { uv: [52, 52, 55, 64] },
11178
- south: { uv: [59, 52, 62, 64] },
11179
- up: { uv: [55, 52, 52, 48] },
11180
- down: { uv: [58, 48, 55, 52], rotation: 180 }
11233
+ east: { uv: [55, 52, 59, 64] },
11234
+ south: { uv: [52, 52, 55, 64] },
11235
+ north: { uv: [59, 52, 62, 64] },
11236
+ up: { uv: [52, 48, 55, 52] },
11237
+ down: { uv: [55, 52, 58, 48], rotation: 180 }
11181
11238
  },
11182
11239
  rightSleeve: {
11183
11240
  ...baseSkinCoordinates.rightSleeve,
11184
- west: { uv: [47, 36, 51, 48] },
11185
- north: { uv: [44, 36, 47, 48] },
11186
- south: { uv: [51, 36, 54, 48] },
11187
- up: { uv: [47, 36, 44, 32] },
11188
- down: { uv: [50, 32, 47, 36], rotation: 180 }
11241
+ east: { uv: [47, 36, 51, 48] },
11242
+ south: { uv: [44, 36, 47, 48] },
11243
+ north: { uv: [51, 36, 54, 48] },
11244
+ up: { uv: [44, 32, 47, 36] },
11245
+ down: { uv: [47, 36, 50, 32], rotation: 180 }
11189
11246
  }
11190
11247
  };
11191
11248
 
@@ -11425,34 +11482,34 @@ var SkinObject = class extends SceneObject {
11425
11482
  }
11426
11483
  {
11427
11484
  {
11428
- const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
11485
+ const leftArmGroup = this.createAndAddGroup("leftArm", 5, 22, 0);
11429
11486
  const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
11430
11487
  const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
11431
- leftArm.position.x = this.slim ? -0.5 : -1;
11488
+ leftArm.position.x = this.slim ? 0.5 : 1;
11432
11489
  const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
11433
11490
  const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
11434
- leftSleeve.position.x = this.slim ? -0.5 : -1;
11491
+ leftSleeve.position.x = this.slim ? 0.5 : 1;
11435
11492
  }
11436
11493
  {
11437
- const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
11494
+ const rightArmGroup = this.createAndAddGroup("rightArm", -5, 22, 0);
11438
11495
  const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
11439
11496
  const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
11440
- rightArm.position.x = this.slim ? 0.5 : 1;
11497
+ rightArm.position.x = this.slim ? -0.5 : -1;
11441
11498
  const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
11442
11499
  const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
11443
- rightSleeve.position.x = this.slim ? 0.5 : 1;
11500
+ rightSleeve.position.x = this.slim ? -0.5 : -1;
11444
11501
  }
11445
11502
  }
11446
11503
  {
11447
11504
  {
11448
- const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
11505
+ const leftLegGroup = this.createAndAddGroup("leftLeg", 1.9, 12, 0);
11449
11506
  const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
11450
11507
  const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
11451
11508
  const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
11452
11509
  const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
11453
11510
  }
11454
11511
  {
11455
- const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
11512
+ const rightLegGroup = this.createAndAddGroup("rightLeg", -1.9, 12, 0);
11456
11513
  const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
11457
11514
  const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
11458
11515
  const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
@@ -11502,9 +11559,10 @@ var SkinObject = class extends SceneObject {
11502
11559
  mesh.geometry = geometry;
11503
11560
  } else {
11504
11561
  const body = this.getGroupByName("body" /* BODY */);
11505
- const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
11562
+ const group = this.createGroup("cape" /* CAPE */);
11563
+ group.position.set(0, body ? 0 : 24, -2);
11506
11564
  (body ?? this).add(group);
11507
- group.rotation.set(toRadians(-6), Math.PI, 0);
11565
+ group.rotation.x = toRadians(6);
11508
11566
  const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
11509
11567
  cape.position.set(0, -8, -0.5);
11510
11568
  }
@@ -11518,7 +11576,7 @@ var SkinObject = class extends SceneObject {
11518
11576
  updateSlim(slim) {
11519
11577
  if (slim === this.slim) return;
11520
11578
  this.slim = slim;
11521
- const offset = slim ? 0.5 : -0.5;
11579
+ const offset = slim ? -0.5 : 0.5;
11522
11580
  for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
11523
11581
  const mesh = this.getMeshByName(part);
11524
11582
  if (mesh) {
@@ -11615,13 +11673,9 @@ var MineRenderScene = class _MineRenderScene extends import_three30.Scene {
11615
11673
  return this.add(...object);
11616
11674
  }
11617
11675
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
11618
- console.log("addSceneObject", asset);
11619
- console.log("parent", parent);
11620
- console.log(_options);
11621
11676
  this.dirty = true;
11622
11677
  const obj = await objectSupplier();
11623
11678
  if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
11624
- console.log("instanceMeshes + key");
11625
11679
  let key = asset.key.serialize();
11626
11680
  if (isModelObject(obj)) {
11627
11681
  const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
@@ -11638,7 +11692,6 @@ var MineRenderScene = class _MineRenderScene extends import_three30.Scene {
11638
11692
  return obj;
11639
11693
  });
11640
11694
  } else {
11641
- console.log("!instanceMeshes | !key");
11642
11695
  obj.scene = this;
11643
11696
  await obj.init();
11644
11697
  if (!isBlockObject(obj)) {
@@ -12335,7 +12388,10 @@ var Renderer = class _Renderer {
12335
12388
  constructor(options) {
12336
12389
  this._dirty = true;
12337
12390
  this._resizeListener = void 0;
12391
+ this._running = false;
12392
+ this._inAnimationLoop = false;
12338
12393
  this._disposed = false;
12394
+ this._frameCallbacks = /* @__PURE__ */ new Map();
12339
12395
  this._debugHelpers = [];
12340
12396
  this._eventDispatchers = /* @__PURE__ */ new Map();
12341
12397
  this._changeListener = () => {
@@ -12346,7 +12402,14 @@ var Renderer = class _Renderer {
12346
12402
  if (!Number.isFinite(pixelRatio) || pixelRatio <= 0) {
12347
12403
  throw new RangeError("render.pixelRatio must be a finite positive number");
12348
12404
  }
12349
- this._animationLoop = this.animate.bind(this);
12405
+ this._animationLoop = (time) => {
12406
+ this._inAnimationLoop = true;
12407
+ try {
12408
+ this.animate(time);
12409
+ } finally {
12410
+ this._inAnimationLoop = false;
12411
+ }
12412
+ };
12350
12413
  this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
12351
12414
  this._scene = this.createScene();
12352
12415
  this._camera = this.createCamera();
@@ -12561,15 +12624,39 @@ var Renderer = class _Renderer {
12561
12624
  this._dirty = dirty;
12562
12625
  this.scene.dirty = dirty;
12563
12626
  }
12627
+ /**
12628
+ * Calls a synchronous animation update before each FPS-limited draw while started.
12629
+ * Subscriptions keep the scene drawing without manual dirty flags. Returns an unsubscribe function.
12630
+ * Registering the same callback twice has no effect. Image exports do not invoke callbacks.
12631
+ */
12632
+ onFrame(callback) {
12633
+ if (this._disposed) return () => {
12634
+ };
12635
+ const subscription = this._frameCallbacks.get(callback) ?? {};
12636
+ this._frameCallbacks.set(callback, subscription);
12637
+ return () => {
12638
+ if (this._frameCallbacks.get(callback) === subscription) this._frameCallbacks.delete(callback);
12639
+ };
12640
+ }
12564
12641
  start() {
12565
12642
  if (this._disposed) return;
12566
12643
  this.stop();
12567
- this.renderer.setAnimationLoop(this._animationLoop);
12644
+ this._running = true;
12645
+ if (!this._inAnimationLoop) this.renderer.setAnimationLoop(this._animationLoop);
12568
12646
  }
12569
12647
  stop() {
12570
12648
  if (this._disposed) return;
12571
- this.renderer.setAnimationLoop(null);
12649
+ this._running = false;
12650
+ if (this._inAnimationLoop) {
12651
+ queueMicrotask(() => {
12652
+ this.renderer.setAnimationLoop(null);
12653
+ if (this._running) this.renderer.setAnimationLoop(this._animationLoop);
12654
+ });
12655
+ } else {
12656
+ this.renderer.setAnimationLoop(null);
12657
+ }
12572
12658
  this._nextFrameTime = void 0;
12659
+ for (const subscription of this._frameCallbacks.values()) subscription.previous = void 0;
12573
12660
  }
12574
12661
  /**
12575
12662
  * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
@@ -12580,6 +12667,7 @@ var Renderer = class _Renderer {
12580
12667
  if (this._disposed) return;
12581
12668
  this.stop();
12582
12669
  this._disposed = true;
12670
+ this._frameCallbacks.clear();
12583
12671
  if (this._resizeListener) {
12584
12672
  window.removeEventListener("resize", this._resizeListener);
12585
12673
  this._resizeListener = void 0;
@@ -12614,18 +12702,25 @@ var Renderer = class _Renderer {
12614
12702
  this.renderer.forceContextLoss();
12615
12703
  }
12616
12704
  animate(t = performance.now()) {
12617
- if (this._disposed) return;
12705
+ if (!this._running) return;
12618
12706
  if (this._controls?.enabled) {
12619
12707
  this._controls.update();
12620
12708
  }
12621
- if (this._disposed) return;
12622
- if (!this.dirty && !this.options.render.renderAlways) return;
12709
+ if (!this._running) return;
12710
+ if (!this.dirty && !this.options.render.renderAlways && !this._frameCallbacks.size) return;
12623
12711
  const interval = this._frameInterval;
12624
12712
  if (interval) {
12625
12713
  const next = this._nextFrameTime;
12626
12714
  if (next !== void 0 && t + 0.1 < next) return;
12627
12715
  this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
12628
12716
  }
12717
+ for (const [callback, subscription] of [...this._frameCallbacks]) {
12718
+ if (this._frameCallbacks.get(callback) !== subscription) continue;
12719
+ const previous = subscription.previous;
12720
+ subscription.previous = t;
12721
+ callback({ time: t / 1e3, delta: previous === void 0 ? 0 : (t - previous) / 1e3 });
12722
+ if (!this._running) return;
12723
+ }
12629
12724
  this.drawFrame();
12630
12725
  }
12631
12726
  drawFrame() {