minerender 2.1.0-alpha.3 → 2.1.0-alpha.31
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.
- package/README.md +2 -0
- package/dist/browser/index.d.mts +246 -122
- package/dist/browser/index.d.ts +246 -122
- package/dist/browser/index.js +1606 -1015
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +1525 -934
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +15212 -13450
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +245 -121
- package/dist/node/index.d.ts +245 -121
- package/dist/node/index.js +1865 -1200
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +1776 -1115
- package/dist/node/index.mjs.map +1 -1
- package/package.json +8 -9
package/dist/browser/index.mjs
CHANGED
|
@@ -23,14 +23,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
24
|
mod
|
|
25
25
|
));
|
|
26
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
27
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
28
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
29
|
-
if (decorator = decorators[i])
|
|
30
|
-
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
31
|
-
if (kind && result) __defProp(target, key, result);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
26
|
|
|
35
27
|
// ../../node_modules/ts-deepmerge/dist/index.js
|
|
36
28
|
var require_dist = __commonJS({
|
|
@@ -40,8 +32,8 @@ var require_dist = __commonJS({
|
|
|
40
32
|
__assign = Object.assign || function(t) {
|
|
41
33
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
42
34
|
s = arguments[i];
|
|
43
|
-
for (var
|
|
44
|
-
t[
|
|
35
|
+
for (var p12 in s) if (Object.prototype.hasOwnProperty.call(s, p12))
|
|
36
|
+
t[p12] = s[p12];
|
|
45
37
|
}
|
|
46
38
|
return t;
|
|
47
39
|
};
|
|
@@ -85,7 +77,7 @@ var require_dist = __commonJS({
|
|
|
85
77
|
return false;
|
|
86
78
|
};
|
|
87
79
|
var PROTECTED_KEYS = ["__proto__"];
|
|
88
|
-
var
|
|
80
|
+
var merge10 = function() {
|
|
89
81
|
var objects = [];
|
|
90
82
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
91
83
|
objects[_i] = arguments[_i];
|
|
@@ -96,9 +88,9 @@ var require_dist = __commonJS({
|
|
|
96
88
|
return;
|
|
97
89
|
}
|
|
98
90
|
if (Array.isArray(result[key]) && Array.isArray(current[key])) {
|
|
99
|
-
result[key] =
|
|
91
|
+
result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
|
|
100
92
|
} else if (isObject(result[key]) && isObject(current[key])) {
|
|
101
|
-
result[key] =
|
|
93
|
+
result[key] = merge10(result[key], current[key]);
|
|
102
94
|
} else {
|
|
103
95
|
result[key] = current[key];
|
|
104
96
|
}
|
|
@@ -109,18 +101,18 @@ var require_dist = __commonJS({
|
|
|
109
101
|
var defaultOptions = {
|
|
110
102
|
mergeArrays: true
|
|
111
103
|
};
|
|
112
|
-
|
|
113
|
-
|
|
104
|
+
merge10.options = defaultOptions;
|
|
105
|
+
merge10.withOptions = function(options) {
|
|
114
106
|
var objects = [];
|
|
115
107
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
116
108
|
objects[_i - 1] = arguments[_i];
|
|
117
109
|
}
|
|
118
|
-
|
|
119
|
-
var result =
|
|
120
|
-
|
|
110
|
+
merge10.options = __assign({ mergeArrays: true }, options);
|
|
111
|
+
var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
|
|
112
|
+
merge10.options = defaultOptions;
|
|
121
113
|
return result;
|
|
122
114
|
};
|
|
123
|
-
exports.default =
|
|
115
|
+
exports.default = merge10;
|
|
124
116
|
}
|
|
125
117
|
});
|
|
126
118
|
|
|
@@ -154,17 +146,20 @@ var _PersistentCache = class _PersistentCache {
|
|
|
154
146
|
static open(name) {
|
|
155
147
|
return Env.provider.openCache(name, _PersistentCache.VERSION);
|
|
156
148
|
}
|
|
149
|
+
/** Loads a missing entry and stores only non-nullish results. */
|
|
157
150
|
async getOrLoad(key, loader) {
|
|
158
151
|
let v = await this.get(key);
|
|
159
152
|
if (typeof v === "undefined" || v === null) {
|
|
160
153
|
v = await loader(key);
|
|
161
|
-
|
|
154
|
+
if (typeof v !== "undefined" && v !== null) {
|
|
155
|
+
await this.put(key, v);
|
|
156
|
+
}
|
|
162
157
|
}
|
|
163
158
|
return v;
|
|
164
159
|
}
|
|
165
160
|
};
|
|
166
161
|
/** Bump to invalidate every persisted entry. */
|
|
167
|
-
_PersistentCache.VERSION =
|
|
162
|
+
_PersistentCache.VERSION = 2;
|
|
168
163
|
var PersistentCache = _PersistentCache;
|
|
169
164
|
|
|
170
165
|
// src/env/browser/BrowserCache.ts
|
|
@@ -265,7 +260,8 @@ var BrowserEnv = class {
|
|
|
265
260
|
}
|
|
266
261
|
openCache(name, version) {
|
|
267
262
|
return new BrowserCache(localforage.createInstance({
|
|
268
|
-
|
|
263
|
+
// IndexedDB schema upgrades retain records; each cache generation needs its own database.
|
|
264
|
+
name: name + version,
|
|
269
265
|
version
|
|
270
266
|
}));
|
|
271
267
|
}
|
|
@@ -282,7 +278,7 @@ registerBrowserEnv();
|
|
|
282
278
|
// src/Axis.ts
|
|
283
279
|
import { Vector3 } from "three";
|
|
284
280
|
var Axis = /* @__PURE__ */ ((Axis3) => {
|
|
285
|
-
Axis3["X"] = "
|
|
281
|
+
Axis3["X"] = "x";
|
|
286
282
|
Axis3["Y"] = "y";
|
|
287
283
|
Axis3["Z"] = "z";
|
|
288
284
|
return Axis3;
|
|
@@ -290,7 +286,7 @@ var Axis = /* @__PURE__ */ ((Axis3) => {
|
|
|
290
286
|
var AXES = Object.values(Axis);
|
|
291
287
|
function axisToVec3(axis) {
|
|
292
288
|
switch (axis) {
|
|
293
|
-
case "
|
|
289
|
+
case "x" /* X */:
|
|
294
290
|
return new Vector3(1, 0, 0);
|
|
295
291
|
case "y" /* Y */:
|
|
296
292
|
return new Vector3(0, 1, 0);
|
|
@@ -393,7 +389,10 @@ function serializeMeshKey(key) {
|
|
|
393
389
|
// src/cache/Caching.ts
|
|
394
390
|
import { Caches } from "@inventivetalent/loading-cache";
|
|
395
391
|
import { Time } from "@inventivetalent/time";
|
|
396
|
-
var
|
|
392
|
+
var _Caching = class _Caching {
|
|
393
|
+
static createAssetCache() {
|
|
394
|
+
return Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
395
|
+
}
|
|
397
396
|
/** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
|
|
398
397
|
static get all() {
|
|
399
398
|
return [
|
|
@@ -410,7 +409,12 @@ var Caching = class {
|
|
|
410
409
|
this.rawModelCache,
|
|
411
410
|
this.mergedModelCache,
|
|
412
411
|
this.modelTextureAtlasCache,
|
|
413
|
-
this.blockStateCache
|
|
412
|
+
this.blockStateCache,
|
|
413
|
+
this.listAssetCache,
|
|
414
|
+
this.defaultBlockStatesCache,
|
|
415
|
+
this.blockTintCache,
|
|
416
|
+
this.entityModelCache,
|
|
417
|
+
this.entityTextureCache
|
|
414
418
|
];
|
|
415
419
|
}
|
|
416
420
|
static clear() {
|
|
@@ -421,8 +425,8 @@ var Caching = class {
|
|
|
421
425
|
/**
|
|
422
426
|
* Clears every cache and stops its expiry timer.
|
|
423
427
|
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
428
|
+
* Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
|
|
429
|
+
* Use {@link shutdown} to also stop requests and the shared Ticker.
|
|
426
430
|
*/
|
|
427
431
|
static end() {
|
|
428
432
|
for (const cache of this.all) {
|
|
@@ -436,20 +440,26 @@ var Caching = class {
|
|
|
436
440
|
};
|
|
437
441
|
}
|
|
438
442
|
};
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
443
|
+
_Caching.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
|
|
444
|
+
_Caching.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
|
|
445
|
+
_Caching.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
|
|
446
|
+
_Caching.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
|
|
447
|
+
_Caching.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
|
|
448
|
+
_Caching.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
|
|
449
|
+
_Caching.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
|
|
450
|
+
_Caching.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
|
|
451
|
+
_Caching.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
452
|
+
_Caching.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
453
|
+
_Caching.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
454
|
+
_Caching.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
455
|
+
_Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
456
|
+
_Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
457
|
+
_Caching.listAssetCache = _Caching.createAssetCache();
|
|
458
|
+
_Caching.defaultBlockStatesCache = _Caching.createAssetCache();
|
|
459
|
+
_Caching.blockTintCache = _Caching.createAssetCache();
|
|
460
|
+
_Caching.entityModelCache = _Caching.createAssetCache();
|
|
461
|
+
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
462
|
+
var Caching = _Caching;
|
|
453
463
|
|
|
454
464
|
// src/Geometries.ts
|
|
455
465
|
var Geometries = class _Geometries {
|
|
@@ -477,6 +487,7 @@ import { CanvasTexture, Texture as Texture2 } from "three";
|
|
|
477
487
|
|
|
478
488
|
// src/texture/TextureLoader.ts
|
|
479
489
|
import { RGBAFormat, Texture } from "three";
|
|
490
|
+
import * as THREE from "three";
|
|
480
491
|
|
|
481
492
|
// src/canvas/CanvasCompat.ts
|
|
482
493
|
function createImage(width, height) {
|
|
@@ -487,9 +498,7 @@ function createCanvas(width, height) {
|
|
|
487
498
|
}
|
|
488
499
|
|
|
489
500
|
// src/request/Requests.ts
|
|
490
|
-
import
|
|
491
|
-
import { JobQueue } from "jobqu";
|
|
492
|
-
import { Time as Time2 } from "@inventivetalent/time";
|
|
501
|
+
import { JobCancelledError, JobQueue } from "jobqu";
|
|
493
502
|
|
|
494
503
|
// src/util/log.ts
|
|
495
504
|
var Reset = "\x1B[0m";
|
|
@@ -499,198 +508,170 @@ function prefix(prefix2) {
|
|
|
499
508
|
return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
|
|
500
509
|
}
|
|
501
510
|
|
|
502
|
-
// src/
|
|
503
|
-
var
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
this.
|
|
508
|
-
this.
|
|
509
|
-
|
|
510
|
-
submit(task) {
|
|
511
|
-
this.queue.push(task);
|
|
512
|
-
}
|
|
513
|
-
run() {
|
|
514
|
-
for (let i = 0; i < this.batch; i++) {
|
|
515
|
-
this.runNext();
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
runNext() {
|
|
519
|
-
let next = this.queue.shift();
|
|
520
|
-
if (next) next();
|
|
511
|
+
// src/request/Requests.ts
|
|
512
|
+
var p = prefix("Requests");
|
|
513
|
+
var RequestError = class extends Error {
|
|
514
|
+
constructor(message, response, cause) {
|
|
515
|
+
super(message);
|
|
516
|
+
this.response = response;
|
|
517
|
+
this.cause = cause;
|
|
518
|
+
this.name = "RequestError";
|
|
521
519
|
}
|
|
522
520
|
};
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
|
|
521
|
+
async function fetchRequest(config, defaultBaseURL) {
|
|
522
|
+
const { url, baseURL = defaultBaseURL, timeout = 5e3, responseType = "json", signal, ...options } = config;
|
|
523
|
+
const target = baseURL && !/^([a-z][a-z\d+.-]*:|\/\/)/i.test(url) ? `${baseURL.replace(/\/+$/, "")}/${url.replace(/^\/+/, "")}` : url;
|
|
524
|
+
const headers = new Headers(options.headers);
|
|
525
|
+
if (typeof window === "undefined" && !headers.has("User-Agent")) {
|
|
526
|
+
headers.set("User-Agent", "MineRender");
|
|
527
|
+
}
|
|
528
|
+
const attemptSignal = AbortSignal.any([
|
|
529
|
+
...signal ? [signal] : [],
|
|
530
|
+
...timeout === 0 ? [] : [AbortSignal.timeout(timeout)]
|
|
531
|
+
]);
|
|
532
|
+
const request = new Request(target, { ...options, headers, signal: attemptSignal });
|
|
533
|
+
attemptSignal.throwIfAborted();
|
|
534
|
+
try {
|
|
535
|
+
const response = await fetch(request);
|
|
536
|
+
const result = {
|
|
537
|
+
data: void 0,
|
|
538
|
+
status: response.status,
|
|
539
|
+
statusText: response.statusText,
|
|
540
|
+
headers: response.headers,
|
|
541
|
+
url: response.url
|
|
542
|
+
};
|
|
543
|
+
if (!response.ok) {
|
|
544
|
+
await response.body?.cancel().catch(() => {
|
|
545
|
+
});
|
|
546
|
+
throw new RequestError(`Request failed with status ${response.status}`, result);
|
|
547
|
+
}
|
|
548
|
+
const emptyBody = request.method === "HEAD" || response.status === 204 || response.status === 205;
|
|
549
|
+
const data = responseType === "arraybuffer" ? await response.arrayBuffer() : emptyBody || response.body === null ? void 0 : await response.json();
|
|
550
|
+
return { ...result, data };
|
|
551
|
+
} catch (error) {
|
|
552
|
+
attemptSignal.throwIfAborted();
|
|
553
|
+
if (/^https?:/.test(request.url) && request.redirect !== "error" && error instanceof TypeError) {
|
|
554
|
+
throw new RequestError("Network request failed", void 0, error);
|
|
547
555
|
}
|
|
556
|
+
throw error;
|
|
548
557
|
}
|
|
549
|
-
geometry.translate(origin.x, origin.y, origin.z);
|
|
550
|
-
}
|
|
551
|
-
function applyModelPartRotation(modelPart, geometry) {
|
|
552
|
-
const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
|
|
553
|
-
geometry.translate(-origin.x, -origin.y, -origin.z);
|
|
554
|
-
geometry.rotateX(toRadians(modelPart.pitch));
|
|
555
|
-
geometry.rotateY(toRadians(modelPart.yaw));
|
|
556
|
-
geometry.rotateZ(toRadians(modelPart.roll));
|
|
557
|
-
geometry.translate(origin.x, origin.y, origin.z);
|
|
558
558
|
}
|
|
559
|
-
function
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
559
|
+
async function abortable(promise, signal) {
|
|
560
|
+
if (!signal) return promise;
|
|
561
|
+
let abort;
|
|
562
|
+
const cancelled = new Promise((_, reject) => {
|
|
563
|
+
abort = () => reject(signal.reason);
|
|
564
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
565
|
+
if (signal.aborted) abort();
|
|
566
|
+
});
|
|
567
|
+
try {
|
|
568
|
+
return await Promise.race([promise, cancelled]);
|
|
569
|
+
} finally {
|
|
570
|
+
signal.removeEventListener("abort", abort);
|
|
570
571
|
}
|
|
571
572
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
let axes = new AxesHelper(1);
|
|
581
|
-
obj.add(axes);
|
|
582
|
-
}
|
|
583
|
-
function addWireframeToObject(obj, color = 16777215, w = 2) {
|
|
584
|
-
let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
|
|
585
|
-
let wireGeo = new EdgesGeometry(boxGeo);
|
|
586
|
-
let wireMat = new LineBasicMaterial({ color, linewidth: w });
|
|
587
|
-
let wireframe = new LineSegments(wireGeo, wireMat);
|
|
588
|
-
obj.add(wireframe);
|
|
589
|
-
let axes = new AxesHelper(1);
|
|
590
|
-
obj.add(axes);
|
|
591
|
-
}
|
|
592
|
-
function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
|
|
593
|
-
let wireGeo = new EdgesGeometry(geo);
|
|
594
|
-
let wireMat = new LineBasicMaterial({ color, linewidth: w });
|
|
595
|
-
let wireframe = new LineSegments(wireGeo, wireMat);
|
|
596
|
-
mesh.add(wireframe);
|
|
597
|
-
let axes = new AxesHelper(1);
|
|
598
|
-
mesh.add(axes);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// src/util/performance.ts
|
|
602
|
-
function captureException(e, ...extra) {
|
|
603
|
-
console.error(e, extra);
|
|
604
|
-
}
|
|
605
|
-
function timingStart(marker) {
|
|
606
|
-
console.time(marker);
|
|
607
|
-
}
|
|
608
|
-
function timingEnd(marker) {
|
|
609
|
-
console.timeEnd(marker);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// src/util/three.ts
|
|
613
|
-
function isObject3D(obj) {
|
|
614
|
-
return obj.isObject3D;
|
|
615
|
-
}
|
|
616
|
-
function isMesh(obj) {
|
|
617
|
-
return obj.isMesh;
|
|
618
|
-
}
|
|
619
|
-
function isInstancedMesh(obj) {
|
|
620
|
-
return obj.isInstancedMesh;
|
|
621
|
-
}
|
|
622
|
-
function isPerspectiveCamera(obj) {
|
|
623
|
-
return obj.isPerspectiveCamera;
|
|
624
|
-
}
|
|
625
|
-
function isOrthographicCamera(obj) {
|
|
626
|
-
return obj.isOrthographicCamera;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
// src/request/Requests.ts
|
|
630
|
-
var p = prefix("Requests");
|
|
631
|
-
if (typeof window === "undefined") {
|
|
632
|
-
axios.defaults.headers["User-Agent"] = "MineRender";
|
|
633
|
-
}
|
|
634
|
-
var _Requests = class _Requests {
|
|
635
|
-
static genericRequest(request) {
|
|
636
|
-
return this.genericQueue.add(request).catch(async (e) => {
|
|
637
|
-
console.debug(p, "generic catch", e.code, e);
|
|
638
|
-
if (this.shouldRetry(e, request)) {
|
|
639
|
-
await sleep(100);
|
|
640
|
-
return this.genericRequest(request);
|
|
641
|
-
}
|
|
642
|
-
throw e;
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
static mcAssetRequest(request) {
|
|
646
|
-
return this.mcAssetRequestQueue.add(request).catch((e) => {
|
|
647
|
-
console.debug(p, "mcAssetRequest catch", e.code, e);
|
|
648
|
-
throw e;
|
|
649
|
-
});
|
|
573
|
+
var RequestQueue = class {
|
|
574
|
+
constructor() {
|
|
575
|
+
this.pendingRequests = 0;
|
|
576
|
+
this.stopped = new AbortController();
|
|
577
|
+
this.queue = new JobQueue(
|
|
578
|
+
(request) => fetchRequest(request, this.baseURL),
|
|
579
|
+
{ interval: 10, maxPerRun: 1, maxActive: 8 }
|
|
580
|
+
);
|
|
650
581
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
582
|
+
async request(request) {
|
|
583
|
+
this.pendingRequests++;
|
|
584
|
+
const signal = request.signal;
|
|
585
|
+
try {
|
|
586
|
+
for (let retries = 0; ; retries++) {
|
|
587
|
+
signal?.throwIfAborted();
|
|
588
|
+
try {
|
|
589
|
+
return await abortable(this.queue.add(request), signal);
|
|
590
|
+
} catch (error) {
|
|
591
|
+
console.debug(p, "Request failed", error);
|
|
592
|
+
const delay = this.retryDelay(error, request, retries);
|
|
593
|
+
if (delay === void 0) {
|
|
594
|
+
throw error;
|
|
658
595
|
}
|
|
659
|
-
|
|
660
|
-
request["minerenderRetry"] = 3;
|
|
661
|
-
return true;
|
|
596
|
+
await this.waitForRetry(delay, signal);
|
|
662
597
|
}
|
|
663
598
|
}
|
|
599
|
+
} finally {
|
|
600
|
+
if (signal?.aborted) {
|
|
601
|
+
this.queue.remove(request);
|
|
602
|
+
}
|
|
603
|
+
this.pendingRequests--;
|
|
664
604
|
}
|
|
665
|
-
|
|
605
|
+
}
|
|
606
|
+
retryDelay(error, request, retries) {
|
|
607
|
+
if (this.stopped.signal.aborted || retries >= 3 || (request.method ?? "get").toLowerCase() !== "get" || request.signal?.aborted) {
|
|
608
|
+
return void 0;
|
|
609
|
+
}
|
|
610
|
+
if (error instanceof RequestError) {
|
|
611
|
+
const status = error.response?.status;
|
|
612
|
+
if (status !== void 0 && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return void 0;
|
|
613
|
+
} else if (!(error instanceof DOMException && error.name === "TimeoutError")) {
|
|
614
|
+
return void 0;
|
|
615
|
+
}
|
|
616
|
+
let delay = 100 * 2 ** retries;
|
|
617
|
+
const retryAfter = error instanceof RequestError ? error.response?.headers.get("Retry-After") : void 0;
|
|
618
|
+
if (retryAfter !== void 0 && retryAfter !== null) {
|
|
619
|
+
const seconds = Number(retryAfter);
|
|
620
|
+
if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {
|
|
621
|
+
return void 0;
|
|
622
|
+
}
|
|
623
|
+
delay = Math.max(delay, seconds * 1e3);
|
|
624
|
+
}
|
|
625
|
+
return delay;
|
|
626
|
+
}
|
|
627
|
+
async waitForRetry(delay, signal) {
|
|
628
|
+
let timer;
|
|
629
|
+
const waiting = new Promise((resolve) => {
|
|
630
|
+
timer = setTimeout(resolve, delay);
|
|
631
|
+
});
|
|
632
|
+
try {
|
|
633
|
+
await abortable(waiting, AbortSignal.any([this.stopped.signal, ...signal ? [signal] : []]));
|
|
634
|
+
} finally {
|
|
635
|
+
clearTimeout(timer);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
get pendingSize() {
|
|
639
|
+
return this.pendingRequests;
|
|
640
|
+
}
|
|
641
|
+
end() {
|
|
642
|
+
this.queue.end();
|
|
643
|
+
this.stopped.abort(new JobCancelledError("ended"));
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
var Requests = class {
|
|
647
|
+
static genericRequest(request) {
|
|
648
|
+
return this.genericQueue.request(request);
|
|
649
|
+
}
|
|
650
|
+
static mcAssetRequest(request) {
|
|
651
|
+
return this.mcAssetRequestQueue.request(request);
|
|
666
652
|
}
|
|
667
653
|
static setMcAssetRoot(root) {
|
|
668
|
-
this.
|
|
654
|
+
this.mcAssetRequestQueue.baseURL = root;
|
|
669
655
|
}
|
|
656
|
+
/** Counts unsettled calls, including retry delays and requests still running after shutdown. */
|
|
670
657
|
static get queueSizes() {
|
|
671
658
|
return {
|
|
672
|
-
generic: this.genericQueue.
|
|
673
|
-
mcAsset: this.mcAssetRequestQueue.
|
|
659
|
+
generic: this.genericQueue.pendingSize,
|
|
660
|
+
mcAsset: this.mcAssetRequestQueue.pendingSize
|
|
674
661
|
};
|
|
675
662
|
}
|
|
676
663
|
/**
|
|
677
|
-
*
|
|
678
|
-
*
|
|
664
|
+
* Permanently stops both queues and rejects waiting, retrying, and future requests.
|
|
665
|
+
* Requests already running can finish. Idle queues hold no timer, so Node can exit without
|
|
666
|
+
* this cleanup. See {@link shutdown}.
|
|
679
667
|
*/
|
|
680
668
|
static end() {
|
|
681
669
|
this.genericQueue.end();
|
|
682
670
|
this.mcAssetRequestQueue.end();
|
|
683
671
|
}
|
|
684
672
|
};
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
});
|
|
688
|
-
_Requests.mcAssetInstance = axios.create({
|
|
689
|
-
timeout: 5e3
|
|
690
|
-
});
|
|
691
|
-
_Requests.genericQueue = new JobQueue((request) => _Requests.axiosInstance.request(request), Time2.millis(10), 1);
|
|
692
|
-
_Requests.mcAssetRequestQueue = new JobQueue((request) => _Requests.mcAssetInstance.request(request), Time2.millis(10), 1);
|
|
693
|
-
var Requests = _Requests;
|
|
673
|
+
Requests.genericQueue = new RequestQueue();
|
|
674
|
+
Requests.mcAssetRequestQueue = new RequestQueue();
|
|
694
675
|
|
|
695
676
|
// src/WrappedImage.ts
|
|
696
677
|
var WrappedImage = class {
|
|
@@ -728,10 +709,10 @@ var WrappedImage = class {
|
|
|
728
709
|
return this.animated ? this.width : this.height;
|
|
729
710
|
}
|
|
730
711
|
get frameCount() {
|
|
731
|
-
return this.height / this.
|
|
712
|
+
return this.height / this.frameHeight;
|
|
732
713
|
}
|
|
733
714
|
getFrameY(frame) {
|
|
734
|
-
return this.
|
|
715
|
+
return this.frameHeight * Math.max(0, Math.min(this.frameCount - 1, frame));
|
|
735
716
|
}
|
|
736
717
|
getSectionData(sx, sy, sw, sh) {
|
|
737
718
|
return this.dta.data.getImageData(sx, sy, sw, sh);
|
|
@@ -741,7 +722,7 @@ var WrappedImage = class {
|
|
|
741
722
|
}
|
|
742
723
|
getFrameSectionData(frame) {
|
|
743
724
|
const y = this.getFrameY(frame);
|
|
744
|
-
return this.getSectionData(0, y, this.
|
|
725
|
+
return this.getSectionData(0, y, this.frameWidth, this.frameHeight);
|
|
745
726
|
}
|
|
746
727
|
};
|
|
747
728
|
|
|
@@ -755,29 +736,41 @@ var ImageLoader = class _ImageLoader {
|
|
|
755
736
|
static async loadAsync(src) {
|
|
756
737
|
return new Promise((resolve, reject) => {
|
|
757
738
|
const image = this._createImage();
|
|
758
|
-
image.src = src;
|
|
759
739
|
image.onload = () => resolve(image);
|
|
760
|
-
image.onerror = (err) => reject(err);
|
|
740
|
+
image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
|
|
741
|
+
image.src = src;
|
|
761
742
|
});
|
|
762
743
|
}
|
|
763
744
|
static loadElement(src, onload, onerr) {
|
|
764
745
|
const image = this._createImage();
|
|
765
|
-
image.src = src;
|
|
766
746
|
if (onload)
|
|
767
747
|
image.onload = onload;
|
|
768
748
|
if (onerr)
|
|
769
749
|
image.onerror = onerr;
|
|
750
|
+
image.src = src;
|
|
770
751
|
return image;
|
|
771
752
|
}
|
|
772
753
|
static async loadData(src) {
|
|
773
754
|
console.debug(p2, "loadData", src);
|
|
774
|
-
|
|
755
|
+
const image = await this.loadCanvasData(src);
|
|
756
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
775
757
|
}
|
|
776
758
|
static async loadCanvasData(src) {
|
|
777
|
-
|
|
759
|
+
const keyStr = serializeImageKey({ src });
|
|
760
|
+
const info = this.getInfo(src);
|
|
761
|
+
const cached = Caching.rawImageCache.getIfPresent(keyStr);
|
|
762
|
+
try {
|
|
763
|
+
return await this.infoToCanvasData(await info);
|
|
764
|
+
} catch (err) {
|
|
765
|
+
if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
|
|
766
|
+
Caching.rawImageCache.invalidate(keyStr);
|
|
767
|
+
}
|
|
768
|
+
throw err;
|
|
769
|
+
}
|
|
778
770
|
}
|
|
779
771
|
static async infoToCanvasData(info) {
|
|
780
|
-
const
|
|
772
|
+
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
773
|
+
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
781
774
|
const canvas = createCanvas(info.width, info.height);
|
|
782
775
|
const context = canvas.getContext("2d");
|
|
783
776
|
context.drawImage(image, 0, 0);
|
|
@@ -788,11 +781,8 @@ var ImageLoader = class _ImageLoader {
|
|
|
788
781
|
};
|
|
789
782
|
}
|
|
790
783
|
static async infoToData(info) {
|
|
791
|
-
const image = await
|
|
792
|
-
|
|
793
|
-
const context = canvas.getContext("2d");
|
|
794
|
-
context.drawImage(image, 0, 0);
|
|
795
|
-
return context.getImageData(0, 0, canvas.width, canvas.height);
|
|
784
|
+
const image = await this.infoToCanvasData(info);
|
|
785
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
796
786
|
}
|
|
797
787
|
static async getData(src) {
|
|
798
788
|
const keyStr = serializeImageKey({ src });
|
|
@@ -807,38 +797,25 @@ var ImageLoader = class _ImageLoader {
|
|
|
807
797
|
});
|
|
808
798
|
}
|
|
809
799
|
static async processResponse(response) {
|
|
810
|
-
const src = response.
|
|
800
|
+
const src = response.url;
|
|
811
801
|
const data = Buffer2.from(response.data);
|
|
812
802
|
const { width, height, type } = Env.provider.imageSize(data);
|
|
803
|
+
if (!width || !height) {
|
|
804
|
+
throw new Error("Invalid or unsupported image dimensions");
|
|
805
|
+
}
|
|
813
806
|
return {
|
|
814
807
|
src,
|
|
815
|
-
width
|
|
816
|
-
height
|
|
808
|
+
width,
|
|
809
|
+
height,
|
|
817
810
|
type,
|
|
818
811
|
data
|
|
819
812
|
};
|
|
820
813
|
}
|
|
821
814
|
static async loadInfo(src) {
|
|
822
|
-
if (src.startsWith("data:image/png;base64")) {
|
|
823
|
-
return this.processResponse({
|
|
824
|
-
config: {
|
|
825
|
-
url: src
|
|
826
|
-
},
|
|
827
|
-
data: Buffer2.from(src.substr("data:image/png;base64,".length), "base64")
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
815
|
return Requests.genericRequest({
|
|
831
816
|
url: src,
|
|
832
817
|
responseType: "arraybuffer"
|
|
833
|
-
}).then(this.processResponse)
|
|
834
|
-
return {
|
|
835
|
-
src,
|
|
836
|
-
width: 0,
|
|
837
|
-
height: 0,
|
|
838
|
-
type: void 0,
|
|
839
|
-
data: Buffer2.from([0])
|
|
840
|
-
};
|
|
841
|
-
});
|
|
818
|
+
}).then(this.processResponse);
|
|
842
819
|
}
|
|
843
820
|
static async getInfo(src) {
|
|
844
821
|
const keyStr = serializeImageKey({ src });
|
|
@@ -860,15 +837,22 @@ var ImageLoader = class _ImageLoader {
|
|
|
860
837
|
|
|
861
838
|
// src/texture/TextureLoader.ts
|
|
862
839
|
var TextureLoader = class {
|
|
840
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
841
|
+
static hasFailed(texture) {
|
|
842
|
+
return this.failedTextures.has(texture);
|
|
843
|
+
}
|
|
863
844
|
static createTexture() {
|
|
864
845
|
return new Texture();
|
|
865
846
|
}
|
|
866
847
|
static loadInBackground(src, format = RGBAFormat, rotation = 0) {
|
|
867
848
|
const texture = this.createTexture();
|
|
868
|
-
|
|
869
|
-
image
|
|
849
|
+
texture.colorSpace = THREE.SRGBColorSpace;
|
|
850
|
+
const image = ImageLoader.loadElement(src, () => {
|
|
870
851
|
texture.needsUpdate = true;
|
|
871
|
-
}
|
|
852
|
+
}, (error) => {
|
|
853
|
+
this.failedTextures.add(texture);
|
|
854
|
+
console.warn("Failed to load texture", src, error);
|
|
855
|
+
});
|
|
872
856
|
texture.image = image;
|
|
873
857
|
texture.format = format;
|
|
874
858
|
texture.rotation = rotation;
|
|
@@ -876,22 +860,27 @@ var TextureLoader = class {
|
|
|
876
860
|
}
|
|
877
861
|
static load(src, format = RGBAFormat, rotation = 0) {
|
|
878
862
|
const texture = new Texture();
|
|
863
|
+
texture.colorSpace = THREE.SRGBColorSpace;
|
|
879
864
|
ImageLoader.getData(src).then((image) => {
|
|
880
|
-
texture.needsUpdate = true;
|
|
881
865
|
texture.image = image;
|
|
866
|
+
texture.needsUpdate = true;
|
|
867
|
+
}).catch((error) => {
|
|
868
|
+
this.failedTextures.add(texture);
|
|
869
|
+
console.warn("Failed to load texture", src, error);
|
|
882
870
|
});
|
|
883
871
|
texture.format = format;
|
|
884
872
|
texture.rotation = rotation;
|
|
885
873
|
return Textures.initTextureProps(texture);
|
|
886
874
|
}
|
|
887
875
|
};
|
|
876
|
+
TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
|
|
888
877
|
|
|
889
878
|
// src/texture/Textures.ts
|
|
890
|
-
import * as
|
|
879
|
+
import * as THREE2 from "three";
|
|
891
880
|
var Textures = class _Textures {
|
|
892
881
|
static initTextureProps(texture) {
|
|
893
|
-
texture.magFilter =
|
|
894
|
-
texture.minFilter =
|
|
882
|
+
texture.magFilter = THREE2.NearestFilter;
|
|
883
|
+
texture.minFilter = THREE2.NearestFilter;
|
|
895
884
|
texture.anisotropy = 0;
|
|
896
885
|
return texture;
|
|
897
886
|
}
|
|
@@ -902,10 +891,16 @@ var Textures = class _Textures {
|
|
|
902
891
|
return new Texture2();
|
|
903
892
|
}
|
|
904
893
|
static createCanvasTexture(canvas) {
|
|
905
|
-
|
|
894
|
+
const texture = new CanvasTexture(canvas);
|
|
895
|
+
texture.colorSpace = THREE2.SRGBColorSpace;
|
|
896
|
+
return this.initTextureProps(texture);
|
|
906
897
|
}
|
|
907
898
|
static getImage(key) {
|
|
908
899
|
const keyStr = serializeTextureKey(key);
|
|
900
|
+
const cached = Caching.textureCache.peek(keyStr);
|
|
901
|
+
if (cached && TextureLoader.hasFailed(cached)) {
|
|
902
|
+
Caching.textureCache.invalidate(keyStr);
|
|
903
|
+
}
|
|
909
904
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
910
905
|
return _Textures.createImage(key);
|
|
911
906
|
});
|
|
@@ -949,6 +944,7 @@ var _Materials = class _Materials {
|
|
|
949
944
|
uniform bool SHADE;
|
|
950
945
|
|
|
951
946
|
varying vec2 vUv;
|
|
947
|
+
varying vec3 vTint;
|
|
952
948
|
varying float light;
|
|
953
949
|
varying float lift;
|
|
954
950
|
|
|
@@ -961,7 +957,11 @@ var _Materials = class _Materials {
|
|
|
961
957
|
|
|
962
958
|
if (SHADE) {
|
|
963
959
|
|
|
964
|
-
|
|
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
|
|
965
965
|
|
|
966
966
|
float yLight = (1.0+N.y) * 0.5;
|
|
967
967
|
light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT;
|
|
@@ -979,6 +979,7 @@ var _Materials = class _Materials {
|
|
|
979
979
|
}
|
|
980
980
|
|
|
981
981
|
vUv = uv;
|
|
982
|
+
vTint = color;
|
|
982
983
|
|
|
983
984
|
#ifdef USE_INSTANCING
|
|
984
985
|
gl_Position = projectionMatrix * viewMatrix * modelMatrix * instanceMatrix * vec4(position, 1.0);
|
|
@@ -1000,12 +1001,14 @@ var _Materials = class _Materials {
|
|
|
1000
1001
|
uniform float BRIGHTNESS;
|
|
1001
1002
|
|
|
1002
1003
|
varying vec2 vUv;
|
|
1004
|
+
varying vec3 vTint;
|
|
1003
1005
|
varying float light;
|
|
1004
1006
|
varying float lift;
|
|
1005
1007
|
|
|
1006
1008
|
void main(void)
|
|
1007
1009
|
{
|
|
1008
1010
|
vec4 color = texture2D(map, vUv);
|
|
1011
|
+
color.rgb *= vTint;
|
|
1009
1012
|
|
|
1010
1013
|
if (color.a < 0.01) discard;
|
|
1011
1014
|
|
|
@@ -1019,6 +1022,9 @@ var _Materials = class _Materials {
|
|
|
1019
1022
|
gl_FragColor = vec4(lift + color.rgb * light2, 1.0);
|
|
1020
1023
|
|
|
1021
1024
|
}
|
|
1025
|
+
|
|
1026
|
+
#include <tonemapping_fragment>
|
|
1027
|
+
#include <colorspace_fragment>
|
|
1022
1028
|
}
|
|
1023
1029
|
`;
|
|
1024
1030
|
try {
|
|
@@ -1047,6 +1053,10 @@ var _Materials = class _Materials {
|
|
|
1047
1053
|
}
|
|
1048
1054
|
static getImage(key) {
|
|
1049
1055
|
const keyStr = serializeMaterialKey(key);
|
|
1056
|
+
const map = Caching.materialCache.peek(keyStr)?.map;
|
|
1057
|
+
if (map && TextureLoader.hasFailed(map)) {
|
|
1058
|
+
Caching.materialCache.invalidate(keyStr);
|
|
1059
|
+
}
|
|
1050
1060
|
return Caching.materialCache.get(keyStr, (k) => {
|
|
1051
1061
|
return _Materials.createImage(key);
|
|
1052
1062
|
});
|
|
@@ -1071,10 +1081,10 @@ _Materials.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA
|
|
|
1071
1081
|
var Materials = _Materials;
|
|
1072
1082
|
|
|
1073
1083
|
// src/Meshes.ts
|
|
1074
|
-
import { Mesh
|
|
1084
|
+
import { Mesh } from "three";
|
|
1075
1085
|
var Meshes = class _Meshes {
|
|
1076
1086
|
static createBox(key) {
|
|
1077
|
-
return new
|
|
1087
|
+
return new Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
|
|
1078
1088
|
}
|
|
1079
1089
|
static getBox(key) {
|
|
1080
1090
|
const keyStr = serializeMeshKey(key);
|
|
@@ -1085,7 +1095,7 @@ var Meshes = class _Meshes {
|
|
|
1085
1095
|
};
|
|
1086
1096
|
|
|
1087
1097
|
// src/UVMapper.ts
|
|
1088
|
-
import { Float32BufferAttribute as Float32BufferAttribute2, Vector2 } from "three";
|
|
1098
|
+
import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector34 } from "three";
|
|
1089
1099
|
|
|
1090
1100
|
// src/model/ModelMerger.ts
|
|
1091
1101
|
var import_ts_deepmerge = __toESM(require_dist());
|
|
@@ -1121,6 +1131,7 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1121
1131
|
this.rootType = rootType;
|
|
1122
1132
|
this.extension = extension;
|
|
1123
1133
|
this.root = root;
|
|
1134
|
+
this.isAssetKey = true;
|
|
1124
1135
|
}
|
|
1125
1136
|
static parse(assetType, str, origin) {
|
|
1126
1137
|
let namespace = origin?.namespace || DEFAULT_NAMESPACE;
|
|
@@ -1136,12 +1147,15 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1136
1147
|
split.shift();
|
|
1137
1148
|
}
|
|
1138
1149
|
let path = split.join("/");
|
|
1139
|
-
|
|
1150
|
+
const extension = assetType === "textures" ? ".png" : origin?.extension ?? ".json";
|
|
1151
|
+
if (extension && path.endsWith(extension)) {
|
|
1152
|
+
path = path.slice(0, -extension.length);
|
|
1153
|
+
}
|
|
1140
1154
|
return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin?.root);
|
|
1141
1155
|
}
|
|
1142
1156
|
toString() {
|
|
1143
1157
|
let a = [
|
|
1144
|
-
|
|
1158
|
+
this.root ?? AssetLoader.ROOT,
|
|
1145
1159
|
this.rootType ?? "__rootType__",
|
|
1146
1160
|
this.assetType ?? "__assetType__",
|
|
1147
1161
|
this.type ?? "__type__",
|
|
@@ -1151,12 +1165,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1151
1165
|
return a.join("/");
|
|
1152
1166
|
}
|
|
1153
1167
|
getFullPath() {
|
|
1154
|
-
let
|
|
1168
|
+
let p12 = [];
|
|
1155
1169
|
if (this.type) {
|
|
1156
|
-
|
|
1170
|
+
p12.push(this.type);
|
|
1157
1171
|
}
|
|
1158
|
-
|
|
1159
|
-
return
|
|
1172
|
+
p12.push(this.path);
|
|
1173
|
+
return p12.join("/");
|
|
1160
1174
|
}
|
|
1161
1175
|
toNamespacedString() {
|
|
1162
1176
|
return this.namespace + ":" + this.getFullPath();
|
|
@@ -1166,22 +1180,84 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1166
1180
|
}
|
|
1167
1181
|
};
|
|
1168
1182
|
function isBasicAssetKey(obj) {
|
|
1169
|
-
return "
|
|
1183
|
+
return obj !== null && typeof obj === "object" && typeof obj.namespace === "string" && typeof obj.path === "string";
|
|
1170
1184
|
}
|
|
1171
1185
|
function isAssetKey(obj) {
|
|
1172
|
-
return isBasicAssetKey(obj) &&
|
|
1186
|
+
return isBasicAssetKey(obj) && obj.isAssetKey === true;
|
|
1173
1187
|
}
|
|
1174
1188
|
|
|
1189
|
+
// src/model/DisplayTransforms.ts
|
|
1190
|
+
import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
|
|
1191
|
+
|
|
1192
|
+
// src/model/DisplayPosition.ts
|
|
1193
|
+
var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
|
|
1194
|
+
DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
|
|
1195
|
+
DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
|
|
1196
|
+
DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
|
|
1197
|
+
DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
|
|
1198
|
+
DisplayPosition2["GUI"] = "gui";
|
|
1199
|
+
DisplayPosition2["HEAD"] = "head";
|
|
1200
|
+
DisplayPosition2["GROUND"] = "ground";
|
|
1201
|
+
DisplayPosition2["FIXED"] = "fixed";
|
|
1202
|
+
DisplayPosition2["ON_SHELF"] = "on_shelf";
|
|
1203
|
+
return DisplayPosition2;
|
|
1204
|
+
})(DisplayPosition || {});
|
|
1205
|
+
var DISPLAY_POSITIONS = Object.values(DisplayPosition);
|
|
1206
|
+
|
|
1207
|
+
// src/model/DisplayTransforms.ts
|
|
1208
|
+
var DisplayTransforms = class {
|
|
1209
|
+
/** Resolve hand fallbacks within one model, before inheriting parent display entries. */
|
|
1210
|
+
static withHandFallbacks(display) {
|
|
1211
|
+
if (!display) return void 0;
|
|
1212
|
+
const resolved = { ...display };
|
|
1213
|
+
for (const [left, right] of [
|
|
1214
|
+
["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
|
|
1215
|
+
["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
|
|
1216
|
+
]) {
|
|
1217
|
+
if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
|
|
1218
|
+
}
|
|
1219
|
+
return resolved;
|
|
1220
|
+
}
|
|
1221
|
+
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1222
|
+
static getMatrix(display, position) {
|
|
1223
|
+
const transform = this.withHandFallbacks(display)?.[position] ?? {};
|
|
1224
|
+
const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
|
|
1225
|
+
const sign = left ? -1 : 1;
|
|
1226
|
+
const [x, y, z] = transform.rotation ?? [0, 0, 0];
|
|
1227
|
+
const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
|
|
1228
|
+
const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
|
|
1229
|
+
translation.x *= sign;
|
|
1230
|
+
const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
|
|
1231
|
+
return new Matrix4().compose(translation, rotation, scale);
|
|
1232
|
+
}
|
|
1233
|
+
static apply(geometry, matrix) {
|
|
1234
|
+
geometry.applyMatrix4(matrix);
|
|
1235
|
+
if (matrix.determinant() < 0) {
|
|
1236
|
+
if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
|
|
1237
|
+
const index = geometry.index;
|
|
1238
|
+
for (let i = 0; i < index.count; i += 3) {
|
|
1239
|
+
const second = index.getX(i + 1);
|
|
1240
|
+
index.setX(i + 1, index.getX(i + 2));
|
|
1241
|
+
index.setX(i + 2, second);
|
|
1242
|
+
}
|
|
1243
|
+
index.needsUpdate = true;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1175
1248
|
// src/model/ModelMerger.ts
|
|
1176
1249
|
var ModelMerger = class {
|
|
1177
1250
|
static async mergeWithParents(model) {
|
|
1178
1251
|
const models = await this.collectAllParents(model);
|
|
1179
1252
|
let merged = {};
|
|
1180
|
-
for (
|
|
1181
|
-
|
|
1253
|
+
for (const source of [...models, model]) {
|
|
1254
|
+
const inheritedDisplay = merged.display;
|
|
1255
|
+
merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
|
|
1256
|
+
if (source.display) {
|
|
1257
|
+
merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
|
|
1258
|
+
}
|
|
1182
1259
|
}
|
|
1183
|
-
merged = (
|
|
1184
|
-
merged.hierarchy = models.map((m) => m.parent).filter((p13) => `${p13}`);
|
|
1260
|
+
merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
|
|
1185
1261
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1186
1262
|
return merged;
|
|
1187
1263
|
}
|
|
@@ -1191,6 +1267,7 @@ var ModelMerger = class {
|
|
|
1191
1267
|
}
|
|
1192
1268
|
const models = [];
|
|
1193
1269
|
const parentKey = AssetKey.parse("models", model.parent);
|
|
1270
|
+
parentKey.root = model.key?.root;
|
|
1194
1271
|
const parentModel = await Models.getRaw(parentKey);
|
|
1195
1272
|
if (parentModel) {
|
|
1196
1273
|
models.unshift(parentModel);
|
|
@@ -1200,9 +1277,6 @@ var ModelMerger = class {
|
|
|
1200
1277
|
}
|
|
1201
1278
|
};
|
|
1202
1279
|
|
|
1203
|
-
// src/assets/Models.ts
|
|
1204
|
-
import { Memoize } from "typescript-memoize";
|
|
1205
|
-
|
|
1206
1280
|
// src/assets/source/parser/AssetParsers.ts
|
|
1207
1281
|
var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
|
|
1208
1282
|
AssetParser2["MODEL"] = "model";
|
|
@@ -1216,30 +1290,65 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
|
|
|
1216
1290
|
})(AssetParser || {});
|
|
1217
1291
|
|
|
1218
1292
|
// src/assets/Models.ts
|
|
1219
|
-
var
|
|
1293
|
+
var Models = class _Models {
|
|
1220
1294
|
// opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
|
|
1221
1295
|
// the library, and would require an EnvProvider before any entry has had a chance to register
|
|
1222
1296
|
static get PERSISTENT_CACHE() {
|
|
1223
1297
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
|
|
1224
1298
|
}
|
|
1225
1299
|
static async getItemList() {
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
"
|
|
1230
|
-
|
|
1231
|
-
"assets",
|
|
1232
|
-
".json",
|
|
1233
|
-
DEFAULT_ROOT
|
|
1234
|
-
), "list" /* LIST */).then((r) => r?.files ?? []);
|
|
1300
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
|
|
1301
|
+
const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
|
|
1302
|
+
return Caching.listAssetCache.get(key.serialize(), async () => {
|
|
1303
|
+
return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
|
|
1304
|
+
}).then((r) => r?.files ?? []);
|
|
1235
1305
|
}
|
|
1236
1306
|
static async loadAndMerge(key) {
|
|
1237
|
-
const model = await this.getRaw(key);
|
|
1307
|
+
const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
|
|
1238
1308
|
if (!model) {
|
|
1239
1309
|
return void 0;
|
|
1240
1310
|
}
|
|
1241
1311
|
return ModelMerger.mergeWithParents(model);
|
|
1242
1312
|
}
|
|
1313
|
+
static async getItemModel(key) {
|
|
1314
|
+
const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
|
|
1315
|
+
const model = await this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(itemKey.serialize()), async () => {
|
|
1316
|
+
const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
|
|
1317
|
+
if (!result) return void 0;
|
|
1318
|
+
if (result.key.assetType !== "items") return { ...result.asset, key };
|
|
1319
|
+
const reference = this.defaultItemModel(result.asset.model, key);
|
|
1320
|
+
const modelKey = AssetKey.parse("models", reference);
|
|
1321
|
+
modelKey.root = key.root;
|
|
1322
|
+
const model2 = await this.getRaw(modelKey);
|
|
1323
|
+
if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
|
|
1324
|
+
return model2;
|
|
1325
|
+
});
|
|
1326
|
+
return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
|
|
1327
|
+
}
|
|
1328
|
+
// Item previews use the GUI context, false conditions, and zero numeric properties.
|
|
1329
|
+
static defaultItemModel(node, key) {
|
|
1330
|
+
if (!node || typeof node.type !== "string") {
|
|
1331
|
+
throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
|
|
1332
|
+
}
|
|
1333
|
+
switch (node.type.replace(/^minecraft:/, "")) {
|
|
1334
|
+
case "model":
|
|
1335
|
+
if (typeof node.model === "string" && node.model) return node.model;
|
|
1336
|
+
break;
|
|
1337
|
+
case "condition":
|
|
1338
|
+
return this.defaultItemModel(node.on_false, key);
|
|
1339
|
+
case "select": {
|
|
1340
|
+
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;
|
|
1341
|
+
return this.defaultItemModel(selected ?? node.fallback, key);
|
|
1342
|
+
}
|
|
1343
|
+
case "range_dispatch": {
|
|
1344
|
+
const selected = node.entries?.reduce((match, entry) => {
|
|
1345
|
+
return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
|
|
1346
|
+
}, void 0);
|
|
1347
|
+
return this.defaultItemModel(selected?.model ?? node.fallback, key);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
|
|
1351
|
+
}
|
|
1243
1352
|
static async getRaw(key) {
|
|
1244
1353
|
if (!key.assetType) {
|
|
1245
1354
|
key.assetType = "models";
|
|
@@ -1249,7 +1358,7 @@ var _Models = class _Models {
|
|
|
1249
1358
|
}
|
|
1250
1359
|
const keyStr = key.serialize();
|
|
1251
1360
|
return Caching.rawModelCache.get(keyStr, (k) => {
|
|
1252
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1361
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1253
1362
|
return AssetLoader.get(key, "model" /* MODEL */);
|
|
1254
1363
|
});
|
|
1255
1364
|
}).then((asset) => {
|
|
@@ -1278,31 +1387,32 @@ var _Models = class _Models {
|
|
|
1278
1387
|
return this.PERSISTENT_CACHE.clear();
|
|
1279
1388
|
}
|
|
1280
1389
|
};
|
|
1281
|
-
__decorateClass([
|
|
1282
|
-
Memoize()
|
|
1283
|
-
], _Models, "getItemList", 1);
|
|
1284
|
-
var Models = _Models;
|
|
1285
1390
|
|
|
1286
1391
|
// src/assets/BlockStates.ts
|
|
1287
|
-
import { Memoize as Memoize2 } from "typescript-memoize";
|
|
1288
1392
|
var BlockStates = class {
|
|
1289
1393
|
static get PERSISTENT_CACHE() {
|
|
1290
1394
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
|
|
1291
1395
|
}
|
|
1396
|
+
// BlockState names are hardcoded
|
|
1292
1397
|
static async getList() {
|
|
1293
|
-
|
|
1398
|
+
const key = new AssetKey(
|
|
1294
1399
|
DEFAULT_NAMESPACE,
|
|
1295
1400
|
"_list",
|
|
1296
1401
|
"blockstates",
|
|
1297
1402
|
void 0,
|
|
1298
1403
|
"assets",
|
|
1299
1404
|
".json",
|
|
1300
|
-
|
|
1301
|
-
)
|
|
1405
|
+
AssetLoader.ROOT
|
|
1406
|
+
);
|
|
1407
|
+
return Caching.listAssetCache.get(key.serialize(), () => {
|
|
1408
|
+
return AssetLoader.get(key, "list" /* LIST */);
|
|
1409
|
+
}).then((r) => r?.files ?? []);
|
|
1302
1410
|
}
|
|
1303
1411
|
static async getDefaultStates() {
|
|
1304
1412
|
const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
|
|
1305
|
-
return
|
|
1413
|
+
return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
|
|
1414
|
+
return AssetLoader.get(key, "json" /* JSON */);
|
|
1415
|
+
});
|
|
1306
1416
|
}
|
|
1307
1417
|
static async getDefaultState(key) {
|
|
1308
1418
|
const defaultStates = await this.getDefaultStates();
|
|
@@ -1320,7 +1430,7 @@ var BlockStates = class {
|
|
|
1320
1430
|
}
|
|
1321
1431
|
const keyStr = key.serialize();
|
|
1322
1432
|
return Caching.blockStateCache.get(keyStr, (k) => {
|
|
1323
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1433
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1324
1434
|
return AssetLoader.get(key, "blockstate" /* BLOCKSTATE */);
|
|
1325
1435
|
});
|
|
1326
1436
|
}).then((asset) => {
|
|
@@ -1341,17 +1451,11 @@ var BlockStates = class {
|
|
|
1341
1451
|
await this.PERSISTENT_CACHE.clear();
|
|
1342
1452
|
}
|
|
1343
1453
|
};
|
|
1344
|
-
__decorateClass([
|
|
1345
|
-
Memoize2()
|
|
1346
|
-
], BlockStates, "getList", 1);
|
|
1347
|
-
__decorateClass([
|
|
1348
|
-
Memoize2()
|
|
1349
|
-
], BlockStates, "getDefaultStates", 1);
|
|
1350
1454
|
var DefaultBlockStates = class {
|
|
1351
1455
|
};
|
|
1352
1456
|
|
|
1353
1457
|
// src/assets/Assets.ts
|
|
1354
|
-
var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.
|
|
1458
|
+
var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
|
|
1355
1459
|
var DEFAULT_NAMESPACE = "minecraft";
|
|
1356
1460
|
var Assets = class {
|
|
1357
1461
|
/**
|
|
@@ -1363,16 +1467,153 @@ var Assets = class {
|
|
|
1363
1467
|
static async getModel(key) {
|
|
1364
1468
|
return Models.getMerged(key);
|
|
1365
1469
|
}
|
|
1366
|
-
static async getBlockState(key) {
|
|
1367
|
-
return BlockStates.get(key);
|
|
1470
|
+
static async getBlockState(key) {
|
|
1471
|
+
return BlockStates.get(key);
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
// src/assets/source/AssetSource.ts
|
|
1476
|
+
var AssetSource = class {
|
|
1477
|
+
constructor() {
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Identifies this source's content across sessions for persistent caching. Sources that
|
|
1481
|
+
* cannot tell whether their content changed (an unnamed archive, for example) return
|
|
1482
|
+
* undefined, which keeps their results out of long-lived caches.
|
|
1483
|
+
*/
|
|
1484
|
+
get cacheId() {
|
|
1485
|
+
return void 0;
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
var AssetLoadError = class extends Error {
|
|
1489
|
+
constructor(source, key, path, cause) {
|
|
1490
|
+
super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
|
|
1491
|
+
this.source = source;
|
|
1492
|
+
this.key = key;
|
|
1493
|
+
this.path = path;
|
|
1494
|
+
this.cause = cause;
|
|
1495
|
+
this.name = "AssetLoadError";
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
// src/util/BatchedExecutor.ts
|
|
1500
|
+
var BatchedExecutor = class {
|
|
1501
|
+
constructor(interval = 1, batch = 30) {
|
|
1502
|
+
this.interval = interval;
|
|
1503
|
+
this.batch = batch;
|
|
1504
|
+
this.queue = [];
|
|
1505
|
+
this.task = setInterval(() => this.run());
|
|
1506
|
+
}
|
|
1507
|
+
submit(task) {
|
|
1508
|
+
this.queue.push(task);
|
|
1509
|
+
}
|
|
1510
|
+
run() {
|
|
1511
|
+
for (let i = 0; i < this.batch; i++) {
|
|
1512
|
+
this.runNext();
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
runNext() {
|
|
1516
|
+
let next = this.queue.shift();
|
|
1517
|
+
if (next) next();
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1521
|
+
// src/util/model.ts
|
|
1522
|
+
import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector33 } from "three";
|
|
1523
|
+
function applyElementRotation(rotation, geometry) {
|
|
1524
|
+
const origin = new Vector33(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
|
|
1525
|
+
geometry.translate(-origin.x, -origin.y, -origin.z);
|
|
1526
|
+
switch (rotation.axis) {
|
|
1527
|
+
case "x" /* X */:
|
|
1528
|
+
geometry.rotateX(toRadians(rotation.angle));
|
|
1529
|
+
break;
|
|
1530
|
+
case "y" /* Y */:
|
|
1531
|
+
geometry.rotateY(toRadians(rotation.angle));
|
|
1532
|
+
break;
|
|
1533
|
+
case "z" /* Z */:
|
|
1534
|
+
geometry.rotateZ(toRadians(rotation.angle));
|
|
1535
|
+
break;
|
|
1536
|
+
}
|
|
1537
|
+
if (rotation.rescale) {
|
|
1538
|
+
if (Math.abs(rotation.angle) === 22.5) {
|
|
1539
|
+
const s = 1 / Math.cos(0.39269909262657166);
|
|
1540
|
+
geometry.scale(s, 1, s);
|
|
1541
|
+
} else {
|
|
1542
|
+
const s = 1 / Math.cos(0.7853981852531433);
|
|
1543
|
+
geometry.scale(s, 1, s);
|
|
1544
|
+
}
|
|
1368
1545
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1546
|
+
geometry.translate(origin.x, origin.y, origin.z);
|
|
1547
|
+
}
|
|
1548
|
+
function applyGenericRotation(axis, rotation, obj) {
|
|
1549
|
+
switch (axis) {
|
|
1550
|
+
case "x" /* X */:
|
|
1551
|
+
obj.rotateOnAxis(new Vector33(1, 0, 0), toRadians(rotation));
|
|
1552
|
+
break;
|
|
1553
|
+
case "y" /* Y */:
|
|
1554
|
+
obj.rotateOnAxis(new Vector33(0, 1, 0), toRadians(rotation));
|
|
1555
|
+
break;
|
|
1556
|
+
case "z" /* Z */:
|
|
1557
|
+
obj.rotateOnAxis(new Vector33(0, 0, 1), toRadians(rotation));
|
|
1558
|
+
break;
|
|
1374
1559
|
}
|
|
1375
|
-
}
|
|
1560
|
+
}
|
|
1561
|
+
function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
|
|
1562
|
+
let size = new Vector33();
|
|
1563
|
+
box.getSize(size);
|
|
1564
|
+
let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
|
|
1565
|
+
let wireGeo = new EdgesGeometry(boxGeo);
|
|
1566
|
+
let wireMat = new LineBasicMaterial({ color, linewidth: w });
|
|
1567
|
+
let wireframe = new LineSegments(wireGeo, wireMat);
|
|
1568
|
+
obj.add(wireframe);
|
|
1569
|
+
let axes = new AxesHelper(1);
|
|
1570
|
+
obj.add(axes);
|
|
1571
|
+
}
|
|
1572
|
+
function addWireframeToObject(obj, color = 16777215, w = 2) {
|
|
1573
|
+
let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
|
|
1574
|
+
let wireGeo = new EdgesGeometry(boxGeo);
|
|
1575
|
+
let wireMat = new LineBasicMaterial({ color, linewidth: w });
|
|
1576
|
+
let wireframe = new LineSegments(wireGeo, wireMat);
|
|
1577
|
+
obj.add(wireframe);
|
|
1578
|
+
let axes = new AxesHelper(1);
|
|
1579
|
+
obj.add(axes);
|
|
1580
|
+
}
|
|
1581
|
+
function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
|
|
1582
|
+
let wireGeo = new EdgesGeometry(geo);
|
|
1583
|
+
let wireMat = new LineBasicMaterial({ color, linewidth: w });
|
|
1584
|
+
let wireframe = new LineSegments(wireGeo, wireMat);
|
|
1585
|
+
mesh.add(wireframe);
|
|
1586
|
+
let axes = new AxesHelper(1);
|
|
1587
|
+
mesh.add(axes);
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
// src/util/performance.ts
|
|
1591
|
+
function captureException(e, ...extra) {
|
|
1592
|
+
console.error(e, extra);
|
|
1593
|
+
}
|
|
1594
|
+
function timingStart(marker) {
|
|
1595
|
+
console.time(marker);
|
|
1596
|
+
}
|
|
1597
|
+
function timingEnd(marker) {
|
|
1598
|
+
console.timeEnd(marker);
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
// src/util/three.ts
|
|
1602
|
+
function isObject3D(obj) {
|
|
1603
|
+
return obj.isObject3D;
|
|
1604
|
+
}
|
|
1605
|
+
function isMesh(obj) {
|
|
1606
|
+
return obj.isMesh;
|
|
1607
|
+
}
|
|
1608
|
+
function isInstancedMesh(obj) {
|
|
1609
|
+
return obj.isInstancedMesh;
|
|
1610
|
+
}
|
|
1611
|
+
function isPerspectiveCamera(obj) {
|
|
1612
|
+
return obj.isPerspectiveCamera;
|
|
1613
|
+
}
|
|
1614
|
+
function isOrthographicCamera(obj) {
|
|
1615
|
+
return obj.isOrthographicCamera;
|
|
1616
|
+
}
|
|
1376
1617
|
|
|
1377
1618
|
// src/nbt/NBTHelper.ts
|
|
1378
1619
|
var NBTHelper = class {
|
|
@@ -1402,17 +1643,17 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1402
1643
|
if (typeof namespaced !== "undefined") {
|
|
1403
1644
|
return namespaced;
|
|
1404
1645
|
}
|
|
1405
|
-
if (typeof key.root !== "undefined" && key.root !==
|
|
1646
|
+
if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
1406
1647
|
console.info(p3, "Retrying", key, "with default root+namespace");
|
|
1407
|
-
const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension,
|
|
1648
|
+
const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
1408
1649
|
const namespacedRooted = await this.load(namespacedRootedKey, parser);
|
|
1409
1650
|
if (typeof namespacedRooted !== "undefined") {
|
|
1410
1651
|
return namespacedRooted;
|
|
1411
1652
|
}
|
|
1412
1653
|
}
|
|
1413
|
-
} else if (typeof key.root !== "undefined" && key.root !==
|
|
1654
|
+
} else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
1414
1655
|
console.info(p3, "Retrying", key, "with default root");
|
|
1415
|
-
const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension,
|
|
1656
|
+
const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
1416
1657
|
const rooted = await this.load(rootKey, parser);
|
|
1417
1658
|
if (typeof rooted !== "undefined") {
|
|
1418
1659
|
return rooted;
|
|
@@ -1424,31 +1665,25 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1424
1665
|
console.info(p3, "Loading", key);
|
|
1425
1666
|
const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1426
1667
|
console.debug(p3, url);
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
} catch (e) {
|
|
1436
|
-
console.warn("Parser failed to process response", response, e);
|
|
1437
|
-
throw e;
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
return void 0;
|
|
1441
|
-
}).catch((err) => {
|
|
1442
|
-
if (err.response) {
|
|
1443
|
-
let response = err.response;
|
|
1444
|
-
if (response.status === 404) {
|
|
1445
|
-
console.debug(p3, key, "not found");
|
|
1668
|
+
const request = { url };
|
|
1669
|
+
try {
|
|
1670
|
+
parser.config(request);
|
|
1671
|
+
let response;
|
|
1672
|
+
try {
|
|
1673
|
+
response = await Requests.mcAssetRequest(request);
|
|
1674
|
+
} catch (cause) {
|
|
1675
|
+
if (cause instanceof RequestError && cause.response?.status === 404) {
|
|
1446
1676
|
return void 0;
|
|
1447
1677
|
}
|
|
1678
|
+
throw cause;
|
|
1448
1679
|
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1680
|
+
if (response.data === void 0) {
|
|
1681
|
+
throw new Error("Asset response has no data");
|
|
1682
|
+
}
|
|
1683
|
+
return await parser.parse(response);
|
|
1684
|
+
} catch (cause) {
|
|
1685
|
+
throw new AssetLoadError(this, key, request.url, cause);
|
|
1686
|
+
}
|
|
1452
1687
|
}
|
|
1453
1688
|
assetBasePath(key) {
|
|
1454
1689
|
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 + "/" : ""}`;
|
|
@@ -1461,6 +1696,9 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1461
1696
|
get root() {
|
|
1462
1697
|
return this._root;
|
|
1463
1698
|
}
|
|
1699
|
+
get cacheId() {
|
|
1700
|
+
return `hosted:${this._root}`;
|
|
1701
|
+
}
|
|
1464
1702
|
get options() {
|
|
1465
1703
|
return this._options;
|
|
1466
1704
|
}
|
|
@@ -1537,9 +1775,10 @@ var HostedAssetSource = _HostedAssetSource;
|
|
|
1537
1775
|
// src/assets/source/archive/BrowserArchiveProxy.ts
|
|
1538
1776
|
import { BlobReader, BlobWriter, ZipReader } from "@zip.js/zip.js";
|
|
1539
1777
|
var BrowserArchiveProxy = class {
|
|
1540
|
-
constructor(blob) {
|
|
1778
|
+
constructor(blob, id) {
|
|
1541
1779
|
this._blob = blob;
|
|
1542
1780
|
this._reader = new ZipReader(new BlobReader(this._blob));
|
|
1781
|
+
this.id = id ?? (typeof File !== "undefined" && blob instanceof File ? `${blob.name}:${blob.size}:${blob.lastModified}` : void 0);
|
|
1543
1782
|
}
|
|
1544
1783
|
async getEntries() {
|
|
1545
1784
|
return (await this._reader.getEntries()).map((e) => {
|
|
@@ -1555,7 +1794,6 @@ var BrowserArchiveProxy = class {
|
|
|
1555
1794
|
};
|
|
1556
1795
|
|
|
1557
1796
|
// src/assets/source/archive/ArchiveAssetSource.ts
|
|
1558
|
-
var p4 = prefix("ArchiveAssetSource");
|
|
1559
1797
|
var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
1560
1798
|
constructor(archiveProxy) {
|
|
1561
1799
|
super();
|
|
@@ -1565,6 +1803,10 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1565
1803
|
static blob(blob) {
|
|
1566
1804
|
return new _ArchiveAssetSource(new BrowserArchiveProxy(blob));
|
|
1567
1805
|
}
|
|
1806
|
+
get cacheId() {
|
|
1807
|
+
const id = this._archiveProxy.id;
|
|
1808
|
+
return id === void 0 ? void 0 : `archive:${id}`;
|
|
1809
|
+
}
|
|
1568
1810
|
async getEntries() {
|
|
1569
1811
|
return this._archiveProxy.getEntries();
|
|
1570
1812
|
}
|
|
@@ -1574,74 +1816,31 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1574
1816
|
}
|
|
1575
1817
|
async get(key, parser) {
|
|
1576
1818
|
const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
|
|
1577
|
-
|
|
1578
|
-
let entries = await this.getEntries();
|
|
1579
|
-
const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1580
|
-
console.log(path);
|
|
1581
|
-
const entry = await this.getEntry(path);
|
|
1582
|
-
console.log(entry);
|
|
1583
|
-
if (!entry) {
|
|
1584
|
-
return void 0;
|
|
1585
|
-
}
|
|
1586
|
-
let blob = await entry.getData();
|
|
1587
|
-
const url = URL.createObjectURL(blob);
|
|
1588
|
-
console.log(url);
|
|
1589
|
-
let req = {
|
|
1590
|
-
url
|
|
1591
|
-
};
|
|
1592
|
-
responseParser.config(req);
|
|
1593
|
-
return Requests.genericRequest(req).then((response) => {
|
|
1594
|
-
if (response && response.data) {
|
|
1595
|
-
try {
|
|
1596
|
-
return responseParser.parse(response);
|
|
1597
|
-
} catch (e) {
|
|
1598
|
-
console.warn("Parser failed to process response", response, e);
|
|
1599
|
-
throw e;
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
return void 0;
|
|
1603
|
-
}).catch((err) => {
|
|
1604
|
-
if (err.response) {
|
|
1605
|
-
let response = err.response;
|
|
1606
|
-
if (response.status === 404) {
|
|
1607
|
-
console.debug(p4, key, "not found");
|
|
1608
|
-
return void 0;
|
|
1609
|
-
}
|
|
1610
|
-
}
|
|
1611
|
-
console.debug(p4, "Failed to load", key, err?.message);
|
|
1612
|
-
return void 0;
|
|
1613
|
-
});
|
|
1819
|
+
return this.load(key, responseParser);
|
|
1614
1820
|
}
|
|
1615
|
-
//TODO: abstract this
|
|
1616
1821
|
async load(key, parser) {
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
parser.config(req);
|
|
1624
|
-
return await Requests.genericRequest(req).then((response) => {
|
|
1625
|
-
if (response && response.data) {
|
|
1626
|
-
try {
|
|
1627
|
-
return parser.parse(response);
|
|
1628
|
-
} catch (e) {
|
|
1629
|
-
console.warn("Parser failed to process response", response, e);
|
|
1630
|
-
throw e;
|
|
1631
|
-
}
|
|
1822
|
+
const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1823
|
+
let url;
|
|
1824
|
+
try {
|
|
1825
|
+
const entry = await this.getEntry(path);
|
|
1826
|
+
if (!entry) {
|
|
1827
|
+
return void 0;
|
|
1632
1828
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
return void 0;
|
|
1640
|
-
}
|
|
1829
|
+
url = URL.createObjectURL(await entry.getData());
|
|
1830
|
+
const request = { url };
|
|
1831
|
+
parser.config(request);
|
|
1832
|
+
const response = await Requests.genericRequest(request);
|
|
1833
|
+
if (response.data === void 0) {
|
|
1834
|
+
throw new Error("Asset response has no data");
|
|
1641
1835
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1836
|
+
return await parser.parse(response);
|
|
1837
|
+
} catch (cause) {
|
|
1838
|
+
throw new AssetLoadError(this, key, path, cause);
|
|
1839
|
+
} finally {
|
|
1840
|
+
if (url !== void 0) {
|
|
1841
|
+
URL.revokeObjectURL(url);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1645
1844
|
}
|
|
1646
1845
|
assetBasePath(key) {
|
|
1647
1846
|
return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
|
|
@@ -1649,18 +1848,54 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1649
1848
|
};
|
|
1650
1849
|
|
|
1651
1850
|
// src/assets/AssetLoader.ts
|
|
1652
|
-
var
|
|
1653
|
-
var
|
|
1851
|
+
var p4 = prefix("AssetLoader");
|
|
1852
|
+
var FALLBACK_ROOT = "https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master";
|
|
1654
1853
|
var _AssetLoader = class _AssetLoader {
|
|
1854
|
+
static get version() {
|
|
1855
|
+
return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
|
|
1856
|
+
}
|
|
1857
|
+
static setVersion(version) {
|
|
1858
|
+
this.ROOT = `https://assets.mcasset.cloud/${version}`;
|
|
1859
|
+
const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });
|
|
1860
|
+
const index = this._SOURCES.findIndex((s) => s.key === "mcassets");
|
|
1861
|
+
if (index !== -1) {
|
|
1862
|
+
this._SOURCES[index] = { key: "mcassets", source };
|
|
1863
|
+
} else {
|
|
1864
|
+
this.addSource("mcassets", source);
|
|
1865
|
+
}
|
|
1866
|
+
Caching.clear();
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Scope for persistent cache keys. Empty with only the default vanilla sources, so their
|
|
1870
|
+
* entries stay valid across sessions; otherwise it names every added source (resource packs,
|
|
1871
|
+
* mirrors) so their results never masquerade as vanilla assets after a reload.
|
|
1872
|
+
*/
|
|
1873
|
+
static get persistentScope() {
|
|
1874
|
+
const parts = [];
|
|
1875
|
+
for (const { key, source } of this._SOURCES) {
|
|
1876
|
+
const id = source.cacheId;
|
|
1877
|
+
if (key === "mcassets" && id === `hosted:${this.ROOT}`) continue;
|
|
1878
|
+
if (key === "mcassets-fallback" && id === `hosted:${FALLBACK_ROOT}`) continue;
|
|
1879
|
+
if (id === void 0) return this.SESSION_SCOPE;
|
|
1880
|
+
parts.push(`${key}=${id}`);
|
|
1881
|
+
}
|
|
1882
|
+
return parts.join("|");
|
|
1883
|
+
}
|
|
1884
|
+
/** Prefixes a persistent cache key with the current source scope. */
|
|
1885
|
+
static persistentKey(key) {
|
|
1886
|
+
const scope = this.persistentScope;
|
|
1887
|
+
return scope ? `${scope}
|
|
1888
|
+
${key}` : key;
|
|
1889
|
+
}
|
|
1655
1890
|
static addSource(key, source, override = true) {
|
|
1656
1891
|
if (override) {
|
|
1657
1892
|
const existing = this.removeSource(key);
|
|
1658
1893
|
if (existing) {
|
|
1659
|
-
console.log(
|
|
1894
|
+
console.log(p4, "Removed existing AssetSource", key);
|
|
1660
1895
|
}
|
|
1661
1896
|
}
|
|
1662
1897
|
this._SOURCES.unshift({ key, source });
|
|
1663
|
-
console.log(
|
|
1898
|
+
console.log(p4, "Added AssetSource", key);
|
|
1664
1899
|
}
|
|
1665
1900
|
static removeSource(key) {
|
|
1666
1901
|
const index = this._SOURCES.findIndex((s) => s.key === key);
|
|
@@ -1673,7 +1908,6 @@ var _AssetLoader = class _AssetLoader {
|
|
|
1673
1908
|
return void 0;
|
|
1674
1909
|
}
|
|
1675
1910
|
static async getAll(key, parser) {
|
|
1676
|
-
console.log(this._SOURCES);
|
|
1677
1911
|
let promises = [];
|
|
1678
1912
|
for (const source of this._SOURCES) {
|
|
1679
1913
|
promises.push(source.source.get(key, parser));
|
|
@@ -1682,30 +1916,42 @@ var _AssetLoader = class _AssetLoader {
|
|
|
1682
1916
|
return results.filter((r) => r != void 0);
|
|
1683
1917
|
});
|
|
1684
1918
|
}
|
|
1919
|
+
/** Returns the first defined result in source-priority order, without merging assets. */
|
|
1685
1920
|
static async get(key, parser) {
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1921
|
+
const keys = [key];
|
|
1922
|
+
if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
|
|
1923
|
+
keys.push(new AssetKey(
|
|
1924
|
+
key.namespace,
|
|
1925
|
+
key.path,
|
|
1926
|
+
key.assetType === "structure" ? "structures" : "structure",
|
|
1927
|
+
key.type,
|
|
1928
|
+
key.rootType,
|
|
1929
|
+
key.extension,
|
|
1930
|
+
key.root
|
|
1931
|
+
));
|
|
1932
|
+
}
|
|
1933
|
+
return (await this.getFirst(keys, parser))?.asset;
|
|
1934
|
+
}
|
|
1935
|
+
/** Tries each path within a source before considering lower-priority sources. */
|
|
1936
|
+
static async getFirst(keys, parser) {
|
|
1937
|
+
const sources = [...this._SOURCES];
|
|
1938
|
+
for (const source of sources) {
|
|
1939
|
+
for (const key of keys) {
|
|
1940
|
+
const result = await source.source.get(key, parser);
|
|
1941
|
+
if (result !== void 0) {
|
|
1942
|
+
return { key, asset: result };
|
|
1699
1943
|
}
|
|
1700
1944
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1945
|
+
}
|
|
1946
|
+
return void 0;
|
|
1703
1947
|
}
|
|
1704
1948
|
};
|
|
1705
1949
|
_AssetLoader.ROOT = DEFAULT_ROOT;
|
|
1706
1950
|
_AssetLoader._SOURCES = [];
|
|
1707
|
-
|
|
1708
|
-
_AssetLoader.
|
|
1951
|
+
/** Used when a registered source cannot identify its content, so nothing persists past this session. */
|
|
1952
|
+
_AssetLoader.SESSION_SCOPE = `session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1953
|
+
_AssetLoader.addSource("mcassets-fallback", new HostedAssetSource(FALLBACK_ROOT, { retryDefaults: false }));
|
|
1954
|
+
_AssetLoader.addSource("mcassets", new HostedAssetSource(_AssetLoader.ROOT, { retryDefaults: false }));
|
|
1709
1955
|
var AssetLoader = _AssetLoader;
|
|
1710
1956
|
|
|
1711
1957
|
// src/assets/ModelTextures.ts
|
|
@@ -1714,11 +1960,21 @@ var ModelTextures = class {
|
|
|
1714
1960
|
return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
|
|
1715
1961
|
}
|
|
1716
1962
|
static async get(key) {
|
|
1717
|
-
const
|
|
1718
|
-
|
|
1719
|
-
|
|
1963
|
+
const keyStr = key.serialize();
|
|
1964
|
+
const pending = this.preload(key);
|
|
1965
|
+
const cached = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
1966
|
+
try {
|
|
1967
|
+
const asset = await pending;
|
|
1968
|
+
if (asset) {
|
|
1969
|
+
return await ImageLoader.infoToCanvasData(asset);
|
|
1970
|
+
}
|
|
1971
|
+
return void 0;
|
|
1972
|
+
} catch (err) {
|
|
1973
|
+
if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
|
|
1974
|
+
Caching.textureAssetCache.invalidate(keyStr);
|
|
1975
|
+
}
|
|
1976
|
+
throw err;
|
|
1720
1977
|
}
|
|
1721
|
-
return void 0;
|
|
1722
1978
|
}
|
|
1723
1979
|
static async preload(key) {
|
|
1724
1980
|
const keyStr = key.serialize();
|
|
@@ -1737,7 +1993,7 @@ var ModelTextures = class {
|
|
|
1737
1993
|
}
|
|
1738
1994
|
const keyStr = key.serialize();
|
|
1739
1995
|
return Caching.textureMetaCache.get(keyStr, (k) => {
|
|
1740
|
-
return this.PERSISTENT_META_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1996
|
+
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1741
1997
|
return AssetLoader.get(key, "meta" /* META */).then((asset) => {
|
|
1742
1998
|
if (asset)
|
|
1743
1999
|
asset.key = key;
|
|
@@ -1888,17 +2144,20 @@ var TextureAtlas = class {
|
|
|
1888
2144
|
// src/model/ModelGenerator.ts
|
|
1889
2145
|
var ModelGenerator = class {
|
|
1890
2146
|
static generateItemModel(imageData, layer) {
|
|
2147
|
+
const tintindex = this.ITEM_LAYERS.indexOf(layer);
|
|
1891
2148
|
const mainElement = {
|
|
1892
2149
|
from: [0, 0, 7.5],
|
|
1893
2150
|
to: [16, 16, 8.5],
|
|
1894
2151
|
faces: {
|
|
1895
2152
|
"south": {
|
|
1896
2153
|
uv: [0, 0, 16, 16],
|
|
1897
|
-
texture: `#${layer}
|
|
2154
|
+
texture: `#${layer}`,
|
|
2155
|
+
tintindex
|
|
1898
2156
|
},
|
|
1899
2157
|
"north": {
|
|
1900
2158
|
uv: [16, 0, 0, 16],
|
|
1901
|
-
texture: `#${layer}
|
|
2159
|
+
texture: `#${layer}`,
|
|
2160
|
+
tintindex
|
|
1902
2161
|
}
|
|
1903
2162
|
},
|
|
1904
2163
|
shade: true
|
|
@@ -1909,11 +2168,19 @@ var ModelGenerator = class {
|
|
|
1909
2168
|
ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
|
|
1910
2169
|
|
|
1911
2170
|
// src/UVMapper.ts
|
|
1912
|
-
var
|
|
2171
|
+
var p5 = prefix("UVMapper");
|
|
1913
2172
|
var DEFAULT_UV = [0, 0, 16, 16];
|
|
1914
2173
|
var X = 0;
|
|
1915
2174
|
var Y = 1;
|
|
1916
2175
|
var Z = 2;
|
|
2176
|
+
var FACE_UV_AXES = {
|
|
2177
|
+
east: [new Vector34(0, 0, -1), new Vector34(0, -1, 0)],
|
|
2178
|
+
west: [new Vector34(0, 0, 1), new Vector34(0, -1, 0)],
|
|
2179
|
+
up: [new Vector34(1, 0, 0), new Vector34(0, 0, 1)],
|
|
2180
|
+
down: [new Vector34(1, 0, 0), new Vector34(0, 0, -1)],
|
|
2181
|
+
south: [new Vector34(1, 0, 0), new Vector34(0, -1, 0)],
|
|
2182
|
+
north: [new Vector34(-1, 0, 0), new Vector34(0, -1, 0)]
|
|
2183
|
+
};
|
|
1917
2184
|
var UVMapper = class {
|
|
1918
2185
|
static makeUv(uvCoord, originalTextureSize, actualTextureSize) {
|
|
1919
2186
|
if (uvCoord === 0) return 0;
|
|
@@ -2011,6 +2278,42 @@ var UVMapper = class {
|
|
|
2011
2278
|
static facesToUv(faces, originalTextureSize, actualTextureSize) {
|
|
2012
2279
|
return new Float32BufferAttribute2(this.facesToUvArray(faces, originalTextureSize, actualTextureSize), 2);
|
|
2013
2280
|
}
|
|
2281
|
+
static lockUvs(geometry, faces, atlas, rotation) {
|
|
2282
|
+
const uv = geometry.getAttribute("uv");
|
|
2283
|
+
for (let faceIndex = 0; faceIndex < CUBE_FACES.length; faceIndex++) {
|
|
2284
|
+
const faceName = CUBE_FACES[faceIndex];
|
|
2285
|
+
const texture = faces[faceName]?.texture?.substring(1);
|
|
2286
|
+
const position = texture && atlas.positions[texture];
|
|
2287
|
+
const size = texture && atlas.sizes[texture];
|
|
2288
|
+
if (!position || !size) continue;
|
|
2289
|
+
const [sourceU, sourceV] = FACE_UV_AXES[faceName];
|
|
2290
|
+
const uAxis = sourceU.clone().applyEuler(rotation);
|
|
2291
|
+
const vAxis = sourceV.clone().applyEuler(rotation);
|
|
2292
|
+
const normal = vAxis.clone().cross(uAxis);
|
|
2293
|
+
const targetFace = CUBE_FACES.find((name) => {
|
|
2294
|
+
const [u, v] = FACE_UV_AXES[name];
|
|
2295
|
+
return v.clone().cross(u).dot(normal) > 0.5;
|
|
2296
|
+
});
|
|
2297
|
+
const [targetU, targetV] = FACE_UV_AXES[targetFace];
|
|
2298
|
+
const uu = Math.round(targetU.dot(uAxis));
|
|
2299
|
+
const uvCross = Math.round(targetU.dot(vAxis));
|
|
2300
|
+
const vu = Math.round(targetV.dot(uAxis));
|
|
2301
|
+
const vv = Math.round(targetV.dot(vAxis));
|
|
2302
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
2303
|
+
const index = faceIndex * 4 + corner;
|
|
2304
|
+
const u = (uv.getX(index) * atlas.image.width - position[0]) / size[0] - 0.5;
|
|
2305
|
+
const v = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] - 0.5;
|
|
2306
|
+
const lockedU = uu * u + uvCross * v + 0.5;
|
|
2307
|
+
const lockedV = vu * u + vv * v + 0.5;
|
|
2308
|
+
uv.setXY(
|
|
2309
|
+
index,
|
|
2310
|
+
(position[0] + lockedU * size[0]) / atlas.image.width,
|
|
2311
|
+
1 - (position[1] + lockedV * size[1]) / atlas.image.height
|
|
2312
|
+
);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
uv.needsUpdate = true;
|
|
2316
|
+
}
|
|
2014
2317
|
static async getAtlas(model) {
|
|
2015
2318
|
const keyStr = model.key.serialize();
|
|
2016
2319
|
return Caching.modelTextureAtlasCache.get(keyStr, (k) => {
|
|
@@ -2086,7 +2389,7 @@ var UVMapper = class {
|
|
|
2086
2389
|
const metaMap = {};
|
|
2087
2390
|
const model = { ...originalModel };
|
|
2088
2391
|
const isItemModel = !("elements" in model);
|
|
2089
|
-
console.debug(
|
|
2392
|
+
console.debug(p5, "Creating Atlas for", model.key);
|
|
2090
2393
|
if (model.textures) {
|
|
2091
2394
|
const promises = [];
|
|
2092
2395
|
const uniqueTextureNames = [];
|
|
@@ -2100,7 +2403,7 @@ var UVMapper = class {
|
|
|
2100
2403
|
const assetKey = AssetKey.parse("textures", textureValue, model.key);
|
|
2101
2404
|
promises.push(ModelTextures.get(assetKey).then((asset) => {
|
|
2102
2405
|
if (!asset) {
|
|
2103
|
-
console.warn(
|
|
2406
|
+
console.warn(p5, "Missing texture", assetKey);
|
|
2104
2407
|
return;
|
|
2105
2408
|
}
|
|
2106
2409
|
textureMap[textureKey] = new WrappedImage(asset);
|
|
@@ -2112,7 +2415,7 @@ var UVMapper = class {
|
|
|
2112
2415
|
}
|
|
2113
2416
|
await Promise.all(promises);
|
|
2114
2417
|
const textureCount = uniqueTextureNames.length;
|
|
2115
|
-
console.debug(
|
|
2418
|
+
console.debug(p5, "Creating Atlas for", textureCount, "textures");
|
|
2116
2419
|
this.fillMissingTextureKeys(model.textures, textureMap);
|
|
2117
2420
|
this.fillMissingTextureKeys(model.textures, metaMap);
|
|
2118
2421
|
const sizes = {};
|
|
@@ -2132,7 +2435,7 @@ var UVMapper = class {
|
|
|
2132
2435
|
this.fillMissingTextureKeys(model.textures, sizes);
|
|
2133
2436
|
const s = Math.ceil(Math.sqrt(textureCount + 1));
|
|
2134
2437
|
const size = Math.ceil(s * maxWidth);
|
|
2135
|
-
console.debug(
|
|
2438
|
+
console.debug(p5, "Atlas size:", size);
|
|
2136
2439
|
const squaredSize = size * size;
|
|
2137
2440
|
const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
|
|
2138
2441
|
const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
|
|
@@ -2187,10 +2490,10 @@ var UVMapper = class {
|
|
|
2187
2490
|
}
|
|
2188
2491
|
}
|
|
2189
2492
|
const atlasImageData = image.toDataURL();
|
|
2190
|
-
console.log(
|
|
2493
|
+
console.log(p5, "Atlas Image for", model.key, atlasImageData);
|
|
2191
2494
|
this.fillMissingTextureKeys(model.textures, positions);
|
|
2192
2495
|
if (isItemModel) {
|
|
2193
|
-
console.debug(
|
|
2496
|
+
console.debug(p5, "Generating item model for", model);
|
|
2194
2497
|
model.elements = [];
|
|
2195
2498
|
for (let layerName of ModelGenerator.ITEM_LAYERS) {
|
|
2196
2499
|
const textureImage = textureMap[layerName];
|
|
@@ -2198,7 +2501,7 @@ var UVMapper = class {
|
|
|
2198
2501
|
model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
|
|
2199
2502
|
}
|
|
2200
2503
|
}
|
|
2201
|
-
console.debug(
|
|
2504
|
+
console.debug(p5, "Item model elements", model.elements);
|
|
2202
2505
|
}
|
|
2203
2506
|
if (!model.elements) {
|
|
2204
2507
|
}
|
|
@@ -2216,17 +2519,13 @@ var UVMapper = class {
|
|
|
2216
2519
|
this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
|
|
2217
2520
|
continue;
|
|
2218
2521
|
}
|
|
2522
|
+
if (!face.texture) continue;
|
|
2219
2523
|
if (!face.uv) {
|
|
2220
2524
|
face.uv = this.getFallbackUv(element, faceName);
|
|
2221
2525
|
}
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
if (faceTexture) {
|
|
2226
|
-
faceTexture = faceTexture.substr(1);
|
|
2227
|
-
texPosition = positions[faceTexture] || [0, 0];
|
|
2228
|
-
texSize = sizes[faceTexture] || [16, 16];
|
|
2229
|
-
}
|
|
2526
|
+
const faceTexture = face.texture.substr(1);
|
|
2527
|
+
const texPosition = positions[faceTexture] || [0, 0];
|
|
2528
|
+
const texSize = sizes[faceTexture] || [16, 16];
|
|
2230
2529
|
let texPosV = new Vector2(texPosition[0], texPosition[1]);
|
|
2231
2530
|
const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
|
|
2232
2531
|
tl.add(texPosV);
|
|
@@ -2258,7 +2557,7 @@ var UVMapper = class {
|
|
|
2258
2557
|
hasTransparency
|
|
2259
2558
|
);
|
|
2260
2559
|
} else {
|
|
2261
|
-
console.warn(
|
|
2560
|
+
console.warn(p5, "Model does not have any textures", model);
|
|
2262
2561
|
}
|
|
2263
2562
|
return void 0;
|
|
2264
2563
|
}
|
|
@@ -2300,18 +2599,18 @@ var MinecraftCubeTexture = class {
|
|
|
2300
2599
|
}
|
|
2301
2600
|
getUvEast(w, h, l) {
|
|
2302
2601
|
return [
|
|
2303
|
-
[this.mapW(this.u), this.mapH(this.v + l + h)],
|
|
2304
|
-
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2305
|
-
[this.mapW(this.u), this.mapH(this.v + l)],
|
|
2306
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)]
|
|
2602
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2603
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
|
|
2604
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
|
|
2605
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2307
2606
|
];
|
|
2308
2607
|
}
|
|
2309
2608
|
getUvWest(w, h, l) {
|
|
2310
2609
|
return [
|
|
2311
|
-
[this.mapW(this.u + l
|
|
2312
|
-
[this.mapW(this.u
|
|
2313
|
-
[this.mapW(this.u + l
|
|
2314
|
-
[this.mapW(this.u
|
|
2610
|
+
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2611
|
+
[this.mapW(this.u), this.mapH(this.v + l + h)],
|
|
2612
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2613
|
+
[this.mapW(this.u), this.mapH(this.v + l)]
|
|
2315
2614
|
];
|
|
2316
2615
|
}
|
|
2317
2616
|
getUvUp(w, h, l) {
|
|
@@ -2324,26 +2623,26 @@ var MinecraftCubeTexture = class {
|
|
|
2324
2623
|
}
|
|
2325
2624
|
getUvDown(w, h, l) {
|
|
2326
2625
|
return [
|
|
2327
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2328
|
-
[this.mapW(this.u + l + w), this.mapH(this.v + l)],
|
|
2329
2626
|
[this.mapW(this.u + l), this.mapH(this.v)],
|
|
2330
|
-
[this.mapW(this.u + l + w), this.mapH(this.v)]
|
|
2627
|
+
[this.mapW(this.u + l + w), this.mapH(this.v)],
|
|
2628
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2629
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2331
2630
|
];
|
|
2332
2631
|
}
|
|
2333
2632
|
getUvSouth(w, h, l) {
|
|
2334
2633
|
return [
|
|
2335
|
-
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2336
2634
|
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l + h)],
|
|
2337
|
-
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
|
|
2338
|
-
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)]
|
|
2635
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2636
|
+
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
|
|
2637
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
|
|
2339
2638
|
];
|
|
2340
2639
|
}
|
|
2341
2640
|
getUvNorth(w, h, l) {
|
|
2342
2641
|
return [
|
|
2343
|
-
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2344
2642
|
[this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
|
|
2345
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2346
|
-
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2643
|
+
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2644
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)],
|
|
2645
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)]
|
|
2347
2646
|
];
|
|
2348
2647
|
}
|
|
2349
2648
|
getFaceUv(face, w, h, l) {
|
|
@@ -2362,10 +2661,12 @@ var MinecraftCubeTexture = class {
|
|
|
2362
2661
|
return this.getUvNorth(w, h, l);
|
|
2363
2662
|
}
|
|
2364
2663
|
}
|
|
2365
|
-
toUvArray(w, h, l) {
|
|
2664
|
+
toUvArray(w, h, l, mirror = false) {
|
|
2366
2665
|
const uv = [];
|
|
2367
2666
|
for (let i = 0; i < CUBE_FACES.length; i++) {
|
|
2368
|
-
|
|
2667
|
+
const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
|
|
2668
|
+
const corners = this.getFaceUv(face, w, h, l);
|
|
2669
|
+
UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
|
|
2369
2670
|
}
|
|
2370
2671
|
return uv;
|
|
2371
2672
|
}
|
|
@@ -2395,76 +2696,85 @@ function shutdown() {
|
|
|
2395
2696
|
Caching.end();
|
|
2396
2697
|
}
|
|
2397
2698
|
|
|
2699
|
+
// src/error/MineRenderError.ts
|
|
2700
|
+
var MineRenderError = class _MineRenderError extends Error {
|
|
2701
|
+
constructor(msg) {
|
|
2702
|
+
super(msg);
|
|
2703
|
+
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
2704
|
+
}
|
|
2705
|
+
get name() {
|
|
2706
|
+
return "MineRenderError";
|
|
2707
|
+
}
|
|
2708
|
+
};
|
|
2709
|
+
|
|
2398
2710
|
// src/assets/Entities.ts
|
|
2399
|
-
import { Memoize as Memoize3 } from "typescript-memoize";
|
|
2400
2711
|
var Entities = class {
|
|
2401
|
-
static async getBlockEntityModels() {
|
|
2402
|
-
const key = AssetKey.parse("models", "minerender:blockEntityModels");
|
|
2403
|
-
console.log(key);
|
|
2404
|
-
return AssetLoader.get(key, "json" /* JSON */);
|
|
2405
|
-
}
|
|
2406
|
-
static async getEntityModels() {
|
|
2407
|
-
const key = AssetKey.parse("models", "minerender:entityModels");
|
|
2408
|
-
console.log(key);
|
|
2409
|
-
return AssetLoader.get(key, "json" /* JSON */);
|
|
2410
|
-
}
|
|
2411
|
-
// BlockEntity names are hardcoded
|
|
2412
|
-
static async getBlockList() {
|
|
2413
|
-
const models = await this.getBlockEntityModels();
|
|
2414
|
-
if (!models) {
|
|
2415
|
-
return [];
|
|
2416
|
-
}
|
|
2417
|
-
return Object.keys(models);
|
|
2418
|
-
}
|
|
2419
2712
|
static async getEntityList() {
|
|
2420
|
-
const
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
if (!models) {
|
|
2429
|
-
return void 0;
|
|
2430
|
-
}
|
|
2431
|
-
if (!textureKey) {
|
|
2432
|
-
textureKey = modelKey;
|
|
2433
|
-
}
|
|
2434
|
-
const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
|
|
2435
|
-
return {
|
|
2436
|
-
key: textureKey,
|
|
2437
|
-
parts: models[baseKey.toNamespacedString()]
|
|
2713
|
+
const collect = async (path) => {
|
|
2714
|
+
const prefix2 = path ? `${path}/` : "";
|
|
2715
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
|
|
2716
|
+
const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
2717
|
+
if (!list) return [];
|
|
2718
|
+
const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
2719
|
+
const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
2720
|
+
return [...files, ...children.flat()];
|
|
2438
2721
|
};
|
|
2722
|
+
return collect("");
|
|
2723
|
+
}
|
|
2724
|
+
static async getEntity(modelKey, textureKey, options) {
|
|
2725
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
2726
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
2727
|
+
const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
2728
|
+
if (!model) return void 0;
|
|
2729
|
+
const layerName = options?.layer ?? "main";
|
|
2730
|
+
const layer = model.layers[layerName];
|
|
2731
|
+
if (!layer) {
|
|
2732
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
2733
|
+
}
|
|
2734
|
+
let texture;
|
|
2735
|
+
if (textureKey) {
|
|
2736
|
+
const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
|
|
2737
|
+
texture = isAssetKey(textureKey) && textureKey.assetType === "textures" && path2.startsWith("entity/") ? textureKey : new AssetKey(textureKey.namespace, path2, "textures", "entity", "assets", ".png", isAssetKey(textureKey) ? textureKey.root : void 0);
|
|
2738
|
+
} else if (layer.textureLocation !== void 0) {
|
|
2739
|
+
texture = AssetKey.parse("textures", layer.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
2740
|
+
} else {
|
|
2741
|
+
texture = await this.resolveTexture(modelKey);
|
|
2742
|
+
}
|
|
2743
|
+
return { key: textureKey ?? modelKey, texture, layer, id: model.id };
|
|
2744
|
+
}
|
|
2745
|
+
static async resolveTexture(modelKey) {
|
|
2746
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
2747
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
2748
|
+
return Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
2749
|
+
const name = path.split("/").pop();
|
|
2750
|
+
for (const candidate of [path, `${path}/${name}`]) {
|
|
2751
|
+
const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
|
|
2752
|
+
if (await ModelTextures.get(texture)) return texture;
|
|
2753
|
+
}
|
|
2754
|
+
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json");
|
|
2755
|
+
const list = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
2756
|
+
const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
2757
|
+
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
2758
|
+
if (!file) return void 0;
|
|
2759
|
+
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json");
|
|
2760
|
+
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
2761
|
+
const assets = variant?.assets;
|
|
2762
|
+
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
2763
|
+
return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
|
|
2764
|
+
});
|
|
2439
2765
|
}
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
}
|
|
2448
|
-
const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
|
|
2449
|
-
return {
|
|
2450
|
-
key: textureKey,
|
|
2451
|
-
parts: models[baseKey.toNamespacedString()]
|
|
2452
|
-
};
|
|
2766
|
+
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
2767
|
+
static getBlockList() {
|
|
2768
|
+
return this.getEntityList();
|
|
2769
|
+
}
|
|
2770
|
+
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
2771
|
+
static getBlock(modelKey, textureKey, options) {
|
|
2772
|
+
return this.getEntity(modelKey, textureKey, options);
|
|
2453
2773
|
}
|
|
2454
|
-
};
|
|
2455
|
-
__decorateClass([
|
|
2456
|
-
Memoize3()
|
|
2457
|
-
], Entities, "getBlockEntityModels", 1);
|
|
2458
|
-
__decorateClass([
|
|
2459
|
-
Memoize3()
|
|
2460
|
-
], Entities, "getEntityModels", 1);
|
|
2461
|
-
var EntityModels = class {
|
|
2462
|
-
};
|
|
2463
|
-
var BlockEntityModels = class {
|
|
2464
2774
|
};
|
|
2465
2775
|
|
|
2466
2776
|
// src/renderer/SceneObject.ts
|
|
2467
|
-
import { Euler, InstancedMesh, MathUtils, Matrix4 as
|
|
2777
|
+
import { Euler as Euler3, InstancedMesh, MathUtils, Matrix4 as Matrix43, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector35 } from "three";
|
|
2468
2778
|
|
|
2469
2779
|
// src/instance/InstanceReference.ts
|
|
2470
2780
|
var InstanceReference = class {
|
|
@@ -2509,20 +2819,9 @@ function isInstanceReference(obj) {
|
|
|
2509
2819
|
return obj.isInstanceReference;
|
|
2510
2820
|
}
|
|
2511
2821
|
|
|
2512
|
-
// src/error/MineRenderError.ts
|
|
2513
|
-
var MineRenderError = class _MineRenderError extends Error {
|
|
2514
|
-
constructor(msg) {
|
|
2515
|
-
super(msg);
|
|
2516
|
-
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
2517
|
-
}
|
|
2518
|
-
get name() {
|
|
2519
|
-
return "MineRenderError";
|
|
2520
|
-
}
|
|
2521
|
-
};
|
|
2522
|
-
|
|
2523
2822
|
// src/renderer/SceneObject.ts
|
|
2524
|
-
var
|
|
2525
|
-
var
|
|
2823
|
+
var import_ts_deepmerge3 = __toESM(require_dist());
|
|
2824
|
+
var p6 = prefix("SceneObject");
|
|
2526
2825
|
var _SceneObject = class _SceneObject extends Object3D2 {
|
|
2527
2826
|
constructor(options) {
|
|
2528
2827
|
super();
|
|
@@ -2530,7 +2829,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2530
2829
|
this.materialCallbacks = {};
|
|
2531
2830
|
this._isInstanced = false;
|
|
2532
2831
|
this._instanceCounter = 0;
|
|
2533
|
-
this.options = (0,
|
|
2832
|
+
this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
2534
2833
|
console.log("SceneObject options", this.options);
|
|
2535
2834
|
}
|
|
2536
2835
|
set scene(scene) {
|
|
@@ -2624,6 +2923,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2624
2923
|
}
|
|
2625
2924
|
createInstancedMesh(name, geometry, material, count) {
|
|
2626
2925
|
const mesh = new InstancedMesh(geometry, material, count);
|
|
2926
|
+
mesh.count = 0;
|
|
2627
2927
|
if (name) {
|
|
2628
2928
|
mesh.name = `mesh:${name}`;
|
|
2629
2929
|
}
|
|
@@ -2644,15 +2944,8 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2644
2944
|
return this.toggleObjectVisibility(this.getMeshByName(name), visible);
|
|
2645
2945
|
}
|
|
2646
2946
|
iterateAllMeshes(cb) {
|
|
2647
|
-
this.
|
|
2648
|
-
if (obj
|
|
2649
|
-
cb(obj);
|
|
2650
|
-
}
|
|
2651
|
-
obj.children.forEach((obj1) => {
|
|
2652
|
-
if (obj1.isMesh) {
|
|
2653
|
-
cb(obj1);
|
|
2654
|
-
}
|
|
2655
|
-
});
|
|
2947
|
+
this.traverse((obj) => {
|
|
2948
|
+
if (isMesh(obj)) cb(obj);
|
|
2656
2949
|
});
|
|
2657
2950
|
}
|
|
2658
2951
|
//</editor-fold>
|
|
@@ -2700,10 +2993,14 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2700
2993
|
nextInstance() {
|
|
2701
2994
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2702
2995
|
const i = this._instanceCounter++;
|
|
2703
|
-
this.setMatrixAt(i, new
|
|
2704
|
-
|
|
2996
|
+
this.setMatrixAt(i, new Matrix43());
|
|
2997
|
+
const mesh = this.children[0];
|
|
2998
|
+
if (mesh && isInstancedMesh(mesh)) {
|
|
2999
|
+
mesh.count = Math.min(this._instanceCounter, mesh.instanceMatrix.count);
|
|
3000
|
+
}
|
|
3001
|
+
console.debug(p6, "nextInstance " + i);
|
|
2705
3002
|
if (i === this.options.maxInstanceCount) {
|
|
2706
|
-
console.warn(
|
|
3003
|
+
console.warn(p6, "Max instance count reached for " + this);
|
|
2707
3004
|
}
|
|
2708
3005
|
if (this.scene) {
|
|
2709
3006
|
this.scene.stats.instanceCount++;
|
|
@@ -2713,7 +3010,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2713
3010
|
}
|
|
2714
3011
|
//</editor-fold>
|
|
2715
3012
|
//<editor-fold desc="TRANSFORMATION">
|
|
2716
|
-
getMatrixAt(index, matrix = new
|
|
3013
|
+
getMatrixAt(index, matrix = new Matrix43()) {
|
|
2717
3014
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2718
3015
|
const child = this.children[0];
|
|
2719
3016
|
if (child && isInstancedMesh(child)) {
|
|
@@ -2732,16 +3029,16 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2732
3029
|
}
|
|
2733
3030
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
2734
3031
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2735
|
-
const oldPosition = new
|
|
2736
|
-
const oldRotation = new
|
|
2737
|
-
const oldScale = new
|
|
2738
|
-
const matrix = new
|
|
3032
|
+
const oldPosition = new Vector35();
|
|
3033
|
+
const oldRotation = new Quaternion3();
|
|
3034
|
+
const oldScale = new Vector35();
|
|
3035
|
+
const matrix = new Matrix43();
|
|
2739
3036
|
if (!scale || !rotation || !position) {
|
|
2740
3037
|
this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
|
|
2741
3038
|
}
|
|
2742
3039
|
matrix.compose(
|
|
2743
3040
|
position ? position : oldPosition,
|
|
2744
|
-
rotation ? new
|
|
3041
|
+
rotation ? new Quaternion3().setFromEuler(rotation) : oldRotation,
|
|
2745
3042
|
scale ? scale : oldScale
|
|
2746
3043
|
);
|
|
2747
3044
|
this.setMatrixAt(index, matrix);
|
|
@@ -2750,7 +3047,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2750
3047
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2751
3048
|
this.setPositionRotationScaleAt(index, position);
|
|
2752
3049
|
}
|
|
2753
|
-
getPositionAt(index, vector = new
|
|
3050
|
+
getPositionAt(index, vector = new Vector35()) {
|
|
2754
3051
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2755
3052
|
const matrix = this.getMatrixAt(index);
|
|
2756
3053
|
vector.setFromMatrixPosition(matrix);
|
|
@@ -2760,7 +3057,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2760
3057
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2761
3058
|
this.setPositionRotationScaleAt(index, void 0, rotation, void 0);
|
|
2762
3059
|
}
|
|
2763
|
-
getRotationAt(index, euler = new
|
|
3060
|
+
getRotationAt(index, euler = new Euler3()) {
|
|
2764
3061
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2765
3062
|
const matrix = this.getMatrixAt(index);
|
|
2766
3063
|
euler.setFromRotationMatrix(matrix);
|
|
@@ -2770,7 +3067,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2770
3067
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2771
3068
|
this.setPositionRotationScaleAt(index, void 0, void 0, scale);
|
|
2772
3069
|
}
|
|
2773
|
-
getScaleAt(index, vector = new
|
|
3070
|
+
getScaleAt(index, vector = new Vector35()) {
|
|
2774
3071
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2775
3072
|
const matrix = this.getMatrixAt(index);
|
|
2776
3073
|
vector.setFromMatrixScale(matrix);
|
|
@@ -2879,7 +3176,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2879
3176
|
}
|
|
2880
3177
|
//</editor-fold>
|
|
2881
3178
|
};
|
|
2882
|
-
_SceneObject.DEFAULT_OPTIONS = (0,
|
|
3179
|
+
_SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
|
|
2883
3180
|
instanceMeshes: true,
|
|
2884
3181
|
maxInstanceCount: 50,
|
|
2885
3182
|
mergeMeshes: true,
|
|
@@ -2891,16 +3188,15 @@ function isSceneObject(obj) {
|
|
|
2891
3188
|
}
|
|
2892
3189
|
|
|
2893
3190
|
// src/entity/scene/EntityObject.ts
|
|
2894
|
-
var
|
|
3191
|
+
var import_ts_deepmerge4 = __toESM(require_dist());
|
|
2895
3192
|
import { Object3D as Object3D3 } from "three";
|
|
2896
|
-
|
|
2897
|
-
var EntityObject = class extends SceneObject {
|
|
3193
|
+
var _EntityObject = class _EntityObject extends SceneObject {
|
|
2898
3194
|
constructor(entity, options) {
|
|
2899
3195
|
super();
|
|
2900
3196
|
this.entity = entity;
|
|
2901
3197
|
this.isEntityObject = true;
|
|
2902
3198
|
this.meshesCreated = false;
|
|
2903
|
-
this.options = (0,
|
|
3199
|
+
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
2904
3200
|
}
|
|
2905
3201
|
async init() {
|
|
2906
3202
|
this.createMeshes();
|
|
@@ -2909,65 +3205,78 @@ var EntityObject = class extends SceneObject {
|
|
|
2909
3205
|
dispose() {
|
|
2910
3206
|
super.dispose();
|
|
2911
3207
|
}
|
|
2912
|
-
|
|
2913
|
-
this.
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
3208
|
+
get textureKey() {
|
|
3209
|
+
if (this.entity.texture) return this.entity.texture;
|
|
3210
|
+
const key = this.entity.key;
|
|
3211
|
+
return new AssetKey(
|
|
3212
|
+
key.namespace,
|
|
3213
|
+
isAssetKey(key) ? key.getFullPath() : key.path,
|
|
2917
3214
|
"textures",
|
|
2918
3215
|
"entity",
|
|
2919
3216
|
"assets",
|
|
2920
3217
|
".png"
|
|
2921
|
-
)
|
|
3218
|
+
);
|
|
3219
|
+
}
|
|
3220
|
+
async loadTextures() {
|
|
3221
|
+
this.imageData = await ModelTextures.get(this.textureKey);
|
|
2922
3222
|
}
|
|
2923
|
-
//TODO: abstract this, since extracted model data can be used for entities, blocks, players
|
|
2924
3223
|
createMeshes(force = false) {
|
|
2925
3224
|
if (this.meshesCreated && !force) return;
|
|
2926
|
-
const
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
const partAnchor = new Object3D3();
|
|
2931
|
-
partAnchor.position.x = part.pivotX;
|
|
2932
|
-
partAnchor.position.y = part.pivotY;
|
|
2933
|
-
partAnchor.position.z = part.pivotZ;
|
|
2934
|
-
for (let cube of part.cubes) {
|
|
2935
|
-
const w = cube.maxX - cube.minX;
|
|
2936
|
-
const h = cube.maxY - cube.minY;
|
|
2937
|
-
const l = cube.maxZ - cube.minZ;
|
|
2938
|
-
const uv = texture.toUvArray(w, h, l);
|
|
2939
|
-
const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
|
|
2940
|
-
cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
|
|
2941
|
-
cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
|
|
2942
|
-
applyModelPartRotation(part, cubeGeo);
|
|
2943
|
-
const mesh = this.createMesh(partName, cubeGeo, mat);
|
|
2944
|
-
partAnchor.add(mesh);
|
|
2945
|
-
if (this.options.wireframe) {
|
|
2946
|
-
addWireframeToMesh(cubeGeo, mesh);
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
this.add(partAnchor);
|
|
2950
|
-
}
|
|
3225
|
+
const modelRoot = new Object3D3();
|
|
3226
|
+
if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
|
|
3227
|
+
this.add(modelRoot);
|
|
3228
|
+
this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
|
|
2951
3229
|
this.meshesCreated = true;
|
|
2952
3230
|
}
|
|
2953
|
-
|
|
2954
|
-
const
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
3231
|
+
createPart(name, part, parent, textureSize, material) {
|
|
3232
|
+
const anchor = this.createGroup(name);
|
|
3233
|
+
anchor.position.fromArray(part.pose.offset);
|
|
3234
|
+
anchor.rotation.set(...part.pose.rotation, "ZYX");
|
|
3235
|
+
anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
|
|
3236
|
+
parent.add(anchor);
|
|
3237
|
+
const size = part.texture ?? textureSize;
|
|
3238
|
+
for (const cube of part.cubes) {
|
|
3239
|
+
const [width, height, depth] = cube.size;
|
|
3240
|
+
const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
|
|
3241
|
+
const texture = new MinecraftCubeTexture(...cube.uv, ...size);
|
|
3242
|
+
const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
|
|
3243
|
+
const geometry = this._getBoxGeometryForDimensionsAndUv(
|
|
3244
|
+
width + growX * 2,
|
|
3245
|
+
height + growY * 2,
|
|
3246
|
+
depth + growZ * 2,
|
|
3247
|
+
uv
|
|
3248
|
+
).clone();
|
|
3249
|
+
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
3250
|
+
const mesh = this.createMesh(name, geometry, material);
|
|
3251
|
+
anchor.add(mesh);
|
|
3252
|
+
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
3253
|
+
}
|
|
3254
|
+
for (const [childName, child] of Object.entries(part.children)) {
|
|
3255
|
+
this.createPart(childName, child, anchor, size, material);
|
|
2967
3256
|
}
|
|
2968
3257
|
}
|
|
3258
|
+
async applyTextures() {
|
|
3259
|
+
const assetKeyStr = this.textureKey.serialize();
|
|
3260
|
+
const keyStr = `entity:${assetKeyStr}`;
|
|
3261
|
+
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
3262
|
+
if (!mat) {
|
|
3263
|
+
const pending = this.loadTextures();
|
|
3264
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
3265
|
+
await pending;
|
|
3266
|
+
if (!this.imageData) return;
|
|
3267
|
+
const canvas = this.imageData.data.canvas;
|
|
3268
|
+
const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
|
|
3269
|
+
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
3270
|
+
this.imageData = void 0;
|
|
3271
|
+
}
|
|
3272
|
+
this.iterateAllMeshes((mesh) => {
|
|
3273
|
+
mesh.material = mat;
|
|
3274
|
+
});
|
|
3275
|
+
this.notifyDirty();
|
|
3276
|
+
}
|
|
2969
3277
|
};
|
|
2970
|
-
|
|
3278
|
+
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, { flip: true });
|
|
3279
|
+
var EntityObject = _EntityObject;
|
|
2971
3280
|
function isEntityObject(obj) {
|
|
2972
3281
|
return obj.isEntityObject;
|
|
2973
3282
|
}
|
|
@@ -2979,7 +3288,7 @@ var GuiObject = class extends SceneObject {
|
|
|
2979
3288
|
|
|
2980
3289
|
// src/inspector/SceneInspector.ts
|
|
2981
3290
|
import { Raycaster, Vector2 as Vector22 } from "three";
|
|
2982
|
-
var
|
|
3291
|
+
var p7 = prefix("SceneInspector");
|
|
2983
3292
|
var help = "<span>Ctrl+Click to Select<br/></span><br/>";
|
|
2984
3293
|
var SceneInspector = class {
|
|
2985
3294
|
constructor(renderer) {
|
|
@@ -3048,7 +3357,7 @@ var SceneInspector = class {
|
|
|
3048
3357
|
}
|
|
3049
3358
|
selectObject(targetObject, targetIntersection) {
|
|
3050
3359
|
this.selectedObject = targetObject;
|
|
3051
|
-
console.log(
|
|
3360
|
+
console.log(p7, "selected", targetObject);
|
|
3052
3361
|
this.redraw(targetObject, targetIntersection);
|
|
3053
3362
|
}
|
|
3054
3363
|
redraw(targetObject, targetIntersection) {
|
|
@@ -3346,7 +3655,7 @@ var SceneStatsDisplay = class {
|
|
|
3346
3655
|
};
|
|
3347
3656
|
|
|
3348
3657
|
// src/instance/InstanceManager.ts
|
|
3349
|
-
var
|
|
3658
|
+
var p8 = prefix("InstanceManager");
|
|
3350
3659
|
var InstanceManager = class {
|
|
3351
3660
|
constructor() {
|
|
3352
3661
|
this.isInstanceManager = true;
|
|
@@ -3354,7 +3663,7 @@ var InstanceManager = class {
|
|
|
3354
3663
|
}
|
|
3355
3664
|
async get(key) {
|
|
3356
3665
|
if (key in this.instanceCache) {
|
|
3357
|
-
console.debug(
|
|
3666
|
+
console.debug(p8, "key in cache", key);
|
|
3358
3667
|
return (await this.instanceCache[key]).nextInstance();
|
|
3359
3668
|
}
|
|
3360
3669
|
return void 0;
|
|
@@ -3363,13 +3672,17 @@ var InstanceManager = class {
|
|
|
3363
3672
|
if (key in this.instanceCache) {
|
|
3364
3673
|
return await this.get(key);
|
|
3365
3674
|
}
|
|
3366
|
-
console.debug(
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
})
|
|
3372
|
-
|
|
3675
|
+
console.debug(p8, "key not in cache", key);
|
|
3676
|
+
const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
|
|
3677
|
+
this.instanceCache[key] = pending;
|
|
3678
|
+
try {
|
|
3679
|
+
return await pending;
|
|
3680
|
+
} catch (error) {
|
|
3681
|
+
if (this.instanceCache[key] === pending) {
|
|
3682
|
+
delete this.instanceCache[key];
|
|
3683
|
+
}
|
|
3684
|
+
throw error;
|
|
3685
|
+
}
|
|
3373
3686
|
}
|
|
3374
3687
|
reset() {
|
|
3375
3688
|
for (let instanceCacheKey in this.instanceCache) {
|
|
@@ -3386,20 +3699,6 @@ function isInstanceable(obj) {
|
|
|
3386
3699
|
return "nextInstance" in obj;
|
|
3387
3700
|
}
|
|
3388
3701
|
|
|
3389
|
-
// src/model/DisplayPosition.ts
|
|
3390
|
-
var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
|
|
3391
|
-
DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
|
|
3392
|
-
DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
|
|
3393
|
-
DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
|
|
3394
|
-
DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
|
|
3395
|
-
DisplayPosition2["GUI"] = "gui";
|
|
3396
|
-
DisplayPosition2["HEAD"] = "head";
|
|
3397
|
-
DisplayPosition2["GROUND"] = "ground";
|
|
3398
|
-
DisplayPosition2["FIXED"] = "fixed";
|
|
3399
|
-
return DisplayPosition2;
|
|
3400
|
-
})(DisplayPosition || {});
|
|
3401
|
-
var DISPLAY_POSITIONS = Object.values(DisplayPosition);
|
|
3402
|
-
|
|
3403
3702
|
// src/model/GuiLight.ts
|
|
3404
3703
|
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
3405
3704
|
GuiLight2["FRONT"] = "front";
|
|
@@ -3422,8 +3721,93 @@ function isQuadArray(obj) {
|
|
|
3422
3721
|
return Array.isArray(obj) && obj.length === 4;
|
|
3423
3722
|
}
|
|
3424
3723
|
|
|
3724
|
+
// src/model/block/blockTints.json
|
|
3725
|
+
var blockTints_default = {
|
|
3726
|
+
"minecraft:large_fern": { source: "grass" },
|
|
3727
|
+
"minecraft:tall_grass": { source: "grass" },
|
|
3728
|
+
"minecraft:grass_block": { source: "grass" },
|
|
3729
|
+
"minecraft:fern": { source: "grass" },
|
|
3730
|
+
"minecraft:grass": { source: "grass" },
|
|
3731
|
+
"minecraft:short_grass": { source: "grass" },
|
|
3732
|
+
"minecraft:potted_fern": { source: "grass" },
|
|
3733
|
+
"minecraft:bush": { source: "grass" },
|
|
3734
|
+
"minecraft:pink_petals": { source: "grass", untinted: [0] },
|
|
3735
|
+
"minecraft:wildflowers": { source: "grass", untinted: [0] },
|
|
3736
|
+
"minecraft:spruce_leaves": { source: "constant", color: 6396257 },
|
|
3737
|
+
"minecraft:birch_leaves": { source: "constant", color: 8431445 },
|
|
3738
|
+
"minecraft:oak_leaves": { source: "constant", color: 4764952 },
|
|
3739
|
+
"minecraft:jungle_leaves": { source: "constant", color: 4764952 },
|
|
3740
|
+
"minecraft:acacia_leaves": { source: "constant", color: 4764952 },
|
|
3741
|
+
"minecraft:dark_oak_leaves": { source: "constant", color: 4764952 },
|
|
3742
|
+
"minecraft:vine": { source: "constant", color: 4764952 },
|
|
3743
|
+
"minecraft:mangrove_leaves": { source: "constant", color: 4764952 },
|
|
3744
|
+
"minecraft:leaf_litter": { source: "constant", color: 6044722 },
|
|
3745
|
+
"minecraft:water_cauldron": { source: "constant", color: 4159204 },
|
|
3746
|
+
"minecraft:redstone_wire": { source: "redstone" },
|
|
3747
|
+
"minecraft:attached_melon_stem": { source: "constant", color: 14731036 },
|
|
3748
|
+
"minecraft:attached_pumpkin_stem": { source: "constant", color: 14731036 },
|
|
3749
|
+
"minecraft:melon_stem": { source: "stem" },
|
|
3750
|
+
"minecraft:pumpkin_stem": { source: "stem" },
|
|
3751
|
+
"minecraft:lily_pad": { source: "constant", color: 7455580 }
|
|
3752
|
+
};
|
|
3753
|
+
|
|
3754
|
+
// src/model/block/BlockTints.ts
|
|
3755
|
+
var rules = blockTints_default;
|
|
3756
|
+
var BlockTints = class {
|
|
3757
|
+
/** Resolves block preview colors without biome context; explicit tints take precedence. */
|
|
3758
|
+
static async get(key, state, model, tints) {
|
|
3759
|
+
const rule = key && rules[key.toNamespacedString()];
|
|
3760
|
+
if (!key || !rule) return tints;
|
|
3761
|
+
const indices = /* @__PURE__ */ new Set();
|
|
3762
|
+
for (const element of model.elements ?? []) {
|
|
3763
|
+
for (const face of Object.values(element.faces)) {
|
|
3764
|
+
const index = face?.tintindex;
|
|
3765
|
+
if (index !== void 0 && index >= 0 && tints?.[index] === void 0 && !rule.untinted?.includes(index)) {
|
|
3766
|
+
indices.add(index);
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
}
|
|
3770
|
+
if (!indices.size) return tints;
|
|
3771
|
+
let color;
|
|
3772
|
+
switch (rule.source) {
|
|
3773
|
+
case "constant":
|
|
3774
|
+
color = rule.color;
|
|
3775
|
+
break;
|
|
3776
|
+
case "grass":
|
|
3777
|
+
color = await this.grassColor(key);
|
|
3778
|
+
break;
|
|
3779
|
+
case "redstone": {
|
|
3780
|
+
const power = Number(state.power ?? 0) / 15;
|
|
3781
|
+
const red = power * 0.6 + (power > 0 ? 0.4 : 0.3);
|
|
3782
|
+
const green = Math.max(0, power * power * 0.7 - 0.5);
|
|
3783
|
+
const blue = Math.max(0, power * power * 0.6 - 0.7);
|
|
3784
|
+
color = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
|
|
3785
|
+
break;
|
|
3786
|
+
}
|
|
3787
|
+
case "stem": {
|
|
3788
|
+
const age = Number(state.age ?? 0);
|
|
3789
|
+
color = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
|
|
3790
|
+
break;
|
|
3791
|
+
}
|
|
3792
|
+
}
|
|
3793
|
+
return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
|
|
3794
|
+
}
|
|
3795
|
+
static async grassColor(origin) {
|
|
3796
|
+
const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
|
|
3797
|
+
return await Caching.blockTintCache.get(key.serialize(), async () => {
|
|
3798
|
+
const image = await ModelTextures.get(key);
|
|
3799
|
+
if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
|
|
3800
|
+
if (image.width !== 256 || image.height !== 256) {
|
|
3801
|
+
throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
|
|
3802
|
+
}
|
|
3803
|
+
const [red, green, blue] = image.data.getImageData(127, 127, 1, 1).data;
|
|
3804
|
+
return red << 16 | green << 8 | blue;
|
|
3805
|
+
});
|
|
3806
|
+
}
|
|
3807
|
+
};
|
|
3808
|
+
|
|
3425
3809
|
// src/model/scene/ModelObject.ts
|
|
3426
|
-
import { BoxGeometry as BoxGeometry5, Matrix4 as
|
|
3810
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler4, Matrix4 as Matrix44 } from "three";
|
|
3427
3811
|
|
|
3428
3812
|
// src/three/BufferGeometryUtils.js
|
|
3429
3813
|
import {
|
|
@@ -3435,7 +3819,7 @@ import {
|
|
|
3435
3819
|
TriangleFanDrawMode,
|
|
3436
3820
|
TriangleStripDrawMode,
|
|
3437
3821
|
TrianglesDrawMode,
|
|
3438
|
-
Vector3 as
|
|
3822
|
+
Vector3 as Vector36
|
|
3439
3823
|
} from "three";
|
|
3440
3824
|
function computeTangents(geometry) {
|
|
3441
3825
|
geometry.computeTangents();
|
|
@@ -3754,15 +4138,15 @@ function computeMorphedAttributes(object) {
|
|
|
3754
4138
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
3755
4139
|
return null;
|
|
3756
4140
|
}
|
|
3757
|
-
const _vA = new
|
|
3758
|
-
const _vB = new
|
|
3759
|
-
const _vC = new
|
|
3760
|
-
const _tempA = new
|
|
3761
|
-
const _tempB = new
|
|
3762
|
-
const _tempC = new
|
|
3763
|
-
const _morphA = new
|
|
3764
|
-
const _morphB = new
|
|
3765
|
-
const _morphC = new
|
|
4141
|
+
const _vA = new Vector36();
|
|
4142
|
+
const _vB = new Vector36();
|
|
4143
|
+
const _vC = new Vector36();
|
|
4144
|
+
const _tempA = new Vector36();
|
|
4145
|
+
const _tempB = new Vector36();
|
|
4146
|
+
const _tempC = new Vector36();
|
|
4147
|
+
const _morphA = new Vector36();
|
|
4148
|
+
const _morphB = new Vector36();
|
|
4149
|
+
const _morphC = new Vector36();
|
|
3766
4150
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
3767
4151
|
_vA.fromBufferAttribute(attribute, a2);
|
|
3768
4152
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -3968,15 +4352,16 @@ function computeMorphedAttributes(object) {
|
|
|
3968
4352
|
}
|
|
3969
4353
|
|
|
3970
4354
|
// src/model/scene/ModelObject.ts
|
|
3971
|
-
var
|
|
3972
|
-
var
|
|
4355
|
+
var import_ts_deepmerge5 = __toESM(require_dist());
|
|
4356
|
+
var p9 = prefix("ModelObject");
|
|
3973
4357
|
var _ModelObject = class _ModelObject extends SceneObject {
|
|
3974
4358
|
constructor(originalModel, options) {
|
|
3975
4359
|
super(options);
|
|
3976
4360
|
this.originalModel = originalModel;
|
|
3977
4361
|
this.isModelObject = true;
|
|
3978
4362
|
this.meshesCreated = false;
|
|
3979
|
-
this.options = (0,
|
|
4363
|
+
this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
|
|
4364
|
+
if (this.options.tints) this.options.tints = { ...this.options.tints };
|
|
3980
4365
|
console.log("ModelObject options", this.options);
|
|
3981
4366
|
}
|
|
3982
4367
|
async init() {
|
|
@@ -3998,17 +4383,36 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
3998
4383
|
createMeshes(force = false) {
|
|
3999
4384
|
if (this.meshesCreated && !force) return;
|
|
4000
4385
|
const mat = Materials.MISSING_TEXTURE;
|
|
4386
|
+
const displayTransform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : void 0;
|
|
4001
4387
|
let allGeos = [];
|
|
4002
4388
|
if (this.atlas) {
|
|
4003
4389
|
if (this.atlas.model.elements) {
|
|
4004
4390
|
this.atlas.model.elements?.forEach((el) => {
|
|
4005
4391
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
4006
|
-
|
|
4007
|
-
|
|
4392
|
+
if (this.options.uvLockRotation) {
|
|
4393
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler4(...this.options.uvLockRotation));
|
|
4394
|
+
}
|
|
4395
|
+
if (this.options.tints) {
|
|
4396
|
+
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
4397
|
+
for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
|
|
4398
|
+
const tintIndex = el.faces[faceName]?.tintindex;
|
|
4399
|
+
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
4400
|
+
const tint = this.options.tints[tintIndex];
|
|
4401
|
+
if (tint === void 0) continue;
|
|
4402
|
+
const color = new Color3(tint);
|
|
4403
|
+
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4404
|
+
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
4405
|
+
}
|
|
4406
|
+
}
|
|
4407
|
+
elGeo.setAttribute("color", new BufferAttribute4(colors, 3));
|
|
4408
|
+
}
|
|
4409
|
+
elGeo.applyMatrix4(new Matrix44().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
|
|
4410
|
+
elGeo.applyMatrix4(new Matrix44().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4008
4411
|
if (el.rotation) {
|
|
4009
4412
|
applyElementRotation(el.rotation, elGeo);
|
|
4010
4413
|
}
|
|
4011
|
-
elGeo.applyMatrix4(new
|
|
4414
|
+
elGeo.applyMatrix4(new Matrix44().makeTranslation(-8, -8, -8));
|
|
4415
|
+
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4012
4416
|
if (this.options.mergeMeshes) {
|
|
4013
4417
|
allGeos.push(elGeo);
|
|
4014
4418
|
} else {
|
|
@@ -4019,10 +4423,10 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4019
4423
|
}
|
|
4020
4424
|
});
|
|
4021
4425
|
} else {
|
|
4022
|
-
console.debug(
|
|
4426
|
+
console.debug(p9, this.atlas.model, "has no elements");
|
|
4023
4427
|
}
|
|
4024
4428
|
} else {
|
|
4025
|
-
console.debug(
|
|
4429
|
+
console.debug(p9, "Missing atlas for", this);
|
|
4026
4430
|
}
|
|
4027
4431
|
if (this.options.mergeMeshes) {
|
|
4028
4432
|
let combinedGeo;
|
|
@@ -4030,6 +4434,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4030
4434
|
combinedGeo = mergeBufferGeometries(allGeos);
|
|
4031
4435
|
} else {
|
|
4032
4436
|
combinedGeo = new BoxGeometry5(16, 16, 16);
|
|
4437
|
+
if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
|
|
4033
4438
|
}
|
|
4034
4439
|
combinedGeo.computeBoundingBox();
|
|
4035
4440
|
let mesh;
|
|
@@ -4059,6 +4464,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4059
4464
|
/*TODO: get this from render options*/
|
|
4060
4465
|
);
|
|
4061
4466
|
this.iterateAllMeshes((mesh) => {
|
|
4467
|
+
if (mesh.geometry.hasAttribute("color")) mat.vertexColors = true;
|
|
4062
4468
|
mesh.material = mat;
|
|
4063
4469
|
});
|
|
4064
4470
|
if (this.atlas.hasAnimation) {
|
|
@@ -4074,16 +4480,26 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4074
4480
|
}
|
|
4075
4481
|
}
|
|
4076
4482
|
};
|
|
4077
|
-
_ModelObject.DEFAULT_OPTIONS = (0,
|
|
4483
|
+
_ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
|
|
4078
4484
|
var ModelObject = _ModelObject;
|
|
4079
4485
|
function isModelObject(obj) {
|
|
4080
4486
|
return obj.isModelObject;
|
|
4081
4487
|
}
|
|
4082
4488
|
|
|
4083
4489
|
// src/model/block/scene/BlockObject.ts
|
|
4084
|
-
var
|
|
4085
|
-
import { Euler as
|
|
4086
|
-
var
|
|
4490
|
+
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4491
|
+
import { Euler as Euler5, Matrix4 as Matrix45, Vector3 as Vector37 } from "three";
|
|
4492
|
+
var p10 = prefix("BlockObject");
|
|
4493
|
+
function matchesCondition(condition, state) {
|
|
4494
|
+
return Object.entries(condition).every(([key, value]) => {
|
|
4495
|
+
if (Array.isArray(value)) {
|
|
4496
|
+
if (key === "OR") return value.some((child) => matchesCondition(child, state));
|
|
4497
|
+
if (key === "AND") return value.every((child) => matchesCondition(child, state));
|
|
4498
|
+
return false;
|
|
4499
|
+
}
|
|
4500
|
+
return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
|
|
4501
|
+
});
|
|
4502
|
+
}
|
|
4087
4503
|
var _BlockObject = class _BlockObject extends SceneObject {
|
|
4088
4504
|
constructor(blockState, options) {
|
|
4089
4505
|
super(options);
|
|
@@ -4097,11 +4513,11 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4097
4513
|
this._instanceModel = [];
|
|
4098
4514
|
this._variants = [];
|
|
4099
4515
|
this._models = [];
|
|
4100
|
-
this.options = (0,
|
|
4516
|
+
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
4101
4517
|
}
|
|
4102
4518
|
async init() {
|
|
4103
4519
|
if (this.options.applyDefaultState) {
|
|
4104
|
-
const defaultState = this.blockState.key ? BlockStates.getDefaultState(this.blockState.key) : void 0;
|
|
4520
|
+
const defaultState = this.blockState.key ? await BlockStates.getDefaultState(this.blockState.key) : void 0;
|
|
4105
4521
|
if (defaultState && Object.keys(defaultState).length > 0) {
|
|
4106
4522
|
const state = {};
|
|
4107
4523
|
for (let k in defaultState) {
|
|
@@ -4112,15 +4528,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4112
4528
|
if (this.blockState.variants) {
|
|
4113
4529
|
await this.setState(Object.keys(this.blockState.variants)[0]);
|
|
4114
4530
|
} else if (this.blockState.multipart) {
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
if (k) {
|
|
4119
|
-
await this.setState(k, part.when[k].split("|")[0]);
|
|
4120
|
-
break;
|
|
4121
|
-
}
|
|
4122
|
-
}
|
|
4123
|
-
}
|
|
4531
|
+
const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
|
|
4532
|
+
const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
|
|
4533
|
+
await this.setState(state);
|
|
4124
4534
|
}
|
|
4125
4535
|
}
|
|
4126
4536
|
} else {
|
|
@@ -4135,7 +4545,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4135
4545
|
if (isModelObject(model)) {
|
|
4136
4546
|
model.removeFromScene();
|
|
4137
4547
|
} else if (isInstanceReference(model)) {
|
|
4138
|
-
model.setScale(new
|
|
4548
|
+
model.setScale(new Vector37(0, 0, 0));
|
|
4139
4549
|
}
|
|
4140
4550
|
}
|
|
4141
4551
|
super.removeFromScene();
|
|
@@ -4177,55 +4587,11 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4177
4587
|
} else if (this.blockState.multipart) {
|
|
4178
4588
|
for (let part of this.blockState.multipart) {
|
|
4179
4589
|
if (!part.apply) {
|
|
4180
|
-
console.debug(
|
|
4590
|
+
console.debug(p10, "Missing apply for blockState part", part);
|
|
4181
4591
|
continue;
|
|
4182
4592
|
}
|
|
4183
|
-
if (!part.when) {
|
|
4593
|
+
if (!part.when || matchesCondition(part.when, state)) {
|
|
4184
4594
|
out.push(this.getSingleVariant(part.apply));
|
|
4185
|
-
} else {
|
|
4186
|
-
let matches = true;
|
|
4187
|
-
if ("OR" in part.when) {
|
|
4188
|
-
const or = part.when.OR;
|
|
4189
|
-
let anyMatch = false;
|
|
4190
|
-
for (let o of or) {
|
|
4191
|
-
for (let k in o) {
|
|
4192
|
-
const split = o[k].split("|");
|
|
4193
|
-
let m = false;
|
|
4194
|
-
for (let s of split) {
|
|
4195
|
-
if (`${state[k]}` === `${s}`) {
|
|
4196
|
-
m = true;
|
|
4197
|
-
break;
|
|
4198
|
-
}
|
|
4199
|
-
}
|
|
4200
|
-
if (m) {
|
|
4201
|
-
anyMatch = true;
|
|
4202
|
-
break;
|
|
4203
|
-
}
|
|
4204
|
-
}
|
|
4205
|
-
}
|
|
4206
|
-
if (!anyMatch) {
|
|
4207
|
-
matches = false;
|
|
4208
|
-
}
|
|
4209
|
-
} else {
|
|
4210
|
-
for (let k in part.when) {
|
|
4211
|
-
const split = part.when[k].split("|");
|
|
4212
|
-
let m = false;
|
|
4213
|
-
for (let s of split) {
|
|
4214
|
-
if (`${state[k]}` === `${s}`) {
|
|
4215
|
-
m = true;
|
|
4216
|
-
break;
|
|
4217
|
-
}
|
|
4218
|
-
}
|
|
4219
|
-
if (!m) {
|
|
4220
|
-
matches = false;
|
|
4221
|
-
break;
|
|
4222
|
-
}
|
|
4223
|
-
}
|
|
4224
|
-
}
|
|
4225
|
-
if (matches) {
|
|
4226
|
-
const variants = part.apply;
|
|
4227
|
-
out.push(this.getSingleVariant(variants));
|
|
4228
|
-
}
|
|
4229
4595
|
}
|
|
4230
4596
|
}
|
|
4231
4597
|
}
|
|
@@ -4240,7 +4606,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4240
4606
|
}
|
|
4241
4607
|
for (let model of this._models) {
|
|
4242
4608
|
if (isInstanceReference(model)) {
|
|
4243
|
-
model.setScale(new
|
|
4609
|
+
model.setScale(new Vector37(0, 0, 0));
|
|
4244
4610
|
} else {
|
|
4245
4611
|
model.dispose();
|
|
4246
4612
|
}
|
|
@@ -4255,11 +4621,21 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4255
4621
|
}
|
|
4256
4622
|
}
|
|
4257
4623
|
getSingleVariant(variants) {
|
|
4258
|
-
if (Array.isArray(variants))
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4624
|
+
if (!Array.isArray(variants)) return variants;
|
|
4625
|
+
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
4626
|
+
const total = variants.reduce((sum, variant) => {
|
|
4627
|
+
const weight = variant.weight ?? 1;
|
|
4628
|
+
if (!Number.isInteger(weight) || weight < 1) {
|
|
4629
|
+
throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
|
|
4630
|
+
}
|
|
4631
|
+
return sum + weight;
|
|
4632
|
+
}, 0);
|
|
4633
|
+
let choice = Math.random() * total;
|
|
4634
|
+
for (const variant of variants) {
|
|
4635
|
+
choice -= variant.weight ?? 1;
|
|
4636
|
+
if (choice < 0) return variant;
|
|
4637
|
+
}
|
|
4638
|
+
return variants[variants.length - 1];
|
|
4263
4639
|
}
|
|
4264
4640
|
// @deprecated
|
|
4265
4641
|
async createAVariant(variants, instanceInfo) {
|
|
@@ -4267,28 +4643,27 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4267
4643
|
await this.createVariant(variant);
|
|
4268
4644
|
}
|
|
4269
4645
|
async createVariant(variant) {
|
|
4270
|
-
const
|
|
4271
|
-
const obj = await this.scene.addModel(model, this.options);
|
|
4272
|
-
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
4273
|
-
this._isInstanced = true;
|
|
4274
|
-
this._instanceCounter = 1;
|
|
4275
|
-
}
|
|
4276
|
-
let rotation = new Euler3(0, 0, 0);
|
|
4646
|
+
const rotation = new Euler5();
|
|
4277
4647
|
if (typeof variant.x !== "undefined") {
|
|
4278
4648
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4279
4649
|
}
|
|
4280
4650
|
if (typeof variant.y !== "undefined") {
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4651
|
+
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
4652
|
+
}
|
|
4653
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
4654
|
+
modelKey.root = this.blockState.key?.root;
|
|
4655
|
+
const model = await Models.getMerged(modelKey);
|
|
4656
|
+
const options = {
|
|
4657
|
+
...this.options,
|
|
4658
|
+
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
4659
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
4660
|
+
};
|
|
4661
|
+
const obj = await this.scene.addModel(model, options);
|
|
4662
|
+
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
4663
|
+
this._isInstanced = true;
|
|
4664
|
+
this._instanceCounter = 1;
|
|
4286
4665
|
}
|
|
4287
4666
|
obj.setRotation(rotation);
|
|
4288
|
-
setTimeout(() => {
|
|
4289
|
-
obj.setRotation(rotation);
|
|
4290
|
-
}, 150);
|
|
4291
|
-
console.log(obj);
|
|
4292
4667
|
return obj;
|
|
4293
4668
|
}
|
|
4294
4669
|
async resetState() {
|
|
@@ -4357,7 +4732,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4357
4732
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
4358
4733
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
4359
4734
|
}
|
|
4360
|
-
getMatrixAt(index, matrix = new
|
|
4735
|
+
getMatrixAt(index, matrix = new Matrix45()) {
|
|
4361
4736
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
4362
4737
|
const child = this._models[0];
|
|
4363
4738
|
if (child && isModelObject(child)) {
|
|
@@ -4378,15 +4753,16 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4378
4753
|
}
|
|
4379
4754
|
}
|
|
4380
4755
|
setPosition(position) {
|
|
4381
|
-
|
|
4756
|
+
this.position.copy(position);
|
|
4382
4757
|
for (let model of this._models) {
|
|
4383
4758
|
model.setPosition(position);
|
|
4384
4759
|
}
|
|
4760
|
+
this.notifyDirty();
|
|
4385
4761
|
}
|
|
4386
4762
|
//TODO: should override rotation + scale methods
|
|
4387
4763
|
//TODO
|
|
4388
4764
|
};
|
|
4389
|
-
_BlockObject.DEFAULT_OPTIONS = (0,
|
|
4765
|
+
_BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
|
|
4390
4766
|
applyDefaultState: true
|
|
4391
4767
|
});
|
|
4392
4768
|
var BlockObject = _BlockObject;
|
|
@@ -4436,7 +4812,7 @@ var StructureParser = class {
|
|
|
4436
4812
|
|
|
4437
4813
|
// src/renderer/MineRenderScene.ts
|
|
4438
4814
|
import { Scene as Scene2 } from "three";
|
|
4439
|
-
var
|
|
4815
|
+
var import_ts_deepmerge8 = __toESM(require_dist());
|
|
4440
4816
|
|
|
4441
4817
|
// src/skin/SkinPart.ts
|
|
4442
4818
|
var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
|
|
@@ -5054,90 +5430,80 @@ var baseSkinCoordinates = {
|
|
|
5054
5430
|
]
|
|
5055
5431
|
},
|
|
5056
5432
|
up: {
|
|
5057
|
-
uv: [
|
|
5058
|
-
4,
|
|
5059
|
-
36,
|
|
5060
|
-
8,
|
|
5061
|
-
32
|
|
5062
|
-
]
|
|
5063
|
-
},
|
|
5064
|
-
down: {
|
|
5065
|
-
uv: [
|
|
5066
|
-
8,
|
|
5067
|
-
32,
|
|
5068
|
-
12,
|
|
5069
|
-
36
|
|
5070
|
-
],
|
|
5071
|
-
rotation: 180
|
|
5072
|
-
}
|
|
5073
|
-
},
|
|
5074
|
-
cape: {
|
|
5075
|
-
//TODO
|
|
5076
|
-
east: {
|
|
5077
|
-
uv: [
|
|
5078
|
-
0,
|
|
5079
|
-
36,
|
|
5080
|
-
4,
|
|
5081
|
-
48
|
|
5082
|
-
]
|
|
5083
|
-
},
|
|
5084
|
-
west: {
|
|
5085
5433
|
uv: [
|
|
5086
5434
|
8,
|
|
5087
5435
|
36,
|
|
5088
|
-
12,
|
|
5089
|
-
48
|
|
5090
|
-
]
|
|
5091
|
-
},
|
|
5092
|
-
north: {
|
|
5093
|
-
uv: [
|
|
5094
5436
|
4,
|
|
5095
|
-
|
|
5096
|
-
8,
|
|
5097
|
-
48
|
|
5437
|
+
32
|
|
5098
5438
|
]
|
|
5099
5439
|
},
|
|
5100
|
-
|
|
5440
|
+
down: {
|
|
5101
5441
|
uv: [
|
|
5102
5442
|
12,
|
|
5103
|
-
36,
|
|
5104
|
-
16,
|
|
5105
|
-
48
|
|
5106
|
-
]
|
|
5107
|
-
},
|
|
5108
|
-
up: {
|
|
5109
|
-
uv: [
|
|
5110
|
-
4,
|
|
5111
5443
|
32,
|
|
5112
5444
|
8,
|
|
5113
5445
|
36
|
|
5114
|
-
]
|
|
5115
|
-
},
|
|
5116
|
-
down: {
|
|
5117
|
-
uv: [
|
|
5118
|
-
8,
|
|
5119
|
-
32,
|
|
5120
|
-
12,
|
|
5121
|
-
36
|
|
5122
5446
|
],
|
|
5123
5447
|
rotation: 180
|
|
5124
5448
|
}
|
|
5449
|
+
},
|
|
5450
|
+
cape: {
|
|
5451
|
+
east: { uv: [0, 1, 1, 17] },
|
|
5452
|
+
west: { uv: [11, 1, 12, 17] },
|
|
5453
|
+
north: { uv: [1, 1, 11, 17] },
|
|
5454
|
+
south: { uv: [12, 1, 22, 17] },
|
|
5455
|
+
up: { uv: [11, 1, 1, 0] },
|
|
5456
|
+
down: { uv: [21, 0, 11, 1] }
|
|
5125
5457
|
}
|
|
5126
5458
|
};
|
|
5127
5459
|
var classicSkinTextureCoordinates = {
|
|
5128
5460
|
...baseSkinCoordinates
|
|
5129
5461
|
};
|
|
5130
|
-
var slimSkinTextureCoordinates = {
|
|
5462
|
+
var slimSkinTextureCoordinates = {
|
|
5463
|
+
...baseSkinCoordinates,
|
|
5464
|
+
leftArm: {
|
|
5465
|
+
...baseSkinCoordinates.leftArm,
|
|
5466
|
+
west: { uv: [39, 52, 43, 64] },
|
|
5467
|
+
north: { uv: [36, 52, 39, 64] },
|
|
5468
|
+
south: { uv: [43, 52, 46, 64] },
|
|
5469
|
+
up: { uv: [39, 52, 36, 48] },
|
|
5470
|
+
down: { uv: [42, 48, 39, 52] }
|
|
5471
|
+
},
|
|
5472
|
+
rightArm: {
|
|
5473
|
+
...baseSkinCoordinates.rightArm,
|
|
5474
|
+
west: { uv: [47, 20, 51, 32] },
|
|
5475
|
+
north: { uv: [44, 20, 47, 32] },
|
|
5476
|
+
south: { uv: [51, 20, 54, 32] },
|
|
5477
|
+
up: { uv: [47, 20, 44, 16] },
|
|
5478
|
+
down: { uv: [50, 16, 47, 20] }
|
|
5479
|
+
},
|
|
5480
|
+
leftSleeve: {
|
|
5481
|
+
...baseSkinCoordinates.leftSleeve,
|
|
5482
|
+
west: { uv: [55, 52, 59, 64] },
|
|
5483
|
+
north: { uv: [52, 52, 55, 64] },
|
|
5484
|
+
south: { uv: [59, 52, 62, 64] },
|
|
5485
|
+
up: { uv: [55, 52, 52, 48] },
|
|
5486
|
+
down: { uv: [58, 48, 55, 52], rotation: 180 }
|
|
5487
|
+
},
|
|
5488
|
+
rightSleeve: {
|
|
5489
|
+
...baseSkinCoordinates.rightSleeve,
|
|
5490
|
+
west: { uv: [47, 36, 51, 48] },
|
|
5491
|
+
north: { uv: [44, 36, 47, 48] },
|
|
5492
|
+
south: { uv: [51, 36, 54, 48] },
|
|
5493
|
+
up: { uv: [47, 36, 44, 32] },
|
|
5494
|
+
down: { uv: [50, 32, 47, 36], rotation: 180 }
|
|
5495
|
+
}
|
|
5496
|
+
};
|
|
5131
5497
|
|
|
5132
5498
|
// src/skin/SkinGeometries.ts
|
|
5133
5499
|
var box8inner = [8, 8, 8];
|
|
5134
|
-
var box8outer = [
|
|
5500
|
+
var box8outer = [9, 9, 9];
|
|
5135
5501
|
var box8_12_4inner = [8, 12, 4];
|
|
5136
|
-
var box8_12_4outer = [8.
|
|
5502
|
+
var box8_12_4outer = [8.5, 12.5, 4.5];
|
|
5137
5503
|
var box4_12_4inner = [4, 12, 4];
|
|
5138
|
-
var box4_12_4outer = [4.
|
|
5504
|
+
var box4_12_4outer = [4.5, 12.5, 4.5];
|
|
5139
5505
|
var box3_12_4inner = [3, 12, 4];
|
|
5140
|
-
var box3_12_4outer = [3.
|
|
5506
|
+
var box3_12_4outer = [3.5, 12.5, 4.5];
|
|
5141
5507
|
var box10_16_1 = [10, 16, 1];
|
|
5142
5508
|
var baseSkinGeometries = {
|
|
5143
5509
|
head: box8inner,
|
|
@@ -5167,114 +5533,313 @@ var slimSkinGeometries = {
|
|
|
5167
5533
|
};
|
|
5168
5534
|
|
|
5169
5535
|
// src/skin/scene/SkinObject.ts
|
|
5170
|
-
var
|
|
5536
|
+
var import_ts_deepmerge7 = __toESM(require_dist());
|
|
5537
|
+
|
|
5538
|
+
// src/skin/SkinTextures.ts
|
|
5539
|
+
import { DataTexture, DoubleSide as DoubleSide2, FrontSide as FrontSide2, MeshBasicMaterial as MeshBasicMaterial3, SRGBColorSpace as SRGBColorSpace3 } from "three";
|
|
5540
|
+
|
|
5541
|
+
// src/skin/SkinImage.ts
|
|
5542
|
+
var SkinImage = class {
|
|
5543
|
+
static async getData(src) {
|
|
5544
|
+
const key = serializeImageKey({ src });
|
|
5545
|
+
return await Caching.imageDataCache.get(`skin:${key}`, async () => {
|
|
5546
|
+
const info = await ImageLoader.getInfo(src);
|
|
5547
|
+
if (info.type !== "png") return ImageLoader.getData(src);
|
|
5548
|
+
try {
|
|
5549
|
+
return await this.decodePng(info.data);
|
|
5550
|
+
} catch (error) {
|
|
5551
|
+
Caching.rawImageCache.invalidate(key);
|
|
5552
|
+
throw error;
|
|
5553
|
+
}
|
|
5554
|
+
});
|
|
5555
|
+
}
|
|
5556
|
+
static async decodePng(bytes) {
|
|
5557
|
+
const { decode, convertIndexedToRgb } = await import("fast-png");
|
|
5558
|
+
const png = decode(bytes);
|
|
5559
|
+
let { data, channels, depth } = png;
|
|
5560
|
+
if (channels === 1 && (png.palette || depth < 8)) {
|
|
5561
|
+
const max = (1 << depth) - 1;
|
|
5562
|
+
const palette = png.palette ?? Array.from({ length: max + 1 }, (_, value) => {
|
|
5563
|
+
const gray = value * 255 / max;
|
|
5564
|
+
return [gray, gray, gray, png.transparency?.[0] === value ? 0 : 255];
|
|
5565
|
+
});
|
|
5566
|
+
data = convertIndexedToRgb({ ...png, palette });
|
|
5567
|
+
channels = palette[0].length;
|
|
5568
|
+
depth = 8;
|
|
5569
|
+
}
|
|
5570
|
+
const pixels = new Uint8ClampedArray(png.width * png.height * 4);
|
|
5571
|
+
for (let pixel = 0; pixel < png.width * png.height; pixel++) {
|
|
5572
|
+
const source = pixel * channels;
|
|
5573
|
+
const target = pixel * 4;
|
|
5574
|
+
const sample = (channel) => depth === 16 ? data[source + channel] >>> 8 : data[source + channel];
|
|
5575
|
+
pixels[target] = sample(0);
|
|
5576
|
+
pixels[target + 1] = sample(channels < 3 ? 0 : 1);
|
|
5577
|
+
pixels[target + 2] = sample(channels < 3 ? 0 : 2);
|
|
5578
|
+
pixels[target + 3] = channels % 2 === 0 ? sample(channels - 1) : png.transparency?.every((value, channel) => data[source + channel] === value) ? 0 : 255;
|
|
5579
|
+
}
|
|
5580
|
+
return { width: png.width, height: png.height, data: pixels, colorSpace: "srgb" };
|
|
5581
|
+
}
|
|
5582
|
+
};
|
|
5583
|
+
|
|
5584
|
+
// src/skin/SkinTextures.ts
|
|
5585
|
+
var SkinTextures = class {
|
|
5586
|
+
static async get(src, legacy) {
|
|
5587
|
+
const image = await SkinImage.getData(src);
|
|
5588
|
+
const scale = image.width / 64;
|
|
5589
|
+
if (!Number.isInteger(scale) || scale < 1 || image.height !== image.width && image.height !== image.width / 2) {
|
|
5590
|
+
throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; expected 64x64 or 64x32, or an integer-scaled equivalent`);
|
|
5591
|
+
}
|
|
5592
|
+
const isLegacy = legacy ?? image.height === image.width / 2;
|
|
5593
|
+
if (!isLegacy && image.height !== image.width) {
|
|
5594
|
+
throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; non-legacy skins must be square`);
|
|
5595
|
+
}
|
|
5596
|
+
const slim = !isLegacy && this.isSlim(image, scale);
|
|
5597
|
+
const key = `skin:${serializeImageKey({ src })}:${isLegacy}`;
|
|
5598
|
+
const material = Caching.materialCache.get(key, () => {
|
|
5599
|
+
const pixels = isLegacy ? this.normalizeLegacy(image, scale) : new Uint8Array(image.data);
|
|
5600
|
+
this.makeBaseOpaque(pixels, image.width, scale);
|
|
5601
|
+
return this.createMaterial(pixels, image.width, image.width);
|
|
5602
|
+
});
|
|
5603
|
+
return { material, slim, legacy: isLegacy };
|
|
5604
|
+
}
|
|
5605
|
+
static async getCape(src, layout = "minecraft") {
|
|
5606
|
+
const image = await SkinImage.getData(src);
|
|
5607
|
+
const scale = image.width / 64;
|
|
5608
|
+
if (layout === "minecraft" && (!Number.isInteger(scale) || scale < 1 || image.height !== image.width / 2)) {
|
|
5609
|
+
throw new MineRenderError(`Invalid cape dimensions ${image.width}x${image.height}; expected 64x32 or an integer-scaled equivalent`);
|
|
5610
|
+
}
|
|
5611
|
+
return Caching.materialCache.get(`cape:${serializeImageKey({ src })}`, () => {
|
|
5612
|
+
return this.createMaterial(new Uint8Array(image.data), image.width, image.height, false);
|
|
5613
|
+
});
|
|
5614
|
+
}
|
|
5615
|
+
static createMaterial(pixels, width, height, transparent = true) {
|
|
5616
|
+
const texture = Textures.initTextureProps(new DataTexture(pixels, width, height));
|
|
5617
|
+
texture.colorSpace = SRGBColorSpace3;
|
|
5618
|
+
texture.flipY = true;
|
|
5619
|
+
texture.needsUpdate = true;
|
|
5620
|
+
return new MeshBasicMaterial3({ map: texture, transparent, side: transparent ? DoubleSide2 : FrontSide2, alphaTest: transparent ? 0.1 : 0 });
|
|
5621
|
+
}
|
|
5622
|
+
static isSlim(image, scale) {
|
|
5623
|
+
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
5624
|
+
for (let row = y * scale; row < (y + 12) * scale; row++) {
|
|
5625
|
+
for (let column = x * scale; column < (x + 1) * scale; column++) {
|
|
5626
|
+
if (image.data[(row * image.width + column) * 4 + 3] !== 0) return false;
|
|
5627
|
+
}
|
|
5628
|
+
}
|
|
5629
|
+
}
|
|
5630
|
+
return true;
|
|
5631
|
+
}
|
|
5632
|
+
static normalizeLegacy(image, scale) {
|
|
5633
|
+
const pixels = new Uint8Array(image.width * image.width * 4);
|
|
5634
|
+
pixels.set(image.data.subarray(0, image.width * image.width / 2 * 4));
|
|
5635
|
+
for (const [sx, sy, dx, dy, width, height] of [
|
|
5636
|
+
[4, 16, 20, 48, 4, 4],
|
|
5637
|
+
[8, 16, 24, 48, 4, 4],
|
|
5638
|
+
[0, 20, 24, 52, 4, 12],
|
|
5639
|
+
[4, 20, 20, 52, 4, 12],
|
|
5640
|
+
[8, 20, 16, 52, 4, 12],
|
|
5641
|
+
[12, 20, 28, 52, 4, 12],
|
|
5642
|
+
[44, 16, 36, 48, 4, 4],
|
|
5643
|
+
[48, 16, 40, 48, 4, 4],
|
|
5644
|
+
[40, 20, 40, 52, 4, 12],
|
|
5645
|
+
[44, 20, 36, 52, 4, 12],
|
|
5646
|
+
[48, 20, 32, 52, 4, 12],
|
|
5647
|
+
[52, 20, 44, 52, 4, 12]
|
|
5648
|
+
]) {
|
|
5649
|
+
for (let y = 0; y < height * scale; y++) {
|
|
5650
|
+
for (let x = 0; x < width * scale; x++) {
|
|
5651
|
+
const source = ((sy * scale + y) * image.width + sx * scale + x) * 4;
|
|
5652
|
+
const target = ((dy * scale + y) * image.width + (dx + width) * scale - 1 - x) * 4;
|
|
5653
|
+
pixels.set(image.data.subarray(source, source + 4), target);
|
|
5654
|
+
}
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5657
|
+
let clearHat = true;
|
|
5658
|
+
for (let y = 0; y < 32 * scale; y++) {
|
|
5659
|
+
for (let x = 32 * scale; x < image.width; x++) {
|
|
5660
|
+
if (pixels[(y * image.width + x) * 4 + 3] < 128) clearHat = false;
|
|
5661
|
+
}
|
|
5662
|
+
}
|
|
5663
|
+
if (clearHat) {
|
|
5664
|
+
for (let y = 0; y < 32 * scale; y++) {
|
|
5665
|
+
for (let x = 32 * scale; x < image.width; x++) {
|
|
5666
|
+
pixels[(y * image.width + x) * 4 + 3] = 0;
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
5669
|
+
}
|
|
5670
|
+
return pixels;
|
|
5671
|
+
}
|
|
5672
|
+
static makeBaseOpaque(pixels, width, scale) {
|
|
5673
|
+
for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64]]) {
|
|
5674
|
+
for (let y = y0 * scale; y < y1 * scale; y++) {
|
|
5675
|
+
for (let x = x0 * scale; x < x1 * scale; x++) pixels[(y * width + x) * 4 + 3] = 255;
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
};
|
|
5680
|
+
|
|
5681
|
+
// src/skin/CapeLayout.ts
|
|
5682
|
+
var capeTextureSizes = {
|
|
5683
|
+
minecraft: [64, 32],
|
|
5684
|
+
optifine: [46, 22],
|
|
5685
|
+
labymod: [22, 17]
|
|
5686
|
+
};
|
|
5687
|
+
|
|
5688
|
+
// src/skin/scene/SkinObject.ts
|
|
5171
5689
|
var SkinObject = class extends SceneObject {
|
|
5172
5690
|
constructor(options) {
|
|
5173
5691
|
super();
|
|
5174
5692
|
this.slim = false;
|
|
5175
|
-
this.
|
|
5176
|
-
this.
|
|
5177
|
-
this.
|
|
5178
|
-
this.options = (0,
|
|
5693
|
+
this.detectedSlim = false;
|
|
5694
|
+
this.skinLoad = 0;
|
|
5695
|
+
this.capeLoad = 0;
|
|
5696
|
+
this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
5697
|
+
this.slim = this.options.slim ?? false;
|
|
5179
5698
|
}
|
|
5180
5699
|
async init() {
|
|
5700
|
+
const cape = this.getGroupByName("cape" /* CAPE */);
|
|
5181
5701
|
this.createMeshes();
|
|
5702
|
+
if (cape) this.getGroupByName("body" /* BODY */).attach(cape);
|
|
5182
5703
|
}
|
|
5183
5704
|
removeMeshes() {
|
|
5184
5705
|
}
|
|
5185
5706
|
createMeshes() {
|
|
5186
|
-
|
|
5187
|
-
const mat = Materials.MISSING_TEXTURE;
|
|
5707
|
+
const mat = this.skinMaterial ?? Materials.MISSING_TEXTURE;
|
|
5188
5708
|
{
|
|
5189
5709
|
const headGroup = this.createAndAddGroup("head", 0, 28, 0, "y" /* Y */, -4);
|
|
5190
5710
|
const headGeo = this.getBoxGeometry("head" /* HEAD */);
|
|
5191
5711
|
const head = this.createAndAddMesh("head", headGroup, headGeo, mat, "y" /* Y */, 4);
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
5195
|
-
}
|
|
5712
|
+
const hatGeo = this.getBoxGeometry("hat" /* HAT */);
|
|
5713
|
+
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
5196
5714
|
}
|
|
5197
5715
|
{
|
|
5198
|
-
const bodyGroup = this.createAndAddGroup("body", 0,
|
|
5716
|
+
const bodyGroup = this.createAndAddGroup("body", 0, 24, 0);
|
|
5199
5717
|
const bodyGeo = this.getBoxGeometry("body" /* BODY */);
|
|
5200
|
-
const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat);
|
|
5718
|
+
const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat, "y" /* Y */, -6);
|
|
5201
5719
|
const jacketGeo = this.getBoxGeometry("jacket" /* JACKET */);
|
|
5202
|
-
const jacket = this.createAndAddMesh("jacket", bodyGroup, jacketGeo, mat);
|
|
5720
|
+
const jacket = this.createAndAddMesh("jacket", bodyGroup, jacketGeo, mat, "y" /* Y */, -6);
|
|
5203
5721
|
}
|
|
5204
5722
|
{
|
|
5205
5723
|
{
|
|
5206
|
-
const leftArmGroup = this.createAndAddGroup("leftArm",
|
|
5724
|
+
const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
|
|
5207
5725
|
const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
|
|
5208
5726
|
const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
|
|
5727
|
+
leftArm.position.x = this.slim ? -0.5 : -1;
|
|
5209
5728
|
const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
|
|
5210
5729
|
const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
|
|
5730
|
+
leftSleeve.position.x = this.slim ? -0.5 : -1;
|
|
5211
5731
|
}
|
|
5212
5732
|
{
|
|
5213
|
-
const rightArmGroup = this.createAndAddGroup("rightArm",
|
|
5733
|
+
const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
|
|
5214
5734
|
const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
|
|
5215
5735
|
const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
|
|
5736
|
+
rightArm.position.x = this.slim ? 0.5 : 1;
|
|
5216
5737
|
const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
|
|
5217
5738
|
const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
|
|
5739
|
+
rightSleeve.position.x = this.slim ? 0.5 : 1;
|
|
5218
5740
|
}
|
|
5219
5741
|
}
|
|
5220
5742
|
{
|
|
5221
5743
|
{
|
|
5222
|
-
const leftLegGroup = this.createAndAddGroup("leftLeg", -
|
|
5744
|
+
const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
|
|
5223
5745
|
const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
|
|
5224
|
-
const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -
|
|
5746
|
+
const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
|
|
5225
5747
|
const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
|
|
5226
|
-
const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -
|
|
5748
|
+
const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
|
|
5227
5749
|
}
|
|
5228
5750
|
{
|
|
5229
|
-
const rightLegGroup = this.createAndAddGroup("rightLeg",
|
|
5751
|
+
const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
|
|
5230
5752
|
const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
|
|
5231
|
-
const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -
|
|
5753
|
+
const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
|
|
5232
5754
|
const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
|
|
5233
|
-
const rightTrousers = this.createAndAddMesh("rightTrousers", rightLegGroup, rightTrousersGeo, mat, "y" /* Y */, -
|
|
5755
|
+
const rightTrousers = this.createAndAddMesh("rightTrousers", rightLegGroup, rightTrousersGeo, mat, "y" /* Y */, -6);
|
|
5234
5756
|
}
|
|
5235
5757
|
}
|
|
5236
|
-
console.log("#createMeshes done");
|
|
5237
5758
|
}
|
|
5238
|
-
setSkinTexture(src) {
|
|
5759
|
+
async setSkinTexture(src) {
|
|
5239
5760
|
if (typeof src === "undefined") return;
|
|
5240
5761
|
this.skinTextureSrc = src;
|
|
5241
|
-
const
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5762
|
+
const load = ++this.skinLoad;
|
|
5763
|
+
const texture = await SkinTextures.get(src, this.options.legacy);
|
|
5764
|
+
if (load !== this.skinLoad) return;
|
|
5765
|
+
this.skinMaterial = texture.material;
|
|
5766
|
+
this.detectedSlim = texture.slim;
|
|
5767
|
+
this.updateSlim(this.options.slim ?? this.detectedSlim);
|
|
5768
|
+
for (const part of SKIN_PARTS) {
|
|
5769
|
+
if (part === "cape" /* CAPE */) continue;
|
|
5770
|
+
const mesh = this.getMeshByName(part);
|
|
5247
5771
|
if (mesh) {
|
|
5248
|
-
mesh.material =
|
|
5772
|
+
mesh.material = texture.material;
|
|
5249
5773
|
}
|
|
5250
5774
|
}
|
|
5775
|
+
this.notifyDirty();
|
|
5776
|
+
}
|
|
5777
|
+
/** Load a cape texture in the selected layout, or pass undefined to remove the cape. */
|
|
5778
|
+
async setCapeTexture(src, layout = "minecraft") {
|
|
5779
|
+
const load = ++this.capeLoad;
|
|
5780
|
+
if (src === void 0) {
|
|
5781
|
+
const group = this.getGroupByName("cape" /* CAPE */);
|
|
5782
|
+
group?.removeFromParent();
|
|
5783
|
+
this.notifyDirty();
|
|
5784
|
+
return;
|
|
5785
|
+
}
|
|
5786
|
+
const material = await SkinTextures.getCape(src, layout);
|
|
5787
|
+
if (load !== this.capeLoad) return;
|
|
5788
|
+
const size = capeTextureSizes[layout];
|
|
5789
|
+
const geometry = this._getBoxGeometryFromDimensions(
|
|
5790
|
+
classicSkinGeometries.cape,
|
|
5791
|
+
classicSkinTextureCoordinates.cape,
|
|
5792
|
+
size,
|
|
5793
|
+
size
|
|
5794
|
+
);
|
|
5795
|
+
const mesh = this.getMeshByName("cape" /* CAPE */);
|
|
5796
|
+
if (mesh) {
|
|
5797
|
+
mesh.material = material;
|
|
5798
|
+
mesh.geometry = geometry;
|
|
5799
|
+
} else {
|
|
5800
|
+
const body = this.getGroupByName("body" /* BODY */);
|
|
5801
|
+
const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
|
|
5802
|
+
(body ?? this).add(group);
|
|
5803
|
+
group.rotation.set(toRadians(-6), Math.PI, 0);
|
|
5804
|
+
const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
|
|
5805
|
+
cape.position.set(0, -8, -0.5);
|
|
5806
|
+
}
|
|
5807
|
+
this.notifyDirty();
|
|
5251
5808
|
}
|
|
5252
|
-
|
|
5809
|
+
/** Select the arm model, or pass undefined to use texture detection. */
|
|
5253
5810
|
setSlim(slim) {
|
|
5254
|
-
|
|
5255
|
-
|
|
5811
|
+
this.options.slim = slim;
|
|
5812
|
+
this.updateSlim(slim ?? this.detectedSlim);
|
|
5813
|
+
}
|
|
5814
|
+
updateSlim(slim) {
|
|
5815
|
+
if (slim === this.slim) return;
|
|
5256
5816
|
this.slim = slim;
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5817
|
+
const offset = slim ? 0.5 : -0.5;
|
|
5818
|
+
for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
|
|
5819
|
+
const mesh = this.getMeshByName(part);
|
|
5820
|
+
if (mesh) {
|
|
5821
|
+
mesh.geometry = this.getBoxGeometry(part);
|
|
5822
|
+
mesh.position.x += part === "leftArm" /* LEFT_ARM */ || part === "leftSleeve" /* LEFT_SLEEVE */ ? offset : -offset;
|
|
5263
5823
|
}
|
|
5264
5824
|
}
|
|
5265
|
-
|
|
5825
|
+
this.notifyDirty();
|
|
5266
5826
|
}
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
this.legacy = legacy;
|
|
5827
|
+
/** Select the texture layout, or pass undefined to detect it from image dimensions. */
|
|
5828
|
+
async setLegacy(legacy) {
|
|
5829
|
+
if (legacy === this.options.legacy) return;
|
|
5830
|
+
this.options.legacy = legacy;
|
|
5831
|
+
if (this.skinTextureSrc) await this.setSkinTexture(this.skinTextureSrc);
|
|
5832
|
+
}
|
|
5833
|
+
dispose() {
|
|
5834
|
+
this.skinLoad++;
|
|
5835
|
+
this.capeLoad++;
|
|
5836
|
+
super.dispose();
|
|
5271
5837
|
}
|
|
5272
5838
|
//TODO: layer toggles
|
|
5273
5839
|
getBoxGeometry(part) {
|
|
5274
|
-
console.log("slim", this.slim);
|
|
5275
5840
|
const coordinates = this.slim ? slimSkinTextureCoordinates : classicSkinTextureCoordinates;
|
|
5276
5841
|
const geometries = this.slim ? slimSkinGeometries : classicSkinGeometries;
|
|
5277
|
-
return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [
|
|
5842
|
+
return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [64, 64]);
|
|
5278
5843
|
}
|
|
5279
5844
|
};
|
|
5280
5845
|
|
|
@@ -5292,7 +5857,7 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
|
|
|
5292
5857
|
this.dirty = true;
|
|
5293
5858
|
}
|
|
5294
5859
|
};
|
|
5295
|
-
this.options = (0,
|
|
5860
|
+
this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
|
|
5296
5861
|
}
|
|
5297
5862
|
add(...objects) {
|
|
5298
5863
|
for (const object of objects) {
|
|
@@ -5350,7 +5915,14 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
|
|
|
5350
5915
|
const obj = await objectSupplier();
|
|
5351
5916
|
if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
|
|
5352
5917
|
console.log("instanceMeshes + key");
|
|
5353
|
-
|
|
5918
|
+
let key = asset.key.serialize();
|
|
5919
|
+
if (isModelObject(obj)) {
|
|
5920
|
+
const { displayPosition, uvLockRotation, tints } = obj.options;
|
|
5921
|
+
if (displayPosition) key += `|display:${displayPosition}`;
|
|
5922
|
+
if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
|
|
5923
|
+
const palette = Object.entries(tints ?? {}).sort(([a], [b]) => Number(a) - Number(b));
|
|
5924
|
+
if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
|
|
5925
|
+
}
|
|
5354
5926
|
return this.instanceManager.getOrCreate(key, async () => {
|
|
5355
5927
|
obj.scene = this;
|
|
5356
5928
|
await obj.init();
|
|
@@ -5377,10 +5949,10 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
|
|
|
5377
5949
|
this.dirty = true;
|
|
5378
5950
|
const obj = new SkinObject(options);
|
|
5379
5951
|
obj.scene = this;
|
|
5380
|
-
await obj.init();
|
|
5381
5952
|
if (skin) {
|
|
5382
|
-
obj.setSkinTexture(skin);
|
|
5953
|
+
await obj.setSkinTexture(skin);
|
|
5383
5954
|
}
|
|
5955
|
+
await obj.init();
|
|
5384
5956
|
parent.add(obj);
|
|
5385
5957
|
return obj;
|
|
5386
5958
|
}
|
|
@@ -5388,15 +5960,15 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
|
|
|
5388
5960
|
return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
|
|
5389
5961
|
}
|
|
5390
5962
|
};
|
|
5391
|
-
_MineRenderScene.DEFAULT_OPTIONS = (0,
|
|
5963
|
+
_MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
|
|
5392
5964
|
var MineRenderScene = _MineRenderScene;
|
|
5393
5965
|
function isMineRenderScene(obj) {
|
|
5394
5966
|
return obj.isMineRenderScene;
|
|
5395
5967
|
}
|
|
5396
5968
|
|
|
5397
5969
|
// src/renderer/Renderer.ts
|
|
5398
|
-
import { AxesHelper as
|
|
5399
|
-
var
|
|
5970
|
+
import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace4, Vector3 as Vector39, WebGLRenderer } from "three";
|
|
5971
|
+
var import_ts_deepmerge9 = __toESM(require_dist());
|
|
5400
5972
|
import Stats from "stats.js";
|
|
5401
5973
|
import { EffectComposer, RenderPass } from "postprocessing";
|
|
5402
5974
|
|
|
@@ -5404,11 +5976,11 @@ import { EffectComposer, RenderPass } from "postprocessing";
|
|
|
5404
5976
|
import {
|
|
5405
5977
|
EventDispatcher,
|
|
5406
5978
|
MOUSE,
|
|
5407
|
-
Quaternion as
|
|
5979
|
+
Quaternion as Quaternion4,
|
|
5408
5980
|
Spherical,
|
|
5409
5981
|
TOUCH,
|
|
5410
5982
|
Vector2 as Vector23,
|
|
5411
|
-
Vector3 as
|
|
5983
|
+
Vector3 as Vector38
|
|
5412
5984
|
} from "three";
|
|
5413
5985
|
var _changeEvent = { type: "change" };
|
|
5414
5986
|
var _startEvent = { type: "start" };
|
|
@@ -5422,7 +5994,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5422
5994
|
this.domElement = domElement;
|
|
5423
5995
|
this.domElement.style.touchAction = "none";
|
|
5424
5996
|
this.enabled = true;
|
|
5425
|
-
this.target = new
|
|
5997
|
+
this.target = new Vector38();
|
|
5426
5998
|
this.minDistance = 0;
|
|
5427
5999
|
this.maxDistance = Infinity;
|
|
5428
6000
|
this.minZoom = 0;
|
|
@@ -5474,11 +6046,11 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5474
6046
|
state = STATE.NONE;
|
|
5475
6047
|
};
|
|
5476
6048
|
this.update = function() {
|
|
5477
|
-
const offset = new
|
|
5478
|
-
const quat = new
|
|
6049
|
+
const offset = new Vector38();
|
|
6050
|
+
const quat = new Quaternion4().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
|
|
5479
6051
|
const quatInverse = quat.clone().invert();
|
|
5480
|
-
const lastPosition = new
|
|
5481
|
-
const lastQuaternion = new
|
|
6052
|
+
const lastPosition = new Vector38();
|
|
6053
|
+
const lastQuaternion = new Quaternion4();
|
|
5482
6054
|
const twoPI = 2 * Math.PI;
|
|
5483
6055
|
return function update() {
|
|
5484
6056
|
const position = scope.object.position;
|
|
@@ -5567,7 +6139,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5567
6139
|
const spherical = new Spherical();
|
|
5568
6140
|
const sphericalDelta = new Spherical();
|
|
5569
6141
|
let scale = 1;
|
|
5570
|
-
const panOffset = new
|
|
6142
|
+
const panOffset = new Vector38();
|
|
5571
6143
|
let zoomChanged = false;
|
|
5572
6144
|
const rotateStart = new Vector23();
|
|
5573
6145
|
const rotateEnd = new Vector23();
|
|
@@ -5593,7 +6165,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5593
6165
|
sphericalDelta.phi -= angle;
|
|
5594
6166
|
}
|
|
5595
6167
|
const panLeft = function() {
|
|
5596
|
-
const v = new
|
|
6168
|
+
const v = new Vector38();
|
|
5597
6169
|
return function panLeft2(distance, objectMatrix) {
|
|
5598
6170
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
5599
6171
|
v.multiplyScalar(-distance);
|
|
@@ -5601,7 +6173,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5601
6173
|
};
|
|
5602
6174
|
}();
|
|
5603
6175
|
const panUp = function() {
|
|
5604
|
-
const v = new
|
|
6176
|
+
const v = new Vector38();
|
|
5605
6177
|
return function panUp2(distance, objectMatrix) {
|
|
5606
6178
|
if (scope.screenSpacePanning === true) {
|
|
5607
6179
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -5614,7 +6186,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5614
6186
|
};
|
|
5615
6187
|
}();
|
|
5616
6188
|
const pan = function() {
|
|
5617
|
-
const offset = new
|
|
6189
|
+
const offset = new Vector38();
|
|
5618
6190
|
return function pan2(deltaX, deltaY) {
|
|
5619
6191
|
const element = scope.domElement;
|
|
5620
6192
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -6054,8 +6626,6 @@ var MapControls = class extends OrbitControls {
|
|
|
6054
6626
|
var _Renderer = class _Renderer {
|
|
6055
6627
|
constructor(options) {
|
|
6056
6628
|
this._dirty = true;
|
|
6057
|
-
this._animationTimer = void 0;
|
|
6058
|
-
this._animationFrame = void 0;
|
|
6059
6629
|
this._resizeListener = void 0;
|
|
6060
6630
|
this._disposed = false;
|
|
6061
6631
|
this._debugHelpers = [];
|
|
@@ -6063,9 +6633,9 @@ var _Renderer = class _Renderer {
|
|
|
6063
6633
|
this._changeListener = () => {
|
|
6064
6634
|
this._dirty = true;
|
|
6065
6635
|
};
|
|
6066
|
-
this.options = (0,
|
|
6636
|
+
this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
|
|
6067
6637
|
this._animationLoop = this.animate.bind(this);
|
|
6068
|
-
this.
|
|
6638
|
+
this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
|
|
6069
6639
|
this._scene = this.createScene();
|
|
6070
6640
|
this._camera = this.createCamera();
|
|
6071
6641
|
this._renderer = this.createRenderer();
|
|
@@ -6112,13 +6682,13 @@ var _Renderer = class _Renderer {
|
|
|
6112
6682
|
renderer.setClearColor(0, 0);
|
|
6113
6683
|
renderer.shadowMap.enabled = true;
|
|
6114
6684
|
renderer.shadowMap.type = PCFSoftShadowMap;
|
|
6115
|
-
renderer.
|
|
6685
|
+
renderer.outputColorSpace = SRGBColorSpace4;
|
|
6116
6686
|
renderer.setSize(this.viewWidth, this.viewHeight);
|
|
6117
6687
|
return renderer;
|
|
6118
6688
|
}
|
|
6119
6689
|
createComposer() {
|
|
6690
|
+
if (!this.options.composer.enabled) return void 0;
|
|
6120
6691
|
const composer = new EffectComposer(this.renderer);
|
|
6121
|
-
if (!this.options.composer.enabled) return composer;
|
|
6122
6692
|
composer.setSize(this.viewWidth, this.viewHeight);
|
|
6123
6693
|
composer.addPass(new RenderPass(this.scene, this.camera));
|
|
6124
6694
|
return composer;
|
|
@@ -6159,7 +6729,7 @@ var _Renderer = class _Renderer {
|
|
|
6159
6729
|
this.scene.add(gridHelper3);
|
|
6160
6730
|
}
|
|
6161
6731
|
if (this.options.debug.axes) {
|
|
6162
|
-
const axesHelper = new
|
|
6732
|
+
const axesHelper = new AxesHelper2(64);
|
|
6163
6733
|
this._debugHelpers.push(axesHelper);
|
|
6164
6734
|
this.scene.add(axesHelper);
|
|
6165
6735
|
}
|
|
@@ -6227,7 +6797,7 @@ var _Renderer = class _Renderer {
|
|
|
6227
6797
|
this.camera.updateProjectionMatrix();
|
|
6228
6798
|
}
|
|
6229
6799
|
this.renderer.setSize(width, height);
|
|
6230
|
-
this.composer
|
|
6800
|
+
this.composer?.setSize(width, height);
|
|
6231
6801
|
this._dirty = true;
|
|
6232
6802
|
}
|
|
6233
6803
|
//<editor-fold desc="RENDER">
|
|
@@ -6246,12 +6816,7 @@ var _Renderer = class _Renderer {
|
|
|
6246
6816
|
stop() {
|
|
6247
6817
|
if (this._disposed) return;
|
|
6248
6818
|
this.renderer.setAnimationLoop(null);
|
|
6249
|
-
|
|
6250
|
-
clearTimeout(this._animationTimer);
|
|
6251
|
-
this._animationTimer = void 0;
|
|
6252
|
-
if (this._animationFrame)
|
|
6253
|
-
cancelAnimationFrame(this._animationFrame);
|
|
6254
|
-
this._animationFrame = void 0;
|
|
6819
|
+
this._nextFrameTime = void 0;
|
|
6255
6820
|
}
|
|
6256
6821
|
/**
|
|
6257
6822
|
* Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
|
|
@@ -6291,25 +6856,30 @@ var _Renderer = class _Renderer {
|
|
|
6291
6856
|
}
|
|
6292
6857
|
}
|
|
6293
6858
|
this._debugHelpers.length = 0;
|
|
6294
|
-
this.composer
|
|
6859
|
+
this.composer?.dispose();
|
|
6295
6860
|
this.renderer.dispose();
|
|
6296
6861
|
this.renderer.forceContextLoss();
|
|
6297
6862
|
}
|
|
6298
|
-
animate(t) {
|
|
6863
|
+
animate(t = performance.now()) {
|
|
6299
6864
|
if (this._disposed) return;
|
|
6300
|
-
if (this._stats) {
|
|
6301
|
-
this._stats.begin();
|
|
6302
|
-
}
|
|
6303
6865
|
if (this._controls?.enabled) {
|
|
6304
6866
|
this._controls.update();
|
|
6305
6867
|
}
|
|
6306
6868
|
if (this._disposed) return;
|
|
6307
|
-
if (this.dirty
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6869
|
+
if (!this.dirty && !this.options.render.renderAlways) return;
|
|
6870
|
+
const interval = this._frameInterval;
|
|
6871
|
+
if (interval) {
|
|
6872
|
+
const next = this._nextFrameTime;
|
|
6873
|
+
if (next !== void 0 && t + 0.1 < next) return;
|
|
6874
|
+
this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
|
|
6875
|
+
}
|
|
6876
|
+
if (this._stats) {
|
|
6877
|
+
this._stats.begin();
|
|
6878
|
+
}
|
|
6879
|
+
if (this.options.composer.enabled && this.composer) {
|
|
6880
|
+
this.composer.render();
|
|
6881
|
+
} else {
|
|
6882
|
+
this.renderer.render(this.scene, this.camera);
|
|
6313
6883
|
}
|
|
6314
6884
|
this.dirty = false;
|
|
6315
6885
|
if (this._stats) {
|
|
@@ -6348,7 +6918,7 @@ var _Renderer = class _Renderer {
|
|
|
6348
6918
|
}
|
|
6349
6919
|
///
|
|
6350
6920
|
};
|
|
6351
|
-
_Renderer.DEFAULT_OPTIONS = (0,
|
|
6921
|
+
_Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
|
|
6352
6922
|
camera: {
|
|
6353
6923
|
type: "perspective",
|
|
6354
6924
|
near: 1,
|
|
@@ -6363,8 +6933,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge10.default)({}, {
|
|
|
6363
6933
|
top: void 0,
|
|
6364
6934
|
bottom: void 0
|
|
6365
6935
|
},
|
|
6366
|
-
position: new
|
|
6367
|
-
lookingAt: new
|
|
6936
|
+
position: new Vector39(50, 50, 50),
|
|
6937
|
+
lookingAt: new Vector39(0, 0, 0)
|
|
6368
6938
|
},
|
|
6369
6939
|
render: {
|
|
6370
6940
|
fpsLimit: 60,
|
|
@@ -6397,7 +6967,7 @@ var Skins = class {
|
|
|
6397
6967
|
return this.fromUsername(uuidOrUsername);
|
|
6398
6968
|
}
|
|
6399
6969
|
static async fromUuid(uuid) {
|
|
6400
|
-
return this.
|
|
6970
|
+
return this.getMcProxySkinUrl(uuid);
|
|
6401
6971
|
}
|
|
6402
6972
|
static async fromUsername(username) {
|
|
6403
6973
|
return this.usernameToUuid(username).then((uuid) => {
|
|
@@ -6424,7 +6994,7 @@ var Skins = class {
|
|
|
6424
6994
|
return this.capeFromUsername(uuidOrUsername);
|
|
6425
6995
|
}
|
|
6426
6996
|
static async capeFromUuid(uuid) {
|
|
6427
|
-
return this.
|
|
6997
|
+
return this.getMcProxyCapeUrl(uuid);
|
|
6428
6998
|
}
|
|
6429
6999
|
static async capeFromUsername(username) {
|
|
6430
7000
|
return this.usernameToUuid(username).then((uuid) => {
|
|
@@ -6434,19 +7004,31 @@ var Skins = class {
|
|
|
6434
7004
|
return void 0;
|
|
6435
7005
|
});
|
|
6436
7006
|
}
|
|
6437
|
-
static
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
}
|
|
6442
|
-
return void 0;
|
|
6443
|
-
});
|
|
7007
|
+
/** Returns a full static cape texture for a username or UUID. */
|
|
7008
|
+
static async capeFromCapesDev(player, capeType = "minecraft") {
|
|
7009
|
+
const cape = await this.getCapesDev(player, capeType);
|
|
7010
|
+
return cape?.exists ? cape.imageUrls?.still?.full : void 0;
|
|
6444
7011
|
}
|
|
6445
7012
|
//</editor-fold>
|
|
6446
7013
|
//<editor-fold desc="Helpers">
|
|
6447
7014
|
static async usernameToUuid(username) {
|
|
6448
|
-
return this.
|
|
7015
|
+
return this.usernameToUuidMcProxy(username);
|
|
7016
|
+
}
|
|
7017
|
+
static async usernameToUuidMcProxy(username) {
|
|
7018
|
+
return Requests.genericRequest({
|
|
7019
|
+
baseURL: "https://mcproxy.dev",
|
|
7020
|
+
url: "/uuid/" + username
|
|
7021
|
+
}).then((res) => {
|
|
7022
|
+
if (res.status === 200) {
|
|
7023
|
+
return res.data["data"]["id"];
|
|
7024
|
+
}
|
|
7025
|
+
return void 0;
|
|
7026
|
+
}).catch((err) => {
|
|
7027
|
+
console.warn(err);
|
|
7028
|
+
return void 0;
|
|
7029
|
+
});
|
|
6449
7030
|
}
|
|
7031
|
+
/** @deprecated **/
|
|
6450
7032
|
static async usernameToUuidSkinProxy(username) {
|
|
6451
7033
|
return Requests.genericRequest({
|
|
6452
7034
|
baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
|
|
@@ -6499,18 +7081,15 @@ var Skins = class {
|
|
|
6499
7081
|
return void 0;
|
|
6500
7082
|
});
|
|
6501
7083
|
}
|
|
6502
|
-
static async getCapesDev(
|
|
7084
|
+
static async getCapesDev(player, type = "all") {
|
|
6503
7085
|
return Requests.genericRequest({
|
|
6504
7086
|
baseURL: "https://api.capes.dev",
|
|
6505
|
-
url: "/load/" +
|
|
7087
|
+
url: "/load/" + encodeURIComponent(player) + "/" + encodeURIComponent(type)
|
|
6506
7088
|
}).then((res) => {
|
|
6507
7089
|
if (res.status === 200) {
|
|
6508
7090
|
return res.data;
|
|
6509
7091
|
}
|
|
6510
7092
|
return void 0;
|
|
6511
|
-
}).catch((err) => {
|
|
6512
|
-
console.warn(err);
|
|
6513
|
-
return void 0;
|
|
6514
7093
|
});
|
|
6515
7094
|
}
|
|
6516
7095
|
static getCrafatarSkinUrl(uuid) {
|
|
@@ -6525,20 +7104,28 @@ var Skins = class {
|
|
|
6525
7104
|
static getMineSkinPlayerSkinUrl(uuid) {
|
|
6526
7105
|
return "https://mineskin.org/skin/player/" + uuid;
|
|
6527
7106
|
}
|
|
7107
|
+
/** @deprecated **/
|
|
6528
7108
|
static getSkinProxySkinUrl(uuid) {
|
|
6529
7109
|
return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
|
|
6530
7110
|
}
|
|
7111
|
+
/** @deprecated **/
|
|
6531
7112
|
static getSkinProxyCapeUrl(uuid) {
|
|
6532
7113
|
return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
|
|
6533
7114
|
}
|
|
7115
|
+
static getMcProxySkinUrl(uuid) {
|
|
7116
|
+
return "https://mcproxy.dev/skin/" + uuid;
|
|
7117
|
+
}
|
|
7118
|
+
static getMcProxyCapeUrl(uuid) {
|
|
7119
|
+
return "https://mcproxy.dev/cape/" + uuid;
|
|
7120
|
+
}
|
|
6534
7121
|
//</editor-fold>
|
|
6535
7122
|
};
|
|
6536
7123
|
|
|
6537
7124
|
// src/world/Chunk.ts
|
|
6538
|
-
import { Box3 as Box32, Object3D as Object3D6, Vector3 as
|
|
7125
|
+
import { Box3 as Box32, Object3D as Object3D6, Vector3 as Vector311 } from "three";
|
|
6539
7126
|
|
|
6540
7127
|
// src/world/MineRenderWorld.ts
|
|
6541
|
-
import { Vector3 as
|
|
7128
|
+
import { Vector3 as Vector310 } from "three";
|
|
6542
7129
|
var MineRenderWorld = class {
|
|
6543
7130
|
constructor(scene) {
|
|
6544
7131
|
this._size = 4;
|
|
@@ -6549,10 +7136,10 @@ var MineRenderWorld = class {
|
|
|
6549
7136
|
}
|
|
6550
7137
|
getBlockAt(posOrX, y, z) {
|
|
6551
7138
|
if (typeof posOrX == "number") {
|
|
6552
|
-
return this.getBlockAt(new
|
|
7139
|
+
return this.getBlockAt(new Vector310(posOrX, y, z));
|
|
6553
7140
|
}
|
|
6554
7141
|
if (isTripleArray(posOrX)) {
|
|
6555
|
-
return this.getBlockAt(new
|
|
7142
|
+
return this.getBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]));
|
|
6556
7143
|
}
|
|
6557
7144
|
const chunk = this.getChunkAt(posOrX);
|
|
6558
7145
|
if (typeof chunk === "undefined") {
|
|
@@ -6563,10 +7150,10 @@ var MineRenderWorld = class {
|
|
|
6563
7150
|
}
|
|
6564
7151
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
6565
7152
|
if (typeof posOrX == "number") {
|
|
6566
|
-
return this.setBlockAt(new
|
|
7153
|
+
return this.setBlockAt(new Vector310(posOrX, yOrBlock, z), block);
|
|
6567
7154
|
}
|
|
6568
7155
|
if (isTripleArray(posOrX)) {
|
|
6569
|
-
return this.setBlockAt(new
|
|
7156
|
+
return this.setBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
6570
7157
|
}
|
|
6571
7158
|
this.validatePosBounds(posOrX);
|
|
6572
7159
|
const chunk = this.getOrCreateChunkAt(posOrX);
|
|
@@ -6612,14 +7199,14 @@ var MineRenderWorld = class {
|
|
|
6612
7199
|
return this._chunks[index];
|
|
6613
7200
|
}
|
|
6614
7201
|
static worldToScenePosition(pos) {
|
|
6615
|
-
return new
|
|
7202
|
+
return new Vector310(
|
|
6616
7203
|
pos.x * 16,
|
|
6617
7204
|
pos.y * 16,
|
|
6618
7205
|
pos.z * 16
|
|
6619
7206
|
);
|
|
6620
7207
|
}
|
|
6621
7208
|
static sceneToWorldPosition(pos) {
|
|
6622
|
-
return new
|
|
7209
|
+
return new Vector310(
|
|
6623
7210
|
pos.x / 16,
|
|
6624
7211
|
pos.y / 16,
|
|
6625
7212
|
pos.z / 16
|
|
@@ -6648,7 +7235,7 @@ var MineRenderWorld = class {
|
|
|
6648
7235
|
};
|
|
6649
7236
|
|
|
6650
7237
|
// src/world/Chunk.ts
|
|
6651
|
-
var
|
|
7238
|
+
var p11 = prefix("Chunk");
|
|
6652
7239
|
var Chunk = class _Chunk {
|
|
6653
7240
|
constructor(scene, x, y, z) {
|
|
6654
7241
|
this._blocks = [];
|
|
@@ -6661,7 +7248,7 @@ var Chunk = class _Chunk {
|
|
|
6661
7248
|
scene.add(anchor);
|
|
6662
7249
|
anchor.position.set(this.x * 256 + 128 - 8, this.y * 256 + 128 - 8, this.z * 256 + 128 - 8);
|
|
6663
7250
|
addBox3WireframeToObject(
|
|
6664
|
-
new Box32(new
|
|
7251
|
+
new Box32(new Vector311(0, 0, 0), new Vector311(256, 256, 256)),
|
|
6665
7252
|
anchor,
|
|
6666
7253
|
16776960,
|
|
6667
7254
|
4
|
|
@@ -6669,10 +7256,10 @@ var Chunk = class _Chunk {
|
|
|
6669
7256
|
}
|
|
6670
7257
|
getBlockAt(posOrX, y, z) {
|
|
6671
7258
|
if (typeof posOrX == "number") {
|
|
6672
|
-
return this.getBlockAt(new
|
|
7259
|
+
return this.getBlockAt(new Vector311(posOrX, y, z));
|
|
6673
7260
|
}
|
|
6674
7261
|
if (isTripleArray(posOrX)) {
|
|
6675
|
-
return this.getBlockAt(new
|
|
7262
|
+
return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
|
|
6676
7263
|
}
|
|
6677
7264
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
6678
7265
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -6680,10 +7267,10 @@ var Chunk = class _Chunk {
|
|
|
6680
7267
|
}
|
|
6681
7268
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
6682
7269
|
if (typeof posOrX == "number") {
|
|
6683
|
-
return this.setBlockAt(new
|
|
7270
|
+
return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
|
|
6684
7271
|
}
|
|
6685
7272
|
if (isTripleArray(posOrX)) {
|
|
6686
|
-
return this.setBlockAt(new
|
|
7273
|
+
return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
6687
7274
|
}
|
|
6688
7275
|
const worldPos = posOrX;
|
|
6689
7276
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -6700,7 +7287,7 @@ var Chunk = class _Chunk {
|
|
|
6700
7287
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
6701
7288
|
const current = this._blocks[index];
|
|
6702
7289
|
if (typeof current !== "undefined") {
|
|
6703
|
-
console.debug(
|
|
7290
|
+
console.debug(p11, "deleting existing block at", pos, worldPos, index);
|
|
6704
7291
|
current.object.removeFromScene();
|
|
6705
7292
|
delete this._blocks[index];
|
|
6706
7293
|
}
|
|
@@ -6729,7 +7316,7 @@ var Chunk = class _Chunk {
|
|
|
6729
7316
|
}
|
|
6730
7317
|
async clear() {
|
|
6731
7318
|
let promises = [];
|
|
6732
|
-
let pos = new
|
|
7319
|
+
let pos = new Vector311();
|
|
6733
7320
|
for (let x = 0; x < 16; x++) {
|
|
6734
7321
|
for (let z = 0; z < 16; z++) {
|
|
6735
7322
|
for (let y = 0; y < 16; y++) {
|
|
@@ -6748,14 +7335,14 @@ var Chunk = class _Chunk {
|
|
|
6748
7335
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
6749
7336
|
}
|
|
6750
7337
|
worldPosToChunkPos(pos) {
|
|
6751
|
-
return new
|
|
7338
|
+
return new Vector311(
|
|
6752
7339
|
pos.x - this.x * 16,
|
|
6753
7340
|
pos.y - this.y * 16,
|
|
6754
7341
|
pos.z - this.z * 16
|
|
6755
7342
|
);
|
|
6756
7343
|
}
|
|
6757
7344
|
chunkPosToWorldPos(pos) {
|
|
6758
|
-
return new
|
|
7345
|
+
return new Vector311(
|
|
6759
7346
|
this.x * 16 + pos.x,
|
|
6760
7347
|
this.y * 16 + pos.y,
|
|
6761
7348
|
this.z * 16 + pos.z
|
|
@@ -6766,6 +7353,7 @@ export {
|
|
|
6766
7353
|
AXES,
|
|
6767
7354
|
ArchiveAssetSource,
|
|
6768
7355
|
AssetKey,
|
|
7356
|
+
AssetLoadError,
|
|
6769
7357
|
AssetLoader,
|
|
6770
7358
|
AssetParser,
|
|
6771
7359
|
AssetSource,
|
|
@@ -6775,9 +7363,9 @@ export {
|
|
|
6775
7363
|
BUILTIN_GENERATED,
|
|
6776
7364
|
BasicAssetKey,
|
|
6777
7365
|
BatchedExecutor,
|
|
6778
|
-
BlockEntityModels,
|
|
6779
7366
|
BlockObject,
|
|
6780
7367
|
BlockStates,
|
|
7368
|
+
BlockTints,
|
|
6781
7369
|
BrowserArchiveProxy,
|
|
6782
7370
|
BrowserCache,
|
|
6783
7371
|
BrowserEnv,
|
|
@@ -6794,8 +7382,8 @@ export {
|
|
|
6794
7382
|
DISPLAY_POSITIONS,
|
|
6795
7383
|
DefaultBlockStates,
|
|
6796
7384
|
DisplayPosition,
|
|
7385
|
+
DisplayTransforms,
|
|
6797
7386
|
Entities,
|
|
6798
|
-
EntityModels,
|
|
6799
7387
|
EntityObject,
|
|
6800
7388
|
Env,
|
|
6801
7389
|
Geometries,
|
|
@@ -6823,6 +7411,7 @@ export {
|
|
|
6823
7411
|
OrbitControls,
|
|
6824
7412
|
PersistentCache,
|
|
6825
7413
|
Renderer,
|
|
7414
|
+
RequestError,
|
|
6826
7415
|
Requests,
|
|
6827
7416
|
SKIN_PARTS,
|
|
6828
7417
|
SceneInspector,
|
|
@@ -6830,8 +7419,10 @@ export {
|
|
|
6830
7419
|
SceneStats,
|
|
6831
7420
|
SceneStatsDisplay,
|
|
6832
7421
|
SchematicParser,
|
|
7422
|
+
SkinImage,
|
|
6833
7423
|
SkinObject,
|
|
6834
7424
|
SkinPart,
|
|
7425
|
+
SkinTextures,
|
|
6835
7426
|
Skins,
|
|
6836
7427
|
StructureParser,
|
|
6837
7428
|
TextureAtlas,
|
|
@@ -6846,10 +7437,10 @@ export {
|
|
|
6846
7437
|
addWireframeToObject,
|
|
6847
7438
|
applyElementRotation,
|
|
6848
7439
|
applyGenericRotation,
|
|
6849
|
-
applyModelPartRotation,
|
|
6850
7440
|
axisToVec3,
|
|
6851
7441
|
base64decode,
|
|
6852
7442
|
base64encode,
|
|
7443
|
+
capeTextureSizes,
|
|
6853
7444
|
captureException,
|
|
6854
7445
|
changeEvent,
|
|
6855
7446
|
clampRotationDegrees,
|