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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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);
@@ -1128,7 +1087,7 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1128
1087
  this.root = root;
1129
1088
  }
1130
1089
  static parse(assetType, str, origin) {
1131
- let namespace = origin?.namespace || DEFAULT_NAMESPACE;
1090
+ let namespace = (origin == null ? void 0 : origin.namespace) || DEFAULT_NAMESPACE;
1132
1091
  if (str.includes(":")) {
1133
1092
  let split2 = str.split(":");
1134
1093
  namespace = split2[0];
@@ -1141,12 +1100,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1141
1100
  split.shift();
1142
1101
  }
1143
1102
  let path = split.join("/");
1144
- let extension = assetType === "textures" ? ".png" : origin?.assetType || ".json";
1145
- 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);
1146
1105
  }
1147
1106
  toString() {
1148
1107
  let a = [
1149
- this.root ?? AssetLoader.ROOT,
1108
+ typeof this.root !== "undefined" || AssetLoader.ROOT !== DEFAULT_ROOT ? this.root ?? AssetLoader.ROOT : "__root__",
1150
1109
  this.rootType ?? "__rootType__",
1151
1110
  this.assetType ?? "__assetType__",
1152
1111
  this.type ?? "__type__",
@@ -1156,12 +1115,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
1156
1115
  return a.join("/");
1157
1116
  }
1158
1117
  getFullPath() {
1159
- let p12 = [];
1118
+ let p13 = [];
1160
1119
  if (this.type) {
1161
- p12.push(this.type);
1120
+ p13.push(this.type);
1162
1121
  }
1163
- p12.push(this.path);
1164
- return p12.join("/");
1122
+ p13.push(this.path);
1123
+ return p13.join("/");
1165
1124
  }
1166
1125
  toNamespacedString() {
1167
1126
  return this.namespace + ":" + this.getFullPath();
@@ -1183,10 +1142,10 @@ var ModelMerger = class {
1183
1142
  const models = await this.collectAllParents(model);
1184
1143
  let merged = {};
1185
1144
  for (let parentModel of models) {
1186
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1145
+ merged = (0, import_ts_deepmerge.default)(merged, parentModel);
1187
1146
  }
1188
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1189
- 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}`);
1190
1149
  merged.hierarchy.push(`${merged.parent}`);
1191
1150
  return merged;
1192
1151
  }
@@ -1196,7 +1155,6 @@ var ModelMerger = class {
1196
1155
  }
1197
1156
  const models = [];
1198
1157
  const parentKey = AssetKey.parse("models", model.parent);
1199
- parentKey.root = model.key?.root;
1200
1158
  const parentModel = await Models.getRaw(parentKey);
1201
1159
  if (parentModel) {
1202
1160
  models.unshift(parentModel);
@@ -1206,6 +1164,9 @@ var ModelMerger = class {
1206
1164
  }
1207
1165
  };
1208
1166
 
1167
+ // src/assets/Models.ts
1168
+ import { Memoize } from "typescript-memoize";
1169
+
1209
1170
  // src/assets/source/parser/AssetParsers.ts
1210
1171
  var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1211
1172
  AssetParser2["MODEL"] = "model";
@@ -1219,65 +1180,30 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
1219
1180
  })(AssetParser || {});
1220
1181
 
1221
1182
  // src/assets/Models.ts
1222
- var Models = class _Models {
1183
+ var _Models = class _Models {
1223
1184
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1224
1185
  // the library, and would require an EnvProvider before any entry has had a chance to register
1225
1186
  static get PERSISTENT_CACHE() {
1226
1187
  return this._persistentCache ??= PersistentCache.open("minerender-models");
1227
1188
  }
1228
1189
  static async getItemList() {
1229
- const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
1230
- const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
1231
- return Caching.listAssetCache.get(key.serialize(), async () => {
1232
- return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
1233
- }).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) ?? []);
1234
1199
  }
1235
1200
  static async loadAndMerge(key) {
1236
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
1201
+ const model = await this.getRaw(key);
1237
1202
  if (!model) {
1238
1203
  return void 0;
1239
1204
  }
1240
1205
  return ModelMerger.mergeWithParents(model);
1241
1206
  }
1242
- static async getItemModel(key) {
1243
- const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1244
- const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
1245
- const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1246
- if (!result) return void 0;
1247
- if (result.key.assetType !== "items") return { ...result.asset, key };
1248
- const reference = this.defaultItemModel(result.asset.model, key);
1249
- const modelKey = AssetKey.parse("models", reference);
1250
- modelKey.root = key.root;
1251
- const model2 = await this.getRaw(modelKey);
1252
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
1253
- return model2;
1254
- });
1255
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1256
- }
1257
- // Item previews use the GUI context, false conditions, and zero numeric properties.
1258
- static defaultItemModel(node, key) {
1259
- if (!node || typeof node.type !== "string") {
1260
- throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
1261
- }
1262
- switch (node.type.replace(/^minecraft:/, "")) {
1263
- case "model":
1264
- if (typeof node.model === "string" && node.model) return node.model;
1265
- break;
1266
- case "condition":
1267
- return this.defaultItemModel(node.on_false, key);
1268
- case "select": {
1269
- 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;
1270
- return this.defaultItemModel(selected ?? node.fallback, key);
1271
- }
1272
- case "range_dispatch": {
1273
- const selected = node.entries?.reduce((match, entry) => {
1274
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
1275
- }, void 0);
1276
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
1277
- }
1278
- }
1279
- throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
1280
- }
1281
1207
  static async getRaw(key) {
1282
1208
  if (!key.assetType) {
1283
1209
  key.assetType = "models";
@@ -1316,15 +1242,19 @@ var Models = class _Models {
1316
1242
  return this.PERSISTENT_CACHE.clear();
1317
1243
  }
1318
1244
  };
1245
+ __decorateClass([
1246
+ Memoize()
1247
+ ], _Models, "getItemList", 1);
1248
+ var Models = _Models;
1319
1249
 
1320
1250
  // src/assets/BlockStates.ts
1251
+ import { Memoize as Memoize2 } from "typescript-memoize";
1321
1252
  var BlockStates = class {
1322
1253
  static get PERSISTENT_CACHE() {
1323
1254
  return this._persistentCache ??= PersistentCache.open("minerender-blockstates");
1324
1255
  }
1325
- // BlockState names are hardcoded
1326
1256
  static async getList() {
1327
- const key = new AssetKey(
1257
+ return AssetLoader.get(new AssetKey(
1328
1258
  DEFAULT_NAMESPACE,
1329
1259
  "_list",
1330
1260
  "blockstates",
@@ -1332,16 +1262,11 @@ var BlockStates = class {
1332
1262
  "assets",
1333
1263
  ".json",
1334
1264
  DEFAULT_ROOT
1335
- );
1336
- return Caching.listAssetCache.get(key.serialize(), () => {
1337
- return AssetLoader.get(key, "list" /* LIST */);
1338
- }).then((r) => r?.files ?? []);
1265
+ ), "list" /* LIST */).then((r) => (r == null ? void 0 : r.files) ?? []);
1339
1266
  }
1340
1267
  static async getDefaultStates() {
1341
1268
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
1342
- return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
1343
- return AssetLoader.get(key, "json" /* JSON */);
1344
- });
1269
+ return AssetLoader.get(key, "json" /* JSON */);
1345
1270
  }
1346
1271
  static async getDefaultState(key) {
1347
1272
  const defaultStates = await this.getDefaultStates();
@@ -1380,11 +1305,17 @@ var BlockStates = class {
1380
1305
  await this.PERSISTENT_CACHE.clear();
1381
1306
  }
1382
1307
  };
1308
+ __decorateClass([
1309
+ Memoize2()
1310
+ ], BlockStates, "getList", 1);
1311
+ __decorateClass([
1312
+ Memoize2()
1313
+ ], BlockStates, "getDefaultStates", 1);
1383
1314
  var DefaultBlockStates = class {
1384
1315
  };
1385
1316
 
1386
1317
  // src/assets/Assets.ts
1387
- var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
1318
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
1388
1319
  var DEFAULT_NAMESPACE = "minecraft";
1389
1320
  var Assets = class {
1390
1321
  /**
@@ -1406,150 +1337,13 @@ var AssetSource = class {
1406
1337
  constructor() {
1407
1338
  }
1408
1339
  };
1409
- var AssetLoadError = class extends Error {
1410
- constructor(source, key, path, cause) {
1411
- super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
1412
- this.source = source;
1413
- this.key = key;
1414
- this.path = path;
1415
- this.cause = cause;
1416
- this.name = "AssetLoadError";
1417
- }
1418
- };
1419
-
1420
- // src/util/BatchedExecutor.ts
1421
- var BatchedExecutor = class {
1422
- constructor(interval = 1, batch = 30) {
1423
- this.interval = interval;
1424
- this.batch = batch;
1425
- this.queue = [];
1426
- this.task = setInterval(() => this.run());
1427
- }
1428
- submit(task) {
1429
- this.queue.push(task);
1430
- }
1431
- run() {
1432
- for (let i = 0; i < this.batch; i++) {
1433
- this.runNext();
1434
- }
1435
- }
1436
- runNext() {
1437
- let next = this.queue.shift();
1438
- if (next) next();
1439
- }
1440
- };
1441
-
1442
- // src/util/model.ts
1443
- import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1444
- function applyElementRotation(rotation, geometry) {
1445
- const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1446
- geometry.translate(-origin.x, -origin.y, -origin.z);
1447
- switch (rotation.axis) {
1448
- case "x" /* X */:
1449
- geometry.rotateX(toRadians(rotation.angle));
1450
- break;
1451
- case "y" /* Y */:
1452
- geometry.rotateY(toRadians(rotation.angle));
1453
- break;
1454
- case "z" /* Z */:
1455
- geometry.rotateZ(toRadians(rotation.angle));
1456
- break;
1457
- }
1458
- if (rotation.rescale) {
1459
- if (Math.abs(rotation.angle) === 22.5) {
1460
- const s = 1 / Math.cos(0.39269909262657166);
1461
- geometry.scale(s, 1, s);
1462
- } else {
1463
- const s = 1 / Math.cos(0.7853981852531433);
1464
- geometry.scale(s, 1, s);
1465
- }
1466
- }
1467
- geometry.translate(origin.x, origin.y, origin.z);
1468
- }
1469
- function applyModelPartRotation(modelPart, geometry) {
1470
- const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1471
- geometry.translate(-origin.x, -origin.y, -origin.z);
1472
- geometry.rotateX(toRadians(modelPart.pitch));
1473
- geometry.rotateY(toRadians(modelPart.yaw));
1474
- geometry.rotateZ(toRadians(modelPart.roll));
1475
- geometry.translate(origin.x, origin.y, origin.z);
1476
- }
1477
- function applyGenericRotation(axis, rotation, obj) {
1478
- switch (axis) {
1479
- case "x" /* X */:
1480
- obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1481
- break;
1482
- case "y" /* Y */:
1483
- obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1484
- break;
1485
- case "z" /* Z */:
1486
- obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1487
- break;
1488
- }
1489
- }
1490
- function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1491
- let size = new Vector32();
1492
- box.getSize(size);
1493
- let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1494
- let wireGeo = new EdgesGeometry(boxGeo);
1495
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1496
- let wireframe = new LineSegments(wireGeo, wireMat);
1497
- obj.add(wireframe);
1498
- let axes = new AxesHelper(1);
1499
- obj.add(axes);
1500
- }
1501
- function addWireframeToObject(obj, color = 16777215, w = 2) {
1502
- let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
1503
- let wireGeo = new EdgesGeometry(boxGeo);
1504
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1505
- let wireframe = new LineSegments(wireGeo, wireMat);
1506
- obj.add(wireframe);
1507
- let axes = new AxesHelper(1);
1508
- obj.add(axes);
1509
- }
1510
- function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1511
- let wireGeo = new EdgesGeometry(geo);
1512
- let wireMat = new LineBasicMaterial({ color, linewidth: w });
1513
- let wireframe = new LineSegments(wireGeo, wireMat);
1514
- mesh.add(wireframe);
1515
- let axes = new AxesHelper(1);
1516
- mesh.add(axes);
1517
- }
1518
-
1519
- // src/util/performance.ts
1520
- function captureException(e, ...extra) {
1521
- console.error(e, extra);
1522
- }
1523
- function timingStart(marker) {
1524
- console.time(marker);
1525
- }
1526
- function timingEnd(marker) {
1527
- console.timeEnd(marker);
1528
- }
1529
-
1530
- // src/util/three.ts
1531
- function isObject3D(obj) {
1532
- return obj.isObject3D;
1533
- }
1534
- function isMesh(obj) {
1535
- return obj.isMesh;
1536
- }
1537
- function isInstancedMesh(obj) {
1538
- return obj.isInstancedMesh;
1539
- }
1540
- function isPerspectiveCamera(obj) {
1541
- return obj.isPerspectiveCamera;
1542
- }
1543
- function isOrthographicCamera(obj) {
1544
- return obj.isOrthographicCamera;
1545
- }
1546
-
1547
- // src/nbt/NBTHelper.ts
1548
- var NBTHelper = class {
1549
- static async fromBuffer(buffer) {
1550
- const prismarineNbt = await import("prismarine-nbt");
1551
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer);
1552
- 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;
1553
1347
  }
1554
1348
  };
1555
1349
 
@@ -1559,83 +1353,7 @@ var p3 = prefix("HostedAssetSource");
1559
1353
  var DEFAULT_OPTIONS = {
1560
1354
  retryDefaults: true
1561
1355
  };
1562
- var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1563
- static {
1564
- this.MODEL = {
1565
- config(request) {
1566
- },
1567
- parse(response) {
1568
- return response.data;
1569
- }
1570
- };
1571
- }
1572
- static {
1573
- this.BLOCKSTATE = {
1574
- config(request) {
1575
- },
1576
- parse(response) {
1577
- return response.data;
1578
- }
1579
- };
1580
- }
1581
- static {
1582
- this.META = {
1583
- config(request) {
1584
- },
1585
- parse(response) {
1586
- return response.data;
1587
- }
1588
- };
1589
- }
1590
- static {
1591
- this.NBT = {
1592
- config(request) {
1593
- request.responseType = "arraybuffer";
1594
- },
1595
- parse(response) {
1596
- return NBTHelper.fromBuffer(Buffer.from(response.data));
1597
- }
1598
- };
1599
- }
1600
- static {
1601
- this.IMAGE = {
1602
- config(request) {
1603
- request.responseType = "arraybuffer";
1604
- },
1605
- async parse(response) {
1606
- return await ImageLoader.processResponse(response);
1607
- }
1608
- };
1609
- }
1610
- static {
1611
- this.LIST = {
1612
- config(request) {
1613
- },
1614
- parse(response) {
1615
- return response.data;
1616
- }
1617
- };
1618
- }
1619
- static {
1620
- this.JSON = {
1621
- config(request) {
1622
- },
1623
- parse(response) {
1624
- return response.data;
1625
- }
1626
- };
1627
- }
1628
- static {
1629
- this.PARSER_MAP = /* @__PURE__ */ new Map([
1630
- ["model" /* MODEL */, _HostedAssetSource.MODEL],
1631
- ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
1632
- ["meta" /* META */, _HostedAssetSource.META],
1633
- ["nbt" /* NBT */, _HostedAssetSource.NBT],
1634
- ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
1635
- ["list" /* LIST */, _HostedAssetSource.LIST],
1636
- ["json" /* JSON */, _HostedAssetSource.JSON]
1637
- ]);
1638
- }
1356
+ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
1639
1357
  async loadOrRetryWithDefaults(key, parser) {
1640
1358
  const direct = await this.load(key, parser);
1641
1359
  if (typeof direct !== "undefined") {
@@ -1670,25 +1388,31 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1670
1388
  console.info(p3, "Loading", key);
1671
1389
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1672
1390
  console.debug(p3, url);
1673
- const request = { url };
1674
- try {
1675
- parser.config(request);
1676
- let response;
1677
- try {
1678
- response = await Requests.mcAssetRequest(request);
1679
- } catch (cause) {
1680
- if (cause instanceof RequestError && cause.response?.status === 404) {
1681
- 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;
1682
1402
  }
1683
- throw cause;
1684
1403
  }
1685
- if (response.data === void 0) {
1686
- 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
+ }
1687
1412
  }
1688
- return await parser.parse(response);
1689
- } catch (cause) {
1690
- throw new AssetLoadError(this, key, request.url, cause);
1691
- }
1413
+ console.debug(p3, "Failed to load", key, err == null ? void 0 : err.message);
1414
+ return void 0;
1415
+ });
1692
1416
  }
1693
1417
  assetBasePath(key) {
1694
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 + "/" : ""}`;
@@ -1712,6 +1436,67 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
1712
1436
  return this.load(key, responseParser);
1713
1437
  }
1714
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;
1715
1500
 
1716
1501
  // src/assets/source/archive/BrowserArchiveProxy.ts
1717
1502
  import { BlobReader, BlobWriter, ZipReader } from "@zip.js/zip.js";
@@ -1734,6 +1519,7 @@ var BrowserArchiveProxy = class {
1734
1519
  };
1735
1520
 
1736
1521
  // src/assets/source/archive/ArchiveAssetSource.ts
1522
+ var p4 = prefix("ArchiveAssetSource");
1737
1523
  var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1738
1524
  constructor(archiveProxy) {
1739
1525
  super();
@@ -1752,31 +1538,74 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1752
1538
  }
1753
1539
  async get(key, parser) {
1754
1540
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
1755
- return this.load(key, responseParser);
1756
- }
1757
- async load(key, parser) {
1541
+ console.log("ArchiveAssetSource.get", key, parser);
1542
+ let entries = await this.getEntries();
1758
1543
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1759
- let url;
1760
- try {
1761
- const entry = await this.getEntry(path);
1762
- if (!entry) {
1763
- 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
+ }
1764
1565
  }
1765
- url = URL.createObjectURL(await entry.getData());
1766
- const request = { url };
1767
- parser.config(request);
1768
- const response = await Requests.genericRequest(request);
1769
- if (response.data === void 0) {
1770
- throw new Error("Asset response has no data");
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
+ }
1771
1574
  }
1772
- return await parser.parse(response);
1773
- } catch (cause) {
1774
- throw new AssetLoadError(this, key, path, cause);
1775
- } finally {
1776
- if (url !== void 0) {
1777
- URL.revokeObjectURL(url);
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
+ }
1778
1596
  }
