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.
@@ -2416,27 +2416,66 @@ var init_TextureAtlas = __esm({
2416
2416
  var ModelGenerator;
2417
2417
  var init_ModelGenerator = __esm({
2418
2418
  "src/model/ModelGenerator.ts"() {
2419
+ init_CubeFace();
2419
2420
  ModelGenerator = class {
2421
+ /**
2422
+ * Front and back faces plus one zero-thickness side face per run of texels that border a transparent texel,
2423
+ * like vanilla's ItemModelGenerator. Pass the pixels of a single (first) animation frame.
2424
+ */
2420
2425
  static generateItemModel(imageData, layer) {
2421
2426
  const tintindex = this.ITEM_LAYERS.indexOf(layer);
2427
+ const texture = `#${layer}`;
2422
2428
  const mainElement = {
2423
2429
  from: [0, 0, 7.5],
2424
2430
  to: [16, 16, 8.5],
2425
2431
  faces: {
2426
2432
  "south": {
2427
2433
  uv: [0, 0, 16, 16],
2428
- texture: `#${layer}`,
2434
+ texture,
2429
2435
  tintindex
2430
2436
  },
2431
2437
  "north": {
2432
2438
  uv: [16, 0, 0, 16],
2433
- texture: `#${layer}`,
2439
+ texture,
2434
2440
  tintindex
2435
2441
  }
2436
2442
  },
2437
2443
  shade: true
2438
2444
  };
2439
- return [mainElement];
2445
+ const elements = [mainElement];
2446
+ const { width, height, data } = imageData;
2447
+ const opaque = (x, y) => x >= 0 && y >= 0 && x < width && y < height && data[(y * width + x) * 4 + 3] !== 0;
2448
+ const sx = 16 / width;
2449
+ const sy = 16 / height;
2450
+ const sides = [["up" /* UP */, 0, -1], ["down" /* DOWN */, 0, 1], ["west" /* WEST */, -1, 0], ["east" /* EAST */, 1, 0]];
2451
+ for (const [face, dx, dy] of sides) {
2452
+ const horizontal = dx === 0;
2453
+ const lines = horizontal ? height : width;
2454
+ const length = horizontal ? width : height;
2455
+ for (let line = 0; line < lines; line++) {
2456
+ for (let start = 0; start < length; start++) {
2457
+ const exposed = (i) => horizontal ? opaque(i, line) && !opaque(i, line + dy) : opaque(line, i) && !opaque(line + dx, i);
2458
+ if (!exposed(start)) continue;
2459
+ let end = start + 1;
2460
+ while (end < length && exposed(end)) end++;
2461
+ let uv, from, to;
2462
+ if (horizontal) {
2463
+ const y = 16 - (line + (dy > 0 ? 1 : 0)) * sy;
2464
+ uv = [start * sx, line * sy, end * sx, (line + 1) * sy];
2465
+ from = [start * sx, y, 7.5];
2466
+ to = [end * sx, y, 8.5];
2467
+ } else {
2468
+ const x = (line + (dx > 0 ? 1 : 0)) * sx;
2469
+ uv = [line * sx, start * sy, (line + 1) * sx, end * sy];
2470
+ from = [x, 16 - end * sy, 7.5];
2471
+ to = [x, 16 - start * sy, 8.5];
2472
+ }
2473
+ elements.push({ from, to, faces: { [face]: { uv, texture, tintindex } }, shade: true });
2474
+ start = end;
2475
+ }
2476
+ }
2477
+ }
2478
+ return elements;
2440
2479
  }
2441
2480
  };
2442
2481
  ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
@@ -2804,7 +2843,15 @@ var init_UVMapper = __esm({
2804
2843
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2805
2844
  const textureImage = textureMap[layerName];
2806
2845
  if (textureImage) {
2807
- model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2846
+ const [width, height] = sizes[layerName];
2847
+ const frame = frames[layerName]?.[0].index ?? 0;
2848
+ const columns = textureImage.width / width;
2849
+ model.elements.push(...ModelGenerator.generateItemModel(textureImage.getSectionData(
2850
+ frame % columns * width,
2851
+ Math.floor(frame / columns) * height,
2852
+ width,
2853
+ height
2854
+ ), layerName));
2808
2855
  }
2809
2856
  }
2810
2857
  console.debug(p5, "Item model elements", model.elements);
@@ -4020,7 +4067,6 @@ var init_ModelObject = __esm({
4020
4067
  if (this.options.tints) this.options.tints = { ...this.options.tints };
4021
4068
  this.addEventListener("added", () => this.updateAnimationSubscription());
4022
4069
  this.addEventListener("removed", () => this.updateAnimationSubscription());
4023
- console.log("ModelObject options", this.options);
4024
4070
  }
4025
4071
  async init() {
4026
4072
  await this.loadTextures();
@@ -4903,6 +4949,10 @@ var _EntityObject = class _EntityObject extends SceneObject {
4903
4949
  uv
4904
4950
  ).clone();
4905
4951
  geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
4952
+ if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
4953
+ const index = Array.from(geometry.getIndex().array);
4954
+ geometry.setIndex(index.concat(index.slice().reverse()));
4955
+ }
4906
4956
  const mesh = this.createMesh(name, geometry, material);
4907
4957
  mesh.renderOrder = renderOrder;
4908
4958
  anchor.add(mesh);
@@ -7920,7 +7970,7 @@ var SceneStatsDisplay = class {
7920
7970
  }
7921
7971
  init() {
7922
7972
  this.statsContainer.classList.add("minerender-stats");
7923
- setInterval(() => {
7973
+ this.interval = setInterval(() => {
7924
7974
  for (let line of this.lines) {
7925
7975
  line.update();
7926
7976
  }
@@ -7929,6 +7979,13 @@ var SceneStatsDisplay = class {
7929
7979
  appendTo(el) {
7930
7980
  el.append(this.statsContainer);
7931
7981
  }
7982
+ dispose() {
7983
+ clearInterval(this.interval);
7984
+ this.interval = void 0;
7985
+ this.lines.length = 0;
7986
+ this.statsContainer.replaceChildren();
7987
+ this.statsContainer.remove();
7988
+ }
7932
7989
  add(line) {
7933
7990
  if (typeof line !== "undefined") {
7934
7991
  this.lines.push(line);
@@ -10366,7 +10423,7 @@ var SKIN_PARTS = Object.values(SkinPart);
10366
10423
  // src/skin/SkinTextureCoordinates.ts
10367
10424
  var baseSkinCoordinates = {
10368
10425
  head: {
10369
- east: {
10426
+ west: {
10370
10427
  // left
10371
10428
  uv: [
10372
10429
  0,
@@ -10375,7 +10432,7 @@ var baseSkinCoordinates = {
10375
10432
  16
10376
10433
  ]
10377
10434
  },
10378
- west: {
10435
+ east: {
10379
10436
  // right
10380
10437
  uv: [
10381
10438
  16,
@@ -10384,7 +10441,7 @@ var baseSkinCoordinates = {
10384
10441
  16
10385
10442
  ]
10386
10443
  },
10387
- north: {
10444
+ south: {
10388
10445
  // front
10389
10446
  uv: [
10390
10447
  8,
@@ -10393,7 +10450,7 @@ var baseSkinCoordinates = {
10393
10450
  16
10394
10451
  ]
10395
10452
  },
10396
- south: {
10453
+ north: {
10397
10454
  // back
10398
10455
  uv: [
10399
10456
  24,
@@ -10405,24 +10462,24 @@ var baseSkinCoordinates = {
10405
10462
  up: {
10406
10463
  // top
10407
10464
  uv: [
10408
- 16,
10409
10465
  8,
10410
- 8,
10411
- 0
10466
+ 0,
10467
+ 16,
10468
+ 8
10412
10469
  ]
10413
10470
  },
10414
10471
  down: {
10415
10472
  // bottom
10416
10473
  uv: [
10417
- 24,
10418
- 0,
10419
10474
  16,
10420
- 8
10475
+ 8,
10476
+ 24,
10477
+ 0
10421
10478
  ]
10422
10479
  }
10423
10480
  },
10424
10481
  body: {
10425
- east: {
10482
+ west: {
10426
10483
  uv: [
10427
10484
  16,
10428
10485
  20,
@@ -10430,7 +10487,7 @@ var baseSkinCoordinates = {
10430
10487
  32
10431
10488
  ]
10432
10489
  },
10433
- west: {
10490
+ east: {
10434
10491
  uv: [
10435
10492
  28,
10436
10493
  20,
@@ -10438,7 +10495,7 @@ var baseSkinCoordinates = {
10438
10495
  32
10439
10496
  ]
10440
10497
  },
10441
- north: {
10498
+ south: {
10442
10499
  uv: [
10443
10500
  20,
10444
10501
  20,
@@ -10446,7 +10503,7 @@ var baseSkinCoordinates = {
10446
10503
  32
10447
10504
  ]
10448
10505
  },
10449
- south: {
10506
+ north: {
10450
10507
  uv: [
10451
10508
  32,
10452
10509
  20,
@@ -10456,23 +10513,23 @@ var baseSkinCoordinates = {
10456
10513
  },
10457
10514
  up: {
10458
10515
  uv: [
10459
- 28,
10460
- 20,
10461
10516
  20,
10462
- 16
10517
+ 16,
10518
+ 28,
10519
+ 20
10463
10520
  ]
10464
10521
  },
10465
10522
  down: {
10466
10523
  uv: [
10467
- 36,
10468
- 16,
10469
10524
  28,
10470
- 20
10525
+ 20,
10526
+ 36,
10527
+ 16
10471
10528
  ]
10472
10529
  }
10473
10530
  },
10474
10531
  leftArm: {
10475
- east: {
10532
+ west: {
10476
10533
  uv: [
10477
10534
  32,
10478
10535
  52,
@@ -10480,7 +10537,7 @@ var baseSkinCoordinates = {
10480
10537
  64
10481
10538
  ]
10482
10539
  },
10483
- west: {
10540
+ east: {
10484
10541
  uv: [
10485
10542
  40,
10486
10543
  52,
@@ -10488,7 +10545,7 @@ var baseSkinCoordinates = {
10488
10545
  64
10489
10546
  ]
10490
10547
  },
10491
- north: {
10548
+ south: {
10492
10549
  uv: [
10493
10550
  36,
10494
10551
  52,
@@ -10496,7 +10553,7 @@ var baseSkinCoordinates = {
10496
10553
  64
10497
10554
  ]
10498
10555
  },
10499
- south: {
10556
+ north: {
10500
10557
  uv: [
10501
10558
  44,
10502
10559
  52,
@@ -10506,23 +10563,23 @@ var baseSkinCoordinates = {
10506
10563
  },
10507
10564
  up: {
10508
10565
  uv: [
10509
- 40,
10510
- 52,
10511
10566
  36,
10512
- 48
10567
+ 48,
10568
+ 40,
10569
+ 52
10513
10570
  ]
10514
10571
  },
10515
10572
  down: {
10516
10573
  uv: [
10517
- 44,
10518
- 48,
10519
10574
  40,
10520
- 52
10575
+ 52,
10576
+ 44,
10577
+ 48
10521
10578
  ]
10522
10579
  }
10523
10580
  },
10524
10581
  rightArm: {
10525
- east: {
10582
+ west: {
10526
10583
  uv: [
10527
10584
  40,
10528
10585
  20,
@@ -10530,7 +10587,7 @@ var baseSkinCoordinates = {
10530
10587
  32
10531
10588
  ]
10532
10589
  },
10533
- west: {
10590
+ east: {
10534
10591
  uv: [
10535
10592
  48,
10536
10593
  20,
@@ -10538,7 +10595,7 @@ var baseSkinCoordinates = {
10538
10595
  32
10539
10596
  ]
10540
10597
  },
10541
- north: {
10598
+ south: {
10542
10599
  uv: [
10543
10600
  44,
10544
10601
  20,
@@ -10546,7 +10603,7 @@ var baseSkinCoordinates = {
10546
10603
  32
10547
10604
  ]
10548
10605
  },
10549
- south: {
10606
+ north: {
10550
10607
  uv: [
10551
10608
  52,
10552
10609
  20,
@@ -10556,23 +10613,23 @@ var baseSkinCoordinates = {
10556
10613
  },
10557
10614
  up: {
10558
10615
  uv: [
10559
- 48,
10560
- 20,
10561
10616
  44,
10562
- 16
10617
+ 16,
10618
+ 48,
10619
+ 20
10563
10620
  ]
10564
10621
  },
10565
10622
  down: {
10566
10623
  uv: [
10567
- 52,
10568
- 16,
10569
10624
  48,
10570
- 20
10625
+ 20,
10626
+ 52,
10627
+ 16
10571
10628
  ]
10572
10629
  }
10573
10630
  },
10574
10631
  leftLeg: {
10575
- east: {
10632
+ west: {
10576
10633
  uv: [
10577
10634
  16,
10578
10635
  52,
@@ -10580,7 +10637,7 @@ var baseSkinCoordinates = {
10580
10637
  64
10581
10638
  ]
10582
10639
  },
10583
- west: {
10640
+ east: {
10584
10641
  uv: [
10585
10642
  24,
10586
10643
  52,
@@ -10588,7 +10645,7 @@ var baseSkinCoordinates = {
10588
10645
  64
10589
10646
  ]
10590
10647
  },
10591
- north: {
10648
+ south: {
10592
10649
  uv: [
10593
10650
  20,
10594
10651
  52,
@@ -10596,7 +10653,7 @@ var baseSkinCoordinates = {
10596
10653
  64
10597
10654
  ]
10598
10655
  },
10599
- south: {
10656
+ north: {
10600
10657
  uv: [
10601
10658
  28,
10602
10659
  52,
@@ -10606,24 +10663,24 @@ var baseSkinCoordinates = {
10606
10663
  },
10607
10664
  up: {
10608
10665
  uv: [
10609
- 24,
10610
- 52,
10611
10666
  20,
10612
- 48
10667
+ 48,
10668
+ 24,
10669
+ 52
10613
10670
  ]
10614
10671
  },
10615
10672
  down: {
10616
10673
  uv: [
10617
- 28,
10618
- 48,
10619
10674
  24,
10620
- 52
10675
+ 52,
10676
+ 28,
10677
+ 48
10621
10678
  ],
10622
10679
  rotation: 180
10623
10680
  }
10624
10681
  },
10625
10682
  rightLeg: {
10626
- east: {
10683
+ west: {
10627
10684
  uv: [
10628
10685
  0,
10629
10686
  20,
@@ -10631,7 +10688,7 @@ var baseSkinCoordinates = {
10631
10688
  32
10632
10689
  ]
10633
10690
  },
10634
- west: {
10691
+ east: {
10635
10692
  uv: [
10636
10693
  8,
10637
10694
  20,
@@ -10639,7 +10696,7 @@ var baseSkinCoordinates = {
10639
10696
  32
10640
10697
  ]
10641
10698
  },
10642
- north: {
10699
+ south: {
10643
10700
  uv: [
10644
10701
  4,
10645
10702
  20,
@@ -10647,7 +10704,7 @@ var baseSkinCoordinates = {
10647
10704
  32
10648
10705
  ]
10649
10706
  },
10650
- south: {
10707
+ north: {
10651
10708
  uv: [
10652
10709
  12,
10653
10710
  20,
@@ -10657,23 +10714,23 @@ var baseSkinCoordinates = {
10657
10714
  },
10658
10715
  up: {
10659
10716
  uv: [
10660
- 8,
10661
- 20,
10662
10717
  4,
10663
- 16
10718
+ 16,
10719
+ 8,
10720
+ 20
10664
10721
  ]
10665
10722
  },
10666
10723
  down: {
10667
10724
  uv: [
10668
- 12,
10669
- 16,
10670
10725
  8,
10671
- 20
10726
+ 20,
10727
+ 12,
10728
+ 16
10672
10729
  ]
10673
10730
  }
10674
10731
  },
10675
10732
  hat: {
10676
- east: {
10733
+ west: {
10677
10734
  uv: [
10678
10735
  32,
10679
10736
  8,
@@ -10681,7 +10738,7 @@ var baseSkinCoordinates = {
10681
10738
  16
10682
10739
  ]
10683
10740
  },
10684
- west: {
10741
+ east: {
10685
10742
  uv: [
10686
10743
  48,
10687
10744
  8,
@@ -10689,7 +10746,7 @@ var baseSkinCoordinates = {
10689
10746
  16
10690
10747
  ]
10691
10748
  },
10692
- north: {
10749
+ south: {
10693
10750
  uv: [
10694
10751
  40,
10695
10752
  8,
@@ -10697,7 +10754,7 @@ var baseSkinCoordinates = {
10697
10754
  16
10698
10755
  ]
10699
10756
  },
10700
- south: {
10757
+ north: {
10701
10758
  uv: [
10702
10759
  56,
10703
10760
  8,
@@ -10707,24 +10764,24 @@ var baseSkinCoordinates = {
10707
10764
  },
10708
10765
  up: {
10709
10766
  uv: [
10710
- 48,
10711
- 8,
10712
10767
  40,
10713
- 0
10768
+ 0,
10769
+ 48,
10770
+ 8
10714
10771
  ]
10715
10772
  },
10716
10773
  down: {
10717
10774
  uv: [
10718
- 56,
10719
- 0,
10720
10775
  48,
10721
- 8
10776
+ 8,
10777
+ 56,
10778
+ 0
10722
10779
  ],
10723
10780
  rotation: 180
10724
10781
  }
10725
10782
  },
10726
10783
  jacket: {
10727
- east: {
10784
+ west: {
10728
10785
  uv: [
10729
10786
  16,
10730
10787
  36,
@@ -10732,7 +10789,7 @@ var baseSkinCoordinates = {
10732
10789
  48
10733
10790
  ]
10734
10791
  },
10735
- west: {
10792
+ east: {
10736
10793
  uv: [
10737
10794
  28,
10738
10795
  36,
@@ -10740,7 +10797,7 @@ var baseSkinCoordinates = {
10740
10797
  48
10741
10798
  ]
10742
10799
  },
10743
- north: {
10800
+ south: {
10744
10801
  uv: [
10745
10802
  20,
10746
10803
  36,
@@ -10748,7 +10805,7 @@ var baseSkinCoordinates = {
10748
10805
  48
10749
10806
  ]
10750
10807
  },
10751
- south: {
10808
+ north: {
10752
10809
  uv: [
10753
10810
  32,
10754
10811
  36,
@@ -10758,24 +10815,24 @@ var baseSkinCoordinates = {
10758
10815
  },
10759
10816
  up: {
10760
10817
  uv: [
10761
- 28,
10762
- 36,
10763
10818
  20,
10764
- 32
10819
+ 32,
10820
+ 28,
10821
+ 36
10765
10822
  ]
10766
10823
  },
10767
10824
  down: {
10768
10825
  uv: [
10769
- 36,
10770
- 32,
10771
10826
  28,
10772
- 36
10827
+ 36,
10828
+ 36,
10829
+ 32
10773
10830
  ],
10774
10831
  rotation: 180
10775
10832
  }
10776
10833
  },
10777
10834
  leftSleeve: {
10778
- east: {
10835
+ west: {
10779
10836
  uv: [
10780
10837
  48,
10781
10838
  52,
@@ -10783,7 +10840,7 @@ var baseSkinCoordinates = {
10783
10840
  64
10784
10841
  ]
10785
10842
  },
10786
- west: {
10843
+ east: {
10787
10844
  uv: [
10788
10845
  56,
10789
10846
  52,
@@ -10791,7 +10848,7 @@ var baseSkinCoordinates = {
10791
10848
  64
10792
10849
  ]
10793
10850
  },
10794
- north: {
10851
+ south: {
10795
10852
  uv: [
10796
10853
  52,
10797
10854
  52,
@@ -10799,7 +10856,7 @@ var baseSkinCoordinates = {
10799
10856
  64
10800
10857
  ]
10801
10858
  },
10802
- south: {
10859
+ north: {
10803
10860
  uv: [
10804
10861
  60,
10805
10862
  52,
@@ -10809,24 +10866,24 @@ var baseSkinCoordinates = {
10809
10866
  },
10810
10867
  up: {
10811
10868
  uv: [
10812
- 56,
10813
- 52,
10814
10869
  52,
10815
- 48
10870
+ 48,
10871
+ 56,
10872
+ 52
10816
10873
  ]
10817
10874
  },
10818
10875
  down: {
10819
10876
  uv: [
10820
- 60,
10821
- 48,
10822
10877
  56,
10823
- 52
10878
+ 52,
10879
+ 60,
10880
+ 48
10824
10881
  ],
10825
10882
  rotation: 180
10826
10883
  }
10827
10884
  },
10828
10885
  rightSleeve: {
10829
- east: {
10886
+ west: {
10830
10887
  uv: [
10831
10888
  40,
10832
10889
  36,
@@ -10834,7 +10891,7 @@ var baseSkinCoordinates = {
10834
10891
  48
10835
10892
  ]
10836
10893
  },
10837
- west: {
10894
+ east: {
10838
10895
  uv: [
10839
10896
  48,
10840
10897
  36,
@@ -10842,7 +10899,7 @@ var baseSkinCoordinates = {
10842
10899
  48
10843
10900
  ]
10844
10901
  },
10845
- north: {
10902
+ south: {
10846
10903
  uv: [
10847
10904
  44,
10848
10905
  36,
@@ -10850,7 +10907,7 @@ var baseSkinCoordinates = {
10850
10907
  48
10851
10908
  ]
10852
10909
  },
10853
- south: {
10910
+ north: {
10854
10911
  uv: [
10855
10912
  52,
10856
10913
  36,
@@ -10860,24 +10917,24 @@ var baseSkinCoordinates = {
10860
10917
  },
10861
10918
  up: {
10862
10919
  uv: [
10863
- 48,
10864
- 36,
10865
10920
  44,
10866
- 32
10921
+ 32,
10922
+ 48,
10923
+ 36
10867
10924
  ]
10868
10925
  },
10869
10926
  down: {
10870
10927
  uv: [
10871
- 52,
10872
- 32,
10873
10928
  48,
10874
- 36
10929
+ 36,
10930
+ 52,
10931
+ 32
10875
10932
  ],
10876
10933
  rotation: 180
10877
10934
  }
10878
10935
  },
10879
10936
  leftTrousers: {
10880
- east: {
10937
+ west: {
10881
10938
  uv: [
10882
10939
  0,
10883
10940
  52,
@@ -10885,7 +10942,7 @@ var baseSkinCoordinates = {
10885
10942
  64
10886
10943
  ]
10887
10944
  },
10888
- west: {
10945
+ east: {
10889
10946
  uv: [
10890
10947
  8,
10891
10948
  52,
@@ -10893,7 +10950,7 @@ var baseSkinCoordinates = {
10893
10950
  64
10894
10951
  ]
10895
10952
  },
10896
- north: {
10953
+ south: {
10897
10954
  uv: [
10898
10955
  4,
10899
10956
  52,
@@ -10901,7 +10958,7 @@ var baseSkinCoordinates = {
10901
10958
  64
10902
10959
  ]
10903
10960
  },
10904
- south: {
10961
+ north: {
10905
10962
  uv: [
10906
10963
  12,
10907
10964
  52,
@@ -10911,23 +10968,23 @@ var baseSkinCoordinates = {
10911
10968
  },
10912
10969
  up: {
10913
10970
  uv: [
10914
- 8,
10915
- 52,
10916
10971
  4,
10917
- 48
10972
+ 48,
10973
+ 8,
10974
+ 52
10918
10975
  ]
10919
10976
  },
10920
10977
  down: {
10921
10978
  uv: [
10922
- 12,
10923
- 48,
10924
10979
  8,
10925
- 52
10980
+ 52,
10981
+ 12,
10982
+ 48
10926
10983
  ]
10927
10984
  }
10928
10985
  },
10929
10986
  rightTrousers: {
10930
- east: {
10987
+ west: {
10931
10988
  uv: [
10932
10989
  0,
10933
10990
  36,
@@ -10935,7 +10992,7 @@ var baseSkinCoordinates = {
10935
10992
  48
10936
10993
  ]
10937
10994
  },
10938
- west: {
10995
+ east: {
10939
10996
  uv: [
10940
10997
  8,
10941
10998
  36,
@@ -10943,7 +11000,7 @@ var baseSkinCoordinates = {
10943
11000
  48
10944
11001
  ]
10945
11002
  },
10946
- north: {
11003
+ south: {
10947
11004
  uv: [
10948
11005
  4,
10949
11006
  36,
@@ -10951,7 +11008,7 @@ var baseSkinCoordinates = {
10951
11008
  48
10952
11009
  ]
10953
11010
  },
10954
- south: {
11011
+ north: {
10955
11012
  uv: [
10956
11013
  12,
10957
11014
  36,
@@ -10961,18 +11018,18 @@ var baseSkinCoordinates = {
10961
11018
  },
10962
11019
  up: {
10963
11020
  uv: [
10964
- 8,
10965
- 36,
10966
11021
  4,
10967
- 32
11022
+ 32,
11023
+ 8,
11024
+ 36
10968
11025
  ]
10969
11026
  },
10970
11027
  down: {
10971
11028
  uv: [
10972
- 12,
10973
- 32,
10974
11029
  8,
10975
- 36
11030
+ 36,
11031
+ 12,
11032
+ 32
10976
11033
  ],
10977
11034
  rotation: 180
10978
11035
  }
@@ -10993,35 +11050,35 @@ var slimSkinTextureCoordinates = {
10993
11050
  ...baseSkinCoordinates,
10994
11051
  leftArm: {
10995
11052
  ...baseSkinCoordinates.leftArm,
10996
- west: { uv: [39, 52, 43, 64] },
10997
- north: { uv: [36, 52, 39, 64] },
10998
- south: { uv: [43, 52, 46, 64] },
10999
- up: { uv: [39, 52, 36, 48] },
11000
- down: { uv: [42, 48, 39, 52] }
11053
+ east: { uv: [39, 52, 43, 64] },
11054
+ south: { uv: [36, 52, 39, 64] },
11055
+ north: { uv: [43, 52, 46, 64] },
11056
+ up: { uv: [36, 48, 39, 52] },
11057
+ down: { uv: [39, 52, 42, 48] }
11001
11058
  },
11002
11059
  rightArm: {
11003
11060
  ...baseSkinCoordinates.rightArm,
11004
- west: { uv: [47, 20, 51, 32] },
11005
- north: { uv: [44, 20, 47, 32] },
11006
- south: { uv: [51, 20, 54, 32] },
11007
- up: { uv: [47, 20, 44, 16] },
11008
- down: { uv: [50, 16, 47, 20] }
11061
+ east: { uv: [47, 20, 51, 32] },
11062
+ south: { uv: [44, 20, 47, 32] },
11063
+ north: { uv: [51, 20, 54, 32] },
11064
+ up: { uv: [44, 16, 47, 20] },
11065
+ down: { uv: [47, 20, 50, 16] }
11009
11066
  },
11010
11067
  leftSleeve: {
11011
11068
  ...baseSkinCoordinates.leftSleeve,
11012
- west: { uv: [55, 52, 59, 64] },
11013
- north: { uv: [52, 52, 55, 64] },
11014
- south: { uv: [59, 52, 62, 64] },
11015
- up: { uv: [55, 52, 52, 48] },
11016
- down: { uv: [58, 48, 55, 52], rotation: 180 }
11069
+ east: { uv: [55, 52, 59, 64] },
11070
+ south: { uv: [52, 52, 55, 64] },
11071
+ north: { uv: [59, 52, 62, 64] },
11072
+ up: { uv: [52, 48, 55, 52] },
11073
+ down: { uv: [55, 52, 58, 48], rotation: 180 }
11017
11074
  },
11018
11075
  rightSleeve: {
11019
11076
  ...baseSkinCoordinates.rightSleeve,
11020
- west: { uv: [47, 36, 51, 48] },
11021
- north: { uv: [44, 36, 47, 48] },
11022
- south: { uv: [51, 36, 54, 48] },
11023
- up: { uv: [47, 36, 44, 32] },
11024
- down: { uv: [50, 32, 47, 36], rotation: 180 }
11077
+ east: { uv: [47, 36, 51, 48] },
11078
+ south: { uv: [44, 36, 47, 48] },
11079
+ north: { uv: [51, 36, 54, 48] },
11080
+ up: { uv: [44, 32, 47, 36] },
11081
+ down: { uv: [47, 36, 50, 32], rotation: 180 }
11025
11082
  }
11026
11083
  };
11027
11084
 
@@ -11261,34 +11318,34 @@ var SkinObject = class extends SceneObject {
11261
11318
  }
11262
11319
  {
11263
11320
  {
11264
- const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
11321
+ const leftArmGroup = this.createAndAddGroup("leftArm", 5, 22, 0);
11265
11322
  const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
11266
11323
  const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
11267
- leftArm.position.x = this.slim ? -0.5 : -1;
11324
+ leftArm.position.x = this.slim ? 0.5 : 1;
11268
11325
  const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
11269
11326
  const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
11270
- leftSleeve.position.x = this.slim ? -0.5 : -1;
11327
+ leftSleeve.position.x = this.slim ? 0.5 : 1;
11271
11328
  }
11272
11329
  {
11273
- const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
11330
+ const rightArmGroup = this.createAndAddGroup("rightArm", -5, 22, 0);
11274
11331
  const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
11275
11332
  const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
11276
- rightArm.position.x = this.slim ? 0.5 : 1;
11333
+ rightArm.position.x = this.slim ? -0.5 : -1;
11277
11334
  const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
11278
11335
  const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
11279
- rightSleeve.position.x = this.slim ? 0.5 : 1;
11336
+ rightSleeve.position.x = this.slim ? -0.5 : -1;
11280
11337
  }
11281
11338
  }
11282
11339
  {
11283
11340
  {
11284
- const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
11341
+ const leftLegGroup = this.createAndAddGroup("leftLeg", 1.9, 12, 0);
11285
11342
  const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
11286
11343
  const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
11287
11344
  const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
11288
11345
  const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
11289
11346
  }
11290
11347
  {
11291
- const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
11348
+ const rightLegGroup = this.createAndAddGroup("rightLeg", -1.9, 12, 0);
11292
11349
  const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
11293
11350
  const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
11294
11351
  const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
@@ -11338,9 +11395,10 @@ var SkinObject = class extends SceneObject {
11338
11395
  mesh.geometry = geometry;
11339
11396
  } else {
11340
11397
  const body = this.getGroupByName("body" /* BODY */);
11341
- const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
11398
+ const group = this.createGroup("cape" /* CAPE */);
11399
+ group.position.set(0, body ? 0 : 24, -2);
11342
11400
  (body ?? this).add(group);
11343
- group.rotation.set(toRadians(-6), Math.PI, 0);
11401
+ group.rotation.x = toRadians(6);
11344
11402
  const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
11345
11403
  cape.position.set(0, -8, -0.5);
11346
11404
  }
@@ -11354,7 +11412,7 @@ var SkinObject = class extends SceneObject {
11354
11412
  updateSlim(slim) {
11355
11413
  if (slim === this.slim) return;
11356
11414
  this.slim = slim;
11357
- const offset = slim ? 0.5 : -0.5;
11415
+ const offset = slim ? -0.5 : 0.5;
11358
11416
  for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
11359
11417
  const mesh = this.getMeshByName(part);
11360
11418
  if (mesh) {
@@ -11448,13 +11506,9 @@ var _MineRenderScene = class _MineRenderScene extends Scene5 {
11448
11506
  return this.add(...object);
11449
11507
  }
11450
11508
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
11451
- console.log("addSceneObject", asset);
11452
- console.log("parent", parent);
11453
- console.log(_options);
11454
11509
  this.dirty = true;
11455
11510
  const obj = await objectSupplier();
11456
11511
  if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
11457
- console.log("instanceMeshes + key");
11458
11512
  let key = asset.key.serialize();
11459
11513
  if (isModelObject(obj)) {
11460
11514
  const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
@@ -11471,7 +11525,6 @@ var _MineRenderScene = class _MineRenderScene extends Scene5 {
11471
11525
  return obj;
11472
11526
  });
11473
11527
  } else {
11474
- console.log("!instanceMeshes | !key");
11475
11528
  obj.scene = this;
11476
11529
  await obj.init();
11477
11530
  if (!isBlockObject(obj)) {
@@ -12178,7 +12231,10 @@ var _Renderer = class _Renderer {
12178
12231
  constructor(options) {
12179
12232
  this._dirty = true;
12180
12233
  this._resizeListener = void 0;
12234
+ this._running = false;
12235
+ this._inAnimationLoop = false;
12181
12236
  this._disposed = false;
12237
+ this._frameCallbacks = /* @__PURE__ */ new Map();
12182
12238
  this._debugHelpers = [];
12183
12239
  this._eventDispatchers = /* @__PURE__ */ new Map();
12184
12240
  this._changeListener = () => {
@@ -12189,7 +12245,14 @@ var _Renderer = class _Renderer {
12189
12245
  if (!Number.isFinite(pixelRatio) || pixelRatio <= 0) {
12190
12246
  throw new RangeError("render.pixelRatio must be a finite positive number");
12191
12247
  }
12192
- this._animationLoop = this.animate.bind(this);
12248
+ this._animationLoop = (time) => {
12249
+ this._inAnimationLoop = true;
12250
+ try {
12251
+ this.animate(time);
12252
+ } finally {
12253
+ this._inAnimationLoop = false;
12254
+ }
12255
+ };
12193
12256
  this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
12194
12257
  this._scene = this.createScene();
12195
12258
  this._camera = this.createCamera();
@@ -12364,15 +12427,39 @@ var _Renderer = class _Renderer {
12364
12427
  this._dirty = dirty;
12365
12428
  this.scene.dirty = dirty;
12366
12429
  }
12430
+ /**
12431
+ * Calls a synchronous animation update before each FPS-limited draw while started.
12432
+ * Subscriptions keep the scene drawing without manual dirty flags. Returns an unsubscribe function.
12433
+ * Registering the same callback twice has no effect. Image exports do not invoke callbacks.
12434
+ */
12435
+ onFrame(callback) {
12436
+ if (this._disposed) return () => {
12437
+ };
12438
+ const subscription = this._frameCallbacks.get(callback) ?? {};
12439
+ this._frameCallbacks.set(callback, subscription);
12440
+ return () => {
12441
+ if (this._frameCallbacks.get(callback) === subscription) this._frameCallbacks.delete(callback);
12442
+ };
12443
+ }
12367
12444
  start() {
12368
12445
  if (this._disposed) return;
12369
12446
  this.stop();
12370
- this.renderer.setAnimationLoop(this._animationLoop);
12447
+ this._running = true;
12448
+ if (!this._inAnimationLoop) this.renderer.setAnimationLoop(this._animationLoop);
12371
12449
  }
12372
12450
  stop() {
12373
12451
  if (this._disposed) return;
12374
- this.renderer.setAnimationLoop(null);
12452
+ this._running = false;
12453
+ if (this._inAnimationLoop) {
12454
+ queueMicrotask(() => {
12455
+ this.renderer.setAnimationLoop(null);
12456
+ if (this._running) this.renderer.setAnimationLoop(this._animationLoop);
12457
+ });
12458
+ } else {
12459
+ this.renderer.setAnimationLoop(null);
12460
+ }
12375
12461
  this._nextFrameTime = void 0;
12462
+ for (const subscription of this._frameCallbacks.values()) subscription.previous = void 0;
12376
12463
  }
12377
12464
  /**
12378
12465
  * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
@@ -12383,6 +12470,7 @@ var _Renderer = class _Renderer {
12383
12470
  if (this._disposed) return;
12384
12471
  this.stop();
12385
12472
  this._disposed = true;
12473
+ this._frameCallbacks.clear();
12386
12474
  if (this._resizeListener) {
12387
12475
  window.removeEventListener("resize", this._resizeListener);
12388
12476
  this._resizeListener = void 0;
@@ -12417,18 +12505,25 @@ var _Renderer = class _Renderer {
12417
12505
  this.renderer.forceContextLoss();
12418
12506
  }
12419
12507
  animate(t = performance.now()) {
12420
- if (this._disposed) return;
12508
+ if (!this._running) return;
12421
12509
  if (this._controls?.enabled) {
12422
12510
  this._controls.update();
12423
12511
  }
12424
- if (this._disposed) return;
12425
- if (!this.dirty && !this.options.render.renderAlways) return;
12512
+ if (!this._running) return;
12513
+ if (!this.dirty && !this.options.render.renderAlways && !this._frameCallbacks.size) return;
12426
12514
  const interval = this._frameInterval;
12427
12515
  if (interval) {
12428
12516
  const next = this._nextFrameTime;
12429
12517
  if (next !== void 0 && t + 0.1 < next) return;
12430
12518
  this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
12431
12519
  }
12520
+ for (const [callback, subscription] of [...this._frameCallbacks]) {
12521
+ if (this._frameCallbacks.get(callback) !== subscription) continue;
12522
+ const previous = subscription.previous;
12523
+ subscription.previous = t;
12524
+ callback({ time: t / 1e3, delta: previous === void 0 ? 0 : (t - previous) / 1e3 });
12525
+ if (!this._running) return;
12526
+ }
12432
12527
  this.drawFrame();
12433
12528
  }
12434
12529
  drawFrame() {