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.js
CHANGED
|
@@ -28,14 +28,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
mod
|
|
29
29
|
));
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
32
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
33
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
34
|
-
if (decorator = decorators[i])
|
|
35
|
-
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
36
|
-
if (kind && result) __defProp(target, key, result);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
31
|
|
|
40
32
|
// ../../node_modules/ts-deepmerge/dist/index.js
|
|
41
33
|
var require_dist = __commonJS({
|
|
@@ -45,8 +37,8 @@ var require_dist = __commonJS({
|
|
|
45
37
|
__assign = Object.assign || function(t) {
|
|
46
38
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
47
39
|
s = arguments[i];
|
|
48
|
-
for (var
|
|
49
|
-
t[
|
|
40
|
+
for (var p12 in s) if (Object.prototype.hasOwnProperty.call(s, p12))
|
|
41
|
+
t[p12] = s[p12];
|
|
50
42
|
}
|
|
51
43
|
return t;
|
|
52
44
|
};
|
|
@@ -90,7 +82,7 @@ var require_dist = __commonJS({
|
|
|
90
82
|
return false;
|
|
91
83
|
};
|
|
92
84
|
var PROTECTED_KEYS = ["__proto__"];
|
|
93
|
-
var
|
|
85
|
+
var merge10 = function() {
|
|
94
86
|
var objects = [];
|
|
95
87
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
96
88
|
objects[_i] = arguments[_i];
|
|
@@ -101,9 +93,9 @@ var require_dist = __commonJS({
|
|
|
101
93
|
return;
|
|
102
94
|
}
|
|
103
95
|
if (Array.isArray(result[key]) && Array.isArray(current[key])) {
|
|
104
|
-
result[key] =
|
|
96
|
+
result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
|
|
105
97
|
} else if (isObject(result[key]) && isObject(current[key])) {
|
|
106
|
-
result[key] =
|
|
98
|
+
result[key] = merge10(result[key], current[key]);
|
|
107
99
|
} else {
|
|
108
100
|
result[key] = current[key];
|
|
109
101
|
}
|
|
@@ -114,18 +106,18 @@ var require_dist = __commonJS({
|
|
|
114
106
|
var defaultOptions = {
|
|
115
107
|
mergeArrays: true
|
|
116
108
|
};
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
merge10.options = defaultOptions;
|
|
110
|
+
merge10.withOptions = function(options) {
|
|
119
111
|
var objects = [];
|
|
120
112
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
121
113
|
objects[_i - 1] = arguments[_i];
|
|
122
114
|
}
|
|
123
|
-
|
|
124
|
-
var result =
|
|
125
|
-
|
|
115
|
+
merge10.options = __assign({ mergeArrays: true }, options);
|
|
116
|
+
var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
|
|
117
|
+
merge10.options = defaultOptions;
|
|
126
118
|
return result;
|
|
127
119
|
};
|
|
128
|
-
exports.default =
|
|
120
|
+
exports.default = merge10;
|
|
129
121
|
}
|
|
130
122
|
});
|
|
131
123
|
|
|
@@ -135,6 +127,7 @@ __export(index_browser_exports, {
|
|
|
135
127
|
AXES: () => AXES,
|
|
136
128
|
ArchiveAssetSource: () => ArchiveAssetSource,
|
|
137
129
|
AssetKey: () => AssetKey,
|
|
130
|
+
AssetLoadError: () => AssetLoadError,
|
|
138
131
|
AssetLoader: () => AssetLoader,
|
|
139
132
|
AssetParser: () => AssetParser,
|
|
140
133
|
AssetSource: () => AssetSource,
|
|
@@ -144,9 +137,9 @@ __export(index_browser_exports, {
|
|
|
144
137
|
BUILTIN_GENERATED: () => BUILTIN_GENERATED,
|
|
145
138
|
BasicAssetKey: () => BasicAssetKey,
|
|
146
139
|
BatchedExecutor: () => BatchedExecutor,
|
|
147
|
-
BlockEntityModels: () => BlockEntityModels,
|
|
148
140
|
BlockObject: () => BlockObject,
|
|
149
141
|
BlockStates: () => BlockStates,
|
|
142
|
+
BlockTints: () => BlockTints,
|
|
150
143
|
BrowserArchiveProxy: () => BrowserArchiveProxy,
|
|
151
144
|
BrowserCache: () => BrowserCache,
|
|
152
145
|
BrowserEnv: () => BrowserEnv,
|
|
@@ -163,8 +156,8 @@ __export(index_browser_exports, {
|
|
|
163
156
|
DISPLAY_POSITIONS: () => DISPLAY_POSITIONS,
|
|
164
157
|
DefaultBlockStates: () => DefaultBlockStates,
|
|
165
158
|
DisplayPosition: () => DisplayPosition,
|
|
159
|
+
DisplayTransforms: () => DisplayTransforms,
|
|
166
160
|
Entities: () => Entities,
|
|
167
|
-
EntityModels: () => EntityModels,
|
|
168
161
|
EntityObject: () => EntityObject,
|
|
169
162
|
Env: () => Env,
|
|
170
163
|
Geometries: () => Geometries,
|
|
@@ -192,6 +185,7 @@ __export(index_browser_exports, {
|
|
|
192
185
|
OrbitControls: () => OrbitControls,
|
|
193
186
|
PersistentCache: () => PersistentCache,
|
|
194
187
|
Renderer: () => Renderer,
|
|
188
|
+
RequestError: () => RequestError,
|
|
195
189
|
Requests: () => Requests,
|
|
196
190
|
SKIN_PARTS: () => SKIN_PARTS,
|
|
197
191
|
SceneInspector: () => SceneInspector,
|
|
@@ -199,8 +193,10 @@ __export(index_browser_exports, {
|
|
|
199
193
|
SceneStats: () => SceneStats,
|
|
200
194
|
SceneStatsDisplay: () => SceneStatsDisplay,
|
|
201
195
|
SchematicParser: () => SchematicParser,
|
|
196
|
+
SkinImage: () => SkinImage,
|
|
202
197
|
SkinObject: () => SkinObject,
|
|
203
198
|
SkinPart: () => SkinPart,
|
|
199
|
+
SkinTextures: () => SkinTextures,
|
|
204
200
|
Skins: () => Skins,
|
|
205
201
|
StructureParser: () => StructureParser,
|
|
206
202
|
TextureAtlas: () => TextureAtlas,
|
|
@@ -215,10 +211,10 @@ __export(index_browser_exports, {
|
|
|
215
211
|
addWireframeToObject: () => addWireframeToObject,
|
|
216
212
|
applyElementRotation: () => applyElementRotation,
|
|
217
213
|
applyGenericRotation: () => applyGenericRotation,
|
|
218
|
-
applyModelPartRotation: () => applyModelPartRotation,
|
|
219
214
|
axisToVec3: () => axisToVec3,
|
|
220
215
|
base64decode: () => base64decode,
|
|
221
216
|
base64encode: () => base64encode,
|
|
217
|
+
capeTextureSizes: () => capeTextureSizes,
|
|
222
218
|
captureException: () => captureException,
|
|
223
219
|
changeEvent: () => changeEvent,
|
|
224
220
|
clampRotationDegrees: () => clampRotationDegrees,
|
|
@@ -308,17 +304,20 @@ var _PersistentCache = class _PersistentCache {
|
|
|
308
304
|
static open(name) {
|
|
309
305
|
return Env.provider.openCache(name, _PersistentCache.VERSION);
|
|
310
306
|
}
|
|
307
|
+
/** Loads a missing entry and stores only non-nullish results. */
|
|
311
308
|
async getOrLoad(key, loader) {
|
|
312
309
|
let v = await this.get(key);
|
|
313
310
|
if (typeof v === "undefined" || v === null) {
|
|
314
311
|
v = await loader(key);
|
|
315
|
-
|
|
312
|
+
if (typeof v !== "undefined" && v !== null) {
|
|
313
|
+
await this.put(key, v);
|
|
314
|
+
}
|
|
316
315
|
}
|
|
317
316
|
return v;
|
|
318
317
|
}
|
|
319
318
|
};
|
|
320
319
|
/** Bump to invalidate every persisted entry. */
|
|
321
|
-
_PersistentCache.VERSION =
|
|
320
|
+
_PersistentCache.VERSION = 2;
|
|
322
321
|
var PersistentCache = _PersistentCache;
|
|
323
322
|
|
|
324
323
|
// src/env/browser/BrowserCache.ts
|
|
@@ -419,7 +418,8 @@ var BrowserEnv = class {
|
|
|
419
418
|
}
|
|
420
419
|
openCache(name, version) {
|
|
421
420
|
return new BrowserCache(import_localforage.default.createInstance({
|
|
422
|
-
|
|
421
|
+
// IndexedDB schema upgrades retain records; each cache generation needs its own database.
|
|
422
|
+
name: name + version,
|
|
423
423
|
version
|
|
424
424
|
}));
|
|
425
425
|
}
|
|
@@ -436,7 +436,7 @@ registerBrowserEnv();
|
|
|
436
436
|
// src/Axis.ts
|
|
437
437
|
var import_three = require("three");
|
|
438
438
|
var Axis = /* @__PURE__ */ ((Axis3) => {
|
|
439
|
-
Axis3["X"] = "
|
|
439
|
+
Axis3["X"] = "x";
|
|
440
440
|
Axis3["Y"] = "y";
|
|
441
441
|
Axis3["Z"] = "z";
|
|
442
442
|
return Axis3;
|
|
@@ -444,7 +444,7 @@ var Axis = /* @__PURE__ */ ((Axis3) => {
|
|
|
444
444
|
var AXES = Object.values(Axis);
|
|
445
445
|
function axisToVec3(axis) {
|
|
446
446
|
switch (axis) {
|
|
447
|
-
case "
|
|
447
|
+
case "x" /* X */:
|
|
448
448
|
return new import_three.Vector3(1, 0, 0);
|
|
449
449
|
case "y" /* Y */:
|
|
450
450
|
return new import_three.Vector3(0, 1, 0);
|
|
@@ -547,7 +547,10 @@ function serializeMeshKey(key) {
|
|
|
547
547
|
// src/cache/Caching.ts
|
|
548
548
|
var import_loading_cache = require("@inventivetalent/loading-cache");
|
|
549
549
|
var import_time = require("@inventivetalent/time");
|
|
550
|
-
var
|
|
550
|
+
var _Caching = class _Caching {
|
|
551
|
+
static createAssetCache() {
|
|
552
|
+
return import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
553
|
+
}
|
|
551
554
|
/** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
|
|
552
555
|
static get all() {
|
|
553
556
|
return [
|
|
@@ -564,7 +567,12 @@ var Caching = class {
|
|
|
564
567
|
this.rawModelCache,
|
|
565
568
|
this.mergedModelCache,
|
|
566
569
|
this.modelTextureAtlasCache,
|
|
567
|
-
this.blockStateCache
|
|
570
|
+
this.blockStateCache,
|
|
571
|
+
this.listAssetCache,
|
|
572
|
+
this.defaultBlockStatesCache,
|
|
573
|
+
this.blockTintCache,
|
|
574
|
+
this.entityModelCache,
|
|
575
|
+
this.entityTextureCache
|
|
568
576
|
];
|
|
569
577
|
}
|
|
570
578
|
static clear() {
|
|
@@ -575,8 +583,8 @@ var Caching = class {
|
|
|
575
583
|
/**
|
|
576
584
|
* Clears every cache and stops its expiry timer.
|
|
577
585
|
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
586
|
+
* Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
|
|
587
|
+
* Use {@link shutdown} to also stop requests and the shared Ticker.
|
|
580
588
|
*/
|
|
581
589
|
static end() {
|
|
582
590
|
for (const cache of this.all) {
|
|
@@ -590,20 +598,26 @@ var Caching = class {
|
|
|
590
598
|
};
|
|
591
599
|
}
|
|
592
600
|
};
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
601
|
+
_Caching.rawImageCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(5)).buildAsync();
|
|
602
|
+
_Caching.imageDataCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
|
|
603
|
+
_Caching.canvasImageDataCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
|
|
604
|
+
_Caching.wrappedImageCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(10)).buildAsync();
|
|
605
|
+
_Caching.boxGeometryCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(20)).build();
|
|
606
|
+
_Caching.textureCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
|
|
607
|
+
_Caching.materialCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
|
|
608
|
+
_Caching.boxMeshCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).build();
|
|
609
|
+
_Caching.textureAssetCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
610
|
+
_Caching.textureMetaCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
611
|
+
_Caching.rawModelCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
612
|
+
_Caching.mergedModelCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
613
|
+
_Caching.modelTextureAtlasCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
614
|
+
_Caching.blockStateCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
615
|
+
_Caching.listAssetCache = _Caching.createAssetCache();
|
|
616
|
+
_Caching.defaultBlockStatesCache = _Caching.createAssetCache();
|
|
617
|
+
_Caching.blockTintCache = _Caching.createAssetCache();
|
|
618
|
+
_Caching.entityModelCache = _Caching.createAssetCache();
|
|
619
|
+
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
620
|
+
var Caching = _Caching;
|
|
607
621
|
|
|
608
622
|
// src/Geometries.ts
|
|
609
623
|
var Geometries = class _Geometries {
|
|
@@ -624,13 +638,14 @@ var Geometries = class _Geometries {
|
|
|
624
638
|
};
|
|
625
639
|
|
|
626
640
|
// src/Materials.ts
|
|
627
|
-
var
|
|
641
|
+
var import_three5 = require("three");
|
|
628
642
|
|
|
629
643
|
// src/texture/Textures.ts
|
|
630
|
-
var
|
|
644
|
+
var import_three4 = require("three");
|
|
631
645
|
|
|
632
646
|
// src/texture/TextureLoader.ts
|
|
633
|
-
var
|
|
647
|
+
var import_three3 = require("three");
|
|
648
|
+
var THREE = __toESM(require("three"));
|
|
634
649
|
|
|
635
650
|
// src/canvas/CanvasCompat.ts
|
|
636
651
|
function createImage(width, height) {
|
|
@@ -641,9 +656,7 @@ function createCanvas(width, height) {
|
|
|
641
656
|
}
|
|
642
657
|
|
|
643
658
|
// src/request/Requests.ts
|
|
644
|
-
var import_axios = __toESM(require("axios"));
|
|
645
659
|
var import_jobqu = require("jobqu");
|
|
646
|
-
var import_time2 = require("@inventivetalent/time");
|
|
647
660
|
|
|
648
661
|
// src/util/log.ts
|
|
649
662
|
var Reset = "\x1B[0m";
|
|
@@ -653,198 +666,170 @@ function prefix(prefix2) {
|
|
|
653
666
|
return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
|
|
654
667
|
}
|
|
655
668
|
|
|
656
|
-
// src/
|
|
657
|
-
var
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
this.
|
|
662
|
-
this.
|
|
663
|
-
|
|
664
|
-
submit(task) {
|
|
665
|
-
this.queue.push(task);
|
|
666
|
-
}
|
|
667
|
-
run() {
|
|
668
|
-
for (let i = 0; i < this.batch; i++) {
|
|
669
|
-
this.runNext();
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
runNext() {
|
|
673
|
-
let next = this.queue.shift();
|
|
674
|
-
if (next) next();
|
|
669
|
+
// src/request/Requests.ts
|
|
670
|
+
var p = prefix("Requests");
|
|
671
|
+
var RequestError = class extends Error {
|
|
672
|
+
constructor(message, response, cause) {
|
|
673
|
+
super(message);
|
|
674
|
+
this.response = response;
|
|
675
|
+
this.cause = cause;
|
|
676
|
+
this.name = "RequestError";
|
|
675
677
|
}
|
|
676
678
|
};
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
|
|
679
|
+
async function fetchRequest(config, defaultBaseURL) {
|
|
680
|
+
const { url, baseURL = defaultBaseURL, timeout = 5e3, responseType = "json", signal, ...options } = config;
|
|
681
|
+
const target = baseURL && !/^([a-z][a-z\d+.-]*:|\/\/)/i.test(url) ? `${baseURL.replace(/\/+$/, "")}/${url.replace(/^\/+/, "")}` : url;
|
|
682
|
+
const headers = new Headers(options.headers);
|
|
683
|
+
if (typeof window === "undefined" && !headers.has("User-Agent")) {
|
|
684
|
+
headers.set("User-Agent", "MineRender");
|
|
685
|
+
}
|
|
686
|
+
const attemptSignal = AbortSignal.any([
|
|
687
|
+
...signal ? [signal] : [],
|
|
688
|
+
...timeout === 0 ? [] : [AbortSignal.timeout(timeout)]
|
|
689
|
+
]);
|
|
690
|
+
const request = new Request(target, { ...options, headers, signal: attemptSignal });
|
|
691
|
+
attemptSignal.throwIfAborted();
|
|
692
|
+
try {
|
|
693
|
+
const response = await fetch(request);
|
|
694
|
+
const result = {
|
|
695
|
+
data: void 0,
|
|
696
|
+
status: response.status,
|
|
697
|
+
statusText: response.statusText,
|
|
698
|
+
headers: response.headers,
|
|
699
|
+
url: response.url
|
|
700
|
+
};
|
|
701
|
+
if (!response.ok) {
|
|
702
|
+
await response.body?.cancel().catch(() => {
|
|
703
|
+
});
|
|
704
|
+
throw new RequestError(`Request failed with status ${response.status}`, result);
|
|
701
705
|
}
|
|
706
|
+
const emptyBody = request.method === "HEAD" || response.status === 204 || response.status === 205;
|
|
707
|
+
const data = responseType === "arraybuffer" ? await response.arrayBuffer() : emptyBody || response.body === null ? void 0 : await response.json();
|
|
708
|
+
return { ...result, data };
|
|
709
|
+
} catch (error) {
|
|
710
|
+
attemptSignal.throwIfAborted();
|
|
711
|
+
if (/^https?:/.test(request.url) && request.redirect !== "error" && error instanceof TypeError) {
|
|
712
|
+
throw new RequestError("Network request failed", void 0, error);
|
|
713
|
+
}
|
|
714
|
+
throw error;
|
|
702
715
|
}
|
|
703
|
-
geometry.translate(origin.x, origin.y, origin.z);
|
|
704
|
-
}
|
|
705
|
-
function applyModelPartRotation(modelPart, geometry) {
|
|
706
|
-
const origin = new import_three3.Vector3(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
|
|
707
|
-
geometry.translate(-origin.x, -origin.y, -origin.z);
|
|
708
|
-
geometry.rotateX(toRadians(modelPart.pitch));
|
|
709
|
-
geometry.rotateY(toRadians(modelPart.yaw));
|
|
710
|
-
geometry.rotateZ(toRadians(modelPart.roll));
|
|
711
|
-
geometry.translate(origin.x, origin.y, origin.z);
|
|
712
716
|
}
|
|
713
|
-
function
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
717
|
+
async function abortable(promise, signal) {
|
|
718
|
+
if (!signal) return promise;
|
|
719
|
+
let abort;
|
|
720
|
+
const cancelled = new Promise((_, reject) => {
|
|
721
|
+
abort = () => reject(signal.reason);
|
|
722
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
723
|
+
if (signal.aborted) abort();
|
|
724
|
+
});
|
|
725
|
+
try {
|
|
726
|
+
return await Promise.race([promise, cancelled]);
|
|
727
|
+
} finally {
|
|
728
|
+
signal.removeEventListener("abort", abort);
|
|
724
729
|
}
|
|
725
730
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
let axes = new import_three3.AxesHelper(1);
|
|
735
|
-
obj.add(axes);
|
|
736
|
-
}
|
|
737
|
-
function addWireframeToObject(obj, color = 16777215, w = 2) {
|
|
738
|
-
let boxGeo = new import_three3.BoxGeometry(16, 16, 16, 1, 1, 1);
|
|
739
|
-
let wireGeo = new import_three3.EdgesGeometry(boxGeo);
|
|
740
|
-
let wireMat = new import_three3.LineBasicMaterial({ color, linewidth: w });
|
|
741
|
-
let wireframe = new import_three3.LineSegments(wireGeo, wireMat);
|
|
742
|
-
obj.add(wireframe);
|
|
743
|
-
let axes = new import_three3.AxesHelper(1);
|
|
744
|
-
obj.add(axes);
|
|
745
|
-
}
|
|
746
|
-
function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
|
|
747
|
-
let wireGeo = new import_three3.EdgesGeometry(geo);
|
|
748
|
-
let wireMat = new import_three3.LineBasicMaterial({ color, linewidth: w });
|
|
749
|
-
let wireframe = new import_three3.LineSegments(wireGeo, wireMat);
|
|
750
|
-
mesh.add(wireframe);
|
|
751
|
-
let axes = new import_three3.AxesHelper(1);
|
|
752
|
-
mesh.add(axes);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
// src/util/performance.ts
|
|
756
|
-
function captureException(e, ...extra) {
|
|
757
|
-
console.error(e, extra);
|
|
758
|
-
}
|
|
759
|
-
function timingStart(marker) {
|
|
760
|
-
console.time(marker);
|
|
761
|
-
}
|
|
762
|
-
function timingEnd(marker) {
|
|
763
|
-
console.timeEnd(marker);
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
// src/util/three.ts
|
|
767
|
-
function isObject3D(obj) {
|
|
768
|
-
return obj.isObject3D;
|
|
769
|
-
}
|
|
770
|
-
function isMesh(obj) {
|
|
771
|
-
return obj.isMesh;
|
|
772
|
-
}
|
|
773
|
-
function isInstancedMesh(obj) {
|
|
774
|
-
return obj.isInstancedMesh;
|
|
775
|
-
}
|
|
776
|
-
function isPerspectiveCamera(obj) {
|
|
777
|
-
return obj.isPerspectiveCamera;
|
|
778
|
-
}
|
|
779
|
-
function isOrthographicCamera(obj) {
|
|
780
|
-
return obj.isOrthographicCamera;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// src/request/Requests.ts
|
|
784
|
-
var p = prefix("Requests");
|
|
785
|
-
if (typeof window === "undefined") {
|
|
786
|
-
import_axios.default.defaults.headers["User-Agent"] = "MineRender";
|
|
787
|
-
}
|
|
788
|
-
var _Requests = class _Requests {
|
|
789
|
-
static genericRequest(request) {
|
|
790
|
-
return this.genericQueue.add(request).catch(async (e) => {
|
|
791
|
-
console.debug(p, "generic catch", e.code, e);
|
|
792
|
-
if (this.shouldRetry(e, request)) {
|
|
793
|
-
await sleep(100);
|
|
794
|
-
return this.genericRequest(request);
|
|
795
|
-
}
|
|
796
|
-
throw e;
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
static mcAssetRequest(request) {
|
|
800
|
-
return this.mcAssetRequestQueue.add(request).catch((e) => {
|
|
801
|
-
console.debug(p, "mcAssetRequest catch", e.code, e);
|
|
802
|
-
throw e;
|
|
803
|
-
});
|
|
731
|
+
var RequestQueue = class {
|
|
732
|
+
constructor() {
|
|
733
|
+
this.pendingRequests = 0;
|
|
734
|
+
this.stopped = new AbortController();
|
|
735
|
+
this.queue = new import_jobqu.JobQueue(
|
|
736
|
+
(request) => fetchRequest(request, this.baseURL),
|
|
737
|
+
{ interval: 10, maxPerRun: 1, maxActive: 8 }
|
|
738
|
+
);
|
|
804
739
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
740
|
+
async request(request) {
|
|
741
|
+
this.pendingRequests++;
|
|
742
|
+
const signal = request.signal;
|
|
743
|
+
try {
|
|
744
|
+
for (let retries = 0; ; retries++) {
|
|
745
|
+
signal?.throwIfAborted();
|
|
746
|
+
try {
|
|
747
|
+
return await abortable(this.queue.add(request), signal);
|
|
748
|
+
} catch (error) {
|
|
749
|
+
console.debug(p, "Request failed", error);
|
|
750
|
+
const delay = this.retryDelay(error, request, retries);
|
|
751
|
+
if (delay === void 0) {
|
|
752
|
+
throw error;
|
|
812
753
|
}
|
|
813
|
-
|
|
814
|
-
request["minerenderRetry"] = 3;
|
|
815
|
-
return true;
|
|
754
|
+
await this.waitForRetry(delay, signal);
|
|
816
755
|
}
|
|
817
756
|
}
|
|
757
|
+
} finally {
|
|
758
|
+
if (signal?.aborted) {
|
|
759
|
+
this.queue.remove(request);
|
|
760
|
+
}
|
|
761
|
+
this.pendingRequests--;
|
|
818
762
|
}
|
|
819
|
-
|
|
763
|
+
}
|
|
764
|
+
retryDelay(error, request, retries) {
|
|
765
|
+
if (this.stopped.signal.aborted || retries >= 3 || (request.method ?? "get").toLowerCase() !== "get" || request.signal?.aborted) {
|
|
766
|
+
return void 0;
|
|
767
|
+
}
|
|
768
|
+
if (error instanceof RequestError) {
|
|
769
|
+
const status = error.response?.status;
|
|
770
|
+
if (status !== void 0 && status !== 408 && status !== 429 && !(status >= 500 && status < 600)) return void 0;
|
|
771
|
+
} else if (!(error instanceof DOMException && error.name === "TimeoutError")) {
|
|
772
|
+
return void 0;
|
|
773
|
+
}
|
|
774
|
+
let delay = 100 * 2 ** retries;
|
|
775
|
+
const retryAfter = error instanceof RequestError ? error.response?.headers.get("Retry-After") : void 0;
|
|
776
|
+
if (retryAfter !== void 0 && retryAfter !== null) {
|
|
777
|
+
const seconds = Number(retryAfter);
|
|
778
|
+
if (!retryAfter.trim() || !Number.isFinite(seconds) || seconds < 0) {
|
|
779
|
+
return void 0;
|
|
780
|
+
}
|
|
781
|
+
delay = Math.max(delay, seconds * 1e3);
|
|
782
|
+
}
|
|
783
|
+
return delay;
|
|
784
|
+
}
|
|
785
|
+
async waitForRetry(delay, signal) {
|
|
786
|
+
let timer;
|
|
787
|
+
const waiting = new Promise((resolve) => {
|
|
788
|
+
timer = setTimeout(resolve, delay);
|
|
789
|
+
});
|
|
790
|
+
try {
|
|
791
|
+
await abortable(waiting, AbortSignal.any([this.stopped.signal, ...signal ? [signal] : []]));
|
|
792
|
+
} finally {
|
|
793
|
+
clearTimeout(timer);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
get pendingSize() {
|
|
797
|
+
return this.pendingRequests;
|
|
798
|
+
}
|
|
799
|
+
end() {
|
|
800
|
+
this.queue.end();
|
|
801
|
+
this.stopped.abort(new import_jobqu.JobCancelledError("ended"));
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
var Requests = class {
|
|
805
|
+
static genericRequest(request) {
|
|
806
|
+
return this.genericQueue.request(request);
|
|
807
|
+
}
|
|
808
|
+
static mcAssetRequest(request) {
|
|
809
|
+
return this.mcAssetRequestQueue.request(request);
|
|
820
810
|
}
|
|
821
811
|
static setMcAssetRoot(root) {
|
|
822
|
-
this.
|
|
812
|
+
this.mcAssetRequestQueue.baseURL = root;
|
|
823
813
|
}
|
|
814
|
+
/** Counts unsettled calls, including retry delays and requests still running after shutdown. */
|
|
824
815
|
static get queueSizes() {
|
|
825
816
|
return {
|
|
826
|
-
generic: this.genericQueue.
|
|
827
|
-
mcAsset: this.mcAssetRequestQueue.
|
|
817
|
+
generic: this.genericQueue.pendingSize,
|
|
818
|
+
mcAsset: this.mcAssetRequestQueue.pendingSize
|
|
828
819
|
};
|
|
829
820
|
}
|
|
830
821
|
/**
|
|
831
|
-
*
|
|
832
|
-
*
|
|
822
|
+
* Permanently stops both queues and rejects waiting, retrying, and future requests.
|
|
823
|
+
* Requests already running can finish. Idle queues hold no timer, so Node can exit without
|
|
824
|
+
* this cleanup. See {@link shutdown}.
|
|
833
825
|
*/
|
|
834
826
|
static end() {
|
|
835
827
|
this.genericQueue.end();
|
|
836
828
|
this.mcAssetRequestQueue.end();
|
|
837
829
|
}
|
|
838
830
|
};
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
});
|
|
842
|
-
_Requests.mcAssetInstance = import_axios.default.create({
|
|
843
|
-
timeout: 5e3
|
|
844
|
-
});
|
|
845
|
-
_Requests.genericQueue = new import_jobqu.JobQueue((request) => _Requests.axiosInstance.request(request), import_time2.Time.millis(10), 1);
|
|
846
|
-
_Requests.mcAssetRequestQueue = new import_jobqu.JobQueue((request) => _Requests.mcAssetInstance.request(request), import_time2.Time.millis(10), 1);
|
|
847
|
-
var Requests = _Requests;
|
|
831
|
+
Requests.genericQueue = new RequestQueue();
|
|
832
|
+
Requests.mcAssetRequestQueue = new RequestQueue();
|
|
848
833
|
|
|
849
834
|
// src/WrappedImage.ts
|
|
850
835
|
var WrappedImage = class {
|
|
@@ -882,10 +867,10 @@ var WrappedImage = class {
|
|
|
882
867
|
return this.animated ? this.width : this.height;
|
|
883
868
|
}
|
|
884
869
|
get frameCount() {
|
|
885
|
-
return this.height / this.
|
|
870
|
+
return this.height / this.frameHeight;
|
|
886
871
|
}
|
|
887
872
|
getFrameY(frame) {
|
|
888
|
-
return this.
|
|
873
|
+
return this.frameHeight * Math.max(0, Math.min(this.frameCount - 1, frame));
|
|
889
874
|
}
|
|
890
875
|
getSectionData(sx, sy, sw, sh) {
|
|
891
876
|
return this.dta.data.getImageData(sx, sy, sw, sh);
|
|
@@ -895,7 +880,7 @@ var WrappedImage = class {
|
|
|
895
880
|
}
|
|
896
881
|
getFrameSectionData(frame) {
|
|
897
882
|
const y = this.getFrameY(frame);
|
|
898
|
-
return this.getSectionData(0, y, this.
|
|
883
|
+
return this.getSectionData(0, y, this.frameWidth, this.frameHeight);
|
|
899
884
|
}
|
|
900
885
|
};
|
|
901
886
|
|
|
@@ -909,29 +894,41 @@ var ImageLoader = class _ImageLoader {
|
|
|
909
894
|
static async loadAsync(src) {
|
|
910
895
|
return new Promise((resolve, reject) => {
|
|
911
896
|
const image = this._createImage();
|
|
912
|
-
image.src = src;
|
|
913
897
|
image.onload = () => resolve(image);
|
|
914
|
-
image.onerror = (err) => reject(err);
|
|
898
|
+
image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
|
|
899
|
+
image.src = src;
|
|
915
900
|
});
|
|
916
901
|
}
|
|
917
902
|
static loadElement(src, onload, onerr) {
|
|
918
903
|
const image = this._createImage();
|
|
919
|
-
image.src = src;
|
|
920
904
|
if (onload)
|
|
921
905
|
image.onload = onload;
|
|
922
906
|
if (onerr)
|
|
923
907
|
image.onerror = onerr;
|
|
908
|
+
image.src = src;
|
|
924
909
|
return image;
|
|
925
910
|
}
|
|
926
911
|
static async loadData(src) {
|
|
927
912
|
console.debug(p2, "loadData", src);
|
|
928
|
-
|
|
913
|
+
const image = await this.loadCanvasData(src);
|
|
914
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
929
915
|
}
|
|
930
916
|
static async loadCanvasData(src) {
|
|
931
|
-
|
|
917
|
+
const keyStr = serializeImageKey({ src });
|
|
918
|
+
const info = this.getInfo(src);
|
|
919
|
+
const cached = Caching.rawImageCache.getIfPresent(keyStr);
|
|
920
|
+
try {
|
|
921
|
+
return await this.infoToCanvasData(await info);
|
|
922
|
+
} catch (err) {
|
|
923
|
+
if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
|
|
924
|
+
Caching.rawImageCache.invalidate(keyStr);
|
|
925
|
+
}
|
|
926
|
+
throw err;
|
|
927
|
+
}
|
|
932
928
|
}
|
|
933
929
|
static async infoToCanvasData(info) {
|
|
934
|
-
const
|
|
930
|
+
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
931
|
+
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
935
932
|
const canvas = createCanvas(info.width, info.height);
|
|
936
933
|
const context = canvas.getContext("2d");
|
|
937
934
|
context.drawImage(image, 0, 0);
|
|
@@ -942,11 +939,8 @@ var ImageLoader = class _ImageLoader {
|
|
|
942
939
|
};
|
|
943
940
|
}
|
|
944
941
|
static async infoToData(info) {
|
|
945
|
-
const image = await
|
|
946
|
-
|
|
947
|
-
const context = canvas.getContext("2d");
|
|
948
|
-
context.drawImage(image, 0, 0);
|
|
949
|
-
return context.getImageData(0, 0, canvas.width, canvas.height);
|
|
942
|
+
const image = await this.infoToCanvasData(info);
|
|
943
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
950
944
|
}
|
|
951
945
|
static async getData(src) {
|
|
952
946
|
const keyStr = serializeImageKey({ src });
|
|
@@ -961,38 +955,25 @@ var ImageLoader = class _ImageLoader {
|
|
|
961
955
|
});
|
|
962
956
|
}
|
|
963
957
|
static async processResponse(response) {
|
|
964
|
-
const src = response.
|
|
958
|
+
const src = response.url;
|
|
965
959
|
const data = import_buffer.Buffer.from(response.data);
|
|
966
960
|
const { width, height, type } = Env.provider.imageSize(data);
|
|
961
|
+
if (!width || !height) {
|
|
962
|
+
throw new Error("Invalid or unsupported image dimensions");
|
|
963
|
+
}
|
|
967
964
|
return {
|
|
968
965
|
src,
|
|
969
|
-
width
|
|
970
|
-
height
|
|
966
|
+
width,
|
|
967
|
+
height,
|
|
971
968
|
type,
|
|
972
969
|
data
|
|
973
970
|
};
|
|
974
971
|
}
|
|
975
972
|
static async loadInfo(src) {
|
|
976
|
-
if (src.startsWith("data:image/png;base64")) {
|
|
977
|
-
return this.processResponse({
|
|
978
|
-
config: {
|
|
979
|
-
url: src
|
|
980
|
-
},
|
|
981
|
-
data: import_buffer.Buffer.from(src.substr("data:image/png;base64,".length), "base64")
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
973
|
return Requests.genericRequest({
|
|
985
974
|
url: src,
|
|
986
975
|
responseType: "arraybuffer"
|
|
987
|
-
}).then(this.processResponse)
|
|
988
|
-
return {
|
|
989
|
-
src,
|
|
990
|
-
width: 0,
|
|
991
|
-
height: 0,
|
|
992
|
-
type: void 0,
|
|
993
|
-
data: import_buffer.Buffer.from([0])
|
|
994
|
-
};
|
|
995
|
-
});
|
|
976
|
+
}).then(this.processResponse);
|
|
996
977
|
}
|
|
997
978
|
static async getInfo(src) {
|
|
998
979
|
const keyStr = serializeImageKey({ src });
|
|
@@ -1014,38 +995,50 @@ var ImageLoader = class _ImageLoader {
|
|
|
1014
995
|
|
|
1015
996
|
// src/texture/TextureLoader.ts
|
|
1016
997
|
var TextureLoader = class {
|
|
998
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
999
|
+
static hasFailed(texture) {
|
|
1000
|
+
return this.failedTextures.has(texture);
|
|
1001
|
+
}
|
|
1017
1002
|
static createTexture() {
|
|
1018
|
-
return new
|
|
1003
|
+
return new import_three3.Texture();
|
|
1019
1004
|
}
|
|
1020
|
-
static loadInBackground(src, format =
|
|
1005
|
+
static loadInBackground(src, format = import_three3.RGBAFormat, rotation = 0) {
|
|
1021
1006
|
const texture = this.createTexture();
|
|
1022
|
-
|
|
1023
|
-
image
|
|
1007
|
+
texture.colorSpace = THREE.SRGBColorSpace;
|
|
1008
|
+
const image = ImageLoader.loadElement(src, () => {
|
|
1024
1009
|
texture.needsUpdate = true;
|
|
1025
|
-
}
|
|
1010
|
+
}, (error) => {
|
|
1011
|
+
this.failedTextures.add(texture);
|
|
1012
|
+
console.warn("Failed to load texture", src, error);
|
|
1013
|
+
});
|
|
1026
1014
|
texture.image = image;
|
|
1027
1015
|
texture.format = format;
|
|
1028
1016
|
texture.rotation = rotation;
|
|
1029
1017
|
return Textures.initTextureProps(texture);
|
|
1030
1018
|
}
|
|
1031
|
-
static load(src, format =
|
|
1032
|
-
const texture = new
|
|
1019
|
+
static load(src, format = import_three3.RGBAFormat, rotation = 0) {
|
|
1020
|
+
const texture = new import_three3.Texture();
|
|
1021
|
+
texture.colorSpace = THREE.SRGBColorSpace;
|
|
1033
1022
|
ImageLoader.getData(src).then((image) => {
|
|
1034
|
-
texture.needsUpdate = true;
|
|
1035
1023
|
texture.image = image;
|
|
1024
|
+
texture.needsUpdate = true;
|
|
1025
|
+
}).catch((error) => {
|
|
1026
|
+
this.failedTextures.add(texture);
|
|
1027
|
+
console.warn("Failed to load texture", src, error);
|
|
1036
1028
|
});
|
|
1037
1029
|
texture.format = format;
|
|
1038
1030
|
texture.rotation = rotation;
|
|
1039
1031
|
return Textures.initTextureProps(texture);
|
|
1040
1032
|
}
|
|
1041
1033
|
};
|
|
1034
|
+
TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
|
|
1042
1035
|
|
|
1043
1036
|
// src/texture/Textures.ts
|
|
1044
|
-
var
|
|
1037
|
+
var THREE2 = __toESM(require("three"));
|
|
1045
1038
|
var Textures = class _Textures {
|
|
1046
1039
|
static initTextureProps(texture) {
|
|
1047
|
-
texture.magFilter =
|
|
1048
|
-
texture.minFilter =
|
|
1040
|
+
texture.magFilter = THREE2.NearestFilter;
|
|
1041
|
+
texture.minFilter = THREE2.NearestFilter;
|
|
1049
1042
|
texture.anisotropy = 0;
|
|
1050
1043
|
return texture;
|
|
1051
1044
|
}
|
|
@@ -1053,13 +1046,19 @@ var Textures = class _Textures {
|
|
|
1053
1046
|
return TextureLoader.load(key.src, key.format, key.rotation);
|
|
1054
1047
|
}
|
|
1055
1048
|
static createAsset(key) {
|
|
1056
|
-
return new
|
|
1049
|
+
return new import_three4.Texture();
|
|
1057
1050
|
}
|
|
1058
1051
|
static createCanvasTexture(canvas) {
|
|
1059
|
-
|
|
1052
|
+
const texture = new import_three4.CanvasTexture(canvas);
|
|
1053
|
+
texture.colorSpace = THREE2.SRGBColorSpace;
|
|
1054
|
+
return this.initTextureProps(texture);
|
|
1060
1055
|
}
|
|
1061
1056
|
static getImage(key) {
|
|
1062
1057
|
const keyStr = serializeTextureKey(key);
|
|
1058
|
+
const cached = Caching.textureCache.peek(keyStr);
|
|
1059
|
+
if (cached && TextureLoader.hasFailed(cached)) {
|
|
1060
|
+
Caching.textureCache.invalidate(keyStr);
|
|
1061
|
+
}
|
|
1063
1062
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
1064
1063
|
return _Textures.createImage(key);
|
|
1065
1064
|
});
|
|
@@ -1075,26 +1074,26 @@ var _Materials = class _Materials {
|
|
|
1075
1074
|
}
|
|
1076
1075
|
static createImage(key) {
|
|
1077
1076
|
const transparent = key.transparent || false;
|
|
1078
|
-
return new
|
|
1077
|
+
return new import_three5.MeshBasicMaterial({
|
|
1079
1078
|
map: Textures.getImage(key.texture),
|
|
1080
1079
|
transparent,
|
|
1081
|
-
side: transparent ?
|
|
1080
|
+
side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
|
|
1082
1081
|
alphaTest: 0.5
|
|
1083
1082
|
});
|
|
1084
1083
|
}
|
|
1085
1084
|
static createBasicCanvasMaterial(canvas, transparent = false, shade = false) {
|
|
1086
1085
|
if (shade) {
|
|
1087
|
-
return new
|
|
1086
|
+
return new import_three5.MeshStandardMaterial({
|
|
1088
1087
|
map: Textures.createCanvasTexture(canvas),
|
|
1089
1088
|
transparent,
|
|
1090
|
-
side: transparent ?
|
|
1089
|
+
side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
|
|
1091
1090
|
alphaTest: 0.5
|
|
1092
1091
|
});
|
|
1093
1092
|
}
|
|
1094
|
-
return new
|
|
1093
|
+
return new import_three5.MeshBasicMaterial({
|
|
1095
1094
|
map: Textures.createCanvasTexture(canvas),
|
|
1096
1095
|
transparent,
|
|
1097
|
-
side: transparent ?
|
|
1096
|
+
side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
|
|
1098
1097
|
alphaTest: 0.5
|
|
1099
1098
|
});
|
|
1100
1099
|
}
|
|
@@ -1103,6 +1102,7 @@ var _Materials = class _Materials {
|
|
|
1103
1102
|
uniform bool SHADE;
|
|
1104
1103
|
|
|
1105
1104
|
varying vec2 vUv;
|
|
1105
|
+
varying vec3 vTint;
|
|
1106
1106
|
varying float light;
|
|
1107
1107
|
varying float lift;
|
|
1108
1108
|
|
|
@@ -1115,7 +1115,11 @@ var _Materials = class _Materials {
|
|
|
1115
1115
|
|
|
1116
1116
|
if (SHADE) {
|
|
1117
1117
|
|
|
1118
|
-
|
|
1118
|
+
#ifdef USE_INSTANCING
|
|
1119
|
+
vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
|
|
1120
|
+
#else
|
|
1121
|
+
vec3 N = vec3( modelMatrix * vec4(normal, 0.0) );
|
|
1122
|
+
#endif
|
|
1119
1123
|
|
|
1120
1124
|
float yLight = (1.0+N.y) * 0.5;
|
|
1121
1125
|
light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT;
|
|
@@ -1133,6 +1137,7 @@ var _Materials = class _Materials {
|
|
|
1133
1137
|
}
|
|
1134
1138
|
|
|
1135
1139
|
vUv = uv;
|
|
1140
|
+
vTint = color;
|
|
1136
1141
|
|
|
1137
1142
|
#ifdef USE_INSTANCING
|
|
1138
1143
|
gl_Position = projectionMatrix * viewMatrix * modelMatrix * instanceMatrix * vec4(position, 1.0);
|
|
@@ -1154,12 +1159,14 @@ var _Materials = class _Materials {
|
|
|
1154
1159
|
uniform float BRIGHTNESS;
|
|
1155
1160
|
|
|
1156
1161
|
varying vec2 vUv;
|
|
1162
|
+
varying vec3 vTint;
|
|
1157
1163
|
varying float light;
|
|
1158
1164
|
varying float lift;
|
|
1159
1165
|
|
|
1160
1166
|
void main(void)
|
|
1161
1167
|
{
|
|
1162
1168
|
vec4 color = texture2D(map, vUv);
|
|
1169
|
+
color.rgb *= vTint;
|
|
1163
1170
|
|
|
1164
1171
|
if (color.a < 0.01) discard;
|
|
1165
1172
|
|
|
@@ -1173,16 +1180,19 @@ var _Materials = class _Materials {
|
|
|
1173
1180
|
gl_FragColor = vec4(lift + color.rgb * light2, 1.0);
|
|
1174
1181
|
|
|
1175
1182
|
}
|
|
1183
|
+
|
|
1184
|
+
#include <tonemapping_fragment>
|
|
1185
|
+
#include <colorspace_fragment>
|
|
1176
1186
|
}
|
|
1177
1187
|
`;
|
|
1178
1188
|
try {
|
|
1179
|
-
return new
|
|
1189
|
+
return new import_three5.ShaderMaterial({
|
|
1180
1190
|
uniforms: {
|
|
1181
1191
|
SHADE: { value: true },
|
|
1182
1192
|
BRIGHTNESS: { value: 1 },
|
|
1183
1193
|
EMISSIVE: { value: false },
|
|
1184
1194
|
base: {
|
|
1185
|
-
value: new
|
|
1195
|
+
value: new import_three5.Color(12698049)
|
|
1186
1196
|
/*TODO*/
|
|
1187
1197
|
},
|
|
1188
1198
|
map: { value: Textures.createCanvasTexture(canvas) }
|
|
@@ -1191,7 +1201,7 @@ var _Materials = class _Materials {
|
|
|
1191
1201
|
fragmentShader: fragShader,
|
|
1192
1202
|
vertexColors: true,
|
|
1193
1203
|
transparent,
|
|
1194
|
-
side: transparent ?
|
|
1204
|
+
side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
|
|
1195
1205
|
alphaTest: 0.5
|
|
1196
1206
|
});
|
|
1197
1207
|
} catch (e) {
|
|
@@ -1201,6 +1211,10 @@ var _Materials = class _Materials {
|
|
|
1201
1211
|
}
|
|
1202
1212
|
static getImage(key) {
|
|
1203
1213
|
const keyStr = serializeMaterialKey(key);
|
|
1214
|
+
const map = Caching.materialCache.peek(keyStr)?.map;
|
|
1215
|
+
if (map && TextureLoader.hasFailed(map)) {
|
|
1216
|
+
Caching.materialCache.invalidate(keyStr);
|
|
1217
|
+
}
|
|
1204
1218
|
return Caching.materialCache.get(keyStr, (k) => {
|
|
1205
1219
|
return _Materials.createImage(key);
|
|
1206
1220
|
});
|
|
@@ -1225,10 +1239,10 @@ _Materials.MISSING_TEXTURE_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA
|
|
|
1225
1239
|
var Materials = _Materials;
|
|
1226
1240
|
|
|
1227
1241
|
// src/Meshes.ts
|
|
1228
|
-
var
|
|
1242
|
+
var import_three6 = require("three");
|
|
1229
1243
|
var Meshes = class _Meshes {
|
|
1230
1244
|
static createBox(key) {
|
|
1231
|
-
return new
|
|
1245
|
+
return new import_three6.Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
|
|
1232
1246
|
}
|
|
1233
1247
|
static getBox(key) {
|
|
1234
1248
|
const keyStr = serializeMeshKey(key);
|
|
@@ -1239,7 +1253,7 @@ var Meshes = class _Meshes {
|
|
|
1239
1253
|
};
|
|
1240
1254
|
|
|
1241
1255
|
// src/UVMapper.ts
|
|
1242
|
-
var
|
|
1256
|
+
var import_three9 = require("three");
|
|
1243
1257
|
|
|
1244
1258
|
// src/model/ModelMerger.ts
|
|
1245
1259
|
var import_ts_deepmerge = __toESM(require_dist());
|
|
@@ -1275,6 +1289,7 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1275
1289
|
this.rootType = rootType;
|
|
1276
1290
|
this.extension = extension;
|
|
1277
1291
|
this.root = root;
|
|
1292
|
+
this.isAssetKey = true;
|
|
1278
1293
|
}
|
|
1279
1294
|
static parse(assetType, str, origin) {
|
|
1280
1295
|
let namespace = origin?.namespace || DEFAULT_NAMESPACE;
|
|
@@ -1290,12 +1305,15 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1290
1305
|
split.shift();
|
|
1291
1306
|
}
|
|
1292
1307
|
let path = split.join("/");
|
|
1293
|
-
|
|
1308
|
+
const extension = assetType === "textures" ? ".png" : origin?.extension ?? ".json";
|
|
1309
|
+
if (extension && path.endsWith(extension)) {
|
|
1310
|
+
path = path.slice(0, -extension.length);
|
|
1311
|
+
}
|
|
1294
1312
|
return new _AssetKey(namespace, path, assetType, type, "assets", extension, origin?.root);
|
|
1295
1313
|
}
|
|
1296
1314
|
toString() {
|
|
1297
1315
|
let a = [
|
|
1298
|
-
|
|
1316
|
+
this.root ?? AssetLoader.ROOT,
|
|
1299
1317
|
this.rootType ?? "__rootType__",
|
|
1300
1318
|
this.assetType ?? "__assetType__",
|
|
1301
1319
|
this.type ?? "__type__",
|
|
@@ -1305,12 +1323,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1305
1323
|
return a.join("/");
|
|
1306
1324
|
}
|
|
1307
1325
|
getFullPath() {
|
|
1308
|
-
let
|
|
1326
|
+
let p12 = [];
|
|
1309
1327
|
if (this.type) {
|
|
1310
|
-
|
|
1328
|
+
p12.push(this.type);
|
|
1311
1329
|
}
|
|
1312
|
-
|
|
1313
|
-
return
|
|
1330
|
+
p12.push(this.path);
|
|
1331
|
+
return p12.join("/");
|
|
1314
1332
|
}
|
|
1315
1333
|
toNamespacedString() {
|
|
1316
1334
|
return this.namespace + ":" + this.getFullPath();
|
|
@@ -1320,22 +1338,84 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1320
1338
|
}
|
|
1321
1339
|
};
|
|
1322
1340
|
function isBasicAssetKey(obj) {
|
|
1323
|
-
return "
|
|
1341
|
+
return obj !== null && typeof obj === "object" && typeof obj.namespace === "string" && typeof obj.path === "string";
|
|
1324
1342
|
}
|
|
1325
1343
|
function isAssetKey(obj) {
|
|
1326
|
-
return isBasicAssetKey(obj) &&
|
|
1344
|
+
return isBasicAssetKey(obj) && obj.isAssetKey === true;
|
|
1327
1345
|
}
|
|
1328
1346
|
|
|
1347
|
+
// src/model/DisplayTransforms.ts
|
|
1348
|
+
var import_three7 = require("three");
|
|
1349
|
+
|
|
1350
|
+
// src/model/DisplayPosition.ts
|
|
1351
|
+
var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
|
|
1352
|
+
DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
|
|
1353
|
+
DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
|
|
1354
|
+
DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
|
|
1355
|
+
DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
|
|
1356
|
+
DisplayPosition2["GUI"] = "gui";
|
|
1357
|
+
DisplayPosition2["HEAD"] = "head";
|
|
1358
|
+
DisplayPosition2["GROUND"] = "ground";
|
|
1359
|
+
DisplayPosition2["FIXED"] = "fixed";
|
|
1360
|
+
DisplayPosition2["ON_SHELF"] = "on_shelf";
|
|
1361
|
+
return DisplayPosition2;
|
|
1362
|
+
})(DisplayPosition || {});
|
|
1363
|
+
var DISPLAY_POSITIONS = Object.values(DisplayPosition);
|
|
1364
|
+
|
|
1365
|
+
// src/model/DisplayTransforms.ts
|
|
1366
|
+
var DisplayTransforms = class {
|
|
1367
|
+
/** Resolve hand fallbacks within one model, before inheriting parent display entries. */
|
|
1368
|
+
static withHandFallbacks(display) {
|
|
1369
|
+
if (!display) return void 0;
|
|
1370
|
+
const resolved = { ...display };
|
|
1371
|
+
for (const [left, right] of [
|
|
1372
|
+
["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
|
|
1373
|
+
["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
|
|
1374
|
+
]) {
|
|
1375
|
+
if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
|
|
1376
|
+
}
|
|
1377
|
+
return resolved;
|
|
1378
|
+
}
|
|
1379
|
+
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1380
|
+
static getMatrix(display, position) {
|
|
1381
|
+
const transform = this.withHandFallbacks(display)?.[position] ?? {};
|
|
1382
|
+
const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
|
|
1383
|
+
const sign = left ? -1 : 1;
|
|
1384
|
+
const [x, y, z] = transform.rotation ?? [0, 0, 0];
|
|
1385
|
+
const rotation = new import_three7.Quaternion().setFromEuler(new import_three7.Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
|
|
1386
|
+
const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
|
|
1387
|
+
translation.x *= sign;
|
|
1388
|
+
const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
|
|
1389
|
+
return new import_three7.Matrix4().compose(translation, rotation, scale);
|
|
1390
|
+
}
|
|
1391
|
+
static apply(geometry, matrix) {
|
|
1392
|
+
geometry.applyMatrix4(matrix);
|
|
1393
|
+
if (matrix.determinant() < 0) {
|
|
1394
|
+
if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
|
|
1395
|
+
const index = geometry.index;
|
|
1396
|
+
for (let i = 0; i < index.count; i += 3) {
|
|
1397
|
+
const second = index.getX(i + 1);
|
|
1398
|
+
index.setX(i + 1, index.getX(i + 2));
|
|
1399
|
+
index.setX(i + 2, second);
|
|
1400
|
+
}
|
|
1401
|
+
index.needsUpdate = true;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1329
1406
|
// src/model/ModelMerger.ts
|
|
1330
1407
|
var ModelMerger = class {
|
|
1331
1408
|
static async mergeWithParents(model) {
|
|
1332
1409
|
const models = await this.collectAllParents(model);
|
|
1333
1410
|
let merged = {};
|
|
1334
|
-
for (
|
|
1335
|
-
|
|
1411
|
+
for (const source of [...models, model]) {
|
|
1412
|
+
const inheritedDisplay = merged.display;
|
|
1413
|
+
merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
|
|
1414
|
+
if (source.display) {
|
|
1415
|
+
merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
|
|
1416
|
+
}
|
|
1336
1417
|
}
|
|
1337
|
-
merged = (
|
|
1338
|
-
merged.hierarchy = models.map((m) => m.parent).filter((p13) => `${p13}`);
|
|
1418
|
+
merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
|
|
1339
1419
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1340
1420
|
return merged;
|
|
1341
1421
|
}
|
|
@@ -1345,6 +1425,7 @@ var ModelMerger = class {
|
|
|
1345
1425
|
}
|
|
1346
1426
|
const models = [];
|
|
1347
1427
|
const parentKey = AssetKey.parse("models", model.parent);
|
|
1428
|
+
parentKey.root = model.key?.root;
|
|
1348
1429
|
const parentModel = await Models.getRaw(parentKey);
|
|
1349
1430
|
if (parentModel) {
|
|
1350
1431
|
models.unshift(parentModel);
|
|
@@ -1354,9 +1435,6 @@ var ModelMerger = class {
|
|
|
1354
1435
|
}
|
|
1355
1436
|
};
|
|
1356
1437
|
|
|
1357
|
-
// src/assets/Models.ts
|
|
1358
|
-
var import_typescript_memoize = require("typescript-memoize");
|
|
1359
|
-
|
|
1360
1438
|
// src/assets/source/parser/AssetParsers.ts
|
|
1361
1439
|
var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
|
|
1362
1440
|
AssetParser2["MODEL"] = "model";
|
|
@@ -1370,30 +1448,65 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
|
|
|
1370
1448
|
})(AssetParser || {});
|
|
1371
1449
|
|
|
1372
1450
|
// src/assets/Models.ts
|
|
1373
|
-
var
|
|
1451
|
+
var Models = class _Models {
|
|
1374
1452
|
// opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
|
|
1375
1453
|
// the library, and would require an EnvProvider before any entry has had a chance to register
|
|
1376
1454
|
static get PERSISTENT_CACHE() {
|
|
1377
1455
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
|
|
1378
1456
|
}
|
|
1379
1457
|
static async getItemList() {
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
"
|
|
1384
|
-
|
|
1385
|
-
"assets",
|
|
1386
|
-
".json",
|
|
1387
|
-
DEFAULT_ROOT
|
|
1388
|
-
), "list" /* LIST */).then((r) => r?.files ?? []);
|
|
1458
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
|
|
1459
|
+
const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
|
|
1460
|
+
return Caching.listAssetCache.get(key.serialize(), async () => {
|
|
1461
|
+
return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
|
|
1462
|
+
}).then((r) => r?.files ?? []);
|
|
1389
1463
|
}
|
|
1390
1464
|
static async loadAndMerge(key) {
|
|
1391
|
-
const model = await this.getRaw(key);
|
|
1465
|
+
const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
|
|
1392
1466
|
if (!model) {
|
|
1393
1467
|
return void 0;
|
|
1394
1468
|
}
|
|
1395
1469
|
return ModelMerger.mergeWithParents(model);
|
|
1396
1470
|
}
|
|
1471
|
+
static async getItemModel(key) {
|
|
1472
|
+
const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
|
|
1473
|
+
const model = await this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(itemKey.serialize()), async () => {
|
|
1474
|
+
const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
|
|
1475
|
+
if (!result) return void 0;
|
|
1476
|
+
if (result.key.assetType !== "items") return { ...result.asset, key };
|
|
1477
|
+
const reference = this.defaultItemModel(result.asset.model, key);
|
|
1478
|
+
const modelKey = AssetKey.parse("models", reference);
|
|
1479
|
+
modelKey.root = key.root;
|
|
1480
|
+
const model2 = await this.getRaw(modelKey);
|
|
1481
|
+
if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
|
|
1482
|
+
return model2;
|
|
1483
|
+
});
|
|
1484
|
+
return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
|
|
1485
|
+
}
|
|
1486
|
+
// Item previews use the GUI context, false conditions, and zero numeric properties.
|
|
1487
|
+
static defaultItemModel(node, key) {
|
|
1488
|
+
if (!node || typeof node.type !== "string") {
|
|
1489
|
+
throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
|
|
1490
|
+
}
|
|
1491
|
+
switch (node.type.replace(/^minecraft:/, "")) {
|
|
1492
|
+
case "model":
|
|
1493
|
+
if (typeof node.model === "string" && node.model) return node.model;
|
|
1494
|
+
break;
|
|
1495
|
+
case "condition":
|
|
1496
|
+
return this.defaultItemModel(node.on_false, key);
|
|
1497
|
+
case "select": {
|
|
1498
|
+
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;
|
|
1499
|
+
return this.defaultItemModel(selected ?? node.fallback, key);
|
|
1500
|
+
}
|
|
1501
|
+
case "range_dispatch": {
|
|
1502
|
+
const selected = node.entries?.reduce((match, entry) => {
|
|
1503
|
+
return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
|
|
1504
|
+
}, void 0);
|
|
1505
|
+
return this.defaultItemModel(selected?.model ?? node.fallback, key);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
|
|
1509
|
+
}
|
|
1397
1510
|
static async getRaw(key) {
|
|
1398
1511
|
if (!key.assetType) {
|
|
1399
1512
|
key.assetType = "models";
|
|
@@ -1403,7 +1516,7 @@ var _Models = class _Models {
|
|
|
1403
1516
|
}
|
|
1404
1517
|
const keyStr = key.serialize();
|
|
1405
1518
|
return Caching.rawModelCache.get(keyStr, (k) => {
|
|
1406
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1519
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1407
1520
|
return AssetLoader.get(key, "model" /* MODEL */);
|
|
1408
1521
|
});
|
|
1409
1522
|
}).then((asset) => {
|
|
@@ -1432,31 +1545,32 @@ var _Models = class _Models {
|
|
|
1432
1545
|
return this.PERSISTENT_CACHE.clear();
|
|
1433
1546
|
}
|
|
1434
1547
|
};
|
|
1435
|
-
__decorateClass([
|
|
1436
|
-
(0, import_typescript_memoize.Memoize)()
|
|
1437
|
-
], _Models, "getItemList", 1);
|
|
1438
|
-
var Models = _Models;
|
|
1439
1548
|
|
|
1440
1549
|
// src/assets/BlockStates.ts
|
|
1441
|
-
var import_typescript_memoize2 = require("typescript-memoize");
|
|
1442
1550
|
var BlockStates = class {
|
|
1443
1551
|
static get PERSISTENT_CACHE() {
|
|
1444
1552
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
|
|
1445
1553
|
}
|
|
1554
|
+
// BlockState names are hardcoded
|
|
1446
1555
|
static async getList() {
|
|
1447
|
-
|
|
1556
|
+
const key = new AssetKey(
|
|
1448
1557
|
DEFAULT_NAMESPACE,
|
|
1449
1558
|
"_list",
|
|
1450
1559
|
"blockstates",
|
|
1451
1560
|
void 0,
|
|
1452
1561
|
"assets",
|
|
1453
1562
|
".json",
|
|
1454
|
-
|
|
1455
|
-
)
|
|
1563
|
+
AssetLoader.ROOT
|
|
1564
|
+
);
|
|
1565
|
+
return Caching.listAssetCache.get(key.serialize(), () => {
|
|
1566
|
+
return AssetLoader.get(key, "list" /* LIST */);
|
|
1567
|
+
}).then((r) => r?.files ?? []);
|
|
1456
1568
|
}
|
|
1457
1569
|
static async getDefaultStates() {
|
|
1458
1570
|
const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
|
|
1459
|
-
return
|
|
1571
|
+
return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
|
|
1572
|
+
return AssetLoader.get(key, "json" /* JSON */);
|
|
1573
|
+
});
|
|
1460
1574
|
}
|
|
1461
1575
|
static async getDefaultState(key) {
|
|
1462
1576
|
const defaultStates = await this.getDefaultStates();
|
|
@@ -1474,7 +1588,7 @@ var BlockStates = class {
|
|
|
1474
1588
|
}
|
|
1475
1589
|
const keyStr = key.serialize();
|
|
1476
1590
|
return Caching.blockStateCache.get(keyStr, (k) => {
|
|
1477
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1591
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1478
1592
|
return AssetLoader.get(key, "blockstate" /* BLOCKSTATE */);
|
|
1479
1593
|
});
|
|
1480
1594
|
}).then((asset) => {
|
|
@@ -1495,17 +1609,11 @@ var BlockStates = class {
|
|
|
1495
1609
|
await this.PERSISTENT_CACHE.clear();
|
|
1496
1610
|
}
|
|
1497
1611
|
};
|
|
1498
|
-
__decorateClass([
|
|
1499
|
-
(0, import_typescript_memoize2.Memoize)()
|
|
1500
|
-
], BlockStates, "getList", 1);
|
|
1501
|
-
__decorateClass([
|
|
1502
|
-
(0, import_typescript_memoize2.Memoize)()
|
|
1503
|
-
], BlockStates, "getDefaultStates", 1);
|
|
1504
1612
|
var DefaultBlockStates = class {
|
|
1505
1613
|
};
|
|
1506
1614
|
|
|
1507
1615
|
// src/assets/Assets.ts
|
|
1508
|
-
var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.
|
|
1616
|
+
var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
|
|
1509
1617
|
var DEFAULT_NAMESPACE = "minecraft";
|
|
1510
1618
|
var Assets = class {
|
|
1511
1619
|
/**
|
|
@@ -1526,8 +1634,145 @@ var Assets = class {
|
|
|
1526
1634
|
var AssetSource = class {
|
|
1527
1635
|
constructor() {
|
|
1528
1636
|
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Identifies this source's content across sessions for persistent caching. Sources that
|
|
1639
|
+
* cannot tell whether their content changed (an unnamed archive, for example) return
|
|
1640
|
+
* undefined, which keeps their results out of long-lived caches.
|
|
1641
|
+
*/
|
|
1642
|
+
get cacheId() {
|
|
1643
|
+
return void 0;
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
var AssetLoadError = class extends Error {
|
|
1647
|
+
constructor(source, key, path, cause) {
|
|
1648
|
+
super(`Failed to load ${key.toNamespacedString()} from ${path}${cause instanceof Error ? `: ${cause.message}` : ""}`);
|
|
1649
|
+
this.source = source;
|
|
1650
|
+
this.key = key;
|
|
1651
|
+
this.path = path;
|
|
1652
|
+
this.cause = cause;
|
|
1653
|
+
this.name = "AssetLoadError";
|
|
1654
|
+
}
|
|
1529
1655
|
};
|
|
1530
1656
|
|
|
1657
|
+
// src/util/BatchedExecutor.ts
|
|
1658
|
+
var BatchedExecutor = class {
|
|
1659
|
+
constructor(interval = 1, batch = 30) {
|
|
1660
|
+
this.interval = interval;
|
|
1661
|
+
this.batch = batch;
|
|
1662
|
+
this.queue = [];
|
|
1663
|
+
this.task = setInterval(() => this.run());
|
|
1664
|
+
}
|
|
1665
|
+
submit(task) {
|
|
1666
|
+
this.queue.push(task);
|
|
1667
|
+
}
|
|
1668
|
+
run() {
|
|
1669
|
+
for (let i = 0; i < this.batch; i++) {
|
|
1670
|
+
this.runNext();
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
runNext() {
|
|
1674
|
+
let next = this.queue.shift();
|
|
1675
|
+
if (next) next();
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
|
|
1679
|
+
// src/util/model.ts
|
|
1680
|
+
var import_three8 = require("three");
|
|
1681
|
+
function applyElementRotation(rotation, geometry) {
|
|
1682
|
+
const origin = new import_three8.Vector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
|
|
1683
|
+
geometry.translate(-origin.x, -origin.y, -origin.z);
|
|
1684
|
+
switch (rotation.axis) {
|
|
1685
|
+
case "x" /* X */:
|
|
1686
|
+
geometry.rotateX(toRadians(rotation.angle));
|
|
1687
|
+
break;
|
|
1688
|
+
case "y" /* Y */:
|
|
1689
|
+
geometry.rotateY(toRadians(rotation.angle));
|
|
1690
|
+
break;
|
|
1691
|
+
case "z" /* Z */:
|
|
1692
|
+
geometry.rotateZ(toRadians(rotation.angle));
|
|
1693
|
+
break;
|
|
1694
|
+
}
|
|
1695
|
+
if (rotation.rescale) {
|
|
1696
|
+
if (Math.abs(rotation.angle) === 22.5) {
|
|
1697
|
+
const s = 1 / Math.cos(0.39269909262657166);
|
|
1698
|
+
geometry.scale(s, 1, s);
|
|
1699
|
+
} else {
|
|
1700
|
+
const s = 1 / Math.cos(0.7853981852531433);
|
|
1701
|
+
geometry.scale(s, 1, s);
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
geometry.translate(origin.x, origin.y, origin.z);
|
|
1705
|
+
}
|
|
1706
|
+
function applyGenericRotation(axis, rotation, obj) {
|
|
1707
|
+
switch (axis) {
|
|
1708
|
+
case "x" /* X */:
|
|
1709
|
+
obj.rotateOnAxis(new import_three8.Vector3(1, 0, 0), toRadians(rotation));
|
|
1710
|
+
break;
|
|
1711
|
+
case "y" /* Y */:
|
|
1712
|
+
obj.rotateOnAxis(new import_three8.Vector3(0, 1, 0), toRadians(rotation));
|
|
1713
|
+
break;
|
|
1714
|
+
case "z" /* Z */:
|
|
1715
|
+
obj.rotateOnAxis(new import_three8.Vector3(0, 0, 1), toRadians(rotation));
|
|
1716
|
+
break;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
|
|
1720
|
+
let size = new import_three8.Vector3();
|
|
1721
|
+
box.getSize(size);
|
|
1722
|
+
let boxGeo = new import_three8.BoxGeometry(size.x, size.y, size.z, 1, 1, 1);
|
|
1723
|
+
let wireGeo = new import_three8.EdgesGeometry(boxGeo);
|
|
1724
|
+
let wireMat = new import_three8.LineBasicMaterial({ color, linewidth: w });
|
|
1725
|
+
let wireframe = new import_three8.LineSegments(wireGeo, wireMat);
|
|
1726
|
+
obj.add(wireframe);
|
|
1727
|
+
let axes = new import_three8.AxesHelper(1);
|
|
1728
|
+
obj.add(axes);
|
|
1729
|
+
}
|
|
1730
|
+
function addWireframeToObject(obj, color = 16777215, w = 2) {
|
|
1731
|
+
let boxGeo = new import_three8.BoxGeometry(16, 16, 16, 1, 1, 1);
|
|
1732
|
+
let wireGeo = new import_three8.EdgesGeometry(boxGeo);
|
|
1733
|
+
let wireMat = new import_three8.LineBasicMaterial({ color, linewidth: w });
|
|
1734
|
+
let wireframe = new import_three8.LineSegments(wireGeo, wireMat);
|
|
1735
|
+
obj.add(wireframe);
|
|
1736
|
+
let axes = new import_three8.AxesHelper(1);
|
|
1737
|
+
obj.add(axes);
|
|
1738
|
+
}
|
|
1739
|
+
function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
|
|
1740
|
+
let wireGeo = new import_three8.EdgesGeometry(geo);
|
|
1741
|
+
let wireMat = new import_three8.LineBasicMaterial({ color, linewidth: w });
|
|
1742
|
+
let wireframe = new import_three8.LineSegments(wireGeo, wireMat);
|
|
1743
|
+
mesh.add(wireframe);
|
|
1744
|
+
let axes = new import_three8.AxesHelper(1);
|
|
1745
|
+
mesh.add(axes);
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
// src/util/performance.ts
|
|
1749
|
+
function captureException(e, ...extra) {
|
|
1750
|
+
console.error(e, extra);
|
|
1751
|
+
}
|
|
1752
|
+
function timingStart(marker) {
|
|
1753
|
+
console.time(marker);
|
|
1754
|
+
}
|
|
1755
|
+
function timingEnd(marker) {
|
|
1756
|
+
console.timeEnd(marker);
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
// src/util/three.ts
|
|
1760
|
+
function isObject3D(obj) {
|
|
1761
|
+
return obj.isObject3D;
|
|
1762
|
+
}
|
|
1763
|
+
function isMesh(obj) {
|
|
1764
|
+
return obj.isMesh;
|
|
1765
|
+
}
|
|
1766
|
+
function isInstancedMesh(obj) {
|
|
1767
|
+
return obj.isInstancedMesh;
|
|
1768
|
+
}
|
|
1769
|
+
function isPerspectiveCamera(obj) {
|
|
1770
|
+
return obj.isPerspectiveCamera;
|
|
1771
|
+
}
|
|
1772
|
+
function isOrthographicCamera(obj) {
|
|
1773
|
+
return obj.isOrthographicCamera;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1531
1776
|
// src/nbt/NBTHelper.ts
|
|
1532
1777
|
var NBTHelper = class {
|
|
1533
1778
|
static async fromBuffer(buffer) {
|
|
@@ -1556,17 +1801,17 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1556
1801
|
if (typeof namespaced !== "undefined") {
|
|
1557
1802
|
return namespaced;
|
|
1558
1803
|
}
|
|
1559
|
-
if (typeof key.root !== "undefined" && key.root !==
|
|
1804
|
+
if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
1560
1805
|
console.info(p3, "Retrying", key, "with default root+namespace");
|
|
1561
|
-
const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension,
|
|
1806
|
+
const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
1562
1807
|
const namespacedRooted = await this.load(namespacedRootedKey, parser);
|
|
1563
1808
|
if (typeof namespacedRooted !== "undefined") {
|
|
1564
1809
|
return namespacedRooted;
|
|
1565
1810
|
}
|
|
1566
1811
|
}
|
|
1567
|
-
} else if (typeof key.root !== "undefined" && key.root !==
|
|
1812
|
+
} else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
1568
1813
|
console.info(p3, "Retrying", key, "with default root");
|
|
1569
|
-
const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension,
|
|
1814
|
+
const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
1570
1815
|
const rooted = await this.load(rootKey, parser);
|
|
1571
1816
|
if (typeof rooted !== "undefined") {
|
|
1572
1817
|
return rooted;
|
|
@@ -1578,31 +1823,25 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1578
1823
|
console.info(p3, "Loading", key);
|
|
1579
1824
|
const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1580
1825
|
console.debug(p3, url);
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
} catch (e) {
|
|
1590
|
-
console.warn("Parser failed to process response", response, e);
|
|
1591
|
-
throw e;
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
return void 0;
|
|
1595
|
-
}).catch((err) => {
|
|
1596
|
-
if (err.response) {
|
|
1597
|
-
let response = err.response;
|
|
1598
|
-
if (response.status === 404) {
|
|
1599
|
-
console.debug(p3, key, "not found");
|
|
1826
|
+
const request = { url };
|
|
1827
|
+
try {
|
|
1828
|
+
parser.config(request);
|
|
1829
|
+
let response;
|
|
1830
|
+
try {
|
|
1831
|
+
response = await Requests.mcAssetRequest(request);
|
|
1832
|
+
} catch (cause) {
|
|
1833
|
+
if (cause instanceof RequestError && cause.response?.status === 404) {
|
|
1600
1834
|
return void 0;
|
|
1601
1835
|
}
|
|
1836
|
+
throw cause;
|
|
1602
1837
|
}
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1838
|
+
if (response.data === void 0) {
|
|
1839
|
+
throw new Error("Asset response has no data");
|
|
1840
|
+
}
|
|
1841
|
+
return await parser.parse(response);
|
|
1842
|
+
} catch (cause) {
|
|
1843
|
+
throw new AssetLoadError(this, key, request.url, cause);
|
|
1844
|
+
}
|
|
1606
1845
|
}
|
|
1607
1846
|
assetBasePath(key) {
|
|
1608
1847
|
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 + "/" : ""}`;
|
|
@@ -1615,6 +1854,9 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1615
1854
|
get root() {
|
|
1616
1855
|
return this._root;
|
|
1617
1856
|
}
|
|
1857
|
+
get cacheId() {
|
|
1858
|
+
return `hosted:${this._root}`;
|
|
1859
|
+
}
|
|
1618
1860
|
get options() {
|
|
1619
1861
|
return this._options;
|
|
1620
1862
|
}
|
|
@@ -1691,9 +1933,10 @@ var HostedAssetSource = _HostedAssetSource;
|
|
|
1691
1933
|
// src/assets/source/archive/BrowserArchiveProxy.ts
|
|
1692
1934
|
var import_zip = require("@zip.js/zip.js");
|
|
1693
1935
|
var BrowserArchiveProxy = class {
|
|
1694
|
-
constructor(blob) {
|
|
1936
|
+
constructor(blob, id) {
|
|
1695
1937
|
this._blob = blob;
|
|
1696
1938
|
this._reader = new import_zip.ZipReader(new import_zip.BlobReader(this._blob));
|
|
1939
|
+
this.id = id ?? (typeof File !== "undefined" && blob instanceof File ? `${blob.name}:${blob.size}:${blob.lastModified}` : void 0);
|
|
1697
1940
|
}
|
|
1698
1941
|
async getEntries() {
|
|
1699
1942
|
return (await this._reader.getEntries()).map((e) => {
|
|
@@ -1709,7 +1952,6 @@ var BrowserArchiveProxy = class {
|
|
|
1709
1952
|
};
|
|
1710
1953
|
|
|
1711
1954
|
// src/assets/source/archive/ArchiveAssetSource.ts
|
|
1712
|
-
var p4 = prefix("ArchiveAssetSource");
|
|
1713
1955
|
var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
1714
1956
|
constructor(archiveProxy) {
|
|
1715
1957
|
super();
|
|
@@ -1719,6 +1961,10 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1719
1961
|
static blob(blob) {
|
|
1720
1962
|
return new _ArchiveAssetSource(new BrowserArchiveProxy(blob));
|
|
1721
1963
|
}
|
|
1964
|
+
get cacheId() {
|
|
1965
|
+
const id = this._archiveProxy.id;
|
|
1966
|
+
return id === void 0 ? void 0 : `archive:${id}`;
|
|
1967
|
+
}
|
|
1722
1968
|
async getEntries() {
|
|
1723
1969
|
return this._archiveProxy.getEntries();
|
|
1724
1970
|
}
|
|
@@ -1728,74 +1974,31 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1728
1974
|
}
|
|
1729
1975
|
async get(key, parser) {
|
|
1730
1976
|
const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
|
|
1731
|
-
|
|
1732
|
-
let entries = await this.getEntries();
|
|
1733
|
-
const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1734
|
-
console.log(path);
|
|
1735
|
-
const entry = await this.getEntry(path);
|
|
1736
|
-
console.log(entry);
|
|
1737
|
-
if (!entry) {
|
|
1738
|
-
return void 0;
|
|
1739
|
-
}
|
|
1740
|
-
let blob = await entry.getData();
|
|
1741
|
-
const url = URL.createObjectURL(blob);
|
|
1742
|
-
console.log(url);
|
|
1743
|
-
let req = {
|
|
1744
|
-
url
|
|
1745
|
-
};
|
|
1746
|
-
responseParser.config(req);
|
|
1747
|
-
return Requests.genericRequest(req).then((response) => {
|
|
1748
|
-
if (response && response.data) {
|
|
1749
|
-
try {
|
|
1750
|
-
return responseParser.parse(response);
|
|
1751
|
-
} catch (e) {
|
|
1752
|
-
console.warn("Parser failed to process response", response, e);
|
|
1753
|
-
throw e;
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
return void 0;
|
|
1757
|
-
}).catch((err) => {
|
|
1758
|
-
if (err.response) {
|
|
1759
|
-
let response = err.response;
|
|
1760
|
-
if (response.status === 404) {
|
|
1761
|
-
console.debug(p4, key, "not found");
|
|
1762
|
-
return void 0;
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
console.debug(p4, "Failed to load", key, err?.message);
|
|
1766
|
-
return void 0;
|
|
1767
|
-
});
|
|
1977
|
+
return this.load(key, responseParser);
|
|
1768
1978
|
}
|
|
1769
|
-
//TODO: abstract this
|
|
1770
1979
|
async load(key, parser) {
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
parser.config(req);
|
|
1778
|
-
return await Requests.genericRequest(req).then((response) => {
|
|
1779
|
-
if (response && response.data) {
|
|
1780
|
-
try {
|
|
1781
|
-
return parser.parse(response);
|
|
1782
|
-
} catch (e) {
|
|
1783
|
-
console.warn("Parser failed to process response", response, e);
|
|
1784
|
-
throw e;
|
|
1785
|
-
}
|
|
1980
|
+
const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1981
|
+
let url;
|
|
1982
|
+
try {
|
|
1983
|
+
const entry = await this.getEntry(path);
|
|
1984
|
+
if (!entry) {
|
|
1985
|
+
return void 0;
|
|
1786
1986
|
}
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
return void 0;
|
|
1794
|
-
}
|
|
1987
|
+
url = URL.createObjectURL(await entry.getData());
|
|
1988
|
+
const request = { url };
|
|
1989
|
+
parser.config(request);
|
|
1990
|
+
const response = await Requests.genericRequest(request);
|
|
1991
|
+
if (response.data === void 0) {
|
|
1992
|
+
throw new Error("Asset response has no data");
|
|
1795
1993
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1994
|
+
return await parser.parse(response);
|
|
1995
|
+
} catch (cause) {
|
|
1996
|
+
throw new AssetLoadError(this, key, path, cause);
|
|
1997
|
+
} finally {
|
|
1998
|
+
if (url !== void 0) {
|
|
1999
|
+
URL.revokeObjectURL(url);
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
1799
2002
|
}
|
|
1800
2003
|
assetBasePath(key) {
|
|
1801
2004
|
return `${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
|
|
@@ -1803,18 +2006,54 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1803
2006
|
};
|
|
1804
2007
|
|
|
1805
2008
|
// src/assets/AssetLoader.ts
|
|
1806
|
-
var
|
|
1807
|
-
var
|
|
2009
|
+
var p4 = prefix("AssetLoader");
|
|
2010
|
+
var FALLBACK_ROOT = "https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master";
|
|
1808
2011
|
var _AssetLoader = class _AssetLoader {
|
|
2012
|
+
static get version() {
|
|
2013
|
+
return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
|
|
2014
|
+
}
|
|
2015
|
+
static setVersion(version) {
|
|
2016
|
+
this.ROOT = `https://assets.mcasset.cloud/${version}`;
|
|
2017
|
+
const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });
|
|
2018
|
+
const index = this._SOURCES.findIndex((s) => s.key === "mcassets");
|
|
2019
|
+
if (index !== -1) {
|
|
2020
|
+
this._SOURCES[index] = { key: "mcassets", source };
|
|
2021
|
+
} else {
|
|
2022
|
+
this.addSource("mcassets", source);
|
|
2023
|
+
}
|
|
2024
|
+
Caching.clear();
|
|
2025
|
+
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Scope for persistent cache keys. Empty with only the default vanilla sources, so their
|
|
2028
|
+
* entries stay valid across sessions; otherwise it names every added source (resource packs,
|
|
2029
|
+
* mirrors) so their results never masquerade as vanilla assets after a reload.
|
|
2030
|
+
*/
|
|
2031
|
+
static get persistentScope() {
|
|
2032
|
+
const parts = [];
|
|
2033
|
+
for (const { key, source } of this._SOURCES) {
|
|
2034
|
+
const id = source.cacheId;
|
|
2035
|
+
if (key === "mcassets" && id === `hosted:${this.ROOT}`) continue;
|
|
2036
|
+
if (key === "mcassets-fallback" && id === `hosted:${FALLBACK_ROOT}`) continue;
|
|
2037
|
+
if (id === void 0) return this.SESSION_SCOPE;
|
|
2038
|
+
parts.push(`${key}=${id}`);
|
|
2039
|
+
}
|
|
2040
|
+
return parts.join("|");
|
|
2041
|
+
}
|
|
2042
|
+
/** Prefixes a persistent cache key with the current source scope. */
|
|
2043
|
+
static persistentKey(key) {
|
|
2044
|
+
const scope = this.persistentScope;
|
|
2045
|
+
return scope ? `${scope}
|
|
2046
|
+
${key}` : key;
|
|
2047
|
+
}
|
|
1809
2048
|
static addSource(key, source, override = true) {
|
|
1810
2049
|
if (override) {
|
|
1811
2050
|
const existing = this.removeSource(key);
|
|
1812
2051
|
if (existing) {
|
|
1813
|
-
console.log(
|
|
2052
|
+
console.log(p4, "Removed existing AssetSource", key);
|
|
1814
2053
|
}
|
|
1815
2054
|
}
|
|
1816
2055
|
this._SOURCES.unshift({ key, source });
|
|
1817
|
-
console.log(
|
|
2056
|
+
console.log(p4, "Added AssetSource", key);
|
|
1818
2057
|
}
|
|
1819
2058
|
static removeSource(key) {
|
|
1820
2059
|
const index = this._SOURCES.findIndex((s) => s.key === key);
|
|
@@ -1827,7 +2066,6 @@ var _AssetLoader = class _AssetLoader {
|
|
|
1827
2066
|
return void 0;
|
|
1828
2067
|
}
|
|
1829
2068
|
static async getAll(key, parser) {
|
|
1830
|
-
console.log(this._SOURCES);
|
|
1831
2069
|
let promises = [];
|
|
1832
2070
|
for (const source of this._SOURCES) {
|
|
1833
2071
|
promises.push(source.source.get(key, parser));
|
|
@@ -1836,30 +2074,42 @@ var _AssetLoader = class _AssetLoader {
|
|
|
1836
2074
|
return results.filter((r) => r != void 0);
|
|
1837
2075
|
});
|
|
1838
2076
|
}
|
|
2077
|
+
/** Returns the first defined result in source-priority order, without merging assets. */
|
|
1839
2078
|
static async get(key, parser) {
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
2079
|
+
const keys = [key];
|
|
2080
|
+
if (key.rootType === "data" && (key.assetType === "structure" || key.assetType === "structures")) {
|
|
2081
|
+
keys.push(new AssetKey(
|
|
2082
|
+
key.namespace,
|
|
2083
|
+
key.path,
|
|
2084
|
+
key.assetType === "structure" ? "structures" : "structure",
|
|
2085
|
+
key.type,
|
|
2086
|
+
key.rootType,
|
|
2087
|
+
key.extension,
|
|
2088
|
+
key.root
|
|
2089
|
+
));
|
|
2090
|
+
}
|
|
2091
|
+
return (await this.getFirst(keys, parser))?.asset;
|
|
2092
|
+
}
|
|
2093
|
+
/** Tries each path within a source before considering lower-priority sources. */
|
|
2094
|
+
static async getFirst(keys, parser) {
|
|
2095
|
+
const sources = [...this._SOURCES];
|
|
2096
|
+
for (const source of sources) {
|
|
2097
|
+
for (const key of keys) {
|
|
2098
|
+
const result = await source.source.get(key, parser);
|
|
2099
|
+
if (result !== void 0) {
|
|
2100
|
+
return { key, asset: result };
|
|
1853
2101
|
}
|
|
1854
2102
|
}
|
|
1855
|
-
|
|
1856
|
-
|
|
2103
|
+
}
|
|
2104
|
+
return void 0;
|
|
1857
2105
|
}
|
|
1858
2106
|
};
|
|
1859
2107
|
_AssetLoader.ROOT = DEFAULT_ROOT;
|
|
1860
2108
|
_AssetLoader._SOURCES = [];
|
|
1861
|
-
|
|
1862
|
-
_AssetLoader.
|
|
2109
|
+
/** Used when a registered source cannot identify its content, so nothing persists past this session. */
|
|
2110
|
+
_AssetLoader.SESSION_SCOPE = `session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
2111
|
+
_AssetLoader.addSource("mcassets-fallback", new HostedAssetSource(FALLBACK_ROOT, { retryDefaults: false }));
|
|
2112
|
+
_AssetLoader.addSource("mcassets", new HostedAssetSource(_AssetLoader.ROOT, { retryDefaults: false }));
|
|
1863
2113
|
var AssetLoader = _AssetLoader;
|
|
1864
2114
|
|
|
1865
2115
|
// src/assets/ModelTextures.ts
|
|
@@ -1868,11 +2118,21 @@ var ModelTextures = class {
|
|
|
1868
2118
|
return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
|
|
1869
2119
|
}
|
|
1870
2120
|
static async get(key) {
|
|
1871
|
-
const
|
|
1872
|
-
|
|
1873
|
-
|
|
2121
|
+
const keyStr = key.serialize();
|
|
2122
|
+
const pending = this.preload(key);
|
|
2123
|
+
const cached = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
2124
|
+
try {
|
|
2125
|
+
const asset = await pending;
|
|
2126
|
+
if (asset) {
|
|
2127
|
+
return await ImageLoader.infoToCanvasData(asset);
|
|
2128
|
+
}
|
|
2129
|
+
return void 0;
|
|
2130
|
+
} catch (err) {
|
|
2131
|
+
if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
|
|
2132
|
+
Caching.textureAssetCache.invalidate(keyStr);
|
|
2133
|
+
}
|
|
2134
|
+
throw err;
|
|
1874
2135
|
}
|
|
1875
|
-
return void 0;
|
|
1876
2136
|
}
|
|
1877
2137
|
static async preload(key) {
|
|
1878
2138
|
const keyStr = key.serialize();
|
|
@@ -1891,7 +2151,7 @@ var ModelTextures = class {
|
|
|
1891
2151
|
}
|
|
1892
2152
|
const keyStr = key.serialize();
|
|
1893
2153
|
return Caching.textureMetaCache.get(keyStr, (k) => {
|
|
1894
|
-
return this.PERSISTENT_META_CACHE.getOrLoad(keyStr, (k1) => {
|
|
2154
|
+
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1895
2155
|
return AssetLoader.get(key, "meta" /* META */).then((asset) => {
|
|
1896
2156
|
if (asset)
|
|
1897
2157
|
asset.key = key;
|
|
@@ -2042,17 +2302,20 @@ var TextureAtlas = class {
|
|
|
2042
2302
|
// src/model/ModelGenerator.ts
|
|
2043
2303
|
var ModelGenerator = class {
|
|
2044
2304
|
static generateItemModel(imageData, layer) {
|
|
2305
|
+
const tintindex = this.ITEM_LAYERS.indexOf(layer);
|
|
2045
2306
|
const mainElement = {
|
|
2046
2307
|
from: [0, 0, 7.5],
|
|
2047
2308
|
to: [16, 16, 8.5],
|
|
2048
2309
|
faces: {
|
|
2049
2310
|
"south": {
|
|
2050
2311
|
uv: [0, 0, 16, 16],
|
|
2051
|
-
texture: `#${layer}
|
|
2312
|
+
texture: `#${layer}`,
|
|
2313
|
+
tintindex
|
|
2052
2314
|
},
|
|
2053
2315
|
"north": {
|
|
2054
2316
|
uv: [16, 0, 0, 16],
|
|
2055
|
-
texture: `#${layer}
|
|
2317
|
+
texture: `#${layer}`,
|
|
2318
|
+
tintindex
|
|
2056
2319
|
}
|
|
2057
2320
|
},
|
|
2058
2321
|
shade: true
|
|
@@ -2063,11 +2326,19 @@ var ModelGenerator = class {
|
|
|
2063
2326
|
ModelGenerator.ITEM_LAYERS = ["layer0", "layer1", "layer2", "layer3", "layer4"];
|
|
2064
2327
|
|
|
2065
2328
|
// src/UVMapper.ts
|
|
2066
|
-
var
|
|
2329
|
+
var p5 = prefix("UVMapper");
|
|
2067
2330
|
var DEFAULT_UV = [0, 0, 16, 16];
|
|
2068
2331
|
var X = 0;
|
|
2069
2332
|
var Y = 1;
|
|
2070
2333
|
var Z = 2;
|
|
2334
|
+
var FACE_UV_AXES = {
|
|
2335
|
+
east: [new import_three9.Vector3(0, 0, -1), new import_three9.Vector3(0, -1, 0)],
|
|
2336
|
+
west: [new import_three9.Vector3(0, 0, 1), new import_three9.Vector3(0, -1, 0)],
|
|
2337
|
+
up: [new import_three9.Vector3(1, 0, 0), new import_three9.Vector3(0, 0, 1)],
|
|
2338
|
+
down: [new import_three9.Vector3(1, 0, 0), new import_three9.Vector3(0, 0, -1)],
|
|
2339
|
+
south: [new import_three9.Vector3(1, 0, 0), new import_three9.Vector3(0, -1, 0)],
|
|
2340
|
+
north: [new import_three9.Vector3(-1, 0, 0), new import_three9.Vector3(0, -1, 0)]
|
|
2341
|
+
};
|
|
2071
2342
|
var UVMapper = class {
|
|
2072
2343
|
static makeUv(uvCoord, originalTextureSize, actualTextureSize) {
|
|
2073
2344
|
if (uvCoord === 0) return 0;
|
|
@@ -2163,7 +2434,43 @@ var UVMapper = class {
|
|
|
2163
2434
|
return array;
|
|
2164
2435
|
}
|
|
2165
2436
|
static facesToUv(faces, originalTextureSize, actualTextureSize) {
|
|
2166
|
-
return new
|
|
2437
|
+
return new import_three9.Float32BufferAttribute(this.facesToUvArray(faces, originalTextureSize, actualTextureSize), 2);
|
|
2438
|
+
}
|
|
2439
|
+
static lockUvs(geometry, faces, atlas, rotation) {
|
|
2440
|
+
const uv = geometry.getAttribute("uv");
|
|
2441
|
+
for (let faceIndex = 0; faceIndex < CUBE_FACES.length; faceIndex++) {
|
|
2442
|
+
const faceName = CUBE_FACES[faceIndex];
|
|
2443
|
+
const texture = faces[faceName]?.texture?.substring(1);
|
|
2444
|
+
const position = texture && atlas.positions[texture];
|
|
2445
|
+
const size = texture && atlas.sizes[texture];
|
|
2446
|
+
if (!position || !size) continue;
|
|
2447
|
+
const [sourceU, sourceV] = FACE_UV_AXES[faceName];
|
|
2448
|
+
const uAxis = sourceU.clone().applyEuler(rotation);
|
|
2449
|
+
const vAxis = sourceV.clone().applyEuler(rotation);
|
|
2450
|
+
const normal = vAxis.clone().cross(uAxis);
|
|
2451
|
+
const targetFace = CUBE_FACES.find((name) => {
|
|
2452
|
+
const [u, v] = FACE_UV_AXES[name];
|
|
2453
|
+
return v.clone().cross(u).dot(normal) > 0.5;
|
|
2454
|
+
});
|
|
2455
|
+
const [targetU, targetV] = FACE_UV_AXES[targetFace];
|
|
2456
|
+
const uu = Math.round(targetU.dot(uAxis));
|
|
2457
|
+
const uvCross = Math.round(targetU.dot(vAxis));
|
|
2458
|
+
const vu = Math.round(targetV.dot(uAxis));
|
|
2459
|
+
const vv = Math.round(targetV.dot(vAxis));
|
|
2460
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
2461
|
+
const index = faceIndex * 4 + corner;
|
|
2462
|
+
const u = (uv.getX(index) * atlas.image.width - position[0]) / size[0] - 0.5;
|
|
2463
|
+
const v = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] - 0.5;
|
|
2464
|
+
const lockedU = uu * u + uvCross * v + 0.5;
|
|
2465
|
+
const lockedV = vu * u + vv * v + 0.5;
|
|
2466
|
+
uv.setXY(
|
|
2467
|
+
index,
|
|
2468
|
+
(position[0] + lockedU * size[0]) / atlas.image.width,
|
|
2469
|
+
1 - (position[1] + lockedV * size[1]) / atlas.image.height
|
|
2470
|
+
);
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
uv.needsUpdate = true;
|
|
2167
2474
|
}
|
|
2168
2475
|
static async getAtlas(model) {
|
|
2169
2476
|
const keyStr = model.key.serialize();
|
|
@@ -2205,32 +2512,32 @@ var UVMapper = class {
|
|
|
2205
2512
|
v1 *= scaleV;
|
|
2206
2513
|
u2 *= scaleU;
|
|
2207
2514
|
v2 *= scaleV;
|
|
2208
|
-
let tl = new
|
|
2209
|
-
let tr = new
|
|
2210
|
-
let bl = new
|
|
2211
|
-
let br = new
|
|
2515
|
+
let tl = new import_three9.Vector2(u1, v1);
|
|
2516
|
+
let tr = new import_three9.Vector2(u2, v1);
|
|
2517
|
+
let bl = new import_three9.Vector2(u1, v2);
|
|
2518
|
+
let br = new import_three9.Vector2(u2, v2);
|
|
2212
2519
|
switch (rotation) {
|
|
2213
2520
|
case 0:
|
|
2214
2521
|
case 360:
|
|
2215
2522
|
default:
|
|
2216
2523
|
break;
|
|
2217
2524
|
case 90:
|
|
2218
|
-
tl = new
|
|
2219
|
-
tr = new
|
|
2220
|
-
bl = new
|
|
2221
|
-
br = new
|
|
2525
|
+
tl = new import_three9.Vector2(u1, v2);
|
|
2526
|
+
tr = new import_three9.Vector2(u1, v1);
|
|
2527
|
+
bl = new import_three9.Vector2(u2, v2);
|
|
2528
|
+
br = new import_three9.Vector2(u2, v1);
|
|
2222
2529
|
break;
|
|
2223
2530
|
case 180:
|
|
2224
|
-
tl = new
|
|
2225
|
-
tr = new
|
|
2226
|
-
bl = new
|
|
2227
|
-
br = new
|
|
2531
|
+
tl = new import_three9.Vector2(u2, v2);
|
|
2532
|
+
tr = new import_three9.Vector2(u1, v2);
|
|
2533
|
+
bl = new import_three9.Vector2(u2, v1);
|
|
2534
|
+
br = new import_three9.Vector2(u1, v1);
|
|
2228
2535
|
break;
|
|
2229
2536
|
case 270:
|
|
2230
|
-
tl = new
|
|
2231
|
-
tr = new
|
|
2232
|
-
bl = new
|
|
2233
|
-
br = new
|
|
2537
|
+
tl = new import_three9.Vector2(u2, v1);
|
|
2538
|
+
tr = new import_three9.Vector2(u2, v2);
|
|
2539
|
+
bl = new import_three9.Vector2(u1, v1);
|
|
2540
|
+
br = new import_three9.Vector2(u1, v2);
|
|
2234
2541
|
break;
|
|
2235
2542
|
}
|
|
2236
2543
|
return [tl, tr, bl, br];
|
|
@@ -2240,7 +2547,7 @@ var UVMapper = class {
|
|
|
2240
2547
|
const metaMap = {};
|
|
2241
2548
|
const model = { ...originalModel };
|
|
2242
2549
|
const isItemModel = !("elements" in model);
|
|
2243
|
-
console.debug(
|
|
2550
|
+
console.debug(p5, "Creating Atlas for", model.key);
|
|
2244
2551
|
if (model.textures) {
|
|
2245
2552
|
const promises = [];
|
|
2246
2553
|
const uniqueTextureNames = [];
|
|
@@ -2254,7 +2561,7 @@ var UVMapper = class {
|
|
|
2254
2561
|
const assetKey = AssetKey.parse("textures", textureValue, model.key);
|
|
2255
2562
|
promises.push(ModelTextures.get(assetKey).then((asset) => {
|
|
2256
2563
|
if (!asset) {
|
|
2257
|
-
console.warn(
|
|
2564
|
+
console.warn(p5, "Missing texture", assetKey);
|
|
2258
2565
|
return;
|
|
2259
2566
|
}
|
|
2260
2567
|
textureMap[textureKey] = new WrappedImage(asset);
|
|
@@ -2266,7 +2573,7 @@ var UVMapper = class {
|
|
|
2266
2573
|
}
|
|
2267
2574
|
await Promise.all(promises);
|
|
2268
2575
|
const textureCount = uniqueTextureNames.length;
|
|
2269
|
-
console.debug(
|
|
2576
|
+
console.debug(p5, "Creating Atlas for", textureCount, "textures");
|
|
2270
2577
|
this.fillMissingTextureKeys(model.textures, textureMap);
|
|
2271
2578
|
this.fillMissingTextureKeys(model.textures, metaMap);
|
|
2272
2579
|
const sizes = {};
|
|
@@ -2286,7 +2593,7 @@ var UVMapper = class {
|
|
|
2286
2593
|
this.fillMissingTextureKeys(model.textures, sizes);
|
|
2287
2594
|
const s = Math.ceil(Math.sqrt(textureCount + 1));
|
|
2288
2595
|
const size = Math.ceil(s * maxWidth);
|
|
2289
|
-
console.debug(
|
|
2596
|
+
console.debug(p5, "Atlas size:", size);
|
|
2290
2597
|
const squaredSize = size * size;
|
|
2291
2598
|
const missing = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX/AP8AAACfphTyAAAAFUlEQVQoz2MIhQKGVVAwKjIqQrwIAHRz/wFI17TEAAAAAElFTkSuQmCC");
|
|
2292
2599
|
const empty = await ImageLoader.getData("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA5JREFUKM9jGAWjgAIAAAJAAAFSSwuTAAAAAElFTkSuQmCC");
|
|
@@ -2341,10 +2648,10 @@ var UVMapper = class {
|
|
|
2341
2648
|
}
|
|
2342
2649
|
}
|
|
2343
2650
|
const atlasImageData = image.toDataURL();
|
|
2344
|
-
console.log(
|
|
2651
|
+
console.log(p5, "Atlas Image for", model.key, atlasImageData);
|
|
2345
2652
|
this.fillMissingTextureKeys(model.textures, positions);
|
|
2346
2653
|
if (isItemModel) {
|
|
2347
|
-
console.debug(
|
|
2654
|
+
console.debug(p5, "Generating item model for", model);
|
|
2348
2655
|
model.elements = [];
|
|
2349
2656
|
for (let layerName of ModelGenerator.ITEM_LAYERS) {
|
|
2350
2657
|
const textureImage = textureMap[layerName];
|
|
@@ -2352,7 +2659,7 @@ var UVMapper = class {
|
|
|
2352
2659
|
model.elements.push(...ModelGenerator.generateItemModel(textureImage.data, layerName));
|
|
2353
2660
|
}
|
|
2354
2661
|
}
|
|
2355
|
-
console.debug(
|
|
2662
|
+
console.debug(p5, "Item model elements", model.elements);
|
|
2356
2663
|
}
|
|
2357
2664
|
if (!model.elements) {
|
|
2358
2665
|
}
|
|
@@ -2370,18 +2677,14 @@ var UVMapper = class {
|
|
|
2370
2677
|
this.setCubeFaceUvInArray(uv, faceIndex * 4, [0, 1, 8 / size, (size - 8) / size]);
|
|
2371
2678
|
continue;
|
|
2372
2679
|
}
|
|
2680
|
+
if (!face.texture) continue;
|
|
2373
2681
|
if (!face.uv) {
|
|
2374
2682
|
face.uv = this.getFallbackUv(element, faceName);
|
|
2375
2683
|
}
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
faceTexture = faceTexture.substr(1);
|
|
2381
|
-
texPosition = positions[faceTexture] || [0, 0];
|
|
2382
|
-
texSize = sizes[faceTexture] || [16, 16];
|
|
2383
|
-
}
|
|
2384
|
-
let texPosV = new import_three8.Vector2(texPosition[0], texPosition[1]);
|
|
2684
|
+
const faceTexture = face.texture.substr(1);
|
|
2685
|
+
const texPosition = positions[faceTexture] || [0, 0];
|
|
2686
|
+
const texSize = sizes[faceTexture] || [16, 16];
|
|
2687
|
+
let texPosV = new import_three9.Vector2(texPosition[0], texPosition[1]);
|
|
2385
2688
|
const [tl, tr, bl, br] = this.expandAndRotateMcUvs(face.uv, face.rotation, texSize[0], texSize[1]);
|
|
2386
2689
|
tl.add(texPosV);
|
|
2387
2690
|
tr.add(texPosV);
|
|
@@ -2412,7 +2715,7 @@ var UVMapper = class {
|
|
|
2412
2715
|
hasTransparency
|
|
2413
2716
|
);
|
|
2414
2717
|
} else {
|
|
2415
|
-
console.warn(
|
|
2718
|
+
console.warn(p5, "Model does not have any textures", model);
|
|
2416
2719
|
}
|
|
2417
2720
|
return void 0;
|
|
2418
2721
|
}
|
|
@@ -2454,18 +2757,18 @@ var MinecraftCubeTexture = class {
|
|
|
2454
2757
|
}
|
|
2455
2758
|
getUvEast(w, h, l) {
|
|
2456
2759
|
return [
|
|
2457
|
-
[this.mapW(this.u), this.mapH(this.v + l + h)],
|
|
2458
|
-
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2459
|
-
[this.mapW(this.u), this.mapH(this.v + l)],
|
|
2460
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)]
|
|
2760
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2761
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
|
|
2762
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
|
|
2763
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2461
2764
|
];
|
|
2462
2765
|
}
|
|
2463
2766
|
getUvWest(w, h, l) {
|
|
2464
2767
|
return [
|
|
2465
|
-
[this.mapW(this.u + l
|
|
2466
|
-
[this.mapW(this.u
|
|
2467
|
-
[this.mapW(this.u + l
|
|
2468
|
-
[this.mapW(this.u
|
|
2768
|
+
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2769
|
+
[this.mapW(this.u), this.mapH(this.v + l + h)],
|
|
2770
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2771
|
+
[this.mapW(this.u), this.mapH(this.v + l)]
|
|
2469
2772
|
];
|
|
2470
2773
|
}
|
|
2471
2774
|
getUvUp(w, h, l) {
|
|
@@ -2478,26 +2781,26 @@ var MinecraftCubeTexture = class {
|
|
|
2478
2781
|
}
|
|
2479
2782
|
getUvDown(w, h, l) {
|
|
2480
2783
|
return [
|
|
2481
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2482
|
-
[this.mapW(this.u + l + w), this.mapH(this.v + l)],
|
|
2483
2784
|
[this.mapW(this.u + l), this.mapH(this.v)],
|
|
2484
|
-
[this.mapW(this.u + l + w), this.mapH(this.v)]
|
|
2785
|
+
[this.mapW(this.u + l + w), this.mapH(this.v)],
|
|
2786
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2787
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2485
2788
|
];
|
|
2486
2789
|
}
|
|
2487
2790
|
getUvSouth(w, h, l) {
|
|
2488
2791
|
return [
|
|
2489
|
-
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2490
2792
|
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l + h)],
|
|
2491
|
-
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
|
|
2492
|
-
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)]
|
|
2793
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2794
|
+
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
|
|
2795
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
|
|
2493
2796
|
];
|
|
2494
2797
|
}
|
|
2495
2798
|
getUvNorth(w, h, l) {
|
|
2496
2799
|
return [
|
|
2497
|
-
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2498
2800
|
[this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
|
|
2499
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2500
|
-
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2801
|
+
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2802
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)],
|
|
2803
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)]
|
|
2501
2804
|
];
|
|
2502
2805
|
}
|
|
2503
2806
|
getFaceUv(face, w, h, l) {
|
|
@@ -2516,10 +2819,12 @@ var MinecraftCubeTexture = class {
|
|
|
2516
2819
|
return this.getUvNorth(w, h, l);
|
|
2517
2820
|
}
|
|
2518
2821
|
}
|
|
2519
|
-
toUvArray(w, h, l) {
|
|
2822
|
+
toUvArray(w, h, l, mirror = false) {
|
|
2520
2823
|
const uv = [];
|
|
2521
2824
|
for (let i = 0; i < CUBE_FACES.length; i++) {
|
|
2522
|
-
|
|
2825
|
+
const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
|
|
2826
|
+
const corners = this.getFaceUv(face, w, h, l);
|
|
2827
|
+
UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
|
|
2523
2828
|
}
|
|
2524
2829
|
return uv;
|
|
2525
2830
|
}
|
|
@@ -2549,76 +2854,85 @@ function shutdown() {
|
|
|
2549
2854
|
Caching.end();
|
|
2550
2855
|
}
|
|
2551
2856
|
|
|
2857
|
+
// src/error/MineRenderError.ts
|
|
2858
|
+
var MineRenderError = class _MineRenderError extends Error {
|
|
2859
|
+
constructor(msg) {
|
|
2860
|
+
super(msg);
|
|
2861
|
+
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
2862
|
+
}
|
|
2863
|
+
get name() {
|
|
2864
|
+
return "MineRenderError";
|
|
2865
|
+
}
|
|
2866
|
+
};
|
|
2867
|
+
|
|
2552
2868
|
// src/assets/Entities.ts
|
|
2553
|
-
var import_typescript_memoize3 = require("typescript-memoize");
|
|
2554
2869
|
var Entities = class {
|
|
2555
|
-
static async getBlockEntityModels() {
|
|
2556
|
-
const key = AssetKey.parse("models", "minerender:blockEntityModels");
|
|
2557
|
-
console.log(key);
|
|
2558
|
-
return AssetLoader.get(key, "json" /* JSON */);
|
|
2559
|
-
}
|
|
2560
|
-
static async getEntityModels() {
|
|
2561
|
-
const key = AssetKey.parse("models", "minerender:entityModels");
|
|
2562
|
-
console.log(key);
|
|
2563
|
-
return AssetLoader.get(key, "json" /* JSON */);
|
|
2564
|
-
}
|
|
2565
|
-
// BlockEntity names are hardcoded
|
|
2566
|
-
static async getBlockList() {
|
|
2567
|
-
const models = await this.getBlockEntityModels();
|
|
2568
|
-
if (!models) {
|
|
2569
|
-
return [];
|
|
2570
|
-
}
|
|
2571
|
-
return Object.keys(models);
|
|
2572
|
-
}
|
|
2573
2870
|
static async getEntityList() {
|
|
2574
|
-
const
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
if (!models) {
|
|
2583
|
-
return void 0;
|
|
2584
|
-
}
|
|
2585
|
-
if (!textureKey) {
|
|
2586
|
-
textureKey = modelKey;
|
|
2587
|
-
}
|
|
2588
|
-
const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
|
|
2589
|
-
return {
|
|
2590
|
-
key: textureKey,
|
|
2591
|
-
parts: models[baseKey.toNamespacedString()]
|
|
2871
|
+
const collect = async (path) => {
|
|
2872
|
+
const prefix2 = path ? `${path}/` : "";
|
|
2873
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
|
|
2874
|
+
const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
2875
|
+
if (!list) return [];
|
|
2876
|
+
const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
2877
|
+
const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
2878
|
+
return [...files, ...children.flat()];
|
|
2592
2879
|
};
|
|
2880
|
+
return collect("");
|
|
2881
|
+
}
|
|
2882
|
+
static async getEntity(modelKey, textureKey, options) {
|
|
2883
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
2884
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
2885
|
+
const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
2886
|
+
if (!model) return void 0;
|
|
2887
|
+
const layerName = options?.layer ?? "main";
|
|
2888
|
+
const layer = model.layers[layerName];
|
|
2889
|
+
if (!layer) {
|
|
2890
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
2891
|
+
}
|
|
2892
|
+
let texture;
|
|
2893
|
+
if (textureKey) {
|
|
2894
|
+
const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
|
|
2895
|
+
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);
|
|
2896
|
+
} else if (layer.textureLocation !== void 0) {
|
|
2897
|
+
texture = AssetKey.parse("textures", layer.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
2898
|
+
} else {
|
|
2899
|
+
texture = await this.resolveTexture(modelKey);
|
|
2900
|
+
}
|
|
2901
|
+
return { key: textureKey ?? modelKey, texture, layer, id: model.id };
|
|
2902
|
+
}
|
|
2903
|
+
static async resolveTexture(modelKey) {
|
|
2904
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
2905
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
2906
|
+
return Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
2907
|
+
const name = path.split("/").pop();
|
|
2908
|
+
for (const candidate of [path, `${path}/${name}`]) {
|
|
2909
|
+
const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
|
|
2910
|
+
if (await ModelTextures.get(texture)) return texture;
|
|
2911
|
+
}
|
|
2912
|
+
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json");
|
|
2913
|
+
const list = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
2914
|
+
const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
2915
|
+
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
2916
|
+
if (!file) return void 0;
|
|
2917
|
+
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json");
|
|
2918
|
+
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
2919
|
+
const assets = variant?.assets;
|
|
2920
|
+
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
2921
|
+
return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
|
|
2922
|
+
});
|
|
2593
2923
|
}
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
}
|
|
2602
|
-
const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
|
|
2603
|
-
return {
|
|
2604
|
-
key: textureKey,
|
|
2605
|
-
parts: models[baseKey.toNamespacedString()]
|
|
2606
|
-
};
|
|
2924
|
+
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
2925
|
+
static getBlockList() {
|
|
2926
|
+
return this.getEntityList();
|
|
2927
|
+
}
|
|
2928
|
+
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
2929
|
+
static getBlock(modelKey, textureKey, options) {
|
|
2930
|
+
return this.getEntity(modelKey, textureKey, options);
|
|
2607
2931
|
}
|
|
2608
|
-
};
|
|
2609
|
-
__decorateClass([
|
|
2610
|
-
(0, import_typescript_memoize3.Memoize)()
|
|
2611
|
-
], Entities, "getBlockEntityModels", 1);
|
|
2612
|
-
__decorateClass([
|
|
2613
|
-
(0, import_typescript_memoize3.Memoize)()
|
|
2614
|
-
], Entities, "getEntityModels", 1);
|
|
2615
|
-
var EntityModels = class {
|
|
2616
|
-
};
|
|
2617
|
-
var BlockEntityModels = class {
|
|
2618
2932
|
};
|
|
2619
2933
|
|
|
2620
2934
|
// src/renderer/SceneObject.ts
|
|
2621
|
-
var
|
|
2935
|
+
var import_three10 = require("three");
|
|
2622
2936
|
|
|
2623
2937
|
// src/instance/InstanceReference.ts
|
|
2624
2938
|
var InstanceReference = class {
|
|
@@ -2663,28 +2977,17 @@ function isInstanceReference(obj) {
|
|
|
2663
2977
|
return obj.isInstanceReference;
|
|
2664
2978
|
}
|
|
2665
2979
|
|
|
2666
|
-
// src/error/MineRenderError.ts
|
|
2667
|
-
var MineRenderError = class _MineRenderError extends Error {
|
|
2668
|
-
constructor(msg) {
|
|
2669
|
-
super(msg);
|
|
2670
|
-
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
2671
|
-
}
|
|
2672
|
-
get name() {
|
|
2673
|
-
return "MineRenderError";
|
|
2674
|
-
}
|
|
2675
|
-
};
|
|
2676
|
-
|
|
2677
2980
|
// src/renderer/SceneObject.ts
|
|
2678
|
-
var
|
|
2679
|
-
var
|
|
2680
|
-
var _SceneObject = class _SceneObject extends
|
|
2981
|
+
var import_ts_deepmerge3 = __toESM(require_dist());
|
|
2982
|
+
var p6 = prefix("SceneObject");
|
|
2983
|
+
var _SceneObject = class _SceneObject extends import_three10.Object3D {
|
|
2681
2984
|
constructor(options) {
|
|
2682
2985
|
super();
|
|
2683
2986
|
this.isSceneObject = true;
|
|
2684
2987
|
this.materialCallbacks = {};
|
|
2685
2988
|
this._isInstanced = false;
|
|
2686
2989
|
this._instanceCounter = 0;
|
|
2687
|
-
this.options = (0,
|
|
2990
|
+
this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
2688
2991
|
console.log("SceneObject options", this.options);
|
|
2689
2992
|
}
|
|
2690
2993
|
set scene(scene) {
|
|
@@ -2715,7 +3018,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2715
3018
|
return group;
|
|
2716
3019
|
}
|
|
2717
3020
|
createGroup(name, x = 0, y = 0, z = 0, offsetAxis, offset = 0) {
|
|
2718
|
-
const obj = new
|
|
3021
|
+
const obj = new import_three10.Object3D();
|
|
2719
3022
|
if (name) {
|
|
2720
3023
|
obj.name = `group:${name}`;
|
|
2721
3024
|
}
|
|
@@ -2765,7 +3068,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2765
3068
|
return mesh;
|
|
2766
3069
|
}
|
|
2767
3070
|
createMesh(name, geometry, material, offsetAxis, offset = 0) {
|
|
2768
|
-
const mesh = new
|
|
3071
|
+
const mesh = new import_three10.Mesh(geometry, material);
|
|
2769
3072
|
if (name) {
|
|
2770
3073
|
mesh.name = `mesh:${name}`;
|
|
2771
3074
|
}
|
|
@@ -2777,7 +3080,8 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2777
3080
|
return mesh;
|
|
2778
3081
|
}
|
|
2779
3082
|
createInstancedMesh(name, geometry, material, count) {
|
|
2780
|
-
const mesh = new
|
|
3083
|
+
const mesh = new import_three10.InstancedMesh(geometry, material, count);
|
|
3084
|
+
mesh.count = 0;
|
|
2781
3085
|
if (name) {
|
|
2782
3086
|
mesh.name = `mesh:${name}`;
|
|
2783
3087
|
}
|
|
@@ -2798,15 +3102,8 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2798
3102
|
return this.toggleObjectVisibility(this.getMeshByName(name), visible);
|
|
2799
3103
|
}
|
|
2800
3104
|
iterateAllMeshes(cb) {
|
|
2801
|
-
this.
|
|
2802
|
-
if (obj
|
|
2803
|
-
cb(obj);
|
|
2804
|
-
}
|
|
2805
|
-
obj.children.forEach((obj1) => {
|
|
2806
|
-
if (obj1.isMesh) {
|
|
2807
|
-
cb(obj1);
|
|
2808
|
-
}
|
|
2809
|
-
});
|
|
3105
|
+
this.traverse((obj) => {
|
|
3106
|
+
if (isMesh(obj)) cb(obj);
|
|
2810
3107
|
});
|
|
2811
3108
|
}
|
|
2812
3109
|
//</editor-fold>
|
|
@@ -2854,10 +3151,14 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2854
3151
|
nextInstance() {
|
|
2855
3152
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2856
3153
|
const i = this._instanceCounter++;
|
|
2857
|
-
this.setMatrixAt(i, new
|
|
2858
|
-
|
|
3154
|
+
this.setMatrixAt(i, new import_three10.Matrix4());
|
|
3155
|
+
const mesh = this.children[0];
|
|
3156
|
+
if (mesh && isInstancedMesh(mesh)) {
|
|
3157
|
+
mesh.count = Math.min(this._instanceCounter, mesh.instanceMatrix.count);
|
|
3158
|
+
}
|
|
3159
|
+
console.debug(p6, "nextInstance " + i);
|
|
2859
3160
|
if (i === this.options.maxInstanceCount) {
|
|
2860
|
-
console.warn(
|
|
3161
|
+
console.warn(p6, "Max instance count reached for " + this);
|
|
2861
3162
|
}
|
|
2862
3163
|
if (this.scene) {
|
|
2863
3164
|
this.scene.stats.instanceCount++;
|
|
@@ -2867,7 +3168,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2867
3168
|
}
|
|
2868
3169
|
//</editor-fold>
|
|
2869
3170
|
//<editor-fold desc="TRANSFORMATION">
|
|
2870
|
-
getMatrixAt(index, matrix = new
|
|
3171
|
+
getMatrixAt(index, matrix = new import_three10.Matrix4()) {
|
|
2871
3172
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2872
3173
|
const child = this.children[0];
|
|
2873
3174
|
if (child && isInstancedMesh(child)) {
|
|
@@ -2886,16 +3187,16 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2886
3187
|
}
|
|
2887
3188
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
2888
3189
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2889
|
-
const oldPosition = new
|
|
2890
|
-
const oldRotation = new
|
|
2891
|
-
const oldScale = new
|
|
2892
|
-
const matrix = new
|
|
3190
|
+
const oldPosition = new import_three10.Vector3();
|
|
3191
|
+
const oldRotation = new import_three10.Quaternion();
|
|
3192
|
+
const oldScale = new import_three10.Vector3();
|
|
3193
|
+
const matrix = new import_three10.Matrix4();
|
|
2893
3194
|
if (!scale || !rotation || !position) {
|
|
2894
3195
|
this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
|
|
2895
3196
|
}
|
|
2896
3197
|
matrix.compose(
|
|
2897
3198
|
position ? position : oldPosition,
|
|
2898
|
-
rotation ? new
|
|
3199
|
+
rotation ? new import_three10.Quaternion().setFromEuler(rotation) : oldRotation,
|
|
2899
3200
|
scale ? scale : oldScale
|
|
2900
3201
|
);
|
|
2901
3202
|
this.setMatrixAt(index, matrix);
|
|
@@ -2904,7 +3205,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2904
3205
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2905
3206
|
this.setPositionRotationScaleAt(index, position);
|
|
2906
3207
|
}
|
|
2907
|
-
getPositionAt(index, vector = new
|
|
3208
|
+
getPositionAt(index, vector = new import_three10.Vector3()) {
|
|
2908
3209
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2909
3210
|
const matrix = this.getMatrixAt(index);
|
|
2910
3211
|
vector.setFromMatrixPosition(matrix);
|
|
@@ -2914,7 +3215,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2914
3215
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2915
3216
|
this.setPositionRotationScaleAt(index, void 0, rotation, void 0);
|
|
2916
3217
|
}
|
|
2917
|
-
getRotationAt(index, euler = new
|
|
3218
|
+
getRotationAt(index, euler = new import_three10.Euler()) {
|
|
2918
3219
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2919
3220
|
const matrix = this.getMatrixAt(index);
|
|
2920
3221
|
euler.setFromRotationMatrix(matrix);
|
|
@@ -2924,7 +3225,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
2924
3225
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2925
3226
|
this.setPositionRotationScaleAt(index, void 0, void 0, scale);
|
|
2926
3227
|
}
|
|
2927
|
-
getScaleAt(index, vector = new
|
|
3228
|
+
getScaleAt(index, vector = new import_three10.Vector3()) {
|
|
2928
3229
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
2929
3230
|
const matrix = this.getMatrixAt(index);
|
|
2930
3231
|
vector.setFromMatrixScale(matrix);
|
|
@@ -3033,7 +3334,7 @@ var _SceneObject = class _SceneObject extends import_three9.Object3D {
|
|
|
3033
3334
|
}
|
|
3034
3335
|
//</editor-fold>
|
|
3035
3336
|
};
|
|
3036
|
-
_SceneObject.DEFAULT_OPTIONS = (0,
|
|
3337
|
+
_SceneObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge3.default)({}, {
|
|
3037
3338
|
instanceMeshes: true,
|
|
3038
3339
|
maxInstanceCount: 50,
|
|
3039
3340
|
mergeMeshes: true,
|
|
@@ -3045,16 +3346,15 @@ function isSceneObject(obj) {
|
|
|
3045
3346
|
}
|
|
3046
3347
|
|
|
3047
3348
|
// src/entity/scene/EntityObject.ts
|
|
3048
|
-
var
|
|
3049
|
-
var
|
|
3050
|
-
var
|
|
3051
|
-
var EntityObject = class extends SceneObject {
|
|
3349
|
+
var import_ts_deepmerge4 = __toESM(require_dist());
|
|
3350
|
+
var import_three12 = require("three");
|
|
3351
|
+
var _EntityObject = class _EntityObject extends SceneObject {
|
|
3052
3352
|
constructor(entity, options) {
|
|
3053
3353
|
super();
|
|
3054
3354
|
this.entity = entity;
|
|
3055
3355
|
this.isEntityObject = true;
|
|
3056
3356
|
this.meshesCreated = false;
|
|
3057
|
-
this.options = (0,
|
|
3357
|
+
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
3058
3358
|
}
|
|
3059
3359
|
async init() {
|
|
3060
3360
|
this.createMeshes();
|
|
@@ -3063,65 +3363,78 @@ var EntityObject = class extends SceneObject {
|
|
|
3063
3363
|
dispose() {
|
|
3064
3364
|
super.dispose();
|
|
3065
3365
|
}
|
|
3066
|
-
|
|
3067
|
-
this.
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3366
|
+
get textureKey() {
|
|
3367
|
+
if (this.entity.texture) return this.entity.texture;
|
|
3368
|
+
const key = this.entity.key;
|
|
3369
|
+
return new AssetKey(
|
|
3370
|
+
key.namespace,
|
|
3371
|
+
isAssetKey(key) ? key.getFullPath() : key.path,
|
|
3071
3372
|
"textures",
|
|
3072
3373
|
"entity",
|
|
3073
3374
|
"assets",
|
|
3074
3375
|
".png"
|
|
3075
|
-
)
|
|
3376
|
+
);
|
|
3377
|
+
}
|
|
3378
|
+
async loadTextures() {
|
|
3379
|
+
this.imageData = await ModelTextures.get(this.textureKey);
|
|
3076
3380
|
}
|
|
3077
|
-
//TODO: abstract this, since extracted model data can be used for entities, blocks, players
|
|
3078
3381
|
createMeshes(force = false) {
|
|
3079
3382
|
if (this.meshesCreated && !force) return;
|
|
3080
|
-
const
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
const partAnchor = new import_three11.Object3D();
|
|
3085
|
-
partAnchor.position.x = part.pivotX;
|
|
3086
|
-
partAnchor.position.y = part.pivotY;
|
|
3087
|
-
partAnchor.position.z = part.pivotZ;
|
|
3088
|
-
for (let cube of part.cubes) {
|
|
3089
|
-
const w = cube.maxX - cube.minX;
|
|
3090
|
-
const h = cube.maxY - cube.minY;
|
|
3091
|
-
const l = cube.maxZ - cube.minZ;
|
|
3092
|
-
const uv = texture.toUvArray(w, h, l);
|
|
3093
|
-
const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
|
|
3094
|
-
cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
|
|
3095
|
-
cubeGeo.applyMatrix4(new THREE2.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
|
|
3096
|
-
applyModelPartRotation(part, cubeGeo);
|
|
3097
|
-
const mesh = this.createMesh(partName, cubeGeo, mat);
|
|
3098
|
-
partAnchor.add(mesh);
|
|
3099
|
-
if (this.options.wireframe) {
|
|
3100
|
-
addWireframeToMesh(cubeGeo, mesh);
|
|
3101
|
-
}
|
|
3102
|
-
}
|
|
3103
|
-
this.add(partAnchor);
|
|
3104
|
-
}
|
|
3383
|
+
const modelRoot = new import_three12.Object3D();
|
|
3384
|
+
if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
|
|
3385
|
+
this.add(modelRoot);
|
|
3386
|
+
this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
|
|
3105
3387
|
this.meshesCreated = true;
|
|
3106
3388
|
}
|
|
3107
|
-
|
|
3108
|
-
const
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3389
|
+
createPart(name, part, parent, textureSize, material) {
|
|
3390
|
+
const anchor = this.createGroup(name);
|
|
3391
|
+
anchor.position.fromArray(part.pose.offset);
|
|
3392
|
+
anchor.rotation.set(...part.pose.rotation, "ZYX");
|
|
3393
|
+
anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
|
|
3394
|
+
parent.add(anchor);
|
|
3395
|
+
const size = part.texture ?? textureSize;
|
|
3396
|
+
for (const cube of part.cubes) {
|
|
3397
|
+
const [width, height, depth] = cube.size;
|
|
3398
|
+
const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
|
|
3399
|
+
const texture = new MinecraftCubeTexture(...cube.uv, ...size);
|
|
3400
|
+
const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
|
|
3401
|
+
const geometry = this._getBoxGeometryForDimensionsAndUv(
|
|
3402
|
+
width + growX * 2,
|
|
3403
|
+
height + growY * 2,
|
|
3404
|
+
depth + growZ * 2,
|
|
3405
|
+
uv
|
|
3406
|
+
).clone();
|
|
3407
|
+
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
3408
|
+
const mesh = this.createMesh(name, geometry, material);
|
|
3409
|
+
anchor.add(mesh);
|
|
3410
|
+
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
3411
|
+
}
|
|
3412
|
+
for (const [childName, child] of Object.entries(part.children)) {
|
|
3413
|
+
this.createPart(childName, child, anchor, size, material);
|
|
3121
3414
|
}
|
|
3122
3415
|
}
|
|
3416
|
+
async applyTextures() {
|
|
3417
|
+
const assetKeyStr = this.textureKey.serialize();
|
|
3418
|
+
const keyStr = `entity:${assetKeyStr}`;
|
|
3419
|
+
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
3420
|
+
if (!mat) {
|
|
3421
|
+
const pending = this.loadTextures();
|
|
3422
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
3423
|
+
await pending;
|
|
3424
|
+
if (!this.imageData) return;
|
|
3425
|
+
const canvas = this.imageData.data.canvas;
|
|
3426
|
+
const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
|
|
3427
|
+
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
3428
|
+
this.imageData = void 0;
|
|
3429
|
+
}
|
|
3430
|
+
this.iterateAllMeshes((mesh) => {
|
|
3431
|
+
mesh.material = mat;
|
|
3432
|
+
});
|
|
3433
|
+
this.notifyDirty();
|
|
3434
|
+
}
|
|
3123
3435
|
};
|
|
3124
|
-
|
|
3436
|
+
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, { flip: true });
|
|
3437
|
+
var EntityObject = _EntityObject;
|
|
3125
3438
|
function isEntityObject(obj) {
|
|
3126
3439
|
return obj.isEntityObject;
|
|
3127
3440
|
}
|
|
@@ -3132,16 +3445,16 @@ var GuiObject = class extends SceneObject {
|
|
|
3132
3445
|
};
|
|
3133
3446
|
|
|
3134
3447
|
// src/inspector/SceneInspector.ts
|
|
3135
|
-
var
|
|
3136
|
-
var
|
|
3448
|
+
var import_three13 = require("three");
|
|
3449
|
+
var p7 = prefix("SceneInspector");
|
|
3137
3450
|
var help = "<span>Ctrl+Click to Select<br/></span><br/>";
|
|
3138
3451
|
var SceneInspector = class {
|
|
3139
3452
|
constructor(renderer) {
|
|
3140
3453
|
this.renderer = renderer;
|
|
3141
|
-
this.mouse = new
|
|
3454
|
+
this.mouse = new import_three13.Vector2();
|
|
3142
3455
|
this.objectInfoContainer = document.createElement("div");
|
|
3143
3456
|
this.objectControlsContainer = document.createElement("div");
|
|
3144
|
-
this.raycaster = new
|
|
3457
|
+
this.raycaster = new import_three13.Raycaster();
|
|
3145
3458
|
this.init();
|
|
3146
3459
|
}
|
|
3147
3460
|
init() {
|
|
@@ -3202,7 +3515,7 @@ var SceneInspector = class {
|
|
|
3202
3515
|
}
|
|
3203
3516
|
selectObject(targetObject, targetIntersection) {
|
|
3204
3517
|
this.selectedObject = targetObject;
|
|
3205
|
-
console.log(
|
|
3518
|
+
console.log(p7, "selected", targetObject);
|
|
3206
3519
|
this.redraw(targetObject, targetIntersection);
|
|
3207
3520
|
}
|
|
3208
3521
|
redraw(targetObject, targetIntersection) {
|
|
@@ -3500,7 +3813,7 @@ var SceneStatsDisplay = class {
|
|
|
3500
3813
|
};
|
|
3501
3814
|
|
|
3502
3815
|
// src/instance/InstanceManager.ts
|
|
3503
|
-
var
|
|
3816
|
+
var p8 = prefix("InstanceManager");
|
|
3504
3817
|
var InstanceManager = class {
|
|
3505
3818
|
constructor() {
|
|
3506
3819
|
this.isInstanceManager = true;
|
|
@@ -3508,7 +3821,7 @@ var InstanceManager = class {
|
|
|
3508
3821
|
}
|
|
3509
3822
|
async get(key) {
|
|
3510
3823
|
if (key in this.instanceCache) {
|
|
3511
|
-
console.debug(
|
|
3824
|
+
console.debug(p8, "key in cache", key);
|
|
3512
3825
|
return (await this.instanceCache[key]).nextInstance();
|
|
3513
3826
|
}
|
|
3514
3827
|
return void 0;
|
|
@@ -3517,13 +3830,17 @@ var InstanceManager = class {
|
|
|
3517
3830
|
if (key in this.instanceCache) {
|
|
3518
3831
|
return await this.get(key);
|
|
3519
3832
|
}
|
|
3520
|
-
console.debug(
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
})
|
|
3526
|
-
|
|
3833
|
+
console.debug(p8, "key not in cache", key);
|
|
3834
|
+
const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
|
|
3835
|
+
this.instanceCache[key] = pending;
|
|
3836
|
+
try {
|
|
3837
|
+
return await pending;
|
|
3838
|
+
} catch (error) {
|
|
3839
|
+
if (this.instanceCache[key] === pending) {
|
|
3840
|
+
delete this.instanceCache[key];
|
|
3841
|
+
}
|
|
3842
|
+
throw error;
|
|
3843
|
+
}
|
|
3527
3844
|
}
|
|
3528
3845
|
reset() {
|
|
3529
3846
|
for (let instanceCacheKey in this.instanceCache) {
|
|
@@ -3540,20 +3857,6 @@ function isInstanceable(obj) {
|
|
|
3540
3857
|
return "nextInstance" in obj;
|
|
3541
3858
|
}
|
|
3542
3859
|
|
|
3543
|
-
// src/model/DisplayPosition.ts
|
|
3544
|
-
var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
|
|
3545
|
-
DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
|
|
3546
|
-
DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
|
|
3547
|
-
DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
|
|
3548
|
-
DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
|
|
3549
|
-
DisplayPosition2["GUI"] = "gui";
|
|
3550
|
-
DisplayPosition2["HEAD"] = "head";
|
|
3551
|
-
DisplayPosition2["GROUND"] = "ground";
|
|
3552
|
-
DisplayPosition2["FIXED"] = "fixed";
|
|
3553
|
-
return DisplayPosition2;
|
|
3554
|
-
})(DisplayPosition || {});
|
|
3555
|
-
var DISPLAY_POSITIONS = Object.values(DisplayPosition);
|
|
3556
|
-
|
|
3557
3860
|
// src/model/GuiLight.ts
|
|
3558
3861
|
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
3559
3862
|
GuiLight2["FRONT"] = "front";
|
|
@@ -3576,11 +3879,96 @@ function isQuadArray(obj) {
|
|
|
3576
3879
|
return Array.isArray(obj) && obj.length === 4;
|
|
3577
3880
|
}
|
|
3578
3881
|
|
|
3882
|
+
// src/model/block/blockTints.json
|
|
3883
|
+
var blockTints_default = {
|
|
3884
|
+
"minecraft:large_fern": { source: "grass" },
|
|
3885
|
+
"minecraft:tall_grass": { source: "grass" },
|
|
3886
|
+
"minecraft:grass_block": { source: "grass" },
|
|
3887
|
+
"minecraft:fern": { source: "grass" },
|
|
3888
|
+
"minecraft:grass": { source: "grass" },
|
|
3889
|
+
"minecraft:short_grass": { source: "grass" },
|
|
3890
|
+
"minecraft:potted_fern": { source: "grass" },
|
|
3891
|
+
"minecraft:bush": { source: "grass" },
|
|
3892
|
+
"minecraft:pink_petals": { source: "grass", untinted: [0] },
|
|
3893
|
+
"minecraft:wildflowers": { source: "grass", untinted: [0] },
|
|
3894
|
+
"minecraft:spruce_leaves": { source: "constant", color: 6396257 },
|
|
3895
|
+
"minecraft:birch_leaves": { source: "constant", color: 8431445 },
|
|
3896
|
+
"minecraft:oak_leaves": { source: "constant", color: 4764952 },
|
|
3897
|
+
"minecraft:jungle_leaves": { source: "constant", color: 4764952 },
|
|
3898
|
+
"minecraft:acacia_leaves": { source: "constant", color: 4764952 },
|
|
3899
|
+
"minecraft:dark_oak_leaves": { source: "constant", color: 4764952 },
|
|
3900
|
+
"minecraft:vine": { source: "constant", color: 4764952 },
|
|
3901
|
+
"minecraft:mangrove_leaves": { source: "constant", color: 4764952 },
|
|
3902
|
+
"minecraft:leaf_litter": { source: "constant", color: 6044722 },
|
|
3903
|
+
"minecraft:water_cauldron": { source: "constant", color: 4159204 },
|
|
3904
|
+
"minecraft:redstone_wire": { source: "redstone" },
|
|
3905
|
+
"minecraft:attached_melon_stem": { source: "constant", color: 14731036 },
|
|
3906
|
+
"minecraft:attached_pumpkin_stem": { source: "constant", color: 14731036 },
|
|
3907
|
+
"minecraft:melon_stem": { source: "stem" },
|
|
3908
|
+
"minecraft:pumpkin_stem": { source: "stem" },
|
|
3909
|
+
"minecraft:lily_pad": { source: "constant", color: 7455580 }
|
|
3910
|
+
};
|
|
3911
|
+
|
|
3912
|
+
// src/model/block/BlockTints.ts
|
|
3913
|
+
var rules = blockTints_default;
|
|
3914
|
+
var BlockTints = class {
|
|
3915
|
+
/** Resolves block preview colors without biome context; explicit tints take precedence. */
|
|
3916
|
+
static async get(key, state, model, tints) {
|
|
3917
|
+
const rule = key && rules[key.toNamespacedString()];
|
|
3918
|
+
if (!key || !rule) return tints;
|
|
3919
|
+
const indices = /* @__PURE__ */ new Set();
|
|
3920
|
+
for (const element of model.elements ?? []) {
|
|
3921
|
+
for (const face of Object.values(element.faces)) {
|
|
3922
|
+
const index = face?.tintindex;
|
|
3923
|
+
if (index !== void 0 && index >= 0 && tints?.[index] === void 0 && !rule.untinted?.includes(index)) {
|
|
3924
|
+
indices.add(index);
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
if (!indices.size) return tints;
|
|
3929
|
+
let color;
|
|
3930
|
+
switch (rule.source) {
|
|
3931
|
+
case "constant":
|
|
3932
|
+
color = rule.color;
|
|
3933
|
+
break;
|
|
3934
|
+
case "grass":
|
|
3935
|
+
color = await this.grassColor(key);
|
|
3936
|
+
break;
|
|
3937
|
+
case "redstone": {
|
|
3938
|
+
const power = Number(state.power ?? 0) / 15;
|
|
3939
|
+
const red = power * 0.6 + (power > 0 ? 0.4 : 0.3);
|
|
3940
|
+
const green = Math.max(0, power * power * 0.7 - 0.5);
|
|
3941
|
+
const blue = Math.max(0, power * power * 0.6 - 0.7);
|
|
3942
|
+
color = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
|
|
3943
|
+
break;
|
|
3944
|
+
}
|
|
3945
|
+
case "stem": {
|
|
3946
|
+
const age = Number(state.age ?? 0);
|
|
3947
|
+
color = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
|
|
3948
|
+
break;
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
|
|
3952
|
+
}
|
|
3953
|
+
static async grassColor(origin) {
|
|
3954
|
+
const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
|
|
3955
|
+
return await Caching.blockTintCache.get(key.serialize(), async () => {
|
|
3956
|
+
const image = await ModelTextures.get(key);
|
|
3957
|
+
if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
|
|
3958
|
+
if (image.width !== 256 || image.height !== 256) {
|
|
3959
|
+
throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
|
|
3960
|
+
}
|
|
3961
|
+
const [red, green, blue] = image.data.getImageData(127, 127, 1, 1).data;
|
|
3962
|
+
return red << 16 | green << 8 | blue;
|
|
3963
|
+
});
|
|
3964
|
+
}
|
|
3965
|
+
};
|
|
3966
|
+
|
|
3579
3967
|
// src/model/scene/ModelObject.ts
|
|
3580
|
-
var
|
|
3968
|
+
var import_three16 = require("three");
|
|
3581
3969
|
|
|
3582
3970
|
// src/three/BufferGeometryUtils.js
|
|
3583
|
-
var
|
|
3971
|
+
var import_three15 = require("three");
|
|
3584
3972
|
function computeTangents(geometry) {
|
|
3585
3973
|
geometry.computeTangents();
|
|
3586
3974
|
console.warn("THREE.BufferGeometryUtils: .computeTangents() has been removed. Use BufferGeometry.computeTangents() instead.");
|
|
@@ -3592,7 +3980,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
|
|
|
3592
3980
|
const attributes = {};
|
|
3593
3981
|
const morphAttributes = {};
|
|
3594
3982
|
const morphTargetsRelative = geometries[0].morphTargetsRelative;
|
|
3595
|
-
const mergedGeometry = new
|
|
3983
|
+
const mergedGeometry = new import_three15.BufferGeometry();
|
|
3596
3984
|
let offset = 0;
|
|
3597
3985
|
for (let i = 0; i < geometries.length; ++i) {
|
|
3598
3986
|
const geometry = geometries[i];
|
|
@@ -3716,7 +4104,7 @@ function mergeBufferAttributes(attributes) {
|
|
|
3716
4104
|
array.set(attributes[i].array, offset);
|
|
3717
4105
|
offset += attributes[i].array.length;
|
|
3718
4106
|
}
|
|
3719
|
-
return new
|
|
4107
|
+
return new import_three15.BufferAttribute(array, itemSize, normalized);
|
|
3720
4108
|
}
|
|
3721
4109
|
function interleaveAttributes(attributes) {
|
|
3722
4110
|
let TypedArray;
|
|
@@ -3732,7 +4120,7 @@ function interleaveAttributes(attributes) {
|
|
|
3732
4120
|
arrayLength += attribute.array.length;
|
|
3733
4121
|
stride += attribute.itemSize;
|
|
3734
4122
|
}
|
|
3735
|
-
const interleavedBuffer = new
|
|
4123
|
+
const interleavedBuffer = new import_three15.InterleavedBuffer(new TypedArray(arrayLength), stride);
|
|
3736
4124
|
let offset = 0;
|
|
3737
4125
|
const res = [];
|
|
3738
4126
|
const getters = ["getX", "getY", "getZ", "getW"];
|
|
@@ -3741,7 +4129,7 @@ function interleaveAttributes(attributes) {
|
|
|
3741
4129
|
const attribute = attributes[j];
|
|
3742
4130
|
const itemSize = attribute.itemSize;
|
|
3743
4131
|
const count = attribute.count;
|
|
3744
|
-
const iba = new
|
|
4132
|
+
const iba = new import_three15.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
|
|
3745
4133
|
res.push(iba);
|
|
3746
4134
|
offset += itemSize;
|
|
3747
4135
|
for (let c = 0; c < count; c++) {
|
|
@@ -3825,13 +4213,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
3825
4213
|
const name = attributeNames[i];
|
|
3826
4214
|
const oldAttribute = geometry.getAttribute(name);
|
|
3827
4215
|
const buffer = new oldAttribute.array.constructor(attrArrays[name]);
|
|
3828
|
-
const attribute = new
|
|
4216
|
+
const attribute = new import_three15.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
|
|
3829
4217
|
result.setAttribute(name, attribute);
|
|
3830
4218
|
if (name in morphAttrsArrays) {
|
|
3831
4219
|
for (let j = 0; j < morphAttrsArrays[name].length; j++) {
|
|
3832
4220
|
const oldMorphAttribute = geometry.morphAttributes[name][j];
|
|
3833
4221
|
const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
|
|
3834
|
-
const morphAttribute = new
|
|
4222
|
+
const morphAttribute = new import_three15.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
|
|
3835
4223
|
result.morphAttributes[name][j] = morphAttribute;
|
|
3836
4224
|
}
|
|
3837
4225
|
}
|
|
@@ -3840,11 +4228,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
3840
4228
|
return result;
|
|
3841
4229
|
}
|
|
3842
4230
|
function toTrianglesDrawMode(geometry, drawMode) {
|
|
3843
|
-
if (drawMode ===
|
|
4231
|
+
if (drawMode === import_three15.TrianglesDrawMode) {
|
|
3844
4232
|
console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
|
|
3845
4233
|
return geometry;
|
|
3846
4234
|
}
|
|
3847
|
-
if (drawMode ===
|
|
4235
|
+
if (drawMode === import_three15.TriangleFanDrawMode || drawMode === import_three15.TriangleStripDrawMode) {
|
|
3848
4236
|
let index = geometry.getIndex();
|
|
3849
4237
|
if (index === null) {
|
|
3850
4238
|
const indices = [];
|
|
@@ -3862,7 +4250,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
|
|
|
3862
4250
|
}
|
|
3863
4251
|
const numberOfTriangles = index.count - 2;
|
|
3864
4252
|
const newIndices = [];
|
|
3865
|
-
if (drawMode ===
|
|
4253
|
+
if (drawMode === import_three15.TriangleFanDrawMode) {
|
|
3866
4254
|
for (let i = 1; i <= numberOfTriangles; i++) {
|
|
3867
4255
|
newIndices.push(index.getX(0));
|
|
3868
4256
|
newIndices.push(index.getX(i));
|
|
@@ -3898,15 +4286,15 @@ function computeMorphedAttributes(object) {
|
|
|
3898
4286
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
3899
4287
|
return null;
|
|
3900
4288
|
}
|
|
3901
|
-
const _vA = new
|
|
3902
|
-
const _vB = new
|
|
3903
|
-
const _vC = new
|
|
3904
|
-
const _tempA = new
|
|
3905
|
-
const _tempB = new
|
|
3906
|
-
const _tempC = new
|
|
3907
|
-
const _morphA = new
|
|
3908
|
-
const _morphB = new
|
|
3909
|
-
const _morphC = new
|
|
4289
|
+
const _vA = new import_three15.Vector3();
|
|
4290
|
+
const _vB = new import_three15.Vector3();
|
|
4291
|
+
const _vC = new import_three15.Vector3();
|
|
4292
|
+
const _tempA = new import_three15.Vector3();
|
|
4293
|
+
const _tempB = new import_three15.Vector3();
|
|
4294
|
+
const _tempC = new import_three15.Vector3();
|
|
4295
|
+
const _morphA = new import_three15.Vector3();
|
|
4296
|
+
const _morphB = new import_three15.Vector3();
|
|
4297
|
+
const _morphC = new import_three15.Vector3();
|
|
3910
4298
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
3911
4299
|
_vA.fromBufferAttribute(attribute, a2);
|
|
3912
4300
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4101,8 +4489,8 @@ function computeMorphedAttributes(object) {
|
|
|
4101
4489
|
}
|
|
4102
4490
|
}
|
|
4103
4491
|
}
|
|
4104
|
-
const morphedPositionAttribute = new
|
|
4105
|
-
const morphedNormalAttribute = new
|
|
4492
|
+
const morphedPositionAttribute = new import_three15.Float32BufferAttribute(modifiedPosition, 3);
|
|
4493
|
+
const morphedNormalAttribute = new import_three15.Float32BufferAttribute(modifiedNormal, 3);
|
|
4106
4494
|
return {
|
|
4107
4495
|
positionAttribute,
|
|
4108
4496
|
normalAttribute,
|
|
@@ -4112,15 +4500,16 @@ function computeMorphedAttributes(object) {
|
|
|
4112
4500
|
}
|
|
4113
4501
|
|
|
4114
4502
|
// src/model/scene/ModelObject.ts
|
|
4115
|
-
var
|
|
4116
|
-
var
|
|
4503
|
+
var import_ts_deepmerge5 = __toESM(require_dist());
|
|
4504
|
+
var p9 = prefix("ModelObject");
|
|
4117
4505
|
var _ModelObject = class _ModelObject extends SceneObject {
|
|
4118
4506
|
constructor(originalModel, options) {
|
|
4119
4507
|
super(options);
|
|
4120
4508
|
this.originalModel = originalModel;
|
|
4121
4509
|
this.isModelObject = true;
|
|
4122
4510
|
this.meshesCreated = false;
|
|
4123
|
-
this.options = (0,
|
|
4511
|
+
this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
|
|
4512
|
+
if (this.options.tints) this.options.tints = { ...this.options.tints };
|
|
4124
4513
|
console.log("ModelObject options", this.options);
|
|
4125
4514
|
}
|
|
4126
4515
|
async init() {
|
|
@@ -4142,17 +4531,36 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4142
4531
|
createMeshes(force = false) {
|
|
4143
4532
|
if (this.meshesCreated && !force) return;
|
|
4144
4533
|
const mat = Materials.MISSING_TEXTURE;
|
|
4534
|
+
const displayTransform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : void 0;
|
|
4145
4535
|
let allGeos = [];
|
|
4146
4536
|
if (this.atlas) {
|
|
4147
4537
|
if (this.atlas.model.elements) {
|
|
4148
4538
|
this.atlas.model.elements?.forEach((el) => {
|
|
4149
4539
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
4150
|
-
|
|
4151
|
-
|
|
4540
|
+
if (this.options.uvLockRotation) {
|
|
4541
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three16.Euler(...this.options.uvLockRotation));
|
|
4542
|
+
}
|
|
4543
|
+
if (this.options.tints) {
|
|
4544
|
+
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
4545
|
+
for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
|
|
4546
|
+
const tintIndex = el.faces[faceName]?.tintindex;
|
|
4547
|
+
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
4548
|
+
const tint = this.options.tints[tintIndex];
|
|
4549
|
+
if (tint === void 0) continue;
|
|
4550
|
+
const color = new import_three16.Color(tint);
|
|
4551
|
+
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4552
|
+
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
elGeo.setAttribute("color", new import_three16.BufferAttribute(colors, 3));
|
|
4556
|
+
}
|
|
4557
|
+
elGeo.applyMatrix4(new import_three16.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
|
|
4558
|
+
elGeo.applyMatrix4(new import_three16.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4152
4559
|
if (el.rotation) {
|
|
4153
4560
|
applyElementRotation(el.rotation, elGeo);
|
|
4154
4561
|
}
|
|
4155
|
-
elGeo.applyMatrix4(new
|
|
4562
|
+
elGeo.applyMatrix4(new import_three16.Matrix4().makeTranslation(-8, -8, -8));
|
|
4563
|
+
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4156
4564
|
if (this.options.mergeMeshes) {
|
|
4157
4565
|
allGeos.push(elGeo);
|
|
4158
4566
|
} else {
|
|
@@ -4163,17 +4571,18 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4163
4571
|
}
|
|
4164
4572
|
});
|
|
4165
4573
|
} else {
|
|
4166
|
-
console.debug(
|
|
4574
|
+
console.debug(p9, this.atlas.model, "has no elements");
|
|
4167
4575
|
}
|
|
4168
4576
|
} else {
|
|
4169
|
-
console.debug(
|
|
4577
|
+
console.debug(p9, "Missing atlas for", this);
|
|
4170
4578
|
}
|
|
4171
4579
|
if (this.options.mergeMeshes) {
|
|
4172
4580
|
let combinedGeo;
|
|
4173
4581
|
if (allGeos.length > 0) {
|
|
4174
4582
|
combinedGeo = mergeBufferGeometries(allGeos);
|
|
4175
4583
|
} else {
|
|
4176
|
-
combinedGeo = new
|
|
4584
|
+
combinedGeo = new import_three16.BoxGeometry(16, 16, 16);
|
|
4585
|
+
if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
|
|
4177
4586
|
}
|
|
4178
4587
|
combinedGeo.computeBoundingBox();
|
|
4179
4588
|
let mesh;
|
|
@@ -4203,6 +4612,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4203
4612
|
/*TODO: get this from render options*/
|
|
4204
4613
|
);
|
|
4205
4614
|
this.iterateAllMeshes((mesh) => {
|
|
4615
|
+
if (mesh.geometry.hasAttribute("color")) mat.vertexColors = true;
|
|
4206
4616
|
mesh.material = mat;
|
|
4207
4617
|
});
|
|
4208
4618
|
if (this.atlas.hasAnimation) {
|
|
@@ -4218,16 +4628,26 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4218
4628
|
}
|
|
4219
4629
|
}
|
|
4220
4630
|
};
|
|
4221
|
-
_ModelObject.DEFAULT_OPTIONS = (0,
|
|
4631
|
+
_ModelObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
|
|
4222
4632
|
var ModelObject = _ModelObject;
|
|
4223
4633
|
function isModelObject(obj) {
|
|
4224
4634
|
return obj.isModelObject;
|
|
4225
4635
|
}
|
|
4226
4636
|
|
|
4227
4637
|
// src/model/block/scene/BlockObject.ts
|
|
4228
|
-
var
|
|
4229
|
-
var
|
|
4230
|
-
var
|
|
4638
|
+
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4639
|
+
var import_three17 = require("three");
|
|
4640
|
+
var p10 = prefix("BlockObject");
|
|
4641
|
+
function matchesCondition(condition, state) {
|
|
4642
|
+
return Object.entries(condition).every(([key, value]) => {
|
|
4643
|
+
if (Array.isArray(value)) {
|
|
4644
|
+
if (key === "OR") return value.some((child) => matchesCondition(child, state));
|
|
4645
|
+
if (key === "AND") return value.every((child) => matchesCondition(child, state));
|
|
4646
|
+
return false;
|
|
4647
|
+
}
|
|
4648
|
+
return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
|
|
4649
|
+
});
|
|
4650
|
+
}
|
|
4231
4651
|
var _BlockObject = class _BlockObject extends SceneObject {
|
|
4232
4652
|
constructor(blockState, options) {
|
|
4233
4653
|
super(options);
|
|
@@ -4241,11 +4661,11 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4241
4661
|
this._instanceModel = [];
|
|
4242
4662
|
this._variants = [];
|
|
4243
4663
|
this._models = [];
|
|
4244
|
-
this.options = (0,
|
|
4664
|
+
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
4245
4665
|
}
|
|
4246
4666
|
async init() {
|
|
4247
4667
|
if (this.options.applyDefaultState) {
|
|
4248
|
-
const defaultState = this.blockState.key ? BlockStates.getDefaultState(this.blockState.key) : void 0;
|
|
4668
|
+
const defaultState = this.blockState.key ? await BlockStates.getDefaultState(this.blockState.key) : void 0;
|
|
4249
4669
|
if (defaultState && Object.keys(defaultState).length > 0) {
|
|
4250
4670
|
const state = {};
|
|
4251
4671
|
for (let k in defaultState) {
|
|
@@ -4256,15 +4676,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4256
4676
|
if (this.blockState.variants) {
|
|
4257
4677
|
await this.setState(Object.keys(this.blockState.variants)[0]);
|
|
4258
4678
|
} else if (this.blockState.multipart) {
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
if (k) {
|
|
4263
|
-
await this.setState(k, part.when[k].split("|")[0]);
|
|
4264
|
-
break;
|
|
4265
|
-
}
|
|
4266
|
-
}
|
|
4267
|
-
}
|
|
4679
|
+
const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
|
|
4680
|
+
const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
|
|
4681
|
+
await this.setState(state);
|
|
4268
4682
|
}
|
|
4269
4683
|
}
|
|
4270
4684
|
} else {
|
|
@@ -4279,7 +4693,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4279
4693
|
if (isModelObject(model)) {
|
|
4280
4694
|
model.removeFromScene();
|
|
4281
4695
|
} else if (isInstanceReference(model)) {
|
|
4282
|
-
model.setScale(new
|
|
4696
|
+
model.setScale(new import_three17.Vector3(0, 0, 0));
|
|
4283
4697
|
}
|
|
4284
4698
|
}
|
|
4285
4699
|
super.removeFromScene();
|
|
@@ -4321,55 +4735,11 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4321
4735
|
} else if (this.blockState.multipart) {
|
|
4322
4736
|
for (let part of this.blockState.multipart) {
|
|
4323
4737
|
if (!part.apply) {
|
|
4324
|
-
console.debug(
|
|
4738
|
+
console.debug(p10, "Missing apply for blockState part", part);
|
|
4325
4739
|
continue;
|
|
4326
4740
|
}
|
|
4327
|
-
if (!part.when) {
|
|
4741
|
+
if (!part.when || matchesCondition(part.when, state)) {
|
|
4328
4742
|
out.push(this.getSingleVariant(part.apply));
|
|
4329
|
-
} else {
|
|
4330
|
-
let matches = true;
|
|
4331
|
-
if ("OR" in part.when) {
|
|
4332
|
-
const or = part.when.OR;
|
|
4333
|
-
let anyMatch = false;
|
|
4334
|
-
for (let o of or) {
|
|
4335
|
-
for (let k in o) {
|
|
4336
|
-
const split = o[k].split("|");
|
|
4337
|
-
let m = false;
|
|
4338
|
-
for (let s of split) {
|
|
4339
|
-
if (`${state[k]}` === `${s}`) {
|
|
4340
|
-
m = true;
|
|
4341
|
-
break;
|
|
4342
|
-
}
|
|
4343
|
-
}
|
|
4344
|
-
if (m) {
|
|
4345
|
-
anyMatch = true;
|
|
4346
|
-
break;
|
|
4347
|
-
}
|
|
4348
|
-
}
|
|
4349
|
-
}
|
|
4350
|
-
if (!anyMatch) {
|
|
4351
|
-
matches = false;
|
|
4352
|
-
}
|
|
4353
|
-
} else {
|
|
4354
|
-
for (let k in part.when) {
|
|
4355
|
-
const split = part.when[k].split("|");
|
|
4356
|
-
let m = false;
|
|
4357
|
-
for (let s of split) {
|
|
4358
|
-
if (`${state[k]}` === `${s}`) {
|
|
4359
|
-
m = true;
|
|
4360
|
-
break;
|
|
4361
|
-
}
|
|
4362
|
-
}
|
|
4363
|
-
if (!m) {
|
|
4364
|
-
matches = false;
|
|
4365
|
-
break;
|
|
4366
|
-
}
|
|
4367
|
-
}
|
|
4368
|
-
}
|
|
4369
|
-
if (matches) {
|
|
4370
|
-
const variants = part.apply;
|
|
4371
|
-
out.push(this.getSingleVariant(variants));
|
|
4372
|
-
}
|
|
4373
4743
|
}
|
|
4374
4744
|
}
|
|
4375
4745
|
}
|
|
@@ -4384,7 +4754,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4384
4754
|
}
|
|
4385
4755
|
for (let model of this._models) {
|
|
4386
4756
|
if (isInstanceReference(model)) {
|
|
4387
|
-
model.setScale(new
|
|
4757
|
+
model.setScale(new import_three17.Vector3(0, 0, 0));
|
|
4388
4758
|
} else {
|
|
4389
4759
|
model.dispose();
|
|
4390
4760
|
}
|
|
@@ -4399,11 +4769,21 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4399
4769
|
}
|
|
4400
4770
|
}
|
|
4401
4771
|
getSingleVariant(variants) {
|
|
4402
|
-
if (Array.isArray(variants))
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4772
|
+
if (!Array.isArray(variants)) return variants;
|
|
4773
|
+
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
4774
|
+
const total = variants.reduce((sum, variant) => {
|
|
4775
|
+
const weight = variant.weight ?? 1;
|
|
4776
|
+
if (!Number.isInteger(weight) || weight < 1) {
|
|
4777
|
+
throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
|
|
4778
|
+
}
|
|
4779
|
+
return sum + weight;
|
|
4780
|
+
}, 0);
|
|
4781
|
+
let choice = Math.random() * total;
|
|
4782
|
+
for (const variant of variants) {
|
|
4783
|
+
choice -= variant.weight ?? 1;
|
|
4784
|
+
if (choice < 0) return variant;
|
|
4785
|
+
}
|
|
4786
|
+
return variants[variants.length - 1];
|
|
4407
4787
|
}
|
|
4408
4788
|
// @deprecated
|
|
4409
4789
|
async createAVariant(variants, instanceInfo) {
|
|
@@ -4411,28 +4791,27 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4411
4791
|
await this.createVariant(variant);
|
|
4412
4792
|
}
|
|
4413
4793
|
async createVariant(variant) {
|
|
4414
|
-
const
|
|
4415
|
-
const obj = await this.scene.addModel(model, this.options);
|
|
4416
|
-
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
4417
|
-
this._isInstanced = true;
|
|
4418
|
-
this._instanceCounter = 1;
|
|
4419
|
-
}
|
|
4420
|
-
let rotation = new import_three16.Euler(0, 0, 0);
|
|
4794
|
+
const rotation = new import_three17.Euler();
|
|
4421
4795
|
if (typeof variant.x !== "undefined") {
|
|
4422
4796
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4423
4797
|
}
|
|
4424
4798
|
if (typeof variant.y !== "undefined") {
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4799
|
+
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
4800
|
+
}
|
|
4801
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
4802
|
+
modelKey.root = this.blockState.key?.root;
|
|
4803
|
+
const model = await Models.getMerged(modelKey);
|
|
4804
|
+
const options = {
|
|
4805
|
+
...this.options,
|
|
4806
|
+
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
4807
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
4808
|
+
};
|
|
4809
|
+
const obj = await this.scene.addModel(model, options);
|
|
4810
|
+
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
4811
|
+
this._isInstanced = true;
|
|
4812
|
+
this._instanceCounter = 1;
|
|
4430
4813
|
}
|
|
4431
4814
|
obj.setRotation(rotation);
|
|
4432
|
-
setTimeout(() => {
|
|
4433
|
-
obj.setRotation(rotation);
|
|
4434
|
-
}, 150);
|
|
4435
|
-
console.log(obj);
|
|
4436
4815
|
return obj;
|
|
4437
4816
|
}
|
|
4438
4817
|
async resetState() {
|
|
@@ -4501,7 +4880,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4501
4880
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
4502
4881
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
4503
4882
|
}
|
|
4504
|
-
getMatrixAt(index, matrix = new
|
|
4883
|
+
getMatrixAt(index, matrix = new import_three17.Matrix4()) {
|
|
4505
4884
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
4506
4885
|
const child = this._models[0];
|
|
4507
4886
|
if (child && isModelObject(child)) {
|
|
@@ -4522,15 +4901,16 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4522
4901
|
}
|
|
4523
4902
|
}
|
|
4524
4903
|
setPosition(position) {
|
|
4525
|
-
|
|
4904
|
+
this.position.copy(position);
|
|
4526
4905
|
for (let model of this._models) {
|
|
4527
4906
|
model.setPosition(position);
|
|
4528
4907
|
}
|
|
4908
|
+
this.notifyDirty();
|
|
4529
4909
|
}
|
|
4530
4910
|
//TODO: should override rotation + scale methods
|
|
4531
4911
|
//TODO
|
|
4532
4912
|
};
|
|
4533
|
-
_BlockObject.DEFAULT_OPTIONS = (0,
|
|
4913
|
+
_BlockObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge6.default)({}, ModelObject.DEFAULT_OPTIONS, {
|
|
4534
4914
|
applyDefaultState: true
|
|
4535
4915
|
});
|
|
4536
4916
|
var BlockObject = _BlockObject;
|
|
@@ -4579,8 +4959,8 @@ var StructureParser = class {
|
|
|
4579
4959
|
};
|
|
4580
4960
|
|
|
4581
4961
|
// src/renderer/MineRenderScene.ts
|
|
4582
|
-
var
|
|
4583
|
-
var
|
|
4962
|
+
var import_three19 = require("three");
|
|
4963
|
+
var import_ts_deepmerge8 = __toESM(require_dist());
|
|
4584
4964
|
|
|
4585
4965
|
// src/skin/SkinPart.ts
|
|
4586
4966
|
var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
|
|
@@ -5198,90 +5578,80 @@ var baseSkinCoordinates = {
|
|
|
5198
5578
|
]
|
|
5199
5579
|
},
|
|
5200
5580
|
up: {
|
|
5201
|
-
uv: [
|
|
5202
|
-
4,
|
|
5203
|
-
36,
|
|
5204
|
-
8,
|
|
5205
|
-
32
|
|
5206
|
-
]
|
|
5207
|
-
},
|
|
5208
|
-
down: {
|
|
5209
|
-
uv: [
|
|
5210
|
-
8,
|
|
5211
|
-
32,
|
|
5212
|
-
12,
|
|
5213
|
-
36
|
|
5214
|
-
],
|
|
5215
|
-
rotation: 180
|
|
5216
|
-
}
|
|
5217
|
-
},
|
|
5218
|
-
cape: {
|
|
5219
|
-
//TODO
|
|
5220
|
-
east: {
|
|
5221
|
-
uv: [
|
|
5222
|
-
0,
|
|
5223
|
-
36,
|
|
5224
|
-
4,
|
|
5225
|
-
48
|
|
5226
|
-
]
|
|
5227
|
-
},
|
|
5228
|
-
west: {
|
|
5229
5581
|
uv: [
|
|
5230
5582
|
8,
|
|
5231
5583
|
36,
|
|
5232
|
-
12,
|
|
5233
|
-
48
|
|
5234
|
-
]
|
|
5235
|
-
},
|
|
5236
|
-
north: {
|
|
5237
|
-
uv: [
|
|
5238
5584
|
4,
|
|
5239
|
-
|
|
5240
|
-
8,
|
|
5241
|
-
48
|
|
5585
|
+
32
|
|
5242
5586
|
]
|
|
5243
5587
|
},
|
|
5244
|
-
|
|
5588
|
+
down: {
|
|
5245
5589
|
uv: [
|
|
5246
5590
|
12,
|
|
5247
|
-
36,
|
|
5248
|
-
16,
|
|
5249
|
-
48
|
|
5250
|
-
]
|
|
5251
|
-
},
|
|
5252
|
-
up: {
|
|
5253
|
-
uv: [
|
|
5254
|
-
4,
|
|
5255
5591
|
32,
|
|
5256
5592
|
8,
|
|
5257
5593
|
36
|
|
5258
|
-
]
|
|
5259
|
-
},
|
|
5260
|
-
down: {
|
|
5261
|
-
uv: [
|
|
5262
|
-
8,
|
|
5263
|
-
32,
|
|
5264
|
-
12,
|
|
5265
|
-
36
|
|
5266
5594
|
],
|
|
5267
5595
|
rotation: 180
|
|
5268
5596
|
}
|
|
5597
|
+
},
|
|
5598
|
+
cape: {
|
|
5599
|
+
east: { uv: [0, 1, 1, 17] },
|
|
5600
|
+
west: { uv: [11, 1, 12, 17] },
|
|
5601
|
+
north: { uv: [1, 1, 11, 17] },
|
|
5602
|
+
south: { uv: [12, 1, 22, 17] },
|
|
5603
|
+
up: { uv: [11, 1, 1, 0] },
|
|
5604
|
+
down: { uv: [21, 0, 11, 1] }
|
|
5269
5605
|
}
|
|
5270
5606
|
};
|
|
5271
5607
|
var classicSkinTextureCoordinates = {
|
|
5272
5608
|
...baseSkinCoordinates
|
|
5273
5609
|
};
|
|
5274
|
-
var slimSkinTextureCoordinates = {
|
|
5610
|
+
var slimSkinTextureCoordinates = {
|
|
5611
|
+
...baseSkinCoordinates,
|
|
5612
|
+
leftArm: {
|
|
5613
|
+
...baseSkinCoordinates.leftArm,
|
|
5614
|
+
west: { uv: [39, 52, 43, 64] },
|
|
5615
|
+
north: { uv: [36, 52, 39, 64] },
|
|
5616
|
+
south: { uv: [43, 52, 46, 64] },
|
|
5617
|
+
up: { uv: [39, 52, 36, 48] },
|
|
5618
|
+
down: { uv: [42, 48, 39, 52] }
|
|
5619
|
+
},
|
|
5620
|
+
rightArm: {
|
|
5621
|
+
...baseSkinCoordinates.rightArm,
|
|
5622
|
+
west: { uv: [47, 20, 51, 32] },
|
|
5623
|
+
north: { uv: [44, 20, 47, 32] },
|
|
5624
|
+
south: { uv: [51, 20, 54, 32] },
|
|
5625
|
+
up: { uv: [47, 20, 44, 16] },
|
|
5626
|
+
down: { uv: [50, 16, 47, 20] }
|
|
5627
|
+
},
|
|
5628
|
+
leftSleeve: {
|
|
5629
|
+
...baseSkinCoordinates.leftSleeve,
|
|
5630
|
+
west: { uv: [55, 52, 59, 64] },
|
|
5631
|
+
north: { uv: [52, 52, 55, 64] },
|
|
5632
|
+
south: { uv: [59, 52, 62, 64] },
|
|
5633
|
+
up: { uv: [55, 52, 52, 48] },
|
|
5634
|
+
down: { uv: [58, 48, 55, 52], rotation: 180 }
|
|
5635
|
+
},
|
|
5636
|
+
rightSleeve: {
|
|
5637
|
+
...baseSkinCoordinates.rightSleeve,
|
|
5638
|
+
west: { uv: [47, 36, 51, 48] },
|
|
5639
|
+
north: { uv: [44, 36, 47, 48] },
|
|
5640
|
+
south: { uv: [51, 36, 54, 48] },
|
|
5641
|
+
up: { uv: [47, 36, 44, 32] },
|
|
5642
|
+
down: { uv: [50, 32, 47, 36], rotation: 180 }
|
|
5643
|
+
}
|
|
5644
|
+
};
|
|
5275
5645
|
|
|
5276
5646
|
// src/skin/SkinGeometries.ts
|
|
5277
5647
|
var box8inner = [8, 8, 8];
|
|
5278
|
-
var box8outer = [
|
|
5648
|
+
var box8outer = [9, 9, 9];
|
|
5279
5649
|
var box8_12_4inner = [8, 12, 4];
|
|
5280
|
-
var box8_12_4outer = [8.
|
|
5650
|
+
var box8_12_4outer = [8.5, 12.5, 4.5];
|
|
5281
5651
|
var box4_12_4inner = [4, 12, 4];
|
|
5282
|
-
var box4_12_4outer = [4.
|
|
5652
|
+
var box4_12_4outer = [4.5, 12.5, 4.5];
|
|
5283
5653
|
var box3_12_4inner = [3, 12, 4];
|
|
5284
|
-
var box3_12_4outer = [3.
|
|
5654
|
+
var box3_12_4outer = [3.5, 12.5, 4.5];
|
|
5285
5655
|
var box10_16_1 = [10, 16, 1];
|
|
5286
5656
|
var baseSkinGeometries = {
|
|
5287
5657
|
head: box8inner,
|
|
@@ -5311,119 +5681,318 @@ var slimSkinGeometries = {
|
|
|
5311
5681
|
};
|
|
5312
5682
|
|
|
5313
5683
|
// src/skin/scene/SkinObject.ts
|
|
5314
|
-
var
|
|
5684
|
+
var import_ts_deepmerge7 = __toESM(require_dist());
|
|
5685
|
+
|
|
5686
|
+
// src/skin/SkinTextures.ts
|
|
5687
|
+
var import_three18 = require("three");
|
|
5688
|
+
|
|
5689
|
+
// src/skin/SkinImage.ts
|
|
5690
|
+
var SkinImage = class {
|
|
5691
|
+
static async getData(src) {
|
|
5692
|
+
const key = serializeImageKey({ src });
|
|
5693
|
+
return await Caching.imageDataCache.get(`skin:${key}`, async () => {
|
|
5694
|
+
const info = await ImageLoader.getInfo(src);
|
|
5695
|
+
if (info.type !== "png") return ImageLoader.getData(src);
|
|
5696
|
+
try {
|
|
5697
|
+
return await this.decodePng(info.data);
|
|
5698
|
+
} catch (error) {
|
|
5699
|
+
Caching.rawImageCache.invalidate(key);
|
|
5700
|
+
throw error;
|
|
5701
|
+
}
|
|
5702
|
+
});
|
|
5703
|
+
}
|
|
5704
|
+
static async decodePng(bytes) {
|
|
5705
|
+
const { decode, convertIndexedToRgb } = await import("fast-png");
|
|
5706
|
+
const png = decode(bytes);
|
|
5707
|
+
let { data, channels, depth } = png;
|
|
5708
|
+
if (channels === 1 && (png.palette || depth < 8)) {
|
|
5709
|
+
const max = (1 << depth) - 1;
|
|
5710
|
+
const palette = png.palette ?? Array.from({ length: max + 1 }, (_, value) => {
|
|
5711
|
+
const gray = value * 255 / max;
|
|
5712
|
+
return [gray, gray, gray, png.transparency?.[0] === value ? 0 : 255];
|
|
5713
|
+
});
|
|
5714
|
+
data = convertIndexedToRgb({ ...png, palette });
|
|
5715
|
+
channels = palette[0].length;
|
|
5716
|
+
depth = 8;
|
|
5717
|
+
}
|
|
5718
|
+
const pixels = new Uint8ClampedArray(png.width * png.height * 4);
|
|
5719
|
+
for (let pixel = 0; pixel < png.width * png.height; pixel++) {
|
|
5720
|
+
const source = pixel * channels;
|
|
5721
|
+
const target = pixel * 4;
|
|
5722
|
+
const sample = (channel) => depth === 16 ? data[source + channel] >>> 8 : data[source + channel];
|
|
5723
|
+
pixels[target] = sample(0);
|
|
5724
|
+
pixels[target + 1] = sample(channels < 3 ? 0 : 1);
|
|
5725
|
+
pixels[target + 2] = sample(channels < 3 ? 0 : 2);
|
|
5726
|
+
pixels[target + 3] = channels % 2 === 0 ? sample(channels - 1) : png.transparency?.every((value, channel) => data[source + channel] === value) ? 0 : 255;
|
|
5727
|
+
}
|
|
5728
|
+
return { width: png.width, height: png.height, data: pixels, colorSpace: "srgb" };
|
|
5729
|
+
}
|
|
5730
|
+
};
|
|
5731
|
+
|
|
5732
|
+
// src/skin/SkinTextures.ts
|
|
5733
|
+
var SkinTextures = class {
|
|
5734
|
+
static async get(src, legacy) {
|
|
5735
|
+
const image = await SkinImage.getData(src);
|
|
5736
|
+
const scale = image.width / 64;
|
|
5737
|
+
if (!Number.isInteger(scale) || scale < 1 || image.height !== image.width && image.height !== image.width / 2) {
|
|
5738
|
+
throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; expected 64x64 or 64x32, or an integer-scaled equivalent`);
|
|
5739
|
+
}
|
|
5740
|
+
const isLegacy = legacy ?? image.height === image.width / 2;
|
|
5741
|
+
if (!isLegacy && image.height !== image.width) {
|
|
5742
|
+
throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; non-legacy skins must be square`);
|
|
5743
|
+
}
|
|
5744
|
+
const slim = !isLegacy && this.isSlim(image, scale);
|
|
5745
|
+
const key = `skin:${serializeImageKey({ src })}:${isLegacy}`;
|
|
5746
|
+
const material = Caching.materialCache.get(key, () => {
|
|
5747
|
+
const pixels = isLegacy ? this.normalizeLegacy(image, scale) : new Uint8Array(image.data);
|
|
5748
|
+
this.makeBaseOpaque(pixels, image.width, scale);
|
|
5749
|
+
return this.createMaterial(pixels, image.width, image.width);
|
|
5750
|
+
});
|
|
5751
|
+
return { material, slim, legacy: isLegacy };
|
|
5752
|
+
}
|
|
5753
|
+
static async getCape(src, layout = "minecraft") {
|
|
5754
|
+
const image = await SkinImage.getData(src);
|
|
5755
|
+
const scale = image.width / 64;
|
|
5756
|
+
if (layout === "minecraft" && (!Number.isInteger(scale) || scale < 1 || image.height !== image.width / 2)) {
|
|
5757
|
+
throw new MineRenderError(`Invalid cape dimensions ${image.width}x${image.height}; expected 64x32 or an integer-scaled equivalent`);
|
|
5758
|
+
}
|
|
5759
|
+
return Caching.materialCache.get(`cape:${serializeImageKey({ src })}`, () => {
|
|
5760
|
+
return this.createMaterial(new Uint8Array(image.data), image.width, image.height, false);
|
|
5761
|
+
});
|
|
5762
|
+
}
|
|
5763
|
+
static createMaterial(pixels, width, height, transparent = true) {
|
|
5764
|
+
const texture = Textures.initTextureProps(new import_three18.DataTexture(pixels, width, height));
|
|
5765
|
+
texture.colorSpace = import_three18.SRGBColorSpace;
|
|
5766
|
+
texture.flipY = true;
|
|
5767
|
+
texture.needsUpdate = true;
|
|
5768
|
+
return new import_three18.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three18.DoubleSide : import_three18.FrontSide, alphaTest: transparent ? 0.1 : 0 });
|
|
5769
|
+
}
|
|
5770
|
+
static isSlim(image, scale) {
|
|
5771
|
+
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
5772
|
+
for (let row = y * scale; row < (y + 12) * scale; row++) {
|
|
5773
|
+
for (let column = x * scale; column < (x + 1) * scale; column++) {
|
|
5774
|
+
if (image.data[(row * image.width + column) * 4 + 3] !== 0) return false;
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5777
|
+
}
|
|
5778
|
+
return true;
|
|
5779
|
+
}
|
|
5780
|
+
static normalizeLegacy(image, scale) {
|
|
5781
|
+
const pixels = new Uint8Array(image.width * image.width * 4);
|
|
5782
|
+
pixels.set(image.data.subarray(0, image.width * image.width / 2 * 4));
|
|
5783
|
+
for (const [sx, sy, dx, dy, width, height] of [
|
|
5784
|
+
[4, 16, 20, 48, 4, 4],
|
|
5785
|
+
[8, 16, 24, 48, 4, 4],
|
|
5786
|
+
[0, 20, 24, 52, 4, 12],
|
|
5787
|
+
[4, 20, 20, 52, 4, 12],
|
|
5788
|
+
[8, 20, 16, 52, 4, 12],
|
|
5789
|
+
[12, 20, 28, 52, 4, 12],
|
|
5790
|
+
[44, 16, 36, 48, 4, 4],
|
|
5791
|
+
[48, 16, 40, 48, 4, 4],
|
|
5792
|
+
[40, 20, 40, 52, 4, 12],
|
|
5793
|
+
[44, 20, 36, 52, 4, 12],
|
|
5794
|
+
[48, 20, 32, 52, 4, 12],
|
|
5795
|
+
[52, 20, 44, 52, 4, 12]
|
|
5796
|
+
]) {
|
|
5797
|
+
for (let y = 0; y < height * scale; y++) {
|
|
5798
|
+
for (let x = 0; x < width * scale; x++) {
|
|
5799
|
+
const source = ((sy * scale + y) * image.width + sx * scale + x) * 4;
|
|
5800
|
+
const target = ((dy * scale + y) * image.width + (dx + width) * scale - 1 - x) * 4;
|
|
5801
|
+
pixels.set(image.data.subarray(source, source + 4), target);
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5805
|
+
let clearHat = true;
|
|
5806
|
+
for (let y = 0; y < 32 * scale; y++) {
|
|
5807
|
+
for (let x = 32 * scale; x < image.width; x++) {
|
|
5808
|
+
if (pixels[(y * image.width + x) * 4 + 3] < 128) clearHat = false;
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5811
|
+
if (clearHat) {
|
|
5812
|
+
for (let y = 0; y < 32 * scale; y++) {
|
|
5813
|
+
for (let x = 32 * scale; x < image.width; x++) {
|
|
5814
|
+
pixels[(y * image.width + x) * 4 + 3] = 0;
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5817
|
+
}
|
|
5818
|
+
return pixels;
|
|
5819
|
+
}
|
|
5820
|
+
static makeBaseOpaque(pixels, width, scale) {
|
|
5821
|
+
for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64]]) {
|
|
5822
|
+
for (let y = y0 * scale; y < y1 * scale; y++) {
|
|
5823
|
+
for (let x = x0 * scale; x < x1 * scale; x++) pixels[(y * width + x) * 4 + 3] = 255;
|
|
5824
|
+
}
|
|
5825
|
+
}
|
|
5826
|
+
}
|
|
5827
|
+
};
|
|
5828
|
+
|
|
5829
|
+
// src/skin/CapeLayout.ts
|
|
5830
|
+
var capeTextureSizes = {
|
|
5831
|
+
minecraft: [64, 32],
|
|
5832
|
+
optifine: [46, 22],
|
|
5833
|
+
labymod: [22, 17]
|
|
5834
|
+
};
|
|
5835
|
+
|
|
5836
|
+
// src/skin/scene/SkinObject.ts
|
|
5315
5837
|
var SkinObject = class extends SceneObject {
|
|
5316
5838
|
constructor(options) {
|
|
5317
5839
|
super();
|
|
5318
5840
|
this.slim = false;
|
|
5319
|
-
this.
|
|
5320
|
-
this.
|
|
5321
|
-
this.
|
|
5322
|
-
this.options = (0,
|
|
5841
|
+
this.detectedSlim = false;
|
|
5842
|
+
this.skinLoad = 0;
|
|
5843
|
+
this.capeLoad = 0;
|
|
5844
|
+
this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
5845
|
+
this.slim = this.options.slim ?? false;
|
|
5323
5846
|
}
|
|
5324
5847
|
async init() {
|
|
5848
|
+
const cape = this.getGroupByName("cape" /* CAPE */);
|
|
5325
5849
|
this.createMeshes();
|
|
5850
|
+
if (cape) this.getGroupByName("body" /* BODY */).attach(cape);
|
|
5326
5851
|
}
|
|
5327
5852
|
removeMeshes() {
|
|
5328
5853
|
}
|
|
5329
5854
|
createMeshes() {
|
|
5330
|
-
|
|
5331
|
-
const mat = Materials.MISSING_TEXTURE;
|
|
5855
|
+
const mat = this.skinMaterial ?? Materials.MISSING_TEXTURE;
|
|
5332
5856
|
{
|
|
5333
5857
|
const headGroup = this.createAndAddGroup("head", 0, 28, 0, "y" /* Y */, -4);
|
|
5334
5858
|
const headGeo = this.getBoxGeometry("head" /* HEAD */);
|
|
5335
5859
|
const head = this.createAndAddMesh("head", headGroup, headGeo, mat, "y" /* Y */, 4);
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
5339
|
-
}
|
|
5860
|
+
const hatGeo = this.getBoxGeometry("hat" /* HAT */);
|
|
5861
|
+
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
5340
5862
|
}
|
|
5341
5863
|
{
|
|
5342
|
-
const bodyGroup = this.createAndAddGroup("body", 0,
|
|
5864
|
+
const bodyGroup = this.createAndAddGroup("body", 0, 24, 0);
|
|
5343
5865
|
const bodyGeo = this.getBoxGeometry("body" /* BODY */);
|
|
5344
|
-
const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat);
|
|
5866
|
+
const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat, "y" /* Y */, -6);
|
|
5345
5867
|
const jacketGeo = this.getBoxGeometry("jacket" /* JACKET */);
|
|
5346
|
-
const jacket = this.createAndAddMesh("jacket", bodyGroup, jacketGeo, mat);
|
|
5868
|
+
const jacket = this.createAndAddMesh("jacket", bodyGroup, jacketGeo, mat, "y" /* Y */, -6);
|
|
5347
5869
|
}
|
|
5348
5870
|
{
|
|
5349
5871
|
{
|
|
5350
|
-
const leftArmGroup = this.createAndAddGroup("leftArm",
|
|
5872
|
+
const leftArmGroup = this.createAndAddGroup("leftArm", -5, 22, 0);
|
|
5351
5873
|
const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
|
|
5352
5874
|
const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
|
|
5875
|
+
leftArm.position.x = this.slim ? -0.5 : -1;
|
|
5353
5876
|
const leftSleeveGeo = this.getBoxGeometry("leftSleeve" /* LEFT_SLEEVE */);
|
|
5354
5877
|
const leftSleeve = this.createAndAddMesh("leftSleeve", leftArmGroup, leftSleeveGeo, mat, "y" /* Y */, -4);
|
|
5878
|
+
leftSleeve.position.x = this.slim ? -0.5 : -1;
|
|
5355
5879
|
}
|
|
5356
5880
|
{
|
|
5357
|
-
const rightArmGroup = this.createAndAddGroup("rightArm",
|
|
5881
|
+
const rightArmGroup = this.createAndAddGroup("rightArm", 5, 22, 0);
|
|
5358
5882
|
const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
|
|
5359
5883
|
const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
|
|
5884
|
+
rightArm.position.x = this.slim ? 0.5 : 1;
|
|
5360
5885
|
const rightSleeveGeo = this.getBoxGeometry("rightSleeve" /* RIGHT_SLEEVE */);
|
|
5361
5886
|
const rightSleeve = this.createAndAddMesh("rightSleeve", rightArmGroup, rightSleeveGeo, mat, "y" /* Y */, -4);
|
|
5887
|
+
rightSleeve.position.x = this.slim ? 0.5 : 1;
|
|
5362
5888
|
}
|
|
5363
5889
|
}
|
|
5364
5890
|
{
|
|
5365
5891
|
{
|
|
5366
|
-
const leftLegGroup = this.createAndAddGroup("leftLeg", -
|
|
5892
|
+
const leftLegGroup = this.createAndAddGroup("leftLeg", -1.9, 12, 0);
|
|
5367
5893
|
const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
|
|
5368
|
-
const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -
|
|
5894
|
+
const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
|
|
5369
5895
|
const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
|
|
5370
|
-
const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -
|
|
5896
|
+
const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
|
|
5371
5897
|
}
|
|
5372
5898
|
{
|
|
5373
|
-
const rightLegGroup = this.createAndAddGroup("rightLeg",
|
|
5899
|
+
const rightLegGroup = this.createAndAddGroup("rightLeg", 1.9, 12, 0);
|
|
5374
5900
|
const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
|
|
5375
|
-
const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -
|
|
5901
|
+
const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
|
|
5376
5902
|
const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
|
|
5377
|
-
const rightTrousers = this.createAndAddMesh("rightTrousers", rightLegGroup, rightTrousersGeo, mat, "y" /* Y */, -
|
|
5903
|
+
const rightTrousers = this.createAndAddMesh("rightTrousers", rightLegGroup, rightTrousersGeo, mat, "y" /* Y */, -6);
|
|
5378
5904
|
}
|
|
5379
5905
|
}
|
|
5380
|
-
console.log("#createMeshes done");
|
|
5381
5906
|
}
|
|
5382
|
-
setSkinTexture(src) {
|
|
5907
|
+
async setSkinTexture(src) {
|
|
5383
5908
|
if (typeof src === "undefined") return;
|
|
5384
5909
|
this.skinTextureSrc = src;
|
|
5385
|
-
const
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5910
|
+
const load = ++this.skinLoad;
|
|
5911
|
+
const texture = await SkinTextures.get(src, this.options.legacy);
|
|
5912
|
+
if (load !== this.skinLoad) return;
|
|
5913
|
+
this.skinMaterial = texture.material;
|
|
5914
|
+
this.detectedSlim = texture.slim;
|
|
5915
|
+
this.updateSlim(this.options.slim ?? this.detectedSlim);
|
|
5916
|
+
for (const part of SKIN_PARTS) {
|
|
5917
|
+
if (part === "cape" /* CAPE */) continue;
|
|
5918
|
+
const mesh = this.getMeshByName(part);
|
|
5391
5919
|
if (mesh) {
|
|
5392
|
-
mesh.material =
|
|
5920
|
+
mesh.material = texture.material;
|
|
5393
5921
|
}
|
|
5394
5922
|
}
|
|
5923
|
+
this.notifyDirty();
|
|
5924
|
+
}
|
|
5925
|
+
/** Load a cape texture in the selected layout, or pass undefined to remove the cape. */
|
|
5926
|
+
async setCapeTexture(src, layout = "minecraft") {
|
|
5927
|
+
const load = ++this.capeLoad;
|
|
5928
|
+
if (src === void 0) {
|
|
5929
|
+
const group = this.getGroupByName("cape" /* CAPE */);
|
|
5930
|
+
group?.removeFromParent();
|
|
5931
|
+
this.notifyDirty();
|
|
5932
|
+
return;
|
|
5933
|
+
}
|
|
5934
|
+
const material = await SkinTextures.getCape(src, layout);
|
|
5935
|
+
if (load !== this.capeLoad) return;
|
|
5936
|
+
const size = capeTextureSizes[layout];
|
|
5937
|
+
const geometry = this._getBoxGeometryFromDimensions(
|
|
5938
|
+
classicSkinGeometries.cape,
|
|
5939
|
+
classicSkinTextureCoordinates.cape,
|
|
5940
|
+
size,
|
|
5941
|
+
size
|
|
5942
|
+
);
|
|
5943
|
+
const mesh = this.getMeshByName("cape" /* CAPE */);
|
|
5944
|
+
if (mesh) {
|
|
5945
|
+
mesh.material = material;
|
|
5946
|
+
mesh.geometry = geometry;
|
|
5947
|
+
} else {
|
|
5948
|
+
const body = this.getGroupByName("body" /* BODY */);
|
|
5949
|
+
const group = this.createGroup("cape" /* CAPE */, 0, body ? 0 : 24, 2);
|
|
5950
|
+
(body ?? this).add(group);
|
|
5951
|
+
group.rotation.set(toRadians(-6), Math.PI, 0);
|
|
5952
|
+
const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
|
|
5953
|
+
cape.position.set(0, -8, -0.5);
|
|
5954
|
+
}
|
|
5955
|
+
this.notifyDirty();
|
|
5395
5956
|
}
|
|
5396
|
-
|
|
5957
|
+
/** Select the arm model, or pass undefined to use texture detection. */
|
|
5397
5958
|
setSlim(slim) {
|
|
5398
|
-
|
|
5399
|
-
|
|
5959
|
+
this.options.slim = slim;
|
|
5960
|
+
this.updateSlim(slim ?? this.detectedSlim);
|
|
5961
|
+
}
|
|
5962
|
+
updateSlim(slim) {
|
|
5963
|
+
if (slim === this.slim) return;
|
|
5400
5964
|
this.slim = slim;
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5965
|
+
const offset = slim ? 0.5 : -0.5;
|
|
5966
|
+
for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
|
|
5967
|
+
const mesh = this.getMeshByName(part);
|
|
5968
|
+
if (mesh) {
|
|
5969
|
+
mesh.geometry = this.getBoxGeometry(part);
|
|
5970
|
+
mesh.position.x += part === "leftArm" /* LEFT_ARM */ || part === "leftSleeve" /* LEFT_SLEEVE */ ? offset : -offset;
|
|
5407
5971
|
}
|
|
5408
5972
|
}
|
|
5409
|
-
|
|
5973
|
+
this.notifyDirty();
|
|
5410
5974
|
}
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
this.legacy = legacy;
|
|
5975
|
+
/** Select the texture layout, or pass undefined to detect it from image dimensions. */
|
|
5976
|
+
async setLegacy(legacy) {
|
|
5977
|
+
if (legacy === this.options.legacy) return;
|
|
5978
|
+
this.options.legacy = legacy;
|
|
5979
|
+
if (this.skinTextureSrc) await this.setSkinTexture(this.skinTextureSrc);
|
|
5980
|
+
}
|
|
5981
|
+
dispose() {
|
|
5982
|
+
this.skinLoad++;
|
|
5983
|
+
this.capeLoad++;
|
|
5984
|
+
super.dispose();
|
|
5415
5985
|
}
|
|
5416
5986
|
//TODO: layer toggles
|
|
5417
5987
|
getBoxGeometry(part) {
|
|
5418
|
-
console.log("slim", this.slim);
|
|
5419
5988
|
const coordinates = this.slim ? slimSkinTextureCoordinates : classicSkinTextureCoordinates;
|
|
5420
5989
|
const geometries = this.slim ? slimSkinGeometries : classicSkinGeometries;
|
|
5421
|
-
return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [
|
|
5990
|
+
return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [64, 64]);
|
|
5422
5991
|
}
|
|
5423
5992
|
};
|
|
5424
5993
|
|
|
5425
5994
|
// src/renderer/MineRenderScene.ts
|
|
5426
|
-
var _MineRenderScene = class _MineRenderScene extends
|
|
5995
|
+
var _MineRenderScene = class _MineRenderScene extends import_three19.Scene {
|
|
5427
5996
|
constructor(options) {
|
|
5428
5997
|
super();
|
|
5429
5998
|
this.isMineRenderScene = true;
|
|
@@ -5436,7 +6005,7 @@ var _MineRenderScene = class _MineRenderScene extends import_three17.Scene {
|
|
|
5436
6005
|
this.dirty = true;
|
|
5437
6006
|
}
|
|
5438
6007
|
};
|
|
5439
|
-
this.options = (0,
|
|
6008
|
+
this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
|
|
5440
6009
|
}
|
|
5441
6010
|
add(...objects) {
|
|
5442
6011
|
for (const object of objects) {
|
|
@@ -5494,7 +6063,14 @@ var _MineRenderScene = class _MineRenderScene extends import_three17.Scene {
|
|
|
5494
6063
|
const obj = await objectSupplier();
|
|
5495
6064
|
if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
|
|
5496
6065
|
console.log("instanceMeshes + key");
|
|
5497
|
-
|
|
6066
|
+
let key = asset.key.serialize();
|
|
6067
|
+
if (isModelObject(obj)) {
|
|
6068
|
+
const { displayPosition, uvLockRotation, tints } = obj.options;
|
|
6069
|
+
if (displayPosition) key += `|display:${displayPosition}`;
|
|
6070
|
+
if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
|
|
6071
|
+
const palette = Object.entries(tints ?? {}).sort(([a], [b]) => Number(a) - Number(b));
|
|
6072
|
+
if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
|
|
6073
|
+
}
|
|
5498
6074
|
return this.instanceManager.getOrCreate(key, async () => {
|
|
5499
6075
|
obj.scene = this;
|
|
5500
6076
|
await obj.init();
|
|
@@ -5521,10 +6097,10 @@ var _MineRenderScene = class _MineRenderScene extends import_three17.Scene {
|
|
|
5521
6097
|
this.dirty = true;
|
|
5522
6098
|
const obj = new SkinObject(options);
|
|
5523
6099
|
obj.scene = this;
|
|
5524
|
-
await obj.init();
|
|
5525
6100
|
if (skin) {
|
|
5526
|
-
obj.setSkinTexture(skin);
|
|
6101
|
+
await obj.setSkinTexture(skin);
|
|
5527
6102
|
}
|
|
6103
|
+
await obj.init();
|
|
5528
6104
|
parent.add(obj);
|
|
5529
6105
|
return obj;
|
|
5530
6106
|
}
|
|
@@ -5532,24 +6108,24 @@ var _MineRenderScene = class _MineRenderScene extends import_three17.Scene {
|
|
|
5532
6108
|
return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
|
|
5533
6109
|
}
|
|
5534
6110
|
};
|
|
5535
|
-
_MineRenderScene.DEFAULT_OPTIONS = (0,
|
|
6111
|
+
_MineRenderScene.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
|
|
5536
6112
|
var MineRenderScene = _MineRenderScene;
|
|
5537
6113
|
function isMineRenderScene(obj) {
|
|
5538
6114
|
return obj.isMineRenderScene;
|
|
5539
6115
|
}
|
|
5540
6116
|
|
|
5541
6117
|
// src/renderer/Renderer.ts
|
|
5542
|
-
var
|
|
5543
|
-
var
|
|
6118
|
+
var import_three21 = require("three");
|
|
6119
|
+
var import_ts_deepmerge9 = __toESM(require_dist());
|
|
5544
6120
|
var import_stats = __toESM(require("stats.js"));
|
|
5545
6121
|
var import_postprocessing = require("postprocessing");
|
|
5546
6122
|
|
|
5547
6123
|
// src/three/OrbitControls.js
|
|
5548
|
-
var
|
|
6124
|
+
var import_three20 = require("three");
|
|
5549
6125
|
var _changeEvent = { type: "change" };
|
|
5550
6126
|
var _startEvent = { type: "start" };
|
|
5551
6127
|
var _endEvent = { type: "end" };
|
|
5552
|
-
var OrbitControls = class extends
|
|
6128
|
+
var OrbitControls = class extends import_three20.EventDispatcher {
|
|
5553
6129
|
constructor(object, domElement) {
|
|
5554
6130
|
super();
|
|
5555
6131
|
if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
|
|
@@ -5558,7 +6134,7 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5558
6134
|
this.domElement = domElement;
|
|
5559
6135
|
this.domElement.style.touchAction = "none";
|
|
5560
6136
|
this.enabled = true;
|
|
5561
|
-
this.target = new
|
|
6137
|
+
this.target = new import_three20.Vector3();
|
|
5562
6138
|
this.minDistance = 0;
|
|
5563
6139
|
this.maxDistance = Infinity;
|
|
5564
6140
|
this.minZoom = 0;
|
|
@@ -5580,8 +6156,8 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5580
6156
|
this.autoRotate = false;
|
|
5581
6157
|
this.autoRotateSpeed = 2;
|
|
5582
6158
|
this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
|
|
5583
|
-
this.mouseButtons = { LEFT:
|
|
5584
|
-
this.touches = { ONE:
|
|
6159
|
+
this.mouseButtons = { LEFT: import_three20.MOUSE.ROTATE, MIDDLE: import_three20.MOUSE.DOLLY, RIGHT: import_three20.MOUSE.PAN };
|
|
6160
|
+
this.touches = { ONE: import_three20.TOUCH.ROTATE, TWO: import_three20.TOUCH.DOLLY_PAN };
|
|
5585
6161
|
this.target0 = this.target.clone();
|
|
5586
6162
|
this.position0 = this.object.position.clone();
|
|
5587
6163
|
this.zoom0 = this.object.zoom;
|
|
@@ -5610,11 +6186,11 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5610
6186
|
state = STATE.NONE;
|
|
5611
6187
|
};
|
|
5612
6188
|
this.update = function() {
|
|
5613
|
-
const offset = new
|
|
5614
|
-
const quat = new
|
|
6189
|
+
const offset = new import_three20.Vector3();
|
|
6190
|
+
const quat = new import_three20.Quaternion().setFromUnitVectors(object.up, new import_three20.Vector3(0, 1, 0));
|
|
5615
6191
|
const quatInverse = quat.clone().invert();
|
|
5616
|
-
const lastPosition = new
|
|
5617
|
-
const lastQuaternion = new
|
|
6192
|
+
const lastPosition = new import_three20.Vector3();
|
|
6193
|
+
const lastQuaternion = new import_three20.Quaternion();
|
|
5618
6194
|
const twoPI = 2 * Math.PI;
|
|
5619
6195
|
return function update() {
|
|
5620
6196
|
const position = scope.object.position;
|
|
@@ -5700,20 +6276,20 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5700
6276
|
};
|
|
5701
6277
|
let state = STATE.NONE;
|
|
5702
6278
|
const EPS = 1e-6;
|
|
5703
|
-
const spherical = new
|
|
5704
|
-
const sphericalDelta = new
|
|
6279
|
+
const spherical = new import_three20.Spherical();
|
|
6280
|
+
const sphericalDelta = new import_three20.Spherical();
|
|
5705
6281
|
let scale = 1;
|
|
5706
|
-
const panOffset = new
|
|
6282
|
+
const panOffset = new import_three20.Vector3();
|
|
5707
6283
|
let zoomChanged = false;
|
|
5708
|
-
const rotateStart = new
|
|
5709
|
-
const rotateEnd = new
|
|
5710
|
-
const rotateDelta = new
|
|
5711
|
-
const panStart = new
|
|
5712
|
-
const panEnd = new
|
|
5713
|
-
const panDelta = new
|
|
5714
|
-
const dollyStart = new
|
|
5715
|
-
const dollyEnd = new
|
|
5716
|
-
const dollyDelta = new
|
|
6284
|
+
const rotateStart = new import_three20.Vector2();
|
|
6285
|
+
const rotateEnd = new import_three20.Vector2();
|
|
6286
|
+
const rotateDelta = new import_three20.Vector2();
|
|
6287
|
+
const panStart = new import_three20.Vector2();
|
|
6288
|
+
const panEnd = new import_three20.Vector2();
|
|
6289
|
+
const panDelta = new import_three20.Vector2();
|
|
6290
|
+
const dollyStart = new import_three20.Vector2();
|
|
6291
|
+
const dollyEnd = new import_three20.Vector2();
|
|
6292
|
+
const dollyDelta = new import_three20.Vector2();
|
|
5717
6293
|
const pointers = [];
|
|
5718
6294
|
const pointerPositions = {};
|
|
5719
6295
|
function getAutoRotationAngle() {
|
|
@@ -5729,7 +6305,7 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5729
6305
|
sphericalDelta.phi -= angle;
|
|
5730
6306
|
}
|
|
5731
6307
|
const panLeft = function() {
|
|
5732
|
-
const v = new
|
|
6308
|
+
const v = new import_three20.Vector3();
|
|
5733
6309
|
return function panLeft2(distance, objectMatrix) {
|
|
5734
6310
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
5735
6311
|
v.multiplyScalar(-distance);
|
|
@@ -5737,7 +6313,7 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5737
6313
|
};
|
|
5738
6314
|
}();
|
|
5739
6315
|
const panUp = function() {
|
|
5740
|
-
const v = new
|
|
6316
|
+
const v = new import_three20.Vector3();
|
|
5741
6317
|
return function panUp2(distance, objectMatrix) {
|
|
5742
6318
|
if (scope.screenSpacePanning === true) {
|
|
5743
6319
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -5750,7 +6326,7 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5750
6326
|
};
|
|
5751
6327
|
}();
|
|
5752
6328
|
const pan = function() {
|
|
5753
|
-
const offset = new
|
|
6329
|
+
const offset = new import_three20.Vector3();
|
|
5754
6330
|
return function pan2(deltaX, deltaY) {
|
|
5755
6331
|
const element = scope.domElement;
|
|
5756
6332
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -5999,12 +6575,12 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
5999
6575
|
mouseAction = -1;
|
|
6000
6576
|
}
|
|
6001
6577
|
switch (mouseAction) {
|
|
6002
|
-
case
|
|
6578
|
+
case import_three20.MOUSE.DOLLY:
|
|
6003
6579
|
if (scope.enableZoom === false) return;
|
|
6004
6580
|
handleMouseDownDolly(event);
|
|
6005
6581
|
state = STATE.DOLLY;
|
|
6006
6582
|
break;
|
|
6007
|
-
case
|
|
6583
|
+
case import_three20.MOUSE.ROTATE:
|
|
6008
6584
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
6009
6585
|
if (scope.enablePan === false) return;
|
|
6010
6586
|
handleMouseDownPan(event);
|
|
@@ -6015,7 +6591,7 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
6015
6591
|
state = STATE.ROTATE;
|
|
6016
6592
|
}
|
|
6017
6593
|
break;
|
|
6018
|
-
case
|
|
6594
|
+
case import_three20.MOUSE.PAN:
|
|
6019
6595
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
6020
6596
|
if (scope.enableRotate === false) return;
|
|
6021
6597
|
handleMouseDownRotate(event);
|
|
@@ -6071,12 +6647,12 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
6071
6647
|
switch (pointers.length) {
|
|
6072
6648
|
case 1:
|
|
6073
6649
|
switch (scope.touches.ONE) {
|
|
6074
|
-
case
|
|
6650
|
+
case import_three20.TOUCH.ROTATE:
|
|
6075
6651
|
if (scope.enableRotate === false) return;
|
|
6076
6652
|
handleTouchStartRotate();
|
|
6077
6653
|
state = STATE.TOUCH_ROTATE;
|
|
6078
6654
|
break;
|
|
6079
|
-
case
|
|
6655
|
+
case import_three20.TOUCH.PAN:
|
|
6080
6656
|
if (scope.enablePan === false) return;
|
|
6081
6657
|
handleTouchStartPan();
|
|
6082
6658
|
state = STATE.TOUCH_PAN;
|
|
@@ -6087,12 +6663,12 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
6087
6663
|
break;
|
|
6088
6664
|
case 2:
|
|
6089
6665
|
switch (scope.touches.TWO) {
|
|
6090
|
-
case
|
|
6666
|
+
case import_three20.TOUCH.DOLLY_PAN:
|
|
6091
6667
|
if (scope.enableZoom === false && scope.enablePan === false) return;
|
|
6092
6668
|
handleTouchStartDollyPan();
|
|
6093
6669
|
state = STATE.TOUCH_DOLLY_PAN;
|
|
6094
6670
|
break;
|
|
6095
|
-
case
|
|
6671
|
+
case import_three20.TOUCH.DOLLY_ROTATE:
|
|
6096
6672
|
if (scope.enableZoom === false && scope.enableRotate === false) return;
|
|
6097
6673
|
handleTouchStartDollyRotate();
|
|
6098
6674
|
state = STATE.TOUCH_DOLLY_ROTATE;
|
|
@@ -6159,7 +6735,7 @@ var OrbitControls = class extends import_three18.EventDispatcher {
|
|
|
6159
6735
|
function trackPointer(event) {
|
|
6160
6736
|
let position = pointerPositions[event.pointerId];
|
|
6161
6737
|
if (position === void 0) {
|
|
6162
|
-
position = new
|
|
6738
|
+
position = new import_three20.Vector2();
|
|
6163
6739
|
pointerPositions[event.pointerId] = position;
|
|
6164
6740
|
}
|
|
6165
6741
|
position.set(event.pageX, event.pageY);
|
|
@@ -6179,10 +6755,10 @@ var MapControls = class extends OrbitControls {
|
|
|
6179
6755
|
constructor(object, domElement) {
|
|
6180
6756
|
super(object, domElement);
|
|
6181
6757
|
this.screenSpacePanning = false;
|
|
6182
|
-
this.mouseButtons.LEFT =
|
|
6183
|
-
this.mouseButtons.RIGHT =
|
|
6184
|
-
this.touches.ONE =
|
|
6185
|
-
this.touches.TWO =
|
|
6758
|
+
this.mouseButtons.LEFT = import_three20.MOUSE.PAN;
|
|
6759
|
+
this.mouseButtons.RIGHT = import_three20.MOUSE.ROTATE;
|
|
6760
|
+
this.touches.ONE = import_three20.TOUCH.PAN;
|
|
6761
|
+
this.touches.TWO = import_three20.TOUCH.DOLLY_ROTATE;
|
|
6186
6762
|
}
|
|
6187
6763
|
};
|
|
6188
6764
|
|
|
@@ -6190,8 +6766,6 @@ var MapControls = class extends OrbitControls {
|
|
|
6190
6766
|
var _Renderer = class _Renderer {
|
|
6191
6767
|
constructor(options) {
|
|
6192
6768
|
this._dirty = true;
|
|
6193
|
-
this._animationTimer = void 0;
|
|
6194
|
-
this._animationFrame = void 0;
|
|
6195
6769
|
this._resizeListener = void 0;
|
|
6196
6770
|
this._disposed = false;
|
|
6197
6771
|
this._debugHelpers = [];
|
|
@@ -6199,9 +6773,9 @@ var _Renderer = class _Renderer {
|
|
|
6199
6773
|
this._changeListener = () => {
|
|
6200
6774
|
this._dirty = true;
|
|
6201
6775
|
};
|
|
6202
|
-
this.options = (0,
|
|
6776
|
+
this.options = (0, import_ts_deepmerge9.default)({}, _Renderer.DEFAULT_OPTIONS, options ?? {});
|
|
6203
6777
|
this._animationLoop = this.animate.bind(this);
|
|
6204
|
-
this.
|
|
6778
|
+
this._frameInterval = this.options.render.fpsLimit > 0 ? 1e3 / this.options.render.fpsLimit : void 0;
|
|
6205
6779
|
this._scene = this.createScene();
|
|
6206
6780
|
this._camera = this.createCamera();
|
|
6207
6781
|
this._renderer = this.createRenderer();
|
|
@@ -6221,14 +6795,14 @@ var _Renderer = class _Renderer {
|
|
|
6221
6795
|
switch (this.options.camera.type) {
|
|
6222
6796
|
case "perspective":
|
|
6223
6797
|
default:
|
|
6224
|
-
return new
|
|
6798
|
+
return new import_three21.PerspectiveCamera(
|
|
6225
6799
|
this.options.camera.perspective.fov,
|
|
6226
6800
|
this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
|
|
6227
6801
|
this.options.camera.near,
|
|
6228
6802
|
this.options.camera.far
|
|
6229
6803
|
);
|
|
6230
6804
|
case "orthographic":
|
|
6231
|
-
return new
|
|
6805
|
+
return new import_three21.OrthographicCamera(
|
|
6232
6806
|
this.options.camera.orthographic.left ?? this.viewWidth / -2,
|
|
6233
6807
|
this.options.camera.orthographic.right ?? this.viewWidth / 2,
|
|
6234
6808
|
this.options.camera.orthographic.top ?? this.viewHeight / 2,
|
|
@@ -6239,7 +6813,7 @@ var _Renderer = class _Renderer {
|
|
|
6239
6813
|
}
|
|
6240
6814
|
}
|
|
6241
6815
|
createRenderer() {
|
|
6242
|
-
const renderer = new
|
|
6816
|
+
const renderer = new import_three21.WebGLRenderer({
|
|
6243
6817
|
antialias: this.options.render.antialias,
|
|
6244
6818
|
alpha: true,
|
|
6245
6819
|
powerPreference: "high-performance",
|
|
@@ -6247,14 +6821,14 @@ var _Renderer = class _Renderer {
|
|
|
6247
6821
|
});
|
|
6248
6822
|
renderer.setClearColor(0, 0);
|
|
6249
6823
|
renderer.shadowMap.enabled = true;
|
|
6250
|
-
renderer.shadowMap.type =
|
|
6251
|
-
renderer.
|
|
6824
|
+
renderer.shadowMap.type = import_three21.PCFSoftShadowMap;
|
|
6825
|
+
renderer.outputColorSpace = import_three21.SRGBColorSpace;
|
|
6252
6826
|
renderer.setSize(this.viewWidth, this.viewHeight);
|
|
6253
6827
|
return renderer;
|
|
6254
6828
|
}
|
|
6255
6829
|
createComposer() {
|
|
6830
|
+
if (!this.options.composer.enabled) return void 0;
|
|
6256
6831
|
const composer = new import_postprocessing.EffectComposer(this.renderer);
|
|
6257
|
-
if (!this.options.composer.enabled) return composer;
|
|
6258
6832
|
composer.setSize(this.viewWidth, this.viewHeight);
|
|
6259
6833
|
composer.addPass(new import_postprocessing.RenderPass(this.scene, this.camera));
|
|
6260
6834
|
return composer;
|
|
@@ -6282,20 +6856,20 @@ var _Renderer = class _Renderer {
|
|
|
6282
6856
|
window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
|
|
6283
6857
|
}
|
|
6284
6858
|
if (this.options.debug.grid) {
|
|
6285
|
-
const gridHelper = new
|
|
6859
|
+
const gridHelper = new import_three21.GridHelper(128, 16);
|
|
6286
6860
|
this._debugHelpers.push(gridHelper);
|
|
6287
6861
|
this.scene.add(gridHelper);
|
|
6288
|
-
const gridHelper2 = new
|
|
6862
|
+
const gridHelper2 = new import_three21.GridHelper(128, 16);
|
|
6289
6863
|
this._debugHelpers.push(gridHelper2);
|
|
6290
6864
|
gridHelper2.rotation.x = 90 * (Math.PI / 180);
|
|
6291
6865
|
this.scene.add(gridHelper2);
|
|
6292
|
-
const gridHelper3 = new
|
|
6866
|
+
const gridHelper3 = new import_three21.GridHelper(128, 16);
|
|
6293
6867
|
this._debugHelpers.push(gridHelper3);
|
|
6294
6868
|
gridHelper3.rotation.z = 90 * (Math.PI / 180);
|
|
6295
6869
|
this.scene.add(gridHelper3);
|
|
6296
6870
|
}
|
|
6297
6871
|
if (this.options.debug.axes) {
|
|
6298
|
-
const axesHelper = new
|
|
6872
|
+
const axesHelper = new import_three21.AxesHelper(64);
|
|
6299
6873
|
this._debugHelpers.push(axesHelper);
|
|
6300
6874
|
this.scene.add(axesHelper);
|
|
6301
6875
|
}
|
|
@@ -6363,7 +6937,7 @@ var _Renderer = class _Renderer {
|
|
|
6363
6937
|
this.camera.updateProjectionMatrix();
|
|
6364
6938
|
}
|
|
6365
6939
|
this.renderer.setSize(width, height);
|
|
6366
|
-
this.composer
|
|
6940
|
+
this.composer?.setSize(width, height);
|
|
6367
6941
|
this._dirty = true;
|
|
6368
6942
|
}
|
|
6369
6943
|
//<editor-fold desc="RENDER">
|
|
@@ -6382,12 +6956,7 @@ var _Renderer = class _Renderer {
|
|
|
6382
6956
|
stop() {
|
|
6383
6957
|
if (this._disposed) return;
|
|
6384
6958
|
this.renderer.setAnimationLoop(null);
|
|
6385
|
-
|
|
6386
|
-
clearTimeout(this._animationTimer);
|
|
6387
|
-
this._animationTimer = void 0;
|
|
6388
|
-
if (this._animationFrame)
|
|
6389
|
-
cancelAnimationFrame(this._animationFrame);
|
|
6390
|
-
this._animationFrame = void 0;
|
|
6959
|
+
this._nextFrameTime = void 0;
|
|
6391
6960
|
}
|
|
6392
6961
|
/**
|
|
6393
6962
|
* Stops rendering and releases owned resources. Repeated calls have no effect, and a disposed
|
|
@@ -6427,25 +6996,30 @@ var _Renderer = class _Renderer {
|
|
|
6427
6996
|
}
|
|
6428
6997
|
}
|
|
6429
6998
|
this._debugHelpers.length = 0;
|
|
6430
|
-
this.composer
|
|
6999
|
+
this.composer?.dispose();
|
|
6431
7000
|
this.renderer.dispose();
|
|
6432
7001
|
this.renderer.forceContextLoss();
|
|
6433
7002
|
}
|
|
6434
|
-
animate(t) {
|
|
7003
|
+
animate(t = performance.now()) {
|
|
6435
7004
|
if (this._disposed) return;
|
|
6436
|
-
if (this._stats) {
|
|
6437
|
-
this._stats.begin();
|
|
6438
|
-
}
|
|
6439
7005
|
if (this._controls?.enabled) {
|
|
6440
7006
|
this._controls.update();
|
|
6441
7007
|
}
|
|
6442
7008
|
if (this._disposed) return;
|
|
6443
|
-
if (this.dirty
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
7009
|
+
if (!this.dirty && !this.options.render.renderAlways) return;
|
|
7010
|
+
const interval = this._frameInterval;
|
|
7011
|
+
if (interval) {
|
|
7012
|
+
const next = this._nextFrameTime;
|
|
7013
|
+
if (next !== void 0 && t + 0.1 < next) return;
|
|
7014
|
+
this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
|
|
7015
|
+
}
|
|
7016
|
+
if (this._stats) {
|
|
7017
|
+
this._stats.begin();
|
|
7018
|
+
}
|
|
7019
|
+
if (this.options.composer.enabled && this.composer) {
|
|
7020
|
+
this.composer.render();
|
|
7021
|
+
} else {
|
|
7022
|
+
this.renderer.render(this.scene, this.camera);
|
|
6449
7023
|
}
|
|
6450
7024
|
this.dirty = false;
|
|
6451
7025
|
if (this._stats) {
|
|
@@ -6484,7 +7058,7 @@ var _Renderer = class _Renderer {
|
|
|
6484
7058
|
}
|
|
6485
7059
|
///
|
|
6486
7060
|
};
|
|
6487
|
-
_Renderer.DEFAULT_OPTIONS = (0,
|
|
7061
|
+
_Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
|
|
6488
7062
|
camera: {
|
|
6489
7063
|
type: "perspective",
|
|
6490
7064
|
near: 1,
|
|
@@ -6499,8 +7073,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge10.default)({}, {
|
|
|
6499
7073
|
top: void 0,
|
|
6500
7074
|
bottom: void 0
|
|
6501
7075
|
},
|
|
6502
|
-
position: new
|
|
6503
|
-
lookingAt: new
|
|
7076
|
+
position: new import_three21.Vector3(50, 50, 50),
|
|
7077
|
+
lookingAt: new import_three21.Vector3(0, 0, 0)
|
|
6504
7078
|
},
|
|
6505
7079
|
render: {
|
|
6506
7080
|
fpsLimit: 60,
|
|
@@ -6533,7 +7107,7 @@ var Skins = class {
|
|
|
6533
7107
|
return this.fromUsername(uuidOrUsername);
|
|
6534
7108
|
}
|
|
6535
7109
|
static async fromUuid(uuid) {
|
|
6536
|
-
return this.
|
|
7110
|
+
return this.getMcProxySkinUrl(uuid);
|
|
6537
7111
|
}
|
|
6538
7112
|
static async fromUsername(username) {
|
|
6539
7113
|
return this.usernameToUuid(username).then((uuid) => {
|
|
@@ -6560,7 +7134,7 @@ var Skins = class {
|
|
|
6560
7134
|
return this.capeFromUsername(uuidOrUsername);
|
|
6561
7135
|
}
|
|
6562
7136
|
static async capeFromUuid(uuid) {
|
|
6563
|
-
return this.
|
|
7137
|
+
return this.getMcProxyCapeUrl(uuid);
|
|
6564
7138
|
}
|
|
6565
7139
|
static async capeFromUsername(username) {
|
|
6566
7140
|
return this.usernameToUuid(username).then((uuid) => {
|
|
@@ -6570,19 +7144,31 @@ var Skins = class {
|
|
|
6570
7144
|
return void 0;
|
|
6571
7145
|
});
|
|
6572
7146
|
}
|
|
6573
|
-
static
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
}
|
|
6578
|
-
return void 0;
|
|
6579
|
-
});
|
|
7147
|
+
/** Returns a full static cape texture for a username or UUID. */
|
|
7148
|
+
static async capeFromCapesDev(player, capeType = "minecraft") {
|
|
7149
|
+
const cape = await this.getCapesDev(player, capeType);
|
|
7150
|
+
return cape?.exists ? cape.imageUrls?.still?.full : void 0;
|
|
6580
7151
|
}
|
|
6581
7152
|
//</editor-fold>
|
|
6582
7153
|
//<editor-fold desc="Helpers">
|
|
6583
7154
|
static async usernameToUuid(username) {
|
|
6584
|
-
return this.
|
|
7155
|
+
return this.usernameToUuidMcProxy(username);
|
|
7156
|
+
}
|
|
7157
|
+
static async usernameToUuidMcProxy(username) {
|
|
7158
|
+
return Requests.genericRequest({
|
|
7159
|
+
baseURL: "https://mcproxy.dev",
|
|
7160
|
+
url: "/uuid/" + username
|
|
7161
|
+
}).then((res) => {
|
|
7162
|
+
if (res.status === 200) {
|
|
7163
|
+
return res.data["data"]["id"];
|
|
7164
|
+
}
|
|
7165
|
+
return void 0;
|
|
7166
|
+
}).catch((err) => {
|
|
7167
|
+
console.warn(err);
|
|
7168
|
+
return void 0;
|
|
7169
|
+
});
|
|
6585
7170
|
}
|
|
7171
|
+
/** @deprecated **/
|
|
6586
7172
|
static async usernameToUuidSkinProxy(username) {
|
|
6587
7173
|
return Requests.genericRequest({
|
|
6588
7174
|
baseURL: "https://minecraft-skin-proxy.inventive.workers.dev",
|
|
@@ -6635,18 +7221,15 @@ var Skins = class {
|
|
|
6635
7221
|
return void 0;
|
|
6636
7222
|
});
|
|
6637
7223
|
}
|
|
6638
|
-
static async getCapesDev(
|
|
7224
|
+
static async getCapesDev(player, type = "all") {
|
|
6639
7225
|
return Requests.genericRequest({
|
|
6640
7226
|
baseURL: "https://api.capes.dev",
|
|
6641
|
-
url: "/load/" +
|
|
7227
|
+
url: "/load/" + encodeURIComponent(player) + "/" + encodeURIComponent(type)
|
|
6642
7228
|
}).then((res) => {
|
|
6643
7229
|
if (res.status === 200) {
|
|
6644
7230
|
return res.data;
|
|
6645
7231
|
}
|
|
6646
7232
|
return void 0;
|
|
6647
|
-
}).catch((err) => {
|
|
6648
|
-
console.warn(err);
|
|
6649
|
-
return void 0;
|
|
6650
7233
|
});
|
|
6651
7234
|
}
|
|
6652
7235
|
static getCrafatarSkinUrl(uuid) {
|
|
@@ -6661,20 +7244,28 @@ var Skins = class {
|
|
|
6661
7244
|
static getMineSkinPlayerSkinUrl(uuid) {
|
|
6662
7245
|
return "https://mineskin.org/skin/player/" + uuid;
|
|
6663
7246
|
}
|
|
7247
|
+
/** @deprecated **/
|
|
6664
7248
|
static getSkinProxySkinUrl(uuid) {
|
|
6665
7249
|
return "https://minecraft-skin-proxy.inventive.workers.dev/skin/" + uuid;
|
|
6666
7250
|
}
|
|
7251
|
+
/** @deprecated **/
|
|
6667
7252
|
static getSkinProxyCapeUrl(uuid) {
|
|
6668
7253
|
return "https://minecraft-skin-proxy.inventive.workers.dev/cape/" + uuid;
|
|
6669
7254
|
}
|
|
7255
|
+
static getMcProxySkinUrl(uuid) {
|
|
7256
|
+
return "https://mcproxy.dev/skin/" + uuid;
|
|
7257
|
+
}
|
|
7258
|
+
static getMcProxyCapeUrl(uuid) {
|
|
7259
|
+
return "https://mcproxy.dev/cape/" + uuid;
|
|
7260
|
+
}
|
|
6670
7261
|
//</editor-fold>
|
|
6671
7262
|
};
|
|
6672
7263
|
|
|
6673
7264
|
// src/world/Chunk.ts
|
|
6674
|
-
var
|
|
7265
|
+
var import_three24 = require("three");
|
|
6675
7266
|
|
|
6676
7267
|
// src/world/MineRenderWorld.ts
|
|
6677
|
-
var
|
|
7268
|
+
var import_three23 = require("three");
|
|
6678
7269
|
var MineRenderWorld = class {
|
|
6679
7270
|
constructor(scene) {
|
|
6680
7271
|
this._size = 4;
|
|
@@ -6685,10 +7276,10 @@ var MineRenderWorld = class {
|
|
|
6685
7276
|
}
|
|
6686
7277
|
getBlockAt(posOrX, y, z) {
|
|
6687
7278
|
if (typeof posOrX == "number") {
|
|
6688
|
-
return this.getBlockAt(new
|
|
7279
|
+
return this.getBlockAt(new import_three23.Vector3(posOrX, y, z));
|
|
6689
7280
|
}
|
|
6690
7281
|
if (isTripleArray(posOrX)) {
|
|
6691
|
-
return this.getBlockAt(new
|
|
7282
|
+
return this.getBlockAt(new import_three23.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
6692
7283
|
}
|
|
6693
7284
|
const chunk = this.getChunkAt(posOrX);
|
|
6694
7285
|
if (typeof chunk === "undefined") {
|
|
@@ -6699,10 +7290,10 @@ var MineRenderWorld = class {
|
|
|
6699
7290
|
}
|
|
6700
7291
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
6701
7292
|
if (typeof posOrX == "number") {
|
|
6702
|
-
return this.setBlockAt(new
|
|
7293
|
+
return this.setBlockAt(new import_three23.Vector3(posOrX, yOrBlock, z), block);
|
|
6703
7294
|
}
|
|
6704
7295
|
if (isTripleArray(posOrX)) {
|
|
6705
|
-
return this.setBlockAt(new
|
|
7296
|
+
return this.setBlockAt(new import_three23.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
6706
7297
|
}
|
|
6707
7298
|
this.validatePosBounds(posOrX);
|
|
6708
7299
|
const chunk = this.getOrCreateChunkAt(posOrX);
|
|
@@ -6748,14 +7339,14 @@ var MineRenderWorld = class {
|
|
|
6748
7339
|
return this._chunks[index];
|
|
6749
7340
|
}
|
|
6750
7341
|
static worldToScenePosition(pos) {
|
|
6751
|
-
return new
|
|
7342
|
+
return new import_three23.Vector3(
|
|
6752
7343
|
pos.x * 16,
|
|
6753
7344
|
pos.y * 16,
|
|
6754
7345
|
pos.z * 16
|
|
6755
7346
|
);
|
|
6756
7347
|
}
|
|
6757
7348
|
static sceneToWorldPosition(pos) {
|
|
6758
|
-
return new
|
|
7349
|
+
return new import_three23.Vector3(
|
|
6759
7350
|
pos.x / 16,
|
|
6760
7351
|
pos.y / 16,
|
|
6761
7352
|
pos.z / 16
|
|
@@ -6784,7 +7375,7 @@ var MineRenderWorld = class {
|
|
|
6784
7375
|
};
|
|
6785
7376
|
|
|
6786
7377
|
// src/world/Chunk.ts
|
|
6787
|
-
var
|
|
7378
|
+
var p11 = prefix("Chunk");
|
|
6788
7379
|
var Chunk = class _Chunk {
|
|
6789
7380
|
constructor(scene, x, y, z) {
|
|
6790
7381
|
this._blocks = [];
|
|
@@ -6792,12 +7383,12 @@ var Chunk = class _Chunk {
|
|
|
6792
7383
|
this.x = x;
|
|
6793
7384
|
this.y = y;
|
|
6794
7385
|
this.z = z;
|
|
6795
|
-
let anchor = new
|
|
7386
|
+
let anchor = new import_three24.Object3D();
|
|
6796
7387
|
this._anchor = anchor;
|
|
6797
7388
|
scene.add(anchor);
|
|
6798
7389
|
anchor.position.set(this.x * 256 + 128 - 8, this.y * 256 + 128 - 8, this.z * 256 + 128 - 8);
|
|
6799
7390
|
addBox3WireframeToObject(
|
|
6800
|
-
new
|
|
7391
|
+
new import_three24.Box3(new import_three24.Vector3(0, 0, 0), new import_three24.Vector3(256, 256, 256)),
|
|
6801
7392
|
anchor,
|
|
6802
7393
|
16776960,
|
|
6803
7394
|
4
|
|
@@ -6805,10 +7396,10 @@ var Chunk = class _Chunk {
|
|
|
6805
7396
|
}
|
|
6806
7397
|
getBlockAt(posOrX, y, z) {
|
|
6807
7398
|
if (typeof posOrX == "number") {
|
|
6808
|
-
return this.getBlockAt(new
|
|
7399
|
+
return this.getBlockAt(new import_three24.Vector3(posOrX, y, z));
|
|
6809
7400
|
}
|
|
6810
7401
|
if (isTripleArray(posOrX)) {
|
|
6811
|
-
return this.getBlockAt(new
|
|
7402
|
+
return this.getBlockAt(new import_three24.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
6812
7403
|
}
|
|
6813
7404
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
6814
7405
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -6816,10 +7407,10 @@ var Chunk = class _Chunk {
|
|
|
6816
7407
|
}
|
|
6817
7408
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
6818
7409
|
if (typeof posOrX == "number") {
|
|
6819
|
-
return this.setBlockAt(new
|
|
7410
|
+
return this.setBlockAt(new import_three24.Vector3(posOrX, yOrBlock, z), block);
|
|
6820
7411
|
}
|
|
6821
7412
|
if (isTripleArray(posOrX)) {
|
|
6822
|
-
return this.setBlockAt(new
|
|
7413
|
+
return this.setBlockAt(new import_three24.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
6823
7414
|
}
|
|
6824
7415
|
const worldPos = posOrX;
|
|
6825
7416
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -6836,7 +7427,7 @@ var Chunk = class _Chunk {
|
|
|
6836
7427
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
6837
7428
|
const current = this._blocks[index];
|
|
6838
7429
|
if (typeof current !== "undefined") {
|
|
6839
|
-
console.debug(
|
|
7430
|
+
console.debug(p11, "deleting existing block at", pos, worldPos, index);
|
|
6840
7431
|
current.object.removeFromScene();
|
|
6841
7432
|
delete this._blocks[index];
|
|
6842
7433
|
}
|
|
@@ -6865,7 +7456,7 @@ var Chunk = class _Chunk {
|
|
|
6865
7456
|
}
|
|
6866
7457
|
async clear() {
|
|
6867
7458
|
let promises = [];
|
|
6868
|
-
let pos = new
|
|
7459
|
+
let pos = new import_three24.Vector3();
|
|
6869
7460
|
for (let x = 0; x < 16; x++) {
|
|
6870
7461
|
for (let z = 0; z < 16; z++) {
|
|
6871
7462
|
for (let y = 0; y < 16; y++) {
|
|
@@ -6884,14 +7475,14 @@ var Chunk = class _Chunk {
|
|
|
6884
7475
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
6885
7476
|
}
|
|
6886
7477
|
worldPosToChunkPos(pos) {
|
|
6887
|
-
return new
|
|
7478
|
+
return new import_three24.Vector3(
|
|
6888
7479
|
pos.x - this.x * 16,
|
|
6889
7480
|
pos.y - this.y * 16,
|
|
6890
7481
|
pos.z - this.z * 16
|
|
6891
7482
|
);
|
|
6892
7483
|
}
|
|
6893
7484
|
chunkPosToWorldPos(pos) {
|
|
6894
|
-
return new
|
|
7485
|
+
return new import_three24.Vector3(
|
|
6895
7486
|
this.x * 16 + pos.x,
|
|
6896
7487
|
this.y * 16 + pos.y,
|
|
6897
7488
|
this.z * 16 + pos.z
|