1779
- }
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
+ }
1605
+ }
1606
+ console.debug(p4, "Failed to load", key, err == null ? void 0 : err.message);
1607
+ return void 0;
1608
+ });
1780
1609
  }
1781
1610
  assetBasePath(key) {
1782
1611
  return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
@@ -1784,23 +1613,18 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
1784
1613
  };
1785
1614
 
1786
1615
  // src/assets/AssetLoader.ts
1787
- var p4 = prefix("AssetLoader");
1788
- var AssetLoader = class {
1789
- static {
1790
- this.ROOT = DEFAULT_ROOT;
1791
- }
1792
- static {
1793
- this._SOURCES = [];
1794
- }
1616
+ var import_ts_deepmerge3 = __toESM(require_dist());
1617
+ var p5 = prefix("AssetLoader");
1618
+ var _AssetLoader = class _AssetLoader {
1795
1619
  static addSource(key, source, override = true) {
1796
1620
  if (override) {
1797
1621
  const existing = this.removeSource(key);
1798
1622
  if (existing) {
1799
- console.log(p4, "Removed existing AssetSource", key);
1623
+ console.log(p5, "Removed existing AssetSource", key);
1800
1624
  }
1801
1625
  }
1802
1626
  this._SOURCES.unshift({ key, source });
1803
- console.log(p4, "Added AssetSource", key);
1627
+ console.log(p5, "Added AssetSource", key);
1804
1628
  }
1805
1629
  static removeSource(key) {
1806
1630
  const index = this._SOURCES.findIndex((s) => s.key === key);
@@ -1812,11 +1636,8 @@ var AssetLoader = class {
1812
1636
  }
1813
1637
  return void 0;
1814
1638
  }
1815
- static {
1816
- this.addSource("mcassets-fallback", new HostedAssetSource("https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master", { retryDefaults: false }));
1817
- this.addSource("mcassets", new HostedAssetSource(DEFAULT_ROOT, { retryDefaults: false }));
1818
- }
1819
1639
  static async getAll(key, parser) {
1640
+ console.log(this._SOURCES);
1820
1641
  let promises = [];
1821
1642
  for (const source of this._SOURCES) {
1822
1643
  promises.push(source.source.get(key, parser));
@@ -1825,36 +1646,31 @@ var AssetLoader = class {
1825
1646
  return results.filter((r) => r != void 0);
1826
1647
  });
1827
1648
  }
1828
- /** Returns the first defined result in source-priority order, without merging assets. */
1829
1649
  static async get(key, parser) {
1830
- const keys = [key];
1831
- if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
1832
- keys.push(new AssetKey(
1833
- key.namespace,
1834
- key.path,
1835
- key.assetType === "structure" ? "structures" : "structure",
1836
- key.type,
1837
- key.rootType,
1838
- key.extension,
1839
- key.root
1840
- ));
1841
- }
1842
- return (await this.getFirst(keys, parser))?.asset;
1843
- }
1844
- /** Tries each path within a source before considering lower-priority sources. */
1845
- static async getFirst(keys, parser) {
1846
- const sources = [...this._SOURCES];
1847
- for (const source of sources) {
1848
- for (const key of keys) {
1849
- const result = await source.source.get(key, parser);
1850
- if (result !== void 0) {
1851
- 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;
1852
1663
  }
1853
1664
  }
1854
- }
1855
- return void 0;
1665
+ return void 0;
1666
+ });
1856
1667
  }
1857
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;
1858
1674
 
1859
1675
  // src/assets/ModelTextures.ts
