minerender 2.1.0-alpha.0 → 2.1.0-alpha.10

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.
Files changed (94) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/index.d.mts +187 -137
  3. package/dist/browser/index.d.ts +187 -137
  4. package/dist/browser/index.js +1378 -1130
  5. package/dist/browser/index.js.map +1 -1
  6. package/dist/browser/index.mjs +1392 -1144
  7. package/dist/browser/index.mjs.map +1 -1
  8. package/dist/bundle.js +7531 -8873
  9. package/dist/bundle.js.map +1 -1
  10. package/dist/node/index.d.mts +186 -136
  11. package/dist/node/index.d.ts +186 -136
  12. package/dist/node/index.js +1598 -1280
  13. package/dist/node/index.js.map +1 -1
  14. package/dist/node/index.mjs +1550 -1233
  15. package/dist/node/index.mjs.map +1 -1
  16. package/package.json +11 -13
  17. package/.worktrees/jobqu-review/LICENSE +0 -21
  18. package/.worktrees/jobqu-review/README.md +0 -176
  19. package/.worktrees/v2-asset-sources/LICENSE +0 -21
  20. package/.worktrees/v2-asset-sources/README.md +0 -30
  21. package/.worktrees/v2-asset-sources/examples/script-tag/README.md +0 -13
  22. package/.worktrees/v2-asset-sources/examples/vite/README.md +0 -13
  23. package/.worktrees/v2-asset-sources/packages/minerender/LICENSE +0 -21
  24. package/.worktrees/v2-asset-sources/packages/minerender/README.md +0 -24
  25. package/.worktrees/v2-brightness/LICENSE +0 -21
  26. package/.worktrees/v2-brightness/README.md +0 -30
  27. package/.worktrees/v2-brightness/examples/script-tag/README.md +0 -13
  28. package/.worktrees/v2-brightness/examples/vite/README.md +0 -13
  29. package/.worktrees/v2-brightness/packages/minerender/LICENSE +0 -21
  30. package/.worktrees/v2-brightness/packages/minerender/README.md +0 -24
  31. package/.worktrees/v2-cache-recovery/LICENSE +0 -21
  32. package/.worktrees/v2-cache-recovery/README.md +0 -30
  33. package/.worktrees/v2-cache-recovery/examples/script-tag/README.md +0 -13
  34. package/.worktrees/v2-cache-recovery/examples/vite/README.md +0 -13
  35. package/.worktrees/v2-cache-recovery/packages/minerender/LICENSE +0 -21
  36. package/.worktrees/v2-cache-recovery/packages/minerender/README.md +0 -24
  37. package/.worktrees/v2-ci-stack/LICENSE +0 -21
  38. package/.worktrees/v2-ci-stack/README.md +0 -109
  39. package/.worktrees/v2-ci-stack/examples/script-tag/README.md +0 -15
  40. package/.worktrees/v2-ci-stack/examples/vite/README.md +0 -15
  41. package/.worktrees/v2-ci-stack/packages/minerender/LICENSE +0 -21
  42. package/.worktrees/v2-ci-stack/packages/minerender/README.md +0 -11
  43. package/.worktrees/v2-ci-typescript/LICENSE +0 -21
  44. package/.worktrees/v2-ci-typescript/README.md +0 -11
  45. package/.worktrees/v2-controls/LICENSE +0 -21
  46. package/.worktrees/v2-controls/README.md +0 -30
  47. package/.worktrees/v2-controls/examples/script-tag/README.md +0 -13
  48. package/.worktrees/v2-controls/examples/vite/README.md +0 -13
  49. package/.worktrees/v2-controls/packages/minerender/LICENSE +0 -21
  50. package/.worktrees/v2-controls/packages/minerender/README.md +0 -24
  51. package/.worktrees/v2-dependencies/LICENSE +0 -21
  52. package/.worktrees/v2-dependencies/README.md +0 -30
  53. package/.worktrees/v2-dependencies/examples/script-tag/README.md +0 -13
  54. package/.worktrees/v2-dependencies/examples/vite/README.md +0 -13
  55. package/.worktrees/v2-dependencies/packages/minerender/LICENSE +0 -21
  56. package/.worktrees/v2-dependencies/packages/minerender/README.md +0 -24
  57. package/.worktrees/v2-frame-limit/LICENSE +0 -21
  58. package/.worktrees/v2-frame-limit/README.md +0 -30
  59. package/.worktrees/v2-frame-limit/examples/script-tag/README.md +0 -13
  60. package/.worktrees/v2-frame-limit/examples/vite/README.md +0 -13
  61. package/.worktrees/v2-frame-limit/packages/minerender/LICENSE +0 -21
  62. package/.worktrees/v2-frame-limit/packages/minerender/README.md +0 -24
  63. package/.worktrees/v2-images/LICENSE +0 -21
  64. package/.worktrees/v2-images/README.md +0 -30
  65. package/.worktrees/v2-images/examples/script-tag/README.md +0 -13
  66. package/.worktrees/v2-images/examples/vite/README.md +0 -13
  67. package/.worktrees/v2-images/packages/minerender/LICENSE +0 -21
  68. package/.worktrees/v2-images/packages/minerender/README.md +0 -24
  69. package/.worktrees/v2-lifecycle/LICENSE +0 -21
  70. package/.worktrees/v2-lifecycle/README.md +0 -30
  71. package/.worktrees/v2-lifecycle/examples/script-tag/README.md +0 -13
  72. package/.worktrees/v2-lifecycle/examples/vite/README.md +0 -13
  73. package/.worktrees/v2-lifecycle/packages/minerender/LICENSE +0 -21
  74. package/.worktrees/v2-lifecycle/packages/minerender/README.md +0 -24
  75. package/.worktrees/v2-main-conflicts/LICENSE +0 -21
  76. package/.worktrees/v2-main-conflicts/README.md +0 -11
  77. package/.worktrees/v2-monorepo/LICENSE +0 -21
  78. package/.worktrees/v2-monorepo/README.md +0 -30
  79. package/.worktrees/v2-monorepo/examples/script-tag/README.md +0 -13
  80. package/.worktrees/v2-monorepo/examples/vite/README.md +0 -13
  81. package/.worktrees/v2-monorepo/packages/minerender/LICENSE +0 -21
  82. package/.worktrees/v2-monorepo/packages/minerender/README.md +0 -24
  83. package/.worktrees/v2-requests/LICENSE +0 -21
  84. package/.worktrees/v2-requests/README.md +0 -30
  85. package/.worktrees/v2-requests/examples/script-tag/README.md +0 -13
  86. package/.worktrees/v2-requests/examples/vite/README.md +0 -13
  87. package/.worktrees/v2-requests/packages/minerender/LICENSE +0 -21
  88. package/.worktrees/v2-requests/packages/minerender/README.md +0 -26
  89. package/.worktrees/v2-source-errors/LICENSE +0 -21
  90. package/.worktrees/v2-source-errors/README.md +0 -30
  91. package/.worktrees/v2-source-errors/examples/script-tag/README.md +0 -13
  92. package/.worktrees/v2-source-errors/examples/vite/README.md +0 -13
  93. package/.worktrees/v2-source-errors/packages/minerender/LICENSE +0 -21
  94. package/.worktrees/v2-source-errors/packages/minerender/README.md +0 -26
@@ -23,18 +23,10 @@ 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
- };
34
26
 
35
- // node_modules/ts-deepmerge/dist/index.js
27
+ // ../../node_modules/ts-deepmerge/dist/index.js
36
28
  var require_dist = __commonJS({
37
- "node_modules/ts-deepmerge/dist/index.js"(exports) {
29
+ "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
38
30
  "use strict";
39
31
  var __assign = exports && exports.__assign || function() {
40
32
  __assign = Object.assign || function(t) {
@@ -85,7 +77,7 @@ var require_dist = __commonJS({
85
77
  return false;
86
78
  };
87
79
  var PROTECTED_KEYS = ["__proto__"];
88
- var merge11 = function() {
80
+ var merge10 = function() {
89
81
  var objects = [];
90
82
  for (var _i = 0; _i < arguments.length; _i++) {
91
83
  objects[_i] = arguments[_i];
@@ -96,9 +88,9 @@ var require_dist = __commonJS({
96
88
  return;
97
89
  }
98
90
  if (Array.isArray(result[key]) && Array.isArray(current[key])) {
99
- result[key] = merge11.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
91
+ result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
100
92
  } else if (isObject(result[key]) && isObject(current[key])) {
101
- result[key] = merge11(result[key], current[key]);
93
+ result[key] = merge10(result[key], current[key]);
102
94
  } else {
103
95
  result[key] = current[key];
104
96
  }
@@ -109,18 +101,18 @@ var require_dist = __commonJS({
109
101
  var defaultOptions = {
110
102
  mergeArrays: true
111
103
  };
112
- merge11.options = defaultOptions;
113
- merge11.withOptions = function(options) {
104
+ merge10.options = defaultOptions;
105
+ merge10.withOptions = function(options) {
114
106
  var objects = [];
115
107
  for (var _i = 1; _i < arguments.length; _i++) {
116
108
  objects[_i - 1] = arguments[_i];
117
109
  }
118
- merge11.options = __assign({ mergeArrays: true }, options);
119
- var result = merge11.apply(void 0, __spreadArray([], __read(objects), false));
120
- merge11.options = defaultOptions;
110
+ merge10.options = __assign({ mergeArrays: true }, options);
111
+ var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
112
+ merge10.options = defaultOptions;
121
113
  return result;
122
114
  };
123
- exports.default = merge11;
115
+ exports.default = merge10;
124
116
  }
125
117
  });
126
118
 
@@ -154,17 +146,20 @@ var _PersistentCache = class _PersistentCache {
154
146
  static open(name) {
155
147
  return Env.provider.openCache(name, _PersistentCache.VERSION);
156
148
  }
149
+ /** Loads a missing entry and stores only non-nullish results. */
157
150
  async getOrLoad(key, loader) {
158
151
  let v = await this.get(key);
159
152
  if (typeof v === "undefined" || v === null) {
160
153
  v = await loader(key);
161
- await this.put(key, v);
154
+ if (typeof v !== "undefined" && v !== null) {
155
+ await this.put(key, v);
156
+ }
162
157
  }
163
158
  return v;
164
159
  }
165
160
  };
166
161
  /** Bump to invalidate every persisted entry. */
167
- _PersistentCache.VERSION = 1;
162
+ _PersistentCache.VERSION = 2;
168
163
  var PersistentCache = _PersistentCache;
169
164
 
170
165
  // src/env/browser/BrowserCache.ts
@@ -265,7 +260,8 @@ var BrowserEnv = class {
265
260
  }
266
261
  openCache(name, version) {
267
262
  return new BrowserCache(localforage.createInstance({
268
- name,
263
+ // IndexedDB schema upgrades retain records; each cache generation needs its own database.
264
+ name: name + version,
269
265
  version
270
266
  }));
271
267
  }
@@ -393,7 +389,10 @@ function serializeMeshKey(key) {
393
389
  // src/cache/Caching.ts
394
390
  import { Caches } from "@inventivetalent/loading-cache";
395
391
  import { Time } from "@inventivetalent/time";
396
- var Caching = class {
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
+ }
397
396
  /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
398
397
  static get all() {
399
398
  return [
@@ -410,7 +409,10 @@ var Caching = class {
410
409
  this.rawModelCache,
411
410
  this.mergedModelCache,
412
411
  this.modelTextureAtlasCache,
413
- this.blockStateCache
412
+ this.blockStateCache,
413
+ this.listAssetCache,
414
+ this.defaultBlockStatesCache,
415
+ this.entityModelsCache
414
416
  ];
415
417
  }
416
418
  static clear() {
@@ -421,8 +423,8 @@ var Caching = class {
421
423
  /**
422
424
  * Clears every cache and stops its expiry timer.
423
425
  *
424
- * loading-cache reschedules that timer indefinitely, so a Node process will not exit until
425
- * this is called - see {@link shutdown}.
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.
426
428
  */
427
429
  static end() {
428
430
  for (const cache of this.all) {
@@ -436,20 +438,24 @@ var Caching = class {
436
438
  };
437
439
  }
438
440
  };
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();
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;
453
459
 
454
460
  // src/Geometries.ts
455
461
  var Geometries = class _Geometries {
@@ -477,6 +483,7 @@ import { CanvasTexture, Texture as Texture2 } from "three";
477
483
 
478
484
  // src/texture/TextureLoader.ts
479
485
  import { RGBAFormat, Texture } from "three";
486
+ import * as THREE from "three";
480
487
 
481
488
  // src/canvas/CanvasCompat.ts
482
489
  function createImage(width, height) {
@@ -487,9 +494,7 @@ function createCanvas(width, height) {
487
494
  }
488
495
 
489
496
  // src/request/Requests.ts
490
- import axios from "axios";
491
- import { JobQueue } from "jobqu";
492
- import { Time as Time2 } from "@inventivetalent/time";
497
+ import { JobCancelledError, JobQueue } from "jobqu";
493
498
 
494
499
  // src/util/log.ts
495
500
  var Reset = "\x1B[0m";
@@ -499,198 +504,170 @@ function prefix(prefix2) {
499
504
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
500
505
  }
501
506
 
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());
509
- }
510
- submit(task) {
511
- this.queue.push(task);
512
- }
513
- run() {
514
- for (let i = 0; i < this.batch; i++) {
515
- this.runNext();
516
- }
517
- }
518
- runNext() {
519
- let next = this.queue.shift();
520
- if (next) next();
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";
521
515
  }
522
516
  };
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);
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);
547
543
  }
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);
551
+ }
552
+ throw error;
548
553
  }
549
- geometry.translate(origin.x, origin.y, origin.z);
550
- }
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
554
  }
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;
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);
570
567
  }
571
568
  }
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
- });
644
- }
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
- });
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
+ );
650
577
  }
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;
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;
658
591
  }
659
- } else {
660
- request["minerenderRetry"] = 3;
661
- return true;
592
+ await this.waitForRetry(delay, signal);
662
593
  }
663
594
  }
595
+ } finally {
596
+ if (signal?.aborted) {
597
+ this.queue.remove(request);
598
+ }
599
+ this.pendingRequests--;
664
600
  }
665
- return false;
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
+ }
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);
666
648
  }
667
649
  static setMcAssetRoot(root) {
668
- this.mcAssetInstance.defaults.baseURL = root;
650
+ this.mcAssetRequestQueue.baseURL = root;
669
651
  }
