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.
@@ -23,6 +23,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
24
  mod
25
25
  ));
26
+ var __decorateClass = (decorators, target, key, kind) => {
27
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
28
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
29
+ if (decorator = decorators[i])
30
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
31
+ if (kind && result) __defProp(target, key, result);
32
+ return result;
33
+ };
26
34
 
27
35
  // ../../node_modules/ts-deepmerge/dist/index.js
28
36
  var require_dist = __commonJS({
@@ -32,8 +40,8 @@ var require_dist = __commonJS({
32
40
  __assign = Object.assign || function(t) {
33
41
  for (var s, i = 1, n = arguments.length; i < n; i++) {
34
42
  s = arguments[i];
35
- for (var p12 in s) if (Object.prototype.hasOwnProperty.call(s, p12))
36
- t[p12] = s[p12];
43
+ for (var p13 in s) if (Object.prototype.hasOwnProperty.call(s, p13))
44
+ t[p13] = s[p13];
37
45
  }
38
46
  return t;
39
47
  };
@@ -77,7 +85,7 @@ var require_dist = __commonJS({
77
85
  return false;
78
86
  };
79
87
  var PROTECTED_KEYS = ["__proto__"];
80
- var merge10 = function() {
88
+ var merge11 = function() {
81
89
  var objects = [];
82
90
  for (var _i = 0; _i < arguments.length; _i++) {
83
91
  objects[_i] = arguments[_i];
@@ -88,9 +96,9 @@ var require_dist = __commonJS({
88
96
  return;
89
97
  }
90
98
  if (Array.isArray(result[key]) && Array.isArray(current[key])) {
91
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
99
+ result[key] = merge11.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
92
100
  } else if (isObject(result[key]) && isObject(current[key])) {
93
- result[key] = merge10(result[key], current[key]);
101
+ result[key] = merge11(result[key], current[key]);
94
102
  } else {
95
103
  result[key] = current[key];
96
104
  }
@@ -101,18 +109,18 @@ var require_dist = __commonJS({
101
109
  var defaultOptions = {
102
110
  mergeArrays: true
103
111
  };
104
- merge10.options = defaultOptions;
105
- merge10.withOptions = function(options) {
112
+ merge11.options = defaultOptions;
113
+ merge11.withOptions = function(options) {
106
114
  var objects = [];
107
115
  for (var _i = 1; _i < arguments.length; _i++) {
108
116
  objects[_i - 1] = arguments[_i];
109
117
  }
110
- merge10.options = __assign({ mergeArrays: true }, options);
111
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
112
- merge10.options = defaultOptions;
118
+ merge11.options = __assign({ mergeArrays: true }, options);
119
+ var result = merge11.apply(void 0, __spreadArray([], __read(objects), false));
120
+ merge11.options = defaultOptions;
113
121
  return result;
114
122
  };
115
- exports.default = merge10;
123
+ exports.default = merge11;
116
124
  }
117
125
  });
118
126
 
@@ -146,20 +154,17 @@ var _PersistentCache = class _PersistentCache {
146
154
  static open(name) {
147
155
  return Env.provider.openCache(name, _PersistentCache.VERSION);
148
156
  }
149
- /** Loads a missing entry and stores only non-nullish results. */
150
157
  async getOrLoad(key, loader) {
151
158
  let v = await this.get(key);
152
159
  if (typeof v === "undefined" || v === null) {
153
160
  v = await loader(key);
154
- if (typeof v !== "undefined" && v !== null) {
155
- await this.put(key, v);
156
- }
161
+ await this.put(key, v);
157
162
  }
158
163
  return v;
159
164
  }
160
165
  };
161
166
  /** Bump to invalidate every persisted entry. */
162
- _PersistentCache.VERSION = 2;
167
+ _PersistentCache.VERSION = 1;
163
168
  var PersistentCache = _PersistentCache;
164
169
 
165
170
  // src/env/browser/BrowserCache.ts
@@ -260,8 +265,7 @@ var BrowserEnv = class {
260
265
  }
261
266
  openCache(name, version) {
262
267
  return new BrowserCache(localforage.createInstance({
263
- // IndexedDB schema upgrades retain records; each cache generation needs its own database.
264
- name: name + version,
268
+ name,
265
269
  version
266
270
  }));
267
271
  }
@@ -278,7 +282,7 @@ registerBrowserEnv();
278
282
  // src/Axis.ts
279
283
  import { Vector3 } from "three";
280
284
  var Axis = /* @__PURE__ */ ((Axis3) => {
281
- Axis3["X"] = "x";
285
+ Axis3["X"] = "X";
282
286
  Axis3["Y"] = "y";
283
287
  Axis3["Z"] = "z";
284
288
  return Axis3;
@@ -286,7 +290,7 @@ var Axis = /* @__PURE__ */ ((Axis3) => {
286
290
  var AXES = Object.values(Axis);
287
291
  function axisToVec3(axis) {
288
292
  switch (axis) {
289
- case "x" /* X */:
293
+ case "X" /* X */:
290
294
  return new Vector3(1, 0, 0);
291
295
  case "y" /* Y */:
292
296
  return new Vector3(0, 1, 0);
@@ -389,10 +393,7 @@ function serializeMeshKey(key) {
389
393
  // src/cache/Caching.ts
390
394
  import { Caches } from "@inventivetalent/loading-cache";
391
395
  import { Time } from "@inventivetalent/time";
392
- var _Caching = class _Caching {
393
- static createAssetCache() {
394
- return Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
395
- }
396
+ var Caching = class {
396
397
  /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
397
398
  static get all() {
398
399
  return [
@@ -409,10 +410,7 @@ var _Caching = class _Caching {
409
410
  this.rawModelCache,
410
411
  this.mergedModelCache,
411
412
  this.modelTextureAtlasCache,
412
- this.blockStateCache,
413
- this.listAssetCache,
414
- this.defaultBlockStatesCache,
415
- this.entityModelsCache
413
+ this.blockStateCache
416
414
  ];
417
415
  }
418
416
  static clear() {
@@ -423,8 +421,8 @@ var _Caching = class _Caching {
423
421
  /**
424
422
  * Clears every cache and stops its expiry timer.
425
423
  *
426
- * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
427
- * Use {@link shutdown} to also stop requests and the shared Ticker.
424
+ * loading-cache reschedules that timer indefinitely, so a Node process will not exit until
425
+ * this is called - see {@link shutdown}.
428
426
  */
429
427
  static end() {
430
428
  for (const cache of this.all) {
@@ -438,24 +436,20 @@ var _Caching = class _Caching {
438
436
  };
439
437
  }
440
438
  };
441
- _Caching.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
442
- _Caching.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
443
- _Caching.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
444
- _Caching.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
445
- _Caching.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
446
- _Caching.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
447
- _Caching.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
448
- _Caching.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
449
- _Caching.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
450
- _Caching.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
451
- _Caching.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
452
- _Caching.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
453
- _Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
454
- _Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
455
- _Caching.listAssetCache = _Caching.createAssetCache();
456
- _Caching.defaultBlockStatesCache = _Caching.createAssetCache();
457
- _Caching.entityModelsCache = _Caching.createAssetCache();
458
- var Caching = _Caching;
439
+ Caching.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
440
+ Caching.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
441
+ Caching.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
442
+ Caching.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
443
+ Caching.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
444
+ Caching.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
445
+ Caching.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
446
+ Caching.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
447
+ Caching.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
448
+ Caching.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
449
+ Caching.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
450
+ Caching.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
451
+ Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
452
+ Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
459
453
 
460
454
  // src/Geometries.ts
461
455
  var Geometries = class _Geometries {
@@ -483,7 +477,6 @@ import { CanvasTexture, Texture as Texture2 } from "three";
483
477
 
484
478
  // src/texture/TextureLoader.ts
485
479
  import { RGBAFormat, Texture } from "three";
486
- import * as THREE from "three";
487
480
 
488
481
  // src/canvas/CanvasCompat.ts
489
482
  function createImage(width, height) {
@@ -494,7 +487,9 @@ function createCanvas(width, height) {
494
487
  }
495
488
 
496
489
  // src/request/Requests.ts
497
- import { JobCancelledError, JobQueue } from "jobqu";
490
+ import axios from "axios";
491
+ import { JobQueue } from "jobqu";
492
+ import { Time as Time2 } from "@inventivetalent/time";
498
493
 
499
494
  // src/util/log.ts
500
495
  var Reset = "\x1B[0m";
@@ -504,170 +499,198 @@ function prefix(prefix2) {
504
499
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
505
500
  }
506
501
 
507
- // src/request/Requests.ts
508
- var p = prefix("Requests");
509
- var RequestError = class extends Error {
510
- constructor(message, response, cause) {
511
- super(message);
512
- this.response = response;
513
- this.cause = cause;
514
- this.name = "RequestError";
502
+ // src/util/BatchedExecutor.ts
503
+ var BatchedExecutor = class {
504
+ constructor(interval = 1, batch = 30) {
505
+ this.interval = interval;
506
+ this.batch = batch;
507
+ this.queue = [];
508
+ this.task = setInterval(() => this.run());
515
509
  }
516
- };
517
- async function fetchRequest(config, defaultBaseURL) {
518
- const { url, baseURL = defaultBaseURL, timeout = 5e3, responseType = "json", signal, ...options } = config;
519
- const target = baseURL && !/^([a-z][a-z\d+.-]*:|\/\/)/i.test(url) ? `${baseURL.replace(/\/+$/, "")}/${url.replace(/^\/+/, "")}` : url;
520
- const headers = new Headers(options.headers);
521
- if (typeof window === "undefined" && !headers.has("User-Agent")) {
522
- headers.set("User-Agent", "MineRender");
523
- }
524
- const attemptSignal = AbortSignal.any([
525
- ...signal ? [signal] : [],
526
- ...timeout === 0 ? [] : [AbortSignal.timeout(timeout)]
527
- ]);
528
- const request = new Request(target, { ...options, headers, signal: attemptSignal });
529
- attemptSignal.throwIfAborted();
530
- try {
531
- const response = await fetch(request);
532
- const result = {
533
- data: void 0,
534
- status: response.status,
535
- statusText: response.statusText,
536
- headers: response.headers,
537
- url: response.url
538
- };
539
- if (!response.ok) {
540
- await response.body?.cancel().catch(() => {
541
- });
542
- throw new RequestError(`Request failed with status ${response.status}`, result);
510
+ submit(task) {
511
+ this.queue.push(task);
512
+ }
513
+ run() {
514
+ for (let i = 0; i < this.batch; i++) {
515
+ this.runNext();
543
516
  }
544
- const emptyBody = request.method === "HEAD" || response.status === 204 || response.status === 205;
545
- const data = responseType === "arraybuffer" ? await response.arrayBuffer() : emptyBody || response.body === null ? void 0 : await response.json();
546
- return { ...result, data };
547
- } catch (error) {
548
- attemptSignal.throwIfAborted();
549
- if (/^https?:/.test(request.url) && request.redirect !== "error" && error instanceof TypeError) {
550
- throw new RequestError("Network request failed", void 0, error);
517
+ }
518
+ runNext() {
519
+ let next = this.queue.shift();
520
+ if (next) next();
521
+ }
522
+ };
523
+
524
+ // src/util/model.ts
525
+ import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
526
+ function applyElementRotation(rotation, geometry) {
527
+ const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
528
+ geometry.translate(-origin.x, -origin.y, -origin.z);
529
+ switch (rotation.axis) {
530
+ case "X" /* X */:
531
+ geometry.rotateX(toRadians(rotation.angle));
532
+ break;
533
+ case "y" /* Y */:
534
+ geometry.rotateY(toRadians(rotation.angle));
535
+ break;
536
+ case "z" /* Z */:
537
+ geometry.rotateZ(toRadians(rotation.angle));
538
+ break;
539
+ }
540
+ if (rotation.rescale) {
541
+ if (Math.abs(rotation.angle) === 22.5) {
542
+ const s = 1 / Math.cos(0.39269909262657166);
543
+ geometry.scale(s, 1, s);
544
+ } else {
545
+ const s = 1 / Math.cos(0.7853981852531433);
546
+ geometry.scale(s, 1, s);
551
547
  }
552
- throw error;
553
548
  }
549
+ geometry.translate(origin.x, origin.y, origin.z);
554
550
  }
555
- async function abortable(promise, signal) {
556
- if (!signal) return promise;
557
- let abort;
558
- const cancelled = new Promise((_, reject) => {
559
- abort = () => reject(signal.reason);
560
- signal.addEventListener("abort", abort, { once: true });
561
- if (signal.aborted) abort();
562
- });
563
- try {
564
- return await Promise.race([promise, cancelled]);
565
- } finally {
566
- signal.removeEventListener("abort", abort);
551
+ function applyModelPartRotation(modelPart, geometry) {
552
+ const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
553
+ geometry.translate(-origin.x, -origin.y, -origin.z);
554
+ geometry.rotateX(toRadians(modelPart.pitch));
555
+ geometry.rotateY(toRadians(modelPart.yaw));
556
+ geometry.rotateZ(toRadians(modelPart.roll));
557
+ geometry.translate(origin.x, origin.y, origin.z);
558
+ }
559
+ function applyGenericRotation(axis, rotation, obj) {
560
+ switch (axis) {
561
+ case "X" /* X */:
562
+ obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
563
+ break;
564
+ case "y" /* Y */:
565
+ obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
566
+ break;
567
+ case "z" /* Z */:
568
+ obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
569
+ break;
567
570
  }
568
571
  }
569
- var RequestQueue = class {
570
- constructor() {
571
- this.pendingRequests = 0;
572
- this.stopped = new AbortController();
573
- this.queue = new JobQueue(
574
- (request) => fetchRequest(request, this.baseURL),
575
- { interval: 10, maxPerRun: 1, maxActive: 8 }
576
- );
572
+ function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
573
+ let size = new Vector32();
574
+ box.getSize(size);
575
+ let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
576
+ let wireGeo = new EdgesGeometry(boxGeo);
577
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
578
+ let wireframe = new LineSegments(wireGeo, wireMat);
579
+ obj.add(wireframe);
580
+ let axes = new AxesHelper(1);
581
+ obj.add(axes);
582
+ }
583
+ function addWireframeToObject(obj, color = 16777215, w = 2) {
584
+ let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
585
+ let wireGeo = new EdgesGeometry(boxGeo);
586
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
587
+ let wireframe = new LineSegments(wireGeo, wireMat);
588
+ obj.add(wireframe);
589
+ let axes = new AxesHelper(1);
590
+ obj.add(axes);
591
+ }
592
+ function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
593
+ let wireGeo = new EdgesGeometry(geo);
594
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
595
+ let wireframe = new LineSegments(wireGeo, wireMat);
596
+ mesh.add(wireframe);
597
+ let axes = new AxesHelper(1);
598
+ mesh.add(axes);
599
+ }
600
+
601
+ // src/util/performance.ts
602
+ function captureException(e, ...extra) {
603
+ console.error(e, extra);
604
+ }
605
+ function timingStart(marker) {
606
+ console.time(marker);
607
+ }
608
+ function timingEnd(marker) {
609
+ console.timeEnd(marker);
610
+ }
611
+
612
+ // src/util/three.ts
613
+ function isObject3D(obj) {
614
+ return obj.isObject3D;
615
+ }
616
+ function isMesh(obj) {
617
+ return obj.isMesh;
618
+ }
619
+ function isInstancedMesh(obj) {
620
+ return obj.isInstancedMesh;
621
+ }
622
+ function isPerspectiveCamera(obj) {
623
+ return obj.isPerspectiveCamera;
624
+ }
625
+ function isOrthographicCamera(obj) {
626
+ return obj.isOrthographicCamera;
627
+ }
628
+
629
+ // src/request/Requests.ts
630
+ var p = prefix("Requests");
631
+ if (typeof window === "undefined") {
632
+ axios.defaults.headers["User-Agent"] = "MineRender";
633
+ }
634
+ var _Requests = class _Requests {
635
+ static genericRequest(request) {
636
+ return this.genericQueue.add(request).catch(async (e) => {
637
+ console.debug(p, "generic catch", e.code, e);
638
+ if (this.shouldRetry(e, request)) {
639
+ await sleep(100);
640
+ return this.genericRequest(request);
641
+ }
642
+ throw e;
643
+ });
577
644
  }
578
- async request(request) {
579
- this.pendingRequests++;
580
- const signal = request.signal;
581
- try {
582
- for (let retries = 0; ; retries++) {
583
- signal?.throwIfAborted();
584
- try {
585
- return await abortable(this.queue.add(request), signal);
586
- } catch (error) {
587
- console.debug(p, "Request failed", error);
588
- const delay = this.retryDelay(error, request, retries);
589
- if (delay === void 0) {
590
- throw error;
645
+ static mcAssetRequest(request) {
646
+ return this.mcAssetRequestQueue.add(request).catch((e) => {
647
+ console.debug(p, "mcAssetRequest catch", e.code, e);
648
+ throw e;
649
+ });
650
+ }
651
+ static shouldRetry(e, request) {
652
+ if ("code" in e) {
653
+ if ("ECONNABORTED" === e.code) {
654
+ if ("minerenderRetry" in request) {
655
+ if (request["minerenderRetry"] > 0) {
656
+ request["minerenderRetry"]--;
657
+ return true;
591
658
  }
592
- await this.waitForRetry(delay, signal);
659
+ } else {
660
+ request["minerenderRetry"] = 3;
661
+ return true;
593
662
  }
594
663
  }
595
- } finally {
596
- if (signal?.aborted) {
597
- this.queue.remove(request);
598
- }
599
- this.pendingRequests--;
600
- }
601
- }
602
- retryDelay(error, request, retries) {
603
- if (this.stopped.signal.aborted || retries >= 3 || (request.method ?? "get").toLowerCase() !== "get" || request.signal?.aborted) {
604
- return void 0;
605
- }
606
- if (error instanceof RequestError) {
607
- const status = error.response?.status;
608
- if (status !== void 0 && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return void 0;
609
- } else if (!(error instanceof DOMException && error.name === "TimeoutError")) {
610
- return void 0;
611
- }
612
- let delay = 100 * 2 ** retries;
613
- const retryAfter = error instanceof RequestError ? error.response?.headers.get("Retry-After") : void 0;
614
- if (retryAfter !== void 0 && retryAfter !== null) {
615
- const seconds = Number(retryAfter);
616
- if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {
617
- return void 0;
618
- }
619
- delay = Math.max(delay, seconds * 1e3);
620
664
  }
621
- return delay;
622
- }
623
- async waitForRetry(delay, signal) {
624
- let timer;
625
- const waiting = new Promise((resolve) => {
626
- timer = setTimeout(resolve, delay);
627
- });
628
- try {
629
- await abortable(waiting, AbortSignal.any([this.stopped.signal, ...signal ? [signal] : []]));
630
- } finally {
631
- clearTimeout(timer);
632
- }
633
- }
634
- get pendingSize() {
635
- return this.pendingRequests;
636
- }
637
- end() {
638
- this.queue.end();
639
- this.stopped.abort(new JobCancelledError("ended"));
640
- }
641
- };
642
- var Requests = class {
643
- static genericRequest(request) {
644
- return this.genericQueue.request(request);
645
- }
646
- static mcAssetRequest(request) {
647
- return this.mcAssetRequestQueue.request(request);
665
+ return false;
648
666
  }
649
667
  static setMcAssetRoot(root) {
650
- this.mcAssetRequestQueue.baseURL = root;
668
+ this.mcAssetInstance.defaults.baseURL = root;
651
669
  }
652
- /** Counts unsettled calls, including retry delays and requests still running after shutdown. */
653
670
  static get queueSizes() {
654
671
  return {
655
- generic: this.genericQueue.pendingSize,
656
- mcAsset: this.mcAssetRequestQueue.pendingSize
672
+ generic: this.genericQueue.size,
673
+ mcAsset: this.mcAssetRequestQueue.size
657
674
  };
658
675
  }
659
676
  /**
660
- * Permanently stops both queues and rejects waiting, retrying, and future requests.
661
- * Requests already running can finish. Idle queues hold no timer, so Node can exit without
662
- * this cleanup. See {@link shutdown}.
677
+ * Stops both queue timers. jobqu reschedules itself indefinitely, so a Node process will not
678
+ * exit until this is called - see {@link shutdown}.
663
679
  */
664
680
  static end() {
665
681
  this.genericQueue.end();
666
682
  this.mcAssetRequestQueue.end();
667
683
  }
668
684
  };
669
- Requests.genericQueue = new RequestQueue();
670
- Requests.mcAssetRequestQueue = new RequestQueue();
685
+ _Requests.axiosInstance = axios.create({
686
+ timeout: 5e3
687
+ });
688
+ _Requests.mcAssetInstance = axios.create({
689
+ timeout: 5e3
690
+ });
691
+ _Requests.genericQueue = new JobQueue((request) => _Requests.axiosInstance.request(request), Time2.millis(10), 1);
692
+ _Requests.mcAssetRequestQueue = new JobQueue((request) => _Requests.mcAssetInstance.request(request), Time2.millis(10), 1);
693
+ var Requests = _Requests;
671
694
 
672
695
  // src/WrappedImage.ts
673
696
  var WrappedImage = class {
@@ -705,10 +728,10 @@ var WrappedImage = class {
705
728
  return this.animated ? this.width : this.height;
706
729
  }
707
730
  get frameCount() {
708
- return this.height / this.frameHeight;
731
+ return this.height / this.width;
709
732
  }
710
733
  getFrameY(frame) {
711
- return this.frameHeight * Math.max(0, Math.min(this.frameCount - 1, frame));
734
+ return this.height / this.frameCount * Math.max(0, Math.min(this.frameCount, frame));
712
735
  }
713
736
  getSectionData(sx, sy, sw, sh) {
714
737
  return this.dta.data.getImageData(sx, sy, sw, sh);
@@ -718,7 +741,7 @@ var WrappedImage = class {
718
741
  }
719
742
  getFrameSectionData(frame) {
720
743
  const y = this.getFrameY(frame);
721
- return this.getSectionData(0, y, this.frameWidth, this.frameHeight);
744
+ return this.getSectionData(0, y, this.width, this.width + y);
722
745
  }
723
746
  };
724
747
 
@@ -732,41 +755,29 @@ var ImageLoader = class _ImageLoader {
732
755
  static async loadAsync(src) {
733
756
  return new Promise((resolve, reject) => {
734
757
  const image = this._createImage();
735
- image.onload = () => resolve(image);
736
- image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
737
758
  image.src = src;
759
+ image.onload = () => resolve(image);
760
+ image.onerror = (err) => reject(err);
738
761
  });
739
762
  }
740
763
  static loadElement(src, onload, onerr) {
741
764
  const image = this._createImage();
765
+ image.src = src;
742
766
  if (onload)
743
767
  image.onload = onload;
744
768
  if (onerr)
745
769
  image.onerror = onerr;
746
- image.src = src;
747
770
  return image;
748
771
  }
749
772
  static async loadData(src) {
750
773
  console.debug(p2, "loadData", src);
751
- const image = await this.loadCanvasData(src);
752
- return image.data.getImageData(0, 0, image.width, image.height);
774
+ return await this.infoToData(await this.getInfo(src));
753
775
  }
754
776
  static async loadCanvasData(src) {
755
- const keyStr = serializeImageKey({ src });
756
- const info = this.getInfo(src);
757
- const cached = Caching.rawImageCache.getIfPresent(keyStr);
758
- try {
759
- return await this.infoToCanvasData(await info);
760
- } catch (err) {
761
- if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
762
- Caching.rawImageCache.invalidate(keyStr);
763
- }
764
- throw err;
765
- }
777
+ return await this.infoToCanvasData(await this.getInfo(src));
766
778
  }
767
779
  static async infoToCanvasData(info) {
768
- const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
769
- const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
780
+ const image = await _ImageLoader.loadAsync(info.src);
770
781
  const canvas = createCanvas(info.width, info.height);
771
782
  const context = canvas.getContext("2d");
772
783
  context.drawImage(image, 0, 0);
@@ -777,8 +788,11 @@ var ImageLoader = class _ImageLoader {
777
788
  };
778
789
  }
779
790
  static async infoToData(info) {
780
- const image = await this.infoToCanvasData(info);
781
- return image.data.getImageData(0, 0, image.width, image.height);
791
+ const image = await _ImageLoader.loadAsync(info.src);
792
+ const canvas = createCanvas(info.width, info.height);
793
+ const context = canvas.getContext("2d");
794
+ context.drawImage(image, 0, 0);
795
+ return context.getImageData(0, 0, canvas.width, canvas.height);
782
796
  }
783
797
  static async getData(src) {
784
798
  const keyStr = serializeImageKey({ src });
@@ -793,25 +807,38 @@ var ImageLoader = class _ImageLoader {
793
807
  });
794
808
  }
795
809
  static async processResponse(response) {
796
- const src = response.url;
810
+ const src = response.config.url;
797
811
  const data = Buffer2.from(response.data);
798
812
  const { width, height, type } = Env.provider.imageSize(data);
799
- if (!width || !height) {
800
- throw new Error("Invalid or unsupported image dimensions");
801
- }
802
813
  return {
803
814
  src,
804
- width,
805
- height,
815
+ width: width || 0,
816
+ height: height || 0,
806
817
  type,
807
818
  data
808
819
  };
809
820
  }
810
821
  static async loadInfo(src) {
822
+ if (src.startsWith("data:image/png;base64")) {
823
+ return this.processResponse({
824
+ config: {
825
+ url: src
826
+ },
827
+ data: Buffer2.from(src.substr("data:image/png;base64,".length), "base64")
828
+ });
829
+ }
811
830
  return Requests.genericRequest({
812
831
  url: src,
813
832
  responseType: "arraybuffer"
814
- }).then(this.processResponse);
833
+ }).then(this.processResponse).catch((err) => {
834
+ return {
835
+ src,
836
+ width: 0,
837
+ height: 0,
838
+ type: void 0,
839
+ data: Buffer2.from([0])
840
+ };
841
+ });
815
842
  }
816
843
  static async getInfo(src) {
817
844
  const keyStr = serializeImageKey({ src });
@@ -833,22 +860,15 @@ var ImageLoader = class _ImageLoader {
833
860
 
834
861
  // src/texture/TextureLoader.ts
835
862
  var TextureLoader = class {
836
- /** Reports whether image loading failed, so cached textures can be retried. */
837
- static hasFailed(texture) {
838
- return this.failedTextures.has(texture);
839
- }
840
863
  static createTexture() {
841
864
  return new Texture();
842
865
  }
843
866
  static loadInBackground(src, format = RGBAFormat, rotation = 0) {
844
867
  const texture = this.createTexture();
845
- texture.colorSpace = THREE.SRGBColorSpace;
846
- const image = ImageLoader.loadElement(src, () => {
868
+ const image = ImageLoader.loadElement(src);
869
+ image.onload = function() {
847
870
  texture.needsUpdate = true;
848
- }, (error) => {
849
- this.failedTextures.add(texture);
850
- console.warn("Failed to load texture", src, error);
851
- });
871
+ };
852
872
  texture.image = image;
853
873
  texture.format = format;
854
874
  texture.rotation = rotation;
@@ -856,27 +876,22 @@ var TextureLoader = class {
856
876
  }
857
877
  static load(src, format = RGBAFormat, rotation = 0) {
858
878
  const texture = new Texture();
859
- texture.colorSpace = THREE.SRGBColorSpace;
860
879
  ImageLoader.getData(src).then((image) => {
861
- texture.image = image;
862
880
  texture.needsUpdate = true;
863
- }).catch((error) => {
864
- this.failedTextures.add(texture);
865
- console.warn("Failed to load texture", src, error);
881
+ texture.image = image;
866
882
  });
867
883
  texture.format = format;
868
884
  texture.rotation = rotation;
869
885
  return Textures.initTextureProps(texture);
870
886
  }
871
887
  };
872
- TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
873
888
 
874
889
  // src/texture/Textures.ts
875
- import * as THREE2 from "three";
890
+ import * as THREE from "three";
876
891
  var Textures = class _Textures {
877
892
  static initTextureProps(texture) {
878
- texture.magFilter = THREE2.NearestFilter;
879
- texture.minFilter = THREE2.NearestFilter;
893
+ texture.magFilter = THREE.NearestFilter;
894
+ texture.minFilter = THREE.NearestFilter;
880
895
  texture.anisotropy = 0;
881
896
  return texture;
882
897
  }
@@ -887,16 +902,10 @@ var Textures = class _Textures {
887
902
  return new Texture2();
888
903
  }
889
904
  static createCanvasTexture(canvas) {
890
- const texture = new CanvasTexture(canvas);
891
- texture.colorSpace = THREE2.SRGBColorSpace;
892
- return this.initTextureProps(texture);
905
+ return this.initTextureProps(new CanvasTexture(canvas));
893
906
  }
894
907
  static getImage(key) {
895
908
  const keyStr = serializeTextureKey(key);
896
- const cached = Caching.textureCache.peek(keyStr);
897
- if (cached && TextureLoader.hasFailed(cached)) {
898
- Caching.textureCache.invalidate(keyStr);
899
- }
900
909
  return Caching.textureCache.get(keyStr, (k) => {
901
910
  return _Textures.createImage(key);
902
911
  });
@@ -952,11 +961,7 @@ var _Materials = class _Materials {
952
961
 
953
962
  if (SHADE) {
954
963
 
955
- #ifdef USE_INSTANCING
956
- vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
957
- #else
958
- vec3 N = vec3( modelMatrix * vec4(normal, 0.0) );
959
- #endif
964
+ vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
960
965
 
961
966
  float yLight = (1.0+N.y) * 0.5;
962
967
  light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT;
@@ -1014,9 +1019,6 @@ var _Materials = class _Materials {
1014
1019
  gl_FragColor = vec4(lift + color.rgb * light2, 1.0);
1015
1020
 
1016
1021
  }
1017
-
1018
- #include <tonemapping_fragment>
1019
- #include <colorspace_fragment>
1020
1022
  }
1021
1023
  `;
1022
1024
  try {
@@ -1045,10 +1047,6 @@ var _Materials = class _Materials {
1045
1047
  }
1046
1048
  static getImage(key) {
1047
1049
  const keyStr = serializeMaterialKey(key);
1048
- const map = Caching.materialCache.peek(keyStr)?.map;
1049
- if (map && TextureLoader.hasFailed(map)) {
1050
- Caching.materialCache.invalidate(keyStr);
1051
- }
1052
1050
  return Caching.materialCache.get(keyStr, (k) => {
1053
1051
  return _Materials.createImage(key);
1054
1052
  });
@@ -1073,10 +1071,10 @@ _Materials.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA
1073
1071
  var Materials = _Materials;
1074
1072
 
1075
1073
  // src/Meshes.ts
1076
- import { Mesh } from "three";
1074
+ import { Mesh as Mesh2 } from "three";
1077
1075
  var Meshes = class _Meshes {
1078
1076
  static createBox(key) {
1079
- return new Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1077
+ return new Mesh2(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1080
1078
  }
1081
1079
  static getBox(key) {
1082
1080
  const keyStr = serializeMeshKey(key);
@@ -1123,7 +1121,6 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1123
1121
  this.rootType = rootType;
1124
1122
  this.extension = extension;
1125
1123
  this.root = root;
1126
- this.isAssetKey = true;
1127
1124
  }
1128
1125
  static parse(assetType, str, origin) {
1129
1126
  let namespace = origin?.namespace || DEFAULT_NAMESPACE;
@@ -1139,15 +1136,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1139
1136
  split.shift();
1140
1137
  }
1141
1138
  let path = split.join("/");
1142
- const extension = assetType === "textures" ? ".png" : origin?.extension ?? ".json";
1143
- if (extension && path.endsWith(extension)) {
1144
- path = path.slice(0, -extension.length);
1145
- }
1139
+ let extension = assetType === "textures" ? ".png" : origin?.assetType || ".json";
1146
1140
  return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin?.root);
1147
1141
  }
1148
1142
  toString() {
1149
1143
  let a = [
1150
- this.root ?? AssetLoader.ROOT,
1144
+ typeof this.root !== "undefined" || AssetLoader.ROOT !== DEFAULT_ROOT ? this.root ?? AssetLoader.ROOT : "__root__",
1151
1145
  this.rootType ?? "__rootType__",
1152
1146
  this.assetType ?? "__assetType__",
1153
1147
  this.type ?? "__type__",
@@ -1157,12 +1151,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1157
1151
  return a.join("/");
1158
1152
  }
1159
1153
  getFullPath() {
1160
- let p12 = [];
1154
+ let p13 = [];
1161
1155
  if (this.type) {
1162
- p12.push(this.type);
1156
+ p13.push(this.type);
1163
1157
  }
1164
- p12.push(this.path);
1165
- return p12.join("/");
1158
+ p13.push(this.path);
1159
+ return p13.join("/");
1166
1160
  }
1167
1161
  toNamespacedString() {
1168
1162
  return this.namespace + ":" + this.getFullPath();
@@ -1172,10 +1166,10 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1172
1166
  }
1173
1167
  };
1174
1168
  function isBasicAssetKey(obj) {
1175
- return obj !== null && typeof obj === "object" && typeof obj.namespace === "string" && typeof obj.path === "string";
1169
+ return "namespace" in obj && "path" in obj;
1176
1170
  }
1177
1171
  function isAssetKey(obj) {
1178
- return isBasicAssetKey(obj) && obj.isAssetKey === true;
1172
+ return isBasicAssetKey(obj) && "parse" in obj;
1179
1173
  }
1180
1174
 
1181
1175
  // src/model/ModelMerger.ts
@@ -1184,10 +1178,10 @@ var ModelMerger = class {
1184
1178
  const models = await this.collectAllParents(model);
1185
1179
  let merged = {};
1186
1180
  for (let parentModel of models) {
1187
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1181
+ merged = (0, import_ts_deepmerge.default)(merged, parentModel);
1188
1182
  }
1189
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1190
- merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
1183
+ merged = (0, import_ts_deepmerge.default)(merged, model);
1184
+ merged.hierarchy = models.map((m) => m.parent).filter((p13) => `${p13}`);
1191
1185
  merged.hierarchy.push(`${merged.parent}`);
1192
1186
  return merged;
1193
1187
  }
@@ -1197,7 +1191,6 @@ var ModelMerger = class {
1197
1191
  }
1198
1192
  const models = [];
1199
1193
  const parentKey = AssetKey.parse("models", model.parent);
1200
- parentKey.root = model.key?.root;
1201
1194
  const parentModel = await Models.getRaw(parentKey);
1202
1195
  if (parentModel) {
1203
1196
  models.unshift(parentModel);
@@ -1207,6 +1200,9 @@ var ModelMerger = class {
1207
1200
  }
1208
1201
  };
1209
1202
 
1203
+ // src/assets/Models.ts
1204
+ import { Memoize } from "typescript-memoize";
1205
+
1210
1206
  // src/assets/source/parser/AssetParsers.ts
1211
1207
  var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1212
1208
  AssetParser2["MODEL"] = "model";
@@ -1220,65 +1216,30 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1220
1216
  })(AssetParser || {});
1221
1217
 
1222
1218
  // src/assets/Models.ts
1223
- var Models = class _Models {
1219
+ var _Models = class _Models {
1224
1220
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1225
1221
  // the library, and would require an EnvProvider before any entry has had a chance to register
1226
1222
  static get PERSISTENT_CACHE() {
1227
1223
  return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
1228
1224
  }
1229
1225
  static async getItemList() {
1230
- const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
1231
- const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
1232
- return Caching.listAssetCache.get(key.serialize(), async () => {
1233
- return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
1234
- }).then((r) => r?.files ?? []);
1226
+ return AssetLoader.get(new AssetKey(
1227
+ DEFAULT_NAMESPACE,
1228
+ "_list",
1229
+ "models",
1230
+ "item",
1231
+ "assets",
1232
+ ".json",
1233
+ DEFAULT_ROOT
1234
+ ), "list" /* LIST */).then((r) => r?.files ?? []);
1235
1235
  }
1236
1236
  static async loadAndMerge(key) {
1237
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
1237
+ const model = await this.getRaw(key);
1238
1238
  if (!model) {
1239
1239
  return void 0;
1240
1240
  }
1241
1241
  return ModelMerger.mergeWithParents(model);
1242
1242
  }
1243
- static async getItemModel(key) {
1244
- const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1245
- const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
1246
- const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1247
- if (!result) return void 0;
1248
- if (result.key.assetType !== "items") return { ...result.asset, key };
1249
- const reference = this.defaultItemModel(result.asset.model, key);
1250
- const modelKey = AssetKey.parse("models", reference);
1251
- modelKey.root = key.root;
1252
- const model2 = await this.getRaw(modelKey);
1253
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
1254
- return model2;
1255
- });
1256
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1257
- }
1258
- // Item previews use the GUI context, false conditions, and zero numeric properties.
1259
- static defaultItemModel(node, key) {
1260
- if (!node || typeof node.type !== "string") {
1261
- throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
1262
- }
1263
- switch (node.type.replace(/^minecraft:/, "")) {
1264
- case "model":
1265
- if (typeof node.model === "string" && node.model) return node.model;
1266
- break;
1267
- case "condition":
1268
- return this.defaultItemModel(node.on_false, key);
1269
- case "select": {
1270
- 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;
1271
- return this.defaultItemModel(selected ?? node.fallback, key);
1272
- }
1273
- case "range_dispatch": {
1274
- const selected = node.entries?.reduce((match, entry) => {
1275
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
1276
- }, void 0);
1277
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
1278
- }
1279
- }
1280
- throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
1281
- }
1282
1243
  static async getRaw(key) {
1283
1244
  if (!key.assetType) {
1284
1245
  key.assetType = "models";
@@ -1317,15 +1278,19 @@ var Models = class _Models {
1317
1278
  return this.PERSISTENT_CACHE.clear();
1318
1279
  }
1319
1280
  };
1281
+ __decorateClass([
1282
+ Memoize()
1283
+ ], _Models, "getItemList", 1);
1284
+ var Models = _Models;
1320
1285
 
1321
1286
  // src/assets/BlockStates.ts
1287
+ import { Memoize as Memoize2 } from "typescript-memoize";
1322
1288
  var BlockStates = class {
1323
1289
  static get PERSISTENT_CACHE() {
1324
1290
  return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
1325
1291
  }
1326
- // BlockState names are hardcoded
1327
1292
  static async getList() {
1328
- const key = new AssetKey(
1293
+ return AssetLoader.get(new AssetKey(
1329
1294
  DEFAULT_NAMESPACE,
1330
1295
  "_list",
1331
1296
  "blockstates",
@@ -1333,16 +1298,11 @@ var BlockStates = class {
1333
1298
  "assets",
1334
1299
  ".json",
1335
1300
  DEFAULT_ROOT
1336
- );
1337
- return Caching.listAssetCache.get(key.serialize(), () => {
1338
- return AssetLoader.get(key, "list" /* LIST */);
1339
- }).then((r) => r?.files ?? []);
1301
+ ), "list" /* LIST */).then((r) => r?.files ?? []);
1340
1302
  }
1341
1303
  static async getDefaultStates() {
1342
1304
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
1343
- return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
1344
- return AssetLoader.get(key, "json" /* JSON */);
1345
- });
1305
+ return AssetLoader.get(key, "json" /* JSON */);
1346
1306
  }
1347
1307
  static async getDefaultState(key) {
1348
1308
  const defaultStates = await this.getDefaultStates();
@@ -1381,11 +1341,17 @@ var BlockStates = class {
1381
1341
  await this.PERSISTENT_CACHE.clear();
1382
1342
  }
1383
1343
  };
1344
+ __decorateClass([
1345
+ Memoize2()
1346
+ ], BlockStates, "getList", 1);
1347
+ __decorateClass([
1348
+ Memoize2()
1349
+ ], BlockStates, "getDefaultStates", 1);
1384
1350
  var DefaultBlockStates = class {
1385
1351
  };
1386
1352
 
1387
1353
  // src/assets/Assets.ts
1388
- var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
1354
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
1389
1355
  var DEFAULT_NAMESPACE = "minecraft";
1390
1356
  var Assets = class {
1391
1357
  /**
@@ -1407,150 +1373,13 @@ var AssetSource = class {
1407
1373
  constructor() {
1408
1374
  }
1409
1375
  };
1410
- var AssetLoadError = class extends Error {
1411
- constructor(source, key, path, cause) {
1412
- super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
1413
- this.source = source;
1414
- this.key = key;
1415
- this.path = path;
1416
- this.cause = cause;
1417
- this.name = "AssetLoadError";
1418
- }
1419
- };
1420
1376
 
1421
- // src/util/BatchedExecutor.ts
1422
- var BatchedExecutor = class {
1423
- constructor(interval = 1, batch = 30) {
1424
- this.interval = interval;
1425
- this.batch = batch;
1426
- this.queue = [];
1427
- this.task = setInterval(() => this.run());
1428
- }
1429
- submit(task) {
1430
- this.queue.push(task);
1431
- }
1432
- run() {
1433
- for (let i = 0; i < this.batch; i++) {
1434
- this.runNext();
1435
- }
1436
- }
1437
- runNext() {
1438
- let next = this.queue.shift();
1439
- if (next) next();
1440
- }
1441
- };
1442
-
1443
- // src/util/model.ts
1444
- import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1445
- function applyElementRotation(rotation, geometry) {
1446
- const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1447
- geometry.translate(-origin.x, -origin.y, -origin.z);
1448
- switch (rotation.axis) {
1449
- case "x" /* X */:
1450
- geometry.rotateX(toRadians(rotation.angle));
1451
- break;
1452
- case "y" /* Y */:
1453
- geometry.rotateY(toRadians(rotation.angle));
1454
- break;
1455
- case "z" /* Z */:
1456
- geometry.rotateZ(toRadians(rotation.angle));
1457
- break;
1458
- }
1459
- if (rotation.rescale) {
1460
- if (Math.abs(rotation.angle) === 22.5) {
1461
- const s = 1 / Math.cos(0.39269909262657166);
1462
- geometry.scale(s, 1, s);
1463
- } else {
1464
- const s = 1 / Math.cos(0.7853981852531433);
1465
- geometry.scale(s, 1, s);
1466
- }
1467
- }
1468
- geometry.translate(origin.x, origin.y, origin.z);
1469
- }
1470
- function applyModelPartRotation(modelPart, geometry) {
1471
- const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1472
- geometry.translate(-origin.x, -origin.y, -origin.z);
1473
- geometry.rotateX(toRadians(modelPart.pitch));
1474
- geometry.rotateY(toRadians(modelPart.yaw));
1475
- geometry.rotateZ(toRadians(modelPart.roll));
1476
- geometry.translate(origin.x, origin.y, origin.z);
1477
- }
1478
- function applyGenericRotation(axis, rotation, obj) {
1479
- switch (axis) {
1480
- case "x" /* X */:
1481
- obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1482
- break;
1483
- case "y" /* Y */:
1484
- obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1485
- break;
1486
- case "z" /* Z */:
1487
- obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1488
- break;
1489
- }
1490
- }
1491
- function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1492
- let size = new Vector32();
1493
- box.getSize(size);
1494
- let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1495
- let wireGeo = new EdgesGeometry(boxGeo);
1496
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1497
- let wireframe = new LineSegments(wireGeo, wireMat);
1498
- obj.add(wireframe);
1499
- let axes = new AxesHelper(1);
1500
- obj.add(axes);
1501
- }
1502
- function addWireframeToObject(obj, color = 16777215, w = 2) {
1503
- let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
1504
- let wireGeo = new EdgesGeometry(boxGeo);
1505
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1506
- let wireframe = new LineSegments(wireGeo, wireMat);
1507
- obj.add(wireframe);
1508
- let axes = new AxesHelper(1);
1509
- obj.add(axes);
1510
- }
1511
- function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1512
- let wireGeo = new EdgesGeometry(geo);
1513
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1514
- let wireframe = new LineSegments(wireGeo, wireMat);
1515
- mesh.add(wireframe);
1516
- let axes = new AxesHelper(1);
1517
- mesh.add(axes);
1518
- }
1519
-
1520
- // src/util/performance.ts
1521
- function captureException(e, ...extra) {
1522
- console.error(e, extra);
1523
- }
1524
- function timingStart(marker) {
1525
- console.time(marker);
1526
- }
1527
- function timingEnd(marker) {
1528
- console.timeEnd(marker);
1529
- }
1530
-
1531
- // src/util/three.ts
1532
- function isObject3D(obj) {
1533
- return obj.isObject3D;
1534
- }
1535
- function isMesh(obj) {
1536
- return obj.isMesh;
1537
- }
1538
- function isInstancedMesh(obj) {
1539
- return obj.isInstancedMesh;
1540
- }
1541
- function isPerspectiveCamera(obj) {
1542
- return obj.isPerspectiveCamera;
1543
- }
1544
- function isOrthographicCamera(obj) {
1545
- return obj.isOrthographicCamera;
1546
- }
1547
-
1548
- // src/nbt/NBTHelper.ts
1549
- var NBTHelper = class {
1550
- static async fromBuffer(buffer) {
1551
- const prismarineNbt = await import("prismarine-nbt");
1552
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1553
- return parsed;
1377
+ // src/nbt/NBTHelper.ts
1378
+ var NBTHelper = class {
1379
+ static async fromBuffer(buffer) {
1380
+ const prismarineNbt = await import("prismarine-nbt");
1381
+ const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1382
+ return parsed;
1554
1383
  }
1555
1384
  };
1556
1385
 
@@ -1595,25 +1424,31 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1595
1424
  console.info(p3, "Loading", key);
1596
1425
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1597
1426
  console.debug(p3, url);
1598
- const request = { url };
1599
- try {
1600
- parser.config(request);
1601
- let response;
1602
- try {
1603
- response = await Requests.mcAssetRequest(request);
1604
- } catch (cause) {
1605
- if (cause instanceof RequestError && cause.response?.status === 404) {
1606
- return void 0;
1427
+ let req = {
1428
+ url
1429
+ };
1430
+ parser.config(req);
1431
+ return await Requests.mcAssetRequest(req).then((response) => {
1432
+ if (response && response.data) {
1433
+ try {
1434
+ return parser.parse(response);
1435
+ } catch (e) {
1436
+ console.warn("Parser failed to process response", response, e);
1437
+ throw e;
1607
1438
  }
1608
- throw cause;
1609
1439
  }
1610
- if (response.data === void 0) {
1611
- throw new Error("Asset response has no data");
1440
+ return void 0;
1441
+ }).catch((err) => {
1442
+ if (err.response) {
1443
+ let response = err.response;
1444
+ if (response.status === 404) {
1445
+ console.debug(p3, key, "not found");
1446
+ return void 0;
1447
+ }
1612
1448
  }
1613
- return await parser.parse(response);
1614
- } catch (cause) {
1615
- throw new AssetLoadError(this, key, request.url, cause);
1616
- }
1449
+ console.debug(p3, "Failed to load", key, err?.message);
1450
+ return void 0;
1451
+ });
1617
1452
  }
1618
1453
  assetBasePath(key) {
1619
1454
  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 + "/" : ""}`;
@@ -1720,6 +1555,7 @@ var BrowserArchiveProxy = class {
1720
1555
  };
1721
1556
 
1722
1557
  // src/assets/source/archive/ArchiveAssetSource.ts
1558
+ var p4 = prefix("ArchiveAssetSource");
1723
1559
  var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1724
1560
  constructor(archiveProxy) {
1725
1561
  super();
@@ -1738,31 +1574,74 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1738
1574
  }
1739
1575
  async get(key, parser) {
1740
1576
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
1741
- return this.load(key, responseParser);
1742
- }
1743
- async load(key, parser) {
1577
+ console.log("ArchiveAssetSource.get", key, parser);
1578
+ let entries = await this.getEntries();
1744
1579
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1745
- let url;
1746
- try {
1747
- const entry = await this.getEntry(path);
1748
- if (!entry) {
1749
- return void 0;
1580
+ console.log(path);
1581
+ const entry = await this.getEntry(path);
1582
+ console.log(entry);
1583
+ if (!entry) {
1584
+ return void 0;
1585
+ }
1586
+ let blob = await entry.getData();
1587
+ const url = URL.createObjectURL(blob);
1588
+ console.log(url);
1589
+ let req = {
1590
+ url
1591
+ };
1592
+ responseParser.config(req);
1593
+ return Requests.genericRequest(req).then((response) => {
1594
+ if (response && response.data) {
1595
+ try {
1596
+ return responseParser.parse(response);
1597
+ } catch (e) {
1598
+ console.warn("Parser failed to process response", response, e);
1599
+ throw e;
1600
+ }
1601
+ }
1602
+ return void 0;
1603
+ }).catch((err) => {
1604
+ if (err.response) {
1605
+ let response = err.response;
1606
+ if (response.status === 404) {
1607
+ console.debug(p4, key, "not found");
1608
+ return void 0;
1609
+ }
1750
1610
  }
1751
- url = URL.createObjectURL(await entry.getData());
1752
- const request = { url };
1753
- parser.config(request);
1754
- const response = await Requests.genericRequest(request);
1755
- if (response.data === void 0) {
1756
- throw new Error("Asset response has no data");
1611
+ console.debug(p4, "Failed to load", key, err?.message);
1612
+ return void 0;
1613
+ });
1614
+ }
1615
+ //TODO: abstract this
1616
+ async load(key, parser) {
1617
+ console.info(p4, "Loading", key);
1618
+ const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1619
+ console.debug(p4, url);
1620
+ let req = {
1621
+ url
1622
+ };
1623
+ parser.config(req);
1624
+ return await Requests.genericRequest(req).then((response) => {
1625
+ if (response && response.data) {
1626
+ try {
1627
+ return parser.parse(response);
1628
+ } catch (e) {
1629
+ console.warn("Parser failed to process response", response, e);
1630
+ throw e;
1631
+ }
1757
1632
  }
1758
- return await parser.parse(response);
1759
- } catch (cause) {
1760
- throw new AssetLoadError(this, key, path, cause);
1761
- } finally {
1762
- if (url !== void 0) {
1763
- URL.revokeObjectURL(url);
1633
+ return void 0;
1634
+ }).catch((err) => {
1635
+ if (err.response) {
1636
+ let response = err.response;
1637
+ if (response.status === 404) {
1638
+ console.debug(p4, key, "not found");
1639
+ return void 0;
1640
+ }
1764
1641
  }
1765
- }
1642
+ console.debug(p4, "Failed to load", key, err?.message);
1643
+ return void 0;
1644
+ });
1766
1645
  }
1767
1646
  assetBasePath(key) {
1768
1647
  return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1770,17 +1649,18 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1770
1649
  };
1771
1650
 
1772
1651
  // src/assets/AssetLoader.ts
1773
- var p4 = prefix("AssetLoader");
1652
+ var import_ts_deepmerge3 = __toESM(require_dist());
1653
+ var p5 = prefix("AssetLoader");
1774
1654
  var _AssetLoader = class _AssetLoader {
1775
1655
  static addSource(key, source, override = true) {
1776
1656
  if (override) {
1777
1657
  const existing = this.removeSource(key);
1778
1658
  if (existing) {
1779
- console.log(p4, "Removed existing AssetSource", key);
1659
+ console.log(p5, "Removed existing AssetSource", key);
1780
1660
  }
1781
1661
  }
1782
1662
  this._SOURCES.unshift({ key, source });
1783
- console.log(p4, "Added AssetSource", key);
1663
+ console.log(p5, "Added AssetSource", key);
1784
1664
  }
1785
1665
  static removeSource(key) {
1786
1666
  const index = this._SOURCES.findIndex((s) => s.key === key);
@@ -1793,6 +1673,7 @@ var _AssetLoader = class _AssetLoader {
1793
1673
  return void 0;
1794
1674
  }
1795
1675
  static async getAll(key, parser) {
1676
+ console.log(this._SOURCES);
1796
1677
  let promises = [];
1797
1678
  for (const source of this._SOURCES) {
1798
1679
  promises.push(source.source.get(key, parser));
@@ -1801,34 +1682,24 @@ var _AssetLoader = class _AssetLoader {
1801
1682
  return results.filter((r) => r != void 0);
1802
1683
  });
1803
1684
  }
1804
- /** Returns the first defined result in source-priority order, without merging assets. */
1805
1685
  static async get(key, parser) {
1806
- const keys = [key];
1807
- if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
1808
- keys.push(new AssetKey(
1809
- key.namespace,
1810
- key.path,
1811
- key.assetType === "structure" ? "structures" : "structure",
1812
- key.type,
1813
- key.rootType,
1814
- key.extension,
1815
- key.root
1816
- ));
1817
- }
1818
- return (await this.getFirst(keys, parser))?.asset;
1819
- }
1820
- /** Tries each path within a source before considering lower-priority sources. */
1821
- static async getFirst(keys, parser) {
1822
- const sources = [...this._SOURCES];
1823
- for (const source of sources) {
1824
- for (const key of keys) {
1825
- const result = await source.source.get(key, parser);
1826
- if (result !== void 0) {
1827
- return { key, asset: result };
1686
+ console.log(this._SOURCES);
1687
+ let promises = [];
1688
+ for (const source of this._SOURCES) {
1689
+ promises.push(source.source.get(key, parser));
1690
+ }
1691
+ return Promise.all(promises).then((results) => {
1692
+ const fallback = results[results.length - 1];
1693
+ for (const result of results) {
1694
+ if (result) {
1695
+ if (fallback) {
1696
+ return (0, import_ts_deepmerge3.default)({}, fallback, result);
1697
+ }
1698
+ return result;
1828
1699
  }
1829
1700
  }
1830
- }
1831
- return void 0;
1701
+ return void 0;
1702
+ });
1832
1703
  }
1833
1704
  };
1834
1705
  _AssetLoader.ROOT = DEFAULT_ROOT;
@@ -1843,21 +1714,11 @@ var ModelTextures = class {
1843
1714
  return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
1844
1715
  }
1845
1716
  static async get(key) {
1846
- const keyStr = key.serialize();
1847
- const pending = this.preload(key);
1848
- const cached = Caching.textureAssetCache.getIfPresent(keyStr);
1849
- try {
1850
- const asset = await pending;
1851
- if (asset) {
1852
- return await ImageLoader.infoToCanvasData(asset);
1853
- }
1854
- return void 0;
1855
- } catch (err) {
1856
- if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
1857
- Caching.textureAssetCache.invalidate(keyStr);
1858
- }
1859
- throw err;
1717
+ const asset = await this.preload(key);
1718
+ if (asset) {
1719
+ return ImageLoader.infoToCanvasData(asset);
1860
1720
  }
1721
+ return void 0;
1861
1722
  }
1862
1723
  static async preload(key) {
1863
1724
  const keyStr = key.serialize();
@@ -2048,7 +1909,7 @@ var ModelGenerator = class {
2048
1909
  ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2049
1910
 
2050
1911
  // src/UVMapper.ts
2051
- var p5 = prefix("UVMapper");
1912
+ var p6 = prefix("UVMapper");
2052
1913
  var DEFAULT_UV = [0, 0, 16, 16];
2053
1914
  var X = 0;
2054
1915
  var Y = 1;
@@ -2225,7 +2086,7 @@ var UVMapper = class {
2225
2086
  const metaMap = {};
2226
2087
  const model = { ...originalModel };
2227
2088
  const isItemModel = !("elements" in model);
2228
- console.debug(p5, "Creating Atlas for", model.key);
2089
+ console.debug(p6, "Creating Atlas for", model.key);
2229
2090
  if (model.textures) {
2230
2091
  const promises = [];
2231
2092
  const uniqueTextureNames = [];
@@ -2239,7 +2100,7 @@ var UVMapper = class {
2239
2100
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
2240
2101
  promises.push(ModelTextures.get(assetKey).then((asset) => {
2241
2102
  if (!asset) {
2242
- console.warn(p5, "Missing texture", assetKey);
2103
+ console.warn(p6, "Missing texture", assetKey);
2243
2104
  return;
2244
2105
  }
2245
2106
  textureMap[textureKey] = new WrappedImage(asset);
@@ -2251,7 +2112,7 @@ var UVMapper = class {
2251
2112
  }
2252
2113
  await Promise.all(promises);
2253
2114
  const textureCount = uniqueTextureNames.length;
2254
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
2115
+ console.debug(p6, "Creating Atlas for", textureCount, "textures");
2255
2116
  this.fillMissingTextureKeys(model.textures, textureMap);
2256
2117
  this.fillMissingTextureKeys(model.textures, metaMap);
2257
2118
  const sizes = {};
@@ -2271,7 +2132,7 @@ var UVMapper = class {
2271
2132
  this.fillMissingTextureKeys(model.textures, sizes);
2272
2133
  const s = Math.ceil(Math.sqrt(textureCount + 1));
2273
2134
  const size = Math.ceil(s * maxWidth);
2274
- console.debug(p5, "Atlas size:", size);
2135
+ console.debug(p6, "Atlas size:", size);
2275
2136
  const squaredSize = size * size;
2276
2137
  const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
2277
2138
  const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
@@ -2326,10 +2187,10 @@ var UVMapper = class {
2326
2187
  }
2327
2188
  }
2328
2189
  const atlasImageData = image.toDataURL();
2329
- console.log(p5, "Atlas Image for", model.key, atlasImageData);
2190
+ console.log(p6, "Atlas Image for", model.key, atlasImageData);
2330
2191
  this.fillMissingTextureKeys(model.textures, positions);
2331
2192
  if (isItemModel) {
2332
- console.debug(p5, "Generating item model for", model);
2193
+ console.debug(p6, "Generating item model for", model);
2333
2194
  model.elements = [];
2334
2195
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2335
2196
  const textureImage = textureMap[layerName];
@@ -2337,7 +2198,7 @@ var UVMapper = class {
2337
2198
  model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2338
2199
  }
2339
2200
  }
2340
- console.debug(p5, "Item model elements", model.elements);
2201
+ console.debug(p6, "Item model elements", model.elements);
2341
2202
  }
2342
2203
  if (!model.elements) {
2343
2204
  }
@@ -2355,13 +2216,17 @@ var UVMapper = class {
2355
2216
  this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
2356
2217
  continue;
2357
2218
  }
2358
- if (!face.texture) continue;
2359
2219
  if (!face.uv) {
2360
2220
  face.uv = this.getFallbackUv(element, faceName);
2361
2221
  }
2362
- const faceTexture = face.texture.substr(1);
2363
- const texPosition = positions[faceTexture] || [0, 0];
2364
- const texSize = sizes[faceTexture] || [16, 16];
2222
+ let faceTexture = face.texture;
2223
+ let texPosition;
2224
+ let texSize;
2225
+ if (faceTexture) {
2226
+ faceTexture = faceTexture.substr(1);
2227
+ texPosition = positions[faceTexture] || [0, 0];
2228
+ texSize = sizes[faceTexture] || [16, 16];
2229
+ }
2365
2230
  let texPosV = new Vector2(texPosition[0], texPosition[1]);
2366
2231
  const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
2367
2232
  tl.add(texPosV);
@@ -2393,7 +2258,7 @@ var UVMapper = class {
2393
2258
  hasTransparency
2394
2259
  );
2395
2260
  } else {
2396
- console.warn(p5, "Model does not have any textures", model);
2261
+ console.warn(p6, "Model does not have any textures", model);
2397
2262
  }
2398
2263
  return void 0;
2399
2264
  }
@@ -2531,20 +2396,17 @@ function shutdown() {
2531
2396
  }
2532
2397
 
2533
2398
  // src/assets/Entities.ts
2399
+ import { Memoize as Memoize3 } from "typescript-memoize";
2534
2400
  var Entities = class {
2535
2401
  static async getBlockEntityModels() {
2536
2402
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
2537
2403
  console.log(key);
2538
- return Caching.entityModelsCache.get(key.serialize(), () => {
2539
- return AssetLoader.get(key, "json" /* JSON */);
2540
- });
2404
+ return AssetLoader.get(key, "json" /* JSON */);
2541
2405
  }
2542
2406
  static async getEntityModels() {
2543
2407
  const key = AssetKey.parse("models", "minerender:entityModels");
2544
2408
  console.log(key);
2545
- return Caching.entityModelsCache.get(key.serialize(), () => {
2546
- return AssetLoader.get(key, "json" /* JSON */);
2547
- });
2409
+ return AssetLoader.get(key, "json" /* JSON */);
2548
2410
  }
2549
2411
  // BlockEntity names are hardcoded
2550
2412
  static async getBlockList() {
@@ -2590,6 +2452,12 @@ var Entities = class {
2590
2452
  };
2591
2453
  }
2592
2454
  };
2455
+ __decorateClass([
2456
+ Memoize3()
2457
+ ], Entities, "getBlockEntityModels", 1);
2458
+ __decorateClass([
2459
+ Memoize3()
2460
+ ], Entities, "getEntityModels", 1);
2593
2461
  var EntityModels = class {
2594
2462
  };
2595
2463
  var BlockEntityModels = class {
@@ -2653,8 +2521,8 @@ var MineRenderError = class _MineRenderError extends Error {
2653
2521
  };
2654
2522
 
2655
2523
  // src/renderer/SceneObject.ts
2656
- var import_ts_deepmerge3 = __toESM(require_dist());
2657
- var p6 = prefix("SceneObject");
2524
+ var import_ts_deepmerge4 = __toESM(require_dist());
2525
+ var p7 = prefix("SceneObject");
2658
2526
  var _SceneObject = class _SceneObject extends Object3D2 {
2659
2527
  constructor(options) {
2660
2528
  super();
@@ -2662,7 +2530,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2662
2530
  this.materialCallbacks = {};
2663
2531
  this._isInstanced = false;
2664
2532
  this._instanceCounter = 0;
2665
- this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2533
+ this.options = (0, import_ts_deepmerge4.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2666
2534
  console.log("SceneObject options", this.options);
2667
2535
  }
2668
2536
  set scene(scene) {
@@ -2833,9 +2701,9 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2833
2701
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2834
2702
  const i = this._instanceCounter++;
2835
2703
  this.setMatrixAt(i, new Matrix42());
2836
- console.debug(p6, "nextInstance " + i);
2704
+ console.debug(p7, "nextInstance " + i);
2837
2705
  if (i === this.options.maxInstanceCount) {
2838
- console.warn(p6, "Max instance count reached for " + this);
2706
+ console.warn(p7, "Max instance count reached for " + this);
2839
2707
  }
2840
2708
  if (this.scene) {
2841
2709
  this.scene.stats.instanceCount++;
@@ -3011,7 +2879,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
3011
2879
  }
3012
2880
  //</editor-fold>
3013
2881
  };
3014
- _SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
2882
+ _SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, {
3015
2883
  instanceMeshes: true,
3016
2884
  maxInstanceCount: 50,
3017
2885
  mergeMeshes: true,
@@ -3023,16 +2891,16 @@ function isSceneObject(obj) {
3023
2891
  }
3024
2892
 
3025
2893
  // src/entity/scene/EntityObject.ts
3026
- var import_ts_deepmerge4 = __toESM(require_dist());
2894
+ var import_ts_deepmerge5 = __toESM(require_dist());
3027
2895
  import { Object3D as Object3D3 } from "three";
3028
- import * as THREE3 from "three";
2896
+ import * as THREE2 from "three";
3029
2897
  var EntityObject = class extends SceneObject {
3030
2898
  constructor(entity, options) {
3031
2899
  super();
3032
2900
  this.entity = entity;
3033
2901
  this.isEntityObject = true;
3034
2902
  this.meshesCreated = false;
3035
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
2903
+ this.options = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3036
2904
  }
3037
2905
  async init() {
3038
2906
  this.createMeshes();
@@ -3041,8 +2909,8 @@ var EntityObject = class extends SceneObject {
3041
2909
  dispose() {
3042
2910
  super.dispose();
3043
2911
  }
3044
- get textureKey() {
3045
- return new AssetKey(
2912
+ async loadTextures() {
2913
+ this.imageData = await ModelTextures.get(new AssetKey(
3046
2914
  this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
3047
2915
  this.entity.key.path,
3048
2916
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
@@ -3050,10 +2918,7 @@ var EntityObject = class extends SceneObject {
3050
2918
  "entity",
3051
2919
  "assets",
3052
2920
  ".png"
3053
- );
3054
- }
3055
- async loadTextures() {
3056
- this.imageData = await ModelTextures.get(this.textureKey);
2921
+ ));
3057
2922
  }
3058
2923
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3059
2924
  createMeshes(force = false) {
@@ -3072,8 +2937,8 @@ var EntityObject = class extends SceneObject {
3072
2937
  const l = cube.maxZ - cube.minZ;
3073
2938
  const uv = texture.toUvArray(w, h, l);
3074
2939
  const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3075
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3076
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
2940
+ cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
2941
+ cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
3077
2942
  applyModelPartRotation(part, cubeGeo);
3078
2943
  const mesh = this.createMesh(partName, cubeGeo, mat);
3079
2944
  partAnchor.add(mesh);
@@ -3086,26 +2951,23 @@ var EntityObject = class extends SceneObject {
3086
2951
  this.meshesCreated = true;
3087
2952
  }
3088
2953
  async applyTextures() {
3089
- const assetKeyStr = this.textureKey.serialize();
3090
- const keyStr = `entity:${assetKeyStr}`;
3091
- let mat = Caching.materialCache.getIfPresent(keyStr);
3092
- if (!mat) {
3093
- const pending = this.loadTextures();
3094
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3095
- await pending;
3096
- if (!this.imageData) return;
3097
- const canvas = this.imageData.data.canvas;
3098
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3099
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3100
- this.imageData = void 0;
3101
- }
3102
- this.iterateAllMeshes((mesh) => {
3103
- mesh.material = mat;
3104
- });
3105
- this.notifyDirty();
2954
+ const textureAsset = await ModelTextures.preload(new AssetKey(
2955
+ this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
2956
+ this.entity.key.path,
2957
+ "textures",
2958
+ "entity",
2959
+ "assets",
2960
+ ".png"
2961
+ ));
2962
+ if (textureAsset) {
2963
+ let mat = Materials.getImage({ texture: { src: textureAsset.src } });
2964
+ this.iterateAllMeshes((mesh) => {
2965
+ mesh.material = mat;
2966
+ });
2967
+ }
3106
2968
  }
3107
2969
  };
3108
- EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
2970
+ EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3109
2971
  function isEntityObject(obj) {
3110
2972
  return obj.isEntityObject;
3111
2973
  }
@@ -3117,7 +2979,7 @@ var GuiObject = class extends SceneObject {
3117
2979
 
3118
2980
  // src/inspector/SceneInspector.ts
3119
2981
  import { Raycaster, Vector2 as Vector22 } from "three";
3120
- var p7 = prefix("SceneInspector");
2982
+ var p8 = prefix("SceneInspector");
3121
2983
  var help = "<span>Ctrl+Click to Select<br/></span><br/>";
3122
2984
  var SceneInspector = class {
3123
2985
  constructor(renderer) {
@@ -3186,7 +3048,7 @@ var SceneInspector = class {
3186
3048
  }
3187
3049
  selectObject(targetObject, targetIntersection) {
3188
3050
  this.selectedObject = targetObject;
3189
- console.log(p7, "selected", targetObject);
3051
+ console.log(p8, "selected", targetObject);
3190
3052
  this.redraw(targetObject, targetIntersection);
3191
3053
  }
3192
3054
  redraw(targetObject, targetIntersection) {
@@ -3484,7 +3346,7 @@ var SceneStatsDisplay = class {
3484
3346
  };
3485
3347
 
3486
3348
  // src/instance/InstanceManager.ts
3487
- var p8 = prefix("InstanceManager");
3349
+ var p9 = prefix("InstanceManager");
3488
3350
  var InstanceManager = class {
3489
3351
  constructor() {
3490
3352
  this.isInstanceManager = true;
@@ -3492,7 +3354,7 @@ var InstanceManager = class {
3492
3354
  }
3493
3355
  async get(key) {
3494
3356
  if (key in this.instanceCache) {
3495
- console.debug(p8, "key in cache", key);
3357
+ console.debug(p9, "key in cache", key);
3496
3358
  return (await this.instanceCache[key]).nextInstance();
3497
3359
  }
3498
3360
  return void 0;
@@ -3501,17 +3363,13 @@ var InstanceManager = class {
3501
3363
  if (key in this.instanceCache) {
3502
3364
  return await this.get(key);
3503
3365
  }
3504
- console.debug(p8, "key not in cache", key);
3505
- const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
3506
- this.instanceCache[key] = pending;
3507
- try {
3508
- return await pending;
3509
- } catch (error) {
3510
- if (this.instanceCache[key] === pending) {
3511
- delete this.instanceCache[key];
3512
- }
3513
- throw error;
3514
- }
3366
+ console.debug(p9, "key not in cache", key);
3367
+ this.instanceCache[key] = new Promise(async (resolve) => {
3368
+ const obj = await supplier();
3369
+ const instance = obj.nextInstance();
3370
+ resolve(instance);
3371
+ });
3372
+ return await this.instanceCache[key];
3515
3373
  }
3516
3374
  reset() {
3517
3375
  for (let instanceCacheKey in this.instanceCache) {
@@ -4110,15 +3968,15 @@ function computeMorphedAttributes(object) {
4110
3968
  }
4111
3969
 
4112
3970
  // src/model/scene/ModelObject.ts
4113
- var import_ts_deepmerge5 = __toESM(require_dist());
4114
- var p9 = prefix("ModelObject");
3971
+ var import_ts_deepmerge6 = __toESM(require_dist());
3972
+ var p10 = prefix("ModelObject");
4115
3973
  var _ModelObject = class _ModelObject extends SceneObject {
4116
3974
  constructor(originalModel, options) {
4117
3975
  super(options);
4118
3976
  this.originalModel = originalModel;
4119
3977
  this.isModelObject = true;
4120
3978
  this.meshesCreated = false;
4121
- this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
3979
+ this.options = (0, import_ts_deepmerge6.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4122
3980
  console.log("ModelObject options", this.options);
4123
3981
  }
4124
3982
  async init() {
@@ -4161,10 +4019,10 @@ var _ModelObject = class _ModelObject extends SceneObject {
4161
4019
  }
4162
4020
  });
4163
4021
  } else {
4164
- console.debug(p9, this.atlas.model, "has no elements");
4022
+ console.debug(p10, this.atlas.model, "has no elements");
4165
4023
  }
4166
4024
  } else {
4167
- console.debug(p9, "Missing atlas for", this);
4025
+ console.debug(p10, "Missing atlas for", this);
4168
4026
  }
4169
4027
  if (this.options.mergeMeshes) {
4170
4028
  let combinedGeo;
@@ -4216,26 +4074,16 @@ var _ModelObject = class _ModelObject extends SceneObject {
4216
4074
  }
4217
4075
  }
4218
4076
  };
4219
- _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4077
+ _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4220
4078
  var ModelObject = _ModelObject;
4221
4079
  function isModelObject(obj) {
4222
4080
  return obj.isModelObject;
4223
4081
  }
4224
4082
 
4225
4083
  // src/model/block/scene/BlockObject.ts
4226
- var import_ts_deepmerge6 = __toESM(require_dist());
4084
+ var import_ts_deepmerge7 = __toESM(require_dist());
4227
4085
  import { Euler as Euler3, Matrix4 as Matrix46, Vector3 as Vector36 } from "three";
4228
- var p10 = prefix("BlockObject");
4229
- function matchesCondition(condition, state) {
4230
- return Object.entries(condition).every(([key, value]) => {
4231
- if (Array.isArray(value)) {
4232
- if (key === "OR") return value.some((child) => matchesCondition(child, state));
4233
- if (key === "AND") return value.every((child) => matchesCondition(child, state));
4234
- return false;
4235
- }
4236
- return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4237
- });
4238
- }
4086
+ var p11 = prefix("BlockObject");
4239
4087
  var _BlockObject = class _BlockObject extends SceneObject {
4240
4088
  constructor(blockState, options) {
4241
4089
  super(options);
@@ -4249,11 +4097,11 @@ var _BlockObject = class _BlockObject extends SceneObject {
4249
4097
  this._instanceModel = [];
4250
4098
  this._variants = [];
4251
4099
  this._models = [];
4252
- this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4100
+ this.options = (0, import_ts_deepmerge7.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4253
4101
  }
4254
4102
  async init() {
4255
4103
  if (this.options.applyDefaultState) {
4256
- const defaultState = this.blockState.key ? await BlockStates.getDefaultState(this.blockState.key) : void 0;
4104
+ const defaultState = this.blockState.key ? BlockStates.getDefaultState(this.blockState.key) : void 0;
4257
4105
  if (defaultState && Object.keys(defaultState).length > 0) {
4258
4106
  const state = {};
4259
4107
  for (let k in defaultState) {
@@ -4264,9 +4112,15 @@ var _BlockObject = class _BlockObject extends SceneObject {
4264
4112
  if (this.blockState.variants) {
4265
4113
  await this.setState(Object.keys(this.blockState.variants)[0]);
4266
4114
  } else if (this.blockState.multipart) {
4267
- const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4268
- const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4269
- await this.setState(state);
4115
+ for (let part of this.blockState.multipart) {
4116
+ if (part.when && !("OR" in part.when)) {
4117
+ const k = Object.keys(part.when)[0];
4118
+ if (k) {
4119
+ await this.setState(k, part.when[k].split("|")[0]);
4120
+ break;
4121
+ }
4122
+ }
4123
+ }
4270
4124
  }
4271
4125
  }
4272
4126
  } else {
@@ -4323,11 +4177,55 @@ var _BlockObject = class _BlockObject extends SceneObject {
4323
4177
  } else if (this.blockState.multipart) {
4324
4178
  for (let part of this.blockState.multipart) {
4325
4179
  if (!part.apply) {
4326
- console.debug(p10, "Missing apply for blockState part", part);
4180
+ console.debug(p11, "Missing apply for blockState part", part);
4327
4181
  continue;
4328
4182
  }
4329
- if (!part.when || matchesCondition(part.when, state)) {
4183
+ if (!part.when) {
4330
4184
  out.push(this.getSingleVariant(part.apply));
4185
+ } else {
4186
+ let matches = true;
4187
+ if ("OR" in part.when) {
4188
+ const or = part.when.OR;
4189
+ let anyMatch = false;
4190
+ for (let o of or) {
4191
+ for (let k in o) {
4192
+ const split = o[k].split("|");
4193
+ let m = false;
4194
+ for (let s of split) {
4195
+ if (`${state[k]}` === `${s}`) {
4196
+ m = true;
4197
+ break;
4198
+ }
4199
+ }
4200
+ if (m) {
4201
+ anyMatch = true;
4202
+ break;
4203
+ }
4204
+ }
4205
+ }
4206
+ if (!anyMatch) {
4207
+ matches = false;
4208
+ }
4209
+ } else {
4210
+ for (let k in part.when) {
4211
+ const split = part.when[k].split("|");
4212
+ let m = false;
4213
+ for (let s of split) {
4214
+ if (`${state[k]}` === `${s}`) {
4215
+ m = true;
4216
+ break;
4217
+ }
4218
+ }
4219
+ if (!m) {
4220
+ matches = false;
4221
+ break;
4222
+ }
4223
+ }
4224
+ }
4225
+ if (matches) {
4226
+ const variants = part.apply;
4227
+ out.push(this.getSingleVariant(variants));
4228
+ }
4331
4229
  }
4332
4230
  }
4333
4231
  }
@@ -4357,21 +4255,11 @@ var _BlockObject = class _BlockObject extends SceneObject {
4357
4255
  }
4358
4256
  }
4359
4257
  getSingleVariant(variants) {
4360
- if (!Array.isArray(variants)) return variants;
4361
- if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4362
- const total = variants.reduce((sum, variant) => {
4363
- const weight = variant.weight ?? 1;
4364
- if (!Number.isInteger(weight) || weight < 1) {
4365
- throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4366
- }
4367
- return sum + weight;
4368
- }, 0);
4369
- let choice = Math.random() * total;
4370
- for (const variant of variants) {
4371
- choice -= variant.weight ?? 1;
4372
- if (choice < 0) return variant;
4373
- }
4374
- return variants[variants.length - 1];
4258
+ if (Array.isArray(variants)) {
4259
+ return variants[0];
4260
+ } else {
4261
+ return variants;
4262
+ }
4375
4263
  }
4376
4264
  // @deprecated
4377
4265
  async createAVariant(variants, instanceInfo) {
@@ -4397,6 +4285,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
4397
4285
  }
4398
4286
  }
4399
4287
  obj.setRotation(rotation);
4288
+ setTimeout(() => {
4289
+ obj.setRotation(rotation);
4290
+ }, 150);
4400
4291
  console.log(obj);
4401
4292
  return obj;
4402
4293
  }
@@ -4487,16 +4378,15 @@ var _BlockObject = class _BlockObject extends SceneObject {
4487
4378
  }
4488
4379
  }
4489
4380
  setPosition(position) {
4490
- this.position.copy(position);
4381
+ super.setPosition(position);
4491
4382
  for (let model of this._models) {
4492
4383
  model.setPosition(position);
4493
4384
  }
4494
- this.notifyDirty();
4495
4385
  }
4496
4386
  //TODO: should override rotation + scale methods
4497
4387
  //TODO
4498
4388
  };
4499
- _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
4389
+ _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge7.default)({}, ModelObject.DEFAULT_OPTIONS, {
4500
4390
  applyDefaultState: true
4501
4391
  });
4502
4392
  var BlockObject = _BlockObject;
@@ -4546,7 +4436,7 @@ var StructureParser = class {
4546
4436
 
4547
4437
  // src/renderer/MineRenderScene.ts
4548
4438
  import { Scene as Scene2 } from "three";
4549
- var import_ts_deepmerge8 = __toESM(require_dist());
4439
+ var import_ts_deepmerge9 = __toESM(require_dist());
4550
4440
 
4551
4441
  // src/skin/SkinPart.ts
4552
4442
  var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
@@ -5277,7 +5167,7 @@ var slimSkinGeometries = {
5277
5167
  };
5278
5168
 
5279
5169
  // src/skin/scene/SkinObject.ts
5280
- var import_ts_deepmerge7 = __toESM(require_dist());
5170
+ var import_ts_deepmerge8 = __toESM(require_dist());
5281
5171
  var SkinObject = class extends SceneObject {
5282
5172
  constructor(options) {
5283
5173
  super();
@@ -5285,7 +5175,7 @@ var SkinObject = class extends SceneObject {
5285
5175
  this.legacy = false;
5286
5176
  this.skinTextureWidth = 64;
5287
5177
  this.skinTextureHeight = 64;
5288
- this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5178
+ this.options = (0, import_ts_deepmerge8.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5289
5179
  }
5290
5180
  async init() {
5291
5181
  this.createMeshes();
@@ -5402,7 +5292,7 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5402
5292
  this.dirty = true;
5403
5293
  }
5404
5294
  };
5405
- this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5295
+ this.options = (0, import_ts_deepmerge9.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5406
5296
  }
5407
5297
  add(...objects) {
5408
5298
  for (const object of objects) {
@@ -5498,1148 +5388,1114 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5498
5388
  return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
5499
5389
  }
5500
5390
  };
5501
- _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
5391
+ _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {});
5502
5392
  var MineRenderScene = _MineRenderScene;
5503
5393
  function isMineRenderScene(obj) {
5504
5394
  return obj.isMineRenderScene;
5505
5395
  }
5506
5396
 
5507
5397
  // src/renderer/Renderer.ts
5508
- import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector38, WebGLRenderer } from "three";
5509
- var import_ts_deepmerge9 = __toESM(require_dist());
5398
+ import { AxesHelper as AxesHelper3, GridHelper, LinearEncoding, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, Vector3 as Vector37, WebGLRenderer } from "three";
5399
+ var import_ts_deepmerge10 = __toESM(require_dist());
5510
5400
  import Stats from "stats.js";
5511
5401
  import { EffectComposer, RenderPass } from "postprocessing";
5512
-
5513
- // src/three/OrbitControls.js
5514
- import {
5515
- EventDispatcher,
5516
- MOUSE,
5517
- Quaternion as Quaternion3,
5518
- Spherical,
5519
- TOUCH,
5520
- Vector2 as Vector23,
5521
- Vector3 as Vector37
5522
- } from "three";
5523
- var _changeEvent = { type: "change" };
5524
- var _startEvent = { type: "start" };
5525
- var _endEvent = { type: "end" };
5526
- var OrbitControls = class extends EventDispatcher {
5527
- constructor(object, domElement) {
5528
- super();
5529
- if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5530
- if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5531
- this.object = object;
5532
- this.domElement = domElement;
5533
- this.domElement.style.touchAction = "none";
5534
- this.enabled = true;
5535
- this.target = new Vector37();
5536
- this.minDistance = 0;
5537
- this.maxDistance = Infinity;
5538
- this.minZoom = 0;
5539
- this.maxZoom = Infinity;
5540
- this.minPolarAngle = 0;
5541
- this.maxPolarAngle = Math.PI;
5542
- this.minAzimuthAngle = -Infinity;
5543
- this.maxAzimuthAngle = Infinity;
5544
- this.enableDamping = false;
5545
- this.dampingFactor = 0.05;
5546
- this.enableZoom = true;
5547
- this.zoomSpeed = 1;
5548
- this.enableRotate = true;
5549
- this.rotateSpeed = 1;
5550
- this.enablePan = true;
5551
- this.panSpeed = 1;
5552
- this.screenSpacePanning = true;
5553
- this.keyPanSpeed = 7;
5554
- this.autoRotate = false;
5555
- this.autoRotateSpeed = 2;
5556
- this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5557
- this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
5558
- this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
5559
- this.target0 = this.target.clone();
5560
- this.position0 = this.object.position.clone();
5561
- this.zoom0 = this.object.zoom;
5562
- this._domElementKeyEvents = null;
5563
- this.getPolarAngle = function() {
5564
- return spherical.phi;
5565
- };
5566
- this.getAzimuthalAngle = function() {
5567
- return spherical.theta;
5568
- };
5569
- this.getDistance = function() {
5570
- return this.object.position.distanceTo(this.target);
5571
- };
5572
- this.saveState = function() {
5573
- scope.target0.copy(scope.target);
5574
- scope.position0.copy(scope.object.position);
5575
- scope.zoom0 = scope.object.zoom;
5576
- };
5577
- this.reset = function() {
5578
- scope.target.copy(scope.target0);
5579
- scope.object.position.copy(scope.position0);
5580
- scope.object.zoom = scope.zoom0;
5581
- scope.object.updateProjectionMatrix();
5582
- scope.dispatchEvent(_changeEvent);
5583
- scope.update();
5584
- state = STATE.NONE;
5585
- };
5586
- this.update = function() {
5587
- const offset = new Vector37();
5588
- const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector37(0, 1, 0));
5589
- const quatInverse = quat.clone().invert();
5590
- const lastPosition = new Vector37();
5591
- const lastQuaternion = new Quaternion3();
5592
- const twoPI = 2 * Math.PI;
5593
- return function update() {
5594
- const position = scope.object.position;
5595
- offset.copy(position).sub(scope.target);
5596
- offset.applyQuaternion(quat);
5597
- spherical.setFromVector3(offset);
5598
- if (scope.autoRotate && state === STATE.NONE) {
5599
- rotateLeft(getAutoRotationAngle());
5600
- }
5601
- if (scope.enableDamping) {
5602
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5603
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5604
- } else {
5605
- spherical.theta += sphericalDelta.theta;
5606
- spherical.phi += sphericalDelta.phi;
5607
- }
5608
- let min = scope.minAzimuthAngle;
5609
- let max = scope.maxAzimuthAngle;
5610
- if (isFinite(min) && isFinite(max)) {
5611
- if (min < -Math.PI) min += twoPI;
5612
- else if (min > Math.PI) min -= twoPI;
5613
- if (max < -Math.PI) max += twoPI;
5614
- else if (max > Math.PI) max -= twoPI;
5615
- if (min <= max) {
5616
- spherical.theta = Math.max(min, Math.min(max, spherical.theta));
5617
- } else {
5618
- spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
5619
- }
5620
- }
5621
- spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5622
- spherical.makeSafe();
5623
- spherical.radius *= scale;
5624
- spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5625
- if (scope.enableDamping === true) {
5626
- scope.target.addScaledVector(panOffset, scope.dampingFactor);
5627
- } else {
5628
- scope.target.add(panOffset);
5629
- }
5630
- offset.setFromSpherical(spherical);
5631
- offset.applyQuaternion(quatInverse);
5632
- position.copy(scope.target).add(offset);
5633
- scope.object.lookAt(scope.target);
5634
- if (scope.enableDamping === true) {
5635
- sphericalDelta.theta *= 1 - scope.dampingFactor;
5636
- sphericalDelta.phi *= 1 - scope.dampingFactor;
5637
- panOffset.multiplyScalar(1 - scope.dampingFactor);
5638
- } else {
5639
- sphericalDelta.set(0, 0, 0);
5640
- panOffset.set(0, 0, 0);
5641
- }
5642
- scale = 1;
5643
- if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5644
- scope.dispatchEvent(_changeEvent);
5645
- lastPosition.copy(scope.object.position);
5646
- lastQuaternion.copy(scope.object.quaternion);
5647
- zoomChanged = false;
5648
- return true;
5649
- }
5650
- return false;
5651
- };
5652
- }();
5653
- this.dispose = function() {
5654
- scope.domElement.removeEventListener("contextmenu", onContextMenu);
5655
- scope.domElement.removeEventListener("pointerdown", onPointerDown);
5656
- scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5657
- scope.domElement.removeEventListener("wheel", onMouseWheel);
5658
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5659
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5660
- if (scope._domElementKeyEvents !== null) {
5661
- scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
5662
- }
5663
- };
5664
- const scope = this;
5665
- const STATE = {
5666
- NONE: -1,
5667
- ROTATE: 0,
5668
- DOLLY: 1,
5669
- PAN: 2,
5670
- TOUCH_ROTATE: 3,
5671
- TOUCH_PAN: 4,
5672
- TOUCH_DOLLY_PAN: 5,
5673
- TOUCH_DOLLY_ROTATE: 6
5402
+ var _Renderer = class _Renderer {
5403
+ constructor(options) {
5404
+ this._dirty = true;
5405
+ this._animationTimer = void 0;
5406
+ this._animationFrame = void 0;
5407
+ this._resizeListener = void 0;
5408
+ this._disposed = false;
5409
+ this._debugHelpers = [];
5410
+ this._eventDispatchers = /* @__PURE__ */ new Map();
5411
+ this._changeListener = () => {
5412
+ this._dirty = true;
5674
5413
  };
5675
- let state = STATE.NONE;
5676
- const EPS = 1e-6;
5677
- const spherical = new Spherical();
5678
- const sphericalDelta = new Spherical();
5679
- let scale = 1;
5680
- const panOffset = new Vector37();
5681
- let zoomChanged = false;
5682
- const rotateStart = new Vector23();
5683
- const rotateEnd = new Vector23();
5684
- const rotateDelta = new Vector23();
5685
- const panStart = new Vector23();
5686
- const panEnd = new Vector23();
5687
- const panDelta = new Vector23();
5688
- const dollyStart = new Vector23();
5689
- const dollyEnd = new Vector23();
5690
- const dollyDelta = new Vector23();
5691
- const pointers = [];
5692
- const pointerPositions = {};
5693
- function getAutoRotationAngle() {
5694
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
5695
- }
5696
- function getZoomScale() {
5697
- return Math.pow(0.95, scope.zoomSpeed);
5698
- }
5699
- function rotateLeft(angle) {
5700
- sphericalDelta.theta -= angle;
5701
- }
5702
- function rotateUp(angle) {
5703
- sphericalDelta.phi -= angle;
5704
- }
5705
- const panLeft = function() {
5706
- const v = new Vector37();
5707
- return function panLeft2(distance, objectMatrix) {
5708
- v.setFromMatrixColumn(objectMatrix, 0);
5709
- v.multiplyScalar(-distance);
5710
- panOffset.add(v);
5711
- };
5712
- }();
5713
- const panUp = function() {
5714
- const v = new Vector37();
5715
- return function panUp2(distance, objectMatrix) {
5716
- if (scope.screenSpacePanning === true) {
5717
- v.setFromMatrixColumn(objectMatrix, 1);
5718
- } else {
5719
- v.setFromMatrixColumn(objectMatrix, 0);
5720
- v.crossVectors(scope.object.up, v);
5721
- }
5722
- v.multiplyScalar(distance);
5723
- panOffset.add(v);
5724
- };
5725
- }();
5726
- const pan = function() {
5727
- const offset = new Vector37();
5728
- return function pan2(deltaX, deltaY) {
5729
- const element = scope.domElement;
5730
- if (scope.object.isPerspectiveCamera) {
5731
- const position = scope.object.position;
5732
- offset.copy(position).sub(scope.target);
5733
- let targetDistance = offset.length();
5734
- targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
5735
- panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
5736
- panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
5737
- } else if (scope.object.isOrthographicCamera) {
5738
- panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
5739
- panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
5740
- } else {
5741
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
5742
- scope.enablePan = false;
5743
- }
5744
- };
5745
- }();
5746
- function dollyOut(dollyScale) {
5747
- if (scope.object.isPerspectiveCamera) {
5748
- scale /= dollyScale;
5749
- } else if (scope.object.isOrthographicCamera) {
5750
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
5751
- scope.object.updateProjectionMatrix();
5752
- zoomChanged = true;
5753
- } else {
5754
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5755
- scope.enableZoom = false;
5756
- }
5757
- }
5758
- function dollyIn(dollyScale) {
5759
- if (scope.object.isPerspectiveCamera) {
5760
- scale *= dollyScale;
5761
- } else if (scope.object.isOrthographicCamera) {
5762
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
5763
- scope.object.updateProjectionMatrix();
5764
- zoomChanged = true;
5765
- } else {
5766
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5767
- scope.enableZoom = false;
5768
- }
5769
- }
5770
- function handleMouseDownRotate(event) {
5771
- rotateStart.set(event.clientX, event.clientY);
5772
- }
5773
- function handleMouseDownDolly(event) {
5774
- dollyStart.set(event.clientX, event.clientY);
5775
- }
5776
- function handleMouseDownPan(event) {
5777
- panStart.set(event.clientX, event.clientY);
5778
- }
5779
- function handleMouseMoveRotate(event) {
5780
- rotateEnd.set(event.clientX, event.clientY);
5781
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5782
- const element = scope.domElement;
5783
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5784
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5785
- rotateStart.copy(rotateEnd);
5786
- scope.update();
5787
- }
5788
- function handleMouseMoveDolly(event) {
5789
- dollyEnd.set(event.clientX, event.clientY);
5790
- dollyDelta.subVectors(dollyEnd, dollyStart);
5791
- if (dollyDelta.y > 0) {
5792
- dollyOut(getZoomScale());
5793
- } else if (dollyDelta.y < 0) {
5794
- dollyIn(getZoomScale());
5795
- }
5796
- dollyStart.copy(dollyEnd);
5797
- scope.update();
5798
- }
5799
- function handleMouseMovePan(event) {
5800
- panEnd.set(event.clientX, event.clientY);
5801
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5802
- pan(panDelta.x, panDelta.y);
5803
- panStart.copy(panEnd);
5804
- scope.update();
5805
- }
5806
- function handleMouseUp() {
5807
- }
5808
- function handleMouseWheel(event) {
5809
- if (event.deltaY < 0) {
5810
- dollyIn(getZoomScale());
5811
- } else if (event.deltaY > 0) {
5812
- dollyOut(getZoomScale());
5813
- }
5814
- scope.update();
5815
- }
5816
- function handleKeyDown(event) {
5817
- let needsUpdate = false;
5818
- switch (event.code) {
5819
- case scope.keys.UP:
5820
- pan(0, scope.keyPanSpeed);
5821
- needsUpdate = true;
5822
- break;
5823
- case scope.keys.BOTTOM:
5824
- pan(0, -scope.keyPanSpeed);
5825
- needsUpdate = true;
5826
- break;
5827
- case scope.keys.LEFT:
5828
- pan(scope.keyPanSpeed, 0);
5829
- needsUpdate = true;
5830
- break;
5831
- case scope.keys.RIGHT:
5832
- pan(-scope.keyPanSpeed, 0);
5833
- needsUpdate = true;
5834
- break;
5835
- }
5836
- if (needsUpdate) {
5837
- event.preventDefault();
5838
- scope.update();
5839
- }
5840
- }
5841
- function handleTouchStartRotate() {
5842
- if (pointers.length === 1) {
5843
- rotateStart.set(pointers[0].pageX, pointers[0].pageY);
5844
- } else {
5845
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5846
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5847
- rotateStart.set(x, y);
5848
- }
5849
- }
5850
- function handleTouchStartPan() {
5851
- if (pointers.length === 1) {
5852
- panStart.set(pointers[0].pageX, pointers[0].pageY);
5853
- } else {
5854
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5855
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5856
- panStart.set(x, y);
5857
- }
5858
- }
5859
- function handleTouchStartDolly() {
5860
- const dx = pointers[0].pageX - pointers[1].pageX;
5861
- const dy = pointers[0].pageY - pointers[1].pageY;
5862
- const distance = Math.sqrt(dx * dx + dy * dy);
5863
- dollyStart.set(0, distance);
5864
- }
5865
- function handleTouchStartDollyPan() {
5866
- if (scope.enableZoom) handleTouchStartDolly();
5867
- if (scope.enablePan) handleTouchStartPan();
5868
- }
5869
- function handleTouchStartDollyRotate() {
5870
- if (scope.enableZoom) handleTouchStartDolly();
5871
- if (scope.enableRotate) handleTouchStartRotate();
5872
- }
5873
- function handleTouchMoveRotate(event) {
5874
- if (pointers.length == 1) {
5875
- rotateEnd.set(event.pageX, event.pageY);
5876
- } else {
5877
- const position = getSecondPointerPosition(event);
5878
- const x = 0.5 * (event.pageX + position.x);
5879
- const y = 0.5 * (event.pageY + position.y);
5880
- rotateEnd.set(x, y);
5881
- }
5882
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5883
- const element = scope.domElement;
5884
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5885
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5886
- rotateStart.copy(rotateEnd);
5887
- }
5888
- function handleTouchMovePan(event) {
5889
- if (pointers.length === 1) {
5890
- panEnd.set(event.pageX, event.pageY);
5891
- } else {
5892
- const position = getSecondPointerPosition(event);
5893
- const x = 0.5 * (event.pageX + position.x);
5894
- const y = 0.5 * (event.pageY + position.y);
5895
- panEnd.set(x, y);
5896
- }
5897
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5898
- pan(panDelta.x, panDelta.y);
5899
- panStart.copy(panEnd);
5900
- }
5901
- function handleTouchMoveDolly(event) {
5902
- const position = getSecondPointerPosition(event);
5903
- const dx = event.pageX - position.x;
5904
- const dy = event.pageY - position.y;
5905
- const distance = Math.sqrt(dx * dx + dy * dy);
5906
- dollyEnd.set(0, distance);
5907
- dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
5908
- dollyOut(dollyDelta.y);
5909
- dollyStart.copy(dollyEnd);
5910
- }
5911
- function handleTouchMoveDollyPan(event) {
5912
- if (scope.enableZoom) handleTouchMoveDolly(event);
5913
- if (scope.enablePan) handleTouchMovePan(event);
5914
- }
5915
- function handleTouchMoveDollyRotate(event) {
5916
- if (scope.enableZoom) handleTouchMoveDolly(event);
5917
- if (scope.enableRotate) handleTouchMoveRotate(event);
5918
- }
5919
- function handleTouchEnd() {
5414
+ this.options = (0, import_ts_deepmerge10.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
5415
+ this._animationLoop = this.animate.bind(this);
5416
+ this._fpsTimer = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
5417
+ this._scene = this.createScene();
5418
+ this._camera = this.createCamera();
5419
+ this._renderer = this.createRenderer();
5420
+ this._composer = this.createComposer();
5421
+ if (this.options.render.stats) {
5422
+ this._stats = new Stats();
5423
+ document.body.appendChild(this._stats.dom);
5920
5424
  }
5921
- function onPointerDown(event) {
5922
- if (scope.enabled === false) return;
5923
- if (pointers.length === 0) {
5924
- scope.domElement.setPointerCapture(event.pointerId);
5925
- scope.domElement.addEventListener("pointermove", onPointerMove);
5926
- scope.domElement.addEventListener("pointerup", onPointerUp);
5927
- }
5928
- addPointer(event);
5929
- if (event.pointerType === "touch") {
5930
- onTouchStart(event);
5931
- } else {
5932
- onMouseDown(event);
5933
- }
5425
+ this.init();
5426
+ }
5427
+ //<editor-fold desc="INIT">
5428
+ createScene() {
5429
+ return new MineRenderScene();
5430
+ }
5431
+ createCamera() {
5432
+ switch (this.options.camera.type) {
5433
+ case "perspective":
5434
+ default:
5435
+ return new PerspectiveCamera(
5436
+ this.options.camera.perspective.fov,
5437
+ this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
5438
+ this.options.camera.near,
5439
+ this.options.camera.far
5440
+ );
5441
+ case "orthographic":
5442
+ return new OrthographicCamera(
5443
+ this.options.camera.orthographic.left ?? this.viewWidth / -2,
5444
+ this.options.camera.orthographic.right ?? this.viewWidth / 2,
5445
+ this.options.camera.orthographic.top ?? this.viewHeight / 2,
5446
+ this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
5447
+ this.options.camera.near,
5448
+ this.options.camera.far
5449
+ );
5934
5450
  }
5935
- function onPointerMove(event) {
5936
- if (scope.enabled === false) return;
5937
- if (event.pointerType === "touch") {
5938
- onTouchMove(event);
5939
- } else {
5940
- onMouseMove(event);
5941
- }
5451
+ }
5452
+ createRenderer() {
5453
+ const renderer = new WebGLRenderer({
5454
+ antialias: this.options.render.antialias,
5455
+ alpha: true,
5456
+ powerPreference: "high-performance",
5457
+ depth: true
5458
+ });
5459
+ renderer.setClearColor(0, 0);
5460
+ renderer.shadowMap.enabled = true;
5461
+ renderer.shadowMap.type = PCFSoftShadowMap;
5462
+ renderer.outputEncoding = LinearEncoding;
5463
+ renderer.setSize(this.viewWidth, this.viewHeight);
5464
+ return renderer;
5465
+ }
5466
+ createComposer() {
5467
+ const composer = new EffectComposer(this.renderer);
5468
+ if (!this.options.composer.enabled) return composer;
5469
+ composer.setSize(this.viewWidth, this.viewHeight);
5470
+ composer.addPass(new RenderPass(this.scene, this.camera));
5471
+ return composer;
5472
+ }
5473
+ //</editor-fold>
5474
+ init() {
5475
+ if (this._disposed) return;
5476
+ if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
5477
+ window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
5942
5478
  }
5943
- function onPointerUp(event) {
5944
- if (scope.enabled === false) return;
5945
- if (event.pointerType === "touch") {
5946
- onTouchEnd();
5947
- } else {
5948
- onMouseUp(event);
5949
- }
5950
- removePointer(event);
5951
- if (pointers.length === 0) {
5952
- scope.domElement.releasePointerCapture(event.pointerId);
5953
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5954
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5955
- }
5479
+ if (this.options.debug.grid) {
5480
+ const gridHelper = new GridHelper(128, 16);
5481
+ this._debugHelpers.push(gridHelper);
5482
+ this.scene.add(gridHelper);
5483
+ const gridHelper2 = new GridHelper(128, 16);
5484
+ this._debugHelpers.push(gridHelper2);
5485
+ gridHelper2.rotation.x = 90 * (Math.PI / 180);
5486
+ this.scene.add(gridHelper2);
5487
+ const gridHelper3 = new GridHelper(128, 16);
5488
+ this._debugHelpers.push(gridHelper3);
5489
+ gridHelper3.rotation.z = 90 * (Math.PI / 180);
5490
+ this.scene.add(gridHelper3);
5956
5491
  }
5957
- function onPointerCancel(event) {
5958
- removePointer(event);
5492
+ if (this.options.debug.axes) {
5493
+ const axesHelper = new AxesHelper3(64);
5494
+ this._debugHelpers.push(axesHelper);
5495
+ this.scene.add(axesHelper);
5959
5496
  }
5960
- function onMouseDown(event) {
5961
- let mouseAction;
5962
- switch (event.button) {
5963
- case 0:
5964
- mouseAction = scope.mouseButtons.LEFT;
5965
- break;
5966
- case 1:
5967
- mouseAction = scope.mouseButtons.MIDDLE;
5968
- break;
5969
- case 2:
5970
- mouseAction = scope.mouseButtons.RIGHT;
5971
- break;
5972
- default:
5973
- mouseAction = -1;
5974
- }
5975
- switch (mouseAction) {
5976
- case MOUSE.DOLLY:
5977
- if (scope.enableZoom === false) return;
5978
- handleMouseDownDolly(event);
5979
- state = STATE.DOLLY;
5980
- break;
5981
- case MOUSE.ROTATE:
5982
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
5983
- if (scope.enablePan === false) return;
5984
- handleMouseDownPan(event);
5985
- state = STATE.PAN;
5986
- } else {
5987
- if (scope.enableRotate === false) return;
5988
- handleMouseDownRotate(event);
5989
- state = STATE.ROTATE;
5990
- }
5991
- break;
5992
- case MOUSE.PAN:
5993
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
5994
- if (scope.enableRotate === false) return;
5995
- handleMouseDownRotate(event);
5996
- state = STATE.ROTATE;
5997
- } else {
5998
- if (scope.enablePan === false) return;
5999
- handleMouseDownPan(event);
6000
- state = STATE.PAN;
6001
- }
6002
- break;
6003
- default:
6004
- state = STATE.NONE;
6005
- }
6006
- if (state !== STATE.NONE) {
6007
- scope.dispatchEvent(_startEvent);
5497
+ if (this.options.camera.position) {
5498
+ if (isVector3(this.options.camera.position)) {
5499
+ this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
5500
+ } else if (isTripleArray(this.options.camera.position)) {
5501
+ this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
6008
5502
  }
6009
5503
  }
6010
- function onMouseMove(event) {
6011
- if (scope.enabled === false) return;
6012
- switch (state) {
6013
- case STATE.ROTATE:
6014
- if (scope.enableRotate === false) return;
6015
- handleMouseMoveRotate(event);
6016
- break;
6017
- case STATE.DOLLY:
6018
- if (scope.enableZoom === false) return;
6019
- handleMouseMoveDolly(event);
6020
- break;
6021
- case STATE.PAN:
6022
- if (scope.enablePan === false) return;
6023
- handleMouseMovePan(event);
6024
- break;
5504
+ if (this.options.camera.lookingAt) {
5505
+ if (isVector3(this.options.camera.lookingAt)) {
5506
+ this.camera.lookAt(this.options.camera.lookingAt);
5507
+ } else if (isTripleArray(this.options.camera.lookingAt)) {
5508
+ this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
6025
5509
  }
6026
5510
  }
6027
- function onMouseUp(event) {
6028
- handleMouseUp(event);
6029
- scope.dispatchEvent(_endEvent);
6030
- state = STATE.NONE;
6031
- }
6032
- function onMouseWheel(event) {
6033
- if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6034
- event.preventDefault();
6035
- scope.dispatchEvent(_startEvent);
6036
- handleMouseWheel(event);
6037
- scope.dispatchEvent(_endEvent);
5511
+ if (this.options.render.autoResize && !this._resizeListener) {
5512
+ this._resizeListener = () => {
5513
+ this.resize(this.viewWidth, this.viewHeight);
5514
+ };
5515
+ window.addEventListener("resize", this._resizeListener);
6038
5516
  }
6039
- function onKeyDown(event) {
6040
- if (scope.enabled === false || scope.enablePan === false) return;
6041
- handleKeyDown(event);
5517
+ }
5518
+ get element() {
5519
+ return this._element;
5520
+ }
5521
+ appendTo(element) {
5522
+ if (this._disposed) return;
5523
+ this._element = element;
5524
+ this._element.appendChild(this.renderer.domElement);
5525
+ if (this.viewWidth == 0) {
5526
+ console.warn("0 element width");
6042
5527
  }
6043
- function onTouchStart(event) {
6044
- trackPointer(event);
6045
- switch (pointers.length) {
6046
- case 1:
6047
- switch (scope.touches.ONE) {
6048
- case TOUCH.ROTATE:
6049
- if (scope.enableRotate === false) return;
6050
- handleTouchStartRotate();
6051
- state = STATE.TOUCH_ROTATE;
6052
- break;
6053
- case TOUCH.PAN:
6054
- if (scope.enablePan === false) return;
6055
- handleTouchStartPan();
6056
- state = STATE.TOUCH_PAN;
6057
- break;
6058
- default:
6059
- state = STATE.NONE;
6060
- }
6061
- break;
6062
- case 2:
6063
- switch (scope.touches.TWO) {
6064
- case TOUCH.DOLLY_PAN:
6065
- if (scope.enableZoom === false && scope.enablePan === false) return;
6066
- handleTouchStartDollyPan();
6067
- state = STATE.TOUCH_DOLLY_PAN;
6068
- break;
6069
- case TOUCH.DOLLY_ROTATE:
6070
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6071
- handleTouchStartDollyRotate();
6072
- state = STATE.TOUCH_DOLLY_ROTATE;
6073
- break;
6074
- default:
6075
- state = STATE.NONE;
6076
- }
6077
- break;
6078
- default:
6079
- state = STATE.NONE;
6080
- }
6081
- if (state !== STATE.NONE) {
6082
- scope.dispatchEvent(_startEvent);
6083
- }
5528
+ if (this.viewHeight == 0) {
5529
+ console.warn("0 element height");
6084
5530
  }
6085
- function onTouchMove(event) {
6086
- trackPointer(event);
6087
- switch (state) {
6088
- case STATE.TOUCH_ROTATE:
6089
- if (scope.enableRotate === false) return;
6090
- handleTouchMoveRotate(event);
6091
- scope.update();
6092
- break;
6093
- case STATE.TOUCH_PAN:
6094
- if (scope.enablePan === false) return;
6095
- handleTouchMovePan(event);
6096
- scope.update();
6097
- break;
6098
- case STATE.TOUCH_DOLLY_PAN:
6099
- if (scope.enableZoom === false && scope.enablePan === false) return;
6100
- handleTouchMoveDollyPan(event);
6101
- scope.update();
6102
- break;
6103
- case STATE.TOUCH_DOLLY_ROTATE:
6104
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6105
- handleTouchMoveDollyRotate(event);
6106
- scope.update();
6107
- break;
6108
- default:
6109
- state = STATE.NONE;
6110
- }
5531
+ this.resize(this.viewWidth, this.viewHeight);
5532
+ }
5533
+ /**
5534
+ * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
5535
+ * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
5536
+ */
5537
+ registerEventDispatcher(dispatcher, changeEvent2 = "change") {
5538
+ if (this._disposed) return;
5539
+ let events = this._eventDispatchers.get(dispatcher);
5540
+ if (!events) {
5541
+ events = /* @__PURE__ */ new Set();
5542
+ this._eventDispatchers.set(dispatcher, events);
6111
5543
  }
6112
- function onTouchEnd(event) {
6113
- handleTouchEnd(event);
6114
- scope.dispatchEvent(_endEvent);
6115
- state = STATE.NONE;
5544
+ if (events.has(changeEvent2)) return;
5545
+ events.add(changeEvent2);
5546
+ dispatcher.addEventListener(changeEvent2, this._changeListener);
5547
+ }
5548
+ resize(width, height) {
5549
+ if (this._disposed) return;
5550
+ if (isPerspectiveCamera(this.camera)) {
5551
+ this.camera.aspect = width / height;
5552
+ this.camera.updateProjectionMatrix();
5553
+ } else if (isOrthographicCamera(this.camera)) {
5554
+ this.camera.left = width / -2;
5555
+ this.camera.right = width / 2;
5556
+ this.camera.top = height / 2;
5557
+ this.camera.bottom = height / -2;
5558
+ this.camera.updateProjectionMatrix();
6116
5559
  }
6117
- function onContextMenu(event) {
6118
- if (scope.enabled === false) return;
6119
- event.preventDefault();
5560
+ this.renderer.setSize(width, height);
5561
+ this.composer.setSize(width, height);
5562
+ this._dirty = true;
5563
+ }
5564
+ //<editor-fold desc="RENDER">
5565
+ get dirty() {
5566
+ return this._dirty || this.scene.dirty;
5567
+ }
5568
+ set dirty(dirty) {
5569
+ this._dirty = dirty;
5570
+ this.scene.dirty = dirty;
5571
+ }
5572
+ start() {
5573
+ if (this._disposed) return;
5574
+ this.stop();
5575
+ this.renderer.setAnimationLoop(this._animationLoop);
5576
+ }
5577
+ stop() {
5578
+ if (this._disposed) return;
5579
+ this.renderer.setAnimationLoop(null);
5580
+ if (this._animationTimer)
5581
+ clearTimeout(this._animationTimer);
5582
+ this._animationTimer = void 0;
5583
+ if (this._animationFrame)
5584
+ cancelAnimationFrame(this._animationFrame);
5585
+ this._animationFrame = void 0;
5586
+ }
5587
+ /**
5588
+ * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
5589
+ * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
5590
+ * controls must be managed by their owners.
5591
+ */
5592
+ dispose() {
5593
+ if (this._disposed) return;
5594
+ this.stop();
5595
+ this._disposed = true;
5596
+ if (this._resizeListener) {
5597
+ window.removeEventListener("resize", this._resizeListener);
5598
+ this._resizeListener = void 0;
6120
5599
  }
6121
- function addPointer(event) {
6122
- pointers.push(event);
5600
+ for (const [dispatcher, events] of this._eventDispatchers) {
5601
+ for (const event of events) {
5602
+ dispatcher.removeEventListener(event, this._changeListener);
5603
+ }
6123
5604
  }
6124
- function removePointer(event) {
6125
- delete pointerPositions[event.pointerId];
6126
- for (let i = 0; i < pointers.length; i++) {
6127
- if (pointers[i].pointerId == event.pointerId) {
6128
- pointers.splice(i, 1);
6129
- return;
6130
- }
5605
+ this._eventDispatchers.clear();
5606
+ this._stats?.dom.remove();
5607
+ this._stats = void 0;
5608
+ this.renderer.domElement.remove();
5609
+ this._element = void 0;
5610
+ this.scene.clear();
5611
+ for (const helper of this._debugHelpers) {
5612
+ helper.geometry.dispose();
5613
+ const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
5614
+ for (const material of materials) {
5615
+ material.dispose();
6131
5616
  }
6132
5617
  }
6133
- function trackPointer(event) {
6134
- let position = pointerPositions[event.pointerId];
6135
- if (position === void 0) {
6136
- position = new Vector23();
6137
- pointerPositions[event.pointerId] = position;
5618
+ this._debugHelpers.length = 0;
5619
+ this.composer.dispose();
5620
+ this.renderer.dispose();
5621
+ this.renderer.forceContextLoss();
5622
+ }
5623
+ animate(t) {
5624
+ if (this._disposed) return;
5625
+ if (this._stats) {
5626
+ this._stats.begin();
5627
+ }
5628
+ if (this.dirty || this.options.render.renderAlways) {
5629
+ if (this.options.composer.enabled) {
5630
+ this.composer.render();
5631
+ } else {
5632
+ this.renderer.render(this.scene, this.camera);
6138
5633
  }
6139
- position.set(event.pageX, event.pageY);
6140
5634
  }
6141
- function getSecondPointerPosition(event) {
6142
- const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6143
- return pointerPositions[pointer.pointerId];
5635
+ this.dirty = false;
5636
+ if (this._stats) {
5637
+ this._stats.end();
6144
5638
  }
6145
- scope.domElement.addEventListener("contextmenu", onContextMenu);
6146
- scope.domElement.addEventListener("pointerdown", onPointerDown);
6147
- scope.domElement.addEventListener("pointercancel", onPointerCancel);
6148
- scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6149
- this.update();
6150
5639
  }
6151
- };
6152
- var MapControls = class extends OrbitControls {
6153
- constructor(object, domElement) {
6154
- super(object, domElement);
6155
- this.screenSpacePanning = false;
6156
- this.mouseButtons.LEFT = MOUSE.PAN;
6157
- this.mouseButtons.RIGHT = MOUSE.ROTATE;
6158
- this.touches.ONE = TOUCH.PAN;
6159
- this.touches.TWO = TOUCH.DOLLY_ROTATE;
5640
+ //</editor-fold>
5641
+ toImage() {
5642
+ return this.renderer.domElement.toDataURL();
5643
+ }
5644
+ ///
5645
+ get attachedToBody() {
5646
+ return this.element === document.body;
5647
+ }
5648
+ get viewWidth() {
5649
+ return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
5650
+ }
5651
+ get viewHeight() {
5652
+ return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
5653
+ }
5654
+ get scene() {
5655
+ return this._scene;
5656
+ }
5657
+ get camera() {
5658
+ return this._camera;
5659
+ }
5660
+ get renderer() {
5661
+ return this._renderer;
6160
5662
  }
5663
+ get composer() {
5664
+ return this._composer;
5665
+ }
5666
+ ///
6161
5667
  };
5668
+ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge10.default)({}, {
5669
+ camera: {
5670
+ type: "perspective",
5671
+ near: 1,
5672
+ far: 5e3,
5673
+ perspective: {
5674
+ aspect: void 0,
5675
+ fov: 50
5676
+ },
5677
+ orthographic: {
5678
+ left: void 0,
5679
+ right: void 0,
5680
+ top: void 0,
5681
+ bottom: void 0
5682
+ },
5683
+ position: new Vector37(50, 50, 50),
5684
+ lookingAt: new Vector37(0, 0, 0)
5685
+ },
5686
+ render: {
5687
+ fpsLimit: 60,
5688
+ stats: false,
5689
+ antialias: true,
5690
+ shade: true,
5691
+ autoResize: true,
5692
+ renderAlways: false
5693
+ },
5694
+ composer: {
5695
+ enabled: true
5696
+ },
5697
+ debug: {
5698
+ grid: false,
5699
+ axes: false
5700
+ }
5701
+ });
5702
+ var Renderer = _Renderer;
6162
5703
 
6163
- // src/renderer/Renderer.ts
6164
- var _Renderer = class _Renderer {
6165
- constructor(options) {
6166
- this._dirty = true;
6167
- this._resizeListener = void 0;
6168
- this._disposed = false;
6169
- this._debugHelpers = [];
6170
- this._eventDispatchers = /* @__PURE__ */ new Map();
6171
- this._changeListener = () => {
6172
- this._dirty = true;
6173
- };
6174
- this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
6175
- this._animationLoop = this.animate.bind(this);
6176
- this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
6177
- this._scene = this.createScene();
6178
- this._camera = this.createCamera();
6179
- this._renderer = this.createRenderer();
6180
- this._composer = this.createComposer();
6181
- if (this.options.render.stats) {
6182
- this._stats = new Stats();
6183
- document.body.appendChild(this._stats.dom);
5704
+ // src/skin/Skins.ts
5705
+ var Skins = class {
5706
+ //<editor-fold desc="Skins">
5707
+ static async fromUuidOrUsername(uuidOrUsername) {
5708
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5709
+ return this.fromUuid(uuidOrUsername);
6184
5710
  }
6185
- this.init();
6186
- this._controls = this.createControls();
5711
+ return this.fromUsername(uuidOrUsername);
5712
+ }
5713
+ static async fromUuid(uuid) {
5714
+ return this.getSkinProxySkinUrl(uuid);
5715
+ }
5716
+ static async fromUsername(username) {
5717
+ return this.usernameToUuid(username).then((uuid) => {
5718
+ if (uuid) {
5719
+ return this.fromUuid(uuid);
5720
+ }
5721
+ return void 0;
5722
+ });
5723
+ }
5724
+ static async fromMineSkin(mineskinId) {
5725
+ return this.getMineSkin(mineskinId).then((mineskin) => {
5726
+ if (mineskin) {
5727
+ return mineskin["data"]["texture"]["value"]["urls"]["skins"];
5728
+ }
5729
+ return void 0;
5730
+ });
5731
+ }
5732
+ //</editor-fold>
5733
+ //<editor-fold desc="Capes">
5734
+ static async capeFromUuidOrUsername(uuidOrUsername) {
5735
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5736
+ return this.capeFromUuid(uuidOrUsername);
5737
+ }
5738
+ return this.capeFromUsername(uuidOrUsername);
5739
+ }
5740
+ static async capeFromUuid(uuid) {
5741
+ return this.getSkinProxyCapeUrl(uuid);
5742
+ }
5743
+ static async capeFromUsername(username) {
5744
+ return this.usernameToUuid(username).then((uuid) => {
5745
+ if (uuid) {
5746
+ return this.capeFromUuid(uuid);
5747
+ }
5748
+ return void 0;
5749
+ });
5750
+ }
5751
+ static async capeFromCapesDev(uuid, capeType = "minecraft") {
5752
+ return this.getCapesDev(uuid, capeType).then((cape) => {
5753
+ if (cape) {
5754
+ return cape?.stillImageUrl;
5755
+ }
5756
+ return void 0;
5757
+ });
5758
+ }
5759
+ //</editor-fold>
5760
+ //<editor-fold desc="Helpers">
5761
+ static async usernameToUuid(username) {
5762
+ return this.usernameToUuidSkinProxy(username);
5763
+ }
5764
+ static async usernameToUuidSkinProxy(username) {
5765
+ return Requests.genericRequest({
5766
+ baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
5767
+ url: "/uuid/" + username
5768
+ }).then((res) => {
5769
+ if (res.status === 200) {
5770
+ return res.data["id"];
5771
+ }
5772
+ return void 0;
5773
+ }).catch((err) => {
5774
+ console.warn(err);
5775
+ return void 0;
5776
+ });
5777
+ }
5778
+ static async usernameToUuidMineTools(username) {
5779
+ return Requests.genericRequest({
5780
+ baseURL: "https://api.minetools.eu",
5781
+ url: "/uuid/" + username
5782
+ }).then((res) => {
5783
+ if (res.status === 200) {
5784
+ return res.data["id"];
5785
+ }
5786
+ return void 0;
5787
+ }).catch((err) => {
5788
+ console.warn(err);
5789
+ return void 0;
5790
+ });
6187
5791
  }
6188
- //<editor-fold desc="INIT">
6189
- createScene() {
6190
- return new MineRenderScene();
5792
+ static async getProfileFromMinetools(uuid) {
5793
+ return Requests.genericRequest({
5794
+ baseURL: "https://api.minetools.eu",
5795
+ url: "/profile/" + uuid
5796
+ }).then((res) => {
5797
+ if (res.status === 200) {
5798
+ return res.data;
5799
+ }
5800
+ });
6191
5801
  }
6192
- createCamera() {
6193
- switch (this.options.camera.type) {
6194
- case "perspective":
6195
- default:
6196
- return new PerspectiveCamera(
6197
- this.options.camera.perspective.fov,
6198
- this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
6199
- this.options.camera.near,
6200
- this.options.camera.far
6201
- );
6202
- case "orthographic":
6203
- return new OrthographicCamera(
6204
- this.options.camera.orthographic.left ?? this.viewWidth / -2,
6205
- this.options.camera.orthographic.right ?? this.viewWidth / 2,
6206
- this.options.camera.orthographic.top ?? this.viewHeight / 2,
6207
- this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
6208
- this.options.camera.near,
6209
- this.options.camera.far
6210
- );
6211
- }
5802
+ static async getMineSkin(mineskinId) {
5803
+ return Requests.genericRequest({
5804
+ baseURL: "https://api.mineskin.org",
5805
+ url: "/get/uuid/" + mineskinId
5806
+ }).then((res) => {
5807
+ if (res.status === 200) {
5808
+ return res.data;
5809
+ }
5810
+ return void 0;
5811
+ }).catch((err) => {
5812
+ console.warn(err);
5813
+ return void 0;
5814
+ });
6212
5815
  }
6213
- createRenderer() {
6214
- const renderer = new WebGLRenderer({
6215
- antialias: this.options.render.antialias,
6216
- alpha: true,
6217
- powerPreference: "high-performance",
6218
- depth: true
5816
+ static async getCapesDev(uuid, type = "all") {
5817
+ return Requests.genericRequest({
5818
+ baseURL: "https://api.capes.dev",
5819
+ url: "/load/" + uuid + "/" + type
5820
+ }).then((res) => {
5821
+ if (res.status === 200) {
5822
+ return res.data;
5823
+ }
5824
+ return void 0;
5825
+ }).catch((err) => {
5826
+ console.warn(err);
5827
+ return void 0;
6219
5828
  });
6220
- renderer.setClearColor(0, 0);
6221
- renderer.shadowMap.enabled = true;
6222
- renderer.shadowMap.type = PCFSoftShadowMap;
6223
- renderer.outputColorSpace = SRGBColorSpace3;
6224
- renderer.setSize(this.viewWidth, this.viewHeight);
6225
- return renderer;
6226
5829
  }
6227
- createComposer() {
6228
- if (!this.options.composer.enabled) return void 0;
6229
- const composer = new EffectComposer(this.renderer);
6230
- composer.setSize(this.viewWidth, this.viewHeight);
6231
- composer.addPass(new RenderPass(this.scene, this.camera));
6232
- return composer;
5830
+ static getCrafatarSkinUrl(uuid) {
5831
+ return "https://crafatar.com/skins/" + uuid;
5832
+ }
5833
+ static getCrafatarCapeUrl(uuid) {
5834
+ return "https://crafatar.com/capes/" + uuid;
6233
5835
  }
6234
- createControls() {
6235
- if (!this.options.controls?.enabled) return void 0;
6236
- const position = this.camera.position.clone();
6237
- const controls = new OrbitControls(this.camera, this.renderer.domElement);
6238
- this.camera.position.copy(position);
6239
- const target = this.options.camera.lookingAt;
6240
- if (isVector3(target)) {
6241
- controls.target.copy(target);
6242
- } else if (isTripleArray(target)) {
6243
- controls.target.set(target[0], target[1], target[2]);
6244
- }
6245
- controls.update();
6246
- controls.saveState();
6247
- this.registerEventDispatcher(controls);
6248
- return controls;
5836
+ static getMcHeadsSkinUrl(uuid) {
5837
+ return "https://mc-heads.net/skin/" + uuid;
5838
+ }
5839
+ static getMineSkinPlayerSkinUrl(uuid) {
5840
+ return "https://mineskin.org/skin/player/" + uuid;
5841
+ }
5842
+ static getSkinProxySkinUrl(uuid) {
5843
+ return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
5844
+ }
5845
+ static getSkinProxyCapeUrl(uuid) {
5846
+ return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
6249
5847
  }
6250
5848
  //</editor-fold>
6251
- init() {
6252
- if (this._disposed) return;
6253
- if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
6254
- window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
5849
+ };
5850
+
5851
+ // src/three/OrbitControls.js
5852
+ import {
5853
+ EventDispatcher as EventDispatcher2,
5854
+ MOUSE,
5855
+ Quaternion as Quaternion3,
5856
+ Spherical,
5857
+ TOUCH,
5858
+ Vector2 as Vector23,
5859
+ Vector3 as Vector38
5860
+ } from "three";
5861
+ var _changeEvent = { type: "change" };
5862
+ var _startEvent = { type: "start" };
5863
+ var _endEvent = { type: "end" };
5864
+ var OrbitControls = class extends EventDispatcher2 {
5865
+ constructor(object, domElement) {
5866
+ super();
5867
+ if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5868
+ if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5869
+ this.object = object;
5870
+ this.domElement = domElement;
5871
+ this.domElement.style.touchAction = "none";
5872
+ this.enabled = true;
5873
+ this.target = new Vector38();
5874
+ this.minDistance = 0;
5875
+ this.maxDistance = Infinity;
5876
+ this.minZoom = 0;
5877
+ this.maxZoom = Infinity;
5878
+ this.minPolarAngle = 0;
5879
+ this.maxPolarAngle = Math.PI;
5880
+ this.minAzimuthAngle = -Infinity;
5881
+ this.maxAzimuthAngle = Infinity;
5882
+ this.enableDamping = false;
5883
+ this.dampingFactor = 0.05;
5884
+ this.enableZoom = true;
5885
+ this.zoomSpeed = 1;
5886
+ this.enableRotate = true;
5887
+ this.rotateSpeed = 1;
5888
+ this.enablePan = true;
5889
+ this.panSpeed = 1;
5890
+ this.screenSpacePanning = true;
5891
+ this.keyPanSpeed = 7;
5892
+ this.autoRotate = false;
5893
+ this.autoRotateSpeed = 2;
5894
+ this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5895
+ this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
5896
+ this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
5897
+ this.target0 = this.target.clone();
5898
+ this.position0 = this.object.position.clone();
5899
+ this.zoom0 = this.object.zoom;
5900
+ this._domElementKeyEvents = null;
5901
+ this.getPolarAngle = function() {
5902
+ return spherical.phi;
5903
+ };
5904
+ this.getAzimuthalAngle = function() {
5905
+ return spherical.theta;
5906
+ };
5907
+ this.getDistance = function() {
5908
+ return this.object.position.distanceTo(this.target);
5909
+ };
5910
+ this.saveState = function() {
5911
+ scope.target0.copy(scope.target);
5912
+ scope.position0.copy(scope.object.position);
5913
+ scope.zoom0 = scope.object.zoom;
5914
+ };
5915
+ this.reset = function() {
5916
+ scope.target.copy(scope.target0);
5917
+ scope.object.position.copy(scope.position0);
5918
+ scope.object.zoom = scope.zoom0;
5919
+ scope.object.updateProjectionMatrix();
5920
+ scope.dispatchEvent(_changeEvent);
5921
+ scope.update();
5922
+ state = STATE.NONE;
5923
+ };
5924
+ this.update = function() {
5925
+ const offset = new Vector38();
5926
+ const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
5927
+ const quatInverse = quat.clone().invert();
5928
+ const lastPosition = new Vector38();
5929
+ const lastQuaternion = new Quaternion3();
5930
+ const twoPI = 2 * Math.PI;
5931
+ return function update() {
5932
+ const position = scope.object.position;
5933
+ offset.copy(position).sub(scope.target);
5934
+ offset.applyQuaternion(quat);
5935
+ spherical.setFromVector3(offset);
5936
+ if (scope.autoRotate && state === STATE.NONE) {
5937
+ rotateLeft(getAutoRotationAngle());
5938
+ }
5939
+ if (scope.enableDamping) {
5940
+ spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5941
+ spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5942
+ } else {
5943
+ spherical.theta += sphericalDelta.theta;
5944
+ spherical.phi += sphericalDelta.phi;
5945
+ }
5946
+ let min = scope.minAzimuthAngle;
5947
+ let max = scope.maxAzimuthAngle;
5948
+ if (isFinite(min) && isFinite(max)) {
5949
+ if (min < -Math.PI) min += twoPI;
5950
+ else if (min > Math.PI) min -= twoPI;
5951
+ if (max < -Math.PI) max += twoPI;
5952
+ else if (max > Math.PI) max -= twoPI;
5953
+ if (min <= max) {
5954
+ spherical.theta = Math.max(min, Math.min(max, spherical.theta));
5955
+ } else {
5956
+ spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
5957
+ }
5958
+ }
5959
+ spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5960
+ spherical.makeSafe();
5961
+ spherical.radius *= scale;
5962
+ spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5963
+ if (scope.enableDamping === true) {
5964
+ scope.target.addScaledVector(panOffset, scope.dampingFactor);
5965
+ } else {
5966
+ scope.target.add(panOffset);
5967
+ }
5968
+ offset.setFromSpherical(spherical);
5969
+ offset.applyQuaternion(quatInverse);
5970
+ position.copy(scope.target).add(offset);
5971
+ scope.object.lookAt(scope.target);
5972
+ if (scope.enableDamping === true) {
5973
+ sphericalDelta.theta *= 1 - scope.dampingFactor;
5974
+ sphericalDelta.phi *= 1 - scope.dampingFactor;
5975
+ panOffset.multiplyScalar(1 - scope.dampingFactor);
5976
+ } else {
5977
+ sphericalDelta.set(0, 0, 0);
5978
+ panOffset.set(0, 0, 0);
5979
+ }
5980
+ scale = 1;
5981
+ if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5982
+ scope.dispatchEvent(_changeEvent);
5983
+ lastPosition.copy(scope.object.position);
5984
+ lastQuaternion.copy(scope.object.quaternion);
5985
+ zoomChanged = false;
5986
+ return true;
5987
+ }
5988
+ return false;
5989
+ };
5990
+ }();
5991
+ this.dispose = function() {
5992
+ scope.domElement.removeEventListener("contextmenu", onContextMenu);
5993
+ scope.domElement.removeEventListener("pointerdown", onPointerDown);
5994
+ scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5995
+ scope.domElement.removeEventListener("wheel", onMouseWheel);
5996
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
5997
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
5998
+ if (scope._domElementKeyEvents !== null) {
5999
+ scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
6000
+ }
6001
+ };
6002
+ const scope = this;
6003
+ const STATE = {
6004
+ NONE: -1,
6005
+ ROTATE: 0,
6006
+ DOLLY: 1,
6007
+ PAN: 2,
6008
+ TOUCH_ROTATE: 3,
6009
+ TOUCH_PAN: 4,
6010
+ TOUCH_DOLLY_PAN: 5,
6011
+ TOUCH_DOLLY_ROTATE: 6
6012
+ };
6013
+ let state = STATE.NONE;
6014
+ const EPS = 1e-6;
6015
+ const spherical = new Spherical();
6016
+ const sphericalDelta = new Spherical();
6017
+ let scale = 1;
6018
+ const panOffset = new Vector38();
6019
+ let zoomChanged = false;
6020
+ const rotateStart = new Vector23();
6021
+ const rotateEnd = new Vector23();
6022
+ const rotateDelta = new Vector23();
6023
+ const panStart = new Vector23();
6024
+ const panEnd = new Vector23();
6025
+ const panDelta = new Vector23();
6026
+ const dollyStart = new Vector23();
6027
+ const dollyEnd = new Vector23();
6028
+ const dollyDelta = new Vector23();
6029
+ const pointers = [];
6030
+ const pointerPositions = {};
6031
+ function getAutoRotationAngle() {
6032
+ return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
6255
6033
  }
6256
- if (this.options.debug.grid) {
6257
- const gridHelper = new GridHelper(128, 16);
6258
- this._debugHelpers.push(gridHelper);
6259
- this.scene.add(gridHelper);
6260
- const gridHelper2 = new GridHelper(128, 16);
6261
- this._debugHelpers.push(gridHelper2);
6262
- gridHelper2.rotation.x = 90 * (Math.PI / 180);
6263
- this.scene.add(gridHelper2);
6264
- const gridHelper3 = new GridHelper(128, 16);
6265
- this._debugHelpers.push(gridHelper3);
6266
- gridHelper3.rotation.z = 90 * (Math.PI / 180);
6267
- this.scene.add(gridHelper3);
6034
+ function getZoomScale() {
6035
+ return Math.pow(0.95, scope.zoomSpeed);
6268
6036
  }
6269
- if (this.options.debug.axes) {
6270
- const axesHelper = new AxesHelper3(64);
6271
- this._debugHelpers.push(axesHelper);
6272
- this.scene.add(axesHelper);
6037
+ function rotateLeft(angle) {
6038
+ sphericalDelta.theta -= angle;
6273
6039
  }
6274
- if (this.options.camera.position) {
6275
- if (isVector3(this.options.camera.position)) {
6276
- this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
6277
- } else if (isTripleArray(this.options.camera.position)) {
6278
- this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
6040
+ function rotateUp(angle) {
6041
+ sphericalDelta.phi -= angle;
6042
+ }
6043
+ const panLeft = function() {
6044
+ const v = new Vector38();
6045
+ return function panLeft2(distance, objectMatrix) {
6046
+ v.setFromMatrixColumn(objectMatrix, 0);
6047
+ v.multiplyScalar(-distance);
6048
+ panOffset.add(v);
6049
+ };
6050
+ }();
6051
+ const panUp = function() {
6052
+ const v = new Vector38();
6053
+ return function panUp2(distance, objectMatrix) {
6054
+ if (scope.screenSpacePanning === true) {
6055
+ v.setFromMatrixColumn(objectMatrix, 1);
6056
+ } else {
6057
+ v.setFromMatrixColumn(objectMatrix, 0);
6058
+ v.crossVectors(scope.object.up, v);
6059
+ }
6060
+ v.multiplyScalar(distance);
6061
+ panOffset.add(v);
6062
+ };
6063
+ }();
6064
+ const pan = function() {
6065
+ const offset = new Vector38();
6066
+ return function pan2(deltaX, deltaY) {
6067
+ const element = scope.domElement;
6068
+ if (scope.object.isPerspectiveCamera) {
6069
+ const position = scope.object.position;
6070
+ offset.copy(position).sub(scope.target);
6071
+ let targetDistance = offset.length();
6072
+ targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
6073
+ panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
6074
+ panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
6075
+ } else if (scope.object.isOrthographicCamera) {
6076
+ panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
6077
+ panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
6078
+ } else {
6079
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
6080
+ scope.enablePan = false;
6081
+ }
6082
+ };
6083
+ }();
6084
+ function dollyOut(dollyScale) {
6085
+ if (scope.object.isPerspectiveCamera) {
6086
+ scale /= dollyScale;
6087
+ } else if (scope.object.isOrthographicCamera) {
6088
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
6089
+ scope.object.updateProjectionMatrix();
6090
+ zoomChanged = true;
6091
+ } else {
6092
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6093
+ scope.enableZoom = false;
6279
6094
  }
6280
6095
  }
6281
- if (this.options.camera.lookingAt) {
6282
- if (isVector3(this.options.camera.lookingAt)) {
6283
- this.camera.lookAt(this.options.camera.lookingAt);
6284
- } else if (isTripleArray(this.options.camera.lookingAt)) {
6285
- this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
6096
+ function dollyIn(dollyScale) {
6097
+ if (scope.object.isPerspectiveCamera) {
6098
+ scale *= dollyScale;
6099
+ } else if (scope.object.isOrthographicCamera) {
6100
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
6101
+ scope.object.updateProjectionMatrix();
6102
+ zoomChanged = true;
6103
+ } else {
6104
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6105
+ scope.enableZoom = false;
6286
6106
  }
6287
6107
  }
6288
- if (this.options.render.autoResize && !this._resizeListener) {
6289
- this._resizeListener = () => {
6290
- this.resize(this.viewWidth, this.viewHeight);
6291
- };
6292
- window.addEventListener("resize", this._resizeListener);
6108
+ function handleMouseDownRotate(event) {
6109
+ rotateStart.set(event.clientX, event.clientY);
6293
6110
  }
6294
- }
6295
- get element() {
6296
- return this._element;
6297
- }
6298
- appendTo(element) {
6299
- if (this._disposed) return;
6300
- this._element = element;
6301
- this._element.appendChild(this.renderer.domElement);
6302
- if (this.viewWidth == 0) {
6303
- console.warn("0 element width");
6111
+ function handleMouseDownDolly(event) {
6112
+ dollyStart.set(event.clientX, event.clientY);
6304
6113
  }
6305
- if (this.viewHeight == 0) {
6306
- console.warn("0 element height");
6114
+ function handleMouseDownPan(event) {
6115
+ panStart.set(event.clientX, event.clientY);
6307
6116
  }
6308
- this.resize(this.viewWidth, this.viewHeight);
6309
- }
6310
- /**
6311
- * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
6312
- * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
6313
- */
6314
- registerEventDispatcher(dispatcher, changeEvent2 = "change") {
6315
- if (this._disposed) return;
6316
- let events = this._eventDispatchers.get(dispatcher);
6317
- if (!events) {
6318
- events = /* @__PURE__ */ new Set();
6319
- this._eventDispatchers.set(dispatcher, events);
6117
+ function handleMouseMoveRotate(event) {
6118
+ rotateEnd.set(event.clientX, event.clientY);
6119
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6120
+ const element = scope.domElement;
6121
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6122
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6123
+ rotateStart.copy(rotateEnd);
6124
+ scope.update();
6320
6125
  }
6321
- if (events.has(changeEvent2)) return;
6322
- events.add(changeEvent2);
6323
- dispatcher.addEventListener(changeEvent2, this._changeListener);
6324
- }
6325
- resize(width, height) {
6326
- if (this._disposed) return;
6327
- if (isPerspectiveCamera(this.camera)) {
6328
- this.camera.aspect = width / height;
6329
- this.camera.updateProjectionMatrix();
6330
- } else if (isOrthographicCamera(this.camera)) {
6331
- this.camera.left = width / -2;
6332
- this.camera.right = width / 2;
6333
- this.camera.top = height / 2;
6334
- this.camera.bottom = height / -2;
6335
- this.camera.updateProjectionMatrix();
6126
+ function handleMouseMoveDolly(event) {
6127
+ dollyEnd.set(event.clientX, event.clientY);
6128
+ dollyDelta.subVectors(dollyEnd, dollyStart);
6129
+ if (dollyDelta.y > 0) {
6130
+ dollyOut(getZoomScale());
6131
+ } else if (dollyDelta.y < 0) {
6132
+ dollyIn(getZoomScale());
6133
+ }
6134
+ dollyStart.copy(dollyEnd);
6135
+ scope.update();
6336
6136
  }
6337
- this.renderer.setSize(width, height);
6338
- this.composer?.setSize(width, height);
6339
- this._dirty = true;
6340
- }
6341
- //<editor-fold desc="RENDER">
6342
- get dirty() {
6343
- return this._dirty || this.scene.dirty;
6344
- }
6345
- set dirty(dirty) {
6346
- this._dirty = dirty;
6347
- this.scene.dirty = dirty;
6348
- }
6349
- start() {
6350
- if (this._disposed) return;
6351
- this.stop();
6352
- this.renderer.setAnimationLoop(this._animationLoop);
6353
- }
6354
- stop() {
6355
- if (this._disposed) return;
6356
- this.renderer.setAnimationLoop(null);
6357
- this._nextFrameTime = void 0;
6358
- }
6359
- /**
6360
- * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
6361
- * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
6362
- * controls must be managed by their owners.
6363
- */
6364
- dispose() {
6365
- if (this._disposed) return;
6366
- this.stop();
6367
- this._disposed = true;
6368
- if (this._resizeListener) {
6369
- window.removeEventListener("resize", this._resizeListener);
6370
- this._resizeListener = void 0;
6137
+ function handleMouseMovePan(event) {
6138
+ panEnd.set(event.clientX, event.clientY);
6139
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6140
+ pan(panDelta.x, panDelta.y);
6141
+ panStart.copy(panEnd);
6142
+ scope.update();
6143
+ }
6144
+ function handleMouseUp() {
6145
+ }
6146
+ function handleMouseWheel(event) {
6147
+ if (event.deltaY < 0) {
6148
+ dollyIn(getZoomScale());
6149
+ } else if (event.deltaY > 0) {
6150
+ dollyOut(getZoomScale());
6151
+ }
6152
+ scope.update();
6153
+ }
6154
+ function handleKeyDown(event) {
6155
+ let needsUpdate = false;
6156
+ switch (event.code) {
6157
+ case scope.keys.UP:
6158
+ pan(0, scope.keyPanSpeed);
6159
+ needsUpdate = true;
6160
+ break;
6161
+ case scope.keys.BOTTOM:
6162
+ pan(0, -scope.keyPanSpeed);
6163
+ needsUpdate = true;
6164
+ break;
6165
+ case scope.keys.LEFT:
6166
+ pan(scope.keyPanSpeed, 0);
6167
+ needsUpdate = true;
6168
+ break;
6169
+ case scope.keys.RIGHT:
6170
+ pan(-scope.keyPanSpeed, 0);
6171
+ needsUpdate = true;
6172
+ break;
6173
+ }
6174
+ if (needsUpdate) {
6175
+ event.preventDefault();
6176
+ scope.update();
6177
+ }
6178
+ }
6179
+ function handleTouchStartRotate() {
6180
+ if (pointers.length === 1) {
6181
+ rotateStart.set(pointers[0].pageX, pointers[0].pageY);
6182
+ } else {
6183
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6184
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6185
+ rotateStart.set(x, y);
6186
+ }
6371
6187
  }
6372
- for (const [dispatcher, events] of this._eventDispatchers) {
6373
- for (const event of events) {
6374
- dispatcher.removeEventListener(event, this._changeListener);
6188
+ function handleTouchStartPan() {
6189
+ if (pointers.length === 1) {
6190
+ panStart.set(pointers[0].pageX, pointers[0].pageY);
6191
+ } else {
6192
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6193
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6194
+ panStart.set(x, y);
6375
6195
  }
6376
6196
  }
6377
- this._eventDispatchers.clear();
6378
- this._stats?.dom.remove();
6379
- this._stats = void 0;
6380
- this.renderer.domElement.remove();
6381
- this._element = void 0;
6382
- if (this._controls) {
6383
- const controls = this._controls;
6384
- this._controls = void 0;
6385
- controls.enabled = false;
6386
- controls.dispose();
6197
+ function handleTouchStartDolly() {
6198
+ const dx = pointers[0].pageX - pointers[1].pageX;
6199
+ const dy = pointers[0].pageY - pointers[1].pageY;
6200
+ const distance = Math.sqrt(dx * dx + dy * dy);
6201
+ dollyStart.set(0, distance);
6387
6202
  }
6388
- this.scene.clear();
6389
- for (const helper of this._debugHelpers) {
6390
- helper.geometry.dispose();
6391
- const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
6392
- for (const material of materials) {
6393
- material.dispose();
6203
+ function handleTouchStartDollyPan() {
6204
+ if (scope.enableZoom) handleTouchStartDolly();
6205
+ if (scope.enablePan) handleTouchStartPan();
6206
+ }
6207
+ function handleTouchStartDollyRotate() {
6208
+ if (scope.enableZoom) handleTouchStartDolly();
6209
+ if (scope.enableRotate) handleTouchStartRotate();
6210
+ }
6211
+ function handleTouchMoveRotate(event) {
6212
+ if (pointers.length == 1) {
6213
+ rotateEnd.set(event.pageX, event.pageY);
6214
+ } else {
6215
+ const position = getSecondPointerPosition(event);
6216
+ const x = 0.5 * (event.pageX + position.x);
6217
+ const y = 0.5 * (event.pageY + position.y);
6218
+ rotateEnd.set(x, y);
6394
6219
  }
6220
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6221
+ const element = scope.domElement;
6222
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6223
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6224
+ rotateStart.copy(rotateEnd);
6395
6225
  }
6396
- this._debugHelpers.length = 0;
6397
- this.composer?.dispose();
6398
- this.renderer.dispose();
6399
- this.renderer.forceContextLoss();
6400
- }
6401
- animate(t = performance.now()) {
6402
- if (this._disposed) return;
6403
- if (this._controls?.enabled) {
6404
- this._controls.update();
6226
+ function handleTouchMovePan(event) {
6227
+ if (pointers.length === 1) {
6228
+ panEnd.set(event.pageX, event.pageY);
6229
+ } else {
6230
+ const position = getSecondPointerPosition(event);
6231
+ const x = 0.5 * (event.pageX + position.x);
6232
+ const y = 0.5 * (event.pageY + position.y);
6233
+ panEnd.set(x, y);
6234
+ }
6235
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6236
+ pan(panDelta.x, panDelta.y);
6237
+ panStart.copy(panEnd);
6405
6238
  }
6406
- if (this._disposed) return;
6407
- if (!this.dirty && !this.options.render.renderAlways) return;
6408
- const interval = this._frameInterval;
6409
- if (interval) {
6410
- const next = this._nextFrameTime;
6411
- if (next !== void 0 && t + 0.1 < next) return;
6412
- this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
6239
+ function handleTouchMoveDolly(event) {
6240
+ const position = getSecondPointerPosition(event);
6241
+ const dx = event.pageX - position.x;
6242
+ const dy = event.pageY - position.y;
6243
+ const distance = Math.sqrt(dx * dx + dy * dy);
6244
+ dollyEnd.set(0, distance);
6245
+ dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
6246
+ dollyOut(dollyDelta.y);
6247
+ dollyStart.copy(dollyEnd);
6413
6248
  }
6414
- if (this._stats) {
6415
- this._stats.begin();
6249
+ function handleTouchMoveDollyPan(event) {
6250
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6251
+ if (scope.enablePan) handleTouchMovePan(event);
6416
6252
  }
6417
- if (this.options.composer.enabled && this.composer) {
6418
- this.composer.render();
6419
- } else {
6420
- this.renderer.render(this.scene, this.camera);
6253
+ function handleTouchMoveDollyRotate(event) {
6254
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6255
+ if (scope.enableRotate) handleTouchMoveRotate(event);
6421
6256
  }
6422
- this.dirty = false;
6423
- if (this._stats) {
6424
- this._stats.end();
6257
+ function handleTouchEnd() {
6425
6258
  }
6426
- }
6427
- //</editor-fold>
6428
- toImage() {
6429
- return this.renderer.domElement.toDataURL();
6430
- }
6431
- ///
6432
- get attachedToBody() {
6433
- return this.element === document.body;
6434
- }
6435
- get viewWidth() {
6436
- return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
6437
- }
6438
- get viewHeight() {
6439
- return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
6440
- }
6441
- get scene() {
6442
- return this._scene;
6443
- }
6444
- get camera() {
6445
- return this._camera;
6446
- }
6447
- get renderer() {
6448
- return this._renderer;
6449
- }
6450
- get composer() {
6451
- return this._composer;
6452
- }
6453
- /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
6454
- get controls() {
6455
- return this._controls;
6456
- }
6457
- ///
6458
- };
6459
- _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6460
- camera: {
6461
- type: "perspective",
6462
- near: 1,
6463
- far: 5e3,
6464
- perspective: {
6465
- aspect: void 0,
6466
- fov: 50
6467
- },
6468
- orthographic: {
6469
- left: void 0,
6470
- right: void 0,
6471
- top: void 0,
6472
- bottom: void 0
6473
- },
6474
- position: new Vector38(50, 50, 50),
6475
- lookingAt: new Vector38(0, 0, 0)
6476
- },
6477
- render: {
6478
- fpsLimit: 60,
6479
- stats: false,
6480
- antialias: true,
6481
- shade: true,
6482
- autoResize: true,
6483
- renderAlways: false
6484
- },
6485
- composer: {
6486
- enabled: true
6487
- },
6488
- controls: {
6489
- enabled: false
6490
- },
6491
- debug: {
6492
- grid: false,
6493
- axes: false
6494
- }
6495
- });
6496
- var Renderer = _Renderer;
6497
-
6498
- // src/skin/Skins.ts
6499
- var Skins = class {
6500
- //<editor-fold desc="Skins">
6501
- static async fromUuidOrUsername(uuidOrUsername) {
6502
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6503
- return this.fromUuid(uuidOrUsername);
6259
+ function onPointerDown(event) {
6260
+ if (scope.enabled === false) return;
6261
+ if (pointers.length === 0) {
6262
+ scope.domElement.setPointerCapture(event.pointerId);
6263
+ scope.domElement.addEventListener("pointermove", onPointerMove);
6264
+ scope.domElement.addEventListener("pointerup", onPointerUp);
6265
+ }
6266
+ addPointer(event);
6267
+ if (event.pointerType === "touch") {
6268
+ onTouchStart(event);
6269
+ } else {
6270
+ onMouseDown(event);
6271
+ }
6504
6272
  }
6505
- return this.fromUsername(uuidOrUsername);
6506
- }
6507
- static async fromUuid(uuid) {
6508
- return this.getSkinProxySkinUrl(uuid);
6509
- }
6510
- static async fromUsername(username) {
6511
- return this.usernameToUuid(username).then((uuid) => {
6512
- if (uuid) {
6513
- return this.fromUuid(uuid);
6273
+ function onPointerMove(event) {
6274
+ if (scope.enabled === false) return;
6275
+ if (event.pointerType === "touch") {
6276
+ onTouchMove(event);
6277
+ } else {
6278
+ onMouseMove(event);
6514
6279
  }
6515
- return void 0;
6516
- });
6517
- }
6518
- static async fromMineSkin(mineskinId) {
6519
- return this.getMineSkin(mineskinId).then((mineskin) => {
6520
- if (mineskin) {
6521
- return mineskin["data"]["texture"]["value"]["urls"]["skins"];
6280
+ }
6281
+ function onPointerUp(event) {
6282
+ if (scope.enabled === false) return;
6283
+ if (event.pointerType === "touch") {
6284
+ onTouchEnd();
6285
+ } else {
6286
+ onMouseUp(event);
6287
+ }
6288
+ removePointer(event);
6289
+ if (pointers.length === 0) {
6290
+ scope.domElement.releasePointerCapture(event.pointerId);
6291
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
6292
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
6293
+ }
6294
+ }
6295
+ function onPointerCancel(event) {
6296
+ removePointer(event);
6297
+ }
6298
+ function onMouseDown(event) {
6299
+ let mouseAction;
6300
+ switch (event.button) {
6301
+ case 0:
6302
+ mouseAction = scope.mouseButtons.LEFT;
6303
+ break;
6304
+ case 1:
6305
+ mouseAction = scope.mouseButtons.MIDDLE;
6306
+ break;
6307
+ case 2:
6308
+ mouseAction = scope.mouseButtons.RIGHT;
6309
+ break;
6310
+ default:
6311
+ mouseAction = -1;
6312
+ }
6313
+ switch (mouseAction) {
6314
+ case MOUSE.DOLLY:
6315
+ if (scope.enableZoom === false) return;
6316
+ handleMouseDownDolly(event);
6317
+ state = STATE.DOLLY;
6318
+ break;
6319
+ case MOUSE.ROTATE:
6320
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6321
+ if (scope.enablePan === false) return;
6322
+ handleMouseDownPan(event);
6323
+ state = STATE.PAN;
6324
+ } else {
6325
+ if (scope.enableRotate === false) return;
6326
+ handleMouseDownRotate(event);
6327
+ state = STATE.ROTATE;
6328
+ }
6329
+ break;
6330
+ case MOUSE.PAN:
6331
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6332
+ if (scope.enableRotate === false) return;
6333
+ handleMouseDownRotate(event);
6334
+ state = STATE.ROTATE;
6335
+ } else {
6336
+ if (scope.enablePan === false) return;
6337
+ handleMouseDownPan(event);
6338
+ state = STATE.PAN;
6339
+ }
6340
+ break;
6341
+ default:
6342
+ state = STATE.NONE;
6343
+ }
6344
+ if (state !== STATE.NONE) {
6345
+ scope.dispatchEvent(_startEvent);
6522
6346
  }
6523
- return void 0;
6524
- });
6525
- }
6526
- //</editor-fold>
6527
- //<editor-fold desc="Capes">
6528
- static async capeFromUuidOrUsername(uuidOrUsername) {
6529
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6530
- return this.capeFromUuid(uuidOrUsername);
6531
6347
  }
6532
- return this.capeFromUsername(uuidOrUsername);
6533
- }
6534
- static async capeFromUuid(uuid) {
6535
- return this.getSkinProxyCapeUrl(uuid);
6536
- }
6537
- static async capeFromUsername(username) {
6538
- return this.usernameToUuid(username).then((uuid) => {
6539
- if (uuid) {
6540
- return this.capeFromUuid(uuid);
6541
- }
6542
- return void 0;
6543
- });
6544
- }
6545
- static async capeFromCapesDev(uuid, capeType = "minecraft") {
6546
- return this.getCapesDev(uuid, capeType).then((cape) => {
6547
- if (cape) {
6548
- return cape?.stillImageUrl;
6348
+ function onMouseMove(event) {
6349
+ if (scope.enabled === false) return;
6350
+ switch (state) {
6351
+ case STATE.ROTATE:
6352
+ if (scope.enableRotate === false) return;
6353
+ handleMouseMoveRotate(event);
6354
+ break;
6355
+ case STATE.DOLLY:
6356
+ if (scope.enableZoom === false) return;
6357
+ handleMouseMoveDolly(event);
6358
+ break;
6359
+ case STATE.PAN:
6360
+ if (scope.enablePan === false) return;
6361
+ handleMouseMovePan(event);
6362
+ break;
6549
6363
  }
6550
- return void 0;
6551
- });
6552
- }
6553
- //</editor-fold>
6554
- //<editor-fold desc="Helpers">
6555
- static async usernameToUuid(username) {
6556
- return this.usernameToUuidSkinProxy(username);
6557
- }
6558
- static async usernameToUuidSkinProxy(username) {
6559
- return Requests.genericRequest({
6560
- baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
6561
- url: "/uuid/" + username
6562
- }).then((res) => {
6563
- if (res.status === 200) {
6564
- return res.data["id"];
6364
+ }
6365
+ function onMouseUp(event) {
6366
+ handleMouseUp(event);
6367
+ scope.dispatchEvent(_endEvent);
6368
+ state = STATE.NONE;
6369
+ }
6370
+ function onMouseWheel(event) {
6371
+ if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6372
+ event.preventDefault();
6373
+ scope.dispatchEvent(_startEvent);
6374
+ handleMouseWheel(event);
6375
+ scope.dispatchEvent(_endEvent);
6376
+ }
6377
+ function onKeyDown(event) {
6378
+ if (scope.enabled === false || scope.enablePan === false) return;
6379
+ handleKeyDown(event);
6380
+ }
6381
+ function onTouchStart(event) {
6382
+ trackPointer(event);
6383
+ switch (pointers.length) {
6384
+ case 1:
6385
+ switch (scope.touches.ONE) {
6386
+ case TOUCH.ROTATE:
6387
+ if (scope.enableRotate === false) return;
6388
+ handleTouchStartRotate();
6389
+ state = STATE.TOUCH_ROTATE;
6390
+ break;
6391
+ case TOUCH.PAN:
6392
+ if (scope.enablePan === false) return;
6393
+ handleTouchStartPan();
6394
+ state = STATE.TOUCH_PAN;
6395
+ break;
6396
+ default:
6397
+ state = STATE.NONE;
6398
+ }
6399
+ break;
6400
+ case 2:
6401
+ switch (scope.touches.TWO) {
6402
+ case TOUCH.DOLLY_PAN:
6403
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6404
+ handleTouchStartDollyPan();
6405
+ state = STATE.TOUCH_DOLLY_PAN;
6406
+ break;
6407
+ case TOUCH.DOLLY_ROTATE:
6408
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6409
+ handleTouchStartDollyRotate();
6410
+ state = STATE.TOUCH_DOLLY_ROTATE;
6411
+ break;
6412
+ default:
6413
+ state = STATE.NONE;
6414
+ }
6415
+ break;
6416
+ default:
6417
+ state = STATE.NONE;
6565
6418
  }
6566
- return void 0;
6567
- }).catch((err) => {
6568
- console.warn(err);
6569
- return void 0;
6570
- });
6571
- }
6572
- static async usernameToUuidMineTools(username) {
6573
- return Requests.genericRequest({
6574
- baseURL: "https://api.minetools.eu",
6575
- url: "/uuid/" + username
6576
- }).then((res) => {
6577
- if (res.status === 200) {
6578
- return res.data["id"];
6419
+ if (state !== STATE.NONE) {
6420
+ scope.dispatchEvent(_startEvent);
6579
6421
  }
6580
- return void 0;
6581
- }).catch((err) => {
6582
- console.warn(err);
6583
- return void 0;
6584
- });
6585
- }
6586
- static async getProfileFromMinetools(uuid) {
6587
- return Requests.genericRequest({
6588
- baseURL: "https://api.minetools.eu",
6589
- url: "/profile/" + uuid
6590
- }).then((res) => {
6591
- if (res.status === 200) {
6592
- return res.data;
6422
+ }
6423
+ function onTouchMove(event) {
6424
+ trackPointer(event);
6425
+ switch (state) {
6426
+ case STATE.TOUCH_ROTATE:
6427
+ if (scope.enableRotate === false) return;
6428
+ handleTouchMoveRotate(event);
6429
+ scope.update();
6430
+ break;
6431
+ case STATE.TOUCH_PAN:
6432
+ if (scope.enablePan === false) return;
6433
+ handleTouchMovePan(event);
6434
+ scope.update();
6435
+ break;
6436
+ case STATE.TOUCH_DOLLY_PAN:
6437
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6438
+ handleTouchMoveDollyPan(event);
6439
+ scope.update();
6440
+ break;
6441
+ case STATE.TOUCH_DOLLY_ROTATE:
6442
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6443
+ handleTouchMoveDollyRotate(event);
6444
+ scope.update();
6445
+ break;
6446
+ default:
6447
+ state = STATE.NONE;
6593
6448
  }
6594
- });
6595
- }
6596
- static async getMineSkin(mineskinId) {
6597
- return Requests.genericRequest({
6598
- baseURL: "https://api.mineskin.org",
6599
- url: "/get/uuid/" + mineskinId
6600
- }).then((res) => {
6601
- if (res.status === 200) {
6602
- return res.data;
6449
+ }
6450
+ function onTouchEnd(event) {
6451
+ handleTouchEnd(event);
6452
+ scope.dispatchEvent(_endEvent);
6453
+ state = STATE.NONE;
6454
+ }
6455
+ function onContextMenu(event) {
6456
+ if (scope.enabled === false) return;
6457
+ event.preventDefault();
6458
+ }
6459
+ function addPointer(event) {
6460
+ pointers.push(event);
6461
+ }
6462
+ function removePointer(event) {
6463
+ delete pointerPositions[event.pointerId];
6464
+ for (let i = 0; i < pointers.length; i++) {
6465
+ if (pointers[i].pointerId == event.pointerId) {
6466
+ pointers.splice(i, 1);
6467
+ return;
6468
+ }
6603
6469
  }
6604
- return void 0;
6605
- }).catch((err) => {
6606
- console.warn(err);
6607
- return void 0;
6608
- });
6609
- }
6610
- static async getCapesDev(uuid, type = "all") {
6611
- return Requests.genericRequest({
6612
- baseURL: "https://api.capes.dev",
6613
- url: "/load/" + uuid + "/" + type
6614
- }).then((res) => {
6615
- if (res.status === 200) {
6616
- return res.data;
6470
+ }
6471
+ function trackPointer(event) {
6472
+ let position = pointerPositions[event.pointerId];
6473
+ if (position === void 0) {
6474
+ position = new Vector23();
6475
+ pointerPositions[event.pointerId] = position;
6617
6476
  }
6618
- return void 0;
6619
- }).catch((err) => {
6620
- console.warn(err);
6621
- return void 0;
6622
- });
6623
- }
6624
- static getCrafatarSkinUrl(uuid) {
6625
- return "https://crafatar.com/skins/" + uuid;
6626
- }
6627
- static getCrafatarCapeUrl(uuid) {
6628
- return "https://crafatar.com/capes/" + uuid;
6629
- }
6630
- static getMcHeadsSkinUrl(uuid) {
6631
- return "https://mc-heads.net/skin/" + uuid;
6632
- }
6633
- static getMineSkinPlayerSkinUrl(uuid) {
6634
- return "https://mineskin.org/skin/player/" + uuid;
6635
- }
6636
- static getSkinProxySkinUrl(uuid) {
6637
- return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
6477
+ position.set(event.pageX, event.pageY);
6478
+ }
6479
+ function getSecondPointerPosition(event) {
6480
+ const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6481
+ return pointerPositions[pointer.pointerId];
6482
+ }
6483
+ scope.domElement.addEventListener("contextmenu", onContextMenu);
6484
+ scope.domElement.addEventListener("pointerdown", onPointerDown);
6485
+ scope.domElement.addEventListener("pointercancel", onPointerCancel);
6486
+ scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6487
+ this.update();
6638
6488
  }
6639
- static getSkinProxyCapeUrl(uuid) {
6640
- return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
6489
+ };
6490
+ var MapControls = class extends OrbitControls {
6491
+ constructor(object, domElement) {
6492
+ super(object, domElement);
6493
+ this.screenSpacePanning = false;
6494
+ this.mouseButtons.LEFT = MOUSE.PAN;
6495
+ this.mouseButtons.RIGHT = MOUSE.ROTATE;
6496
+ this.touches.ONE = TOUCH.PAN;
6497
+ this.touches.TWO = TOUCH.DOLLY_ROTATE;
6641
6498
  }
6642
- //</editor-fold>
6643
6499
  };
6644
6500
 
6645
6501
  // src/world/Chunk.ts
@@ -6756,7 +6612,7 @@ var MineRenderWorld = class {
6756
6612
  };
6757
6613
 
6758
6614
  // src/world/Chunk.ts
6759
- var p11 = prefix("Chunk");
6615
+ var p12 = prefix("Chunk");
6760
6616
  var Chunk = class _Chunk {
6761
6617
  constructor(scene, x, y, z) {
6762
6618
  this._blocks = [];
@@ -6808,7 +6664,7 @@ var Chunk = class _Chunk {
6808
6664
  const index = _Chunk.chunkPosToBlockIndex(pos);
6809
6665
  const current = this._blocks[index];
6810
6666
  if (typeof current !== "undefined") {
6811
- console.debug(p11, "deleting existing block at", pos, worldPos, index);
6667
+ console.debug(p12, "deleting existing block at", pos, worldPos, index);
6812
6668
  current.object.removeFromScene();
6813
6669
  delete this._blocks[index];
6814
6670
  }
@@ -6874,7 +6730,6 @@ export {
6874
6730
  AXES,
6875
6731
  ArchiveAssetSource,
6876
6732
  AssetKey,
6877
- AssetLoadError,
6878
6733
  AssetLoader,
6879
6734
  AssetParser,
6880
6735
  AssetSource,
@@ -6932,7 +6787,6 @@ export {
6932
6787
  OrbitControls,
6933
6788
  PersistentCache,
6934
6789
  Renderer,
6935
- RequestError,
6936
6790
  Requests,
6937
6791
  SKIN_PARTS,
6938
6792
  SceneInspector,