1860
1676
  var ModelTextures = class {
@@ -1862,21 +1678,11 @@ var ModelTextures = class {
1862
1678
  return this._persistentMetaCache ??= PersistentCache.open("minerender-texturemeta");
1863
1679
  }
1864
1680
  static async get(key) {
1865
- const keyStr = key.serialize();
1866
- const pending = this.preload(key);
1867
- const cached = Caching.textureAssetCache.getIfPresent(keyStr);
1868
- try {
1869
- const asset = await pending;
1870
- if (asset) {
1871
- return await ImageLoader.infoToCanvasData(asset);
1872
- }
1873
- return void 0;
1874
- } catch (err) {
1875
- if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
1876
- Caching.textureAssetCache.invalidate(keyStr);
1877
- }
1878
- throw err;
1681
+ const asset = await this.preload(key);
1682
+ if (asset) {
1683
+ return ImageLoader.infoToCanvasData(asset);
1879
1684
  }
1685
+ return void 0;
1880
1686
  }
1881
1687
  static async preload(key) {
1882
1688
  const keyStr = key.serialize();
@@ -1950,28 +1756,7 @@ var CanvasImage = class {
1950
1756
  };
1951
1757
 
1952
1758
  // src/Ticker.ts
1953
- var Ticker = class _Ticker {
1954
- static {
1955
- this.TPS = 20;
1956
- }
1957
- static {
1958
- this.counter = 0;
1959
- }
1960
- static {
1961
- this._tickers = /* @__PURE__ */ new Map();
1962
- }
1963
- static {
1964
- this.oneSecondTps = 0;
1965
- }
1966
- static {
1967
- this.oneSecondTicks = 0;
1968
- }
1969
- static {
1970
- this.fiveSecondTps = 0;
1971
- }
1972
- static {
1973
- this.fiveSecondTicks = 0;
1974
- }
1759
+ var _Ticker = class _Ticker {
1975
1760
  static schedule(fn, ms) {
1976
1761
  const handle = setInterval(fn, ms);
1977
1762
  const unref = handle.unref;
@@ -2033,6 +1818,14 @@ var Ticker = class _Ticker {
2033
1818
  this._tickers.clear();
2034
1819
  }
2035
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;
2036
1829
 
2037
1830
  // src/texture/TextureAtlas.ts
2038
1831
  var TextureAtlas = class {
@@ -2058,9 +1851,6 @@ var TextureAtlas = class {
2058
1851
 
2059
1852
  // src/model/ModelGenerator.ts
2060
1853
  var ModelGenerator = class {
2061
- static {
2062
- this.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2063
- }
2064
1854
  static generateItemModel(imageData, layer) {
2065
1855
  const mainElement = {
2066
1856
  from: [0, 0, 7.5],
@@ -2080,9 +1870,10 @@ var ModelGenerator = class {
2080
1870
  return [mainElement];
2081
1871
  }
2082
1872
  };
1873
+ ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
2083
1874
 
2084
1875
  // src/UVMapper.ts
2085
- var p5 = prefix("UVMapper");
1876
+ var p6 = prefix("UVMapper");
2086
1877
  var DEFAULT_UV = [0, 0, 16, 16];
2087
1878
  var X = 0;
2088
1879
  var Y = 1;
@@ -2255,11 +2046,12 @@ var UVMapper = class {
2255
2046
  return [tl, tr, bl, br];
2256
2047
  }
2257
2048
  static async createAtlas(originalModel) {
2049
+ var _a;
2258
2050
  const textureMap = {};
2259
2051
  const metaMap = {};
2260
2052
  const model = { ...originalModel };
2261
2053
  const isItemModel = !("elements" in model);
2262
- console.debug(p5, "Creating Atlas for", model.key);
2054
+ console.debug(p6, "Creating Atlas for", model.key);
2263
2055
  if (model.textures) {
2264
2056
  const promises = [];
2265
2057
  const uniqueTextureNames = [];
@@ -2273,7 +2065,7 @@ var UVMapper = class {
2273
2065
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
2274
2066
  promises.push(ModelTextures.get(assetKey).then((asset) => {
2275
2067
  if (!asset) {
2276
- console.warn(p5, "Missing texture", assetKey);
2068
+ console.warn(p6, "Missing texture", assetKey);
2277
2069
  return;
2278
2070
  }
2279
2071
  textureMap[textureKey] = new WrappedImage(asset);
@@ -2285,7 +2077,7 @@ var UVMapper = class {
2285
2077
  }
2286
2078
  await Promise.all(promises);
2287
2079
  const textureCount = uniqueTextureNames.length;
2288
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
2080
+ console.debug(p6, "Creating Atlas for", textureCount, "textures");
2289
2081
  this.fillMissingTextureKeys(model.textures, textureMap);
2290
2082
  this.fillMissingTextureKeys(model.textures, metaMap);
2291
2083
  const sizes = {};
@@ -2305,7 +2097,7 @@ var UVMapper = class {
2305
2097
  this.fillMissingTextureKeys(model.textures, sizes);
2306
2098
  const s = Math.ceil(Math.sqrt(textureCount + 1));
2307
2099
  const size = Math.ceil(s * maxWidth);
2308
- console.debug(p5, "Atlas size:", size);
2100
+ console.debug(p6, "Atlas size:", size);
2309
2101
  const squaredSize = size * size;
2310
2102
  const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
2311
2103
  const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
@@ -2334,15 +2126,16 @@ var UVMapper = class {
2334
2126
  if (texture.animated) {
2335
2127
  hasAnimation = true;
2336
2128
  const meta = metaMap[textureKey];
2337
- const frameTime = meta?.animation?.frametime ?? 1;
2129
+ const frameTime = ((_a = meta == null ? void 0 : meta.animation) == null ? void 0 : _a.frametime) ?? 1;
2338
2130
  console.log(meta);
2339
2131
  console.log(frameTime);
2340
2132
  let t = 0;
2341
2133
  let f = 0;
2342
2134
  animatorFunctions[textureKey] = () => {
2135
+ var _a2;
2343
2136
  if (t++ >= frameTime) {
2344
2137
  t = 0;
2345
- const frames = meta?.animation?.frames;
2138
+ const frames = (_a2 = meta == null ? void 0 : meta.animation) == null ? void 0 : _a2.frames;
2346
2139
  const frame = frames ? frames[f] : f;
2347
2140
  image.putData(texture.getFrameSectionData(frame), x, y, 0, 0, maxWidth, maxWidth);
2348
2141
  f++;
@@ -2360,10 +2153,10 @@ var UVMapper = class {
2360
2153
  }
2361
2154
  }
2362
2155
  const atlasImageData = image.toDataURL();
2363
- console.log(p5, "Atlas Image for", model.key, atlasImageData);
2156
+ console.log(p6, "Atlas Image for", model.key, atlasImageData);
2364
2157
  this.fillMissingTextureKeys(model.textures, positions);
2365
2158
  if (isItemModel) {
2366
- console.debug(p5, "Generating item model for", model);
2159
+ console.debug(p6, "Generating item model for", model);
2367
2160
  model.elements = [];
2368
2161
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
2369
2162
  const textureImage = textureMap[layerName];
@@ -2371,7 +2164,7 @@ var UVMapper = class {
2371
2164
  model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
2372
2165
  }
2373
2166
  }
2374
- console.debug(p5, "Item model elements", model.elements);
2167
+ console.debug(p6, "Item model elements", model.elements);
2375
2168
  }
2376
2169
  if (!model.elements) {
2377
2170
  }
@@ -2389,13 +2182,17 @@ var UVMapper = class {
2389
2182
  this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
2390
2183
  continue;
2391
2184
  }
2392
- if (!face.texture) continue;
2393
2185
  if (!face.uv) {
2394
2186
  face.uv = this.getFallbackUv(element, faceName);
2395
2187
  }
2396
- const faceTexture = face.texture.substr(1);
2397
- const texPosition = positions[faceTexture] || [0, 0];
2398
- 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
+ }
2399
2196
  let texPosV = new Vector2(texPosition[0], texPosition[1]);
2400
2197
  const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
2401
2198
  tl.add(texPosV);
@@ -2427,7 +2224,7 @@ var UVMapper = class {
2427
2224
  hasTransparency
2428
2225
  );
2429
2226
  } else {
2430
- console.warn(p5, "Model does not have any textures", model);
2227
+ console.warn(p6, "Model does not have any textures", model);
2431
2228
  }
2432
2229
  return void 0;
2433
2230
  }
@@ -2565,20 +2362,17 @@ function shutdown() {
2565
2362
  }
2566
2363
 
2567
2364
  // src/assets/Entities.ts
2365
+ import { Memoize as Memoize3 } from "typescript-memoize";
2568
2366
  var Entities = class {
2569
2367
  static async getBlockEntityModels() {
2570
2368
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
2571
2369
  console.log(key);
2572
- return Caching.entityModelsCache.get(key.serialize(), () => {
2573
- return AssetLoader.get(key, "json" /* JSON */);
2574
- });
2370
+ return AssetLoader.get(key, "json" /* JSON */);
2575
2371
  }
2576
2372
  static async getEntityModels() {
2577
2373
  const key = AssetKey.parse("models", "minerender:entityModels");
2578
2374
  console.log(key);
2579
- return Caching.entityModelsCache.get(key.serialize(), () => {
2580
- return AssetLoader.get(key, "json" /* JSON */);
2581
- });
2375
+ return AssetLoader.get(key, "json" /* JSON */);
2582
2376
  }
2583
2377
  // BlockEntity names are hardcoded
2584
2378
  static async getBlockList() {
@@ -2624,6 +2418,12 @@ var Entities = class {
2624
2418
  };
2625
2419
  }
2626
2420
  };
2421
+ __decorateClass([
2422
+ Memoize3()
2423
+ ], Entities, "getBlockEntityModels", 1);
2424
+ __decorateClass([
2425
+ Memoize3()
2426
+ ], Entities, "getEntityModels", 1);
2627
2427
  var EntityModels = class {
2628
2428
  };
2629
2429
  var BlockEntityModels = class {
@@ -2687,26 +2487,18 @@ var MineRenderError = class _MineRenderError extends Error {
2687
2487
  };
2688
2488
 
2689
2489
  // src/renderer/SceneObject.ts
2690
- var import_ts_deepmerge3 = __toESM(require_dist());
2691
- var p6 = prefix("SceneObject");
2692
- 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 {
2693
2493
  constructor(options) {
2694
2494
  super();
2695
2495
  this.isSceneObject = true;
2696
2496
  this.materialCallbacks = {};
2697
2497
  this._isInstanced = false;
2698
2498
  this._instanceCounter = 0;
2699
- this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2499
+ this.options = (0, import_ts_deepmerge4.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
2700
2500
  console.log("SceneObject options", this.options);
2701
2501
  }
2702
- static {
2703
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
2704
- instanceMeshes: true,
2705
- maxInstanceCount: 50,
2706
- mergeMeshes: true,
2707
- wireframe: false
2708
- });
2709
- }
2710
2502
  set scene(scene) {
2711
2503
  if (!!this._scene) throw new MineRenderError("Scene already set");
2712
2504
  this._scene = scene;
@@ -2875,9 +2667,9 @@ var SceneObject = class _SceneObject extends Object3D2 {
2875
2667
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2876
2668
  const i = this._instanceCounter++;
2877
2669
  this.setMatrixAt(i, new Matrix42());
2878
- console.debug(p6, "nextInstance " + i);
2670
+ console.debug(p7, "nextInstance " + i);
2879
2671
  if (i === this.options.maxInstanceCount) {
2880
- console.warn(p6, "Max instance count reached for " + this);
2672
+ console.warn(p7, "Max instance count reached for " + this);
2881
2673
  }
2882
2674
  if (this.scene) {
2883
2675
  this.scene.stats.instanceCount++;
@@ -3048,29 +2840,34 @@ var SceneObject = class _SceneObject extends Object3D2 {
3048
2840
  this.notifyDirty();
3049
2841
  }
3050
2842
  removeFromScene() {
3051
- this._scene?.remove(this);
2843
+ var _a;
2844
+ (_a = this._scene) == null ? void 0 : _a.remove(this);
3052
2845
  this.notifyDirty();
3053
2846
  }
3054
2847
  //</editor-fold>
3055
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;
3056
2856
  function isSceneObject(obj) {
3057
2857
  return obj.isSceneObject;
3058
2858
  }
3059
2859
 
3060
2860
  // src/entity/scene/EntityObject.ts
3061
- var import_ts_deepmerge4 = __toESM(require_dist());
2861
+ var import_ts_deepmerge5 = __toESM(require_dist());
3062
2862
  import { Object3D as Object3D3 } from "three";
3063
- import * as THREE3 from "three";
2863
+ import * as THREE2 from "three";
3064
2864
  var EntityObject = class extends SceneObject {
3065
2865
  constructor(entity, options) {
3066
2866
  super();
3067
2867
  this.entity = entity;
3068
2868
  this.isEntityObject = true;
3069
2869
  this.meshesCreated = false;
3070
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3071
- }
3072
- static {
3073
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
2870
+ this.options = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3074
2871
  }
3075
2872
  async init() {
3076
2873
  this.createMeshes();
@@ -3079,19 +2876,17 @@ var EntityObject = class extends SceneObject {
3079
2876
  dispose() {
3080
2877
  super.dispose();
3081
2878
  }
3082
- get textureKey() {
3083
- return new AssetKey(
3084
- 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,
3085
2883
  this.entity.key.path,
3086
2884
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
3087
2885
  "textures",
3088
2886
  "entity",
3089
2887
  "assets",
3090
2888
  ".png"
3091
- );
3092
- }
3093
- async loadTextures() {
3094
- this.imageData = await ModelTextures.get(this.textureKey);
2889
+ ));
3095
2890
  }
3096
2891
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3097
2892
  createMeshes(force = false) {
@@ -3110,8 +2905,8 @@ var EntityObject = class extends SceneObject {
3110
2905
  const l = cube.maxZ - cube.minZ;
3111
2906
  const uv = texture.toUvArray(w, h, l);
3112
2907
  const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3113
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3114
- 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));
3115
2910
  applyModelPartRotation(part, cubeGeo);
3116
2911
  const mesh = this.createMesh(partName, cubeGeo, mat);
3117
2912
  partAnchor.add(mesh);
@@ -3124,25 +2919,24 @@ var EntityObject = class extends SceneObject {
3124
2919
  this.meshesCreated = true;
3125
2920
  }
3126
2921
  async applyTextures() {
3127
- const assetKeyStr = this.textureKey.serialize();
3128
- const keyStr = `entity:${assetKeyStr}`;
3129
- let mat = Caching.materialCache.getIfPresent(keyStr);
3130
- if (!mat) {
3131
- const pending = this.loadTextures();
3132
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3133
- await pending;
3134
- if (!this.imageData) return;
3135
- const canvas = this.imageData.data.canvas;
3136
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3137
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3138
- this.imageData = void 0;
3139
- }
3140
- this.iterateAllMeshes((mesh) => {
3141
- mesh.material = mat;
3142
- });
3143
- 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
+ }
3144
2937
  }
3145
2938
  };
2939
+ EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3146
2940
  function isEntityObject(obj) {
3147
2941
  return obj.isEntityObject;
3148
2942
  }
@@ -3154,7 +2948,7 @@ var GuiObject = class extends SceneObject {
3154
2948
 
3155
2949
  // src/inspector/SceneInspector.ts
3156
2950
  import { Raycaster, Vector2 as Vector22 } from "three";
3157
- var p7 = prefix("SceneInspector");
2951
+ var p8 = prefix("SceneInspector");
3158
2952
  var help = "<span>Ctrl+Click to Select<br/></span><br/>";
3159
2953
  var SceneInspector = class {
3160
2954
  constructor(renderer) {
@@ -3183,7 +2977,8 @@ var SceneInspector = class {
3183
2977
  return out;
3184
2978
  }
3185
2979
  onClick(event) {
3186
- if (event.target?.nodeName !== "CANVAS") return;
2980
+ var _a;
2981
+ if (((_a = event.target) == null ? void 0 : _a.nodeName) !== "CANVAS") return;
3187
2982
  if (!event.ctrlKey) return;
3188
2983
  setTimeout(() => {
3189
2984
  this.mouse.x = event.clientX / window.innerWidth * 2 - 1;
@@ -3223,7 +3018,7 @@ var SceneInspector = class {
3223
3018
  }
3224
3019
  selectObject(targetObject, targetIntersection) {
3225
3020
  this.selectedObject = targetObject;
3226
- console.log(p7, "selected", targetObject);
3021
+ console.log(p8, "selected", targetObject);
3227
3022
  this.redraw(targetObject, targetIntersection);
3228
3023
  }
3229
3024
  redraw(targetObject, targetIntersection) {
@@ -3521,7 +3316,7 @@ var SceneStatsDisplay = class {
3521
3316
  };
3522
3317
 
3523
3318
  // src/instance/InstanceManager.ts
3524
- var p8 = prefix("InstanceManager");
3319
+ var p9 = prefix("InstanceManager");
3525
3320
  var InstanceManager = class {
3526
3321
  constructor() {
3527
3322
  this.isInstanceManager = true;
@@ -3529,7 +3324,7 @@ var InstanceManager = class {
3529
3324
  }
3530
3325
  async get(key) {
3531
3326
  if (key in this.instanceCache) {
3532
- console.debug(p8, "key in cache", key);
3327
+ console.debug(p9, "key in cache", key);
3533
3328
  return (await this.instanceCache[key]).nextInstance();
3534
3329
  }
3535
3330
  return void 0;
@@ -3538,17 +3333,13 @@ var InstanceManager = class {
3538
3333
  if (key in this.instanceCache) {
3539
3334
  return await this.get(key);
3540
3335
  }
3541
- console.debug(p8, "key not in cache", key);
3542
- const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
3543
- this.instanceCache[key] = pending;
3544
- try {
3545
- return await pending;
3546
- } catch (error) {
3547
- if (this.instanceCache[key] === pending) {
3548
- delete this.instanceCache[key];
3549
- }
3550
- throw error;
3551
- }
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];
3552
3343
  }
3553
3344
  reset() {
3554
3345
  for (let instanceCacheKey in this.instanceCache) {
@@ -4147,28 +3938,26 @@ function computeMorphedAttributes(object) {
4147
3938
  }
4148
3939
 
4149
3940
  // src/model/scene/ModelObject.ts
4150
- var import_ts_deepmerge5 = __toESM(require_dist());
4151
- var p9 = prefix("ModelObject");
4152
- 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 {
4153
3944
  constructor(originalModel, options) {
4154
3945
  super(options);
4155
3946
  this.originalModel = originalModel;
4156
3947
  this.isModelObject = true;
4157
3948
  this.meshesCreated = false;
4158
- this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
3949
+ this.options = (0, import_ts_deepmerge6.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4159
3950
  console.log("ModelObject options", this.options);
4160
3951
  }
4161
- static {
4162
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4163
- }
4164
3952
  async init() {
4165
3953
  await this.loadTextures();
4166
3954
  this.createMeshes();
4167
3955
  this.applyTextures();
4168
3956
  }
4169
3957
  dispose() {
3958
+ var _a;
4170
3959
  super.dispose();
4171
- this.atlas?.dispose();
3960
+ (_a = this.atlas) == null ? void 0 : _a.dispose();
4172
3961
  }
4173
3962
  get textureAtlas() {
4174
3963
  return this.atlas;
@@ -4178,12 +3967,13 @@ var ModelObject = class _ModelObject extends SceneObject {
4178
3967
  this.atlas = await UVMapper.getAtlas(this.originalModel);
4179
3968
  }
4180
3969
  createMeshes(force = false) {
3970
+ var _a;
4181
3971
  if (this.meshesCreated && !force) return;
4182
3972
  const mat = Materials.MISSING_TEXTURE;
4183
3973
  let allGeos = [];
4184
3974
  if (this.atlas) {
4185
3975
  if (this.atlas.model.elements) {
4186
- this.atlas.model.elements?.forEach((el) => {
3976
+ (_a = this.atlas.model.elements) == null ? void 0 : _a.forEach((el) => {
4187
3977
  const elGeo = this._getBoxGeometryFromElement(el).clone();
4188
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));
4189
3979
  elGeo.applyMatrix4(new Matrix45().makeTranslation(el.from[0], el.from[1], el.from[2]));
@@ -4201,10 +3991,10 @@ var ModelObject = class _ModelObject extends SceneObject {
4201
3991
  }
4202
3992
  });
4203
3993
  } else {
4204
- console.debug(p9, this.atlas.model, "has no elements");
3994
+ console.debug(p10, this.atlas.model, "has no elements");
4205
3995
  }
4206
3996
  } else {
4207
- console.debug(p9, "Missing atlas for", this);
3997
+ console.debug(p10, "Missing atlas for", this);
4208
3998
  }
4209
3999
  if (this.options.mergeMeshes) {
4210
4000
  let combinedGeo;
@@ -4256,25 +4046,17 @@ var ModelObject = class _ModelObject extends SceneObject {
4256
4046
  }
4257
4047
  }
4258
4048
  };
4049
+ _ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4050
+ var ModelObject = _ModelObject;
4259
4051
  function isModelObject(obj) {
4260
4052
  return obj.isModelObject;
4261
4053
  }
4262
4054
 
4263
4055
  // src/model/block/scene/BlockObject.ts
4264
- var import_ts_deepmerge6 = __toESM(require_dist());
4056
+ var import_ts_deepmerge7 = __toESM(require_dist());
4265
4057
  import { Euler as Euler3, Matrix4 as Matrix46, Vector3 as Vector36 } from "three";
4266
- var p10 = prefix("BlockObject");
4267
- function matchesCondition(condition, state) {
4268
- return Object.entries(condition).every(([key, value]) => {
4269
- if (Array.isArray(value)) {
4270
- if (key === "OR") return value.some((child) => matchesCondition(child, state));
4271
- if (key === "AND") return value.every((child) => matchesCondition(child, state));
4272
- return false;
4273
- }
4274
- return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4275
- });
4276
- }
4277
- var BlockObject = class _BlockObject extends SceneObject {
4058
+ var p11 = prefix("BlockObject");
4059
+ var _BlockObject = class _BlockObject extends SceneObject {
4278
4060
  constructor(blockState, options) {
4279
4061
  super(options);
4280
4062
  this.blockState = blockState;
@@ -4287,16 +4069,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4287
4069
  this._instanceModel = [];
4288
4070
  this._variants = [];
4289
4071
  this._models = [];
4290
- this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4291
- }
4292
- static {
4293
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
4294
- applyDefaultState: true
4295
- });
4072
+ this.options = (0, import_ts_deepmerge7.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
4296
4073
  }
4297
4074
  async init() {
4298
4075
  if (this.options.applyDefaultState) {
4299
- 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;
4300
4077
  if (defaultState && Object.keys(defaultState).length > 0) {
4301
4078
  const state = {};
4302
4079
  for (let k in defaultState) {
@@ -4307,9 +4084,15 @@ var BlockObject = class _BlockObject extends SceneObject {
4307
4084
  if (this.blockState.variants) {
4308
4085
  await this.setState(Object.keys(this.blockState.variants)[0]);
4309
4086
  } else if (this.blockState.multipart) {
4310
- const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4311
- const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4312
- 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
+ }
4313
4096
  }
4314
4097
  }
4315
4098
  } else {
@@ -4366,11 +4149,55 @@ var BlockObject = class _BlockObject extends SceneObject {
4366
4149
  } else if (this.blockState.multipart) {
4367
4150
  for (let part of this.blockState.multipart) {
4368
4151
  if (!part.apply) {
4369
- console.debug(p10, "Missing apply for blockState part", part);
4152
+ console.debug(p11, "Missing apply for blockState part", part);
4370
4153
  continue;
4371
4154
  }
4372
- if (!part.when || matchesCondition(part.when, state)) {
4155
+ if (!part.when) {
4373
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
+ }
4374
4201
  }
4375
4202
  }
4376
4203
  }
@@ -4400,21 +4227,11 @@ var BlockObject = class _BlockObject extends SceneObject {
4400
4227
  }
4401
4228
  }
4402
4229
  getSingleVariant(variants) {
4403
- if (!Array.isArray(variants)) return variants;
4404
- if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4405
- const total = variants.reduce((sum, variant) => {
4406
- const weight = variant.weight ?? 1;
4407
- if (!Number.isInteger(weight) || weight < 1) {
4408
- throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4409
- }
4410
- return sum + weight;
4411
- }, 0);
4412
- let choice = Math.random() * total;
4413
- for (const variant of variants) {
4414
- choice -= variant.weight ?? 1;
4415
- if (choice < 0) return variant;
4416
- }
4417
- return variants[variants.length - 1];
4230
+ if (Array.isArray(variants)) {
4231
+ return variants[0];
4232
+ } else {
4233
+ return variants;
4234
+ }
4418
4235
  }
4419
4236
  // @deprecated
4420
4237
  async createAVariant(variants, instanceInfo) {
@@ -4440,6 +4257,9 @@ var BlockObject = class _BlockObject extends SceneObject {
4440
4257
  }
4441
4258
  }
4442
4259
  obj.setRotation(rotation);
4260
+ setTimeout(() => {
4261
+ obj.setRotation(rotation);
4262
+ }, 150);
4443
4263
  console.log(obj);
4444
4264
  return obj;
4445
4265
  }
@@ -4530,15 +4350,18 @@ var BlockObject = class _BlockObject extends SceneObject {
4530
4350
  }
4531
4351
  }
4532
4352
  setPosition(position) {
4533
- this.position.copy(position);
4353
+ super.setPosition(position);
4534
4354
  for (let model of this._models) {
4535
4355
  model.setPosition(position);
4536
4356
  }
4537
- this.notifyDirty();
4538
4357
  }
4539
4358
  //TODO: should override rotation + scale methods
4540
4359
  //TODO
4541
4360
  };
4361
+ _BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge7.default)({}, ModelObject.DEFAULT_OPTIONS, {
4362
+ applyDefaultState: true
4363
+ });
4364
+ var BlockObject = _BlockObject;
4542
4365
  function isBlockObject(obj) {
4543
4366
  return obj.isBlockObject;
4544
4367
  }
@@ -4563,10 +4386,11 @@ var StructureParser = class {
4563
4386
  throw new MineRenderError("Structure does not have palette(s)");
4564
4387
  }
4565
4388
  const blocks = nbt.blocks.value.value.map((block) => {
4389
+ var _a;
4566
4390
  const state = palette.value.value[block.state.value];
4567
4391
  if (state.Name.value === "minecraft:air") return void 0;
4568
4392
  const props = {};
4569
- for (let k in state.Properties?.value) {
4393
+ for (let k in (_a = state.Properties) == null ? void 0 : _a.value) {
4570
4394
  props[k] = state.Properties.value[k].value;
4571
4395
  }
4572
4396
  return {
@@ -4585,7 +4409,7 @@ var StructureParser = class {
4585
4409
 
4586
4410
  // src/renderer/MineRenderScene.ts
4587
4411
  import { Scene as Scene2 } from "three";
4588
- var import_ts_deepmerge8 = __toESM(require_dist());
4412
+ var import_ts_deepmerge9 = __toESM(require_dist());
4589
4413
 
4590
4414
  // src/skin/SkinPart.ts
4591
4415
  var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
@@ -5316,7 +5140,7 @@ var slimSkinGeometries = {
5316
5140
  };
5317
5141
 
5318
5142
  // src/skin/scene/SkinObject.ts
5319
- var import_ts_deepmerge7 = __toESM(require_dist());
5143
+ var import_ts_deepmerge8 = __toESM(require_dist());
5320
5144
  var SkinObject = class extends SceneObject {
5321
5145
  constructor(options) {
5322
5146
  super();
@@ -5324,7 +5148,7 @@ var SkinObject = class extends SceneObject {
5324
5148
  this.legacy = false;
5325
5149
  this.skinTextureWidth = 64;
5326
5150
  this.skinTextureHeight = 64;
5327
- this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5151
+ this.options = (0, import_ts_deepmerge8.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
5328
5152
  }
5329
5153
  async init() {
5330
5154
  this.createMeshes();
@@ -5428,7 +5252,7 @@ var SkinObject = class extends SceneObject {
5428
5252
  };
5429
5253
 
5430
5254
  // src/renderer/MineRenderScene.ts
5431
- var MineRenderScene = class _MineRenderScene extends Scene2 {
5255
+ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5432
5256
  constructor(options) {
5433
5257
  super();
5434
5258
  this.isMineRenderScene = true;
@@ -5437,14 +5261,12 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5437
5261
  this.dirty = true;
5438
5262
  this.observedObjects = /* @__PURE__ */ new Set();
5439
5263
  this.onObjectChange = (event) => {
5440
- if (event.target?.parent === this) {
5264
+ var _a;
5265
+ if (((_a = event.target) == null ? void 0 : _a.parent) === this) {
5441
5266
  this.dirty = true;
5442
5267
  }
5443
5268
  };
5444
- this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5445
- }
5446
- static {
5447
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
5269
+ this.options = (0, import_ts_deepmerge9.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
5448
5270
  }
5449
5271
  add(...objects) {
5450
5272
  for (const object of objects) {
@@ -5452,7 +5274,7 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5452
5274
  try {
5453
5275
  super.add(object);
5454
5276
  } finally {
5455
- if (object?.isObject3D && object !== this) {
5277
+ if ((object == null ? void 0 : object.isObject3D) && object !== this) {
5456
5278
  this.updateObjectRegistration(object, object.parent === this);
5457
5279
  }
5458
5280
  }
@@ -5495,12 +5317,13 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5495
5317
  return this.add(...object);
5496
5318
  }
5497
5319
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
5320
+ var _a, _b;
5498
5321
  console.log("addSceneObject", asset);
5499
5322
  console.log("parent", parent);
5500
5323
  console.log(_options);
5501
5324
  this.dirty = true;
5502
5325
  const obj = await objectSupplier();
5503
- 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") {
5504
5327
  console.log("instanceMeshes + key");
5505
5328
  const key = asset.key.serialize();
5506
5329
  return this.instanceManager.getOrCreate(key, async () => {
@@ -5540,1147 +5363,1117 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5540
5363
  return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
5541
5364
  }
5542
5365
  };
5366
+ _MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {});
5367
+ var MineRenderScene = _MineRenderScene;
5543
5368
  function isMineRenderScene(obj) {
5544
5369
  return obj.isMineRenderScene;
5545
5370
  }
5546
5371
 
5547
5372
  // src/renderer/Renderer.ts
5548
- import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector38, WebGLRenderer } from "three";
5549
- 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());
5550
5375
  import Stats from "stats.js";
5551
5376
  import { EffectComposer, RenderPass } from "postprocessing";
5552
-
5553
- // src/three/OrbitControls.js
5554
- import {
5555
- EventDispatcher,
5556
- MOUSE,
5557
- Quaternion as Quaternion3,
5558
- Spherical,
5559
- TOUCH,
5560
- Vector2 as Vector23,
5561
- Vector3 as Vector37
5562
- } from "three";
5563
- var _changeEvent = { type: "change" };
5564
- var _startEvent = { type: "start" };
5565
- var _endEvent = { type: "end" };
5566
- var OrbitControls = class extends EventDispatcher {
5567
- constructor(object, domElement) {
5568
- super();
5569
- if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
5570
- if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
5571
- this.object = object;
5572
- this.domElement = domElement;
5573
- this.domElement.style.touchAction = "none";
5574
- this.enabled = true;
5575
- this.target = new Vector37();
5576
- this.minDistance = 0;
5577
- this.maxDistance = Infinity;
5578
- this.minZoom = 0;
5579
- this.maxZoom = Infinity;
5580
- this.minPolarAngle = 0;
5581
- this.maxPolarAngle = Math.PI;
5582
- this.minAzimuthAngle = -Infinity;
5583
- this.maxAzimuthAngle = Infinity;
5584
- this.enableDamping = false;
5585
- this.dampingFactor = 0.05;
5586
- this.enableZoom = true;
5587
- this.zoomSpeed = 1;
5588
- this.enableRotate = true;
5589
- this.rotateSpeed = 1;
5590
- this.enablePan = true;
5591
- this.panSpeed = 1;
5592
- this.screenSpacePanning = true;
5593
- this.keyPanSpeed = 7;
5594
- this.autoRotate = false;
5595
- this.autoRotateSpeed = 2;
5596
- this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
5597
- this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
5598
- this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
5599
- this.target0 = this.target.clone();
5600
- this.position0 = this.object.position.clone();
5601
- this.zoom0 = this.object.zoom;
5602
- this._domElementKeyEvents = null;
5603
- this.getPolarAngle = function() {
5604
- return spherical.phi;
5605
- };
5606
- this.getAzimuthalAngle = function() {
5607
- return spherical.theta;
5608
- };
5609
- this.getDistance = function() {
5610
- return this.object.position.distanceTo(this.target);
5611
- };
5612
- this.saveState = function() {
5613
- scope.target0.copy(scope.target);
5614
- scope.position0.copy(scope.object.position);
5615
- scope.zoom0 = scope.object.zoom;
5616
- };
5617
- this.reset = function() {
5618
- scope.target.copy(scope.target0);
5619
- scope.object.position.copy(scope.position0);
5620
- scope.object.zoom = scope.zoom0;
5621
- scope.object.updateProjectionMatrix();
5622
- scope.dispatchEvent(_changeEvent);
5623
- scope.update();
5624
- state = STATE.NONE;
5625
- };
5626
- this.update = function() {
5627
- const offset = new Vector37();
5628
- const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector37(0, 1, 0));
5629
- const quatInverse = quat.clone().invert();
5630
- const lastPosition = new Vector37();
5631
- const lastQuaternion = new Quaternion3();
5632
- const twoPI = 2 * Math.PI;
5633
- return function update() {
5634
- const position = scope.object.position;
5635
- offset.copy(position).sub(scope.target);
5636
- offset.applyQuaternion(quat);
5637
- spherical.setFromVector3(offset);
5638
- if (scope.autoRotate && state === STATE.NONE) {
5639
- rotateLeft(getAutoRotationAngle());
5640
- }
5641
- if (scope.enableDamping) {
5642
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
5643
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
5644
- } else {
5645
- spherical.theta += sphericalDelta.theta;
5646
- spherical.phi += sphericalDelta.phi;
5647
- }
5648
- let min = scope.minAzimuthAngle;
5649
- let max = scope.maxAzimuthAngle;
5650
- if (isFinite(min) && isFinite(max)) {
5651
- if (min < -Math.PI) min += twoPI;
5652
- else if (min > Math.PI) min -= twoPI;
5653
- if (max < -Math.PI) max += twoPI;
5654
- else if (max > Math.PI) max -= twoPI;
5655
- if (min <= max) {
5656
- spherical.theta = Math.max(min, Math.min(max, spherical.theta));
5657
- } else {
5658
- spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
5659
- }
5660
- }
5661
- spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
5662
- spherical.makeSafe();
5663
- spherical.radius *= scale;
5664
- spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
5665
- if (scope.enableDamping === true) {
5666
- scope.target.addScaledVector(panOffset, scope.dampingFactor);
5667
- } else {
5668
- scope.target.add(panOffset);
5669
- }
5670
- offset.setFromSpherical(spherical);
5671
- offset.applyQuaternion(quatInverse);
5672
- position.copy(scope.target).add(offset);
5673
- scope.object.lookAt(scope.target);
5674
- if (scope.enableDamping === true) {
5675
- sphericalDelta.theta *= 1 - scope.dampingFactor;
5676
- sphericalDelta.phi *= 1 - scope.dampingFactor;
5677
- panOffset.multiplyScalar(1 - scope.dampingFactor);
5678
- } else {
5679
- sphericalDelta.set(0, 0, 0);
5680
- panOffset.set(0, 0, 0);
5681
- }
5682
- scale = 1;
5683
- if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
5684
- scope.dispatchEvent(_changeEvent);
5685
- lastPosition.copy(scope.object.position);
5686
- lastQuaternion.copy(scope.object.quaternion);
5687
- zoomChanged = false;
5688
- return true;
5689
- }
5690
- return false;
5691
- };
5692
- }();
5693
- this.dispose = function() {
5694
- scope.domElement.removeEventListener("contextmenu", onContextMenu);
5695
- scope.domElement.removeEventListener("pointerdown", onPointerDown);
5696
- scope.domElement.removeEventListener("pointercancel", onPointerCancel);
5697
- scope.domElement.removeEventListener("wheel", onMouseWheel);
5698
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5699
- scope.domElement.removeEventListener("pointerup", onPointerUp);
5700
- if (scope._domElementKeyEvents !== null) {
5701
- scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
5702
- }
5703
- };
5704
- const scope = this;
5705
- const STATE = {
5706
- NONE: -1,
5707
- ROTATE: 0,
5708
- DOLLY: 1,
5709
- PAN: 2,
5710
- TOUCH_ROTATE: 3,
5711
- TOUCH_PAN: 4,
5712
- TOUCH_DOLLY_PAN: 5,
5713
- 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;
5714
5388
  };
5715
- let state = STATE.NONE;
5716
- const EPS = 1e-6;
5717
- const spherical = new Spherical();
5718
- const sphericalDelta = new Spherical();
5719
- let scale = 1;
5720
- const panOffset = new Vector37();
5721
- let zoomChanged = false;
5722
- const rotateStart = new Vector23();
5723
- const rotateEnd = new Vector23();
5724
- const rotateDelta = new Vector23();
5725
- const panStart = new Vector23();
5726
- const panEnd = new Vector23();
5727
- const panDelta = new Vector23();
5728
- const dollyStart = new Vector23();
5729
- const dollyEnd = new Vector23();
5730
- const dollyDelta = new Vector23();
5731
- const pointers = [];
5732
- const pointerPositions = {};
5733
- function getAutoRotationAngle() {
5734
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
5735
- }
5736
- function getZoomScale() {
5737
- 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);
5738
5399
  }
5739
- function rotateLeft(angle) {
5740
- 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
+ );
5741
5425
  }
5742
- function rotateUp(angle) {
5743
- 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 }));
5744
5453
  }
5745
- const panLeft = function() {
5746
- const v = new Vector37();
5747
- return function panLeft2(distance, objectMatrix) {
5748
- v.setFromMatrixColumn(objectMatrix, 0);
5749
- v.multiplyScalar(-distance);
5750
- panOffset.add(v);
5751
- };
5752
- }();
5753
- const panUp = function() {
5754
- const v = new Vector37();
5755
- return function panUp2(distance, objectMatrix) {
5756
- if (scope.screenSpacePanning === true) {
5757
- v.setFromMatrixColumn(objectMatrix, 1);
5758
- } else {
5759
- v.setFromMatrixColumn(objectMatrix, 0);
5760
- v.crossVectors(scope.object.up, v);
5761
- }
5762
- v.multiplyScalar(distance);
5763
- panOffset.add(v);
5764
- };
5765
- }();
5766
- const pan = function() {
5767
- const offset = new Vector37();
5768
- return function pan2(deltaX, deltaY) {
5769
- const element = scope.domElement;
5770
- if (scope.object.isPerspectiveCamera) {
5771
- const position = scope.object.position;
5772
- offset.copy(position).sub(scope.target);
5773
- let targetDistance = offset.length();
5774
- targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
5775
- panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
5776
- panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
5777
- } else if (scope.object.isOrthographicCamera) {
5778
- panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
5779
- panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
5780
- } else {
5781
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
5782
- scope.enablePan = false;
5783
- }
5784
- };
5785
- }();
5786
- function dollyOut(dollyScale) {
5787
- if (scope.object.isPerspectiveCamera) {
5788
- scale /= dollyScale;
5789
- } else if (scope.object.isOrthographicCamera) {
5790
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
5791
- scope.object.updateProjectionMatrix();
5792
- zoomChanged = true;
5793
- } else {
5794
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5795
- scope.enableZoom = false;
5796
- }
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);
5797
5466
  }
5798
- function dollyIn(dollyScale) {
5799
- if (scope.object.isPerspectiveCamera) {
5800
- scale *= dollyScale;
5801
- } else if (scope.object.isOrthographicCamera) {
5802
- scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
5803
- scope.object.updateProjectionMatrix();
5804
- zoomChanged = true;
5805
- } else {
5806
- console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
5807
- 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]);
5808
5477
  }
5809
5478
  }
5810
- function handleMouseDownRotate(event) {
5811
- 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
+ }
5812
5485
  }
5813
- function handleMouseDownDolly(event) {
5814
- 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);
5815
5491
  }
5816
- function handleMouseDownPan(event) {
5817
- 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");
5818
5502
  }
5819
- function handleMouseMoveRotate(event) {
5820
- rotateEnd.set(event.clientX, event.clientY);
5821
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5822
- const element = scope.domElement;
5823
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5824
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5825
- rotateStart.copy(rotateEnd);
5826
- scope.update();
5503
+ if (this.viewHeight == 0) {
5504
+ console.warn("0 element height");
5827
5505
  }
5828
- function handleMouseMoveDolly(event) {
5829
- dollyEnd.set(event.clientX, event.clientY);
5830
- dollyDelta.subVectors(dollyEnd, dollyStart);
5831
- if (dollyDelta.y > 0) {
5832
- dollyOut(getZoomScale());
5833
- } else if (dollyDelta.y < 0) {
5834
- dollyIn(getZoomScale());
5835
- }
5836
- dollyStart.copy(dollyEnd);
5837
- 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);
5838
5518
  }
5839
- function handleMouseMovePan(event) {
5840
- panEnd.set(event.clientX, event.clientY);
5841
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5842
- pan(panDelta.x, panDelta.y);
5843
- panStart.copy(panEnd);
5844
- 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();
5845
5534
  }
5846
- 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;
5847
5575
  }
5848
- function handleMouseWheel(event) {
5849
- if (event.deltaY < 0) {
5850
- dollyIn(getZoomScale());
5851
- } else if (event.deltaY > 0) {
5852
- dollyOut(getZoomScale());
5576
+ for (const [dispatcher, events] of this._eventDispatchers) {
5577
+ for (const event of events) {
5578
+ dispatcher.removeEventListener(event, this._changeListener);
5853
5579
  }
5854
- scope.update();
5855
5580
  }
5856
- function handleKeyDown(event) {
5857
- let needsUpdate = false;
5858
- switch (event.code) {
5859
- case scope.keys.UP:
5860
- pan(0, scope.keyPanSpeed);
5861
- needsUpdate = true;
5862
- break;
5863
- case scope.keys.BOTTOM:
5864
- pan(0, -scope.keyPanSpeed);
5865
- needsUpdate = true;
5866
- break;
5867
- case scope.keys.LEFT:
5868
- pan(scope.keyPanSpeed, 0);
5869
- needsUpdate = true;
5870
- break;
5871
- case scope.keys.RIGHT:
5872
- pan(-scope.keyPanSpeed, 0);
5873
- needsUpdate = true;
5874
- break;
5875
- }
5876
- if (needsUpdate) {
5877
- event.preventDefault();
5878
- 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();
5879
5592
  }
5880
5593
  }
5881
- function handleTouchStartRotate() {
5882
- if (pointers.length === 1) {
5883
- rotateStart.set(pointers[0].pageX, pointers[0].pageY);
5884
- } else {
5885
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5886
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5887
- rotateStart.set(x, y);
5888
- }
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();
5889
5603
  }
5890
- function handleTouchStartPan() {
5891
- if (pointers.length === 1) {
5892
- 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();
5893
5607
  } else {
5894
- const x = 0.5 * (pointers[0].pageX + pointers[1].pageX);
5895
- const y = 0.5 * (pointers[0].pageY + pointers[1].pageY);
5896
- panStart.set(x, y);
5608
+ this.renderer.render(this.scene, this.camera);
5897
5609
  }
5898
5610
  }
5899
- function handleTouchStartDolly() {
5900
- const dx = pointers[0].pageX - pointers[1].pageX;
5901
- const dy = pointers[0].pageY - pointers[1].pageY;
5902
- const distance = Math.sqrt(dx * dx + dy * dy);
5903
- dollyStart.set(0, distance);
5904
- }
5905
- function handleTouchStartDollyPan() {
5906
- if (scope.enableZoom) handleTouchStartDolly();
5907
- if (scope.enablePan) handleTouchStartPan();
5611
+ this.dirty = false;
5612
+ if (this._stats) {
5613
+ this._stats.end();
5908
5614
  }
5909
- function handleTouchStartDollyRotate() {
5910
- if (scope.enableZoom) handleTouchStartDolly();
5911
- 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);
5912
5688
  }
5913
- function handleTouchMoveRotate(event) {
5914
- if (pointers.length == 1) {
5915
- rotateEnd.set(event.pageX, event.pageY);
5916
- } else {
5917
- const position = getSecondPointerPosition(event);
5918
- const x = 0.5 * (event.pageX + position.x);
5919
- const y = 0.5 * (event.pageY + position.y);
5920
- 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);
5921
5698
  }
5922
- rotateDelta.subVectors(rotateEnd, rotateStart).multiplyScalar(scope.rotateSpeed);
5923
- const element = scope.domElement;
5924
- rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight);
5925
- rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight);
5926
- rotateStart.copy(rotateEnd);
5927
- }
5928
- function handleTouchMovePan(event) {
5929
- if (pointers.length === 1) {
5930
- panEnd.set(event.pageX, event.pageY);
5931
- } else {
5932
- const position = getSecondPointerPosition(event);
5933
- const x = 0.5 * (event.pageX + position.x);
5934
- const y = 0.5 * (event.pageY + position.y);
5935
- 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"];
5936
5706
  }
5937
- panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
5938
- pan(panDelta.x, panDelta.y);
5939
- panStart.copy(panEnd);
5940
- }
5941
- function handleTouchMoveDolly(event) {
5942
- const position = getSecondPointerPosition(event);
5943
- const dx = event.pageX - position.x;
5944
- const dy = event.pageY - position.y;
5945
- const distance = Math.sqrt(dx * dx + dy * dy);
5946
- dollyEnd.set(0, distance);
5947
- dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
5948
- dollyOut(dollyDelta.y);
5949
- dollyStart.copy(dollyEnd);
5950
- }
5951
- function handleTouchMoveDollyPan(event) {
5952
- if (scope.enableZoom) handleTouchMoveDolly(event);
5953
- if (scope.enablePan) handleTouchMovePan(event);
5954
- }
5955
- function handleTouchMoveDollyRotate(event) {
5956
- if (scope.enableZoom) handleTouchMoveDolly(event);
5957
- if (scope.enableRotate) handleTouchMoveRotate(event);
5958
- }
5959
- 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);
5960
5715
  }
5961
- function onPointerDown(event) {
5962
- if (scope.enabled === false) return;
5963
- if (pointers.length === 0) {
5964
- scope.domElement.setPointerCapture(event.pointerId);
5965
- scope.domElement.addEventListener("pointermove", onPointerMove);
5966
- scope.domElement.addEventListener("pointerup", onPointerUp);
5967
- }
5968
- addPointer(event);
5969
- if (event.pointerType === "touch") {
5970
- onTouchStart(event);
5971
- } else {
5972
- 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);
5973
5725
  }
5974
- }
5975
- function onPointerMove(event) {
5976
- if (scope.enabled === false) return;
5977
- if (event.pointerType === "touch") {
5978
- onTouchMove(event);
5979
- } else {
5980
- 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;
5981
5733
  }
5982
- }
5983
- function onPointerUp(event) {
5984
- if (scope.enabled === false) return;
5985
- if (event.pointerType === "touch") {
5986
- onTouchEnd();
5987
- } else {
5988
- 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"];
5989
5749
  }
5990
- removePointer(event);
5991
- if (pointers.length === 0) {
5992
- scope.domElement.releasePointerCapture(event.pointerId);
5993
- scope.domElement.removeEventListener("pointermove", onPointerMove);
5994
- 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"];
5995
5763
  }
5996
- }
5997
- function onPointerCancel(event) {
5998
- removePointer(event);
5999
- }
6000
- function onMouseDown(event) {
6001
- let mouseAction;
6002
- switch (event.button) {
6003
- case 0:
6004
- mouseAction = scope.mouseButtons.LEFT;
6005
- break;
6006
- case 1:
6007
- mouseAction = scope.mouseButtons.MIDDLE;
6008
- break;
6009
- case 2:
6010
- mouseAction = scope.mouseButtons.RIGHT;
6011
- break;
6012
- default:
6013
- 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;
6014
5777
  }
6015
- switch (mouseAction) {
6016
- case MOUSE.DOLLY:
6017
- if (scope.enableZoom === false) return;
6018
- handleMouseDownDolly(event);
6019
- state = STATE.DOLLY;
6020
- break;
6021
- case MOUSE.ROTATE:
6022
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6023
- if (scope.enablePan === false) return;
6024
- handleMouseDownPan(event);
6025
- state = STATE.PAN;
6026
- } else {
6027
- if (scope.enableRotate === false) return;
6028
- handleMouseDownRotate(event);
6029
- state = STATE.ROTATE;
6030
- }
6031
- break;
6032
- case MOUSE.PAN:
6033
- if (event.ctrlKey || event.metaKey || event.shiftKey) {
6034
- if (scope.enableRotate === false) return;
6035
- handleMouseDownRotate(event);
6036
- 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));
6037
5933
  } else {
6038
- if (scope.enablePan === false) return;
6039
- handleMouseDownPan(event);
6040
- state = STATE.PAN;
5934
+ spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
6041
5935
  }
6042
- break;
6043
- default:
6044
- 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);
6045
5978
  }
6046
- if (state !== STATE.NONE) {
6047
- 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;
6048
6072
  }
6049
6073
  }
6050
- function onMouseMove(event) {
6051
- if (scope.enabled === false) return;
6052
- switch (state) {
6053
- case STATE.ROTATE:
6054
- if (scope.enableRotate === false) return;
6055
- handleMouseMoveRotate(event);
6056
- break;
6057
- case STATE.DOLLY:
6058
- if (scope.enableZoom === false) return;
6059
- handleMouseMoveDolly(event);
6060
- break;
6061
- case STATE.PAN:
6062
- if (scope.enablePan === false) return;
6063
- handleMouseMovePan(event);
6064
- 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;
6065
6084
  }
6066
6085
  }
6067
- function onMouseUp(event) {
6068
- handleMouseUp(event);
6069
- scope.dispatchEvent(_endEvent);
6070
- state = STATE.NONE;
6086
+ function handleMouseDownRotate(event) {
6087
+ rotateStart.set(event.clientX, event.clientY);
6071
6088
  }
6072
- function onMouseWheel(event) {
6073
- if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
6074
- event.preventDefault();
6075
- scope.dispatchEvent(_startEvent);
6076
- handleMouseWheel(event);
6077
- scope.dispatchEvent(_endEvent);
6089
+ function handleMouseDownDolly(event) {
6090
+ dollyStart.set(event.clientX, event.clientY);
6078
6091
  }
6079
- function onKeyDown(event) {
6080
- if (scope.enabled === false || scope.enablePan === false) return;
6081
- handleKeyDown(event);
6092
+ function handleMouseDownPan(event) {
6093
+ panStart.set(event.clientX, event.clientY);
6082
6094
  }
6083
- function onTouchStart(event) {
6084
- trackPointer(event);
6085
- switch (pointers.length) {
6086
- case 1:
6087
- switch (scope.touches.ONE) {
6088
- case TOUCH.ROTATE:
6089
- if (scope.enableRotate === false) return;
6090
- handleTouchStartRotate();
6091
- state = STATE.TOUCH_ROTATE;
6092
- break;
6093
- case TOUCH.PAN:
6094
- if (scope.enablePan === false) return;
6095
- handleTouchStartPan();
6096
- state = STATE.TOUCH_PAN;
6097
- break;
6098
- default:
6099
- state = STATE.NONE;
6100
- }
6101
- break;
6102
- case 2:
6103
- switch (scope.touches.TWO) {
6104
- case TOUCH.DOLLY_PAN:
6105
- if (scope.enableZoom === false && scope.enablePan === false) return;
6106
- handleTouchStartDollyPan();
6107
- state = STATE.TOUCH_DOLLY_PAN;
6108
- break;
6109
- case TOUCH.DOLLY_ROTATE:
6110
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6111
- handleTouchStartDollyRotate();
6112
- state = STATE.TOUCH_DOLLY_ROTATE;
6113
- break;
6114
- default:
6115
- state = STATE.NONE;
6116
- }
6117
- break;
6118
- default:
6119
- 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());
6120
6111
  }
6121
- if (state !== STATE.NONE) {
6122
- 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());
6123
6129
  }
6130
+ scope.update();
6124
6131
  }
6125
- function onTouchMove(event) {
6126
- trackPointer(event);
6127
- switch (state) {
6128
- case STATE.TOUCH_ROTATE:
6129
- if (scope.enableRotate === false) return;
6130
- handleTouchMoveRotate(event);
6131
- 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;
6132
6138
  break;
6133
- case STATE.TOUCH_PAN:
6134
- if (scope.enablePan === false) return;
6135
- handleTouchMovePan(event);
6136
- scope.update();
6139
+ case scope.keys.BOTTOM:
6140
+ pan(0, -scope.keyPanSpeed);
6141
+ needsUpdate = true;
6137
6142
  break;
6138
- case STATE.TOUCH_DOLLY_PAN:
6139
- if (scope.enableZoom === false && scope.enablePan === false) return;
6140
- handleTouchMoveDollyPan(event);
6141
- scope.update();
6143
+ case scope.keys.LEFT:
6144
+ pan(scope.keyPanSpeed, 0);
6145
+ needsUpdate = true;
6142
6146
  break;
6143
- case STATE.TOUCH_DOLLY_ROTATE:
6144
- if (scope.enableZoom === false && scope.enableRotate === false) return;
6145
- handleTouchMoveDollyRotate(event);
6146
- scope.update();
6147
+ case scope.keys.RIGHT:
6148
+ pan(-scope.keyPanSpeed, 0);
6149
+ needsUpdate = true;
6147
6150
  break;
6148
- default:
6149
- state = STATE.NONE;
6151
+ }
6152
+ if (needsUpdate) {
6153
+ event.preventDefault();
6154
+ scope.update();
6150
6155
  }
6151
6156
  }
6152
- function onTouchEnd(event) {
6153
- handleTouchEnd(event);
6154
- scope.dispatchEvent(_endEvent);
6155
- state = STATE.NONE;
6156
- }
6157
- function onContextMenu(event) {
6158
- if (scope.enabled === false) return;
6159
- event.preventDefault();
6160
- }
6161
- function addPointer(event) {
6162
- pointers.push(event);
6163
- }
6164
- function removePointer(event) {
6165
- delete pointerPositions[event.pointerId];
6166
- for (let i = 0; i < pointers.length; i++) {
6167
- if (pointers[i].pointerId == event.pointerId) {
6168
- pointers.splice(i, 1);
6169
- return;
6170
- }
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);
6171
6164
  }
6172
6165
  }
6173
- function trackPointer(event) {
6174
- let position = pointerPositions[event.pointerId];
6175
- if (position === void 0) {
6176
- position = new Vector23();
6177
- 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);
6178
6173
  }
6179
- position.set(event.pageX, event.pageY);
6180
6174
  }
6181
- function getSecondPointerPosition(event) {
6182
- const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0];
6183
- 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);
6184
6180
  }
6185
- scope.domElement.addEventListener("contextmenu", onContextMenu);
6186
- scope.domElement.addEventListener("pointerdown", onPointerDown);
6187
- scope.domElement.addEventListener("pointercancel", onPointerCancel);
6188
- scope.domElement.addEventListener("wheel", onMouseWheel, { passive: false });
6189
- this.update();
6190
- }
6191
- };
6192
- var MapControls = class extends OrbitControls {
6193
- constructor(object, domElement) {
6194
- super(object, domElement);
6195
- this.screenSpacePanning = false;
6196
- this.mouseButtons.LEFT = MOUSE.PAN;
6197
- this.mouseButtons.RIGHT = MOUSE.ROTATE;
6198
- this.touches.ONE = TOUCH.PAN;
6199
- this.touches.TWO = TOUCH.DOLLY_ROTATE;
6200
- }
6201
- };
6202
-
6203
- // src/renderer/Renderer.ts
6204
- var Renderer = class _Renderer {
6205
- constructor(options) {
6206
- this._dirty = true;
6207
- this._resizeListener = void 0;
6208
- this._disposed = false;
6209
- this._debugHelpers = [];
6210
- this._eventDispatchers = /* @__PURE__ */ new Map();
6211
- this._changeListener = () => {
6212
- this._dirty = true;
6213
- };
6214
- this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
6215
- this._animationLoop = this.animate.bind(this);
6216
- this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
6217
- this._scene = this.createScene();
6218
- this._camera = this.createCamera();
6219
- this._renderer = this.createRenderer();
6220
- this._composer = this.createComposer();
6221
- if (this.options.render.stats) {
6222
- this._stats = new Stats();
6223
- document.body.appendChild(this._stats.dom);
6181
+ function handleTouchStartDollyPan() {
6182
+ if (scope.enableZoom) handleTouchStartDolly();
6183
+ if (scope.enablePan) handleTouchStartPan();
6224
6184
  }
6225
- this.init();
6226
- this._controls = this.createControls();
6227
- }
6228
- static {
6229
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6230
- camera: {
6231
- type: "perspective",
6232
- near: 1,
6233
- far: 5e3,
6234
- perspective: {
6235
- aspect: void 0,
6236
- fov: 50
6237
- },
6238
- orthographic: {
6239
- left: void 0,
6240
- right: void 0,
6241
- top: void 0,
6242
- bottom: void 0
6243
- },
6244
- position: new Vector38(50, 50, 50),
6245
- lookingAt: new Vector38(0, 0, 0)
6246
- },
6247
- render: {
6248
- fpsLimit: 60,
6249
- stats: false,
6250
- antialias: true,
6251
- shade: true,
6252
- autoResize: true,
6253
- renderAlways: false
6254
- },
6255
- composer: {
6256
- enabled: true
6257
- },
6258
- controls: {
6259
- enabled: false
6260
- },
6261
- debug: {
6262
- grid: false,
6263
- 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);
6264
6197
  }
6265
- });
6266
- }
6267
- //<editor-fold desc="INIT">
6268
- createScene() {
6269
- return new MineRenderScene();
6270
- }
6271
- createCamera() {
6272
- switch (this.options.camera.type) {
6273
- case "perspective":
6274
- default:
6275
- return new PerspectiveCamera(
6276
- this.options.camera.perspective.fov,
6277
- this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
6278
- this.options.camera.near,
6279
- this.options.camera.far
6280
- );
6281
- case "orthographic":
6282
- return new OrthographicCamera(
6283
- this.options.camera.orthographic.left ?? this.viewWidth / -2,
6284
- this.options.camera.orthographic.right ?? this.viewWidth / 2,
6285
- this.options.camera.orthographic.top ?? this.viewHeight / 2,
6286
- this.options.camera.orthographic.bottom ?? this.viewHeight / -2,
6287
- this.options.camera.near,
6288
- this.options.camera.far
6289
- );
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);
6290
6203
  }
6291
- }
6292
- createRenderer() {
6293
- const renderer = new WebGLRenderer({
6294
- antialias: this.options.render.antialias,
6295
- alpha: true,
6296
- powerPreference: "high-performance",
6297
- depth: true
6298
- });
6299
- renderer.setClearColor(0, 0);
6300
- renderer.shadowMap.enabled = true;
6301
- renderer.shadowMap.type = PCFSoftShadowMap;
6302
- renderer.outputColorSpace = SRGBColorSpace3;
6303
- renderer.setSize(this.viewWidth, this.viewHeight);
6304
- return renderer;
6305
- }
6306
- createComposer() {
6307
- if (!this.options.composer.enabled) return void 0;
6308
- const composer = new EffectComposer(this.renderer);
6309
- composer.setSize(this.viewWidth, this.viewHeight);
6310
- composer.addPass(new RenderPass(this.scene, this.camera));
6311
- return composer;
6312
- }
6313
- createControls() {
6314
- if (!this.options.controls?.enabled) return void 0;
6315
- const position = this.camera.position.clone();
6316
- const controls = new OrbitControls(this.camera, this.renderer.domElement);
6317
- this.camera.position.copy(position);
6318
- const target = this.options.camera.lookingAt;
6319
- if (isVector3(target)) {
6320
- controls.target.copy(target);
6321
- } else if (isTripleArray(target)) {
6322
- controls.target.set(target[0], target[1], target[2]);
6323
- }
6324
- controls.update();
6325
- controls.saveState();
6326
- this.registerEventDispatcher(controls);
6327
- return controls;
6328
- }
6329
- //</editor-fold>
6330
- init() {
6331
- if (this._disposed) return;
6332
- if (typeof window["__THREE_DEVTOOLS__"] !== "undefined") {
6333
- 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);
6334
6216
  }
6335
- if (this.options.debug.grid) {
6336
- const gridHelper = new GridHelper(128, 16);
6337
- this._debugHelpers.push(gridHelper);
6338
- this.scene.add(gridHelper);
6339
- const gridHelper2 = new GridHelper(128, 16);
6340
- this._debugHelpers.push(gridHelper2);
6341
- gridHelper2.rotation.x = 90 * (Math.PI / 180);
6342
- this.scene.add(gridHelper2);
6343
- const gridHelper3 = new GridHelper(128, 16);
6344
- this._debugHelpers.push(gridHelper3);
6345
- gridHelper3.rotation.z = 90 * (Math.PI / 180);
6346
- 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);
6347
6230
  }
6348
- if (this.options.debug.axes) {
6349
- const axesHelper = new AxesHelper3(64);
6350
- this._debugHelpers.push(axesHelper);
6351
- this.scene.add(axesHelper);
6231
+ function handleTouchMoveDollyRotate(event) {
6232
+ if (scope.enableZoom) handleTouchMoveDolly(event);
6233
+ if (scope.enableRotate) handleTouchMoveRotate(event);
6352
6234
  }
6353
- if (this.options.camera.position) {
6354
- if (isVector3(this.options.camera.position)) {
6355
- this.camera.position.set(this.options.camera.position.x, this.options.camera.position.y, this.options.camera.position.z);
6356
- } else if (isTripleArray(this.options.camera.position)) {
6357
- this.camera.position.set(this.options.camera.position[0], this.options.camera.position[1], this.options.camera.position[2]);
6358
- }
6235
+ function handleTouchEnd() {
6359
6236
  }
6360
- if (this.options.camera.lookingAt) {
6361
- if (isVector3(this.options.camera.lookingAt)) {
6362
- this.camera.lookAt(this.options.camera.lookingAt);
6363
- } else if (isTripleArray(this.options.camera.lookingAt)) {
6364
- 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);
6365
6249
  }
6366
6250
  }
6367
- if (this.options.render.autoResize && !this._resizeListener) {
6368
- this._resizeListener = () => {
6369
- this.resize(this.viewWidth, this.viewHeight);
6370
- };
6371
- 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
+ }
6372
6258
  }
6373
- }
6374
- get element() {
6375
- return this._element;
6376
- }
6377
- appendTo(element) {
6378
- if (this._disposed) return;
6379
- this._element = element;
6380
- this._element.appendChild(this.renderer.domElement);
6381
- if (this.viewWidth == 0) {
6382
- 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
+ }
6383
6272
  }
6384
- if (this.viewHeight == 0) {
6385
- console.warn("0 element height");
6273
+ function onPointerCancel(event) {
6274
+ removePointer(event);
6386
6275
  }
6387
- this.resize(this.viewWidth, this.viewHeight);
6388
- }
6389
- /**
6390
- * Redraws when the dispatcher emits the selected event. Registering the same pair twice has no effect.
6391
- * The renderer removes its listener on disposal; the caller retains ownership of the dispatcher.
6392
- */
6393
- registerEventDispatcher(dispatcher, changeEvent2 = "change") {
6394
- if (this._disposed) return;
6395
- let events = this._eventDispatchers.get(dispatcher);
6396
- if (!events) {
6397
- events = /* @__PURE__ */ new Set();
6398
- 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
+ }
6399
6325
  }
6400
- if (events.has(changeEvent2)) return;
6401
- events.add(changeEvent2);
6402
- dispatcher.addEventListener(changeEvent2, this._changeListener);
6403
- }
6404
- resize(width, height) {
6405
- if (this._disposed) return;
6406
- if (isPerspectiveCamera(this.camera)) {
6407
- this.camera.aspect = width / height;
6408
- this.camera.updateProjectionMatrix();
6409
- } else if (isOrthographicCamera(this.camera)) {
6410
- this.camera.left = width / -2;
6411
- this.camera.right = width / 2;
6412
- this.camera.top = height / 2;
6413
- this.camera.bottom = height / -2;
6414
- 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
+ }
6415
6342
  }
6416
- this.renderer.setSize(width, height);
6417
- this.composer?.setSize(width, height);
6418
- this._dirty = true;
6419
- }
6420
- //<editor-fold desc="RENDER">
6421
- get dirty() {
6422
- return this._dirty || this.scene.dirty;
6423
- }
6424
- set dirty(dirty) {
6425
- this._dirty = dirty;
6426
- this.scene.dirty = dirty;
6427
- }
6428
- start() {
6429
- if (this._disposed) return;
6430
- this.stop();
6431
- this.renderer.setAnimationLoop(this._animationLoop);
6432
- }
6433
- stop() {
6434
- if (this._disposed) return;
6435
- this.renderer.setAnimationLoop(null);
6436
- this._nextFrameTime = void 0;
6437
- }
6438
- /**
6439
- * Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
6440
- * renderer cannot be restarted. Scene objects are detached; shared assets and caller-owned
6441
- * controls must be managed by their owners.
6442
- */
6443
- dispose() {
6444
- if (this._disposed) return;
6445
- this.stop();
6446
- this._disposed = true;
6447
- if (this._resizeListener) {
6448
- window.removeEventListener("resize", this._resizeListener);
6449
- this._resizeListener = void 0;
6343
+ function onMouseUp(event) {
6344
+ handleMouseUp(event);
6345
+ scope.dispatchEvent(_endEvent);
6346
+ state = STATE.NONE;
6450
6347
  }
6451
- for (const [dispatcher, events] of this._eventDispatchers) {
6452
- for (const event of events) {
6453
- dispatcher.removeEventListener(event, this._changeListener);
6454
- }
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);
6455
6354
  }
6456
- this._eventDispatchers.clear();
6457
- this._stats?.dom.remove();
6458
- this._stats = void 0;
6459
- this.renderer.domElement.remove();
6460
- this._element = void 0;
6461
- if (this._controls) {
6462
- const controls = this._controls;
6463
- this._controls = void 0;
6464
- controls.enabled = false;
6465
- controls.dispose();
6355
+ function onKeyDown(event) {
6356
+ if (scope.enabled === false || scope.enablePan === false) return;
6357
+ handleKeyDown(event);
6466
6358
  }
6467
- this.scene.clear();
6468
- for (const helper of this._debugHelpers) {
6469
- helper.geometry.dispose();
6470
- const materials = Array.isArray(helper.material) ? helper.material : [helper.material];
6471
- for (const material of materials) {
6472
- 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);
6473
6399
  }
6474
6400
  }
6475
- this._debugHelpers.length = 0;
6476
- this.composer?.dispose();
6477
- this.renderer.dispose();
6478
- this.renderer.forceContextLoss();
6479
- }
6480
- animate(t = performance.now()) {
6481
- if (this._disposed) return;
6482
- if (this._controls?.enabled) {
6483
- this._controls.update();
6484
- }
6485
- if (this._disposed) return;
6486
- if (!this.dirty && !this.options.render.renderAlways) return;
6487
- const interval = this._frameInterval;
6488
- if (interval) {
6489
- const next = this._nextFrameTime;
6490
- if (next !== void 0 && t + 0.1 < next) return;
6491
- this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
6492
- }
6493
- if (this._stats) {
6494
- 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
+ }
6495
6427
  }
6496
- if (this.options.composer.enabled && this.composer) {
6497
- this.composer.render();
6498
- } else {
6499
- this.renderer.render(this.scene, this.camera);
6428
+ function onTouchEnd(event) {
6429
+ handleTouchEnd(event);
6430
+ scope.dispatchEvent(_endEvent);
6431
+ state = STATE.NONE;
6500
6432
  }
6501
- this.dirty = false;
6502
- if (this._stats) {
6503
- this._stats.end();
6433
+ function onContextMenu(event) {
6434
+ if (scope.enabled === false) return;
6435
+ event.preventDefault();
6504
6436
  }
6505
- }
6506
- //</editor-fold>
6507
- toImage() {
6508
- return this.renderer.domElement.toDataURL();
6509
- }
6510
- ///
6511
- get attachedToBody() {
6512
- return this.element === document.body;
6513
- }
6514
- get viewWidth() {
6515
- return this.attachedToBody ? window.innerWidth : this.element?.offsetWidth || 0;
6516
- }
6517
- get viewHeight() {
6518
- return this.attachedToBody ? window.innerHeight : this.element?.offsetHeight || 0;
6519
- }
6520
- get scene() {
6521
- return this._scene;
6522
- }
6523
- get camera() {
6524
- return this._camera;
6525
- }
6526
- get renderer() {
6527
- return this._renderer;
6528
- }
6529
- get composer() {
6530
- return this._composer;
6531
- }
6532
- /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
6533
- get controls() {
6534
- return this._controls;
6535
- }
6536
- ///
6537
- };
6538
-
6539
- // src/skin/Skins.ts
6540
- var Skins = class {
6541
- //<editor-fold desc="Skins">
6542
- static async fromUuidOrUsername(uuidOrUsername) {
6543
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6544
- return this.fromUuid(uuidOrUsername);
6437
+ function addPointer(event) {
6438
+ pointers.push(event);
6545
6439
  }
6546
- return this.fromUsername(uuidOrUsername);
6547
- }
6548
- static async fromUuid(uuid) {
6549
- return this.getSkinProxySkinUrl(uuid);
6550
- }
6551
- static async fromUsername(username) {
6552
- return this.usernameToUuid(username).then((uuid) => {
6553
- if (uuid) {
6554
- return this.fromUuid(uuid);
6555
- }
6556
- return void 0;
6557
- });
6558
- }
6559
- static async fromMineSkin(mineskinId) {
6560
- return this.getMineSkin(mineskinId).then((mineskin) => {
6561
- if (mineskin) {
6562
- 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
+ }
6563
6447
  }
6564
- return void 0;
6565
- });
6566
- }
6567
- //</editor-fold>
6568
- //<editor-fold desc="Capes">
6569
- static async capeFromUuidOrUsername(uuidOrUsername) {
6570
- if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
6571
- return this.capeFromUuid(uuidOrUsername);
6572
6448
  }
6573
- return this.capeFromUsername(uuidOrUsername);
6574
- }
6575
- static async capeFromUuid(uuid) {
6576
- return this.getSkinProxyCapeUrl(uuid);
6577
- }
6578
- static async capeFromUsername(username) {
6579
- return this.usernameToUuid(username).then((uuid) => {
6580
- if (uuid) {
6581
- return this.capeFromUuid(uuid);
6582
- }
6583
- return void 0;
6584
- });
6585
- }
6586
- static async capeFromCapesDev(uuid, capeType = "minecraft") {
6587
- return this.getCapesDev(uuid, capeType).then((cape) => {
6588
- if (cape) {
6589
- return cape?.stillImageUrl;
6590
- }
6591
- return void 0;
6592
- });
6593
- }
6594
- //</editor-fold>
6595
- //<editor-fold desc="Helpers">
6596
- static async usernameToUuid(username) {
6597
- return this.usernameToUuidSkinProxy(username);
6598
- }
6599
- static async usernameToUuidSkinProxy(username) {
6600
- return Requests.genericRequest({
6601
- baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
6602
- url: "/uuid/" + username
6603
- }).then((res) => {
6604
- if (res.status === 200) {
6605
- return res.data["id"];
6606
- }
6607
- return void 0;
6608
- }).catch((err) => {
6609
- console.warn(err);
6610
- return void 0;
6611
- });
6612
- }
6613
- static async usernameToUuidMineTools(username) {
6614
- return Requests.genericRequest({
6615
- baseURL: "https://api.minetools.eu",
6616
- url: "/uuid/" + username
6617
- }).then((res) => {
6618
- if (res.status === 200) {
6619
- return res.data["id"];
6620
- }
6621
- return void 0;
6622
- }).catch((err) => {
6623
- console.warn(err);
6624
- return void 0;
6625
- });
6626
- }
6627
- static async getProfileFromMinetools(uuid) {
6628
- return Requests.genericRequest({
6629
- baseURL: "https://api.minetools.eu",
6630
- url: "/profile/" + uuid
6631
- }).then((res) => {
6632
- if (res.status === 200) {
6633
- return res.data;
6634
- }
6635
- });
6636
- }
6637
- static async getMineSkin(mineskinId) {
6638
- return Requests.genericRequest({
6639
- baseURL: "https://api.mineskin.org",
6640
- url: "/get/uuid/" + mineskinId
6641
- }).then((res) => {
6642
- if (res.status === 200) {
6643
- return res.data;
6644
- }
6645
- return void 0;
6646
- }).catch((err) => {
6647
- console.warn(err);
6648
- return void 0;
6649
- });
6650
- }
6651
- static async getCapesDev(uuid, type = "all") {
6652
- return Requests.genericRequest({
6653
- baseURL: "https://api.capes.dev",
6654
- url: "/load/" + uuid + "/" + type
6655
- }).then((res) => {
6656
- if (res.status === 200) {
6657
- 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;
6658
6454
  }
6659
- return void 0;
6660
- }).catch((err) => {
6661
- console.warn(err);
6662
- return void 0;
6663
- });
6664
- }
6665
- static getCrafatarSkinUrl(uuid) {
6666
- return "https://crafatar.com/skins/" + uuid;
6667
- }
6668
- static getCrafatarCapeUrl(uuid) {
6669
- return "https://crafatar.com/capes/" + uuid;
6670
- }
6671
- static getMcHeadsSkinUrl(uuid) {
6672
- return "https://mc-heads.net/skin/" + uuid;
6673
- }
6674
- static getMineSkinPlayerSkinUrl(uuid) {
6675
- return "https://mineskin.org/skin/player/" + uuid;
6676
- }
6677
- static getSkinProxySkinUrl(uuid) {
6678
- 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();
6679
6466
  }
6680
- static getSkinProxyCapeUrl(uuid) {
6681
- 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;
6682
6476
  }
6683
- //</editor-fold>
6684
6477
  };
6685
6478
 
6686
6479
  // src/world/Chunk.ts
@@ -6743,7 +6536,7 @@ var MineRenderWorld = class {
6743
6536
  console.log("CHUNKS", this._chunks);
6744
6537
  for (let chunk of this._chunks.values()) {
6745
6538
  console.log("dispose chunk", chunk);
6746
- await chunk?.dispose();
6539
+ await (chunk == null ? void 0 : chunk.dispose());
6747
6540
  }
6748
6541
  this._chunks.clear();
6749
6542
  }
@@ -6797,7 +6590,7 @@ var MineRenderWorld = class {
6797
6590
  };
6798
6591
 
6799
6592
  // src/world/Chunk.ts
6800
- var p11 = prefix("Chunk");
6593
+ var p12 = prefix("Chunk");
6801
6594
  var Chunk = class _Chunk {
6802
6595
  constructor(scene, x, y, z) {
6803
6596
  this._blocks = [];
@@ -6849,7 +6642,7 @@ var Chunk = class _Chunk {
6849
6642
  const index = _Chunk.chunkPosToBlockIndex(pos);
6850
6643
  const current = this._blocks[index];
6851
6644
  if (typeof current !== "undefined") {
6852
- console.debug(p11, "deleting existing block at", pos, worldPos, index);
6645
+ console.debug(p12, "deleting existing block at", pos, worldPos, index);
6853
6646
  current.object.removeFromScene();
6854
6647
  delete this._blocks[index];
6855
6648
  }
@@ -6915,7 +6708,6 @@ export {
6915
6708
  AXES,
6916
6709
  ArchiveAssetSource,
6917
6710
  AssetKey,
6918
- AssetLoadError,
6919
6711
  AssetLoader,
6920
6712
  AssetParser,
6921
6713
  AssetSource,
@@ -6973,7 +6765,6 @@ export {
6973
6765
  OrbitControls,
6974
6766
  PersistentCache,
6975
6767
  Renderer,
6976
- RequestError,
6977
6768
  Requests,
6978
6769
  SKIN_PARTS,
6979
6770
  SceneInspector,