minerender 2.1.0-alpha.17 → 2.1.0-alpha.2

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.
@@ -28,6 +28,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  mod
29
29
  ));
30
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+ var __decorateClass = (decorators, target, key, kind) => {
32
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
33
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
34
+ if (decorator = decorators[i])
35
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
36
+ if (kind && result) __defProp(target, key, result);
37
+ return result;
38
+ };
31
39
 
32
40
  // ../../node_modules/ts-deepmerge/dist/index.js
33
41
  var require_dist = __commonJS({
@@ -37,8 +45,8 @@ var require_dist = __commonJS({
37
45
  __assign = Object.assign || function(t) {
38
46
  for (var s, i = 1, n = arguments.length; i < n; i++) {
39
47
  s = arguments[i];
40
- for (var p12 in s) if (Object.prototype.hasOwnProperty.call(s, p12))
41
- t[p12] = s[p12];
48
+ for (var p13 in s) if (Object.prototype.hasOwnProperty.call(s, p13))
49
+ t[p13] = s[p13];
42
50
  }
43
51
  return t;
44
52
  };
@@ -82,7 +90,7 @@ var require_dist = __commonJS({
82
90
  return false;
83
91
  };
84
92
  var PROTECTED_KEYS = ["__proto__"];
85
- var merge10 = function() {
93
+ var merge11 = function() {
86
94
  var objects = [];
87
95
  for (var _i = 0; _i < arguments.length; _i++) {
88
96
  objects[_i] = arguments[_i];
@@ -93,9 +101,9 @@ var require_dist = __commonJS({
93
101
  return;
94
102
  }
95
103
  if (Array.isArray(result[key]) && Array.isArray(current[key])) {
96
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
104
+ result[key] = merge11.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
97
105
  } else if (isObject(result[key]) && isObject(current[key])) {
98
- result[key] = merge10(result[key], current[key]);
106
+ result[key] = merge11(result[key], current[key]);
99
107
  } else {
100
108
  result[key] = current[key];
101
109
  }
@@ -106,18 +114,18 @@ var require_dist = __commonJS({
106
114
  var defaultOptions = {
107
115
  mergeArrays: true
108
116
  };
109
- merge10.options = defaultOptions;
110
- merge10.withOptions = function(options) {
117
+ merge11.options = defaultOptions;
118
+ merge11.withOptions = function(options) {
111
119
  var objects = [];
112
120
  for (var _i = 1; _i < arguments.length; _i++) {
113
121
  objects[_i - 1] = arguments[_i];
114
122
  }
115
- merge10.options = __assign({ mergeArrays: true }, options);
116
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
117
- merge10.options = defaultOptions;
123
+ merge11.options = __assign({ mergeArrays: true }, options);
124
+ var result = merge11.apply(void 0, __spreadArray([], __read(objects), false));
125
+ merge11.options = defaultOptions;
118
126
  return result;
119
127
  };
120
- exports2.default = merge10;
128
+ exports2.default = merge11;
121
129
  }
122
130
  });
123
131
 
@@ -127,7 +135,6 @@ __export(index_node_exports, {
127
135
  AXES: () => AXES,
128
136
  ArchiveAssetSource: () => ArchiveAssetSource,
129
137
  AssetKey: () => AssetKey,
130
- AssetLoadError: () => AssetLoadError,
131
138
  AssetLoader: () => AssetLoader,
132
139
  AssetParser: () => AssetParser,
133
140
  AssetSource: () => AssetSource,
@@ -185,7 +192,6 @@ __export(index_node_exports, {
185
192
  OrbitControls: () => OrbitControls,
186
193
  PersistentCache: () => PersistentCache,
187
194
  Renderer: () => Renderer,
188
- RequestError: () => RequestError,
189
195
  Requests: () => Requests,
190
196
  SKIN_PARTS: () => SKIN_PARTS,
191
197
  SceneInspector: () => SceneInspector,
@@ -296,29 +302,25 @@ var Env = class {
296
302
  };
297
303
 
298
304
  // src/cache/PersistentCache.ts
299
- var PersistentCache = class _PersistentCache {
305
+ var _PersistentCache = class _PersistentCache {
300
306
  constructor(backing) {
301
307
  this.backing = backing;
302
308
  }
303
- static {
304
- /** Bump to invalidate every persisted entry. */
305
- this.VERSION = 2;
306
- }
307
309
  static open(name) {
308
310
  return Env.provider.openCache(name, _PersistentCache.VERSION);
309
311
  }
310
- /** Loads a missing entry and stores only non-nullish results. */
311
312
  async getOrLoad(key, loader) {
312
313
  let v = await this.get(key);
313
314
  if (typeof v === "undefined" || v === null) {
314
315
  v = await loader(key);
315
- if (typeof v !== "undefined" && v !== null) {
316
- await this.put(key, v);
317
- }
316
+ await this.put(key, v);
318
317
  }
319
318
  return v;
320
319
  }
321
320
  };
321
+ /** Bump to invalidate every persisted entry. */
322
+ _PersistentCache.VERSION = 1;
323
+ var PersistentCache = _PersistentCache;
322
324
 
323
325
  // src/env/node/NodeCache.ts
324
326
  var NodeCache = class extends PersistentCache {
@@ -396,7 +398,7 @@ registerNodeEnv();
396
398
  // src/Axis.ts
397
399
  var import_three = require("three");
398
400
  var Axis = /* @__PURE__ */ ((Axis3) => {
399
- Axis3["X"] = "x";
401
+ Axis3["X"] = "X";
400
402
  Axis3["Y"] = "y";
401
403
  Axis3["Z"] = "z";
402
404
  return Axis3;
@@ -404,7 +406,7 @@ var Axis = /* @__PURE__ */ ((Axis3) => {
404
406
  var AXES = Object.values(Axis);
405
407
  function axisToVec3(axis) {
406
408
  switch (axis) {
407
- case "x" /* X */:
409
+ case "X" /* X */:
408
410
  return new import_three.Vector3(1, 0, 0);
409
411
  case "y" /* Y */:
410
412
  return new import_three.Vector3(0, 1, 0);
@@ -492,7 +494,8 @@ function serializeImageKey(key) {
492
494
  return md5(key.src);
493
495
  }
494
496
  function serializeBoxGeometryKey(key) {
495
- return md5([key.width, key.height, key.depth, key.uv?.join(":")].join("_"));
497
+ var _a;
498
+ return md5([key.width, key.height, key.depth, (_a = key.uv) == null ? void 0 : _a.join(":")].join("_"));
496
499
  }
497
500
  function serializeTextureKey(key) {
498
501
  return md5([key.src, key.format, key.rotation].join("$"));
@@ -507,61 +510,7 @@ function serializeMeshKey(key) {
507
510
  // src/cache/Caching.ts
508
511
  var import_loading_cache = require("@inventivetalent/loading-cache");
509
512
  var import_time = require("@inventivetalent/time");
510
- var Caching = class _Caching {
511
- static {
512
- this.rawImageCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(5)).buildAsync();
513
- }
514
- static {
515
- this.imageDataCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
516
- }
517
- static {
518
- this.canvasImageDataCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
519
- }
520
- static {
521
- this.wrappedImageCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
522
- }
523
- static {
524
- this.boxGeometryCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(20)).build();
525
- }
526
- static {
527
- this.textureCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
528
- }
529
- static {
530
- this.materialCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
531
- }
532
- static {
533
- this.boxMeshCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
534
- }
535
- static {
536
- this.textureAssetCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
537
- }
538
- static {
539
- this.textureMetaCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
540
- }
541
- static {
542
- this.rawModelCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
543
- }
544
- static {
545
- this.mergedModelCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
546
- }
547
- static {
548
- this.modelTextureAtlasCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
549
- }
550
- static {
551
- this.blockStateCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
552
- }
553
- static {
554
- this.listAssetCache = _Caching.createAssetCache();
555
- }
556
- static {
557
- this.defaultBlockStatesCache = _Caching.createAssetCache();
558
- }
559
- static {
560
- this.entityModelsCache = _Caching.createAssetCache();
561
- }
562
- static createAssetCache() {
563
- return import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
564
- }
513
+ var Caching = class {
565
514
  /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
566
515
  static get all() {
567
516
  return [
@@ -578,10 +527,7 @@ var Caching = class _Caching {
578
527
  this.rawModelCache,
579
528
  this.mergedModelCache,
580
529
  this.modelTextureAtlasCache,
581
- this.blockStateCache,
582
- this.listAssetCache,
583
- this.defaultBlockStatesCache,
584
- this.entityModelsCache
530
+ this.blockStateCache
585
531
  ];
586
532
  }
587
533
  static clear() {
@@ -592,8 +538,8 @@ var Caching = class _Caching {
592
538
  /**
593
539
  * Clears every cache and stops its expiry timer.
594
540
  *
595
- * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
596
- * Use {@link shutdown} to also stop requests and the shared Ticker.
541
+ * loading-cache reschedules that timer indefinitely, so a Node process will not exit until
542
+ * this is called - see {@link shutdown}.
597
543
  */
598
544
  static end() {
599
545
  for (const cache of this.all) {
@@ -607,6 +553,20 @@ var Caching = class _Caching {
607
553
  };
608
554
  }
609
555
  };
556
+ Caching.rawImageCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(5)).buildAsync();
557
+ Caching.imageDataCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
558
+ Caching.canvasImageDataCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
559
+ Caching.wrappedImageCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
560
+ Caching.boxGeometryCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(20)).build();
561
+ Caching.textureCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
562
+ Caching.materialCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
563
+ Caching.boxMeshCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
564
+ Caching.textureAssetCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
565
+ Caching.textureMetaCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
566
+ Caching.rawModelCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
567
+ Caching.mergedModelCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
568
+ Caching.modelTextureAtlasCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
569
+ Caching.blockStateCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
610
570
 
611
571
  // src/Geometries.ts
612
572
  var Geometries = class _Geometries {
@@ -627,14 +587,13 @@ var Geometries = class _Geometries {
627
587
  };
628
588
 
629
589
  // src/Materials.ts
630
- var import_three5 = require("three");
590
+ var import_three6 = require("three");
631
591
 
632
592
  // src/texture/Textures.ts
633
- var import_three4 = require("three");
593
+ var import_three5 = require("three");
634
594
 
635
595
  // src/texture/TextureLoader.ts
636
- var import_three3 = require("three");
637
- var THREE = __toESM(require("three"));
596
+ var import_three4 = require("three");
638
597
 
639
598
  // src/canvas/CanvasCompat.ts
640
599
  function createImage(width, height) {
@@ -645,7 +604,9 @@ function createCanvas2(width, height) {
645
604
  }
646
605
 
647
606
  // src/request/Requests.ts
607
+ var import_axios = __toESM(require("axios"));
648
608
  var import_jobqu = require("jobqu");
609
+ var import_time2 = require("@inventivetalent/time");
649
610
 
650
611
  // src/util/log.ts
651
612
  var Reset = "\x1B[0m";
@@ -655,174 +616,198 @@ function prefix(prefix2) {
655
616
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
656
617
  }
657
618
 
658
- // src/request/Requests.ts
659
- var p = prefix("Requests");
660
- var RequestError = class extends Error {
661
- constructor(message, response, cause) {
662
- super(message);
663
- this.response = response;
664
- this.cause = cause;
665
- this.name = "RequestError";
619
+ // src/util/BatchedExecutor.ts
620
+ var BatchedExecutor = class {
621
+ constructor(interval = 1, batch = 30) {
622
+ this.interval = interval;
623
+ this.batch = batch;
624
+ this.queue = [];
625
+ this.task = setInterval(() => this.run());
666
626
  }
667
- };
668
- async function fetchRequest(config, defaultBaseURL) {
669
- const { url, baseURL = defaultBaseURL, timeout = 5e3, responseType = "json", signal, ...options } = config;
670
- const target = baseURL && !/^([a-z][a-z\d+.-]*:|\/\/)/i.test(url) ? `${baseURL.replace(/\/+$/, "")}/${url.replace(/^\/+/, "")}` : url;
671
- const headers = new Headers(options.headers);
672
- if (typeof window === "undefined" && !headers.has("User-Agent")) {
673
- headers.set("User-Agent", "MineRender");
674
- }
675
- const attemptSignal = AbortSignal.any([
676
- ...signal ? [signal] : [],
677
- ...timeout === 0 ? [] : [AbortSignal.timeout(timeout)]
678
- ]);
679
- const request = new Request(target, { ...options, headers, signal: attemptSignal });
680
- attemptSignal.throwIfAborted();
681
- try {
682
- const response = await fetch(request);
683
- const result = {
684
- data: void 0,
685
- status: response.status,
686
- statusText: response.statusText,
687
- headers: response.headers,
688
- url: response.url
689
- };
690
- if (!response.ok) {
691
- await response.body?.cancel().catch(() => {
692
- });
693
- throw new RequestError(`Request failed with status ${response.status}`, result);
627
+ submit(task) {
628
+ this.queue.push(task);
629
+ }
630
+ run() {
631
+ for (let i = 0; i < this.batch; i++) {
632
+ this.runNext();
694
633
  }
695
- const emptyBody = request.method === "HEAD" || response.status === 204 || response.status === 205;
696
- const data = responseType === "arraybuffer" ? await response.arrayBuffer() : emptyBody || response.body === null ? void 0 : await response.json();
697
- return { ...result, data };
698
- } catch (error) {
699
- attemptSignal.throwIfAborted();
700
- if (/^https?:/.test(request.url) && request.redirect !== "error" && error instanceof TypeError) {
701
- throw new RequestError("Network request failed", void 0, error);
634
+ }
635
+ runNext() {
636
+ let next = this.queue.shift();
637
+ if (next) next();
638
+ }
639
+ };
640
+
641
+ // src/util/model.ts
642
+ var import_three3 = require("three");
643
+ function applyElementRotation(rotation, geometry) {
644
+ const origin = new import_three3.Vector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
645
+ geometry.translate(-origin.x, -origin.y, -origin.z);
646
+ switch (rotation.axis) {
647
+ case "X" /* X */:
648
+ geometry.rotateX(toRadians(rotation.angle));
649
+ break;
650
+ case "y" /* Y */:
651
+ geometry.rotateY(toRadians(rotation.angle));
652
+ break;
653
+ case "z" /* Z */:
654
+ geometry.rotateZ(toRadians(rotation.angle));
655
+ break;
656
+ }
657
+ if (rotation.rescale) {
658
+ if (Math.abs(rotation.angle) === 22.5) {
659
+ const s = 1 / Math.cos(0.39269909262657166);
660
+ geometry.scale(s, 1, s);
661
+ } else {
662
+ const s = 1 / Math.cos(0.7853981852531433);
663
+ geometry.scale(s, 1, s);
702
664
  }
703
- throw error;
704
665
  }
666
+ geometry.translate(origin.x, origin.y, origin.z);
705
667
  }
706
- async function abortable(promise, signal) {
707
- if (!signal) return promise;
708
- let abort;
709
- const cancelled = new Promise((_, reject) => {
710
- abort = () => reject(signal.reason);
711
- signal.addEventListener("abort", abort, { once: true });
712
- if (signal.aborted) abort();
713
- });
714
- try {
715
- return await Promise.race([promise, cancelled]);
716
- } finally {
717
- signal.removeEventListener("abort", abort);
668
+ function applyModelPartRotation(modelPart, geometry) {
669
+ const origin = new import_three3.Vector3(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
670
+ geometry.translate(-origin.x, -origin.y, -origin.z);
671
+ geometry.rotateX(toRadians(modelPart.pitch));
672
+ geometry.rotateY(toRadians(modelPart.yaw));
673
+ geometry.rotateZ(toRadians(modelPart.roll));
674
+ geometry.translate(origin.x, origin.y, origin.z);
675
+ }
676
+ function applyGenericRotation(axis, rotation, obj) {
677
+ switch (axis) {
678
+ case "X" /* X */:
679
+ obj.rotateOnAxis(new import_three3.Vector3(1, 0, 0), toRadians(rotation));
680
+ break;
681
+ case "y" /* Y */:
682
+ obj.rotateOnAxis(new import_three3.Vector3(0, 1, 0), toRadians(rotation));
683
+ break;
684
+ case "z" /* Z */:
685
+ obj.rotateOnAxis(new import_three3.Vector3(0, 0, 1), toRadians(rotation));
686
+ break;
718
687
  }
719
688
  }
720
- var RequestQueue = class {
721
- constructor() {
722
- this.pendingRequests = 0;
723
- this.stopped = new AbortController();
724
- this.queue = new import_jobqu.JobQueue(
725
- (request) => fetchRequest(request, this.baseURL),
726
- { interval: 10, maxPerRun: 1, maxActive: 8 }
727
- );
689
+ function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
690
+ let size = new import_three3.Vector3();
691
+ box.getSize(size);
692
+ let boxGeo = new import_three3.BoxGeometry(size.x, size.y, size.z, 1, 1, 1);
693
+ let wireGeo = new import_three3.EdgesGeometry(boxGeo);
694
+ let wireMat = new import_three3.LineBasicMaterial({ color, linewidth: w });
695
+ let wireframe = new import_three3.LineSegments(wireGeo, wireMat);
696
+ obj.add(wireframe);
697
+ let axes = new import_three3.AxesHelper(1);
698
+ obj.add(axes);
699
+ }
700
+ function addWireframeToObject(obj, color = 16777215, w = 2) {
701
+ let boxGeo = new import_three3.BoxGeometry(16, 16, 16, 1, 1, 1);
702
+ let wireGeo = new import_three3.EdgesGeometry(boxGeo);
703
+ let wireMat = new import_three3.LineBasicMaterial({ color, linewidth: w });
704
+ let wireframe = new import_three3.LineSegments(wireGeo, wireMat);
705
+ obj.add(wireframe);
706
+ let axes = new import_three3.AxesHelper(1);
707
+ obj.add(axes);
708
+ }
709
+ function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
710
+ let wireGeo = new import_three3.EdgesGeometry(geo);
711
+ let wireMat = new import_three3.LineBasicMaterial({ color, linewidth: w });
712
+ let wireframe = new import_three3.LineSegments(wireGeo, wireMat);
713
+ mesh.add(wireframe);
714
+ let axes = new import_three3.AxesHelper(1);
715
+ mesh.add(axes);
716
+ }
717
+
718
+ // src/util/performance.ts
719
+ function captureException(e, ...extra) {
720
+ console.error(e, extra);
721
+ }
722
+ function timingStart(marker) {
723
+ console.time(marker);
724
+ }
725
+ function timingEnd(marker) {
726
+ console.timeEnd(marker);
727
+ }
728
+
729
+ // src/util/three.ts
730
+ function isObject3D(obj) {
731
+ return obj.isObject3D;
732
+ }
733
+ function isMesh(obj) {
734
+ return obj.isMesh;
735
+ }
736
+ function isInstancedMesh(obj) {
737
+ return obj.isInstancedMesh;
738
+ }
739
+ function isPerspectiveCamera(obj) {
740
+ return obj.isPerspectiveCamera;
741
+ }
742
+ function isOrthographicCamera(obj) {
743
+ return obj.isOrthographicCamera;
744
+ }
745
+
746
+ // src/request/Requests.ts
747
+ var p = prefix("Requests");
748
+ if (typeof window === "undefined") {
749
+ import_axios.default.defaults.headers["User-Agent"] = "MineRender";
750
+ }
751
+ var _Requests = class _Requests {
752
+ static genericRequest(request) {
753
+ return this.genericQueue.add(request).catch(async (e) => {
754
+ console.debug(p, "generic catch", e.code, e);
755
+ if (this.shouldRetry(e, request)) {
756
+ await sleep(100);
757
+ return this.genericRequest(request);
758
+ }
759
+ throw e;
760
+ });
728
761
  }
729
- async request(request) {
730
- this.pendingRequests++;
731
- const signal = request.signal;
732
- try {
733
- for (let retries = 0; ; retries++) {
734
- signal?.throwIfAborted();
735
- try {
736
- return await abortable(this.queue.add(request), signal);
737
- } catch (error) {
738
- console.debug(p, "Request failed", error);
739
- const delay = this.retryDelay(error, request, retries);
740
- if (delay === void 0) {
741
- throw error;
762
+ static mcAssetRequest(request) {
763
+ return this.mcAssetRequestQueue.add(request).catch((e) => {
764
+ console.debug(p, "mcAssetRequest catch", e.code, e);
765
+ throw e;
766
+ });
767
+ }
768
+ static shouldRetry(e, request) {
769
+ if ("code" in e) {
770
+ if ("ECONNABORTED" === e.code) {
771
+ if ("minerenderRetry" in request) {
772
+ if (request["minerenderRetry"] > 0) {
773
+ request["minerenderRetry"]--;
774
+ return true;
742
775
  }
743
- await this.waitForRetry(delay, signal);
776
+ } else {
777
+ request["minerenderRetry"] = 3;
778
+ return true;
744
779
  }
745
780
  }
746
- } finally {
747
- if (signal?.aborted) {
748
- this.queue.remove(request);
749
- }
750
- this.pendingRequests--;
751
- }
752
- }
753
- retryDelay(error, request, retries) {
754
- if (this.stopped.signal.aborted || retries >= 3 || (request.method ?? "get").toLowerCase() !== "get" || request.signal?.aborted) {
755
- return void 0;
756
- }
757
- if (error instanceof RequestError) {
758
- const status = error.response?.status;
759
- if (status !== void 0 && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return void 0;
760
- } else if (!(error instanceof DOMException && error.name === "TimeoutError")) {
761
- return void 0;
762
- }
763
- let delay = 100 * 2 ** retries;
764
- const retryAfter = error instanceof RequestError ? error.response?.headers.get("Retry-After") : void 0;
765
- if (retryAfter !== void 0 && retryAfter !== null) {
766
- const seconds = Number(retryAfter);
767
- if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {
768
- return void 0;
769
- }
770
- delay = Math.max(delay, seconds * 1e3);
771
- }
772
- return delay;
773
- }
774
- async waitForRetry(delay, signal) {
775
- let timer;
776
- const waiting = new Promise((resolve) => {
777
- timer = setTimeout(resolve, delay);
778
- });
779
- try {
780
- await abortable(waiting, AbortSignal.any([this.stopped.signal, ...signal ? [signal] : []]));
781
- } finally {
782
- clearTimeout(timer);
783
781
  }
784
- }
785
- get pendingSize() {
786
- return this.pendingRequests;
787
- }
788
- end() {
789
- this.queue.end();
790
- this.stopped.abort(new import_jobqu.JobCancelledError("ended"));
791
- }
792
- };
793
- var Requests = class {
794
- static {
795
- this.genericQueue = new RequestQueue();
796
- }
797
- static {
798
- this.mcAssetRequestQueue = new RequestQueue();
799
- }
800
- static genericRequest(request) {
801
- return this.genericQueue.request(request);
802
- }
803
- static mcAssetRequest(request) {
804
- return this.mcAssetRequestQueue.request(request);
782
+ return false;
805
783
  }
806
784
  static setMcAssetRoot(root) {
807
- this.mcAssetRequestQueue.baseURL = root;
785
+ this.mcAssetInstance.defaults.baseURL = root;
808
786
  }
809
- /** Counts unsettled calls, including retry delays and requests still running after shutdown. */
810
787
  static get queueSizes() {
811
788
  return {
812
- generic: this.genericQueue.pendingSize,
813
- mcAsset: this.mcAssetRequestQueue.pendingSize
789
+ generic: this.genericQueue.size,
790
+ mcAsset: this.mcAssetRequestQueue.size
814
791
  };
815
792
  }
816
793
  /**
817
- * Permanently stops both queues and rejects waiting, retrying, and future requests.
818
- * Requests already running can finish. Idle queues hold no timer, so Node can exit without
819
- * this cleanup. See {@link shutdown}.
794
+ * Stops both queue timers. jobqu reschedules itself indefinitely, so a Node process will not
795
+ * exit until this is called - see {@link shutdown}.
820
796
  */
821
797
  static end() {
822
798
  this.genericQueue.end();
823
799
  this.mcAssetRequestQueue.end();
824
800
  }
825
801
  };
802
+ _Requests.axiosInstance = import_axios.default.create({
803
+ timeout: 5e3
804
+ });
805
+ _Requests.mcAssetInstance = import_axios.default.create({
806
+ timeout: 5e3
807
+ });
808
+ _Requests.genericQueue = new import_jobqu.JobQueue((request) => _Requests.axiosInstance.request(request), import_time2.Time.millis(10), 1);
809
+ _Requests.mcAssetRequestQueue = new import_jobqu.JobQueue((request) => _Requests.mcAssetInstance.request(request), import_time2.Time.millis(10), 1);
810
+ var Requests = _Requests;
826
811
 
827
812
  // src/WrappedImage.ts
828
813
  var WrappedImage = class {
@@ -860,10 +845,10 @@ var WrappedImage = class {
860
845
  return this.animated ? this.width : this.height;
861
846
  }
862
847
  get frameCount() {
863
- return this.height / this.frameHeight;
848
+ return this.height / this.width;
864
849
  }
865
850
  getFrameY(frame) {
866
- return this.frameHeight * Math.max(0, Math.min(this.frameCount - 1, frame));
851
+ return this.height / this.frameCount * Math.max(0, Math.min(this.frameCount, frame));
867
852
  }
868
853
  getSectionData(sx, sy, sw, sh) {
869
854
  return this.dta.data.getImageData(sx, sy, sw, sh);
@@ -873,7 +858,7 @@ var WrappedImage = class {
873
858
  }
874
859
  getFrameSectionData(frame) {
875
860
  const y = this.getFrameY(frame);
876
- return this.getSectionData(0, y, this.frameWidth, this.frameHeight);
861
+ return this.getSectionData(0, y, this.width, this.width + y);
877
862
  }
878
863
  };
879
864
 
@@ -887,41 +872,29 @@ var ImageLoader = class _ImageLoader {
887
872
  static async loadAsync(src) {
888
873
  return new Promise((resolve, reject) => {
889
874
  const image = this._createImage();
890
- image.onload = () => resolve(image);
891
- image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
892
875
  image.src = src;
876
+ image.onload = () => resolve(image);
877
+ image.onerror = (err) => reject(err);
893
878
  });
894
879
  }
895
880
  static loadElement(src, onload, onerr) {
896
881
  const image = this._createImage();
882
+ image.src = src;
897
883
  if (onload)
898
884
  image.onload = onload;
899
885
  if (onerr)
900
886
  image.onerror = onerr;
901
- image.src = src;
902
887
  return image;
903
888
  }
904
889
  static async loadData(src) {
905
890
  console.debug(p2, "loadData", src);
906
- const image = await this.loadCanvasData(src);
907
- return image.data.getImageData(0, 0, image.width, image.height);
891
+ return await this.infoToData(await this.getInfo(src));
908
892
  }
909
893
  static async loadCanvasData(src) {
910
- const keyStr = serializeImageKey({ src });
911
- const info = this.getInfo(src);
912
- const cached = Caching.rawImageCache.getIfPresent(keyStr);
913
- try {
914
- return await this.infoToCanvasData(await info);
915
- } catch (err) {
916
- if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
917
- Caching.rawImageCache.invalidate(keyStr);
918
- }
919
- throw err;
920
- }
894
+ return await this.infoToCanvasData(await this.getInfo(src));
921
895
  }
922
896
  static async infoToCanvasData(info) {
923
- const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
924
- const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
897
+ const image = await _ImageLoader.loadAsync(info.src);
925
898
  const canvas = createCanvas2(info.width, info.height);
926
899
  const context = canvas.getContext("2d");
927
900
  context.drawImage(image, 0, 0);
@@ -932,8 +905,11 @@ var ImageLoader = class _ImageLoader {
932
905
  };
933
906
  }
934
907
  static async infoToData(info) {
935
- const image = await this.infoToCanvasData(info);
936
- return image.data.getImageData(0, 0, image.width, image.height);
908
+ const image = await _ImageLoader.loadAsync(info.src);
909
+ const canvas = createCanvas2(info.width, info.height);
910
+ const context = canvas.getContext("2d");
911
+ context.drawImage(image, 0, 0);
912
+ return context.getImageData(0, 0, canvas.width, canvas.height);
937
913
  }
938
914
  static async getData(src) {
939
915
  const keyStr = serializeImageKey({ src });
@@ -948,25 +924,38 @@ var ImageLoader = class _ImageLoader {
948
924
  });
949
925
  }
950
926
  static async processResponse(response) {
951
- const src = response.url;
927
+ const src = response.config.url;
952
928
  const data = import_buffer.Buffer.from(response.data);
953
929
  const { width, height, type } = Env.provider.imageSize(data);
954
- if (!width || !height) {
955
- throw new Error("Invalid or unsupported image dimensions");
956
- }
957
930
  return {
958
931
  src,
959
- width,
960
- height,
932
+ width: width || 0,
933
+ height: height || 0,
961
934
  type,
962
935
  data
963
936
  };
964
937
  }
965
938
  static async loadInfo(src) {
939
+ if (src.startsWith("data:image/png;base64")) {
940
+ return this.processResponse({
941
+ config: {
942
+ url: src
943
+ },
944
+ data: import_buffer.Buffer.from(src.substr("data:image/png;base64,".length), "base64")
945
+ });
946
+ }
966
947
  return Requests.genericRequest({
967
948
  url: src,
968
949
  responseType: "arraybuffer"
969
- }).then(this.processResponse);
950
+ }).then(this.processResponse).catch((err) => {
951
+ return {
952
+ src,
953
+ width: 0,
954
+ height: 0,
955
+ type: void 0,
956
+ data: import_buffer.Buffer.from([0])
957
+ };
958
+ });
970
959
  }
971
960
  static async getInfo(src) {
972
961
  const keyStr = serializeImageKey({ src });
@@ -988,39 +977,25 @@ var ImageLoader = class _ImageLoader {
988
977
 
989
978
  // src/texture/TextureLoader.ts
990
979
  var TextureLoader = class {
991
- static {
992
- this.failedTextures = /* @__PURE__ */ new WeakSet();
993
- }
994
- /** Reports whether image loading failed, so cached textures can be retried. */
995
- static hasFailed(texture) {
996
- return this.failedTextures.has(texture);
997
- }
998
980
  static createTexture() {
999
- return new import_three3.Texture();
981
+ return new import_three4.Texture();
1000
982
  }
1001
- static loadInBackground(src, format = import_three3.RGBAFormat, rotation = 0) {
983
+ static loadInBackground(src, format = import_three4.RGBAFormat, rotation = 0) {
1002
984
  const texture = this.createTexture();
1003
- texture.colorSpace = THREE.SRGBColorSpace;
1004
- const image = ImageLoader.loadElement(src, () => {
985
+ const image = ImageLoader.loadElement(src);
986
+ image.onload = function() {
1005
987
  texture.needsUpdate = true;
1006
- }, (error) => {
1007
- this.failedTextures.add(texture);
1008
- console.warn("Failed to load texture", src, error);
1009
- });
988
+ };
1010
989
  texture.image = image;
1011
990
  texture.format = format;
1012
991
  texture.rotation = rotation;
1013
992
  return Textures.initTextureProps(texture);
1014
993
  }
1015
- static load(src, format = import_three3.RGBAFormat, rotation = 0) {
1016
- const texture = new import_three3.Texture();
1017
- texture.colorSpace = THREE.SRGBColorSpace;
994
+ static load(src, format = import_three4.RGBAFormat, rotation = 0) {
995
+ const texture = new import_three4.Texture();
1018
996
  ImageLoader.getData(src).then((image) => {
1019
- texture.image = image;
1020
997
  texture.needsUpdate = true;
1021
- }).catch((error) => {
1022
- this.failedTextures.add(texture);
1023
- console.warn("Failed to load texture", src, error);
998
+ texture.image = image;
1024
999
  });
1025
1000
  texture.format = format;
1026
1001
  texture.rotation = rotation;
@@ -1029,11 +1004,11 @@ var TextureLoader = class {
1029
1004
  };
1030
1005
 
1031
1006
  // src/texture/Textures.ts
1032
- var THREE2 = __toESM(require("three"));
1007
+ var THREE = __toESM(require("three"));
1033
1008
  var Textures = class _Textures {
1034
1009
  static initTextureProps(texture) {
1035
- texture.magFilter = THREE2.NearestFilter;
1036
- texture.minFilter = THREE2.NearestFilter;
1010
+ texture.magFilter = THREE.NearestFilter;
1011
+ texture.minFilter = THREE.NearestFilter;
1037
1012
  texture.anisotropy = 0;
1038
1013
  return texture;
1039
1014
  }
@@ -1041,19 +1016,13 @@ var Textures = class _Textures {
1041
1016
  return TextureLoader.load(key.src, key.format, key.rotation);
1042
1017
  }
1043
1018
  static createAsset(key) {
1044
- return new import_three4.Texture();
1019
+ return new import_three5.Texture();
1045
1020
  }
1046
1021
  static createCanvasTexture(canvas) {
1047
- const texture = new import_three4.CanvasTexture(canvas);
1048
- texture.colorSpace = THREE2.SRGBColorSpace;
1049
- return this.initTextureProps(texture);
1022
+ return this.initTextureProps(new import_three5.CanvasTexture(canvas));
1050
1023
  }
1051
1024
  static getImage(key) {
1052
1025
  const keyStr = serializeTextureKey(key);
1053
- const cached = Caching.textureCache.peek(keyStr);
1054
- if (cached && TextureLoader.hasFailed(cached)) {
1055
- Caching.textureCache.invalidate(keyStr);
1056
- }
1057
1026
  return Caching.textureCache.get(keyStr, (k) => {
1058
1027
  return _Textures.createImage(key);
1059
1028
  });
@@ -1061,10 +1030,7 @@ var Textures = class _Textures {
1061
1030
  };
1062
1031
 
1063
1032
  // src/Materials.ts
1064
- var Materials = class _Materials {
1065
- static {
1066
- this.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC";
1067
- }
1033
+ var _Materials = class _Materials {
1068
1034
  // resolved lazily: as a static field this decoded an image the moment the library was
1069
1035
  // imported, which needs both a DOM and an EnvProvider to already be in place
1070
1036
  static get MISSING_TEXTURE() {
@@ -1072,26 +1038,26 @@ var Materials = class _Materials {
1072
1038
  }
1073
1039
  static createImage(key) {
1074
1040
  const transparent = key.transparent || false;
1075
- return new import_three5.MeshBasicMaterial({
1041
+ return new import_three6.MeshBasicMaterial({
1076
1042
  map: Textures.getImage(key.texture),
1077
1043
  transparent,
1078
- side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
1044
+ side: transparent ? import_three6.DoubleSide : import_three6.FrontSide,
1079
1045
  alphaTest: 0.5
1080
1046
  });
1081
1047
  }
1082
1048
  static createBasicCanvasMaterial(canvas, transparent = false, shade = false) {
1083
1049
  if (shade) {
1084
- return new import_three5.MeshStandardMaterial({
1050
+ return new import_three6.MeshStandardMaterial({
1085
1051
  map: Textures.createCanvasTexture(canvas),
1086
1052
  transparent,
1087
- side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
1053
+ side: transparent ? import_three6.DoubleSide : import_three6.FrontSide,
1088
1054
  alphaTest: 0.5
1089
1055
  });
1090
1056
  }
1091
- return new import_three5.MeshBasicMaterial({
1057
+ return new import_three6.MeshBasicMaterial({
1092
1058
  map: Textures.createCanvasTexture(canvas),
1093
1059
  transparent,
1094
- side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
1060
+ side: transparent ? import_three6.DoubleSide : import_three6.FrontSide,
1095
1061
  alphaTest: 0.5
1096
1062
  });
1097
1063
  }
@@ -1112,11 +1078,7 @@ var Materials = class _Materials {
1112
1078
 
1113
1079
  if (SHADE) {
1114
1080
 
1115
- #ifdef USE_INSTANCING
1116
- vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
1117
- #else
1118
- vec3 N = vec3( modelMatrix * vec4(normal, 0.0) );
1119
- #endif
1081
+ vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
1120
1082
 
1121
1083
  float yLight = (1.0+N.y) * 0.5;
1122
1084
  light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT;
@@ -1174,19 +1136,16 @@ var Materials = class _Materials {
1174
1136
  gl_FragColor = vec4(lift + color.rgb * light2, 1.0);
1175
1137
 
1176
1138
  }
1177
-
1178
- #include <tonemapping_fragment>
1179
- #include <colorspace_fragment>
1180
1139
  }
1181
1140
  `;
1182
1141
  try {
1183
- return new import_three5.ShaderMaterial({
1142
+ return new import_three6.ShaderMaterial({
1184
1143
  uniforms: {
1185
1144
  SHADE: { value: true },
1186
1145
  BRIGHTNESS: { value: 1 },
1187
1146
  EMISSIVE: { value: false },
1188
1147
  base: {
1189
- value: new import_three5.Color(12698049)
1148
+ value: new import_three6.Color(12698049)
1190
1149
  /*TODO*/
1191
1150
  },
1192
1151
  map: { value: Textures.createCanvasTexture(canvas) }
@@ -1195,7 +1154,7 @@ var Materials = class _Materials {
1195
1154
  fragmentShader: fragShader,
1196
1155
  vertexColors: true,
1197
1156
  transparent,
1198
- side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
1157
+ side: transparent ? import_three6.DoubleSide : import_three6.FrontSide,
1199
1158
  alphaTest: 0.5
1200
1159
  });
1201
1160
  } catch (e) {
@@ -1205,10 +1164,6 @@ var Materials = class _Materials {
1205
1164
  }
1206
1165
  static getImage(key) {
1207
1166
  const keyStr = serializeMaterialKey(key);
1208
- const map = Caching.materialCache.peek(keyStr)?.map;
1209
- if (map && TextureLoader.hasFailed(map)) {
1210
- Caching.materialCache.invalidate(keyStr);
1211
- }
1212
1167
  return Caching.materialCache.get(keyStr, (k) => {
1213
1168
  return _Materials.createImage(key);
1214
1169
  });
@@ -1229,12 +1184,14 @@ var Materials = class _Materials {
1229
1184
  }
1230
1185
  }
1231
1186
  };
1187
+ _Materials.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC";
1188
+ var Materials = _Materials;
1232
1189
 
1233
1190
  // src/Meshes.ts
1234
- var import_three6 = require("three");
1191
+ var import_three7 = require("three");
1235
1192
  var Meshes = class _Meshes {
1236
1193
  static createBox(key) {
1237
- return new import_three6.Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1194
+ return new import_three7.Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1238
1195
  }
1239
1196
  static getBox(key) {
1240
1197
  const keyStr = serializeMeshKey(key);
@@ -1283,7 +1240,7 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1283
1240
  this.root = root;
1284
1241
  }
1285
1242
  static parse(assetType, str, origin) {
1286
- let namespace = origin?.namespace || DEFAULT_NAMESPACE;
1243
+ let namespace = (origin == null ? void 0 : origin.namespace) || DEFAULT_NAMESPACE;
1287
1244
  if (str.includes(":")) {
1288
1245
  let split2 = str.split(":");
1289
1246
  namespace = split2[0];
@@ -1296,12 +1253,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1296
1253
  split.shift();
1297
1254
  }
1298
1255
  let path = split.join("/");
1299
- let extension = assetType === "textures" ? ".png" : origin?.assetType || ".json";
1300
- return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin?.root);
1256
+ let extension = assetType === "textures" ? ".png" : (origin == null ? void 0 : origin.assetType) || ".json";
1257
+ return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin == null ? void 0 : origin.root);
1301
1258
  }
1302
1259
  toString() {
1303
1260
  let a = [
1304
- this.root ?? AssetLoader.ROOT,
1261
+ typeof this.root !== "undefined" || AssetLoader.ROOT !== DEFAULT_ROOT ? this.root ?? AssetLoader.ROOT : "__root__",
1305
1262
  this.rootType ?? "__rootType__",
1306
1263
  this.assetType ?? "__assetType__",
1307
1264
  this.type ?? "__type__",
@@ -1311,12 +1268,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1311
1268
  return a.join("/");
1312
1269
  }
1313
1270
  getFullPath() {
1314
- let p12 = [];
1271
+ let p13 = [];
1315
1272
  if (this.type) {
1316
- p12.push(this.type);
1273
+ p13.push(this.type);
1317
1274
  }
1318
- p12.push(this.path);
1319
- return p12.join("/");
1275
+ p13.push(this.path);
1276
+ return p13.join("/");
1320
1277
  }
1321
1278
  toNamespacedString() {
1322
1279
  return this.namespace + ":" + this.getFullPath();
@@ -1338,10 +1295,10 @@ var ModelMerger = class {
1338
1295
  const models = await this.collectAllParents(model);
1339
1296
  let merged = {};
1340
1297
  for (let parentModel of models) {
1341
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1298
+ merged = (0, import_ts_deepmerge.default)(merged, parentModel);
1342
1299
  }
1343
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1344
- merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
1300
+ merged = (0, import_ts_deepmerge.default)(merged, model);
1301
+ merged.hierarchy = models.map((m) => m.parent).filter((p13) => `${p13}`);
1345
1302
  merged.hierarchy.push(`${merged.parent}`);
1346
1303
  return merged;
1347
1304
  }
@@ -1351,7 +1308,6 @@ var ModelMerger = class {
1351
1308
  }
1352
1309
  const models = [];
1353
1310
  const parentKey = AssetKey.parse("models", model.parent);
1354
- parentKey.root = model.key?.root;
1355
1311
  const parentModel = await Models.getRaw(parentKey);
1356
1312
  if (parentModel) {
1357
1313
  models.unshift(parentModel);
@@ -1361,6 +1317,9 @@ var ModelMerger = class {
1361
1317
  }
1362
1318
  };
1363
1319
 
1320
+ // src/assets/Models.ts
1321
+ var import_typescript_memoize = require("typescript-memoize");
1322
+
1364
1323
  // src/assets/source/parser/AssetParsers.ts
1365
1324
  var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1366
1325
  AssetParser2["MODEL"] = "model";
@@ -1374,65 +1333,30 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1374
1333
  })(AssetParser || {});
1375
1334
 
1376
1335
  // src/assets/Models.ts
1377
- var Models = class _Models {
1336
+ var _Models = class _Models {
1378
1337
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1379
1338
  // the library, and would require an EnvProvider before any entry has had a chance to register
1380
1339
  static get PERSISTENT_CACHE() {
1381
1340
  return this._persistentCache ??= PersistentCache.open("minerender-models");
1382
1341
  }
1383
1342
  static async getItemList() {
1384
- const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
1385
- const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
1386
- return Caching.listAssetCache.get(key.serialize(), async () => {
1387
- return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
1388
- }).then((r) => r?.files ?? []);
1343
+ return AssetLoader.get(new AssetKey(
1344
+ DEFAULT_NAMESPACE,
1345
+ "_list",
1346
+ "models",
1347
+ "item",
1348
+ "assets",
1349
+ ".json",
1350
+ DEFAULT_ROOT
1351
+ ), "list" /* LIST */).then((r) => (r == null ? void 0 : r.files) ?? []);
1389
1352
  }
1390
1353
  static async loadAndMerge(key) {
1391
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
1354
+ const model = await this.getRaw(key);
1392
1355
  if (!model) {
1393
1356
  return void 0;
1394
1357
  }
1395
1358
  return ModelMerger.mergeWithParents(model);
1396
1359
  }
1397
- static async getItemModel(key) {
1398
- const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1399
- const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
1400
- const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1401
- if (!result) return void 0;
1402
- if (result.key.assetType !== "items") return { ...result.asset, key };
1403
- const reference = this.defaultItemModel(result.asset.model, key);
1404
- const modelKey = AssetKey.parse("models", reference);
1405
- modelKey.root = key.root;
1406
- const model2 = await this.getRaw(modelKey);
1407
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
1408
- return model2;
1409
- });
1410
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1411
- }
1412
- // Item previews use the GUI context, false conditions, and zero numeric properties.
1413
- static defaultItemModel(node, key) {
1414
- if (!node || typeof node.type !== "string") {
1415
- throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
1416
- }
1417
- switch (node.type.replace(/^minecraft:/, "")) {
1418
- case "model":
1419
- if (typeof node.model === "string" && node.model) return node.model;
1420
- break;
1421
- case "condition":
1422
- return this.defaultItemModel(node.on_false, key);
1423
- case "select": {
1424
- const selected = node.property?.replace(/^minecraft:/, "") === "display_context" ? node.cases?.find((entry) => Array.isArray(entry.when) ? entry.when.includes("gui") : entry.when === "gui")?.model : void 0;
1425
- return this.defaultItemModel(selected ?? node.fallback, key);
1426
- }
1427
- case "range_dispatch": {
1428
- const selected = node.entries?.reduce((match, entry) => {
1429
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
1430
- }, void 0);
1431
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
1432
- }
1433
- }
1434
- throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
1435
- }
1436
1360
  static async getRaw(key) {
1437
1361
  if (!key.assetType) {
1438
1362
  key.assetType = "models";
@@ -1471,15 +1395,19 @@ var Models = class _Models {
1471
1395
  return this.PERSISTENT_CACHE.clear();
1472
1396
  }
1473
1397
  };
1398
+ __decorateClass([
1399
+ (0, import_typescript_memoize.Memoize)()
1400
+ ], _Models, "getItemList", 1);
1401
+ var Models = _Models;
1474
1402
 
1475
1403
  // src/assets/BlockStates.ts
1404
+ var import_typescript_memoize2 = require("typescript-memoize");
1476
1405
  var BlockStates = class {
1477
1406
  static get PERSISTENT_CACHE() {
1478
1407
  return this._persistentCache ??= PersistentCache.open("minerender-blockstates");
1479
1408
  }
1480
- // BlockState names are hardcoded
1481
1409
  static async getList() {
1482
- const key = new AssetKey(
1410
+ return AssetLoader.get(new AssetKey(
1483
1411
  DEFAULT_NAMESPACE,
1484
1412
  "_list",
1485
1413
  "blockstates",
@@ -1487,16 +1415,11 @@ var BlockStates = class {
1487
1415
  "assets",
1488
1416
  ".json",
1489
1417
  DEFAULT_ROOT
1490
- );
1491
- return Caching.listAssetCache.get(key.serialize(), () => {
1492
- return AssetLoader.get(key, "list" /* LIST */);
1493
- }).then((r) => r?.files ?? []);
1418
+ ), "list" /* LIST */).then((r) => (r == null ? void 0 : r.files) ?? []);
1494
1419
  }
1495
1420
  static async getDefaultStates() {
1496
1421
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
1497
- return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
1498
- return AssetLoader.get(key, "json" /* JSON */);
1499
- });
1422
+ return AssetLoader.get(key, "json" /* JSON */);
1500
1423
  }
1501
1424
  static async getDefaultState(key) {
1502
1425
  const defaultStates = await this.getDefaultStates();
@@ -1535,11 +1458,17 @@ var BlockStates = class {
1535
1458
  await this.PERSISTENT_CACHE.clear();
1536
1459
  }
1537
1460
  };
1461
+ __decorateClass([
1462
+ (0, import_typescript_memoize2.Memoize)()
1463
+ ], BlockStates, "getList", 1);
1464
+ __decorateClass([
1465
+ (0, import_typescript_memoize2.Memoize)()
1466
+ ], BlockStates, "getDefaultStates", 1);
1538
1467
  var DefaultBlockStates = class {
1539
1468
  };
1540
1469
 
1541
1470
  // src/assets/Assets.ts
1542
- var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
1471
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
1543
1472
  var DEFAULT_NAMESPACE = "minecraft";
1544
1473
  var Assets = class {
1545
1474
  /**
@@ -1561,150 +1490,13 @@ var AssetSource = class {
1561
1490
  constructor() {
1562
1491
  }
1563
1492
  };
1564
- var AssetLoadError = class extends Error {
1565
- constructor(source, key, path, cause) {
1566
- super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
1567
- this.source = source;
1568
- this.key = key;
1569
- this.path = path;
1570
- this.cause = cause;
1571
- this.name = "AssetLoadError";
1572
- }
1573
- };
1574
1493
 
1575
- // src/util/BatchedExecutor.ts
1576
- var BatchedExecutor = class {
1577
- constructor(interval = 1, batch = 30) {
1578
- this.interval = interval;
1579
- this.batch = batch;
1580
- this.queue = [];
1581
- this.task = setInterval(() => this.run());
1582
- }
1583
- submit(task) {
1584
- this.queue.push(task);
1585
- }
1586
- run() {
1587
- for (let i = 0; i < this.batch; i++) {
1588
- this.runNext();
1589
- }
1590
- }
1591
- runNext() {
1592
- let next = this.queue.shift();
1593
- if (next) next();
1594
- }
1595
- };
1596
-
1597
- // src/util/model.ts
1598
- var import_three7 = require("three");
1599
- function applyElementRotation(rotation, geometry) {
1600
- const origin = new import_three7.Vector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1601
- geometry.translate(-origin.x, -origin.y, -origin.z);
1602
- switch (rotation.axis) {
1603
- case "x" /* X */:
1604
- geometry.rotateX(toRadians(rotation.angle));
1605
- break;
1606
- case "y" /* Y */:
1607
- geometry.rotateY(toRadians(rotation.angle));
1608
- break;
1609
- case "z" /* Z */:
1610
- geometry.rotateZ(toRadians(rotation.angle));
1611
- break;
1612
- }
1613
- if (rotation.rescale) {
1614
- if (Math.abs(rotation.angle) === 22.5) {
1615
- const s = 1 / Math.cos(0.39269909262657166);
1616
- geometry.scale(s, 1, s);
1617
- } else {
1618
- const s = 1 / Math.cos(0.7853981852531433);
1619
- geometry.scale(s, 1, s);
1620
- }
1621
- }
1622
- geometry.translate(origin.x, origin.y, origin.z);
1623
- }
1624
- function applyModelPartRotation(modelPart, geometry) {
1625
- const origin = new import_three7.Vector3(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1626
- geometry.translate(-origin.x, -origin.y, -origin.z);
1627
- geometry.rotateX(toRadians(modelPart.pitch));
1628
- geometry.rotateY(toRadians(modelPart.yaw));
1629
- geometry.rotateZ(toRadians(modelPart.roll));
1630
- geometry.translate(origin.x, origin.y, origin.z);
1631
- }
1632
- function applyGenericRotation(axis, rotation, obj) {
1633
- switch (axis) {
1634
- case "x" /* X */:
1635
- obj.rotateOnAxis(new import_three7.Vector3(1, 0, 0), toRadians(rotation));
1636
- break;
1637
- case "y" /* Y */:
1638
- obj.rotateOnAxis(new import_three7.Vector3(0, 1, 0), toRadians(rotation));
1639
- break;
1640
- case "z" /* Z */:
1641
- obj.rotateOnAxis(new import_three7.Vector3(0, 0, 1), toRadians(rotation));
1642
- break;
1643
- }
1644
- }
1645
- function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1646
- let size = new import_three7.Vector3();
1647
- box.getSize(size);
1648
- let boxGeo = new import_three7.BoxGeometry(size.x, size.y, size.z, 1, 1, 1);
1649
- let wireGeo = new import_three7.EdgesGeometry(boxGeo);
1650
- let wireMat = new import_three7.LineBasicMaterial({ color, linewidth: w });
1651
- let wireframe = new import_three7.LineSegments(wireGeo, wireMat);
1652
- obj.add(wireframe);
1653
- let axes = new import_three7.AxesHelper(1);
1654
- obj.add(axes);
1655
- }
1656
- function addWireframeToObject(obj, color = 16777215, w = 2) {
1657
- let boxGeo = new import_three7.BoxGeometry(16, 16, 16, 1, 1, 1);
1658
- let wireGeo = new import_three7.EdgesGeometry(boxGeo);
1659
- let wireMat = new import_three7.LineBasicMaterial({ color, linewidth: w });
1660
- let wireframe = new import_three7.LineSegments(wireGeo, wireMat);
1661
- obj.add(wireframe);
1662
- let axes = new import_three7.AxesHelper(1);
1663
- obj.add(axes);
1664
- }
1665
- function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1666
- let wireGeo = new import_three7.EdgesGeometry(geo);
1667
- let wireMat = new import_three7.LineBasicMaterial({ color, linewidth: w });
1668
- let wireframe = new import_three7.LineSegments(wireGeo, wireMat);
1669
- mesh.add(wireframe);
1670
- let axes = new import_three7.AxesHelper(1);
1671
- mesh.add(axes);
1672
- }
1673
-
1674
- // src/util/performance.ts
1675
- function captureException(e, ...extra) {
1676
- console.error(e, extra);
1677
- }
1678
- function timingStart(marker) {
1679
- console.time(marker);
1680
- }
1681
- function timingEnd(marker) {
1682
- console.timeEnd(marker);
1683
- }
1684
-
1685
- // src/util/three.ts
1686
- function isObject3D(obj) {
1687
- return obj.isObject3D;
1688
- }
1689
- function isMesh(obj) {
1690
- return obj.isMesh;
1691
- }
1692
- function isInstancedMesh(obj) {
1693
- return obj.isInstancedMesh;
1694
- }
1695
- function isPerspectiveCamera(obj) {
1696
- return obj.isPerspectiveCamera;
1697
- }
1698
- function isOrthographicCamera(obj) {
1699
- return obj.isOrthographicCamera;
1700
- }
1701
-
1702
- // src/nbt/NBTHelper.ts
1703
- var NBTHelper = class {
1704
- static async fromBuffer(buffer) {
1705
- const prismarineNbt = await import("prismarine-nbt");
1706
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1707
- return parsed;
1494
+ // src/nbt/NBTHelper.ts
1495
+ var NBTHelper = class {
1496
+ static async fromBuffer(buffer) {
1497
+ const prismarineNbt = await import("prismarine-nbt");
1498
+ const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1499
+ return parsed;
1708
1500
  }
1709
1501
  };
1710
1502
 
@@ -1714,83 +1506,7 @@ var p3 = prefix("HostedAssetSource");
1714
1506
  var DEFAULT_OPTIONS = {
1715
1507
  retryDefaults: true
1716
1508
  };
1717
- var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1718
- static {
1719
- this.MODEL = {
1720
- config(request) {
1721
- },
1722
- parse(response) {
1723
- return response.data;
1724
- }
1725
- };
1726
- }
1727
- static {
1728
- this.BLOCKSTATE = {
1729
- config(request) {
1730
- },
1731
- parse(response) {
1732
- return response.data;
1733
- }
1734
- };
1735
- }
1736
- static {
1737
- this.META = {
1738
- config(request) {
1739
- },
1740
- parse(response) {
1741
- return response.data;
1742
- }
1743
- };
1744
- }
1745
- static {
1746
- this.NBT = {
1747
- config(request) {
1748
- request.responseType = "arraybuffer";
1749
- },
1750
- parse(response) {
1751
- return NBTHelper.fromBuffer(Buffer.from(response.data));
1752
- }
1753
- };
1754
- }
1755
- static {
1756
- this.IMAGE = {
1757
- config(request) {
1758
- request.responseType = "arraybuffer";
1759
- },
1760
- async parse(response) {
1761
- return await ImageLoader.processResponse(response);
1762
- }
1763
- };
1764
- }
1765
- static {
1766
- this.LIST = {
1767
- config(request) {
1768
- },
1769
- parse(response) {
1770
- return response.data;
1771
- }
1772
- };
1773
- }
1774
- static {
1775
- this.JSON = {
1776
- config(request) {
1777
- },
1778
- parse(response) {
1779
- return response.data;
1780
- }
1781
- };
1782
- }
1783
- static {
1784
- this.PARSER_MAP = /* @__PURE__ */ new Map([
1785
- ["model" /* MODEL */, _HostedAssetSource.MODEL],
1786
- ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
1787
- ["meta" /* META */, _HostedAssetSource.META],
1788
- ["nbt" /* NBT */, _HostedAssetSource.NBT],
1789
- ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
1790
- ["list" /* LIST */, _HostedAssetSource.LIST],
1791
- ["json" /* JSON */, _HostedAssetSource.JSON]
1792
- ]);
1793
- }
1509
+ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1794
1510
  async loadOrRetryWithDefaults(key, parser) {
1795
1511
  const direct = await this.load(key, parser);
1796
1512
  if (typeof direct !== "undefined") {
@@ -1825,25 +1541,31 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1825
1541
  console.info(p3, "Loading", key);
1826
1542
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1827
1543
  console.debug(p3, url);
1828
- const request = { url };
1829
- try {
1830
- parser.config(request);
1831
- let response;
1832
- try {
1833
- response = await Requests.mcAssetRequest(request);
1834
- } catch (cause) {
1835
- if (cause instanceof RequestError && cause.response?.status === 404) {
1836
- return void 0;
1544
+ let req = {
1545
+ url
1546
+ };
1547
+ parser.config(req);
1548
+ return await Requests.mcAssetRequest(req).then((response) => {
1549
+ if (response && response.data) {
1550
+ try {
1551
+ return parser.parse(response);
1552
+ } catch (e) {
1553
+ console.warn("Parser failed to process response", response, e);
1554
+ throw e;
1837
1555
  }
1838
- throw cause;
1839
1556
  }
1840
- if (response.data === void 0) {
1841
- throw new Error("Asset response has no data");
1557
+ return void 0;
1558
+ }).catch((err) => {
1559
+ if (err.response) {
1560
+ let response = err.response;
1561
+ if (response.status === 404) {
1562
+ console.debug(p3, key, "not found");
1563
+ return void 0;
1564
+ }
1842
1565
  }
1843
- return await parser.parse(response);
1844
- } catch (cause) {
1845
- throw new AssetLoadError(this, key, request.url, cause);
1846
- }
1566
+ console.debug(p3, "Failed to load", key, err == null ? void 0 : err.message);
1567
+ return void 0;
1568
+ });
1847
1569
  }
1848
1570
  assetBasePath(key) {
1849
1571
  return `${key.root ?? this.root ?? AssetLoader.ROOT}/${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1867,6 +1589,67 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1867
1589
  return this.load(key, responseParser);
1868
1590
  }
1869
1591
  };
1592
+ _HostedAssetSource.MODEL = {
1593
+ config(request) {
1594
+ },
1595
+ parse(response) {
1596
+ return response.data;
1597
+ }
1598
+ };
1599
+ _HostedAssetSource.BLOCKSTATE = {
1600
+ config(request) {
1601
+ },
1602
+ parse(response) {
1603
+ return response.data;
1604
+ }
1605
+ };
1606
+ _HostedAssetSource.META = {
1607
+ config(request) {
1608
+ },
1609
+ parse(response) {
1610
+ return response.data;
1611
+ }
1612
+ };
1613
+ _HostedAssetSource.NBT = {
1614
+ config(request) {
1615
+ request.responseType = "arraybuffer";
1616
+ },
1617
+ parse(response) {
1618
+ return NBTHelper.fromBuffer(Buffer.from(response.data));
1619
+ }
1620
+ };
1621
+ _HostedAssetSource.IMAGE = {
1622
+ config(request) {
1623
+ request.responseType = "arraybuffer";
1624
+ },
1625
+ async parse(response) {
1626
+ return await ImageLoader.processResponse(response);
1627
+ }
1628
+ };
1629
+ _HostedAssetSource.LIST = {
1630
+ config(request) {
1631
+ },
1632
+ parse(response) {
1633
+ return response.data;
1634
+ }
1635
+ };
1636
+ _HostedAssetSource.JSON = {
1637
+ config(request) {
1638
+ },
1639
+ parse(response) {
1640
+ return response.data;
1641
+ }
1642
+ };
1643
+ _HostedAssetSource.PARSER_MAP = /* @__PURE__ */ new Map([
1644
+ ["model" /* MODEL */, _HostedAssetSource.MODEL],
1645
+ ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
1646
+ ["meta" /* META */, _HostedAssetSource.META],
1647
+ ["nbt" /* NBT */, _HostedAssetSource.NBT],
1648
+ ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
1649
+ ["list" /* LIST */, _HostedAssetSource.LIST],
1650
+ ["json" /* JSON */, _HostedAssetSource.JSON]
1651
+ ]);
1652
+ var HostedAssetSource = _HostedAssetSource;
1870
1653
 
1871
1654
  // src/assets/source/archive/BrowserArchiveProxy.ts
1872
1655
  var import_zip = require("@zip.js/zip.js");
@@ -1889,6 +1672,7 @@ var BrowserArchiveProxy = class {
1889
1672
  };
1890
1673
 
1891
1674
  // src/assets/source/archive/ArchiveAssetSource.ts
1675
+ var p4 = prefix("ArchiveAssetSource");
1892
1676
  var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1893
1677
  constructor(archiveProxy) {
1894
1678
  super();
@@ -1907,31 +1691,74 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1907
1691
  }
1908
1692
  async get(key, parser) {
1909
1693
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
1910
- return this.load(key, responseParser);
1911
- }
1912
- async load(key, parser) {
1694
+ console.log("ArchiveAssetSource.get", key, parser);
1695
+ let entries = await this.getEntries();
1913
1696
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1914
- let url;
1915
- try {
1916
- const entry = await this.getEntry(path);
1917
- if (!entry) {
1918
- return void 0;
1697
+ console.log(path);
1698
+ const entry = await this.getEntry(path);
1699
+ console.log(entry);
1700
+ if (!entry) {
1701
+ return void 0;
1702
+ }
1703
+ let blob = await entry.getData();
1704
+ const url = URL.createObjectURL(blob);
1705
+ console.log(url);
1706
+ let req = {
1707
+ url
1708
+ };
1709
+ responseParser.config(req);
1710
+ return Requests.genericRequest(req).then((response) => {
1711
+ if (response && response.data) {
1712
+ try {
1713
+ return responseParser.parse(response);
1714
+ } catch (e) {
1715
+ console.warn("Parser failed to process response", response, e);
1716
+ throw e;
1717
+ }
1919
1718
  }
1920
- url = URL.createObjectURL(await entry.getData());
1921
- const request = { url };
1922
- parser.config(request);
1923
- const response = await Requests.genericRequest(request);
1924
- if (response.data === void 0) {
1925
- throw new Error("Asset response has no data");
1719
+ return void 0;
1720
+ }).catch((err) => {
1721
+ if (err.response) {
1722
+ let response = err.response;
1723
+ if (response.status === 404) {
1724
+ console.debug(p4, key, "not found");
1725
+ return void 0;
1726
+ }
1926
1727
  }
1927
- return await parser.parse(response);
1928
- } catch (cause) {
1929
- throw new AssetLoadError(this, key, path, cause);
1930
- } finally {
1931
- if (url !== void 0) {
1932
- URL.revokeObjectURL(url);
1728
+ console.debug(p4, "Failed to load", key, err == null ? void 0 : err.message);
1729
+ return void 0;
1730
+ });
1731
+ }
1732
+ //TODO: abstract this
1733
+ async load(key, parser) {
1734
+ console.info(p4, "Loading", key);
1735
+ const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1736
+ console.debug(p4, url);
1737
+ let req = {
1738
+ url
1739
+ };
1740
+ parser.config(req);
1741
+ return await Requests.genericRequest(req).then((response) => {
1742
+ if (response && response.data) {
1743
+ try {
1744
+ return parser.parse(response);
1745
+ } catch (e) {
1746
+ console.warn("Parser failed to process response", response, e);
1747
+ throw e;
1748
+ }
1933
1749
  }
1934
- }
1750
+ return void 0;
1751
+ }).catch((err) => {
1752
+ if (err.response) {
1753
+ let response = err.response;
1754
+ if (response.status === 404) {
1755
+ console.debug(p4, key, "not found");
1756
+ return void 0;
1757
+ }
1758
+ }
1759
+ console.debug(p4, "Failed to load", key, err == null ? void 0 : err.message);
1760
+ return void 0;
1761
+ });
1935
1762
  }
1936
1763
  assetBasePath(key) {
1937
1764
  return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1939,23 +1766,18 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1939
1766
  };
1940
1767
 
1941
1768
  // src/assets/AssetLoader.ts
1942
- var p4 = prefix("AssetLoader");
1943
- var AssetLoader = class {
1944
- static {
1945
- this.ROOT = DEFAULT_ROOT;
1946
- }
1947
- static {
1948
- this._SOURCES = [];
1949
- }
1769
+ var import_ts_deepmerge3 = __toESM(require_dist());
1770
+ var p5 = prefix("AssetLoader");
1771
+ var _AssetLoader = class _AssetLoader {
1950
1772
  static addSource(key, source, override = true) {
1951
1773
  if (override) {
1952
1774
  const existing = this.removeSource(key);
1953
1775
  if (existing) {
1954
- console.log(p4, "Removed existing AssetSource", key);
1776
+ console.log(p5, "Removed existing AssetSource", key);
1955
1777
  }
1956
1778
  }
1957
1779
  this._SOURCES.unshift({ key, source });
1958
- console.log(p4, "Added AssetSource", key);
1780
+ console.log(p5, "Added AssetSource", key);
1959
1781
  }
1960
1782
  static removeSource(key) {
1961
1783
  const index = this._SOURCES.findIndex((s) => s.key === key);
@@ -1967,11 +1789,8 @@ var AssetLoader = class {
1967
1789
  }
1968
1790
  return void 0;
1969
1791
  }
1970
- static {
1971
- this.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1972
- this.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1973
- }
1974
1792
  static async getAll(key, parser) {
1793
+ console.log(this._SOURCES);
1975
1794
  let promises = [];
1976
1795
  for (const source of this._SOURCES) {
1977
1796
  promises.push(source.source.get(key, parser));
@@ -1980,36 +1799,31 @@ var AssetLoader = class {
1980
1799
  return results.filter((r) => r != void 0);
1981
1800
  });
1982
1801
  }
1983
- /** Returns the first defined result in source-priority order, without merging assets. */
1984
1802
  static async get(key, parser) {
1985
- const keys = [key];
1986
- if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
1987
- keys.push(new AssetKey(
1988
- key.namespace,
1989
- key.path,
1990
- key.assetType === "structure" ? "structures" : "structure",
1991
- key.type,
1992
- key.rootType,
1993
- key.extension,
1994
- key.root
1995
- ));
1996
- }
1997
- return (await this.getFirst(keys, parser))?.asset;
1998
- }
1999
- /** Tries each path within a source before considering lower-priority sources. */
2000
- static async getFirst(keys, parser) {
2001
- const sources = [...this._SOURCES];
2002
- for (const source of sources) {
2003
- for (const key of keys) {
2004
- const result = await source.source.get(key, parser);
2005
- if (result !== void 0) {
2006
- return { key, asset: result };
1803
+ console.log(this._SOURCES);
1804
+ let promises = [];
1805
+ for (const source of this._SOURCES) {
1806
+ promises.push(source.source.get(key, parser));
1807
+ }
1808
+ return Promise.all(promises).then((results) => {
1809
+ const fallback = results[results.length - 1];
1810
+ for (const result of results) {
1811
+ if (result) {
1812
+ if (fallback) {
1813
+ return (0, import_ts_deepmerge3.default)({}, fallback, result);
1814
+ }
1815
+ return result;
2007
1816
  }
2008
1817
  }
2009
- }
2010
- return void 0;
1818
+ return void 0;
1819
+ });
2011
1820
  }
2012
1821
  };
1822
+ _AssetLoader.ROOT = DEFAULT_ROOT;
1823
+ _AssetLoader._SOURCES = [];
1824
+ _AssetLoader.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1825
+ _AssetLoader.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1826
+ var AssetLoader = _AssetLoader;
2013
1827
 
2014
1828
  // src/assets/ModelTextures.ts
2015
1829
  var ModelTextures = class {
@@ -2017,21 +1831,11 @@ var ModelTextures = class {
2017
1831
  return this._persistentMetaCache ??= PersistentCache.open("minerender-texturemeta");
2018
1832
  }
2019
1833
  static async get(key) {
2020
- const keyStr = key.serialize();
2021
- const pending = this.preload(key);
2022
- const cached = Caching.textureAssetCache.getIfPresent(keyStr);
2023
- try {
2024
- const asset = await pending;
2025
- if (asset) {
2026
- return await ImageLoader.infoToCanvasData(asset);
2027
- }
2028
- return void 0;
2029
- } catch (err) {
2030
- if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
2031
- Caching.textureAssetCache.invalidate(keyStr);
2032
- }
2033
- throw err;
1834
+ const asset = await this.preload(key);
1835
+ if (asset) {
1836
+ return ImageLoader.infoToCanvasData(asset);
2034
1837
  }
1838
+ return void 0;
2035
1839
  }
2036
1840
  static async preload(key) {
2037
1841
  const keyStr = key.serialize();
@@ -2105,28 +1909,7 @@ var CanvasImage = class {
2105
1909
  };
2106
1910
 
2107
1911
  // src/Ticker.ts
2108
- var Ticker = class _Ticker {
2109
- static {
2110
- this.TPS = 20;
2111
- }
2112
- static {
2113
- this.counter = 0;
2114
- }
2115
- static {
2116
- this._tickers = /* @__PURE__ */ new Map();
2117
- }
2118
- static {
2119
- this.oneSecondTps = 0;
2120
- }
2121
- static {
2122
- this.oneSecondTicks = 0;
2123
- }
2124
- static {
2125
- this.fiveSecondTps = 0;
2126
- }
2127
- static {
2128
- this.fiveSecondTicks = 0;
2129
- }
1912
+ var _Ticker = class _Ticker {
2130
1913
  static schedule(fn, ms) {
2131
1914
  const handle = setInterval(fn, ms);
2132
1915
  const unref = handle.unref;
@@ -2188,6 +1971,14 @@ var Ticker = class _Ticker {
2188
1971
  this._tickers.clear();
2189
1972
  }
2190
1973
  };
1974
+ _Ticker.TPS = 20;
1975
+ _Ticker.counter = 0;
1976
+ _Ticker._tickers = /* @__PURE__ */ new Map();
1977
+ _Ticker.oneSecondTps = 0;
1978
+ _Ticker.oneSecondTicks = 0;
1979
+ _Ticker.fiveSecondTps = 0;
1980
+ _Ticker.fiveSecondTicks = 0;
1981
+ var Ticker = _Ticker;
2191
1982
 
2192
1983
  // src/texture/TextureAtlas.ts
2193
1984
  var TextureAtlas = class {
@@ -2213,9 +2004,6 @@ var TextureAtlas = class {
2213
2004
 
2214
2005
  // src/model/ModelGenerator.ts
2215
2006
  var ModelGenerator = class {
2216
- static {
2217
- this.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2218
- }
2219
2007
  static generateItemModel(imageData, layer) {
2220
2008
  const mainElement = {
2221
2009
  from: [0, 0, 7.5],
@@ -2235,9 +2023,10 @@ var ModelGenerator = class {
2235
2023
  return [mainElement];
2236
2024
  }
2237
2025
  };
2026
+ ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2238
2027
 
2239
2028
  // src/UVMapper.ts
2240
- var p5 = prefix("UVMapper");
2029
+ var p6 = prefix("UVMapper");
2241
2030
  var DEFAULT_UV = [0, 0, 16, 16];
2242
2031
  var X = 0;
2243
2032
  var Y = 1;
@@ -2410,11 +2199,12 @@ var UVMapper = class {
2410
2199
  return [tl, tr, bl, br];
2411
2200
  }
2412
2201
  static async createAtlas(originalModel) {
2202
+ var _a;
2413
2203
  const textureMap = {};
2414
2204
  const metaMap = {};
2415
2205
  const model = { ...originalModel };
2416
2206
  const isItemModel = !("elements" in model);
2417
- console.debug(p5, "Creating Atlas for", model.key);
2207
+ console.debug(p6, "Creating Atlas for", model.key);
2418
2208
  if (model.textures) {
2419
2209
  const promises = [];
2420
2210
  const uniqueTextureNames = [];
@@ -2428,7 +2218,7 @@ var UVMapper = class {
2428
2218
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
2429
2219
  promises.push(ModelTextures.get(assetKey).then((asset) => {
2430
2220
  if (!asset) {
2431
- console.warn(p5, "Missing texture", assetKey);
2221
+ console.warn(p6, "Missing texture", assetKey);
2432
2222
  return;
2433
2223
  }
2434
2224
  textureMap[textureKey] = new WrappedImage(asset);
@@ -2440,7 +2230,7 @@ var UVMapper = class {
2440
2230
  }
2441
2231
  await Promise.all(promises);
2442
2232
  const textureCount = uniqueTextureNames.length;
2443
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
2233
+ console.debug(p6, "Creating Atlas for", textureCount, "textures");
2444
2234
  this.fillMissingTextureKeys(model.textures, textureMap);
2445
2235
  this.fillMissingTextureKeys(model.textures, metaMap);
2446
2236
  const sizes = {};
@@ -2460,7 +2250,7 @@ var UVMapper = class {
2460
2250
  this.fillMissingTextureKeys(model.textures, sizes);
2461
2251
  const s = Math.ceil(Math.sqrt(textureCount + 1));
2462
2252
  const size = Math.ceil(s * maxWidth);
2463
- console.debug(p5, "Atlas size:", size);
2253
+ console.debug(p6, "Atlas size:", size);
2464
2254
  const squaredSize = size * size;
2465
2255
  const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
2466
2256
  const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
@@ -2489,15 +2279,16 @@ var UVMapper = class {
2489
2279
  if (texture.animated) {
2490
2280
  hasAnimation = true;
2491
2281
  const meta = metaMap[textureKey];
2492
- const frameTime = meta?.animation?.frametime ?? 1;
2282
+ const frameTime = ((_a = meta == null ? void 0 : meta.animation) == null ? void 0 : _a.frametime) ?? 1;
2493
2283
  console.log(meta);
2494
2284
  console.log(frameTime);
2495
2285
  let t = 0;
2496
2286
  let f = 0;
2497
2287
  animatorFunctions[textureKey] = () => {
2288
+ var _a2;
2498
2289
  if (t++ >= frameTime) {
2499
2290
  t = 0;
2500
- const frames = meta?.animation?.frames;
2291
+ const frames = (_a2 = meta == null ? void 0 : meta.animation) == null ? void 0 : _a2.frames;
2501
2292
  const frame = frames ? frames[f] : f;
2502
2293
  image.putData(texture.getFrameSectionData(frame), x, y, 0, 0, maxWidth, maxWidth);
2503
2294
  f++;
@@ -2515,10 +2306,10 @@ var UVMapper = class {
2515
2306
  }
2516
2307
  }
2517
2308
  const atlasImageData = image.toDataURL();
2518
- console.log(p5, "Atlas Image for", model.key, atlasImageData);
2309
+ console.log(p6, "Atlas Image for", model.key, atlasImageData);
2519
2310
  this.fillMissingTextureKeys(model.textures, positions);
2520
2311
  if (isItemModel) {
2521
- console.debug(p5, "Generating item model for", model);
2312
+ console.debug(p6, "Generating item model for", model);
2522
2313
  model.elements = [];
2523
2314
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2524
2315
  const textureImage = textureMap[layerName];
@@ -2526,7 +2317,7 @@ var UVMapper = class {
2526
2317
  model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2527
2318
  }
2528
2319
  }
2529
- console.debug(p5, "Item model elements", model.elements);
2320
+ console.debug(p6, "Item model elements", model.elements);
2530
2321
  }
2531
2322
  if (!model.elements) {
2532
2323
  }
@@ -2544,13 +2335,17 @@ var UVMapper = class {
2544
2335
  this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
2545
2336
  continue;
2546
2337
  }
2547
- if (!face.texture) continue;
2548
2338
  if (!face.uv) {
2549
2339
  face.uv = this.getFallbackUv(element, faceName);
2550
2340
  }
2551
- const faceTexture = face.texture.substr(1);
2552
- const texPosition = positions[faceTexture] || [0, 0];
2553
- const texSize = sizes[faceTexture] || [16, 16];
2341
+ let faceTexture = face.texture;
2342
+ let texPosition;
2343
+ let texSize;
2344
+ if (faceTexture) {
2345
+ faceTexture = faceTexture.substr(1);
2346
+ texPosition = positions[faceTexture] || [0, 0];
2347
+ texSize = sizes[faceTexture] || [16, 16];
2348
+ }
2554
2349
  let texPosV = new import_three8.Vector2(texPosition[0], texPosition[1]);
2555
2350
  const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
2556
2351
  tl.add(texPosV);
@@ -2582,7 +2377,7 @@ var UVMapper = class {
2582
2377
  hasTransparency
2583
2378
  );
2584
2379
  } else {
2585
- console.warn(p5, "Model does not have any textures", model);
2380
+ console.warn(p6, "Model does not have any textures", model);
2586
2381
  }
2587
2382
  return void 0;
2588
2383
  }
@@ -2720,20 +2515,17 @@ function shutdown() {
2720
2515
  }
2721
2516
 
2722
2517
  // src/assets/Entities.ts
2518
+ var import_typescript_memoize3 = require("typescript-memoize");
2723
2519
  var Entities = class {
2724
2520
  static async getBlockEntityModels() {
2725
2521
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
2726
2522
  console.log(key);
2727
- return Caching.entityModelsCache.get(key.serialize(), () => {
2728
- return AssetLoader.get(key, "json" /* JSON */);
2729
- });
2523
+ return AssetLoader.get(key, "json" /* JSON */);
2730
2524
  }
2731
2525
  static async getEntityModels() {
2732
2526
  const key = AssetKey.parse("models", "minerender:entityModels");
2733
2527
  console.log(key);
2734
- return Caching.entityModelsCache.get(key.serialize(), () => {
2735
- return AssetLoader.get(key, "json" /* JSON */);
2736
- });
2528
+ return AssetLoader.get(key, "json" /* JSON */);
2737
2529
  }
2738
2530
  // BlockEntity names are hardcoded
2739
2531
  static async getBlockList() {
@@ -2779,6 +2571,12 @@ var Entities = class {
2779
2571
  };
2780
2572
  }
2781
2573
  };
2574
+ __decorateClass([
2575
+ (0, import_typescript_memoize3.Memoize)()
2576
+ ], Entities, "getBlockEntityModels", 1);
2577
+ __decorateClass([
2578
+ (0, import_typescript_memoize3.Memoize)()
2579
+ ], Entities, "getEntityModels", 1);
2782
2580
  var EntityModels = class {
2783
2581
  };
2784
2582
  var BlockEntityModels = class {
@@ -2842,26 +2640,18 @@ var MineRenderError = class _MineRenderError extends Error {
2842
2640
  };
2843
2641
 
2844
2642
  // src/renderer/SceneObject.ts
2845
- var import_ts_deepmerge3 = __toESM(require_dist());
2846
- var p6 = prefix("SceneObject");
2847
- var SceneObject = class _SceneObject extends import_three9.Object3D {
2643
+ var import_ts_deepmerge4 = __toESM(require_dist());
2644
+ var p7 = prefix("SceneObject");
2645
+ var _SceneObject = class _SceneObject extends import_three9.Object3D {
2848
2646
  constructor(options) {
2849
2647
  super();
2850
2648
  this.isSceneObject = true;
2851
2649
  this.materialCallbacks = {};
2852
2650
  this._isInstanced = false;
2853
2651
  this._instanceCounter = 0;
2854
- this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2652
+ this.options = (0, import_ts_deepmerge4.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2855
2653
  console.log("SceneObject options", this.options);
2856
2654
  }
2857
- static {
2858
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
2859
- instanceMeshes: true,
2860
- maxInstanceCount: 50,
2861
- mergeMeshes: true,
2862
- wireframe: false
2863
- });
2864
- }
2865
2655
  set scene(scene) {
2866
2656
  if (!!this._scene) throw new MineRenderError("Scene already set");
2867
2657
  this._scene = scene;
@@ -3030,9 +2820,9 @@ var SceneObject = class _SceneObject extends import_three9.Object3D {
3030
2820
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3031
2821
  const i = this._instanceCounter++;
3032
2822
  this.setMatrixAt(i, new import_three9.Matrix4());
3033
- console.debug(p6, "nextInstance " + i);
2823
+ console.debug(p7, "nextInstance " + i);
3034
2824
  if (i === this.options.maxInstanceCount) {
3035
- console.warn(p6, "Max instance count reached for " + this);
2825
+ console.warn(p7, "Max instance count reached for " + this);
3036
2826
  }
3037
2827
  if (this.scene) {
3038
2828
  this.scene.stats.instanceCount++;
@@ -3203,29 +2993,34 @@ var SceneObject = class _SceneObject extends import_three9.Object3D {
3203
2993
  this.notifyDirty();
3204
2994
  }
3205
2995
  removeFromScene() {
3206
- this._scene?.remove(this);
2996
+ var _a;
2997
+ (_a = this._scene) == null ? void 0 : _a.remove(this);
3207
2998
  this.notifyDirty();
3208
2999
  }
3209
3000
  //</editor-fold>
3210
3001
  };
3002
+ _SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, {
3003
+ instanceMeshes: true,
3004
+ maxInstanceCount: 50,
3005
+ mergeMeshes: true,
3006
+ wireframe: false
3007
+ });
3008
+ var SceneObject = _SceneObject;
3211
3009
  function isSceneObject(obj) {
3212
3010
  return obj.isSceneObject;
3213
3011
  }
3214
3012
 
3215
3013
  // src/entity/scene/EntityObject.ts
3216
- var import_ts_deepmerge4 = __toESM(require_dist());
3014
+ var import_ts_deepmerge5 = __toESM(require_dist());
3217
3015
  var import_three11 = require("three");
3218
- var THREE3 = __toESM(require("three"));
3016
+ var THREE2 = __toESM(require("three"));
3219
3017
  var EntityObject = class extends SceneObject {
3220
3018
  constructor(entity, options) {
3221
3019
  super();
3222
3020
  this.entity = entity;
3223
3021
  this.isEntityObject = true;
3224
3022
  this.meshesCreated = false;
3225
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3226
- }
3227
- static {
3228
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3023
+ this.options = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3229
3024
  }
3230
3025
  async init() {
3231
3026
  this.createMeshes();
@@ -3234,19 +3029,17 @@ var EntityObject = class extends SceneObject {
3234
3029
  dispose() {
3235
3030
  super.dispose();
3236
3031
  }
3237
- get textureKey() {
3238
- return new AssetKey(
3239
- this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
3032
+ async loadTextures() {
3033
+ var _a;
3034
+ this.imageData = await ModelTextures.get(new AssetKey(
3035
+ ((_a = this.entity.key) == null ? void 0 : _a.namespace) ?? DEFAULT_NAMESPACE,
3240
3036
  this.entity.key.path,
3241
3037
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
3242
3038
  "textures",
3243
3039
  "entity",
3244
3040
  "assets",
3245
3041
  ".png"
3246
- );
3247
- }
3248
- async loadTextures() {
3249
- this.imageData = await ModelTextures.get(this.textureKey);
3042
+ ));
3250
3043
  }
3251
3044
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3252
3045
  createMeshes(force = false) {
@@ -3265,8 +3058,8 @@ var EntityObject = class extends SceneObject {
3265
3058
  const l = cube.maxZ - cube.minZ;
3266
3059
  const uv = texture.toUvArray(w, h, l);
3267
3060
  const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3268
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3269
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
3061
+ cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3062
+ cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
3270
3063
  applyModelPartRotation(part, cubeGeo);
3271
3064
  const mesh = this.createMesh(partName, cubeGeo, mat);
3272
3065
  partAnchor.add(mesh);
@@ -3279,25 +3072,24 @@ var EntityObject = class extends SceneObject {
3279
3072
  this.meshesCreated = true;
3280
3073
  }
3281
3074
  async applyTextures() {
3282
- const assetKeyStr = this.textureKey.serialize();
3283
- const keyStr = `entity:${assetKeyStr}`;
3284
- let mat = Caching.materialCache.getIfPresent(keyStr);
3285
- if (!mat) {
3286
- const pending = this.loadTextures();
3287
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3288
- await pending;
3289
- if (!this.imageData) return;
3290
- const canvas = this.imageData.data.canvas;
3291
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3292
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3293
- this.imageData = void 0;
3294
- }
3295
- this.iterateAllMeshes((mesh) => {
3296
- mesh.material = mat;
3297
- });
3298
- this.notifyDirty();
3075
+ var _a;
3076
+ const textureAsset = await ModelTextures.preload(new AssetKey(
3077
+ ((_a = this.entity.key) == null ? void 0 : _a.namespace) ?? DEFAULT_NAMESPACE,
3078
+ this.entity.key.path,
3079
+ "textures",
3080
+ "entity",
3081
+ "assets",
3082
+ ".png"
3083
+ ));
3084
+ if (textureAsset) {
3085
+ let mat = Materials.getImage({ texture: { src: textureAsset.src } });
3086
+ this.iterateAllMeshes((mesh) => {
3087
+ mesh.material = mat;
3088
+ });
3089
+ }
3299
3090
  }
3300
3091
  };
3092
+ EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3301
3093
  function isEntityObject(obj) {
3302
3094
  return obj.isEntityObject;
3303
3095
  }
@@ -3309,7 +3101,7 @@ var GuiObject = class extends SceneObject {
3309
3101
 
3310
3102
  // src/inspector/SceneInspector.ts
3311
3103
  var import_three12 = require("three");
3312
- var p7 = prefix("SceneInspector");
3104
+ var p8 = prefix("SceneInspector");
3313
3105
  var help = "<span>Ctrl+Click to Select<br/></span><br/>";
3314
3106
  var SceneInspector = class {
3315
3107
  constructor(renderer) {
@@ -3338,7 +3130,8 @@ var SceneInspector = class {
3338
3130
  return out;
3339
3131
  }
3340
3132
  onClick(event) {
3341
- if (event.target?.nodeName !== "CANVAS") return;
3133
+ var _a;
3134
+ if (((_a = event.target) == null ? void 0 : _a.nodeName) !== "CANVAS") return;
3342
3135
  if (!event.ctrlKey) return;
3343
3136
  setTimeout(() => {
3344
3137
  this.mouse.x = event.clientX / window.innerWidth * 2 - 1;
@@ -3378,7 +3171,7 @@ var SceneInspector = class {
3378
3171
  }
3379
3172
  selectObject(targetObject, targetIntersection) {
3380
3173
  this.selectedObject = targetObject;
3381
- console.log(p7, "selected", targetObject);
3174
+ console.log(p8, "selected", targetObject);
3382
3175
  this.redraw(targetObject, targetIntersection);
3383
3176
  }
3384
3177
  redraw(targetObject, targetIntersection) {
@@ -3676,7 +3469,7 @@ var SceneStatsDisplay = class {
3676
3469
  };
3677
3470
 
3678
3471
  // src/instance/InstanceManager.ts
3679
- var p8 = prefix("InstanceManager");
3472
+ var p9 = prefix("InstanceManager");
3680
3473
  var InstanceManager = class {
3681
3474
  constructor() {
3682
3475
  this.isInstanceManager = true;
@@ -3684,7 +3477,7 @@ var InstanceManager = class {
3684
3477
  }
3685
3478
  async get(key) {
3686
3479
  if (key in this.instanceCache) {
3687
- console.debug(p8, "key in cache", key);
3480
+ console.debug(p9, "key in cache", key);
3688
3481
  return (await this.instanceCache[key]).nextInstance();
3689
3482
  }
3690
3483
  return void 0;
@@ -3693,17 +3486,13 @@ var InstanceManager = class {
3693
3486
  if (key in this.instanceCache) {
3694
3487
  return await this.get(key);
3695
3488
  }
3696
- console.debug(p8, "key not in cache", key);
3697
- const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
3698
- this.instanceCache[key] = pending;
3699
- try {
3700
- return await pending;
3701
- } catch (error) {
3702
- if (this.instanceCache[key] === pending) {
3703
- delete this.instanceCache[key];
3704
- }
3705
- throw error;
3706
- }
3489
+ console.debug(p9, "key not in cache", key);
3490
+ this.instanceCache[key] = new Promise(async (resolve) => {
3491
+ const obj = await supplier();
3492
+ const instance = obj.nextInstance();
3493
+ resolve(instance);
3494
+ });
3495
+ return await this.instanceCache[key];
3707
3496
  }
3708
3497
  reset() {
3709
3498
  for (let instanceCacheKey in this.instanceCache) {
@@ -4292,28 +4081,26 @@ function computeMorphedAttributes(object) {
4292
4081
  }
4293
4082
 
4294
4083
  // src/model/scene/ModelObject.ts
4295
- var import_ts_deepmerge5 = __toESM(require_dist());
4296
- var p9 = prefix("ModelObject");
4297
- var ModelObject = class _ModelObject extends SceneObject {
4084
+ var import_ts_deepmerge6 = __toESM(require_dist());
4085
+ var p10 = prefix("ModelObject");
4086
+ var _ModelObject = class _ModelObject extends SceneObject {
4298
4087
  constructor(originalModel, options) {
4299
4088
  super(options);
4300
4089
  this.originalModel = originalModel;
4301
4090
  this.isModelObject = true;
4302
4091
  this.meshesCreated = false;
4303
- this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4092
+ this.options = (0, import_ts_deepmerge6.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4304
4093
  console.log("ModelObject options", this.options);
4305
4094
  }
4306
- static {
4307
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4308
- }
4309
4095
  async init() {
4310
4096
  await this.loadTextures();
4311
4097
  this.createMeshes();
4312
4098
  this.applyTextures();
4313
4099
  }
4314
4100
  dispose() {
4101
+ var _a;
4315
4102
  super.dispose();
4316
- this.atlas?.dispose();
4103
+ (_a = this.atlas) == null ? void 0 : _a.dispose();
4317
4104
  }
4318
4105
  get textureAtlas() {
4319
4106
  return this.atlas;
@@ -4323,12 +4110,13 @@ var ModelObject = class _ModelObject extends SceneObject {
4323
4110
  this.atlas = await UVMapper.getAtlas(this.originalModel);
4324
4111
  }
4325
4112
  createMeshes(force = false) {
4113
+ var _a;
4326
4114
  if (this.meshesCreated && !force) return;
4327
4115
  const mat = Materials.MISSING_TEXTURE;
4328
4116
  let allGeos = [];
4329
4117
  if (this.atlas) {
4330
4118
  if (this.atlas.model.elements) {
4331
- this.atlas.model.elements?.forEach((el) => {
4119
+ (_a = this.atlas.model.elements) == null ? void 0 : _a.forEach((el) => {
4332
4120
  const elGeo = this._getBoxGeometryFromElement(el).clone();
4333
4121
  elGeo.applyMatrix4(new import_three15.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4334
4122
  elGeo.applyMatrix4(new import_three15.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
@@ -4346,10 +4134,10 @@ var ModelObject = class _ModelObject extends SceneObject {
4346
4134
  }
4347
4135
  });
4348
4136
  } else {
4349
- console.debug(p9, this.atlas.model, "has no elements");
4137
+ console.debug(p10, this.atlas.model, "has no elements");
4350
4138
  }
4351
4139
  } else {
4352
- console.debug(p9, "Missing atlas for", this);
4140
+ console.debug(p10, "Missing atlas for", this);
4353
4141
  }
4354
4142
  if (this.options.mergeMeshes) {
4355
4143
  let combinedGeo;
@@ -4401,25 +4189,17 @@ var ModelObject = class _ModelObject extends SceneObject {
4401
4189
  }
4402
4190
  }
4403
4191
  };
4192
+ _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4193
+ var ModelObject = _ModelObject;
4404
4194
  function isModelObject(obj) {
4405
4195
  return obj.isModelObject;
4406
4196
  }
4407
4197
 
4408
4198
  // src/model/block/scene/BlockObject.ts
4409
- var import_ts_deepmerge6 = __toESM(require_dist());
4199
+ var import_ts_deepmerge7 = __toESM(require_dist());
4410
4200
  var import_three16 = require("three");
4411
- var p10 = prefix("BlockObject");
4412
- function matchesCondition(condition, state) {
4413
- return Object.entries(condition).every(([key, value]) => {
4414
- if (Array.isArray(value)) {
4415
- if (key === "OR") return value.some((child) => matchesCondition(child, state));
4416
- if (key === "AND") return value.every((child) => matchesCondition(child, state));
4417
- return false;
4418
- }
4419
- return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4420
- });
4421
- }
4422
- var BlockObject = class _BlockObject extends SceneObject {
4201
+ var p11 = prefix("BlockObject");
4202
+ var _BlockObject = class _BlockObject extends SceneObject {
4423
4203
  constructor(blockState, options) {
4424
4204
  super(options);
4425
4205
  this.blockState = blockState;
@@ -4432,16 +4212,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4432
4212
  this._instanceModel = [];
4433
4213
  this._variants = [];
4434
4214
  this._models = [];
4435
- this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4436
- }
4437
- static {
4438
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
4439
- applyDefaultState: true
4440
- });
4215
+ this.options = (0, import_ts_deepmerge7.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4441
4216
  }
4442
4217
  async init() {
4443
4218
  if (this.options.applyDefaultState) {
4444
- const defaultState = this.blockState.key ? await BlockStates.getDefaultState(this.blockState.key) : void 0;
4219
+ const defaultState = this.blockState.key ? BlockStates.getDefaultState(this.blockState.key) : void 0;
4445
4220
  if (defaultState && Object.keys(defaultState).length > 0) {
4446
4221
  const state = {};
4447
4222
  for (let k in defaultState) {
@@ -4452,11 +4227,17 @@ var BlockObject = class _BlockObject extends SceneObject {
4452
4227
  if (this.blockState.variants) {
4453
4228
  await this.setState(Object.keys(this.blockState.variants)[0]);
4454
4229
  } else if (this.blockState.multipart) {
4455
- const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4456
- const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4457
- await this.setState(state);
4458
- }
4459
- }
4230
+ for (let part of this.blockState.multipart) {
4231
+ if (part.when && !("OR" in part.when)) {
4232
+ const k = Object.keys(part.when)[0];
4233
+ if (k) {
4234
+ await this.setState(k, part.when[k].split("|")[0]);
4235
+ break;
4236
+ }
4237
+ }
4238
+ }
4239
+ }
4240
+ }
4460
4241
  } else {
4461
4242
  await this.recreateModels();
4462
4243
  }
@@ -4511,11 +4292,55 @@ var BlockObject = class _BlockObject extends SceneObject {
4511
4292
  } else if (this.blockState.multipart) {
4512
4293
  for (let part of this.blockState.multipart) {
4513
4294
  if (!part.apply) {
4514
- console.debug(p10, "Missing apply for blockState part", part);
4295
+ console.debug(p11, "Missing apply for blockState part", part);
4515
4296
  continue;
4516
4297
  }
4517
- if (!part.when || matchesCondition(part.when, state)) {
4298
+ if (!part.when) {
4518
4299
  out.push(this.getSingleVariant(part.apply));
4300
+ } else {
4301
+ let matches = true;
4302
+ if ("OR" in part.when) {
4303
+ const or = part.when.OR;
4304
+ let anyMatch = false;
4305
+ for (let o of or) {
4306
+ for (let k in o) {
4307
+ const split = o[k].split("|");
4308
+ let m = false;
4309
+ for (let s of split) {
4310
+ if (`${state[k]}` === `${s}`) {
4311
+ m = true;
4312
+ break;
4313
+ }
4314
+ }
4315
+ if (m) {
4316
+ anyMatch = true;
4317
+ break;
4318
+ }
4319
+ }
4320
+ }
4321
+ if (!anyMatch) {
4322
+ matches = false;
4323
+ }
4324
+ } else {
4325
+ for (let k in part.when) {
4326
+ const split = part.when[k].split("|");
4327
+ let m = false;
4328
+ for (let s of split) {
4329
+ if (`${state[k]}` === `${s}`) {
4330
+ m = true;
4331
+ break;
4332
+ }
4333
+ }
4334
+ if (!m) {
4335
+ matches = false;
4336
+ break;
4337
+ }
4338
+ }
4339
+ }
4340
+ if (matches) {
4341
+ const variants = part.apply;
4342
+ out.push(this.getSingleVariant(variants));
4343
+ }
4519
4344
  }
4520
4345
  }
4521
4346
  }
@@ -4545,21 +4370,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4545
4370
  }
4546
4371
  }
4547
4372
  getSingleVariant(variants) {
4548
- if (!Array.isArray(variants)) return variants;
4549
- if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4550
- const total = variants.reduce((sum, variant) => {
4551
- const weight = variant.weight ?? 1;
4552
- if (!Number.isInteger(weight) || weight < 1) {
4553
- throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4554
- }
4555
- return sum + weight;
4556
- }, 0);
4557
- let choice = Math.random() * total;
4558
- for (const variant of variants) {
4559
- choice -= variant.weight ?? 1;
4560
- if (choice < 0) return variant;
4561
- }
4562
- return variants[variants.length - 1];
4373
+ if (Array.isArray(variants)) {
4374
+ return variants[0];
4375
+ } else {
4376
+ return variants;
4377
+ }
4563
4378
  }
4564
4379
  // @deprecated
4565
4380
  async createAVariant(variants, instanceInfo) {
@@ -4585,6 +4400,9 @@ var BlockObject = class _BlockObject extends SceneObject {
4585
4400
  }
4586
4401
  }
4587
4402
  obj.setRotation(rotation);
4403
+ setTimeout(() => {
4404
+ obj.setRotation(rotation);
4405
+ }, 150);
4588
4406
  console.log(obj);
4589
4407
  return obj;
4590
4408
  }
@@ -4675,15 +4493,18 @@ var BlockObject = class _BlockObject extends SceneObject {
4675
4493
  }
4676
4494
  }
4677
4495
  setPosition(position) {
4678
- this.position.copy(position);
4496
+ super.setPosition(position);
4679
4497
  for (let model of this._models) {
4680
4498
  model.setPosition(position);
4681
4499
  }
4682
- this.notifyDirty();
4683
4500
  }
4684
4501
  //TODO: should override rotation + scale methods
4685
4502
  //TODO
4686
4503
  };
4504
+ _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge7.default)({}, ModelObject.DEFAULT_OPTIONS, {
4505
+ applyDefaultState: true
4506
+ });
4507
+ var BlockObject = _BlockObject;
4687
4508
  function isBlockObject(obj) {
4688
4509
  return obj.isBlockObject;
4689
4510
  }
@@ -4708,10 +4529,11 @@ var StructureParser = class {
4708
4529
  throw new MineRenderError("Structure does not have palette(s)");
4709
4530
  }
4710
4531
  const blocks = nbt.blocks.value.value.map((block) => {
4532
+ var _a;
4711
4533
  const state = palette.value.value[block.state.value];
4712
4534
  if (state.Name.value === "minecraft:air") return void 0;
4713
4535
  const props = {};
4714
- for (let k in state.Properties?.value) {
4536
+ for (let k in (_a = state.Properties) == null ? void 0 : _a.value) {
4715
4537
  props[k] = state.Properties.value[k].value;
4716
4538
  }
4717
4539
  return {
@@ -4730,7 +4552,7 @@ var StructureParser = class {
4730
4552
 
4731
4553
  // src/renderer/MineRenderScene.ts
4732
4554
  var import_three17 = require("three");
4733
- var import_ts_deepmerge8 = __toESM(require_dist());
4555
+ var import_ts_deepmerge9 = __toESM(require_dist());
4734
4556
 
4735
4557
  // src/skin/SkinPart.ts
4736
4558
  var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
@@ -5461,7 +5283,7 @@ var slimSkinGeometries = {
5461
5283
  };
5462
5284
 
5463
5285
  // src/skin/scene/SkinObject.ts
5464
- var import_ts_deepmerge7 = __toESM(require_dist());
5286
+ var import_ts_deepmerge8 = __toESM(require_dist());
5465
5287
  var SkinObject = class extends SceneObject {
5466
5288
  constructor(options) {
5467
5289
  super();
@@ -5469,7 +5291,7 @@ var SkinObject = class extends SceneObject {
5469
5291
  this.legacy = false;
5470
5292
  this.skinTextureWidth = 64;
5471
5293
  this.skinTextureHeight = 64;
5472
- this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5294
+ this.options = (0, import_ts_deepmerge8.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5473
5295
  }
5474
5296
  async init() {
5475
5297
  this.createMeshes();
@@ -5573,7 +5395,7 @@ var SkinObject = class extends SceneObject {
5573
5395
  };
5574
5396
 
5575
5397
  // src/renderer/MineRenderScene.ts
5576
- var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5398
+ var _MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5577
5399
  constructor(options) {
5578
5400
  super();
5579
5401
  this.isMineRenderScene = true;
@@ -5582,14 +5404,12 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5582
5404
  this.dirty = true;
5583
5405
  this.observedObjects = /* @__PURE__ */ new Set();
5584
5406
  this.onObjectChange = (event) => {
5585
- if (event.target?.parent === this) {
5407
+ var _a;
5408
+ if (((_a = event.target) == null ? void 0 : _a.parent) === this) {
5586
5409
  this.dirty = true;
5587
5410
  }
5588
5411
  };
5589
- this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5590
- }
5591
- static {
5592
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
5412
+ this.options = (0, import_ts_deepmerge9.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5593
5413
  }
5594
5414
  add(...objects) {
5595
5415
  for (const object of objects) {
@@ -5597,7 +5417,7 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5597
5417
  try {
5598
5418
  super.add(object);
5599
5419
  } finally {
5600
- if (object?.isObject3D && object !== this) {
5420
+ if ((object == null ? void 0 : object.isObject3D) && object !== this) {
5601
5421
  this.updateObjectRegistration(object, object.parent === this);
5602
5422
  }
5603
5423
  }
@@ -5640,12 +5460,13 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5640
5460
  return this.add(...object);
5641
5461
  }
5642
5462
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
5463
+ var _a, _b;
5643
5464
  console.log("addSceneObject", asset);
5644
5465
  console.log("parent", parent);
5645
5466
  console.log(_options);
5646
5467
  this.dirty = true;
5647
5468
  const obj = await objectSupplier();
5648
- if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
5469
+ if (((_a = obj == null ? void 0 : obj.options) == null ? void 0 : _a.instanceMeshes) && asset.key && ((_b = asset.key) == null ? void 0 : _b.assetType) === "models") {
5649
5470
  console.log("instanceMeshes + key");
5650
5471
  const key = asset.key.serialize();
5651
5472
  return this.instanceManager.getOrCreate(key, async () => {
@@ -5685,1139 +5506,1109 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5685
5506
  return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
5686
5507
  }
5687
5508
  };
5509
+ _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {});
5510
+ var MineRenderScene = _MineRenderScene;
5688
5511
  function isMineRenderScene(obj) {
5689
5512
  return obj.isMineRenderScene;
5690
5513
  }
5691
5514
 
5692
5515
  // src/renderer/Renderer.ts
5693
- var import_three19 = require("three");
5694
- var import_ts_deepmerge9 = __toESM(require_dist());
5516
+ var import_three18 = require("three");
5517
+ var import_ts_deepmerge10 = __toESM(require_dist());
5695
5518
  var import_stats = __toESM(require("stats.js"));
5696
5519
  var import_postprocessing = require("postprocessing");
5697
-
5698
- // src/three/OrbitControls.js
5699
- var import_three18 = require("three");
5700
- var _changeEvent = { type: "change" };
5701
- var _startEvent = { type: "start" };
5702
- var _endEvent = { type: "end" };
5703
- var OrbitControls = class extends import_three18.EventDispatcher {
5704
- constructor(object, domElement) {
5705
- super();
5706
- if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5707
- if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5708
- this.object = object;
5709
- this.domElement = domElement;
5710
- this.domElement.style.touchAction = "none";
5711
- this.enabled = true;
5712
- this.target = new import_three18.Vector3();
5713
- this.minDistance = 0;
5714
- this.maxDistance = Infinity;
5715
- this.minZoom = 0;
5716
- this.maxZoom = Infinity;
5717
- this.minPolarAngle = 0;
5718
- this.maxPolarAngle = Math.PI;
5719
- this.minAzimuthAngle = -Infinity;
5720
- this.maxAzimuthAngle = Infinity;
5721
- this.enableDamping = false;
5722
- this.dampingFactor = 0.05;
5723
- this.enableZoom = true;
5724
- this.zoomSpeed = 1;
5725
- this.enableRotate = true;
5726
- this.rotateSpeed = 1;
5727
- this.enablePan = true;
5728
- this.panSpeed = 1;
5729
- this.screenSpacePanning = true;
5730
- this.keyPanSpeed = 7;
5731
- this.autoRotate = false;
5732
- this.autoRotateSpeed = 2;
5733
- this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5734
- this.mouseButtons = { LEFT: import_three18.MOUSE.ROTATE, MIDDLE: import_three18.MOUSE.DOLLY, RIGHT: import_three18.MOUSE.PAN };
5735
- this.touches = { ONE: import_three18.TOUCH.ROTATE, TWO: import_three18.TOUCH.DOLLY_PAN };
5736
- this.target0 = this.target.clone();
5737
- this.position0 = this.object.position.clone();
5738
- this.zoom0 = this.object.zoom;
5739
- this._domElementKeyEvents = null;
5740
- this.getPolarAngle = function() {
5741
- return spherical.phi;
5742
- };
5743
- this.getAzimuthalAngle = function() {
5744
- return spherical.theta;
5745
- };
5746
- this.getDistance = function() {
5747
- return this.object.position.distanceTo(this.target);
5748
- };
5749
- this.saveState = function() {
5750
- scope.target0.copy(scope.target);
5751
- scope.position0.copy(scope.object.position);
5752
- scope.zoom0 = scope.object.zoom;
5753
- };
5754
- this.reset = function() {
5755
- scope.target.copy(scope.target0);
5756
- scope.object.position.copy(scope.position0);
5757
- scope.object.zoom = scope.zoom0;
5758
- scope.object.updateProjectionMatrix();
5759
- scope.dispatchEvent(_changeEvent);
5760
- scope.update();
5761
- state = STATE.NONE;
5762
- };
5763
- this.update = function() {
5764
- const offset = new import_three18.Vector3();
5765
- const quat = new import_three18.Quaternion().setFromUnitVectors(object.up, new import_three18.Vector3(0, 1, 0));
5766
- const quatInverse = quat.clone().invert();
5767
- const lastPosition = new import_three18.Vector3();
5768
- const lastQuaternion = new import_three18.Quaternion();
5769
- const twoPI = 2 * Math.PI;
5770
- return function update() {
5771
- const position = scope.object.position;
5772
- offset.copy(position).sub(scope.target);
5773
- offset.applyQuaternion(quat);
5774
- spherical.setFromVector3(offset);
5775
- if (scope.autoRotate && state === STATE.NONE) {
5776
- rotateLeft(getAutoRotationAngle());
5777
- }
5778
- if (scope.enableDamping) {
5779
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5780
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5781
- } else {
5782
- spherical.theta += sphericalDelta.theta;
5783
- spherical.phi += sphericalDelta.phi;
5784
- }
5785
- let min = scope.minAzimuthAngle;
5786
- let max = scope.maxAzimuthAngle;
5787
- if (isFinite(min) && isFinite(max)) {
5788
- if (min < -Math.PI) min += twoPI;
5789
- else if (min > Math.PI) min -= twoPI;
5790
- if (max < -Math.PI) max += twoPI;
5791
- else if (max > Math.PI) max -= twoPI;
5792
- if (min <= max) {
5793
- spherical.theta = Math.max(min, Math.min(max, spherical.theta));
5794
- } else {
5795
- spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
5796
- }
5797
- }
5798
- spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5799
- spherical.makeSafe();
5800
- spherical.radius *= scale;
5801
- spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5802
- if (scope.enableDamping === true) {
5803
- scope.target.addScaledVector(panOffset, scope.dampingFactor);
5804
- } else {
5805
- scope.target.add(panOffset);
5806
- }
5807
- offset.setFromSpherical(spherical);
5808
- offset.applyQuaternion(quatInverse);
5809
- position.copy(scope.target).add(offset);
5810
- scope.object.lookAt(scope.target);
5811
- if (scope.enableDamping === true) {
5812
- sphericalDelta.theta *= 1 - scope.dampingFactor;
5813
- sphericalDelta.phi *= 1 - scope.dampingFactor;
5814
- panOffset.multiplyScalar(1 - scope.dampingFactor);
5815
- } else {
5816
- sphericalDelta.set(0, 0, 0);
5817
- panOffset.set(0, 0, 0);
5818
- }
5819
- scale = 1;
5820
- if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5821
- scope.dispatchEvent(_changeEvent);
5822
- lastPosition.copy(scope.object.position);
5823
- lastQuaternion.copy(scope.object.quaternion);
5824
- zoomChanged = false;
5825
- return true;
5826
- }
5827
- return false;
5828
- };
5829
- }();
5830
- this.dispose = function() {
5831
- scope.domElement.removeEventListener("contextmenu", onContextMenu);
5832
- scope.domElement.removeEventListener("pointerdown", onPointerDown);
5833
- scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5834
- scope.domElement.removeEventListener("wheel", onMouseWheel);
5835
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5836
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5837
- if (scope._domElementKeyEvents !== null) {
5838
- scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
5839
- }
5840
- };
5841
- const scope = this;
5842
- const STATE = {
5843
- NONE: -1,
5844
- ROTATE: 0,
5845
- DOLLY: 1,
5846
- PAN: 2,
5847
- TOUCH_ROTATE: 3,
5848
- TOUCH_PAN: 4,
5849
- TOUCH_DOLLY_PAN: 5,
5850
- TOUCH_DOLLY_ROTATE: 6
5520
+ var _Renderer = class _Renderer {
5521
+ constructor(options) {
5522
+ this._dirty = true;
5523
+ this._animationTimer = void 0;
5524
+ this._animationFrame = void 0;
5525
+ this._resizeListener = void 0;
5526
+ this._disposed = false;
5527
+ this._debugHelpers = [];
5528
+ this._eventDispatchers = /* @__PURE__ */ new Map();
5529
+ this._changeListener = () => {
5530
+ this._dirty = true;
5851
5531
  };
5852
- let state = STATE.NONE;
5853
- const EPS = 1e-6;
5854
- const spherical = new import_three18.Spherical();
5855
- const sphericalDelta = new import_three18.Spherical();
5856
- let scale = 1;
5857
- const panOffset = new import_three18.Vector3();
5858
- let zoomChanged = false;
5859
- const rotateStart = new import_three18.Vector2();
5860
- const rotateEnd = new import_three18.Vector2();
5861
- const rotateDelta = new import_three18.Vector2();
5862
- const panStart = new import_three18.Vector2();
5863
- const panEnd = new import_three18.Vector2();
5864
- const panDelta = new import_three18.Vector2();
5865
- const dollyStart = new import_three18.Vector2();
5866
- const dollyEnd = new import_three18.Vector2();
5867
- const dollyDelta = new import_three18.Vector2();
5868
- const pointers = [];
5869
- const pointerPositions = {};
5870
- function getAutoRotationAngle() {
5871
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
5532
+ this.options = (0, import_ts_deepmerge10.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
5533
+ this._animationLoop = this.animate.bind(this);
5534
+ this._fpsTimer = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
5535
+ this._scene = this.createScene();
5536
+ this._camera = this.createCamera();
5537
+ this._renderer = this.createRenderer();
5538
+ this._composer = this.createComposer();
5539
+ if (this.options.render.stats) {
5540
+ this._stats = new import_stats.default();
5541
+ document.body.appendChild(this._stats.dom);
5872
5542
  }
5873
- function getZoomScale() {
5874
- return Math.pow(0.95, scope.zoomSpeed);
5543
+ this.init();
5544
+ }
5545
+ //<editor-fold desc="INIT">
5546
+ createScene() {
5547
+ return new MineRenderScene();
5548
+ }
5549
+ createCamera() {
5550
+ switch (this.options.camera.type) {
5551
+ case "perspective":
5552
+ default:
5553
+ return new import_three18.PerspectiveCamera(
5554
+ this.options.camera.perspective.fov,
5555
+ this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
5556
+ this.options.camera.near,
5557
+ this.options.camera.far
5558
+ );
5559
+ case "orthographic":
5560
+ return new import_three18.OrthographicCamera(
5561
+ this.options.camera.orthographic.left ?? this.viewWidth / -2,
5562
+ this.options.camera.orthographic.right ?? this.viewWidth / 2,
5563
+ this.options.camera.orthographic.top ?? this.viewHeight / 2,
5564
+ this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
5565
+ this.options.camera.near,
5566
+ this.options.camera.far
5567
+ );
5875
5568
  }
5876
- function rotateLeft(angle) {
5877
- sphericalDelta.theta -= angle;
5569
+ }
5570
+ createRenderer() {
5571
+ const renderer = new import_three18.WebGLRenderer({
5572
+ antialias: this.options.render.antialias,
5573
+ alpha: true,
5574
+ powerPreference: "high-performance",
5575
+ depth: true
5576
+ });
5577
+ renderer.setClearColor(0, 0);
5578
+ renderer.shadowMap.enabled = true;
5579
+ renderer.shadowMap.type = import_three18.PCFSoftShadowMap;
5580
+ renderer.outputEncoding = import_three18.LinearEncoding;
5581
+ renderer.setSize(this.viewWidth, this.viewHeight);
5582
+ return renderer;
5583
+ }
5584
+ createComposer() {
5585
+ const composer = new import_postprocessing.EffectComposer(this.renderer);
5586
+ if (!this.options.composer.enabled) return composer;
5587
+ composer.setSize(this.viewWidth, this.viewHeight);
5588
+ composer.addPass(new import_postprocessing.RenderPass(this.scene, this.camera));
5589
+ return composer;
5590
+ }
5591
+ //</editor-fold>
5592
+ init() {
5593
+ if (this._disposed) return;
5594
+ if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
5595
+ window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
5878
5596
  }
5879
- function rotateUp(angle) {
5880
- sphericalDelta.phi -= angle;
5597
+ if (this.options.debug.grid) {
5598
+ const gridHelper = new import_three18.GridHelper(128, 16);
5599
+ this._debugHelpers.push(gridHelper);
5600
+ this.scene.add(gridHelper);
5601
+ const gridHelper2 = new import_three18.GridHelper(128, 16);
5602
+ this._debugHelpers.push(gridHelper2);
5603
+ gridHelper2.rotation.x = 90 * (Math.PI / 180);
5604
+ this.scene.add(gridHelper2);
5605
+ const gridHelper3 = new import_three18.GridHelper(128, 16);
5606
+ this._debugHelpers.push(gridHelper3);
5607
+ gridHelper3.rotation.z = 90 * (Math.PI / 180);
5608
+ this.scene.add(gridHelper3);
5881
5609
  }
5882
- const panLeft = function() {
5883
- const v = new import_three18.Vector3();
5884
- return function panLeft2(distance, objectMatrix) {
5885
- v.setFromMatrixColumn(objectMatrix, 0);
5886
- v.multiplyScalar(-distance);
5887
- panOffset.add(v);
5888
- };
5889
- }();
5890
- const panUp = function() {
5891
- const v = new import_three18.Vector3();
5892
- return function panUp2(distance, objectMatrix) {
5893
- if (scope.screenSpacePanning === true) {
5894
- v.setFromMatrixColumn(objectMatrix, 1);
5895
- } else {
5896
- v.setFromMatrixColumn(objectMatrix, 0);
5897
- v.crossVectors(scope.object.up, v);
5898
- }
5899
- v.multiplyScalar(distance);
5900
- panOffset.add(v);
5901
- };
5902
- }();
5903
- const pan = function() {
5904
- const offset = new import_three18.Vector3();
5905
- return function pan2(deltaX, deltaY) {
5906
- const element = scope.domElement;
5907
- if (scope.object.isPerspectiveCamera) {
5908
- const position = scope.object.position;
5909
- offset.copy(position).sub(scope.target);
5910
- let targetDistance = offset.length();
5911
- targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
5912
- panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
5913
- panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
5914
- } else if (scope.object.isOrthographicCamera) {
5915
- panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
5916
- panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
5917
- } else {
5918
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
5919
- scope.enablePan = false;
5920
- }
5921
- };
5922
- }();
5923
- function dollyOut(dollyScale) {
5924
- if (scope.object.isPerspectiveCamera) {
5925
- scale /= dollyScale;
5926
- } else if (scope.object.isOrthographicCamera) {
5927
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
5928
- scope.object.updateProjectionMatrix();
5929
- zoomChanged = true;
5930
- } else {
5931
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5932
- scope.enableZoom = false;
5933
- }
5610
+ if (this.options.debug.axes) {
5611
+ const axesHelper = new import_three18.AxesHelper(64);
5612
+ this._debugHelpers.push(axesHelper);
5613
+ this.scene.add(axesHelper);
5934
5614
  }
5935
- function dollyIn(dollyScale) {
5936
- if (scope.object.isPerspectiveCamera) {
5937
- scale *= dollyScale;
5938
- } else if (scope.object.isOrthographicCamera) {
5939
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
5940
- scope.object.updateProjectionMatrix();
5941
- zoomChanged = true;
5942
- } else {
5943
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5944
- scope.enableZoom = false;
5615
+ if (this.options.camera.position) {
5616
+ if (isVector3(this.options.camera.position)) {
5617
+ this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
5618
+ } else if (isTripleArray(this.options.camera.position)) {
5619
+ this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
5945
5620
  }
5946
5621
  }
5947
- function handleMouseDownRotate(event) {
5948
- rotateStart.set(event.clientX, event.clientY);
5622
+ if (this.options.camera.lookingAt) {
5623
+ if (isVector3(this.options.camera.lookingAt)) {
5624
+ this.camera.lookAt(this.options.camera.lookingAt);
5625
+ } else if (isTripleArray(this.options.camera.lookingAt)) {
5626
+ this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
5627
+ }
5949
5628
  }
5950
- function handleMouseDownDolly(event) {
5951
- dollyStart.set(event.clientX, event.clientY);
5629
+ if (this.options.render.autoResize && !this._resizeListener) {
5630
+ this._resizeListener = () => {
5631
+ this.resize(this.viewWidth, this.viewHeight);
5632
+ };
5633
+ window.addEventListener("resize", this._resizeListener);
5952
5634
  }
5953
- function handleMouseDownPan(event) {
5954
- panStart.set(event.clientX, event.clientY);
5635
+ }
5636
+ get element() {
5637
+ return this._element;
5638
+ }
5639
+ appendTo(element) {
5640
+ if (this._disposed) return;
5641
+ this._element = element;
5642
+ this._element.appendChild(this.renderer.domElement);
5643
+ if (this.viewWidth == 0) {
5644
+ console.warn("0 element width");
5955
5645
  }
5956
- function handleMouseMoveRotate(event) {
5957
- rotateEnd.set(event.clientX, event.clientY);
5958
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5959
- const element = scope.domElement;
5960
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5961
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5962
- rotateStart.copy(rotateEnd);
5963
- scope.update();
5646
+ if (this.viewHeight == 0) {
5647
+ console.warn("0 element height");
5964
5648
  }
5965
- function handleMouseMoveDolly(event) {
5966
- dollyEnd.set(event.clientX, event.clientY);
5967
- dollyDelta.subVectors(dollyEnd, dollyStart);
5968
- if (dollyDelta.y > 0) {
5969
- dollyOut(getZoomScale());
5970
- } else if (dollyDelta.y < 0) {
5971
- dollyIn(getZoomScale());
5972
- }
5973
- dollyStart.copy(dollyEnd);
5974
- scope.update();
5649
+ this.resize(this.viewWidth, this.viewHeight);
5650
+ }
5651
+ /**
5652
+ * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
5653
+ * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
5654
+ */
5655
+ registerEventDispatcher(dispatcher, changeEvent2 = "change") {
5656
+ if (this._disposed) return;
5657
+ let events = this._eventDispatchers.get(dispatcher);
5658
+ if (!events) {
5659
+ events = /* @__PURE__ */ new Set();
5660
+ this._eventDispatchers.set(dispatcher, events);
5975
5661
  }
5976
- function handleMouseMovePan(event) {
5977
- panEnd.set(event.clientX, event.clientY);
5978
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5979
- pan(panDelta.x, panDelta.y);
5980
- panStart.copy(panEnd);
5981
- scope.update();
5662
+ if (events.has(changeEvent2)) return;
5663
+ events.add(changeEvent2);
5664
+ dispatcher.addEventListener(changeEvent2, this._changeListener);
5665
+ }
5666
+ resize(width, height) {
5667
+ if (this._disposed) return;
5668
+ if (isPerspectiveCamera(this.camera)) {
5669
+ this.camera.aspect = width / height;
5670
+ this.camera.updateProjectionMatrix();
5671
+ } else if (isOrthographicCamera(this.camera)) {
5672
+ this.camera.left = width / -2;
5673
+ this.camera.right = width / 2;
5674
+ this.camera.top = height / 2;
5675
+ this.camera.bottom = height / -2;
5676
+ this.camera.updateProjectionMatrix();
5982
5677
  }
5983
- function handleMouseUp() {
5678
+ this.renderer.setSize(width, height);
5679
+ this.composer.setSize(width, height);
5680
+ this._dirty = true;
5681
+ }
5682
+ //<editor-fold desc="RENDER">
5683
+ get dirty() {
5684
+ return this._dirty || this.scene.dirty;
5685
+ }
5686
+ set dirty(dirty) {
5687
+ this._dirty = dirty;
5688
+ this.scene.dirty = dirty;
5689
+ }
5690
+ start() {
5691
+ if (this._disposed) return;
5692
+ this.stop();
5693
+ this.renderer.setAnimationLoop(this._animationLoop);
5694
+ }
5695
+ stop() {
5696
+ if (this._disposed) return;
5697
+ this.renderer.setAnimationLoop(null);
5698
+ if (this._animationTimer)
5699
+ clearTimeout(this._animationTimer);
5700
+ this._animationTimer = void 0;
5701
+ if (this._animationFrame)
5702
+ cancelAnimationFrame(this._animationFrame);
5703
+ this._animationFrame = void 0;
5704
+ }
5705
+ /**
5706
+ * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
5707
+ * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
5708
+ * controls must be managed by their owners.
5709
+ */
5710
+ dispose() {
5711
+ var _a;
5712
+ if (this._disposed) return;
5713
+ this.stop();
5714
+ this._disposed = true;
5715
+ if (this._resizeListener) {
5716
+ window.removeEventListener("resize", this._resizeListener);
5717
+ this._resizeListener = void 0;
5984
5718
  }
5985
- function handleMouseWheel(event) {
5986
- if (event.deltaY < 0) {
5987
- dollyIn(getZoomScale());
5988
- } else if (event.deltaY > 0) {
5989
- dollyOut(getZoomScale());
5719
+ for (const [dispatcher, events] of this._eventDispatchers) {
5720
+ for (const event of events) {
5721
+ dispatcher.removeEventListener(event, this._changeListener);
5990
5722
  }
5991
- scope.update();
5992
5723
  }
5993
- function handleKeyDown(event) {
5994
- let needsUpdate = false;
5995
- switch (event.code) {
5996
- case scope.keys.UP:
5997
- pan(0, scope.keyPanSpeed);
5998
- needsUpdate = true;
5999
- break;
6000
- case scope.keys.BOTTOM:
6001
- pan(0, -scope.keyPanSpeed);
6002
- needsUpdate = true;
6003
- break;
6004
- case scope.keys.LEFT:
6005
- pan(scope.keyPanSpeed, 0);
6006
- needsUpdate = true;
6007
- break;
6008
- case scope.keys.RIGHT:
6009
- pan(-scope.keyPanSpeed, 0);
6010
- needsUpdate = true;
6011
- break;
6012
- }
6013
- if (needsUpdate) {
6014
- event.preventDefault();
6015
- scope.update();
5724
+ this._eventDispatchers.clear();
5725
+ (_a = this._stats) == null ? void 0 : _a.dom.remove();
5726
+ this._stats = void 0;
5727
+ this.renderer.domElement.remove();
5728
+ this._element = void 0;
5729
+ this.scene.clear();
5730
+ for (const helper of this._debugHelpers) {
5731
+ helper.geometry.dispose();
5732
+ const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
5733
+ for (const material of materials) {
5734
+ material.dispose();
6016
5735
  }
6017
5736
  }
6018
- function handleTouchStartRotate() {
6019
- if (pointers.length === 1) {
6020
- rotateStart.set(pointers[0].pageX, pointers[0].pageY);
6021
- } else {
6022
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6023
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6024
- rotateStart.set(x, y);
6025
- }
5737
+ this._debugHelpers.length = 0;
5738
+ this.composer.dispose();
5739
+ this.renderer.dispose();
5740
+ this.renderer.forceContextLoss();
5741
+ }
5742
+ animate(t) {
5743
+ if (this._disposed) return;
5744
+ if (this._stats) {
5745
+ this._stats.begin();
6026
5746
  }
6027
- function handleTouchStartPan() {
6028
- if (pointers.length === 1) {
6029
- panStart.set(pointers[0].pageX, pointers[0].pageY);
5747
+ if (this.dirty || this.options.render.renderAlways) {
5748
+ if (this.options.composer.enabled) {
5749
+ this.composer.render();
6030
5750
  } else {
6031
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6032
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6033
- panStart.set(x, y);
5751
+ this.renderer.render(this.scene, this.camera);
6034
5752
  }
6035
5753
  }
6036
- function handleTouchStartDolly() {
6037
- const dx = pointers[0].pageX - pointers[1].pageX;
6038
- const dy = pointers[0].pageY - pointers[1].pageY;
6039
- const distance = Math.sqrt(dx * dx + dy * dy);
6040
- dollyStart.set(0, distance);
6041
- }
6042
- function handleTouchStartDollyPan() {
6043
- if (scope.enableZoom) handleTouchStartDolly();
6044
- if (scope.enablePan) handleTouchStartPan();
5754
+ this.dirty = false;
5755
+ if (this._stats) {
5756
+ this._stats.end();
6045
5757
  }
6046
- function handleTouchStartDollyRotate() {
6047
- if (scope.enableZoom) handleTouchStartDolly();
6048
- if (scope.enableRotate) handleTouchStartRotate();
5758
+ }
5759
+ //</editor-fold>
5760
+ toImage() {
5761
+ return this.renderer.domElement.toDataURL();
5762
+ }
5763
+ ///
5764
+ get attachedToBody() {
5765
+ return this.element === document.body;
5766
+ }
5767
+ get viewWidth() {
5768
+ var _a;
5769
+ return this.attachedToBody ? window.innerWidth : ((_a = this.element) == null ? void 0 : _a.offsetWidth) || 0;
5770
+ }
5771
+ get viewHeight() {
5772
+ var _a;
5773
+ return this.attachedToBody ? window.innerHeight : ((_a = this.element) == null ? void 0 : _a.offsetHeight) || 0;
5774
+ }
5775
+ get scene() {
5776
+ return this._scene;
5777
+ }
5778
+ get camera() {
5779
+ return this._camera;
5780
+ }
5781
+ get renderer() {
5782
+ return this._renderer;
5783
+ }
5784
+ get composer() {
5785
+ return this._composer;
5786
+ }
5787
+ ///
5788
+ };
5789
+ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge10.default)({}, {
5790
+ camera: {
5791
+ type: "perspective",
5792
+ near: 1,
5793
+ far: 5e3,
5794
+ perspective: {
5795
+ aspect: void 0,
5796
+ fov: 50
5797
+ },
5798
+ orthographic: {
5799
+ left: void 0,
5800
+ right: void 0,
5801
+ top: void 0,
5802
+ bottom: void 0
5803
+ },
5804
+ position: new import_three18.Vector3(50, 50, 50),
5805
+ lookingAt: new import_three18.Vector3(0, 0, 0)
5806
+ },
5807
+ render: {
5808
+ fpsLimit: 60,
5809
+ stats: false,
5810
+ antialias: true,
5811
+ shade: true,
5812
+ autoResize: true,
5813
+ renderAlways: false
5814
+ },
5815
+ composer: {
5816
+ enabled: true
5817
+ },
5818
+ debug: {
5819
+ grid: false,
5820
+ axes: false
5821
+ }
5822
+ });
5823
+ var Renderer = _Renderer;
5824
+
5825
+ // src/skin/Skins.ts
5826
+ var Skins = class {
5827
+ //<editor-fold desc="Skins">
5828
+ static async fromUuidOrUsername(uuidOrUsername) {
5829
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5830
+ return this.fromUuid(uuidOrUsername);
6049
5831
  }
6050
- function handleTouchMoveRotate(event) {
6051
- if (pointers.length == 1) {
6052
- rotateEnd.set(event.pageX, event.pageY);
6053
- } else {
6054
- const position = getSecondPointerPosition(event);
6055
- const x = 0.5 * (event.pageX + position.x);
6056
- const y = 0.5 * (event.pageY + position.y);
6057
- rotateEnd.set(x, y);
5832
+ return this.fromUsername(uuidOrUsername);
5833
+ }
5834
+ static async fromUuid(uuid) {
5835
+ return this.getSkinProxySkinUrl(uuid);
5836
+ }
5837
+ static async fromUsername(username) {
5838
+ return this.usernameToUuid(username).then((uuid) => {
5839
+ if (uuid) {
5840
+ return this.fromUuid(uuid);
6058
5841
  }
6059
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6060
- const element = scope.domElement;
6061
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6062
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6063
- rotateStart.copy(rotateEnd);
5842
+ return void 0;
5843
+ });
5844
+ }
5845
+ static async fromMineSkin(mineskinId) {
5846
+ return this.getMineSkin(mineskinId).then((mineskin) => {
5847
+ if (mineskin) {
5848
+ return mineskin["data"]["texture"]["value"]["urls"]["skins"];
5849
+ }
5850
+ return void 0;
5851
+ });
5852
+ }
5853
+ //</editor-fold>
5854
+ //<editor-fold desc="Capes">
5855
+ static async capeFromUuidOrUsername(uuidOrUsername) {
5856
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5857
+ return this.capeFromUuid(uuidOrUsername);
6064
5858
  }
6065
- function handleTouchMovePan(event) {
6066
- if (pointers.length === 1) {
6067
- panEnd.set(event.pageX, event.pageY);
6068
- } else {
6069
- const position = getSecondPointerPosition(event);
6070
- const x = 0.5 * (event.pageX + position.x);
6071
- const y = 0.5 * (event.pageY + position.y);
6072
- panEnd.set(x, y);
5859
+ return this.capeFromUsername(uuidOrUsername);
5860
+ }
5861
+ static async capeFromUuid(uuid) {
5862
+ return this.getSkinProxyCapeUrl(uuid);
5863
+ }
5864
+ static async capeFromUsername(username) {
5865
+ return this.usernameToUuid(username).then((uuid) => {
5866
+ if (uuid) {
5867
+ return this.capeFromUuid(uuid);
5868
+ }
5869
+ return void 0;
5870
+ });
5871
+ }
5872
+ static async capeFromCapesDev(uuid, capeType = "minecraft") {
5873
+ return this.getCapesDev(uuid, capeType).then((cape) => {
5874
+ if (cape) {
5875
+ return cape == null ? void 0 : cape.stillImageUrl;
5876
+ }
5877
+ return void 0;
5878
+ });
5879
+ }
5880
+ //</editor-fold>
5881
+ //<editor-fold desc="Helpers">
5882
+ static async usernameToUuid(username) {
5883
+ return this.usernameToUuidSkinProxy(username);
5884
+ }
5885
+ static async usernameToUuidSkinProxy(username) {
5886
+ return Requests.genericRequest({
5887
+ baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
5888
+ url: "/uuid/" + username
5889
+ }).then((res) => {
5890
+ if (res.status === 200) {
5891
+ return res.data["id"];
5892
+ }
5893
+ return void 0;
5894
+ }).catch((err) => {
5895
+ console.warn(err);
5896
+ return void 0;
5897
+ });
5898
+ }
5899
+ static async usernameToUuidMineTools(username) {
5900
+ return Requests.genericRequest({
5901
+ baseURL: "https://api.minetools.eu",
5902
+ url: "/uuid/" + username
5903
+ }).then((res) => {
5904
+ if (res.status === 200) {
5905
+ return res.data["id"];
5906
+ }
5907
+ return void 0;
5908
+ }).catch((err) => {
5909
+ console.warn(err);
5910
+ return void 0;
5911
+ });
5912
+ }
5913
+ static async getProfileFromMinetools(uuid) {
5914
+ return Requests.genericRequest({
5915
+ baseURL: "https://api.minetools.eu",
5916
+ url: "/profile/" + uuid
5917
+ }).then((res) => {
5918
+ if (res.status === 200) {
5919
+ return res.data;
5920
+ }
5921
+ });
5922
+ }
5923
+ static async getMineSkin(mineskinId) {
5924
+ return Requests.genericRequest({
5925
+ baseURL: "https://api.mineskin.org",
5926
+ url: "/get/uuid/" + mineskinId
5927
+ }).then((res) => {
5928
+ if (res.status === 200) {
5929
+ return res.data;
5930
+ }
5931
+ return void 0;
5932
+ }).catch((err) => {
5933
+ console.warn(err);
5934
+ return void 0;
5935
+ });
5936
+ }
5937
+ static async getCapesDev(uuid, type = "all") {
5938
+ return Requests.genericRequest({
5939
+ baseURL: "https://api.capes.dev",
5940
+ url: "/load/" + uuid + "/" + type
5941
+ }).then((res) => {
5942
+ if (res.status === 200) {
5943
+ return res.data;
5944
+ }
5945
+ return void 0;
5946
+ }).catch((err) => {
5947
+ console.warn(err);
5948
+ return void 0;
5949
+ });
5950
+ }
5951
+ static getCrafatarSkinUrl(uuid) {
5952
+ return "https://crafatar.com/skins/" + uuid;
5953
+ }
5954
+ static getCrafatarCapeUrl(uuid) {
5955
+ return "https://crafatar.com/capes/" + uuid;
5956
+ }
5957
+ static getMcHeadsSkinUrl(uuid) {
5958
+ return "https://mc-heads.net/skin/" + uuid;
5959
+ }
5960
+ static getMineSkinPlayerSkinUrl(uuid) {
5961
+ return "https://mineskin.org/skin/player/" + uuid;
5962
+ }
5963
+ static getSkinProxySkinUrl(uuid) {
5964
+ return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
5965
+ }
5966
+ static getSkinProxyCapeUrl(uuid) {
5967
+ return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
5968
+ }
5969
+ //</editor-fold>
5970
+ };
5971
+
5972
+ // src/three/OrbitControls.js
5973
+ var import_three20 = require("three");
5974
+ var _changeEvent = { type: "change" };
5975
+ var _startEvent = { type: "start" };
5976
+ var _endEvent = { type: "end" };
5977
+ var OrbitControls = class extends import_three20.EventDispatcher {
5978
+ constructor(object, domElement) {
5979
+ super();
5980
+ if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5981
+ if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5982
+ this.object = object;
5983
+ this.domElement = domElement;
5984
+ this.domElement.style.touchAction = "none";
5985
+ this.enabled = true;
5986
+ this.target = new import_three20.Vector3();
5987
+ this.minDistance = 0;
5988
+ this.maxDistance = Infinity;
5989
+ this.minZoom = 0;
5990
+ this.maxZoom = Infinity;
5991
+ this.minPolarAngle = 0;
5992
+ this.maxPolarAngle = Math.PI;
5993
+ this.minAzimuthAngle = -Infinity;
5994
+ this.maxAzimuthAngle = Infinity;
5995
+ this.enableDamping = false;
5996
+ this.dampingFactor = 0.05;
5997
+ this.enableZoom = true;
5998
+ this.zoomSpeed = 1;
5999
+ this.enableRotate = true;
6000
+ this.rotateSpeed = 1;
6001
+ this.enablePan = true;
6002
+ this.panSpeed = 1;
6003
+ this.screenSpacePanning = true;
6004
+ this.keyPanSpeed = 7;
6005
+ this.autoRotate = false;
6006
+ this.autoRotateSpeed = 2;
6007
+ this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
6008
+ this.mouseButtons = { LEFT: import_three20.MOUSE.ROTATE, MIDDLE: import_three20.MOUSE.DOLLY, RIGHT: import_three20.MOUSE.PAN };
6009
+ this.touches = { ONE: import_three20.TOUCH.ROTATE, TWO: import_three20.TOUCH.DOLLY_PAN };
6010
+ this.target0 = this.target.clone();
6011
+ this.position0 = this.object.position.clone();
6012
+ this.zoom0 = this.object.zoom;
6013
+ this._domElementKeyEvents = null;
6014
+ this.getPolarAngle = function() {
6015
+ return spherical.phi;
6016
+ };
6017
+ this.getAzimuthalAngle = function() {
6018
+ return spherical.theta;
6019
+ };
6020
+ this.getDistance = function() {
6021
+ return this.object.position.distanceTo(this.target);
6022
+ };
6023
+ this.saveState = function() {
6024
+ scope.target0.copy(scope.target);
6025
+ scope.position0.copy(scope.object.position);
6026
+ scope.zoom0 = scope.object.zoom;
6027
+ };
6028
+ this.reset = function() {
6029
+ scope.target.copy(scope.target0);
6030
+ scope.object.position.copy(scope.position0);
6031
+ scope.object.zoom = scope.zoom0;
6032
+ scope.object.updateProjectionMatrix();
6033
+ scope.dispatchEvent(_changeEvent);
6034
+ scope.update();
6035
+ state = STATE.NONE;
6036
+ };
6037
+ this.update = function() {
6038
+ const offset = new import_three20.Vector3();
6039
+ const quat = new import_three20.Quaternion().setFromUnitVectors(object.up, new import_three20.Vector3(0, 1, 0));
6040
+ const quatInverse = quat.clone().invert();
6041
+ const lastPosition = new import_three20.Vector3();
6042
+ const lastQuaternion = new import_three20.Quaternion();
6043
+ const twoPI = 2 * Math.PI;
6044
+ return function update() {
6045
+ const position = scope.object.position;
6046
+ offset.copy(position).sub(scope.target);
6047
+ offset.applyQuaternion(quat);
6048
+ spherical.setFromVector3(offset);
6049
+ if (scope.autoRotate && state === STATE.NONE) {
6050
+ rotateLeft(getAutoRotationAngle());
6051
+ }
6052
+ if (scope.enableDamping) {
6053
+ spherical.theta += sphericalDelta.theta * scope.dampingFactor;
6054
+ spherical.phi += sphericalDelta.phi * scope.dampingFactor;
6055
+ } else {
6056
+ spherical.theta += sphericalDelta.theta;
6057
+ spherical.phi += sphericalDelta.phi;
6058
+ }
6059
+ let min = scope.minAzimuthAngle;
6060
+ let max = scope.maxAzimuthAngle;
6061
+ if (isFinite(min) && isFinite(max)) {
6062
+ if (min < -Math.PI) min += twoPI;
6063
+ else if (min > Math.PI) min -= twoPI;
6064
+ if (max < -Math.PI) max += twoPI;
6065
+ else if (max > Math.PI) max -= twoPI;
6066
+ if (min <= max) {
6067
+ spherical.theta = Math.max(min, Math.min(max, spherical.theta));
6068
+ } else {
6069
+ spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
6070
+ }
6071
+ }
6072
+ spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
6073
+ spherical.makeSafe();
6074
+ spherical.radius *= scale;
6075
+ spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
6076
+ if (scope.enableDamping === true) {
6077
+ scope.target.addScaledVector(panOffset, scope.dampingFactor);
6078
+ } else {
6079
+ scope.target.add(panOffset);
6080
+ }
6081
+ offset.setFromSpherical(spherical);
6082
+ offset.applyQuaternion(quatInverse);
6083
+ position.copy(scope.target).add(offset);
6084
+ scope.object.lookAt(scope.target);
6085
+ if (scope.enableDamping === true) {
6086
+ sphericalDelta.theta *= 1 - scope.dampingFactor;
6087
+ sphericalDelta.phi *= 1 - scope.dampingFactor;
6088
+ panOffset.multiplyScalar(1 - scope.dampingFactor);
6089
+ } else {
6090
+ sphericalDelta.set(0, 0, 0);
6091
+ panOffset.set(0, 0, 0);
6092
+ }
6093
+ scale = 1;
6094
+ if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
6095
+ scope.dispatchEvent(_changeEvent);
6096
+ lastPosition.copy(scope.object.position);
6097
+ lastQuaternion.copy(scope.object.quaternion);
6098
+ zoomChanged = false;
6099
+ return true;
6100
+ }
6101
+ return false;
6102
+ };
6103
+ }();
6104
+ this.dispose = function() {
6105
+ scope.domElement.removeEventListener("contextmenu", onContextMenu);
6106
+ scope.domElement.removeEventListener("pointerdown", onPointerDown);
6107
+ scope.domElement.removeEventListener("pointercancel", onPointerCancel);
6108
+ scope.domElement.removeEventListener("wheel", onMouseWheel);
6109
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
6110
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
6111
+ if (scope._domElementKeyEvents !== null) {
6112
+ scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
6073
6113
  }
6074
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6075
- pan(panDelta.x, panDelta.y);
6076
- panStart.copy(panEnd);
6077
- }
6078
- function handleTouchMoveDolly(event) {
6079
- const position = getSecondPointerPosition(event);
6080
- const dx = event.pageX - position.x;
6081
- const dy = event.pageY - position.y;
6082
- const distance = Math.sqrt(dx * dx + dy * dy);
6083
- dollyEnd.set(0, distance);
6084
- dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
6085
- dollyOut(dollyDelta.y);
6086
- dollyStart.copy(dollyEnd);
6114
+ };
6115
+ const scope = this;
6116
+ const STATE = {
6117
+ NONE: -1,
6118
+ ROTATE: 0,
6119
+ DOLLY: 1,
6120
+ PAN: 2,
6121
+ TOUCH_ROTATE: 3,
6122
+ TOUCH_PAN: 4,
6123
+ TOUCH_DOLLY_PAN: 5,
6124
+ TOUCH_DOLLY_ROTATE: 6
6125
+ };
6126
+ let state = STATE.NONE;
6127
+ const EPS = 1e-6;
6128
+ const spherical = new import_three20.Spherical();
6129
+ const sphericalDelta = new import_three20.Spherical();
6130
+ let scale = 1;
6131
+ const panOffset = new import_three20.Vector3();
6132
+ let zoomChanged = false;
6133
+ const rotateStart = new import_three20.Vector2();
6134
+ const rotateEnd = new import_three20.Vector2();
6135
+ const rotateDelta = new import_three20.Vector2();
6136
+ const panStart = new import_three20.Vector2();
6137
+ const panEnd = new import_three20.Vector2();
6138
+ const panDelta = new import_three20.Vector2();
6139
+ const dollyStart = new import_three20.Vector2();
6140
+ const dollyEnd = new import_three20.Vector2();
6141
+ const dollyDelta = new import_three20.Vector2();
6142
+ const pointers = [];
6143
+ const pointerPositions = {};
6144
+ function getAutoRotationAngle() {
6145
+ return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
6087
6146
  }
6088
- function handleTouchMoveDollyPan(event) {
6089
- if (scope.enableZoom) handleTouchMoveDolly(event);
6090
- if (scope.enablePan) handleTouchMovePan(event);
6147
+ function getZoomScale() {
6148
+ return Math.pow(0.95, scope.zoomSpeed);
6091
6149
  }
6092
- function handleTouchMoveDollyRotate(event) {
6093
- if (scope.enableZoom) handleTouchMoveDolly(event);
6094
- if (scope.enableRotate) handleTouchMoveRotate(event);
6150
+ function rotateLeft(angle) {
6151
+ sphericalDelta.theta -= angle;
6095
6152
  }
6096
- function handleTouchEnd() {
6153
+ function rotateUp(angle) {
6154
+ sphericalDelta.phi -= angle;
6097
6155
  }
6098
- function onPointerDown(event) {
6099
- if (scope.enabled === false) return;
6100
- if (pointers.length === 0) {
6101
- scope.domElement.setPointerCapture(event.pointerId);
6102
- scope.domElement.addEventListener("pointermove", onPointerMove);
6103
- scope.domElement.addEventListener("pointerup", onPointerUp);
6104
- }
6105
- addPointer(event);
6106
- if (event.pointerType === "touch") {
6107
- onTouchStart(event);
6156
+ const panLeft = function() {
6157
+ const v = new import_three20.Vector3();
6158
+ return function panLeft2(distance, objectMatrix) {
6159
+ v.setFromMatrixColumn(objectMatrix, 0);
6160
+ v.multiplyScalar(-distance);
6161
+ panOffset.add(v);
6162
+ };
6163
+ }();
6164
+ const panUp = function() {
6165
+ const v = new import_three20.Vector3();
6166
+ return function panUp2(distance, objectMatrix) {
6167
+ if (scope.screenSpacePanning === true) {
6168
+ v.setFromMatrixColumn(objectMatrix, 1);
6169
+ } else {
6170
+ v.setFromMatrixColumn(objectMatrix, 0);
6171
+ v.crossVectors(scope.object.up, v);
6172
+ }
6173
+ v.multiplyScalar(distance);
6174
+ panOffset.add(v);
6175
+ };
6176
+ }();
6177
+ const pan = function() {
6178
+ const offset = new import_three20.Vector3();
6179
+ return function pan2(deltaX, deltaY) {
6180
+ const element = scope.domElement;
6181
+ if (scope.object.isPerspectiveCamera) {
6182
+ const position = scope.object.position;
6183
+ offset.copy(position).sub(scope.target);
6184
+ let targetDistance = offset.length();
6185
+ targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
6186
+ panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
6187
+ panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
6188
+ } else if (scope.object.isOrthographicCamera) {
6189
+ panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
6190
+ panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
6191
+ } else {
6192
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
6193
+ scope.enablePan = false;
6194
+ }
6195
+ };
6196
+ }();
6197
+ function dollyOut(dollyScale) {
6198
+ if (scope.object.isPerspectiveCamera) {
6199
+ scale /= dollyScale;
6200
+ } else if (scope.object.isOrthographicCamera) {
6201
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
6202
+ scope.object.updateProjectionMatrix();
6203
+ zoomChanged = true;
6108
6204
  } else {
6109
- onMouseDown(event);
6205
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6206
+ scope.enableZoom = false;
6110
6207
  }
6111
6208
  }
6112
- function onPointerMove(event) {
6113
- if (scope.enabled === false) return;
6114
- if (event.pointerType === "touch") {
6115
- onTouchMove(event);
6209
+ function dollyIn(dollyScale) {
6210
+ if (scope.object.isPerspectiveCamera) {
6211
+ scale *= dollyScale;
6212
+ } else if (scope.object.isOrthographicCamera) {
6213
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
6214
+ scope.object.updateProjectionMatrix();
6215
+ zoomChanged = true;
6116
6216
  } else {
6117
- onMouseMove(event);
6217
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6218
+ scope.enableZoom = false;
6118
6219
  }
6119
6220
  }
6120
- function onPointerUp(event) {
6121
- if (scope.enabled === false) return;
6122
- if (event.pointerType === "touch") {
6123
- onTouchEnd();
6124
- } else {
6125
- onMouseUp(event);
6126
- }
6127
- removePointer(event);
6128
- if (pointers.length === 0) {
6129
- scope.domElement.releasePointerCapture(event.pointerId);
6130
- scope.domElement.removeEventListener("pointermove", onPointerMove);
6131
- scope.domElement.removeEventListener("pointerup", onPointerUp);
6132
- }
6221
+ function handleMouseDownRotate(event) {
6222
+ rotateStart.set(event.clientX, event.clientY);
6133
6223
  }
6134
- function onPointerCancel(event) {
6135
- removePointer(event);
6224
+ function handleMouseDownDolly(event) {
6225
+ dollyStart.set(event.clientX, event.clientY);
6136
6226
  }
6137
- function onMouseDown(event) {
6138
- let mouseAction;
6139
- switch (event.button) {
6140
- case 0:
6141
- mouseAction = scope.mouseButtons.LEFT;
6142
- break;
6143
- case 1:
6144
- mouseAction = scope.mouseButtons.MIDDLE;
6145
- break;
6146
- case 2:
6147
- mouseAction = scope.mouseButtons.RIGHT;
6148
- break;
6149
- default:
6150
- mouseAction = -1;
6151
- }
6152
- switch (mouseAction) {
6153
- case import_three18.MOUSE.DOLLY:
6154
- if (scope.enableZoom === false) return;
6155
- handleMouseDownDolly(event);
6156
- state = STATE.DOLLY;
6157
- break;
6158
- case import_three18.MOUSE.ROTATE:
6159
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6160
- if (scope.enablePan === false) return;
6161
- handleMouseDownPan(event);
6162
- state = STATE.PAN;
6163
- } else {
6164
- if (scope.enableRotate === false) return;
6165
- handleMouseDownRotate(event);
6166
- state = STATE.ROTATE;
6167
- }
6168
- break;
6169
- case import_three18.MOUSE.PAN:
6170
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6171
- if (scope.enableRotate === false) return;
6172
- handleMouseDownRotate(event);
6173
- state = STATE.ROTATE;
6174
- } else {
6175
- if (scope.enablePan === false) return;
6176
- handleMouseDownPan(event);
6177
- state = STATE.PAN;
6178
- }
6179
- break;
6180
- default:
6181
- state = STATE.NONE;
6182
- }
6183
- if (state !== STATE.NONE) {
6184
- scope.dispatchEvent(_startEvent);
6185
- }
6227
+ function handleMouseDownPan(event) {
6228
+ panStart.set(event.clientX, event.clientY);
6186
6229
  }
6187
- function onMouseMove(event) {
6188
- if (scope.enabled === false) return;
6189
- switch (state) {
6190
- case STATE.ROTATE:
6191
- if (scope.enableRotate === false) return;
6192
- handleMouseMoveRotate(event);
6193
- break;
6194
- case STATE.DOLLY:
6195
- if (scope.enableZoom === false) return;
6196
- handleMouseMoveDolly(event);
6197
- break;
6198
- case STATE.PAN:
6199
- if (scope.enablePan === false) return;
6200
- handleMouseMovePan(event);
6201
- break;
6202
- }
6230
+ function handleMouseMoveRotate(event) {
6231
+ rotateEnd.set(event.clientX, event.clientY);
6232
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6233
+ const element = scope.domElement;
6234
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6235
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6236
+ rotateStart.copy(rotateEnd);
6237
+ scope.update();
6203
6238
  }
6204
- function onMouseUp(event) {
6205
- handleMouseUp(event);
6206
- scope.dispatchEvent(_endEvent);
6207
- state = STATE.NONE;
6239
+ function handleMouseMoveDolly(event) {
6240
+ dollyEnd.set(event.clientX, event.clientY);
6241
+ dollyDelta.subVectors(dollyEnd, dollyStart);
6242
+ if (dollyDelta.y > 0) {
6243
+ dollyOut(getZoomScale());
6244
+ } else if (dollyDelta.y < 0) {
6245
+ dollyIn(getZoomScale());
6246
+ }
6247
+ dollyStart.copy(dollyEnd);
6248
+ scope.update();
6208
6249
  }
6209
- function onMouseWheel(event) {
6210
- if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6211
- event.preventDefault();
6212
- scope.dispatchEvent(_startEvent);
6213
- handleMouseWheel(event);
6214
- scope.dispatchEvent(_endEvent);
6250
+ function handleMouseMovePan(event) {
6251
+ panEnd.set(event.clientX, event.clientY);
6252
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6253
+ pan(panDelta.x, panDelta.y);
6254
+ panStart.copy(panEnd);
6255
+ scope.update();
6215
6256
  }
6216
- function onKeyDown(event) {
6217
- if (scope.enabled === false || scope.enablePan === false) return;
6218
- handleKeyDown(event);
6257
+ function handleMouseUp() {
6219
6258
  }
6220
- function onTouchStart(event) {
6221
- trackPointer(event);
6222
- switch (pointers.length) {
6223
- case 1:
6224
- switch (scope.touches.ONE) {
6225
- case import_three18.TOUCH.ROTATE:
6226
- if (scope.enableRotate === false) return;
6227
- handleTouchStartRotate();
6228
- state = STATE.TOUCH_ROTATE;
6229
- break;
6230
- case import_three18.TOUCH.PAN:
6231
- if (scope.enablePan === false) return;
6232
- handleTouchStartPan();
6233
- state = STATE.TOUCH_PAN;
6234
- break;
6235
- default:
6236
- state = STATE.NONE;
6237
- }
6238
- break;
6239
- case 2:
6240
- switch (scope.touches.TWO) {
6241
- case import_three18.TOUCH.DOLLY_PAN:
6242
- if (scope.enableZoom === false && scope.enablePan === false) return;
6243
- handleTouchStartDollyPan();
6244
- state = STATE.TOUCH_DOLLY_PAN;
6245
- break;
6246
- case import_three18.TOUCH.DOLLY_ROTATE:
6247
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6248
- handleTouchStartDollyRotate();
6249
- state = STATE.TOUCH_DOLLY_ROTATE;
6250
- break;
6251
- default:
6252
- state = STATE.NONE;
6253
- }
6254
- break;
6255
- default:
6256
- state = STATE.NONE;
6257
- }
6258
- if (state !== STATE.NONE) {
6259
- scope.dispatchEvent(_startEvent);
6259
+ function handleMouseWheel(event) {
6260
+ if (event.deltaY < 0) {
6261
+ dollyIn(getZoomScale());
6262
+ } else if (event.deltaY > 0) {
6263
+ dollyOut(getZoomScale());
6260
6264
  }
6265
+ scope.update();
6261
6266
  }
6262
- function onTouchMove(event) {
6263
- trackPointer(event);
6264
- switch (state) {
6265
- case STATE.TOUCH_ROTATE:
6266
- if (scope.enableRotate === false) return;
6267
- handleTouchMoveRotate(event);
6268
- scope.update();
6267
+ function handleKeyDown(event) {
6268
+ let needsUpdate = false;
6269
+ switch (event.code) {
6270
+ case scope.keys.UP:
6271
+ pan(0, scope.keyPanSpeed);
6272
+ needsUpdate = true;
6269
6273
  break;
6270
- case STATE.TOUCH_PAN:
6271
- if (scope.enablePan === false) return;
6272
- handleTouchMovePan(event);
6273
- scope.update();
6274
+ case scope.keys.BOTTOM:
6275
+ pan(0, -scope.keyPanSpeed);
6276
+ needsUpdate = true;
6274
6277
  break;
6275
- case STATE.TOUCH_DOLLY_PAN:
6276
- if (scope.enableZoom === false && scope.enablePan === false) return;
6277
- handleTouchMoveDollyPan(event);
6278
- scope.update();
6278
+ case scope.keys.LEFT:
6279
+ pan(scope.keyPanSpeed, 0);
6280
+ needsUpdate = true;
6279
6281
  break;
6280
- case STATE.TOUCH_DOLLY_ROTATE:
6281
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6282
- handleTouchMoveDollyRotate(event);
6283
- scope.update();
6282
+ case scope.keys.RIGHT:
6283
+ pan(-scope.keyPanSpeed, 0);
6284
+ needsUpdate = true;
6284
6285
  break;
6285
- default:
6286
- state = STATE.NONE;
6286
+ }
6287
+ if (needsUpdate) {
6288
+ event.preventDefault();
6289
+ scope.update();
6287
6290
  }
6288
6291
  }
6289
- function onTouchEnd(event) {
6290
- handleTouchEnd(event);
6291
- scope.dispatchEvent(_endEvent);
6292
- state = STATE.NONE;
6293
- }
6294
- function onContextMenu(event) {
6295
- if (scope.enabled === false) return;
6296
- event.preventDefault();
6297
- }
6298
- function addPointer(event) {
6299
- pointers.push(event);
6300
- }
6301
- function removePointer(event) {
6302
- delete pointerPositions[event.pointerId];
6303
- for (let i = 0; i < pointers.length; i++) {
6304
- if (pointers[i].pointerId == event.pointerId) {
6305
- pointers.splice(i, 1);
6306
- return;
6307
- }
6292
+ function handleTouchStartRotate() {
6293
+ if (pointers.length === 1) {
6294
+ rotateStart.set(pointers[0].pageX, pointers[0].pageY);
6295
+ } else {
6296
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6297
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6298
+ rotateStart.set(x, y);
6308
6299
  }
6309
6300
  }
6310
- function trackPointer(event) {
6311
- let position = pointerPositions[event.pointerId];
6312
- if (position === void 0) {
6313
- position = new import_three18.Vector2();
6314
- pointerPositions[event.pointerId] = position;
6301
+ function handleTouchStartPan() {
6302
+ if (pointers.length === 1) {
6303
+ panStart.set(pointers[0].pageX, pointers[0].pageY);
6304
+ } else {
6305
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6306
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6307
+ panStart.set(x, y);
6315
6308
  }
6316
- position.set(event.pageX, event.pageY);
6317
6309
  }
6318
- function getSecondPointerPosition(event) {
6319
- const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6320
- return pointerPositions[pointer.pointerId];
6310
+ function handleTouchStartDolly() {
6311
+ const dx = pointers[0].pageX - pointers[1].pageX;
6312
+ const dy = pointers[0].pageY - pointers[1].pageY;
6313
+ const distance = Math.sqrt(dx * dx + dy * dy);
6314
+ dollyStart.set(0, distance);
6321
6315
  }
6322
- scope.domElement.addEventListener("contextmenu", onContextMenu);
6323
- scope.domElement.addEventListener("pointerdown", onPointerDown);
6324
- scope.domElement.addEventListener("pointercancel", onPointerCancel);
6325
- scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6326
- this.update();
6327
- }
6328
- };
6329
- var MapControls = class extends OrbitControls {
6330
- constructor(object, domElement) {
6331
- super(object, domElement);
6332
- this.screenSpacePanning = false;
6333
- this.mouseButtons.LEFT = import_three18.MOUSE.PAN;
6334
- this.mouseButtons.RIGHT = import_three18.MOUSE.ROTATE;
6335
- this.touches.ONE = import_three18.TOUCH.PAN;
6336
- this.touches.TWO = import_three18.TOUCH.DOLLY_ROTATE;
6337
- }
6338
- };
6339
-
6340
- // src/renderer/Renderer.ts
6341
- var Renderer = class _Renderer {
6342
- constructor(options) {
6343
- this._dirty = true;
6344
- this._resizeListener = void 0;
6345
- this._disposed = false;
6346
- this._debugHelpers = [];
6347
- this._eventDispatchers = /* @__PURE__ */ new Map();
6348
- this._changeListener = () => {
6349
- this._dirty = true;
6350
- };
6351
- this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
6352
- this._animationLoop = this.animate.bind(this);
6353
- this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
6354
- this._scene = this.createScene();
6355
- this._camera = this.createCamera();
6356
- this._renderer = this.createRenderer();
6357
- this._composer = this.createComposer();
6358
- if (this.options.render.stats) {
6359
- this._stats = new import_stats.default();
6360
- document.body.appendChild(this._stats.dom);
6316
+ function handleTouchStartDollyPan() {
6317
+ if (scope.enableZoom) handleTouchStartDolly();
6318
+ if (scope.enablePan) handleTouchStartPan();
6361
6319
  }
6362
- this.init();
6363
- this._controls = this.createControls();
6364
- }
6365
- static {
6366
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6367
- camera: {
6368
- type: "perspective",
6369
- near: 1,
6370
- far: 5e3,
6371
- perspective: {
6372
- aspect: void 0,
6373
- fov: 50
6374
- },
6375
- orthographic: {
6376
- left: void 0,
6377
- right: void 0,
6378
- top: void 0,
6379
- bottom: void 0
6380
- },
6381
- position: new import_three19.Vector3(50, 50, 50),
6382
- lookingAt: new import_three19.Vector3(0, 0, 0)
6383
- },
6384
- render: {
6385
- fpsLimit: 60,
6386
- stats: false,
6387
- antialias: true,
6388
- shade: true,
6389
- autoResize: true,
6390
- renderAlways: false
6391
- },
6392
- composer: {
6393
- enabled: true
6394
- },
6395
- controls: {
6396
- enabled: false
6397
- },
6398
- debug: {
6399
- grid: false,
6400
- axes: false
6320
+ function handleTouchStartDollyRotate() {
6321
+ if (scope.enableZoom) handleTouchStartDolly();
6322
+ if (scope.enableRotate) handleTouchStartRotate();
6323
+ }
6324
+ function handleTouchMoveRotate(event) {
6325
+ if (pointers.length == 1) {
6326
+ rotateEnd.set(event.pageX, event.pageY);
6327
+ } else {
6328
+ const position = getSecondPointerPosition(event);
6329
+ const x = 0.5 * (event.pageX + position.x);
6330
+ const y = 0.5 * (event.pageY + position.y);
6331
+ rotateEnd.set(x, y);
6401
6332
  }
6402
- });
6403
- }
6404
- //<editor-fold desc="INIT">
6405
- createScene() {
6406
- return new MineRenderScene();
6407
- }
6408
- createCamera() {
6409
- switch (this.options.camera.type) {
6410
- case "perspective":
6411
- default:
6412
- return new import_three19.PerspectiveCamera(
6413
- this.options.camera.perspective.fov,
6414
- this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
6415
- this.options.camera.near,
6416
- this.options.camera.far
6417
- );
6418
- case "orthographic":
6419
- return new import_three19.OrthographicCamera(
6420
- this.options.camera.orthographic.left ?? this.viewWidth / -2,
6421
- this.options.camera.orthographic.right ?? this.viewWidth / 2,
6422
- this.options.camera.orthographic.top ?? this.viewHeight / 2,
6423
- this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
6424
- this.options.camera.near,
6425
- this.options.camera.far
6426
- );
6333
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6334
+ const element = scope.domElement;
6335
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6336
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6337
+ rotateStart.copy(rotateEnd);
6427
6338
  }
6428
- }
6429
- createRenderer() {
6430
- const renderer = new import_three19.WebGLRenderer({
6431
- antialias: this.options.render.antialias,
6432
- alpha: true,
6433
- powerPreference: "high-performance",
6434
- depth: true
6435
- });
6436
- renderer.setClearColor(0, 0);
6437
- renderer.shadowMap.enabled = true;
6438
- renderer.shadowMap.type = import_three19.PCFSoftShadowMap;
6439
- renderer.outputColorSpace = import_three19.SRGBColorSpace;
6440
- renderer.setSize(this.viewWidth, this.viewHeight);
6441
- return renderer;
6442
- }
6443
- createComposer() {
6444
- if (!this.options.composer.enabled) return void 0;
6445
- const composer = new import_postprocessing.EffectComposer(this.renderer);
6446
- composer.setSize(this.viewWidth, this.viewHeight);
6447
- composer.addPass(new import_postprocessing.RenderPass(this.scene, this.camera));
6448
- return composer;
6449
- }
6450
- createControls() {
6451
- if (!this.options.controls?.enabled) return void 0;
6452
- const position = this.camera.position.clone();
6453
- const controls = new OrbitControls(this.camera, this.renderer.domElement);
6454
- this.camera.position.copy(position);
6455
- const target = this.options.camera.lookingAt;
6456
- if (isVector3(target)) {
6457
- controls.target.copy(target);
6458
- } else if (isTripleArray(target)) {
6459
- controls.target.set(target[0], target[1], target[2]);
6460
- }
6461
- controls.update();
6462
- controls.saveState();
6463
- this.registerEventDispatcher(controls);
6464
- return controls;
6465
- }
6466
- //</editor-fold>
6467
- init() {
6468
- if (this._disposed) return;
6469
- if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
6470
- window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
6339
+ function handleTouchMovePan(event) {
6340
+ if (pointers.length === 1) {
6341
+ panEnd.set(event.pageX, event.pageY);
6342
+ } else {
6343
+ const position = getSecondPointerPosition(event);
6344
+ const x = 0.5 * (event.pageX + position.x);
6345
+ const y = 0.5 * (event.pageY + position.y);
6346
+ panEnd.set(x, y);
6347
+ }
6348
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6349
+ pan(panDelta.x, panDelta.y);
6350
+ panStart.copy(panEnd);
6351
+ }
6352
+ function handleTouchMoveDolly(event) {
6353
+ const position = getSecondPointerPosition(event);
6354
+ const dx = event.pageX - position.x;
6355
+ const dy = event.pageY - position.y;
6356
+ const distance = Math.sqrt(dx * dx + dy * dy);
6357
+ dollyEnd.set(0, distance);
6358
+ dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
6359
+ dollyOut(dollyDelta.y);
6360
+ dollyStart.copy(dollyEnd);
6471
6361
  }
6472
- if (this.options.debug.grid) {
6473
- const gridHelper = new import_three19.GridHelper(128, 16);
6474
- this._debugHelpers.push(gridHelper);
6475
- this.scene.add(gridHelper);
6476
- const gridHelper2 = new import_three19.GridHelper(128, 16);
6477
- this._debugHelpers.push(gridHelper2);
6478
- gridHelper2.rotation.x = 90 * (Math.PI / 180);
6479
- this.scene.add(gridHelper2);
6480
- const gridHelper3 = new import_three19.GridHelper(128, 16);
6481
- this._debugHelpers.push(gridHelper3);
6482
- gridHelper3.rotation.z = 90 * (Math.PI / 180);
6483
- this.scene.add(gridHelper3);
6362
+ function handleTouchMoveDollyPan(event) {
6363
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6364
+ if (scope.enablePan) handleTouchMovePan(event);
6484
6365
  }
6485
- if (this.options.debug.axes) {
6486
- const axesHelper = new import_three19.AxesHelper(64);
6487
- this._debugHelpers.push(axesHelper);
6488
- this.scene.add(axesHelper);
6366
+ function handleTouchMoveDollyRotate(event) {
6367
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6368
+ if (scope.enableRotate) handleTouchMoveRotate(event);
6489
6369
  }
6490
- if (this.options.camera.position) {
6491
- if (isVector3(this.options.camera.position)) {
6492
- this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
6493
- } else if (isTripleArray(this.options.camera.position)) {
6494
- this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
6370
+ function handleTouchEnd() {
6371
+ }
6372
+ function onPointerDown(event) {
6373
+ if (scope.enabled === false) return;
6374
+ if (pointers.length === 0) {
6375
+ scope.domElement.setPointerCapture(event.pointerId);
6376
+ scope.domElement.addEventListener("pointermove", onPointerMove);
6377
+ scope.domElement.addEventListener("pointerup", onPointerUp);
6378
+ }
6379
+ addPointer(event);
6380
+ if (event.pointerType === "touch") {
6381
+ onTouchStart(event);
6382
+ } else {
6383
+ onMouseDown(event);
6495
6384
  }
6496
6385
  }
6497
- if (this.options.camera.lookingAt) {
6498
- if (isVector3(this.options.camera.lookingAt)) {
6499
- this.camera.lookAt(this.options.camera.lookingAt);
6500
- } else if (isTripleArray(this.options.camera.lookingAt)) {
6501
- this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
6386
+ function onPointerMove(event) {
6387
+ if (scope.enabled === false) return;
6388
+ if (event.pointerType === "touch") {
6389
+ onTouchMove(event);
6390
+ } else {
6391
+ onMouseMove(event);
6502
6392
  }
6503
6393
  }
6504
- if (this.options.render.autoResize && !this._resizeListener) {
6505
- this._resizeListener = () => {
6506
- this.resize(this.viewWidth, this.viewHeight);
6507
- };
6508
- window.addEventListener("resize", this._resizeListener);
6394
+ function onPointerUp(event) {
6395
+ if (scope.enabled === false) return;
6396
+ if (event.pointerType === "touch") {
6397
+ onTouchEnd();
6398
+ } else {
6399
+ onMouseUp(event);
6400
+ }
6401
+ removePointer(event);
6402
+ if (pointers.length === 0) {
6403
+ scope.domElement.releasePointerCapture(event.pointerId);
6404
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
6405
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
6406
+ }
6509
6407
  }
6510
- }
6511
- get element() {
6512
- return this._element;
6513
- }
6514
- appendTo(element) {
6515
- if (this._disposed) return;
6516
- this._element = element;
6517
- this._element.appendChild(this.renderer.domElement);
6518
- if (this.viewWidth == 0) {
6519
- console.warn("0 element width");
6408
+ function onPointerCancel(event) {
6409
+ removePointer(event);
6520
6410
  }
6521
- if (this.viewHeight == 0) {
6522
- console.warn("0 element height");
6411
+ function onMouseDown(event) {
6412
+ let mouseAction;
6413
+ switch (event.button) {
6414
+ case 0:
6415
+ mouseAction = scope.mouseButtons.LEFT;
6416
+ break;
6417
+ case 1:
6418
+ mouseAction = scope.mouseButtons.MIDDLE;
6419
+ break;
6420
+ case 2:
6421
+ mouseAction = scope.mouseButtons.RIGHT;
6422
+ break;
6423
+ default:
6424
+ mouseAction = -1;
6425
+ }
6426
+ switch (mouseAction) {
6427
+ case import_three20.MOUSE.DOLLY:
6428
+ if (scope.enableZoom === false) return;
6429
+ handleMouseDownDolly(event);
6430
+ state = STATE.DOLLY;
6431
+ break;
6432
+ case import_three20.MOUSE.ROTATE:
6433
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6434
+ if (scope.enablePan === false) return;
6435
+ handleMouseDownPan(event);
6436
+ state = STATE.PAN;
6437
+ } else {
6438
+ if (scope.enableRotate === false) return;
6439
+ handleMouseDownRotate(event);
6440
+ state = STATE.ROTATE;
6441
+ }
6442
+ break;
6443
+ case import_three20.MOUSE.PAN:
6444
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6445
+ if (scope.enableRotate === false) return;
6446
+ handleMouseDownRotate(event);
6447
+ state = STATE.ROTATE;
6448
+ } else {
6449
+ if (scope.enablePan === false) return;
6450
+ handleMouseDownPan(event);
6451
+ state = STATE.PAN;
6452
+ }
6453
+ break;
6454
+ default:
6455
+ state = STATE.NONE;
6456
+ }
6457
+ if (state !== STATE.NONE) {
6458
+ scope.dispatchEvent(_startEvent);
6459
+ }
6523
6460
  }
6524
- this.resize(this.viewWidth, this.viewHeight);
6525
- }
6526
- /**
6527
- * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
6528
- * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
6529
- */
6530
- registerEventDispatcher(dispatcher, changeEvent2 = "change") {
6531
- if (this._disposed) return;
6532
- let events = this._eventDispatchers.get(dispatcher);
6533
- if (!events) {
6534
- events = /* @__PURE__ */ new Set();
6535
- this._eventDispatchers.set(dispatcher, events);
6461
+ function onMouseMove(event) {
6462
+ if (scope.enabled === false) return;
6463
+ switch (state) {
6464
+ case STATE.ROTATE:
6465
+ if (scope.enableRotate === false) return;
6466
+ handleMouseMoveRotate(event);
6467
+ break;
6468
+ case STATE.DOLLY:
6469
+ if (scope.enableZoom === false) return;
6470
+ handleMouseMoveDolly(event);
6471
+ break;
6472
+ case STATE.PAN:
6473
+ if (scope.enablePan === false) return;
6474
+ handleMouseMovePan(event);
6475
+ break;
6476
+ }
6536
6477
  }
6537
- if (events.has(changeEvent2)) return;
6538
- events.add(changeEvent2);
6539
- dispatcher.addEventListener(changeEvent2, this._changeListener);
6540
- }
6541
- resize(width, height) {
6542
- if (this._disposed) return;
6543
- if (isPerspectiveCamera(this.camera)) {
6544
- this.camera.aspect = width / height;
6545
- this.camera.updateProjectionMatrix();
6546
- } else if (isOrthographicCamera(this.camera)) {
6547
- this.camera.left = width / -2;
6548
- this.camera.right = width / 2;
6549
- this.camera.top = height / 2;
6550
- this.camera.bottom = height / -2;
6551
- this.camera.updateProjectionMatrix();
6478
+ function onMouseUp(event) {
6479
+ handleMouseUp(event);
6480
+ scope.dispatchEvent(_endEvent);
6481
+ state = STATE.NONE;
6552
6482
  }
6553
- this.renderer.setSize(width, height);
6554
- this.composer?.setSize(width, height);
6555
- this._dirty = true;
6556
- }
6557
- //<editor-fold desc="RENDER">
6558
- get dirty() {
6559
- return this._dirty || this.scene.dirty;
6560
- }
6561
- set dirty(dirty) {
6562
- this._dirty = dirty;
6563
- this.scene.dirty = dirty;
6564
- }
6565
- start() {
6566
- if (this._disposed) return;
6567
- this.stop();
6568
- this.renderer.setAnimationLoop(this._animationLoop);
6569
- }
6570
- stop() {
6571
- if (this._disposed) return;
6572
- this.renderer.setAnimationLoop(null);
6573
- this._nextFrameTime = void 0;
6574
- }
6575
- /**
6576
- * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
6577
- * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
6578
- * controls must be managed by their owners.
6579
- */
6580
- dispose() {
6581
- if (this._disposed) return;
6582
- this.stop();
6583
- this._disposed = true;
6584
- if (this._resizeListener) {
6585
- window.removeEventListener("resize", this._resizeListener);
6586
- this._resizeListener = void 0;
6483
+ function onMouseWheel(event) {
6484
+ if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6485
+ event.preventDefault();
6486
+ scope.dispatchEvent(_startEvent);
6487
+ handleMouseWheel(event);
6488
+ scope.dispatchEvent(_endEvent);
6587
6489
  }
6588
- for (const [dispatcher, events] of this._eventDispatchers) {
6589
- for (const event of events) {
6590
- dispatcher.removeEventListener(event, this._changeListener);
6490
+ function onKeyDown(event) {
6491
+ if (scope.enabled === false || scope.enablePan === false) return;
6492
+ handleKeyDown(event);
6493
+ }
6494
+ function onTouchStart(event) {
6495
+ trackPointer(event);
6496
+ switch (pointers.length) {
6497
+ case 1:
6498
+ switch (scope.touches.ONE) {
6499
+ case import_three20.TOUCH.ROTATE:
6500
+ if (scope.enableRotate === false) return;
6501
+ handleTouchStartRotate();
6502
+ state = STATE.TOUCH_ROTATE;
6503
+ break;
6504
+ case import_three20.TOUCH.PAN:
6505
+ if (scope.enablePan === false) return;
6506
+ handleTouchStartPan();
6507
+ state = STATE.TOUCH_PAN;
6508
+ break;
6509
+ default:
6510
+ state = STATE.NONE;
6511
+ }
6512
+ break;
6513
+ case 2:
6514
+ switch (scope.touches.TWO) {
6515
+ case import_three20.TOUCH.DOLLY_PAN:
6516
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6517
+ handleTouchStartDollyPan();
6518
+ state = STATE.TOUCH_DOLLY_PAN;
6519
+ break;
6520
+ case import_three20.TOUCH.DOLLY_ROTATE:
6521
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6522
+ handleTouchStartDollyRotate();
6523
+ state = STATE.TOUCH_DOLLY_ROTATE;
6524
+ break;
6525
+ default:
6526
+ state = STATE.NONE;
6527
+ }
6528
+ break;
6529
+ default:
6530
+ state = STATE.NONE;
6531
+ }
6532
+ if (state !== STATE.NONE) {
6533
+ scope.dispatchEvent(_startEvent);
6591
6534
  }
6592
6535
  }
6593
- this._eventDispatchers.clear();
6594
- this._stats?.dom.remove();
6595
- this._stats = void 0;
6596
- this.renderer.domElement.remove();
6597
- this._element = void 0;
6598
- if (this._controls) {
6599
- const controls = this._controls;
6600
- this._controls = void 0;
6601
- controls.enabled = false;
6602
- controls.dispose();
6603
- }
6604
- this.scene.clear();
6605
- for (const helper of this._debugHelpers) {
6606
- helper.geometry.dispose();
6607
- const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
6608
- for (const material of materials) {
6609
- material.dispose();
6536
+ function onTouchMove(event) {
6537
+ trackPointer(event);
6538
+ switch (state) {
6539
+ case STATE.TOUCH_ROTATE:
6540
+ if (scope.enableRotate === false) return;
6541
+ handleTouchMoveRotate(event);
6542
+ scope.update();
6543
+ break;
6544
+ case STATE.TOUCH_PAN:
6545
+ if (scope.enablePan === false) return;
6546
+ handleTouchMovePan(event);
6547
+ scope.update();
6548
+ break;
6549
+ case STATE.TOUCH_DOLLY_PAN:
6550
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6551
+ handleTouchMoveDollyPan(event);
6552
+ scope.update();
6553
+ break;
6554
+ case STATE.TOUCH_DOLLY_ROTATE:
6555
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6556
+ handleTouchMoveDollyRotate(event);
6557
+ scope.update();
6558
+ break;
6559
+ default:
6560
+ state = STATE.NONE;
6610
6561
  }
6611
6562
  }
6612
- this._debugHelpers.length = 0;
6613
- this.composer?.dispose();
6614
- this.renderer.dispose();
6615
- this.renderer.forceContextLoss();
6616
- }
6617
- animate(t = performance.now()) {
6618
- if (this._disposed) return;
6619
- if (this._controls?.enabled) {
6620
- this._controls.update();
6621
- }
6622
- if (this._disposed) return;
6623
- if (!this.dirty && !this.options.render.renderAlways) return;
6624
- const interval = this._frameInterval;
6625
- if (interval) {
6626
- const next = this._nextFrameTime;
6627
- if (next !== void 0 && t + 0.1 < next) return;
6628
- this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
6629
- }
6630
- if (this._stats) {
6631
- this._stats.begin();
6632
- }
6633
- if (this.options.composer.enabled && this.composer) {
6634
- this.composer.render();
6635
- } else {
6636
- this.renderer.render(this.scene, this.camera);
6563
+ function onTouchEnd(event) {
6564
+ handleTouchEnd(event);
6565
+ scope.dispatchEvent(_endEvent);
6566
+ state = STATE.NONE;
6637
6567
  }
6638
- this.dirty = false;
6639
- if (this._stats) {
6640
- this._stats.end();
6568
+ function onContextMenu(event) {
6569
+ if (scope.enabled === false) return;
6570
+ event.preventDefault();
6641
6571
  }
6642
- }
6643
- //</editor-fold>
6644
- toImage() {
6645
- return this.renderer.domElement.toDataURL();
6646
- }
6647
- ///
6648
- get attachedToBody() {
6649
- return this.element === document.body;
6650
- }
6651
- get viewWidth() {
6652
- return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
6653
- }
6654
- get viewHeight() {
6655
- return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
6656
- }
6657
- get scene() {
6658
- return this._scene;
6659
- }
6660
- get camera() {
6661
- return this._camera;
6662
- }
6663
- get renderer() {
6664
- return this._renderer;
6665
- }
6666
- get composer() {
6667
- return this._composer;
6668
- }
6669
- /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
6670
- get controls() {
6671
- return this._controls;
6672
- }
6673
- ///
6674
- };
6675
-
6676
- // src/skin/Skins.ts
6677
- var Skins = class {
6678
- //<editor-fold desc="Skins">
6679
- static async fromUuidOrUsername(uuidOrUsername) {
6680
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6681
- return this.fromUuid(uuidOrUsername);
6572
+ function addPointer(event) {
6573
+ pointers.push(event);
6682
6574
  }
6683
- return this.fromUsername(uuidOrUsername);
6684
- }
6685
- static async fromUuid(uuid) {
6686
- return this.getSkinProxySkinUrl(uuid);
6687
- }
6688
- static async fromUsername(username) {
6689
- return this.usernameToUuid(username).then((uuid) => {
6690
- if (uuid) {
6691
- return this.fromUuid(uuid);
6692
- }
6693
- return void 0;
6694
- });
6695
- }
6696
- static async fromMineSkin(mineskinId) {
6697
- return this.getMineSkin(mineskinId).then((mineskin) => {
6698
- if (mineskin) {
6699
- return mineskin["data"]["texture"]["value"]["urls"]["skins"];
6575
+ function removePointer(event) {
6576
+ delete pointerPositions[event.pointerId];
6577
+ for (let i = 0; i < pointers.length; i++) {
6578
+ if (pointers[i].pointerId == event.pointerId) {
6579
+ pointers.splice(i, 1);
6580
+ return;
6581
+ }
6700
6582
  }
6701
- return void 0;
6702
- });
6703
- }
6704
- //</editor-fold>
6705
- //<editor-fold desc="Capes">
6706
- static async capeFromUuidOrUsername(uuidOrUsername) {
6707
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6708
- return this.capeFromUuid(uuidOrUsername);
6709
6583
  }
6710
- return this.capeFromUsername(uuidOrUsername);
6711
- }
6712
- static async capeFromUuid(uuid) {
6713
- return this.getSkinProxyCapeUrl(uuid);
6714
- }
6715
- static async capeFromUsername(username) {
6716
- return this.usernameToUuid(username).then((uuid) => {
6717
- if (uuid) {
6718
- return this.capeFromUuid(uuid);
6719
- }
6720
- return void 0;
6721
- });
6722
- }
6723
- static async capeFromCapesDev(uuid, capeType = "minecraft") {
6724
- return this.getCapesDev(uuid, capeType).then((cape) => {
6725
- if (cape) {
6726
- return cape?.stillImageUrl;
6727
- }
6728
- return void 0;
6729
- });
6730
- }
6731
- //</editor-fold>
6732
- //<editor-fold desc="Helpers">
6733
- static async usernameToUuid(username) {
6734
- return this.usernameToUuidSkinProxy(username);
6735
- }
6736
- static async usernameToUuidSkinProxy(username) {
6737
- return Requests.genericRequest({
6738
- baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
6739
- url: "/uuid/" + username
6740
- }).then((res) => {
6741
- if (res.status === 200) {
6742
- return res.data["id"];
6743
- }
6744
- return void 0;
6745
- }).catch((err) => {
6746
- console.warn(err);
6747
- return void 0;
6748
- });
6749
- }
6750
- static async usernameToUuidMineTools(username) {
6751
- return Requests.genericRequest({
6752
- baseURL: "https://api.minetools.eu",
6753
- url: "/uuid/" + username
6754
- }).then((res) => {
6755
- if (res.status === 200) {
6756
- return res.data["id"];
6757
- }
6758
- return void 0;
6759
- }).catch((err) => {
6760
- console.warn(err);
6761
- return void 0;
6762
- });
6763
- }
6764
- static async getProfileFromMinetools(uuid) {
6765
- return Requests.genericRequest({
6766
- baseURL: "https://api.minetools.eu",
6767
- url: "/profile/" + uuid
6768
- }).then((res) => {
6769
- if (res.status === 200) {
6770
- return res.data;
6771
- }
6772
- });
6773
- }
6774
- static async getMineSkin(mineskinId) {
6775
- return Requests.genericRequest({
6776
- baseURL: "https://api.mineskin.org",
6777
- url: "/get/uuid/" + mineskinId
6778
- }).then((res) => {
6779
- if (res.status === 200) {
6780
- return res.data;
6781
- }
6782
- return void 0;
6783
- }).catch((err) => {
6784
- console.warn(err);
6785
- return void 0;
6786
- });
6787
- }
6788
- static async getCapesDev(uuid, type = "all") {
6789
- return Requests.genericRequest({
6790
- baseURL: "https://api.capes.dev",
6791
- url: "/load/" + uuid + "/" + type
6792
- }).then((res) => {
6793
- if (res.status === 200) {
6794
- return res.data;
6584
+ function trackPointer(event) {
6585
+ let position = pointerPositions[event.pointerId];
6586
+ if (position === void 0) {
6587
+ position = new import_three20.Vector2();
6588
+ pointerPositions[event.pointerId] = position;
6795
6589
  }
6796
- return void 0;
6797
- }).catch((err) => {
6798
- console.warn(err);
6799
- return void 0;
6800
- });
6801
- }
6802
- static getCrafatarSkinUrl(uuid) {
6803
- return "https://crafatar.com/skins/" + uuid;
6804
- }
6805
- static getCrafatarCapeUrl(uuid) {
6806
- return "https://crafatar.com/capes/" + uuid;
6807
- }
6808
- static getMcHeadsSkinUrl(uuid) {
6809
- return "https://mc-heads.net/skin/" + uuid;
6810
- }
6811
- static getMineSkinPlayerSkinUrl(uuid) {
6812
- return "https://mineskin.org/skin/player/" + uuid;
6813
- }
6814
- static getSkinProxySkinUrl(uuid) {
6815
- return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
6590
+ position.set(event.pageX, event.pageY);
6591
+ }
6592
+ function getSecondPointerPosition(event) {
6593
+ const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6594
+ return pointerPositions[pointer.pointerId];
6595
+ }
6596
+ scope.domElement.addEventListener("contextmenu", onContextMenu);
6597
+ scope.domElement.addEventListener("pointerdown", onPointerDown);
6598
+ scope.domElement.addEventListener("pointercancel", onPointerCancel);
6599
+ scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6600
+ this.update();
6816
6601
  }
6817
- static getSkinProxyCapeUrl(uuid) {
6818
- return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
6602
+ };
6603
+ var MapControls = class extends OrbitControls {
6604
+ constructor(object, domElement) {
6605
+ super(object, domElement);
6606
+ this.screenSpacePanning = false;
6607
+ this.mouseButtons.LEFT = import_three20.MOUSE.PAN;
6608
+ this.mouseButtons.RIGHT = import_three20.MOUSE.ROTATE;
6609
+ this.touches.ONE = import_three20.TOUCH.PAN;
6610
+ this.touches.TWO = import_three20.TOUCH.DOLLY_ROTATE;
6819
6611
  }
6820
- //</editor-fold>
6821
6612
  };
6822
6613
 
6823
6614
  // src/world/Chunk.ts
@@ -6880,7 +6671,7 @@ var MineRenderWorld = class {
6880
6671
  console.log("CHUNKS", this._chunks);
6881
6672
  for (let chunk of this._chunks.values()) {
6882
6673
  console.log("dispose chunk", chunk);
6883
- await chunk?.dispose();
6674
+ await (chunk == null ? void 0 : chunk.dispose());
6884
6675
  }
6885
6676
  this._chunks.clear();
6886
6677
  }
@@ -6934,7 +6725,7 @@ var MineRenderWorld = class {
6934
6725
  };
6935
6726
 
6936
6727
  // src/world/Chunk.ts
6937
- var p11 = prefix("Chunk");
6728
+ var p12 = prefix("Chunk");
6938
6729
  var Chunk = class _Chunk {
6939
6730
  constructor(scene, x, y, z) {
6940
6731
  this._blocks = [];
@@ -6986,7 +6777,7 @@ var Chunk = class _Chunk {
6986
6777
  const index = _Chunk.chunkPosToBlockIndex(pos);
6987
6778
  const current = this._blocks[index];
6988
6779
  if (typeof current !== "undefined") {
6989
- console.debug(p11, "deleting existing block at", pos, worldPos, index);
6780
+ console.debug(p12, "deleting existing block at", pos, worldPos, index);
6990
6781
  current.object.removeFromScene();
6991
6782
  delete this._blocks[index];
6992
6783
  }
@@ -7053,7 +6844,6 @@ var Chunk = class _Chunk {
7053
6844
  AXES,
7054
6845
  ArchiveAssetSource,
7055
6846
  AssetKey,
7056
- AssetLoadError,
7057
6847
  AssetLoader,
7058
6848
  AssetParser,
7059
6849
  AssetSource,
@@ -7111,7 +6901,6 @@ var Chunk = class _Chunk {
7111
6901
  OrbitControls,
7112
6902
  PersistentCache,
7113
6903
  Renderer,
7114
- RequestError,
7115
6904
  Requests,
7116
6905
  SKIN_PARTS,
7117
6906
  SceneInspector,