minerender 2.1.0-alpha.18 → 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);
@@ -1281,10 +1238,9 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1281
1238
  this.rootType = rootType;
1282
1239
  this.extension = extension;
1283
1240
  this.root = root;
1284
- this.isAssetKey = true;
1285
1241
  }
1286
1242
  static parse(assetType, str, origin) {
1287
- let namespace = origin?.namespace || DEFAULT_NAMESPACE;
1243
+ let namespace = (origin == null ? void 0 : origin.namespace) || DEFAULT_NAMESPACE;
1288
1244
  if (str.includes(":")) {
1289
1245
  let split2 = str.split(":");
1290
1246
  namespace = split2[0];
@@ -1297,15 +1253,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1297
1253
  split.shift();
1298
1254
  }
1299
1255
  let path = split.join("/");
1300
- const extension = assetType === "textures" ? ".png" : origin?.extension ?? ".json";
1301
- if (extension && path.endsWith(extension)) {
1302
- path = path.slice(0, -extension.length);
1303
- }
1304
- 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);
1305
1258
  }
1306
1259
  toString() {
1307
1260
  let a = [
1308
- this.root ?? AssetLoader.ROOT,
1261
+ typeof this.root !== "undefined" || AssetLoader.ROOT !== DEFAULT_ROOT ? this.root ?? AssetLoader.ROOT : "__root__",
1309
1262
  this.rootType ?? "__rootType__",
1310
1263
  this.assetType ?? "__assetType__",
1311
1264
  this.type ?? "__type__",
@@ -1315,12 +1268,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1315
1268
  return a.join("/");
1316
1269
  }
1317
1270
  getFullPath() {
1318
- let p12 = [];
1271
+ let p13 = [];
1319
1272
  if (this.type) {
1320
- p12.push(this.type);
1273
+ p13.push(this.type);
1321
1274
  }
1322
- p12.push(this.path);
1323
- return p12.join("/");
1275
+ p13.push(this.path);
1276
+ return p13.join("/");
1324
1277
  }
1325
1278
  toNamespacedString() {
1326
1279
  return this.namespace + ":" + this.getFullPath();
@@ -1330,10 +1283,10 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1330
1283
  }
1331
1284
  };
1332
1285
  function isBasicAssetKey(obj) {
1333
- return obj !== null && typeof obj === "object" && typeof obj.namespace === "string" && typeof obj.path === "string";
1286
+ return "namespace" in obj && "path" in obj;
1334
1287
  }
1335
1288
  function isAssetKey(obj) {
1336
- return isBasicAssetKey(obj) && obj.isAssetKey === true;
1289
+ return isBasicAssetKey(obj) && "parse" in obj;
1337
1290
  }
1338
1291
 
1339
1292
  // src/model/ModelMerger.ts
@@ -1342,10 +1295,10 @@ var ModelMerger = class {
1342
1295
  const models = await this.collectAllParents(model);
1343
1296
  let merged = {};
1344
1297
  for (let parentModel of models) {
1345
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1298
+ merged = (0, import_ts_deepmerge.default)(merged, parentModel);
1346
1299
  }
1347
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1348
- 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}`);
1349
1302
  merged.hierarchy.push(`${merged.parent}`);
1350
1303
  return merged;
1351
1304
  }
@@ -1355,7 +1308,6 @@ var ModelMerger = class {
1355
1308
  }
1356
1309
  const models = [];
1357
1310
  const parentKey = AssetKey.parse("models", model.parent);
1358
- parentKey.root = model.key?.root;
1359
1311
  const parentModel = await Models.getRaw(parentKey);
1360
1312
  if (parentModel) {
1361
1313
  models.unshift(parentModel);
@@ -1365,6 +1317,9 @@ var ModelMerger = class {
1365
1317
  }
1366
1318
  };
1367
1319
 
1320
+ // src/assets/Models.ts
1321
+ var import_typescript_memoize = require("typescript-memoize");
1322
+
1368
1323
  // src/assets/source/parser/AssetParsers.ts
1369
1324
  var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1370
1325
  AssetParser2["MODEL"] = "model";
@@ -1378,65 +1333,30 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1378
1333
  })(AssetParser || {});
1379
1334
 
1380
1335
  // src/assets/Models.ts
1381
- var Models = class _Models {
1336
+ var _Models = class _Models {
1382
1337
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1383
1338
  // the library, and would require an EnvProvider before any entry has had a chance to register
1384
1339
  static get PERSISTENT_CACHE() {
1385
1340
  return this._persistentCache ??= PersistentCache.open("minerender-models");
1386
1341
  }
1387
1342
  static async getItemList() {
1388
- const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
1389
- const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
1390
- return Caching.listAssetCache.get(key.serialize(), async () => {
1391
- return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
1392
- }).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) ?? []);
1393
1352
  }
1394
1353
  static async loadAndMerge(key) {
1395
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
1354
+ const model = await this.getRaw(key);
1396
1355
  if (!model) {
1397
1356
  return void 0;
1398
1357
  }
1399
1358
  return ModelMerger.mergeWithParents(model);
1400
1359
  }
1401
- static async getItemModel(key) {
1402
- const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1403
- const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
1404
- const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1405
- if (!result) return void 0;
1406
- if (result.key.assetType !== "items") return { ...result.asset, key };
1407
- const reference = this.defaultItemModel(result.asset.model, key);
1408
- const modelKey = AssetKey.parse("models", reference);
1409
- modelKey.root = key.root;
1410
- const model2 = await this.getRaw(modelKey);
1411
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
1412
- return model2;
1413
- });
1414
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1415
- }
1416
- // Item previews use the GUI context, false conditions, and zero numeric properties.
1417
- static defaultItemModel(node, key) {
1418
- if (!node || typeof node.type !== "string") {
1419
- throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
1420
- }
1421
- switch (node.type.replace(/^minecraft:/, "")) {
1422
- case "model":
1423
- if (typeof node.model === "string" && node.model) return node.model;
1424
- break;
1425
- case "condition":
1426
- return this.defaultItemModel(node.on_false, key);
1427
- case "select": {
1428
- 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;
1429
- return this.defaultItemModel(selected ?? node.fallback, key);
1430
- }
1431
- case "range_dispatch": {
1432
- const selected = node.entries?.reduce((match, entry) => {
1433
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
1434
- }, void 0);
1435
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
1436
- }
1437
- }
1438
- throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
1439
- }
1440
1360
  static async getRaw(key) {
1441
1361
  if (!key.assetType) {
1442
1362
  key.assetType = "models";
@@ -1475,15 +1395,19 @@ var Models = class _Models {
1475
1395
  return this.PERSISTENT_CACHE.clear();
1476
1396
  }
1477
1397
  };
1398
+ __decorateClass([
1399
+ (0, import_typescript_memoize.Memoize)()
1400
+ ], _Models, "getItemList", 1);
1401
+ var Models = _Models;
1478
1402
 
1479
1403
  // src/assets/BlockStates.ts
1404
+ var import_typescript_memoize2 = require("typescript-memoize");
1480
1405
  var BlockStates = class {
1481
1406
  static get PERSISTENT_CACHE() {
1482
1407
  return this._persistentCache ??= PersistentCache.open("minerender-blockstates");
1483
1408
  }
1484
- // BlockState names are hardcoded
1485
1409
  static async getList() {
1486
- const key = new AssetKey(
1410
+ return AssetLoader.get(new AssetKey(
1487
1411
  DEFAULT_NAMESPACE,
1488
1412
  "_list",
1489
1413
  "blockstates",
@@ -1491,16 +1415,11 @@ var BlockStates = class {
1491
1415
  "assets",
1492
1416
  ".json",
1493
1417
  DEFAULT_ROOT
1494
- );
1495
- return Caching.listAssetCache.get(key.serialize(), () => {
1496
- return AssetLoader.get(key, "list" /* LIST */);
1497
- }).then((r) => r?.files ?? []);
1418
+ ), "list" /* LIST */).then((r) => (r == null ? void 0 : r.files) ?? []);
1498
1419
  }
1499
1420
  static async getDefaultStates() {
1500
1421
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
1501
- return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
1502
- return AssetLoader.get(key, "json" /* JSON */);
1503
- });
1422
+ return AssetLoader.get(key, "json" /* JSON */);
1504
1423
  }
1505
1424
  static async getDefaultState(key) {
1506
1425
  const defaultStates = await this.getDefaultStates();
@@ -1539,11 +1458,17 @@ var BlockStates = class {
1539
1458
  await this.PERSISTENT_CACHE.clear();
1540
1459
  }
1541
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);
1542
1467
  var DefaultBlockStates = class {
1543
1468
  };
1544
1469
 
1545
1470
  // src/assets/Assets.ts
1546
- var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
1471
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
1547
1472
  var DEFAULT_NAMESPACE = "minecraft";
1548
1473
  var Assets = class {
1549
1474
  /**
@@ -1565,150 +1490,13 @@ var AssetSource = class {
1565
1490
  constructor() {
1566
1491
  }
1567
1492
  };
1568
- var AssetLoadError = class extends Error {
1569
- constructor(source, key, path, cause) {
1570
- super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
1571
- this.source = source;
1572
- this.key = key;
1573
- this.path = path;
1574
- this.cause = cause;
1575
- this.name = "AssetLoadError";
1576
- }
1577
- };
1578
1493
 
1579
- // src/util/BatchedExecutor.ts
1580
- var BatchedExecutor = class {
1581
- constructor(interval = 1, batch = 30) {
1582
- this.interval = interval;
1583
- this.batch = batch;
1584
- this.queue = [];
1585
- this.task = setInterval(() => this.run());
1586
- }
1587
- submit(task) {
1588
- this.queue.push(task);
1589
- }
1590
- run() {
1591
- for (let i = 0; i < this.batch; i++) {
1592
- this.runNext();
1593
- }
1594
- }
1595
- runNext() {
1596
- let next = this.queue.shift();
1597
- if (next) next();
1598
- }
1599
- };
1600
-
1601
- // src/util/model.ts
1602
- var import_three7 = require("three");
1603
- function applyElementRotation(rotation, geometry) {
1604
- const origin = new import_three7.Vector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1605
- geometry.translate(-origin.x, -origin.y, -origin.z);
1606
- switch (rotation.axis) {
1607
- case "x" /* X */:
1608
- geometry.rotateX(toRadians(rotation.angle));
1609
- break;
1610
- case "y" /* Y */:
1611
- geometry.rotateY(toRadians(rotation.angle));
1612
- break;
1613
- case "z" /* Z */:
1614
- geometry.rotateZ(toRadians(rotation.angle));
1615
- break;
1616
- }
1617
- if (rotation.rescale) {
1618
- if (Math.abs(rotation.angle) === 22.5) {
1619
- const s = 1 / Math.cos(0.39269909262657166);
1620
- geometry.scale(s, 1, s);
1621
- } else {
1622
- const s = 1 / Math.cos(0.7853981852531433);
1623
- geometry.scale(s, 1, s);
1624
- }
1625
- }
1626
- geometry.translate(origin.x, origin.y, origin.z);
1627
- }
1628
- function applyModelPartRotation(modelPart, geometry) {
1629
- const origin = new import_three7.Vector3(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1630
- geometry.translate(-origin.x, -origin.y, -origin.z);
1631
- geometry.rotateX(toRadians(modelPart.pitch));
1632
- geometry.rotateY(toRadians(modelPart.yaw));
1633
- geometry.rotateZ(toRadians(modelPart.roll));
1634
- geometry.translate(origin.x, origin.y, origin.z);
1635
- }
1636
- function applyGenericRotation(axis, rotation, obj) {
1637
- switch (axis) {
1638
- case "x" /* X */:
1639
- obj.rotateOnAxis(new import_three7.Vector3(1, 0, 0), toRadians(rotation));
1640
- break;
1641
- case "y" /* Y */:
1642
- obj.rotateOnAxis(new import_three7.Vector3(0, 1, 0), toRadians(rotation));
1643
- break;
1644
- case "z" /* Z */:
1645
- obj.rotateOnAxis(new import_three7.Vector3(0, 0, 1), toRadians(rotation));
1646
- break;
1647
- }
1648
- }
1649
- function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1650
- let size = new import_three7.Vector3();
1651
- box.getSize(size);
1652
- let boxGeo = new import_three7.BoxGeometry(size.x, size.y, size.z, 1, 1, 1);
1653
- let wireGeo = new import_three7.EdgesGeometry(boxGeo);
1654
- let wireMat = new import_three7.LineBasicMaterial({ color, linewidth: w });
1655
- let wireframe = new import_three7.LineSegments(wireGeo, wireMat);
1656
- obj.add(wireframe);
1657
- let axes = new import_three7.AxesHelper(1);
1658
- obj.add(axes);
1659
- }
1660
- function addWireframeToObject(obj, color = 16777215, w = 2) {
1661
- let boxGeo = new import_three7.BoxGeometry(16, 16, 16, 1, 1, 1);
1662
- let wireGeo = new import_three7.EdgesGeometry(boxGeo);
1663
- let wireMat = new import_three7.LineBasicMaterial({ color, linewidth: w });
1664
- let wireframe = new import_three7.LineSegments(wireGeo, wireMat);
1665
- obj.add(wireframe);
1666
- let axes = new import_three7.AxesHelper(1);
1667
- obj.add(axes);
1668
- }
1669
- function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1670
- let wireGeo = new import_three7.EdgesGeometry(geo);
1671
- let wireMat = new import_three7.LineBasicMaterial({ color, linewidth: w });
1672
- let wireframe = new import_three7.LineSegments(wireGeo, wireMat);
1673
- mesh.add(wireframe);
1674
- let axes = new import_three7.AxesHelper(1);
1675
- mesh.add(axes);
1676
- }
1677
-
1678
- // src/util/performance.ts
1679
- function captureException(e, ...extra) {
1680
- console.error(e, extra);
1681
- }
1682
- function timingStart(marker) {
1683
- console.time(marker);
1684
- }
1685
- function timingEnd(marker) {
1686
- console.timeEnd(marker);
1687
- }
1688
-
1689
- // src/util/three.ts
1690
- function isObject3D(obj) {
1691
- return obj.isObject3D;
1692
- }
1693
- function isMesh(obj) {
1694
- return obj.isMesh;
1695
- }
1696
- function isInstancedMesh(obj) {
1697
- return obj.isInstancedMesh;
1698
- }
1699
- function isPerspectiveCamera(obj) {
1700
- return obj.isPerspectiveCamera;
1701
- }
1702
- function isOrthographicCamera(obj) {
1703
- return obj.isOrthographicCamera;
1704
- }
1705
-
1706
- // src/nbt/NBTHelper.ts
1707
- var NBTHelper = class {
1708
- static async fromBuffer(buffer) {
1709
- const prismarineNbt = await import("prismarine-nbt");
1710
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1711
- 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;
1712
1500
  }
1713
1501
  };
1714
1502
 
@@ -1718,83 +1506,7 @@ var p3 = prefix("HostedAssetSource");
1718
1506
  var DEFAULT_OPTIONS = {
1719
1507
  retryDefaults: true
1720
1508
  };
1721
- var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1722
- static {
1723
- this.MODEL = {
1724
- config(request) {
1725
- },
1726
- parse(response) {
1727
- return response.data;
1728
- }
1729
- };
1730
- }
1731
- static {
1732
- this.BLOCKSTATE = {
1733
- config(request) {
1734
- },
1735
- parse(response) {
1736
- return response.data;
1737
- }
1738
- };
1739
- }
1740
- static {
1741
- this.META = {
1742
- config(request) {
1743
- },
1744
- parse(response) {
1745
- return response.data;
1746
- }
1747
- };
1748
- }
1749
- static {
1750
- this.NBT = {
1751
- config(request) {
1752
- request.responseType = "arraybuffer";
1753
- },
1754
- parse(response) {
1755
- return NBTHelper.fromBuffer(Buffer.from(response.data));
1756
- }
1757
- };
1758
- }
1759
- static {
1760
- this.IMAGE = {
1761
- config(request) {
1762
- request.responseType = "arraybuffer";
1763
- },
1764
- async parse(response) {
1765
- return await ImageLoader.processResponse(response);
1766
- }
1767
- };
1768
- }
1769
- static {
1770
- this.LIST = {
1771
- config(request) {
1772
- },
1773
- parse(response) {
1774
- return response.data;
1775
- }
1776
- };
1777
- }
1778
- static {
1779
- this.JSON = {
1780
- config(request) {
1781
- },
1782
- parse(response) {
1783
- return response.data;
1784
- }
1785
- };
1786
- }
1787
- static {
1788
- this.PARSER_MAP = /* @__PURE__ */ new Map([
1789
- ["model" /* MODEL */, _HostedAssetSource.MODEL],
1790
- ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
1791
- ["meta" /* META */, _HostedAssetSource.META],
1792
- ["nbt" /* NBT */, _HostedAssetSource.NBT],
1793
- ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
1794
- ["list" /* LIST */, _HostedAssetSource.LIST],
1795
- ["json" /* JSON */, _HostedAssetSource.JSON]
1796
- ]);
1797
- }
1509
+ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1798
1510
  async loadOrRetryWithDefaults(key, parser) {
1799
1511
  const direct = await this.load(key, parser);
1800
1512
  if (typeof direct !== "undefined") {
@@ -1829,25 +1541,31 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1829
1541
  console.info(p3, "Loading", key);
1830
1542
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1831
1543
  console.debug(p3, url);
1832
- const request = { url };
1833
- try {
1834
- parser.config(request);
1835
- let response;
1836
- try {
1837
- response = await Requests.mcAssetRequest(request);
1838
- } catch (cause) {
1839
- if (cause instanceof RequestError && cause.response?.status === 404) {
1840
- 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;
1841
1555
  }
1842
- throw cause;
1843
1556
  }
1844
- if (response.data === void 0) {
1845
- 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
+ }
1846
1565
  }
1847
- return await parser.parse(response);
1848
- } catch (cause) {
1849
- throw new AssetLoadError(this, key, request.url, cause);
1850
- }
1566
+ console.debug(p3, "Failed to load", key, err == null ? void 0 : err.message);
1567
+ return void 0;
1568
+ });
1851
1569
  }
1852
1570
  assetBasePath(key) {
1853
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 + "/" : ""}`;
@@ -1871,6 +1589,67 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1871
1589
  return this.load(key, responseParser);