652
+ /** Counts unsettled calls, including retry delays and requests still running after shutdown. */
670
653
  static get queueSizes() {
671
654
  return {
672
- generic: this.genericQueue.size,
673
- mcAsset: this.mcAssetRequestQueue.size
655
+ generic: this.genericQueue.pendingSize,
656
+ mcAsset: this.mcAssetRequestQueue.pendingSize
674
657
  };
675
658
  }
676
659
  /**
677
- * Stops both queue timers. jobqu reschedules itself indefinitely, so a Node process will not
678
- * exit until this is called - see {@link shutdown}.
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}.
679
663
  */
680
664
  static end() {
681
665
  this.genericQueue.end();
682
666
  this.mcAssetRequestQueue.end();
683
667
  }
684
668
  };
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;
669
+ Requests.genericQueue = new RequestQueue();
670
+ Requests.mcAssetRequestQueue = new RequestQueue();
694
671
 
695
672
  // src/WrappedImage.ts
696
673
  var WrappedImage = class {
@@ -755,29 +732,41 @@ var ImageLoader = class _ImageLoader {
755
732
  static async loadAsync(src) {
756
733
  return new Promise((resolve, reject) => {
757
734
  const image = this._createImage();
758
- image.src = src;
759
735
  image.onload = () => resolve(image);
760
- image.onerror = (err) => reject(err);
736
+ image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
737
+ image.src = src;
761
738
  });
762
739
  }
763
740
  static loadElement(src, onload, onerr) {
764
741
  const image = this._createImage();
765
- image.src = src;
766
742
  if (onload)
767
743
  image.onload = onload;
768
744
  if (onerr)
769
745
  image.onerror = onerr;
746
+ image.src = src;
770
747
  return image;
771
748
  }
772
749
  static async loadData(src) {
773
750
  console.debug(p2, "loadData", src);
774
- return await this.infoToData(await this.getInfo(src));
751
+ const image = await this.loadCanvasData(src);
752
+ return image.data.getImageData(0, 0, image.width, image.height);
775
753
  }
776
754
  static async loadCanvasData(src) {
777
- return await this.infoToCanvasData(await this.getInfo(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
+ }
778
766
  }
779
767
  static async infoToCanvasData(info) {
780
- const image = await _ImageLoader.loadAsync(info.src);
768
+ const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
769
+ const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
781
770
  const canvas = createCanvas(info.width, info.height);
782
771
  const context = canvas.getContext("2d");
783
772
  context.drawImage(image, 0, 0);
@@ -788,11 +777,8 @@ var ImageLoader = class _ImageLoader {
788
777
  };
789
778
  }
790
779
  static async infoToData(info) {
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);
780
+ const image = await this.infoToCanvasData(info);
781
+ return image.data.getImageData(0, 0, image.width, image.height);
796
782
  }
797
783
  static async getData(src) {
798
784
  const keyStr = serializeImageKey({ src });
@@ -807,38 +793,25 @@ var ImageLoader = class _ImageLoader {
807
793
  });
808
794
  }
809
795
  static async processResponse(response) {
810
- const src = response.config.url;
796
+ const src = response.url;
811
797
  const data = Buffer2.from(response.data);
812
798
  const { width, height, type } = Env.provider.imageSize(data);
799
+ if (!width || !height) {
800
+ throw new Error("Invalid or unsupported image dimensions");
801
+ }
813
802
  return {
814
803
  src,
815
- width: width || 0,
816
- height: height || 0,
804
+ width,
805
+ height,
817
806
  type,
818
807
  data
819
808
  };
820
809
  }
821
810
  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
- }
830
811
  return Requests.genericRequest({
831
812
  url: src,
832
813
  responseType: "arraybuffer"
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
- });
814
+ }).then(this.processResponse);
842
815
  }
