minerender 2.1.0-alpha.18 → 2.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,6 +23,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
24
  mod
25
25
  ));
26
+ var __decorateClass = (decorators, target, key, kind) => {
27
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
28
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
29
+ if (decorator = decorators[i])
30
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
31
+ if (kind && result) __defProp(target, key, result);
32
+ return result;
33
+ };
26
34
 
27
35
  // ../../node_modules/ts-deepmerge/dist/index.js
28
36
  var require_dist = __commonJS({
@@ -32,8 +40,8 @@ var require_dist = __commonJS({
32
40
  __assign = Object.assign || function(t) {
33
41
  for (var s, i = 1, n = arguments.length; i < n; i++) {
34
42
  s = arguments[i];
35
- for (var p12 in s) if (Object.prototype.hasOwnProperty.call(s, p12))
36
- t[p12] = s[p12];
43
+ for (var p13 in s) if (Object.prototype.hasOwnProperty.call(s, p13))
44
+ t[p13] = s[p13];
37
45
  }
38
46
  return t;
39
47
  };
@@ -77,7 +85,7 @@ var require_dist = __commonJS({
77
85
  return false;
78
86
  };
79
87
  var PROTECTED_KEYS = ["__proto__"];
80
- var merge10 = function() {
88
+ var merge11 = function() {
81
89
  var objects = [];
82
90
  for (var _i = 0; _i < arguments.length; _i++) {
83
91
  objects[_i] = arguments[_i];
@@ -88,9 +96,9 @@ var require_dist = __commonJS({
88
96
  return;
89
97
  }
90
98
  if (Array.isArray(result[key]) && Array.isArray(current[key])) {
91
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
99
+ result[key] = merge11.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
92
100
  } else if (isObject(result[key]) && isObject(current[key])) {
93
- result[key] = merge10(result[key], current[key]);
101
+ result[key] = merge11(result[key], current[key]);
94
102
  } else {
95
103
  result[key] = current[key];
96
104
  }
@@ -101,18 +109,18 @@ var require_dist = __commonJS({
101
109
  var defaultOptions = {
102
110
  mergeArrays: true
103
111
  };
104
- merge10.options = defaultOptions;
105
- merge10.withOptions = function(options) {
112
+ merge11.options = defaultOptions;
113
+ merge11.withOptions = function(options) {
106
114
  var objects = [];
107
115
  for (var _i = 1; _i < arguments.length; _i++) {
108
116
  objects[_i - 1] = arguments[_i];
109
117
  }
110
- merge10.options = __assign({ mergeArrays: true }, options);
111
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
112
- merge10.options = defaultOptions;
118
+ merge11.options = __assign({ mergeArrays: true }, options);
119
+ var result = merge11.apply(void 0, __spreadArray([], __read(objects), false));
120
+ merge11.options = defaultOptions;
113
121
  return result;
114
122
  };
115
- exports.default = merge10;
123
+ exports.default = merge11;
116
124
  }
117
125
  });
118
126
 
@@ -141,29 +149,25 @@ var Env = class {
141
149
  };
142
150
 
143
151
  // src/cache/PersistentCache.ts
144
- var PersistentCache = class _PersistentCache {
152
+ var _PersistentCache = class _PersistentCache {
145
153
  constructor(backing) {
146
154
  this.backing = backing;
147
155
  }
148
- static {
149
- /** Bump to invalidate every persisted entry. */
150
- this.VERSION = 2;
151
- }
152
156
  static open(name) {
153
157
  return Env.provider.openCache(name, _PersistentCache.VERSION);
154
158
  }
155
- /** Loads a missing entry and stores only non-nullish results. */
156
159
  async getOrLoad(key, loader) {
157
160
  let v = await this.get(key);
158
161
  if (typeof v === "undefined" || v === null) {
159
162
  v = await loader(key);
160
- if (typeof v !== "undefined" && v !== null) {
161
- await this.put(key, v);
162
- }
163
+ await this.put(key, v);
163
164
  }
164
165
  return v;
165
166
  }
166
167
  };
168
+ /** Bump to invalidate every persisted entry. */
169
+ _PersistentCache.VERSION = 1;
170
+ var PersistentCache = _PersistentCache;
167
171
 
168
172
  // src/env/node/NodeCache.ts
169
173
  var NodeCache = class extends PersistentCache {
@@ -241,7 +245,7 @@ registerNodeEnv();
241
245
  // src/Axis.ts
242
246
  import { Vector3 } from "three";
243
247
  var Axis = /* @__PURE__ */ ((Axis3) => {
244
- Axis3["X"] = "x";
248
+ Axis3["X"] = "X";
245
249
  Axis3["Y"] = "y";
246
250
  Axis3["Z"] = "z";
247
251
  return Axis3;
@@ -249,7 +253,7 @@ var Axis = /* @__PURE__ */ ((Axis3) => {
249
253
  var AXES = Object.values(Axis);
250
254
  function axisToVec3(axis) {
251
255
  switch (axis) {
252
- case "x" /* X */:
256
+ case "X" /* X */:
253
257
  return new Vector3(1, 0, 0);
254
258
  case "y" /* Y */:
255
259
  return new Vector3(0, 1, 0);
@@ -337,7 +341,8 @@ function serializeImageKey(key) {
337
341
  return md5(key.src);
338
342
  }
339
343
  function serializeBoxGeometryKey(key) {
340
- return md5([key.width, key.height, key.depth, key.uv?.join(":")].join("_"));
344
+ var _a;
345
+ return md5([key.width, key.height, key.depth, (_a = key.uv) == null ? void 0 : _a.join(":")].join("_"));
341
346
  }
342
347
  function serializeTextureKey(key) {
343
348
  return md5([key.src, key.format, key.rotation].join("$"));
@@ -352,61 +357,7 @@ function serializeMeshKey(key) {
352
357
  // src/cache/Caching.ts
353
358
  import { Caches } from "@inventivetalent/loading-cache";
354
359
  import { Time } from "@inventivetalent/time";
355
- var Caching = class _Caching {
356
- static {
357
- this.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
358
- }
359
- static {
360
- this.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
361
- }
362
- static {
363
- this.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
364
- }
365
- static {
366
- this.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
367
- }
368
- static {
369
- this.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
370
- }
371
- static {
372
- this.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
373
- }
374
- static {
375
- this.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
376
- }
377
- static {
378
- this.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
379
- }
380
- static {
381
- this.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
382
- }
383
- static {
384
- this.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
385
- }
386
- static {
387
- this.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
388
- }
389
- static {
390
- this.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
391
- }
392
- static {
393
- this.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
394
- }
395
- static {
396
- this.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
397
- }
398
- static {
399
- this.listAssetCache = _Caching.createAssetCache();
400
- }
401
- static {
402
- this.defaultBlockStatesCache = _Caching.createAssetCache();
403
- }
404
- static {
405
- this.entityModelsCache = _Caching.createAssetCache();
406
- }
407
- static createAssetCache() {
408
- return Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
409
- }
360
+ var Caching = class {
410
361
  /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
411
362
  static get all() {
412
363
  return [
@@ -423,10 +374,7 @@ var Caching = class _Caching {
423
374
  this.rawModelCache,
424
375
  this.mergedModelCache,
425
376
  this.modelTextureAtlasCache,
426
- this.blockStateCache,
427
- this.listAssetCache,
428
- this.defaultBlockStatesCache,
429
- this.entityModelsCache
377
+ this.blockStateCache
430
378
  ];
431
379
  }
432
380
  static clear() {
@@ -437,8 +385,8 @@ var Caching = class _Caching {
437
385
  /**
438
386
  * Clears every cache and stops its expiry timer.
439
387
  *
440
- * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
441
- * Use {@link shutdown} to also stop requests and the shared Ticker.
388
+ * loading-cache reschedules that timer indefinitely, so a Node process will not exit until
389
+ * this is called - see {@link shutdown}.
442
390
  */
443
391
  static end() {
444
392
  for (const cache of this.all) {
@@ -452,6 +400,20 @@ var Caching = class _Caching {
452
400
  };
453
401
  }
454
402
  };
403
+ Caching.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
404
+ Caching.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
405
+ Caching.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
406
+ Caching.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
407
+ Caching.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
408
+ Caching.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
409
+ Caching.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
410
+ Caching.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
411
+ Caching.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
412
+ Caching.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
413
+ Caching.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
414
+ Caching.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
415
+ Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
416
+ Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
455
417
 
456
418
  // src/Geometries.ts
457
419
  var Geometries = class _Geometries {
@@ -479,7 +441,6 @@ import { CanvasTexture, Texture as Texture2 } from "three";
479
441
 
480
442
  // src/texture/TextureLoader.ts
481
443
  import { RGBAFormat, Texture } from "three";
482
- import * as THREE from "three";
483
444
 
484
445
  // src/canvas/CanvasCompat.ts
485
446
  function createImage(width, height) {
@@ -490,7 +451,9 @@ function createCanvas2(width, height) {
490
451
  }
491
452
 
492
453
  // src/request/Requests.ts
493
- import { JobCancelledError, JobQueue } from "jobqu";
454
+ import axios from "axios";
455
+ import { JobQueue } from "jobqu";
456
+ import { Time as Time2 } from "@inventivetalent/time";
494
457
 
495
458
  // src/util/log.ts
496
459
  var Reset = "\x1B[0m";
@@ -500,174 +463,198 @@ function prefix(prefix2) {
500
463
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
501
464
  }
502
465
 
503
- // src/request/Requests.ts
504
- var p = prefix("Requests");
505
- var RequestError = class extends Error {
506
- constructor(message, response, cause) {
507
- super(message);
508
- this.response = response;
509
- this.cause = cause;
510
- this.name = "RequestError";
466
+ // src/util/BatchedExecutor.ts
467
+ var BatchedExecutor = class {
468
+ constructor(interval = 1, batch = 30) {
469
+ this.interval = interval;
470
+ this.batch = batch;
471
+ this.queue = [];
472
+ this.task = setInterval(() => this.run());
511
473
  }
512
- };
513
- async function fetchRequest(config, defaultBaseURL) {
514
- const { url, baseURL = defaultBaseURL, timeout = 5e3, responseType = "json", signal, ...options } = config;
515
- const target = baseURL && !/^([a-z][a-z\d+.-]*:|\/\/)/i.test(url) ? `${baseURL.replace(/\/+$/, "")}/${url.replace(/^\/+/, "")}` : url;
516
- const headers = new Headers(options.headers);
517
- if (typeof window === "undefined" && !headers.has("User-Agent")) {
518
- headers.set("User-Agent", "MineRender");
519
- }
520
- const attemptSignal = AbortSignal.any([
521
- ...signal ? [signal] : [],
522
- ...timeout === 0 ? [] : [AbortSignal.timeout(timeout)]
523
- ]);
524
- const request = new Request(target, { ...options, headers, signal: attemptSignal });
525
- attemptSignal.throwIfAborted();
526
- try {
527
- const response = await fetch(request);
528
- const result = {
529
- data: void 0,
530
- status: response.status,
531
- statusText: response.statusText,
532
- headers: response.headers,
533
- url: response.url
534
- };
535
- if (!response.ok) {
536
- await response.body?.cancel().catch(() => {
537
- });
538
- throw new RequestError(`Request failed with status ${response.status}`, result);
474
+ submit(task) {
475
+ this.queue.push(task);
476
+ }
477
+ run() {
478
+ for (let i = 0; i < this.batch; i++) {
479
+ this.runNext();
539
480
  }
540
- const emptyBody = request.method === "HEAD" || response.status === 204 || response.status === 205;
541
- const data = responseType === "arraybuffer" ? await response.arrayBuffer() : emptyBody || response.body === null ? void 0 : await response.json();
542
- return { ...result, data };
543
- } catch (error) {
544
- attemptSignal.throwIfAborted();
545
- if (/^https?:/.test(request.url) && request.redirect !== "error" && error instanceof TypeError) {
546
- throw new RequestError("Network request failed", void 0, error);
481
+ }
482
+ runNext() {
483
+ let next = this.queue.shift();
484
+ if (next) next();
485
+ }
486
+ };
487
+
488
+ // src/util/model.ts
489
+ import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
490
+ function applyElementRotation(rotation, geometry) {
491
+ const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
492
+ geometry.translate(-origin.x, -origin.y, -origin.z);
493
+ switch (rotation.axis) {
494
+ case "X" /* X */:
495
+ geometry.rotateX(toRadians(rotation.angle));
496
+ break;
497
+ case "y" /* Y */:
498
+ geometry.rotateY(toRadians(rotation.angle));
499
+ break;
500
+ case "z" /* Z */:
501
+ geometry.rotateZ(toRadians(rotation.angle));
502
+ break;
503
+ }
504
+ if (rotation.rescale) {
505
+ if (Math.abs(rotation.angle) === 22.5) {
506
+ const s = 1 / Math.cos(0.39269909262657166);
507
+ geometry.scale(s, 1, s);
508
+ } else {
509
+ const s = 1 / Math.cos(0.7853981852531433);
510
+ geometry.scale(s, 1, s);
547
511
  }
548
- throw error;
549
512
  }
513
+ geometry.translate(origin.x, origin.y, origin.z);
550
514
  }
551
- async function abortable(promise, signal) {
552
- if (!signal) return promise;
553
- let abort;
554
- const cancelled = new Promise((_, reject) => {
555
- abort = () => reject(signal.reason);
556
- signal.addEventListener("abort", abort, { once: true });
557
- if (signal.aborted) abort();
558
- });
559
- try {
560
- return await Promise.race([promise, cancelled]);
561
- } finally {
562
- signal.removeEventListener("abort", abort);
515
+ function applyModelPartRotation(modelPart, geometry) {
516
+ const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
517
+ geometry.translate(-origin.x, -origin.y, -origin.z);
518
+ geometry.rotateX(toRadians(modelPart.pitch));
519
+ geometry.rotateY(toRadians(modelPart.yaw));
520
+ geometry.rotateZ(toRadians(modelPart.roll));
521
+ geometry.translate(origin.x, origin.y, origin.z);
522
+ }
523
+ function applyGenericRotation(axis, rotation, obj) {
524
+ switch (axis) {
525
+ case "X" /* X */:
526
+ obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
527
+ break;
528
+ case "y" /* Y */:
529
+ obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
530
+ break;
531
+ case "z" /* Z */:
532
+ obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
533
+ break;
563
534
  }
564
535
  }
565
- var RequestQueue = class {
566
- constructor() {
567
- this.pendingRequests = 0;
568
- this.stopped = new AbortController();
569
- this.queue = new JobQueue(
570
- (request) => fetchRequest(request, this.baseURL),
571
- { interval: 10, maxPerRun: 1, maxActive: 8 }
572
- );
536
+ function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
537
+ let size = new Vector32();
538
+ box.getSize(size);
539
+ let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
540
+ let wireGeo = new EdgesGeometry(boxGeo);
541
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
542
+ let wireframe = new LineSegments(wireGeo, wireMat);
543
+ obj.add(wireframe);
544
+ let axes = new AxesHelper(1);
545
+ obj.add(axes);
546
+ }
547
+ function addWireframeToObject(obj, color = 16777215, w = 2) {
548
+ let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
549
+ let wireGeo = new EdgesGeometry(boxGeo);
550
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
551
+ let wireframe = new LineSegments(wireGeo, wireMat);
552
+ obj.add(wireframe);
553
+ let axes = new AxesHelper(1);
554
+ obj.add(axes);
555
+ }
556
+ function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
557
+ let wireGeo = new EdgesGeometry(geo);
558
+ let wireMat = new LineBasicMaterial({ color, linewidth: w });
559
+ let wireframe = new LineSegments(wireGeo, wireMat);
560
+ mesh.add(wireframe);
561
+ let axes = new AxesHelper(1);
562
+ mesh.add(axes);
563
+ }
564
+
565
+ // src/util/performance.ts
566
+ function captureException(e, ...extra) {
567
+ console.error(e, extra);
568
+ }
569
+ function timingStart(marker) {
570
+ console.time(marker);
571
+ }
572
+ function timingEnd(marker) {
573
+ console.timeEnd(marker);
574
+ }
575
+
576
+ // src/util/three.ts
577
+ function isObject3D(obj) {
578
+ return obj.isObject3D;
579
+ }
580
+ function isMesh(obj) {
581
+ return obj.isMesh;
582
+ }
583
+ function isInstancedMesh(obj) {
584
+ return obj.isInstancedMesh;
585
+ }
586
+ function isPerspectiveCamera(obj) {
587
+ return obj.isPerspectiveCamera;
588
+ }
589
+ function isOrthographicCamera(obj) {
590
+ return obj.isOrthographicCamera;
591
+ }
592
+
593
+ // src/request/Requests.ts
594
+ var p = prefix("Requests");
595
+ if (typeof window === "undefined") {
596
+ axios.defaults.headers["User-Agent"] = "MineRender";
597
+ }
598
+ var _Requests = class _Requests {
599
+ static genericRequest(request) {
600
+ return this.genericQueue.add(request).catch(async (e) => {
601
+ console.debug(p, "generic catch", e.code, e);
602
+ if (this.shouldRetry(e, request)) {
603
+ await sleep(100);
604
+ return this.genericRequest(request);
605
+ }
606
+ throw e;
607
+ });
573
608
  }
574
- async request(request) {
575
- this.pendingRequests++;
576
- const signal = request.signal;
577
- try {
578
- for (let retries = 0; ; retries++) {
579
- signal?.throwIfAborted();
580
- try {
581
- return await abortable(this.queue.add(request), signal);
582
- } catch (error) {
583
- console.debug(p, "Request failed", error);
584
- const delay = this.retryDelay(error, request, retries);
585
- if (delay === void 0) {
586
- throw error;
609
+ static mcAssetRequest(request) {
610
+ return this.mcAssetRequestQueue.add(request).catch((e) => {
611
+ console.debug(p, "mcAssetRequest catch", e.code, e);
612
+ throw e;
613
+ });
614
+ }
615
+ static shouldRetry(e, request) {
616
+ if ("code" in e) {
617
+ if ("ECONNABORTED" === e.code) {
618
+ if ("minerenderRetry" in request) {
619
+ if (request["minerenderRetry"] > 0) {
620
+ request["minerenderRetry"]--;
621
+ return true;
587
622
  }
588
- await this.waitForRetry(delay, signal);
623
+ } else {
624
+ request["minerenderRetry"] = 3;
625
+ return true;
589
626
  }
590
627
  }
591
- } finally {
592
- if (signal?.aborted) {
593
- this.queue.remove(request);
594
- }
595
- this.pendingRequests--;
596
- }
597
- }
598
- retryDelay(error, request, retries) {
599
- if (this.stopped.signal.aborted || retries >= 3 || (request.method ?? "get").toLowerCase() !== "get" || request.signal?.aborted) {
600
- return void 0;
601
- }
602
- if (error instanceof RequestError) {
603
- const status = error.response?.status;
604
- if (status !== void 0 && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return void 0;
605
- } else if (!(error instanceof DOMException && error.name === "TimeoutError")) {
606
- return void 0;
607
- }
608
- let delay = 100 * 2 ** retries;
609
- const retryAfter = error instanceof RequestError ? error.response?.headers.get("Retry-After") : void 0;
610
- if (retryAfter !== void 0 && retryAfter !== null) {
611
- const seconds = Number(retryAfter);
612
- if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {
613
- return void 0;
614
- }
615
- delay = Math.max(delay, seconds * 1e3);
616
- }
617
- return delay;
618
- }
619
- async waitForRetry(delay, signal) {
620
- let timer;
621
- const waiting = new Promise((resolve) => {
622
- timer = setTimeout(resolve, delay);
623
- });
624
- try {
625
- await abortable(waiting, AbortSignal.any([this.stopped.signal, ...signal ? [signal] : []]));
626
- } finally {
627
- clearTimeout(timer);
628
628
  }
629
- }
630
- get pendingSize() {
631
- return this.pendingRequests;
632
- }
633
- end() {
634
- this.queue.end();
635
- this.stopped.abort(new JobCancelledError("ended"));
636
- }
637
- };
638
- var Requests = class {
639
- static {
640
- this.genericQueue = new RequestQueue();
641
- }
642
- static {
643
- this.mcAssetRequestQueue = new RequestQueue();
644
- }
645
- static genericRequest(request) {
646
- return this.genericQueue.request(request);
647
- }
648
- static mcAssetRequest(request) {
649
- return this.mcAssetRequestQueue.request(request);
629
+ return false;
650
630
  }
651
631
  static setMcAssetRoot(root) {
652
- this.mcAssetRequestQueue.baseURL = root;
632
+ this.mcAssetInstance.defaults.baseURL = root;
653
633
  }
654
- /** Counts unsettled calls, including retry delays and requests still running after shutdown. */
655
634
  static get queueSizes() {
656
635
  return {
657
- generic: this.genericQueue.pendingSize,
658
- mcAsset: this.mcAssetRequestQueue.pendingSize
636
+ generic: this.genericQueue.size,
637
+ mcAsset: this.mcAssetRequestQueue.size
659
638
  };
660
639
  }
661
640
  /**
662
- * Permanently stops both queues and rejects waiting, retrying, and future requests.
663
- * Requests already running can finish. Idle queues hold no timer, so Node can exit without
664
- * this cleanup. See {@link shutdown}.
641
+ * Stops both queue timers. jobqu reschedules itself indefinitely, so a Node process will not
642
+ * exit until this is called - see {@link shutdown}.
665
643
  */
666
644
  static end() {
667
645
  this.genericQueue.end();
668
646
  this.mcAssetRequestQueue.end();
669
647
  }
670
648
  };
649
+ _Requests.axiosInstance = axios.create({
650
+ timeout: 5e3
651
+ });
652
+ _Requests.mcAssetInstance = axios.create({
653
+ timeout: 5e3
654
+ });
655
+ _Requests.genericQueue = new JobQueue((request) => _Requests.axiosInstance.request(request), Time2.millis(10), 1);
656
+ _Requests.mcAssetRequestQueue = new JobQueue((request) => _Requests.mcAssetInstance.request(request), Time2.millis(10), 1);
657
+ var Requests = _Requests;
671
658
 
672
659
  // src/WrappedImage.ts
673
660
  var WrappedImage = class {
@@ -705,10 +692,10 @@ var WrappedImage = class {
705
692
  return this.animated ? this.width : this.height;
706
693
  }
707
694
  get frameCount() {
708
- return this.height / this.frameHeight;
695
+ return this.height / this.width;
709
696
  }
710
697
  getFrameY(frame) {
711
- return this.frameHeight * Math.max(0, Math.min(this.frameCount - 1, frame));
698
+ return this.height / this.frameCount * Math.max(0, Math.min(this.frameCount, frame));
712
699
  }
713
700
  getSectionData(sx, sy, sw, sh) {
714
701
  return this.dta.data.getImageData(sx, sy, sw, sh);
@@ -718,7 +705,7 @@ var WrappedImage = class {
718
705
  }
719
706
  getFrameSectionData(frame) {
720
707
  const y = this.getFrameY(frame);
721
- return this.getSectionData(0, y, this.frameWidth, this.frameHeight);
708
+ return this.getSectionData(0, y, this.width, this.width + y);
722
709
  }
723
710
  };
724
711
 
@@ -732,41 +719,29 @@ var ImageLoader = class _ImageLoader {
732
719
  static async loadAsync(src) {
733
720
  return new Promise((resolve, reject) => {
734
721
  const image = this._createImage();
735
- image.onload = () => resolve(image);
736
- image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
737
722
  image.src = src;
723
+ image.onload = () => resolve(image);
724
+ image.onerror = (err) => reject(err);
738
725
  });
739
726
  }
740
727
  static loadElement(src, onload, onerr) {
741
728
  const image = this._createImage();
729
+ image.src = src;
742
730
  if (onload)
743
731
  image.onload = onload;
744
732
  if (onerr)
745
733
  image.onerror = onerr;
746
- image.src = src;
747
734
  return image;
748
735
  }
749
736
  static async loadData(src) {
750
737
  console.debug(p2, "loadData", src);
751
- const image = await this.loadCanvasData(src);
752
- return image.data.getImageData(0, 0, image.width, image.height);
738
+ return await this.infoToData(await this.getInfo(src));
753
739
  }
754
740
  static async loadCanvasData(src) {
755
- const keyStr = serializeImageKey({ src });
756
- const info = this.getInfo(src);
757
- const cached = Caching.rawImageCache.getIfPresent(keyStr);
758
- try {
759
- return await this.infoToCanvasData(await info);
760
- } catch (err) {
761
- if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
762
- Caching.rawImageCache.invalidate(keyStr);
763
- }
764
- throw err;
765
- }
741
+ return await this.infoToCanvasData(await this.getInfo(src));
766
742
  }
767
743
  static async infoToCanvasData(info) {
768
- const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
769
- const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
744
+ const image = await _ImageLoader.loadAsync(info.src);
770
745
  const canvas = createCanvas2(info.width, info.height);
771
746
  const context = canvas.getContext("2d");
772
747
  context.drawImage(image, 0, 0);
@@ -777,8 +752,11 @@ var ImageLoader = class _ImageLoader {
777
752
  };
778
753
  }
779
754
  static async infoToData(info) {
780
- const image = await this.infoToCanvasData(info);
781
- return image.data.getImageData(0, 0, image.width, image.height);
755
+ const image = await _ImageLoader.loadAsync(info.src);
756
+ const canvas = createCanvas2(info.width, info.height);
757
+ const context = canvas.getContext("2d");
758
+ context.drawImage(image, 0, 0);
759
+ return context.getImageData(0, 0, canvas.width, canvas.height);
782
760
  }
783
761
  static async getData(src) {
784
762
  const keyStr = serializeImageKey({ src });
@@ -793,25 +771,38 @@ var ImageLoader = class _ImageLoader {
793
771
  });
794
772
  }
795
773
  static async processResponse(response) {
796
- const src = response.url;
774
+ const src = response.config.url;
797
775
  const data = Buffer2.from(response.data);
798
776
  const { width, height, type } = Env.provider.imageSize(data);
799
- if (!width || !height) {
800
- throw new Error("Invalid or unsupported image dimensions");
801
- }
802
777
  return {
803
778
  src,
804
- width,
805
- height,
779
+ width: width || 0,
780
+ height: height || 0,
806
781
  type,
807
782
  data
808
783
  };
809
784
  }
810
785
  static async loadInfo(src) {
786
+ if (src.startsWith("data:image/png;base64")) {
787
+ return this.processResponse({
788
+ config: {
789
+ url: src
790
+ },
791
+ data: Buffer2.from(src.substr("data:image/png;base64,".length), "base64")
792
+ });
793
+ }
811
794
  return Requests.genericRequest({
812
795
  url: src,
813
796
  responseType: "arraybuffer"
814
- }).then(this.processResponse);
797
+ }).then(this.processResponse).catch((err) => {
798
+ return {
799
+ src,
800
+ width: 0,
801
+ height: 0,
802
+ type: void 0,
803
+ data: Buffer2.from([0])
804
+ };
805
+ });
815
806
  }
816
807
  static async getInfo(src) {
817
808
  const keyStr = serializeImageKey({ src });
@@ -833,25 +824,15 @@ var ImageLoader = class _ImageLoader {
833
824
 
834
825
  // src/texture/TextureLoader.ts
835
826
  var TextureLoader = class {
836
- static {
837
- this.failedTextures = /* @__PURE__ */ new WeakSet();
838
- }
839
- /** Reports whether image loading failed, so cached textures can be retried. */
840
- static hasFailed(texture) {
841
- return this.failedTextures.has(texture);
842
- }
843
827
  static createTexture() {
844
828
  return new Texture();
845
829
  }
846
830
  static loadInBackground(src, format = RGBAFormat, rotation = 0) {
847
831
  const texture = this.createTexture();
848
- texture.colorSpace = THREE.SRGBColorSpace;
849
- const image = ImageLoader.loadElement(src, () => {
832
+ const image = ImageLoader.loadElement(src);
833
+ image.onload = function() {
850
834
  texture.needsUpdate = true;
851
- }, (error) => {
852
- this.failedTextures.add(texture);
853
- console.warn("Failed to load texture", src, error);
854
- });
835
+ };
855
836
  texture.image = image;
856
837
  texture.format = format;
857
838
  texture.rotation = rotation;
@@ -859,13 +840,9 @@ var TextureLoader = class {
859
840
  }
860
841
  static load(src, format = RGBAFormat, rotation = 0) {
861
842
  const texture = new Texture();
862
- texture.colorSpace = THREE.SRGBColorSpace;
863
843
  ImageLoader.getData(src).then((image) => {
864
- texture.image = image;
865
844
  texture.needsUpdate = true;
866
- }).catch((error) => {
867
- this.failedTextures.add(texture);
868
- console.warn("Failed to load texture", src, error);
845
+ texture.image = image;
869
846
  });
870
847
  texture.format = format;
871
848
  texture.rotation = rotation;
@@ -874,11 +851,11 @@ var TextureLoader = class {
874
851
  };
875
852
 
876
853
  // src/texture/Textures.ts
877
- import * as THREE2 from "three";
854
+ import * as THREE from "three";
878
855
  var Textures = class _Textures {
879
856
  static initTextureProps(texture) {
880
- texture.magFilter = THREE2.NearestFilter;
881
- texture.minFilter = THREE2.NearestFilter;
857
+ texture.magFilter = THREE.NearestFilter;
858
+ texture.minFilter = THREE.NearestFilter;
882
859
  texture.anisotropy = 0;
883
860
  return texture;
884
861
  }
@@ -889,16 +866,10 @@ var Textures = class _Textures {
889
866
  return new Texture2();
890
867
  }
891
868
  static createCanvasTexture(canvas) {
892
- const texture = new CanvasTexture(canvas);
893
- texture.colorSpace = THREE2.SRGBColorSpace;
894
- return this.initTextureProps(texture);
869
+ return this.initTextureProps(new CanvasTexture(canvas));
895
870
  }
896
871
  static getImage(key) {
897
872
  const keyStr = serializeTextureKey(key);
898
- const cached = Caching.textureCache.peek(keyStr);
899
- if (cached && TextureLoader.hasFailed(cached)) {
900
- Caching.textureCache.invalidate(keyStr);
901
- }
902
873
  return Caching.textureCache.get(keyStr, (k) => {
903
874
  return _Textures.createImage(key);
904
875
  });
@@ -906,10 +877,7 @@ var Textures = class _Textures {
906
877
  };
907
878
 
908
879
  // src/Materials.ts
909
- var Materials = class _Materials {
910
- static {
911
- this.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC";
912
- }
880
+ var _Materials = class _Materials {
913
881
  // resolved lazily: as a static field this decoded an image the moment the library was
914
882
  // imported, which needs both a DOM and an EnvProvider to already be in place
915
883
  static get MISSING_TEXTURE() {
@@ -957,11 +925,7 @@ var Materials = class _Materials {
957
925
 
958
926
  if (SHADE) {
959
927
 
960
- #ifdef USE_INSTANCING
961
- vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
962
- #else
963
- vec3 N = vec3( modelMatrix * vec4(normal, 0.0) );
964
- #endif
928
+ vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
965
929
 
966
930
  float yLight = (1.0+N.y) * 0.5;
967
931
  light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT;
@@ -1019,9 +983,6 @@ var Materials = class _Materials {
1019
983
  gl_FragColor = vec4(lift + color.rgb * light2, 1.0);
1020
984
 
1021
985
  }
1022
-
1023
- #include <tonemapping_fragment>
1024
- #include <colorspace_fragment>
1025
986
  }
1026
987
  `;
1027
988
  try {
@@ -1050,10 +1011,6 @@ var Materials = class _Materials {
1050
1011
  }
1051
1012
  static getImage(key) {
1052
1013
  const keyStr = serializeMaterialKey(key);
1053
- const map = Caching.materialCache.peek(keyStr)?.map;
1054
- if (map && TextureLoader.hasFailed(map)) {
1055
- Caching.materialCache.invalidate(keyStr);
1056
- }
1057
1014
  return Caching.materialCache.get(keyStr, (k) => {
1058
1015
  return _Materials.createImage(key);
1059
1016
  });
@@ -1074,12 +1031,14 @@ var Materials = class _Materials {
1074
1031
  }
1075
1032
  }
1076
1033
  };
1034
+ _Materials.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC";
1035
+ var Materials = _Materials;
1077
1036
 
1078
1037
  // src/Meshes.ts
1079
- import { Mesh } from "three";
1038
+ import { Mesh as Mesh2 } from "three";
1080
1039
  var Meshes = class _Meshes {
1081
1040
  static createBox(key) {
1082
- return new Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1041
+ return new Mesh2(Geometries.getBox(key.geometry), Materials.getImage(key.material));
1083
1042
  }
1084
1043
  static getBox(key) {
1085
1044
  const keyStr = serializeMeshKey(key);
@@ -1126,10 +1085,9 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1126
1085
  this.rootType = rootType;
1127
1086
  this.extension = extension;
1128
1087
  this.root = root;
1129
- this.isAssetKey = true;
1130
1088
  }
1131
1089
  static parse(assetType, str, origin) {
1132
- let namespace = origin?.namespace || DEFAULT_NAMESPACE;
1090
+ let namespace = (origin == null ? void 0 : origin.namespace) || DEFAULT_NAMESPACE;
1133
1091
  if (str.includes(":")) {
1134
1092
  let split2 = str.split(":");
1135
1093
  namespace = split2[0];
@@ -1142,15 +1100,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1142
1100
  split.shift();
1143
1101
  }
1144
1102
  let path = split.join("/");
1145
- const extension = assetType === "textures" ? ".png" : origin?.extension ?? ".json";
1146
- if (extension && path.endsWith(extension)) {
1147
- path = path.slice(0, -extension.length);
1148
- }
1149
- return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin?.root);
1103
+ let extension = assetType === "textures" ? ".png" : (origin == null ? void 0 : origin.assetType) || ".json";
1104
+ return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin == null ? void 0 : origin.root);
1150
1105
  }
1151
1106
  toString() {
1152
1107
  let a = [
1153
- this.root ?? AssetLoader.ROOT,
1108
+ typeof this.root !== "undefined" || AssetLoader.ROOT !== DEFAULT_ROOT ? this.root ?? AssetLoader.ROOT : "__root__",
1154
1109
  this.rootType ?? "__rootType__",
1155
1110
  this.assetType ?? "__assetType__",
1156
1111
  this.type ?? "__type__",
@@ -1160,12 +1115,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1160
1115
  return a.join("/");
1161
1116
  }
1162
1117
  getFullPath() {
1163
- let p12 = [];
1118
+ let p13 = [];
1164
1119
  if (this.type) {
1165
- p12.push(this.type);
1120
+ p13.push(this.type);
1166
1121
  }
1167
- p12.push(this.path);
1168
- return p12.join("/");
1122
+ p13.push(this.path);
1123
+ return p13.join("/");
1169
1124
  }
1170
1125
  toNamespacedString() {
1171
1126
  return this.namespace + ":" + this.getFullPath();
@@ -1175,10 +1130,10 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1175
1130
  }
1176
1131
  };
1177
1132
  function isBasicAssetKey(obj) {
1178
- return obj !== null && typeof obj === "object" && typeof obj.namespace === "string" && typeof obj.path === "string";
1133
+ return "namespace" in obj && "path" in obj;
1179
1134
  }
1180
1135
  function isAssetKey(obj) {
1181
- return isBasicAssetKey(obj) && obj.isAssetKey === true;
1136
+ return isBasicAssetKey(obj) && "parse" in obj;
1182
1137
  }
1183
1138
 
1184
1139
  // src/model/ModelMerger.ts
@@ -1187,10 +1142,10 @@ var ModelMerger = class {
1187
1142
  const models = await this.collectAllParents(model);
1188
1143
  let merged = {};
1189
1144
  for (let parentModel of models) {
1190
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1145
+ merged = (0, import_ts_deepmerge.default)(merged, parentModel);
1191
1146
  }
1192
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1193
- merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
1147
+ merged = (0, import_ts_deepmerge.default)(merged, model);
1148
+ merged.hierarchy = models.map((m) => m.parent).filter((p13) => `${p13}`);
1194
1149
  merged.hierarchy.push(`${merged.parent}`);
1195
1150
  return merged;
1196
1151
  }
@@ -1200,7 +1155,6 @@ var ModelMerger = class {
1200
1155
  }
1201
1156
  const models = [];
1202
1157
  const parentKey = AssetKey.parse("models", model.parent);
1203
- parentKey.root = model.key?.root;
1204
1158
  const parentModel = await Models.getRaw(parentKey);
1205
1159
  if (parentModel) {
1206
1160
  models.unshift(parentModel);
@@ -1210,6 +1164,9 @@ var ModelMerger = class {
1210
1164
  }
1211
1165
  };
1212
1166
 
1167
+ // src/assets/Models.ts
1168
+ import { Memoize } from "typescript-memoize";
1169
+
1213
1170
  // src/assets/source/parser/AssetParsers.ts
1214
1171
  var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1215
1172
  AssetParser2["MODEL"] = "model";
@@ -1223,65 +1180,30 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1223
1180
  })(AssetParser || {});
1224
1181
 
1225
1182
  // src/assets/Models.ts
1226
- var Models = class _Models {
1183
+ var _Models = class _Models {
1227
1184
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1228
1185
  // the library, and would require an EnvProvider before any entry has had a chance to register
1229
1186
  static get PERSISTENT_CACHE() {
1230
1187
  return this._persistentCache ??= PersistentCache.open("minerender-models");
1231
1188
  }
1232
1189
  static async getItemList() {
1233
- const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
1234
- const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
1235
- return Caching.listAssetCache.get(key.serialize(), async () => {
1236
- return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
1237
- }).then((r) => r?.files ?? []);
1190
+ return AssetLoader.get(new AssetKey(
1191
+ DEFAULT_NAMESPACE,
1192
+ "_list",
1193
+ "models",
1194
+ "item",
1195
+ "assets",
1196
+ ".json",
1197
+ DEFAULT_ROOT
1198
+ ), "list" /* LIST */).then((r) => (r == null ? void 0 : r.files) ?? []);
1238
1199
  }
1239
1200
  static async loadAndMerge(key) {
1240
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
1201
+ const model = await this.getRaw(key);
1241
1202
  if (!model) {
1242
1203
  return void 0;
1243
1204
  }
1244
1205
  return ModelMerger.mergeWithParents(model);
1245
1206
  }
1246
- static async getItemModel(key) {
1247
- const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1248
- const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
1249
- const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1250
- if (!result) return void 0;
1251
- if (result.key.assetType !== "items") return { ...result.asset, key };
1252
- const reference = this.defaultItemModel(result.asset.model, key);
1253
- const modelKey = AssetKey.parse("models", reference);
1254
- modelKey.root = key.root;
1255
- const model2 = await this.getRaw(modelKey);
1256
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
1257
- return model2;
1258
- });
1259
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1260
- }
1261
- // Item previews use the GUI context, false conditions, and zero numeric properties.
1262
- static defaultItemModel(node, key) {
1263
- if (!node || typeof node.type !== "string") {
1264
- throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
1265
- }
1266
- switch (node.type.replace(/^minecraft:/, "")) {
1267
- case "model":
1268
- if (typeof node.model === "string" && node.model) return node.model;
1269
- break;
1270
- case "condition":
1271
- return this.defaultItemModel(node.on_false, key);
1272
- case "select": {
1273
- const selected = node.property?.replace(/^minecraft:/, "") === "display_context" ? node.cases?.find((entry) => Array.isArray(entry.when) ? entry.when.includes("gui") : entry.when === "gui")?.model : void 0;
1274
- return this.defaultItemModel(selected ?? node.fallback, key);
1275
- }
1276
- case "range_dispatch": {
1277
- const selected = node.entries?.reduce((match, entry) => {
1278
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
1279
- }, void 0);
1280
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
1281
- }
1282
- }
1283
- throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
1284
- }
1285
1207
  static async getRaw(key) {
1286
1208
  if (!key.assetType) {
1287
1209
  key.assetType = "models";
@@ -1320,15 +1242,19 @@ var Models = class _Models {
1320
1242
  return this.PERSISTENT_CACHE.clear();
1321
1243
  }
1322
1244
  };
1245
+ __decorateClass([
1246
+ Memoize()
1247
+ ], _Models, "getItemList", 1);
1248
+ var Models = _Models;
1323
1249
 
1324
1250
  // src/assets/BlockStates.ts
1251
+ import { Memoize as Memoize2 } from "typescript-memoize";
1325
1252
  var BlockStates = class {
1326
1253
  static get PERSISTENT_CACHE() {
1327
1254
  return this._persistentCache ??= PersistentCache.open("minerender-blockstates");
1328
1255
  }
1329
- // BlockState names are hardcoded
1330
1256
  static async getList() {
1331
- const key = new AssetKey(
1257
+ return AssetLoader.get(new AssetKey(
1332
1258
  DEFAULT_NAMESPACE,
1333
1259
  "_list",
1334
1260
  "blockstates",
@@ -1336,16 +1262,11 @@ var BlockStates = class {
1336
1262
  "assets",
1337
1263
  ".json",
1338
1264
  DEFAULT_ROOT
1339
- );
1340
- return Caching.listAssetCache.get(key.serialize(), () => {
1341
- return AssetLoader.get(key, "list" /* LIST */);
1342
- }).then((r) => r?.files ?? []);
1265
+ ), "list" /* LIST */).then((r) => (r == null ? void 0 : r.files) ?? []);
1343
1266
  }
1344
1267
  static async getDefaultStates() {
1345
1268
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
1346
- return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
1347
- return AssetLoader.get(key, "json" /* JSON */);
1348
- });
1269
+ return AssetLoader.get(key, "json" /* JSON */);
1349
1270
  }
1350
1271
  static async getDefaultState(key) {
1351
1272
  const defaultStates = await this.getDefaultStates();
@@ -1384,11 +1305,17 @@ var BlockStates = class {
1384
1305
  await this.PERSISTENT_CACHE.clear();
1385
1306
  }
1386
1307
  };
1308
+ __decorateClass([
1309
+ Memoize2()
1310
+ ], BlockStates, "getList", 1);
1311
+ __decorateClass([
1312
+ Memoize2()
1313
+ ], BlockStates, "getDefaultStates", 1);
1387
1314
  var DefaultBlockStates = class {
1388
1315
  };
1389
1316
 
1390
1317
  // src/assets/Assets.ts
1391
- var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
1318
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
1392
1319
  var DEFAULT_NAMESPACE = "minecraft";
1393
1320
  var Assets = class {
1394
1321
  /**
@@ -1410,150 +1337,13 @@ var AssetSource = class {
1410
1337
  constructor() {
1411
1338
  }
1412
1339
  };
1413
- var AssetLoadError = class extends Error {
1414
- constructor(source, key, path, cause) {
1415
- super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
1416
- this.source = source;
1417
- this.key = key;
1418
- this.path = path;
1419
- this.cause = cause;
1420
- this.name = "AssetLoadError";
1421
- }
1422
- };
1423
-
1424
- // src/util/BatchedExecutor.ts
1425
- var BatchedExecutor = class {
1426
- constructor(interval = 1, batch = 30) {
1427
- this.interval = interval;
1428
- this.batch = batch;
1429
- this.queue = [];
1430
- this.task = setInterval(() => this.run());
1431
- }
1432
- submit(task) {
1433
- this.queue.push(task);
1434
- }
1435
- run() {
1436
- for (let i = 0; i < this.batch; i++) {
1437
- this.runNext();
1438
- }
1439
- }
1440
- runNext() {
1441
- let next = this.queue.shift();
1442
- if (next) next();
1443
- }
1444
- };
1445
-
1446
- // src/util/model.ts
1447
- import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1448
- function applyElementRotation(rotation, geometry) {
1449
- const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1450
- geometry.translate(-origin.x, -origin.y, -origin.z);
1451
- switch (rotation.axis) {
1452
- case "x" /* X */:
1453
- geometry.rotateX(toRadians(rotation.angle));
1454
- break;
1455
- case "y" /* Y */:
1456
- geometry.rotateY(toRadians(rotation.angle));
1457
- break;
1458
- case "z" /* Z */:
1459
- geometry.rotateZ(toRadians(rotation.angle));
1460
- break;
1461
- }
1462
- if (rotation.rescale) {
1463
- if (Math.abs(rotation.angle) === 22.5) {
1464
- const s = 1 / Math.cos(0.39269909262657166);
1465
- geometry.scale(s, 1, s);
1466
- } else {
1467
- const s = 1 / Math.cos(0.7853981852531433);
1468
- geometry.scale(s, 1, s);
1469
- }
1470
- }
1471
- geometry.translate(origin.x, origin.y, origin.z);
1472
- }
1473
- function applyModelPartRotation(modelPart, geometry) {
1474
- const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1475
- geometry.translate(-origin.x, -origin.y, -origin.z);
1476
- geometry.rotateX(toRadians(modelPart.pitch));
1477
- geometry.rotateY(toRadians(modelPart.yaw));
1478
- geometry.rotateZ(toRadians(modelPart.roll));
1479
- geometry.translate(origin.x, origin.y, origin.z);
1480
- }
1481
- function applyGenericRotation(axis, rotation, obj) {
1482
- switch (axis) {
1483
- case "x" /* X */:
1484
- obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1485
- break;
1486
- case "y" /* Y */:
1487
- obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1488
- break;
1489
- case "z" /* Z */:
1490
- obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1491
- break;
1492
- }
1493
- }
1494
- function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1495
- let size = new Vector32();
1496
- box.getSize(size);
1497
- let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1498
- let wireGeo = new EdgesGeometry(boxGeo);
1499
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1500
- let wireframe = new LineSegments(wireGeo, wireMat);
1501
- obj.add(wireframe);
1502
- let axes = new AxesHelper(1);
1503
- obj.add(axes);
1504
- }
1505
- function addWireframeToObject(obj, color = 16777215, w = 2) {
1506
- let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
1507
- let wireGeo = new EdgesGeometry(boxGeo);
1508
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1509
- let wireframe = new LineSegments(wireGeo, wireMat);
1510
- obj.add(wireframe);
1511
- let axes = new AxesHelper(1);
1512
- obj.add(axes);
1513
- }
1514
- function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1515
- let wireGeo = new EdgesGeometry(geo);
1516
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1517
- let wireframe = new LineSegments(wireGeo, wireMat);
1518
- mesh.add(wireframe);
1519
- let axes = new AxesHelper(1);
1520
- mesh.add(axes);
1521
- }
1522
-
1523
- // src/util/performance.ts
1524
- function captureException(e, ...extra) {
1525
- console.error(e, extra);
1526
- }
1527
- function timingStart(marker) {
1528
- console.time(marker);
1529
- }
1530
- function timingEnd(marker) {
1531
- console.timeEnd(marker);
1532
- }
1533
-
1534
- // src/util/three.ts
1535
- function isObject3D(obj) {
1536
- return obj.isObject3D;
1537
- }
1538
- function isMesh(obj) {
1539
- return obj.isMesh;
1540
- }
1541
- function isInstancedMesh(obj) {
1542
- return obj.isInstancedMesh;
1543
- }
1544
- function isPerspectiveCamera(obj) {
1545
- return obj.isPerspectiveCamera;
1546
- }
1547
- function isOrthographicCamera(obj) {
1548
- return obj.isOrthographicCamera;
1549
- }
1550
-
1551
- // src/nbt/NBTHelper.ts
1552
- var NBTHelper = class {
1553
- static async fromBuffer(buffer) {
1554
- const prismarineNbt = await import("prismarine-nbt");
1555
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1556
- return parsed;
1340
+
1341
+ // src/nbt/NBTHelper.ts
1342
+ var NBTHelper = class {
1343
+ static async fromBuffer(buffer) {
1344
+ const prismarineNbt = await import("prismarine-nbt");
1345
+ const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1346
+ return parsed;
1557
1347
  }
1558
1348
  };
1559
1349
 
@@ -1563,83 +1353,7 @@ var p3 = prefix("HostedAssetSource");
1563
1353
  var DEFAULT_OPTIONS = {
1564
1354
  retryDefaults: true
1565
1355
  };
1566
- var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1567
- static {
1568
- this.MODEL = {
1569
- config(request) {
1570
- },
1571
- parse(response) {
1572
- return response.data;
1573
- }
1574
- };
1575
- }
1576
- static {
1577
- this.BLOCKSTATE = {
1578
- config(request) {
1579
- },
1580
- parse(response) {
1581
- return response.data;
1582
- }
1583
- };
1584
- }
1585
- static {
1586
- this.META = {
1587
- config(request) {
1588
- },
1589
- parse(response) {
1590
- return response.data;
1591
- }
1592
- };
1593
- }
1594
- static {
1595
- this.NBT = {
1596
- config(request) {
1597
- request.responseType = "arraybuffer";
1598
- },
1599
- parse(response) {
1600
- return NBTHelper.fromBuffer(Buffer.from(response.data));
1601
- }
1602
- };
1603
- }
1604
- static {
1605
- this.IMAGE = {
1606
- config(request) {
1607
- request.responseType = "arraybuffer";
1608
- },
1609
- async parse(response) {
1610
- return await ImageLoader.processResponse(response);
1611
- }
1612
- };
1613
- }
1614
- static {
1615
- this.LIST = {
1616
- config(request) {
1617
- },
1618
- parse(response) {
1619
- return response.data;
1620
- }
1621
- };
1622
- }
1623
- static {
1624
- this.JSON = {
1625
- config(request) {
1626
- },
1627
- parse(response) {
1628
- return response.data;
1629
- }
1630
- };
1631
- }
1632
- static {
1633
- this.PARSER_MAP = /* @__PURE__ */ new Map([
1634
- ["model" /* MODEL */, _HostedAssetSource.MODEL],
1635
- ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
1636
- ["meta" /* META */, _HostedAssetSource.META],
1637
- ["nbt" /* NBT */, _HostedAssetSource.NBT],
1638
- ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
1639
- ["list" /* LIST */, _HostedAssetSource.LIST],
1640
- ["json" /* JSON */, _HostedAssetSource.JSON]
1641
- ]);
1642
- }
1356
+ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1643
1357
  async loadOrRetryWithDefaults(key, parser) {
1644
1358
  const direct = await this.load(key, parser);
1645
1359
  if (typeof direct !== "undefined") {
@@ -1674,25 +1388,31 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1674
1388
  console.info(p3, "Loading", key);
1675
1389
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1676
1390
  console.debug(p3, url);
1677
- const request = { url };
1678
- try {
1679
- parser.config(request);
1680
- let response;
1681
- try {
1682
- response = await Requests.mcAssetRequest(request);
1683
- } catch (cause) {
1684
- if (cause instanceof RequestError && cause.response?.status === 404) {
1685
- return void 0;
1391
+ let req = {
1392
+ url
1393
+ };
1394
+ parser.config(req);
1395
+ return await Requests.mcAssetRequest(req).then((response) => {
1396
+ if (response && response.data) {
1397
+ try {
1398
+ return parser.parse(response);
1399
+ } catch (e) {
1400
+ console.warn("Parser failed to process response", response, e);
1401
+ throw e;
1686
1402
  }
1687
- throw cause;
1688
1403
  }
1689
- if (response.data === void 0) {
1690
- throw new Error("Asset response has no data");
1404
+ return void 0;
1405
+ }).catch((err) => {
1406
+ if (err.response) {
1407
+ let response = err.response;
1408
+ if (response.status === 404) {
1409
+ console.debug(p3, key, "not found");
1410
+ return void 0;
1411
+ }
1691
1412
  }
1692
- return await parser.parse(response);
1693
- } catch (cause) {
1694
- throw new AssetLoadError(this, key, request.url, cause);
1695
- }
1413
+ console.debug(p3, "Failed to load", key, err == null ? void 0 : err.message);
1414
+ return void 0;
1415
+ });
1696
1416
  }
1697
1417
  assetBasePath(key) {
1698
1418
  return `${key.root ?? this.root ?? AssetLoader.ROOT}/${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1716,6 +1436,67 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1716
1436
  return this.load(key, responseParser);
1717
1437
  }
1718
1438
  };
1439
+ _HostedAssetSource.MODEL = {
1440
+ config(request) {
1441
+ },
1442
+ parse(response) {
1443
+ return response.data;
1444
+ }
1445
+ };
1446
+ _HostedAssetSource.BLOCKSTATE = {
1447
+ config(request) {
1448
+ },
1449
+ parse(response) {
1450
+ return response.data;
1451
+ }
1452
+ };
1453
+ _HostedAssetSource.META = {
1454
+ config(request) {
1455
+ },
1456
+ parse(response) {
1457
+ return response.data;
1458
+ }
1459
+ };
1460
+ _HostedAssetSource.NBT = {
1461
+ config(request) {
1462
+ request.responseType = "arraybuffer";
1463
+ },
1464
+ parse(response) {
1465
+ return NBTHelper.fromBuffer(Buffer.from(response.data));
1466
+ }
1467
+ };
1468
+ _HostedAssetSource.IMAGE = {
1469
+ config(request) {
1470
+ request.responseType = "arraybuffer";
1471
+ },
1472
+ async parse(response) {
1473
+ return await ImageLoader.processResponse(response);
1474
+ }
1475
+ };
1476
+ _HostedAssetSource.LIST = {
1477
+ config(request) {
1478
+ },
1479
+ parse(response) {
1480
+ return response.data;
1481
+ }
1482
+ };
1483
+ _HostedAssetSource.JSON = {
1484
+ config(request) {
1485
+ },
1486
+ parse(response) {
1487
+ return response.data;
1488
+ }
1489
+ };
1490
+ _HostedAssetSource.PARSER_MAP = /* @__PURE__ */ new Map([
1491
+ ["model" /* MODEL */, _HostedAssetSource.MODEL],
1492
+ ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
1493
+ ["meta" /* META */, _HostedAssetSource.META],
1494
+ ["nbt" /* NBT */, _HostedAssetSource.NBT],
1495
+ ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
1496
+ ["list" /* LIST */, _HostedAssetSource.LIST],
1497
+ ["json" /* JSON */, _HostedAssetSource.JSON]
1498
+ ]);
1499
+ var HostedAssetSource = _HostedAssetSource;
1719
1500
 
1720
1501
  // src/assets/source/archive/BrowserArchiveProxy.ts
1721
1502
  import { BlobReader, BlobWriter, ZipReader } from "@zip.js/zip.js";
@@ -1738,6 +1519,7 @@ var BrowserArchiveProxy = class {
1738
1519
  };
1739
1520
 
1740
1521
  // src/assets/source/archive/ArchiveAssetSource.ts
1522
+ var p4 = prefix("ArchiveAssetSource");
1741
1523
  var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1742
1524
  constructor(archiveProxy) {
1743
1525
  super();
@@ -1756,31 +1538,74 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1756
1538
  }
1757
1539
  async get(key, parser) {
1758
1540
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
1759
- return this.load(key, responseParser);
1760
- }
1761
- async load(key, parser) {
1541
+ console.log("ArchiveAssetSource.get", key, parser);
1542
+ let entries = await this.getEntries();
1762
1543
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1763
- let url;
1764
- try {
1765
- const entry = await this.getEntry(path);
1766
- if (!entry) {
1767
- return void 0;
1544
+ console.log(path);
1545
+ const entry = await this.getEntry(path);
1546
+ console.log(entry);
1547
+ if (!entry) {
1548
+ return void 0;
1549
+ }
1550
+ let blob = await entry.getData();
1551
+ const url = URL.createObjectURL(blob);
1552
+ console.log(url);
1553
+ let req = {
1554
+ url
1555
+ };
1556
+ responseParser.config(req);
1557
+ return Requests.genericRequest(req).then((response) => {
1558
+ if (response && response.data) {
1559
+ try {
1560
+ return responseParser.parse(response);
1561
+ } catch (e) {
1562
+ console.warn("Parser failed to process response", response, e);
1563
+ throw e;
1564
+ }
1565
+ }
1566
+ return void 0;
1567
+ }).catch((err) => {
1568
+ if (err.response) {
1569
+ let response = err.response;
1570
+ if (response.status === 404) {
1571
+ console.debug(p4, key, "not found");
1572
+ return void 0;
1573
+ }
1768
1574
  }
1769
- url = URL.createObjectURL(await entry.getData());
1770
- const request = { url };
1771
- parser.config(request);
1772
- const response = await Requests.genericRequest(request);
1773
- if (response.data === void 0) {
1774
- throw new Error("Asset response has no data");
1575
+ console.debug(p4, "Failed to load", key, err == null ? void 0 : err.message);
1576
+ return void 0;
1577
+ });
1578
+ }
1579
+ //TODO: abstract this
1580
+ async load(key, parser) {
1581
+ console.info(p4, "Loading", key);
1582
+ const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1583
+ console.debug(p4, url);
1584
+ let req = {
1585
+ url
1586
+ };
1587
+ parser.config(req);
1588
+ return await Requests.genericRequest(req).then((response) => {
1589
+ if (response && response.data) {
1590
+ try {
1591
+ return parser.parse(response);
1592
+ } catch (e) {
1593
+ console.warn("Parser failed to process response", response, e);
1594
+ throw e;
1595
+ }
1775
1596
  }
1776
- return await parser.parse(response);
1777
- } catch (cause) {
1778
- throw new AssetLoadError(this, key, path, cause);
1779
- } finally {
1780
- if (url !== void 0) {
1781
- URL.revokeObjectURL(url);
1597
+ return void 0;
1598
+ }).catch((err) => {
1599
+ if (err.response) {
1600
+ let response = err.response;
1601
+ if (response.status === 404) {
1602
+ console.debug(p4, key, "not found");
1603
+ return void 0;
1604
+ }
1782
1605
  }
1783
- }
1606
+ console.debug(p4, "Failed to load", key, err == null ? void 0 : err.message);
1607
+ return void 0;
1608
+ });
1784
1609
  }
1785
1610
  assetBasePath(key) {
1786
1611
  return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1788,23 +1613,18 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1788
1613
  };
1789
1614
 
1790
1615
  // src/assets/AssetLoader.ts
1791
- var p4 = prefix("AssetLoader");
1792
- var AssetLoader = class {
1793
- static {
1794
- this.ROOT = DEFAULT_ROOT;
1795
- }
1796
- static {
1797
- this._SOURCES = [];
1798
- }
1616
+ var import_ts_deepmerge3 = __toESM(require_dist());
1617
+ var p5 = prefix("AssetLoader");
1618
+ var _AssetLoader = class _AssetLoader {
1799
1619
  static addSource(key, source, override = true) {
1800
1620
  if (override) {
1801
1621
  const existing = this.removeSource(key);
1802
1622
  if (existing) {
1803
- console.log(p4, "Removed existing AssetSource", key);
1623
+ console.log(p5, "Removed existing AssetSource", key);
1804
1624
  }
1805
1625
  }
1806
1626
  this._SOURCES.unshift({ key, source });
1807
- console.log(p4, "Added AssetSource", key);
1627
+ console.log(p5, "Added AssetSource", key);
1808
1628
  }
1809
1629
  static removeSource(key) {
1810
1630
  const index = this._SOURCES.findIndex((s) => s.key === key);
@@ -1816,11 +1636,8 @@ var AssetLoader = class {
1816
1636
  }
1817
1637
  return void 0;
1818
1638
  }
1819
- static {
1820
- this.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1821
- this.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1822
- }
1823
1639
  static async getAll(key, parser) {
1640
+ console.log(this._SOURCES);
1824
1641
  let promises = [];
1825
1642
  for (const source of this._SOURCES) {
1826
1643
  promises.push(source.source.get(key, parser));
@@ -1829,36 +1646,31 @@ var AssetLoader = class {
1829
1646
  return results.filter((r) => r != void 0);
1830
1647
  });
1831
1648
  }
1832
- /** Returns the first defined result in source-priority order, without merging assets. */
1833
1649
  static async get(key, parser) {
1834
- const keys = [key];
1835
- if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
1836
- keys.push(new AssetKey(
1837
- key.namespace,
1838
- key.path,
1839
- key.assetType === "structure" ? "structures" : "structure",
1840
- key.type,
1841
- key.rootType,
1842
- key.extension,
1843
- key.root
1844
- ));
1845
- }
1846
- return (await this.getFirst(keys, parser))?.asset;
1847
- }
1848
- /** Tries each path within a source before considering lower-priority sources. */
1849
- static async getFirst(keys, parser) {
1850
- const sources = [...this._SOURCES];
1851
- for (const source of sources) {
1852
- for (const key of keys) {
1853
- const result = await source.source.get(key, parser);
1854
- if (result !== void 0) {
1855
- return { key, asset: result };
1650
+ console.log(this._SOURCES);
1651
+ let promises = [];
1652
+ for (const source of this._SOURCES) {
1653
+ promises.push(source.source.get(key, parser));
1654
+ }
1655
+ return Promise.all(promises).then((results) => {
1656
+ const fallback = results[results.length - 1];
1657
+ for (const result of results) {
1658
+ if (result) {
1659
+ if (fallback) {
1660
+ return (0, import_ts_deepmerge3.default)({}, fallback, result);
1661
+ }
1662
+ return result;
1856
1663
  }
1857
1664
  }
1858
- }
1859
- return void 0;
1665
+ return void 0;
1666
+ });
1860
1667
  }
1861
1668
  };
1669
+ _AssetLoader.ROOT = DEFAULT_ROOT;
1670
+ _AssetLoader._SOURCES = [];
1671
+ _AssetLoader.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1672
+ _AssetLoader.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1673
+ var AssetLoader = _AssetLoader;
1862
1674
 
1863
1675
  // src/assets/ModelTextures.ts
1864
1676
  var ModelTextures = class {
@@ -1866,21 +1678,11 @@ var ModelTextures = class {
1866
1678
  return this._persistentMetaCache ??= PersistentCache.open("minerender-texturemeta");
1867
1679
  }
1868
1680
  static async get(key) {
1869
- const keyStr = key.serialize();
1870
- const pending = this.preload(key);
1871
- const cached = Caching.textureAssetCache.getIfPresent(keyStr);
1872
- try {
1873
- const asset = await pending;
1874
- if (asset) {
1875
- return await ImageLoader.infoToCanvasData(asset);
1876
- }
1877
- return void 0;
1878
- } catch (err) {
1879
- if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
1880
- Caching.textureAssetCache.invalidate(keyStr);
1881
- }
1882
- throw err;
1681
+ const asset = await this.preload(key);
1682
+ if (asset) {
1683
+ return ImageLoader.infoToCanvasData(asset);
1883
1684
  }
1685
+ return void 0;
1884
1686
  }
1885
1687
  static async preload(key) {
1886
1688
  const keyStr = key.serialize();
@@ -1954,28 +1756,7 @@ var CanvasImage = class {
1954
1756
  };
1955
1757
 
1956
1758
  // src/Ticker.ts
1957
- var Ticker = class _Ticker {
1958
- static {
1959
- this.TPS = 20;
1960
- }
1961
- static {
1962
- this.counter = 0;
1963
- }
1964
- static {
1965
- this._tickers = /* @__PURE__ */ new Map();
1966
- }
1967
- static {
1968
- this.oneSecondTps = 0;
1969
- }
1970
- static {
1971
- this.oneSecondTicks = 0;
1972
- }
1973
- static {
1974
- this.fiveSecondTps = 0;
1975
- }
1976
- static {
1977
- this.fiveSecondTicks = 0;
1978
- }
1759
+ var _Ticker = class _Ticker {
1979
1760
  static schedule(fn, ms) {
1980
1761
  const handle = setInterval(fn, ms);
1981
1762
  const unref = handle.unref;
@@ -2037,6 +1818,14 @@ var Ticker = class _Ticker {
2037
1818
  this._tickers.clear();
2038
1819
  }
2039
1820
  };
1821
+ _Ticker.TPS = 20;
1822
+ _Ticker.counter = 0;
1823
+ _Ticker._tickers = /* @__PURE__ */ new Map();
1824
+ _Ticker.oneSecondTps = 0;
1825
+ _Ticker.oneSecondTicks = 0;
1826
+ _Ticker.fiveSecondTps = 0;
1827
+ _Ticker.fiveSecondTicks = 0;
1828
+ var Ticker = _Ticker;
2040
1829
 
2041
1830
  // src/texture/TextureAtlas.ts
2042
1831
  var TextureAtlas = class {
@@ -2062,9 +1851,6 @@ var TextureAtlas = class {
2062
1851
 
2063
1852
  // src/model/ModelGenerator.ts
2064
1853
  var ModelGenerator = class {
2065
- static {
2066
- this.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2067
- }
2068
1854
  static generateItemModel(imageData, layer) {
2069
1855
  const mainElement = {
2070
1856
  from: [0, 0, 7.5],
@@ -2084,9 +1870,10 @@ var ModelGenerator = class {
2084
1870
  return [mainElement];
2085
1871
  }
2086
1872
  };
1873
+ ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2087
1874
 
2088
1875
  // src/UVMapper.ts
2089
- var p5 = prefix("UVMapper");
1876
+ var p6 = prefix("UVMapper");
2090
1877
  var DEFAULT_UV = [0, 0, 16, 16];
2091
1878
  var X = 0;
2092
1879
  var Y = 1;
@@ -2259,11 +2046,12 @@ var UVMapper = class {
2259
2046
  return [tl, tr, bl, br];
2260
2047
  }
2261
2048
  static async createAtlas(originalModel) {
2049
+ var _a;
2262
2050
  const textureMap = {};
2263
2051
  const metaMap = {};
2264
2052
  const model = { ...originalModel };
2265
2053
  const isItemModel = !("elements" in model);
2266
- console.debug(p5, "Creating Atlas for", model.key);
2054
+ console.debug(p6, "Creating Atlas for", model.key);
2267
2055
  if (model.textures) {
2268
2056
  const promises = [];
2269
2057
  const uniqueTextureNames = [];
@@ -2277,7 +2065,7 @@ var UVMapper = class {
2277
2065
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
2278
2066
  promises.push(ModelTextures.get(assetKey).then((asset) => {
2279
2067
  if (!asset) {
2280
- console.warn(p5, "Missing texture", assetKey);
2068
+ console.warn(p6, "Missing texture", assetKey);
2281
2069
  return;
2282
2070
  }
2283
2071
  textureMap[textureKey] = new WrappedImage(asset);
@@ -2289,7 +2077,7 @@ var UVMapper = class {
2289
2077
  }
2290
2078
  await Promise.all(promises);
2291
2079
  const textureCount = uniqueTextureNames.length;
2292
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
2080
+ console.debug(p6, "Creating Atlas for", textureCount, "textures");
2293
2081
  this.fillMissingTextureKeys(model.textures, textureMap);
2294
2082
  this.fillMissingTextureKeys(model.textures, metaMap);
2295
2083
  const sizes = {};
@@ -2309,7 +2097,7 @@ var UVMapper = class {
2309
2097
  this.fillMissingTextureKeys(model.textures, sizes);
2310
2098
  const s = Math.ceil(Math.sqrt(textureCount + 1));
2311
2099
  const size = Math.ceil(s * maxWidth);
2312
- console.debug(p5, "Atlas size:", size);
2100
+ console.debug(p6, "Atlas size:", size);
2313
2101
  const squaredSize = size * size;
2314
2102
  const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
2315
2103
  const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
@@ -2338,15 +2126,16 @@ var UVMapper = class {
2338
2126
  if (texture.animated) {
2339
2127
  hasAnimation = true;
2340
2128
  const meta = metaMap[textureKey];
2341
- const frameTime = meta?.animation?.frametime ?? 1;
2129
+ const frameTime = ((_a = meta == null ? void 0 : meta.animation) == null ? void 0 : _a.frametime) ?? 1;
2342
2130
  console.log(meta);
2343
2131
  console.log(frameTime);
2344
2132
  let t = 0;
2345
2133
  let f = 0;
2346
2134
  animatorFunctions[textureKey] = () => {
2135
+ var _a2;
2347
2136
  if (t++ >= frameTime) {
2348
2137
  t = 0;
2349
- const frames = meta?.animation?.frames;
2138
+ const frames = (_a2 = meta == null ? void 0 : meta.animation) == null ? void 0 : _a2.frames;
2350
2139
  const frame = frames ? frames[f] : f;
2351
2140
  image.putData(texture.getFrameSectionData(frame), x, y, 0, 0, maxWidth, maxWidth);
2352
2141
  f++;
@@ -2364,10 +2153,10 @@ var UVMapper = class {
2364
2153
  }
2365
2154
  }
2366
2155
  const atlasImageData = image.toDataURL();
2367
- console.log(p5, "Atlas Image for", model.key, atlasImageData);
2156
+ console.log(p6, "Atlas Image for", model.key, atlasImageData);
2368
2157
  this.fillMissingTextureKeys(model.textures, positions);
2369
2158
  if (isItemModel) {
2370
- console.debug(p5, "Generating item model for", model);
2159
+ console.debug(p6, "Generating item model for", model);
2371
2160
  model.elements = [];
2372
2161
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2373
2162
  const textureImage = textureMap[layerName];
@@ -2375,7 +2164,7 @@ var UVMapper = class {
2375
2164
  model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2376
2165
  }
2377
2166
  }
2378
- console.debug(p5, "Item model elements", model.elements);
2167
+ console.debug(p6, "Item model elements", model.elements);
2379
2168
  }
2380
2169
  if (!model.elements) {
2381
2170
  }
@@ -2393,13 +2182,17 @@ var UVMapper = class {
2393
2182
  this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
2394
2183
  continue;
2395
2184
  }
2396
- if (!face.texture) continue;
2397
2185
  if (!face.uv) {
2398
2186
  face.uv = this.getFallbackUv(element, faceName);
2399
2187
  }
2400
- const faceTexture = face.texture.substr(1);
2401
- const texPosition = positions[faceTexture] || [0, 0];
2402
- const texSize = sizes[faceTexture] || [16, 16];
2188
+ let faceTexture = face.texture;
2189
+ let texPosition;
2190
+ let texSize;
2191
+ if (faceTexture) {
2192
+ faceTexture = faceTexture.substr(1);
2193
+ texPosition = positions[faceTexture] || [0, 0];
2194
+ texSize = sizes[faceTexture] || [16, 16];
2195
+ }
2403
2196
  let texPosV = new Vector2(texPosition[0], texPosition[1]);
2404
2197
  const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
2405
2198
  tl.add(texPosV);
@@ -2431,7 +2224,7 @@ var UVMapper = class {
2431
2224
  hasTransparency
2432
2225
  );
2433
2226
  } else {
2434
- console.warn(p5, "Model does not have any textures", model);
2227
+ console.warn(p6, "Model does not have any textures", model);
2435
2228
  }
2436
2229
  return void 0;
2437
2230
  }
@@ -2569,20 +2362,17 @@ function shutdown() {
2569
2362
  }
2570
2363
 
2571
2364
  // src/assets/Entities.ts
2365
+ import { Memoize as Memoize3 } from "typescript-memoize";
2572
2366
  var Entities = class {
2573
2367
  static async getBlockEntityModels() {
2574
2368
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
2575
2369
  console.log(key);
2576
- return Caching.entityModelsCache.get(key.serialize(), () => {
2577
- return AssetLoader.get(key, "json" /* JSON */);
2578
- });
2370
+ return AssetLoader.get(key, "json" /* JSON */);
2579
2371
  }
2580
2372
  static async getEntityModels() {
2581
2373
  const key = AssetKey.parse("models", "minerender:entityModels");
2582
2374
  console.log(key);
2583
- return Caching.entityModelsCache.get(key.serialize(), () => {
2584
- return AssetLoader.get(key, "json" /* JSON */);
2585
- });
2375
+ return AssetLoader.get(key, "json" /* JSON */);
2586
2376
  }
2587
2377
  // BlockEntity names are hardcoded
2588
2378
  static async getBlockList() {
@@ -2628,6 +2418,12 @@ var Entities = class {
2628
2418
  };
2629
2419
  }
2630
2420
  };
2421
+ __decorateClass([
2422
+ Memoize3()
2423
+ ], Entities, "getBlockEntityModels", 1);
2424
+ __decorateClass([
2425
+ Memoize3()
2426
+ ], Entities, "getEntityModels", 1);
2631
2427
  var EntityModels = class {
2632
2428
  };
2633
2429
  var BlockEntityModels = class {
@@ -2691,26 +2487,18 @@ var MineRenderError = class _MineRenderError extends Error {
2691
2487
  };
2692
2488
 
2693
2489
  // src/renderer/SceneObject.ts
2694
- var import_ts_deepmerge3 = __toESM(require_dist());
2695
- var p6 = prefix("SceneObject");
2696
- var SceneObject = class _SceneObject extends Object3D2 {
2490
+ var import_ts_deepmerge4 = __toESM(require_dist());
2491
+ var p7 = prefix("SceneObject");
2492
+ var _SceneObject = class _SceneObject extends Object3D2 {
2697
2493
  constructor(options) {
2698
2494
  super();
2699
2495
  this.isSceneObject = true;
2700
2496
  this.materialCallbacks = {};
2701
2497
  this._isInstanced = false;
2702
2498
  this._instanceCounter = 0;
2703
- this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2499
+ this.options = (0, import_ts_deepmerge4.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2704
2500
  console.log("SceneObject options", this.options);
2705
2501
  }
2706
- static {
2707
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
2708
- instanceMeshes: true,
2709
- maxInstanceCount: 50,
2710
- mergeMeshes: true,
2711
- wireframe: false
2712
- });
2713
- }
2714
2502
  set scene(scene) {
2715
2503
  if (!!this._scene) throw new MineRenderError("Scene already set");
2716
2504
  this._scene = scene;
@@ -2879,9 +2667,9 @@ var SceneObject = class _SceneObject extends Object3D2 {
2879
2667
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2880
2668
  const i = this._instanceCounter++;
2881
2669
  this.setMatrixAt(i, new Matrix42());
2882
- console.debug(p6, "nextInstance " + i);
2670
+ console.debug(p7, "nextInstance " + i);
2883
2671
  if (i === this.options.maxInstanceCount) {
2884
- console.warn(p6, "Max instance count reached for " + this);
2672
+ console.warn(p7, "Max instance count reached for " + this);
2885
2673
  }
2886
2674
  if (this.scene) {
2887
2675
  this.scene.stats.instanceCount++;
@@ -3052,29 +2840,34 @@ var SceneObject = class _SceneObject extends Object3D2 {
3052
2840
  this.notifyDirty();
3053
2841
  }
3054
2842
  removeFromScene() {
3055
- this._scene?.remove(this);
2843
+ var _a;
2844
+ (_a = this._scene) == null ? void 0 : _a.remove(this);
3056
2845
  this.notifyDirty();
3057
2846
  }
3058
2847
  //</editor-fold>
3059
2848
  };
2849
+ _SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, {
2850
+ instanceMeshes: true,
2851
+ maxInstanceCount: 50,
2852
+ mergeMeshes: true,
2853
+ wireframe: false
2854
+ });
2855
+ var SceneObject = _SceneObject;
3060
2856
  function isSceneObject(obj) {
3061
2857
  return obj.isSceneObject;
3062
2858
  }
3063
2859
 
3064
2860
  // src/entity/scene/EntityObject.ts
3065
- var import_ts_deepmerge4 = __toESM(require_dist());
2861
+ var import_ts_deepmerge5 = __toESM(require_dist());
3066
2862
  import { Object3D as Object3D3 } from "three";
3067
- import * as THREE3 from "three";
2863
+ import * as THREE2 from "three";
3068
2864
  var EntityObject = class extends SceneObject {
3069
2865
  constructor(entity, options) {
3070
2866
  super();
3071
2867
  this.entity = entity;
3072
2868
  this.isEntityObject = true;
3073
2869
  this.meshesCreated = false;
3074
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3075
- }
3076
- static {
3077
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
2870
+ this.options = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3078
2871
  }
3079
2872
  async init() {
3080
2873
  this.createMeshes();
@@ -3083,19 +2876,17 @@ var EntityObject = class extends SceneObject {
3083
2876
  dispose() {
3084
2877
  super.dispose();
3085
2878
  }
3086
- get textureKey() {
3087
- return new AssetKey(
3088
- this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
2879
+ async loadTextures() {
2880
+ var _a;
2881
+ this.imageData = await ModelTextures.get(new AssetKey(
2882
+ ((_a = this.entity.key) == null ? void 0 : _a.namespace) ?? DEFAULT_NAMESPACE,
3089
2883
  this.entity.key.path,
3090
2884
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
3091
2885
  "textures",
3092
2886
  "entity",
3093
2887
  "assets",
3094
2888
  ".png"
3095
- );
3096
- }
3097
- async loadTextures() {
3098
- this.imageData = await ModelTextures.get(this.textureKey);
2889
+ ));
3099
2890
  }
3100
2891
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3101
2892
  createMeshes(force = false) {
@@ -3114,8 +2905,8 @@ var EntityObject = class extends SceneObject {
3114
2905
  const l = cube.maxZ - cube.minZ;
3115
2906
  const uv = texture.toUvArray(w, h, l);
3116
2907
  const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3117
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3118
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
2908
+ cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
2909
+ cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
3119
2910
  applyModelPartRotation(part, cubeGeo);
3120
2911
  const mesh = this.createMesh(partName, cubeGeo, mat);
3121
2912
  partAnchor.add(mesh);
@@ -3128,25 +2919,24 @@ var EntityObject = class extends SceneObject {
3128
2919
  this.meshesCreated = true;
3129
2920
  }
3130
2921
  async applyTextures() {
3131
- const assetKeyStr = this.textureKey.serialize();
3132
- const keyStr = `entity:${assetKeyStr}`;
3133
- let mat = Caching.materialCache.getIfPresent(keyStr);
3134
- if (!mat) {
3135
- const pending = this.loadTextures();
3136
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3137
- await pending;
3138
- if (!this.imageData) return;
3139
- const canvas = this.imageData.data.canvas;
3140
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3141
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3142
- this.imageData = void 0;
3143
- }
3144
- this.iterateAllMeshes((mesh) => {
3145
- mesh.material = mat;
3146
- });
3147
- this.notifyDirty();
2922
+ var _a;
2923
+ const textureAsset = await ModelTextures.preload(new AssetKey(
2924
+ ((_a = this.entity.key) == null ? void 0 : _a.namespace) ?? DEFAULT_NAMESPACE,
2925
+ this.entity.key.path,
2926
+ "textures",
2927
+ "entity",
2928
+ "assets",
2929
+ ".png"
2930
+ ));
2931
+ if (textureAsset) {
2932
+ let mat = Materials.getImage({ texture: { src: textureAsset.src } });
2933
+ this.iterateAllMeshes((mesh) => {
2934
+ mesh.material = mat;
2935
+ });
2936
+ }
3148
2937
  }
3149
2938
  };
2939
+ EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3150
2940
  function isEntityObject(obj) {
3151
2941
  return obj.isEntityObject;
3152
2942
  }
@@ -3158,7 +2948,7 @@ var GuiObject = class extends SceneObject {
3158
2948
 
3159
2949
  // src/inspector/SceneInspector.ts
3160
2950
  import { Raycaster, Vector2 as Vector22 } from "three";
3161
- var p7 = prefix("SceneInspector");
2951
+ var p8 = prefix("SceneInspector");
3162
2952
  var help = "<span>Ctrl+Click to Select<br/></span><br/>";
3163
2953
  var SceneInspector = class {
3164
2954
  constructor(renderer) {
@@ -3187,7 +2977,8 @@ var SceneInspector = class {
3187
2977
  return out;
3188
2978
  }
3189
2979
  onClick(event) {
3190
- if (event.target?.nodeName !== "CANVAS") return;
2980
+ var _a;
2981
+ if (((_a = event.target) == null ? void 0 : _a.nodeName) !== "CANVAS") return;
3191
2982
  if (!event.ctrlKey) return;
3192
2983
  setTimeout(() => {
3193
2984
  this.mouse.x = event.clientX / window.innerWidth * 2 - 1;
@@ -3227,7 +3018,7 @@ var SceneInspector = class {
3227
3018
  }
3228
3019
  selectObject(targetObject, targetIntersection) {
3229
3020
  this.selectedObject = targetObject;
3230
- console.log(p7, "selected", targetObject);
3021
+ console.log(p8, "selected", targetObject);
3231
3022
  this.redraw(targetObject, targetIntersection);
3232
3023
  }
3233
3024
  redraw(targetObject, targetIntersection) {
@@ -3525,7 +3316,7 @@ var SceneStatsDisplay = class {
3525
3316
  };
3526
3317
 
3527
3318
  // src/instance/InstanceManager.ts
3528
- var p8 = prefix("InstanceManager");
3319
+ var p9 = prefix("InstanceManager");
3529
3320
  var InstanceManager = class {
3530
3321
  constructor() {
3531
3322
  this.isInstanceManager = true;
@@ -3533,7 +3324,7 @@ var InstanceManager = class {
3533
3324
  }
3534
3325
  async get(key) {
3535
3326
  if (key in this.instanceCache) {
3536
- console.debug(p8, "key in cache", key);
3327
+ console.debug(p9, "key in cache", key);
3537
3328
  return (await this.instanceCache[key]).nextInstance();
3538
3329
  }
3539
3330
  return void 0;
@@ -3542,17 +3333,13 @@ var InstanceManager = class {
3542
3333
  if (key in this.instanceCache) {
3543
3334
  return await this.get(key);
3544
3335
  }
3545
- console.debug(p8, "key not in cache", key);
3546
- const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
3547
- this.instanceCache[key] = pending;
3548
- try {
3549
- return await pending;
3550
- } catch (error) {
3551
- if (this.instanceCache[key] === pending) {
3552
- delete this.instanceCache[key];
3553
- }
3554
- throw error;
3555
- }
3336
+ console.debug(p9, "key not in cache", key);
3337
+ this.instanceCache[key] = new Promise(async (resolve) => {
3338
+ const obj = await supplier();
3339
+ const instance = obj.nextInstance();
3340
+ resolve(instance);
3341
+ });
3342
+ return await this.instanceCache[key];
3556
3343
  }
3557
3344
  reset() {
3558
3345
  for (let instanceCacheKey in this.instanceCache) {
@@ -4151,28 +3938,26 @@ function computeMorphedAttributes(object) {
4151
3938
  }
4152
3939
 
4153
3940
  // src/model/scene/ModelObject.ts
4154
- var import_ts_deepmerge5 = __toESM(require_dist());
4155
- var p9 = prefix("ModelObject");
4156
- var ModelObject = class _ModelObject extends SceneObject {
3941
+ var import_ts_deepmerge6 = __toESM(require_dist());
3942
+ var p10 = prefix("ModelObject");
3943
+ var _ModelObject = class _ModelObject extends SceneObject {
4157
3944
  constructor(originalModel, options) {
4158
3945
  super(options);
4159
3946
  this.originalModel = originalModel;
4160
3947
  this.isModelObject = true;
4161
3948
  this.meshesCreated = false;
4162
- this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
3949
+ this.options = (0, import_ts_deepmerge6.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4163
3950
  console.log("ModelObject options", this.options);
4164
3951
  }
4165
- static {
4166
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4167
- }
4168
3952
  async init() {
4169
3953
  await this.loadTextures();
4170
3954
  this.createMeshes();
4171
3955
  this.applyTextures();
4172
3956
  }
4173
3957
  dispose() {
3958
+ var _a;
4174
3959
  super.dispose();
4175
- this.atlas?.dispose();
3960
+ (_a = this.atlas) == null ? void 0 : _a.dispose();
4176
3961
  }
4177
3962
  get textureAtlas() {
4178
3963
  return this.atlas;
@@ -4182,12 +3967,13 @@ var ModelObject = class _ModelObject extends SceneObject {
4182
3967
  this.atlas = await UVMapper.getAtlas(this.originalModel);
4183
3968
  }
4184
3969
  createMeshes(force = false) {
3970
+ var _a;
4185
3971
  if (this.meshesCreated && !force) return;
4186
3972
  const mat = Materials.MISSING_TEXTURE;
4187
3973
  let allGeos = [];
4188
3974
  if (this.atlas) {
4189
3975
  if (this.atlas.model.elements) {
4190
- this.atlas.model.elements?.forEach((el) => {
3976
+ (_a = this.atlas.model.elements) == null ? void 0 : _a.forEach((el) => {
4191
3977
  const elGeo = this._getBoxGeometryFromElement(el).clone();
4192
3978
  elGeo.applyMatrix4(new Matrix45().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4193
3979
  elGeo.applyMatrix4(new Matrix45().makeTranslation(el.from[0], el.from[1], el.from[2]));
@@ -4205,10 +3991,10 @@ var ModelObject = class _ModelObject extends SceneObject {
4205
3991
  }
4206
3992
  });
4207
3993
  } else {
4208
- console.debug(p9, this.atlas.model, "has no elements");
3994
+ console.debug(p10, this.atlas.model, "has no elements");
4209
3995
  }
4210
3996
  } else {
4211
- console.debug(p9, "Missing atlas for", this);
3997
+ console.debug(p10, "Missing atlas for", this);
4212
3998
  }
4213
3999
  if (this.options.mergeMeshes) {
4214
4000
  let combinedGeo;
@@ -4260,25 +4046,17 @@ var ModelObject = class _ModelObject extends SceneObject {
4260
4046
  }
4261
4047
  }
4262
4048
  };
4049
+ _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4050
+ var ModelObject = _ModelObject;
4263
4051
  function isModelObject(obj) {
4264
4052
  return obj.isModelObject;
4265
4053
  }
4266
4054
 
4267
4055
  // src/model/block/scene/BlockObject.ts
4268
- var import_ts_deepmerge6 = __toESM(require_dist());
4056
+ var import_ts_deepmerge7 = __toESM(require_dist());
4269
4057
  import { Euler as Euler3, Matrix4 as Matrix46, Vector3 as Vector36 } from "three";
4270
- var p10 = prefix("BlockObject");
4271
- function matchesCondition(condition, state) {
4272
- return Object.entries(condition).every(([key, value]) => {
4273
- if (Array.isArray(value)) {
4274
- if (key === "OR") return value.some((child) => matchesCondition(child, state));
4275
- if (key === "AND") return value.every((child) => matchesCondition(child, state));
4276
- return false;
4277
- }
4278
- return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4279
- });
4280
- }
4281
- var BlockObject = class _BlockObject extends SceneObject {
4058
+ var p11 = prefix("BlockObject");
4059
+ var _BlockObject = class _BlockObject extends SceneObject {
4282
4060
  constructor(blockState, options) {
4283
4061
  super(options);
4284
4062
  this.blockState = blockState;
@@ -4291,16 +4069,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4291
4069
  this._instanceModel = [];
4292
4070
  this._variants = [];
4293
4071
  this._models = [];
4294
- this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4295
- }
4296
- static {
4297
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
4298
- applyDefaultState: true
4299
- });
4072
+ this.options = (0, import_ts_deepmerge7.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4300
4073
  }
4301
4074
  async init() {
4302
4075
  if (this.options.applyDefaultState) {
4303
- const defaultState = this.blockState.key ? await BlockStates.getDefaultState(this.blockState.key) : void 0;
4076
+ const defaultState = this.blockState.key ? BlockStates.getDefaultState(this.blockState.key) : void 0;
4304
4077
  if (defaultState && Object.keys(defaultState).length > 0) {
4305
4078
  const state = {};
4306
4079
  for (let k in defaultState) {
@@ -4311,9 +4084,15 @@ var BlockObject = class _BlockObject extends SceneObject {
4311
4084
  if (this.blockState.variants) {
4312
4085
  await this.setState(Object.keys(this.blockState.variants)[0]);
4313
4086
  } else if (this.blockState.multipart) {
4314
- const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4315
- const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4316
- await this.setState(state);
4087
+ for (let part of this.blockState.multipart) {
4088
+ if (part.when && !("OR" in part.when)) {
4089
+ const k = Object.keys(part.when)[0];
4090
+ if (k) {
4091
+ await this.setState(k, part.when[k].split("|")[0]);
4092
+ break;
4093
+ }
4094
+ }
4095
+ }
4317
4096
  }
4318
4097
  }
4319
4098
  } else {
@@ -4370,11 +4149,55 @@ var BlockObject = class _BlockObject extends SceneObject {
4370
4149
  } else if (this.blockState.multipart) {
4371
4150
  for (let part of this.blockState.multipart) {
4372
4151
  if (!part.apply) {
4373
- console.debug(p10, "Missing apply for blockState part", part);
4152
+ console.debug(p11, "Missing apply for blockState part", part);
4374
4153
  continue;
4375
4154
  }
4376
- if (!part.when || matchesCondition(part.when, state)) {
4155
+ if (!part.when) {
4377
4156
  out.push(this.getSingleVariant(part.apply));
4157
+ } else {
4158
+ let matches = true;
4159
+ if ("OR" in part.when) {
4160
+ const or = part.when.OR;
4161
+ let anyMatch = false;
4162
+ for (let o of or) {
4163
+ for (let k in o) {
4164
+ const split = o[k].split("|");
4165
+ let m = false;
4166
+ for (let s of split) {
4167
+ if (`${state[k]}` === `${s}`) {
4168
+ m = true;
4169
+ break;
4170
+ }
4171
+ }
4172
+ if (m) {
4173
+ anyMatch = true;
4174
+ break;
4175
+ }
4176
+ }
4177
+ }
4178
+ if (!anyMatch) {
4179
+ matches = false;
4180
+ }
4181
+ } else {
4182
+ for (let k in part.when) {
4183
+ const split = part.when[k].split("|");
4184
+ let m = false;
4185
+ for (let s of split) {
4186
+ if (`${state[k]}` === `${s}`) {
4187
+ m = true;
4188
+ break;
4189
+ }
4190
+ }
4191
+ if (!m) {
4192
+ matches = false;
4193
+ break;
4194
+ }
4195
+ }
4196
+ }
4197
+ if (matches) {
4198
+ const variants = part.apply;
4199
+ out.push(this.getSingleVariant(variants));
4200
+ }
4378
4201
  }
4379
4202
  }
4380
4203
  }
@@ -4404,21 +4227,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4404
4227
  }
4405
4228
  }
4406
4229
  getSingleVariant(variants) {
4407
- if (!Array.isArray(variants)) return variants;
4408
- if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4409
- const total = variants.reduce((sum, variant) => {
4410
- const weight = variant.weight ?? 1;
4411
- if (!Number.isInteger(weight) || weight < 1) {
4412
- throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4413
- }
4414
- return sum + weight;
4415
- }, 0);
4416
- let choice = Math.random() * total;
4417
- for (const variant of variants) {
4418
- choice -= variant.weight ?? 1;
4419
- if (choice < 0) return variant;
4420
- }
4421
- return variants[variants.length - 1];
4230
+ if (Array.isArray(variants)) {
4231
+ return variants[0];
4232
+ } else {
4233
+ return variants;
4234
+ }
4422
4235
  }
4423
4236
  // @deprecated
4424
4237
  async createAVariant(variants, instanceInfo) {
@@ -4444,6 +4257,9 @@ var BlockObject = class _BlockObject extends SceneObject {
4444
4257
  }
4445
4258
  }
4446
4259
  obj.setRotation(rotation);
4260
+ setTimeout(() => {
4261
+ obj.setRotation(rotation);
4262
+ }, 150);
4447
4263
  console.log(obj);
4448
4264
  return obj;
4449
4265
  }
@@ -4534,15 +4350,18 @@ var BlockObject = class _BlockObject extends SceneObject {
4534
4350
  }
4535
4351
  }
4536
4352
  setPosition(position) {
4537
- this.position.copy(position);
4353
+ super.setPosition(position);
4538
4354
  for (let model of this._models) {
4539
4355
  model.setPosition(position);
4540
4356
  }
4541
- this.notifyDirty();
4542
4357
  }
4543
4358
  //TODO: should override rotation + scale methods
4544
4359
  //TODO
4545
4360
  };
4361
+ _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge7.default)({}, ModelObject.DEFAULT_OPTIONS, {
4362
+ applyDefaultState: true
4363
+ });
4364
+ var BlockObject = _BlockObject;
4546
4365
  function isBlockObject(obj) {
4547
4366
  return obj.isBlockObject;
4548
4367
  }
@@ -4567,10 +4386,11 @@ var StructureParser = class {
4567
4386
  throw new MineRenderError("Structure does not have palette(s)");
4568
4387
  }
4569
4388
  const blocks = nbt.blocks.value.value.map((block) => {
4389
+ var _a;
4570
4390
  const state = palette.value.value[block.state.value];
4571
4391
  if (state.Name.value === "minecraft:air") return void 0;
4572
4392
  const props = {};
4573
- for (let k in state.Properties?.value) {
4393
+ for (let k in (_a = state.Properties) == null ? void 0 : _a.value) {
4574
4394
  props[k] = state.Properties.value[k].value;
4575
4395
  }
4576
4396
  return {
@@ -4589,7 +4409,7 @@ var StructureParser = class {
4589
4409
 
4590
4410
  // src/renderer/MineRenderScene.ts
4591
4411
  import { Scene as Scene2 } from "three";
4592
- var import_ts_deepmerge8 = __toESM(require_dist());
4412
+ var import_ts_deepmerge9 = __toESM(require_dist());
4593
4413
 
4594
4414
  // src/skin/SkinPart.ts
4595
4415
  var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
@@ -5320,7 +5140,7 @@ var slimSkinGeometries = {
5320
5140
  };
5321
5141
 
5322
5142
  // src/skin/scene/SkinObject.ts
5323
- var import_ts_deepmerge7 = __toESM(require_dist());
5143
+ var import_ts_deepmerge8 = __toESM(require_dist());
5324
5144
  var SkinObject = class extends SceneObject {
5325
5145
  constructor(options) {
5326
5146
  super();
@@ -5328,7 +5148,7 @@ var SkinObject = class extends SceneObject {
5328
5148
  this.legacy = false;
5329
5149
  this.skinTextureWidth = 64;
5330
5150
  this.skinTextureHeight = 64;
5331
- this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5151
+ this.options = (0, import_ts_deepmerge8.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5332
5152
  }
5333
5153
  async init() {
5334
5154
  this.createMeshes();
@@ -5432,7 +5252,7 @@ var SkinObject = class extends SceneObject {
5432
5252
  };
5433
5253
 
5434
5254
  // src/renderer/MineRenderScene.ts
5435
- var MineRenderScene = class _MineRenderScene extends Scene2 {
5255
+ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5436
5256
  constructor(options) {
5437
5257
  super();
5438
5258
  this.isMineRenderScene = true;
@@ -5441,14 +5261,12 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5441
5261
  this.dirty = true;
5442
5262
  this.observedObjects = /* @__PURE__ */ new Set();
5443
5263
  this.onObjectChange = (event) => {
5444
- if (event.target?.parent === this) {
5264
+ var _a;
5265
+ if (((_a = event.target) == null ? void 0 : _a.parent) === this) {
5445
5266
  this.dirty = true;
5446
5267
  }
5447
5268
  };
5448
- this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5449
- }
5450
- static {
5451
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
5269
+ this.options = (0, import_ts_deepmerge9.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5452
5270
  }
5453
5271
  add(...objects) {
5454
5272
  for (const object of objects) {
@@ -5456,7 +5274,7 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5456
5274
  try {
5457
5275
  super.add(object);
5458
5276
  } finally {
5459
- if (object?.isObject3D && object !== this) {
5277
+ if ((object == null ? void 0 : object.isObject3D) && object !== this) {
5460
5278
  this.updateObjectRegistration(object, object.parent === this);
5461
5279
  }
5462
5280
  }
@@ -5499,12 +5317,13 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5499
5317
  return this.add(...object);
5500
5318
  }
5501
5319
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
5320
+ var _a, _b;
5502
5321
  console.log("addSceneObject", asset);
5503
5322
  console.log("parent", parent);
5504
5323
  console.log(_options);
5505
5324
  this.dirty = true;
5506
5325
  const obj = await objectSupplier();
5507
- if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
5326
+ if (((_a = obj == null ? void 0 : obj.options) == null ? void 0 : _a.instanceMeshes) && asset.key && ((_b = asset.key) == null ? void 0 : _b.assetType) === "models") {
5508
5327
  console.log("instanceMeshes + key");
5509
5328
  const key = asset.key.serialize();
5510
5329
  return this.instanceManager.getOrCreate(key, async () => {
@@ -5544,1147 +5363,1117 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5544
5363
  return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
5545
5364
  }
5546
5365
  };
5366
+ _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {});
5367
+ var MineRenderScene = _MineRenderScene;
5547
5368
  function isMineRenderScene(obj) {
5548
5369
  return obj.isMineRenderScene;
5549
5370
  }
5550
5371
 
5551
5372
  // src/renderer/Renderer.ts
5552
- import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector38, WebGLRenderer } from "three";
5553
- var import_ts_deepmerge9 = __toESM(require_dist());
5373
+ import { AxesHelper as AxesHelper3, GridHelper, LinearEncoding, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, Vector3 as Vector37, WebGLRenderer } from "three";
5374
+ var import_ts_deepmerge10 = __toESM(require_dist());
5554
5375
  import Stats from "stats.js";
5555
5376
  import { EffectComposer, RenderPass } from "postprocessing";
5556
-
5557
- // src/three/OrbitControls.js
5558
- import {
5559
- EventDispatcher,
5560
- MOUSE,
5561
- Quaternion as Quaternion3,
5562
- Spherical,
5563
- TOUCH,
5564
- Vector2 as Vector23,
5565
- Vector3 as Vector37
5566
- } from "three";
5567
- var _changeEvent = { type: "change" };
5568
- var _startEvent = { type: "start" };
5569
- var _endEvent = { type: "end" };
5570
- var OrbitControls = class extends EventDispatcher {
5571
- constructor(object, domElement) {
5572
- super();
5573
- if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5574
- if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5575
- this.object = object;
5576
- this.domElement = domElement;
5577
- this.domElement.style.touchAction = "none";
5578
- this.enabled = true;
5579
- this.target = new Vector37();
5580
- this.minDistance = 0;
5581
- this.maxDistance = Infinity;
5582
- this.minZoom = 0;
5583
- this.maxZoom = Infinity;
5584
- this.minPolarAngle = 0;
5585
- this.maxPolarAngle = Math.PI;
5586
- this.minAzimuthAngle = -Infinity;
5587
- this.maxAzimuthAngle = Infinity;
5588
- this.enableDamping = false;
5589
- this.dampingFactor = 0.05;
5590
- this.enableZoom = true;
5591
- this.zoomSpeed = 1;
5592
- this.enableRotate = true;
5593
- this.rotateSpeed = 1;
5594
- this.enablePan = true;
5595
- this.panSpeed = 1;
5596
- this.screenSpacePanning = true;
5597
- this.keyPanSpeed = 7;
5598
- this.autoRotate = false;
5599
- this.autoRotateSpeed = 2;
5600
- this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5601
- this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
5602
- this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
5603
- this.target0 = this.target.clone();
5604
- this.position0 = this.object.position.clone();
5605
- this.zoom0 = this.object.zoom;
5606
- this._domElementKeyEvents = null;
5607
- this.getPolarAngle = function() {
5608
- return spherical.phi;
5609
- };
5610
- this.getAzimuthalAngle = function() {
5611
- return spherical.theta;
5612
- };
5613
- this.getDistance = function() {
5614
- return this.object.position.distanceTo(this.target);
5615
- };
5616
- this.saveState = function() {
5617
- scope.target0.copy(scope.target);
5618
- scope.position0.copy(scope.object.position);
5619
- scope.zoom0 = scope.object.zoom;
5620
- };
5621
- this.reset = function() {
5622
- scope.target.copy(scope.target0);
5623
- scope.object.position.copy(scope.position0);
5624
- scope.object.zoom = scope.zoom0;
5625
- scope.object.updateProjectionMatrix();
5626
- scope.dispatchEvent(_changeEvent);
5627
- scope.update();
5628
- state = STATE.NONE;
5629
- };
5630
- this.update = function() {
5631
- const offset = new Vector37();
5632
- const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector37(0, 1, 0));
5633
- const quatInverse = quat.clone().invert();
5634
- const lastPosition = new Vector37();
5635
- const lastQuaternion = new Quaternion3();
5636
- const twoPI = 2 * Math.PI;
5637
- return function update() {
5638
- const position = scope.object.position;
5639
- offset.copy(position).sub(scope.target);
5640
- offset.applyQuaternion(quat);
5641
- spherical.setFromVector3(offset);
5642
- if (scope.autoRotate && state === STATE.NONE) {
5643
- rotateLeft(getAutoRotationAngle());
5644
- }
5645
- if (scope.enableDamping) {
5646
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5647
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5648
- } else {
5649
- spherical.theta += sphericalDelta.theta;
5650
- spherical.phi += sphericalDelta.phi;
5651
- }
5652
- let min = scope.minAzimuthAngle;
5653
- let max = scope.maxAzimuthAngle;
5654
- if (isFinite(min) && isFinite(max)) {
5655
- if (min < -Math.PI) min += twoPI;
5656
- else if (min > Math.PI) min -= twoPI;
5657
- if (max < -Math.PI) max += twoPI;
5658
- else if (max > Math.PI) max -= twoPI;
5659
- if (min <= max) {
5660
- spherical.theta = Math.max(min, Math.min(max, spherical.theta));
5661
- } else {
5662
- spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
5663
- }
5664
- }
5665
- spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5666
- spherical.makeSafe();
5667
- spherical.radius *= scale;
5668
- spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5669
- if (scope.enableDamping === true) {
5670
- scope.target.addScaledVector(panOffset, scope.dampingFactor);
5671
- } else {
5672
- scope.target.add(panOffset);
5673
- }
5674
- offset.setFromSpherical(spherical);
5675
- offset.applyQuaternion(quatInverse);
5676
- position.copy(scope.target).add(offset);
5677
- scope.object.lookAt(scope.target);
5678
- if (scope.enableDamping === true) {
5679
- sphericalDelta.theta *= 1 - scope.dampingFactor;
5680
- sphericalDelta.phi *= 1 - scope.dampingFactor;
5681
- panOffset.multiplyScalar(1 - scope.dampingFactor);
5682
- } else {
5683
- sphericalDelta.set(0, 0, 0);
5684
- panOffset.set(0, 0, 0);
5685
- }
5686
- scale = 1;
5687
- if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5688
- scope.dispatchEvent(_changeEvent);
5689
- lastPosition.copy(scope.object.position);
5690
- lastQuaternion.copy(scope.object.quaternion);
5691
- zoomChanged = false;
5692
- return true;
5693
- }
5694
- return false;
5695
- };
5696
- }();
5697
- this.dispose = function() {
5698
- scope.domElement.removeEventListener("contextmenu", onContextMenu);
5699
- scope.domElement.removeEventListener("pointerdown", onPointerDown);
5700
- scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5701
- scope.domElement.removeEventListener("wheel", onMouseWheel);
5702
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5703
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5704
- if (scope._domElementKeyEvents !== null) {
5705
- scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
5706
- }
5707
- };
5708
- const scope = this;
5709
- const STATE = {
5710
- NONE: -1,
5711
- ROTATE: 0,
5712
- DOLLY: 1,
5713
- PAN: 2,
5714
- TOUCH_ROTATE: 3,
5715
- TOUCH_PAN: 4,
5716
- TOUCH_DOLLY_PAN: 5,
5717
- TOUCH_DOLLY_ROTATE: 6
5377
+ var _Renderer = class _Renderer {
5378
+ constructor(options) {
5379
+ this._dirty = true;
5380
+ this._animationTimer = void 0;
5381
+ this._animationFrame = void 0;
5382
+ this._resizeListener = void 0;
5383
+ this._disposed = false;
5384
+ this._debugHelpers = [];
5385
+ this._eventDispatchers = /* @__PURE__ */ new Map();
5386
+ this._changeListener = () => {
5387
+ this._dirty = true;
5718
5388
  };
5719
- let state = STATE.NONE;
5720
- const EPS = 1e-6;
5721
- const spherical = new Spherical();
5722
- const sphericalDelta = new Spherical();
5723
- let scale = 1;
5724
- const panOffset = new Vector37();
5725
- let zoomChanged = false;
5726
- const rotateStart = new Vector23();
5727
- const rotateEnd = new Vector23();
5728
- const rotateDelta = new Vector23();
5729
- const panStart = new Vector23();
5730
- const panEnd = new Vector23();
5731
- const panDelta = new Vector23();
5732
- const dollyStart = new Vector23();
5733
- const dollyEnd = new Vector23();
5734
- const dollyDelta = new Vector23();
5735
- const pointers = [];
5736
- const pointerPositions = {};
5737
- function getAutoRotationAngle() {
5738
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
5739
- }
5740
- function getZoomScale() {
5741
- return Math.pow(0.95, scope.zoomSpeed);
5389
+ this.options = (0, import_ts_deepmerge10.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
5390
+ this._animationLoop = this.animate.bind(this);
5391
+ this._fpsTimer = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
5392
+ this._scene = this.createScene();
5393
+ this._camera = this.createCamera();
5394
+ this._renderer = this.createRenderer();
5395
+ this._composer = this.createComposer();
5396
+ if (this.options.render.stats) {
5397
+ this._stats = new Stats();
5398
+ document.body.appendChild(this._stats.dom);
5742
5399
  }
5743
- function rotateLeft(angle) {
5744
- sphericalDelta.theta -= angle;
5400
+ this.init();
5401
+ }
5402
+ //<editor-fold desc="INIT">
5403
+ createScene() {
5404
+ return new MineRenderScene();
5405
+ }
5406
+ createCamera() {
5407
+ switch (this.options.camera.type) {
5408
+ case "perspective":
5409
+ default:
5410
+ return new PerspectiveCamera(
5411
+ this.options.camera.perspective.fov,
5412
+ this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
5413
+ this.options.camera.near,
5414
+ this.options.camera.far
5415
+ );
5416
+ case "orthographic":
5417
+ return new OrthographicCamera(
5418
+ this.options.camera.orthographic.left ?? this.viewWidth / -2,
5419
+ this.options.camera.orthographic.right ?? this.viewWidth / 2,
5420
+ this.options.camera.orthographic.top ?? this.viewHeight / 2,
5421
+ this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
5422
+ this.options.camera.near,
5423
+ this.options.camera.far
5424
+ );
5745
5425
  }
5746
- function rotateUp(angle) {
5747
- sphericalDelta.phi -= angle;
5426
+ }
5427
+ createRenderer() {
5428
+ const renderer = new WebGLRenderer({
5429
+ antialias: this.options.render.antialias,
5430
+ alpha: true,
5431
+ powerPreference: "high-performance",
5432
+ depth: true
5433
+ });
5434
+ renderer.setClearColor(0, 0);
5435
+ renderer.shadowMap.enabled = true;
5436
+ renderer.shadowMap.type = PCFSoftShadowMap;
5437
+ renderer.outputEncoding = LinearEncoding;
5438
+ renderer.setSize(this.viewWidth, this.viewHeight);
5439
+ return renderer;
5440
+ }
5441
+ createComposer() {
5442
+ const composer = new EffectComposer(this.renderer);
5443
+ if (!this.options.composer.enabled) return composer;
5444
+ composer.setSize(this.viewWidth, this.viewHeight);
5445
+ composer.addPass(new RenderPass(this.scene, this.camera));
5446
+ return composer;
5447
+ }
5448
+ //</editor-fold>
5449
+ init() {
5450
+ if (this._disposed) return;
5451
+ if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
5452
+ window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
5748
5453
  }
5749
- const panLeft = function() {
5750
- const v = new Vector37();
5751
- return function panLeft2(distance, objectMatrix) {
5752
- v.setFromMatrixColumn(objectMatrix, 0);
5753
- v.multiplyScalar(-distance);
5754
- panOffset.add(v);
5755
- };
5756
- }();
5757
- const panUp = function() {
5758
- const v = new Vector37();
5759
- return function panUp2(distance, objectMatrix) {
5760
- if (scope.screenSpacePanning === true) {
5761
- v.setFromMatrixColumn(objectMatrix, 1);
5762
- } else {
5763
- v.setFromMatrixColumn(objectMatrix, 0);
5764
- v.crossVectors(scope.object.up, v);
5765
- }
5766
- v.multiplyScalar(distance);
5767
- panOffset.add(v);
5768
- };
5769
- }();
5770
- const pan = function() {
5771
- const offset = new Vector37();
5772
- return function pan2(deltaX, deltaY) {
5773
- const element = scope.domElement;
5774
- if (scope.object.isPerspectiveCamera) {
5775
- const position = scope.object.position;
5776
- offset.copy(position).sub(scope.target);
5777
- let targetDistance = offset.length();
5778
- targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
5779
- panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
5780
- panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
5781
- } else if (scope.object.isOrthographicCamera) {
5782
- panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
5783
- panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
5784
- } else {
5785
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
5786
- scope.enablePan = false;
5787
- }
5788
- };
5789
- }();
5790
- function dollyOut(dollyScale) {
5791
- if (scope.object.isPerspectiveCamera) {
5792
- scale /= dollyScale;
5793
- } else if (scope.object.isOrthographicCamera) {
5794
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
5795
- scope.object.updateProjectionMatrix();
5796
- zoomChanged = true;
5797
- } else {
5798
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5799
- scope.enableZoom = false;
5800
- }
5454
+ if (this.options.debug.grid) {
5455
+ const gridHelper = new GridHelper(128, 16);
5456
+ this._debugHelpers.push(gridHelper);
5457
+ this.scene.add(gridHelper);
5458
+ const gridHelper2 = new GridHelper(128, 16);
5459
+ this._debugHelpers.push(gridHelper2);
5460
+ gridHelper2.rotation.x = 90 * (Math.PI / 180);
5461
+ this.scene.add(gridHelper2);
5462
+ const gridHelper3 = new GridHelper(128, 16);
5463
+ this._debugHelpers.push(gridHelper3);
5464
+ gridHelper3.rotation.z = 90 * (Math.PI / 180);
5465
+ this.scene.add(gridHelper3);
5801
5466
  }
5802
- function dollyIn(dollyScale) {
5803
- if (scope.object.isPerspectiveCamera) {
5804
- scale *= dollyScale;
5805
- } else if (scope.object.isOrthographicCamera) {
5806
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
5807
- scope.object.updateProjectionMatrix();
5808
- zoomChanged = true;
5809
- } else {
5810
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5811
- scope.enableZoom = false;
5467
+ if (this.options.debug.axes) {
5468
+ const axesHelper = new AxesHelper3(64);
5469
+ this._debugHelpers.push(axesHelper);
5470
+ this.scene.add(axesHelper);
5471
+ }
5472
+ if (this.options.camera.position) {
5473
+ if (isVector3(this.options.camera.position)) {
5474
+ this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
5475
+ } else if (isTripleArray(this.options.camera.position)) {
5476
+ this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
5812
5477
  }
5813
5478
  }
5814
- function handleMouseDownRotate(event) {
5815
- rotateStart.set(event.clientX, event.clientY);
5479
+ if (this.options.camera.lookingAt) {
5480
+ if (isVector3(this.options.camera.lookingAt)) {
5481
+ this.camera.lookAt(this.options.camera.lookingAt);
5482
+ } else if (isTripleArray(this.options.camera.lookingAt)) {
5483
+ this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
5484
+ }
5816
5485
  }
5817
- function handleMouseDownDolly(event) {
5818
- dollyStart.set(event.clientX, event.clientY);
5486
+ if (this.options.render.autoResize && !this._resizeListener) {
5487
+ this._resizeListener = () => {
5488
+ this.resize(this.viewWidth, this.viewHeight);
5489
+ };
5490
+ window.addEventListener("resize", this._resizeListener);
5819
5491
  }
5820
- function handleMouseDownPan(event) {
5821
- panStart.set(event.clientX, event.clientY);
5492
+ }
5493
+ get element() {
5494
+ return this._element;
5495
+ }
5496
+ appendTo(element) {
5497
+ if (this._disposed) return;
5498
+ this._element = element;
5499
+ this._element.appendChild(this.renderer.domElement);
5500
+ if (this.viewWidth == 0) {
5501
+ console.warn("0 element width");
5822
5502
  }
5823
- function handleMouseMoveRotate(event) {
5824
- rotateEnd.set(event.clientX, event.clientY);
5825
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5826
- const element = scope.domElement;
5827
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5828
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5829
- rotateStart.copy(rotateEnd);
5830
- scope.update();
5503
+ if (this.viewHeight == 0) {
5504
+ console.warn("0 element height");
5831
5505
  }
5832
- function handleMouseMoveDolly(event) {
5833
- dollyEnd.set(event.clientX, event.clientY);
5834
- dollyDelta.subVectors(dollyEnd, dollyStart);
5835
- if (dollyDelta.y > 0) {
5836
- dollyOut(getZoomScale());
5837
- } else if (dollyDelta.y < 0) {
5838
- dollyIn(getZoomScale());
5839
- }
5840
- dollyStart.copy(dollyEnd);
5841
- scope.update();
5506
+ this.resize(this.viewWidth, this.viewHeight);
5507
+ }
5508
+ /**
5509
+ * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
5510
+ * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
5511
+ */
5512
+ registerEventDispatcher(dispatcher, changeEvent2 = "change") {
5513
+ if (this._disposed) return;
5514
+ let events = this._eventDispatchers.get(dispatcher);
5515
+ if (!events) {
5516
+ events = /* @__PURE__ */ new Set();
5517
+ this._eventDispatchers.set(dispatcher, events);
5842
5518
  }
5843
- function handleMouseMovePan(event) {
5844
- panEnd.set(event.clientX, event.clientY);
5845
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5846
- pan(panDelta.x, panDelta.y);
5847
- panStart.copy(panEnd);
5848
- scope.update();
5519
+ if (events.has(changeEvent2)) return;
5520
+ events.add(changeEvent2);
5521
+ dispatcher.addEventListener(changeEvent2, this._changeListener);
5522
+ }
5523
+ resize(width, height) {
5524
+ if (this._disposed) return;
5525
+ if (isPerspectiveCamera(this.camera)) {
5526
+ this.camera.aspect = width / height;
5527
+ this.camera.updateProjectionMatrix();
5528
+ } else if (isOrthographicCamera(this.camera)) {
5529
+ this.camera.left = width / -2;
5530
+ this.camera.right = width / 2;
5531
+ this.camera.top = height / 2;
5532
+ this.camera.bottom = height / -2;
5533
+ this.camera.updateProjectionMatrix();
5849
5534
  }
5850
- function handleMouseUp() {
5535
+ this.renderer.setSize(width, height);
5536
+ this.composer.setSize(width, height);
5537
+ this._dirty = true;
5538
+ }
5539
+ //<editor-fold desc="RENDER">
5540
+ get dirty() {
5541
+ return this._dirty || this.scene.dirty;
5542
+ }
5543
+ set dirty(dirty) {
5544
+ this._dirty = dirty;
5545
+ this.scene.dirty = dirty;
5546
+ }
5547
+ start() {
5548
+ if (this._disposed) return;
5549
+ this.stop();
5550
+ this.renderer.setAnimationLoop(this._animationLoop);
5551
+ }
5552
+ stop() {
5553
+ if (this._disposed) return;
5554
+ this.renderer.setAnimationLoop(null);
5555
+ if (this._animationTimer)
5556
+ clearTimeout(this._animationTimer);
5557
+ this._animationTimer = void 0;
5558
+ if (this._animationFrame)
5559
+ cancelAnimationFrame(this._animationFrame);
5560
+ this._animationFrame = void 0;
5561
+ }
5562
+ /**
5563
+ * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
5564
+ * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
5565
+ * controls must be managed by their owners.
5566
+ */
5567
+ dispose() {
5568
+ var _a;
5569
+ if (this._disposed) return;
5570
+ this.stop();
5571
+ this._disposed = true;
5572
+ if (this._resizeListener) {
5573
+ window.removeEventListener("resize", this._resizeListener);
5574
+ this._resizeListener = void 0;
5851
5575
  }
5852
- function handleMouseWheel(event) {
5853
- if (event.deltaY < 0) {
5854
- dollyIn(getZoomScale());
5855
- } else if (event.deltaY > 0) {
5856
- dollyOut(getZoomScale());
5576
+ for (const [dispatcher, events] of this._eventDispatchers) {
5577
+ for (const event of events) {
5578
+ dispatcher.removeEventListener(event, this._changeListener);
5857
5579
  }
5858
- scope.update();
5859
5580
  }
5860
- function handleKeyDown(event) {
5861
- let needsUpdate = false;
5862
- switch (event.code) {
5863
- case scope.keys.UP:
5864
- pan(0, scope.keyPanSpeed);
5865
- needsUpdate = true;
5866
- break;
5867
- case scope.keys.BOTTOM:
5868
- pan(0, -scope.keyPanSpeed);
5869
- needsUpdate = true;
5870
- break;
5871
- case scope.keys.LEFT:
5872
- pan(scope.keyPanSpeed, 0);
5873
- needsUpdate = true;
5874
- break;
5875
- case scope.keys.RIGHT:
5876
- pan(-scope.keyPanSpeed, 0);
5877
- needsUpdate = true;
5878
- break;
5879
- }
5880
- if (needsUpdate) {
5881
- event.preventDefault();
5882
- scope.update();
5581
+ this._eventDispatchers.clear();
5582
+ (_a = this._stats) == null ? void 0 : _a.dom.remove();
5583
+ this._stats = void 0;
5584
+ this.renderer.domElement.remove();
5585
+ this._element = void 0;
5586
+ this.scene.clear();
5587
+ for (const helper of this._debugHelpers) {
5588
+ helper.geometry.dispose();
5589
+ const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
5590
+ for (const material of materials) {
5591
+ material.dispose();
5883
5592
  }
5884
5593
  }
5885
- function handleTouchStartRotate() {
5886
- if (pointers.length === 1) {
5887
- rotateStart.set(pointers[0].pageX, pointers[0].pageY);
5888
- } else {
5889
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5890
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5891
- rotateStart.set(x, y);
5892
- }
5594
+ this._debugHelpers.length = 0;
5595
+ this.composer.dispose();
5596
+ this.renderer.dispose();
5597
+ this.renderer.forceContextLoss();
5598
+ }
5599
+ animate(t) {
5600
+ if (this._disposed) return;
5601
+ if (this._stats) {
5602
+ this._stats.begin();
5893
5603
  }
5894
- function handleTouchStartPan() {
5895
- if (pointers.length === 1) {
5896
- panStart.set(pointers[0].pageX, pointers[0].pageY);
5604
+ if (this.dirty || this.options.render.renderAlways) {
5605
+ if (this.options.composer.enabled) {
5606
+ this.composer.render();
5897
5607
  } else {
5898
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5899
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5900
- panStart.set(x, y);
5608
+ this.renderer.render(this.scene, this.camera);
5901
5609
  }
5902
5610
  }
5903
- function handleTouchStartDolly() {
5904
- const dx = pointers[0].pageX - pointers[1].pageX;
5905
- const dy = pointers[0].pageY - pointers[1].pageY;
5906
- const distance = Math.sqrt(dx * dx + dy * dy);
5907
- dollyStart.set(0, distance);
5908
- }
5909
- function handleTouchStartDollyPan() {
5910
- if (scope.enableZoom) handleTouchStartDolly();
5911
- if (scope.enablePan) handleTouchStartPan();
5611
+ this.dirty = false;
5612
+ if (this._stats) {
5613
+ this._stats.end();
5912
5614
  }
5913
- function handleTouchStartDollyRotate() {
5914
- if (scope.enableZoom) handleTouchStartDolly();
5915
- if (scope.enableRotate) handleTouchStartRotate();
5615
+ }
5616
+ //</editor-fold>
5617
+ toImage() {
5618
+ return this.renderer.domElement.toDataURL();
5619
+ }
5620
+ ///
5621
+ get attachedToBody() {
5622
+ return this.element === document.body;
5623
+ }
5624
+ get viewWidth() {
5625
+ var _a;
5626
+ return this.attachedToBody ? window.innerWidth : ((_a = this.element) == null ? void 0 : _a.offsetWidth) || 0;
5627
+ }
5628
+ get viewHeight() {
5629
+ var _a;
5630
+ return this.attachedToBody ? window.innerHeight : ((_a = this.element) == null ? void 0 : _a.offsetHeight) || 0;
5631
+ }
5632
+ get scene() {
5633
+ return this._scene;
5634
+ }
5635
+ get camera() {
5636
+ return this._camera;
5637
+ }
5638
+ get renderer() {
5639
+ return this._renderer;
5640
+ }
5641
+ get composer() {
5642
+ return this._composer;
5643
+ }
5644
+ ///
5645
+ };
5646
+ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge10.default)({}, {
5647
+ camera: {
5648
+ type: "perspective",
5649
+ near: 1,
5650
+ far: 5e3,
5651
+ perspective: {
5652
+ aspect: void 0,
5653
+ fov: 50
5654
+ },
5655
+ orthographic: {
5656
+ left: void 0,
5657
+ right: void 0,
5658
+ top: void 0,
5659
+ bottom: void 0
5660
+ },
5661
+ position: new Vector37(50, 50, 50),
5662
+ lookingAt: new Vector37(0, 0, 0)
5663
+ },
5664
+ render: {
5665
+ fpsLimit: 60,
5666
+ stats: false,
5667
+ antialias: true,
5668
+ shade: true,
5669
+ autoResize: true,
5670
+ renderAlways: false
5671
+ },
5672
+ composer: {
5673
+ enabled: true
5674
+ },
5675
+ debug: {
5676
+ grid: false,
5677
+ axes: false
5678
+ }
5679
+ });
5680
+ var Renderer = _Renderer;
5681
+
5682
+ // src/skin/Skins.ts
5683
+ var Skins = class {
5684
+ //<editor-fold desc="Skins">
5685
+ static async fromUuidOrUsername(uuidOrUsername) {
5686
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5687
+ return this.fromUuid(uuidOrUsername);
5916
5688
  }
5917
- function handleTouchMoveRotate(event) {
5918
- if (pointers.length == 1) {
5919
- rotateEnd.set(event.pageX, event.pageY);
5920
- } else {
5921
- const position = getSecondPointerPosition(event);
5922
- const x = 0.5 * (event.pageX + position.x);
5923
- const y = 0.5 * (event.pageY + position.y);
5924
- rotateEnd.set(x, y);
5689
+ return this.fromUsername(uuidOrUsername);
5690
+ }
5691
+ static async fromUuid(uuid) {
5692
+ return this.getSkinProxySkinUrl(uuid);
5693
+ }
5694
+ static async fromUsername(username) {
5695
+ return this.usernameToUuid(username).then((uuid) => {
5696
+ if (uuid) {
5697
+ return this.fromUuid(uuid);
5925
5698
  }
5926
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5927
- const element = scope.domElement;
5928
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5929
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5930
- rotateStart.copy(rotateEnd);
5931
- }
5932
- function handleTouchMovePan(event) {
5933
- if (pointers.length === 1) {
5934
- panEnd.set(event.pageX, event.pageY);
5935
- } else {
5936
- const position = getSecondPointerPosition(event);
5937
- const x = 0.5 * (event.pageX + position.x);
5938
- const y = 0.5 * (event.pageY + position.y);
5939
- panEnd.set(x, y);
5699
+ return void 0;
5700
+ });
5701
+ }
5702
+ static async fromMineSkin(mineskinId) {
5703
+ return this.getMineSkin(mineskinId).then((mineskin) => {
5704
+ if (mineskin) {
5705
+ return mineskin["data"]["texture"]["value"]["urls"]["skins"];
5940
5706
  }
5941
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5942
- pan(panDelta.x, panDelta.y);
5943
- panStart.copy(panEnd);
5944
- }
5945
- function handleTouchMoveDolly(event) {
5946
- const position = getSecondPointerPosition(event);
5947
- const dx = event.pageX - position.x;
5948
- const dy = event.pageY - position.y;
5949
- const distance = Math.sqrt(dx * dx + dy * dy);
5950
- dollyEnd.set(0, distance);
5951
- dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
5952
- dollyOut(dollyDelta.y);
5953
- dollyStart.copy(dollyEnd);
5954
- }
5955
- function handleTouchMoveDollyPan(event) {
5956
- if (scope.enableZoom) handleTouchMoveDolly(event);
5957
- if (scope.enablePan) handleTouchMovePan(event);
5958
- }
5959
- function handleTouchMoveDollyRotate(event) {
5960
- if (scope.enableZoom) handleTouchMoveDolly(event);
5961
- if (scope.enableRotate) handleTouchMoveRotate(event);
5962
- }
5963
- function handleTouchEnd() {
5707
+ return void 0;
5708
+ });
5709
+ }
5710
+ //</editor-fold>
5711
+ //<editor-fold desc="Capes">
5712
+ static async capeFromUuidOrUsername(uuidOrUsername) {
5713
+ if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
5714
+ return this.capeFromUuid(uuidOrUsername);
5964
5715
  }
5965
- function onPointerDown(event) {
5966
- if (scope.enabled === false) return;
5967
- if (pointers.length === 0) {
5968
- scope.domElement.setPointerCapture(event.pointerId);
5969
- scope.domElement.addEventListener("pointermove", onPointerMove);
5970
- scope.domElement.addEventListener("pointerup", onPointerUp);
5971
- }
5972
- addPointer(event);
5973
- if (event.pointerType === "touch") {
5974
- onTouchStart(event);
5975
- } else {
5976
- onMouseDown(event);
5716
+ return this.capeFromUsername(uuidOrUsername);
5717
+ }
5718
+ static async capeFromUuid(uuid) {
5719
+ return this.getSkinProxyCapeUrl(uuid);
5720
+ }
5721
+ static async capeFromUsername(username) {
5722
+ return this.usernameToUuid(username).then((uuid) => {
5723
+ if (uuid) {
5724
+ return this.capeFromUuid(uuid);
5977
5725
  }
5978
- }
5979
- function onPointerMove(event) {
5980
- if (scope.enabled === false) return;
5981
- if (event.pointerType === "touch") {
5982
- onTouchMove(event);
5983
- } else {
5984
- onMouseMove(event);
5726
+ return void 0;
5727
+ });
5728
+ }
5729
+ static async capeFromCapesDev(uuid, capeType = "minecraft") {
5730
+ return this.getCapesDev(uuid, capeType).then((cape) => {
5731
+ if (cape) {
5732
+ return cape == null ? void 0 : cape.stillImageUrl;
5985
5733
  }
5986
- }
5987
- function onPointerUp(event) {
5988
- if (scope.enabled === false) return;
5989
- if (event.pointerType === "touch") {
5990
- onTouchEnd();
5991
- } else {
5992
- onMouseUp(event);
5734
+ return void 0;
5735
+ });
5736
+ }
5737
+ //</editor-fold>
5738
+ //<editor-fold desc="Helpers">
5739
+ static async usernameToUuid(username) {
5740
+ return this.usernameToUuidSkinProxy(username);
5741
+ }
5742
+ static async usernameToUuidSkinProxy(username) {
5743
+ return Requests.genericRequest({
5744
+ baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
5745
+ url: "/uuid/" + username
5746
+ }).then((res) => {
5747
+ if (res.status === 200) {
5748
+ return res.data["id"];
5993
5749
  }
5994
- removePointer(event);
5995
- if (pointers.length === 0) {
5996
- scope.domElement.releasePointerCapture(event.pointerId);
5997
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5998
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5750
+ return void 0;
5751
+ }).catch((err) => {
5752
+ console.warn(err);
5753
+ return void 0;
5754
+ });
5755
+ }
5756
+ static async usernameToUuidMineTools(username) {
5757
+ return Requests.genericRequest({
5758
+ baseURL: "https://api.minetools.eu",
5759
+ url: "/uuid/" + username
5760
+ }).then((res) => {
5761
+ if (res.status === 200) {
5762
+ return res.data["id"];
5999
5763
  }
6000
- }
6001
- function onPointerCancel(event) {
6002
- removePointer(event);
6003
- }
6004
- function onMouseDown(event) {
6005
- let mouseAction;
6006
- switch (event.button) {
6007
- case 0:
6008
- mouseAction = scope.mouseButtons.LEFT;
6009
- break;
6010
- case 1:
6011
- mouseAction = scope.mouseButtons.MIDDLE;
6012
- break;
6013
- case 2:
6014
- mouseAction = scope.mouseButtons.RIGHT;
6015
- break;
6016
- default:
6017
- mouseAction = -1;
5764
+ return void 0;
5765
+ }).catch((err) => {
5766
+ console.warn(err);
5767
+ return void 0;
5768
+ });
5769
+ }
5770
+ static async getProfileFromMinetools(uuid) {
5771
+ return Requests.genericRequest({
5772
+ baseURL: "https://api.minetools.eu",
5773
+ url: "/profile/" + uuid
5774
+ }).then((res) => {
5775
+ if (res.status === 200) {
5776
+ return res.data;
6018
5777
  }
6019
- switch (mouseAction) {
6020
- case MOUSE.DOLLY:
6021
- if (scope.enableZoom === false) return;
6022
- handleMouseDownDolly(event);
6023
- state = STATE.DOLLY;
6024
- break;
6025
- case MOUSE.ROTATE:
6026
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6027
- if (scope.enablePan === false) return;
6028
- handleMouseDownPan(event);
6029
- state = STATE.PAN;
6030
- } else {
6031
- if (scope.enableRotate === false) return;
6032
- handleMouseDownRotate(event);
6033
- state = STATE.ROTATE;
6034
- }
6035
- break;
6036
- case MOUSE.PAN:
6037
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6038
- if (scope.enableRotate === false) return;
6039
- handleMouseDownRotate(event);
6040
- state = STATE.ROTATE;
5778
+ });
5779
+ }
5780
+ static async getMineSkin(mineskinId) {
5781
+ return Requests.genericRequest({
5782
+ baseURL: "https://api.mineskin.org",
5783
+ url: "/get/uuid/" + mineskinId
5784
+ }).then((res) => {
5785
+ if (res.status === 200) {
5786
+ return res.data;
5787
+ }
5788
+ return void 0;
5789
+ }).catch((err) => {
5790
+ console.warn(err);
5791
+ return void 0;
5792
+ });
5793
+ }
5794
+ static async getCapesDev(uuid, type = "all") {
5795
+ return Requests.genericRequest({
5796
+ baseURL: "https://api.capes.dev",
5797
+ url: "/load/" + uuid + "/" + type
5798
+ }).then((res) => {
5799
+ if (res.status === 200) {
5800
+ return res.data;
5801
+ }
5802
+ return void 0;
5803
+ }).catch((err) => {
5804
+ console.warn(err);
5805
+ return void 0;
5806
+ });
5807
+ }
5808
+ static getCrafatarSkinUrl(uuid) {
5809
+ return "https://crafatar.com/skins/" + uuid;
5810
+ }
5811
+ static getCrafatarCapeUrl(uuid) {
5812
+ return "https://crafatar.com/capes/" + uuid;
5813
+ }
5814
+ static getMcHeadsSkinUrl(uuid) {
5815
+ return "https://mc-heads.net/skin/" + uuid;
5816
+ }
5817
+ static getMineSkinPlayerSkinUrl(uuid) {
5818
+ return "https://mineskin.org/skin/player/" + uuid;
5819
+ }
5820
+ static getSkinProxySkinUrl(uuid) {
5821
+ return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
5822
+ }
5823
+ static getSkinProxyCapeUrl(uuid) {
5824
+ return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
5825
+ }
5826
+ //</editor-fold>
5827
+ };
5828
+
5829
+ // src/three/OrbitControls.js
5830
+ import {
5831
+ EventDispatcher as EventDispatcher2,
5832
+ MOUSE,
5833
+ Quaternion as Quaternion3,
5834
+ Spherical,
5835
+ TOUCH,
5836
+ Vector2 as Vector23,
5837
+ Vector3 as Vector38
5838
+ } from "three";
5839
+ var _changeEvent = { type: "change" };
5840
+ var _startEvent = { type: "start" };
5841
+ var _endEvent = { type: "end" };
5842
+ var OrbitControls = class extends EventDispatcher2 {
5843
+ constructor(object, domElement) {
5844
+ super();
5845
+ if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5846
+ if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5847
+ this.object = object;
5848
+ this.domElement = domElement;
5849
+ this.domElement.style.touchAction = "none";
5850
+ this.enabled = true;
5851
+ this.target = new Vector38();
5852
+ this.minDistance = 0;
5853
+ this.maxDistance = Infinity;
5854
+ this.minZoom = 0;
5855
+ this.maxZoom = Infinity;
5856
+ this.minPolarAngle = 0;
5857
+ this.maxPolarAngle = Math.PI;
5858
+ this.minAzimuthAngle = -Infinity;
5859
+ this.maxAzimuthAngle = Infinity;
5860
+ this.enableDamping = false;
5861
+ this.dampingFactor = 0.05;
5862
+ this.enableZoom = true;
5863
+ this.zoomSpeed = 1;
5864
+ this.enableRotate = true;
5865
+ this.rotateSpeed = 1;
5866
+ this.enablePan = true;
5867
+ this.panSpeed = 1;
5868
+ this.screenSpacePanning = true;
5869
+ this.keyPanSpeed = 7;
5870
+ this.autoRotate = false;
5871
+ this.autoRotateSpeed = 2;
5872
+ this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5873
+ this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
5874
+ this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
5875
+ this.target0 = this.target.clone();
5876
+ this.position0 = this.object.position.clone();
5877
+ this.zoom0 = this.object.zoom;
5878
+ this._domElementKeyEvents = null;
5879
+ this.getPolarAngle = function() {
5880
+ return spherical.phi;
5881
+ };
5882
+ this.getAzimuthalAngle = function() {
5883
+ return spherical.theta;
5884
+ };
5885
+ this.getDistance = function() {
5886
+ return this.object.position.distanceTo(this.target);
5887
+ };
5888
+ this.saveState = function() {
5889
+ scope.target0.copy(scope.target);
5890
+ scope.position0.copy(scope.object.position);
5891
+ scope.zoom0 = scope.object.zoom;
5892
+ };
5893
+ this.reset = function() {
5894
+ scope.target.copy(scope.target0);
5895
+ scope.object.position.copy(scope.position0);
5896
+ scope.object.zoom = scope.zoom0;
5897
+ scope.object.updateProjectionMatrix();
5898
+ scope.dispatchEvent(_changeEvent);
5899
+ scope.update();
5900
+ state = STATE.NONE;
5901
+ };
5902
+ this.update = function() {
5903
+ const offset = new Vector38();
5904
+ const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
5905
+ const quatInverse = quat.clone().invert();
5906
+ const lastPosition = new Vector38();
5907
+ const lastQuaternion = new Quaternion3();
5908
+ const twoPI = 2 * Math.PI;
5909
+ return function update() {
5910
+ const position = scope.object.position;
5911
+ offset.copy(position).sub(scope.target);
5912
+ offset.applyQuaternion(quat);
5913
+ spherical.setFromVector3(offset);
5914
+ if (scope.autoRotate && state === STATE.NONE) {
5915
+ rotateLeft(getAutoRotationAngle());
5916
+ }
5917
+ if (scope.enableDamping) {
5918
+ spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5919
+ spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5920
+ } else {
5921
+ spherical.theta += sphericalDelta.theta;
5922
+ spherical.phi += sphericalDelta.phi;
5923
+ }
5924
+ let min = scope.minAzimuthAngle;
5925
+ let max = scope.maxAzimuthAngle;
5926
+ if (isFinite(min) && isFinite(max)) {
5927
+ if (min < -Math.PI) min += twoPI;
5928
+ else if (min > Math.PI) min -= twoPI;
5929
+ if (max < -Math.PI) max += twoPI;
5930
+ else if (max > Math.PI) max -= twoPI;
5931
+ if (min <= max) {
5932
+ spherical.theta = Math.max(min, Math.min(max, spherical.theta));
6041
5933
  } else {
6042
- if (scope.enablePan === false) return;
6043
- handleMouseDownPan(event);
6044
- state = STATE.PAN;
5934
+ spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
6045
5935
  }
6046
- break;
6047
- default:
6048
- state = STATE.NONE;
5936
+ }
5937
+ spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5938
+ spherical.makeSafe();
5939
+ spherical.radius *= scale;
5940
+ spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5941
+ if (scope.enableDamping === true) {
5942
+ scope.target.addScaledVector(panOffset, scope.dampingFactor);
5943
+ } else {
5944
+ scope.target.add(panOffset);
5945
+ }
5946
+ offset.setFromSpherical(spherical);
5947
+ offset.applyQuaternion(quatInverse);
5948
+ position.copy(scope.target).add(offset);
5949
+ scope.object.lookAt(scope.target);
5950
+ if (scope.enableDamping === true) {
5951
+ sphericalDelta.theta *= 1 - scope.dampingFactor;
5952
+ sphericalDelta.phi *= 1 - scope.dampingFactor;
5953
+ panOffset.multiplyScalar(1 - scope.dampingFactor);
5954
+ } else {
5955
+ sphericalDelta.set(0, 0, 0);
5956
+ panOffset.set(0, 0, 0);
5957
+ }
5958
+ scale = 1;
5959
+ if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5960
+ scope.dispatchEvent(_changeEvent);
5961
+ lastPosition.copy(scope.object.position);
5962
+ lastQuaternion.copy(scope.object.quaternion);
5963
+ zoomChanged = false;
5964
+ return true;
5965
+ }
5966
+ return false;
5967
+ };
5968
+ }();
5969
+ this.dispose = function() {
5970
+ scope.domElement.removeEventListener("contextmenu", onContextMenu);
5971
+ scope.domElement.removeEventListener("pointerdown", onPointerDown);
5972
+ scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5973
+ scope.domElement.removeEventListener("wheel", onMouseWheel);
5974
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
5975
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
5976
+ if (scope._domElementKeyEvents !== null) {
5977
+ scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
6049
5978
  }
6050
- if (state !== STATE.NONE) {
6051
- scope.dispatchEvent(_startEvent);
5979
+ };
5980
+ const scope = this;
5981
+ const STATE = {
5982
+ NONE: -1,
5983
+ ROTATE: 0,
5984
+ DOLLY: 1,
5985
+ PAN: 2,
5986
+ TOUCH_ROTATE: 3,
5987
+ TOUCH_PAN: 4,
5988
+ TOUCH_DOLLY_PAN: 5,
5989
+ TOUCH_DOLLY_ROTATE: 6
5990
+ };
5991
+ let state = STATE.NONE;
5992
+ const EPS = 1e-6;
5993
+ const spherical = new Spherical();
5994
+ const sphericalDelta = new Spherical();
5995
+ let scale = 1;
5996
+ const panOffset = new Vector38();
5997
+ let zoomChanged = false;
5998
+ const rotateStart = new Vector23();
5999
+ const rotateEnd = new Vector23();
6000
+ const rotateDelta = new Vector23();
6001
+ const panStart = new Vector23();
6002
+ const panEnd = new Vector23();
6003
+ const panDelta = new Vector23();
6004
+ const dollyStart = new Vector23();
6005
+ const dollyEnd = new Vector23();
6006
+ const dollyDelta = new Vector23();
6007
+ const pointers = [];
6008
+ const pointerPositions = {};
6009
+ function getAutoRotationAngle() {
6010
+ return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
6011
+ }
6012
+ function getZoomScale() {
6013
+ return Math.pow(0.95, scope.zoomSpeed);
6014
+ }
6015
+ function rotateLeft(angle) {
6016
+ sphericalDelta.theta -= angle;
6017
+ }
6018
+ function rotateUp(angle) {
6019
+ sphericalDelta.phi -= angle;
6020
+ }
6021
+ const panLeft = function() {
6022
+ const v = new Vector38();
6023
+ return function panLeft2(distance, objectMatrix) {
6024
+ v.setFromMatrixColumn(objectMatrix, 0);
6025
+ v.multiplyScalar(-distance);
6026
+ panOffset.add(v);
6027
+ };
6028
+ }();
6029
+ const panUp = function() {
6030
+ const v = new Vector38();
6031
+ return function panUp2(distance, objectMatrix) {
6032
+ if (scope.screenSpacePanning === true) {
6033
+ v.setFromMatrixColumn(objectMatrix, 1);
6034
+ } else {
6035
+ v.setFromMatrixColumn(objectMatrix, 0);
6036
+ v.crossVectors(scope.object.up, v);
6037
+ }
6038
+ v.multiplyScalar(distance);
6039
+ panOffset.add(v);
6040
+ };
6041
+ }();
6042
+ const pan = function() {
6043
+ const offset = new Vector38();
6044
+ return function pan2(deltaX, deltaY) {
6045
+ const element = scope.domElement;
6046
+ if (scope.object.isPerspectiveCamera) {
6047
+ const position = scope.object.position;
6048
+ offset.copy(position).sub(scope.target);
6049
+ let targetDistance = offset.length();
6050
+ targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
6051
+ panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
6052
+ panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
6053
+ } else if (scope.object.isOrthographicCamera) {
6054
+ panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
6055
+ panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
6056
+ } else {
6057
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
6058
+ scope.enablePan = false;
6059
+ }
6060
+ };
6061
+ }();
6062
+ function dollyOut(dollyScale) {
6063
+ if (scope.object.isPerspectiveCamera) {
6064
+ scale /= dollyScale;
6065
+ } else if (scope.object.isOrthographicCamera) {
6066
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
6067
+ scope.object.updateProjectionMatrix();
6068
+ zoomChanged = true;
6069
+ } else {
6070
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6071
+ scope.enableZoom = false;
6052
6072
  }
6053
6073
  }
6054
- function onMouseMove(event) {
6055
- if (scope.enabled === false) return;
6056
- switch (state) {
6057
- case STATE.ROTATE:
6058
- if (scope.enableRotate === false) return;
6059
- handleMouseMoveRotate(event);
6060
- break;
6061
- case STATE.DOLLY:
6062
- if (scope.enableZoom === false) return;
6063
- handleMouseMoveDolly(event);
6064
- break;
6065
- case STATE.PAN:
6066
- if (scope.enablePan === false) return;
6067
- handleMouseMovePan(event);
6068
- break;
6074
+ function dollyIn(dollyScale) {
6075
+ if (scope.object.isPerspectiveCamera) {
6076
+ scale *= dollyScale;
6077
+ } else if (scope.object.isOrthographicCamera) {
6078
+ scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
6079
+ scope.object.updateProjectionMatrix();
6080
+ zoomChanged = true;
6081
+ } else {
6082
+ console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
6083
+ scope.enableZoom = false;
6069
6084
  }
6070
6085
  }
6071
- function onMouseUp(event) {
6072
- handleMouseUp(event);
6073
- scope.dispatchEvent(_endEvent);
6074
- state = STATE.NONE;
6086
+ function handleMouseDownRotate(event) {
6087
+ rotateStart.set(event.clientX, event.clientY);
6075
6088
  }
6076
- function onMouseWheel(event) {
6077
- if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6078
- event.preventDefault();
6079
- scope.dispatchEvent(_startEvent);
6080
- handleMouseWheel(event);
6081
- scope.dispatchEvent(_endEvent);
6089
+ function handleMouseDownDolly(event) {
6090
+ dollyStart.set(event.clientX, event.clientY);
6082
6091
  }
6083
- function onKeyDown(event) {
6084
- if (scope.enabled === false || scope.enablePan === false) return;
6085
- handleKeyDown(event);
6092
+ function handleMouseDownPan(event) {
6093
+ panStart.set(event.clientX, event.clientY);
6086
6094
  }
6087
- function onTouchStart(event) {
6088
- trackPointer(event);
6089
- switch (pointers.length) {
6090
- case 1:
6091
- switch (scope.touches.ONE) {
6092
- case TOUCH.ROTATE:
6093
- if (scope.enableRotate === false) return;
6094
- handleTouchStartRotate();
6095
- state = STATE.TOUCH_ROTATE;
6096
- break;
6097
- case TOUCH.PAN:
6098
- if (scope.enablePan === false) return;
6099
- handleTouchStartPan();
6100
- state = STATE.TOUCH_PAN;
6101
- break;
6102
- default:
6103
- state = STATE.NONE;
6104
- }
6105
- break;
6106
- case 2:
6107
- switch (scope.touches.TWO) {
6108
- case TOUCH.DOLLY_PAN:
6109
- if (scope.enableZoom === false && scope.enablePan === false) return;
6110
- handleTouchStartDollyPan();
6111
- state = STATE.TOUCH_DOLLY_PAN;
6112
- break;
6113
- case TOUCH.DOLLY_ROTATE:
6114
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6115
- handleTouchStartDollyRotate();
6116
- state = STATE.TOUCH_DOLLY_ROTATE;
6117
- break;
6118
- default:
6119
- state = STATE.NONE;
6120
- }
6121
- break;
6122
- default:
6123
- state = STATE.NONE;
6095
+ function handleMouseMoveRotate(event) {
6096
+ rotateEnd.set(event.clientX, event.clientY);
6097
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6098
+ const element = scope.domElement;
6099
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6100
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6101
+ rotateStart.copy(rotateEnd);
6102
+ scope.update();
6103
+ }
6104
+ function handleMouseMoveDolly(event) {
6105
+ dollyEnd.set(event.clientX, event.clientY);
6106
+ dollyDelta.subVectors(dollyEnd, dollyStart);
6107
+ if (dollyDelta.y > 0) {
6108
+ dollyOut(getZoomScale());
6109
+ } else if (dollyDelta.y < 0) {
6110
+ dollyIn(getZoomScale());
6124
6111
  }
6125
- if (state !== STATE.NONE) {
6126
- scope.dispatchEvent(_startEvent);
6112
+ dollyStart.copy(dollyEnd);
6113
+ scope.update();
6114
+ }
6115
+ function handleMouseMovePan(event) {
6116
+ panEnd.set(event.clientX, event.clientY);
6117
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6118
+ pan(panDelta.x, panDelta.y);
6119
+ panStart.copy(panEnd);
6120
+ scope.update();
6121
+ }
6122
+ function handleMouseUp() {
6123
+ }
6124
+ function handleMouseWheel(event) {
6125
+ if (event.deltaY < 0) {
6126
+ dollyIn(getZoomScale());
6127
+ } else if (event.deltaY > 0) {
6128
+ dollyOut(getZoomScale());
6127
6129
  }
6130
+ scope.update();
6128
6131
  }
6129
- function onTouchMove(event) {
6130
- trackPointer(event);
6131
- switch (state) {
6132
- case STATE.TOUCH_ROTATE:
6133
- if (scope.enableRotate === false) return;
6134
- handleTouchMoveRotate(event);
6135
- scope.update();
6132
+ function handleKeyDown(event) {
6133
+ let needsUpdate = false;
6134
+ switch (event.code) {
6135
+ case scope.keys.UP:
6136
+ pan(0, scope.keyPanSpeed);
6137
+ needsUpdate = true;
6136
6138
  break;
6137
- case STATE.TOUCH_PAN:
6138
- if (scope.enablePan === false) return;
6139
- handleTouchMovePan(event);
6140
- scope.update();
6139
+ case scope.keys.BOTTOM:
6140
+ pan(0, -scope.keyPanSpeed);
6141
+ needsUpdate = true;
6141
6142
  break;
6142
- case STATE.TOUCH_DOLLY_PAN:
6143
- if (scope.enableZoom === false && scope.enablePan === false) return;
6144
- handleTouchMoveDollyPan(event);
6145
- scope.update();
6143
+ case scope.keys.LEFT:
6144
+ pan(scope.keyPanSpeed, 0);
6145
+ needsUpdate = true;
6146
6146
  break;
6147
- case STATE.TOUCH_DOLLY_ROTATE:
6148
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6149
- handleTouchMoveDollyRotate(event);
6150
- scope.update();
6147
+ case scope.keys.RIGHT:
6148
+ pan(-scope.keyPanSpeed, 0);
6149
+ needsUpdate = true;
6151
6150
  break;
6152
- default:
6153
- state = STATE.NONE;
6151
+ }
6152
+ if (needsUpdate) {
6153
+ event.preventDefault();
6154
+ scope.update();
6154
6155
  }
6155
6156
  }
6156
- function onTouchEnd(event) {
6157
- handleTouchEnd(event);
6158
- scope.dispatchEvent(_endEvent);
6159
- state = STATE.NONE;
6160
- }
6161
- function onContextMenu(event) {
6162
- if (scope.enabled === false) return;
6163
- event.preventDefault();
6164
- }
6165
- function addPointer(event) {
6166
- pointers.push(event);
6167
- }
6168
- function removePointer(event) {
6169
- delete pointerPositions[event.pointerId];
6170
- for (let i = 0; i < pointers.length; i++) {
6171
- if (pointers[i].pointerId == event.pointerId) {
6172
- pointers.splice(i, 1);
6173
- return;
6174
- }
6157
+ function handleTouchStartRotate() {
6158
+ if (pointers.length === 1) {
6159
+ rotateStart.set(pointers[0].pageX, pointers[0].pageY);
6160
+ } else {
6161
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6162
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6163
+ rotateStart.set(x, y);
6175
6164
  }
6176
6165
  }
6177
- function trackPointer(event) {
6178
- let position = pointerPositions[event.pointerId];
6179
- if (position === void 0) {
6180
- position = new Vector23();
6181
- pointerPositions[event.pointerId] = position;
6166
+ function handleTouchStartPan() {
6167
+ if (pointers.length === 1) {
6168
+ panStart.set(pointers[0].pageX, pointers[0].pageY);
6169
+ } else {
6170
+ const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
6171
+ const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
6172
+ panStart.set(x, y);
6182
6173
  }
6183
- position.set(event.pageX, event.pageY);
6184
6174
  }
6185
- function getSecondPointerPosition(event) {
6186
- const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6187
- return pointerPositions[pointer.pointerId];
6175
+ function handleTouchStartDolly() {
6176
+ const dx = pointers[0].pageX - pointers[1].pageX;
6177
+ const dy = pointers[0].pageY - pointers[1].pageY;
6178
+ const distance = Math.sqrt(dx * dx + dy * dy);
6179
+ dollyStart.set(0, distance);
6188
6180
  }
6189
- scope.domElement.addEventListener("contextmenu", onContextMenu);
6190
- scope.domElement.addEventListener("pointerdown", onPointerDown);
6191
- scope.domElement.addEventListener("pointercancel", onPointerCancel);
6192
- scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6193
- this.update();
6194
- }
6195
- };
6196
- var MapControls = class extends OrbitControls {
6197
- constructor(object, domElement) {
6198
- super(object, domElement);
6199
- this.screenSpacePanning = false;
6200
- this.mouseButtons.LEFT = MOUSE.PAN;
6201
- this.mouseButtons.RIGHT = MOUSE.ROTATE;
6202
- this.touches.ONE = TOUCH.PAN;
6203
- this.touches.TWO = TOUCH.DOLLY_ROTATE;
6204
- }
6205
- };
6206
-
6207
- // src/renderer/Renderer.ts
6208
- var Renderer = class _Renderer {
6209
- constructor(options) {
6210
- this._dirty = true;
6211
- this._resizeListener = void 0;
6212
- this._disposed = false;
6213
- this._debugHelpers = [];
6214
- this._eventDispatchers = /* @__PURE__ */ new Map();
6215
- this._changeListener = () => {
6216
- this._dirty = true;
6217
- };
6218
- this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
6219
- this._animationLoop = this.animate.bind(this);
6220
- this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
6221
- this._scene = this.createScene();
6222
- this._camera = this.createCamera();
6223
- this._renderer = this.createRenderer();
6224
- this._composer = this.createComposer();
6225
- if (this.options.render.stats) {
6226
- this._stats = new Stats();
6227
- document.body.appendChild(this._stats.dom);
6181
+ function handleTouchStartDollyPan() {
6182
+ if (scope.enableZoom) handleTouchStartDolly();
6183
+ if (scope.enablePan) handleTouchStartPan();
6228
6184
  }
6229
- this.init();
6230
- this._controls = this.createControls();
6231
- }
6232
- static {
6233
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6234
- camera: {
6235
- type: "perspective",
6236
- near: 1,
6237
- far: 5e3,
6238
- perspective: {
6239
- aspect: void 0,
6240
- fov: 50
6241
- },
6242
- orthographic: {
6243
- left: void 0,
6244
- right: void 0,
6245
- top: void 0,
6246
- bottom: void 0
6247
- },
6248
- position: new Vector38(50, 50, 50),
6249
- lookingAt: new Vector38(0, 0, 0)
6250
- },
6251
- render: {
6252
- fpsLimit: 60,
6253
- stats: false,
6254
- antialias: true,
6255
- shade: true,
6256
- autoResize: true,
6257
- renderAlways: false
6258
- },
6259
- composer: {
6260
- enabled: true
6261
- },
6262
- controls: {
6263
- enabled: false
6264
- },
6265
- debug: {
6266
- grid: false,
6267
- axes: false
6185
+ function handleTouchStartDollyRotate() {
6186
+ if (scope.enableZoom) handleTouchStartDolly();
6187
+ if (scope.enableRotate) handleTouchStartRotate();
6188
+ }
6189
+ function handleTouchMoveRotate(event) {
6190
+ if (pointers.length == 1) {
6191
+ rotateEnd.set(event.pageX, event.pageY);
6192
+ } else {
6193
+ const position = getSecondPointerPosition(event);
6194
+ const x = 0.5 * (event.pageX + position.x);
6195
+ const y = 0.5 * (event.pageY + position.y);
6196
+ rotateEnd.set(x, y);
6268
6197
  }
6269
- });
6270
- }
6271
- //<editor-fold desc="INIT">
6272
- createScene() {
6273
- return new MineRenderScene();
6274
- }
6275
- createCamera() {
6276
- switch (this.options.camera.type) {
6277
- case "perspective":
6278
- default:
6279
- return new PerspectiveCamera(
6280
- this.options.camera.perspective.fov,
6281
- this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
6282
- this.options.camera.near,
6283
- this.options.camera.far
6284
- );
6285
- case "orthographic":
6286
- return new OrthographicCamera(
6287
- this.options.camera.orthographic.left ?? this.viewWidth / -2,
6288
- this.options.camera.orthographic.right ?? this.viewWidth / 2,
6289
- this.options.camera.orthographic.top ?? this.viewHeight / 2,
6290
- this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
6291
- this.options.camera.near,
6292
- this.options.camera.far
6293
- );
6198
+ rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
6199
+ const element = scope.domElement;
6200
+ rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
6201
+ rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
6202
+ rotateStart.copy(rotateEnd);
6294
6203
  }
6295
- }
6296
- createRenderer() {
6297
- const renderer = new WebGLRenderer({
6298
- antialias: this.options.render.antialias,
6299
- alpha: true,
6300
- powerPreference: "high-performance",
6301
- depth: true
6302
- });
6303
- renderer.setClearColor(0, 0);
6304
- renderer.shadowMap.enabled = true;
6305
- renderer.shadowMap.type = PCFSoftShadowMap;
6306
- renderer.outputColorSpace = SRGBColorSpace3;
6307
- renderer.setSize(this.viewWidth, this.viewHeight);
6308
- return renderer;
6309
- }
6310
- createComposer() {
6311
- if (!this.options.composer.enabled) return void 0;
6312
- const composer = new EffectComposer(this.renderer);
6313
- composer.setSize(this.viewWidth, this.viewHeight);
6314
- composer.addPass(new RenderPass(this.scene, this.camera));
6315
- return composer;
6316
- }
6317
- createControls() {
6318
- if (!this.options.controls?.enabled) return void 0;
6319
- const position = this.camera.position.clone();
6320
- const controls = new OrbitControls(this.camera, this.renderer.domElement);
6321
- this.camera.position.copy(position);
6322
- const target = this.options.camera.lookingAt;
6323
- if (isVector3(target)) {
6324
- controls.target.copy(target);
6325
- } else if (isTripleArray(target)) {
6326
- controls.target.set(target[0], target[1], target[2]);
6327
- }
6328
- controls.update();
6329
- controls.saveState();
6330
- this.registerEventDispatcher(controls);
6331
- return controls;
6332
- }
6333
- //</editor-fold>
6334
- init() {
6335
- if (this._disposed) return;
6336
- if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
6337
- window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
6204
+ function handleTouchMovePan(event) {
6205
+ if (pointers.length === 1) {
6206
+ panEnd.set(event.pageX, event.pageY);
6207
+ } else {
6208
+ const position = getSecondPointerPosition(event);
6209
+ const x = 0.5 * (event.pageX + position.x);
6210
+ const y = 0.5 * (event.pageY + position.y);
6211
+ panEnd.set(x, y);
6212
+ }
6213
+ panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
6214
+ pan(panDelta.x, panDelta.y);
6215
+ panStart.copy(panEnd);
6338
6216
  }
6339
- if (this.options.debug.grid) {
6340
- const gridHelper = new GridHelper(128, 16);
6341
- this._debugHelpers.push(gridHelper);
6342
- this.scene.add(gridHelper);
6343
- const gridHelper2 = new GridHelper(128, 16);
6344
- this._debugHelpers.push(gridHelper2);
6345
- gridHelper2.rotation.x = 90 * (Math.PI / 180);
6346
- this.scene.add(gridHelper2);
6347
- const gridHelper3 = new GridHelper(128, 16);
6348
- this._debugHelpers.push(gridHelper3);
6349
- gridHelper3.rotation.z = 90 * (Math.PI / 180);
6350
- this.scene.add(gridHelper3);
6217
+ function handleTouchMoveDolly(event) {
6218
+ const position = getSecondPointerPosition(event);
6219
+ const dx = event.pageX - position.x;
6220
+ const dy = event.pageY - position.y;
6221
+ const distance = Math.sqrt(dx * dx + dy * dy);
6222
+ dollyEnd.set(0, distance);
6223
+ dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
6224
+ dollyOut(dollyDelta.y);
6225
+ dollyStart.copy(dollyEnd);
6226
+ }
6227
+ function handleTouchMoveDollyPan(event) {
6228
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6229
+ if (scope.enablePan) handleTouchMovePan(event);
6351
6230
  }
6352
- if (this.options.debug.axes) {
6353
- const axesHelper = new AxesHelper3(64);
6354
- this._debugHelpers.push(axesHelper);
6355
- this.scene.add(axesHelper);
6231
+ function handleTouchMoveDollyRotate(event) {
6232
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6233
+ if (scope.enableRotate) handleTouchMoveRotate(event);
6356
6234
  }
6357
- if (this.options.camera.position) {
6358
- if (isVector3(this.options.camera.position)) {
6359
- this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
6360
- } else if (isTripleArray(this.options.camera.position)) {
6361
- this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
6362
- }
6235
+ function handleTouchEnd() {
6363
6236
  }
6364
- if (this.options.camera.lookingAt) {
6365
- if (isVector3(this.options.camera.lookingAt)) {
6366
- this.camera.lookAt(this.options.camera.lookingAt);
6367
- } else if (isTripleArray(this.options.camera.lookingAt)) {
6368
- this.camera.lookAt(this.options.camera.lookingAt[0], this.options.camera.lookingAt[1], this.options.camera.lookingAt[2]);
6237
+ function onPointerDown(event) {
6238
+ if (scope.enabled === false) return;
6239
+ if (pointers.length === 0) {
6240
+ scope.domElement.setPointerCapture(event.pointerId);
6241
+ scope.domElement.addEventListener("pointermove", onPointerMove);
6242
+ scope.domElement.addEventListener("pointerup", onPointerUp);
6243
+ }
6244
+ addPointer(event);
6245
+ if (event.pointerType === "touch") {
6246
+ onTouchStart(event);
6247
+ } else {
6248
+ onMouseDown(event);
6369
6249
  }
6370
6250
  }
6371
- if (this.options.render.autoResize && !this._resizeListener) {
6372
- this._resizeListener = () => {
6373
- this.resize(this.viewWidth, this.viewHeight);
6374
- };
6375
- window.addEventListener("resize", this._resizeListener);
6251
+ function onPointerMove(event) {
6252
+ if (scope.enabled === false) return;
6253
+ if (event.pointerType === "touch") {
6254
+ onTouchMove(event);
6255
+ } else {
6256
+ onMouseMove(event);
6257
+ }
6376
6258
  }
6377
- }
6378
- get element() {
6379
- return this._element;
6380
- }
6381
- appendTo(element) {
6382
- if (this._disposed) return;
6383
- this._element = element;
6384
- this._element.appendChild(this.renderer.domElement);
6385
- if (this.viewWidth == 0) {
6386
- console.warn("0 element width");
6259
+ function onPointerUp(event) {
6260
+ if (scope.enabled === false) return;
6261
+ if (event.pointerType === "touch") {
6262
+ onTouchEnd();
6263
+ } else {
6264
+ onMouseUp(event);
6265
+ }
6266
+ removePointer(event);
6267
+ if (pointers.length === 0) {
6268
+ scope.domElement.releasePointerCapture(event.pointerId);
6269
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
6270
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
6271
+ }
6387
6272
  }
6388
- if (this.viewHeight == 0) {
6389
- console.warn("0 element height");
6273
+ function onPointerCancel(event) {
6274
+ removePointer(event);
6390
6275
  }
6391
- this.resize(this.viewWidth, this.viewHeight);
6392
- }
6393
- /**
6394
- * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
6395
- * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
6396
- */
6397
- registerEventDispatcher(dispatcher, changeEvent2 = "change") {
6398
- if (this._disposed) return;
6399
- let events = this._eventDispatchers.get(dispatcher);
6400
- if (!events) {
6401
- events = /* @__PURE__ */ new Set();
6402
- this._eventDispatchers.set(dispatcher, events);
6276
+ function onMouseDown(event) {
6277
+ let mouseAction;
6278
+ switch (event.button) {
6279
+ case 0:
6280
+ mouseAction = scope.mouseButtons.LEFT;
6281
+ break;
6282
+ case 1:
6283
+ mouseAction = scope.mouseButtons.MIDDLE;
6284
+ break;
6285
+ case 2:
6286
+ mouseAction = scope.mouseButtons.RIGHT;
6287
+ break;
6288
+ default:
6289
+ mouseAction = -1;
6290
+ }
6291
+ switch (mouseAction) {
6292
+ case MOUSE.DOLLY:
6293
+ if (scope.enableZoom === false) return;
6294
+ handleMouseDownDolly(event);
6295
+ state = STATE.DOLLY;
6296
+ break;
6297
+ case MOUSE.ROTATE:
6298
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6299
+ if (scope.enablePan === false) return;
6300
+ handleMouseDownPan(event);
6301
+ state = STATE.PAN;
6302
+ } else {
6303
+ if (scope.enableRotate === false) return;
6304
+ handleMouseDownRotate(event);
6305
+ state = STATE.ROTATE;
6306
+ }
6307
+ break;
6308
+ case MOUSE.PAN:
6309
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
6310
+ if (scope.enableRotate === false) return;
6311
+ handleMouseDownRotate(event);
6312
+ state = STATE.ROTATE;
6313
+ } else {
6314
+ if (scope.enablePan === false) return;
6315
+ handleMouseDownPan(event);
6316
+ state = STATE.PAN;
6317
+ }
6318
+ break;
6319
+ default:
6320
+ state = STATE.NONE;
6321
+ }
6322
+ if (state !== STATE.NONE) {
6323
+ scope.dispatchEvent(_startEvent);
6324
+ }
6403
6325
  }
6404
- if (events.has(changeEvent2)) return;
6405
- events.add(changeEvent2);
6406
- dispatcher.addEventListener(changeEvent2, this._changeListener);
6407
- }
6408
- resize(width, height) {
6409
- if (this._disposed) return;
6410
- if (isPerspectiveCamera(this.camera)) {
6411
- this.camera.aspect = width / height;
6412
- this.camera.updateProjectionMatrix();
6413
- } else if (isOrthographicCamera(this.camera)) {
6414
- this.camera.left = width / -2;
6415
- this.camera.right = width / 2;
6416
- this.camera.top = height / 2;
6417
- this.camera.bottom = height / -2;
6418
- this.camera.updateProjectionMatrix();
6326
+ function onMouseMove(event) {
6327
+ if (scope.enabled === false) return;
6328
+ switch (state) {
6329
+ case STATE.ROTATE:
6330
+ if (scope.enableRotate === false) return;
6331
+ handleMouseMoveRotate(event);
6332
+ break;
6333
+ case STATE.DOLLY:
6334
+ if (scope.enableZoom === false) return;
6335
+ handleMouseMoveDolly(event);
6336
+ break;
6337
+ case STATE.PAN:
6338
+ if (scope.enablePan === false) return;
6339
+ handleMouseMovePan(event);
6340
+ break;
6341
+ }
6419
6342
  }
6420
- this.renderer.setSize(width, height);
6421
- this.composer?.setSize(width, height);
6422
- this._dirty = true;
6423
- }
6424
- //<editor-fold desc="RENDER">
6425
- get dirty() {
6426
- return this._dirty || this.scene.dirty;
6427
- }
6428
- set dirty(dirty) {
6429
- this._dirty = dirty;
6430
- this.scene.dirty = dirty;
6431
- }
6432
- start() {
6433
- if (this._disposed) return;
6434
- this.stop();
6435
- this.renderer.setAnimationLoop(this._animationLoop);
6436
- }
6437
- stop() {
6438
- if (this._disposed) return;
6439
- this.renderer.setAnimationLoop(null);
6440
- this._nextFrameTime = void 0;
6441
- }
6442
- /**
6443
- * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
6444
- * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
6445
- * controls must be managed by their owners.
6446
- */
6447
- dispose() {
6448
- if (this._disposed) return;
6449
- this.stop();
6450
- this._disposed = true;
6451
- if (this._resizeListener) {
6452
- window.removeEventListener("resize", this._resizeListener);
6453
- this._resizeListener = void 0;
6343
+ function onMouseUp(event) {
6344
+ handleMouseUp(event);
6345
+ scope.dispatchEvent(_endEvent);
6346
+ state = STATE.NONE;
6454
6347
  }
6455
- for (const [dispatcher, events] of this._eventDispatchers) {
6456
- for (const event of events) {
6457
- dispatcher.removeEventListener(event, this._changeListener);
6458
- }
6348
+ function onMouseWheel(event) {
6349
+ if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6350
+ event.preventDefault();
6351
+ scope.dispatchEvent(_startEvent);
6352
+ handleMouseWheel(event);
6353
+ scope.dispatchEvent(_endEvent);
6459
6354
  }
6460
- this._eventDispatchers.clear();
6461
- this._stats?.dom.remove();
6462
- this._stats = void 0;
6463
- this.renderer.domElement.remove();
6464
- this._element = void 0;
6465
- if (this._controls) {
6466
- const controls = this._controls;
6467
- this._controls = void 0;
6468
- controls.enabled = false;
6469
- controls.dispose();
6355
+ function onKeyDown(event) {
6356
+ if (scope.enabled === false || scope.enablePan === false) return;
6357
+ handleKeyDown(event);
6470
6358
  }
6471
- this.scene.clear();
6472
- for (const helper of this._debugHelpers) {
6473
- helper.geometry.dispose();
6474
- const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
6475
- for (const material of materials) {
6476
- material.dispose();
6359
+ function onTouchStart(event) {
6360
+ trackPointer(event);
6361
+ switch (pointers.length) {
6362
+ case 1:
6363
+ switch (scope.touches.ONE) {
6364
+ case TOUCH.ROTATE:
6365
+ if (scope.enableRotate === false) return;
6366
+ handleTouchStartRotate();
6367
+ state = STATE.TOUCH_ROTATE;
6368
+ break;
6369
+ case TOUCH.PAN:
6370
+ if (scope.enablePan === false) return;
6371
+ handleTouchStartPan();
6372
+ state = STATE.TOUCH_PAN;
6373
+ break;
6374
+ default:
6375
+ state = STATE.NONE;
6376
+ }
6377
+ break;
6378
+ case 2:
6379
+ switch (scope.touches.TWO) {
6380
+ case TOUCH.DOLLY_PAN:
6381
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6382
+ handleTouchStartDollyPan();
6383
+ state = STATE.TOUCH_DOLLY_PAN;
6384
+ break;
6385
+ case TOUCH.DOLLY_ROTATE:
6386
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6387
+ handleTouchStartDollyRotate();
6388
+ state = STATE.TOUCH_DOLLY_ROTATE;
6389
+ break;
6390
+ default:
6391
+ state = STATE.NONE;
6392
+ }
6393
+ break;
6394
+ default:
6395
+ state = STATE.NONE;
6396
+ }
6397
+ if (state !== STATE.NONE) {
6398
+ scope.dispatchEvent(_startEvent);
6477
6399
  }
6478
6400
  }
6479
- this._debugHelpers.length = 0;
6480
- this.composer?.dispose();
6481
- this.renderer.dispose();
6482
- this.renderer.forceContextLoss();
6483
- }
6484
- animate(t = performance.now()) {
6485
- if (this._disposed) return;
6486
- if (this._controls?.enabled) {
6487
- this._controls.update();
6488
- }
6489
- if (this._disposed) return;
6490
- if (!this.dirty && !this.options.render.renderAlways) return;
6491
- const interval = this._frameInterval;
6492
- if (interval) {
6493
- const next = this._nextFrameTime;
6494
- if (next !== void 0 && t + 0.1 < next) return;
6495
- this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
6496
- }
6497
- if (this._stats) {
6498
- this._stats.begin();
6401
+ function onTouchMove(event) {
6402
+ trackPointer(event);
6403
+ switch (state) {
6404
+ case STATE.TOUCH_ROTATE:
6405
+ if (scope.enableRotate === false) return;
6406
+ handleTouchMoveRotate(event);
6407
+ scope.update();
6408
+ break;
6409
+ case STATE.TOUCH_PAN:
6410
+ if (scope.enablePan === false) return;
6411
+ handleTouchMovePan(event);
6412
+ scope.update();
6413
+ break;
6414
+ case STATE.TOUCH_DOLLY_PAN:
6415
+ if (scope.enableZoom === false && scope.enablePan === false) return;
6416
+ handleTouchMoveDollyPan(event);
6417
+ scope.update();
6418
+ break;
6419
+ case STATE.TOUCH_DOLLY_ROTATE:
6420
+ if (scope.enableZoom === false && scope.enableRotate === false) return;
6421
+ handleTouchMoveDollyRotate(event);
6422
+ scope.update();
6423
+ break;
6424
+ default:
6425
+ state = STATE.NONE;
6426
+ }
6499
6427
  }
6500
- if (this.options.composer.enabled && this.composer) {
6501
- this.composer.render();
6502
- } else {
6503
- this.renderer.render(this.scene, this.camera);
6428
+ function onTouchEnd(event) {
6429
+ handleTouchEnd(event);
6430
+ scope.dispatchEvent(_endEvent);
6431
+ state = STATE.NONE;
6504
6432
  }
6505
- this.dirty = false;
6506
- if (this._stats) {
6507
- this._stats.end();
6433
+ function onContextMenu(event) {
6434
+ if (scope.enabled === false) return;
6435
+ event.preventDefault();
6508
6436
  }
6509
- }
6510
- //</editor-fold>
6511
- toImage() {
6512
- return this.renderer.domElement.toDataURL();
6513
- }
6514
- ///
6515
- get attachedToBody() {
6516
- return this.element === document.body;
6517
- }
6518
- get viewWidth() {
6519
- return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
6520
- }
6521
- get viewHeight() {
6522
- return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
6523
- }
6524
- get scene() {
6525
- return this._scene;
6526
- }
6527
- get camera() {
6528
- return this._camera;
6529
- }
6530
- get renderer() {
6531
- return this._renderer;
6532
- }
6533
- get composer() {
6534
- return this._composer;
6535
- }
6536
- /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
6537
- get controls() {
6538
- return this._controls;
6539
- }
6540
- ///
6541
- };
6542
-
6543
- // src/skin/Skins.ts
6544
- var Skins = class {
6545
- //<editor-fold desc="Skins">
6546
- static async fromUuidOrUsername(uuidOrUsername) {
6547
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6548
- return this.fromUuid(uuidOrUsername);
6437
+ function addPointer(event) {
6438
+ pointers.push(event);
6549
6439
  }
6550
- return this.fromUsername(uuidOrUsername);
6551
- }
6552
- static async fromUuid(uuid) {
6553
- return this.getSkinProxySkinUrl(uuid);
6554
- }
6555
- static async fromUsername(username) {
6556
- return this.usernameToUuid(username).then((uuid) => {
6557
- if (uuid) {
6558
- return this.fromUuid(uuid);
6559
- }
6560
- return void 0;
6561
- });
6562
- }
6563
- static async fromMineSkin(mineskinId) {
6564
- return this.getMineSkin(mineskinId).then((mineskin) => {
6565
- if (mineskin) {
6566
- return mineskin["data"]["texture"]["value"]["urls"]["skins"];
6440
+ function removePointer(event) {
6441
+ delete pointerPositions[event.pointerId];
6442
+ for (let i = 0; i < pointers.length; i++) {
6443
+ if (pointers[i].pointerId == event.pointerId) {
6444
+ pointers.splice(i, 1);
6445
+ return;
6446
+ }
6567
6447
  }
6568
- return void 0;
6569
- });
6570
- }
6571
- //</editor-fold>
6572
- //<editor-fold desc="Capes">
6573
- static async capeFromUuidOrUsername(uuidOrUsername) {
6574
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6575
- return this.capeFromUuid(uuidOrUsername);
6576
6448
  }
6577
- return this.capeFromUsername(uuidOrUsername);
6578
- }
6579
- static async capeFromUuid(uuid) {
6580
- return this.getSkinProxyCapeUrl(uuid);
6581
- }
6582
- static async capeFromUsername(username) {
6583
- return this.usernameToUuid(username).then((uuid) => {
6584
- if (uuid) {
6585
- return this.capeFromUuid(uuid);
6586
- }
6587
- return void 0;
6588
- });
6589
- }
6590
- static async capeFromCapesDev(uuid, capeType = "minecraft") {
6591
- return this.getCapesDev(uuid, capeType).then((cape) => {
6592
- if (cape) {
6593
- return cape?.stillImageUrl;
6594
- }
6595
- return void 0;
6596
- });
6597
- }
6598
- //</editor-fold>
6599
- //<editor-fold desc="Helpers">
6600
- static async usernameToUuid(username) {
6601
- return this.usernameToUuidSkinProxy(username);
6602
- }
6603
- static async usernameToUuidSkinProxy(username) {
6604
- return Requests.genericRequest({
6605
- baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
6606
- url: "/uuid/" + username
6607
- }).then((res) => {
6608
- if (res.status === 200) {
6609
- return res.data["id"];
6610
- }
6611
- return void 0;
6612
- }).catch((err) => {
6613
- console.warn(err);
6614
- return void 0;
6615
- });
6616
- }
6617
- static async usernameToUuidMineTools(username) {
6618
- return Requests.genericRequest({
6619
- baseURL: "https://api.minetools.eu",
6620
- url: "/uuid/" + username
6621
- }).then((res) => {
6622
- if (res.status === 200) {
6623
- return res.data["id"];
6624
- }
6625
- return void 0;
6626
- }).catch((err) => {
6627
- console.warn(err);
6628
- return void 0;
6629
- });
6630
- }
6631
- static async getProfileFromMinetools(uuid) {
6632
- return Requests.genericRequest({
6633
- baseURL: "https://api.minetools.eu",
6634
- url: "/profile/" + uuid
6635
- }).then((res) => {
6636
- if (res.status === 200) {
6637
- return res.data;
6638
- }
6639
- });
6640
- }
6641
- static async getMineSkin(mineskinId) {
6642
- return Requests.genericRequest({
6643
- baseURL: "https://api.mineskin.org",
6644
- url: "/get/uuid/" + mineskinId
6645
- }).then((res) => {
6646
- if (res.status === 200) {
6647
- return res.data;
6648
- }
6649
- return void 0;
6650
- }).catch((err) => {
6651
- console.warn(err);
6652
- return void 0;
6653
- });
6654
- }
6655
- static async getCapesDev(uuid, type = "all") {
6656
- return Requests.genericRequest({
6657
- baseURL: "https://api.capes.dev",
6658
- url: "/load/" + uuid + "/" + type
6659
- }).then((res) => {
6660
- if (res.status === 200) {
6661
- return res.data;
6449
+ function trackPointer(event) {
6450
+ let position = pointerPositions[event.pointerId];
6451
+ if (position === void 0) {
6452
+ position = new Vector23();
6453
+ pointerPositions[event.pointerId] = position;
6662
6454
  }
6663
- return void 0;
6664
- }).catch((err) => {
6665
- console.warn(err);
6666
- return void 0;
6667
- });
6668
- }
6669
- static getCrafatarSkinUrl(uuid) {
6670
- return "https://crafatar.com/skins/" + uuid;
6671
- }
6672
- static getCrafatarCapeUrl(uuid) {
6673
- return "https://crafatar.com/capes/" + uuid;
6674
- }
6675
- static getMcHeadsSkinUrl(uuid) {
6676
- return "https://mc-heads.net/skin/" + uuid;
6677
- }
6678
- static getMineSkinPlayerSkinUrl(uuid) {
6679
- return "https://mineskin.org/skin/player/" + uuid;
6680
- }
6681
- static getSkinProxySkinUrl(uuid) {
6682
- return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
6455
+ position.set(event.pageX, event.pageY);
6456
+ }
6457
+ function getSecondPointerPosition(event) {
6458
+ const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6459
+ return pointerPositions[pointer.pointerId];
6460
+ }
6461
+ scope.domElement.addEventListener("contextmenu", onContextMenu);
6462
+ scope.domElement.addEventListener("pointerdown", onPointerDown);
6463
+ scope.domElement.addEventListener("pointercancel", onPointerCancel);
6464
+ scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6465
+ this.update();
6683
6466
  }
6684
- static getSkinProxyCapeUrl(uuid) {
6685
- return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
6467
+ };
6468
+ var MapControls = class extends OrbitControls {
6469
+ constructor(object, domElement) {
6470
+ super(object, domElement);
6471
+ this.screenSpacePanning = false;
6472
+ this.mouseButtons.LEFT = MOUSE.PAN;
6473
+ this.mouseButtons.RIGHT = MOUSE.ROTATE;
6474
+ this.touches.ONE = TOUCH.PAN;
6475
+ this.touches.TWO = TOUCH.DOLLY_ROTATE;
6686
6476
  }
6687
- //</editor-fold>
6688
6477
  };
6689
6478
 
6690
6479
  // src/world/Chunk.ts
@@ -6747,7 +6536,7 @@ var MineRenderWorld = class {
6747
6536
  console.log("CHUNKS", this._chunks);
6748
6537
  for (let chunk of this._chunks.values()) {
6749
6538
  console.log("dispose chunk", chunk);
6750
- await chunk?.dispose();
6539
+ await (chunk == null ? void 0 : chunk.dispose());
6751
6540
  }
6752
6541
  this._chunks.clear();
6753
6542
  }
@@ -6801,7 +6590,7 @@ var MineRenderWorld = class {
6801
6590
  };
6802
6591
 
6803
6592
  // src/world/Chunk.ts
6804
- var p11 = prefix("Chunk");
6593
+ var p12 = prefix("Chunk");
6805
6594
  var Chunk = class _Chunk {
6806
6595
  constructor(scene, x, y, z) {
6807
6596
  this._blocks = [];
@@ -6853,7 +6642,7 @@ var Chunk = class _Chunk {
6853
6642
  const index = _Chunk.chunkPosToBlockIndex(pos);
6854
6643
  const current = this._blocks[index];
6855
6644
  if (typeof current !== "undefined") {
6856
- console.debug(p11, "deleting existing block at", pos, worldPos, index);
6645
+ console.debug(p12, "deleting existing block at", pos, worldPos, index);
6857
6646
  current.object.removeFromScene();
6858
6647
  delete this._blocks[index];
6859
6648
  }
@@ -6919,7 +6708,6 @@ export {
6919
6708
  AXES,
6920
6709
  ArchiveAssetSource,
6921
6710
  AssetKey,
6922
- AssetLoadError,
6923
6711
  AssetLoader,
6924
6712
  AssetParser,
6925
6713
  AssetSource,
@@ -6977,7 +6765,6 @@ export {
6977
6765
  OrbitControls,
6978
6766
  PersistentCache,
6979
6767
  Renderer,
6980
- RequestError,
6981
6768
  Requests,
6982
6769
  SKIN_PARTS,
6983
6770
  SceneInspector,