1872
1590
  }
1873
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;
1874
1653
 
1875
1654
  // src/assets/source/archive/BrowserArchiveProxy.ts
1876
1655
  var import_zip = require("@zip.js/zip.js");
@@ -1893,6 +1672,7 @@ var BrowserArchiveProxy = class {
1893
1672
  };
1894
1673
 
1895
1674
  // src/assets/source/archive/ArchiveAssetSource.ts
1675
+ var p4 = prefix("ArchiveAssetSource");
1896
1676
  var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1897
1677
  constructor(archiveProxy) {
1898
1678
  super();
@@ -1911,31 +1691,74 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1911
1691
  }
1912
1692
  async get(key, parser) {
1913
1693
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
1914
- return this.load(key, responseParser);
1915
- }
1916
- async load(key, parser) {
1694
+ console.log("ArchiveAssetSource.get", key, parser);
1695
+ let entries = await this.getEntries();
1917
1696
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1918
- let url;
1919
- try {
1920
- const entry = await this.getEntry(path);
1921
- if (!entry) {
1922
- 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
+ }
1718
+ }
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
+ }
1923
1727
  }
1924
- url = URL.createObjectURL(await entry.getData());
1925
- const request = { url };
1926
- parser.config(request);
1927
- const response = await Requests.genericRequest(request);
1928
- if (response.data === void 0) {
1929
- throw new Error("Asset response has no data");
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
+ }
1930
1749
  }
1931
- return await parser.parse(response);
1932
- } catch (cause) {
1933
- throw new AssetLoadError(this, key, path, cause);
1934
- } finally {
1935
- if (url !== void 0) {
1936
- URL.revokeObjectURL(url);
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
+ }
1937
1758
  }
1938
- }
1759
+ console.debug(p4, "Failed to load", key, err == null ? void 0 : err.message);
1760
+ return void 0;
1761
+ });
1939
1762
  }
1940
1763
  assetBasePath(key) {
1941
1764
  return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1943,23 +1766,18 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1943
1766
  };
1944
1767
 
1945
1768
  // src/assets/AssetLoader.ts
1946
- var p4 = prefix("AssetLoader");
1947
- var AssetLoader = class {
1948
- static {
1949
- this.ROOT = DEFAULT_ROOT;
1950
- }
1951
- static {
1952
- this._SOURCES = [];
1953
- }
1769
+ var import_ts_deepmerge3 = __toESM(require_dist());
1770
+ var p5 = prefix("AssetLoader");
1771
+ var _AssetLoader = class _AssetLoader {
1954
1772
  static addSource(key, source, override = true) {
1955
1773
  if (override) {
1956
1774
  const existing = this.removeSource(key);
1957
1775
  if (existing) {
1958
- console.log(p4, "Removed existing AssetSource", key);
1776
+ console.log(p5, "Removed existing AssetSource", key);
1959
1777
  }
1960
1778
  }
1961
1779
  this._SOURCES.unshift({ key, source });
1962
- console.log(p4, "Added AssetSource", key);
1780
+ console.log(p5, "Added AssetSource", key);
1963
1781
  }
1964
1782
  static removeSource(key) {
1965
1783
  const index = this._SOURCES.findIndex((s) => s.key === key);
@@ -1971,11 +1789,8 @@ var AssetLoader = class {
1971
1789
  }
1972
1790
  return void 0;
1973
1791
  }
1974
- static {
1975
- this.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1976
- this.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1977
- }
1978
1792
  static async getAll(key, parser) {
1793
+ console.log(this._SOURCES);
1979
1794
  let promises = [];
1980
1795
  for (const source of this._SOURCES) {
1981
1796
  promises.push(source.source.get(key, parser));
@@ -1984,36 +1799,31 @@ var AssetLoader = class {
1984
1799
  return results.filter((r) => r != void 0);
1985
1800
  });
1986
1801
  }
1987
- /** Returns the first defined result in source-priority order, without merging assets. */
1988
1802
  static async get(key, parser) {
1989
- const keys = [key];
1990
- if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
1991
- keys.push(new AssetKey(
1992
- key.namespace,
1993
- key.path,
1994
- key.assetType === "structure" ? "structures" : "structure",
1995
- key.type,
1996
- key.rootType,
1997
- key.extension,
1998
- key.root
1999
- ));
2000
- }
2001
- return (await this.getFirst(keys, parser))?.asset;
2002
- }
2003
- /** Tries each path within a source before considering lower-priority sources. */
2004
- static async getFirst(keys, parser) {
2005
- const sources = [...this._SOURCES];
2006
- for (const source of sources) {
2007
- for (const key of keys) {
2008
- const result = await source.source.get(key, parser);
2009
- if (result !== void 0) {
2010
- 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;
2011
1816
  }
2012
1817
  }
2013
- }
2014
- return void 0;
1818
+ return void 0;
1819
+ });
2015
1820
  }
2016
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;
2017
1827
 
2018
1828
  // src/assets/ModelTextures.ts