843
816
  static async getInfo(src) {
844
817
  const keyStr = serializeImageKey({ src });
@@ -860,15 +833,22 @@ var ImageLoader = class _ImageLoader {
860
833
 
861
834
  // src/texture/TextureLoader.ts
862
835
  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
+ }
863
840
  static createTexture() {
864
841
  return new Texture();
865
842
  }
866
843
  static loadInBackground(src, format = RGBAFormat, rotation = 0) {
867
844
  const texture = this.createTexture();
868
- const image = ImageLoader.loadElement(src);
869
- image.onload = function() {
845
+ texture.colorSpace = THREE.SRGBColorSpace;
846
+ const image = ImageLoader.loadElement(src, () => {
870
847
  texture.needsUpdate = true;
871
- };
848
+ }, (error) => {
849
+ this.failedTextures.add(texture);
850
+ console.warn("Failed to load texture", src, error);
851
+ });
872
852
  texture.image = image;
873
853
  texture.format = format;
874
854
  texture.rotation = rotation;
@@ -876,22 +856,27 @@ var TextureLoader = class {
876
856
  }
877
857
  static load(src, format = RGBAFormat, rotation = 0) {
878
858
  const texture = new Texture();
859
+ texture.colorSpace = THREE.SRGBColorSpace;
879
860
  ImageLoader.getData(src).then((image) => {
880
- texture.needsUpdate = true;
881
861
  texture.image = image;
862
+ texture.needsUpdate = true;
863
+ }).catch((error) => {
864
+ this.failedTextures.add(texture);
865
+ console.warn("Failed to load texture", src, error);
882
866
  });
883
867
  texture.format = format;
884
868
  texture.rotation = rotation;
885
869
  return Textures.initTextureProps(texture);
886
870
  }
887
871
  };
872
+ TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
888
873
 
889
874
  // src/texture/Textures.ts
890
- import * as THREE from "three";
875
+ import * as THREE2 from "three";
891
876
  var Textures = class _Textures {
892
877
  static initTextureProps(texture) {
893
- texture.magFilter = THREE.NearestFilter;
894
- texture.minFilter = THREE.NearestFilter;
878
+ texture.magFilter = THREE2.NearestFilter;
879
+ texture.minFilter = THREE2.NearestFilter;
895
880
  texture.anisotropy = 0;
896
881
  return texture;
897
882
  }
@@ -902,10 +887,16 @@ var Textures = class _Textures {
902
887
  return new Texture2();
903
888
  }
904
889
  static createCanvasTexture(canvas) {
905
- return this.initTextureProps(new CanvasTexture(canvas));
890
+ const texture = new CanvasTexture(canvas);
891
+ texture.colorSpace = THREE2.SRGBColorSpace;
892
+ return this.initTextureProps(texture);
906
893
  }
907
894
  static getImage(key) {
908
895
  const keyStr = serializeTextureKey(key);
896
+ const cached = Caching.textureCache.peek(keyStr);
897
+ if (cached && TextureLoader.hasFailed(cached)) {
898
+ Caching.textureCache.invalidate(keyStr);
899
+ }
909
900
  return Caching.textureCache.get(keyStr, (k) => {
910
901
  return _Textures.createImage(key);
911
902
  });
@@ -1019,6 +1010,9 @@ var _Materials = class _Materials {
1019
1010
  gl_FragColor = vec4(lift + color.rgb * light2, 1.0);
1020
1011
 
1021
1012
  }
1013
+
1014
+ #include <tonemapping_fragment>
1015
+ #include <colorspace_fragment>
1022
1016
  }
1023
1017
  `;
1024
1018
  try {
@@ -1047,6 +1041,10 @@ var _Materials = class _Materials {
1047
1041
  }
1048
1042
  static getImage(key) {
1049
1043
  const keyStr = serializeMaterialKey(key);
1044
+ const map = Caching.materialCache.peek(keyStr)?.map;
1045
+ if (map && TextureLoader.hasFailed(map)) {
1046
+ Caching.materialCache.invalidate(keyStr);
1047
+ }
1050
1048
  return Caching.materialCache.get(keyStr, (k) => {
1051
1049
  return _Materials.createImage(key);
1052
1050
  });
@@ -1071,10 +1069,10 @@ _Materials.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA
1071
1069
  var Materials = _Materials;
1072
1070
 
1073
1071
  // src/Meshes.ts
1074
- import { Mesh as Mesh2 } from "three";
1072
+ import { Mesh } from "three";
1075
1073
  var Meshes = class _Meshes {
1076
1074
  static createBox(key) {
1077
- return new Mesh2(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1075
+ return new Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1078
1076
  }
1079
1077
  static getBox(key) {
1080
1078
  const keyStr = serializeMeshKey(key);
@@ -1200,9 +1198,6 @@ var ModelMerger = class {
1200
1198
  }
1201
1199
  };
1202
1200
 
1203
- // src/assets/Models.ts
1204
- import { Memoize } from "typescript-memoize";
1205
-
1206
1201
  // src/assets/source/parser/AssetParsers.ts
1207
1202
  var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1208
1203
  AssetParser2["MODEL"] = "model";
@@ -1216,14 +1211,14 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1216
1211
  })(AssetParser || {});
1217
1212
 
1218
1213
  // src/assets/Models.ts
1219
- var _Models = class _Models {
1214
+ var Models = class _Models {
1220
1215
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1221
1216
  // the library, and would require an EnvProvider before any entry has had a chance to register
1222
1217
  static get PERSISTENT_CACHE() {
1223
1218
  return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
1224
1219
  }
1225
1220
  static async getItemList() {
1226
- return AssetLoader.get(new AssetKey(
1221
+ const key = new AssetKey(
1227
1222
  DEFAULT_NAMESPACE,
1228
1223
  "_list",
1229
1224
  "models",
@@ -1231,7 +1226,10 @@ var _Models = class _Models {
1231
1226
  "assets",
1232
1227
  ".json",
1233
1228
  DEFAULT_ROOT
1234
- ), "list" /* LIST */).then((r) => r?.files ?? []);
1229
+ );
1230
+ return Caching.listAssetCache.get(key.serialize(), () => {
1231
+ return AssetLoader.get(key, "list" /* LIST */);
1232
+ }).then((r) => r?.files ?? []);
1235
1233
  }
1236
1234
  static async loadAndMerge(key) {
1237
1235
  const model = await this.getRaw(key);
@@ -1278,19 +1276,15 @@ var _Models = class _Models {
1278
1276
  return this.PERSISTENT_CACHE.clear();
1279
1277
  }
1280
1278
  };
1281
- __decorateClass([
1282
- Memoize()
1283
- ], _Models, "getItemList", 1);
1284
- var Models = _Models;
1285
1279
 
1286
1280
  // src/assets/BlockStates.ts
1287
- import { Memoize as Memoize2 } from "typescript-memoize";
1288
1281
  var BlockStates = class {
1289
1282
  static get PERSISTENT_CACHE() {
1290
1283
  return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
1291
1284
  }
1285
+ // BlockState names are hardcoded
1292
1286
  static async getList() {
1293
- return AssetLoader.get(new AssetKey(
1287
+ const key = new AssetKey(
1294
1288
  DEFAULT_NAMESPACE,
1295
1289
  "_list",
1296
1290
  "blockstates",
@@ -1298,11 +1292,16 @@ var BlockStates = class {
1298
1292
  "assets",
1299
1293
  ".json",
1300
1294
  DEFAULT_ROOT
1301
- ), "list" /* LIST */).then((r) => r?.files ?? []);
1295
+ );
1296
+ return Caching.listAssetCache.get(key.serialize(), () => {
1297
+ return AssetLoader.get(key, "list" /* LIST */);
1298
+ }).then((r) => r?.files ?? []);
1302
1299
  }
1303
1300
  static async getDefaultStates() {
1304
1301
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
1305
- return AssetLoader.get(key, "json" /* JSON */);
1302
+ return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
1303
+ return AssetLoader.get(key, "json" /* JSON */);
1304
+ });
1306
1305
  }
1307
1306
  static async getDefaultState(key) {
1308
1307
  const defaultStates = await this.getDefaultStates();
@@ -1341,17 +1340,11 @@ var BlockStates = class {
1341
1340
  await this.PERSISTENT_CACHE.clear();
1342
1341
  }
1343
1342
  };
1344
- __decorateClass([
1345
- Memoize2()
1346
- ], BlockStates, "getList", 1);
1347
- __decorateClass([
1348
- Memoize2()
1349
- ], BlockStates, "getDefaultStates", 1);
1350
1343
  var DefaultBlockStates = class {
1351
1344
  };
1352
1345
 
1353
1346
  // src/assets/Assets.ts
1354
- var DEFAULT_ROOT = "https://cdn.mcasset.cloud/file/minecraft-assets/1.17.1";
1347
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
1355
1348
  var DEFAULT_NAMESPACE = "minecraft";
1356
1349
  var Assets = class {
1357
1350
  /**
@@ -1374,43 +1367,170 @@ var AssetSource = class {
1374
1367
  }
1375
1368
  };
1376
1369
 
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;
1370
+ // src/util/BatchedExecutor.ts
1371
+ var BatchedExecutor = class {
1372
+ constructor(interval = 1, batch = 30) {
1373
+ this.interval = interval;
1374
+ this.batch = batch;
1375
+ this.queue = [];
1376
+ this.task = setInterval(() => this.run());
1377
+ }
1378
+ submit(task) {
1379
+ this.queue.push(task);
1380
+ }
1381
+ run() {
1382
+ for (let i = 0; i < this.batch; i++) {
1383
+ this.runNext();
1384
+ }
1385
+ }
1386
+ runNext() {
1387
+ let next = this.queue.shift();
1388
+ if (next) next();
1383
1389
  }
1384
1390
  };
1385
1391
 
1386
- // src/assets/source/HostedAssetSource.ts
1387
- var import_ts_deepmerge2 = __toESM(require_dist());
1388
- var p3 = prefix("HostedAssetSource");
1389
- var DEFAULT_OPTIONS = {
1390
- retryDefaults: true
1391
- };
1392
- var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1393
- async loadOrRetryWithDefaults(key, parser) {
1394
- const direct = await this.load(key, parser);
1395
- if (typeof direct !== "undefined") {
1396
- return direct;
1397
- }
1398
- if (key.namespace !== DEFAULT_NAMESPACE) {
1399
- console.info(p3, "Retrying", key, "with default namespace");
1400
- const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
1401
- const namespaced = await this.load(namespaceKey, parser);
1402
- if (typeof namespaced !== "undefined") {
1403
- return namespaced;
1404
- }
1405
- if (typeof key.root !== "undefined" && key.root !== DEFAULT_ROOT || typeof this.root !== "undefined" && this.root !== DEFAULT_ROOT) {
1406
- console.info(p3, "Retrying", key, "with default root+namespace");
1407
- const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, DEFAULT_ROOT);
1408
- const namespacedRooted = await this.load(namespacedRootedKey, parser);
1409
- if (typeof namespacedRooted !== "undefined") {
1410
- return namespacedRooted;
1411
- }
1412
- }
1413
- } else if (typeof key.root !== "undefined" && key.root !== DEFAULT_ROOT || typeof this.root !== "undefined" && this.root !== DEFAULT_ROOT) {
1392
+ // src/util/model.ts
1393
+ import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1394
+ function applyElementRotation(rotation, geometry) {
1395
+ const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1396
+ geometry.translate(-origin.x, -origin.y, -origin.z);
1397
+ switch (rotation.axis) {
1398
+ case "X" /* X */:
1399
+ geometry.rotateX(toRadians(rotation.angle));
1400
+ break;
1401
+ case "y" /* Y */:
1402
+ geometry.rotateY(toRadians(rotation.angle));
1403
+ break;
1404
+ case "z" /* Z */:
1405
+ geometry.rotateZ(toRadians(rotation.angle));
1406
+ break;
1407
+ }
1408
+ if (rotation.rescale) {
1409
+ if (Math.abs(rotation.angle) === 22.5) {
1410
+ const s = 1 / Math.cos(0.39269909262657166);
1411
+ geometry.scale(s, 1, s);
1412
+ } else {
1413
+ const s = 1 / Math.cos(0.7853981852531433);
1414
+ geometry.scale(s, 1, s);
1415
+ }
1416
+ }
1417
+ geometry.translate(origin.x, origin.y, origin.z);
1418
+ }
1419
+ function applyModelPartRotation(modelPart, geometry) {
1420
+ const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1421
+ geometry.translate(-origin.x, -origin.y, -origin.z);
1422
+ geometry.rotateX(toRadians(modelPart.pitch));
1423
+ geometry.rotateY(toRadians(modelPart.yaw));
1424
+ geometry.rotateZ(toRadians(modelPart.roll));
1425
+ geometry.translate(origin.x, origin.y, origin.z);
1426
+ }
1427
+ function applyGenericRotation(axis, rotation, obj) {
1428
+ switch (axis) {
1429
+ case "X" /* X */:
1430
+ obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1431
+ break;
1432
+ case "y" /* Y */:
1433
+ obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1434
+ break;
1435
+ case "z" /* Z */:
1436
+ obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1437
+ break;
1438
+ }
1439
+ }
1440
+ function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1441
+ let size = new Vector32();
1442
+ box.getSize(size);
1443
+ let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1444
+ let wireGeo = new EdgesGeometry(boxGeo);
1445
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
1446
+ let wireframe = new LineSegments(wireGeo, wireMat);
1447
+ obj.add(wireframe);
1448
+ let axes = new AxesHelper(1);
1449
+ obj.add(axes);
1450
+ }
1451
+ function addWireframeToObject(obj, color = 16777215, w = 2) {
1452
+ let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
1453
+ let wireGeo = new EdgesGeometry(boxGeo);
1454
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
1455
+ let wireframe = new LineSegments(wireGeo, wireMat);
1456
+ obj.add(wireframe);
1457
+ let axes = new AxesHelper(1);
1458
+ obj.add(axes);
1459
+ }
1460
+ function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1461
+ let wireGeo = new EdgesGeometry(geo);
1462
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
1463
+ let wireframe = new LineSegments(wireGeo, wireMat);
1464
+ mesh.add(wireframe);
1465
+ let axes = new AxesHelper(1);
1466
+ mesh.add(axes);
1467
+ }
1468
+
1469
+ // src/util/performance.ts
1470
+ function captureException(e, ...extra) {
1471
+ console.error(e, extra);
1472
+ }
1473
+ function timingStart(marker) {
1474
+ console.time(marker);
1475
+ }
1476
+ function timingEnd(marker) {
1477
+ console.timeEnd(marker);
1478
+ }
1479
+
1480
+ // src/util/three.ts
1481
+ function isObject3D(obj) {
1482
+ return obj.isObject3D;
1483
+ }
1484
+ function isMesh(obj) {
1485
+ return obj.isMesh;
1486
+ }
1487
+ function isInstancedMesh(obj) {
1488
+ return obj.isInstancedMesh;
1489
+ }
1490
+ function isPerspectiveCamera(obj) {
1491
+ return obj.isPerspectiveCamera;
1492
+ }
1493
+ function isOrthographicCamera(obj) {
1494
+ return obj.isOrthographicCamera;
1495
+ }
1496
+
1497
+ // src/nbt/NBTHelper.ts
1498
+ var NBTHelper = class {
1499
+ static async fromBuffer(buffer) {
1500
+ const prismarineNbt = await import("prismarine-nbt");
1501
+ const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1502
+ return parsed;
1503
+ }
1504
+ };
1505
+
1506
+ // src/assets/source/HostedAssetSource.ts
1507
+ var import_ts_deepmerge2 = __toESM(require_dist());
1508
+ var p3 = prefix("HostedAssetSource");
1509
+ var DEFAULT_OPTIONS = {
1510
+ retryDefaults: true
1511
+ };
1512
+ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1513
+ async loadOrRetryWithDefaults(key, parser) {
1514
+ const direct = await this.load(key, parser);
1515
+ if (typeof direct !== "undefined") {
1516
+ return direct;
1517
+ }
1518
+ if (key.namespace !== DEFAULT_NAMESPACE) {
1519
+ console.info(p3, "Retrying", key, "with default namespace");
1520
+ const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
1521
+ const namespaced = await this.load(namespaceKey, parser);
1522
+ if (typeof namespaced !== "undefined") {
1523
+ return namespaced;
1524
+ }
1525
+ if (typeof key.root !== "undefined" && key.root !== DEFAULT_ROOT || typeof this.root !== "undefined" && this.root !== DEFAULT_ROOT) {
1526
+ console.info(p3, "Retrying", key, "with default root+namespace");
1527
+ const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, DEFAULT_ROOT);
1528
+ const namespacedRooted = await this.load(namespacedRootedKey, parser);
1529
+ if (typeof namespacedRooted !== "undefined") {
1530
+ return namespacedRooted;
1531
+ }
1532
+ }
1533
+ } else if (typeof key.root !== "undefined" && key.root !== DEFAULT_ROOT || typeof this.root !== "undefined" && this.root !== DEFAULT_ROOT) {
1414
1534
  console.info(p3, "Retrying", key, "with default root");
1415
1535
  const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, DEFAULT_ROOT);
1416
1536
  const rooted = await this.load(rootKey, parser);
@@ -1649,7 +1769,6 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1649
1769
  };
1650
1770
 
1651
1771
  // src/assets/AssetLoader.ts
1652
- var import_ts_deepmerge3 = __toESM(require_dist());
1653
1772
  var p5 = prefix("AssetLoader");
1654
1773
  var _AssetLoader = class _AssetLoader {
1655
1774
  static addSource(key, source, override = true) {
@@ -1673,7 +1792,6 @@ var _AssetLoader = class _AssetLoader {
1673
1792
  return void 0;
1674
1793
  }
1675
1794
  static async getAll(key, parser) {
1676
- console.log(this._SOURCES);
1677
1795
  let promises = [];
1678
1796
  for (const source of this._SOURCES) {
1679
1797
  promises.push(source.source.get(key, parser));
@@ -1682,30 +1800,22 @@ var _AssetLoader = class _AssetLoader {
1682
1800
  return results.filter((r) => r != void 0);
1683
1801
  });
1684
1802
  }
1803
+ /** Returns the first defined result in source-priority order, without merging assets. */
1685
1804
  static async get(key, parser) {
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;
1699
- }
1805
+ const sources = [...this._SOURCES];
1806
+ for (const source of sources) {
1807
+ const result = await source.source.get(key, parser);
1808
+ if (result !== void 0) {
1809
+ return result;
1700
1810
  }
1701
- return void 0;
1702
- });
1811
+ }
1812
+ return void 0;
1703
1813
  }
1704
1814
  };
1705
1815
  _AssetLoader.ROOT = DEFAULT_ROOT;
1706
1816
  _AssetLoader._SOURCES = [];
1707
- _AssetLoader.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master"));
1708
- _AssetLoader.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT));
1817
+ _AssetLoader.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1818
+ _AssetLoader.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1709
1819
  var AssetLoader = _AssetLoader;
1710
1820
 
1711
1821
  // src/assets/ModelTextures.ts
@@ -1714,11 +1824,21 @@ var ModelTextures = class {
1714
1824
  return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
1715
1825
  }
1716
1826
  static async get(key) {
1717
- const asset = await this.preload(key);
1718
- if (asset) {
1719
- return ImageLoader.infoToCanvasData(asset);
1827
+ const keyStr = key.serialize();
1828
+ const pending = this.preload(key);
1829
+ const cached = Caching.textureAssetCache.getIfPresent(keyStr);
1830
+ try {
1831
+ const asset = await pending;
1832
+ if (asset) {
1833
+ return await ImageLoader.infoToCanvasData(asset);
1834
+ }
1835
+ return void 0;
1836
+ } catch (err) {
1837
+ if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
1838
+ Caching.textureAssetCache.invalidate(keyStr);
1839
+ }
1840
+ throw err;
1720
1841
  }
1721
- return void 0;
1722
1842
  }
1723
1843
  static async preload(key) {
1724
1844
  const keyStr = key.serialize();
@@ -2396,17 +2516,20 @@ function shutdown() {
2396
2516
  }
2397
2517
 
2398
2518
  // src/assets/Entities.ts
2399
- import { Memoize as Memoize3 } from "typescript-memoize";
2400
2519
  var Entities = class {
2401
2520
  static async getBlockEntityModels() {
2402
2521
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
2403
2522
  console.log(key);
2404
- return AssetLoader.get(key, "json" /* JSON */);
2523
+ return Caching.entityModelsCache.get(key.serialize(), () => {
2524
+ return AssetLoader.get(key, "json" /* JSON */);
2525
+ });
2405
2526
  }
2406
2527
  static async getEntityModels() {
2407
2528
  const key = AssetKey.parse("models", "minerender:entityModels");
2408
2529
  console.log(key);
2409
- return AssetLoader.get(key, "json" /* JSON */);
2530
+ return Caching.entityModelsCache.get(key.serialize(), () => {
2531
+ return AssetLoader.get(key, "json" /* JSON */);
2532
+ });
2410
2533
  }
2411
2534
  // BlockEntity names are hardcoded
2412
2535
  static async getBlockList() {
@@ -2452,12 +2575,6 @@ var Entities = class {
2452
2575
  };
2453
2576
  }
2454
2577
  };
2455
- __decorateClass([
2456
- Memoize3()
2457
- ], Entities, "getBlockEntityModels", 1);
2458
- __decorateClass([
2459
- Memoize3()
2460
- ], Entities, "getEntityModels", 1);
2461
2578
  var EntityModels = class {
2462
2579
  };
2463
2580
  var BlockEntityModels = class {
@@ -2521,7 +2638,7 @@ var MineRenderError = class _MineRenderError extends Error {
2521
2638
  };
2522
2639
 
2523
2640
  // src/renderer/SceneObject.ts
2524
- var import_ts_deepmerge4 = __toESM(require_dist());
2641
+ var import_ts_deepmerge3 = __toESM(require_dist());
2525
2642
  var p7 = prefix("SceneObject");
2526
2643
  var _SceneObject = class _SceneObject extends Object3D2 {
2527
2644
  constructor(options) {
@@ -2530,7 +2647,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2530
2647
  this.materialCallbacks = {};
2531
2648
  this._isInstanced = false;
2532
2649
  this._instanceCounter = 0;
2533
- this.options = (0, import_ts_deepmerge4.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2650
+ this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2534
2651
  console.log("SceneObject options", this.options);
2535
2652
  }
2536
2653
  set scene(scene) {
@@ -2879,7 +2996,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2879
2996
  }
2880
2997
  //</editor-fold>
2881
2998
  };
2882
- _SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, {
2999
+ _SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
2883
3000
  instanceMeshes: true,
2884
3001
  maxInstanceCount: 50,
2885
3002
  mergeMeshes: true,
@@ -2891,16 +3008,16 @@ function isSceneObject(obj) {
2891
3008
  }
2892
3009
 
2893
3010
  // src/entity/scene/EntityObject.ts
2894
- var import_ts_deepmerge5 = __toESM(require_dist());
3011
+ var import_ts_deepmerge4 = __toESM(require_dist());
2895
3012
  import { Object3D as Object3D3 } from "three";
2896
- import * as THREE2 from "three";
3013
+ import * as THREE3 from "three";
2897
3014
  var EntityObject = class extends SceneObject {
2898
3015
  constructor(entity, options) {
2899
3016
  super();
2900
3017
  this.entity = entity;
2901
3018
  this.isEntityObject = true;
2902
3019
  this.meshesCreated = false;
2903
- this.options = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3020
+ this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
2904
3021
  }
2905
3022
  async init() {
2906
3023
  this.createMeshes();
@@ -2909,8 +3026,8 @@ var EntityObject = class extends SceneObject {
2909
3026
  dispose() {
2910
3027
  super.dispose();
2911
3028
  }
2912
- async loadTextures() {
2913
- this.imageData = await ModelTextures.get(new AssetKey(
3029
+ get textureKey() {
3030
+ return new AssetKey(
2914
3031
  this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
2915
3032
  this.entity.key.path,
2916
3033
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
@@ -2918,7 +3035,10 @@ var EntityObject = class extends SceneObject {
2918
3035
  "entity",
2919
3036
  "assets",
2920
3037
  ".png"
2921
- ));
3038
+ );
3039
+ }
3040
+ async loadTextures() {
3041
+ this.imageData = await ModelTextures.get(this.textureKey);
2922
3042
  }
2923
3043
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
2924
3044
  createMeshes(force = false) {
@@ -2937,8 +3057,8 @@ var EntityObject = class extends SceneObject {
2937
3057
  const l = cube.maxZ - cube.minZ;
2938
3058
  const uv = texture.toUvArray(w, h, l);
2939
3059
  const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
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));
3060
+ cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3061
+ cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
2942
3062
  applyModelPartRotation(part, cubeGeo);
2943
3063
  const mesh = this.createMesh(partName, cubeGeo, mat);
2944
3064
  partAnchor.add(mesh);
@@ -2951,23 +3071,26 @@ var EntityObject = class extends SceneObject {
2951
3071
  this.meshesCreated = true;
2952
3072
  }
2953
3073
  async applyTextures() {
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
- }
3074
+ const assetKeyStr = this.textureKey.serialize();
3075
+ const keyStr = `entity:${assetKeyStr}`;
3076
+ let mat = Caching.materialCache.getIfPresent(keyStr);
3077
+ if (!mat) {
3078
+ const pending = this.loadTextures();
3079
+ const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3080
+ await pending;
3081
+ if (!this.imageData) return;
3082
+ const canvas = this.imageData.data.canvas;
3083
+ const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3084
+ mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3085
+ this.imageData = void 0;
3086
+ }
3087
+ this.iterateAllMeshes((mesh) => {
3088
+ mesh.material = mat;
3089
+ });
3090
+ this.notifyDirty();
2968
3091
  }
2969
3092
  };
2970
- EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3093
+ EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
2971
3094
  function isEntityObject(obj) {
2972
3095
  return obj.isEntityObject;
2973
3096
  }
@@ -3968,7 +4091,7 @@ function computeMorphedAttributes(object) {
3968
4091
  }
3969
4092
 
3970
4093
  // src/model/scene/ModelObject.ts
3971
- var import_ts_deepmerge6 = __toESM(require_dist());
4094
+ var import_ts_deepmerge5 = __toESM(require_dist());
3972
4095
  var p10 = prefix("ModelObject");
3973
4096
  var _ModelObject = class _ModelObject extends SceneObject {
3974
4097
  constructor(originalModel, options) {
@@ -3976,7 +4099,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
3976
4099
  this.originalModel = originalModel;
3977
4100
  this.isModelObject = true;
3978
4101
  this.meshesCreated = false;
3979
- this.options = (0, import_ts_deepmerge6.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4102
+ this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
3980
4103
  console.log("ModelObject options", this.options);
3981
4104
  }
3982
4105
  async init() {
@@ -4074,14 +4197,14 @@ var _ModelObject = class _ModelObject extends SceneObject {
4074
4197
  }
4075
4198
  }
4076
4199
  };
4077
- _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4200
+ _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4078
4201
  var ModelObject = _ModelObject;
4079
4202
  function isModelObject(obj) {
4080
4203
  return obj.isModelObject;
4081
4204
  }
4082
4205
 
4083
4206
  // src/model/block/scene/BlockObject.ts
4084
- var import_ts_deepmerge7 = __toESM(require_dist());
4207
+ var import_ts_deepmerge6 = __toESM(require_dist());
4085
4208
  import { Euler as Euler3, Matrix4 as Matrix46, Vector3 as Vector36 } from "three";
4086
4209
  var p11 = prefix("BlockObject");
4087
4210
  var _BlockObject = class _BlockObject extends SceneObject {
@@ -4097,7 +4220,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4097
4220
  this._instanceModel = [];
4098
4221
  this._variants = [];
4099
4222
  this._models = [];
4100
- this.options = (0, import_ts_deepmerge7.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4223
+ this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4101
4224
  }
4102
4225
  async init() {
4103
4226
  if (this.options.applyDefaultState) {
@@ -4386,7 +4509,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4386
4509
  //TODO: should override rotation + scale methods
4387
4510
  //TODO
4388
4511
  };
4389
- _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge7.default)({}, ModelObject.DEFAULT_OPTIONS, {
4512
+ _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
4390
4513
  applyDefaultState: true
4391
4514
  });
4392
4515
  var BlockObject = _BlockObject;
@@ -4436,7 +4559,7 @@ var StructureParser = class {
4436
4559
 
4437
4560
  // src/renderer/MineRenderScene.ts
4438
4561
  import { Scene as Scene2 } from "three";
4439
- var import_ts_deepmerge9 = __toESM(require_dist());
4562
+ var import_ts_deepmerge8 = __toESM(require_dist());
4440
4563
 
4441
4564
  // src/skin/SkinPart.ts
4442
4565
  var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
@@ -5167,7 +5290,7 @@ var slimSkinGeometries = {
5167
5290
  };
5168
5291
 
5169
5292
  // src/skin/scene/SkinObject.ts
5170
- var import_ts_deepmerge8 = __toESM(require_dist());
5293
+ var import_ts_deepmerge7 = __toESM(require_dist());
5171
5294
  var SkinObject = class extends SceneObject {
5172
5295
  constructor(options) {
5173
5296
  super();
@@ -5175,7 +5298,7 @@ var SkinObject = class extends SceneObject {
5175
5298
  this.legacy = false;
5176
5299
  this.skinTextureWidth = 64;
5177
5300
  this.skinTextureHeight = 64;
5178
- this.options = (0, import_ts_deepmerge8.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5301
+ this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5179
5302
  }
5180
5303
  async init() {
5181
5304
  this.createMeshes();
@@ -5286,24 +5409,54 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5286
5409
  this.stats = new SceneStats();
5287
5410
  this.instanceManager = new InstanceManager();
5288
5411
  this.dirty = true;
5289
- this.options = (0, import_ts_deepmerge9.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5412
+ this.observedObjects = /* @__PURE__ */ new Set();
5413
+ this.onObjectChange = (event) => {
5414
+ if (event.target?.parent === this) {
5415
+ this.dirty = true;
5416
+ }
5417
+ };
5418
+ this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5290
5419
  }
5291
- add(...object) {
5292
- this.dirty = true;
5293
- this.stats.objectCount += object.length;
5294
- for (let obj of object) {
5295
- if (isSceneObject(obj)) {
5296
- this.stats.sceneObjectCount++;
5420
+ add(...objects) {
5421
+ for (const object of objects) {
5422
+ this.dirty = true;
5423
+ try {
5424
+ super.add(object);
5425
+ } finally {
5426
+ if (object?.isObject3D && object !== this) {
5427
+ this.updateObjectRegistration(object, object.parent === this);
5428
+ }
5297
5429
  }
5298
- obj.addEventListener("change", (event) => {
5299
- this.dirty = true;
5300
- });
5301
5430
  }
5302
- return super.add(...object);
5431
+ return this;
5303
5432
  }
5304
- remove(...object) {
5305
- this.dirty = true;
5306
- return super.remove(...object);
5433
+ remove(...objects) {
5434
+ for (const object of objects) {
5435
+ if (!this.children.includes(object)) continue;
5436
+ this.dirty = true;
5437
+ this.updateObjectRegistration(object, false);
5438
+ try {
5439
+ super.remove(object);
5440
+ } finally {
5441
+ this.updateObjectRegistration(object, object.parent === this);
5442
+ }
5443
+ }
5444
+ return this;
5445
+ }
5446
+ updateObjectRegistration(object, attached) {
5447
+ if (this.observedObjects.has(object) === attached) return;
5448
+ if (attached) {
5449
+ this.observedObjects.add(object);
5450
+ object.addEventListener("change", this.onObjectChange);
5451
+ } else {
5452
+ this.observedObjects.delete(object);
5453
+ object.removeEventListener("change", this.onObjectChange);
5454
+ }
5455
+ const change = attached ? 1 : -1;
5456
+ this.stats.objectCount += change;
5457
+ if (isSceneObject(object)) {
5458
+ this.stats.sceneObjectCount += change;
5459
+ }
5307
5460
  }
5308
5461
  async initAndAdd(...object) {
5309
5462
  this.dirty = true;
@@ -5358,420 +5511,32 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5358
5511
  return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
5359
5512
  }
5360
5513
  };
5361
- _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {});
5514
+ _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
5362
5515
  var MineRenderScene = _MineRenderScene;
5363
5516
  function isMineRenderScene(obj) {
5364
5517
  return obj.isMineRenderScene;
5365
5518
  }
5366
5519
 
5367
5520
  // src/renderer/Renderer.ts
5368
- import { AxesHelper as AxesHelper3, GridHelper, LinearEncoding, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, Vector3 as Vector37, WebGLRenderer } from "three";
5369
- var import_ts_deepmerge10 = __toESM(require_dist());
5521
+ import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector38, WebGLRenderer } from "three";
5522
+ var import_ts_deepmerge9 = __toESM(require_dist());
5370
5523
  import Stats from "stats.js";
5371
5524
  import { EffectComposer, RenderPass } from "postprocessing";
5372
- var _Renderer = class _Renderer {
5373
- constructor(options) {
5374
- this._dirty = true;
5375
- this._animationTimer = void 0;
5376
- this._animationFrame = void 0;
5377
- this._resizeListener = void 0;
5378
- this.options = (0, import_ts_deepmerge10.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
5379
- this._animationLoop = this.animate.bind(this);
5380
- this._fpsTimer = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
5381
- this._scene = this.createScene();
5382
- this._camera = this.createCamera();
5383
- this._renderer = this.createRenderer();
5384
- this._composer = this.createComposer();
5385
- if (this.options.render.stats) {
5386
- this._stats = new Stats();
5387
- document.body.appendChild(this._stats.dom);
5388
- }
5389
- this.init();
5390
- }
5391
- //<editor-fold desc="INIT">
5392
- createScene() {
5393
- return new MineRenderScene();
5394
- }
5395
- createCamera() {
5396
- switch (this.options.camera.type) {
5397
- case "perspective":
5398
- default:
5399
- return new PerspectiveCamera(
5400
- this.options.camera.perspective.fov,
5401
- this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
5402
- this.options.camera.near,
5403
- this.options.camera.far
5404
- );
5405
- case "orthographic":
5406
- return new OrthographicCamera(
5407
- this.options.camera.orthographic.left ?? this.viewWidth / -2,
5408
- this.options.camera.orthographic.right ?? this.viewWidth / 2,
5409
- this.options.camera.orthographic.top ?? this.viewHeight / 2,
5410
- this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
5411
- this.options.camera.near,
5412
- this.options.camera.far
5413
- );
5414
- }
5415
- }
5416
- createRenderer() {
5417
- const renderer = new WebGLRenderer({
5418
- antialias: this.options.render.antialias,
5419
- alpha: true,
5420
- powerPreference: "high-performance",
5421
- depth: true
5422
- });
5423
- renderer.setClearColor(0, 0);
5424
- renderer.shadowMap.enabled = true;
5425
- renderer.shadowMap.type = PCFSoftShadowMap;
5426
- renderer.outputEncoding = LinearEncoding;
5427
- renderer.setSize(this.viewWidth, this.viewHeight);
5428
- return renderer;
5429
- }
5430
- createComposer() {
5431
- const composer = new EffectComposer(this.renderer);
5432
- if (!this.options.composer.enabled) return composer;
5433
- composer.setSize(this.viewWidth, this.viewHeight);
5434
- composer.addPass(new RenderPass(this.scene, this.camera));
5435
- return composer;
5436
- }
5437
- //</editor-fold>
5438
- init() {
5439
- if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
5440
- window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
5441
- }
5442
- if (this.options.debug.grid) {
5443
- const gridHelper = new GridHelper(128, 16);
5444
- this.scene.add(gridHelper);
5445
- const gridHelper2 = new GridHelper(128, 16);
5446
- gridHelper2.rotation.x = 90 * (Math.PI / 180);
5447
- this.scene.add(gridHelper2);
5448
- const gridHelper3 = new GridHelper(128, 16);
5449
- gridHelper3.rotation.z = 90 * (Math.PI / 180);
5450
- this.scene.add(gridHelper3);
5451
- }
5452
- if (this.options.debug.axes) {
5453
- const axesHelper = new AxesHelper3(64);
5454
- this.scene.add(axesHelper);
5455
- }
5456
- if (this.options.camera.position) {
5457
- if (isVector3(this.options.camera.position)) {
5458
- this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
5459
- } else if (isTripleArray(this.options.camera.position)) {
5460
- this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
5461
- }
5462
- }
5463
- if (this.options.camera.lookingAt) {
5464
- if (isVector3(this.options.camera.lookingAt)) {
5465
- this.camera.lookAt(this.options.camera.lookingAt);
5466
- } else if (isTripleArray(this.options.camera.lookingAt)) {
5467
- this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
5468
- }
5469
- }
5470
- if (this.options.render.autoResize) {
5471
- this._resizeListener = () => {
5472
- this.resize(this.viewWidth, this.viewHeight);
5473
- };
5474
- window.addEventListener("resize", this._resizeListener);
5475
- }
5476
- }
5477
- get element() {
5478
- return this._element;
5479
- }
5480
- appendTo(element) {
5481
- this._element = element;
5482
- this._element.appendChild(this.renderer.domElement);
5483
- if (this.viewWidth == 0) {
5484
- console.warn("0 element width");
5485
- }
5486
- if (this.viewHeight == 0) {
5487
- console.warn("0 element height");
5488
- }
5489
- this.resize(this.viewWidth, this.viewHeight);
5490
- }
5491
- /**
5492
- * Register an EventDispatcher which may update the scene or renderer in order to redraw the scene
5493
- */
5494
- registerEventDispatcher(dispatcher, changeEvent2 = "change") {
5495
- dispatcher.addEventListener(changeEvent2, (event) => {
5496
- this._dirty = true;
5497
- });
5498
- }
5499
- resize(width, height) {
5500
- if (isPerspectiveCamera(this.camera)) {
5501
- this.camera.aspect = width / height;
5502
- this.camera.updateProjectionMatrix();
5503
- } else if (isOrthographicCamera(this.camera)) {
5504
- this.camera.left = width / -2;
5505
- this.camera.right = width / 2;
5506
- this.camera.top = height / 2;
5507
- this.camera.bottom = height / -2;
5508
- this.camera.updateProjectionMatrix();
5509
- }
5510
- this.renderer.setSize(width, height);
5511
- this.composer.setSize(width, height);
5512
- }
5513
- //<editor-fold desc="RENDER">
5514
- get dirty() {
5515
- return this._dirty || this.scene.dirty;
5516
- }
5517
- set dirty(dirty) {
5518
- this._dirty = dirty;
5519
- this.scene.dirty = dirty;
5520
- }
5521
- start() {
5522
- stop();
5523
- this.renderer.setAnimationLoop(this._animationLoop);
5524
- }
5525
- stop() {
5526
- this.renderer.setAnimationLoop(null);
5527
- if (this._animationTimer)
5528
- clearTimeout(this._animationTimer);
5529
- this._animationTimer = void 0;
5530
- if (this._animationFrame)
5531
- cancelAnimationFrame(this._animationFrame);
5532
- this._animationFrame = void 0;
5533
- }
5534
- animate(t) {
5535
- if (this._stats) {
5536
- this._stats.begin();
5537
- }
5538
- if (this.dirty || this.options.render.renderAlways) {
5539
- if (this.options.composer.enabled) {
5540
- this.composer.render();
5541
- } else {
5542
- this.renderer.render(this.scene, this.camera);
5543
- }
5544
- }
5545
- this.dirty = false;
5546
- if (this._stats) {
5547
- this._stats.end();
5548
- }
5549
- }
5550
- //</editor-fold>
5551
- toImage() {
5552
- return this.renderer.domElement.toDataURL();
5553
- }
5554
- ///
5555
- get attachedToBody() {
5556
- return this.element === document.body;
5557
- }
5558
- get viewWidth() {
5559
- return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
5560
- }
5561
- get viewHeight() {
5562
- return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
5563
- }
5564
- get scene() {
5565
- return this._scene;
5566
- }
5567
- get camera() {
5568
- return this._camera;
5569
- }
5570
- get renderer() {
5571
- return this._renderer;
5572
- }
5573
- get composer() {
5574
- return this._composer;
5575
- }
5576
- ///
5577
- };
5578
- _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge10.default)({}, {
5579
- camera: {
5580
- type: "perspective",
5581
- near: 1,
5582
- far: 5e3,
5583
- perspective: {
5584
- aspect: void 0,
5585
- fov: 50
5586
- },
5587
- orthographic: {
5588
- left: void 0,
5589
- right: void 0,
5590
- top: void 0,
5591
- bottom: void 0
5592
- },
5593
- position: new Vector37(50, 50, 50),
5594
- lookingAt: new Vector37(0, 0, 0)
5595
- },
5596
- render: {
5597
- fpsLimit: 60,
5598
- stats: false,
5599
- antialias: true,
5600
- shade: true,
5601
- autoResize: true,
5602
- renderAlways: false
5603
- },
5604
- composer: {
5605
- enabled: true
5606
- },
5607
- debug: {
5608
- grid: false,
5609
- axes: false
5610
- }
5611
- });
5612
- var Renderer = _Renderer;
5613
-
5614
- // src/skin/Skins.ts
5615
- var Skins = class {
5616
- //<editor-fold desc="Skins">
5617
- static async fromUuidOrUsername(uuidOrUsername) {
5618
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5619
- return this.fromUuid(uuidOrUsername);
5620
- }
5621
- return this.fromUsername(uuidOrUsername);
5622
- }
5623
- static async fromUuid(uuid) {
5624
- return this.getSkinProxySkinUrl(uuid);
5625
- }
5626
- static async fromUsername(username) {
5627
- return this.usernameToUuid(username).then((uuid) => {
5628
- if (uuid) {
5629
- return this.fromUuid(uuid);
5630
- }
5631
- return void 0;
5632
- });
5633
- }
5634
- static async fromMineSkin(mineskinId) {
5635
- return this.getMineSkin(mineskinId).then((mineskin) => {
5636
- if (mineskin) {
5637
- return mineskin["data"]["texture"]["value"]["urls"]["skins"];
5638
- }
5639
- return void 0;
5640
- });
5641
- }
5642
- //</editor-fold>
5643
- //<editor-fold desc="Capes">
5644
- static async capeFromUuidOrUsername(uuidOrUsername) {
5645
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5646
- return this.capeFromUuid(uuidOrUsername);
5647
- }
5648
- return this.capeFromUsername(uuidOrUsername);
5649
- }
5650
- static async capeFromUuid(uuid) {
5651
- return this.getSkinProxyCapeUrl(uuid);
5652
- }
5653
- static async capeFromUsername(username) {
5654
- return this.usernameToUuid(username).then((uuid) => {
5655
- if (uuid) {
5656
- return this.capeFromUuid(uuid);
5657
- }
5658
- return void 0;
5659
- });
5660
- }
5661
- static async capeFromCapesDev(uuid, capeType = "minecraft") {
5662
- return this.getCapesDev(uuid, capeType).then((cape) => {
5663
- if (cape) {
5664
- return cape?.stillImageUrl;
5665
- }
5666
- return void 0;
5667
- });
5668
- }
5669
- //</editor-fold>
5670
- //<editor-fold desc="Helpers">
5671
- static async usernameToUuid(username) {
5672
- return this.usernameToUuidSkinProxy(username);
5673
- }
5674
- static async usernameToUuidSkinProxy(username) {
5675
- return Requests.genericRequest({
5676
- baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
5677
- url: "/uuid/" + username
5678
- }).then((res) => {
5679
- if (res.status === 200) {
5680
- return res.data["id"];
5681
- }
5682
- return void 0;
5683
- }).catch((err) => {
5684
- console.warn(err);
5685
- return void 0;
5686
- });
5687
- }
5688
- static async usernameToUuidMineTools(username) {
5689
- return Requests.genericRequest({
5690
- baseURL: "https://api.minetools.eu",
5691
- url: "/uuid/" + username
5692
- }).then((res) => {
5693
- if (res.status === 200) {
5694
- return res.data["id"];
5695
- }
5696
- return void 0;
5697
- }).catch((err) => {
5698
- console.warn(err);
5699
- return void 0;
5700
- });
5701
- }
5702
- static async getProfileFromMinetools(uuid) {
5703
- return Requests.genericRequest({
5704
- baseURL: "https://api.minetools.eu",
5705
- url: "/profile/" + uuid
5706
- }).then((res) => {
5707
- if (res.status === 200) {
5708
- return res.data;
5709
- }
5710
- });
5711
- }
5712
- static async getMineSkin(mineskinId) {
5713
- return Requests.genericRequest({
5714
- baseURL: "https://api.mineskin.org",
5715
- url: "/get/uuid/" + mineskinId
5716
- }).then((res) => {
5717
- if (res.status === 200) {
5718
- return res.data;
5719
- }
5720
- return void 0;
5721
- }).catch((err) => {
5722
- console.warn(err);
5723
- return void 0;
5724
- });
5725
- }
5726
- static async getCapesDev(uuid, type = "all") {
5727
- return Requests.genericRequest({
5728
- baseURL: "https://api.capes.dev",
5729
- url: "/load/" + uuid + "/" + type
5730
- }).then((res) => {
5731
- if (res.status === 200) {
5732
- return res.data;
5733
- }
5734
- return void 0;
5735
- }).catch((err) => {
5736
- console.warn(err);
5737
- return void 0;
5738
- });
5739
- }
5740
- static getCrafatarSkinUrl(uuid) {
5741
- return "https://crafatar.com/skins/" + uuid;
5742
- }
5743
- static getCrafatarCapeUrl(uuid) {
5744
- return "https://crafatar.com/capes/" + uuid;
5745
- }
5746
- static getMcHeadsSkinUrl(uuid) {
5747
- return "https://mc-heads.net/skin/" + uuid;
5748
- }
5749
- static getMineSkinPlayerSkinUrl(uuid) {
5750
- return "https://mineskin.org/skin/player/" + uuid;
5751
- }
5752
- static getSkinProxySkinUrl(uuid) {
5753
- return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
5754
- }
5755
- static getSkinProxyCapeUrl(uuid) {
5756
- return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
5757
- }
5758
- //</editor-fold>
5759
- };
5760
5525
 
5761
5526
  // src/three/OrbitControls.js
5762
5527
  import {
5763
- EventDispatcher as EventDispatcher2,
5528
+ EventDispatcher,
5764
5529
  MOUSE,
5765
5530
  Quaternion as Quaternion3,
5766
5531
  Spherical,
5767
5532
  TOUCH,
5768
5533
  Vector2 as Vector23,
5769
- Vector3 as Vector38
5534
+ Vector3 as Vector37
5770
5535
  } from "three";
5771
5536
  var _changeEvent = { type: "change" };
5772
5537
  var _startEvent = { type: "start" };
5773
5538
  var _endEvent = { type: "end" };
5774
- var OrbitControls = class extends EventDispatcher2 {
5539
+ var OrbitControls = class extends EventDispatcher {
5775
5540
  constructor(object, domElement) {
5776
5541
  super();
5777
5542
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
@@ -5780,7 +5545,7 @@ var OrbitControls = class extends EventDispatcher2 {
5780
5545
  this.domElement = domElement;
5781
5546
  this.domElement.style.touchAction = "none";
5782
5547
  this.enabled = true;
5783
- this.target = new Vector38();
5548
+ this.target = new Vector37();
5784
5549
  this.minDistance = 0;
5785
5550
  this.maxDistance = Infinity;
5786
5551
  this.minZoom = 0;
@@ -5832,10 +5597,10 @@ var OrbitControls = class extends EventDispatcher2 {
5832
5597
  state = STATE.NONE;
5833
5598
  };
5834
5599
  this.update = function() {
5835
- const offset = new Vector38();
5836
- const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
5600
+ const offset = new Vector37();
5601
+ const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector37(0, 1, 0));
5837
5602
  const quatInverse = quat.clone().invert();
5838
- const lastPosition = new Vector38();
5603
+ const lastPosition = new Vector37();
5839
5604
  const lastQuaternion = new Quaternion3();
5840
5605
  const twoPI = 2 * Math.PI;
5841
5606
  return function update() {
@@ -5925,7 +5690,7 @@ var OrbitControls = class extends EventDispatcher2 {
5925
5690
  const spherical = new Spherical();
5926
5691
  const sphericalDelta = new Spherical();
5927
5692
  let scale = 1;
5928
- const panOffset = new Vector38();
5693
+ const panOffset = new Vector37();
5929
5694
  let zoomChanged = false;
5930
5695
  const rotateStart = new Vector23();
5931
5696
  const rotateEnd = new Vector23();
@@ -5951,7 +5716,7 @@ var OrbitControls = class extends EventDispatcher2 {
5951
5716
  sphericalDelta.phi -= angle;
5952
5717
  }
5953
5718
  const panLeft = function() {
5954
- const v = new Vector38();
5719
+ const v = new Vector37();
5955
5720
  return function panLeft2(distance, objectMatrix) {
5956
5721
  v.setFromMatrixColumn(objectMatrix, 0);
5957
5722
  v.multiplyScalar(-distance);
@@ -5959,7 +5724,7 @@ var OrbitControls = class extends EventDispatcher2 {
5959
5724
  };
5960
5725
  }();
5961
5726
  const panUp = function() {
5962
- const v = new Vector38();
5727
+ const v = new Vector37();
5963
5728
  return function panUp2(distance, objectMatrix) {
5964
5729
  if (scope.screenSpacePanning === true) {
5965
5730
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -5972,7 +5737,7 @@ var OrbitControls = class extends EventDispatcher2 {
5972
5737
  };
5973
5738
  }();
5974
5739
  const pan = function() {
5975
- const offset = new Vector38();
5740
+ const offset = new Vector37();
5976
5741
  return function pan2(deltaX, deltaY) {
5977
5742
  const element = scope.domElement;
5978
5743
  if (scope.object.isPerspectiveCamera) {
@@ -5999,413 +5764,895 @@ var OrbitControls = class extends EventDispatcher2 {
5999
5764
  scope.object.updateProjectionMatrix();
6000
5765
  zoomChanged = true;
6001
5766
  } else {
6002
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6003
- scope.enableZoom = false;
5767
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5768
+ scope.enableZoom = false;
5769
+ }
5770
+ }
5771
+ function dollyIn(dollyScale) {
5772
+ if (scope.object.isPerspectiveCamera) {
5773
+ scale *= dollyScale;
5774
+ } else if (scope.object.isOrthographicCamera) {
5775
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
5776
+ scope.object.updateProjectionMatrix();
5777
+ zoomChanged = true;
5778
+ } else {
5779
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5780
+ scope.enableZoom = false;
5781
+ }
5782
+ }
5783
+ function handleMouseDownRotate(event) {
5784
+ rotateStart.set(event.clientX, event.clientY);
5785
+ }
5786
+ function handleMouseDownDolly(event) {
5787
+ dollyStart.set(event.clientX, event.clientY);
5788
+ }
5789
+ function handleMouseDownPan(event) {
5790
+ panStart.set(event.clientX, event.clientY);
5791
+ }
5792
+ function handleMouseMoveRotate(event) {
5793
+ rotateEnd.set(event.clientX, event.clientY);
5794
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5795
+ const element = scope.domElement;
5796
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5797
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5798
+ rotateStart.copy(rotateEnd);
5799
+ scope.update();
5800
+ }
5801
+ function handleMouseMoveDolly(event) {
5802
+ dollyEnd.set(event.clientX, event.clientY);
5803
+ dollyDelta.subVectors(dollyEnd, dollyStart);
5804
+ if (dollyDelta.y > 0) {
5805
+ dollyOut(getZoomScale());
5806
+ } else if (dollyDelta.y < 0) {
5807
+ dollyIn(getZoomScale());
5808
+ }
5809
+ dollyStart.copy(dollyEnd);
5810
+ scope.update();
5811
+ }
5812
+ function handleMouseMovePan(event) {
5813
+ panEnd.set(event.clientX, event.clientY);
5814
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5815
+ pan(panDelta.x, panDelta.y);
5816
+ panStart.copy(panEnd);
5817
+ scope.update();
5818
+ }
5819
+ function handleMouseUp() {
5820
+ }
5821
+ function handleMouseWheel(event) {
5822
+ if (event.deltaY < 0) {
5823
+ dollyIn(getZoomScale());
5824
+ } else if (event.deltaY > 0) {
5825
+ dollyOut(getZoomScale());
5826
+ }
5827
+ scope.update();
5828
+ }
5829
+ function handleKeyDown(event) {
5830
+ let needsUpdate = false;
5831
+ switch (event.code) {
5832
+ case scope.keys.UP:
5833
+ pan(0, scope.keyPanSpeed);
5834
+ needsUpdate = true;
5835
+ break;
5836
+ case scope.keys.BOTTOM:
5837
+ pan(0, -scope.keyPanSpeed);
5838
+ needsUpdate = true;
5839
+ break;
5840
+ case scope.keys.LEFT:
5841
+ pan(scope.keyPanSpeed, 0);
5842
+ needsUpdate = true;
5843
+ break;
5844
+ case scope.keys.RIGHT:
5845
+ pan(-scope.keyPanSpeed, 0);
5846
+ needsUpdate = true;
5847
+ break;
5848
+ }
5849
+ if (needsUpdate) {
5850
+ event.preventDefault();
5851
+ scope.update();
5852
+ }
5853
+ }
5854
+ function handleTouchStartRotate() {
5855
+ if (pointers.length === 1) {
5856
+ rotateStart.set(pointers[0].pageX, pointers[0].pageY);
5857
+ } else {
5858
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5859
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5860
+ rotateStart.set(x, y);
6004
5861
  }
6005
5862
  }
6006
- function dollyIn(dollyScale) {
6007
- if (scope.object.isPerspectiveCamera) {
6008
- scale *= dollyScale;
6009
- } else if (scope.object.isOrthographicCamera) {
6010
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
6011
- scope.object.updateProjectionMatrix();
6012
- zoomChanged = true;
5863
+ function handleTouchStartPan() {
5864
+ if (pointers.length === 1) {
5865
+ panStart.set(pointers[0].pageX, pointers[0].pageY);
6013
5866
  } else {
6014
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6015
- scope.enableZoom = false;
5867
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5868
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5869
+ panStart.set(x, y);
6016
5870
  }
6017
5871
  }
6018
- function handleMouseDownRotate(event) {
6019
- rotateStart.set(event.clientX, event.clientY);
5872
+ function handleTouchStartDolly() {
5873
+ const dx = pointers[0].pageX - pointers[1].pageX;
5874
+ const dy = pointers[0].pageY - pointers[1].pageY;
5875
+ const distance = Math.sqrt(dx * dx + dy * dy);
5876
+ dollyStart.set(0, distance);
6020
5877
  }
6021
- function handleMouseDownDolly(event) {
6022
- dollyStart.set(event.clientX, event.clientY);
5878
+ function handleTouchStartDollyPan() {
5879
+ if (scope.enableZoom) handleTouchStartDolly();
5880
+ if (scope.enablePan) handleTouchStartPan();
6023
5881
  }
6024
- function handleMouseDownPan(event) {
6025
- panStart.set(event.clientX, event.clientY);
5882
+ function handleTouchStartDollyRotate() {
5883
+ if (scope.enableZoom) handleTouchStartDolly();
5884
+ if (scope.enableRotate) handleTouchStartRotate();
6026
5885
  }
6027
- function handleMouseMoveRotate(event) {
6028
- rotateEnd.set(event.clientX, event.clientY);
5886
+ function handleTouchMoveRotate(event) {
5887
+ if (pointers.length == 1) {
5888
+ rotateEnd.set(event.pageX, event.pageY);
5889
+ } else {
5890
+ const position = getSecondPointerPosition(event);
5891
+ const x = 0.5 * (event.pageX + position.x);
5892
+ const y = 0.5 * (event.pageY + position.y);
5893
+ rotateEnd.set(x, y);
5894
+ }
6029
5895
  rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6030
5896
  const element = scope.domElement;
6031
5897
  rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6032
5898
  rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6033
5899
  rotateStart.copy(rotateEnd);
6034
- scope.update();
6035
5900
  }
6036
- function handleMouseMoveDolly(event) {
6037
- dollyEnd.set(event.clientX, event.clientY);
6038
- dollyDelta.subVectors(dollyEnd, dollyStart);
6039
- if (dollyDelta.y > 0) {
6040
- dollyOut(getZoomScale());
6041
- } else if (dollyDelta.y < 0) {
6042
- dollyIn(getZoomScale());
5901
+ function handleTouchMovePan(event) {
5902
+ if (pointers.length === 1) {
5903
+ panEnd.set(event.pageX, event.pageY);
5904
+ } else {
5905
+ const position = getSecondPointerPosition(event);
5906
+ const x = 0.5 * (event.pageX + position.x);
5907
+ const y = 0.5 * (event.pageY + position.y);
5908
+ panEnd.set(x, y);
5909
+ }
5910
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5911
+ pan(panDelta.x, panDelta.y);
5912
+ panStart.copy(panEnd);
5913
+ }
5914
+ function handleTouchMoveDolly(event) {
5915
+ const position = getSecondPointerPosition(event);
5916
+ const dx = event.pageX - position.x;
5917
+ const dy = event.pageY - position.y;
5918
+ const distance = Math.sqrt(dx * dx + dy * dy);
5919
+ dollyEnd.set(0, distance);
5920
+ dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
5921
+ dollyOut(dollyDelta.y);
5922
+ dollyStart.copy(dollyEnd);
5923
+ }
5924
+ function handleTouchMoveDollyPan(event) {
5925
+ if (scope.enableZoom) handleTouchMoveDolly(event);
5926
+ if (scope.enablePan) handleTouchMovePan(event);
5927
+ }
5928
+ function handleTouchMoveDollyRotate(event) {
5929
+ if (scope.enableZoom) handleTouchMoveDolly(event);
5930
+ if (scope.enableRotate) handleTouchMoveRotate(event);
5931
+ }
5932
+ function handleTouchEnd() {
5933
+ }
5934
+ function onPointerDown(event) {
5935
+ if (scope.enabled === false) return;
5936
+ if (pointers.length === 0) {
5937
+ scope.domElement.setPointerCapture(event.pointerId);
5938
+ scope.domElement.addEventListener("pointermove", onPointerMove);
5939
+ scope.domElement.addEventListener("pointerup", onPointerUp);
5940
+ }
5941
+ addPointer(event);
5942
+ if (event.pointerType === "touch") {
5943
+ onTouchStart(event);
5944
+ } else {
5945
+ onMouseDown(event);
5946
+ }
5947
+ }
5948
+ function onPointerMove(event) {
5949
+ if (scope.enabled === false) return;
5950
+ if (event.pointerType === "touch") {
5951
+ onTouchMove(event);
5952
+ } else {
5953
+ onMouseMove(event);
5954
+ }
5955
+ }
5956
+ function onPointerUp(event) {
5957
+ if (scope.enabled === false) return;
5958
+ if (event.pointerType === "touch") {
5959
+ onTouchEnd();
5960
+ } else {
5961
+ onMouseUp(event);
5962
+ }
5963
+ removePointer(event);
5964
+ if (pointers.length === 0) {
5965
+ scope.domElement.releasePointerCapture(event.pointerId);
5966
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
5967
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
5968
+ }
5969
+ }
5970
+ function onPointerCancel(event) {
5971
+ removePointer(event);
5972
+ }
5973
+ function onMouseDown(event) {
5974
+ let mouseAction;
5975
+ switch (event.button) {
5976
+ case 0:
5977
+ mouseAction = scope.mouseButtons.LEFT;
5978
+ break;
5979
+ case 1:
5980
+ mouseAction = scope.mouseButtons.MIDDLE;
5981
+ break;
5982
+ case 2:
5983
+ mouseAction = scope.mouseButtons.RIGHT;
5984
+ break;
5985
+ default:
5986
+ mouseAction = -1;
5987
+ }
5988
+ switch (mouseAction) {
5989
+ case MOUSE.DOLLY:
5990
+ if (scope.enableZoom === false) return;
5991
+ handleMouseDownDolly(event);
5992
+ state = STATE.DOLLY;
5993
+ break;
5994
+ case MOUSE.ROTATE:
5995
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
5996
+ if (scope.enablePan === false) return;
5997
+ handleMouseDownPan(event);
5998
+ state = STATE.PAN;
5999
+ } else {
6000
+ if (scope.enableRotate === false) return;
6001
+ handleMouseDownRotate(event);
6002
+ state = STATE.ROTATE;
6003
+ }
6004
+ break;
6005
+ case MOUSE.PAN:
6006
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6007
+ if (scope.enableRotate === false) return;
6008
+ handleMouseDownRotate(event);
6009
+ state = STATE.ROTATE;
6010
+ } else {
6011
+ if (scope.enablePan === false) return;
6012
+ handleMouseDownPan(event);
6013
+ state = STATE.PAN;
6014
+ }
6015
+ break;
6016
+ default:
6017
+ state = STATE.NONE;
6018
+ }
6019
+ if (state !== STATE.NONE) {
6020
+ scope.dispatchEvent(_startEvent);
6021
+ }
6022
+ }
6023
+ function onMouseMove(event) {
6024
+ if (scope.enabled === false) return;
6025
+ switch (state) {
6026
+ case STATE.ROTATE:
6027
+ if (scope.enableRotate === false) return;
6028
+ handleMouseMoveRotate(event);
6029
+ break;
6030
+ case STATE.DOLLY:
6031
+ if (scope.enableZoom === false) return;
6032
+ handleMouseMoveDolly(event);
6033
+ break;
6034
+ case STATE.PAN:
6035
+ if (scope.enablePan === false) return;
6036
+ handleMouseMovePan(event);
6037
+ break;
6038
+ }
6039
+ }
6040
+ function onMouseUp(event) {
6041
+ handleMouseUp(event);
6042
+ scope.dispatchEvent(_endEvent);
6043
+ state = STATE.NONE;
6044
+ }
6045
+ function onMouseWheel(event) {
6046
+ if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6047
+ event.preventDefault();
6048
+ scope.dispatchEvent(_startEvent);
6049
+ handleMouseWheel(event);
6050
+ scope.dispatchEvent(_endEvent);
6051
+ }
6052
+ function onKeyDown(event) {
6053
+ if (scope.enabled === false || scope.enablePan === false) return;
6054
+ handleKeyDown(event);
6055
+ }
6056
+ function onTouchStart(event) {
6057
+ trackPointer(event);
6058
+ switch (pointers.length) {
6059
+ case 1:
6060
+ switch (scope.touches.ONE) {
6061
+ case TOUCH.ROTATE:
6062
+ if (scope.enableRotate === false) return;
6063
+ handleTouchStartRotate();
6064
+ state = STATE.TOUCH_ROTATE;
6065
+ break;
6066
+ case TOUCH.PAN:
6067
+ if (scope.enablePan === false) return;
6068
+ handleTouchStartPan();
6069
+ state = STATE.TOUCH_PAN;
6070
+ break;
6071
+ default:
6072
+ state = STATE.NONE;
6073
+ }
6074
+ break;
6075
+ case 2:
6076
+ switch (scope.touches.TWO) {
6077
+ case TOUCH.DOLLY_PAN:
6078
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6079
+ handleTouchStartDollyPan();
6080
+ state = STATE.TOUCH_DOLLY_PAN;
6081
+ break;
6082
+ case TOUCH.DOLLY_ROTATE:
6083
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6084
+ handleTouchStartDollyRotate();
6085
+ state = STATE.TOUCH_DOLLY_ROTATE;
6086
+ break;
6087
+ default:
6088
+ state = STATE.NONE;
6089
+ }
6090
+ break;
6091
+ default:
6092
+ state = STATE.NONE;
6043
6093
  }
6044
- dollyStart.copy(dollyEnd);
6045
- scope.update();
6046
- }
6047
- function handleMouseMovePan(event) {
6048
- panEnd.set(event.clientX, event.clientY);
6049
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6050
- pan(panDelta.x, panDelta.y);
6051
- panStart.copy(panEnd);
6052
- scope.update();
6053
- }
6054
- function handleMouseUp() {
6055
- }
6056
- function handleMouseWheel(event) {
6057
- if (event.deltaY < 0) {
6058
- dollyIn(getZoomScale());
6059
- } else if (event.deltaY > 0) {
6060
- dollyOut(getZoomScale());
6094
+ if (state !== STATE.NONE) {
6095
+ scope.dispatchEvent(_startEvent);
6061
6096
  }
6062
- scope.update();
6063
6097
  }
6064
- function handleKeyDown(event) {
6065
- let needsUpdate = false;
6066
- switch (event.code) {
6067
- case scope.keys.UP:
6068
- pan(0, scope.keyPanSpeed);
6069
- needsUpdate = true;
6098
+ function onTouchMove(event) {
6099
+ trackPointer(event);
6100
+ switch (state) {
6101
+ case STATE.TOUCH_ROTATE:
6102
+ if (scope.enableRotate === false) return;
6103
+ handleTouchMoveRotate(event);
6104
+ scope.update();
6070
6105
  break;
6071
- case scope.keys.BOTTOM:
6072
- pan(0, -scope.keyPanSpeed);
6073
- needsUpdate = true;
6106
+ case STATE.TOUCH_PAN:
6107
+ if (scope.enablePan === false) return;
6108
+ handleTouchMovePan(event);
6109
+ scope.update();
6074
6110
  break;
6075
- case scope.keys.LEFT:
6076
- pan(scope.keyPanSpeed, 0);
6077
- needsUpdate = true;
6111
+ case STATE.TOUCH_DOLLY_PAN:
6112
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6113
+ handleTouchMoveDollyPan(event);
6114
+ scope.update();
6078
6115
  break;
6079
- case scope.keys.RIGHT:
6080
- pan(-scope.keyPanSpeed, 0);
6081
- needsUpdate = true;
6116
+ case STATE.TOUCH_DOLLY_ROTATE:
6117
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6118
+ handleTouchMoveDollyRotate(event);
6119
+ scope.update();
6082
6120
  break;
6083
- }
6084
- if (needsUpdate) {
6085
- event.preventDefault();
6086
- scope.update();
6121
+ default:
6122
+ state = STATE.NONE;
6087
6123
  }
6088
6124
  }
6089
- function handleTouchStartRotate() {
6090
- if (pointers.length === 1) {
6091
- rotateStart.set(pointers[0].pageX, pointers[0].pageY);
6092
- } else {
6093
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6094
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6095
- rotateStart.set(x, y);
6125
+ function onTouchEnd(event) {
6126
+ handleTouchEnd(event);
6127
+ scope.dispatchEvent(_endEvent);
6128
+ state = STATE.NONE;
6129
+ }
6130
+ function onContextMenu(event) {
6131
+ if (scope.enabled === false) return;
6132
+ event.preventDefault();
6133
+ }
6134
+ function addPointer(event) {
6135
+ pointers.push(event);
6136
+ }
6137
+ function removePointer(event) {
6138
+ delete pointerPositions[event.pointerId];
6139
+ for (let i = 0; i < pointers.length; i++) {
6140
+ if (pointers[i].pointerId == event.pointerId) {
6141
+ pointers.splice(i, 1);
6142
+ return;
6143
+ }
6096
6144
  }
6097
6145
  }
6098
- function handleTouchStartPan() {
6099
- if (pointers.length === 1) {
6100
- panStart.set(pointers[0].pageX, pointers[0].pageY);
6101
- } else {
6102
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6103
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6104
- panStart.set(x, y);
6146
+ function trackPointer(event) {
6147
+ let position = pointerPositions[event.pointerId];
6148
+ if (position === void 0) {
6149
+ position = new Vector23();
6150
+ pointerPositions[event.pointerId] = position;
6105
6151
  }
6152
+ position.set(event.pageX, event.pageY);
6106
6153
  }
6107
- function handleTouchStartDolly() {
6108
- const dx = pointers[0].pageX - pointers[1].pageX;
6109
- const dy = pointers[0].pageY - pointers[1].pageY;
6110
- const distance = Math.sqrt(dx * dx + dy * dy);
6111
- dollyStart.set(0, distance);
6154
+ function getSecondPointerPosition(event) {
6155
+ const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6156
+ return pointerPositions[pointer.pointerId];
6112
6157
  }
6113
- function handleTouchStartDollyPan() {
6114
- if (scope.enableZoom) handleTouchStartDolly();
6115
- if (scope.enablePan) handleTouchStartPan();
6158
+ scope.domElement.addEventListener("contextmenu", onContextMenu);
6159
+ scope.domElement.addEventListener("pointerdown", onPointerDown);
6160
+ scope.domElement.addEventListener("pointercancel", onPointerCancel);
6161
+ scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6162
+ this.update();
6163
+ }
6164
+ };
6165
+ var MapControls = class extends OrbitControls {
6166
+ constructor(object, domElement) {
6167
+ super(object, domElement);
6168
+ this.screenSpacePanning = false;
6169
+ this.mouseButtons.LEFT = MOUSE.PAN;
6170
+ this.mouseButtons.RIGHT = MOUSE.ROTATE;
6171
+ this.touches.ONE = TOUCH.PAN;
6172
+ this.touches.TWO = TOUCH.DOLLY_ROTATE;
6173
+ }
6174
+ };
6175
+
6176
+ // src/renderer/Renderer.ts
6177
+ var _Renderer = class _Renderer {
6178
+ constructor(options) {
6179
+ this._dirty = true;
6180
+ this._resizeListener = void 0;
6181
+ this._disposed = false;
6182
+ this._debugHelpers = [];
6183
+ this._eventDispatchers = /* @__PURE__ */ new Map();
6184
+ this._changeListener = () => {
6185
+ this._dirty = true;
6186
+ };
6187
+ this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
6188
+ this._animationLoop = this.animate.bind(this);
6189
+ this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
6190
+ this._scene = this.createScene();
6191
+ this._camera = this.createCamera();
6192
+ this._renderer = this.createRenderer();
6193
+ this._composer = this.createComposer();
6194
+ if (this.options.render.stats) {
6195
+ this._stats = new Stats();
6196
+ document.body.appendChild(this._stats.dom);
6116
6197
  }
6117
- function handleTouchStartDollyRotate() {
6118
- if (scope.enableZoom) handleTouchStartDolly();
6119
- if (scope.enableRotate) handleTouchStartRotate();
6198
+ this.init();
6199
+ this._controls = this.createControls();
6200
+ }
6201
+ //<editor-fold desc="INIT">
6202
+ createScene() {
6203
+ return new MineRenderScene();
6204
+ }
6205
+ createCamera() {
6206
+ switch (this.options.camera.type) {
6207
+ case "perspective":
6208
+ default:
6209
+ return new PerspectiveCamera(
6210
+ this.options.camera.perspective.fov,
6211
+ this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
6212
+ this.options.camera.near,
6213
+ this.options.camera.far
6214
+ );
6215
+ case "orthographic":
6216
+ return new OrthographicCamera(
6217
+ this.options.camera.orthographic.left ?? this.viewWidth / -2,
6218
+ this.options.camera.orthographic.right ?? this.viewWidth / 2,
6219
+ this.options.camera.orthographic.top ?? this.viewHeight / 2,
6220
+ this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
6221
+ this.options.camera.near,
6222
+ this.options.camera.far
6223
+ );
6120
6224
  }
6121
- function handleTouchMoveRotate(event) {
6122
- if (pointers.length == 1) {
6123
- rotateEnd.set(event.pageX, event.pageY);
6124
- } else {
6125
- const position = getSecondPointerPosition(event);
6126
- const x = 0.5 * (event.pageX + position.x);
6127
- const y = 0.5 * (event.pageY + position.y);
6128
- rotateEnd.set(x, y);
6129
- }
6130
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6131
- const element = scope.domElement;
6132
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6133
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6134
- rotateStart.copy(rotateEnd);
6225
+ }
6226
+ createRenderer() {
6227
+ const renderer = new WebGLRenderer({
6228
+ antialias: this.options.render.antialias,
6229
+ alpha: true,
6230
+ powerPreference: "high-performance",
6231
+ depth: true
6232
+ });
6233
+ renderer.setClearColor(0, 0);
6234
+ renderer.shadowMap.enabled = true;
6235
+ renderer.shadowMap.type = PCFSoftShadowMap;
6236
+ renderer.outputColorSpace = SRGBColorSpace3;
6237
+ renderer.setSize(this.viewWidth, this.viewHeight);
6238
+ return renderer;
6239
+ }
6240
+ createComposer() {
6241
+ if (!this.options.composer.enabled) return void 0;
6242
+ const composer = new EffectComposer(this.renderer);
6243
+ composer.setSize(this.viewWidth, this.viewHeight);
6244
+ composer.addPass(new RenderPass(this.scene, this.camera));
6245
+ return composer;
6246
+ }
6247
+ createControls() {
6248
+ if (!this.options.controls?.enabled) return void 0;
6249
+ const position = this.camera.position.clone();
6250
+ const controls = new OrbitControls(this.camera, this.renderer.domElement);
6251
+ this.camera.position.copy(position);
6252
+ const target = this.options.camera.lookingAt;
6253
+ if (isVector3(target)) {
6254
+ controls.target.copy(target);
6255
+ } else if (isTripleArray(target)) {
6256
+ controls.target.set(target[0], target[1], target[2]);
6257
+ }
6258
+ controls.update();
6259
+ controls.saveState();
6260
+ this.registerEventDispatcher(controls);
6261
+ return controls;
6262
+ }
6263
+ //</editor-fold>
6264
+ init() {
6265
+ if (this._disposed) return;
6266
+ if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
6267
+ window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
6135
6268
  }
6136
- function handleTouchMovePan(event) {
6137
- if (pointers.length === 1) {
6138
- panEnd.set(event.pageX, event.pageY);
6139
- } else {
6140
- const position = getSecondPointerPosition(event);
6141
- const x = 0.5 * (event.pageX + position.x);
6142
- const y = 0.5 * (event.pageY + position.y);
6143
- panEnd.set(x, y);
6269
+ if (this.options.debug.grid) {
6270
+ const gridHelper = new GridHelper(128, 16);
6271
+ this._debugHelpers.push(gridHelper);
6272
+ this.scene.add(gridHelper);
6273
+ const gridHelper2 = new GridHelper(128, 16);
6274
+ this._debugHelpers.push(gridHelper2);
6275
+ gridHelper2.rotation.x = 90 * (Math.PI / 180);
6276
+ this.scene.add(gridHelper2);
6277
+ const gridHelper3 = new GridHelper(128, 16);
6278
+ this._debugHelpers.push(gridHelper3);
6279
+ gridHelper3.rotation.z = 90 * (Math.PI / 180);
6280
+ this.scene.add(gridHelper3);
6281
+ }
6282
+ if (this.options.debug.axes) {
6283
+ const axesHelper = new AxesHelper3(64);
6284
+ this._debugHelpers.push(axesHelper);
6285
+ this.scene.add(axesHelper);
6286
+ }
6287
+ if (this.options.camera.position) {
6288
+ if (isVector3(this.options.camera.position)) {
6289
+ this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
6290
+ } else if (isTripleArray(this.options.camera.position)) {
6291
+ this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
6144
6292
  }
6145
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6146
- pan(panDelta.x, panDelta.y);
6147
- panStart.copy(panEnd);
6148
6293
  }
6149
- function handleTouchMoveDolly(event) {
6150
- const position = getSecondPointerPosition(event);
6151
- const dx = event.pageX - position.x;
6152
- const dy = event.pageY - position.y;
6153
- const distance = Math.sqrt(dx * dx + dy * dy);
6154
- dollyEnd.set(0, distance);
6155
- dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
6156
- dollyOut(dollyDelta.y);
6157
- dollyStart.copy(dollyEnd);
6294
+ if (this.options.camera.lookingAt) {
6295
+ if (isVector3(this.options.camera.lookingAt)) {
6296
+ this.camera.lookAt(this.options.camera.lookingAt);
6297
+ } else if (isTripleArray(this.options.camera.lookingAt)) {
6298
+ this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
6299
+ }
6158
6300
  }
6159
- function handleTouchMoveDollyPan(event) {
6160
- if (scope.enableZoom) handleTouchMoveDolly(event);
6161
- if (scope.enablePan) handleTouchMovePan(event);
6301
+ if (this.options.render.autoResize && !this._resizeListener) {
6302
+ this._resizeListener = () => {
6303
+ this.resize(this.viewWidth, this.viewHeight);
6304
+ };
6305
+ window.addEventListener("resize", this._resizeListener);
6162
6306
  }
6163
- function handleTouchMoveDollyRotate(event) {
6164
- if (scope.enableZoom) handleTouchMoveDolly(event);
6165
- if (scope.enableRotate) handleTouchMoveRotate(event);
6307
+ }
6308
+ get element() {
6309
+ return this._element;
6310
+ }
6311
+ appendTo(element) {
6312
+ if (this._disposed) return;
6313
+ this._element = element;
6314
+ this._element.appendChild(this.renderer.domElement);
6315
+ if (this.viewWidth == 0) {
6316
+ console.warn("0 element width");
6166
6317
  }
6167
- function handleTouchEnd() {
6318
+ if (this.viewHeight == 0) {
6319
+ console.warn("0 element height");
6168
6320
  }
6169
- function onPointerDown(event) {
6170
- if (scope.enabled === false) return;
6171
- if (pointers.length === 0) {
6172
- scope.domElement.setPointerCapture(event.pointerId);
6173
- scope.domElement.addEventListener("pointermove", onPointerMove);
6174
- scope.domElement.addEventListener("pointerup", onPointerUp);
6175
- }
6176
- addPointer(event);
6177
- if (event.pointerType === "touch") {
6178
- onTouchStart(event);
6179
- } else {
6180
- onMouseDown(event);
6181
- }
6321
+ this.resize(this.viewWidth, this.viewHeight);
6322
+ }
6323
+ /**
6324
+ * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
6325
+ * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
6326
+ */
6327
+ registerEventDispatcher(dispatcher, changeEvent2 = "change") {
6328
+ if (this._disposed) return;
6329
+ let events = this._eventDispatchers.get(dispatcher);
6330
+ if (!events) {
6331
+ events = /* @__PURE__ */ new Set();
6332
+ this._eventDispatchers.set(dispatcher, events);
6182
6333
  }
6183
- function onPointerMove(event) {
6184
- if (scope.enabled === false) return;
6185
- if (event.pointerType === "touch") {
6186
- onTouchMove(event);
6187
- } else {
6188
- onMouseMove(event);
6189
- }
6334
+ if (events.has(changeEvent2)) return;
6335
+ events.add(changeEvent2);
6336
+ dispatcher.addEventListener(changeEvent2, this._changeListener);
6337
+ }
6338
+ resize(width, height) {
6339
+ if (this._disposed) return;
6340
+ if (isPerspectiveCamera(this.camera)) {
6341
+ this.camera.aspect = width / height;
6342
+ this.camera.updateProjectionMatrix();
6343
+ } else if (isOrthographicCamera(this.camera)) {
6344
+ this.camera.left = width / -2;
6345
+ this.camera.right = width / 2;
6346
+ this.camera.top = height / 2;
6347
+ this.camera.bottom = height / -2;
6348
+ this.camera.updateProjectionMatrix();
6190
6349
  }
6191
- function onPointerUp(event) {
6192
- if (scope.enabled === false) return;
6193
- if (event.pointerType === "touch") {
6194
- onTouchEnd();
6195
- } else {
6196
- onMouseUp(event);
6197
- }
6198
- removePointer(event);
6199
- if (pointers.length === 0) {
6200
- scope.domElement.releasePointerCapture(event.pointerId);
6201
- scope.domElement.removeEventListener("pointermove", onPointerMove);
6202
- scope.domElement.removeEventListener("pointerup", onPointerUp);
6203
- }
6350
+ this.renderer.setSize(width, height);
6351
+ this.composer?.setSize(width, height);
6352
+ this._dirty = true;
6353
+ }
6354
+ //<editor-fold desc="RENDER">
6355
+ get dirty() {
6356
+ return this._dirty || this.scene.dirty;
6357
+ }
6358
+ set dirty(dirty) {
6359
+ this._dirty = dirty;
6360
+ this.scene.dirty = dirty;
6361
+ }
6362
+ start() {
6363
+ if (this._disposed) return;
6364
+ this.stop();
6365
+ this.renderer.setAnimationLoop(this._animationLoop);
6366
+ }
6367
+ stop() {
6368
+ if (this._disposed) return;
6369
+ this.renderer.setAnimationLoop(null);
6370
+ this._nextFrameTime = void 0;
6371
+ }
6372
+ /**
6373
+ * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
6374
+ * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
6375
+ * controls must be managed by their owners.
6376
+ */
6377
+ dispose() {
6378
+ if (this._disposed) return;
6379
+ this.stop();
6380
+ this._disposed = true;
6381
+ if (this._resizeListener) {
6382
+ window.removeEventListener("resize", this._resizeListener);
6383
+ this._resizeListener = void 0;
6384
+ }
6385
+ for (const [dispatcher, events] of this._eventDispatchers) {
6386
+ for (const event of events) {
6387
+ dispatcher.removeEventListener(event, this._changeListener);
6388
+ }
6389
+ }
6390
+ this._eventDispatchers.clear();
6391
+ this._stats?.dom.remove();
6392
+ this._stats = void 0;
6393
+ this.renderer.domElement.remove();
6394
+ this._element = void 0;
6395
+ if (this._controls) {
6396
+ const controls = this._controls;
6397
+ this._controls = void 0;
6398
+ controls.enabled = false;
6399
+ controls.dispose();
6400
+ }
6401
+ this.scene.clear();
6402
+ for (const helper of this._debugHelpers) {
6403
+ helper.geometry.dispose();
6404
+ const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
6405
+ for (const material of materials) {
6406
+ material.dispose();
6407
+ }
6408
+ }
6409
+ this._debugHelpers.length = 0;
6410
+ this.composer?.dispose();
6411
+ this.renderer.dispose();
6412
+ this.renderer.forceContextLoss();
6413
+ }
6414
+ animate(t = performance.now()) {
6415
+ if (this._disposed) return;
6416
+ if (this._controls?.enabled) {
6417
+ this._controls.update();
6418
+ }
6419
+ if (this._disposed) return;
6420
+ if (!this.dirty && !this.options.render.renderAlways) return;
6421
+ const interval = this._frameInterval;
6422
+ if (interval) {
6423
+ const next = this._nextFrameTime;
6424
+ if (next !== void 0 && t + 0.1 < next) return;
6425
+ this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
6204
6426
  }
6205
- function onPointerCancel(event) {
6206
- removePointer(event);
6427
+ if (this._stats) {
6428
+ this._stats.begin();
6207
6429
  }
6208
- function onMouseDown(event) {
6209
- let mouseAction;
6210
- switch (event.button) {
6211
- case 0:
6212
- mouseAction = scope.mouseButtons.LEFT;
6213
- break;
6214
- case 1:
6215
- mouseAction = scope.mouseButtons.MIDDLE;
6216
- break;
6217
- case 2:
6218
- mouseAction = scope.mouseButtons.RIGHT;
6219
- break;
6220
- default:
6221
- mouseAction = -1;
6222
- }
6223
- switch (mouseAction) {
6224
- case MOUSE.DOLLY:
6225
- if (scope.enableZoom === false) return;
6226
- handleMouseDownDolly(event);
6227
- state = STATE.DOLLY;
6228
- break;
6229
- case MOUSE.ROTATE:
6230
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6231
- if (scope.enablePan === false) return;
6232
- handleMouseDownPan(event);
6233
- state = STATE.PAN;
6234
- } else {
6235
- if (scope.enableRotate === false) return;
6236
- handleMouseDownRotate(event);
6237
- state = STATE.ROTATE;
6238
- }
6239
- break;
6240
- case MOUSE.PAN:
6241
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6242
- if (scope.enableRotate === false) return;
6243
- handleMouseDownRotate(event);
6244
- state = STATE.ROTATE;
6245
- } else {
6246
- if (scope.enablePan === false) return;
6247
- handleMouseDownPan(event);
6248
- state = STATE.PAN;
6249
- }
6250
- break;
6251
- default:
6252
- state = STATE.NONE;
6430
+ if (this.options.composer.enabled && this.composer) {
6431
+ this.composer.render();
6432
+ } else {
6433
+ this.renderer.render(this.scene, this.camera);
6434
+ }
6435
+ this.dirty = false;
6436
+ if (this._stats) {
6437
+ this._stats.end();
6438
+ }
6439
+ }
6440
+ //</editor-fold>
6441
+ toImage() {
6442
+ return this.renderer.domElement.toDataURL();
6443
+ }
6444
+ ///
6445
+ get attachedToBody() {
6446
+ return this.element === document.body;
6447
+ }
6448
+ get viewWidth() {
6449
+ return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
6450
+ }
6451
+ get viewHeight() {
6452
+ return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
6453
+ }
6454
+ get scene() {
6455
+ return this._scene;
6456
+ }
6457
+ get camera() {
6458
+ return this._camera;
6459
+ }
6460
+ get renderer() {
6461
+ return this._renderer;
6462
+ }
6463
+ get composer() {
6464
+ return this._composer;
6465
+ }
6466
+ /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
6467
+ get controls() {
6468
+ return this._controls;
6469
+ }
6470
+ ///
6471
+ };
6472
+ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6473
+ camera: {
6474
+ type: "perspective",
6475
+ near: 1,
6476
+ far: 5e3,
6477
+ perspective: {
6478
+ aspect: void 0,
6479
+ fov: 50
6480
+ },
6481
+ orthographic: {
6482
+ left: void 0,
6483
+ right: void 0,
6484
+ top: void 0,
6485
+ bottom: void 0
6486
+ },
6487
+ position: new Vector38(50, 50, 50),
6488
+ lookingAt: new Vector38(0, 0, 0)
6489
+ },
6490
+ render: {
6491
+ fpsLimit: 60,
6492
+ stats: false,
6493
+ antialias: true,
6494
+ shade: true,
6495
+ autoResize: true,
6496
+ renderAlways: false
6497
+ },
6498
+ composer: {
6499
+ enabled: true
6500
+ },
6501
+ controls: {
6502
+ enabled: false
6503
+ },
6504
+ debug: {
6505
+ grid: false,
6506
+ axes: false
6507
+ }
6508
+ });
6509
+ var Renderer = _Renderer;
6510
+
6511
+ // src/skin/Skins.ts
6512
+ var Skins = class {
6513
+ //<editor-fold desc="Skins">
6514
+ static async fromUuidOrUsername(uuidOrUsername) {
6515
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6516
+ return this.fromUuid(uuidOrUsername);
6517
+ }
6518
+ return this.fromUsername(uuidOrUsername);
6519
+ }
6520
+ static async fromUuid(uuid) {
6521
+ return this.getSkinProxySkinUrl(uuid);
6522
+ }
6523
+ static async fromUsername(username) {
6524
+ return this.usernameToUuid(username).then((uuid) => {
6525
+ if (uuid) {
6526
+ return this.fromUuid(uuid);
6253
6527
  }
6254
- if (state !== STATE.NONE) {
6255
- scope.dispatchEvent(_startEvent);
6528
+ return void 0;
6529
+ });
6530
+ }
6531
+ static async fromMineSkin(mineskinId) {
6532
+ return this.getMineSkin(mineskinId).then((mineskin) => {
6533
+ if (mineskin) {
6534
+ return mineskin["data"]["texture"]["value"]["urls"]["skins"];
6256
6535
  }
6536
+ return void 0;
6537
+ });
6538
+ }
6539
+ //</editor-fold>
6540
+ //<editor-fold desc="Capes">
6541
+ static async capeFromUuidOrUsername(uuidOrUsername) {
6542
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6543
+ return this.capeFromUuid(uuidOrUsername);
6257
6544
  }
6258
- function onMouseMove(event) {
6259
- if (scope.enabled === false) return;
6260
- switch (state) {
6261
- case STATE.ROTATE:
6262
- if (scope.enableRotate === false) return;
6263
- handleMouseMoveRotate(event);
6264
- break;
6265
- case STATE.DOLLY:
6266
- if (scope.enableZoom === false) return;
6267
- handleMouseMoveDolly(event);
6268
- break;
6269
- case STATE.PAN:
6270
- if (scope.enablePan === false) return;
6271
- handleMouseMovePan(event);
6272
- break;
6545
+ return this.capeFromUsername(uuidOrUsername);
6546
+ }
6547
+ static async capeFromUuid(uuid) {
6548
+ return this.getSkinProxyCapeUrl(uuid);
6549
+ }
6550
+ static async capeFromUsername(username) {
6551
+ return this.usernameToUuid(username).then((uuid) => {
6552
+ if (uuid) {
6553
+ return this.capeFromUuid(uuid);
6273
6554
  }
6274
- }
6275
- function onMouseUp(event) {
6276
- handleMouseUp(event);
6277
- scope.dispatchEvent(_endEvent);
6278
- state = STATE.NONE;
6279
- }
6280
- function onMouseWheel(event) {
6281
- if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6282
- event.preventDefault();
6283
- scope.dispatchEvent(_startEvent);
6284
- handleMouseWheel(event);
6285
- scope.dispatchEvent(_endEvent);
6286
- }
6287
- function onKeyDown(event) {
6288
- if (scope.enabled === false || scope.enablePan === false) return;
6289
- handleKeyDown(event);
6290
- }
6291
- function onTouchStart(event) {
6292
- trackPointer(event);
6293
- switch (pointers.length) {
6294
- case 1:
6295
- switch (scope.touches.ONE) {
6296
- case TOUCH.ROTATE:
6297
- if (scope.enableRotate === false) return;
6298
- handleTouchStartRotate();
6299
- state = STATE.TOUCH_ROTATE;
6300
- break;
6301
- case TOUCH.PAN:
6302
- if (scope.enablePan === false) return;
6303
- handleTouchStartPan();
6304
- state = STATE.TOUCH_PAN;
6305
- break;
6306
- default:
6307
- state = STATE.NONE;
6308
- }
6309
- break;
6310
- case 2:
6311
- switch (scope.touches.TWO) {
6312
- case TOUCH.DOLLY_PAN:
6313
- if (scope.enableZoom === false && scope.enablePan === false) return;
6314
- handleTouchStartDollyPan();
6315
- state = STATE.TOUCH_DOLLY_PAN;
6316
- break;
6317
- case TOUCH.DOLLY_ROTATE:
6318
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6319
- handleTouchStartDollyRotate();
6320
- state = STATE.TOUCH_DOLLY_ROTATE;
6321
- break;
6322
- default:
6323
- state = STATE.NONE;
6324
- }
6325
- break;
6326
- default:
6327
- state = STATE.NONE;
6555
+ return void 0;
6556
+ });
6557
+ }
6558
+ static async capeFromCapesDev(uuid, capeType = "minecraft") {
6559
+ return this.getCapesDev(uuid, capeType).then((cape) => {
6560
+ if (cape) {
6561
+ return cape?.stillImageUrl;
6328
6562
  }
6329
- if (state !== STATE.NONE) {
6330
- scope.dispatchEvent(_startEvent);
6563
+ return void 0;
6564
+ });
6565
+ }
6566
+ //</editor-fold>
6567
+ //<editor-fold desc="Helpers">
6568
+ static async usernameToUuid(username) {
6569
+ return this.usernameToUuidSkinProxy(username);
6570
+ }
6571
+ static async usernameToUuidSkinProxy(username) {
6572
+ return Requests.genericRequest({
6573
+ baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
6574
+ url: "/uuid/" + username
6575
+ }).then((res) => {
6576
+ if (res.status === 200) {
6577
+ return res.data["id"];
6331
6578
  }
6332
- }
6333
- function onTouchMove(event) {
6334
- trackPointer(event);
6335
- switch (state) {
6336
- case STATE.TOUCH_ROTATE:
6337
- if (scope.enableRotate === false) return;
6338
- handleTouchMoveRotate(event);
6339
- scope.update();
6340
- break;
6341
- case STATE.TOUCH_PAN:
6342
- if (scope.enablePan === false) return;
6343
- handleTouchMovePan(event);
6344
- scope.update();
6345
- break;
6346
- case STATE.TOUCH_DOLLY_PAN:
6347
- if (scope.enableZoom === false && scope.enablePan === false) return;
6348
- handleTouchMoveDollyPan(event);
6349
- scope.update();
6350
- break;
6351
- case STATE.TOUCH_DOLLY_ROTATE:
6352
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6353
- handleTouchMoveDollyRotate(event);
6354
- scope.update();
6355
- break;
6356
- default:
6357
- state = STATE.NONE;
6579
+ return void 0;
6580
+ }).catch((err) => {
6581
+ console.warn(err);
6582
+ return void 0;
6583
+ });
6584
+ }
6585
+ static async usernameToUuidMineTools(username) {
6586
+ return Requests.genericRequest({
6587
+ baseURL: "https://api.minetools.eu",
6588
+ url: "/uuid/" + username
6589
+ }).then((res) => {
6590
+ if (res.status === 200) {
6591
+ return res.data["id"];
6358
6592
  }
6359
- }
6360
- function onTouchEnd(event) {
6361
- handleTouchEnd(event);
6362
- scope.dispatchEvent(_endEvent);
6363
- state = STATE.NONE;
6364
- }
6365
- function onContextMenu(event) {
6366
- if (scope.enabled === false) return;
6367
- event.preventDefault();
6368
- }
6369
- function addPointer(event) {
6370
- pointers.push(event);
6371
- }
6372
- function removePointer(event) {
6373
- delete pointerPositions[event.pointerId];
6374
- for (let i = 0; i < pointers.length; i++) {
6375
- if (pointers[i].pointerId == event.pointerId) {
6376
- pointers.splice(i, 1);
6377
- return;
6378
- }
6593
+ return void 0;
6594
+ }).catch((err) => {
6595
+ console.warn(err);
6596
+ return void 0;
6597
+ });
6598
+ }
6599
+ static async getProfileFromMinetools(uuid) {
6600
+ return Requests.genericRequest({
6601
+ baseURL: "https://api.minetools.eu",
6602
+ url: "/profile/" + uuid
6603
+ }).then((res) => {
6604
+ if (res.status === 200) {
6605
+ return res.data;
6379
6606
  }
6380
- }
6381
- function trackPointer(event) {
6382
- let position = pointerPositions[event.pointerId];
6383
- if (position === void 0) {
6384
- position = new Vector23();
6385
- pointerPositions[event.pointerId] = position;
6607
+ });
6608
+ }
6609
+ static async getMineSkin(mineskinId) {
6610
+ return Requests.genericRequest({
6611
+ baseURL: "https://api.mineskin.org",
6612
+ url: "/get/uuid/" + mineskinId
6613
+ }).then((res) => {
6614
+ if (res.status === 200) {
6615
+ return res.data;
6386
6616
  }
6387
- position.set(event.pageX, event.pageY);
6388
- }
6389
- function getSecondPointerPosition(event) {
6390
- const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6391
- return pointerPositions[pointer.pointerId];
6392
- }
6393
- scope.domElement.addEventListener("contextmenu", onContextMenu);
6394
- scope.domElement.addEventListener("pointerdown", onPointerDown);
6395
- scope.domElement.addEventListener("pointercancel", onPointerCancel);
6396
- scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6397
- this.update();
6617
+ return void 0;
6618
+ }).catch((err) => {
6619
+ console.warn(err);
6620
+ return void 0;
6621
+ });
6398
6622
  }
6399
- };
6400
- var MapControls = class extends OrbitControls {
6401
- constructor(object, domElement) {
6402
- super(object, domElement);
6403
- this.screenSpacePanning = false;
6404
- this.mouseButtons.LEFT = MOUSE.PAN;
6405
- this.mouseButtons.RIGHT = MOUSE.ROTATE;
6406
- this.touches.ONE = TOUCH.PAN;
6407
- this.touches.TWO = TOUCH.DOLLY_ROTATE;
6623
+ static async getCapesDev(uuid, type = "all") {
6624
+ return Requests.genericRequest({
6625
+ baseURL: "https://api.capes.dev",
6626
+ url: "/load/" + uuid + "/" + type
6627
+ }).then((res) => {
6628
+ if (res.status === 200) {
6629
+ return res.data;
6630
+ }
6631
+ return void 0;
6632
+ }).catch((err) => {
6633
+ console.warn(err);
6634
+ return void 0;
6635
+ });
6636
+ }
6637
+ static getCrafatarSkinUrl(uuid) {
6638
+ return "https://crafatar.com/skins/" + uuid;
6408
6639
  }
6640
+ static getCrafatarCapeUrl(uuid) {
6641
+ return "https://crafatar.com/capes/" + uuid;
6642
+ }
6643
+ static getMcHeadsSkinUrl(uuid) {
6644
+ return "https://mc-heads.net/skin/" + uuid;
6645
+ }
6646
+ static getMineSkinPlayerSkinUrl(uuid) {
6647
+ return "https://mineskin.org/skin/player/" + uuid;
6648
+ }
6649
+ static getSkinProxySkinUrl(uuid) {
6650
+ return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
6651
+ }
6652
+ static getSkinProxyCapeUrl(uuid) {
6653
+ return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
6654
+ }
6655
+ //</editor-fold>
6409
6656
  };
6410
6657
 
6411
6658
  // src/world/Chunk.ts
@@ -6697,6 +6944,7 @@ export {
6697
6944
  OrbitControls,
6698
6945
  PersistentCache,
6699
6946
  Renderer,
6947
+ RequestError,
6700
6948
  Requests,
6701
6949
  SKIN_PARTS,
6702
6950
  SceneInspector,