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.
@@ -2496,30 +2496,69 @@ var init_TextureAtlas = __esm({
2496
2496
  var ModelGenerator;
2497
2497
  var init_ModelGenerator = __esm({
2498
2498
  "src/model/ModelGenerator.ts"() {
2499
+ init_CubeFace();
2499
2500
  ModelGenerator = class {
2500
2501
  static {
2501
2502
  this.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2502
2503
  }
2504
+ /**
2505
+ * Front and back faces plus one zero-thickness side face per run of texels that border a transparent texel,
2506
+ * like vanilla's ItemModelGenerator. Pass the pixels of a single (first) animation frame.
2507
+ */
2503
2508
  static generateItemModel(imageData, layer) {
2504
2509
  const tintindex = this.ITEM_LAYERS.indexOf(layer);
2510
+ const texture = `#${layer}`;
2505
2511
  const mainElement = {
2506
2512
  from: [0, 0, 7.5],
2507
2513
  to: [16, 16, 8.5],
2508
2514
  faces: {
2509
2515
  "south": {
2510
2516
  uv: [0, 0, 16, 16],
2511
- texture: `#${layer}`,
2517
+ texture,
2512
2518
  tintindex
2513
2519
  },
2514
2520
  "north": {
2515
2521
  uv: [16, 0, 0, 16],
2516
- texture: `#${layer}`,
2522
+ texture,
2517
2523
  tintindex
2518
2524
  }
2519
2525
  },
2520
2526
  shade: true
2521
2527
  };
2522
- return [mainElement];
2528
+ const elements = [mainElement];
2529
+ const { width, height, data } = imageData;
2530
+ const opaque = (x, y) => x >= 0 && y >= 0 && x < width && y < height && data[(y * width + x) * 4 + 3] !== 0;
2531
+ const sx = 16 / width;
2532
+ const sy = 16 / height;
2533
+ const sides = [["up" /* UP */, 0, -1], ["down" /* DOWN */, 0, 1], ["west" /* WEST */, -1, 0], ["east" /* EAST */, 1, 0]];
2534
+ for (const [face, dx, dy] of sides) {
2535
+ const horizontal = dx === 0;
2536
+ const lines = horizontal ? height : width;
2537
+ const length = horizontal ? width : height;
2538
+ for (let line = 0; line < lines; line++) {
2539
+ for (let start = 0; start < length; start++) {
2540
+ const exposed = (i) => horizontal ? opaque(i, line) && !opaque(i, line + dy) : opaque(line, i) && !opaque(line + dx, i);
2541
+ if (!exposed(start)) continue;
2542
+ let end = start + 1;
2543
+ while (end < length && exposed(end)) end++;
2544
+ let uv, from, to;
2545
+ if (horizontal) {
2546
+ const y = 16 - (line + (dy > 0 ? 1 : 0)) * sy;
2547
+ uv = [start * sx, line * sy, end * sx, (line + 1) * sy];
2548
+ from = [start * sx, y, 7.5];
2549
+ to = [end * sx, y, 8.5];
2550
+ } else {
2551
+ const x = (line + (dx > 0 ? 1 : 0)) * sx;
2552
+ uv = [line * sx, start * sy, (line + 1) * sx, end * sy];
2553
+ from = [x, 16 - end * sy, 7.5];
2554
+ to = [x, 16 - start * sy, 8.5];
2555
+ }
2556
+ elements.push({ from, to, faces: { [face]: { uv, texture, tintindex } }, shade: true });
2557
+ start = end;
2558
+ }
2559
+ }
2560
+ }
2561
+ return elements;
2523
2562
  }
2524
2563
  };
2525
2564
  }
@@ -2886,7 +2925,15 @@ var init_UVMapper = __esm({
2886
2925
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2887
2926
  const textureImage = textureMap[layerName];
2888
2927
  if (textureImage) {
2889
- model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2928
+ const [width, height] = sizes[layerName];
2929
+ const frame = frames[layerName]?.[0].index ?? 0;
2930
+ const columns = textureImage.width / width;
2931
+ model.elements.push(...ModelGenerator.generateItemModel(textureImage.getSectionData(
2932
+ frame % columns * width,
2933
+ Math.floor(frame / columns) * height,
2934
+ width,
2935
+ height
2936
+ ), layerName));
2890
2937
  }
2891
2938
  }
2892
2939
  console.debug(p5, "Item model elements", model.elements);
@@ -4103,7 +4150,6 @@ var init_ModelObject = __esm({
4103
4150
  if (this.options.tints) this.options.tints = { ...this.options.tints };
4104
4151
  this.addEventListener("added", () => this.updateAnimationSubscription());
4105
4152
  this.addEventListener("removed", () => this.updateAnimationSubscription());
4106
- console.log("ModelObject options", this.options);
4107
4153
  }
4108
4154
  static {
4109
4155
  this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
@@ -4952,6 +4998,10 @@ var EntityObject = class _EntityObject extends SceneObject {
4952
4998
  uv
4953
4999
  ).clone();
4954
5000
  geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
5001
+ if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
5002
+ const index = Array.from(geometry.getIndex().array);
5003
+ geometry.setIndex(index.concat(index.slice().reverse()));
5004
+ }
4955
5005
  const mesh = this.createMesh(name, geometry, material);
4956
5006
  mesh.renderOrder = renderOrder;
4957
5007
  anchor.add(mesh);
@@ -7967,7 +8017,7 @@ var SceneStatsDisplay = class {
7967
8017
  }
7968
8018
  init() {
7969
8019
  this.statsContainer.classList.add("minerender-stats");
7970
- setInterval(() => {
8020
+ this.interval = setInterval(() => {
7971
8021
  for (let line of this.lines) {
7972
8022
  line.update();
7973
8023
  }
@@ -7976,6 +8026,13 @@ var SceneStatsDisplay = class {
7976
8026
  appendTo(el) {
7977
8027
  el.append(this.statsContainer);
7978
8028
  }
8029
+ dispose() {
8030
+ clearInterval(this.interval);
8031
+ this.interval = void 0;
8032
+ this.lines.length = 0;
8033
+ this.statsContainer.replaceChildren();
8034
+ this.statsContainer.remove();
8035
+ }
7979
8036
  add(line) {
7980
8037
  if (typeof line !== "undefined") {
7981
8038
  this.lines.push(line);
@@ -10414,7 +10471,7 @@ var SKIN_PARTS = Object.values(SkinPart);
10414
10471
  // src/skin/SkinTextureCoordinates.ts
10415
10472
  var baseSkinCoordinates = {
10416
10473
  head: {
10417
- east: {
10474
+ west: {
10418
10475
  // left
10419
10476
  uv: [
10420
10477
  0,
@@ -10423,7 +10480,7 @@ var baseSkinCoordinates = {
10423
10480
  16
10424
10481
  ]
10425
10482
  },
10426
- west: {
10483
+ east: {
10427
10484
  // right
10428
10485
  uv: [
10429
10486
  16,
@@ -10432,7 +10489,7 @@ var baseSkinCoordinates = {
10432
10489
  16
10433
10490
  ]
10434
10491
  },
10435
- north: {
10492
+ south: {
10436
10493
  // front
10437
10494
  uv: [
10438
10495
  8,
@@ -10441,7 +10498,7 @@ var baseSkinCoordinates = {
10441
10498
  16
10442
10499
  ]
10443
10500
  },
10444
- south: {
10501
+ north: {
10445
10502
  // back
10446
10503
  uv: [
10447
10504
  24,
@@ -10453,24 +10510,24 @@ var baseSkinCoordinates = {
10453
10510
  up: {
10454
10511
  // top
10455
10512
  uv: [
10456
- 16,
10457
10513
  8,
10458
- 8,
10459
- 0
10514
+ 0,
10515
+ 16,
10516
+ 8
10460
10517
  ]
10461
10518
  },
10462
10519
  down: {
10463
10520
  // bottom
10464
10521
  uv: [
10465
- 24,
10466
- 0,
10467
10522
  16,
10468
- 8
10523
+ 8,
10524
+ 24,
10525
+ 0
10469
10526
  ]
10470
10527
  }
10471
10528
  },
10472
10529
  body: {
10473
- east: {
10530
+ west: {
10474
10531
  uv: [
10475
10532
  16,
10476
10533
  20,
@@ -10478,7 +10535,7 @@ var baseSkinCoordinates = {
10478
10535
  32
10479
10536
  ]
10480
10537
  },
10481
- west: {
10538
+ east: {
10482
10539
  uv: [
10483
10540
  28,
10484
10541
  20,
@@ -10486,7 +10543,7 @@ var baseSkinCoordinates = {
10486
10543
  32
10487
10544
  ]
10488
10545
  },
10489
- north: {
10546
+ south: {
10490
10547
  uv: [
10491
10548
  20,
10492
10549
  20,
@@ -10494,7 +10551,7 @@ var baseSkinCoordinates = {
10494
10551
  32
10495
10552
  ]
10496
10553
  },
10497
- south: {
10554
+ north: {
10498
10555
  uv: [
10499
10556
  32,
10500
10557
  20,
@@ -10504,23 +10561,23 @@ var baseSkinCoordinates = {
10504
10561
  },
10505
10562
  up: {
10506
10563
  uv: [
10507
- 28,
10508
- 20,
10509
10564
  20,
10510
- 16
10565
+ 16,
10566
+ 28,
10567
+ 20
10511
10568
  ]
10512
10569
  },
10513
10570
  down: {
10514
10571
  uv: [
10515
- 36,
10516
- 16,
10517
10572
  28,
10518
- 20
10573
+ 20,
10574
+ 36,
10575
+ 16
10519
10576
  ]
10520
10577
  }
10521
10578
  },
10522
10579
  leftArm: {
10523
- east: {
10580
+ west: {
10524
10581
  uv: [
10525
10582
  32,
10526
10583
  52,
@@ -10528,7 +10585,7 @@ var baseSkinCoordinates = {
10528
10585
  64
10529
10586
  ]
10530
10587
  },
10531
- west: {
10588
+ east: {
10532
10589
  uv: [
10533
10590
  40,
10534
10591
  52,
@@ -10536,7 +10593,7 @@ var baseSkinCoordinates = {
10536
10593
  64
10537
10594
  ]
10538
10595
  },
10539
- north: {
10596
+ south: {
10540
10597
  uv: [
10541
10598
  36,
10542
10599
  52,
@@ -10544,7 +10601,7 @@ var baseSkinCoordinates = {
10544
10601
  64
10545
10602
  ]
10546
10603
  },
10547
- south: {
10604
+ north: {
10548
10605
  uv: [
10549
10606
  44,
10550
10607
  52,
@@ -10554,23 +10611,23 @@ var baseSkinCoordinates = {
10554
10611
  },
10555
10612
  up: {
10556
10613
  uv: [
10557
- 40,
10558
- 52,
10559
10614
  36,
10560
- 48
10615
+ 48,
10616
+ 40,
10617
+ 52
10561
10618
  ]
10562
10619
  },
10563
10620
  down: {
10564
10621
  uv: [
10565
- 44,
10566
- 48,
10567
10622
  40,
10568
- 52
10623
+ 52,
10624
+ 44,
10625
+ 48
10569
10626
  ]
10570
10627
  }
10571
10628
  },
10572
10629
  rightArm: {
10573
- east: {
10630
+ west: {
10574
10631
  uv: [
10575
10632
  40,
10576
10633
  20,
@@ -10578,7 +10635,7 @@ var baseSkinCoordinates = {
10578
10635
  32
10579
10636
  ]
10580
10637
  },
10581
- west: {
10638
+ east: {
10582
10639
  uv: [
10583
10640
  48,
10584
10641
  20,
@@ -10586,7 +10643,7 @@ var baseSkinCoordinates = {
10586
10643
  32
10587
10644
  ]
10588
10645
  },
10589
- north: {
10646
+ south: {
10590
10647
  uv: [
10591
10648
  44,
10592
10649
  20,
@@ -10594,7 +10651,7 @@ var baseSkinCoordinates = {
10594
10651
  32
10595
10652
  ]
10596
10653
  },
10597
- south: {
10654
+ north: {
10598
10655
  uv: [
10599
10656
  52,
10600
10657
  20,
@@ -10604,23 +10661,23 @@ var baseSkinCoordinates = {
10604
10661
  },
10605
10662
  up: {
10606
10663
  uv: [
10607
- 48,
10608
- 20,
10609
10664
  44,
10610
- 16
10665
+ 16,
10666
+ 48,
10667
+ 20
10611
10668
  ]
10612
10669
  },
10613
10670
  down: {
10614
10671
  uv: [
10615
- 52,
10616
- 16,
10617
10672
  48,
10618
- 20
10673
+ 20,
10674
+ 52,
10675
+ 16
10619
10676
  ]
10620
10677
  }
10621
10678
  },
10622
10679
  leftLeg: {
10623
- east: {
10680
+ west: {
10624
10681
  uv: [
10625
10682
  16,
10626
10683
  52,
@@ -10628,7 +10685,7 @@ var baseSkinCoordinates = {
10628
10685
  64
10629
10686
  ]
10630
10687
  },
10631
- west: {
10688
+ east: {
10632
10689
  uv: [
10633
10690
  24,
10634
10691
  52,
@@ -10636,7 +10693,7 @@ var baseSkinCoordinates = {
10636
10693
  64
10637
10694
  ]
10638
10695
  },
10639
- north: {
10696
+ south: {
10640
10697
  uv: [
10641
10698
  20,
10642
10699
  52,
@@ -10644,7 +10701,7 @@ var baseSkinCoordinates = {
10644
10701
  64
10645
10702
  ]
10646
10703
  },
10647
- south: {
10704
+ north: {
10648
10705
  uv: [
10649
10706
  28,
10650
10707
  52,
@@ -10654,24 +10711,24 @@ var baseSkinCoordinates = {
10654
10711
  },
10655
10712
  up: {
10656
10713
  uv: [
10657
- 24,
10658
- 52,
10659
10714
  20,
10660
- 48
10715
+ 48,
10716
+ 24,
10717
+ 52
10661
10718
  ]
10662
10719
  },
10663
10720
  down: {
10664
10721
  uv: [
10665
- 28,
10666
- 48,
10667
10722
  24,
10668
- 52
10723
+ 52,
10724
+ 28,
10725
+ 48
10669
10726
  ],
10670
10727
  rotation: 180
10671
10728
  }
10672
10729
  },
10673
10730
  rightLeg: {
10674
- east: {
10731
+ west: {
10675
10732
  uv: [
10676
10733
  0,
10677
10734
  20,
@@ -10679,7 +10736,7 @@ var baseSkinCoordinates = {
10679
10736
  32
10680
10737
  ]
10681
10738
  },
10682
- west: {
10739
+ east: {
10683
10740
  uv: [
10684
10741
  8,
10685
10742
  20,
@@ -10687,7 +10744,7 @@ var baseSkinCoordinates = {
10687
10744
  32
10688
10745
  ]
10689
10746
  },
10690
- north: {
10747
+ south: {
10691
10748
  uv: [
10692
10749
  4,
10693
10750
  20,
@@ -10695,7 +10752,7 @@ var baseSkinCoordinates = {
10695
10752
  32
10696
10753
  ]
10697
10754
  },
10698
- south: {
10755
+ north: {
10699
10756
  uv: [
10700
10757
  12,
10701
10758
  20,
@@ -10705,23 +10762,23 @@ var baseSkinCoordinates = {
10705
10762
  },
10706
10763
  up: {
10707
10764
  uv: [
10708
- 8,
10709
- 20,
10710
10765
  4,
10711
- 16
10766
+ 16,
10767
+ 8,
10768
+ 20
10712
10769
  ]
10713
10770
  },
10714
10771
  down: {
10715
10772
  uv: [
10716
- 12,
10717
- 16,
10718
10773
  8,
10719
- 20
10774
+ 20,
10775
+ 12,
10776
+ 16
10720
10777
  ]
10721
10778
  }
10722
10779
  },
10723
10780
  hat: {
10724
- east: {
10781
+ west: {
10725
10782
  uv: [
10726
10783
  32,
10727
10784
  8,
@@ -10729,7 +10786,7 @@ var baseSkinCoordinates = {
10729
10786
  16
10730
10787
  ]
10731
10788
  },
10732
- west: {
10789
+ east: {
10733
10790
  uv: [
10734
10791
  48,
10735
10792
  8,
@@ -10737,7 +10794,7 @@ var baseSkinCoordinates = {
10737
10794
  16
10738
10795
  ]
10739
10796
  },
10740
- north: {
10797
+ south: {
10741
10798
  uv: [
10742
10799
  40,
10743
10800
  8,
@@ -10745,7 +10802,7 @@ var baseSkinCoordinates = {
10745
10802
  16
10746
10803
  ]
10747
10804
  },
10748
- south: {
10805
+ north: {
10749
10806
  uv: [
10750
10807
  56,
10751
10808
  8,
@@ -10755,24 +10812,24 @@ var baseSkinCoordinates = {
10755
10812
  },
10756
10813
  up: {
10757
10814
  uv: [
10758
- 48,
10759
- 8,
10760
10815
  40,
10761
- 0
10816
+ 0,
10817
+ 48,
10818
+ 8
10762
10819
  ]
10763
10820
  },
10764
10821
  down: {
10765
10822
  uv: [
10766
- 56,
10767
- 0,
10768
10823
  48,
10769
- 8
10824
+ 8,
10825
+ 56,
10826
+ 0
10770
10827
  ],
10771
10828
  rotation: 180
10772
10829
  }
10773
10830
  },
10774
10831
  jacket: {
10775
- east: {
10832
+ west: {
10776
10833
  uv: [
10777
10834
  16,
10778
10835
  36,
@@ -10780,7 +10837,7 @@ var baseSkinCoordinates = {
10780
10837
  48
10781
10838
  ]
10782
10839
  },
10783
- west: {
10840
+ east: {
10784
10841
  uv: [
10785
10842
  28,
10786
10843
  36,
@@ -10788,7 +10845,7 @@ var baseSkinCoordinates = {
10788
10845
  48
10789
10846
  ]
10790
10847
  },
10791
- north: {
10848
+ south: {
10792
10849
  uv: [
10793
10850
  20,
10794
10851
  36,
@@ -10796,7 +10853,7 @@ var baseSkinCoordinates = {
10796
10853
  48
10797
10854
  ]
10798
10855
  },
10799
- south: {
10856
+ north: {
10800
10857
  uv: [
10801
10858
  32,
10802
10859
  36,
@@ -10806,24 +10863,24 @@ var baseSkinCoordinates = {
10806
10863
  },
10807
10864
  up: {
10808
10865
  uv: [
10809
- 28,
10810
- 36,
10811
10866
  20,
10812
- 32
10867
+ 32,
10868
+ 28,
10869
+ 36
10813
10870
  ]
10814
10871
  },
10815
10872
  down: {
10816
10873
  uv: [
10817
- 36,
10818
- 32,
10819
10874
  28,
10820
- 36
10875
+ 36,
10876
+ 36,
10877
+ 32
10821
10878
  ],
10822
10879
  rotation: 180
10823
10880
  }
10824
10881
  },
10825
10882
  leftSleeve: {
10826
- east: {
10883
+ west: {
10827
10884
  uv: [
10828
10885
  48,
10829
10886
  52,
@@ -10831,7 +10888,7 @@ var baseSkinCoordinates = {
10831
10888
  64
10832
10889
  ]
10833
10890
  },
10834
- west: {
10891
+ east: {
10835
10892
  uv: [
10836
10893
  56,
10837
10894
  52,
@@ -10839,7 +10896,7 @@ var baseSkinCoordinates = {
10839
10896
  64
10840
10897
  ]
10841
10898
  },
10842
- north: {
10899
+ south: {
10843
10900
  uv: [
10844
10901
  52,
10845
10902
  52,
@@ -10847,7 +10904,7 @@ var baseSkinCoordinates = {
10847
10904
  64
10848
10905
  ]
10849
10906
  },
10850
- south: {
10907
+ north: {
10851
10908
  uv: [
10852
10909
  60,
10853
10910
  52,
@@ -10857,24 +10914,24 @@ var baseSkinCoordinates = {
10857
10914
  },
10858
10915
  up: {
10859
10916
  uv: [
10860
- 56,
10861
- 52,
10862
10917
  52,
10863
- 48
10918
+ 48,
10919
+ 56,
10920
+ 52
10864
10921
  ]
10865
10922
  },
10866
10923
  down: {
10867
10924
  uv: [
10868
- 60,
10869
- 48,
10870
10925
  56,
10871
- 52
10926
+ 52,
10927
+ 60,
10928
+ 48
10872
10929
  ],
10873
10930
  rotation: 180
10874
10931
  }
10875
10932
  },
10876
10933
  rightSleeve: {
10877
- east: {
10934
+ west: {
10878
10935
  uv: [
10879
10936
  40,
10880
10937
  36,
@@ -10882,7 +10939,7 @@ var baseSkinCoordinates = {
10882
10939
  48
10883
10940
  ]
10884
10941
  },
10885
- west: {
10942
+ east: {
10886
10943
  uv: [
10887
10944
  48,
10888
10945
  36,
@@ -10890,7 +10947,7 @@ var baseSkinCoordinates = {
10890
10947
  48
10891
10948
  ]
10892
10949
  },
10893
- north: {
10950
+ south: {
10894
10951
  uv: [
10895
10952
  44,
10896
10953
  36,
@@ -10898,7 +10955,7 @@ var baseSkinCoordinates = {
10898
10955
  48
10899
10956
  ]
10900
10957
  },
10901
- south: {
10958
+ north: {
10902
10959
  uv: [
10903
10960
  52,
10904
10961
  36,
@@ -10908,24 +10965,24 @@ var baseSkinCoordinates = {
10908
10965
  },
10909
10966
  up: {
10910
10967
  uv: [
10911
- 48,
10912
- 36,
10913
10968
  44,
10914
- 32
10969
+ 32,
10970
+ 48,
10971
+ 36
10915
10972
  ]
10916
10973
  },
10917
10974
  down: {
10918
10975
  uv: [
10919
- 52,
10920
- 32,
10921
10976
  48,
10922
- 36
10977
+ 36,
10978
+ 52,
10979
+ 32
10923
10980
  ],
10924
10981
  rotation: 180
10925
10982
  }
10926
10983
  },
10927
10984
  leftTrousers: {
10928
- east: {
10985
+ west: {
10929
10986
  uv: [
10930
10987
  0,
10931
10988
  52,
@@ -10933,7 +10990,7 @@ var baseSkinCoordinates = {
10933
10990
  64
10934
10991
  ]
10935
10992
  },
10936
- west: {
10993
+ east: {
10937
10994
  uv: [
10938
10995
  8,
10939
10996
  52,
@@ -10941,7 +10998,7 @@ var baseSkinCoordinates = {
10941
10998
  64
10942
10999
  ]
10943
11000
  },
10944
- north: {
11001
+ south: {
10945
11002
  uv: [
10946
11003
  4,
10947
11004
  52,
@@ -10949,7 +11006,7 @@ var baseSkinCoordinates = {
10949
11006
  64
10950
11007
  ]
10951
11008
  },
10952
- south: {
11009
+ north: {
10953
11010
  uv: [
10954
11011
  12,
10955
11012
  52,
@@ -10959,23 +11016,23 @@ var baseSkinCoordinates = {
10959
11016
  },
10960
11017
  up: {
10961
11018
  uv: [
10962
- 8,
10963
- 52,
10964
11019
  4,
10965
- 48
11020
+ 48,
11021
+ 8,
11022
+ 52
10966
11023
  ]
10967
11024
  },
10968
11025
  down: {
10969
11026
  uv: [
10970
- 12,
10971
- 48,
10972
11027
  8,
10973
- 52
11028
+ 52,
11029
+ 12,
11030
+ 48
10974
11031
  ]
10975
11032
  }
10976
11033
  },
10977
11034
  rightTrousers: {
10978
- east: {
11035
+ west: {
10979
11036
  uv: [
10980
11037
  0,
10981
11038
  36,
@@ -10983,7 +11040,7 @@ var baseSkinCoordinates = {
10983
11040
  48
10984
11041
  ]
10985
11042
  },
10986
- west: {
11043
+ east: {
10987
11044
  uv: [
10988
11045
  8,
10989
11046
  36,
@@ -10991,7 +11048,7 @@ var baseSkinCoordinates = {
10991
11048
  48
10992
11049
  ]
10993
11050
  },
10994
- north: {
11051
+ south: {
10995
11052
  uv: [
10996
11053
  4,
10997
11054
  36,
@@ -10999,7 +11056,7 @@ var baseSkinCoordinates = {
10999
11056
  48
11000
11057
  ]
11001
11058
  },
11002
- south: {
11059
+ north: {
11003
11060
  uv: [
11004
11061
  12,
11005
11062
  36,
@@ -11009,18 +11066,18 @@ var baseSkinCoordinates = {
11009
11066
  },
11010
11067
  up: {
11011
11068
  uv: [
11012
- 8,
11013
- 36,
11014
11069
  4,
11015
- 32
11070
+ 32,
11071
+ 8,
11072
+ 36
11016
11073
  ]
11017
11074
  },
11018
11075
  down: {
11019
11076
  uv: [
11020
- 12,
11021
- 32,
11022
11077
  8,
11023
- 36
11078
+ 36,
11079
+ 12,
11080
+ 32
11024
11081
  ],
11025
11082
  rotation: 180
11026
11083
  }
@@ -11041,35 +11098,35 @@ var slimSkinTextureCoordinates = {
11041
11098
  ...baseSkinCoordinates,
11042
11099
  leftArm: {
11043
11100
  ...baseSkinCoordinates.leftArm,
11044
- west: { uv: [39, 52, 43, 64] },
11045
- north: { uv: [36, 52, 39, 64] },
11046
- south: { uv: [43, 52, 46, 64] },
11047
- up: { uv: [39, 52, 36, 48] },
11048
- down: { uv: [42, 48, 39, 52] }
11101
+ east: { uv: [39, 52, 43, 64] },
11102
+ south: { uv: [36, 52, 39, 64] },
11103
+ north: { uv: [43, 52, 46, 64] },
11104
+ up: { uv: [36, 48, 39, 52] },
11105
+ down: { uv: [39, 52, 42, 48] }
11049
11106
  },
11050
11107
  rightArm: {
11051
11108
  ...baseSkinCoordinates.rightArm,
11052
- west: { uv: [47, 20, 51, 32] },
11053
- north: { uv: [44, 20, 47, 32] },
11054
- south: { uv: [51, 20, 54, 32] },
11055
- up: { uv: [47, 20, 44, 16] },
11056
- down: { uv: [50, 16, 47, 20] }
11109
+ east: { uv: [47, 20, 51, 32] },
11110
+ south: { uv: [44, 20, 47, 32] },
11111
+ north: { uv: [51, 20, 54, 32] },
11112
+ up: { uv: [44, 16, 47, 20] },
11113
+ down: { uv: [47, 20, 50, 16] }
11057
11114
  },
11058
11115
  leftSleeve: {
11059
11116
  ...baseSkinCoordinates.leftSleeve,
11060
- west: { uv: [55, 52, 59, 64] },
11061
- north: { uv: [52, 52, 55, 64] },
11062
- south: { uv: [59, 52, 62, 64] },
11063
- up: { uv: [55, 52, 52, 48] },
11064
- down: { uv: [58, 48, 55, 52], rotation: 180 }
11117
+ east: { uv: [55, 52, 59, 64] },
11118
+ south: { uv: [52, 52, 55, 64] },
11119
+ north: { uv: [59, 52, 62, 64] },
11120
+ up: { uv: [52, 48, 55, 52] },
11121
+ down: { uv: [55, 52, 58, 48], rotation: 180 }
11065
11122
  },
11066
11123
  rightSleeve: {
11067
11124
  ...baseSkinCoordinates.rightSleeve,
11068
- west: { uv: [47, 36, 51, 48] },
11069
- north: { uv: [44, 36, 47, 48] },
11070
- south: { uv: [51, 36, 54, 48] },
11071
- up: { uv: [47, 36, 44, 32] },
11072
- down: { uv: [50, 32, 47, 36], rotation: 180 }
11125
+ east: { uv: [47, 36, 51, 48] },
11126
+ south: { uv: [44, 36, 47, 48] },
11127
+ north: { uv: [51, 36, 54, 48] },
11128
+ up: { uv: [44, 32, 47, 36] },
11129
+ down: { uv: [47, 36, 50, 32], rotation: 180 }
11073
11130
  }
11074
11131
  };
11075
11132
 
@@ -11309,34 +11366,34 @@ var SkinObject = class extends SceneObject {
11309
11366
  }
11310
11367
  {
11311
11368
  {
11312
- const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
11369
+ const leftArmGroup = this.createAndAddGroup("leftArm", 5, 22, 0);
11313
11370
  const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
11314
11371
  const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
11315
- leftArm.position.x = this.slim ? -0.5 : -1;
11372
+ leftArm.position.x = this.slim ? 0.5 : 1;
11316
11373
  const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
11317
11374
  const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
11318
- leftSleeve.position.x = this.slim ? -0.5 : -1;
11375
+ leftSleeve.position.x = this.slim ? 0.5 : 1;
11319
11376
  }
11320
11377
  {
11321
- const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
11378
+ const rightArmGroup = this.createAndAddGroup("rightArm", -5, 22, 0);
11322
11379
  const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
11323
11380
  const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
11324
- rightArm.position.x = this.slim ? 0.5 : 1;
11381
+ rightArm.position.x = this.slim ? -0.5 : -1;
11325
11382
  const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
11326
11383
  const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
11327
- rightSleeve.position.x = this.slim ? 0.5 : 1;
11384
+ rightSleeve.position.x = this.slim ? -0.5 : -1;
11328
11385
  }
11329
11386
  }
11330
11387
  {
11331
11388
  {
11332
- const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
11389
+ const leftLegGroup = this.createAndAddGroup("leftLeg", 1.9, 12, 0);
11333
11390
  const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
11334
11391
  const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
11335
11392
  const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
11336
11393
  const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
11337
11394
  }
11338
11395
  {
11339
- const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
11396
+ const rightLegGroup = this.createAndAddGroup("rightLeg", -1.9, 12, 0);
11340
11397
  const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
11341
11398
  const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
11342
11399
  const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
@@ -11386,9 +11443,10 @@ var SkinObject = class extends SceneObject {
11386
11443
  mesh.geometry = geometry;
11387
11444
  } else {
11388
11445
  const body = this.getGroupByName("body" /* BODY */);
11389
- const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
11446
+ const group = this.createGroup("cape" /* CAPE */);
11447
+ group.position.set(0, body ? 0 : 24, -2);
11390
11448
  (body ?? this).add(group);
11391
- group.rotation.set(toRadians(-6), Math.PI, 0);
11449
+ group.rotation.x = toRadians(6);
11392
11450
  const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
11393
11451
  cape.position.set(0, -8, -0.5);
11394
11452
  }
@@ -11402,7 +11460,7 @@ var SkinObject = class extends SceneObject {
11402
11460
  updateSlim(slim) {
11403
11461
  if (slim === this.slim) return;
11404
11462
  this.slim = slim;
11405
- const offset = slim ? 0.5 : -0.5;
11463
+ const offset = slim ? -0.5 : 0.5;
11406
11464
  for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
11407
11465
  const mesh = this.getMeshByName(part);
11408
11466
  if (mesh) {
@@ -11499,13 +11557,9 @@ var MineRenderScene = class _MineRenderScene extends Scene5 {
11499
11557
  return this.add(...object);
11500
11558
  }
11501
11559
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
11502
- console.log("addSceneObject", asset);
11503
- console.log("parent", parent);
11504
- console.log(_options);
11505
11560
  this.dirty = true;
11506
11561
  const obj = await objectSupplier();
11507
11562
  if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
11508
- console.log("instanceMeshes + key");
11509
11563
  let key = asset.key.serialize();
11510
11564
  if (isModelObject(obj)) {
11511
11565
  const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
@@ -11522,7 +11576,6 @@ var MineRenderScene = class _MineRenderScene extends Scene5 {
11522
11576
  return obj;
11523
11577
  });
11524
11578
  } else {
11525
- console.log("!instanceMeshes | !key");
11526
11579
  obj.scene = this;
11527
11580
  await obj.init();
11528
11581
  if (!isBlockObject(obj)) {
@@ -12227,7 +12280,10 @@ var Renderer = class _Renderer {
12227
12280
  constructor(options) {
12228
12281
  this._dirty = true;
12229
12282
  this._resizeListener = void 0;
12283
+ this._running = false;
12284
+ this._inAnimationLoop = false;
12230
12285
  this._disposed = false;
12286
+ this._frameCallbacks = /* @__PURE__ */ new Map();
12231
12287
  this._debugHelpers = [];
12232
12288
  this._eventDispatchers = /* @__PURE__ */ new Map();
12233
12289
  this._changeListener = () => {
@@ -12238,7 +12294,14 @@ var Renderer = class _Renderer {
12238
12294
  if (!Number.isFinite(pixelRatio) || pixelRatio <= 0) {
12239
12295
  throw new RangeError("render.pixelRatio must be a finite positive number");
12240
12296
  }
12241
- this._animationLoop = this.animate.bind(this);
12297
+ this._animationLoop = (time) => {
12298
+ this._inAnimationLoop = true;
12299
+ try {
12300
+ this.animate(time);
12301
+ } finally {
12302
+ this._inAnimationLoop = false;
12303
+ }
12304
+ };
12242
12305
  this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
12243
12306
  this._scene = this.createScene();
12244
12307
  this._camera = this.createCamera();
@@ -12453,15 +12516,39 @@ var Renderer = class _Renderer {
12453
12516
  this._dirty = dirty;
12454
12517
  this.scene.dirty = dirty;
12455
12518
  }
12519
+ /**
12520
+ * Calls a synchronous animation update before each FPS-limited draw while started.
12521
+ * Subscriptions keep the scene drawing without manual dirty flags. Returns an unsubscribe function.
12522
+ * Registering the same callback twice has no effect. Image exports do not invoke callbacks.
12523
+ */
12524
+ onFrame(callback) {
12525
+ if (this._disposed) return () => {
12526
+ };
12527
+ const subscription = this._frameCallbacks.get(callback) ?? {};
12528
+ this._frameCallbacks.set(callback, subscription);
12529
+ return () => {
12530
+ if (this._frameCallbacks.get(callback) === subscription) this._frameCallbacks.delete(callback);
12531
+ };
12532
+ }
12456
12533
  start() {
12457
12534
  if (this._disposed) return;
12458
12535
  this.stop();
12459
- this.renderer.setAnimationLoop(this._animationLoop);
12536
+ this._running = true;
12537
+ if (!this._inAnimationLoop) this.renderer.setAnimationLoop(this._animationLoop);
12460
12538
  }
12461
12539
  stop() {
12462
12540
  if (this._disposed) return;
12463
- this.renderer.setAnimationLoop(null);
12541
+ this._running = false;
12542
+ if (this._inAnimationLoop) {
12543
+ queueMicrotask(() => {
12544
+ this.renderer.setAnimationLoop(null);
12545
+ if (this._running) this.renderer.setAnimationLoop(this._animationLoop);
12546
+ });
12547
+ } else {
12548
+ this.renderer.setAnimationLoop(null);
12549
+ }
12464
12550
  this._nextFrameTime = void 0;
12551
+ for (const subscription of this._frameCallbacks.values()) subscription.previous = void 0;
12465
12552
  }
12466
12553
  /**
12467
12554
  * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
@@ -12472,6 +12559,7 @@ var Renderer = class _Renderer {
12472
12559
  if (this._disposed) return;
12473
12560
  this.stop();
12474
12561
  this._disposed = true;
12562
+ this._frameCallbacks.clear();
12475
12563
  if (this._resizeListener) {
12476
12564
  window.removeEventListener("resize", this._resizeListener);
12477
12565
  this._resizeListener = void 0;
@@ -12506,18 +12594,25 @@ var Renderer = class _Renderer {
12506
12594
  this.renderer.forceContextLoss();
12507
12595
  }
12508
12596
  animate(t = performance.now()) {
12509
- if (this._disposed) return;
12597
+ if (!this._running) return;
12510
12598
  if (this._controls?.enabled) {
12511
12599
  this._controls.update();
12512
12600
  }
12513
- if (this._disposed) return;
12514
- if (!this.dirty && !this.options.render.renderAlways) return;
12601
+ if (!this._running) return;
12602
+ if (!this.dirty && !this.options.render.renderAlways && !this._frameCallbacks.size) return;
12515
12603
  const interval = this._frameInterval;
12516
12604
  if (interval) {
12517
12605
  const next = this._nextFrameTime;
12518
12606
  if (next !== void 0 && t + 0.1 < next) return;
12519
12607
  this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
12520
12608
  }
12609
+ for (const [callback, subscription] of [...this._frameCallbacks]) {
12610
+ if (this._frameCallbacks.get(callback) !== subscription) continue;
12611
+ const previous = subscription.previous;
12612
+ subscription.previous = t;
12613
+ callback({ time: t / 1e3, delta: previous === void 0 ? 0 : (t - previous) / 1e3 });
12614
+ if (!this._running) return;
12615
+ }
12521
12616
  this.drawFrame();
12522
12617
  }
12523
12618
  drawFrame() {