2019
1829
  var ModelTextures = class {
@@ -2021,21 +1831,11 @@ var ModelTextures = class {
2021
1831
  return this._persistentMetaCache ??= PersistentCache.open("minerender-texturemeta");
2022
1832
  }
2023
1833
  static async get(key) {
2024
- const keyStr = key.serialize();
2025
- const pending = this.preload(key);
2026
- const cached = Caching.textureAssetCache.getIfPresent(keyStr);
2027
- try {
2028
- const asset = await pending;
2029
- if (asset) {
2030
- return await ImageLoader.infoToCanvasData(asset);
2031
- }
2032
- return void 0;
2033
- } catch (err) {
2034
- if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
2035
- Caching.textureAssetCache.invalidate(keyStr);
2036
- }
2037
- throw err;
1834
+ const asset = await this.preload(key);
1835
+ if (asset) {
1836
+ return ImageLoader.infoToCanvasData(asset);
2038
1837
  }
1838
+ return void 0;
2039
1839
  }
2040
1840
  static async preload(key) {
2041
1841
  const keyStr = key.serialize();
@@ -2109,28 +1909,7 @@ var CanvasImage = class {
2109
1909
  };
2110
1910
 
2111
1911
  // src/Ticker.ts
2112
- var Ticker = class _Ticker {
2113
- static {
2114
- this.TPS = 20;
2115
- }
2116
- static {
2117
- this.counter = 0;
2118
- }
2119
- static {
2120
- this._tickers = /* @__PURE__ */ new Map();
2121
- }
2122
- static {
2123
- this.oneSecondTps = 0;
2124
- }
2125
- static {
2126
- this.oneSecondTicks = 0;
2127
- }
2128
- static {
2129
- this.fiveSecondTps = 0;
2130
- }
2131
- static {
2132
- this.fiveSecondTicks = 0;
2133
- }
1912
+ var _Ticker = class _Ticker {
2134
1913
  static schedule(fn, ms) {
2135
1914
  const handle = setInterval(fn, ms);
2136
1915
  const unref = handle.unref;
@@ -2192,6 +1971,14 @@ var Ticker = class _Ticker {
2192
1971
  this._tickers.clear();
2193
1972
  }
2194
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;
2195
1982
 
2196
1983
  // src/texture/TextureAtlas.ts
2197
1984
  var TextureAtlas = class {
@@ -2217,9 +2004,6 @@ var TextureAtlas = class {
2217
2004
 
2218
2005
  // src/model/ModelGenerator.ts
2219
2006
  var ModelGenerator = class {
2220
- static {
2221
- this.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2222
- }
2223
2007
  static generateItemModel(imageData, layer) {
2224
2008
  const mainElement = {
2225
2009
  from: [0, 0, 7.5],
@@ -2239,9 +2023,10 @@ var ModelGenerator = class {
2239
2023
  return [mainElement];
2240
2024
  }
2241
2025
  };
2026
+ ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2242
2027
 
2243
2028
  // src/UVMapper.ts
2244
- var p5 = prefix("UVMapper");
2029
+ var p6 = prefix("UVMapper");
2245
2030
  var DEFAULT_UV = [0, 0, 16, 16];
2246
2031
  var X = 0;
2247
2032
  var Y = 1;
@@ -2414,11 +2199,12 @@ var UVMapper = class {
2414
2199
  return [tl, tr, bl, br];
2415
2200
  }
2416
2201
  static async createAtlas(originalModel) {
2202
+ var _a;
2417
2203
  const textureMap = {};
2418
2204
  const metaMap = {};
2419
2205
  const model = { ...originalModel };
2420
2206
  const isItemModel = !("elements" in model);
2421
- console.debug(p5, "Creating Atlas for", model.key);
2207
+ console.debug(p6, "Creating Atlas for", model.key);
2422
2208
  if (model.textures) {
2423
2209
  const promises = [];
2424
2210
  const uniqueTextureNames = [];
@@ -2432,7 +2218,7 @@ var UVMapper = class {
2432
2218
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
2433
2219
  promises.push(ModelTextures.get(assetKey).then((asset) => {
2434
2220
  if (!asset) {
2435
- console.warn(p5, "Missing texture", assetKey);
2221
+ console.warn(p6, "Missing texture", assetKey);
2436
2222
  return;
2437
2223
  }
2438
2224
  textureMap[textureKey] = new WrappedImage(asset);
@@ -2444,7 +2230,7 @@ var UVMapper = class {
2444
2230
  }
2445
2231
  await Promise.all(promises);
2446
2232
  const textureCount = uniqueTextureNames.length;
2447
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
2233
+ console.debug(p6, "Creating Atlas for", textureCount, "textures");
2448
2234
  this.fillMissingTextureKeys(model.textures, textureMap);
2449
2235
  this.fillMissingTextureKeys(model.textures, metaMap);
2450
2236
  const sizes = {};
@@ -2464,7 +2250,7 @@ var UVMapper = class {
2464
2250
  this.fillMissingTextureKeys(model.textures, sizes);
2465
2251
  const s = Math.ceil(Math.sqrt(textureCount + 1));
2466
2252
  const size = Math.ceil(s * maxWidth);
2467
- console.debug(p5, "Atlas size:", size);
2253
+ console.debug(p6, "Atlas size:", size);
2468
2254
  const squaredSize = size * size;
2469
2255
  const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
2470
2256
  const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
@@ -2493,15 +2279,16 @@ var UVMapper = class {
2493
2279
  if (texture.animated) {
2494
2280
  hasAnimation = true;
2495
2281
  const meta = metaMap[textureKey];
2496
- const frameTime = meta?.animation?.frametime ?? 1;
2282
+ const frameTime = ((_a = meta == null ? void 0 : meta.animation) == null ? void 0 : _a.frametime) ?? 1;
2497
2283
  console.log(meta);
2498
2284
  console.log(frameTime);
2499
2285
  let t = 0;
2500
2286
  let f = 0;
2501
2287
  animatorFunctions[textureKey] = () => {
2288
+ var _a2;
2502
2289
  if (t++ >= frameTime) {
2503
2290
  t = 0;
2504
- const frames = meta?.animation?.frames;
2291
+ const frames = (_a2 = meta == null ? void 0 : meta.animation) == null ? void 0 : _a2.frames;
2505
2292
  const frame = frames ? frames[f] : f;
2506
2293
  image.putData(texture.getFrameSectionData(frame), x, y, 0, 0, maxWidth, maxWidth);
2507
2294
  f++;
@@ -2519,10 +2306,10 @@ var UVMapper = class {
2519
2306
  }
2520
2307
  }
2521
2308
  const atlasImageData = image.toDataURL();
2522
- console.log(p5, "Atlas Image for", model.key, atlasImageData);
2309
+ console.log(p6, "Atlas Image for", model.key, atlasImageData);
2523
2310
  this.fillMissingTextureKeys(model.textures, positions);
2524
2311
  if (isItemModel) {
2525
- console.debug(p5, "Generating item model for", model);
2312
+ console.debug(p6, "Generating item model for", model);
2526
2313
  model.elements = [];
2527
2314
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2528
2315
  const textureImage = textureMap[layerName];
@@ -2530,7 +2317,7 @@ var UVMapper = class {
2530
2317
  model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2531
2318
  }
2532
2319
  }
2533
- console.debug(p5, "Item model elements", model.elements);
2320
+ console.debug(p6, "Item model elements", model.elements);
2534
2321
  }
2535
2322
  if (!model.elements) {
2536
2323
  }
@@ -2548,13 +2335,17 @@ var UVMapper = class {
2548
2335
  this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
2549
2336
  continue;
2550
2337
  }
2551
- if (!face.texture) continue;
2552
2338
  if (!face.uv) {
2553
2339
  face.uv = this.getFallbackUv(element, faceName);
2554
2340
  }
2555
- const faceTexture = face.texture.substr(1);
2556
- const texPosition = positions[faceTexture] || [0, 0];
2557
- 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
+ }
2558
2349
  let texPosV = new import_three8.Vector2(texPosition[0], texPosition[1]);
2559
2350
  const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
2560
2351
  tl.add(texPosV);
@@ -2586,7 +2377,7 @@ var UVMapper = class {
2586
2377
  hasTransparency
2587
2378
  );
2588
2379
  } else {
2589
- console.warn(p5, "Model does not have any textures", model);
2380
+ console.warn(p6, "Model does not have any textures", model);
2590
2381
  }
2591
2382
  return void 0;
2592
2383
  }
@@ -2724,20 +2515,17 @@ function shutdown() {
2724
2515
  }
2725
2516
 
2726
2517
  // src/assets/Entities.ts
2518
+ var import_typescript_memoize3 = require("typescript-memoize");
2727
2519
  var Entities = class {
2728
2520
  static async getBlockEntityModels() {
2729
2521
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
2730
2522
  console.log(key);
2731
- return Caching.entityModelsCache.get(key.serialize(), () => {
2732
- return AssetLoader.get(key, "json" /* JSON */);
2733
- });
2523
+ return AssetLoader.get(key, "json" /* JSON */);
2734
2524
  }
2735
2525
  static async getEntityModels() {
2736
2526
  const key = AssetKey.parse("models", "minerender:entityModels");
2737
2527
  console.log(key);
2738
- return Caching.entityModelsCache.get(key.serialize(), () => {
2739
- return AssetLoader.get(key, "json" /* JSON */);
2740
- });
2528
+ return AssetLoader.get(key, "json" /* JSON */);
2741
2529
  }
2742
2530
  // BlockEntity names are hardcoded
2743
2531
  static async getBlockList() {
@@ -2783,6 +2571,12 @@ var Entities = class {
2783
2571
  };
2784
2572
  }
2785
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);
2786
2580
  var EntityModels = class {
2787
2581
  };
2788
2582
  var BlockEntityModels = class {
@@ -2846,26 +2640,18 @@ var MineRenderError = class _MineRenderError extends Error {
2846
2640
  };
2847
2641
 
2848
2642
  // src/renderer/SceneObject.ts
2849
- var import_ts_deepmerge3 = __toESM(require_dist());
2850
- var p6 = prefix("SceneObject");
2851
- 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 {
2852
2646
  constructor(options) {
2853
2647
  super();
2854
2648
  this.isSceneObject = true;
2855
2649
  this.materialCallbacks = {};
2856
2650
  this._isInstanced = false;
2857
2651
  this._instanceCounter = 0;
2858
- this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2652
+ this.options = (0, import_ts_deepmerge4.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2859
2653
  console.log("SceneObject options", this.options);
2860
2654
  }
2861
- static {
2862
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
2863
- instanceMeshes: true,
2864
- maxInstanceCount: 50,
2865
- mergeMeshes: true,
2866
- wireframe: false
2867
- });
2868
- }
2869
2655
  set scene(scene) {
2870
2656
  if (!!this._scene) throw new MineRenderError("Scene already set");
2871
2657
  this._scene = scene;
@@ -3034,9 +2820,9 @@ var SceneObject = class _SceneObject extends import_three9.Object3D {
3034
2820
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3035
2821
  const i = this._instanceCounter++;
3036
2822
  this.setMatrixAt(i, new import_three9.Matrix4());
3037
- console.debug(p6, "nextInstance " + i);
2823
+ console.debug(p7, "nextInstance " + i);
3038
2824
  if (i === this.options.maxInstanceCount) {
3039
- console.warn(p6, "Max instance count reached for " + this);
2825
+ console.warn(p7, "Max instance count reached for " + this);
3040
2826
  }
3041
2827
  if (this.scene) {
3042
2828
  this.scene.stats.instanceCount++;
@@ -3207,29 +2993,34 @@ var SceneObject = class _SceneObject extends import_three9.Object3D {
3207
2993
  this.notifyDirty();
3208
2994
  }
3209
2995
  removeFromScene() {
3210
- this._scene?.remove(this);
2996
+ var _a;
2997
+ (_a = this._scene) == null ? void 0 : _a.remove(this);
3211
2998
  this.notifyDirty();
3212
2999
  }
3213
3000
  //</editor-fold>
3214
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;
3215
3009
  function isSceneObject(obj) {
3216
3010
  return obj.isSceneObject;
3217
3011
  }
3218
3012
 
3219
3013
  // src/entity/scene/EntityObject.ts
3220
- var import_ts_deepmerge4 = __toESM(require_dist());
3014
+ var import_ts_deepmerge5 = __toESM(require_dist());
3221
3015
  var import_three11 = require("three");
3222
- var THREE3 = __toESM(require("three"));
3016
+ var THREE2 = __toESM(require("three"));
3223
3017
  var EntityObject = class extends SceneObject {
3224
3018
  constructor(entity, options) {
3225
3019
  super();
3226
3020
  this.entity = entity;
3227
3021
  this.isEntityObject = true;
3228
3022
  this.meshesCreated = false;
3229
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3230
- }
3231
- static {
3232
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3023
+ this.options = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3233
3024
  }
3234
3025
  async init() {
3235
3026
  this.createMeshes();
@@ -3238,19 +3029,17 @@ var EntityObject = class extends SceneObject {
3238
3029
  dispose() {
3239
3030
  super.dispose();
3240
3031
  }
3241
- get textureKey() {
3242
- return new AssetKey(
3243
- 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,
3244
3036
  this.entity.key.path,
3245
3037
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
3246
3038
  "textures",
3247
3039
  "entity",
3248
3040
  "assets",
3249
3041
  ".png"
3250
- );
3251
- }
3252
- async loadTextures() {
3253
- this.imageData = await ModelTextures.get(this.textureKey);
3042
+ ));
3254
3043
  }
3255
3044
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3256
3045
  createMeshes(force = false) {
@@ -3269,8 +3058,8 @@ var EntityObject = class extends SceneObject {
3269
3058
  const l = cube.maxZ - cube.minZ;
3270
3059
  const uv = texture.toUvArray(w, h, l);
3271
3060
  const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3272
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3273
- 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));
3274
3063
  applyModelPartRotation(part, cubeGeo);
3275
3064
  const mesh = this.createMesh(partName, cubeGeo, mat);
3276
3065
  partAnchor.add(mesh);
@@ -3283,25 +3072,24 @@ var EntityObject = class extends SceneObject {
3283
3072
  this.meshesCreated = true;
3284
3073
  }
3285
3074
  async applyTextures() {
3286
- const assetKeyStr = this.textureKey.serialize();
3287
- const keyStr = `entity:${assetKeyStr}`;
3288
- let mat = Caching.materialCache.getIfPresent(keyStr);
3289
- if (!mat) {
3290
- const pending = this.loadTextures();
3291
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3292
- await pending;
3293
- if (!this.imageData) return;
3294
- const canvas = this.imageData.data.canvas;
3295
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3296
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3297
- this.imageData = void 0;
3298
- }
3299
- this.iterateAllMeshes((mesh) => {
3300
- mesh.material = mat;
3301
- });
3302
- 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
+ }
3303
3090
  }
3304
3091
  };
3092
+ EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3305
3093
  function isEntityObject(obj) {
3306
3094
  return obj.isEntityObject;
3307
3095
  }
@@ -3313,7 +3101,7 @@ var GuiObject = class extends SceneObject {
3313
3101
 
3314
3102
  // src/inspector/SceneInspector.ts
3315
3103
  var import_three12 = require("three");
3316
- var p7 = prefix("SceneInspector");
3104
+ var p8 = prefix("SceneInspector");
3317
3105
  var help = "<span>Ctrl+Click to Select<br/></span><br/>";
3318
3106
  var SceneInspector = class {
3319
3107
  constructor(renderer) {
@@ -3342,7 +3130,8 @@ var SceneInspector = class {
3342
3130
  return out;
3343
3131
  }
3344
3132
  onClick(event) {
3345
- if (event.target?.nodeName !== "CANVAS") return;
3133
+ var _a;
3134
+ if (((_a = event.target) == null ? void 0 : _a.nodeName) !== "CANVAS") return;
3346
3135
  if (!event.ctrlKey) return;
3347
3136
  setTimeout(() => {
3348
3137
  this.mouse.x = event.clientX / window.innerWidth * 2 - 1;
@@ -3382,7 +3171,7 @@ var SceneInspector = class {
3382
3171
  }
3383
3172
  selectObject(targetObject, targetIntersection) {
3384
3173
  this.selectedObject = targetObject;
3385
- console.log(p7, "selected", targetObject);
3174
+ console.log(p8, "selected", targetObject);
3386
3175
  this.redraw(targetObject, targetIntersection);
3387
3176
  }
3388
3177
  redraw(targetObject, targetIntersection) {
@@ -3680,7 +3469,7 @@ var SceneStatsDisplay = class {
3680
3469
  };
3681
3470
 
3682
3471
  // src/instance/InstanceManager.ts
3683
- var p8 = prefix("InstanceManager");
3472
+ var p9 = prefix("InstanceManager");
3684
3473
  var InstanceManager = class {
3685
3474
  constructor() {
3686
3475
  this.isInstanceManager = true;
@@ -3688,7 +3477,7 @@ var InstanceManager = class {
3688
3477
  }
3689
3478
  async get(key) {
3690
3479
  if (key in this.instanceCache) {
3691
- console.debug(p8, "key in cache", key);
3480
+ console.debug(p9, "key in cache", key);
3692
3481
  return (await this.instanceCache[key]).nextInstance();
3693
3482
  }
3694
3483
  return void 0;
@@ -3697,17 +3486,13 @@ var InstanceManager = class {
3697
3486
  if (key in this.instanceCache) {
3698
3487
  return await this.get(key);
3699
3488
  }
3700
- console.debug(p8, "key not in cache", key);
3701
- const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
3702
- this.instanceCache[key] = pending;
3703
- try {
3704
- return await pending;
3705
- } catch (error) {
3706
- if (this.instanceCache[key] === pending) {
3707
- delete this.instanceCache[key];
3708
- }
3709
- throw error;
3710
- }
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];
3711
3496
  }
3712
3497
  reset() {
3713
3498
  for (let instanceCacheKey in this.instanceCache) {
@@ -4296,28 +4081,26 @@ function computeMorphedAttributes(object) {
4296
4081
  }
4297
4082
 
4298
4083
  // src/model/scene/ModelObject.ts
4299
- var import_ts_deepmerge5 = __toESM(require_dist());
4300
- var p9 = prefix("ModelObject");
4301
- 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 {
4302
4087
  constructor(originalModel, options) {
4303
4088
  super(options);
4304
4089
  this.originalModel = originalModel;
4305
4090
  this.isModelObject = true;
4306
4091
  this.meshesCreated = false;
4307
- this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4092
+ this.options = (0, import_ts_deepmerge6.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4308
4093
  console.log("ModelObject options", this.options);
4309
4094
  }
4310
- static {
4311
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4312
- }
4313
4095
  async init() {
4314
4096
  await this.loadTextures();
4315
4097
  this.createMeshes();
4316
4098
  this.applyTextures();
4317
4099
  }
4318
4100
  dispose() {
4101
+ var _a;
4319
4102
  super.dispose();
4320
- this.atlas?.dispose();
4103
+ (_a = this.atlas) == null ? void 0 : _a.dispose();
4321
4104
  }
4322
4105
  get textureAtlas() {
4323
4106
  return this.atlas;
@@ -4327,12 +4110,13 @@ var ModelObject = class _ModelObject extends SceneObject {
4327
4110
  this.atlas = await UVMapper.getAtlas(this.originalModel);
4328
4111
  }
4329
4112
  createMeshes(force = false) {
4113
+ var _a;
4330
4114
  if (this.meshesCreated && !force) return;
4331
4115
  const mat = Materials.MISSING_TEXTURE;
4332
4116
  let allGeos = [];
4333
4117
  if (this.atlas) {
4334
4118
  if (this.atlas.model.elements) {
4335
- this.atlas.model.elements?.forEach((el) => {
4119
+ (_a = this.atlas.model.elements) == null ? void 0 : _a.forEach((el) => {
4336
4120
  const elGeo = this._getBoxGeometryFromElement(el).clone();
4337
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));
4338
4122
  elGeo.applyMatrix4(new import_three15.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
@@ -4350,10 +4134,10 @@ var ModelObject = class _ModelObject extends SceneObject {
4350
4134
  }
4351
4135
  });
4352
4136
  } else {
4353
- console.debug(p9, this.atlas.model, "has no elements");
4137
+ console.debug(p10, this.atlas.model, "has no elements");
4354
4138
  }
4355
4139
  } else {
4356
- console.debug(p9, "Missing atlas for", this);
4140
+ console.debug(p10, "Missing atlas for", this);
4357
4141
  }
4358
4142
  if (this.options.mergeMeshes) {
4359
4143
  let combinedGeo;
@@ -4405,25 +4189,17 @@ var ModelObject = class _ModelObject extends SceneObject {
4405
4189
  }
4406
4190
  }
4407
4191
  };
4192
+ _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4193
+ var ModelObject = _ModelObject;
4408
4194
  function isModelObject(obj) {
4409
4195
  return obj.isModelObject;
4410
4196
  }
4411
4197
 
4412
4198
  // src/model/block/scene/BlockObject.ts
4413
- var import_ts_deepmerge6 = __toESM(require_dist());
4199
+ var import_ts_deepmerge7 = __toESM(require_dist());
4414
4200
  var import_three16 = require("three");
4415
- var p10 = prefix("BlockObject");
4416
- function matchesCondition(condition, state) {
4417
- return Object.entries(condition).every(([key, value]) => {
4418
- if (Array.isArray(value)) {
4419
- if (key === "OR") return value.some((child) => matchesCondition(child, state));
4420
- if (key === "AND") return value.every((child) => matchesCondition(child, state));
4421
- return false;
4422
- }
4423
- return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4424
- });
4425
- }
4426
- var BlockObject = class _BlockObject extends SceneObject {
4201
+ var p11 = prefix("BlockObject");
4202
+ var _BlockObject = class _BlockObject extends SceneObject {
4427
4203
  constructor(blockState, options) {
4428
4204
  super(options);
4429
4205
  this.blockState = blockState;
@@ -4436,16 +4212,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4436
4212
  this._instanceModel = [];
4437
4213
  this._variants = [];
4438
4214
  this._models = [];
4439
- this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4440
- }
4441
- static {
4442
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
4443
- applyDefaultState: true
4444
- });
4215
+ this.options = (0, import_ts_deepmerge7.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4445
4216
  }
4446
4217
  async init() {
4447
4218
  if (this.options.applyDefaultState) {
4448
- 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;
4449
4220
  if (defaultState && Object.keys(defaultState).length > 0) {
4450
4221
  const state = {};
4451
4222
  for (let k in defaultState) {
@@ -4456,10 +4227,16 @@ var BlockObject = class _BlockObject extends SceneObject {
4456
4227
  if (this.blockState.variants) {
4457
4228
  await this.setState(Object.keys(this.blockState.variants)[0]);
4458
4229
  } else if (this.blockState.multipart) {
4459
- const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4460
- const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4461
- await this.setState(state);
4462
- }
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
+ }
4463
4240
  }
4464
4241
  } else {
4465
4242
  await this.recreateModels();
@@ -4515,11 +4292,55 @@ var BlockObject = class _BlockObject extends SceneObject {
4515
4292
  } else if (this.blockState.multipart) {
4516
4293
  for (let part of this.blockState.multipart) {
4517
4294
  if (!part.apply) {
4518
- console.debug(p10, "Missing apply for blockState part", part);
4295
+ console.debug(p11, "Missing apply for blockState part", part);
4519
4296
  continue;
4520
4297
  }
4521
- if (!part.when || matchesCondition(part.when, state)) {
4298
+ if (!part.when) {
4522
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
+ }
4523
4344
  }
4524
4345
  }
4525
4346
  }
@@ -4549,21 +4370,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4549
4370
  }
4550
4371
  }
4551
4372
  getSingleVariant(variants) {
4552
- if (!Array.isArray(variants)) return variants;
4553
- if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4554
- const total = variants.reduce((sum, variant) => {
4555
- const weight = variant.weight ?? 1;
4556
- if (!Number.isInteger(weight) || weight < 1) {
4557
- throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4558
- }
4559
- return sum + weight;
4560
- }, 0);
4561
- let choice = Math.random() * total;
4562
- for (const variant of variants) {
4563
- choice -= variant.weight ?? 1;
4564
- if (choice < 0) return variant;
4565
- }
4566
- return variants[variants.length - 1];
4373
+ if (Array.isArray(variants)) {
4374
+ return variants[0];
4375
+ } else {
4376
+ return variants;
4377
+ }
4567
4378
  }
4568
4379
  // @deprecated
4569
4380
  async createAVariant(variants, instanceInfo) {
@@ -4589,6 +4400,9 @@ var BlockObject = class _BlockObject extends SceneObject {
4589
4400
  }
4590
4401
  }
4591
4402
  obj.setRotation(rotation);
4403
+ setTimeout(() => {
4404
+ obj.setRotation(rotation);
4405
+ }, 150);
4592
4406
  console.log(obj);
4593
4407
  return obj;
4594
4408
  }
@@ -4679,15 +4493,18 @@ var BlockObject = class _BlockObject extends SceneObject {
4679
4493
  }
4680
4494
  }
4681
4495
  setPosition(position) {
4682
- this.position.copy(position);
4496
+ super.setPosition(position);
4683
4497
  for (let model of this._models) {
4684
4498
  model.setPosition(position);
4685
4499
  }
4686
- this.notifyDirty();
4687
4500
  }
4688
4501
  //TODO: should override rotation + scale methods
4689
4502
  //TODO
4690
4503
  };
4504
+ _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge7.default)({}, ModelObject.DEFAULT_OPTIONS, {
4505
+ applyDefaultState: true
4506
+ });
4507
+ var BlockObject = _BlockObject;
4691
4508
  function isBlockObject(obj) {
4692
4509
  return obj.isBlockObject;
4693
4510
  }
@@ -4712,10 +4529,11 @@ var StructureParser = class {
4712
4529
  throw new MineRenderError("Structure does not have palette(s)");
4713
4530
  }
4714
4531
  const blocks = nbt.blocks.value.value.map((block) => {
4532
+ var _a;
4715
4533
  const state = palette.value.value[block.state.value];
4716
4534
  if (state.Name.value === "minecraft:air") return void 0;
4717
4535
  const props = {};
4718
- for (let k in state.Properties?.value) {
4536
+ for (let k in (_a = state.Properties) == null ? void 0 : _a.value) {
4719
4537
  props[k] = state.Properties.value[k].value;
4720
4538
  }
4721
4539
  return {
@@ -4734,7 +4552,7 @@ var StructureParser = class {
4734
4552
 
4735
4553
  // src/renderer/MineRenderScene.ts
4736
4554
  var import_three17 = require("three");
4737
- var import_ts_deepmerge8 = __toESM(require_dist());
4555
+ var import_ts_deepmerge9 = __toESM(require_dist());
4738
4556
 
4739
4557
  // src/skin/SkinPart.ts
4740
4558
  var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
@@ -5465,7 +5283,7 @@ var slimSkinGeometries = {
5465
5283
  };
5466
5284
 
5467
5285
  // src/skin/scene/SkinObject.ts
5468
- var import_ts_deepmerge7 = __toESM(require_dist());
5286
+ var import_ts_deepmerge8 = __toESM(require_dist());
5469
5287
  var SkinObject = class extends SceneObject {
5470
5288
  constructor(options) {
5471
5289
  super();
@@ -5473,7 +5291,7 @@ var SkinObject = class extends SceneObject {
5473
5291
  this.legacy = false;
5474
5292
  this.skinTextureWidth = 64;
5475
5293
  this.skinTextureHeight = 64;
5476
- this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5294
+ this.options = (0, import_ts_deepmerge8.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5477
5295
  }
5478
5296
  async init() {
5479
5297
  this.createMeshes();
@@ -5577,7 +5395,7 @@ var SkinObject = class extends SceneObject {
5577
5395
  };
5578
5396
 
5579
5397
  // src/renderer/MineRenderScene.ts
5580
- var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5398
+ var _MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5581
5399
  constructor(options) {
5582
5400
  super();
5583
5401
  this.isMineRenderScene = true;
@@ -5586,14 +5404,12 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5586
5404
  this.dirty = true;
5587
5405
  this.observedObjects = /* @__PURE__ */ new Set();
5588
5406
  this.onObjectChange = (event) => {
5589
- if (event.target?.parent === this) {
5407
+ var _a;
5408
+ if (((_a = event.target) == null ? void 0 : _a.parent) === this) {
5590
5409
  this.dirty = true;
5591
5410
  }
5592
5411
  };
5593
- this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5594
- }
5595
- static {
5596
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
5412
+ this.options = (0, import_ts_deepmerge9.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5597
5413
  }
5598
5414
  add(...objects) {
5599
5415
  for (const object of objects) {
@@ -5601,7 +5417,7 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5601
5417
  try {
5602
5418
  super.add(object);
5603
5419
  } finally {
5604
- if (object?.isObject3D && object !== this) {
5420
+ if ((object == null ? void 0 : object.isObject3D) && object !== this) {
5605
5421
  this.updateObjectRegistration(object, object.parent === this);
5606
5422
  }
5607
5423
  }
@@ -5644,12 +5460,13 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5644
5460
  return this.add(...object);
5645
5461
  }
5646
5462
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
5463
+ var _a, _b;
5647
5464
  console.log("addSceneObject", asset);
5648
5465
  console.log("parent", parent);
5649
5466
  console.log(_options);
5650
5467
  this.dirty = true;
5651
5468
  const obj = await objectSupplier();
5652
- 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") {
5653
5470
  console.log("instanceMeshes + key");
5654
5471
  const key = asset.key.serialize();
5655
5472
  return this.instanceManager.getOrCreate(key, async () => {
@@ -5689,1139 +5506,1109 @@ var MineRenderScene = class _MineRenderScene extends import_three17.Scene {
5689
5506
  return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
5690
5507
  }
5691
5508
  };
5509
+ _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {});
5510
+ var MineRenderScene = _MineRenderScene;
5692
5511
  function isMineRenderScene(obj) {
5693
5512
  return obj.isMineRenderScene;
5694
5513
  }
5695
5514
 
5696
5515
  // src/renderer/Renderer.ts
5697
- var import_three19 = require("three");
5698
- var import_ts_deepmerge9 = __toESM(require_dist());
5516
+ var import_three18 = require("three");
5517
+ var import_ts_deepmerge10 = __toESM(require_dist());
5699
5518
  var import_stats = __toESM(require("stats.js"));
5700
5519
  var import_postprocessing = require("postprocessing");
5701
-
5702
- // src/three/OrbitControls.js
5703
- var import_three18 = require("three");
5704
- var _changeEvent = { type: "change" };
5705
- var _startEvent = { type: "start" };
5706
- var _endEvent = { type: "end" };
5707
- var OrbitControls = class extends import_three18.EventDispatcher {
5708
- constructor(object, domElement) {
5709
- super();
5710
- if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5711
- if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5712
- this.object = object;
5713
- this.domElement = domElement;
5714
- this.domElement.style.touchAction = "none";
5715
- this.enabled = true;
5716
- this.target = new import_three18.Vector3();
5717
- this.minDistance = 0;
5718
- this.maxDistance = Infinity;
5719
- this.minZoom = 0;
5720
- this.maxZoom = Infinity;
5721
- this.minPolarAngle = 0;
5722
- this.maxPolarAngle = Math.PI;
5723
- this.minAzimuthAngle = -Infinity;
5724
- this.maxAzimuthAngle = Infinity;
5725
- this.enableDamping = false;
5726
- this.dampingFactor = 0.05;
5727
- this.enableZoom = true;
5728
- this.zoomSpeed = 1;
5729
- this.enableRotate = true;
5730
- this.rotateSpeed = 1;
5731
- this.enablePan = true;
5732
- this.panSpeed = 1;
5733
- this.screenSpacePanning = true;
5734
- this.keyPanSpeed = 7;
5735
- this.autoRotate = false;
5736
- this.autoRotateSpeed = 2;
5737
- this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5738
- this.mouseButtons = { LEFT: import_three18.MOUSE.ROTATE, MIDDLE: import_three18.MOUSE.DOLLY, RIGHT: import_three18.MOUSE.PAN };
5739
- this.touches = { ONE: import_three18.TOUCH.ROTATE, TWO: import_three18.TOUCH.DOLLY_PAN };
5740
- this.target0 = this.target.clone();
5741
- this.position0 = this.object.position.clone();
5742
- this.zoom0 = this.object.zoom;
5743
- this._domElementKeyEvents = null;
5744
- this.getPolarAngle = function() {
5745
- return spherical.phi;
5746
- };
5747
- this.getAzimuthalAngle = function() {
5748
- return spherical.theta;
5749
- };
5750
- this.getDistance = function() {
5751
- return this.object.position.distanceTo(this.target);
5752
- };
5753
- this.saveState = function() {
5754
- scope.target0.copy(scope.target);
5755
- scope.position0.copy(scope.object.position);
5756
- scope.zoom0 = scope.object.zoom;
5757
- };
5758
- this.reset = function() {
5759
- scope.target.copy(scope.target0);
5760
- scope.object.position.copy(scope.position0);
5761
- scope.object.zoom = scope.zoom0;
5762
- scope.object.updateProjectionMatrix();
5763
- scope.dispatchEvent(_changeEvent);
5764
- scope.update();
5765
- state = STATE.NONE;
5766
- };
5767
- this.update = function() {
5768
- const offset = new import_three18.Vector3();
5769
- const quat = new import_three18.Quaternion().setFromUnitVectors(object.up, new import_three18.Vector3(0, 1, 0));
5770
- const quatInverse = quat.clone().invert();
5771
- const lastPosition = new import_three18.Vector3();
5772
- const lastQuaternion = new import_three18.Quaternion();
5773
- const twoPI = 2 * Math.PI;
5774
- return function update() {
5775
- const position = scope.object.position;
5776
- offset.copy(position).sub(scope.target);
5777
- offset.applyQuaternion(quat);
5778
- spherical.setFromVector3(offset);
5779
- if (scope.autoRotate && state === STATE.NONE) {
5780
- rotateLeft(getAutoRotationAngle());
5781
- }
5782
- if (scope.enableDamping) {
5783
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5784
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5785
- } else {
5786
- spherical.theta += sphericalDelta.theta;
5787
- spherical.phi += sphericalDelta.phi;
5788
- }
5789
- let min = scope.minAzimuthAngle;
5790
- let max = scope.maxAzimuthAngle;
5791
- if (isFinite(min) && isFinite(max)) {
5792
- if (min < -Math.PI) min += twoPI;
5793
- else if (min > Math.PI) min -= twoPI;
5794
- if (max < -Math.PI) max += twoPI;
5795
- else if (max > Math.PI) max -= twoPI;
5796
- if (min <= max) {
5797
- spherical.theta = Math.max(min, Math.min(max, spherical.theta));
5798
- } else {
5799
- spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
5800
- }
5801
- }
5802
- spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5803
- spherical.makeSafe();
5804
- spherical.radius *= scale;
5805
- spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5806
- if (scope.enableDamping === true) {
5807
- scope.target.addScaledVector(panOffset, scope.dampingFactor);
5808
- } else {
5809
- scope.target.add(panOffset);
5810
- }
5811
- offset.setFromSpherical(spherical);
5812
- offset.applyQuaternion(quatInverse);
5813
- position.copy(scope.target).add(offset);
5814
- scope.object.lookAt(scope.target);
5815
- if (scope.enableDamping === true) {
5816
- sphericalDelta.theta *= 1 - scope.dampingFactor;
5817
- sphericalDelta.phi *= 1 - scope.dampingFactor;
5818
- panOffset.multiplyScalar(1 - scope.dampingFactor);
5819
- } else {
5820
- sphericalDelta.set(0, 0, 0);
5821
- panOffset.set(0, 0, 0);
5822
- }
5823
- scale = 1;
5824
- if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5825
- scope.dispatchEvent(_changeEvent);
5826
- lastPosition.copy(scope.object.position);
5827
- lastQuaternion.copy(scope.object.quaternion);
5828
- zoomChanged = false;
5829
- return true;
5830
- }
5831
- return false;
5832
- };
5833
- }();
5834
- this.dispose = function() {
5835
- scope.domElement.removeEventListener("contextmenu", onContextMenu);
5836
- scope.domElement.removeEventListener("pointerdown", onPointerDown);
5837
- scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5838
- scope.domElement.removeEventListener("wheel", onMouseWheel);
5839
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5840
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5841
- if (scope._domElementKeyEvents !== null) {
5842
- scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
5843
- }
5844
- };
5845
- const scope = this;
5846
- const STATE = {
5847
- NONE: -1,
5848
- ROTATE: 0,
5849
- DOLLY: 1,
5850
- PAN: 2,
5851
- TOUCH_ROTATE: 3,
5852
- TOUCH_PAN: 4,
5853
- TOUCH_DOLLY_PAN: 5,
5854
- 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;
5855
5531
  };
5856
- let state = STATE.NONE;
5857
- const EPS = 1e-6;
5858
- const spherical = new import_three18.Spherical();
5859
- const sphericalDelta = new import_three18.Spherical();
5860
- let scale = 1;
5861
- const panOffset = new import_three18.Vector3();
5862
- let zoomChanged = false;
5863
- const rotateStart = new import_three18.Vector2();
5864
- const rotateEnd = new import_three18.Vector2();
5865
- const rotateDelta = new import_three18.Vector2();
5866
- const panStart = new import_three18.Vector2();
5867
- const panEnd = new import_three18.Vector2();
5868
- const panDelta = new import_three18.Vector2();
5869
- const dollyStart = new import_three18.Vector2();
5870
- const dollyEnd = new import_three18.Vector2();
5871
- const dollyDelta = new import_three18.Vector2();
5872
- const pointers = [];
5873
- const pointerPositions = {};
5874
- function getAutoRotationAngle() {
5875
- 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);
5876
5542
  }
5877
- function getZoomScale() {
5878
- 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
+ );
5879
5568
  }
5880
- function rotateLeft(angle) {
5881
- 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 }));
5882
5596
  }
5883
- function rotateUp(angle) {
5884
- 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);
5885
5609
  }
5886
- const panLeft = function() {
5887
- const v = new import_three18.Vector3();
5888
- return function panLeft2(distance, objectMatrix) {
5889
- v.setFromMatrixColumn(objectMatrix, 0);
5890
- v.multiplyScalar(-distance);
5891
- panOffset.add(v);
5892
- };
5893
- }();
5894
- const panUp = function() {
5895
- const v = new import_three18.Vector3();
5896
- return function panUp2(distance, objectMatrix) {
5897
- if (scope.screenSpacePanning === true) {
5898
- v.setFromMatrixColumn(objectMatrix, 1);
5899
- } else {
5900
- v.setFromMatrixColumn(objectMatrix, 0);
5901
- v.crossVectors(scope.object.up, v);
5902
- }
5903
- v.multiplyScalar(distance);
5904
- panOffset.add(v);
5905
- };
5906
- }();
5907
- const pan = function() {
5908
- const offset = new import_three18.Vector3();
5909
- return function pan2(deltaX, deltaY) {
5910
- const element = scope.domElement;
5911
- if (scope.object.isPerspectiveCamera) {
5912
- const position = scope.object.position;
5913
- offset.copy(position).sub(scope.target);
5914
- let targetDistance = offset.length();
5915
- targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
5916
- panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
5917
- panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
5918
- } else if (scope.object.isOrthographicCamera) {
5919
- panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
5920
- panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
5921
- } else {
5922
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
5923
- scope.enablePan = false;
5924
- }
5925
- };
5926
- }();
5927
- function dollyOut(dollyScale) {
5928
- if (scope.object.isPerspectiveCamera) {
5929
- scale /= dollyScale;
5930
- } else if (scope.object.isOrthographicCamera) {
5931
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
5932
- scope.object.updateProjectionMatrix();
5933
- zoomChanged = true;
5934
- } else {
5935
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5936
- scope.enableZoom = false;
5937
- }
5610
+ if (this.options.debug.axes) {
5611
+ const axesHelper = new import_three18.AxesHelper(64);
5612
+ this._debugHelpers.push(axesHelper);
5613
+ this.scene.add(axesHelper);
5938
5614
  }
5939
- function dollyIn(dollyScale) {
5940
- if (scope.object.isPerspectiveCamera) {
5941
- scale *= dollyScale;
5942
- } else if (scope.object.isOrthographicCamera) {
5943
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
5944
- scope.object.updateProjectionMatrix();
5945
- zoomChanged = true;
5946
- } else {
5947
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5948
- 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]);
5949
5620
  }
5950
5621
  }
5951
- function handleMouseDownRotate(event) {
5952
- 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
+ }
5953
5628
  }
5954
- function handleMouseDownDolly(event) {
5955
- 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);
5956
5634
  }
5957
- function handleMouseDownPan(event) {
5958
- 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");
5959
5645
  }
5960
- function handleMouseMoveRotate(event) {
5961
- rotateEnd.set(event.clientX, event.clientY);
5962
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5963
- const element = scope.domElement;
5964
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5965
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5966
- rotateStart.copy(rotateEnd);
5967
- scope.update();
5646
+ if (this.viewHeight == 0) {
5647
+ console.warn("0 element height");
5968
5648
  }
5969
- function handleMouseMoveDolly(event) {
5970
- dollyEnd.set(event.clientX, event.clientY);
5971
- dollyDelta.subVectors(dollyEnd, dollyStart);
5972
- if (dollyDelta.y > 0) {
5973
- dollyOut(getZoomScale());
5974
- } else if (dollyDelta.y < 0) {
5975
- dollyIn(getZoomScale());
5976
- }
5977
- dollyStart.copy(dollyEnd);
5978
- 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);
5979
5661
  }
5980
- function handleMouseMovePan(event) {
5981
- panEnd.set(event.clientX, event.clientY);
5982
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5983
- pan(panDelta.x, panDelta.y);
5984
- panStart.copy(panEnd);
5985
- 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();
5986
5677
  }
5987
- 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;
5988
5718
  }
5989
- function handleMouseWheel(event) {
5990
- if (event.deltaY < 0) {
5991
- dollyIn(getZoomScale());
5992
- } else if (event.deltaY > 0) {
5993
- dollyOut(getZoomScale());
5719
+ for (const [dispatcher, events] of this._eventDispatchers) {
5720
+ for (const event of events) {
5721
+ dispatcher.removeEventListener(event, this._changeListener);
5994
5722
  }
5995
- scope.update();
5996
5723
  }
5997
- function handleKeyDown(event) {
5998
- let needsUpdate = false;
5999
- switch (event.code) {
6000
- case scope.keys.UP:
6001
- pan(0, scope.keyPanSpeed);
6002
- needsUpdate = true;
6003
- break;
6004
- case scope.keys.BOTTOM:
6005
- pan(0, -scope.keyPanSpeed);
6006
- needsUpdate = true;
6007
- break;
6008
- case scope.keys.LEFT:
6009
- pan(scope.keyPanSpeed, 0);
6010
- needsUpdate = true;
6011
- break;
6012
- case scope.keys.RIGHT:
6013
- pan(-scope.keyPanSpeed, 0);
6014
- needsUpdate = true;
6015
- break;
6016
- }
6017
- if (needsUpdate) {
6018
- event.preventDefault();
6019
- 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();
6020
5735
  }
6021
5736
  }
6022
- function handleTouchStartRotate() {
6023
- if (pointers.length === 1) {
6024
- rotateStart.set(pointers[0].pageX, pointers[0].pageY);
6025
- } else {
6026
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6027
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6028
- rotateStart.set(x, y);
6029
- }
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();
6030
5746
  }
6031
- function handleTouchStartPan() {
6032
- if (pointers.length === 1) {
6033
- 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();
6034
5750
  } else {
6035
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6036
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6037
- panStart.set(x, y);
5751
+ this.renderer.render(this.scene, this.camera);
6038
5752
  }
6039
5753
  }
6040
- function handleTouchStartDolly() {
6041
- const dx = pointers[0].pageX - pointers[1].pageX;
6042
- const dy = pointers[0].pageY - pointers[1].pageY;
6043
- const distance = Math.sqrt(dx * dx + dy * dy);
6044
- dollyStart.set(0, distance);
6045
- }
6046
- function handleTouchStartDollyPan() {
6047
- if (scope.enableZoom) handleTouchStartDolly();
6048
- if (scope.enablePan) handleTouchStartPan();
5754
+ this.dirty = false;
5755
+ if (this._stats) {
5756
+ this._stats.end();
6049
5757
  }
6050
- function handleTouchStartDollyRotate() {
6051
- if (scope.enableZoom) handleTouchStartDolly();
6052
- 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);
6053
5831
  }
6054
- function handleTouchMoveRotate(event) {
6055
- if (pointers.length == 1) {
6056
- rotateEnd.set(event.pageX, event.pageY);
6057
- } else {
6058
- const position = getSecondPointerPosition(event);
6059
- const x = 0.5 * (event.pageX + position.x);
6060
- const y = 0.5 * (event.pageY + position.y);
6061
- 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);
6062
5841
  }
6063
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6064
- const element = scope.domElement;
6065
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6066
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6067
- 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);
6068
5858
  }
6069
- function handleTouchMovePan(event) {
6070
- if (pointers.length === 1) {
6071
- panEnd.set(event.pageX, event.pageY);
6072
- } else {
6073
- const position = getSecondPointerPosition(event);
6074
- const x = 0.5 * (event.pageX + position.x);
6075
- const y = 0.5 * (event.pageY + position.y);
6076
- 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);
6077
6113
  }
6078
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6079
- pan(panDelta.x, panDelta.y);
6080
- panStart.copy(panEnd);
6081
- }
6082
- function handleTouchMoveDolly(event) {
6083
- const position = getSecondPointerPosition(event);
6084
- const dx = event.pageX - position.x;
6085
- const dy = event.pageY - position.y;
6086
- const distance = Math.sqrt(dx * dx + dy * dy);
6087
- dollyEnd.set(0, distance);
6088
- dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
6089
- dollyOut(dollyDelta.y);
6090
- 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;
6091
6146
  }
6092
- function handleTouchMoveDollyPan(event) {
6093
- if (scope.enableZoom) handleTouchMoveDolly(event);
6094
- if (scope.enablePan) handleTouchMovePan(event);
6147
+ function getZoomScale() {
6148
+ return Math.pow(0.95, scope.zoomSpeed);
6095
6149
  }
6096
- function handleTouchMoveDollyRotate(event) {
6097
- if (scope.enableZoom) handleTouchMoveDolly(event);
6098
- if (scope.enableRotate) handleTouchMoveRotate(event);
6150
+ function rotateLeft(angle) {
6151
+ sphericalDelta.theta -= angle;
6099
6152
  }
6100
- function handleTouchEnd() {
6153
+ function rotateUp(angle) {
6154
+ sphericalDelta.phi -= angle;
6101
6155
  }
6102
- function onPointerDown(event) {
6103
- if (scope.enabled === false) return;
6104
- if (pointers.length === 0) {
6105
- scope.domElement.setPointerCapture(event.pointerId);
6106
- scope.domElement.addEventListener("pointermove", onPointerMove);
6107
- scope.domElement.addEventListener("pointerup", onPointerUp);
6108
- }
6109
- addPointer(event);
6110
- if (event.pointerType === "touch") {
6111
- 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;
6112
6204
  } else {
6113
- onMouseDown(event);
6205
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6206
+ scope.enableZoom = false;
6114
6207
  }
6115
6208
  }
6116
- function onPointerMove(event) {
6117
- if (scope.enabled === false) return;
6118
- if (event.pointerType === "touch") {
6119
- 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;
6120
6216
  } else {
6121
- onMouseMove(event);
6217
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6218
+ scope.enableZoom = false;
6122
6219
  }
6123
6220
  }
6124
- function onPointerUp(event) {
6125
- if (scope.enabled === false) return;
6126
- if (event.pointerType === "touch") {
6127
- onTouchEnd();
6128
- } else {
6129
- onMouseUp(event);
6130
- }
6131
- removePointer(event);
6132
- if (pointers.length === 0) {
6133
- scope.domElement.releasePointerCapture(event.pointerId);
6134
- scope.domElement.removeEventListener("pointermove", onPointerMove);
6135
- scope.domElement.removeEventListener("pointerup", onPointerUp);
6136
- }
6221
+ function handleMouseDownRotate(event) {
6222
+ rotateStart.set(event.clientX, event.clientY);
6137
6223
  }
6138
- function onPointerCancel(event) {
6139
- removePointer(event);
6224
+ function handleMouseDownDolly(event) {
6225
+ dollyStart.set(event.clientX, event.clientY);
6140
6226
  }
6141
- function onMouseDown(event) {
6142
- let mouseAction;
6143
- switch (event.button) {
6144
- case 0:
6145
- mouseAction = scope.mouseButtons.LEFT;
6146
- break;
6147
- case 1:
6148
- mouseAction = scope.mouseButtons.MIDDLE;
6149
- break;
6150
- case 2:
6151
- mouseAction = scope.mouseButtons.RIGHT;
6152
- break;
6153
- default:
6154
- mouseAction = -1;
6155
- }
6156
- switch (mouseAction) {
6157
- case import_three18.MOUSE.DOLLY:
6158
- if (scope.enableZoom === false) return;
6159
- handleMouseDownDolly(event);
6160
- state = STATE.DOLLY;
6161
- break;
6162
- case import_three18.MOUSE.ROTATE:
6163
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6164
- if (scope.enablePan === false) return;
6165
- handleMouseDownPan(event);
6166
- state = STATE.PAN;
6167
- } else {
6168
- if (scope.enableRotate === false) return;
6169
- handleMouseDownRotate(event);
6170
- state = STATE.ROTATE;
6171
- }
6172
- break;
6173
- case import_three18.MOUSE.PAN:
6174
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6175
- if (scope.enableRotate === false) return;
6176
- handleMouseDownRotate(event);
6177
- state = STATE.ROTATE;
6178
- } else {
6179
- if (scope.enablePan === false) return;
6180
- handleMouseDownPan(event);
6181
- state = STATE.PAN;
6182
- }
6183
- break;
6184
- default:
6185
- state = STATE.NONE;
6186
- }
6187
- if (state !== STATE.NONE) {
6188
- scope.dispatchEvent(_startEvent);
6189
- }
6227
+ function handleMouseDownPan(event) {
6228
+ panStart.set(event.clientX, event.clientY);
6190
6229
  }
6191
- function onMouseMove(event) {
6192
- if (scope.enabled === false) return;
6193
- switch (state) {
6194
- case STATE.ROTATE:
6195
- if (scope.enableRotate === false) return;
6196
- handleMouseMoveRotate(event);
6197
- break;
6198
- case STATE.DOLLY:
6199
- if (scope.enableZoom === false) return;
6200
- handleMouseMoveDolly(event);
6201
- break;
6202
- case STATE.PAN:
6203
- if (scope.enablePan === false) return;
6204
- handleMouseMovePan(event);
6205
- break;
6206
- }
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();
6207
6238
  }
6208
- function onMouseUp(event) {
6209
- handleMouseUp(event);
6210
- scope.dispatchEvent(_endEvent);
6211
- 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();
6212
6249
  }
6213
- function onMouseWheel(event) {
6214
- if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6215
- event.preventDefault();
6216
- scope.dispatchEvent(_startEvent);
6217
- handleMouseWheel(event);
6218
- 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();
6219
6256
  }
6220
- function onKeyDown(event) {
6221
- if (scope.enabled === false || scope.enablePan === false) return;
6222
- handleKeyDown(event);
6257
+ function handleMouseUp() {
6223
6258
  }
6224
- function onTouchStart(event) {
6225
- trackPointer(event);
6226
- switch (pointers.length) {
6227
- case 1:
6228
- switch (scope.touches.ONE) {
6229
- case import_three18.TOUCH.ROTATE:
6230
- if (scope.enableRotate === false) return;
6231
- handleTouchStartRotate();
6232
- state = STATE.TOUCH_ROTATE;
6233
- break;
6234
- case import_three18.TOUCH.PAN:
6235
- if (scope.enablePan === false) return;
6236
- handleTouchStartPan();
6237
- state = STATE.TOUCH_PAN;
6238
- break;
6239
- default:
6240
- state = STATE.NONE;
6241
- }
6242
- break;
6243
- case 2:
6244
- switch (scope.touches.TWO) {
6245
- case import_three18.TOUCH.DOLLY_PAN:
6246
- if (scope.enableZoom === false && scope.enablePan === false) return;
6247
- handleTouchStartDollyPan();
6248
- state = STATE.TOUCH_DOLLY_PAN;
6249
- break;
6250
- case import_three18.TOUCH.DOLLY_ROTATE:
6251
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6252
- handleTouchStartDollyRotate();
6253
- state = STATE.TOUCH_DOLLY_ROTATE;
6254
- break;
6255
- default:
6256
- state = STATE.NONE;
6257
- }
6258
- break;
6259
- default:
6260
- state = STATE.NONE;
6261
- }
6262
- if (state !== STATE.NONE) {
6263
- scope.dispatchEvent(_startEvent);
6259
+ function handleMouseWheel(event) {
6260
+ if (event.deltaY < 0) {
6261
+ dollyIn(getZoomScale());
6262
+ } else if (event.deltaY > 0) {
6263
+ dollyOut(getZoomScale());
6264
6264
  }
6265
+ scope.update();
6265
6266
  }
6266
- function onTouchMove(event) {
6267
- trackPointer(event);
6268
- switch (state) {
6269
- case STATE.TOUCH_ROTATE:
6270
- if (scope.enableRotate === false) return;
6271
- handleTouchMoveRotate(event);
6272
- 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;
6273
6273
  break;
6274
- case STATE.TOUCH_PAN:
6275
- if (scope.enablePan === false) return;
6276
- handleTouchMovePan(event);
6277
- scope.update();
6274
+ case scope.keys.BOTTOM:
6275
+ pan(0, -scope.keyPanSpeed);
6276
+ needsUpdate = true;
6278
6277
  break;
6279
- case STATE.TOUCH_DOLLY_PAN:
6280
- if (scope.enableZoom === false && scope.enablePan === false) return;
6281
- handleTouchMoveDollyPan(event);
6282
- scope.update();
6278
+ case scope.keys.LEFT:
6279
+ pan(scope.keyPanSpeed, 0);
6280
+ needsUpdate = true;
6283
6281
  break;
6284
- case STATE.TOUCH_DOLLY_ROTATE:
6285
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6286
- handleTouchMoveDollyRotate(event);
6287
- scope.update();
6282
+ case scope.keys.RIGHT:
6283
+ pan(-scope.keyPanSpeed, 0);
6284
+ needsUpdate = true;
6288
6285
  break;
6289
- default:
6290
- state = STATE.NONE;
6286
+ }
6287
+ if (needsUpdate) {
6288
+ event.preventDefault();
6289
+ scope.update();
6291
6290
  }
6292
6291
  }
6293
- function onTouchEnd(event) {
6294
- handleTouchEnd(event);
6295
- scope.dispatchEvent(_endEvent);
6296
- state = STATE.NONE;
6297
- }
6298
- function onContextMenu(event) {
6299
- if (scope.enabled === false) return;
6300
- event.preventDefault();
6301
- }
6302
- function addPointer(event) {
6303
- pointers.push(event);
6304
- }
6305
- function removePointer(event) {
6306
- delete pointerPositions[event.pointerId];
6307
- for (let i = 0; i < pointers.length; i++) {
6308
- if (pointers[i].pointerId == event.pointerId) {
6309
- pointers.splice(i, 1);
6310
- return;
6311
- }
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);
6312
6299
  }
6313
6300
  }
6314
- function trackPointer(event) {
6315
- let position = pointerPositions[event.pointerId];
6316
- if (position === void 0) {
6317
- position = new import_three18.Vector2();
6318
- 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);
6319
6308
  }
6320
- position.set(event.pageX, event.pageY);
6321
6309
  }
6322
- function getSecondPointerPosition(event) {
6323
- const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6324
- 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);
6325
6315
  }
6326
- scope.domElement.addEventListener("contextmenu", onContextMenu);
6327
- scope.domElement.addEventListener("pointerdown", onPointerDown);
6328
- scope.domElement.addEventListener("pointercancel", onPointerCancel);
6329
- scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6330
- this.update();
6331
- }
6332
- };
6333
- var MapControls = class extends OrbitControls {
6334
- constructor(object, domElement) {
6335
- super(object, domElement);
6336
- this.screenSpacePanning = false;
6337
- this.mouseButtons.LEFT = import_three18.MOUSE.PAN;
6338
- this.mouseButtons.RIGHT = import_three18.MOUSE.ROTATE;
6339
- this.touches.ONE = import_three18.TOUCH.PAN;
6340
- this.touches.TWO = import_three18.TOUCH.DOLLY_ROTATE;
6341
- }
6342
- };
6343
-
6344
- // src/renderer/Renderer.ts
6345
- var Renderer = class _Renderer {
6346
- constructor(options) {
6347
- this._dirty = true;
6348
- this._resizeListener = void 0;
6349
- this._disposed = false;
6350
- this._debugHelpers = [];
6351
- this._eventDispatchers = /* @__PURE__ */ new Map();
6352
- this._changeListener = () => {
6353
- this._dirty = true;
6354
- };
6355
- this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
6356
- this._animationLoop = this.animate.bind(this);
6357
- this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
6358
- this._scene = this.createScene();
6359
- this._camera = this.createCamera();
6360
- this._renderer = this.createRenderer();
6361
- this._composer = this.createComposer();
6362
- if (this.options.render.stats) {
6363
- this._stats = new import_stats.default();
6364
- document.body.appendChild(this._stats.dom);
6316
+ function handleTouchStartDollyPan() {
6317
+ if (scope.enableZoom) handleTouchStartDolly();
6318
+ if (scope.enablePan) handleTouchStartPan();
6365
6319
  }
6366
- this.init();
6367
- this._controls = this.createControls();
6368
- }
6369
- static {
6370
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6371
- camera: {
6372
- type: "perspective",
6373
- near: 1,
6374
- far: 5e3,
6375
- perspective: {
6376
- aspect: void 0,
6377
- fov: 50
6378
- },
6379
- orthographic: {
6380
- left: void 0,
6381
- right: void 0,
6382
- top: void 0,
6383
- bottom: void 0
6384
- },
6385
- position: new import_three19.Vector3(50, 50, 50),
6386
- lookingAt: new import_three19.Vector3(0, 0, 0)
6387
- },
6388
- render: {
6389
- fpsLimit: 60,
6390
- stats: false,
6391
- antialias: true,
6392
- shade: true,
6393
- autoResize: true,
6394
- renderAlways: false
6395
- },
6396
- composer: {
6397
- enabled: true
6398
- },
6399
- controls: {
6400
- enabled: false
6401
- },
6402
- debug: {
6403
- grid: false,
6404
- 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);
6405
6332
  }
6406
- });
6407
- }
6408
- //<editor-fold desc="INIT">
6409
- createScene() {
6410
- return new MineRenderScene();
6411
- }
6412
- createCamera() {
6413
- switch (this.options.camera.type) {
6414
- case "perspective":
6415
- default:
6416
- return new import_three19.PerspectiveCamera(
6417
- this.options.camera.perspective.fov,
6418
- this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
6419
- this.options.camera.near,
6420
- this.options.camera.far
6421
- );
6422
- case "orthographic":
6423
- return new import_three19.OrthographicCamera(
6424
- this.options.camera.orthographic.left ?? this.viewWidth / -2,
6425
- this.options.camera.orthographic.right ?? this.viewWidth / 2,
6426
- this.options.camera.orthographic.top ?? this.viewHeight / 2,
6427
- this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
6428
- this.options.camera.near,
6429
- this.options.camera.far
6430
- );
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);
6431
6338
  }
6432
- }
6433
- createRenderer() {
6434
- const renderer = new import_three19.WebGLRenderer({
6435
- antialias: this.options.render.antialias,
6436
- alpha: true,
6437
- powerPreference: "high-performance",
6438
- depth: true
6439
- });
6440
- renderer.setClearColor(0, 0);
6441
- renderer.shadowMap.enabled = true;
6442
- renderer.shadowMap.type = import_three19.PCFSoftShadowMap;
6443
- renderer.outputColorSpace = import_three19.SRGBColorSpace;
6444
- renderer.setSize(this.viewWidth, this.viewHeight);
6445
- return renderer;
6446
- }
6447
- createComposer() {
6448
- if (!this.options.composer.enabled) return void 0;
6449
- const composer = new import_postprocessing.EffectComposer(this.renderer);
6450
- composer.setSize(this.viewWidth, this.viewHeight);
6451
- composer.addPass(new import_postprocessing.RenderPass(this.scene, this.camera));
6452
- return composer;
6453
- }
6454
- createControls() {
6455
- if (!this.options.controls?.enabled) return void 0;
6456
- const position = this.camera.position.clone();
6457
- const controls = new OrbitControls(this.camera, this.renderer.domElement);
6458
- this.camera.position.copy(position);
6459
- const target = this.options.camera.lookingAt;
6460
- if (isVector3(target)) {
6461
- controls.target.copy(target);
6462
- } else if (isTripleArray(target)) {
6463
- controls.target.set(target[0], target[1], target[2]);
6464
- }
6465
- controls.update();
6466
- controls.saveState();
6467
- this.registerEventDispatcher(controls);
6468
- return controls;
6469
- }
6470
- //</editor-fold>
6471
- init() {
6472
- if (this._disposed) return;
6473
- if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
6474
- 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);
6475
6361
  }
6476
- if (this.options.debug.grid) {
6477
- const gridHelper = new import_three19.GridHelper(128, 16);
6478
- this._debugHelpers.push(gridHelper);
6479
- this.scene.add(gridHelper);
6480
- const gridHelper2 = new import_three19.GridHelper(128, 16);
6481
- this._debugHelpers.push(gridHelper2);
6482
- gridHelper2.rotation.x = 90 * (Math.PI / 180);
6483
- this.scene.add(gridHelper2);
6484
- const gridHelper3 = new import_three19.GridHelper(128, 16);
6485
- this._debugHelpers.push(gridHelper3);
6486
- gridHelper3.rotation.z = 90 * (Math.PI / 180);
6487
- this.scene.add(gridHelper3);
6362
+ function handleTouchMoveDollyPan(event) {
6363
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6364
+ if (scope.enablePan) handleTouchMovePan(event);
6488
6365
  }
6489
- if (this.options.debug.axes) {
6490
- const axesHelper = new import_three19.AxesHelper(64);
6491
- this._debugHelpers.push(axesHelper);
6492
- this.scene.add(axesHelper);
6366
+ function handleTouchMoveDollyRotate(event) {
6367
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6368
+ if (scope.enableRotate) handleTouchMoveRotate(event);
6493
6369
  }
6494
- if (this.options.camera.position) {
6495
- if (isVector3(this.options.camera.position)) {
6496
- this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
6497
- } else if (isTripleArray(this.options.camera.position)) {
6498
- 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);
6499
6384
  }
6500
6385
  }
6501
- if (this.options.camera.lookingAt) {
6502
- if (isVector3(this.options.camera.lookingAt)) {
6503
- this.camera.lookAt(this.options.camera.lookingAt);
6504
- } else if (isTripleArray(this.options.camera.lookingAt)) {
6505
- 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);
6506
6392
  }
6507
6393
  }
6508
- if (this.options.render.autoResize && !this._resizeListener) {
6509
- this._resizeListener = () => {
6510
- this.resize(this.viewWidth, this.viewHeight);
6511
- };
6512
- 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
+ }
6513
6407
  }
6514
- }
6515
- get element() {
6516
- return this._element;
6517
- }
6518
- appendTo(element) {
6519
- if (this._disposed) return;
6520
- this._element = element;
6521
- this._element.appendChild(this.renderer.domElement);
6522
- if (this.viewWidth == 0) {
6523
- console.warn("0 element width");
6408
+ function onPointerCancel(event) {
6409
+ removePointer(event);
6524
6410
  }
6525
- if (this.viewHeight == 0) {
6526
- 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
+ }
6527
6460
  }
6528
- this.resize(this.viewWidth, this.viewHeight);
6529
- }
6530
- /**
6531
- * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
6532
- * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
6533
- */
6534
- registerEventDispatcher(dispatcher, changeEvent2 = "change") {
6535
- if (this._disposed) return;
6536
- let events = this._eventDispatchers.get(dispatcher);
6537
- if (!events) {
6538
- events = /* @__PURE__ */ new Set();
6539
- 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
+ }
6540
6477
  }
6541
- if (events.has(changeEvent2)) return;
6542
- events.add(changeEvent2);
6543
- dispatcher.addEventListener(changeEvent2, this._changeListener);
6544
- }
6545
- resize(width, height) {
6546
- if (this._disposed) return;
6547
- if (isPerspectiveCamera(this.camera)) {
6548
- this.camera.aspect = width / height;
6549
- this.camera.updateProjectionMatrix();
6550
- } else if (isOrthographicCamera(this.camera)) {
6551
- this.camera.left = width / -2;
6552
- this.camera.right = width / 2;
6553
- this.camera.top = height / 2;
6554
- this.camera.bottom = height / -2;
6555
- this.camera.updateProjectionMatrix();
6478
+ function onMouseUp(event) {
6479
+ handleMouseUp(event);
6480
+ scope.dispatchEvent(_endEvent);
6481
+ state = STATE.NONE;
6556
6482
  }
6557
- this.renderer.setSize(width, height);
6558
- this.composer?.setSize(width, height);
6559
- this._dirty = true;
6560
- }
6561
- //<editor-fold desc="RENDER">
6562
- get dirty() {
6563
- return this._dirty || this.scene.dirty;
6564
- }
6565
- set dirty(dirty) {
6566
- this._dirty = dirty;
6567
- this.scene.dirty = dirty;
6568
- }
6569
- start() {
6570
- if (this._disposed) return;
6571
- this.stop();
6572
- this.renderer.setAnimationLoop(this._animationLoop);
6573
- }
6574
- stop() {
6575
- if (this._disposed) return;
6576
- this.renderer.setAnimationLoop(null);
6577
- this._nextFrameTime = void 0;
6578
- }
6579
- /**
6580
- * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
6581
- * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
6582
- * controls must be managed by their owners.
6583
- */
6584
- dispose() {
6585
- if (this._disposed) return;
6586
- this.stop();
6587
- this._disposed = true;
6588
- if (this._resizeListener) {
6589
- window.removeEventListener("resize", this._resizeListener);
6590
- 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);
6591
6489
  }
6592
- for (const [dispatcher, events] of this._eventDispatchers) {
6593
- for (const event of events) {
6594
- 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);
6595
6534
  }
6596
6535
  }
6597
- this._eventDispatchers.clear();
6598
- this._stats?.dom.remove();
6599
- this._stats = void 0;
6600
- this.renderer.domElement.remove();
6601
- this._element = void 0;
6602
- if (this._controls) {
6603
- const controls = this._controls;
6604
- this._controls = void 0;
6605
- controls.enabled = false;
6606
- controls.dispose();
6607
- }
6608
- this.scene.clear();
6609
- for (const helper of this._debugHelpers) {
6610
- helper.geometry.dispose();
6611
- const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
6612
- for (const material of materials) {
6613
- 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;
6614
6561
  }
6615
6562
  }
6616
- this._debugHelpers.length = 0;
6617
- this.composer?.dispose();
6618
- this.renderer.dispose();
6619
- this.renderer.forceContextLoss();
6620
- }
6621
- animate(t = performance.now()) {
6622
- if (this._disposed) return;
6623
- if (this._controls?.enabled) {
6624
- this._controls.update();
6625
- }
6626
- if (this._disposed) return;
6627
- if (!this.dirty && !this.options.render.renderAlways) return;
6628
- const interval = this._frameInterval;
6629
- if (interval) {
6630
- const next = this._nextFrameTime;
6631
- if (next !== void 0 && t + 0.1 < next) return;
6632
- this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
6633
- }
6634
- if (this._stats) {
6635
- this._stats.begin();
6636
- }
6637
- if (this.options.composer.enabled && this.composer) {
6638
- this.composer.render();
6639
- } else {
6640
- this.renderer.render(this.scene, this.camera);
6563
+ function onTouchEnd(event) {
6564
+ handleTouchEnd(event);
6565
+ scope.dispatchEvent(_endEvent);
6566
+ state = STATE.NONE;
6641
6567
  }
6642
- this.dirty = false;
6643
- if (this._stats) {
6644
- this._stats.end();
6568
+ function onContextMenu(event) {
6569
+ if (scope.enabled === false) return;
6570
+ event.preventDefault();
6645
6571
  }
6646
- }
6647
- //</editor-fold>
6648
- toImage() {
6649
- return this.renderer.domElement.toDataURL();
6650
- }
6651
- ///
6652
- get attachedToBody() {
6653
- return this.element === document.body;
6654
- }
6655
- get viewWidth() {
6656
- return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
6657
- }
6658
- get viewHeight() {
6659
- return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
6660
- }
6661
- get scene() {
6662
- return this._scene;
6663
- }
6664
- get camera() {
6665
- return this._camera;
6666
- }
6667
- get renderer() {
6668
- return this._renderer;
6669
- }
6670
- get composer() {
6671
- return this._composer;
6672
- }
6673
- /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
6674
- get controls() {
6675
- return this._controls;
6676
- }
6677
- ///
6678
- };
6679
-
6680
- // src/skin/Skins.ts
6681
- var Skins = class {
6682
- //<editor-fold desc="Skins">
6683
- static async fromUuidOrUsername(uuidOrUsername) {
6684
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6685
- return this.fromUuid(uuidOrUsername);
6572
+ function addPointer(event) {
6573
+ pointers.push(event);
6686
6574
  }
6687
- return this.fromUsername(uuidOrUsername);
6688
- }
6689
- static async fromUuid(uuid) {
6690
- return this.getSkinProxySkinUrl(uuid);
6691
- }
6692
- static async fromUsername(username) {
6693
- return this.usernameToUuid(username).then((uuid) => {
6694
- if (uuid) {
6695
- return this.fromUuid(uuid);
6696
- }
6697
- return void 0;
6698
- });
6699
- }
6700
- static async fromMineSkin(mineskinId) {
6701
- return this.getMineSkin(mineskinId).then((mineskin) => {
6702
- if (mineskin) {
6703
- 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
+ }
6704
6582
  }
6705
- return void 0;
6706
- });
6707
- }
6708
- //</editor-fold>
6709
- //<editor-fold desc="Capes">
6710
- static async capeFromUuidOrUsername(uuidOrUsername) {
6711
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6712
- return this.capeFromUuid(uuidOrUsername);
6713
6583
  }
6714
- return this.capeFromUsername(uuidOrUsername);
6715
- }
6716
- static async capeFromUuid(uuid) {
6717
- return this.getSkinProxyCapeUrl(uuid);
6718
- }
6719
- static async capeFromUsername(username) {
6720
- return this.usernameToUuid(username).then((uuid) => {
6721
- if (uuid) {
6722
- return this.capeFromUuid(uuid);
6723
- }
6724
- return void 0;
6725
- });
6726
- }
6727
- static async capeFromCapesDev(uuid, capeType = "minecraft") {
6728
- return this.getCapesDev(uuid, capeType).then((cape) => {
6729
- if (cape) {
6730
- return cape?.stillImageUrl;
6731
- }
6732
- return void 0;
6733
- });
6734
- }
6735
- //</editor-fold>
6736
- //<editor-fold desc="Helpers">
6737
- static async usernameToUuid(username) {
6738
- return this.usernameToUuidSkinProxy(username);
6739
- }
6740
- static async usernameToUuidSkinProxy(username) {
6741
- return Requests.genericRequest({
6742
- baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
6743
- url: "/uuid/" + username
6744
- }).then((res) => {
6745
- if (res.status === 200) {
6746
- return res.data["id"];
6747
- }
6748
- return void 0;
6749
- }).catch((err) => {
6750
- console.warn(err);
6751
- return void 0;
6752
- });
6753
- }
6754
- static async usernameToUuidMineTools(username) {
6755
- return Requests.genericRequest({
6756
- baseURL: "https://api.minetools.eu",
6757
- url: "/uuid/" + username
6758
- }).then((res) => {
6759
- if (res.status === 200) {
6760
- return res.data["id"];
6761
- }
6762
- return void 0;
6763
- }).catch((err) => {
6764
- console.warn(err);
6765
- return void 0;
6766
- });
6767
- }
6768
- static async getProfileFromMinetools(uuid) {
6769
- return Requests.genericRequest({
6770
- baseURL: "https://api.minetools.eu",
6771
- url: "/profile/" + uuid
6772
- }).then((res) => {
6773
- if (res.status === 200) {
6774
- return res.data;
6775
- }
6776
- });
6777
- }
6778
- static async getMineSkin(mineskinId) {
6779
- return Requests.genericRequest({
6780
- baseURL: "https://api.mineskin.org",
6781
- url: "/get/uuid/" + mineskinId
6782
- }).then((res) => {
6783
- if (res.status === 200) {
6784
- return res.data;
6785
- }
6786
- return void 0;
6787
- }).catch((err) => {
6788
- console.warn(err);
6789
- return void 0;
6790
- });
6791
- }
6792
- static async getCapesDev(uuid, type = "all") {
6793
- return Requests.genericRequest({
6794
- baseURL: "https://api.capes.dev",
6795
- url: "/load/" + uuid + "/" + type
6796
- }).then((res) => {
6797
- if (res.status === 200) {
6798
- 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;
6799
6589
  }
6800
- return void 0;
6801
- }).catch((err) => {
6802
- console.warn(err);
6803
- return void 0;
6804
- });
6805
- }
6806
- static getCrafatarSkinUrl(uuid) {
6807
- return "https://crafatar.com/skins/" + uuid;
6808
- }
6809
- static getCrafatarCapeUrl(uuid) {
6810
- return "https://crafatar.com/capes/" + uuid;
6811
- }
6812
- static getMcHeadsSkinUrl(uuid) {
6813
- return "https://mc-heads.net/skin/" + uuid;
6814
- }
6815
- static getMineSkinPlayerSkinUrl(uuid) {
6816
- return "https://mineskin.org/skin/player/" + uuid;
6817
- }
6818
- static getSkinProxySkinUrl(uuid) {
6819
- 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();
6820
6601
  }
6821
- static getSkinProxyCapeUrl(uuid) {
6822
- 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;
6823
6611
  }
6824
- //</editor-fold>
6825
6612
  };
6826
6613
 
6827
6614
  // src/world/Chunk.ts
@@ -6884,7 +6671,7 @@ var MineRenderWorld = class {
6884
6671
  console.log("CHUNKS", this._chunks);
6885
6672
  for (let chunk of this._chunks.values()) {
6886
6673
  console.log("dispose chunk", chunk);
6887
- await chunk?.dispose();
6674
+ await (chunk == null ? void 0 : chunk.dispose());
6888
6675
  }
6889
6676
  this._chunks.clear();
6890
6677
  }
@@ -6938,7 +6725,7 @@ var MineRenderWorld = class {
6938
6725
  };
6939
6726
 
6940
6727
  // src/world/Chunk.ts
6941
- var p11 = prefix("Chunk");
6728
+ var p12 = prefix("Chunk");
6942
6729
  var Chunk = class _Chunk {
6943
6730
  constructor(scene, x, y, z) {
6944
6731
  this._blocks = [];
@@ -6990,7 +6777,7 @@ var Chunk = class _Chunk {
6990
6777
  const index = _Chunk.chunkPosToBlockIndex(pos);
6991
6778
  const current = this._blocks[index];
6992
6779
  if (typeof current !== "undefined") {
6993
- console.debug(p11, "deleting existing block at", pos, worldPos, index);
6780
+ console.debug(p12, "deleting existing block at", pos, worldPos, index);
6994
6781
  current.object.removeFromScene();
6995
6782
  delete this._blocks[index];
6996
6783
  }
@@ -7057,7 +6844,6 @@ var Chunk = class _Chunk {
7057
6844
  AXES,
7058
6845
  ArchiveAssetSource,
7059
6846
  AssetKey,
7060
- AssetLoadError,
7061
6847
  AssetLoader,
7062
6848
  AssetParser,
7063
6849
  AssetSource,
@@ -7115,7 +6901,6 @@ var Chunk = class _Chunk {
7115
6901
  OrbitControls,
7116
6902
  PersistentCache,
7117
6903
  Renderer,
7118
- RequestError,
7119
6904
  Requests,
7120
6905
  SKIN_PARTS,
7121
6906
  SceneInspector,