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.
@@ -2418,27 +2418,66 @@ var init_TextureAtlas = __esm({
2418
2418
  var ModelGenerator;
2419
2419
  var init_ModelGenerator = __esm({
2420
2420
  "src/model/ModelGenerator.ts"() {
2421
+ init_CubeFace();
2421
2422
  ModelGenerator = class {
2423
+ /**
2424
+ * Front and back faces plus one zero-thickness side face per run of texels that border a transparent texel,
2425
+ * like vanilla's ItemModelGenerator. Pass the pixels of a single (first) animation frame.
2426
+ */
2422
2427
  static generateItemModel(imageData, layer) {
2423
2428
  const tintindex = this.ITEM_LAYERS.indexOf(layer);
2429
+ const texture = `#${layer}`;
2424
2430
  const mainElement = {
2425
2431
  from: [0, 0, 7.5],
2426
2432
  to: [16, 16, 8.5],
2427
2433
  faces: {
2428
2434
  "south": {
2429
2435
  uv: [0, 0, 16, 16],
2430
- texture: `#${layer}`,
2436
+ texture,
2431
2437
  tintindex
2432
2438
  },
2433
2439
  "north": {
2434
2440
  uv: [16, 0, 0, 16],
2435
- texture: `#${layer}`,
2441
+ texture,
2436
2442
  tintindex
2437
2443
  }
2438
2444
  },
2439
2445
  shade: true
2440
2446
  };
2441
- return [mainElement];
2447
+ const elements = [mainElement];
2448
+ const { width, height, data } = imageData;
2449
+ const opaque = (x, y) => x >= 0 && y >= 0 && x < width && y < height && data[(y * width + x) * 4 + 3] !== 0;
2450
+ const sx = 16 / width;
2451
+ const sy = 16 / height;
2452
+ const sides = [["up" /* UP */, 0, -1], ["down" /* DOWN */, 0, 1], ["west" /* WEST */, -1, 0], ["east" /* EAST */, 1, 0]];
2453
+ for (const [face, dx, dy] of sides) {
2454
+ const horizontal = dx === 0;
2455
+ const lines = horizontal ? height : width;
2456
+ const length = horizontal ? width : height;
2457
+ for (let line = 0; line < lines; line++) {
2458
+ for (let start = 0; start < length; start++) {
2459
+ const exposed = (i) => horizontal ? opaque(i, line) && !opaque(i, line + dy) : opaque(line, i) && !opaque(line + dx, i);
2460
+ if (!exposed(start)) continue;
2461
+ let end = start + 1;
2462
+ while (end < length && exposed(end)) end++;
2463
+ let uv, from, to;
2464
+ if (horizontal) {
2465
+ const y = 16 - (line + (dy > 0 ? 1 : 0)) * sy;
2466
+ uv = [start * sx, line * sy, end * sx, (line + 1) * sy];
2467
+ from = [start * sx, y, 7.5];
2468
+ to = [end * sx, y, 8.5];
2469
+ } else {
2470
+ const x = (line + (dx > 0 ? 1 : 0)) * sx;
2471
+ uv = [line * sx, start * sy, (line + 1) * sx, end * sy];
2472
+ from = [x, 16 - end * sy, 7.5];
2473
+ to = [x, 16 - start * sy, 8.5];
2474
+ }
2475
+ elements.push({ from, to, faces: { [face]: { uv, texture, tintindex } }, shade: true });
2476
+ start = end;
2477
+ }
2478
+ }
2479
+ }
2480
+ return elements;
2442
2481
  }
2443
2482
  };
2444
2483
  ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
@@ -2806,7 +2845,15 @@ var init_UVMapper = __esm({
2806
2845
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2807
2846
  const textureImage = textureMap[layerName];
2808
2847
  if (textureImage) {
2809
- model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2848
+ const [width, height] = sizes[layerName];
2849
+ const frame = frames[layerName]?.[0].index ?? 0;
2850
+ const columns = textureImage.width / width;
2851
+ model.elements.push(...ModelGenerator.generateItemModel(textureImage.getSectionData(
2852
+ frame % columns * width,
2853
+ Math.floor(frame / columns) * height,
2854
+ width,
2855
+ height
2856
+ ), layerName));
2810
2857
  }
2811
2858
  }
2812
2859
  console.debug(p5, "Item model elements", model.elements);
@@ -4013,7 +4060,6 @@ var init_ModelObject = __esm({
4013
4060
  if (this.options.tints) this.options.tints = { ...this.options.tints };
4014
4061
  this.addEventListener("added", () => this.updateAnimationSubscription());
4015
4062
  this.addEventListener("removed", () => this.updateAnimationSubscription());
4016
- console.log("ModelObject options", this.options);
4017
4063
  }
4018
4064
  async init() {
4019
4065
  await this.loadTextures();
@@ -5065,6 +5111,10 @@ var _EntityObject = class _EntityObject extends SceneObject {
5065
5111
  uv
5066
5112
  ).clone();
5067
5113
  geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
5114
+ if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
5115
+ const index = Array.from(geometry.getIndex().array);
5116
+ geometry.setIndex(index.concat(index.slice().reverse()));
5117
+ }
5068
5118
  const mesh = this.createMesh(name, geometry, material);
5069
5119
  mesh.renderOrder = renderOrder;
5070
5120
  anchor.add(mesh);
@@ -8037,7 +8087,7 @@ var SceneStatsDisplay = class {
8037
8087
  }
8038
8088
  init() {
8039
8089
  this.statsContainer.classList.add("minerender-stats");
8040
- setInterval(() => {
8090
+ this.interval = setInterval(() => {
8041
8091
  for (let line of this.lines) {
8042
8092
  line.update();
8043
8093
  }
@@ -8046,6 +8096,13 @@ var SceneStatsDisplay = class {
8046
8096
  appendTo(el) {
8047
8097
  el.append(this.statsContainer);
8048
8098
  }
8099
+ dispose() {
8100
+ clearInterval(this.interval);
8101
+ this.interval = void 0;
8102
+ this.lines.length = 0;
8103
+ this.statsContainer.replaceChildren();
8104
+ this.statsContainer.remove();
8105
+ }
8049
8106
  add(line) {
8050
8107
  if (typeof line !== "undefined") {
8051
8108
  this.lines.push(line);
@@ -10483,7 +10540,7 @@ var SKIN_PARTS = Object.values(SkinPart);
10483
10540
  // src/skin/SkinTextureCoordinates.ts
10484
10541
  var baseSkinCoordinates = {
10485
10542
  head: {
10486
- east: {
10543
+ west: {
10487
10544
  // left
10488
10545
  uv: [
10489
10546
  0,
@@ -10492,7 +10549,7 @@ var baseSkinCoordinates = {
10492
10549
  16
10493
10550
  ]
10494
10551
  },
10495
- west: {
10552
+ east: {
10496
10553
  // right
10497
10554
  uv: [
10498
10555
  16,
@@ -10501,7 +10558,7 @@ var baseSkinCoordinates = {
10501
10558
  16
10502
10559
  ]
10503
10560
  },
10504
- north: {
10561
+ south: {
10505
10562
  // front
10506
10563
  uv: [
10507
10564
  8,
@@ -10510,7 +10567,7 @@ var baseSkinCoordinates = {
10510
10567
  16
10511
10568
  ]
10512
10569
  },
10513
- south: {
10570
+ north: {
10514
10571
  // back
10515
10572
  uv: [
10516
10573
  24,
@@ -10522,24 +10579,24 @@ var baseSkinCoordinates = {
10522
10579
  up: {
10523
10580
  // top
10524
10581
  uv: [
10525
- 16,
10526
10582
  8,
10527
- 8,
10528
- 0
10583
+ 0,
10584
+ 16,
10585
+ 8
10529
10586
  ]
10530
10587
  },
10531
10588
  down: {
10532
10589
  // bottom
10533
10590
  uv: [
10534
- 24,
10535
- 0,
10536
10591
  16,
10537
- 8
10592
+ 8,
10593
+ 24,
10594
+ 0
10538
10595
  ]
10539
10596
  }
10540
10597
  },
10541
10598
  body: {
10542
- east: {
10599
+ west: {
10543
10600
  uv: [
10544
10601
  16,
10545
10602
  20,
@@ -10547,7 +10604,7 @@ var baseSkinCoordinates = {
10547
10604
  32
10548
10605
  ]
10549
10606
  },
10550
- west: {
10607
+ east: {
10551
10608
  uv: [
10552
10609
  28,
10553
10610
  20,
@@ -10555,7 +10612,7 @@ var baseSkinCoordinates = {
10555
10612
  32
10556
10613
  ]
10557
10614
  },
10558
- north: {
10615
+ south: {
10559
10616
  uv: [
10560
10617
  20,
10561
10618
  20,
@@ -10563,7 +10620,7 @@ var baseSkinCoordinates = {
10563
10620
  32
10564
10621
  ]
10565
10622
  },
10566
- south: {
10623
+ north: {
10567
10624
  uv: [
10568
10625
  32,
10569
10626
  20,
@@ -10573,23 +10630,23 @@ var baseSkinCoordinates = {
10573
10630
  },
10574
10631
  up: {
10575
10632
  uv: [
10576
- 28,
10577
- 20,
10578
10633
  20,
10579
- 16
10634
+ 16,
10635
+ 28,
10636
+ 20
10580
10637
  ]
10581
10638
  },
10582
10639
  down: {
10583
10640
  uv: [
10584
- 36,
10585
- 16,
10586
10641
  28,
10587
- 20
10642
+ 20,
10643
+ 36,
10644
+ 16
10588
10645
  ]
10589
10646
  }
10590
10647
  },
10591
10648
  leftArm: {
10592
- east: {
10649
+ west: {
10593
10650
  uv: [
10594
10651
  32,
10595
10652
  52,
@@ -10597,7 +10654,7 @@ var baseSkinCoordinates = {
10597
10654
  64
10598
10655
  ]
10599
10656
  },
10600
- west: {
10657
+ east: {
10601
10658
  uv: [
10602
10659
  40,
10603
10660
  52,
@@ -10605,7 +10662,7 @@ var baseSkinCoordinates = {
10605
10662
  64
10606
10663
  ]
10607
10664
  },
10608
- north: {
10665
+ south: {
10609
10666
  uv: [
10610
10667
  36,
10611
10668
  52,
@@ -10613,7 +10670,7 @@ var baseSkinCoordinates = {
10613
10670
  64
10614
10671
  ]
10615
10672
  },
10616
- south: {
10673
+ north: {
10617
10674
  uv: [
10618
10675
  44,
10619
10676
  52,
@@ -10623,23 +10680,23 @@ var baseSkinCoordinates = {
10623
10680
  },
10624
10681
  up: {
10625
10682
  uv: [
10626
- 40,
10627
- 52,
10628
10683
  36,
10629
- 48
10684
+ 48,
10685
+ 40,
10686
+ 52
10630
10687
  ]
10631
10688
  },
10632
10689
  down: {
10633
10690
  uv: [
10634
- 44,
10635
- 48,
10636
10691
  40,
10637
- 52
10692
+ 52,
10693
+ 44,
10694
+ 48
10638
10695
  ]
10639
10696
  }
10640
10697
  },
10641
10698
  rightArm: {
10642
- east: {
10699
+ west: {
10643
10700
  uv: [
10644
10701
  40,
10645
10702
  20,
@@ -10647,7 +10704,7 @@ var baseSkinCoordinates = {
10647
10704
  32
10648
10705
  ]
10649
10706
  },
10650
- west: {
10707
+ east: {
10651
10708
  uv: [
10652
10709
  48,
10653
10710
  20,
@@ -10655,7 +10712,7 @@ var baseSkinCoordinates = {
10655
10712
  32
10656
10713
  ]
10657
10714
  },
10658
- north: {
10715
+ south: {
10659
10716
  uv: [
10660
10717
  44,
10661
10718
  20,
@@ -10663,7 +10720,7 @@ var baseSkinCoordinates = {
10663
10720
  32
10664
10721
  ]
10665
10722
  },
10666
- south: {
10723
+ north: {
10667
10724
  uv: [
10668
10725
  52,
10669
10726
  20,
@@ -10673,23 +10730,23 @@ var baseSkinCoordinates = {
10673
10730
  },
10674
10731
  up: {
10675
10732
  uv: [
10676
- 48,
10677
- 20,
10678
10733
  44,
10679
- 16
10734
+ 16,
10735
+ 48,
10736
+ 20
10680
10737
  ]
10681
10738
  },
10682
10739
  down: {
10683
10740
  uv: [
10684
- 52,
10685
- 16,
10686
10741
  48,
10687
- 20
10742
+ 20,
10743
+ 52,
10744
+ 16
10688
10745
  ]
10689
10746
  }
10690
10747
  },
10691
10748
  leftLeg: {
10692
- east: {
10749
+ west: {
10693
10750
  uv: [
10694
10751
  16,
10695
10752
  52,
@@ -10697,7 +10754,7 @@ var baseSkinCoordinates = {
10697
10754
  64
10698
10755
  ]
10699
10756
  },
10700
- west: {
10757
+ east: {
10701
10758
  uv: [
10702
10759
  24,
10703
10760
  52,
@@ -10705,7 +10762,7 @@ var baseSkinCoordinates = {
10705
10762
  64
10706
10763
  ]
10707
10764
  },
10708
- north: {
10765
+ south: {
10709
10766
  uv: [
10710
10767
  20,
10711
10768
  52,
@@ -10713,7 +10770,7 @@ var baseSkinCoordinates = {
10713
10770
  64
10714
10771
  ]
10715
10772
  },
10716
- south: {
10773
+ north: {
10717
10774
  uv: [
10718
10775
  28,
10719
10776
  52,
@@ -10723,24 +10780,24 @@ var baseSkinCoordinates = {
10723
10780
  },
10724
10781
  up: {
10725
10782
  uv: [
10726
- 24,
10727
- 52,
10728
10783
  20,
10729
- 48
10784
+ 48,
10785
+ 24,
10786
+ 52
10730
10787
  ]
10731
10788
  },
10732
10789
  down: {
10733
10790
  uv: [
10734
- 28,
10735
- 48,
10736
10791
  24,
10737
- 52
10792
+ 52,
10793
+ 28,
10794
+ 48
10738
10795
  ],
10739
10796
  rotation: 180
10740
10797
  }
10741
10798
  },
10742
10799
  rightLeg: {
10743
- east: {
10800
+ west: {
10744
10801
  uv: [
10745
10802
  0,
10746
10803
  20,
@@ -10748,7 +10805,7 @@ var baseSkinCoordinates = {
10748
10805
  32
10749
10806
  ]
10750
10807
  },
10751
- west: {
10808
+ east: {
10752
10809
  uv: [
10753
10810
  8,
10754
10811
  20,
@@ -10756,7 +10813,7 @@ var baseSkinCoordinates = {
10756
10813
  32
10757
10814
  ]
10758
10815
  },
10759
- north: {
10816
+ south: {
10760
10817
  uv: [
10761
10818
  4,
10762
10819
  20,
@@ -10764,7 +10821,7 @@ var baseSkinCoordinates = {
10764
10821
  32
10765
10822
  ]
10766
10823
  },
10767
- south: {
10824
+ north: {
10768
10825
  uv: [
10769
10826
  12,
10770
10827
  20,
@@ -10774,23 +10831,23 @@ var baseSkinCoordinates = {
10774
10831
  },
10775
10832
  up: {
10776
10833
  uv: [
10777
- 8,
10778
- 20,
10779
10834
  4,
10780
- 16
10835
+ 16,
10836
+ 8,
10837
+ 20
10781
10838
  ]
10782
10839
  },
10783
10840
  down: {
10784
10841
  uv: [
10785
- 12,
10786
- 16,
10787
10842
  8,
10788
- 20
10843
+ 20,
10844
+ 12,
10845
+ 16
10789
10846
  ]
10790
10847
  }
10791
10848
  },
10792
10849
  hat: {
10793
- east: {
10850
+ west: {
10794
10851
  uv: [
10795
10852
  32,
10796
10853
  8,
@@ -10798,7 +10855,7 @@ var baseSkinCoordinates = {
10798
10855
  16
10799
10856
  ]
10800
10857
  },
10801
- west: {
10858
+ east: {
10802
10859
  uv: [
10803
10860
  48,
10804
10861
  8,
@@ -10806,7 +10863,7 @@ var baseSkinCoordinates = {
10806
10863
  16
10807
10864
  ]
10808
10865
  },
10809
- north: {
10866
+ south: {
10810
10867
  uv: [
10811
10868
  40,
10812
10869
  8,
@@ -10814,7 +10871,7 @@ var baseSkinCoordinates = {
10814
10871
  16
10815
10872
  ]
10816
10873
  },
10817
- south: {
10874
+ north: {
10818
10875
  uv: [
10819
10876
  56,
10820
10877
  8,
@@ -10824,24 +10881,24 @@ var baseSkinCoordinates = {
10824
10881
  },
10825
10882
  up: {
10826
10883
  uv: [
10827
- 48,
10828
- 8,
10829
10884
  40,
10830
- 0
10885
+ 0,
10886
+ 48,
10887
+ 8
10831
10888
  ]
10832
10889
  },
10833
10890
  down: {
10834
10891
  uv: [
10835
- 56,
10836
- 0,
10837
10892
  48,
10838
- 8
10893
+ 8,
10894
+ 56,
10895
+ 0
10839
10896
  ],
10840
10897
  rotation: 180
10841
10898
  }
10842
10899
  },
10843
10900
  jacket: {
10844
- east: {
10901
+ west: {
10845
10902
  uv: [
10846
10903
  16,
10847
10904
  36,
@@ -10849,7 +10906,7 @@ var baseSkinCoordinates = {
10849
10906
  48
10850
10907
  ]
10851
10908
  },
10852
- west: {
10909
+ east: {
10853
10910
  uv: [
10854
10911
  28,
10855
10912
  36,
@@ -10857,7 +10914,7 @@ var baseSkinCoordinates = {
10857
10914
  48
10858
10915
  ]
10859
10916
  },
10860
- north: {
10917
+ south: {
10861
10918
  uv: [
10862
10919
  20,
10863
10920
  36,
@@ -10865,7 +10922,7 @@ var baseSkinCoordinates = {
10865
10922
  48
10866
10923
  ]
10867
10924
  },
10868
- south: {
10925
+ north: {
10869
10926
  uv: [
10870
10927
  32,
10871
10928
  36,
@@ -10875,24 +10932,24 @@ var baseSkinCoordinates = {
10875
10932
  },
10876
10933
  up: {
10877
10934
  uv: [
10878
- 28,
10879
- 36,
10880
10935
  20,
10881
- 32
10936
+ 32,
10937
+ 28,
10938
+ 36
10882
10939
  ]
10883
10940
  },
10884
10941
  down: {
10885
10942
  uv: [
10886
- 36,
10887
- 32,
10888
10943
  28,
10889
- 36
10944
+ 36,
10945
+ 36,
10946
+ 32
10890
10947
  ],
10891
10948
  rotation: 180
10892
10949
  }
10893
10950
  },
10894
10951
  leftSleeve: {
10895
- east: {
10952
+ west: {
10896
10953
  uv: [
10897
10954
  48,
10898
10955
  52,
@@ -10900,7 +10957,7 @@ var baseSkinCoordinates = {
10900
10957
  64
10901
10958
  ]
10902
10959
  },
10903
- west: {
10960
+ east: {
10904
10961
  uv: [
10905
10962
  56,
10906
10963
  52,
@@ -10908,7 +10965,7 @@ var baseSkinCoordinates = {
10908
10965
  64
10909
10966
  ]
10910
10967
  },
10911
- north: {
10968
+ south: {
10912
10969
  uv: [
10913
10970
  52,
10914
10971
  52,
@@ -10916,7 +10973,7 @@ var baseSkinCoordinates = {
10916
10973
  64
10917
10974
  ]
10918
10975
  },
10919
- south: {
10976
+ north: {
10920
10977
  uv: [
10921
10978
  60,
10922
10979
  52,
@@ -10926,24 +10983,24 @@ var baseSkinCoordinates = {
10926
10983
  },
10927
10984
  up: {
10928
10985
  uv: [
10929
- 56,
10930
- 52,
10931
10986
  52,
10932
- 48
10987
+ 48,
10988
+ 56,
10989
+ 52
10933
10990
  ]
10934
10991
  },
10935
10992
  down: {
10936
10993
  uv: [
10937
- 60,
10938
- 48,
10939
10994
  56,
10940
- 52
10995
+ 52,
10996
+ 60,
10997
+ 48
10941
10998
  ],
10942
10999
  rotation: 180
10943
11000
  }
10944
11001
  },
10945
11002
  rightSleeve: {
10946
- east: {
11003
+ west: {
10947
11004
  uv: [
10948
11005
  40,
10949
11006
  36,
@@ -10951,7 +11008,7 @@ var baseSkinCoordinates = {
10951
11008
  48
10952
11009
  ]
10953
11010
  },
10954
- west: {
11011
+ east: {
10955
11012
  uv: [
10956
11013
  48,
10957
11014
  36,
@@ -10959,7 +11016,7 @@ var baseSkinCoordinates = {
10959
11016
  48
10960
11017
  ]
10961
11018
  },
10962
- north: {
11019
+ south: {
10963
11020
  uv: [
10964
11021
  44,
10965
11022
  36,
@@ -10967,7 +11024,7 @@ var baseSkinCoordinates = {
10967
11024
  48
10968
11025
  ]
10969
11026
  },
10970
- south: {
11027
+ north: {
10971
11028
  uv: [
10972
11029
  52,
10973
11030
  36,
@@ -10977,24 +11034,24 @@ var baseSkinCoordinates = {
10977
11034
  },
10978
11035
  up: {
10979
11036
  uv: [
10980
- 48,
10981
- 36,
10982
11037
  44,
10983
- 32
11038
+ 32,
11039
+ 48,
11040
+ 36
10984
11041
  ]
10985
11042
  },
10986
11043
  down: {
10987
11044
  uv: [
10988
- 52,
10989
- 32,
10990
11045
  48,
10991
- 36
11046
+ 36,
11047
+ 52,
11048
+ 32
10992
11049
  ],
10993
11050
  rotation: 180
10994
11051
  }
10995
11052
  },
10996
11053
  leftTrousers: {
10997
- east: {
11054
+ west: {
10998
11055
  uv: [
10999
11056
  0,
11000
11057
  52,
@@ -11002,7 +11059,7 @@ var baseSkinCoordinates = {
11002
11059
  64
11003
11060
  ]
11004
11061
  },
11005
- west: {
11062
+ east: {
11006
11063
  uv: [
11007
11064
  8,
11008
11065
  52,
@@ -11010,7 +11067,7 @@ var baseSkinCoordinates = {
11010
11067
  64
11011
11068
  ]
11012
11069
  },
11013
- north: {
11070
+ south: {
11014
11071
  uv: [
11015
11072
  4,
11016
11073
  52,
@@ -11018,7 +11075,7 @@ var baseSkinCoordinates = {
11018
11075
  64
11019
11076
  ]
11020
11077
  },
11021
- south: {
11078
+ north: {
11022
11079
  uv: [
11023
11080
  12,
11024
11081
  52,
@@ -11028,23 +11085,23 @@ var baseSkinCoordinates = {
11028
11085
  },
11029
11086
  up: {
11030
11087
  uv: [
11031
- 8,
11032
- 52,
11033
11088
  4,
11034
- 48
11089
+ 48,
11090
+ 8,
11091
+ 52
11035
11092
  ]
11036
11093
  },
11037
11094
  down: {
11038
11095
  uv: [
11039
- 12,
11040
- 48,
11041
11096
  8,
11042
- 52
11097
+ 52,
11098
+ 12,
11099
+ 48
11043
11100
  ]
11044
11101
  }
11045
11102
  },
11046
11103
  rightTrousers: {
11047
- east: {
11104
+ west: {
11048
11105
  uv: [
11049
11106
  0,
11050
11107
  36,
@@ -11052,7 +11109,7 @@ var baseSkinCoordinates = {
11052
11109
  48
11053
11110
  ]
11054
11111
  },
11055
- west: {
11112
+ east: {
11056
11113
  uv: [
11057
11114
  8,
11058
11115
  36,
@@ -11060,7 +11117,7 @@ var baseSkinCoordinates = {
11060
11117
  48
11061
11118
  ]
11062
11119
  },
11063
- north: {
11120
+ south: {
11064
11121
  uv: [
11065
11122
  4,
11066
11123
  36,
@@ -11068,7 +11125,7 @@ var baseSkinCoordinates = {
11068
11125
  48
11069
11126
  ]
11070
11127
  },
11071
- south: {
11128
+ north: {
11072
11129
  uv: [
11073
11130
  12,
11074
11131
  36,
@@ -11078,18 +11135,18 @@ var baseSkinCoordinates = {
11078
11135
  },
11079
11136
  up: {
11080
11137
  uv: [
11081
- 8,
11082
- 36,
11083
11138
  4,
11084
- 32
11139
+ 32,
11140
+ 8,
11141
+ 36
11085
11142
  ]
11086
11143
  },
11087
11144
  down: {
11088
11145
  uv: [
11089
- 12,
11090
- 32,
11091
11146
  8,
11092
- 36
11147
+ 36,
11148
+ 12,
11149
+ 32
11093
11150
  ],
11094
11151
  rotation: 180
11095
11152
  }
@@ -11110,35 +11167,35 @@ var slimSkinTextureCoordinates = {
11110
11167
  ...baseSkinCoordinates,
11111
11168
  leftArm: {
11112
11169
  ...baseSkinCoordinates.leftArm,
11113
- west: { uv: [39, 52, 43, 64] },
11114
- north: { uv: [36, 52, 39, 64] },
11115
- south: { uv: [43, 52, 46, 64] },
11116
- up: { uv: [39, 52, 36, 48] },
11117
- down: { uv: [42, 48, 39, 52] }
11170
+ east: { uv: [39, 52, 43, 64] },
11171
+ south: { uv: [36, 52, 39, 64] },
11172
+ north: { uv: [43, 52, 46, 64] },
11173
+ up: { uv: [36, 48, 39, 52] },
11174
+ down: { uv: [39, 52, 42, 48] }
11118
11175
  },
11119
11176
  rightArm: {
11120
11177
  ...baseSkinCoordinates.rightArm,
11121
- west: { uv: [47, 20, 51, 32] },
11122
- north: { uv: [44, 20, 47, 32] },
11123
- south: { uv: [51, 20, 54, 32] },
11124
- up: { uv: [47, 20, 44, 16] },
11125
- down: { uv: [50, 16, 47, 20] }
11178
+ east: { uv: [47, 20, 51, 32] },
11179
+ south: { uv: [44, 20, 47, 32] },
11180
+ north: { uv: [51, 20, 54, 32] },
11181
+ up: { uv: [44, 16, 47, 20] },
11182
+ down: { uv: [47, 20, 50, 16] }
11126
11183
  },
11127
11184
  leftSleeve: {
11128
11185
  ...baseSkinCoordinates.leftSleeve,
11129
- west: { uv: [55, 52, 59, 64] },
11130
- north: { uv: [52, 52, 55, 64] },
11131
- south: { uv: [59, 52, 62, 64] },
11132
- up: { uv: [55, 52, 52, 48] },
11133
- down: { uv: [58, 48, 55, 52], rotation: 180 }
11186
+ east: { uv: [55, 52, 59, 64] },
11187
+ south: { uv: [52, 52, 55, 64] },
11188
+ north: { uv: [59, 52, 62, 64] },
11189
+ up: { uv: [52, 48, 55, 52] },
11190
+ down: { uv: [55, 52, 58, 48], rotation: 180 }
11134
11191
  },
11135
11192
  rightSleeve: {
11136
11193
  ...baseSkinCoordinates.rightSleeve,
11137
- west: { uv: [47, 36, 51, 48] },
11138
- north: { uv: [44, 36, 47, 48] },
11139
- south: { uv: [51, 36, 54, 48] },
11140
- up: { uv: [47, 36, 44, 32] },
11141
- down: { uv: [50, 32, 47, 36], rotation: 180 }
11194
+ east: { uv: [47, 36, 51, 48] },
11195
+ south: { uv: [44, 36, 47, 48] },
11196
+ north: { uv: [51, 36, 54, 48] },
11197
+ up: { uv: [44, 32, 47, 36] },
11198
+ down: { uv: [47, 36, 50, 32], rotation: 180 }
11142
11199
  }
11143
11200
  };
11144
11201
 
@@ -11378,34 +11435,34 @@ var SkinObject = class extends SceneObject {
11378
11435
  }
11379
11436
  {
11380
11437
  {
11381
- const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
11438
+ const leftArmGroup = this.createAndAddGroup("leftArm", 5, 22, 0);
11382
11439
  const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
11383
11440
  const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
11384
- leftArm.position.x = this.slim ? -0.5 : -1;
11441
+ leftArm.position.x = this.slim ? 0.5 : 1;
11385
11442
  const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
11386
11443
  const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
11387
- leftSleeve.position.x = this.slim ? -0.5 : -1;
11444
+ leftSleeve.position.x = this.slim ? 0.5 : 1;
11388
11445
  }
11389
11446
  {
11390
- const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
11447
+ const rightArmGroup = this.createAndAddGroup("rightArm", -5, 22, 0);
11391
11448
  const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
11392
11449
  const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
11393
- rightArm.position.x = this.slim ? 0.5 : 1;
11450
+ rightArm.position.x = this.slim ? -0.5 : -1;
11394
11451
  const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
11395
11452
  const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
11396
- rightSleeve.position.x = this.slim ? 0.5 : 1;
11453
+ rightSleeve.position.x = this.slim ? -0.5 : -1;
11397
11454
  }
11398
11455
  }
11399
11456
  {
11400
11457
  {
11401
- const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
11458
+ const leftLegGroup = this.createAndAddGroup("leftLeg", 1.9, 12, 0);
11402
11459
  const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
11403
11460
  const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
11404
11461
  const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
11405
11462
  const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
11406
11463
  }
11407
11464
  {
11408
- const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
11465
+ const rightLegGroup = this.createAndAddGroup("rightLeg", -1.9, 12, 0);
11409
11466
  const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
11410
11467
  const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
11411
11468
  const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
@@ -11455,9 +11512,10 @@ var SkinObject = class extends SceneObject {
11455
11512
  mesh.geometry = geometry;
11456
11513
  } else {
11457
11514
  const body = this.getGroupByName("body" /* BODY */);
11458
- const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
11515
+ const group = this.createGroup("cape" /* CAPE */);
11516
+ group.position.set(0, body ? 0 : 24, -2);
11459
11517
  (body ?? this).add(group);
11460
- group.rotation.set(toRadians(-6), Math.PI, 0);
11518
+ group.rotation.x = toRadians(6);
11461
11519
  const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
11462
11520
  cape.position.set(0, -8, -0.5);
11463
11521
  }
@@ -11471,7 +11529,7 @@ var SkinObject = class extends SceneObject {
11471
11529
  updateSlim(slim) {
11472
11530
  if (slim === this.slim) return;
11473
11531
  this.slim = slim;
11474
- const offset = slim ? 0.5 : -0.5;
11532
+ const offset = slim ? -0.5 : 0.5;
11475
11533
  for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
11476
11534
  const mesh = this.getMeshByName(part);
11477
11535
  if (mesh) {
@@ -11565,13 +11623,9 @@ var _MineRenderScene = class _MineRenderScene extends import_three30.Scene {
11565
11623
  return this.add(...object);
11566
11624
  }
11567
11625
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
11568
- console.log("addSceneObject", asset);
11569
- console.log("parent", parent);
11570
- console.log(_options);
11571
11626
  this.dirty = true;
11572
11627
  const obj = await objectSupplier();
11573
11628
  if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
11574
- console.log("instanceMeshes + key");
11575
11629
  let key = asset.key.serialize();
11576
11630
  if (isModelObject(obj)) {
11577
11631
  const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
@@ -11588,7 +11642,6 @@ var _MineRenderScene = class _MineRenderScene extends import_three30.Scene {
11588
11642
  return obj;
11589
11643
  });
11590
11644
  } else {
11591
- console.log("!instanceMeshes | !key");
11592
11645
  obj.scene = this;
11593
11646
  await obj.init();
11594
11647
  if (!isBlockObject(obj)) {
@@ -12287,7 +12340,10 @@ var _Renderer = class _Renderer {
12287
12340
  constructor(options) {
12288
12341
  this._dirty = true;
12289
12342
  this._resizeListener = void 0;
12343
+ this._running = false;
12344
+ this._inAnimationLoop = false;
12290
12345
  this._disposed = false;
12346
+ this._frameCallbacks = /* @__PURE__ */ new Map();
12291
12347
  this._debugHelpers = [];
12292
12348
  this._eventDispatchers = /* @__PURE__ */ new Map();
12293
12349
  this._changeListener = () => {
@@ -12298,7 +12354,14 @@ var _Renderer = class _Renderer {
12298
12354
  if (!Number.isFinite(pixelRatio) || pixelRatio <= 0) {
12299
12355
  throw new RangeError("render.pixelRatio must be a finite positive number");
12300
12356
  }
12301
- this._animationLoop = this.animate.bind(this);
12357
+ this._animationLoop = (time) => {
12358
+ this._inAnimationLoop = true;
12359
+ try {
12360
+ this.animate(time);
12361
+ } finally {
12362
+ this._inAnimationLoop = false;
12363
+ }
12364
+ };
12302
12365
  this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
12303
12366
  this._scene = this.createScene();
12304
12367
  this._camera = this.createCamera();
@@ -12473,15 +12536,39 @@ var _Renderer = class _Renderer {
12473
12536
  this._dirty = dirty;
12474
12537
  this.scene.dirty = dirty;
12475
12538
  }
12539
+ /**
12540
+ * Calls a synchronous animation update before each FPS-limited draw while started.
12541
+ * Subscriptions keep the scene drawing without manual dirty flags. Returns an unsubscribe function.
12542
+ * Registering the same callback twice has no effect. Image exports do not invoke callbacks.
12543
+ */
12544
+ onFrame(callback) {
12545
+ if (this._disposed) return () => {
12546
+ };
12547
+ const subscription = this._frameCallbacks.get(callback) ?? {};
12548
+ this._frameCallbacks.set(callback, subscription);
12549
+ return () => {
12550
+ if (this._frameCallbacks.get(callback) === subscription) this._frameCallbacks.delete(callback);
12551
+ };
12552
+ }
12476
12553
  start() {
12477
12554
  if (this._disposed) return;
12478
12555
  this.stop();
12479
- this.renderer.setAnimationLoop(this._animationLoop);
12556
+ this._running = true;
12557
+ if (!this._inAnimationLoop) this.renderer.setAnimationLoop(this._animationLoop);
12480
12558
  }
12481
12559
  stop() {
12482
12560
  if (this._disposed) return;
12483
- this.renderer.setAnimationLoop(null);
12561
+ this._running = false;
12562
+ if (this._inAnimationLoop) {
12563
+ queueMicrotask(() => {
12564
+ this.renderer.setAnimationLoop(null);
12565
+ if (this._running) this.renderer.setAnimationLoop(this._animationLoop);
12566
+ });
12567
+ } else {
12568
+ this.renderer.setAnimationLoop(null);
12569
+ }
12484
12570
  this._nextFrameTime = void 0;
12571
+ for (const subscription of this._frameCallbacks.values()) subscription.previous = void 0;
12485
12572
  }
12486
12573
  /**
12487
12574
  * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
@@ -12492,6 +12579,7 @@ var _Renderer = class _Renderer {
12492
12579
  if (this._disposed) return;
12493
12580
  this.stop();
12494
12581
  this._disposed = true;
12582
+ this._frameCallbacks.clear();
12495
12583
  if (this._resizeListener) {
12496
12584
  window.removeEventListener("resize", this._resizeListener);
12497
12585
  this._resizeListener = void 0;
@@ -12526,18 +12614,25 @@ var _Renderer = class _Renderer {
12526
12614
  this.renderer.forceContextLoss();
12527
12615
  }
12528
12616
  animate(t = performance.now()) {
12529
- if (this._disposed) return;
12617
+ if (!this._running) return;
12530
12618
  if (this._controls?.enabled) {
12531
12619
  this._controls.update();
12532
12620
  }
12533
- if (this._disposed) return;
12534
- if (!this.dirty && !this.options.render.renderAlways) return;
12621
+ if (!this._running) return;
12622
+ if (!this.dirty && !this.options.render.renderAlways && !this._frameCallbacks.size) return;
12535
12623
  const interval = this._frameInterval;
12536
12624
  if (interval) {
12537
12625
  const next = this._nextFrameTime;
12538
12626
  if (next !== void 0 && t + 0.1 < next) return;
12539
12627
  this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
12540
12628
  }
12629
+ for (const [callback, subscription] of [...this._frameCallbacks]) {
12630
+ if (this._frameCallbacks.get(callback) !== subscription) continue;
12631
+ const previous = subscription.previous;
12632
+ subscription.previous = t;
12633
+ callback({ time: t / 1e3, delta: previous === void 0 ? 0 : (t - previous) / 1e3 });
12634
+ if (!this._running) return;
12635
+ }
12541
12636
  this.drawFrame();
12542
12637
  }
12543
12638
  drawFrame() {