minerender 2.1.0-beta.7 → 2.1.0-beta.8
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 +10 -1
- package/dist/browser/esm/armor/Armor.mjs +84 -0
- package/dist/browser/esm/armor/Armor.mjs.map +1 -0
- package/dist/browser/esm/armor/index.mjs +3 -0
- package/dist/browser/esm/armor/index.mjs.map +1 -0
- package/dist/browser/esm/assets/BlockEntities.mjs +2 -0
- package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
- package/dist/browser/esm/assets/Entities.mjs +39 -11
- package/dist/browser/esm/assets/Entities.mjs.map +1 -1
- package/dist/browser/esm/assets/MineRenderData.mjs +8 -17
- package/dist/browser/esm/assets/MineRenderData.mjs.map +1 -1
- package/dist/browser/esm/assets/ModelTextures.mjs +13 -7
- package/dist/browser/esm/assets/ModelTextures.mjs.map +1 -1
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs +22 -0
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs.map +1 -0
- package/dist/browser/esm/cache/Caching.mjs +8 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +31 -5
- package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
- package/dist/browser/esm/env/browser/BrowserEnv.mjs +11 -4
- package/dist/browser/esm/env/browser/BrowserEnv.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +129 -13
- package/dist/browser/esm/index.browser.mjs.map +1 -1
- package/dist/browser/esm/index.mjs +1 -0
- package/dist/browser/esm/index.mjs.map +1 -1
- package/dist/browser/esm/model/ItemGlint.mjs +7 -6
- package/dist/browser/esm/model/ItemGlint.mjs.map +1 -1
- package/dist/browser/esm/model/block/scene/BlockObject.mjs +16 -5
- package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
- package/dist/browser/esm/scene/SceneDocument.mjs +35 -5
- package/dist/browser/esm/scene/SceneDocument.mjs.map +1 -1
- package/dist/browser/esm/scene/SceneDocumentLoader.mjs +14 -3
- package/dist/browser/esm/scene/SceneDocumentLoader.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinGeometries.mjs +4 -1
- package/dist/browser/esm/skin/SkinGeometries.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinPart.mjs +2 -0
- package/dist/browser/esm/skin/SkinPart.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinTextureCoordinates.mjs +11 -1
- package/dist/browser/esm/skin/SkinTextureCoordinates.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinTextures.mjs +1 -1
- package/dist/browser/esm/skin/SkinTextures.mjs.map +1 -1
- package/dist/browser/esm/skin/scene/SkinObject.mjs +119 -7
- package/dist/browser/esm/skin/scene/SkinObject.mjs.map +1 -1
- package/dist/browser/esm/texture/PalettedTextures.mjs +46 -0
- package/dist/browser/esm/texture/PalettedTextures.mjs.map +1 -0
- package/dist/browser/esm/texture/index.mjs +1 -0
- package/dist/browser/esm/texture/index.mjs.map +1 -1
- package/dist/browser/esm/util/util.mjs +0 -2
- package/dist/browser/esm/util/util.mjs.map +1 -1
- package/dist/browser/esm/world/Chunk.mjs +62 -33
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +98 -13
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +65 -9
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +21 -15
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/esm/world/SectionWorker.mjs +8 -2
- package/dist/browser/esm/world/SectionWorker.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +109 -15
- package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
- package/dist/browser/index.d.ts +129 -13
- package/dist/browser/index.js +1592 -894
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +1330 -619
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +117 -12
- package/dist/node/index.d.ts +117 -12
- package/dist/node/index.js +1505 -793
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +1303 -593
- package/dist/node/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/browser/index.js
CHANGED
|
@@ -56,37 +56,6 @@ var init_Env = __esm({
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
// src/cache/PersistentCache.ts
|
|
60
|
-
var _PersistentCache, PersistentCache;
|
|
61
|
-
var init_PersistentCache = __esm({
|
|
62
|
-
"src/cache/PersistentCache.ts"() {
|
|
63
|
-
init_Env();
|
|
64
|
-
_PersistentCache = class _PersistentCache {
|
|
65
|
-
constructor(backing) {
|
|
66
|
-
this.backing = backing;
|
|
67
|
-
}
|
|
68
|
-
/** Opens a named store in the active environment using the current cache schema version. */
|
|
69
|
-
static open(name) {
|
|
70
|
-
return Env.provider.openCache(name, _PersistentCache.VERSION);
|
|
71
|
-
}
|
|
72
|
-
/** Loads a missing entry and stores only non-nullish results. */
|
|
73
|
-
async getOrLoad(key, loader) {
|
|
74
|
-
let v = await this.get(key);
|
|
75
|
-
if (typeof v === "undefined" || v === null) {
|
|
76
|
-
v = await loader(key);
|
|
77
|
-
if (typeof v !== "undefined" && v !== null) {
|
|
78
|
-
await this.put(key, v);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return v;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
/** Bump to invalidate every persisted entry. */
|
|
85
|
-
_PersistentCache.VERSION = 2;
|
|
86
|
-
PersistentCache = _PersistentCache;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
59
|
// src/util/log.ts
|
|
91
60
|
function readSwitch() {
|
|
92
61
|
switchRead = true;
|
|
@@ -168,6 +137,37 @@ var init_log = __esm({
|
|
|
168
137
|
}
|
|
169
138
|
});
|
|
170
139
|
|
|
140
|
+
// src/cache/PersistentCache.ts
|
|
141
|
+
var _PersistentCache, PersistentCache;
|
|
142
|
+
var init_PersistentCache = __esm({
|
|
143
|
+
"src/cache/PersistentCache.ts"() {
|
|
144
|
+
init_Env();
|
|
145
|
+
_PersistentCache = class _PersistentCache {
|
|
146
|
+
constructor(backing) {
|
|
147
|
+
this.backing = backing;
|
|
148
|
+
}
|
|
149
|
+
/** Opens a named store in the active environment using the current cache schema version. */
|
|
150
|
+
static open(name) {
|
|
151
|
+
return Env.provider.openCache(name, _PersistentCache.VERSION);
|
|
152
|
+
}
|
|
153
|
+
/** Loads a missing entry and stores only non-nullish results. */
|
|
154
|
+
async getOrLoad(key, loader) {
|
|
155
|
+
let v = await this.get(key);
|
|
156
|
+
if (typeof v === "undefined" || v === null) {
|
|
157
|
+
v = await loader(key);
|
|
158
|
+
if (typeof v !== "undefined" && v !== null) {
|
|
159
|
+
await this.put(key, v);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return v;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
/** Bump to invalidate every persisted entry. */
|
|
166
|
+
_PersistentCache.VERSION = 2;
|
|
167
|
+
PersistentCache = _PersistentCache;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
171
|
// src/Axis.ts
|
|
172
172
|
function axisToVec3(axis) {
|
|
173
173
|
switch (axis) {
|
|
@@ -264,8 +264,6 @@ async function sleep(timeout) {
|
|
|
264
264
|
});
|
|
265
265
|
}
|
|
266
266
|
function yieldToEventLoop() {
|
|
267
|
-
const scheduler = globalThis.scheduler;
|
|
268
|
-
if (scheduler?.yield) return scheduler.yield();
|
|
269
267
|
return new Promise((resolve) => {
|
|
270
268
|
if (typeof MessageChannel !== "undefined") {
|
|
271
269
|
const channel = new MessageChannel();
|
|
@@ -353,9 +351,12 @@ var init_Caching = __esm({
|
|
|
353
351
|
this.entityTextureCache,
|
|
354
352
|
this.entityAnimationCache,
|
|
355
353
|
this.blockEntityIndexCache,
|
|
354
|
+
this.entityDatasetVersionCache,
|
|
356
355
|
this.fontCache,
|
|
357
356
|
this.unihexCache,
|
|
358
357
|
this.bannerPatternCache,
|
|
358
|
+
this.equipmentCache,
|
|
359
|
+
this.trimCache,
|
|
359
360
|
this.mineRenderDataCache,
|
|
360
361
|
this.usernameUuidCache,
|
|
361
362
|
this.biomeCache
|
|
@@ -387,6 +388,8 @@ var init_Caching = __esm({
|
|
|
387
388
|
};
|
|
388
389
|
}
|
|
389
390
|
};
|
|
391
|
+
/** Cached in place of a missing asset. The caches drop `undefined` results, which would request the asset again. */
|
|
392
|
+
_Caching.MISSING = false;
|
|
390
393
|
_Caching._generation = 0;
|
|
391
394
|
_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();
|
|
392
395
|
_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();
|
|
@@ -408,9 +411,12 @@ var init_Caching = __esm({
|
|
|
408
411
|
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
409
412
|
_Caching.entityAnimationCache = _Caching.createAssetCache();
|
|
410
413
|
_Caching.blockEntityIndexCache = _Caching.createAssetCache();
|
|
414
|
+
_Caching.entityDatasetVersionCache = _Caching.createAssetCache();
|
|
411
415
|
_Caching.unihexCache = _Caching.createAssetCache();
|
|
412
416
|
_Caching.fontCache = _Caching.createAssetCache();
|
|
413
417
|
_Caching.bannerPatternCache = _Caching.createAssetCache();
|
|
418
|
+
_Caching.equipmentCache = _Caching.createAssetCache();
|
|
419
|
+
_Caching.trimCache = _Caching.createAssetCache();
|
|
414
420
|
_Caching.mineRenderDataCache = _Caching.createAssetCache();
|
|
415
421
|
_Caching.usernameUuidCache = import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
|
|
416
422
|
_Caching.biomeCache = _Caching.createAssetCache();
|
|
@@ -511,12 +517,12 @@ async function abortable(promise, signal) {
|
|
|
511
517
|
signal.removeEventListener("abort", abort);
|
|
512
518
|
}
|
|
513
519
|
}
|
|
514
|
-
var import_jobqu,
|
|
520
|
+
var import_jobqu, log3, RequestError, RequestQueue, Requests;
|
|
515
521
|
var init_Requests = __esm({
|
|
516
522
|
"src/request/Requests.ts"() {
|
|
517
523
|
import_jobqu = require("jobqu");
|
|
518
524
|
init_log();
|
|
519
|
-
|
|
525
|
+
log3 = logger("Requests");
|
|
520
526
|
RequestError = class extends Error {
|
|
521
527
|
constructor(message, response, cause) {
|
|
522
528
|
super(message);
|
|
@@ -543,7 +549,7 @@ var init_Requests = __esm({
|
|
|
543
549
|
try {
|
|
544
550
|
return await abortable(this.queue.add(request), signal);
|
|
545
551
|
} catch (error) {
|
|
546
|
-
|
|
552
|
+
log3.debug("Request failed", error);
|
|
547
553
|
const delay = this.retryDelay(error, request, retries);
|
|
548
554
|
if (delay === void 0) {
|
|
549
555
|
throw error;
|
|
@@ -725,7 +731,7 @@ var init_base64 = __esm({
|
|
|
725
731
|
});
|
|
726
732
|
|
|
727
733
|
// src/image/ImageLoader.ts
|
|
728
|
-
var
|
|
734
|
+
var log4, ImageLoader;
|
|
729
735
|
var init_ImageLoader = __esm({
|
|
730
736
|
"src/image/ImageLoader.ts"() {
|
|
731
737
|
init_CanvasCompat();
|
|
@@ -736,7 +742,7 @@ var init_ImageLoader = __esm({
|
|
|
736
742
|
init_WrappedImage();
|
|
737
743
|
init_base64();
|
|
738
744
|
init_log();
|
|
739
|
-
|
|
745
|
+
log4 = logger("ImageLoader");
|
|
740
746
|
ImageLoader = class _ImageLoader {
|
|
741
747
|
static _createImage() {
|
|
742
748
|
return createImage();
|
|
@@ -761,7 +767,7 @@ var init_ImageLoader = __esm({
|
|
|
761
767
|
return image;
|
|
762
768
|
}
|
|
763
769
|
static async loadData(src) {
|
|
764
|
-
|
|
770
|
+
log4.debug("loadData", src);
|
|
765
771
|
const image = await this.loadCanvasData(src);
|
|
766
772
|
return image.data.getImageData(0, 0, image.width, image.height);
|
|
767
773
|
}
|
|
@@ -868,7 +874,7 @@ var init_ImageLoader = __esm({
|
|
|
868
874
|
});
|
|
869
875
|
|
|
870
876
|
// src/texture/TextureLoader.ts
|
|
871
|
-
var import_three3, THREE,
|
|
877
|
+
var import_three3, THREE, log5, TextureLoader;
|
|
872
878
|
var init_TextureLoader = __esm({
|
|
873
879
|
"src/texture/TextureLoader.ts"() {
|
|
874
880
|
import_three3 = require("three");
|
|
@@ -876,7 +882,7 @@ var init_TextureLoader = __esm({
|
|
|
876
882
|
init_ImageLoader();
|
|
877
883
|
init_Textures();
|
|
878
884
|
init_log();
|
|
879
|
-
|
|
885
|
+
log5 = logger("TextureLoader");
|
|
880
886
|
TextureLoader = class {
|
|
881
887
|
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
882
888
|
static hasFailed(texture) {
|
|
@@ -892,7 +898,7 @@ var init_TextureLoader = __esm({
|
|
|
892
898
|
texture.needsUpdate = true;
|
|
893
899
|
}, (error) => {
|
|
894
900
|
this.failedTextures.add(texture);
|
|
895
|
-
|
|
901
|
+
log5.warn("Failed to load texture", src, error);
|
|
896
902
|
});
|
|
897
903
|
texture.image = image;
|
|
898
904
|
texture.format = format2;
|
|
@@ -908,7 +914,7 @@ var init_TextureLoader = __esm({
|
|
|
908
914
|
texture.needsUpdate = true;
|
|
909
915
|
}).catch((error) => {
|
|
910
916
|
this.failedTextures.add(texture);
|
|
911
|
-
|
|
917
|
+
log5.warn("Failed to load texture", src, error);
|
|
912
918
|
});
|
|
913
919
|
texture.format = format2;
|
|
914
920
|
texture.rotation = rotation;
|
|
@@ -984,7 +990,7 @@ var init_Textures = __esm({
|
|
|
984
990
|
});
|
|
985
991
|
|
|
986
992
|
// src/Materials.ts
|
|
987
|
-
var import_three5,
|
|
993
|
+
var import_three5, log6, Materials;
|
|
988
994
|
var init_Materials = __esm({
|
|
989
995
|
"src/Materials.ts"() {
|
|
990
996
|
init_CacheKey();
|
|
@@ -993,7 +999,7 @@ var init_Materials = __esm({
|
|
|
993
999
|
init_TextureLoader();
|
|
994
1000
|
init_Caching();
|
|
995
1001
|
init_log();
|
|
996
|
-
|
|
1002
|
+
log6 = logger("Materials");
|
|
997
1003
|
Materials = class _Materials {
|
|
998
1004
|
/** Shared checkerboard material, created on first access. */
|
|
999
1005
|
static get MISSING_TEXTURE() {
|
|
@@ -1264,7 +1270,7 @@ var init_Materials = __esm({
|
|
|
1264
1270
|
Object.assign(material.defaultAttributeValues, { shade: [1], uvBounds: [0, 0, 1, 1] });
|
|
1265
1271
|
return material;
|
|
1266
1272
|
} catch (e) {
|
|
1267
|
-
|
|
1273
|
+
log6.warn(e);
|
|
1268
1274
|
}
|
|
1269
1275
|
return this.createBasicCanvasMaterial(canvas, transparent, shade);
|
|
1270
1276
|
}
|
|
@@ -1634,7 +1640,7 @@ var init_merge = __esm({
|
|
|
1634
1640
|
});
|
|
1635
1641
|
|
|
1636
1642
|
// src/assets/source/HostedAssetSource.ts
|
|
1637
|
-
var BINARY_TIMEOUT,
|
|
1643
|
+
var BINARY_TIMEOUT, log7, DEFAULT_OPTIONS, _HostedAssetSource, HostedAssetSource;
|
|
1638
1644
|
var init_HostedAssetSource = __esm({
|
|
1639
1645
|
"src/assets/source/HostedAssetSource.ts"() {
|
|
1640
1646
|
init_AssetSource();
|
|
@@ -1648,7 +1654,7 @@ var init_HostedAssetSource = __esm({
|
|
|
1648
1654
|
init_parser();
|
|
1649
1655
|
init_merge();
|
|
1650
1656
|
BINARY_TIMEOUT = 6e4;
|
|
1651
|
-
|
|
1657
|
+
log7 = logger("HostedAssetSource");
|
|
1652
1658
|
DEFAULT_OPTIONS = {
|
|
1653
1659
|
retryDefaults: true
|
|
1654
1660
|
};
|
|
@@ -1660,14 +1666,14 @@ var init_HostedAssetSource = __esm({
|
|
|
1660
1666
|
return direct;
|
|
1661
1667
|
}
|
|
1662
1668
|
if (key.namespace !== DEFAULT_NAMESPACE) {
|
|
1663
|
-
|
|
1669
|
+
log7.debug("Retrying", key, "with default namespace");
|
|
1664
1670
|
const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
|
|
1665
1671
|
const namespaced = await this.load(namespaceKey, parser);
|
|
1666
1672
|
if (typeof namespaced !== "undefined") {
|
|
1667
1673
|
return namespaced;
|
|
1668
1674
|
}
|
|
1669
1675
|
if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
1670
|
-
|
|
1676
|
+
log7.debug("Retrying", key, "with default root+namespace");
|
|
1671
1677
|
const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
1672
1678
|
const namespacedRooted = await this.load(namespacedRootedKey, parser);
|
|
1673
1679
|
if (typeof namespacedRooted !== "undefined") {
|
|
@@ -1675,7 +1681,7 @@ var init_HostedAssetSource = __esm({
|
|
|
1675
1681
|
}
|
|
1676
1682
|
}
|
|
1677
1683
|
} else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
1678
|
-
|
|
1684
|
+
log7.debug("Retrying", key, "with default root");
|
|
1679
1685
|
const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
1680
1686
|
const rooted = await this.load(rootKey, parser);
|
|
1681
1687
|
if (typeof rooted !== "undefined") {
|
|
@@ -1686,7 +1692,7 @@ var init_HostedAssetSource = __esm({
|
|
|
1686
1692
|
}
|
|
1687
1693
|
async load(key, parser) {
|
|
1688
1694
|
const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
1689
|
-
|
|
1695
|
+
log7.debug("Loading", url);
|
|
1690
1696
|
const request = { url };
|
|
1691
1697
|
try {
|
|
1692
1698
|
parser.config(request);
|
|
@@ -2139,7 +2145,7 @@ var init_source = __esm({
|
|
|
2139
2145
|
});
|
|
2140
2146
|
|
|
2141
2147
|
// src/assets/AssetLoader.ts
|
|
2142
|
-
var
|
|
2148
|
+
var log8, AssetLoader;
|
|
2143
2149
|
var init_AssetLoader = __esm({
|
|
2144
2150
|
"src/assets/AssetLoader.ts"() {
|
|
2145
2151
|
init_AssetDefaults();
|
|
@@ -2147,7 +2153,7 @@ var init_AssetLoader = __esm({
|
|
|
2147
2153
|
init_log();
|
|
2148
2154
|
init_source();
|
|
2149
2155
|
init_Caching();
|
|
2150
|
-
|
|
2156
|
+
log8 = logger("AssetLoader");
|
|
2151
2157
|
AssetLoader = class {
|
|
2152
2158
|
static get _SOURCES() {
|
|
2153
2159
|
return this.sources ?? (this.sources = [{ key: "mcassets", source: new HostedAssetSource(this.ROOT, { retryDefaults: false }) }]);
|
|
@@ -2202,11 +2208,11 @@ ${key}` : key;
|
|
|
2202
2208
|
if (override) {
|
|
2203
2209
|
const existing = this.removeSource(key);
|
|
2204
2210
|
if (existing) {
|
|
2205
|
-
|
|
2211
|
+
log8.info("Removed existing AssetSource", key);
|
|
2206
2212
|
}
|
|
2207
2213
|
}
|
|
2208
2214
|
this._SOURCES.unshift({ key, source });
|
|
2209
|
-
|
|
2215
|
+
log8.info("Added AssetSource", key);
|
|
2210
2216
|
}
|
|
2211
2217
|
/** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */
|
|
2212
2218
|
static removeSource(key) {
|
|
@@ -2321,15 +2327,21 @@ var init_ModelTextures = __esm({
|
|
|
2321
2327
|
key.extension += ".mcmeta";
|
|
2322
2328
|
}
|
|
2323
2329
|
const keyStr = key.serialize();
|
|
2324
|
-
|
|
2325
|
-
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2330
|
+
const meta = await Caching.textureMetaCache.get(keyStr, (k) => {
|
|
2331
|
+
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), async (k1) => {
|
|
2332
|
+
if (AssetLoader.persistentScope === "") {
|
|
2333
|
+
const path = key.getFullPath();
|
|
2334
|
+
const slash = path.lastIndexOf("/");
|
|
2335
|
+
const listKey = new AssetKey(key.namespace, `${path.slice(0, slash + 1)}_list`, "textures", void 0, "assets", ".json", key.root);
|
|
2336
|
+
const list2 = await Caching.listAssetCache.get(listKey.serialize(), () => AssetLoader.get(listKey, "list" /* LIST */)).catch(() => void 0);
|
|
2337
|
+
if (list2 && !list2.files.includes(`${path.slice(slash + 1)}${key.extension}`)) return Caching.MISSING;
|
|
2338
|
+
}
|
|
2339
|
+
const asset2 = await AssetLoader.get(key, "meta" /* META */);
|
|
2340
|
+
if (asset2) asset2.key = key;
|
|
2341
|
+
return asset2 ?? Caching.MISSING;
|
|
2331
2342
|
});
|
|
2332
2343
|
});
|
|
2344
|
+
return meta === Caching.MISSING ? void 0 : meta;
|
|
2333
2345
|
}
|
|
2334
2346
|
/** Clears persisted texture metadata. Use {@link Caching.clear} to discard in-memory textures and metadata. */
|
|
2335
2347
|
static async clearCache() {
|
|
@@ -2386,11 +2398,11 @@ var init_CanvasImage = __esm({
|
|
|
2386
2398
|
});
|
|
2387
2399
|
|
|
2388
2400
|
// src/Ticker.ts
|
|
2389
|
-
var
|
|
2401
|
+
var log9, _Ticker, Ticker;
|
|
2390
2402
|
var init_Ticker = __esm({
|
|
2391
2403
|
"src/Ticker.ts"() {
|
|
2392
2404
|
init_log();
|
|
2393
|
-
|
|
2405
|
+
log9 = logger("Ticker");
|
|
2394
2406
|
_Ticker = class _Ticker {
|
|
2395
2407
|
static schedule(fn, ms) {
|
|
2396
2408
|
const handle = setInterval(fn, ms);
|
|
@@ -2408,7 +2420,7 @@ var init_Ticker = __esm({
|
|
|
2408
2420
|
try {
|
|
2409
2421
|
t();
|
|
2410
2422
|
} catch (e) {
|
|
2411
|
-
|
|
2423
|
+
log9.warn(e);
|
|
2412
2424
|
}
|
|
2413
2425
|
});
|
|
2414
2426
|
_Ticker.oneSecondTicks++;
|
|
@@ -2653,7 +2665,7 @@ var init_cubeUv = __esm({
|
|
|
2653
2665
|
});
|
|
2654
2666
|
|
|
2655
2667
|
// src/UVMapper.ts
|
|
2656
|
-
var import_three7,
|
|
2668
|
+
var import_three7, log10, X, Y, Z, FACE_UV_AXES, UVMapper, MinecraftFaceUV;
|
|
2657
2669
|
var init_UVMapper = __esm({
|
|
2658
2670
|
"src/UVMapper.ts"() {
|
|
2659
2671
|
import_three7 = require("three");
|
|
@@ -2668,7 +2680,7 @@ var init_UVMapper = __esm({
|
|
|
2668
2680
|
init_ModelGenerator();
|
|
2669
2681
|
init_log();
|
|
2670
2682
|
init_cubeUv();
|
|
2671
|
-
|
|
2683
|
+
log10 = logger("UVMapper");
|
|
2672
2684
|
X = 0;
|
|
2673
2685
|
Y = 1;
|
|
2674
2686
|
Z = 2;
|
|
@@ -2901,7 +2913,7 @@ var init_UVMapper = __esm({
|
|
|
2901
2913
|
model.elements = originalModel.elements.map((element) => ({ ...element }));
|
|
2902
2914
|
}
|
|
2903
2915
|
const isItemModel = !("elements" in model);
|
|
2904
|
-
|
|
2916
|
+
log10.debug("Creating Atlas for", model.key);
|
|
2905
2917
|
if (model.textures) {
|
|
2906
2918
|
const promises = [];
|
|
2907
2919
|
const uniqueTextureNames = [];
|
|
@@ -2915,7 +2927,7 @@ var init_UVMapper = __esm({
|
|
|
2915
2927
|
const assetKey = AssetKey.parse("textures", textureValue, model.key);
|
|
2916
2928
|
promises.push(ModelTextures.get(assetKey).then((asset2) => {
|
|
2917
2929
|
if (!asset2) {
|
|
2918
|
-
|
|
2930
|
+
log10.warn("Missing texture", assetKey);
|
|
2919
2931
|
return;
|
|
2920
2932
|
}
|
|
2921
2933
|
textureMap[textureKey] = new WrappedImage(asset2);
|
|
@@ -2927,7 +2939,7 @@ var init_UVMapper = __esm({
|
|
|
2927
2939
|
}
|
|
2928
2940
|
await Promise.all(promises);
|
|
2929
2941
|
const textureCount = uniqueTextureNames.length;
|
|
2930
|
-
|
|
2942
|
+
log10.debug("Creating Atlas for", textureCount, "textures");
|
|
2931
2943
|
this.fillMissingTextureKeys(model.textures, textureMap);
|
|
2932
2944
|
this.fillMissingTextureKeys(model.textures, metaMap);
|
|
2933
2945
|
const sizes = {};
|
|
@@ -2958,7 +2970,7 @@ var init_UVMapper = __esm({
|
|
|
2958
2970
|
this.fillMissingTextureKeys(model.textures, sizes);
|
|
2959
2971
|
const s = Math.ceil(Math.sqrt(textureCount + 1));
|
|
2960
2972
|
const size = Math.ceil(s * maxWidth);
|
|
2961
|
-
|
|
2973
|
+
log10.debug("Atlas size:", size);
|
|
2962
2974
|
const squaredSize = size * size;
|
|
2963
2975
|
const image = new CanvasImage(size, size);
|
|
2964
2976
|
const missing = Textures.getMissing().image;
|
|
@@ -3037,7 +3049,7 @@ var init_UVMapper = __esm({
|
|
|
3037
3049
|
}
|
|
3038
3050
|
this.fillMissingTextureKeys(model.textures, positions);
|
|
3039
3051
|
if (isItemModel) {
|
|
3040
|
-
|
|
3052
|
+
log10.debug("Generating item model for", model);
|
|
3041
3053
|
model.elements = [];
|
|
3042
3054
|
for (let layerName of ModelGenerator.ITEM_LAYERS) {
|
|
3043
3055
|
const textureImage = textureMap[layerName];
|
|
@@ -3053,7 +3065,7 @@ var init_UVMapper = __esm({
|
|
|
3053
3065
|
), layerName));
|
|
3054
3066
|
}
|
|
3055
3067
|
}
|
|
3056
|
-
|
|
3068
|
+
log10.debug("Item model elements", model.elements);
|
|
3057
3069
|
}
|
|
3058
3070
|
if (!model.elements) {
|
|
3059
3071
|
}
|
|
@@ -3110,7 +3122,7 @@ var init_UVMapper = __esm({
|
|
|
3110
3122
|
hasTranslucency
|
|
3111
3123
|
);
|
|
3112
3124
|
} else {
|
|
3113
|
-
|
|
3125
|
+
log10.warn("Model does not have any textures", model);
|
|
3114
3126
|
}
|
|
3115
3127
|
return void 0;
|
|
3116
3128
|
}
|
|
@@ -3234,23 +3246,303 @@ var init_MinecraftCubeTexture = __esm({
|
|
|
3234
3246
|
}
|
|
3235
3247
|
});
|
|
3236
3248
|
|
|
3249
|
+
// src/assets/_versions/DatasetVersions.ts
|
|
3250
|
+
var parseRelease, compare2, nearestRelease;
|
|
3251
|
+
var init_DatasetVersions = __esm({
|
|
3252
|
+
"src/assets/_versions/DatasetVersions.ts"() {
|
|
3253
|
+
parseRelease = (value) => /^\d+\.\d+(?:\.\d+)?$/.test(value) ? value.split(".").map(Number) : void 0;
|
|
3254
|
+
compare2 = (left, right) => {
|
|
3255
|
+
for (let i = 0; i < 3; i++) {
|
|
3256
|
+
const difference = (left[i] ?? 0) - (right[i] ?? 0);
|
|
3257
|
+
if (difference) return difference;
|
|
3258
|
+
}
|
|
3259
|
+
return 0;
|
|
3260
|
+
};
|
|
3261
|
+
nearestRelease = (requestedVersion, published) => {
|
|
3262
|
+
const requested = parseRelease(requestedVersion);
|
|
3263
|
+
if (!requested) return void 0;
|
|
3264
|
+
const versions = published.map((name) => ({ name, number: parseRelease(name) })).filter((entry) => !!entry.number).sort((left, right) => compare2(left.number, right.number));
|
|
3265
|
+
const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
|
|
3266
|
+
const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare2(left.number, right.number))[0] ?? versions.filter((entry) => compare2(entry.number, requested) <= 0).pop() ?? versions[0];
|
|
3267
|
+
return selected?.name;
|
|
3268
|
+
};
|
|
3269
|
+
}
|
|
3270
|
+
});
|
|
3271
|
+
|
|
3272
|
+
// src/error/MineRenderError.ts
|
|
3273
|
+
var MineRenderError;
|
|
3274
|
+
var init_MineRenderError = __esm({
|
|
3275
|
+
"src/error/MineRenderError.ts"() {
|
|
3276
|
+
MineRenderError = class _MineRenderError extends Error {
|
|
3277
|
+
constructor(msg) {
|
|
3278
|
+
super(msg);
|
|
3279
|
+
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
3280
|
+
}
|
|
3281
|
+
get name() {
|
|
3282
|
+
return "MineRenderError";
|
|
3283
|
+
}
|
|
3284
|
+
};
|
|
3285
|
+
}
|
|
3286
|
+
});
|
|
3287
|
+
|
|
3288
|
+
// src/assets/Entities.ts
|
|
3289
|
+
var Entities;
|
|
3290
|
+
var init_Entities = __esm({
|
|
3291
|
+
"src/assets/Entities.ts"() {
|
|
3292
|
+
init_AssetKey();
|
|
3293
|
+
init_DatasetVersions();
|
|
3294
|
+
init_AssetLoader();
|
|
3295
|
+
init_source();
|
|
3296
|
+
init_Caching();
|
|
3297
|
+
init_AssetDefaults();
|
|
3298
|
+
init_MineRenderError();
|
|
3299
|
+
init_ModelTextures();
|
|
3300
|
+
Entities = class {
|
|
3301
|
+
/**
|
|
3302
|
+
* Resolves `root` (default: the active version). Uses the exact dataset when published or when the
|
|
3303
|
+
* version is not a release; otherwise selects the nearest published release, like {@link MineRenderData.resolve}.
|
|
3304
|
+
* Textures keep the requested root.
|
|
3305
|
+
*/
|
|
3306
|
+
static async getDatasetRoot(root) {
|
|
3307
|
+
const requestRoot = (root ?? AssetLoader.ROOT).replace(/\/+$/, "");
|
|
3308
|
+
const requestedVersion = requestRoot.slice(requestRoot.lastIndexOf("/") + 1);
|
|
3309
|
+
const base = requestRoot.slice(0, requestRoot.lastIndexOf("/"));
|
|
3310
|
+
const selected = await Caching.entityDatasetVersionCache.get(root ?? `sources:${AssetLoader.ROOT}`, async () => {
|
|
3311
|
+
const key = new AssetKey("entity-models", "version", void 0, void 0, void 0, ".json", root);
|
|
3312
|
+
key.rootType = void 0;
|
|
3313
|
+
if (!parseRelease(requestedVersion) || await AssetLoader.get(key, "json" /* JSON */) !== void 0) return requestedVersion;
|
|
3314
|
+
const indexKey = new AssetKey("entity-models", "versions", void 0, void 0, void 0, ".json", base);
|
|
3315
|
+
indexKey.rootType = void 0;
|
|
3316
|
+
const index = await AssetLoader.get(indexKey, "json" /* JSON */);
|
|
3317
|
+
if (index === void 0) return requestedVersion;
|
|
3318
|
+
if (!index || typeof index !== "object" || Array.isArray(index) || !Array.isArray(index.versions) || !index.versions.every((entry) => entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.name === "string")) {
|
|
3319
|
+
throw new MineRenderError(`Invalid entity model version index at ${base}/entity-models/versions.json`);
|
|
3320
|
+
}
|
|
3321
|
+
return nearestRelease(requestedVersion, index.versions.map((entry) => entry.name)) ?? requestedVersion;
|
|
3322
|
+
});
|
|
3323
|
+
return selected === requestedVersion ? root : `${base}/${selected}`;
|
|
3324
|
+
}
|
|
3325
|
+
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
3326
|
+
static async getEntityList() {
|
|
3327
|
+
const root = await this.getDatasetRoot();
|
|
3328
|
+
const collect = async (path) => {
|
|
3329
|
+
const prefix2 = path ? `${path}/` : "";
|
|
3330
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json", root);
|
|
3331
|
+
const list2 = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
3332
|
+
if (!list2) return [];
|
|
3333
|
+
const files = list2.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
3334
|
+
const children = await Promise.all(list2.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
3335
|
+
return [...files, ...children.flat()];
|
|
3336
|
+
};
|
|
3337
|
+
return collect("");
|
|
3338
|
+
}
|
|
3339
|
+
/** @internal */
|
|
3340
|
+
static async getModelFile(modelKey) {
|
|
3341
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3342
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", await this.getDatasetRoot(isAssetKey(modelKey) ? modelKey.root : void 0));
|
|
3343
|
+
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3344
|
+
}
|
|
3345
|
+
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
3346
|
+
static async getLayerList(modelKey) {
|
|
3347
|
+
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
3348
|
+
}
|
|
3349
|
+
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
3350
|
+
static async getPassList(modelKey) {
|
|
3351
|
+
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
3352
|
+
}
|
|
3353
|
+
/**
|
|
3354
|
+
* Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.
|
|
3355
|
+
* By default, selects `main`, unconditional passes, and passes enabled by `options.when`.
|
|
3356
|
+
*
|
|
3357
|
+
* @param modelKey - Dataset model, such as `new BasicAssetKey("minecraft", "zombie")`.
|
|
3358
|
+
* @param textureKey - Texture override for the first selected layer.
|
|
3359
|
+
* @param options - Layer selection, conditional passes, and per-layer texture overrides.
|
|
3360
|
+
* @returns The selected model, or `undefined` when its dataset file is missing.
|
|
3361
|
+
*/
|
|
3362
|
+
static async getEntity(modelKey, textureKey, options) {
|
|
3363
|
+
const model = await this.getModelFile(modelKey);
|
|
3364
|
+
if (!model) return void 0;
|
|
3365
|
+
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
3366
|
+
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
3367
|
+
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
3368
|
+
draws.push(...passes);
|
|
3369
|
+
const names = [];
|
|
3370
|
+
const selected = draws.map((pass) => {
|
|
3371
|
+
const layer = model.layers[pass.layer];
|
|
3372
|
+
if (!layer) {
|
|
3373
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
3374
|
+
}
|
|
3375
|
+
let name = pass.layer;
|
|
3376
|
+
for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
|
|
3377
|
+
names.push(name);
|
|
3378
|
+
return { name, layer, pass };
|
|
3379
|
+
});
|
|
3380
|
+
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
|
|
3381
|
+
const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
|
|
3382
|
+
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
3383
|
+
let texture;
|
|
3384
|
+
if (override) {
|
|
3385
|
+
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
3386
|
+
texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
|
|
3387
|
+
} else if (textureLocation !== void 0) {
|
|
3388
|
+
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
3389
|
+
if (isAssetKey(modelKey)) texture.root = modelKey.root;
|
|
3390
|
+
} else {
|
|
3391
|
+
texture = await this.resolveTexture(modelKey);
|
|
3392
|
+
}
|
|
3393
|
+
const render = pass.render ?? layer.render;
|
|
3394
|
+
return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
3395
|
+
})));
|
|
3396
|
+
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
3397
|
+
}
|
|
3398
|
+
/**
|
|
3399
|
+
* Native and sampled vanilla clips by name, or undefined when the model or selected version has none.
|
|
3400
|
+
*/
|
|
3401
|
+
static async getAnimations(modelKey) {
|
|
3402
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3403
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", await this.getDatasetRoot(isAssetKey(modelKey) ? modelKey.root : void 0));
|
|
3404
|
+
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3405
|
+
return file?.animations;
|
|
3406
|
+
}
|
|
3407
|
+
/** Finds a fallback texture using the model path, its directory, and vanilla variant data. */
|
|
3408
|
+
static async resolveTexture(modelKey) {
|
|
3409
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3410
|
+
const root = isAssetKey(modelKey) ? modelKey.root : void 0;
|
|
3411
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", root);
|
|
3412
|
+
const texture = await Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
3413
|
+
const name = path.split("/").pop();
|
|
3414
|
+
for (const candidate of [path, `${path}/${name}`]) {
|
|
3415
|
+
const texture3 = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png", root);
|
|
3416
|
+
if (await ModelTextures.get(texture3)) return texture3;
|
|
3417
|
+
}
|
|
3418
|
+
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json", root);
|
|
3419
|
+
const list2 = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
3420
|
+
const files = list2?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
3421
|
+
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
3422
|
+
if (!file) return Caching.MISSING;
|
|
3423
|
+
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json", root);
|
|
3424
|
+
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
3425
|
+
const assets = variant?.assets;
|
|
3426
|
+
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
3427
|
+
if (typeof textureId !== "string") return Caching.MISSING;
|
|
3428
|
+
const texture2 = AssetKey.parse("textures", textureId);
|
|
3429
|
+
texture2.root = root;
|
|
3430
|
+
return texture2;
|
|
3431
|
+
});
|
|
3432
|
+
return texture === Caching.MISSING ? void 0 : texture;
|
|
3433
|
+
}
|
|
3434
|
+
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
3435
|
+
static getBlockList() {
|
|
3436
|
+
return this.getEntityList();
|
|
3437
|
+
}
|
|
3438
|
+
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
3439
|
+
static getBlock(modelKey, textureKey, options) {
|
|
3440
|
+
return this.getEntity(modelKey, textureKey, options);
|
|
3441
|
+
}
|
|
3442
|
+
};
|
|
3443
|
+
}
|
|
3444
|
+
});
|
|
3445
|
+
|
|
3446
|
+
// src/armor/Armor.ts
|
|
3447
|
+
var Armor_exports = {};
|
|
3448
|
+
__export(Armor_exports, {
|
|
3449
|
+
Armor: () => Armor
|
|
3450
|
+
});
|
|
3451
|
+
var ARMOR_TRANSFORM, Armor;
|
|
3452
|
+
var init_Armor = __esm({
|
|
3453
|
+
"src/armor/Armor.ts"() {
|
|
3454
|
+
init_AssetKey();
|
|
3455
|
+
init_AssetLoader();
|
|
3456
|
+
init_Entities();
|
|
3457
|
+
init_AssetParsers();
|
|
3458
|
+
init_Caching();
|
|
3459
|
+
init_MineRenderError();
|
|
3460
|
+
ARMOR_TRANSFORM = [
|
|
3461
|
+
{ rotate: [0, Math.PI, 0] },
|
|
3462
|
+
{ scale: [-1, -1, 1] },
|
|
3463
|
+
{ translate: [0, -24, 0] }
|
|
3464
|
+
];
|
|
3465
|
+
Armor = class {
|
|
3466
|
+
/** Loads 1.21.4+ armor in SkinObject's frame, or returns undefined when no layer draws. */
|
|
3467
|
+
static async getEntity(armor) {
|
|
3468
|
+
const model = await Entities.getModelFile(new BasicAssetKey("minecraft", "player"));
|
|
3469
|
+
const layers = {};
|
|
3470
|
+
const slots = { chest: "chestplate", legs: "leggings", feet: "boots", head: "helmet" };
|
|
3471
|
+
for (const slot of Object.keys(slots)) {
|
|
3472
|
+
const value = armor[slot];
|
|
3473
|
+
if (value === void 0) continue;
|
|
3474
|
+
const piece = typeof value === "string" ? { asset: value } : value;
|
|
3475
|
+
const name = slots[slot], geometry = model?.layers[name];
|
|
3476
|
+
if (!geometry) throw new MineRenderError(`Missing armor geometry ${name}; armor needs Minecraft 1.21.4 or later`);
|
|
3477
|
+
const id = this.identifier(piece.asset);
|
|
3478
|
+
const key = new AssetKey(id.namespace, id.path, "equipment", void 0, "assets", ".json");
|
|
3479
|
+
const equipment = await Caching.equipmentCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3480
|
+
if (!equipment) throw new MineRenderError(`Missing equipment asset ${piece.asset}; armor takes equipment asset IDs such as minecraft:diamond and needs Minecraft 1.21.4 or later`);
|
|
3481
|
+
const layerType = slot === "legs" ? "humanoid_leggings" : "humanoid";
|
|
3482
|
+
const equipmentLayers = equipment.layers[layerType];
|
|
3483
|
+
if (!equipmentLayers?.length) continue;
|
|
3484
|
+
let count = 0;
|
|
3485
|
+
const add = (texture, settings) => {
|
|
3486
|
+
layers[++count === 1 ? name : `${name}#${count}`] = { key: texture, texture, layer: geometry, ...settings };
|
|
3487
|
+
};
|
|
3488
|
+
let glint = piece.glint;
|
|
3489
|
+
for (const layer of equipmentLayers) {
|
|
3490
|
+
let color2;
|
|
3491
|
+
if (layer.dyeable) {
|
|
3492
|
+
const undyed = layer.dyeable.color_when_undyed;
|
|
3493
|
+
color2 = piece.color || (Array.isArray(undyed) ? Math.floor(undyed[0] * 255) << 16 | Math.floor(undyed[1] * 255) << 8 | Math.floor(undyed[2] * 255) : undyed === void 0 ? void 0 : undyed & 16777215);
|
|
3494
|
+
if (color2 === void 0) continue;
|
|
3495
|
+
}
|
|
3496
|
+
const texture = this.identifier(layer.texture);
|
|
3497
|
+
add(
|
|
3498
|
+
new AssetKey(texture.namespace, `equipment/${layerType}/${texture.path}`, "textures", "entity", "assets", ".png"),
|
|
3499
|
+
{ ...color2 !== void 0 && { color: color2 }, ...glint && { glint: true } }
|
|
3500
|
+
);
|
|
3501
|
+
glint = false;
|
|
3502
|
+
}
|
|
3503
|
+
if (piece.trim) {
|
|
3504
|
+
const patternId = this.identifier(piece.trim.pattern), materialId = this.identifier(piece.trim.material);
|
|
3505
|
+
const patternKey = new AssetKey(patternId.namespace, patternId.path, "trim_pattern", void 0, "data", ".json");
|
|
3506
|
+
const materialKey = new AssetKey(materialId.namespace, materialId.path, "trim_material", void 0, "data", ".json");
|
|
3507
|
+
const pattern2 = await Caching.trimCache.get(patternKey.serialize(), () => AssetLoader.get(patternKey, "json" /* JSON */));
|
|
3508
|
+
if (!pattern2) throw new MineRenderError(`Missing trim pattern ${piece.trim.pattern}`);
|
|
3509
|
+
const material = await Caching.trimCache.get(materialKey.serialize(), () => AssetLoader.get(materialKey, "json" /* JSON */));
|
|
3510
|
+
if (!material) throw new MineRenderError(`Missing trim material ${piece.trim.material}`);
|
|
3511
|
+
const patternAsset = this.identifier(pattern2.asset_id);
|
|
3512
|
+
const suffix = material.override_armor_assets?.[id.toNamespacedString()] ?? material.asset_name;
|
|
3513
|
+
add(new AssetKey(patternAsset.namespace, `entity/${layerType}/${patternAsset.path}`, "textures", "trims", "assets", ".png"), {
|
|
3514
|
+
palette: {
|
|
3515
|
+
key: new AssetKey("minecraft", "color_palettes/trim_palette", "textures", "trims", "assets", ".png"),
|
|
3516
|
+
permutation: new AssetKey("minecraft", `color_palettes/${suffix}`, "textures", "trims", "assets", ".png")
|
|
3517
|
+
},
|
|
3518
|
+
render: pattern2.decal ? "cutout_z_offset" : "cutout"
|
|
3519
|
+
});
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
const first = Object.values(layers)[0];
|
|
3523
|
+
return first ? { ...first, id: "minecraft:player", layers, transform: ARMOR_TRANSFORM } : void 0;
|
|
3524
|
+
}
|
|
3525
|
+
static identifier(value) {
|
|
3526
|
+
if (!isResourceLocation(value) || value.split(/[:/]/).some((part) => !part || part === "." || part === "..")) {
|
|
3527
|
+
throw new MineRenderError(`Invalid armor identifier ${value}`);
|
|
3528
|
+
}
|
|
3529
|
+
const [namespace, path] = value.includes(":") ? value.split(":") : ["minecraft", value];
|
|
3530
|
+
return new BasicAssetKey(namespace, path);
|
|
3531
|
+
}
|
|
3532
|
+
};
|
|
3533
|
+
}
|
|
3534
|
+
});
|
|
3535
|
+
|
|
3237
3536
|
// src/assets/MineRenderData.ts
|
|
3238
|
-
var object2,
|
|
3537
|
+
var object2, MineRenderData;
|
|
3239
3538
|
var init_MineRenderData = __esm({
|
|
3240
3539
|
"src/assets/MineRenderData.ts"() {
|
|
3540
|
+
init_DatasetVersions();
|
|
3241
3541
|
init_AssetKey();
|
|
3242
3542
|
init_AssetLoader();
|
|
3243
3543
|
init_AssetParsers();
|
|
3244
3544
|
init_Caching();
|
|
3245
3545
|
object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3246
|
-
release = (value) => /^\d+\.\d+(?:\.\d+)?$/.test(value) ? value.split(".").map(Number) : void 0;
|
|
3247
|
-
compare2 = (left, right) => {
|
|
3248
|
-
for (let i = 0; i < 3; i++) {
|
|
3249
|
-
const difference = (left[i] ?? 0) - (right[i] ?? 0);
|
|
3250
|
-
if (difference) return difference;
|
|
3251
|
-
}
|
|
3252
|
-
return 0;
|
|
3253
|
-
};
|
|
3254
3546
|
MineRenderData = class {
|
|
3255
3547
|
/** Loads one registry. Missing files and invalid data reject the request. */
|
|
3256
3548
|
static async get(dataset, root) {
|
|
@@ -3280,9 +3572,9 @@ var init_MineRenderData = __esm({
|
|
|
3280
3572
|
const scope = AssetLoader.persistentScope;
|
|
3281
3573
|
return this.cached(`resolve:${requestRoot === void 0 ? "sources" : "explicit"}:${root}`, scope, defaultRoot, async () => {
|
|
3282
3574
|
const requestedVersion = root.slice(root.lastIndexOf("/") + 1);
|
|
3283
|
-
let manifest = await this.manifest(root, requestRoot !== void 0 &&
|
|
3575
|
+
let manifest = await this.manifest(root, requestRoot !== void 0 && parseRelease(requestedVersion) ? requestedVersion : void 0, requestRoot);
|
|
3284
3576
|
if (manifest) return { requestedVersion, version: manifest.minecraftVersion, root, manifest };
|
|
3285
|
-
const requested =
|
|
3577
|
+
const requested = parseRelease(requestedVersion);
|
|
3286
3578
|
if (!requested) {
|
|
3287
3579
|
throw new Error(`No MineRender data is published for ${requestedVersion}; automatic fallback requires a release`);
|
|
3288
3580
|
}
|
|
@@ -3294,14 +3586,12 @@ var init_MineRenderData = __esm({
|
|
|
3294
3586
|
}
|
|
3295
3587
|
return value.versions;
|
|
3296
3588
|
});
|
|
3297
|
-
const
|
|
3298
|
-
const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
|
|
3299
|
-
const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare2(left.number, right.number))[0] ?? versions.filter((entry) => compare2(entry.number, requested) <= 0).pop() ?? versions[0];
|
|
3589
|
+
const selected = nearestRelease(requestedVersion, index.map((entry) => entry.name));
|
|
3300
3590
|
if (!selected) throw new Error(`No compatible MineRender data is published for ${requestedVersion}`);
|
|
3301
|
-
const resolvedRoot = `${base}/${selected
|
|
3302
|
-
manifest = await this.manifest(resolvedRoot, selected
|
|
3303
|
-
if (!manifest) throw new Error(`Missing MineRender manifest for published version ${selected
|
|
3304
|
-
return { requestedVersion, version: selected
|
|
3591
|
+
const resolvedRoot = `${base}/${selected}`;
|
|
3592
|
+
manifest = await this.manifest(resolvedRoot, selected, resolvedRoot);
|
|
3593
|
+
if (!manifest) throw new Error(`Missing MineRender manifest for published version ${selected}`);
|
|
3594
|
+
return { requestedVersion, version: selected, root: resolvedRoot, manifest };
|
|
3305
3595
|
});
|
|
3306
3596
|
}
|
|
3307
3597
|
static async manifest(root, expectedVersion, requestRoot) {
|
|
@@ -3633,22 +3923,6 @@ var init_ItemDefaults = __esm({
|
|
|
3633
3923
|
}
|
|
3634
3924
|
});
|
|
3635
3925
|
|
|
3636
|
-
// src/error/MineRenderError.ts
|
|
3637
|
-
var MineRenderError;
|
|
3638
|
-
var init_MineRenderError = __esm({
|
|
3639
|
-
"src/error/MineRenderError.ts"() {
|
|
3640
|
-
MineRenderError = class _MineRenderError extends Error {
|
|
3641
|
-
constructor(msg) {
|
|
3642
|
-
super(msg);
|
|
3643
|
-
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
3644
|
-
}
|
|
3645
|
-
get name() {
|
|
3646
|
-
return "MineRenderError";
|
|
3647
|
-
}
|
|
3648
|
-
};
|
|
3649
|
-
}
|
|
3650
|
-
});
|
|
3651
|
-
|
|
3652
3926
|
// src/texture/Colormaps.ts
|
|
3653
3927
|
var Colormaps;
|
|
3654
3928
|
var init_Colormaps = __esm({
|
|
@@ -4422,16 +4696,17 @@ var init_Biomes = __esm({
|
|
|
4422
4696
|
});
|
|
4423
4697
|
|
|
4424
4698
|
// src/assets/BlockEntities.ts
|
|
4425
|
-
var import_three9,
|
|
4699
|
+
var import_three9, log11, BlockEntities;
|
|
4426
4700
|
var init_BlockEntities = __esm({
|
|
4427
4701
|
"src/assets/BlockEntities.ts"() {
|
|
4428
4702
|
import_three9 = require("three");
|
|
4429
4703
|
init_AssetKey();
|
|
4704
|
+
init_Entities();
|
|
4430
4705
|
init_AssetLoader();
|
|
4431
4706
|
init_source();
|
|
4432
4707
|
init_Caching();
|
|
4433
4708
|
init_log();
|
|
4434
|
-
|
|
4709
|
+
log11 = logger("BlockEntities");
|
|
4435
4710
|
BlockEntities = class {
|
|
4436
4711
|
/**
|
|
4437
4712
|
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
@@ -4443,9 +4718,10 @@ var init_BlockEntities = __esm({
|
|
|
4443
4718
|
key.rootType = void 0;
|
|
4444
4719
|
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4445
4720
|
try {
|
|
4721
|
+
key.root = await Entities.getDatasetRoot(root);
|
|
4446
4722
|
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4447
4723
|
} catch (error) {
|
|
4448
|
-
|
|
4724
|
+
log11.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
4449
4725
|
return {};
|
|
4450
4726
|
}
|
|
4451
4727
|
});
|
|
@@ -4528,136 +4804,6 @@ var init_DecoratedPots = __esm({
|
|
|
4528
4804
|
}
|
|
4529
4805
|
});
|
|
4530
4806
|
|
|
4531
|
-
// src/assets/Entities.ts
|
|
4532
|
-
var Entities;
|
|
4533
|
-
var init_Entities = __esm({
|
|
4534
|
-
"src/assets/Entities.ts"() {
|
|
4535
|
-
init_AssetKey();
|
|
4536
|
-
init_AssetLoader();
|
|
4537
|
-
init_source();
|
|
4538
|
-
init_Caching();
|
|
4539
|
-
init_AssetDefaults();
|
|
4540
|
-
init_MineRenderError();
|
|
4541
|
-
init_ModelTextures();
|
|
4542
|
-
Entities = class {
|
|
4543
|
-
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
4544
|
-
static async getEntityList() {
|
|
4545
|
-
const collect = async (path) => {
|
|
4546
|
-
const prefix2 = path ? `${path}/` : "";
|
|
4547
|
-
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
|
|
4548
|
-
const list2 = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
4549
|
-
if (!list2) return [];
|
|
4550
|
-
const files = list2.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
4551
|
-
const children = await Promise.all(list2.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
4552
|
-
return [...files, ...children.flat()];
|
|
4553
|
-
};
|
|
4554
|
-
return collect("");
|
|
4555
|
-
}
|
|
4556
|
-
static async getModelFile(modelKey) {
|
|
4557
|
-
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4558
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
4559
|
-
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4560
|
-
}
|
|
4561
|
-
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
4562
|
-
static async getLayerList(modelKey) {
|
|
4563
|
-
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
4564
|
-
}
|
|
4565
|
-
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
4566
|
-
static async getPassList(modelKey) {
|
|
4567
|
-
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
4568
|
-
}
|
|
4569
|
-
/**
|
|
4570
|
-
* Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.
|
|
4571
|
-
* By default, selects `main`, unconditional passes, and passes enabled by `options.when`.
|
|
4572
|
-
*
|
|
4573
|
-
* @param modelKey - Dataset model, such as `new BasicAssetKey("minecraft", "zombie")`.
|
|
4574
|
-
* @param textureKey - Texture override for the first selected layer.
|
|
4575
|
-
* @param options - Layer selection, conditional passes, and per-layer texture overrides.
|
|
4576
|
-
* @returns The selected model, or `undefined` when its dataset file is missing.
|
|
4577
|
-
*/
|
|
4578
|
-
static async getEntity(modelKey, textureKey, options) {
|
|
4579
|
-
const model = await this.getModelFile(modelKey);
|
|
4580
|
-
if (!model) return void 0;
|
|
4581
|
-
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
4582
|
-
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
4583
|
-
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
4584
|
-
draws.push(...passes);
|
|
4585
|
-
const names = [];
|
|
4586
|
-
const selected = draws.map((pass) => {
|
|
4587
|
-
const layer = model.layers[pass.layer];
|
|
4588
|
-
if (!layer) {
|
|
4589
|
-
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
4590
|
-
}
|
|
4591
|
-
let name = pass.layer;
|
|
4592
|
-
for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
|
|
4593
|
-
names.push(name);
|
|
4594
|
-
return { name, layer, pass };
|
|
4595
|
-
});
|
|
4596
|
-
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
|
|
4597
|
-
const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
|
|
4598
|
-
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
4599
|
-
let texture;
|
|
4600
|
-
if (override) {
|
|
4601
|
-
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
4602
|
-
texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
|
|
4603
|
-
} else if (textureLocation !== void 0) {
|
|
4604
|
-
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
4605
|
-
if (isAssetKey(modelKey)) texture.root = modelKey.root;
|
|
4606
|
-
} else {
|
|
4607
|
-
texture = await this.resolveTexture(modelKey);
|
|
4608
|
-
}
|
|
4609
|
-
const render = pass.render ?? layer.render;
|
|
4610
|
-
return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
4611
|
-
})));
|
|
4612
|
-
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4613
|
-
}
|
|
4614
|
-
/**
|
|
4615
|
-
* Native and sampled vanilla clips by name, or undefined when the model or selected version has none.
|
|
4616
|
-
*/
|
|
4617
|
-
static async getAnimations(modelKey) {
|
|
4618
|
-
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4619
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
4620
|
-
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4621
|
-
return file?.animations;
|
|
4622
|
-
}
|
|
4623
|
-
/** Finds a fallback texture using the model path, its directory, and vanilla variant data. */
|
|
4624
|
-
static async resolveTexture(modelKey) {
|
|
4625
|
-
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4626
|
-
const root = isAssetKey(modelKey) ? modelKey.root : void 0;
|
|
4627
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", root);
|
|
4628
|
-
return Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
4629
|
-
const name = path.split("/").pop();
|
|
4630
|
-
for (const candidate of [path, `${path}/${name}`]) {
|
|
4631
|
-
const texture2 = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png", root);
|
|
4632
|
-
if (await ModelTextures.get(texture2)) return texture2;
|
|
4633
|
-
}
|
|
4634
|
-
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json", root);
|
|
4635
|
-
const list2 = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
4636
|
-
const files = list2?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
4637
|
-
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
4638
|
-
if (!file) return void 0;
|
|
4639
|
-
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json", root);
|
|
4640
|
-
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
4641
|
-
const assets = variant?.assets;
|
|
4642
|
-
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
4643
|
-
if (typeof textureId !== "string") return void 0;
|
|
4644
|
-
const texture = AssetKey.parse("textures", textureId);
|
|
4645
|
-
texture.root = root;
|
|
4646
|
-
return texture;
|
|
4647
|
-
});
|
|
4648
|
-
}
|
|
4649
|
-
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
4650
|
-
static getBlockList() {
|
|
4651
|
-
return this.getEntityList();
|
|
4652
|
-
}
|
|
4653
|
-
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
4654
|
-
static getBlock(modelKey, textureKey, options) {
|
|
4655
|
-
return this.getEntity(modelKey, textureKey, options);
|
|
4656
|
-
}
|
|
4657
|
-
};
|
|
4658
|
-
}
|
|
4659
|
-
});
|
|
4660
|
-
|
|
4661
4807
|
// src/assets/_fonts/Unihex.ts
|
|
4662
4808
|
var Unihex_exports = {};
|
|
4663
4809
|
__export(Unihex_exports, {
|
|
@@ -4716,7 +4862,7 @@ async function parseUnihex(key) {
|
|
|
4716
4862
|
}
|
|
4717
4863
|
return { indices, rows, metrics };
|
|
4718
4864
|
} catch (error) {
|
|
4719
|
-
|
|
4865
|
+
log12.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4720
4866
|
return void 0;
|
|
4721
4867
|
}
|
|
4722
4868
|
}
|
|
@@ -4735,7 +4881,7 @@ async function loadUnihex(provider, fontKey, characters) {
|
|
|
4735
4881
|
return { ...override, from, to };
|
|
4736
4882
|
});
|
|
4737
4883
|
} catch (error) {
|
|
4738
|
-
|
|
4884
|
+
log12.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4739
4885
|
return glyphs;
|
|
4740
4886
|
}
|
|
4741
4887
|
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
@@ -4783,7 +4929,7 @@ async function loadUnihex(provider, fontKey, characters) {
|
|
|
4783
4929
|
}
|
|
4784
4930
|
return glyphs;
|
|
4785
4931
|
}
|
|
4786
|
-
var import_zip2,
|
|
4932
|
+
var import_zip2, log12, ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
|
|
4787
4933
|
var init_Unihex = __esm({
|
|
4788
4934
|
"src/assets/_fonts/Unihex.ts"() {
|
|
4789
4935
|
import_zip2 = require("@zip.js/zip.js");
|
|
@@ -4794,7 +4940,7 @@ var init_Unihex = __esm({
|
|
|
4794
4940
|
init_AssetParsers();
|
|
4795
4941
|
init_CanvasCompat();
|
|
4796
4942
|
init_log();
|
|
4797
|
-
|
|
4943
|
+
log12 = logger("Unihex");
|
|
4798
4944
|
ATLAS_SIZE = 512;
|
|
4799
4945
|
GLYPH_HEIGHT = 16;
|
|
4800
4946
|
UnihexAtlas = class {
|
|
@@ -5797,6 +5943,266 @@ var init_model = __esm({
|
|
|
5797
5943
|
}
|
|
5798
5944
|
});
|
|
5799
5945
|
|
|
5946
|
+
// src/model/ItemGlint.ts
|
|
5947
|
+
var ItemGlint_exports = {};
|
|
5948
|
+
__export(ItemGlint_exports, {
|
|
5949
|
+
ItemGlint: () => ItemGlint
|
|
5950
|
+
});
|
|
5951
|
+
var import_three14, ItemGlint;
|
|
5952
|
+
var init_ItemGlint = __esm({
|
|
5953
|
+
"src/model/ItemGlint.ts"() {
|
|
5954
|
+
import_three14 = require("three");
|
|
5955
|
+
init_AssetKey();
|
|
5956
|
+
init_Models();
|
|
5957
|
+
init_ModelTextures();
|
|
5958
|
+
init_Caching();
|
|
5959
|
+
init_Textures();
|
|
5960
|
+
init_Ticker();
|
|
5961
|
+
init_CubeFace();
|
|
5962
|
+
init_DisplayPosition();
|
|
5963
|
+
ItemGlint = class _ItemGlint {
|
|
5964
|
+
constructor(owner, material) {
|
|
5965
|
+
this.owner = owner;
|
|
5966
|
+
this.material = material;
|
|
5967
|
+
this.updateTime();
|
|
5968
|
+
}
|
|
5969
|
+
/** Enables glint for enchantments or a lodestone compass unless a boolean component overrides them. */
|
|
5970
|
+
static enabled(components = {}, itemId) {
|
|
5971
|
+
const override = Models.componentValue(components, "enchantment_glint_override");
|
|
5972
|
+
if (override !== void 0) {
|
|
5973
|
+
if (typeof override !== "boolean") throw new Error("Item enchantment_glint_override must be a boolean");
|
|
5974
|
+
return override;
|
|
5975
|
+
}
|
|
5976
|
+
if (itemId === "minecraft:compass") {
|
|
5977
|
+
Models.componentValue(components, "lodestone_tracker");
|
|
5978
|
+
if (Object.prototype.hasOwnProperty.call(components, "lodestone_tracker") || Object.prototype.hasOwnProperty.call(components, "minecraft:lodestone_tracker")) return true;
|
|
5979
|
+
}
|
|
5980
|
+
const enchantments = Models.componentValue(components, "enchantments");
|
|
5981
|
+
if (enchantments === void 0) return false;
|
|
5982
|
+
if (!enchantments || typeof enchantments !== "object" || Array.isArray(enchantments)) throw new Error("Item enchantments must be an object");
|
|
5983
|
+
return Object.keys(enchantments).length > 0;
|
|
5984
|
+
}
|
|
5985
|
+
/** @internal */
|
|
5986
|
+
static async create(owner, baseMap, root, entityMeshes, kind = "item") {
|
|
5987
|
+
const key = new AssetKey("minecraft", `enchanted_glint_${kind}`, "textures", "misc", "assets", ".png", root);
|
|
5988
|
+
const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;
|
|
5989
|
+
let texture = Caching.textureCache.getIfPresent(textureKey);
|
|
5990
|
+
if (!texture) {
|
|
5991
|
+
const pending = ModelTextures.get(key);
|
|
5992
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);
|
|
5993
|
+
const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);
|
|
5994
|
+
if (!image) throw new Error(`Missing ${kind} glint texture ${key.toNamespacedString()}`);
|
|
5995
|
+
if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes, kind);
|
|
5996
|
+
texture = Caching.textureCache.get(textureKey, () => {
|
|
5997
|
+
const texture2 = Textures.createCanvasTexture(image.data.canvas);
|
|
5998
|
+
texture2.wrapS = texture2.wrapT = metadata?.texture?.clamp ? import_three14.ClampToEdgeWrapping : import_three14.RepeatWrapping;
|
|
5999
|
+
if (metadata?.texture?.blur) texture2.magFilter = texture2.minFilter = import_three14.LinearFilter;
|
|
6000
|
+
return texture2;
|
|
6001
|
+
});
|
|
6002
|
+
}
|
|
6003
|
+
const material = new import_three14.ShaderMaterial({
|
|
6004
|
+
name: "item-glint",
|
|
6005
|
+
transparent: true,
|
|
6006
|
+
depthWrite: false,
|
|
6007
|
+
depthFunc: import_three14.EqualDepth,
|
|
6008
|
+
side: import_three14.DoubleSide,
|
|
6009
|
+
forceSinglePass: true,
|
|
6010
|
+
blending: import_three14.CustomBlending,
|
|
6011
|
+
blendSrc: import_three14.SrcColorFactor,
|
|
6012
|
+
blendDst: import_three14.OneFactor,
|
|
6013
|
+
blendSrcAlpha: import_three14.ZeroFactor,
|
|
6014
|
+
blendDstAlpha: import_three14.OneFactor,
|
|
6015
|
+
toneMapped: false,
|
|
6016
|
+
// TextureTransform.ARMOR_ENTITY_GLINT_TEXTURING uses a smaller UV scale than item glint.
|
|
6017
|
+
defines: entityMeshes ? { ENTITY_GLINT: true, ENTITY_GLINT_SCALE: kind === "armor" ? "0.16" : "0.5" } : {},
|
|
6018
|
+
uniforms: {
|
|
6019
|
+
...!entityMeshes && { baseMap: { value: baseMap } },
|
|
6020
|
+
glintMap: { value: texture },
|
|
6021
|
+
glintOffset: { value: new import_three14.Vector2() },
|
|
6022
|
+
glintAlpha: { value: 0.75 }
|
|
6023
|
+
},
|
|
6024
|
+
vertexShader: `
|
|
6025
|
+
uniform vec2 glintOffset;
|
|
6026
|
+
#ifndef ENTITY_GLINT
|
|
6027
|
+
attribute vec4 uvBounds;
|
|
6028
|
+
attribute vec2 glintUv;
|
|
6029
|
+
flat out vec4 vUvBounds;
|
|
6030
|
+
centroid out vec2 vUv;
|
|
6031
|
+
#endif
|
|
6032
|
+
varying vec2 vGlintUv;
|
|
6033
|
+
void main() {
|
|
6034
|
+
#ifdef ENTITY_GLINT
|
|
6035
|
+
vec2 p = vec2(uv.x, 1.0 - uv.y) * ENTITY_GLINT_SCALE;
|
|
6036
|
+
#else
|
|
6037
|
+
vUv = uv;
|
|
6038
|
+
vUvBounds = uvBounds;
|
|
6039
|
+
vec2 p = glintUv * 8.0;
|
|
6040
|
+
#endif
|
|
6041
|
+
float angle = radians(10.0);
|
|
6042
|
+
vGlintUv = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y) + glintOffset;
|
|
6043
|
+
vec4 mvPosition = vec4(position, 1.0);
|
|
6044
|
+
mvPosition = modelViewMatrix * mvPosition;
|
|
6045
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
6046
|
+
}
|
|
6047
|
+
`,
|
|
6048
|
+
fragmentShader: `
|
|
6049
|
+
#ifndef ENTITY_GLINT
|
|
6050
|
+
uniform sampler2D baseMap;
|
|
6051
|
+
flat in vec4 vUvBounds;
|
|
6052
|
+
centroid in vec2 vUv;
|
|
6053
|
+
#endif
|
|
6054
|
+
uniform sampler2D glintMap;
|
|
6055
|
+
uniform float glintAlpha;
|
|
6056
|
+
varying vec2 vGlintUv;
|
|
6057
|
+
void main() {
|
|
6058
|
+
#ifndef ENTITY_GLINT
|
|
6059
|
+
vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);
|
|
6060
|
+
if (texture2D(baseMap, mapUv).a < 0.01) discard;
|
|
6061
|
+
#endif
|
|
6062
|
+
vec4 color = texture2D(glintMap, vec2(vGlintUv.x, 1.0 - vGlintUv.y));
|
|
6063
|
+
if (color.a < 0.1) discard;
|
|
6064
|
+
gl_FragColor = color;
|
|
6065
|
+
#include <colorspace_fragment>
|
|
6066
|
+
gl_FragColor.rgb *= glintAlpha;
|
|
6067
|
+
}
|
|
6068
|
+
`
|
|
6069
|
+
});
|
|
6070
|
+
if (!entityMeshes) Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
6071
|
+
const targets = entityMeshes ? [...entityMeshes] : [];
|
|
6072
|
+
if (!entityMeshes) owner.iterateAllMeshes((mesh) => targets.push({ mesh }));
|
|
6073
|
+
for (const { mesh: base, parent = base } of targets) {
|
|
6074
|
+
const pass = new import_three14.Mesh(base.geometry, material);
|
|
6075
|
+
pass.name = `${base.name}:glint`;
|
|
6076
|
+
pass.userData.minerenderItemGlint = true;
|
|
6077
|
+
pass.raycast = () => {
|
|
6078
|
+
};
|
|
6079
|
+
pass.renderOrder = parent.renderOrder + 0.5;
|
|
6080
|
+
parent.add(pass);
|
|
6081
|
+
}
|
|
6082
|
+
return new _ItemGlint(owner, material);
|
|
6083
|
+
}
|
|
6084
|
+
/**
|
|
6085
|
+
* Maps glint before model centering and display transforms. Ordinary sprites approximate Minecraft's shared atlas density.
|
|
6086
|
+
* @internal
|
|
6087
|
+
*/
|
|
6088
|
+
static mapUvs(geometry, faces, atlas, itemId, display) {
|
|
6089
|
+
const uv = geometry.getAttribute("uv");
|
|
6090
|
+
const mapped = new Float32Array(uv.count * 2);
|
|
6091
|
+
if (itemId === "minecraft:compass" || itemId === "minecraft:recovery_compass" || itemId === "minecraft:clock") {
|
|
6092
|
+
const positions = geometry.getAttribute("position"), normals = geometry.getAttribute("normal");
|
|
6093
|
+
const scale = display === "gui" /* GUI */ ? 0.5 : display === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || display === "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */ ? 0.75 : 1;
|
|
6094
|
+
const factor = 1 / (16 * 128 * scale);
|
|
6095
|
+
for (let index = 0; index < positions.count; index++) {
|
|
6096
|
+
const x = positions.getX(index), y = positions.getY(index), z = positions.getZ(index);
|
|
6097
|
+
const nx = normals.getX(index), ny = normals.getY(index), nz = normals.getZ(index);
|
|
6098
|
+
const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);
|
|
6099
|
+
let u, v;
|
|
6100
|
+
if (ay >= az && ay >= ax) {
|
|
6101
|
+
u = x;
|
|
6102
|
+
v = ny < 0 ? -z : z;
|
|
6103
|
+
} else if (az >= ax) {
|
|
6104
|
+
u = nz < 0 ? -x : x;
|
|
6105
|
+
v = -y;
|
|
6106
|
+
} else {
|
|
6107
|
+
u = nx < 0 ? -z : z;
|
|
6108
|
+
v = -y;
|
|
6109
|
+
}
|
|
6110
|
+
mapped[index * 2] = u * factor;
|
|
6111
|
+
mapped[index * 2 + 1] = v * factor;
|
|
6112
|
+
}
|
|
6113
|
+
geometry.setAttribute("glintUv", new import_three14.Float32BufferAttribute(mapped, 2));
|
|
6114
|
+
return;
|
|
6115
|
+
}
|
|
6116
|
+
for (const [faceIndex, face] of CUBE_FACES.entries()) {
|
|
6117
|
+
const texture = faces[face]?.texture?.substring(1);
|
|
6118
|
+
const position = texture && atlas.positions[texture] || [0, 0];
|
|
6119
|
+
const size = texture && atlas.sizes[texture] || [atlas.image.width, atlas.image.height];
|
|
6120
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
6121
|
+
const index = faceIndex * 4 + corner;
|
|
6122
|
+
mapped[index * 2] = (uv.getX(index) * atlas.image.width - position[0]) / size[0] / 32;
|
|
6123
|
+
mapped[index * 2 + 1] = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] / 32;
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
geometry.setAttribute("glintUv", new import_three14.Float32BufferAttribute(mapped, 2));
|
|
6127
|
+
}
|
|
6128
|
+
updateTime() {
|
|
6129
|
+
const time = Math.trunc(Date.now() * 4);
|
|
6130
|
+
this.material.uniforms.glintOffset.value.set(-(time % 11e4) / 11e4, time % 3e4 / 3e4);
|
|
6131
|
+
}
|
|
6132
|
+
/** @internal */
|
|
6133
|
+
updateSubscription(active) {
|
|
6134
|
+
if (active && this.ticker === void 0) {
|
|
6135
|
+
this.updateTime();
|
|
6136
|
+
this.ticker = Ticker.add(() => {
|
|
6137
|
+
this.updateTime();
|
|
6138
|
+
this.owner.notifyDirty();
|
|
6139
|
+
});
|
|
6140
|
+
} else if (!active) {
|
|
6141
|
+
Ticker.remove(this.ticker);
|
|
6142
|
+
this.ticker = void 0;
|
|
6143
|
+
}
|
|
6144
|
+
}
|
|
6145
|
+
dispose() {
|
|
6146
|
+
Ticker.remove(this.ticker);
|
|
6147
|
+
this.ticker = void 0;
|
|
6148
|
+
this.material.dispose();
|
|
6149
|
+
}
|
|
6150
|
+
};
|
|
6151
|
+
}
|
|
6152
|
+
});
|
|
6153
|
+
|
|
6154
|
+
// src/texture/PalettedTextures.ts
|
|
6155
|
+
var PalettedTextures_exports = {};
|
|
6156
|
+
__export(PalettedTextures_exports, {
|
|
6157
|
+
PalettedTextures: () => PalettedTextures
|
|
6158
|
+
});
|
|
6159
|
+
var PalettedTextures;
|
|
6160
|
+
var init_PalettedTextures = __esm({
|
|
6161
|
+
"src/texture/PalettedTextures.ts"() {
|
|
6162
|
+
init_ModelTextures();
|
|
6163
|
+
init_Caching();
|
|
6164
|
+
init_CanvasImage();
|
|
6165
|
+
init_MineRenderError();
|
|
6166
|
+
PalettedTextures = class {
|
|
6167
|
+
/** Loads a texture with a palette permutation, sharing the resulting canvas between callers. */
|
|
6168
|
+
static async get(texture, key, permutation2) {
|
|
6169
|
+
return Caching.canvasImageDataCache.get(`palette:${texture.serialize()}:${key.serialize()}:${permutation2.serialize()}`, async () => {
|
|
6170
|
+
const source = await ModelTextures.get(texture);
|
|
6171
|
+
if (!source) return void 0;
|
|
6172
|
+
const [palette, replacement] = await Promise.all([ModelTextures.get(key), ModelTextures.get(permutation2)]);
|
|
6173
|
+
if (!palette) throw new MineRenderError(`Missing palette ${key.toNamespacedString()}`);
|
|
6174
|
+
if (!replacement) throw new MineRenderError(`Missing palette ${permutation2.toNamespacedString()}`);
|
|
6175
|
+
const pixels = source.data.getImageData(0, 0, source.width, source.height);
|
|
6176
|
+
const colors2 = palette.data.getImageData(0, 0, palette.width, palette.height).data;
|
|
6177
|
+
const replacements = replacement.data.getImageData(0, 0, replacement.width, replacement.height).data;
|
|
6178
|
+
const image = new CanvasImage(source.width, source.height);
|
|
6179
|
+
const output = image.context.createImageData(source.width, source.height);
|
|
6180
|
+
output.data.set(this.permute(pixels.data, colors2, replacements));
|
|
6181
|
+
image.putData(output);
|
|
6182
|
+
return { data: image.context, width: image.width, height: image.height };
|
|
6183
|
+
});
|
|
6184
|
+
}
|
|
6185
|
+
/** @internal */
|
|
6186
|
+
static permute(pixels, key, permutation2) {
|
|
6187
|
+
if (key.length !== permutation2.length) throw new MineRenderError("Palette images must have the same pixel count");
|
|
6188
|
+
const mapping = /* @__PURE__ */ new Map();
|
|
6189
|
+
for (let i = 0; i < key.length; i += 4) {
|
|
6190
|
+
if (key[i + 3] !== 0) mapping.set(key[i] << 16 | key[i + 1] << 8 | key[i + 2], i);
|
|
6191
|
+
}
|
|
6192
|
+
const output = new Uint8ClampedArray(pixels);
|
|
6193
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
6194
|
+
if (pixels[i + 3] === 0) continue;
|
|
6195
|
+
const mapped = mapping.get(pixels[i] << 16 | pixels[i + 1] << 8 | pixels[i + 2]);
|
|
6196
|
+
if (mapped === void 0) continue;
|
|
6197
|
+
output.set(permutation2.subarray(mapped, mapped + 3), i);
|
|
6198
|
+
output[i + 3] = Math.floor(pixels[i + 3] * permutation2[mapped + 3] / 255);
|
|
6199
|
+
}
|
|
6200
|
+
return output;
|
|
6201
|
+
}
|
|
6202
|
+
};
|
|
6203
|
+
}
|
|
6204
|
+
});
|
|
6205
|
+
|
|
5800
6206
|
// src/entity/scene/EntityObject.ts
|
|
5801
6207
|
var EntityObject_exports = {};
|
|
5802
6208
|
__export(EntityObject_exports, {
|
|
@@ -5806,13 +6212,13 @@ __export(EntityObject_exports, {
|
|
|
5806
6212
|
function isEntityObject(obj) {
|
|
5807
6213
|
return obj.isEntityObject;
|
|
5808
6214
|
}
|
|
5809
|
-
var
|
|
6215
|
+
var import_three15, ItemGlintClass, PalettedTexturesClass, _EntityObject, EntityObject;
|
|
5810
6216
|
var init_EntityObject = __esm({
|
|
5811
6217
|
"src/entity/scene/EntityObject.ts"() {
|
|
5812
6218
|
init_SceneObject();
|
|
5813
6219
|
init_Caching();
|
|
5814
6220
|
init_merge();
|
|
5815
|
-
|
|
6221
|
+
import_three15 = require("three");
|
|
5816
6222
|
init_Ticker();
|
|
5817
6223
|
init_model();
|
|
5818
6224
|
init_ModelTextures();
|
|
@@ -5837,8 +6243,14 @@ var init_EntityObject = __esm({
|
|
|
5837
6243
|
this.animationPlayers = [];
|
|
5838
6244
|
this.partPoses = /* @__PURE__ */ new Map();
|
|
5839
6245
|
this.options = (0, import_ts_deepmerge.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
5840
|
-
this.addEventListener("added", () =>
|
|
5841
|
-
|
|
6246
|
+
this.addEventListener("added", () => {
|
|
6247
|
+
this.updateScrollSubscription();
|
|
6248
|
+
this.glint?.updateSubscription(!!this.parent);
|
|
6249
|
+
});
|
|
6250
|
+
this.addEventListener("removed", () => {
|
|
6251
|
+
this.updateScrollSubscription();
|
|
6252
|
+
this.glint?.updateSubscription(!!this.parent);
|
|
6253
|
+
});
|
|
5842
6254
|
}
|
|
5843
6255
|
/** An optional shared material replaces texture loading for every selected draw; its owner retains disposal. */
|
|
5844
6256
|
async init(material) {
|
|
@@ -5849,12 +6261,26 @@ var init_EntityObject = __esm({
|
|
|
5849
6261
|
mesh.material = material;
|
|
5850
6262
|
});
|
|
5851
6263
|
this.notifyDirty();
|
|
5852
|
-
} else
|
|
6264
|
+
} else {
|
|
6265
|
+
await this.applyTextures();
|
|
6266
|
+
const layers = Object.entries(this.entityLayers).filter(([, layer]) => layer.glint);
|
|
6267
|
+
const meshes = [];
|
|
6268
|
+
for (const [name] of layers) this.getLayerGroup(name)?.traverse((object4) => {
|
|
6269
|
+
if (isMesh(object4)) meshes.push(object4);
|
|
6270
|
+
});
|
|
6271
|
+
if (meshes.length) {
|
|
6272
|
+
const ItemGlint2 = ItemGlintClass ?? (ItemGlintClass = (await Promise.resolve().then(() => (init_ItemGlint(), ItemGlint_exports))).ItemGlint);
|
|
6273
|
+
this.glint = await ItemGlint2.create(this, void 0, this.getTextureKey(layers[0][1]).root, meshes.map((mesh) => ({ mesh })), "armor");
|
|
6274
|
+
this.glint.updateSubscription(!!this.parent);
|
|
6275
|
+
}
|
|
6276
|
+
}
|
|
5853
6277
|
}
|
|
5854
6278
|
dispose() {
|
|
5855
6279
|
super.dispose();
|
|
5856
6280
|
}
|
|
5857
6281
|
disposeAndRemoveAllChildren() {
|
|
6282
|
+
this.glint?.dispose();
|
|
6283
|
+
this.glint = void 0;
|
|
5858
6284
|
this.clearScrollMaterials();
|
|
5859
6285
|
for (const geometry of this.geometries) geometry.dispose();
|
|
5860
6286
|
this.geometries.clear();
|
|
@@ -6013,17 +6439,21 @@ var init_EntityObject = __esm({
|
|
|
6013
6439
|
);
|
|
6014
6440
|
}
|
|
6015
6441
|
async loadTextures(layer = this.entity) {
|
|
6442
|
+
if (layer.palette) {
|
|
6443
|
+
const PalettedTextures2 = PalettedTexturesClass ?? (PalettedTexturesClass = (await Promise.resolve().then(() => (init_PalettedTextures(), PalettedTextures_exports))).PalettedTextures);
|
|
6444
|
+
return PalettedTextures2.get(this.getTextureKey(layer), layer.palette.key, layer.palette.permutation);
|
|
6445
|
+
}
|
|
6016
6446
|
return ModelTextures.get(this.getTextureKey(layer));
|
|
6017
6447
|
}
|
|
6018
6448
|
createMeshes(force = false) {
|
|
6019
6449
|
if (this.meshesCreated && !force) return;
|
|
6020
|
-
const modelRoot = new
|
|
6450
|
+
const modelRoot = new import_three15.Object3D();
|
|
6021
6451
|
let transformNode = modelRoot;
|
|
6022
6452
|
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
6023
6453
|
if (transform) {
|
|
6024
6454
|
for (const [index, op] of transform.entries()) {
|
|
6025
6455
|
if (index > 0) {
|
|
6026
|
-
const child = new
|
|
6456
|
+
const child = new import_three15.Object3D();
|
|
6027
6457
|
transformNode.add(child);
|
|
6028
6458
|
transformNode = child;
|
|
6029
6459
|
}
|
|
@@ -6085,10 +6515,10 @@ var init_EntityObject = __esm({
|
|
|
6085
6515
|
this.clearScrollMaterials();
|
|
6086
6516
|
const results = await Promise.allSettled(Object.entries(this.entityLayers).map(async ([name, layer]) => {
|
|
6087
6517
|
const mode = layer.render ?? layer.layer.render ?? "cutout";
|
|
6088
|
-
const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
|
|
6518
|
+
const tint = (layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint]) ?? layer.color;
|
|
6089
6519
|
const scroll = Materials.entityModeScroll(mode);
|
|
6090
6520
|
const assetKeyStr = this.getTextureKey(layer).serialize();
|
|
6091
|
-
const keyStr = `entity:${mode}:${tint === void 0 ? "" : new
|
|
6521
|
+
const keyStr = `entity:${mode}:${tint === void 0 ? "" : new import_three15.Color(tint).getHexString()}:${assetKeyStr}` + (layer.palette ? `:${layer.palette.key.serialize()}:${layer.palette.permutation.serialize()}` : "");
|
|
6092
6522
|
let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
|
|
6093
6523
|
if (!mat) {
|
|
6094
6524
|
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
@@ -6153,7 +6583,7 @@ function getMinMax(attribute, start, count) {
|
|
|
6153
6583
|
else if (a === 2) value = attribute.getZ(i);
|
|
6154
6584
|
else if (a === 3) value = attribute.getW(i);
|
|
6155
6585
|
if (attribute.normalized === true) {
|
|
6156
|
-
value =
|
|
6586
|
+
value = import_three19.MathUtils.normalize(value, attribute.array);
|
|
6157
6587
|
}
|
|
6158
6588
|
}
|
|
6159
6589
|
output.min[a] = Math.min(output.min[a], value);
|
|
@@ -6201,10 +6631,10 @@ function getToBlobPromise(canvas, mimeType) {
|
|
|
6201
6631
|
return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
|
|
6202
6632
|
}
|
|
6203
6633
|
}
|
|
6204
|
-
var
|
|
6634
|
+
var import_three19, KHR_mesh_quantization_ExtraAttrTypes, GLTFExporter, WEBGL_CONSTANTS, KHR_MESH_QUANTIZATION, THREE_TO_WEBGL, PATH_PROPERTIES, DEFAULT_SPECULAR_COLOR, GLB_HEADER_BYTES, GLB_HEADER_MAGIC, GLB_VERSION, GLB_CHUNK_PREFIX_BYTES, GLB_CHUNK_TYPE_JSON, GLB_CHUNK_TYPE_BIN, GLTFWriter, GLTFLightExtension, GLTFMaterialsUnlitExtension, GLTFMaterialsClearcoatExtension, GLTFMaterialsDispersionExtension, GLTFMaterialsIridescenceExtension, GLTFMaterialsTransmissionExtension, GLTFMaterialsVolumeExtension, GLTFMaterialsIorExtension, GLTFMaterialsSpecularExtension, GLTFMaterialsSheenExtension, GLTFMaterialsAnisotropyExtension, GLTFMaterialsEmissiveStrengthExtension, GLTFMaterialsBumpExtension, GLTFMeshGpuInstancing;
|
|
6205
6635
|
var init_GLTFExporter = __esm({
|
|
6206
6636
|
"../../node_modules/three/examples/jsm/exporters/GLTFExporter.js"() {
|
|
6207
|
-
|
|
6637
|
+
import_three19 = require("three");
|
|
6208
6638
|
KHR_mesh_quantization_ExtraAttrTypes = {
|
|
6209
6639
|
POSITION: [
|
|
6210
6640
|
"byte",
|
|
@@ -6383,22 +6813,22 @@ var init_GLTFExporter = __esm({
|
|
|
6383
6813
|
};
|
|
6384
6814
|
KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
|
|
6385
6815
|
THREE_TO_WEBGL = {};
|
|
6386
|
-
THREE_TO_WEBGL[
|
|
6387
|
-
THREE_TO_WEBGL[
|
|
6388
|
-
THREE_TO_WEBGL[
|
|
6389
|
-
THREE_TO_WEBGL[
|
|
6390
|
-
THREE_TO_WEBGL[
|
|
6391
|
-
THREE_TO_WEBGL[
|
|
6392
|
-
THREE_TO_WEBGL[
|
|
6393
|
-
THREE_TO_WEBGL[
|
|
6394
|
-
THREE_TO_WEBGL[
|
|
6816
|
+
THREE_TO_WEBGL[import_three19.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
|
|
6817
|
+
THREE_TO_WEBGL[import_three19.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
|
|
6818
|
+
THREE_TO_WEBGL[import_three19.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
|
|
6819
|
+
THREE_TO_WEBGL[import_three19.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
|
|
6820
|
+
THREE_TO_WEBGL[import_three19.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
|
|
6821
|
+
THREE_TO_WEBGL[import_three19.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
|
|
6822
|
+
THREE_TO_WEBGL[import_three19.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
|
|
6823
|
+
THREE_TO_WEBGL[import_three19.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
|
|
6824
|
+
THREE_TO_WEBGL[import_three19.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
|
|
6395
6825
|
PATH_PROPERTIES = {
|
|
6396
6826
|
scale: "scale",
|
|
6397
6827
|
position: "translation",
|
|
6398
6828
|
quaternion: "rotation",
|
|
6399
6829
|
morphTargetInfluences: "weights"
|
|
6400
6830
|
};
|
|
6401
|
-
DEFAULT_SPECULAR_COLOR = new
|
|
6831
|
+
DEFAULT_SPECULAR_COLOR = new import_three19.Color();
|
|
6402
6832
|
GLB_HEADER_BYTES = 12;
|
|
6403
6833
|
GLB_HEADER_MAGIC = 1179937895;
|
|
6404
6834
|
GLB_VERSION = 2;
|
|
@@ -6422,7 +6852,7 @@ var init_GLTFExporter = __esm({
|
|
|
6422
6852
|
this.json = {
|
|
6423
6853
|
asset: {
|
|
6424
6854
|
version: "2.0",
|
|
6425
|
-
generator: "THREE.GLTFExporter r" +
|
|
6855
|
+
generator: "THREE.GLTFExporter r" + import_three19.REVISION
|
|
6426
6856
|
}
|
|
6427
6857
|
};
|
|
6428
6858
|
this.cache = {
|
|
@@ -6574,7 +7004,7 @@ var init_GLTFExporter = __esm({
|
|
|
6574
7004
|
isNormalizedNormalAttribute(normal) {
|
|
6575
7005
|
const cache = this.cache;
|
|
6576
7006
|
if (cache.attributesNormalized.has(normal)) return false;
|
|
6577
|
-
const v = new
|
|
7007
|
+
const v = new import_three19.Vector3();
|
|
6578
7008
|
for (let i = 0, il = normal.count; i < il; i++) {
|
|
6579
7009
|
if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
|
|
6580
7010
|
}
|
|
@@ -6591,7 +7021,7 @@ var init_GLTFExporter = __esm({
|
|
|
6591
7021
|
const cache = this.cache;
|
|
6592
7022
|
if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
|
|
6593
7023
|
const attribute = normal.clone();
|
|
6594
|
-
const v = new
|
|
7024
|
+
const v = new import_three19.Vector3();
|
|
6595
7025
|
for (let i = 0, il = attribute.count; i < il; i++) {
|
|
6596
7026
|
v.fromBufferAttribute(attribute, i);
|
|
6597
7027
|
if (v.x === 0 && v.y === 0 && v.z === 0) {
|
|
@@ -6635,7 +7065,7 @@ var init_GLTFExporter = __esm({
|
|
|
6635
7065
|
async buildMetalRoughTextureAsync(metalnessMap, roughnessMap) {
|
|
6636
7066
|
if (metalnessMap === roughnessMap) return metalnessMap;
|
|
6637
7067
|
function getEncodingConversion(map) {
|
|
6638
|
-
if (map.colorSpace ===
|
|
7068
|
+
if (map.colorSpace === import_three19.SRGBColorSpace) {
|
|
6639
7069
|
return function SRGBToLinear(c) {
|
|
6640
7070
|
return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
|
|
6641
7071
|
};
|
|
@@ -6644,10 +7074,10 @@ var init_GLTFExporter = __esm({
|
|
|
6644
7074
|
return c;
|
|
6645
7075
|
};
|
|
6646
7076
|
}
|
|
6647
|
-
if (metalnessMap instanceof
|
|
7077
|
+
if (metalnessMap instanceof import_three19.CompressedTexture) {
|
|
6648
7078
|
metalnessMap = await this.decompressTextureAsync(metalnessMap);
|
|
6649
7079
|
}
|
|
6650
|
-
if (roughnessMap instanceof
|
|
7080
|
+
if (roughnessMap instanceof import_three19.CompressedTexture) {
|
|
6651
7081
|
roughnessMap = await this.decompressTextureAsync(roughnessMap);
|
|
6652
7082
|
}
|
|
6653
7083
|
const metalness = metalnessMap ? metalnessMap.image : null;
|
|
@@ -6682,8 +7112,8 @@ var init_GLTFExporter = __esm({
|
|
|
6682
7112
|
context.putImageData(composite, 0, 0);
|
|
6683
7113
|
const reference = metalnessMap || roughnessMap;
|
|
6684
7114
|
const texture = reference.clone();
|
|
6685
|
-
texture.source = new
|
|
6686
|
-
texture.colorSpace =
|
|
7115
|
+
texture.source = new import_three19.TextureSource(canvas);
|
|
7116
|
+
texture.colorSpace = import_three19.NoColorSpace;
|
|
6687
7117
|
texture.channel = (metalnessMap || roughnessMap).channel;
|
|
6688
7118
|
if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
|
|
6689
7119
|
console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
|
|
@@ -6704,7 +7134,7 @@ var init_GLTFExporter = __esm({
|
|
|
6704
7134
|
* @return {Promise<THREE.Texture>} The derived normal map texture.
|
|
6705
7135
|
*/
|
|
6706
7136
|
async buildNormalMapTextureAsync(normalMap, flipX, flipY) {
|
|
6707
|
-
if (normalMap instanceof
|
|
7137
|
+
if (normalMap instanceof import_three19.CompressedTexture) {
|
|
6708
7138
|
normalMap = await this.decompressTextureAsync(normalMap);
|
|
6709
7139
|
}
|
|
6710
7140
|
const image = normalMap.image;
|
|
@@ -6723,7 +7153,7 @@ var init_GLTFExporter = __esm({
|
|
|
6723
7153
|
}
|
|
6724
7154
|
context.putImageData(imageData, 0, 0);
|
|
6725
7155
|
const texture = normalMap.clone();
|
|
6726
|
-
texture.source = new
|
|
7156
|
+
texture.source = new import_three19.TextureSource(canvas);
|
|
6727
7157
|
return texture;
|
|
6728
7158
|
}
|
|
6729
7159
|
async decompressTextureAsync(texture, maxTextureSize = Infinity) {
|
|
@@ -6787,7 +7217,7 @@ var init_GLTFExporter = __esm({
|
|
|
6787
7217
|
else if (a === 2) value = attribute.getZ(i);
|
|
6788
7218
|
else if (a === 3) value = attribute.getW(i);
|
|
6789
7219
|
if (attribute.normalized === true) {
|
|
6790
|
-
value =
|
|
7220
|
+
value = import_three19.MathUtils.normalize(value, attribute.array);
|
|
6791
7221
|
}
|
|
6792
7222
|
}
|
|
6793
7223
|
if (componentType === WEBGL_CONSTANTS.FLOAT) {
|
|
@@ -6942,7 +7372,7 @@ var init_GLTFExporter = __esm({
|
|
|
6942
7372
|
ctx.scale(1, -1);
|
|
6943
7373
|
}
|
|
6944
7374
|
if (image.data !== void 0) {
|
|
6945
|
-
if (format2 !==
|
|
7375
|
+
if (format2 !== import_three19.RGBAFormat) {
|
|
6946
7376
|
console.error("GLTFExporter: Only RGBAFormat is supported.", format2);
|
|
6947
7377
|
}
|
|
6948
7378
|
if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
|
|
@@ -6970,7 +7400,7 @@ var init_GLTFExporter = __esm({
|
|
|
6970
7400
|
})
|
|
6971
7401
|
);
|
|
6972
7402
|
} else {
|
|
6973
|
-
imageDef.uri =
|
|
7403
|
+
imageDef.uri = import_three19.ImageUtils.getDataURL(canvas, mimeType);
|
|
6974
7404
|
}
|
|
6975
7405
|
const index = json.images.push(imageDef) - 1;
|
|
6976
7406
|
cachedImages[key] = index;
|
|
@@ -7007,7 +7437,7 @@ var init_GLTFExporter = __esm({
|
|
|
7007
7437
|
const json = this.json;
|
|
7008
7438
|
if (cache.textures.has(map)) return cache.textures.get(map);
|
|
7009
7439
|
if (!json.textures) json.textures = [];
|
|
7010
|
-
if (map instanceof
|
|
7440
|
+
if (map instanceof import_three19.CompressedTexture) {
|
|
7011
7441
|
map = await this.decompressTextureAsync(map, options.maxTextureSize);
|
|
7012
7442
|
}
|
|
7013
7443
|
const mimeType = map.userData.mimeType;
|
|
@@ -7140,7 +7570,7 @@ var init_GLTFExporter = __esm({
|
|
|
7140
7570
|
materialDef.alphaCutoff = material.alphaTest;
|
|
7141
7571
|
}
|
|
7142
7572
|
}
|
|
7143
|
-
if (material.side ===
|
|
7573
|
+
if (material.side === import_three19.DoubleSide) materialDef.doubleSided = true;
|
|
7144
7574
|
if (material.name !== "") materialDef.name = material.name;
|
|
7145
7575
|
this.serializeUserData(material, materialDef);
|
|
7146
7576
|
await this._invokeAllAsync(async function(ext) {
|
|
@@ -7389,7 +7819,7 @@ var init_GLTFExporter = __esm({
|
|
|
7389
7819
|
} else {
|
|
7390
7820
|
cameraDef.perspective = {
|
|
7391
7821
|
aspectRatio: camera.aspect,
|
|
7392
|
-
yfov:
|
|
7822
|
+
yfov: import_three19.MathUtils.degToRad(camera.fov),
|
|
7393
7823
|
zfar: camera.far <= 0 ? 1e-3 : camera.far,
|
|
7394
7824
|
znear: camera.near < 0 ? 0 : camera.near
|
|
7395
7825
|
};
|
|
@@ -7417,8 +7847,8 @@ var init_GLTFExporter = __esm({
|
|
|
7417
7847
|
const samplers = [];
|
|
7418
7848
|
for (let i = 0; i < tracks.length; ++i) {
|
|
7419
7849
|
const track = tracks[i];
|
|
7420
|
-
const trackBinding =
|
|
7421
|
-
let trackNode =
|
|
7850
|
+
const trackBinding = import_three19.PropertyBinding.parseTrackName(track.name);
|
|
7851
|
+
let trackNode = import_three19.PropertyBinding.findNode(root, trackBinding.nodeName);
|
|
7422
7852
|
const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
|
|
7423
7853
|
if (trackBinding.objectName === "bones") {
|
|
7424
7854
|
if (trackNode.isSkinnedMesh === true) {
|
|
@@ -7440,14 +7870,14 @@ var init_GLTFExporter = __esm({
|
|
|
7440
7870
|
if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
|
|
7441
7871
|
interpolation = "CUBICSPLINE";
|
|
7442
7872
|
outputItemSize /= 3;
|
|
7443
|
-
} else if (track.getInterpolation() ===
|
|
7873
|
+
} else if (track.getInterpolation() === import_three19.InterpolateDiscrete) {
|
|
7444
7874
|
interpolation = "STEP";
|
|
7445
7875
|
} else {
|
|
7446
7876
|
interpolation = "LINEAR";
|
|
7447
7877
|
}
|
|
7448
7878
|
samplers.push({
|
|
7449
|
-
input: this.processAccessor(new
|
|
7450
|
-
output: this.processAccessor(new
|
|
7879
|
+
input: this.processAccessor(new import_three19.BufferAttribute(track.times, inputItemSize)),
|
|
7880
|
+
output: this.processAccessor(new import_three19.BufferAttribute(track.values, outputItemSize)),
|
|
7451
7881
|
interpolation
|
|
7452
7882
|
});
|
|
7453
7883
|
channels.push({
|
|
@@ -7481,7 +7911,7 @@ var init_GLTFExporter = __esm({
|
|
|
7481
7911
|
if (rootJoint === void 0) return null;
|
|
7482
7912
|
const joints = [];
|
|
7483
7913
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
7484
|
-
const temporaryBoneInverse = new
|
|
7914
|
+
const temporaryBoneInverse = new import_three19.Matrix4();
|
|
7485
7915
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
7486
7916
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
7487
7917
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7489,7 +7919,7 @@ var init_GLTFExporter = __esm({
|
|
|
7489
7919
|
}
|
|
7490
7920
|
if (json.skins === void 0) json.skins = [];
|
|
7491
7921
|
json.skins.push({
|
|
7492
|
-
inverseBindMatrices: this.processAccessor(new
|
|
7922
|
+
inverseBindMatrices: this.processAccessor(new import_three19.BufferAttribute(inverseBindMatrices, 16)),
|
|
7493
7923
|
joints,
|
|
7494
7924
|
skeleton: nodeMap.get(rootJoint)
|
|
7495
7925
|
});
|
|
@@ -7651,7 +8081,7 @@ var init_GLTFExporter = __esm({
|
|
|
7651
8081
|
* @param {Array<THREE.Object3D>} objects List of objects to process
|
|
7652
8082
|
*/
|
|
7653
8083
|
async processObjectsAsync(objects) {
|
|
7654
|
-
const scene = new
|
|
8084
|
+
const scene = new import_three19.Scene();
|
|
7655
8085
|
scene.name = "AuxScene";
|
|
7656
8086
|
for (let i = 0; i < objects.length; i++) {
|
|
7657
8087
|
scene.children.push(objects[i]);
|
|
@@ -7669,7 +8099,7 @@ var init_GLTFExporter = __esm({
|
|
|
7669
8099
|
});
|
|
7670
8100
|
const objectsWithoutScene = [];
|
|
7671
8101
|
for (let i = 0; i < input.length; i++) {
|
|
7672
|
-
if (input[i] instanceof
|
|
8102
|
+
if (input[i] instanceof import_three19.Scene) {
|
|
7673
8103
|
await this.processSceneAsync(input[i]);
|
|
7674
8104
|
} else {
|
|
7675
8105
|
objectsWithoutScene.push(input[i]);
|
|
@@ -8067,10 +8497,10 @@ var init_GLTFExporter = __esm({
|
|
|
8067
8497
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
8068
8498
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
8069
8499
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
8070
|
-
const matrix = new
|
|
8071
|
-
const position = new
|
|
8072
|
-
const quaternion = new
|
|
8073
|
-
const scale = new
|
|
8500
|
+
const matrix = new import_three19.Matrix4();
|
|
8501
|
+
const position = new import_three19.Vector3();
|
|
8502
|
+
const quaternion = new import_three19.Quaternion();
|
|
8503
|
+
const scale = new import_three19.Vector3();
|
|
8074
8504
|
for (let i = 0; i < mesh.count; i++) {
|
|
8075
8505
|
mesh.getMatrixAt(i, matrix);
|
|
8076
8506
|
matrix.decompose(position, quaternion, scale);
|
|
@@ -8079,9 +8509,9 @@ var init_GLTFExporter = __esm({
|
|
|
8079
8509
|
scale.toArray(scaleAttr, i * 3);
|
|
8080
8510
|
}
|
|
8081
8511
|
const attributes = {
|
|
8082
|
-
TRANSLATION: writer.processAccessor(new
|
|
8083
|
-
ROTATION: writer.processAccessor(new
|
|
8084
|
-
SCALE: writer.processAccessor(new
|
|
8512
|
+
TRANSLATION: writer.processAccessor(new import_three19.BufferAttribute(translationAttr, 3)),
|
|
8513
|
+
ROTATION: writer.processAccessor(new import_three19.BufferAttribute(rotationAttr, 4)),
|
|
8514
|
+
SCALE: writer.processAccessor(new import_three19.BufferAttribute(scaleAttr, 3))
|
|
8085
8515
|
};
|
|
8086
8516
|
if (mesh.instanceColor)
|
|
8087
8517
|
attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
|
|
@@ -8146,8 +8576,8 @@ var init_GLTFExporter = __esm({
|
|
|
8146
8576
|
const sourceTracks = clip.tracks;
|
|
8147
8577
|
for (let i = 0; i < sourceTracks.length; ++i) {
|
|
8148
8578
|
let sourceTrack = sourceTracks[i];
|
|
8149
|
-
const sourceTrackBinding =
|
|
8150
|
-
const sourceTrackNode =
|
|
8579
|
+
const sourceTrackBinding = import_three19.PropertyBinding.parseTrackName(sourceTrack.name);
|
|
8580
|
+
const sourceTrackNode = import_three19.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
|
|
8151
8581
|
if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
|
|
8152
8582
|
tracks.push(sourceTrack);
|
|
8153
8583
|
continue;
|
|
@@ -8158,7 +8588,7 @@ var init_GLTFExporter = __esm({
|
|
|
8158
8588
|
}
|
|
8159
8589
|
console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
|
|
8160
8590
|
sourceTrack = sourceTrack.clone();
|
|
8161
|
-
sourceTrack.setInterpolation(
|
|
8591
|
+
sourceTrack.setInterpolation(import_three19.InterpolateLinear);
|
|
8162
8592
|
}
|
|
8163
8593
|
const targetCount = sourceTrackNode.morphTargetInfluences.length;
|
|
8164
8594
|
const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
|
|
@@ -8192,7 +8622,7 @@ var init_GLTFExporter = __esm({
|
|
|
8192
8622
|
return clip;
|
|
8193
8623
|
},
|
|
8194
8624
|
toTypedBufferAttribute: function(srcAttribute, TypedArray) {
|
|
8195
|
-
const dstAttribute = new
|
|
8625
|
+
const dstAttribute = new import_three19.BufferAttribute(new TypedArray(srcAttribute.count * srcAttribute.itemSize), srcAttribute.itemSize, false);
|
|
8196
8626
|
if (!srcAttribute.normalized && !srcAttribute.isInterleavedBufferAttribute) {
|
|
8197
8627
|
dstAttribute.array.set(srcAttribute.array);
|
|
8198
8628
|
return dstAttribute;
|
|
@@ -8270,7 +8700,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8270
8700
|
batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };
|
|
8271
8701
|
batches.push(batch);
|
|
8272
8702
|
}
|
|
8273
|
-
const color2 = new
|
|
8703
|
+
const color2 = new import_three21.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8274
8704
|
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8275
8705
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8276
8706
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
@@ -8312,12 +8742,12 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8312
8742
|
}
|
|
8313
8743
|
}
|
|
8314
8744
|
}
|
|
8315
|
-
return batches.map(({ image, positions, uvs, colors: colors2, indices }) => ({ image, geometry: new
|
|
8745
|
+
return batches.map(({ image, positions, uvs, colors: colors2, indices }) => ({ image, geometry: new import_three21.BufferGeometry().setAttribute("position", new import_three21.Float32BufferAttribute(positions, 3)).setAttribute("uv", new import_three21.Float32BufferAttribute(uvs, 2)).setAttribute("color", new import_three21.Float32BufferAttribute(colors2, 3)).setIndex(indices) }));
|
|
8316
8746
|
}
|
|
8317
|
-
var
|
|
8747
|
+
var import_three21;
|
|
8318
8748
|
var init_GuiText = __esm({
|
|
8319
8749
|
"src/gui/GuiText.ts"() {
|
|
8320
|
-
|
|
8750
|
+
import_three21 = require("three");
|
|
8321
8751
|
init_Fonts();
|
|
8322
8752
|
}
|
|
8323
8753
|
});
|
|
@@ -8326,7 +8756,7 @@ var init_GuiText = __esm({
|
|
|
8326
8756
|
function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop, scaling) {
|
|
8327
8757
|
if (crop || !scaling || scaling.type === "stretch") {
|
|
8328
8758
|
const [x, y, w, h] = crop ?? [0, 0, imageWidth, imageHeight];
|
|
8329
|
-
const geometry = new
|
|
8759
|
+
const geometry = new import_three22.PlaneGeometry(width, height);
|
|
8330
8760
|
const uv = geometry.getAttribute("uv");
|
|
8331
8761
|
for (let i = 0; i < uv.count; i++) {
|
|
8332
8762
|
uv.setXY(
|
|
@@ -8397,12 +8827,12 @@ function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop,
|
|
|
8397
8827
|
}
|
|
8398
8828
|
}
|
|
8399
8829
|
}
|
|
8400
|
-
return new
|
|
8830
|
+
return new import_three22.BufferGeometry().setAttribute("position", new import_three22.Float32BufferAttribute(positions, 3)).setAttribute("normal", new import_three22.Float32BufferAttribute(normals, 3)).setAttribute("uv", new import_three22.Float32BufferAttribute(uvs, 2)).setIndex(indices);
|
|
8401
8831
|
}
|
|
8402
|
-
var
|
|
8832
|
+
var import_three22;
|
|
8403
8833
|
var init_GuiTextureGeometry = __esm({
|
|
8404
8834
|
"src/gui/GuiTextureGeometry.ts"() {
|
|
8405
|
-
|
|
8835
|
+
import_three22 = require("three");
|
|
8406
8836
|
}
|
|
8407
8837
|
});
|
|
8408
8838
|
|
|
@@ -8418,7 +8848,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
|
|
|
8418
8848
|
const attributes = {};
|
|
8419
8849
|
const morphAttributes = {};
|
|
8420
8850
|
const morphTargetsRelative = geometries[0].morphTargetsRelative;
|
|
8421
|
-
const mergedGeometry = new
|
|
8851
|
+
const mergedGeometry = new import_three23.BufferGeometry();
|
|
8422
8852
|
let offset = 0;
|
|
8423
8853
|
for (let i = 0; i < geometries.length; ++i) {
|
|
8424
8854
|
const geometry = geometries[i];
|
|
@@ -8542,7 +8972,7 @@ function mergeBufferAttributes(attributes) {
|
|
|
8542
8972
|
array.set(attributes[i].array, offset);
|
|
8543
8973
|
offset += attributes[i].array.length;
|
|
8544
8974
|
}
|
|
8545
|
-
return new
|
|
8975
|
+
return new import_three23.BufferAttribute(array, itemSize, normalized);
|
|
8546
8976
|
}
|
|
8547
8977
|
function interleaveAttributes(attributes) {
|
|
8548
8978
|
let TypedArray;
|
|
@@ -8558,7 +8988,7 @@ function interleaveAttributes(attributes) {
|
|
|
8558
8988
|
arrayLength += attribute.array.length;
|
|
8559
8989
|
stride += attribute.itemSize;
|
|
8560
8990
|
}
|
|
8561
|
-
const interleavedBuffer = new
|
|
8991
|
+
const interleavedBuffer = new import_three23.InterleavedBuffer(new TypedArray(arrayLength), stride);
|
|
8562
8992
|
let offset = 0;
|
|
8563
8993
|
const res = [];
|
|
8564
8994
|
const getters = ["getX", "getY", "getZ", "getW"];
|
|
@@ -8567,7 +8997,7 @@ function interleaveAttributes(attributes) {
|
|
|
8567
8997
|
const attribute = attributes[j];
|
|
8568
8998
|
const itemSize = attribute.itemSize;
|
|
8569
8999
|
const count = attribute.count;
|
|
8570
|
-
const iba = new
|
|
9000
|
+
const iba = new import_three23.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
|
|
8571
9001
|
res.push(iba);
|
|
8572
9002
|
offset += itemSize;
|
|
8573
9003
|
for (let c = 0; c < count; c++) {
|
|
@@ -8651,13 +9081,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
8651
9081
|
const name = attributeNames[i];
|
|
8652
9082
|
const oldAttribute = geometry.getAttribute(name);
|
|
8653
9083
|
const buffer = new oldAttribute.array.constructor(attrArrays[name]);
|
|
8654
|
-
const attribute = new
|
|
9084
|
+
const attribute = new import_three23.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
|
|
8655
9085
|
result.setAttribute(name, attribute);
|
|
8656
9086
|
if (name in morphAttrsArrays) {
|
|
8657
9087
|
for (let j = 0; j < morphAttrsArrays[name].length; j++) {
|
|
8658
9088
|
const oldMorphAttribute = geometry.morphAttributes[name][j];
|
|
8659
9089
|
const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
|
|
8660
|
-
const morphAttribute = new
|
|
9090
|
+
const morphAttribute = new import_three23.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
|
|
8661
9091
|
result.morphAttributes[name][j] = morphAttribute;
|
|
8662
9092
|
}
|
|
8663
9093
|
}
|
|
@@ -8666,11 +9096,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
8666
9096
|
return result;
|
|
8667
9097
|
}
|
|
8668
9098
|
function toTrianglesDrawMode(geometry, drawMode) {
|
|
8669
|
-
if (drawMode ===
|
|
9099
|
+
if (drawMode === import_three23.TrianglesDrawMode) {
|
|
8670
9100
|
console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
|
|
8671
9101
|
return geometry;
|
|
8672
9102
|
}
|
|
8673
|
-
if (drawMode ===
|
|
9103
|
+
if (drawMode === import_three23.TriangleFanDrawMode || drawMode === import_three23.TriangleStripDrawMode) {
|
|
8674
9104
|
let index = geometry.getIndex();
|
|
8675
9105
|
if (index === null) {
|
|
8676
9106
|
const indices = [];
|
|
@@ -8688,7 +9118,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
|
|
|
8688
9118
|
}
|
|
8689
9119
|
const numberOfTriangles = index.count - 2;
|
|
8690
9120
|
const newIndices = [];
|
|
8691
|
-
if (drawMode ===
|
|
9121
|
+
if (drawMode === import_three23.TriangleFanDrawMode) {
|
|
8692
9122
|
for (let i = 1; i <= numberOfTriangles; i++) {
|
|
8693
9123
|
newIndices.push(index.getX(0));
|
|
8694
9124
|
newIndices.push(index.getX(i));
|
|
@@ -8724,15 +9154,15 @@ function computeMorphedAttributes(object4) {
|
|
|
8724
9154
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
8725
9155
|
return null;
|
|
8726
9156
|
}
|
|
8727
|
-
const _vA = new
|
|
8728
|
-
const _vB = new
|
|
8729
|
-
const _vC = new
|
|
8730
|
-
const _tempA = new
|
|
8731
|
-
const _tempB = new
|
|
8732
|
-
const _tempC = new
|
|
8733
|
-
const _morphA = new
|
|
8734
|
-
const _morphB = new
|
|
8735
|
-
const _morphC = new
|
|
9157
|
+
const _vA = new import_three23.Vector3();
|
|
9158
|
+
const _vB = new import_three23.Vector3();
|
|
9159
|
+
const _vC = new import_three23.Vector3();
|
|
9160
|
+
const _tempA = new import_three23.Vector3();
|
|
9161
|
+
const _tempB = new import_three23.Vector3();
|
|
9162
|
+
const _tempC = new import_three23.Vector3();
|
|
9163
|
+
const _morphA = new import_three23.Vector3();
|
|
9164
|
+
const _morphB = new import_three23.Vector3();
|
|
9165
|
+
const _morphC = new import_three23.Vector3();
|
|
8736
9166
|
function _calculateMorphedAttributeData(object5, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
8737
9167
|
_vA.fromBufferAttribute(attribute, a2);
|
|
8738
9168
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -8927,8 +9357,8 @@ function computeMorphedAttributes(object4) {
|
|
|
8927
9357
|
}
|
|
8928
9358
|
}
|
|
8929
9359
|
}
|
|
8930
|
-
const morphedPositionAttribute = new
|
|
8931
|
-
const morphedNormalAttribute = new
|
|
9360
|
+
const morphedPositionAttribute = new import_three23.Float32BufferAttribute(modifiedPosition, 3);
|
|
9361
|
+
const morphedNormalAttribute = new import_three23.Float32BufferAttribute(modifiedNormal, 3);
|
|
8932
9362
|
return {
|
|
8933
9363
|
positionAttribute,
|
|
8934
9364
|
normalAttribute,
|
|
@@ -8936,25 +9366,25 @@ function computeMorphedAttributes(object4) {
|
|
|
8936
9366
|
morphedNormalAttribute
|
|
8937
9367
|
};
|
|
8938
9368
|
}
|
|
8939
|
-
var
|
|
9369
|
+
var import_three23;
|
|
8940
9370
|
var init_BufferGeometryUtils = __esm({
|
|
8941
9371
|
"src/three/BufferGeometryUtils.js"() {
|
|
8942
|
-
|
|
9372
|
+
import_three23 = require("three");
|
|
8943
9373
|
}
|
|
8944
9374
|
});
|
|
8945
9375
|
|
|
8946
9376
|
// src/model/ModelCulling.ts
|
|
8947
|
-
var
|
|
9377
|
+
var import_three24, ModelCulling;
|
|
8948
9378
|
var init_ModelCulling = __esm({
|
|
8949
9379
|
"src/model/ModelCulling.ts"() {
|
|
8950
|
-
|
|
9380
|
+
import_three24 = require("three");
|
|
8951
9381
|
init_CubeFace();
|
|
8952
9382
|
ModelCulling = class {
|
|
8953
9383
|
/** Rotates a world-direction bit mask into model space. Bits follow {@link CUBE_FACES}. */
|
|
8954
9384
|
static toLocalMask(worldMask, rotation) {
|
|
8955
9385
|
let localMask = 0;
|
|
8956
9386
|
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
8957
|
-
const normal = new
|
|
9387
|
+
const normal = new import_three24.Vector3(...offset).applyEuler(rotation);
|
|
8958
9388
|
const worldFace = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
|
|
8959
9389
|
if (worldFace < 0) return 0;
|
|
8960
9390
|
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
@@ -8988,13 +9418,13 @@ var init_ModelCulling = __esm({
|
|
|
8988
9418
|
});
|
|
8989
9419
|
|
|
8990
9420
|
// src/skin/Skins.ts
|
|
8991
|
-
var
|
|
9421
|
+
var log13, Skins;
|
|
8992
9422
|
var init_Skins = __esm({
|
|
8993
9423
|
"src/skin/Skins.ts"() {
|
|
8994
9424
|
init_Requests();
|
|
8995
9425
|
init_Caching();
|
|
8996
9426
|
init_log();
|
|
8997
|
-
|
|
9427
|
+
log13 = logger("Skins");
|
|
8998
9428
|
Skins = class {
|
|
8999
9429
|
//<editor-fold desc="Skins">
|
|
9000
9430
|
/** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */
|
|
@@ -9066,7 +9496,7 @@ var init_Skins = __esm({
|
|
|
9066
9496
|
}
|
|
9067
9497
|
return void 0;
|
|
9068
9498
|
}).catch((err) => {
|
|
9069
|
-
|
|
9499
|
+
log13.warn(err);
|
|
9070
9500
|
return void 0;
|
|
9071
9501
|
});
|
|
9072
9502
|
}
|
|
@@ -9081,7 +9511,7 @@ var init_Skins = __esm({
|
|
|
9081
9511
|
}
|
|
9082
9512
|
return void 0;
|
|
9083
9513
|
}).catch((err) => {
|
|
9084
|
-
|
|
9514
|
+
log13.warn(err);
|
|
9085
9515
|
return void 0;
|
|
9086
9516
|
});
|
|
9087
9517
|
}
|
|
@@ -9095,7 +9525,7 @@ var init_Skins = __esm({
|
|
|
9095
9525
|
}
|
|
9096
9526
|
return void 0;
|
|
9097
9527
|
}).catch((err) => {
|
|
9098
|
-
|
|
9528
|
+
log13.warn(err);
|
|
9099
9529
|
return void 0;
|
|
9100
9530
|
});
|
|
9101
9531
|
}
|
|
@@ -9119,7 +9549,7 @@ var init_Skins = __esm({
|
|
|
9119
9549
|
}
|
|
9120
9550
|
return void 0;
|
|
9121
9551
|
}).catch((err) => {
|
|
9122
|
-
|
|
9552
|
+
log13.warn(err);
|
|
9123
9553
|
return void 0;
|
|
9124
9554
|
});
|
|
9125
9555
|
}
|
|
@@ -9217,10 +9647,10 @@ var init_SkinImage = __esm({
|
|
|
9217
9647
|
});
|
|
9218
9648
|
|
|
9219
9649
|
// src/skin/SkinTextures.ts
|
|
9220
|
-
var
|
|
9650
|
+
var import_three25, SkinTextures;
|
|
9221
9651
|
var init_SkinTextures = __esm({
|
|
9222
9652
|
"src/skin/SkinTextures.ts"() {
|
|
9223
|
-
|
|
9653
|
+
import_three25 = require("three");
|
|
9224
9654
|
init_Caching();
|
|
9225
9655
|
init_CacheKey();
|
|
9226
9656
|
init_MineRenderError();
|
|
@@ -9258,11 +9688,11 @@ var init_SkinTextures = __esm({
|
|
|
9258
9688
|
});
|
|
9259
9689
|
}
|
|
9260
9690
|
static createMaterial(pixels, width, height, transparent = true) {
|
|
9261
|
-
const texture = Textures.initTextureProps(new
|
|
9262
|
-
texture.colorSpace =
|
|
9691
|
+
const texture = Textures.initTextureProps(new import_three25.DataTexture(pixels, width, height));
|
|
9692
|
+
texture.colorSpace = import_three25.SRGBColorSpace;
|
|
9263
9693
|
texture.flipY = true;
|
|
9264
9694
|
texture.needsUpdate = true;
|
|
9265
|
-
return new
|
|
9695
|
+
return new import_three25.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three25.DoubleSide : import_three25.FrontSide, alphaTest: transparent ? 0.1 : 0 });
|
|
9266
9696
|
}
|
|
9267
9697
|
static isSlim(image, scale) {
|
|
9268
9698
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
@@ -9315,7 +9745,7 @@ var init_SkinTextures = __esm({
|
|
|
9315
9745
|
return pixels;
|
|
9316
9746
|
}
|
|
9317
9747
|
static makeBaseOpaque(pixels, width, scale) {
|
|
9318
|
-
for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64]]) {
|
|
9748
|
+
for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64], [32, 0, 38, 7]]) {
|
|
9319
9749
|
for (let y = y0 * scale; y < y1 * scale; y++) {
|
|
9320
9750
|
for (let x = x0 * scale; x < x1 * scale; x++) pixels[(y * width + x) * 4 + 3] = 255;
|
|
9321
9751
|
}
|
|
@@ -9326,6 +9756,10 @@ var init_SkinTextures = __esm({
|
|
|
9326
9756
|
});
|
|
9327
9757
|
|
|
9328
9758
|
// src/skin/PlayerHeadTextures.ts
|
|
9759
|
+
var PlayerHeadTextures_exports = {};
|
|
9760
|
+
__export(PlayerHeadTextures_exports, {
|
|
9761
|
+
PlayerHeadTextures: () => PlayerHeadTextures
|
|
9762
|
+
});
|
|
9329
9763
|
var PlayerHeadTextures;
|
|
9330
9764
|
var init_PlayerHeadTextures = __esm({
|
|
9331
9765
|
"src/skin/PlayerHeadTextures.ts"() {
|
|
@@ -9446,10 +9880,10 @@ var init_PlayerHeadTextures = __esm({
|
|
|
9446
9880
|
});
|
|
9447
9881
|
|
|
9448
9882
|
// src/model/SpecialItems.ts
|
|
9449
|
-
var
|
|
9883
|
+
var import_three26, SpecialItems;
|
|
9450
9884
|
var init_SpecialItems = __esm({
|
|
9451
9885
|
"src/model/SpecialItems.ts"() {
|
|
9452
|
-
|
|
9886
|
+
import_three26 = require("three");
|
|
9453
9887
|
init_AssetKey();
|
|
9454
9888
|
init_Entities();
|
|
9455
9889
|
init_BannerPatterns();
|
|
@@ -9487,8 +9921,8 @@ var init_SpecialItems = __esm({
|
|
|
9487
9921
|
const sideTextures = DecoratedPots.getSideTextures(components["minecraft:pot_decorations"], root);
|
|
9488
9922
|
const baseTexture = texture("decorated_pot_base", "decorated_pot");
|
|
9489
9923
|
const [base, sides] = await Promise.all([
|
|
9490
|
-
load("decorated_pot_base", baseTexture, new
|
|
9491
|
-
load("decorated_pot_sides", texture("decorated_pot_side", "decorated_pot"), new
|
|
9924
|
+
load("decorated_pot_base", baseTexture, new import_three26.Matrix4()),
|
|
9925
|
+
load("decorated_pot_sides", texture("decorated_pot_side", "decorated_pot"), new import_three26.Matrix4())
|
|
9492
9926
|
]);
|
|
9493
9927
|
const layers = {
|
|
9494
9928
|
base: { key: base.model.key, texture: baseTexture, layer: base.model.layer, render: "solid" }
|
|
@@ -9516,7 +9950,7 @@ var init_SpecialItems = __esm({
|
|
|
9516
9950
|
const part = await load(
|
|
9517
9951
|
"player_head",
|
|
9518
9952
|
skin.texture,
|
|
9519
|
-
new
|
|
9953
|
+
new import_three26.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three26.Matrix4().makeScale(-1, -1, 1)),
|
|
9520
9954
|
{ head: [0, Math.PI, 0] }
|
|
9521
9955
|
);
|
|
9522
9956
|
const main = { ...part.model, texture: skin.texture, render: "translucent" };
|
|
@@ -9533,7 +9967,7 @@ var init_SpecialItems = __esm({
|
|
|
9533
9967
|
const statue = await load(
|
|
9534
9968
|
special.pose === "standing" ? "copper_golem" : `copper_golem_${special.pose}`,
|
|
9535
9969
|
key,
|
|
9536
|
-
new
|
|
9970
|
+
new import_three26.Matrix4().makeTranslation(8, 24, 8).multiply(new import_three26.Matrix4().makeScale(-1, -1, 1))
|
|
9537
9971
|
);
|
|
9538
9972
|
const pose = statue.model.layer.root.pose;
|
|
9539
9973
|
statue.rotations.root = [pose.rotation[0], Math.PI, Math.PI];
|
|
@@ -9549,7 +9983,7 @@ var init_SpecialItems = __esm({
|
|
|
9549
9983
|
const part = await load(
|
|
9550
9984
|
trident ? "trident" : "conduit",
|
|
9551
9985
|
texture(trident ? "trident" : "conduit/base", ""),
|
|
9552
|
-
trident ? new
|
|
9986
|
+
trident ? new import_three26.Matrix4().makeScale(1, -1, -1) : new import_three26.Matrix4().makeTranslation(8, 8, 8),
|
|
9553
9987
|
{},
|
|
9554
9988
|
trident ? ["main"] : ["shell"]
|
|
9555
9989
|
);
|
|
@@ -9570,7 +10004,7 @@ var init_SpecialItems = __esm({
|
|
|
9570
10004
|
const patterns = await BannerPatterns.getLayers(components["minecraft:banner_patterns"], banner ? "banner" : "shield", root);
|
|
9571
10005
|
const patterned = banner || color2 !== void 0 || patterns.length > 0;
|
|
9572
10006
|
const baseTexture = texture(banner ? "banner_base" : patterned ? "shield_base" : "shield_base_nopattern", "");
|
|
9573
|
-
const transform = banner ? new
|
|
10007
|
+
const transform = banner ? new import_three26.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three26.Matrix4().makeScale(2 / 3, -2 / 3, -2 / 3)) : new import_three26.Matrix4().makeScale(1, -1, -1);
|
|
9574
10008
|
const part = await load(banner ? "standing_banner" : "shield", baseTexture, transform, {}, banner ? ["main", "flag"] : ["main"]);
|
|
9575
10009
|
const layers = Object.fromEntries(Object.entries(part.model.layers ?? { main: part.model }).map(([name, layer]) => [name, { ...layer, render: "solid" }]));
|
|
9576
10010
|
let overlay2;
|
|
@@ -9608,7 +10042,7 @@ var init_SpecialItems = __esm({
|
|
|
9608
10042
|
case "minecraft:chest":
|
|
9609
10043
|
case "chest": {
|
|
9610
10044
|
const angle = -(special.openness ?? 0) * Math.PI / 2;
|
|
9611
|
-
const chest = await load("chest", texture(special.texture, "chest"), new
|
|
10045
|
+
const chest = await load("chest", texture(special.texture, "chest"), new import_three26.Matrix4(), {
|
|
9612
10046
|
lid: [angle, 0, 0],
|
|
9613
10047
|
lock: [angle, 0, 0]
|
|
9614
10048
|
});
|
|
@@ -9630,18 +10064,18 @@ var init_SpecialItems = __esm({
|
|
|
9630
10064
|
if (!Object.prototype.hasOwnProperty.call(directions, orientation)) throw new Error(`Unsupported shulker-box orientation ${orientation}`);
|
|
9631
10065
|
if (typeof openness !== "number" || !Number.isFinite(openness)) throw new Error("Shulker-box openness must be finite");
|
|
9632
10066
|
if (typeof special.texture !== "string" || !special.texture) throw new Error("Shulker-box texture is required");
|
|
9633
|
-
const transform = new
|
|
10067
|
+
const transform = new import_three26.Matrix4().makeTranslation(8, 8, 8).multiply(new import_three26.Matrix4().makeScale(0.9995, 0.9995, 0.9995)).multiply(new import_three26.Matrix4().makeRotationFromEuler(new import_three26.Euler(...directions[orientation], "XYZ"))).multiply(new import_three26.Matrix4().makeScale(1, -1, -1)).multiply(new import_three26.Matrix4().makeTranslation(0, -16, 0));
|
|
9634
10068
|
const box = await load("shulker_box", texture(special.texture, "shulker"), transform, { lid: [0, openness * Math.PI * 1.5, 0] });
|
|
9635
10069
|
box.positions = { lid: [0, 24 - openness * 8, 0] };
|
|
9636
10070
|
return [box];
|
|
9637
10071
|
}
|
|
9638
10072
|
case "minecraft:bed":
|
|
9639
10073
|
case "bed": {
|
|
9640
|
-
const transform = new
|
|
10074
|
+
const transform = new import_three26.Matrix4().makeTranslation(0, 9, 0).multiply(new import_three26.Matrix4().makeRotationX(Math.PI / 2)).multiply(new import_three26.Matrix4().makeTranslation(8, 8, 8)).multiply(new import_three26.Matrix4().makeRotationZ(Math.PI)).multiply(new import_three26.Matrix4().makeTranslation(-8, -8, -8));
|
|
9641
10075
|
const key = texture(special.texture, "bed");
|
|
9642
10076
|
return Promise.all([
|
|
9643
10077
|
load("bed_head", key, transform),
|
|
9644
|
-
load("bed_foot", key, new
|
|
10078
|
+
load("bed_foot", key, new import_three26.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
|
|
9645
10079
|
]);
|
|
9646
10080
|
}
|
|
9647
10081
|
case "minecraft:head":
|
|
@@ -9652,266 +10086,63 @@ var init_SpecialItems = __esm({
|
|
|
9652
10086
|
zombie: "zombie_head",
|
|
9653
10087
|
creeper: "creeper_head",
|
|
9654
10088
|
dragon: "dragon_skull",
|
|
9655
|
-
piglin: "piglin_head"
|
|
9656
|
-
};
|
|
9657
|
-
const id = Object.prototype.hasOwnProperty.call(models, special.kind) ? models[special.kind] : void 0;
|
|
9658
|
-
if (!id) throw new Error(`Unsupported special item head kind ${special.kind}`);
|
|
9659
|
-
const animation = (special.animation ?? 0) * Math.PI * 0.2;
|
|
9660
|
-
const rotations = { head: [0, Math.PI, 0] };
|
|
9661
|
-
if (special.kind === "dragon") rotations.jaw = [(Math.sin(animation) + 1) * 0.2, 0, 0];
|
|
9662
|
-
if (special.kind === "piglin") {
|
|
9663
|
-
rotations.left_ear = [0, 0, -(Math.cos(animation * 1.2) + 2.5) * 0.2];
|
|
9664
|
-
rotations.right_ear = [0, 0, (Math.cos(animation) + 2.5) * 0.2];
|
|
9665
|
-
}
|
|
9666
|
-
return [await load(
|
|
9667
|
-
id,
|
|
9668
|
-
special.texture ? texture(special.texture, "") : void 0,
|
|
9669
|
-
new
|
|
9670
|
-
rotations
|
|
9671
|
-
)];
|
|
9672
|
-
}
|
|
9673
|
-
}
|
|
9674
|
-
}
|
|
9675
|
-
/** An owned material with model-preview shading; its entity texture remains shared. */
|
|
9676
|
-
static createMaterial(source, shade) {
|
|
9677
|
-
const material = source.clone();
|
|
9678
|
-
if (shade) {
|
|
9679
|
-
material.onBeforeCompile = (shader) => {
|
|
9680
|
-
shader.vertexShader = `varying float itemLight;
|
|
9681
|
-
${shader.vertexShader}`.replace("#include <begin_vertex>", `
|
|
9682
|
-
#include <begin_vertex>
|
|
9683
|
-
vec3 N = inverseTransformDirection(normalMatrix * normal, viewMatrix);
|
|
9684
|
-
itemLight = (1.0 + N.y) * 0.25 - N.x * N.x * 0.15 + N.z * N.z * 0.05 + 0.5;
|
|
9685
|
-
`);
|
|
9686
|
-
shader.fragmentShader = `varying float itemLight;
|
|
9687
|
-
${shader.fragmentShader}`.replace(
|
|
9688
|
-
"#include <color_fragment>",
|
|
9689
|
-
"#include <color_fragment>\ndiffuseColor.rgb *= itemLight;"
|
|
9690
|
-
);
|
|
9691
|
-
};
|
|
9692
|
-
material.customProgramCacheKey = () => "special-item-side";
|
|
9693
|
-
}
|
|
9694
|
-
return material;
|
|
9695
|
-
}
|
|
9696
|
-
};
|
|
9697
|
-
}
|
|
9698
|
-
});
|
|
9699
|
-
|
|
9700
|
-
// src/model/GuiLight.ts
|
|
9701
|
-
var GuiLight;
|
|
9702
|
-
var init_GuiLight = __esm({
|
|
9703
|
-
"src/model/GuiLight.ts"() {
|
|
9704
|
-
GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
9705
|
-
GuiLight2["FRONT"] = "front";
|
|
9706
|
-
GuiLight2["SIDE"] = "side";
|
|
9707
|
-
return GuiLight2;
|
|
9708
|
-
})(GuiLight || {});
|
|
9709
|
-
}
|
|
9710
|
-
});
|
|
9711
|
-
|
|
9712
|
-
// src/model/ItemGlint.ts
|
|
9713
|
-
var import_three26, ItemGlint;
|
|
9714
|
-
var init_ItemGlint = __esm({
|
|
9715
|
-
"src/model/ItemGlint.ts"() {
|
|
9716
|
-
import_three26 = require("three");
|
|
9717
|
-
init_AssetKey();
|
|
9718
|
-
init_Models();
|
|
9719
|
-
init_ModelTextures();
|
|
9720
|
-
init_Caching();
|
|
9721
|
-
init_Textures();
|
|
9722
|
-
init_Ticker();
|
|
9723
|
-
init_CubeFace();
|
|
9724
|
-
init_DisplayPosition();
|
|
9725
|
-
ItemGlint = class _ItemGlint {
|
|
9726
|
-
constructor(owner, material) {
|
|
9727
|
-
this.owner = owner;
|
|
9728
|
-
this.material = material;
|
|
9729
|
-
this.updateTime();
|
|
9730
|
-
}
|
|
9731
|
-
/** Enables glint for enchantments or a lodestone compass unless a boolean component overrides them. */
|
|
9732
|
-
static enabled(components = {}, itemId) {
|
|
9733
|
-
const override = Models.componentValue(components, "enchantment_glint_override");
|
|
9734
|
-
if (override !== void 0) {
|
|
9735
|
-
if (typeof override !== "boolean") throw new Error("Item enchantment_glint_override must be a boolean");
|
|
9736
|
-
return override;
|
|
9737
|
-
}
|
|
9738
|
-
if (itemId === "minecraft:compass") {
|
|
9739
|
-
Models.componentValue(components, "lodestone_tracker");
|
|
9740
|
-
if (Object.prototype.hasOwnProperty.call(components, "lodestone_tracker") || Object.prototype.hasOwnProperty.call(components, "minecraft:lodestone_tracker")) return true;
|
|
9741
|
-
}
|
|
9742
|
-
const enchantments = Models.componentValue(components, "enchantments");
|
|
9743
|
-
if (enchantments === void 0) return false;
|
|
9744
|
-
if (!enchantments || typeof enchantments !== "object" || Array.isArray(enchantments)) throw new Error("Item enchantments must be an object");
|
|
9745
|
-
return Object.keys(enchantments).length > 0;
|
|
9746
|
-
}
|
|
9747
|
-
/** @internal */
|
|
9748
|
-
static async create(owner, baseMap, root, entityMeshes) {
|
|
9749
|
-
const key = new AssetKey("minecraft", "enchanted_glint_item", "textures", "misc", "assets", ".png", root);
|
|
9750
|
-
const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;
|
|
9751
|
-
let texture = Caching.textureCache.getIfPresent(textureKey);
|
|
9752
|
-
if (!texture) {
|
|
9753
|
-
const pending = ModelTextures.get(key);
|
|
9754
|
-
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);
|
|
9755
|
-
const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);
|
|
9756
|
-
if (!image) throw new Error(`Missing item glint texture ${key.toNamespacedString()}`);
|
|
9757
|
-
if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes);
|
|
9758
|
-
texture = Caching.textureCache.get(textureKey, () => {
|
|
9759
|
-
const texture2 = Textures.createCanvasTexture(image.data.canvas);
|
|
9760
|
-
texture2.wrapS = texture2.wrapT = metadata?.texture?.clamp ? import_three26.ClampToEdgeWrapping : import_three26.RepeatWrapping;
|
|
9761
|
-
if (metadata?.texture?.blur) texture2.magFilter = texture2.minFilter = import_three26.LinearFilter;
|
|
9762
|
-
return texture2;
|
|
9763
|
-
});
|
|
9764
|
-
}
|
|
9765
|
-
const material = new import_three26.ShaderMaterial({
|
|
9766
|
-
name: "item-glint",
|
|
9767
|
-
transparent: true,
|
|
9768
|
-
depthWrite: false,
|
|
9769
|
-
depthFunc: import_three26.EqualDepth,
|
|
9770
|
-
side: import_three26.DoubleSide,
|
|
9771
|
-
forceSinglePass: true,
|
|
9772
|
-
blending: import_three26.CustomBlending,
|
|
9773
|
-
blendSrc: import_three26.SrcColorFactor,
|
|
9774
|
-
blendDst: import_three26.OneFactor,
|
|
9775
|
-
blendSrcAlpha: import_three26.ZeroFactor,
|
|
9776
|
-
blendDstAlpha: import_three26.OneFactor,
|
|
9777
|
-
toneMapped: false,
|
|
9778
|
-
defines: entityMeshes ? { ENTITY_GLINT: true } : {},
|
|
9779
|
-
uniforms: {
|
|
9780
|
-
...!entityMeshes && { baseMap: { value: baseMap } },
|
|
9781
|
-
glintMap: { value: texture },
|
|
9782
|
-
glintOffset: { value: new import_three26.Vector2() },
|
|
9783
|
-
glintAlpha: { value: 0.75 }
|
|
9784
|
-
},
|
|
9785
|
-
vertexShader: `
|
|
9786
|
-
uniform vec2 glintOffset;
|
|
9787
|
-
#ifndef ENTITY_GLINT
|
|
9788
|
-
attribute vec4 uvBounds;
|
|
9789
|
-
attribute vec2 glintUv;
|
|
9790
|
-
flat out vec4 vUvBounds;
|
|
9791
|
-
centroid out vec2 vUv;
|
|
9792
|
-
#endif
|
|
9793
|
-
varying vec2 vGlintUv;
|
|
9794
|
-
void main() {
|
|
9795
|
-
#ifdef ENTITY_GLINT
|
|
9796
|
-
vec2 p = vec2(uv.x, 1.0 - uv.y) * 0.5;
|
|
9797
|
-
#else
|
|
9798
|
-
vUv = uv;
|
|
9799
|
-
vUvBounds = uvBounds;
|
|
9800
|
-
vec2 p = glintUv * 8.0;
|
|
9801
|
-
#endif
|
|
9802
|
-
float angle = radians(10.0);
|
|
9803
|
-
vGlintUv = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y) + glintOffset;
|
|
9804
|
-
vec4 mvPosition = vec4(position, 1.0);
|
|
9805
|
-
mvPosition = modelViewMatrix * mvPosition;
|
|
9806
|
-
gl_Position = projectionMatrix * mvPosition;
|
|
9807
|
-
}
|
|
9808
|
-
`,
|
|
9809
|
-
fragmentShader: `
|
|
9810
|
-
#ifndef ENTITY_GLINT
|
|
9811
|
-
uniform sampler2D baseMap;
|
|
9812
|
-
flat in vec4 vUvBounds;
|
|
9813
|
-
centroid in vec2 vUv;
|
|
9814
|
-
#endif
|
|
9815
|
-
uniform sampler2D glintMap;
|
|
9816
|
-
uniform float glintAlpha;
|
|
9817
|
-
varying vec2 vGlintUv;
|
|
9818
|
-
void main() {
|
|
9819
|
-
#ifndef ENTITY_GLINT
|
|
9820
|
-
vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);
|
|
9821
|
-
if (texture2D(baseMap, mapUv).a < 0.01) discard;
|
|
9822
|
-
#endif
|
|
9823
|
-
vec4 color = texture2D(glintMap, vec2(vGlintUv.x, 1.0 - vGlintUv.y));
|
|
9824
|
-
if (color.a < 0.1) discard;
|
|
9825
|
-
gl_FragColor = color;
|
|
9826
|
-
#include <colorspace_fragment>
|
|
9827
|
-
gl_FragColor.rgb *= glintAlpha;
|
|
9828
|
-
}
|
|
9829
|
-
`
|
|
9830
|
-
});
|
|
9831
|
-
if (!entityMeshes) Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
9832
|
-
const targets = entityMeshes ? [...entityMeshes] : [];
|
|
9833
|
-
if (!entityMeshes) owner.iterateAllMeshes((mesh) => targets.push({ mesh }));
|
|
9834
|
-
for (const { mesh: base, parent = base } of targets) {
|
|
9835
|
-
const pass = new import_three26.Mesh(base.geometry, material);
|
|
9836
|
-
pass.name = `${base.name}:glint`;
|
|
9837
|
-
pass.userData.minerenderItemGlint = true;
|
|
9838
|
-
pass.raycast = () => {
|
|
9839
|
-
};
|
|
9840
|
-
pass.renderOrder = parent.renderOrder + 0.5;
|
|
9841
|
-
parent.add(pass);
|
|
9842
|
-
}
|
|
9843
|
-
return new _ItemGlint(owner, material);
|
|
9844
|
-
}
|
|
9845
|
-
/**
|
|
9846
|
-
* Maps glint before model centering and display transforms. Ordinary sprites approximate Minecraft's shared atlas density.
|
|
9847
|
-
* @internal
|
|
9848
|
-
*/
|
|
9849
|
-
static mapUvs(geometry, faces, atlas, itemId, display) {
|
|
9850
|
-
const uv = geometry.getAttribute("uv");
|
|
9851
|
-
const mapped = new Float32Array(uv.count * 2);
|
|
9852
|
-
if (itemId === "minecraft:compass" || itemId === "minecraft:recovery_compass" || itemId === "minecraft:clock") {
|
|
9853
|
-
const positions = geometry.getAttribute("position"), normals = geometry.getAttribute("normal");
|
|
9854
|
-
const scale = display === "gui" /* GUI */ ? 0.5 : display === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || display === "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */ ? 0.75 : 1;
|
|
9855
|
-
const factor = 1 / (16 * 128 * scale);
|
|
9856
|
-
for (let index = 0; index < positions.count; index++) {
|
|
9857
|
-
const x = positions.getX(index), y = positions.getY(index), z = positions.getZ(index);
|
|
9858
|
-
const nx = normals.getX(index), ny = normals.getY(index), nz = normals.getZ(index);
|
|
9859
|
-
const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);
|
|
9860
|
-
let u, v;
|
|
9861
|
-
if (ay >= az && ay >= ax) {
|
|
9862
|
-
u = x;
|
|
9863
|
-
v = ny < 0 ? -z : z;
|
|
9864
|
-
} else if (az >= ax) {
|
|
9865
|
-
u = nz < 0 ? -x : x;
|
|
9866
|
-
v = -y;
|
|
9867
|
-
} else {
|
|
9868
|
-
u = nx < 0 ? -z : z;
|
|
9869
|
-
v = -y;
|
|
9870
|
-
}
|
|
9871
|
-
mapped[index * 2] = u * factor;
|
|
9872
|
-
mapped[index * 2 + 1] = v * factor;
|
|
9873
|
-
}
|
|
9874
|
-
geometry.setAttribute("glintUv", new import_three26.Float32BufferAttribute(mapped, 2));
|
|
9875
|
-
return;
|
|
9876
|
-
}
|
|
9877
|
-
for (const [faceIndex, face] of CUBE_FACES.entries()) {
|
|
9878
|
-
const texture = faces[face]?.texture?.substring(1);
|
|
9879
|
-
const position = texture && atlas.positions[texture] || [0, 0];
|
|
9880
|
-
const size = texture && atlas.sizes[texture] || [atlas.image.width, atlas.image.height];
|
|
9881
|
-
for (let corner = 0; corner < 4; corner++) {
|
|
9882
|
-
const index = faceIndex * 4 + corner;
|
|
9883
|
-
mapped[index * 2] = (uv.getX(index) * atlas.image.width - position[0]) / size[0] / 32;
|
|
9884
|
-
mapped[index * 2 + 1] = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] / 32;
|
|
10089
|
+
piglin: "piglin_head"
|
|
10090
|
+
};
|
|
10091
|
+
const id = Object.prototype.hasOwnProperty.call(models, special.kind) ? models[special.kind] : void 0;
|
|
10092
|
+
if (!id) throw new Error(`Unsupported special item head kind ${special.kind}`);
|
|
10093
|
+
const animation = (special.animation ?? 0) * Math.PI * 0.2;
|
|
10094
|
+
const rotations = { head: [0, Math.PI, 0] };
|
|
10095
|
+
if (special.kind === "dragon") rotations.jaw = [(Math.sin(animation) + 1) * 0.2, 0, 0];
|
|
10096
|
+
if (special.kind === "piglin") {
|
|
10097
|
+
rotations.left_ear = [0, 0, -(Math.cos(animation * 1.2) + 2.5) * 0.2];
|
|
10098
|
+
rotations.right_ear = [0, 0, (Math.cos(animation) + 2.5) * 0.2];
|
|
10099
|
+
}
|
|
10100
|
+
return [await load(
|
|
10101
|
+
id,
|
|
10102
|
+
special.texture ? texture(special.texture, "") : void 0,
|
|
10103
|
+
new import_three26.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three26.Matrix4().makeScale(-1, -1, 1)),
|
|
10104
|
+
rotations
|
|
10105
|
+
)];
|
|
9885
10106
|
}
|
|
9886
10107
|
}
|
|
9887
|
-
geometry.setAttribute("glintUv", new import_three26.Float32BufferAttribute(mapped, 2));
|
|
9888
10108
|
}
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
9898
|
-
|
|
9899
|
-
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
10109
|
+
/** An owned material with model-preview shading; its entity texture remains shared. */
|
|
10110
|
+
static createMaterial(source, shade) {
|
|
10111
|
+
const material = source.clone();
|
|
10112
|
+
if (shade) {
|
|
10113
|
+
material.onBeforeCompile = (shader) => {
|
|
10114
|
+
shader.vertexShader = `varying float itemLight;
|
|
10115
|
+
${shader.vertexShader}`.replace("#include <begin_vertex>", `
|
|
10116
|
+
#include <begin_vertex>
|
|
10117
|
+
vec3 N = inverseTransformDirection(normalMatrix * normal, viewMatrix);
|
|
10118
|
+
itemLight = (1.0 + N.y) * 0.25 - N.x * N.x * 0.15 + N.z * N.z * 0.05 + 0.5;
|
|
10119
|
+
`);
|
|
10120
|
+
shader.fragmentShader = `varying float itemLight;
|
|
10121
|
+
${shader.fragmentShader}`.replace(
|
|
10122
|
+
"#include <color_fragment>",
|
|
10123
|
+
"#include <color_fragment>\ndiffuseColor.rgb *= itemLight;"
|
|
10124
|
+
);
|
|
10125
|
+
};
|
|
10126
|
+
material.customProgramCacheKey = () => "special-item-side";
|
|
9904
10127
|
}
|
|
9905
|
-
|
|
9906
|
-
dispose() {
|
|
9907
|
-
Ticker.remove(this.ticker);
|
|
9908
|
-
this.ticker = void 0;
|
|
9909
|
-
this.material.dispose();
|
|
10128
|
+
return material;
|
|
9910
10129
|
}
|
|
9911
10130
|
};
|
|
9912
10131
|
}
|
|
9913
10132
|
});
|
|
9914
10133
|
|
|
10134
|
+
// src/model/GuiLight.ts
|
|
10135
|
+
var GuiLight;
|
|
10136
|
+
var init_GuiLight = __esm({
|
|
10137
|
+
"src/model/GuiLight.ts"() {
|
|
10138
|
+
GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
10139
|
+
GuiLight2["FRONT"] = "front";
|
|
10140
|
+
GuiLight2["SIDE"] = "side";
|
|
10141
|
+
return GuiLight2;
|
|
10142
|
+
})(GuiLight || {});
|
|
10143
|
+
}
|
|
10144
|
+
});
|
|
10145
|
+
|
|
9915
10146
|
// src/model/scene/ModelObject.ts
|
|
9916
10147
|
var ModelObject_exports = {};
|
|
9917
10148
|
__export(ModelObject_exports, {
|
|
@@ -9921,7 +10152,7 @@ __export(ModelObject_exports, {
|
|
|
9921
10152
|
function isModelObject(obj) {
|
|
9922
10153
|
return obj.isModelObject;
|
|
9923
10154
|
}
|
|
9924
|
-
var import_three27,
|
|
10155
|
+
var import_three27, log14, _ModelObject, ModelObject;
|
|
9925
10156
|
var init_ModelObject = __esm({
|
|
9926
10157
|
"src/model/scene/ModelObject.ts"() {
|
|
9927
10158
|
init_SceneObject();
|
|
@@ -9941,7 +10172,7 @@ var init_ModelObject = __esm({
|
|
|
9941
10172
|
init_GuiLight();
|
|
9942
10173
|
init_ItemTints();
|
|
9943
10174
|
init_ItemGlint();
|
|
9944
|
-
|
|
10175
|
+
log14 = logger("ModelObject");
|
|
9945
10176
|
_ModelObject = class _ModelObject extends SceneObject {
|
|
9946
10177
|
constructor(originalModel, options) {
|
|
9947
10178
|
super(options);
|
|
@@ -10123,10 +10354,10 @@ var init_ModelObject = __esm({
|
|
|
10123
10354
|
}
|
|
10124
10355
|
});
|
|
10125
10356
|
} else {
|
|
10126
|
-
|
|
10357
|
+
log14.debug(this.atlas.model, "has no elements");
|
|
10127
10358
|
}
|
|
10128
10359
|
} else {
|
|
10129
|
-
|
|
10360
|
+
log14.debug("Missing atlas for", this);
|
|
10130
10361
|
}
|
|
10131
10362
|
if (this.options.mergeMeshes) {
|
|
10132
10363
|
let combinedGeo;
|
|
@@ -10939,7 +11170,7 @@ __export(BlockObject_exports, {
|
|
|
10939
11170
|
function isBlockObject(obj) {
|
|
10940
11171
|
return obj.isBlockObject;
|
|
10941
11172
|
}
|
|
10942
|
-
var import_three34,
|
|
11173
|
+
var import_three34, log17, _BlockObject, BlockObject;
|
|
10943
11174
|
var init_BlockObject = __esm({
|
|
10944
11175
|
"src/model/block/scene/BlockObject.ts"() {
|
|
10945
11176
|
init_SceneObject();
|
|
@@ -10959,7 +11190,7 @@ var init_BlockObject = __esm({
|
|
|
10959
11190
|
init_Entities();
|
|
10960
11191
|
init_Biomes();
|
|
10961
11192
|
init_log();
|
|
10962
|
-
|
|
11193
|
+
log17 = logger("BlockObject");
|
|
10963
11194
|
_BlockObject = class _BlockObject extends SceneObject {
|
|
10964
11195
|
constructor(blockState3, options) {
|
|
10965
11196
|
super(options);
|
|
@@ -11051,20 +11282,28 @@ var init_BlockObject = __esm({
|
|
|
11051
11282
|
if (!key || this.options.displayPosition) return false;
|
|
11052
11283
|
const generation = this._entityGeneration;
|
|
11053
11284
|
const created = [];
|
|
11285
|
+
const placement = new import_three34.Matrix4();
|
|
11054
11286
|
let resolved;
|
|
11055
11287
|
try {
|
|
11056
11288
|
resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
|
|
11057
11289
|
if (!resolved) return false;
|
|
11290
|
+
BlockEntities.matrix(resolved, placement);
|
|
11058
11291
|
for (const part of resolved.parts) {
|
|
11059
11292
|
const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
|
|
11060
|
-
|
|
11293
|
+
let texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
11294
|
+
if (part.textureLocation === void 0 && namespace === "minecraft" && path === "player_head") {
|
|
11295
|
+
const { PlayerHeadTextures: PlayerHeadTextures2 } = await Promise.resolve().then(() => (init_PlayerHeadTextures(), PlayerHeadTextures_exports));
|
|
11296
|
+
texture = (await PlayerHeadTextures2.get(void 0, key.root)).texture;
|
|
11297
|
+
}
|
|
11061
11298
|
if (texture) texture.root = key.root;
|
|
11062
11299
|
const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
|
|
11063
11300
|
if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
|
|
11064
|
-
|
|
11301
|
+
const object4 = await this.scene.addEntity(entity, { wireframe: this.options.wireframe });
|
|
11302
|
+
this.placeEntity(object4, placement);
|
|
11303
|
+
created.push(object4);
|
|
11065
11304
|
}
|
|
11066
11305
|
} catch (error) {
|
|
11067
|
-
|
|
11306
|
+
log17.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
11068
11307
|
this.removeEntities(created);
|
|
11069
11308
|
return false;
|
|
11070
11309
|
}
|
|
@@ -11072,18 +11311,21 @@ var init_BlockObject = __esm({
|
|
|
11072
11311
|
this.removeEntities(created);
|
|
11073
11312
|
return true;
|
|
11074
11313
|
}
|
|
11075
|
-
|
|
11314
|
+
this._entityPlacement.copy(placement);
|
|
11076
11315
|
this._entities = created;
|
|
11077
11316
|
this.placeEntities();
|
|
11078
11317
|
this.setVisible(this.visible);
|
|
11079
11318
|
return true;
|
|
11080
11319
|
}
|
|
11081
11320
|
placeEntities() {
|
|
11082
|
-
const matrix = new import_three34.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
|
|
11083
11321
|
for (const entity of this._entities) {
|
|
11084
|
-
|
|
11322
|
+
this.placeEntity(entity, this._entityPlacement);
|
|
11085
11323
|
}
|
|
11086
11324
|
}
|
|
11325
|
+
placeEntity(entity, placement) {
|
|
11326
|
+
const matrix = new import_three34.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(placement);
|
|
11327
|
+
matrix.decompose(entity.position, entity.quaternion, entity.scale);
|
|
11328
|
+
}
|
|
11087
11329
|
get isOccluding() {
|
|
11088
11330
|
if (!this.visible) {
|
|
11089
11331
|
return false;
|
|
@@ -11377,6 +11619,7 @@ __export(index_browser_exports, {
|
|
|
11377
11619
|
AnvilParser: () => AnvilParser,
|
|
11378
11620
|
AnvilWorldSource: () => AnvilWorldSource,
|
|
11379
11621
|
ArchiveAssetSource: () => ArchiveAssetSource,
|
|
11622
|
+
Armor: () => Armor,
|
|
11380
11623
|
AssetKey: () => AssetKey,
|
|
11381
11624
|
AssetLoadError: () => AssetLoadError,
|
|
11382
11625
|
AssetLoader: () => AssetLoader,
|
|
@@ -11459,6 +11702,7 @@ __export(index_browser_exports, {
|
|
|
11459
11702
|
OrbitControls: () => OrbitControls,
|
|
11460
11703
|
PackFormats: () => PackFormats,
|
|
11461
11704
|
PackMetadata: () => PackMetadata,
|
|
11705
|
+
PalettedTextures: () => PalettedTextures,
|
|
11462
11706
|
PersistentCache: () => PersistentCache,
|
|
11463
11707
|
PlayerHeadTextures: () => PlayerHeadTextures,
|
|
11464
11708
|
Renames: () => Renames,
|
|
@@ -11593,6 +11837,7 @@ module.exports = __toCommonJS(index_browser_exports);
|
|
|
11593
11837
|
|
|
11594
11838
|
// src/env/browser/BrowserEnv.ts
|
|
11595
11839
|
init_Env();
|
|
11840
|
+
init_log();
|
|
11596
11841
|
|
|
11597
11842
|
// src/env/browser/BrowserCache.ts
|
|
11598
11843
|
init_PersistentCache();
|
|
@@ -11693,6 +11938,7 @@ function probeImageSize(data) {
|
|
|
11693
11938
|
|
|
11694
11939
|
// src/env/browser/BrowserEnv.ts
|
|
11695
11940
|
var import_meta = {};
|
|
11941
|
+
var log2 = logger("BrowserEnv");
|
|
11696
11942
|
function lazyLocalForage(options) {
|
|
11697
11943
|
let instance;
|
|
11698
11944
|
const store = () => instance ?? (instance = import("localforage").then((module2) => module2.default.createInstance(options)));
|
|
@@ -11708,7 +11954,8 @@ function lazyLocalForage(options) {
|
|
|
11708
11954
|
};
|
|
11709
11955
|
}
|
|
11710
11956
|
var BrowserEnv = class {
|
|
11711
|
-
constructor() {
|
|
11957
|
+
constructor(options = {}) {
|
|
11958
|
+
this.options = options;
|
|
11712
11959
|
this.name = "browser";
|
|
11713
11960
|
}
|
|
11714
11961
|
createCanvas(width, height) {
|
|
@@ -11737,14 +11984,18 @@ var BrowserEnv = class {
|
|
|
11737
11984
|
createWorker(name) {
|
|
11738
11985
|
if (name !== "section" || typeof Worker === "undefined") return void 0;
|
|
11739
11986
|
try {
|
|
11987
|
+
const sectionWorker = this.options.sectionWorker;
|
|
11988
|
+
if (typeof sectionWorker === "function") return sectionWorker();
|
|
11989
|
+
if (sectionWorker !== void 0) return new Worker(sectionWorker, { type: "module" });
|
|
11740
11990
|
return new Worker(new URL("./section.worker.mjs", import_meta.url), { type: "module" });
|
|
11741
|
-
} catch {
|
|
11991
|
+
} catch (error) {
|
|
11992
|
+
log2.warn("Could not start the section worker, so sections build on the main thread. Pass sectionWorker to registerBrowserEnv to load it from another URL.", error);
|
|
11742
11993
|
return void 0;
|
|
11743
11994
|
}
|
|
11744
11995
|
}
|
|
11745
11996
|
};
|
|
11746
|
-
function registerBrowserEnv() {
|
|
11747
|
-
const env = new BrowserEnv();
|
|
11997
|
+
function registerBrowserEnv(options) {
|
|
11998
|
+
const env = new BrowserEnv(options);
|
|
11748
11999
|
Env.register(env);
|
|
11749
12000
|
return env;
|
|
11750
12001
|
}
|
|
@@ -11816,6 +12067,9 @@ function shutdown() {
|
|
|
11816
12067
|
Caching.end();
|
|
11817
12068
|
}
|
|
11818
12069
|
|
|
12070
|
+
// src/armor/index.ts
|
|
12071
|
+
init_Armor();
|
|
12072
|
+
|
|
11819
12073
|
// src/assets/index.ts
|
|
11820
12074
|
init_AssetDefaults();
|
|
11821
12075
|
init_AssetKey();
|
|
@@ -11907,10 +12161,10 @@ init_EntityObject();
|
|
|
11907
12161
|
init_MineRenderError();
|
|
11908
12162
|
|
|
11909
12163
|
// src/export/SceneExporter.ts
|
|
11910
|
-
var
|
|
12164
|
+
var import_three20 = require("three");
|
|
11911
12165
|
|
|
11912
12166
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
11913
|
-
var
|
|
12167
|
+
var import_three17 = require("three");
|
|
11914
12168
|
var OBJExporter = class {
|
|
11915
12169
|
/**
|
|
11916
12170
|
* Parses the given 3D object and generates the OBJ output.
|
|
@@ -11925,17 +12179,17 @@ var OBJExporter = class {
|
|
|
11925
12179
|
let indexVertex = 0;
|
|
11926
12180
|
let indexVertexUvs = 0;
|
|
11927
12181
|
let indexNormals = 0;
|
|
11928
|
-
const vertex = new
|
|
11929
|
-
const color2 = new
|
|
11930
|
-
const normal = new
|
|
11931
|
-
const uv = new
|
|
12182
|
+
const vertex = new import_three17.Vector3();
|
|
12183
|
+
const color2 = new import_three17.Color();
|
|
12184
|
+
const normal = new import_three17.Vector3();
|
|
12185
|
+
const uv = new import_three17.Vector2();
|
|
11932
12186
|
const face = [];
|
|
11933
12187
|
function parseMesh(mesh) {
|
|
11934
12188
|
let nbVertex = 0;
|
|
11935
12189
|
let nbNormals = 0;
|
|
11936
12190
|
let nbVertexUvs = 0;
|
|
11937
12191
|
const geometry = mesh.geometry;
|
|
11938
|
-
const normalMatrixWorld = new
|
|
12192
|
+
const normalMatrixWorld = new import_three17.Matrix3();
|
|
11939
12193
|
const vertices = geometry.getAttribute("position");
|
|
11940
12194
|
const normals = geometry.getAttribute("normal");
|
|
11941
12195
|
const uvs = geometry.getAttribute("uv");
|
|
@@ -12026,7 +12280,7 @@ var OBJExporter = class {
|
|
|
12026
12280
|
output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
|
|
12027
12281
|
if (colors2 !== void 0) {
|
|
12028
12282
|
color2.fromBufferAttribute(colors2, i);
|
|
12029
|
-
|
|
12283
|
+
import_three17.ColorManagement.workingToColorSpace(color2, import_three17.SRGBColorSpace);
|
|
12030
12284
|
output += " " + color2.r + " " + color2.g + " " + color2.b;
|
|
12031
12285
|
}
|
|
12032
12286
|
output += "\n";
|
|
@@ -12055,7 +12309,7 @@ var OBJExporter = class {
|
|
|
12055
12309
|
};
|
|
12056
12310
|
|
|
12057
12311
|
// ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
|
|
12058
|
-
var
|
|
12312
|
+
var import_three18 = require("three");
|
|
12059
12313
|
var PLYExporter = class {
|
|
12060
12314
|
/**
|
|
12061
12315
|
* Parses the given 3D object and generates the PLY output.
|
|
@@ -12156,7 +12410,7 @@ var PLYExporter = class {
|
|
|
12156
12410
|
includeIndices = false;
|
|
12157
12411
|
}
|
|
12158
12412
|
});
|
|
12159
|
-
const tempColor = new
|
|
12413
|
+
const tempColor = new import_three18.Color();
|
|
12160
12414
|
includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
|
|
12161
12415
|
includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
|
|
12162
12416
|
includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
|
|
@@ -12205,8 +12459,8 @@ property list uchar int vertex_index
|
|
|
12205
12459
|
`;
|
|
12206
12460
|
}
|
|
12207
12461
|
header += "end_header\n";
|
|
12208
|
-
const vertex = new
|
|
12209
|
-
const normalMatrixWorld = new
|
|
12462
|
+
const vertex = new import_three18.Vector3();
|
|
12463
|
+
const normalMatrixWorld = new import_three18.Matrix3();
|
|
12210
12464
|
let result = null;
|
|
12211
12465
|
if (options.binary === true) {
|
|
12212
12466
|
const headerBin = new TextEncoder().encode(header);
|
|
@@ -12284,7 +12538,7 @@ property list uchar int vertex_index
|
|
|
12284
12538
|
if (includeColors === true) {
|
|
12285
12539
|
if (colors2 != null) {
|
|
12286
12540
|
tempColor.fromBufferAttribute(colors2, i);
|
|
12287
|
-
|
|
12541
|
+
import_three18.ColorManagement.workingToColorSpace(tempColor, import_three18.SRGBColorSpace);
|
|
12288
12542
|
const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
|
|
12289
12543
|
const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
|
|
12290
12544
|
const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
|
|
@@ -12386,7 +12640,7 @@ property list uchar int vertex_index
|
|
|
12386
12640
|
if (includeColors === true) {
|
|
12387
12641
|
if (colors2 != null) {
|
|
12388
12642
|
tempColor.fromBufferAttribute(colors2, i);
|
|
12389
|
-
|
|
12643
|
+
import_three18.ColorManagement.workingToColorSpace(tempColor, import_three18.SRGBColorSpace);
|
|
12390
12644
|
const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
|
|
12391
12645
|
const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
|
|
12392
12646
|
const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
|
|
@@ -12538,10 +12792,10 @@ var SceneExporter = class {
|
|
|
12538
12792
|
}
|
|
12539
12793
|
};
|
|
12540
12794
|
function localMatrix(object4) {
|
|
12541
|
-
return object4.matrixAutoUpdate ? new
|
|
12795
|
+
return object4.matrixAutoUpdate ? new import_three20.Matrix4().compose(object4.position, object4.quaternion, object4.scale) : object4.matrix.clone();
|
|
12542
12796
|
}
|
|
12543
12797
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
12544
|
-
const scene = new
|
|
12798
|
+
const scene = new import_three20.Scene();
|
|
12545
12799
|
const geometries = [];
|
|
12546
12800
|
const materials = [];
|
|
12547
12801
|
const textures = [];
|
|
@@ -12559,7 +12813,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12559
12813
|
if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
|
|
12560
12814
|
throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
|
|
12561
12815
|
}
|
|
12562
|
-
material = new
|
|
12816
|
+
material = new import_three20.MeshBasicMaterial({
|
|
12563
12817
|
map: uniforms.map.value,
|
|
12564
12818
|
vertexColors: source.vertexColors,
|
|
12565
12819
|
transparent: source.transparent,
|
|
@@ -12569,7 +12823,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12569
12823
|
});
|
|
12570
12824
|
material.name = source.name;
|
|
12571
12825
|
} else if (shader.isShaderMaterial) {
|
|
12572
|
-
material = new
|
|
12826
|
+
material = new import_three20.MeshBasicMaterial({ vertexColors: source.vertexColors });
|
|
12573
12827
|
material.name = source.name;
|
|
12574
12828
|
} else {
|
|
12575
12829
|
const copySource = Object.create(source);
|
|
@@ -12623,11 +12877,11 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12623
12877
|
const material = copyMaterial(sourceMaterial, geometry);
|
|
12624
12878
|
if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
|
|
12625
12879
|
if (bakeColors || instanceColor) {
|
|
12626
|
-
const tint = (material.color ?? new
|
|
12880
|
+
const tint = (material.color ?? new import_three20.Color()).clone();
|
|
12627
12881
|
if (instanceColor) tint.multiply(instanceColor);
|
|
12628
12882
|
if (bakeColors) {
|
|
12629
12883
|
const original = geometry.getAttribute("color");
|
|
12630
|
-
const colors2 = new
|
|
12884
|
+
const colors2 = new import_three20.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
|
|
12631
12885
|
for (let i = 0; i < colors2.count; i++) {
|
|
12632
12886
|
colors2.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
|
|
12633
12887
|
}
|
|
@@ -12636,7 +12890,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12636
12890
|
material.color.copy(tint);
|
|
12637
12891
|
}
|
|
12638
12892
|
}
|
|
12639
|
-
const copy = new
|
|
12893
|
+
const copy = new import_three20.Mesh(geometry, material);
|
|
12640
12894
|
copy.name = mesh.name;
|
|
12641
12895
|
copy.renderOrder = mesh.renderOrder;
|
|
12642
12896
|
scene.add(copy);
|
|
@@ -12650,9 +12904,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12650
12904
|
const instanced = mesh;
|
|
12651
12905
|
if (instanced.isInstancedMesh) {
|
|
12652
12906
|
for (let i = 0; i < instanced.count; i++) {
|
|
12653
|
-
const matrix = new
|
|
12907
|
+
const matrix = new import_three20.Matrix4();
|
|
12654
12908
|
instanced.getMatrixAt(i, matrix);
|
|
12655
|
-
const color2 = instanced.instanceColor ? new
|
|
12909
|
+
const color2 = instanced.instanceColor ? new import_three20.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
12656
12910
|
addMesh(mesh, world.clone().multiply(matrix), color2);
|
|
12657
12911
|
}
|
|
12658
12912
|
} else {
|
|
@@ -12664,7 +12918,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12664
12918
|
try {
|
|
12665
12919
|
const ancestors = [];
|
|
12666
12920
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
12667
|
-
const world = new
|
|
12921
|
+
const world = new import_three20.Matrix4();
|
|
12668
12922
|
for (const ancestor of ancestors) {
|
|
12669
12923
|
if (!ancestor.visible) return { scene, dispose };
|
|
12670
12924
|
world.multiply(localMatrix(ancestor));
|
|
@@ -12678,7 +12932,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12678
12932
|
}
|
|
12679
12933
|
function selectAlphaMode(material, geometry) {
|
|
12680
12934
|
const texture = material.map;
|
|
12681
|
-
if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !==
|
|
12935
|
+
if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== import_three20.RGBAFormat || texture.type !== import_three20.UnsignedByteType || texture.wrapS !== import_three20.ClampToEdgeWrapping || texture.wrapT !== import_three20.ClampToEdgeWrapping || texture.magFilter !== import_three20.NearestFilter || texture.minFilter !== import_three20.NearestFilter || texture.anisotropy > 1 || texture.offset.x !== 0 || texture.offset.y !== 0 || texture.repeat.x !== 1 || texture.repeat.y !== 1 || texture.rotation !== 0 || !texture.matrixAutoUpdate && !texture.matrix.elements.every((value, i) => value === (i % 4 === 0 ? 1 : 0))) return;
|
|
12682
12936
|
const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
|
|
12683
12937
|
const colors2 = geometry.getAttribute("color");
|
|
12684
12938
|
if (!uv || material.vertexColors && colors2?.itemSize === 4) return;
|
|
@@ -12715,7 +12969,7 @@ function selectAlphaMode(material, geometry) {
|
|
|
12715
12969
|
}
|
|
12716
12970
|
function copyDataTexture(source) {
|
|
12717
12971
|
const image = source.image;
|
|
12718
|
-
if (!image.data || source.format !==
|
|
12972
|
+
if (!image.data || source.format !== import_three20.RGBAFormat || source.type !== import_three20.UnsignedByteType) {
|
|
12719
12973
|
throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
|
|
12720
12974
|
}
|
|
12721
12975
|
const canvas = createCanvas(image.width, image.height);
|
|
@@ -12726,8 +12980,8 @@ function copyDataTexture(source) {
|
|
|
12726
12980
|
context.putImageData(pixels, 0, 0);
|
|
12727
12981
|
const copySource = Object.create(source);
|
|
12728
12982
|
copySource.userData = {};
|
|
12729
|
-
copySource.source = new
|
|
12730
|
-
return new
|
|
12983
|
+
copySource.source = new import_three20.TextureSource(canvas);
|
|
12984
|
+
return new import_three20.Texture().copy(copySource);
|
|
12731
12985
|
}
|
|
12732
12986
|
|
|
12733
12987
|
// src/export/VideoExporter.ts
|
|
@@ -13090,7 +13344,7 @@ init_SceneObject();
|
|
|
13090
13344
|
init_util();
|
|
13091
13345
|
init_log();
|
|
13092
13346
|
init_three();
|
|
13093
|
-
var
|
|
13347
|
+
var log15 = logger("SceneInspector");
|
|
13094
13348
|
var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
|
|
13095
13349
|
var SceneInspector = class {
|
|
13096
13350
|
constructor(renderer) {
|
|
@@ -13184,7 +13438,7 @@ var SceneInspector = class {
|
|
|
13184
13438
|
}
|
|
13185
13439
|
selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
|
|
13186
13440
|
this.selectedObject = targetObject;
|
|
13187
|
-
|
|
13441
|
+
log15.debug("selected", targetObject);
|
|
13188
13442
|
this.redraw(targetObject, targetIntersection, instance);
|
|
13189
13443
|
}
|
|
13190
13444
|
redraw(targetObject, targetIntersection, instance) {
|
|
@@ -13444,7 +13698,7 @@ var SceneStatsDisplay = class {
|
|
|
13444
13698
|
|
|
13445
13699
|
// src/instance/InstanceManager.ts
|
|
13446
13700
|
init_log();
|
|
13447
|
-
var
|
|
13701
|
+
var log16 = logger("InstanceManager");
|
|
13448
13702
|
var InstanceManager = class {
|
|
13449
13703
|
constructor() {
|
|
13450
13704
|
this.isInstanceManager = true;
|
|
@@ -13453,7 +13707,7 @@ var InstanceManager = class {
|
|
|
13453
13707
|
/** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */
|
|
13454
13708
|
async get(key) {
|
|
13455
13709
|
if (key in this.instanceCache) {
|
|
13456
|
-
|
|
13710
|
+
log16.debug("key in cache", key);
|
|
13457
13711
|
return (await this.instanceCache[key]).nextInstance();
|
|
13458
13712
|
}
|
|
13459
13713
|
return void 0;
|
|
@@ -13463,7 +13717,7 @@ var InstanceManager = class {
|
|
|
13463
13717
|
if (key in this.instanceCache) {
|
|
13464
13718
|
return await this.get(key);
|
|
13465
13719
|
}
|
|
13466
|
-
|
|
13720
|
+
log16.debug("key not in cache", key);
|
|
13467
13721
|
const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
|
|
13468
13722
|
this.instanceCache[key] = pending;
|
|
13469
13723
|
try {
|
|
@@ -14337,12 +14591,13 @@ function isFlyControls(obj) {
|
|
|
14337
14591
|
}
|
|
14338
14592
|
|
|
14339
14593
|
// src/renderer/MineRenderScene.ts
|
|
14340
|
-
var
|
|
14594
|
+
var import_three37 = require("three");
|
|
14341
14595
|
init_SceneObject();
|
|
14342
14596
|
init_merge();
|
|
14343
14597
|
|
|
14344
14598
|
// src/skin/scene/SkinObject.ts
|
|
14345
14599
|
init_SceneObject();
|
|
14600
|
+
var import_three36 = require("three");
|
|
14346
14601
|
|
|
14347
14602
|
// src/skin/SkinPart.ts
|
|
14348
14603
|
var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
|
|
@@ -14359,11 +14614,21 @@ var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
|
|
|
14359
14614
|
SkinPart2["RIGHT_TROUSERS"] = "rightTrousers";
|
|
14360
14615
|
SkinPart2["LEFT_TROUSERS"] = "leftTrousers";
|
|
14361
14616
|
SkinPart2["CAPE"] = "cape";
|
|
14617
|
+
SkinPart2["LEFT_EAR"] = "leftEar";
|
|
14618
|
+
SkinPart2["RIGHT_EAR"] = "rightEar";
|
|
14362
14619
|
return SkinPart2;
|
|
14363
14620
|
})(SkinPart || {});
|
|
14364
14621
|
var SKIN_PARTS = Object.values(SkinPart);
|
|
14365
14622
|
|
|
14366
14623
|
// src/skin/SkinTextureCoordinates.ts
|
|
14624
|
+
var earCoordinates = {
|
|
14625
|
+
west: { uv: [24, 1, 25, 7] },
|
|
14626
|
+
east: { uv: [31, 1, 32, 7] },
|
|
14627
|
+
south: { uv: [25, 1, 31, 7] },
|
|
14628
|
+
north: { uv: [32, 1, 38, 7] },
|
|
14629
|
+
up: { uv: [25, 0, 31, 1] },
|
|
14630
|
+
down: { uv: [31, 1, 37, 0] }
|
|
14631
|
+
};
|
|
14367
14632
|
var baseSkinCoordinates = {
|
|
14368
14633
|
head: {
|
|
14369
14634
|
west: {
|
|
@@ -14984,7 +15249,9 @@ var baseSkinCoordinates = {
|
|
|
14984
15249
|
south: { uv: [12, 1, 22, 17] },
|
|
14985
15250
|
up: { uv: [11, 1, 1, 0] },
|
|
14986
15251
|
down: { uv: [21, 0, 11, 1] }
|
|
14987
|
-
}
|
|
15252
|
+
},
|
|
15253
|
+
leftEar: earCoordinates,
|
|
15254
|
+
rightEar: earCoordinates
|
|
14988
15255
|
};
|
|
14989
15256
|
var classicSkinTextureCoordinates = {
|
|
14990
15257
|
...baseSkinCoordinates
|
|
@@ -15035,6 +15302,7 @@ var box4_12_4outer = [4.5, 12.5, 4.5];
|
|
|
15035
15302
|
var box3_12_4inner = [3, 12, 4];
|
|
15036
15303
|
var box3_12_4outer = [3.5, 12.5, 4.5];
|
|
15037
15304
|
var box10_16_1 = [10, 16, 1];
|
|
15305
|
+
var box8_8_3ear = [8, 8, 3];
|
|
15038
15306
|
var baseSkinGeometries = {
|
|
15039
15307
|
head: box8inner,
|
|
15040
15308
|
hat: box8outer,
|
|
@@ -15048,7 +15316,9 @@ var baseSkinGeometries = {
|
|
|
15048
15316
|
leftTrousers: box4_12_4outer,
|
|
15049
15317
|
rightLeg: box4_12_4inner,
|
|
15050
15318
|
rightTrousers: box4_12_4outer,
|
|
15051
|
-
cape: box10_16_1
|
|
15319
|
+
cape: box10_16_1,
|
|
15320
|
+
leftEar: box8_8_3ear,
|
|
15321
|
+
rightEar: box8_8_3ear
|
|
15052
15322
|
};
|
|
15053
15323
|
var classicSkinGeometries = { ...{}, ...baseSkinGeometries };
|
|
15054
15324
|
var slimSkinGeometries = {
|
|
@@ -15077,6 +15347,12 @@ var capeTextureSizes = {
|
|
|
15077
15347
|
};
|
|
15078
15348
|
|
|
15079
15349
|
// src/skin/scene/SkinObject.ts
|
|
15350
|
+
var ArmorClass;
|
|
15351
|
+
var EntityObjectClass;
|
|
15352
|
+
function hasCubes(part) {
|
|
15353
|
+
return part.cubes.length > 0 || Object.values(part.children).some(hasCubes);
|
|
15354
|
+
}
|
|
15355
|
+
var UPSIDE_DOWN_OFFSET = (1.8 + 0.1) * 16 / 0.9375;
|
|
15080
15356
|
var SkinObject = class extends SceneObject {
|
|
15081
15357
|
constructor(options) {
|
|
15082
15358
|
super();
|
|
@@ -15084,27 +15360,42 @@ var SkinObject = class extends SceneObject {
|
|
|
15084
15360
|
this.detectedSlim = false;
|
|
15085
15361
|
this.skinLoad = 0;
|
|
15086
15362
|
this.capeLoad = 0;
|
|
15363
|
+
this.armorLoad = 0;
|
|
15364
|
+
this.armorObjects = [];
|
|
15087
15365
|
this.options = (0, import_ts_deepmerge.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
15088
15366
|
this.slim = this.options.slim ?? false;
|
|
15089
15367
|
}
|
|
15090
15368
|
async init() {
|
|
15091
15369
|
const cape = this.getGroupByName("cape" /* CAPE */);
|
|
15370
|
+
const capeOnBody = cape?.parent === this.getGroupByName("body" /* BODY */);
|
|
15092
15371
|
this.createMeshes();
|
|
15093
|
-
if (cape)
|
|
15372
|
+
if (cape) {
|
|
15373
|
+
const body = this.getGroupByName("body" /* BODY */);
|
|
15374
|
+
if (capeOnBody) body.add(cape);
|
|
15375
|
+
else body.attach(cape);
|
|
15376
|
+
}
|
|
15377
|
+
for (const { part, object: object4 } of this.armorObjects) this.getGroupByName(part).add(object4);
|
|
15378
|
+
this.updateEars();
|
|
15379
|
+
this.updateUpsideDown();
|
|
15094
15380
|
}
|
|
15095
15381
|
removeMeshes() {
|
|
15096
15382
|
}
|
|
15097
15383
|
createMeshes() {
|
|
15098
15384
|
const mat = this.skinMaterial ?? Materials.MISSING_TEXTURE;
|
|
15385
|
+
this.model?.removeFromParent();
|
|
15386
|
+
const model = this.model = new import_three36.Object3D();
|
|
15387
|
+
this.add(model);
|
|
15099
15388
|
{
|
|
15100
|
-
const headGroup = this.
|
|
15389
|
+
const headGroup = this.createGroup("head", 0, 28, 0, "y" /* Y */, -4);
|
|
15390
|
+
model.add(headGroup);
|
|
15101
15391
|
const headGeo = this.getBoxGeometry("head" /* HEAD */);
|
|
15102
15392
|
const head = this.createAndAddMesh("head", headGroup, headGeo, mat, "y" /* Y */, 4);
|
|
15103
15393
|
const hatGeo = this.getBoxGeometry("hat" /* HAT */);
|
|
15104
15394
|
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
15105
15395
|
}
|
|
15106
15396
|
{
|
|
15107
|
-
const bodyGroup = this.
|
|
15397
|
+
const bodyGroup = this.createGroup("body", 0, 24, 0);
|
|
15398
|
+
model.add(bodyGroup);
|
|
15108
15399
|
const bodyGeo = this.getBoxGeometry("body" /* BODY */);
|
|
15109
15400
|
const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat, "y" /* Y */, -6);
|
|
15110
15401
|
const jacketGeo = this.getBoxGeometry("jacket" /* JACKET */);
|
|
@@ -15112,7 +15403,8 @@ var SkinObject = class extends SceneObject {
|
|
|
15112
15403
|
}
|
|
15113
15404
|
{
|
|
15114
15405
|
{
|
|
15115
|
-
const leftArmGroup = this.
|
|
15406
|
+
const leftArmGroup = this.createGroup("leftArm", 5, 22, 0);
|
|
15407
|
+
model.add(leftArmGroup);
|
|
15116
15408
|
const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
|
|
15117
15409
|
const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
|
|
15118
15410
|
leftArm.position.x = this.slim ? 0.5 : 1;
|
|
@@ -15121,7 +15413,8 @@ var SkinObject = class extends SceneObject {
|
|
|
15121
15413
|
leftSleeve.position.x = this.slim ? 0.5 : 1;
|
|
15122
15414
|
}
|
|
15123
15415
|
{
|
|
15124
|
-
const rightArmGroup = this.
|
|
15416
|
+
const rightArmGroup = this.createGroup("rightArm", -5, 22, 0);
|
|
15417
|
+
model.add(rightArmGroup);
|
|
15125
15418
|
const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
|
|
15126
15419
|
const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
|
|
15127
15420
|
rightArm.position.x = this.slim ? -0.5 : -1;
|
|
@@ -15132,14 +15425,16 @@ var SkinObject = class extends SceneObject {
|
|
|
15132
15425
|
}
|
|
15133
15426
|
{
|
|
15134
15427
|
{
|
|
15135
|
-
const leftLegGroup = this.
|
|
15428
|
+
const leftLegGroup = this.createGroup("leftLeg", 1.9, 12, 0);
|
|
15429
|
+
model.add(leftLegGroup);
|
|
15136
15430
|
const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
|
|
15137
15431
|
const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
|
|
15138
15432
|
const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
|
|
15139
15433
|
const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
|
|
15140
15434
|
}
|
|
15141
15435
|
{
|
|
15142
|
-
const rightLegGroup = this.
|
|
15436
|
+
const rightLegGroup = this.createGroup("rightLeg", -1.9, 12, 0);
|
|
15437
|
+
model.add(rightLegGroup);
|
|
15143
15438
|
const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
|
|
15144
15439
|
const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
|
|
15145
15440
|
const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
|
|
@@ -15206,6 +15501,54 @@ var SkinObject = class extends SceneObject {
|
|
|
15206
15501
|
}
|
|
15207
15502
|
this.notifyDirty();
|
|
15208
15503
|
}
|
|
15504
|
+
/**
|
|
15505
|
+
* Loads armor from 1.21.4+ equipment assets, or pass undefined to remove it.
|
|
15506
|
+
* Each piece moves with the skin part it covers.
|
|
15507
|
+
*/
|
|
15508
|
+
async setArmor(armor) {
|
|
15509
|
+
const load = ++this.armorLoad;
|
|
15510
|
+
const objects = [];
|
|
15511
|
+
if (armor) {
|
|
15512
|
+
const Armor2 = ArmorClass ?? (ArmorClass = (await Promise.resolve().then(() => (init_Armor(), Armor_exports))).Armor);
|
|
15513
|
+
const EntityObject2 = EntityObjectClass ?? (EntityObjectClass = (await Promise.resolve().then(() => (init_EntityObject(), EntityObject_exports))).EntityObject);
|
|
15514
|
+
const model = await Armor2.getEntity(armor);
|
|
15515
|
+
if (model) {
|
|
15516
|
+
const parts = { head: "head", body: "body", left_arm: "leftArm", right_arm: "rightArm", left_leg: "leftLeg", right_leg: "rightLeg" };
|
|
15517
|
+
for (const [name, part] of Object.entries(parts)) {
|
|
15518
|
+
const layers = {};
|
|
15519
|
+
for (const [draw, layer] of Object.entries(model.layers)) {
|
|
15520
|
+
const child = layer.layer.root.children[name];
|
|
15521
|
+
if (!child || !hasCubes(child)) continue;
|
|
15522
|
+
const pose = { offset: [0, 0, 0], rotation: [0, 0, 0] };
|
|
15523
|
+
layers[draw] = { ...layer, layer: { ...layer.layer, root: {
|
|
15524
|
+
pose,
|
|
15525
|
+
cubes: [],
|
|
15526
|
+
children: { [name]: { ...child, pose } }
|
|
15527
|
+
} } };
|
|
15528
|
+
}
|
|
15529
|
+
const first = Object.values(layers)[0];
|
|
15530
|
+
if (!first) continue;
|
|
15531
|
+
const object4 = new EntityObject2({ ...first, id: model.id, layers }, { flip: false });
|
|
15532
|
+
object4.rotation.x = Math.PI;
|
|
15533
|
+
objects.push({ part, object: object4 });
|
|
15534
|
+
}
|
|
15535
|
+
}
|
|
15536
|
+
}
|
|
15537
|
+
const results = await Promise.allSettled(objects.map(({ object: object4 }) => object4.init()));
|
|
15538
|
+
const failure = results.find((result) => result.status === "rejected");
|
|
15539
|
+
if (load !== this.armorLoad || failure) {
|
|
15540
|
+
for (const { object: object4 } of objects) object4.dispose();
|
|
15541
|
+
if (load === this.armorLoad && failure?.status === "rejected") throw failure.reason;
|
|
15542
|
+
return;
|
|
15543
|
+
}
|
|
15544
|
+
for (const { object: object4 } of this.armorObjects) {
|
|
15545
|
+
object4.dispose();
|
|
15546
|
+
object4.removeFromParent();
|
|
15547
|
+
}
|
|
15548
|
+
this.armorObjects = objects;
|
|
15549
|
+
for (const { part, object: object4 } of objects) this.getGroupByName(part)?.add(object4);
|
|
15550
|
+
this.notifyDirty();
|
|
15551
|
+
}
|
|
15209
15552
|
/** Select the arm model, or pass undefined to use texture detection. */
|
|
15210
15553
|
setSlim(slim) {
|
|
15211
15554
|
this.options.slim = slim;
|
|
@@ -15224,6 +15567,39 @@ var SkinObject = class extends SceneObject {
|
|
|
15224
15567
|
}
|
|
15225
15568
|
this.notifyDirty();
|
|
15226
15569
|
}
|
|
15570
|
+
/** Shows or hides deadmau5's ears, which vanilla draws from the skin texture at 24,0 for that player only. */
|
|
15571
|
+
setEars(ears) {
|
|
15572
|
+
if (ears === (this.options.ears ?? false)) return;
|
|
15573
|
+
this.options.ears = ears;
|
|
15574
|
+
this.updateEars();
|
|
15575
|
+
}
|
|
15576
|
+
updateEars() {
|
|
15577
|
+
const head = this.getGroupByName("head" /* HEAD */);
|
|
15578
|
+
if (!head) return;
|
|
15579
|
+
for (const [part, x] of [["leftEar" /* LEFT_EAR */, 6], ["rightEar" /* RIGHT_EAR */, -6]]) {
|
|
15580
|
+
const ear = this.getMeshByName(part);
|
|
15581
|
+
if (!this.options.ears) {
|
|
15582
|
+
ear?.removeFromParent();
|
|
15583
|
+
} else if (!ear) {
|
|
15584
|
+
const mesh = this.createAndAddMesh(part, head, this.getBoxGeometry(part), this.skinMaterial ?? Materials.MISSING_TEXTURE);
|
|
15585
|
+
mesh.position.set(x, 9, 0.5);
|
|
15586
|
+
}
|
|
15587
|
+
}
|
|
15588
|
+
this.notifyDirty();
|
|
15589
|
+
}
|
|
15590
|
+
/** Turns the player upside down, as vanilla does for players named Dinnerbone or Grumm. */
|
|
15591
|
+
setUpsideDown(upsideDown) {
|
|
15592
|
+
if (upsideDown === (this.options.upsideDown ?? false)) return;
|
|
15593
|
+
this.options.upsideDown = upsideDown;
|
|
15594
|
+
this.updateUpsideDown();
|
|
15595
|
+
}
|
|
15596
|
+
updateUpsideDown() {
|
|
15597
|
+
if (!this.model) return;
|
|
15598
|
+
const upsideDown = this.options.upsideDown ?? false;
|
|
15599
|
+
this.model.position.y = upsideDown ? UPSIDE_DOWN_OFFSET : 0;
|
|
15600
|
+
this.model.rotation.z = upsideDown ? Math.PI : 0;
|
|
15601
|
+
this.notifyDirty();
|
|
15602
|
+
}
|
|
15227
15603
|
/** Select the texture layout, or pass undefined to detect it from image dimensions. */
|
|
15228
15604
|
async setLegacy(legacy) {
|
|
15229
15605
|
if (legacy === this.options.legacy) return;
|
|
@@ -15233,6 +15609,11 @@ var SkinObject = class extends SceneObject {
|
|
|
15233
15609
|
dispose() {
|
|
15234
15610
|
this.skinLoad++;
|
|
15235
15611
|
this.capeLoad++;
|
|
15612
|
+
this.armorLoad++;
|
|
15613
|
+
for (const { object: object4 } of this.armorObjects.splice(0)) {
|
|
15614
|
+
object4.dispose();
|
|
15615
|
+
object4.removeFromParent();
|
|
15616
|
+
}
|
|
15236
15617
|
super.dispose();
|
|
15237
15618
|
}
|
|
15238
15619
|
//TODO: layer toggles
|
|
@@ -15252,10 +15633,10 @@ function isBlockObject2(obj) {
|
|
|
15252
15633
|
}
|
|
15253
15634
|
var ModelObjectClass;
|
|
15254
15635
|
var BlockObjectClass;
|
|
15255
|
-
var
|
|
15636
|
+
var EntityObjectClass2;
|
|
15256
15637
|
var GuiObjectClass;
|
|
15257
15638
|
var ItemTintsClass;
|
|
15258
|
-
var _MineRenderScene = class _MineRenderScene extends
|
|
15639
|
+
var _MineRenderScene = class _MineRenderScene extends import_three37.Scene {
|
|
15259
15640
|
constructor(options) {
|
|
15260
15641
|
super();
|
|
15261
15642
|
this.isMineRenderScene = true;
|
|
@@ -15393,7 +15774,7 @@ var _MineRenderScene = class _MineRenderScene extends import_three36.Scene {
|
|
|
15393
15774
|
}
|
|
15394
15775
|
/** Adds an entity loaded with {@link Entities.getEntity}, using its selected layers and textures. */
|
|
15395
15776
|
async addEntity(entity, options, parent = this) {
|
|
15396
|
-
const EntityObject2 =
|
|
15777
|
+
const EntityObject2 = EntityObjectClass2 ?? (EntityObjectClass2 = (await Promise.resolve().then(() => (init_EntityObject(), EntityObject_exports))).EntityObject);
|
|
15397
15778
|
return this.addSceneObject(entity, () => new EntityObject2(entity, options), options, parent);
|
|
15398
15779
|
}
|
|
15399
15780
|
/**
|
|
@@ -15417,7 +15798,7 @@ function isMineRenderScene(obj) {
|
|
|
15417
15798
|
}
|
|
15418
15799
|
|
|
15419
15800
|
// src/renderer/Renderer.ts
|
|
15420
|
-
var
|
|
15801
|
+
var import_three39 = require("three");
|
|
15421
15802
|
init_merge();
|
|
15422
15803
|
var import_stats = __toESM(require("stats.js"));
|
|
15423
15804
|
var import_postprocessing = require("postprocessing");
|
|
@@ -15426,11 +15807,11 @@ init_Model();
|
|
|
15426
15807
|
init_three();
|
|
15427
15808
|
|
|
15428
15809
|
// src/three/OrbitControls.js
|
|
15429
|
-
var
|
|
15810
|
+
var import_three38 = require("three");
|
|
15430
15811
|
var _changeEvent = { type: "change" };
|
|
15431
15812
|
var _startEvent = { type: "start" };
|
|
15432
15813
|
var _endEvent = { type: "end" };
|
|
15433
|
-
var OrbitControls = class extends
|
|
15814
|
+
var OrbitControls = class extends import_three38.EventDispatcher {
|
|
15434
15815
|
constructor(object4, domElement) {
|
|
15435
15816
|
super();
|
|
15436
15817
|
if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
|
|
@@ -15439,7 +15820,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15439
15820
|
this.domElement = domElement;
|
|
15440
15821
|
this.domElement.style.touchAction = "none";
|
|
15441
15822
|
this.enabled = true;
|
|
15442
|
-
this.target = new
|
|
15823
|
+
this.target = new import_three38.Vector3();
|
|
15443
15824
|
this.minDistance = 0;
|
|
15444
15825
|
this.maxDistance = Infinity;
|
|
15445
15826
|
this.minZoom = 0;
|
|
@@ -15461,8 +15842,8 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15461
15842
|
this.autoRotate = false;
|
|
15462
15843
|
this.autoRotateSpeed = 2;
|
|
15463
15844
|
this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
|
|
15464
|
-
this.mouseButtons = { LEFT:
|
|
15465
|
-
this.touches = { ONE:
|
|
15845
|
+
this.mouseButtons = { LEFT: import_three38.MOUSE.ROTATE, MIDDLE: import_three38.MOUSE.DOLLY, RIGHT: import_three38.MOUSE.PAN };
|
|
15846
|
+
this.touches = { ONE: import_three38.TOUCH.ROTATE, TWO: import_three38.TOUCH.DOLLY_PAN };
|
|
15466
15847
|
this.target0 = this.target.clone();
|
|
15467
15848
|
this.position0 = this.object.position.clone();
|
|
15468
15849
|
this.zoom0 = this.object.zoom;
|
|
@@ -15491,11 +15872,11 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15491
15872
|
state = STATE.NONE;
|
|
15492
15873
|
};
|
|
15493
15874
|
this.update = function() {
|
|
15494
|
-
const offset = new
|
|
15495
|
-
const quat = new
|
|
15875
|
+
const offset = new import_three38.Vector3();
|
|
15876
|
+
const quat = new import_three38.Quaternion().setFromUnitVectors(object4.up, new import_three38.Vector3(0, 1, 0));
|
|
15496
15877
|
const quatInverse = quat.clone().invert();
|
|
15497
|
-
const lastPosition = new
|
|
15498
|
-
const lastQuaternion = new
|
|
15878
|
+
const lastPosition = new import_three38.Vector3();
|
|
15879
|
+
const lastQuaternion = new import_three38.Quaternion();
|
|
15499
15880
|
const twoPI = 2 * Math.PI;
|
|
15500
15881
|
return function update() {
|
|
15501
15882
|
const position = scope.object.position;
|
|
@@ -15581,20 +15962,20 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15581
15962
|
};
|
|
15582
15963
|
let state = STATE.NONE;
|
|
15583
15964
|
const EPS = 1e-6;
|
|
15584
|
-
const spherical = new
|
|
15585
|
-
const sphericalDelta = new
|
|
15965
|
+
const spherical = new import_three38.Spherical();
|
|
15966
|
+
const sphericalDelta = new import_three38.Spherical();
|
|
15586
15967
|
let scale = 1;
|
|
15587
|
-
const panOffset = new
|
|
15968
|
+
const panOffset = new import_three38.Vector3();
|
|
15588
15969
|
let zoomChanged = false;
|
|
15589
|
-
const rotateStart = new
|
|
15590
|
-
const rotateEnd = new
|
|
15591
|
-
const rotateDelta = new
|
|
15592
|
-
const panStart = new
|
|
15593
|
-
const panEnd = new
|
|
15594
|
-
const panDelta = new
|
|
15595
|
-
const dollyStart = new
|
|
15596
|
-
const dollyEnd = new
|
|
15597
|
-
const dollyDelta = new
|
|
15970
|
+
const rotateStart = new import_three38.Vector2();
|
|
15971
|
+
const rotateEnd = new import_three38.Vector2();
|
|
15972
|
+
const rotateDelta = new import_three38.Vector2();
|
|
15973
|
+
const panStart = new import_three38.Vector2();
|
|
15974
|
+
const panEnd = new import_three38.Vector2();
|
|
15975
|
+
const panDelta = new import_three38.Vector2();
|
|
15976
|
+
const dollyStart = new import_three38.Vector2();
|
|
15977
|
+
const dollyEnd = new import_three38.Vector2();
|
|
15978
|
+
const dollyDelta = new import_three38.Vector2();
|
|
15598
15979
|
const pointers = [];
|
|
15599
15980
|
const pointerPositions = {};
|
|
15600
15981
|
function getAutoRotationAngle() {
|
|
@@ -15610,7 +15991,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15610
15991
|
sphericalDelta.phi -= angle;
|
|
15611
15992
|
}
|
|
15612
15993
|
const panLeft = function() {
|
|
15613
|
-
const v = new
|
|
15994
|
+
const v = new import_three38.Vector3();
|
|
15614
15995
|
return function panLeft2(distance, objectMatrix) {
|
|
15615
15996
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
15616
15997
|
v.multiplyScalar(-distance);
|
|
@@ -15618,7 +15999,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15618
15999
|
};
|
|
15619
16000
|
}();
|
|
15620
16001
|
const panUp = function() {
|
|
15621
|
-
const v = new
|
|
16002
|
+
const v = new import_three38.Vector3();
|
|
15622
16003
|
return function panUp2(distance, objectMatrix) {
|
|
15623
16004
|
if (scope.screenSpacePanning === true) {
|
|
15624
16005
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -15631,7 +16012,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15631
16012
|
};
|
|
15632
16013
|
}();
|
|
15633
16014
|
const pan = function() {
|
|
15634
|
-
const offset = new
|
|
16015
|
+
const offset = new import_three38.Vector3();
|
|
15635
16016
|
return function pan2(deltaX, deltaY) {
|
|
15636
16017
|
const element = scope.domElement;
|
|
15637
16018
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -15880,12 +16261,12 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15880
16261
|
mouseAction = -1;
|
|
15881
16262
|
}
|
|
15882
16263
|
switch (mouseAction) {
|
|
15883
|
-
case
|
|
16264
|
+
case import_three38.MOUSE.DOLLY:
|
|
15884
16265
|
if (scope.enableZoom === false) return;
|
|
15885
16266
|
handleMouseDownDolly(event);
|
|
15886
16267
|
state = STATE.DOLLY;
|
|
15887
16268
|
break;
|
|
15888
|
-
case
|
|
16269
|
+
case import_three38.MOUSE.ROTATE:
|
|
15889
16270
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
15890
16271
|
if (scope.enablePan === false) return;
|
|
15891
16272
|
handleMouseDownPan(event);
|
|
@@ -15896,7 +16277,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15896
16277
|
state = STATE.ROTATE;
|
|
15897
16278
|
}
|
|
15898
16279
|
break;
|
|
15899
|
-
case
|
|
16280
|
+
case import_three38.MOUSE.PAN:
|
|
15900
16281
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
15901
16282
|
if (scope.enableRotate === false) return;
|
|
15902
16283
|
handleMouseDownRotate(event);
|
|
@@ -15952,12 +16333,12 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15952
16333
|
switch (pointers.length) {
|
|
15953
16334
|
case 1:
|
|
15954
16335
|
switch (scope.touches.ONE) {
|
|
15955
|
-
case
|
|
16336
|
+
case import_three38.TOUCH.ROTATE:
|
|
15956
16337
|
if (scope.enableRotate === false) return;
|
|
15957
16338
|
handleTouchStartRotate();
|
|
15958
16339
|
state = STATE.TOUCH_ROTATE;
|
|
15959
16340
|
break;
|
|
15960
|
-
case
|
|
16341
|
+
case import_three38.TOUCH.PAN:
|
|
15961
16342
|
if (scope.enablePan === false) return;
|
|
15962
16343
|
handleTouchStartPan();
|
|
15963
16344
|
state = STATE.TOUCH_PAN;
|
|
@@ -15968,12 +16349,12 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15968
16349
|
break;
|
|
15969
16350
|
case 2:
|
|
15970
16351
|
switch (scope.touches.TWO) {
|
|
15971
|
-
case
|
|
16352
|
+
case import_three38.TOUCH.DOLLY_PAN:
|
|
15972
16353
|
if (scope.enableZoom === false && scope.enablePan === false) return;
|
|
15973
16354
|
handleTouchStartDollyPan();
|
|
15974
16355
|
state = STATE.TOUCH_DOLLY_PAN;
|
|
15975
16356
|
break;
|
|
15976
|
-
case
|
|
16357
|
+
case import_three38.TOUCH.DOLLY_ROTATE:
|
|
15977
16358
|
if (scope.enableZoom === false && scope.enableRotate === false) return;
|
|
15978
16359
|
handleTouchStartDollyRotate();
|
|
15979
16360
|
state = STATE.TOUCH_DOLLY_ROTATE;
|
|
@@ -16040,7 +16421,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
16040
16421
|
function trackPointer(event) {
|
|
16041
16422
|
let position = pointerPositions[event.pointerId];
|
|
16042
16423
|
if (position === void 0) {
|
|
16043
|
-
position = new
|
|
16424
|
+
position = new import_three38.Vector2();
|
|
16044
16425
|
pointerPositions[event.pointerId] = position;
|
|
16045
16426
|
}
|
|
16046
16427
|
position.set(event.pageX, event.pageY);
|
|
@@ -16060,16 +16441,16 @@ var MapControls = class extends OrbitControls {
|
|
|
16060
16441
|
constructor(object4, domElement) {
|
|
16061
16442
|
super(object4, domElement);
|
|
16062
16443
|
this.screenSpacePanning = false;
|
|
16063
|
-
this.mouseButtons.LEFT =
|
|
16064
|
-
this.mouseButtons.RIGHT =
|
|
16065
|
-
this.touches.ONE =
|
|
16066
|
-
this.touches.TWO =
|
|
16444
|
+
this.mouseButtons.LEFT = import_three38.MOUSE.PAN;
|
|
16445
|
+
this.mouseButtons.RIGHT = import_three38.MOUSE.ROTATE;
|
|
16446
|
+
this.touches.ONE = import_three38.TOUCH.PAN;
|
|
16447
|
+
this.touches.TWO = import_three38.TOUCH.DOLLY_ROTATE;
|
|
16067
16448
|
}
|
|
16068
16449
|
};
|
|
16069
16450
|
|
|
16070
16451
|
// src/renderer/Renderer.ts
|
|
16071
16452
|
init_log();
|
|
16072
|
-
var
|
|
16453
|
+
var log18 = logger("Renderer");
|
|
16073
16454
|
var _Renderer = class _Renderer {
|
|
16074
16455
|
constructor(options, surface) {
|
|
16075
16456
|
this._width = 0;
|
|
@@ -16136,14 +16517,14 @@ var _Renderer = class _Renderer {
|
|
|
16136
16517
|
switch (this.options.camera.type) {
|
|
16137
16518
|
case "perspective":
|
|
16138
16519
|
default:
|
|
16139
|
-
return new
|
|
16520
|
+
return new import_three39.PerspectiveCamera(
|
|
16140
16521
|
this.options.camera.perspective.fov,
|
|
16141
16522
|
this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
|
|
16142
16523
|
this.options.camera.near,
|
|
16143
16524
|
this.options.camera.far
|
|
16144
16525
|
);
|
|
16145
16526
|
case "orthographic":
|
|
16146
|
-
return new
|
|
16527
|
+
return new import_three39.OrthographicCamera(
|
|
16147
16528
|
this.options.camera.orthographic.left ?? this.viewWidth / -2,
|
|
16148
16529
|
this.options.camera.orthographic.right ?? this.viewWidth / 2,
|
|
16149
16530
|
this.options.camera.orthographic.top ?? this.viewHeight / 2,
|
|
@@ -16159,7 +16540,7 @@ var _Renderer = class _Renderer {
|
|
|
16159
16540
|
}
|
|
16160
16541
|
const pixelRatio = this.options.render.pixelRatio ?? 1;
|
|
16161
16542
|
this._surface?.resize?.(Math.floor(this.viewWidth * pixelRatio), Math.floor(this.viewHeight * pixelRatio));
|
|
16162
|
-
const renderer = new
|
|
16543
|
+
const renderer = new import_three39.WebGLRenderer({
|
|
16163
16544
|
canvas: this._surface?.canvas,
|
|
16164
16545
|
context: this._surface?.context,
|
|
16165
16546
|
antialias: this.options.render.antialias,
|
|
@@ -16169,8 +16550,8 @@ var _Renderer = class _Renderer {
|
|
|
16169
16550
|
});
|
|
16170
16551
|
renderer.setClearColor(0, 0);
|
|
16171
16552
|
renderer.shadowMap.enabled = true;
|
|
16172
|
-
renderer.shadowMap.type =
|
|
16173
|
-
renderer.outputColorSpace =
|
|
16553
|
+
renderer.shadowMap.type = import_three39.PCFShadowMap;
|
|
16554
|
+
renderer.outputColorSpace = import_three39.SRGBColorSpace;
|
|
16174
16555
|
if (this._surface) {
|
|
16175
16556
|
renderer.setDrawingBufferSize(this.viewWidth, this.viewHeight, pixelRatio);
|
|
16176
16557
|
} else {
|
|
@@ -16193,8 +16574,8 @@ var _Renderer = class _Renderer {
|
|
|
16193
16574
|
initialTarget() {
|
|
16194
16575
|
const target = this.options.camera.lookingAt;
|
|
16195
16576
|
if (isVector3(target)) return target.clone();
|
|
16196
|
-
if (isTripleArray(target)) return new
|
|
16197
|
-
return new
|
|
16577
|
+
if (isTripleArray(target)) return new import_three39.Vector3(target[0], target[1], target[2]);
|
|
16578
|
+
return new import_three39.Vector3();
|
|
16198
16579
|
}
|
|
16199
16580
|
createControlsFor(mode, target) {
|
|
16200
16581
|
let controls;
|
|
@@ -16227,7 +16608,7 @@ var _Renderer = class _Renderer {
|
|
|
16227
16608
|
let target;
|
|
16228
16609
|
if (isFlyControls(current)) {
|
|
16229
16610
|
const distance = this._orbitDistance ?? (this.camera.position.distanceTo(this.initialTarget()) || 1);
|
|
16230
|
-
target = new
|
|
16611
|
+
target = new import_three39.Vector3(0, 0, -distance).applyQuaternion(this.camera.quaternion).add(this.camera.position);
|
|
16231
16612
|
} else {
|
|
16232
16613
|
target = current.target.clone();
|
|
16233
16614
|
this._orbitDistance = this.camera.position.distanceTo(target);
|
|
@@ -16267,20 +16648,20 @@ var _Renderer = class _Renderer {
|
|
|
16267
16648
|
window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
|
|
16268
16649
|
}
|
|
16269
16650
|
if (this.options.debug.grid) {
|
|
16270
|
-
const gridHelper = new
|
|
16651
|
+
const gridHelper = new import_three39.GridHelper(128, 16);
|
|
16271
16652
|
this._debugHelpers.push(gridHelper);
|
|
16272
16653
|
this.scene.add(gridHelper);
|
|
16273
|
-
const gridHelper2 = new
|
|
16654
|
+
const gridHelper2 = new import_three39.GridHelper(128, 16);
|
|
16274
16655
|
this._debugHelpers.push(gridHelper2);
|
|
16275
16656
|
gridHelper2.rotation.x = 90 * (Math.PI / 180);
|
|
16276
16657
|
this.scene.add(gridHelper2);
|
|
16277
|
-
const gridHelper3 = new
|
|
16658
|
+
const gridHelper3 = new import_three39.GridHelper(128, 16);
|
|
16278
16659
|
this._debugHelpers.push(gridHelper3);
|
|
16279
16660
|
gridHelper3.rotation.z = 90 * (Math.PI / 180);
|
|
16280
16661
|
this.scene.add(gridHelper3);
|
|
16281
16662
|
}
|
|
16282
16663
|
if (this.options.debug.axes) {
|
|
16283
|
-
const axesHelper = new
|
|
16664
|
+
const axesHelper = new import_three39.AxesHelper(64);
|
|
16284
16665
|
this._debugHelpers.push(axesHelper);
|
|
16285
16666
|
this.scene.add(axesHelper);
|
|
16286
16667
|
}
|
|
@@ -16314,10 +16695,10 @@ var _Renderer = class _Renderer {
|
|
|
16314
16695
|
this._element = element;
|
|
16315
16696
|
this._element.appendChild(this.renderer.domElement);
|
|
16316
16697
|
if (this.viewWidth == 0) {
|
|
16317
|
-
|
|
16698
|
+
log18.warn("0 element width");
|
|
16318
16699
|
}
|
|
16319
16700
|
if (this.viewHeight == 0) {
|
|
16320
|
-
|
|
16701
|
+
log18.warn("0 element height");
|
|
16321
16702
|
}
|
|
16322
16703
|
this.resize(this.viewWidth, this.viewHeight);
|
|
16323
16704
|
}
|
|
@@ -16613,8 +16994,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge.default)({}, {
|
|
|
16613
16994
|
top: void 0,
|
|
16614
16995
|
bottom: void 0
|
|
16615
16996
|
},
|
|
16616
|
-
position: new
|
|
16617
|
-
lookingAt: new
|
|
16997
|
+
position: new import_three39.Vector3(50, 50, 50),
|
|
16998
|
+
lookingAt: new import_three39.Vector3(0, 0, 0)
|
|
16618
16999
|
},
|
|
16619
17000
|
render: {
|
|
16620
17001
|
fpsLimit: 60,
|
|
@@ -16741,6 +17122,23 @@ var itemContext = (withDisplayContext) => (value, path) => {
|
|
|
16741
17122
|
}
|
|
16742
17123
|
});
|
|
16743
17124
|
};
|
|
17125
|
+
function entityAnimation(value, path) {
|
|
17126
|
+
const animation = object3(value, path);
|
|
17127
|
+
if (["name", "clips"].filter((key) => animation[key] !== void 0).length !== 1) {
|
|
17128
|
+
fail(path, "expected exactly one of name or clips");
|
|
17129
|
+
}
|
|
17130
|
+
fields(value, path, { name: text, clips: (value2, path2) => {
|
|
17131
|
+
list((value3, path3) => {
|
|
17132
|
+
fields(value3, path3, { name: text, weight: nonnegative }, ["name"]);
|
|
17133
|
+
})(value2, path2);
|
|
17134
|
+
if (!value2.length) fail(path2, "expected at least one clip");
|
|
17135
|
+
const names = /* @__PURE__ */ new Set();
|
|
17136
|
+
for (const [index, clip] of value2.entries()) {
|
|
17137
|
+
if (names.has(clip.name)) fail(`${path2}[${index}].name`, `duplicate clip "${clip.name}"`);
|
|
17138
|
+
names.add(clip.name);
|
|
17139
|
+
}
|
|
17140
|
+
}, loop: boolean, speed: nonnegative, time: nonnegative, paused: boolean });
|
|
17141
|
+
}
|
|
16744
17142
|
function guiLayer(value, path) {
|
|
16745
17143
|
const layer = object3(value, path);
|
|
16746
17144
|
if (["texture", "item", "text"].filter((key) => layer[key] !== void 0).length !== 1) {
|
|
@@ -16781,13 +17179,27 @@ function validateObject(value, path) {
|
|
|
16781
17179
|
const required = ["id", "type"];
|
|
16782
17180
|
const renderOptions = { wireframe: boolean };
|
|
16783
17181
|
switch (input.type) {
|
|
16784
|
-
case "skin":
|
|
17182
|
+
case "skin": {
|
|
17183
|
+
const piece = (value2, path2) => {
|
|
17184
|
+
if (typeof value2 === "string") asset(value2, path2);
|
|
17185
|
+
else fields(value2, path2, {
|
|
17186
|
+
asset,
|
|
17187
|
+
color,
|
|
17188
|
+
glint: boolean,
|
|
17189
|
+
trim: (value3, path3) => {
|
|
17190
|
+
fields(value3, path3, { pattern: asset, material: asset }, ["pattern", "material"]);
|
|
17191
|
+
}
|
|
17192
|
+
}, ["asset"]);
|
|
17193
|
+
};
|
|
16785
17194
|
fields(value, path, {
|
|
16786
17195
|
...common,
|
|
16787
17196
|
skin: text,
|
|
16788
17197
|
cape: (value2, path2) => {
|
|
16789
17198
|
fields(value2, path2, { texture: text, layout: enumeration(["minecraft", "optifine", "labymod"]) }, ["texture"]);
|
|
16790
17199
|
},
|
|
17200
|
+
armor: (value2, path2) => {
|
|
17201
|
+
fields(value2, path2, { head: piece, chest: piece, legs: piece, feet: piece });
|
|
17202
|
+
},
|
|
16791
17203
|
hiddenParts: list(enumeration(SKIN_PARTS)),
|
|
16792
17204
|
pose: (value2, path2) => {
|
|
16793
17205
|
fields(value2, path2, {
|
|
@@ -16801,10 +17213,11 @@ function validateObject(value, path) {
|
|
|
16801
17213
|
});
|
|
16802
17214
|
},
|
|
16803
17215
|
options: (value2, path2) => {
|
|
16804
|
-
fields(value2, path2, { slim: boolean, legacy: boolean });
|
|
17216
|
+
fields(value2, path2, { slim: boolean, legacy: boolean, ears: boolean, upsideDown: boolean });
|
|
16805
17217
|
}
|
|
16806
17218
|
}, required);
|
|
16807
17219
|
break;
|
|
17220
|
+
}
|
|
16808
17221
|
case "block":
|
|
16809
17222
|
fields(value, path, {
|
|
16810
17223
|
...common,
|
|
@@ -16843,9 +17256,7 @@ function validateObject(value, path) {
|
|
|
16843
17256
|
})
|
|
16844
17257
|
});
|
|
16845
17258
|
},
|
|
16846
|
-
animation:
|
|
16847
|
-
fields(value2, path2, { name: text, loop: boolean, speed: nonnegative, time: nonnegative, paused: boolean }, ["name"]);
|
|
16848
|
-
}
|
|
17259
|
+
animation: entityAnimation
|
|
16849
17260
|
}, [...required, "asset"]);
|
|
16850
17261
|
if (Array.isArray(input.layers) && !input.layers.length) fail(`${path}.layers`, "expected at least one layer");
|
|
16851
17262
|
break;
|
|
@@ -16953,7 +17364,7 @@ async function decodeSceneDocument(value) {
|
|
|
16953
17364
|
}
|
|
16954
17365
|
|
|
16955
17366
|
// src/scene/SceneDocumentLoader.ts
|
|
16956
|
-
var
|
|
17367
|
+
var import_three41 = require("three");
|
|
16957
17368
|
init_AssetKey();
|
|
16958
17369
|
init_AssetLoader();
|
|
16959
17370
|
init_BlockStates();
|
|
@@ -17015,7 +17426,7 @@ var SceneDocumentLoader = class {
|
|
|
17015
17426
|
if (definition.minecraftVersion !== void 0 && definition.minecraftVersion !== AssetLoader.version) {
|
|
17016
17427
|
throw new Error(`Scene requires Minecraft ${definition.minecraftVersion}; call AssetLoader.setVersion("${definition.minecraftVersion}") before loading it`);
|
|
17017
17428
|
}
|
|
17018
|
-
const root = new
|
|
17429
|
+
const root = new import_three41.Group();
|
|
17019
17430
|
root.name = "MineRender scene document";
|
|
17020
17431
|
const objects = [];
|
|
17021
17432
|
let disposed = false;
|
|
@@ -17055,7 +17466,7 @@ var SceneDocumentLoader = class {
|
|
|
17055
17466
|
return this.loadValidatedObject(scene, definition, parent);
|
|
17056
17467
|
}
|
|
17057
17468
|
static async loadValidatedObject(scene, definition, parent) {
|
|
17058
|
-
const root = new
|
|
17469
|
+
const root = new import_three41.Group();
|
|
17059
17470
|
root.name = definition.name ?? definition.id;
|
|
17060
17471
|
root.userData.sceneObjectId = definition.id;
|
|
17061
17472
|
root.position.fromArray(definition.position ?? [0, 0, 0]);
|
|
@@ -17074,6 +17485,7 @@ var SceneDocumentLoader = class {
|
|
|
17074
17485
|
await skin.setSkinTexture(texture);
|
|
17075
17486
|
await content.initialize(skin);
|
|
17076
17487
|
if (definition.cape) await skin.setCapeTexture(await skinTexture(definition.cape.texture, true), definition.cape.layout);
|
|
17488
|
+
if (definition.armor) await skin.setArmor(definition.armor);
|
|
17077
17489
|
for (const [part, rotation] of Object.entries(definition.pose ?? {})) {
|
|
17078
17490
|
skin.getGroupByName(part)?.rotation.set(...rotation, "XYZ");
|
|
17079
17491
|
}
|
|
@@ -17112,10 +17524,20 @@ var SceneDocumentLoader = class {
|
|
|
17112
17524
|
const entity = await content.addEntity(model, { ...definition.options, instanceMeshes: false });
|
|
17113
17525
|
object4 = entity;
|
|
17114
17526
|
if (definition.animation) {
|
|
17527
|
+
const animation = definition.animation;
|
|
17115
17528
|
const animations = await Entities.getAnimations(key);
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17529
|
+
if (animation.name !== void 0) {
|
|
17530
|
+
const clip = animations && Object.prototype.hasOwnProperty.call(animations, animation.name) ? animations[animation.name] : void 0;
|
|
17531
|
+
if (!clip) throw new Error(`Entity ${definition.asset} has no animation "${animation.name}"`);
|
|
17532
|
+
entity.playAnimation(clip, animation);
|
|
17533
|
+
} else {
|
|
17534
|
+
const clips = animation.clips.map(({ name }) => {
|
|
17535
|
+
const clip = animations && Object.prototype.hasOwnProperty.call(animations, name) ? animations[name] : void 0;
|
|
17536
|
+
if (!clip) throw new Error(`Entity ${definition.asset} has no animation "${name}"`);
|
|
17537
|
+
return clip;
|
|
17538
|
+
});
|
|
17539
|
+
entity.playAnimations(clips, { ...animation, weights: animation.clips.map((clip) => clip.weight ?? 1) });
|
|
17540
|
+
}
|
|
17119
17541
|
}
|
|
17120
17542
|
break;
|
|
17121
17543
|
}
|
|
@@ -17164,6 +17586,7 @@ init_Skins();
|
|
|
17164
17586
|
|
|
17165
17587
|
// src/texture/index.ts
|
|
17166
17588
|
init_Colormaps();
|
|
17589
|
+
init_PalettedTextures();
|
|
17167
17590
|
init_TextureAtlas();
|
|
17168
17591
|
init_TextureLoader();
|
|
17169
17592
|
init_Textures();
|
|
@@ -17953,7 +18376,7 @@ var AnvilWorldSource = class {
|
|
|
17953
18376
|
read.waiters++;
|
|
17954
18377
|
return new Promise((resolve, reject) => {
|
|
17955
18378
|
let finished = false;
|
|
17956
|
-
const
|
|
18379
|
+
const release = () => {
|
|
17957
18380
|
if (finished) return false;
|
|
17958
18381
|
finished = true;
|
|
17959
18382
|
signal?.removeEventListener("abort", abort);
|
|
@@ -17961,7 +18384,7 @@ var AnvilWorldSource = class {
|
|
|
17961
18384
|
return true;
|
|
17962
18385
|
};
|
|
17963
18386
|
const abort = () => {
|
|
17964
|
-
if (!
|
|
18387
|
+
if (!release()) return;
|
|
17965
18388
|
if (!read.waiters && !read.settled) {
|
|
17966
18389
|
if (this.pending.get(key) === read) this.pending.delete(key);
|
|
17967
18390
|
read.controller.abort(signal.reason);
|
|
@@ -17971,10 +18394,10 @@ var AnvilWorldSource = class {
|
|
|
17971
18394
|
signal?.addEventListener("abort", abort, { once: true });
|
|
17972
18395
|
read.promise.then(
|
|
17973
18396
|
(data) => {
|
|
17974
|
-
if (
|
|
18397
|
+
if (release()) resolve(data);
|
|
17975
18398
|
},
|
|
17976
18399
|
(error) => {
|
|
17977
|
-
if (
|
|
18400
|
+
if (release()) reject(error);
|
|
17978
18401
|
}
|
|
17979
18402
|
);
|
|
17980
18403
|
if (signal?.aborted) abort();
|
|
@@ -17996,20 +18419,22 @@ var AnvilWorldSource = class {
|
|
|
17996
18419
|
};
|
|
17997
18420
|
|
|
17998
18421
|
// src/world/Chunk.ts
|
|
17999
|
-
|
|
18422
|
+
init_BlockObject();
|
|
18423
|
+
var import_three48 = require("three");
|
|
18000
18424
|
init_BlockStates();
|
|
18001
18425
|
init_AssetKey();
|
|
18002
18426
|
|
|
18003
18427
|
// src/world/MineRenderWorld.ts
|
|
18004
|
-
var
|
|
18428
|
+
var import_three46 = require("three");
|
|
18005
18429
|
init_Model();
|
|
18006
18430
|
init_util();
|
|
18007
18431
|
init_AssetKey();
|
|
18008
18432
|
init_BlockStates();
|
|
18433
|
+
init_BlockEntities();
|
|
18009
18434
|
init_CubeFace();
|
|
18010
18435
|
|
|
18011
18436
|
// src/world/SectionModels.ts
|
|
18012
|
-
var
|
|
18437
|
+
var import_three42 = require("three");
|
|
18013
18438
|
init_AssetKey();
|
|
18014
18439
|
init_Models();
|
|
18015
18440
|
init_CubeFace();
|
|
@@ -18035,7 +18460,7 @@ function cached(map, key, load) {
|
|
|
18035
18460
|
}
|
|
18036
18461
|
function compactQuads(geometry, keep) {
|
|
18037
18462
|
const quads = keep.flatMap((kept, index) => kept ? [index] : []);
|
|
18038
|
-
const compact = new
|
|
18463
|
+
const compact = new import_three42.BufferGeometry();
|
|
18039
18464
|
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3, shade: 1 })) {
|
|
18040
18465
|
const source2 = geometry.getAttribute(name);
|
|
18041
18466
|
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : name === "shade" ? [1] : void 0;
|
|
@@ -18047,7 +18472,7 @@ function compactQuads(geometry, keep) {
|
|
|
18047
18472
|
}
|
|
18048
18473
|
}
|
|
18049
18474
|
}
|
|
18050
|
-
compact.setAttribute(name, new
|
|
18475
|
+
compact.setAttribute(name, new import_three42.BufferAttribute(values, size));
|
|
18051
18476
|
}
|
|
18052
18477
|
const source = geometry.getIndex();
|
|
18053
18478
|
const indices = [];
|
|
@@ -18103,6 +18528,10 @@ var SectionModels = class {
|
|
|
18103
18528
|
biomeTint: source ? [...templates.values()].some((template) => template.biomeTint?.some((value) => value === 1)) || void 0 : void 0
|
|
18104
18529
|
};
|
|
18105
18530
|
}
|
|
18531
|
+
/** Starts loading the state's models and atlases so a later `prepareState` with the same properties finds them loaded. */
|
|
18532
|
+
async preload(blockState3, properties = {}) {
|
|
18533
|
+
await this.state(blockState3, properties);
|
|
18534
|
+
}
|
|
18106
18535
|
async state(blockState3, properties) {
|
|
18107
18536
|
let states = this.states.get(blockState3);
|
|
18108
18537
|
if (!states) this.states.set(blockState3, states = /* @__PURE__ */ new Map());
|
|
@@ -18125,22 +18554,24 @@ var SectionModels = class {
|
|
|
18125
18554
|
async prepare(blockState3, properties) {
|
|
18126
18555
|
const state = { ...await BlockStateResolver.defaults(blockState3), ...properties };
|
|
18127
18556
|
const groups = BlockStateResolver.matching(blockState3, state);
|
|
18128
|
-
if (!groups.length) return void 0;
|
|
18557
|
+
if (!groups.length || groups.some((group) => Array.isArray(group) && !group.length)) return void 0;
|
|
18558
|
+
const variants = groups.flatMap((group) => Array.isArray(group) ? group : [group]);
|
|
18559
|
+
if (variants.some((variant) => !variant.model)) return void 0;
|
|
18560
|
+
const settled = await Promise.allSettled(variants.map(async (variant) => {
|
|
18561
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
18562
|
+
modelKey.root = blockState3.key?.root;
|
|
18563
|
+
const model = await Models.getMerged(modelKey);
|
|
18564
|
+
if (!model?.elements?.length) return void 0;
|
|
18565
|
+
const atlas = await UVMapper.getAtlas(model);
|
|
18566
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
18567
|
+
if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
|
|
18568
|
+
return { model, atlas, rotation };
|
|
18569
|
+
}));
|
|
18129
18570
|
const prepared = /* @__PURE__ */ new Map();
|
|
18130
|
-
for (const
|
|
18131
|
-
|
|
18132
|
-
if (!
|
|
18133
|
-
|
|
18134
|
-
if (!variant.model) return void 0;
|
|
18135
|
-
const modelKey = AssetKey.parse("models", variant.model);
|
|
18136
|
-
modelKey.root = blockState3.key?.root;
|
|
18137
|
-
const model = await Models.getMerged(modelKey);
|
|
18138
|
-
if (!model?.elements?.length) return void 0;
|
|
18139
|
-
const atlas = await UVMapper.getAtlas(model);
|
|
18140
|
-
const rotation = BlockStateResolver.rotation(variant);
|
|
18141
|
-
if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
|
|
18142
|
-
prepared.set(variant, { model, atlas, rotation });
|
|
18143
|
-
}
|
|
18571
|
+
for (const [i, result] of settled.entries()) {
|
|
18572
|
+
if (result.status === "rejected") throw result.reason;
|
|
18573
|
+
if (!result.value) return void 0;
|
|
18574
|
+
prepared.set(variants[i], result.value);
|
|
18144
18575
|
}
|
|
18145
18576
|
return { state, groups, choices: prepared };
|
|
18146
18577
|
}
|
|
@@ -18157,7 +18588,7 @@ var SectionModels = class {
|
|
|
18157
18588
|
});
|
|
18158
18589
|
await object4.init();
|
|
18159
18590
|
let geometry = object4.children[0].geometry;
|
|
18160
|
-
geometry.applyMatrix4(new
|
|
18591
|
+
geometry.applyMatrix4(new import_three42.Matrix4().makeRotationFromEuler(rotation));
|
|
18161
18592
|
object4.clear();
|
|
18162
18593
|
const keep = [];
|
|
18163
18594
|
const cullFaces = [];
|
|
@@ -18173,7 +18604,7 @@ var SectionModels = class {
|
|
|
18173
18604
|
cullFaces.push(0);
|
|
18174
18605
|
continue;
|
|
18175
18606
|
}
|
|
18176
|
-
const normal = new
|
|
18607
|
+
const normal = new import_three42.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
|
|
18177
18608
|
const world = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
|
|
18178
18609
|
cullFaces.push(world < 0 ? 0 : 1 << world);
|
|
18179
18610
|
}
|
|
@@ -18277,10 +18708,10 @@ function resolveSavedEntity(entity) {
|
|
|
18277
18708
|
|
|
18278
18709
|
// src/world/_entities/WorldEntities.ts
|
|
18279
18710
|
init_BannerPatterns();
|
|
18280
|
-
var
|
|
18711
|
+
var import_three45 = require("three");
|
|
18281
18712
|
|
|
18282
18713
|
// src/world/_picking/Picking.ts
|
|
18283
|
-
var
|
|
18714
|
+
var import_three43 = require("three");
|
|
18284
18715
|
init_three();
|
|
18285
18716
|
function pickableMeshes(root, scene, raycaster) {
|
|
18286
18717
|
const result = [];
|
|
@@ -18308,16 +18739,16 @@ function hitNormal(hit) {
|
|
|
18308
18739
|
const mesh = hit.object;
|
|
18309
18740
|
const matrix = mesh.matrixWorld.clone();
|
|
18310
18741
|
if (isInstancedMesh(mesh) && hit.instanceId !== void 0) {
|
|
18311
|
-
const instance = new
|
|
18742
|
+
const instance = new import_three43.Matrix4();
|
|
18312
18743
|
mesh.getMatrixAt(hit.instanceId, instance);
|
|
18313
18744
|
matrix.multiply(instance);
|
|
18314
18745
|
}
|
|
18315
|
-
return hit.face.normal.clone().applyNormalMatrix(new
|
|
18746
|
+
return hit.face.normal.clone().applyNormalMatrix(new import_three43.Matrix3().getNormalMatrix(matrix));
|
|
18316
18747
|
}
|
|
18317
18748
|
|
|
18318
18749
|
// src/world/_entities/WorldEntities.ts
|
|
18319
18750
|
init_log();
|
|
18320
|
-
var
|
|
18751
|
+
var log19 = logger("WorldEntities");
|
|
18321
18752
|
var WorldEntities = class {
|
|
18322
18753
|
constructor(scene) {
|
|
18323
18754
|
this.scene = scene;
|
|
@@ -18338,7 +18769,7 @@ var WorldEntities = class {
|
|
|
18338
18769
|
const owner = owners.get(mesh);
|
|
18339
18770
|
return {
|
|
18340
18771
|
type: owner.type,
|
|
18341
|
-
position: new
|
|
18772
|
+
position: new import_three45.Vector3(...owner.position),
|
|
18342
18773
|
object: owner.object,
|
|
18343
18774
|
point: hit.point.clone(),
|
|
18344
18775
|
normal: hitNormal(hit),
|
|
@@ -18386,7 +18817,7 @@ var WorldEntities = class {
|
|
|
18386
18817
|
placement.owner.set(object4, { type: key.toNamespacedString(), position: placement.position });
|
|
18387
18818
|
this.scene.add(object4);
|
|
18388
18819
|
} catch (error) {
|
|
18389
|
-
|
|
18820
|
+
log19.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
|
|
18390
18821
|
} finally {
|
|
18391
18822
|
if (object4 && !placement.owner.has(object4)) object4.dispose();
|
|
18392
18823
|
}
|
|
@@ -18599,7 +19030,8 @@ function skipsBlockFace(data, rule, block, neighbor, face) {
|
|
|
18599
19030
|
|
|
18600
19031
|
// src/world/MineRenderWorld.ts
|
|
18601
19032
|
init_log();
|
|
18602
|
-
var
|
|
19033
|
+
var log20 = logger("MineRenderWorld");
|
|
19034
|
+
var YIELD_INTERVAL_MS = 8;
|
|
18603
19035
|
var MineRenderWorld = class {
|
|
18604
19036
|
constructor(scene, options = {}) {
|
|
18605
19037
|
this._chunks = /* @__PURE__ */ new Map();
|
|
@@ -18713,7 +19145,7 @@ var MineRenderWorld = class {
|
|
|
18713
19145
|
failures.set(chunk, error);
|
|
18714
19146
|
if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) === chunk) this.pendingBiomes.set(chunk, void 0);
|
|
18715
19147
|
}
|
|
18716
|
-
if (performance.now() - sliceStart >
|
|
19148
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18717
19149
|
await yieldToEventLoop();
|
|
18718
19150
|
sliceStart = performance.now();
|
|
18719
19151
|
}
|
|
@@ -18726,25 +19158,25 @@ var MineRenderWorld = class {
|
|
|
18726
19158
|
}
|
|
18727
19159
|
getBlockAt(posOrX, y, z) {
|
|
18728
19160
|
if (typeof posOrX == "number") {
|
|
18729
|
-
return this.getBlockAt(new
|
|
19161
|
+
return this.getBlockAt(new import_three46.Vector3(posOrX, y, z));
|
|
18730
19162
|
}
|
|
18731
19163
|
if (isTripleArray(posOrX)) {
|
|
18732
|
-
return this.getBlockAt(new
|
|
19164
|
+
return this.getBlockAt(new import_three46.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
18733
19165
|
}
|
|
18734
19166
|
this.validatePosBounds(posOrX);
|
|
18735
19167
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
18736
19168
|
}
|
|
18737
19169
|
getBiomeAt(posOrX, y, z) {
|
|
18738
|
-
if (typeof posOrX === "number") return this.getBiomeAt(new
|
|
18739
|
-
if (isTripleArray(posOrX)) return this.getBiomeAt(new
|
|
19170
|
+
if (typeof posOrX === "number") return this.getBiomeAt(new import_three46.Vector3(posOrX, y, z));
|
|
19171
|
+
if (isTripleArray(posOrX)) return this.getBiomeAt(new import_three46.Vector3(...posOrX));
|
|
18740
19172
|
this.validatePosBounds(posOrX);
|
|
18741
19173
|
const cx = Math.floor(posOrX.x / 16), cy = Math.floor(posOrX.y / 16), cz = Math.floor(posOrX.z / 16);
|
|
18742
19174
|
const lx = posOrX.x - cx * 16, ly = posOrX.y - cy * 16, lz = posOrX.z - cz * 16;
|
|
18743
19175
|
return this.biomes.get(`${cx}_${cz}`)?.get(cy)?.[Math.floor(lx / 4) + Math.floor(lz / 4) * 4 + Math.floor(ly / 4) * 16];
|
|
18744
19176
|
}
|
|
18745
19177
|
getLightAt(posOrX, y, z) {
|
|
18746
|
-
if (typeof posOrX === "number") return this.getLightAt(new
|
|
18747
|
-
if (isTripleArray(posOrX)) return this.getLightAt(new
|
|
19178
|
+
if (typeof posOrX === "number") return this.getLightAt(new import_three46.Vector3(posOrX, y, z));
|
|
19179
|
+
if (isTripleArray(posOrX)) return this.getLightAt(new import_three46.Vector3(...posOrX));
|
|
18748
19180
|
this.validatePosBounds(posOrX);
|
|
18749
19181
|
const { x, y: py, z: pz } = posOrX;
|
|
18750
19182
|
const cx = Math.floor(x / 16), cy = Math.floor(py / 16), cz = Math.floor(pz / 16);
|
|
@@ -18762,10 +19194,10 @@ var MineRenderWorld = class {
|
|
|
18762
19194
|
}
|
|
18763
19195
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
18764
19196
|
if (typeof posOrX == "number") {
|
|
18765
|
-
return this.setBlockAt(new
|
|
19197
|
+
return this.setBlockAt(new import_three46.Vector3(posOrX, yOrBlock, z), block);
|
|
18766
19198
|
}
|
|
18767
19199
|
if (isTripleArray(posOrX)) {
|
|
18768
|
-
return this.setBlockAt(new
|
|
19200
|
+
return this.setBlockAt(new import_three46.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
18769
19201
|
}
|
|
18770
19202
|
return this.placeBlock(posOrX, yOrBlock);
|
|
18771
19203
|
}
|
|
@@ -18776,10 +19208,10 @@ var MineRenderWorld = class {
|
|
|
18776
19208
|
}
|
|
18777
19209
|
async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
|
|
18778
19210
|
if (typeof posOrX === "number") {
|
|
18779
|
-
return this.setBlockVisibleAt(new
|
|
19211
|
+
return this.setBlockVisibleAt(new import_three46.Vector3(posOrX, yOrVisible, z), visible);
|
|
18780
19212
|
}
|
|
18781
19213
|
if (isTripleArray(posOrX)) {
|
|
18782
|
-
return this.setBlockVisibleAt(new
|
|
19214
|
+
return this.setBlockVisibleAt(new import_three46.Vector3(...posOrX), yOrVisible);
|
|
18783
19215
|
}
|
|
18784
19216
|
this.validatePosBounds(posOrX);
|
|
18785
19217
|
await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
|
|
@@ -18805,7 +19237,7 @@ var MineRenderWorld = class {
|
|
|
18805
19237
|
const collect = async (positions2) => {
|
|
18806
19238
|
for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
|
|
18807
19239
|
};
|
|
18808
|
-
const place = (block) => this.placeBlock(new
|
|
19240
|
+
const place = (block) => this.placeBlock(new import_three46.Vector3(...block.position), block, collect);
|
|
18809
19241
|
const keys = /* @__PURE__ */ new Map();
|
|
18810
19242
|
const types = /* @__PURE__ */ new Set();
|
|
18811
19243
|
for (const block of multiblock.blocks) {
|
|
@@ -18814,15 +19246,18 @@ var MineRenderWorld = class {
|
|
|
18814
19246
|
const key = AssetKey.parse("blockstates", block.type);
|
|
18815
19247
|
keys.set(key.serialize(), key);
|
|
18816
19248
|
}
|
|
18817
|
-
await BlockStates.getAll(keys.values());
|
|
19249
|
+
const loaded = await BlockStates.getAll(keys.values());
|
|
19250
|
+
const states = new Map([...keys.keys()].map((key, i) => [key, loaded[i]]));
|
|
18818
19251
|
if (!useBatches) {
|
|
18819
19252
|
for (const block of multiblock.blocks) await place(block);
|
|
18820
19253
|
return;
|
|
18821
19254
|
}
|
|
18822
19255
|
if (!executor) {
|
|
18823
19256
|
const groups2 = /* @__PURE__ */ new Map();
|
|
18824
|
-
const
|
|
19257
|
+
const distinct = /* @__PURE__ */ new Map();
|
|
19258
|
+
const position = new import_three46.Vector3();
|
|
18825
19259
|
for (const block of multiblock.blocks) {
|
|
19260
|
+
if (this.sectionModels && !Chunk.isAir(block)) distinct.set(ChunkData.paletteKey(block), block);
|
|
18826
19261
|
const [x, y, z] = block.position;
|
|
18827
19262
|
this.validatePosBounds(position.set(x, y, z));
|
|
18828
19263
|
const cx = Math.floor(x / 16), cy = Math.floor(y / 16), cz = Math.floor(z / 16);
|
|
@@ -18833,6 +19268,16 @@ var MineRenderWorld = class {
|
|
|
18833
19268
|
if (!group) groups2.set(chunk, group = []);
|
|
18834
19269
|
group.push({ index: (y - cy * 16) * 256 + (z - cz * 16) * 16 + x - cx * 16, block });
|
|
18835
19270
|
}
|
|
19271
|
+
if (this.sectionModels) {
|
|
19272
|
+
for (const block of distinct.values()) {
|
|
19273
|
+
const state = states.get(AssetKey.parse("blockstates", block.type).serialize());
|
|
19274
|
+
if (!state) continue;
|
|
19275
|
+
void (async () => {
|
|
19276
|
+
if (state.key && BlockEntities.entry(await BlockEntities.getIndex(state.key.root), state.key.toNamespacedString())) return;
|
|
19277
|
+
await this.sectionModels.preload(state, block.properties);
|
|
19278
|
+
})().catch(() => void 0);
|
|
19279
|
+
}
|
|
19280
|
+
}
|
|
18836
19281
|
await this.placeChunkGroups(groups2, changes);
|
|
18837
19282
|
return;
|
|
18838
19283
|
}
|
|
@@ -18861,14 +19306,14 @@ var MineRenderWorld = class {
|
|
|
18861
19306
|
try {
|
|
18862
19307
|
positions = await chunk.placeBlocks(blocks);
|
|
18863
19308
|
} finally {
|
|
18864
|
-
positions ?? (positions = blocks.map(({ index }) => new
|
|
19309
|
+
positions ?? (positions = blocks.map(({ index }) => new import_three46.Vector3(
|
|
18865
19310
|
chunk.x * 16 + index % 16,
|
|
18866
19311
|
chunk.y * 16 + Math.floor(index / 256),
|
|
18867
19312
|
chunk.z * 16 + Math.floor(index / 16) % 16
|
|
18868
19313
|
)));
|
|
18869
19314
|
for (const pos of positions) changes.set(`${pos.x},${pos.y},${pos.z}`, pos);
|
|
18870
19315
|
}
|
|
18871
|
-
if (performance.now() - sliceStart >
|
|
19316
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18872
19317
|
await yieldToEventLoop();
|
|
18873
19318
|
sliceStart = performance.now();
|
|
18874
19319
|
}
|
|
@@ -18876,6 +19321,62 @@ var MineRenderWorld = class {
|
|
|
18876
19321
|
}
|
|
18877
19322
|
/** Replaces a chunk column's blocks, biomes, and saved light and, with `renderEntities`, its supported saved mobs. */
|
|
18878
19323
|
async placeChunk(chunk, executor) {
|
|
19324
|
+
return this.placeColumn(chunk, executor);
|
|
19325
|
+
}
|
|
19326
|
+
/**
|
|
19327
|
+
* Replaces parsed columns in input order, then refreshes neighboring geometry once.
|
|
19328
|
+
* Duplicate coordinates retain their order. A failed column stops placement; queued refreshes finish before rejection.
|
|
19329
|
+
*/
|
|
19330
|
+
async placeChunks(chunks) {
|
|
19331
|
+
const columns = [];
|
|
19332
|
+
for (const chunk of chunks) {
|
|
19333
|
+
const { x, z } = chunk ?? {};
|
|
19334
|
+
if (![x, z].every(Number.isSafeInteger)) {
|
|
19335
|
+
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
19336
|
+
}
|
|
19337
|
+
const sections = Array.from(chunk.sections, (section) => {
|
|
19338
|
+
const { y } = section ?? {};
|
|
19339
|
+
if (!Number.isSafeInteger(y)) throw new RangeError("Chunk section coordinates must be safe integers");
|
|
19340
|
+
return { ...section, y };
|
|
19341
|
+
});
|
|
19342
|
+
columns.push({ ...chunk, x, z, sections });
|
|
19343
|
+
}
|
|
19344
|
+
if (!columns.length) return;
|
|
19345
|
+
await this.culling;
|
|
19346
|
+
let failed = false, failure, sliceStart = performance.now();
|
|
19347
|
+
try {
|
|
19348
|
+
for (const column of columns) {
|
|
19349
|
+
await this.placeColumn(column, void 0, true);
|
|
19350
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19351
|
+
await yieldToEventLoop();
|
|
19352
|
+
sliceStart = performance.now();
|
|
19353
|
+
}
|
|
19354
|
+
}
|
|
19355
|
+
} catch (error) {
|
|
19356
|
+
failed = true;
|
|
19357
|
+
failure = error;
|
|
19358
|
+
} finally {
|
|
19359
|
+
try {
|
|
19360
|
+
const failures = await this.refreshBiomes(true);
|
|
19361
|
+
if (failures.size) log20.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
19362
|
+
} catch (error) {
|
|
19363
|
+
if (!failed) {
|
|
19364
|
+
failed = true;
|
|
19365
|
+
failure = error;
|
|
19366
|
+
}
|
|
19367
|
+
}
|
|
19368
|
+
try {
|
|
19369
|
+
await this.updateCulling([]);
|
|
19370
|
+
} catch (error) {
|
|
19371
|
+
if (!failed) {
|
|
19372
|
+
failed = true;
|
|
19373
|
+
failure = error;
|
|
19374
|
+
}
|
|
19375
|
+
}
|
|
19376
|
+
}
|
|
19377
|
+
if (failed) throw failure;
|
|
19378
|
+
}
|
|
19379
|
+
async placeColumn(chunk, executor, deferCulling = false) {
|
|
18879
19380
|
if (![chunk.x, chunk.z].every(Number.isSafeInteger)) {
|
|
18880
19381
|
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
18881
19382
|
}
|
|
@@ -18913,7 +19414,7 @@ var MineRenderWorld = class {
|
|
|
18913
19414
|
}
|
|
18914
19415
|
for (const section of chunk.sections) {
|
|
18915
19416
|
if (section.biomes) {
|
|
18916
|
-
const position = new
|
|
19417
|
+
const position = new import_three46.Vector3(chunk.x * 16, section.y * 16, chunk.z * 16);
|
|
18917
19418
|
this.validatePosBounds(position);
|
|
18918
19419
|
const copy = [...section.biomes];
|
|
18919
19420
|
if (copy.length !== 64 || !copy.every((id) => typeof id === "string" && id.length > 0)) {
|
|
@@ -18929,7 +19430,7 @@ var MineRenderWorld = class {
|
|
|
18929
19430
|
for (const section of chunk.sections) {
|
|
18930
19431
|
if (!executor) {
|
|
18931
19432
|
if (!occupiedSections.has(section.y)) continue;
|
|
18932
|
-
const position = new
|
|
19433
|
+
const position = new import_three46.Vector3(chunk.x * 16, section.y * 16, chunk.z * 16);
|
|
18933
19434
|
this.validatePosBounds(position);
|
|
18934
19435
|
const target = this.getOrCreateChunkAt(position);
|
|
18935
19436
|
try {
|
|
@@ -18937,7 +19438,7 @@ var MineRenderWorld = class {
|
|
|
18937
19438
|
} finally {
|
|
18938
19439
|
this.markSectionChanged(target);
|
|
18939
19440
|
}
|
|
18940
|
-
if (performance.now() - sliceStart >
|
|
19441
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18941
19442
|
await yieldToEventLoop();
|
|
18942
19443
|
sliceStart = performance.now();
|
|
18943
19444
|
}
|
|
@@ -18960,9 +19461,12 @@ var MineRenderWorld = class {
|
|
|
18960
19461
|
await placeEntities?.();
|
|
18961
19462
|
} finally {
|
|
18962
19463
|
this.markBiomesChanged(chunk.x, chunk.z, void 0, false);
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
19464
|
+
if (deferCulling) await this.updateCulling([...changes.values()], true);
|
|
19465
|
+
else {
|
|
19466
|
+
const failures = await this.refreshBiomes();
|
|
19467
|
+
if (failures.size) log20.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
19468
|
+
await this.updateCulling([...changes.values()]);
|
|
19469
|
+
}
|
|
18966
19470
|
}
|
|
18967
19471
|
}
|
|
18968
19472
|
/**
|
|
@@ -18992,14 +19496,14 @@ var MineRenderWorld = class {
|
|
|
18992
19496
|
for (const { x, z } of columns.values()) {
|
|
18993
19497
|
this.entities?.clearColumn(x, z);
|
|
18994
19498
|
await this.clearChunkColumn(x, z);
|
|
18995
|
-
if (performance.now() - sliceStart >
|
|
19499
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18996
19500
|
await yieldToEventLoop();
|
|
18997
19501
|
sliceStart = performance.now();
|
|
18998
19502
|
}
|
|
18999
19503
|
}
|
|
19000
19504
|
} finally {
|
|
19001
19505
|
const failures = await this.refreshBiomes(true);
|
|
19002
|
-
if (failures.size)
|
|
19506
|
+
if (failures.size) log20.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
19003
19507
|
await this.updateCulling([]);
|
|
19004
19508
|
}
|
|
19005
19509
|
}
|
|
@@ -19062,7 +19566,7 @@ var MineRenderWorld = class {
|
|
|
19062
19566
|
this.sectionModels?.clear();
|
|
19063
19567
|
}
|
|
19064
19568
|
updateCulling(positions, defer = false) {
|
|
19065
|
-
const neighbor = new
|
|
19569
|
+
const neighbor = new import_three46.Vector3();
|
|
19066
19570
|
for (const pos of positions) {
|
|
19067
19571
|
const cx = Math.floor(pos.x / 16), cy = Math.floor(pos.y / 16), cz = Math.floor(pos.z / 16);
|
|
19068
19572
|
const chunk = this._chunks.get(`${cx}_${cy}_${cz}`);
|
|
@@ -19131,15 +19635,25 @@ var MineRenderWorld = class {
|
|
|
19131
19635
|
for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
|
|
19132
19636
|
await chunk.refreshLight(indices === "all" ? void 0 : indices);
|
|
19133
19637
|
chunk.refreshAmbientOcclusion(this._ambientOcclusion);
|
|
19134
|
-
if (
|
|
19638
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19135
19639
|
await yieldToEventLoop();
|
|
19136
19640
|
sliceStart = performance.now();
|
|
19137
19641
|
}
|
|
19138
19642
|
}
|
|
19139
|
-
const
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19643
|
+
const pending = [];
|
|
19644
|
+
for (const chunk of [...batch.keys()]) {
|
|
19645
|
+
const build = (async () => {
|
|
19646
|
+
await chunk.rebuildSectionMesh();
|
|
19647
|
+
batch.delete(chunk);
|
|
19648
|
+
})();
|
|
19649
|
+
void build.catch(() => void 0);
|
|
19650
|
+
pending.push(build);
|
|
19651
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19652
|
+
await yieldToEventLoop();
|
|
19653
|
+
sliceStart = performance.now();
|
|
19654
|
+
}
|
|
19655
|
+
}
|
|
19656
|
+
const builds = await Promise.allSettled(pending);
|
|
19143
19657
|
const failure = builds.find((result) => result.status === "rejected");
|
|
19144
19658
|
if (failure?.status === "rejected") throw failure.reason;
|
|
19145
19659
|
} catch (error) {
|
|
@@ -19222,7 +19736,7 @@ var MineRenderWorld = class {
|
|
|
19222
19736
|
}
|
|
19223
19737
|
/** Converts block coordinates to scene units by multiplying each component by 16. */
|
|
19224
19738
|
static worldToScenePosition(pos) {
|
|
19225
|
-
return new
|
|
19739
|
+
return new import_three46.Vector3(
|
|
19226
19740
|
pos.x * 16,
|
|
19227
19741
|
pos.y * 16,
|
|
19228
19742
|
pos.z * 16
|
|
@@ -19230,7 +19744,7 @@ var MineRenderWorld = class {
|
|
|
19230
19744
|
}
|
|
19231
19745
|
/** Converts scene units to block coordinates without rounding to an integer block. */
|
|
19232
19746
|
static sceneToWorldPosition(pos) {
|
|
19233
|
-
return new
|
|
19747
|
+
return new import_three46.Vector3(
|
|
19234
19748
|
pos.x / 16,
|
|
19235
19749
|
pos.y / 16,
|
|
19236
19750
|
pos.z / 16
|
|
@@ -19254,7 +19768,7 @@ init_Model();
|
|
|
19254
19768
|
init_BlockEntities();
|
|
19255
19769
|
|
|
19256
19770
|
// src/world/SectionMesh.ts
|
|
19257
|
-
var
|
|
19771
|
+
var import_three47 = require("three");
|
|
19258
19772
|
init_CanvasCompat();
|
|
19259
19773
|
init_Materials();
|
|
19260
19774
|
|
|
@@ -19531,6 +20045,8 @@ function sectionGeometryTransferables(pages) {
|
|
|
19531
20045
|
|
|
19532
20046
|
// src/world/SectionWorker.ts
|
|
19533
20047
|
init_Env();
|
|
20048
|
+
init_log();
|
|
20049
|
+
var log21 = logger("SectionWorker");
|
|
19534
20050
|
var _SectionWorker = class _SectionWorker {
|
|
19535
20051
|
constructor(worker) {
|
|
19536
20052
|
this.worker = worker;
|
|
@@ -19544,8 +20060,12 @@ var _SectionWorker = class _SectionWorker {
|
|
|
19544
20060
|
if (reply.type === "pages") pending.resolve(reply.pages);
|
|
19545
20061
|
else pending.reject(new Error(reply.message));
|
|
19546
20062
|
});
|
|
19547
|
-
|
|
19548
|
-
|
|
20063
|
+
const fallBack = (message) => {
|
|
20064
|
+
log21.warn(`${message}, so sections build on the main thread`);
|
|
20065
|
+
this.fail(message);
|
|
20066
|
+
};
|
|
20067
|
+
worker.addEventListener("error", (event) => fallBack(event.message || "Section worker failed"));
|
|
20068
|
+
worker.addEventListener("messageerror", () => fallBack("Section worker message could not be deserialized"));
|
|
19549
20069
|
}
|
|
19550
20070
|
/** The shared worker, or undefined when the environment has none or a previous worker failed. */
|
|
19551
20071
|
static shared() {
|
|
@@ -19582,8 +20102,11 @@ _SectionWorker.initialized = false;
|
|
|
19582
20102
|
var SectionWorker = _SectionWorker;
|
|
19583
20103
|
|
|
19584
20104
|
// src/world/SectionMesh.ts
|
|
20105
|
+
var BLOCK_SIZE = 16;
|
|
20106
|
+
var QUAD_VERTICES = 4;
|
|
20107
|
+
var QUAD_INDICES = 6;
|
|
19585
20108
|
var templateCache = /* @__PURE__ */ new WeakMap();
|
|
19586
|
-
var WATER_TINT = new
|
|
20109
|
+
var WATER_TINT = new import_three47.Color(4159204).toArray();
|
|
19587
20110
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19588
20111
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19589
20112
|
const atlases2 = [];
|
|
@@ -19618,8 +20141,8 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19618
20141
|
if (!data) {
|
|
19619
20142
|
const indices = template.geometry.getIndex();
|
|
19620
20143
|
const position = template.geometry.getAttribute("position");
|
|
19621
|
-
const quads = indices.count /
|
|
19622
|
-
if (indices.count %
|
|
20144
|
+
const quads = indices.count / QUAD_INDICES;
|
|
20145
|
+
if (indices.count % QUAD_INDICES !== 0 || position.count !== quads * QUAD_VERTICES) {
|
|
19623
20146
|
throw new RangeError("Section template geometry must hold four vertices and six indices per quad");
|
|
19624
20147
|
}
|
|
19625
20148
|
data = {
|
|
@@ -19629,8 +20152,8 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19629
20152
|
uvs: new Float32Array(quads * 8),
|
|
19630
20153
|
uvBounds: new Float32Array(quads * 16),
|
|
19631
20154
|
colors: new Float32Array(quads * 12),
|
|
19632
|
-
shade: new Float32Array(quads *
|
|
19633
|
-
indices: new Uint16Array(quads *
|
|
20155
|
+
shade: new Float32Array(quads * QUAD_VERTICES),
|
|
20156
|
+
indices: new Uint16Array(quads * QUAD_INDICES),
|
|
19634
20157
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
19635
20158
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
19636
20159
|
atlas: 0,
|
|
@@ -19642,7 +20165,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19642
20165
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
19643
20166
|
const color2 = template.geometry.getAttribute("color");
|
|
19644
20167
|
const shade = template.geometry.getAttribute("shade");
|
|
19645
|
-
for (let vertex = 0; vertex < quads *
|
|
20168
|
+
for (let vertex = 0; vertex < quads * QUAD_VERTICES; vertex++) {
|
|
19646
20169
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
19647
20170
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
19648
20171
|
data.uvs.set([uv.getX(vertex), uv.getY(vertex)], vertex * 2);
|
|
@@ -19655,7 +20178,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19655
20178
|
data.colors.set([color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1], vertex * 3);
|
|
19656
20179
|
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
19657
20180
|
}
|
|
19658
|
-
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) -
|
|
20181
|
+
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - QUAD_VERTICES * Math.floor(i2 / QUAD_INDICES);
|
|
19659
20182
|
templateCache.set(template, data);
|
|
19660
20183
|
}
|
|
19661
20184
|
id = input.templateData.length;
|
|
@@ -19688,7 +20211,55 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19688
20211
|
}
|
|
19689
20212
|
return { input, atlases: atlases2 };
|
|
19690
20213
|
}
|
|
19691
|
-
|
|
20214
|
+
function sortTransparentQuads(mesh) {
|
|
20215
|
+
const index = mesh.geometry.getIndex();
|
|
20216
|
+
if (index.count <= QUAD_INDICES) return;
|
|
20217
|
+
index.setUsage(import_three47.DynamicDrawUsage);
|
|
20218
|
+
const count = index.count / QUAD_INDICES;
|
|
20219
|
+
let source, centers, depths, order;
|
|
20220
|
+
const view = new import_three47.Matrix4(), localCamera = new import_three47.Vector3(), key = new import_three47.Vector3(), previous = new import_three47.Vector3();
|
|
20221
|
+
let previousOrthographic;
|
|
20222
|
+
mesh.onBeforeRender = (_renderer, _scene, camera) => {
|
|
20223
|
+
localCamera.setFromMatrixPosition(camera.matrixWorld).applyMatrix4(view.copy(mesh.matrixWorld).invert());
|
|
20224
|
+
const orthographic = !!camera.isOrthographicCamera;
|
|
20225
|
+
if (orthographic) {
|
|
20226
|
+
view.multiplyMatrices(camera.matrixWorldInverse, mesh.matrixWorld);
|
|
20227
|
+
key.set(view.elements[2], view.elements[6], view.elements[10]);
|
|
20228
|
+
} else {
|
|
20229
|
+
key.copy(localCamera).divideScalar(BLOCK_SIZE).floor();
|
|
20230
|
+
}
|
|
20231
|
+
if (orthographic === previousOrthographic && key.equals(previous)) return;
|
|
20232
|
+
previous.copy(key);
|
|
20233
|
+
previousOrthographic = orthographic;
|
|
20234
|
+
if (!centers) {
|
|
20235
|
+
source = new Uint32Array(index.array);
|
|
20236
|
+
centers = new Float32Array(count * 3);
|
|
20237
|
+
depths = new Float32Array(count);
|
|
20238
|
+
order = Uint32Array.from({ length: count }, (_, quad) => quad);
|
|
20239
|
+
const positions = mesh.geometry.getAttribute("position");
|
|
20240
|
+
for (let quad = 0; quad < count; quad++) {
|
|
20241
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
20242
|
+
let center = 0;
|
|
20243
|
+
for (let corner = 0; corner < QUAD_VERTICES; corner++) center += positions.getComponent(quad * QUAD_VERTICES + corner, axis);
|
|
20244
|
+
centers[quad * 3 + axis] = center / QUAD_VERTICES;
|
|
20245
|
+
}
|
|
20246
|
+
}
|
|
20247
|
+
}
|
|
20248
|
+
for (let quad = 0; quad < count; quad++) {
|
|
20249
|
+
const x = centers[quad * 3], y = centers[quad * 3 + 1], z = centers[quad * 3 + 2];
|
|
20250
|
+
depths[quad] = orthographic ? key.x * x + key.y * y + key.z * z : -((x - localCamera.x) ** 2 + (y - localCamera.y) ** 2 + (z - localCamera.z) ** 2);
|
|
20251
|
+
}
|
|
20252
|
+
order.sort((a, b) => depths[a] - depths[b] || a - b);
|
|
20253
|
+
if (!order.some((quad, offset) => index.array[offset * QUAD_INDICES] !== source[quad * QUAD_INDICES])) return;
|
|
20254
|
+
for (let offset = 0; offset < count; offset++) {
|
|
20255
|
+
for (let indexOffset = 0; indexOffset < QUAD_INDICES; indexOffset++) {
|
|
20256
|
+
index.array[offset * QUAD_INDICES + indexOffset] = source[order[offset] * QUAD_INDICES + indexOffset];
|
|
20257
|
+
}
|
|
20258
|
+
}
|
|
20259
|
+
index.needsUpdate = true;
|
|
20260
|
+
};
|
|
20261
|
+
}
|
|
20262
|
+
var SectionMesh = class _SectionMesh extends import_three47.Group {
|
|
19692
20263
|
constructor() {
|
|
19693
20264
|
super(...arguments);
|
|
19694
20265
|
this.ownedMeshes = [];
|
|
@@ -19697,7 +20268,11 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19697
20268
|
/** Returns the owning section cell for a triangle hit on this mesh's merged geometry. */
|
|
19698
20269
|
getBlockIndex(hit) {
|
|
19699
20270
|
if (hit.faceIndex === void 0 || hit.faceIndex === null) return void 0;
|
|
19700
|
-
|
|
20271
|
+
const mesh = hit.object;
|
|
20272
|
+
const owners = this.blockIndices.get(mesh);
|
|
20273
|
+
if (!owners) return void 0;
|
|
20274
|
+
const vertex = mesh.geometry.getIndex().getX(hit.faceIndex * 3);
|
|
20275
|
+
return owners[Math.floor(vertex / QUAD_VERTICES)];
|
|
19701
20276
|
}
|
|
19702
20277
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19703
20278
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
@@ -19719,27 +20294,28 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19719
20294
|
for (const { atlas, x, y } of page.placements) {
|
|
19720
20295
|
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19721
20296
|
}
|
|
19722
|
-
const geometry = new
|
|
19723
|
-
geometry.setAttribute("position", new
|
|
19724
|
-
geometry.setAttribute("normal", new
|
|
19725
|
-
geometry.setAttribute("uv", new
|
|
19726
|
-
geometry.setAttribute("uvBounds", new
|
|
19727
|
-
geometry.setAttribute("color", new
|
|
19728
|
-
geometry.setAttribute("shade", new
|
|
19729
|
-
geometry.setIndex(new
|
|
20297
|
+
const geometry = new import_three47.BufferGeometry();
|
|
20298
|
+
geometry.setAttribute("position", new import_three47.Float32BufferAttribute(page.positions.buffer, 3));
|
|
20299
|
+
geometry.setAttribute("normal", new import_three47.Float32BufferAttribute(page.normals.buffer, 3));
|
|
20300
|
+
geometry.setAttribute("uv", new import_three47.Float32BufferAttribute(page.uvs.buffer, 2));
|
|
20301
|
+
geometry.setAttribute("uvBounds", new import_three47.Float32BufferAttribute(page.uvBounds.buffer, 4));
|
|
20302
|
+
geometry.setAttribute("color", new import_three47.Float32BufferAttribute(page.colors.buffer, 3));
|
|
20303
|
+
geometry.setAttribute("shade", new import_three47.Float32BufferAttribute(page.shade.buffer, 1));
|
|
20304
|
+
geometry.setIndex(new import_three47.Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19730
20305
|
geometry.computeBoundingBox();
|
|
19731
20306
|
geometry.computeBoundingSphere();
|
|
19732
20307
|
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19733
20308
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19734
|
-
material.side =
|
|
20309
|
+
material.side = import_three47.FrontSide;
|
|
19735
20310
|
if (page.layer === 2) {
|
|
19736
|
-
material.side = import_three46.DoubleSide;
|
|
19737
|
-
material.forceSinglePass = true;
|
|
19738
20311
|
material.depthWrite = !material.transparent;
|
|
20312
|
+
material.side = import_three47.DoubleSide;
|
|
20313
|
+
material.forceSinglePass = true;
|
|
19739
20314
|
}
|
|
19740
20315
|
material.vertexColors = true;
|
|
19741
20316
|
const texture = material.uniforms?.map?.value ?? material.map;
|
|
19742
|
-
const mesh = new
|
|
20317
|
+
const mesh = new import_three47.Mesh(geometry, material);
|
|
20318
|
+
if (transparent) sortTransparentQuads(mesh);
|
|
19743
20319
|
section.add(mesh);
|
|
19744
20320
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19745
20321
|
const unsubscribe = [];
|
|
@@ -19780,7 +20356,7 @@ init_CubeFace();
|
|
|
19780
20356
|
init_BlockTints();
|
|
19781
20357
|
init_Biomes();
|
|
19782
20358
|
init_InstanceReference();
|
|
19783
|
-
var WATER_TINT2 = new
|
|
20359
|
+
var WATER_TINT2 = new import_three48.Color(4159204).toArray();
|
|
19784
20360
|
var Chunk = class _Chunk {
|
|
19785
20361
|
constructor(scene, x, y, z, onBlocksChanged, sectionModels, neighborCell, biomeAt, onBiomesChanged, lightAt, onLightCleared, ambientLight = 0, biomeBlend) {
|
|
19786
20362
|
this.onBlocksChanged = onBlocksChanged;
|
|
@@ -19798,7 +20374,7 @@ var Chunk = class _Chunk {
|
|
|
19798
20374
|
this.sectionBlocks = /* @__PURE__ */ new Map();
|
|
19799
20375
|
this.hiddenBlocks = /* @__PURE__ */ new Set();
|
|
19800
20376
|
this.fluidCells = new Uint8Array(4096);
|
|
19801
|
-
this.blockPosition = new
|
|
20377
|
+
this.blockPosition = new import_three48.Vector3();
|
|
19802
20378
|
this.meshDirty = false;
|
|
19803
20379
|
this.meshGeneration = 0;
|
|
19804
20380
|
this.blockChanges = /* @__PURE__ */ new Set();
|
|
@@ -19858,7 +20434,7 @@ var Chunk = class _Chunk {
|
|
|
19858
20434
|
const info = owner.chunk.renderedBlocks.get(owner.index);
|
|
19859
20435
|
if (!info) continue;
|
|
19860
20436
|
return {
|
|
19861
|
-
position: new
|
|
20437
|
+
position: new import_three48.Vector3(
|
|
19862
20438
|
owner.chunk.x * 16 + owner.index % 16,
|
|
19863
20439
|
owner.chunk.y * 16 + Math.floor(owner.index / 256),
|
|
19864
20440
|
owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16
|
|
@@ -19873,18 +20449,18 @@ var Chunk = class _Chunk {
|
|
|
19873
20449
|
}
|
|
19874
20450
|
getBlockAt(posOrX, y, z) {
|
|
19875
20451
|
if (typeof posOrX == "number") {
|
|
19876
|
-
return this.getBlockAt(new
|
|
20452
|
+
return this.getBlockAt(new import_three48.Vector3(posOrX, y, z));
|
|
19877
20453
|
}
|
|
19878
20454
|
if (isTripleArray(posOrX)) {
|
|
19879
|
-
return this.getBlockAt(new
|
|
20455
|
+
return this.getBlockAt(new import_three48.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
19880
20456
|
}
|
|
19881
20457
|
const pos = this.blockPosition.set(posOrX.x - this.x * 16, posOrX.y - this.y * 16, posOrX.z - this.z * 16);
|
|
19882
20458
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
19883
20459
|
return this.renderedBlocks.get(index);
|
|
19884
20460
|
}
|
|
19885
20461
|
getBiomeAt(posOrX, y, z) {
|
|
19886
|
-
if (typeof posOrX === "number") return this.getBiomeAt(new
|
|
19887
|
-
if (isTripleArray(posOrX)) return this.getBiomeAt(new
|
|
20462
|
+
if (typeof posOrX === "number") return this.getBiomeAt(new import_three48.Vector3(posOrX, y, z));
|
|
20463
|
+
if (isTripleArray(posOrX)) return this.getBiomeAt(new import_three48.Vector3(...posOrX));
|
|
19888
20464
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
19889
20465
|
_Chunk.chunkPosToBlockIndex(pos);
|
|
19890
20466
|
return this.biomeAt ? this.biomeAt(posOrX.x, posOrX.y, posOrX.z) : this.biomes?.[Math.floor(pos.x / 4) + Math.floor(pos.z / 4) * 4 + Math.floor(pos.y / 4) * 16];
|
|
@@ -19962,17 +20538,17 @@ var Chunk = class _Chunk {
|
|
|
19962
20538
|
this.hiddenBlocks.add(index);
|
|
19963
20539
|
this.renderedBlocks.get(index)?.object?.setVisible(false);
|
|
19964
20540
|
}
|
|
19965
|
-
const positions = blocks.map(({ index }) => new
|
|
20541
|
+
const positions = blocks.map(({ index }) => new import_three48.Vector3(...this.positionAt(index)));
|
|
19966
20542
|
if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
|
|
19967
20543
|
else await this.rebuildSectionMesh();
|
|
19968
20544
|
}
|
|
19969
20545
|
}
|
|
19970
20546
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
19971
20547
|
if (typeof posOrX == "number") {
|
|
19972
|
-
return this.setBlockAt(new
|
|
20548
|
+
return this.setBlockAt(new import_three48.Vector3(posOrX, yOrBlock, z), block);
|
|
19973
20549
|
}
|
|
19974
20550
|
if (isTripleArray(posOrX)) {
|
|
19975
|
-
return this.setBlockAt(new
|
|
20551
|
+
return this.setBlockAt(new import_three48.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
19976
20552
|
}
|
|
19977
20553
|
const worldPos = posOrX;
|
|
19978
20554
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -20034,8 +20610,10 @@ var Chunk = class _Chunk {
|
|
|
20034
20610
|
if (rejected?.status === "rejected") throw rejected.reason;
|
|
20035
20611
|
}
|
|
20036
20612
|
const positions = [];
|
|
20037
|
-
|
|
20038
|
-
|
|
20613
|
+
const jobs = /* @__PURE__ */ new Map();
|
|
20614
|
+
let failureOrder = Infinity, failure;
|
|
20615
|
+
for (const [order, { index, key, block }] of placements.entries()) {
|
|
20616
|
+
jobs.delete(index);
|
|
20039
20617
|
this.hiddenBlocks.delete(index);
|
|
20040
20618
|
this.data.assign(index, this.data.intern(block), block?.nbt);
|
|
20041
20619
|
const readBlock = this.data.snapshot(index);
|
|
@@ -20045,13 +20623,12 @@ var Chunk = class _Chunk {
|
|
|
20045
20623
|
this.fluidCells[index] = 0;
|
|
20046
20624
|
this.renderedBlocks.delete(index);
|
|
20047
20625
|
this.objectBlocks.delete(index);
|
|
20048
|
-
const worldPos = new
|
|
20626
|
+
const worldPos = new import_three48.Vector3(
|
|
20049
20627
|
this.x * 16 + index % 16,
|
|
20050
20628
|
this.y * 16 + Math.floor(index / 256),
|
|
20051
20629
|
this.z * 16 + Math.floor(index / 16) % 16
|
|
20052
20630
|
);
|
|
20053
20631
|
positions.push(worldPos);
|
|
20054
|
-
let object4;
|
|
20055
20632
|
try {
|
|
20056
20633
|
if (!readBlock) continue;
|
|
20057
20634
|
const resolved = resolutions.get(key);
|
|
@@ -20073,7 +20650,7 @@ var Chunk = class _Chunk {
|
|
|
20073
20650
|
this.sectionBlocks.set(index, templates.map((template) => ({ index, template, cullMask: 0, biomeTint: context?.tint })));
|
|
20074
20651
|
this.meshDirty = true;
|
|
20075
20652
|
} else {
|
|
20076
|
-
|
|
20653
|
+
jobs.set(index, { order, readBlock, blockState: blockState3, position: MineRenderWorld.worldToScenePosition(worldPos), options: {
|
|
20077
20654
|
mergeMeshes: true,
|
|
20078
20655
|
instanceMeshes: true,
|
|
20079
20656
|
maxInstanceCount: 2e3,
|
|
@@ -20081,13 +20658,12 @@ var Chunk = class _Chunk {
|
|
|
20081
20658
|
variantPosition,
|
|
20082
20659
|
biome: context?.biome,
|
|
20083
20660
|
biomePosition: this.biomePosition(index, blockState3, stored)
|
|
20084
|
-
});
|
|
20085
|
-
|
|
20661
|
+
} });
|
|
20662
|
+
continue;
|
|
20086
20663
|
}
|
|
20087
20664
|
this.renderedBlocks.set(index, { get block() {
|
|
20088
20665
|
return readBlock();
|
|
20089
|
-
}, object:
|
|
20090
|
-
if (object4) this.objectBlocks.add(index);
|
|
20666
|
+
}, object: void 0 });
|
|
20091
20667
|
} catch (error) {
|
|
20092
20668
|
if (preserveDataOnFailure && readBlock) {
|
|
20093
20669
|
this.renderedBlocks.set(index, { get block() {
|
|
@@ -20095,12 +20671,35 @@ var Chunk = class _Chunk {
|
|
|
20095
20671
|
}, object: void 0 });
|
|
20096
20672
|
} else this.data.assign(index, 0);
|
|
20097
20673
|
this.fluidCells[index] = 0;
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
20674
|
+
if (order < failureOrder) {
|
|
20675
|
+
failureOrder = order;
|
|
20676
|
+
failure = error;
|
|
20677
|
+
}
|
|
20101
20678
|
}
|
|
20102
20679
|
}
|
|
20103
|
-
|
|
20680
|
+
const pending = [...jobs];
|
|
20681
|
+
const objects = await Promise.allSettled(pending.map(([, job]) => this.createBlockObject(job.blockState, job.position, job.options)));
|
|
20682
|
+
for (const [i, [index, { order, readBlock }]] of pending.entries()) {
|
|
20683
|
+
const result = objects[i];
|
|
20684
|
+
if (result.status === "fulfilled") {
|
|
20685
|
+
this.renderedBlocks.set(index, { get block() {
|
|
20686
|
+
return readBlock();
|
|
20687
|
+
}, object: result.value });
|
|
20688
|
+
this.objectBlocks.add(index);
|
|
20689
|
+
} else {
|
|
20690
|
+
if (preserveDataOnFailure) {
|
|
20691
|
+
this.renderedBlocks.set(index, { get block() {
|
|
20692
|
+
return readBlock();
|
|
20693
|
+
}, object: void 0 });
|
|
20694
|
+
} else this.data.assign(index, 0);
|
|
20695
|
+
this.fluidCells[index] = 0;
|
|
20696
|
+
if (order < failureOrder) {
|
|
20697
|
+
failureOrder = order;
|
|
20698
|
+
failure = result.reason;
|
|
20699
|
+
}
|
|
20700
|
+
}
|
|
20701
|
+
}
|
|
20702
|
+
if (failureOrder < Infinity) throw failure;
|
|
20104
20703
|
return positions;
|
|
20105
20704
|
}
|
|
20106
20705
|
/** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */
|
|
@@ -20171,37 +20770,42 @@ var Chunk = class _Chunk {
|
|
|
20171
20770
|
failed = true;
|
|
20172
20771
|
}
|
|
20173
20772
|
}
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
)
|
|
20191
|
-
this.renderedBlocks.get(index).object = object4;
|
|
20773
|
+
const objects = await Promise.allSettled(perBlocks.map(({ index, blockState: blockState3, biome }) => this.createBlockObject(blockState3, new import_three48.Vector3(
|
|
20774
|
+
this.x * 256 + index % 16 * 16,
|
|
20775
|
+
this.y * 256 + Math.floor(index / 256) * 16,
|
|
20776
|
+
this.z * 256 + Math.floor(index / 16) % 16 * 16
|
|
20777
|
+
), {
|
|
20778
|
+
mergeMeshes: true,
|
|
20779
|
+
instanceMeshes: true,
|
|
20780
|
+
maxInstanceCount: 2e3,
|
|
20781
|
+
initialState: this.data.stateAt(this.data.idAt(index)).properties,
|
|
20782
|
+
variantPosition: this.positionAt(index),
|
|
20783
|
+
biome,
|
|
20784
|
+
biomePosition: this.biomePosition(index, blockState3, this.data.stateAt(this.data.idAt(index)))
|
|
20785
|
+
})));
|
|
20786
|
+
for (const [i, { index }] of perBlocks.entries()) {
|
|
20787
|
+
const result = objects[i];
|
|
20788
|
+
if (result.status === "fulfilled") {
|
|
20789
|
+
this.renderedBlocks.get(index).object = result.value;
|
|
20192
20790
|
this.objectBlocks.add(index);
|
|
20193
|
-
}
|
|
20791
|
+
} else {
|
|
20194
20792
|
this.data.assign(index, 0);
|
|
20195
20793
|
this.fluidCells[index] = 0;
|
|
20196
20794
|
this.renderedBlocks.delete(index);
|
|
20197
20795
|
this.objectBlocks.delete(index);
|
|
20198
|
-
|
|
20199
|
-
if (!failed) failure = error;
|
|
20796
|
+
if (!failed) failure = result.reason;
|
|
20200
20797
|
failed = true;
|
|
20201
20798
|
}
|
|
20202
20799
|
}
|
|
20203
20800
|
if (failed) throw failure;
|
|
20204
20801
|
}
|
|
20802
|
+
createBlockObject(blockState3, position, options) {
|
|
20803
|
+
return this.scene.addSceneObject(blockState3, () => {
|
|
20804
|
+
const object4 = new BlockObject(blockState3, options);
|
|
20805
|
+
object4.position.copy(position);
|
|
20806
|
+
return object4;
|
|
20807
|
+
}, options);
|
|
20808
|
+
}
|
|
20205
20809
|
positionAt(index) {
|
|
20206
20810
|
return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];
|
|
20207
20811
|
}
|
|
@@ -20256,11 +20860,11 @@ var Chunk = class _Chunk {
|
|
|
20256
20860
|
const context = {};
|
|
20257
20861
|
if (source && prepared2?.biomeTint) {
|
|
20258
20862
|
const color2 = await biomeColor(source);
|
|
20259
|
-
if (color2 !== void 0) context.tint = new
|
|
20863
|
+
if (color2 !== void 0) context.tint = new import_three48.Color(color2).toArray();
|
|
20260
20864
|
}
|
|
20261
20865
|
if (fluid?.kind === "water") {
|
|
20262
20866
|
const color2 = await biomeColor("water");
|
|
20263
|
-
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new
|
|
20867
|
+
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new import_three48.Color(color2).toArray();
|
|
20264
20868
|
}
|
|
20265
20869
|
contexts.set(index, context);
|
|
20266
20870
|
}));
|
|
@@ -20298,7 +20902,7 @@ var Chunk = class _Chunk {
|
|
|
20298
20902
|
context.prepared = await prepare(async () => await available() ? BlockTints.getBiomeColor(blockState3?.key, biome, position) : void 0);
|
|
20299
20903
|
if (fluid?.kind === "water" && await available()) {
|
|
20300
20904
|
const color2 = await Biomes.getColor(biome, "water", blockState3?.key);
|
|
20301
|
-
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new
|
|
20905
|
+
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new import_three48.Color(color2).toArray();
|
|
20302
20906
|
}
|
|
20303
20907
|
}
|
|
20304
20908
|
for (const index of indices2) contexts.set(index, context);
|
|
@@ -20490,7 +21094,7 @@ var Chunk = class _Chunk {
|
|
|
20490
21094
|
async clear(notify = true) {
|
|
20491
21095
|
if (this.blockChanges.size) await Promise.allSettled(this.blockChanges);
|
|
20492
21096
|
const positions = notify && this.onBlocksChanged ? [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
20493
|
-
new
|
|
21097
|
+
new import_three48.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
20494
21098
|
)) : [];
|
|
20495
21099
|
for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
|
|
20496
21100
|
this.sectionBlocks.clear();
|
|
@@ -20526,14 +21130,14 @@ var Chunk = class _Chunk {
|
|
|
20526
21130
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
20527
21131
|
}
|
|
20528
21132
|
worldPosToChunkPos(pos) {
|
|
20529
|
-
return new
|
|
21133
|
+
return new import_three48.Vector3(
|
|
20530
21134
|
pos.x - this.x * 16,
|
|
20531
21135
|
pos.y - this.y * 16,
|
|
20532
21136
|
pos.z - this.z * 16
|
|
20533
21137
|
);
|
|
20534
21138
|
}
|
|
20535
21139
|
chunkPosToWorldPos(pos) {
|
|
20536
|
-
return new
|
|
21140
|
+
return new import_three48.Vector3(
|
|
20537
21141
|
this.x * 16 + pos.x,
|
|
20538
21142
|
this.y * 16 + pos.y,
|
|
20539
21143
|
this.z * 16 + pos.z
|
|
@@ -20542,6 +21146,7 @@ var Chunk = class _Chunk {
|
|
|
20542
21146
|
};
|
|
20543
21147
|
|
|
20544
21148
|
// src/world/WorldStreamer.ts
|
|
21149
|
+
var MAX_PREFETCHED_COLUMNS = 4;
|
|
20545
21150
|
var WorldStreamer = class {
|
|
20546
21151
|
constructor(world, source, options = {}) {
|
|
20547
21152
|
this.world = world;
|
|
@@ -20551,6 +21156,7 @@ var WorldStreamer = class {
|
|
|
20551
21156
|
this.missing = /* @__PURE__ */ new Map();
|
|
20552
21157
|
this.failed = /* @__PURE__ */ new Map();
|
|
20553
21158
|
this.desired = [];
|
|
21159
|
+
this.reads = /* @__PURE__ */ new Map();
|
|
20554
21160
|
this.disposed = false;
|
|
20555
21161
|
this.loadRadius = options.loadRadius ?? 2;
|
|
20556
21162
|
this.unloadRadius = options.unloadRadius ?? Math.min(32, this.loadRadius + 1);
|
|
@@ -20595,6 +21201,12 @@ var WorldStreamer = class {
|
|
|
20595
21201
|
if (this.loading && !this.within(this.loading.position, this.loadRadius)) {
|
|
20596
21202
|
this.loading.controller.abort();
|
|
20597
21203
|
}
|
|
21204
|
+
for (const [key, read] of this.reads) {
|
|
21205
|
+
if (!this.within(read.position, this.loadRadius)) {
|
|
21206
|
+
read.controller.abort();
|
|
21207
|
+
if (read.ready) this.reads.delete(key);
|
|
21208
|
+
}
|
|
21209
|
+
}
|
|
20598
21210
|
}
|
|
20599
21211
|
return this.running ?? (this.running = Promise.resolve().then(() => this.drain()));
|
|
20600
21212
|
}
|
|
@@ -20615,8 +21227,11 @@ var WorldStreamer = class {
|
|
|
20615
21227
|
this.desired = [];
|
|
20616
21228
|
this.center = void 0;
|
|
20617
21229
|
this.loading?.controller.abort();
|
|
21230
|
+
for (const read of this.reads.values()) read.controller.abort();
|
|
20618
21231
|
return this.disposal ?? (this.disposal = Promise.resolve().then(async () => {
|
|
20619
21232
|
await this.running?.catch(() => void 0);
|
|
21233
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
21234
|
+
this.reads.clear();
|
|
20620
21235
|
try {
|
|
20621
21236
|
await this.unloadMany([...this.owned.values()]);
|
|
20622
21237
|
} finally {
|
|
@@ -20642,6 +21257,10 @@ var WorldStreamer = class {
|
|
|
20642
21257
|
await this.unloadMany(obsolete);
|
|
20643
21258
|
continue;
|
|
20644
21259
|
}
|
|
21260
|
+
if (this.world.placeChunks) {
|
|
21261
|
+
if (await this.placeReadyChunks()) continue;
|
|
21262
|
+
return;
|
|
21263
|
+
}
|
|
20645
21264
|
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
20646
21265
|
if (!position) return;
|
|
20647
21266
|
let chunk;
|
|
@@ -20664,26 +21283,105 @@ var WorldStreamer = class {
|
|
|
20664
21283
|
continue;
|
|
20665
21284
|
}
|
|
20666
21285
|
this.owned.set(this.key(position), position);
|
|
21286
|
+
await this.placeOwnedColumns([position], () => this.world.placeChunk(chunk));
|
|
21287
|
+
}
|
|
21288
|
+
} finally {
|
|
21289
|
+
for (const [key, read] of this.reads) {
|
|
21290
|
+
read.controller.abort();
|
|
21291
|
+
if (read.ready) this.reads.delete(key);
|
|
21292
|
+
}
|
|
21293
|
+
this.running = void 0;
|
|
21294
|
+
}
|
|
21295
|
+
}
|
|
21296
|
+
fillReadSlots() {
|
|
21297
|
+
while (!this.disposed && this.reads.size < MAX_PREFETCHED_COLUMNS) {
|
|
21298
|
+
const position = this.desired.find((position2) => this.needsLoad(position2) && !this.reads.has(this.key(position2)));
|
|
21299
|
+
if (!position) return;
|
|
21300
|
+
const key = this.key(position);
|
|
21301
|
+
const read = {
|
|
21302
|
+
position,
|
|
21303
|
+
controller: new AbortController(),
|
|
21304
|
+
promise: Promise.resolve(),
|
|
21305
|
+
ready: false,
|
|
21306
|
+
failed: false
|
|
21307
|
+
};
|
|
21308
|
+
this.reads.set(key, read);
|
|
21309
|
+
read.promise = (async () => {
|
|
20667
21310
|
try {
|
|
20668
|
-
await this.
|
|
20669
|
-
this.
|
|
21311
|
+
read.chunk = await this.source.getChunk(position.x, position.z, read.controller.signal);
|
|
21312
|
+
if (read.chunk) this.validateChunk(read.chunk, position);
|
|
20670
21313
|
} catch (error) {
|
|
20671
|
-
|
|
20672
|
-
|
|
20673
|
-
|
|
20674
|
-
|
|
20675
|
-
|
|
20676
|
-
|
|
20677
|
-
} catch {
|
|
20678
|
-
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
20679
|
-
}
|
|
20680
|
-
throw failure;
|
|
21314
|
+
read.failed = true;
|
|
21315
|
+
read.error = error;
|
|
21316
|
+
} finally {
|
|
21317
|
+
read.ready = true;
|
|
21318
|
+
if (read.controller.signal.aborted || this.disposed || !this.within(position, this.loadRadius)) {
|
|
21319
|
+
this.reads.delete(key);
|
|
20681
21320
|
}
|
|
20682
|
-
|
|
21321
|
+
}
|
|
21322
|
+
})();
|
|
21323
|
+
}
|
|
21324
|
+
}
|
|
21325
|
+
/** Places only the ready prefix, so later source reads cannot delay the nearest ready column. */
|
|
21326
|
+
async placeReadyChunks() {
|
|
21327
|
+
this.fillReadSlots();
|
|
21328
|
+
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
21329
|
+
if (!position) {
|
|
21330
|
+
if (!this.reads.size) return false;
|
|
21331
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
21332
|
+
return true;
|
|
21333
|
+
}
|
|
21334
|
+
const head = this.reads.get(this.key(position));
|
|
21335
|
+
if (!head) {
|
|
21336
|
+
for (let index = this.desired.length - 1; index >= 0; index--) {
|
|
21337
|
+
const key = this.key(this.desired[index]);
|
|
21338
|
+
if (this.reads.get(key)?.ready) {
|
|
21339
|
+
this.reads.delete(key);
|
|
21340
|
+
return true;
|
|
20683
21341
|
}
|
|
20684
21342
|
}
|
|
20685
|
-
|
|
20686
|
-
|
|
21343
|
+
await Promise.race([...this.reads.values()].map((read) => read.promise));
|
|
21344
|
+
return true;
|
|
21345
|
+
}
|
|
21346
|
+
if (!head.ready) {
|
|
21347
|
+
await head.promise;
|
|
21348
|
+
return true;
|
|
21349
|
+
}
|
|
21350
|
+
const chunks = [], positions = [];
|
|
21351
|
+
for (const desired of this.desired) {
|
|
21352
|
+
if (!this.needsLoad(desired)) continue;
|
|
21353
|
+
const key = this.key(desired), read = this.reads.get(key);
|
|
21354
|
+
if (!read?.ready) break;
|
|
21355
|
+
this.reads.delete(key);
|
|
21356
|
+
if (read.failed) this.failed.set(key, { ...desired, error: read.error });
|
|
21357
|
+
else if (!read.chunk) this.missing.set(key, desired);
|
|
21358
|
+
else {
|
|
21359
|
+
chunks.push(read.chunk);
|
|
21360
|
+
positions.push(desired);
|
|
21361
|
+
}
|
|
21362
|
+
}
|
|
21363
|
+
if (!chunks.length) return true;
|
|
21364
|
+
for (const position2 of positions) this.owned.set(this.key(position2), position2);
|
|
21365
|
+
await this.placeOwnedColumns(positions, () => this.world.placeChunks(chunks));
|
|
21366
|
+
return true;
|
|
21367
|
+
}
|
|
21368
|
+
async placeOwnedColumns(positions, place) {
|
|
21369
|
+
try {
|
|
21370
|
+
await place();
|
|
21371
|
+
for (const position of positions) this.loaded.set(this.key(position), position);
|
|
21372
|
+
} catch (error) {
|
|
21373
|
+
try {
|
|
21374
|
+
await this.unloadMany(positions);
|
|
21375
|
+
} catch (cleanupError) {
|
|
21376
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
21377
|
+
try {
|
|
21378
|
+
Object.defineProperty(failure, "cause", { value: cleanupError, configurable: true });
|
|
21379
|
+
} catch {
|
|
21380
|
+
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
21381
|
+
}
|
|
21382
|
+
throw failure;
|
|
21383
|
+
}
|
|
21384
|
+
throw error;
|
|
20687
21385
|
}
|
|
20688
21386
|
}
|
|
20689
21387
|
needsLoad(position) {
|