minerender 2.1.0-alpha.23 → 2.1.0-alpha.25
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/dist/browser/index.d.mts +44 -48
- package/dist/browser/index.d.ts +44 -48
- package/dist/browser/index.js +133 -142
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +182 -191
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +137 -148
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +44 -48
- package/dist/node/index.d.ts +44 -48
- package/dist/node/index.js +134 -145
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +183 -191
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.mjs
CHANGED
|
@@ -413,7 +413,8 @@ var _Caching = class _Caching {
|
|
|
413
413
|
this.listAssetCache,
|
|
414
414
|
this.defaultBlockStatesCache,
|
|
415
415
|
this.blockTintCache,
|
|
416
|
-
this.
|
|
416
|
+
this.entityModelCache,
|
|
417
|
+
this.entityTextureCache
|
|
417
418
|
];
|
|
418
419
|
}
|
|
419
420
|
static clear() {
|
|
@@ -456,7 +457,8 @@ _Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).e
|
|
|
456
457
|
_Caching.listAssetCache = _Caching.createAssetCache();
|
|
457
458
|
_Caching.defaultBlockStatesCache = _Caching.createAssetCache();
|
|
458
459
|
_Caching.blockTintCache = _Caching.createAssetCache();
|
|
459
|
-
_Caching.
|
|
460
|
+
_Caching.entityModelCache = _Caching.createAssetCache();
|
|
461
|
+
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
460
462
|
var Caching = _Caching;
|
|
461
463
|
|
|
462
464
|
// src/Geometries.ts
|
|
@@ -1535,14 +1537,6 @@ function applyElementRotation(rotation, geometry) {
|
|
|
1535
1537
|
}
|
|
1536
1538
|
geometry.translate(origin.x, origin.y, origin.z);
|
|
1537
1539
|
}
|
|
1538
|
-
function applyModelPartRotation(modelPart, geometry) {
|
|
1539
|
-
const origin = new Vector33(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
|
|
1540
|
-
geometry.translate(-origin.x, -origin.y, -origin.z);
|
|
1541
|
-
geometry.rotateX(toRadians(modelPart.pitch));
|
|
1542
|
-
geometry.rotateY(toRadians(modelPart.yaw));
|
|
1543
|
-
geometry.rotateZ(toRadians(modelPart.roll));
|
|
1544
|
-
geometry.translate(origin.x, origin.y, origin.z);
|
|
1545
|
-
}
|
|
1546
1540
|
function applyGenericRotation(axis, rotation, obj) {
|
|
1547
1541
|
switch (axis) {
|
|
1548
1542
|
case "x" /* X */:
|
|
@@ -2564,18 +2558,18 @@ var MinecraftCubeTexture = class {
|
|
|
2564
2558
|
}
|
|
2565
2559
|
getUvEast(w, h, l) {
|
|
2566
2560
|
return [
|
|
2567
|
-
[this.mapW(this.u), this.mapH(this.v + l + h)],
|
|
2568
|
-
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2569
|
-
[this.mapW(this.u), this.mapH(this.v + l)],
|
|
2570
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)]
|
|
2561
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2562
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
|
|
2563
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
|
|
2564
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2571
2565
|
];
|
|
2572
2566
|
}
|
|
2573
2567
|
getUvWest(w, h, l) {
|
|
2574
2568
|
return [
|
|
2575
|
-
[this.mapW(this.u + l
|
|
2576
|
-
[this.mapW(this.u
|
|
2577
|
-
[this.mapW(this.u + l
|
|
2578
|
-
[this.mapW(this.u
|
|
2569
|
+
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2570
|
+
[this.mapW(this.u), this.mapH(this.v + l + h)],
|
|
2571
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2572
|
+
[this.mapW(this.u), this.mapH(this.v + l)]
|
|
2579
2573
|
];
|
|
2580
2574
|
}
|
|
2581
2575
|
getUvUp(w, h, l) {
|
|
@@ -2588,26 +2582,26 @@ var MinecraftCubeTexture = class {
|
|
|
2588
2582
|
}
|
|
2589
2583
|
getUvDown(w, h, l) {
|
|
2590
2584
|
return [
|
|
2591
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2592
|
-
[this.mapW(this.u + l + w), this.mapH(this.v + l)],
|
|
2593
2585
|
[this.mapW(this.u + l), this.mapH(this.v)],
|
|
2594
|
-
[this.mapW(this.u + l + w), this.mapH(this.v)]
|
|
2586
|
+
[this.mapW(this.u + l + w), this.mapH(this.v)],
|
|
2587
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2588
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2595
2589
|
];
|
|
2596
2590
|
}
|
|
2597
2591
|
getUvSouth(w, h, l) {
|
|
2598
2592
|
return [
|
|
2599
|
-
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2600
2593
|
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l + h)],
|
|
2601
|
-
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
|
|
2602
|
-
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)]
|
|
2594
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
|
|
2595
|
+
[this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
|
|
2596
|
+
[this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
|
|
2603
2597
|
];
|
|
2604
2598
|
}
|
|
2605
2599
|
getUvNorth(w, h, l) {
|
|
2606
2600
|
return [
|
|
2607
|
-
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2608
2601
|
[this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
|
|
2609
|
-
[this.mapW(this.u + l), this.mapH(this.v + l)],
|
|
2610
|
-
[this.mapW(this.u + l + w), this.mapH(this.v + l)]
|
|
2602
|
+
[this.mapW(this.u + l), this.mapH(this.v + l + h)],
|
|
2603
|
+
[this.mapW(this.u + l + w), this.mapH(this.v + l)],
|
|
2604
|
+
[this.mapW(this.u + l), this.mapH(this.v + l)]
|
|
2611
2605
|
];
|
|
2612
2606
|
}
|
|
2613
2607
|
getFaceUv(face, w, h, l) {
|
|
@@ -2626,10 +2620,12 @@ var MinecraftCubeTexture = class {
|
|
|
2626
2620
|
return this.getUvNorth(w, h, l);
|
|
2627
2621
|
}
|
|
2628
2622
|
}
|
|
2629
|
-
toUvArray(w, h, l) {
|
|
2623
|
+
toUvArray(w, h, l, mirror = false) {
|
|
2630
2624
|
const uv = [];
|
|
2631
2625
|
for (let i = 0; i < CUBE_FACES.length; i++) {
|
|
2632
|
-
|
|
2626
|
+
const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
|
|
2627
|
+
const corners = this.getFaceUv(face, w, h, l);
|
|
2628
|
+
UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
|
|
2633
2629
|
}
|
|
2634
2630
|
return uv;
|
|
2635
2631
|
}
|
|
@@ -2659,69 +2655,79 @@ function shutdown() {
|
|
|
2659
2655
|
Caching.end();
|
|
2660
2656
|
}
|
|
2661
2657
|
|
|
2662
|
-
// src/
|
|
2663
|
-
var
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
return Caching.entityModelsCache.get(key.serialize(), () => {
|
|
2668
|
-
return AssetLoader.get(key, "json" /* JSON */);
|
|
2669
|
-
});
|
|
2670
|
-
}
|
|
2671
|
-
static async getEntityModels() {
|
|
2672
|
-
const key = AssetKey.parse("models", "minerender:entityModels");
|
|
2673
|
-
console.log(key);
|
|
2674
|
-
return Caching.entityModelsCache.get(key.serialize(), () => {
|
|
2675
|
-
return AssetLoader.get(key, "json" /* JSON */);
|
|
2676
|
-
});
|
|
2658
|
+
// src/error/MineRenderError.ts
|
|
2659
|
+
var MineRenderError = class _MineRenderError extends Error {
|
|
2660
|
+
constructor(msg) {
|
|
2661
|
+
super(msg);
|
|
2662
|
+
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
2677
2663
|
}
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
const models = await this.getBlockEntityModels();
|
|
2681
|
-
if (!models) {
|
|
2682
|
-
return [];
|
|
2683
|
-
}
|
|
2684
|
-
return Object.keys(models);
|
|
2664
|
+
get name() {
|
|
2665
|
+
return "MineRenderError";
|
|
2685
2666
|
}
|
|
2667
|
+
};
|
|
2668
|
+
|
|
2669
|
+
// src/assets/Entities.ts
|
|
2670
|
+
var Entities = class {
|
|
2686
2671
|
static async getEntityList() {
|
|
2687
|
-
const
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
if (!models) {
|
|
2696
|
-
return void 0;
|
|
2697
|
-
}
|
|
2698
|
-
if (!textureKey) {
|
|
2699
|
-
textureKey = modelKey;
|
|
2700
|
-
}
|
|
2701
|
-
const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
|
|
2702
|
-
return {
|
|
2703
|
-
key: textureKey,
|
|
2704
|
-
parts: models[baseKey.toNamespacedString()]
|
|
2672
|
+
const collect = async (path) => {
|
|
2673
|
+
const prefix2 = path ? `${path}/` : "";
|
|
2674
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
|
|
2675
|
+
const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
2676
|
+
if (!list) return [];
|
|
2677
|
+
const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
2678
|
+
const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
2679
|
+
return [...files, ...children.flat()];
|
|
2705
2680
|
};
|
|
2681
|
+
return collect("");
|
|
2682
|
+
}
|
|
2683
|
+
static async getEntity(modelKey, textureKey, options) {
|
|
2684
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
2685
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
2686
|
+
const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
2687
|
+
if (!model) return void 0;
|
|
2688
|
+
const layerName = options?.layer ?? "main";
|
|
2689
|
+
const layer = model.layers[layerName];
|
|
2690
|
+
if (!layer) {
|
|
2691
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
2692
|
+
}
|
|
2693
|
+
let texture;
|
|
2694
|
+
if (textureKey) {
|
|
2695
|
+
const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
|
|
2696
|
+
texture = isAssetKey(textureKey) && textureKey.assetType === "textures" && path2.startsWith("entity/") ? textureKey : new AssetKey(textureKey.namespace, path2, "textures", "entity", "assets", ".png", isAssetKey(textureKey) ? textureKey.root : void 0);
|
|
2697
|
+
} else {
|
|
2698
|
+
texture = await this.resolveTexture(modelKey);
|
|
2699
|
+
}
|
|
2700
|
+
return { key: textureKey ?? modelKey, texture, layer, id: model.id };
|
|
2701
|
+
}
|
|
2702
|
+
static async resolveTexture(modelKey) {
|
|
2703
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
2704
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
2705
|
+
return Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
2706
|
+
const name = path.split("/").pop();
|
|
2707
|
+
for (const candidate of [path, `${path}/${name}`]) {
|
|
2708
|
+
const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
|
|
2709
|
+
if (await ModelTextures.get(texture)) return texture;
|
|
2710
|
+
}
|
|
2711
|
+
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json");
|
|
2712
|
+
const list = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
2713
|
+
const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
2714
|
+
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
2715
|
+
if (!file) return void 0;
|
|
2716
|
+
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json");
|
|
2717
|
+
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
2718
|
+
const assets = variant?.assets;
|
|
2719
|
+
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
2720
|
+
return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
|
|
2721
|
+
});
|
|
2706
2722
|
}
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
}
|
|
2715
|
-
const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
|
|
2716
|
-
return {
|
|
2717
|
-
key: textureKey,
|
|
2718
|
-
parts: models[baseKey.toNamespacedString()]
|
|
2719
|
-
};
|
|
2723
|
+
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
2724
|
+
static getBlockList() {
|
|
2725
|
+
return this.getEntityList();
|
|
2726
|
+
}
|
|
2727
|
+
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
2728
|
+
static getBlock(modelKey, textureKey, options) {
|
|
2729
|
+
return this.getEntity(modelKey, textureKey, options);
|
|
2720
2730
|
}
|
|
2721
|
-
};
|
|
2722
|
-
var EntityModels = class {
|
|
2723
|
-
};
|
|
2724
|
-
var BlockEntityModels = class {
|
|
2725
2731
|
};
|
|
2726
2732
|
|
|
2727
2733
|
// src/renderer/SceneObject.ts
|
|
@@ -2770,17 +2776,6 @@ function isInstanceReference(obj) {
|
|
|
2770
2776
|
return obj.isInstanceReference;
|
|
2771
2777
|
}
|
|
2772
2778
|
|
|
2773
|
-
// src/error/MineRenderError.ts
|
|
2774
|
-
var MineRenderError = class _MineRenderError extends Error {
|
|
2775
|
-
constructor(msg) {
|
|
2776
|
-
super(msg);
|
|
2777
|
-
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
2778
|
-
}
|
|
2779
|
-
get name() {
|
|
2780
|
-
return "MineRenderError";
|
|
2781
|
-
}
|
|
2782
|
-
};
|
|
2783
|
-
|
|
2784
2779
|
// src/renderer/SceneObject.ts
|
|
2785
2780
|
var import_ts_deepmerge3 = __toESM(require_dist());
|
|
2786
2781
|
var p6 = prefix("SceneObject");
|
|
@@ -2906,15 +2901,8 @@ var _SceneObject = class _SceneObject extends Object3D2 {
|
|
|
2906
2901
|
return this.toggleObjectVisibility(this.getMeshByName(name), visible);
|
|
2907
2902
|
}
|
|
2908
2903
|
iterateAllMeshes(cb) {
|
|
2909
|
-
this.
|
|
2910
|
-
if (obj
|
|
2911
|
-
cb(obj);
|
|
2912
|
-
}
|
|
2913
|
-
obj.children.forEach((obj1) => {
|
|
2914
|
-
if (obj1.isMesh) {
|
|
2915
|
-
cb(obj1);
|
|
2916
|
-
}
|
|
2917
|
-
});
|
|
2904
|
+
this.traverse((obj) => {
|
|
2905
|
+
if (isMesh(obj)) cb(obj);
|
|
2918
2906
|
});
|
|
2919
2907
|
}
|
|
2920
2908
|
//</editor-fold>
|
|
@@ -3159,14 +3147,13 @@ function isSceneObject(obj) {
|
|
|
3159
3147
|
// src/entity/scene/EntityObject.ts
|
|
3160
3148
|
var import_ts_deepmerge4 = __toESM(require_dist());
|
|
3161
3149
|
import { Object3D as Object3D3 } from "three";
|
|
3162
|
-
|
|
3163
|
-
var EntityObject = class extends SceneObject {
|
|
3150
|
+
var _EntityObject = class _EntityObject extends SceneObject {
|
|
3164
3151
|
constructor(entity, options) {
|
|
3165
3152
|
super();
|
|
3166
3153
|
this.entity = entity;
|
|
3167
3154
|
this.isEntityObject = true;
|
|
3168
3155
|
this.meshesCreated = false;
|
|
3169
|
-
this.options = (0, import_ts_deepmerge4.default)({},
|
|
3156
|
+
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
3170
3157
|
}
|
|
3171
3158
|
async init() {
|
|
3172
3159
|
this.createMeshes();
|
|
@@ -3176,10 +3163,11 @@ var EntityObject = class extends SceneObject {
|
|
|
3176
3163
|
super.dispose();
|
|
3177
3164
|
}
|
|
3178
3165
|
get textureKey() {
|
|
3166
|
+
if (this.entity.texture) return this.entity.texture;
|
|
3167
|
+
const key = this.entity.key;
|
|
3179
3168
|
return new AssetKey(
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
//TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
|
|
3169
|
+
key.namespace,
|
|
3170
|
+
isAssetKey(key) ? key.getFullPath() : key.path,
|
|
3183
3171
|
"textures",
|
|
3184
3172
|
"entity",
|
|
3185
3173
|
"assets",
|
|
@@ -3189,36 +3177,41 @@ var EntityObject = class extends SceneObject {
|
|
|
3189
3177
|
async loadTextures() {
|
|
3190
3178
|
this.imageData = await ModelTextures.get(this.textureKey);
|
|
3191
3179
|
}
|
|
3192
|
-
//TODO: abstract this, since extracted model data can be used for entities, blocks, players
|
|
3193
3180
|
createMeshes(force = false) {
|
|
3194
3181
|
if (this.meshesCreated && !force) return;
|
|
3195
|
-
const
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
const partAnchor = new Object3D3();
|
|
3200
|
-
partAnchor.position.x = part.pivotX;
|
|
3201
|
-
partAnchor.position.y = part.pivotY;
|
|
3202
|
-
partAnchor.position.z = part.pivotZ;
|
|
3203
|
-
for (let cube of part.cubes) {
|
|
3204
|
-
const w = cube.maxX - cube.minX;
|
|
3205
|
-
const h = cube.maxY - cube.minY;
|
|
3206
|
-
const l = cube.maxZ - cube.minZ;
|
|
3207
|
-
const uv = texture.toUvArray(w, h, l);
|
|
3208
|
-
const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
|
|
3209
|
-
cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
|
|
3210
|
-
cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
|
|
3211
|
-
applyModelPartRotation(part, cubeGeo);
|
|
3212
|
-
const mesh = this.createMesh(partName, cubeGeo, mat);
|
|
3213
|
-
partAnchor.add(mesh);
|
|
3214
|
-
if (this.options.wireframe) {
|
|
3215
|
-
addWireframeToMesh(cubeGeo, mesh);
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
this.add(partAnchor);
|
|
3219
|
-
}
|
|
3182
|
+
const modelRoot = new Object3D3();
|
|
3183
|
+
if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
|
|
3184
|
+
this.add(modelRoot);
|
|
3185
|
+
this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
|
|
3220
3186
|
this.meshesCreated = true;
|
|
3221
3187
|
}
|
|
3188
|
+
createPart(name, part, parent, textureSize, material) {
|
|
3189
|
+
const anchor = this.createGroup(name);
|
|
3190
|
+
anchor.position.fromArray(part.pose.offset);
|
|
3191
|
+
anchor.rotation.set(...part.pose.rotation, "ZYX");
|
|
3192
|
+
anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
|
|
3193
|
+
parent.add(anchor);
|
|
3194
|
+
const size = part.texture ?? textureSize;
|
|
3195
|
+
for (const cube of part.cubes) {
|
|
3196
|
+
const [width, height, depth] = cube.size;
|
|
3197
|
+
const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
|
|
3198
|
+
const texture = new MinecraftCubeTexture(...cube.uv, ...size);
|
|
3199
|
+
const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
|
|
3200
|
+
const geometry = this._getBoxGeometryForDimensionsAndUv(
|
|
3201
|
+
width + growX * 2,
|
|
3202
|
+
height + growY * 2,
|
|
3203
|
+
depth + growZ * 2,
|
|
3204
|
+
uv
|
|
3205
|
+
).clone();
|
|
3206
|
+
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
3207
|
+
const mesh = this.createMesh(name, geometry, material);
|
|
3208
|
+
anchor.add(mesh);
|
|
3209
|
+
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
3210
|
+
}
|
|
3211
|
+
for (const [childName, child] of Object.entries(part.children)) {
|
|
3212
|
+
this.createPart(childName, child, anchor, size, material);
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3222
3215
|
async applyTextures() {
|
|
3223
3216
|
const assetKeyStr = this.textureKey.serialize();
|
|
3224
3217
|
const keyStr = `entity:${assetKeyStr}`;
|
|
@@ -3239,7 +3232,8 @@ var EntityObject = class extends SceneObject {
|
|
|
3239
3232
|
this.notifyDirty();
|
|
3240
3233
|
}
|
|
3241
3234
|
};
|
|
3242
|
-
|
|
3235
|
+
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, { flip: true });
|
|
3236
|
+
var EntityObject = _EntityObject;
|
|
3243
3237
|
function isEntityObject(obj) {
|
|
3244
3238
|
return obj.isEntityObject;
|
|
3245
3239
|
}
|
|
@@ -3770,7 +3764,7 @@ var BlockTints = class {
|
|
|
3770
3764
|
};
|
|
3771
3765
|
|
|
3772
3766
|
// src/model/scene/ModelObject.ts
|
|
3773
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as
|
|
3767
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler4, Matrix4 as Matrix44 } from "three";
|
|
3774
3768
|
|
|
3775
3769
|
// src/three/BufferGeometryUtils.js
|
|
3776
3770
|
import {
|
|
@@ -3782,7 +3776,7 @@ import {
|
|
|
3782
3776
|
TriangleFanDrawMode,
|
|
3783
3777
|
TriangleStripDrawMode,
|
|
3784
3778
|
TrianglesDrawMode,
|
|
3785
|
-
Vector3 as
|
|
3779
|
+
Vector3 as Vector36
|
|
3786
3780
|
} from "three";
|
|
3787
3781
|
function computeTangents(geometry) {
|
|
3788
3782
|
geometry.computeTangents();
|
|
@@ -4101,15 +4095,15 @@ function computeMorphedAttributes(object) {
|
|
|
4101
4095
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
4102
4096
|
return null;
|
|
4103
4097
|
}
|
|
4104
|
-
const _vA = new
|
|
4105
|
-
const _vB = new
|
|
4106
|
-
const _vC = new
|
|
4107
|
-
const _tempA = new
|
|
4108
|
-
const _tempB = new
|
|
4109
|
-
const _tempC = new
|
|
4110
|
-
const _morphA = new
|
|
4111
|
-
const _morphB = new
|
|
4112
|
-
const _morphC = new
|
|
4098
|
+
const _vA = new Vector36();
|
|
4099
|
+
const _vB = new Vector36();
|
|
4100
|
+
const _vC = new Vector36();
|
|
4101
|
+
const _tempA = new Vector36();
|
|
4102
|
+
const _tempB = new Vector36();
|
|
4103
|
+
const _tempC = new Vector36();
|
|
4104
|
+
const _morphA = new Vector36();
|
|
4105
|
+
const _morphB = new Vector36();
|
|
4106
|
+
const _morphC = new Vector36();
|
|
4113
4107
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
4114
4108
|
_vA.fromBufferAttribute(attribute, a2);
|
|
4115
4109
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4353,7 +4347,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4353
4347
|
this.atlas.model.elements?.forEach((el) => {
|
|
4354
4348
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
4355
4349
|
if (this.options.uvLockRotation) {
|
|
4356
|
-
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new
|
|
4350
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler4(...this.options.uvLockRotation));
|
|
4357
4351
|
}
|
|
4358
4352
|
if (this.options.tints) {
|
|
4359
4353
|
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
@@ -4369,12 +4363,12 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4369
4363
|
}
|
|
4370
4364
|
elGeo.setAttribute("color", new BufferAttribute4(colors, 3));
|
|
4371
4365
|
}
|
|
4372
|
-
elGeo.applyMatrix4(new
|
|
4373
|
-
elGeo.applyMatrix4(new
|
|
4366
|
+
elGeo.applyMatrix4(new Matrix44().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
|
|
4367
|
+
elGeo.applyMatrix4(new Matrix44().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4374
4368
|
if (el.rotation) {
|
|
4375
4369
|
applyElementRotation(el.rotation, elGeo);
|
|
4376
4370
|
}
|
|
4377
|
-
elGeo.applyMatrix4(new
|
|
4371
|
+
elGeo.applyMatrix4(new Matrix44().makeTranslation(-8, -8, -8));
|
|
4378
4372
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4379
4373
|
if (this.options.mergeMeshes) {
|
|
4380
4374
|
allGeos.push(elGeo);
|
|
@@ -4451,7 +4445,7 @@ function isModelObject(obj) {
|
|
|
4451
4445
|
|
|
4452
4446
|
// src/model/block/scene/BlockObject.ts
|
|
4453
4447
|
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4454
|
-
import { Euler as
|
|
4448
|
+
import { Euler as Euler5, Matrix4 as Matrix45, Vector3 as Vector37 } from "three";
|
|
4455
4449
|
var p10 = prefix("BlockObject");
|
|
4456
4450
|
function matchesCondition(condition, state) {
|
|
4457
4451
|
return Object.entries(condition).every(([key, value]) => {
|
|
@@ -4508,7 +4502,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4508
4502
|
if (isModelObject(model)) {
|
|
4509
4503
|
model.removeFromScene();
|
|
4510
4504
|
} else if (isInstanceReference(model)) {
|
|
4511
|
-
model.setScale(new
|
|
4505
|
+
model.setScale(new Vector37(0, 0, 0));
|
|
4512
4506
|
}
|
|
4513
4507
|
}
|
|
4514
4508
|
super.removeFromScene();
|
|
@@ -4569,7 +4563,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4569
4563
|
}
|
|
4570
4564
|
for (let model of this._models) {
|
|
4571
4565
|
if (isInstanceReference(model)) {
|
|
4572
|
-
model.setScale(new
|
|
4566
|
+
model.setScale(new Vector37(0, 0, 0));
|
|
4573
4567
|
} else {
|
|
4574
4568
|
model.dispose();
|
|
4575
4569
|
}
|
|
@@ -4606,7 +4600,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4606
4600
|
await this.createVariant(variant);
|
|
4607
4601
|
}
|
|
4608
4602
|
async createVariant(variant) {
|
|
4609
|
-
const rotation = new
|
|
4603
|
+
const rotation = new Euler5();
|
|
4610
4604
|
if (typeof variant.x !== "undefined") {
|
|
4611
4605
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4612
4606
|
}
|
|
@@ -4693,7 +4687,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4693
4687
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
4694
4688
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
4695
4689
|
}
|
|
4696
|
-
getMatrixAt(index, matrix = new
|
|
4690
|
+
getMatrixAt(index, matrix = new Matrix45()) {
|
|
4697
4691
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
4698
4692
|
const child = this._models[0];
|
|
4699
4693
|
if (child && isModelObject(child)) {
|
|
@@ -5739,7 +5733,7 @@ function isMineRenderScene(obj) {
|
|
|
5739
5733
|
}
|
|
5740
5734
|
|
|
5741
5735
|
// src/renderer/Renderer.ts
|
|
5742
|
-
import { AxesHelper as
|
|
5736
|
+
import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector39, WebGLRenderer } from "three";
|
|
5743
5737
|
var import_ts_deepmerge9 = __toESM(require_dist());
|
|
5744
5738
|
import Stats from "stats.js";
|
|
5745
5739
|
import { EffectComposer, RenderPass } from "postprocessing";
|
|
@@ -5752,7 +5746,7 @@ import {
|
|
|
5752
5746
|
Spherical,
|
|
5753
5747
|
TOUCH,
|
|
5754
5748
|
Vector2 as Vector23,
|
|
5755
|
-
Vector3 as
|
|
5749
|
+
Vector3 as Vector38
|
|
5756
5750
|
} from "three";
|
|
5757
5751
|
var _changeEvent = { type: "change" };
|
|
5758
5752
|
var _startEvent = { type: "start" };
|
|
@@ -5766,7 +5760,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5766
5760
|
this.domElement = domElement;
|
|
5767
5761
|
this.domElement.style.touchAction = "none";
|
|
5768
5762
|
this.enabled = true;
|
|
5769
|
-
this.target = new
|
|
5763
|
+
this.target = new Vector38();
|
|
5770
5764
|
this.minDistance = 0;
|
|
5771
5765
|
this.maxDistance = Infinity;
|
|
5772
5766
|
this.minZoom = 0;
|
|
@@ -5818,10 +5812,10 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5818
5812
|
state = STATE.NONE;
|
|
5819
5813
|
};
|
|
5820
5814
|
this.update = function() {
|
|
5821
|
-
const offset = new
|
|
5822
|
-
const quat = new Quaternion4().setFromUnitVectors(object.up, new
|
|
5815
|
+
const offset = new Vector38();
|
|
5816
|
+
const quat = new Quaternion4().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
|
|
5823
5817
|
const quatInverse = quat.clone().invert();
|
|
5824
|
-
const lastPosition = new
|
|
5818
|
+
const lastPosition = new Vector38();
|
|
5825
5819
|
const lastQuaternion = new Quaternion4();
|
|
5826
5820
|
const twoPI = 2 * Math.PI;
|
|
5827
5821
|
return function update() {
|
|
@@ -5911,7 +5905,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5911
5905
|
const spherical = new Spherical();
|
|
5912
5906
|
const sphericalDelta = new Spherical();
|
|
5913
5907
|
let scale = 1;
|
|
5914
|
-
const panOffset = new
|
|
5908
|
+
const panOffset = new Vector38();
|
|
5915
5909
|
let zoomChanged = false;
|
|
5916
5910
|
const rotateStart = new Vector23();
|
|
5917
5911
|
const rotateEnd = new Vector23();
|
|
@@ -5937,7 +5931,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5937
5931
|
sphericalDelta.phi -= angle;
|
|
5938
5932
|
}
|
|
5939
5933
|
const panLeft = function() {
|
|
5940
|
-
const v = new
|
|
5934
|
+
const v = new Vector38();
|
|
5941
5935
|
return function panLeft2(distance, objectMatrix) {
|
|
5942
5936
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
5943
5937
|
v.multiplyScalar(-distance);
|
|
@@ -5945,7 +5939,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5945
5939
|
};
|
|
5946
5940
|
}();
|
|
5947
5941
|
const panUp = function() {
|
|
5948
|
-
const v = new
|
|
5942
|
+
const v = new Vector38();
|
|
5949
5943
|
return function panUp2(distance, objectMatrix) {
|
|
5950
5944
|
if (scope.screenSpacePanning === true) {
|
|
5951
5945
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -5958,7 +5952,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
5958
5952
|
};
|
|
5959
5953
|
}();
|
|
5960
5954
|
const pan = function() {
|
|
5961
|
-
const offset = new
|
|
5955
|
+
const offset = new Vector38();
|
|
5962
5956
|
return function pan2(deltaX, deltaY) {
|
|
5963
5957
|
const element = scope.domElement;
|
|
5964
5958
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -6501,7 +6495,7 @@ var _Renderer = class _Renderer {
|
|
|
6501
6495
|
this.scene.add(gridHelper3);
|
|
6502
6496
|
}
|
|
6503
6497
|
if (this.options.debug.axes) {
|
|
6504
|
-
const axesHelper = new
|
|
6498
|
+
const axesHelper = new AxesHelper2(64);
|
|
6505
6499
|
this._debugHelpers.push(axesHelper);
|
|
6506
6500
|
this.scene.add(axesHelper);
|
|
6507
6501
|
}
|
|
@@ -6705,8 +6699,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
|
|
|
6705
6699
|
top: void 0,
|
|
6706
6700
|
bottom: void 0
|
|
6707
6701
|
},
|
|
6708
|
-
position: new
|
|
6709
|
-
lookingAt: new
|
|
6702
|
+
position: new Vector39(50, 50, 50),
|
|
6703
|
+
lookingAt: new Vector39(0, 0, 0)
|
|
6710
6704
|
},
|
|
6711
6705
|
render: {
|
|
6712
6706
|
fpsLimit: 60,
|
|
@@ -6900,10 +6894,10 @@ var Skins = class {
|
|
|
6900
6894
|
};
|
|
6901
6895
|
|
|
6902
6896
|
// src/world/Chunk.ts
|
|
6903
|
-
import { Box3 as Box32, Object3D as Object3D6, Vector3 as
|
|
6897
|
+
import { Box3 as Box32, Object3D as Object3D6, Vector3 as Vector311 } from "three";
|
|
6904
6898
|
|
|
6905
6899
|
// src/world/MineRenderWorld.ts
|
|
6906
|
-
import { Vector3 as
|
|
6900
|
+
import { Vector3 as Vector310 } from "three";
|
|
6907
6901
|
var MineRenderWorld = class {
|
|
6908
6902
|
constructor(scene) {
|
|
6909
6903
|
this._size = 4;
|
|
@@ -6914,10 +6908,10 @@ var MineRenderWorld = class {
|
|
|
6914
6908
|
}
|
|
6915
6909
|
getBlockAt(posOrX, y, z) {
|
|
6916
6910
|
if (typeof posOrX == "number") {
|
|
6917
|
-
return this.getBlockAt(new
|
|
6911
|
+
return this.getBlockAt(new Vector310(posOrX, y, z));
|
|
6918
6912
|
}
|
|
6919
6913
|
if (isTripleArray(posOrX)) {
|
|
6920
|
-
return this.getBlockAt(new
|
|
6914
|
+
return this.getBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]));
|
|
6921
6915
|
}
|
|
6922
6916
|
const chunk = this.getChunkAt(posOrX);
|
|
6923
6917
|
if (typeof chunk === "undefined") {
|
|
@@ -6928,10 +6922,10 @@ var MineRenderWorld = class {
|
|
|
6928
6922
|
}
|
|
6929
6923
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
6930
6924
|
if (typeof posOrX == "number") {
|
|
6931
|
-
return this.setBlockAt(new
|
|
6925
|
+
return this.setBlockAt(new Vector310(posOrX, yOrBlock, z), block);
|
|
6932
6926
|
}
|
|
6933
6927
|
if (isTripleArray(posOrX)) {
|
|
6934
|
-
return this.setBlockAt(new
|
|
6928
|
+
return this.setBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
6935
6929
|
}
|
|
6936
6930
|
this.validatePosBounds(posOrX);
|
|
6937
6931
|
const chunk = this.getOrCreateChunkAt(posOrX);
|
|
@@ -6977,14 +6971,14 @@ var MineRenderWorld = class {
|
|
|
6977
6971
|
return this._chunks[index];
|
|
6978
6972
|
}
|
|
6979
6973
|
static worldToScenePosition(pos) {
|
|
6980
|
-
return new
|
|
6974
|
+
return new Vector310(
|
|
6981
6975
|
pos.x * 16,
|
|
6982
6976
|
pos.y * 16,
|
|
6983
6977
|
pos.z * 16
|
|
6984
6978
|
);
|
|
6985
6979
|
}
|
|
6986
6980
|
static sceneToWorldPosition(pos) {
|
|
6987
|
-
return new
|
|
6981
|
+
return new Vector310(
|
|
6988
6982
|
pos.x / 16,
|
|
6989
6983
|
pos.y / 16,
|
|
6990
6984
|
pos.z / 16
|
|
@@ -7026,7 +7020,7 @@ var Chunk = class _Chunk {
|
|
|
7026
7020
|
scene.add(anchor);
|
|
7027
7021
|
anchor.position.set(this.x * 256 + 128 - 8, this.y * 256 + 128 - 8, this.z * 256 + 128 - 8);
|
|
7028
7022
|
addBox3WireframeToObject(
|
|
7029
|
-
new Box32(new
|
|
7023
|
+
new Box32(new Vector311(0, 0, 0), new Vector311(256, 256, 256)),
|
|
7030
7024
|
anchor,
|
|
7031
7025
|
16776960,
|
|
7032
7026
|
4
|
|
@@ -7034,10 +7028,10 @@ var Chunk = class _Chunk {
|
|
|
7034
7028
|
}
|
|
7035
7029
|
getBlockAt(posOrX, y, z) {
|
|
7036
7030
|
if (typeof posOrX == "number") {
|
|
7037
|
-
return this.getBlockAt(new
|
|
7031
|
+
return this.getBlockAt(new Vector311(posOrX, y, z));
|
|
7038
7032
|
}
|
|
7039
7033
|
if (isTripleArray(posOrX)) {
|
|
7040
|
-
return this.getBlockAt(new
|
|
7034
|
+
return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
|
|
7041
7035
|
}
|
|
7042
7036
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
7043
7037
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -7045,10 +7039,10 @@ var Chunk = class _Chunk {
|
|
|
7045
7039
|
}
|
|
7046
7040
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7047
7041
|
if (typeof posOrX == "number") {
|
|
7048
|
-
return this.setBlockAt(new
|
|
7042
|
+
return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
|
|
7049
7043
|
}
|
|
7050
7044
|
if (isTripleArray(posOrX)) {
|
|
7051
|
-
return this.setBlockAt(new
|
|
7045
|
+
return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7052
7046
|
}
|
|
7053
7047
|
const worldPos = posOrX;
|
|
7054
7048
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -7094,7 +7088,7 @@ var Chunk = class _Chunk {
|
|
|
7094
7088
|
}
|
|
7095
7089
|
async clear() {
|
|
7096
7090
|
let promises = [];
|
|
7097
|
-
let pos = new
|
|
7091
|
+
let pos = new Vector311();
|
|
7098
7092
|
for (let x = 0; x < 16; x++) {
|
|
7099
7093
|
for (let z = 0; z < 16; z++) {
|
|
7100
7094
|
for (let y = 0; y < 16; y++) {
|
|
@@ -7113,14 +7107,14 @@ var Chunk = class _Chunk {
|
|
|
7113
7107
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
7114
7108
|
}
|
|
7115
7109
|
worldPosToChunkPos(pos) {
|
|
7116
|
-
return new
|
|
7110
|
+
return new Vector311(
|
|
7117
7111
|
pos.x - this.x * 16,
|
|
7118
7112
|
pos.y - this.y * 16,
|
|
7119
7113
|
pos.z - this.z * 16
|
|
7120
7114
|
);
|
|
7121
7115
|
}
|
|
7122
7116
|
chunkPosToWorldPos(pos) {
|
|
7123
|
-
return new
|
|
7117
|
+
return new Vector311(
|
|
7124
7118
|
this.x * 16 + pos.x,
|
|
7125
7119
|
this.y * 16 + pos.y,
|
|
7126
7120
|
this.z * 16 + pos.z
|
|
@@ -7141,7 +7135,6 @@ export {
|
|
|
7141
7135
|
BUILTIN_GENERATED,
|
|
7142
7136
|
BasicAssetKey,
|
|
7143
7137
|
BatchedExecutor,
|
|
7144
|
-
BlockEntityModels,
|
|
7145
7138
|
BlockObject,
|
|
7146
7139
|
BlockStates,
|
|
7147
7140
|
BlockTints,
|
|
@@ -7163,7 +7156,6 @@ export {
|
|
|
7163
7156
|
DisplayPosition,
|
|
7164
7157
|
DisplayTransforms,
|
|
7165
7158
|
Entities,
|
|
7166
|
-
EntityModels,
|
|
7167
7159
|
EntityObject,
|
|
7168
7160
|
Env,
|
|
7169
7161
|
Geometries,
|
|
@@ -7215,7 +7207,6 @@ export {
|
|
|
7215
7207
|
addWireframeToObject,
|
|
7216
7208
|
applyElementRotation,
|
|
7217
7209
|
applyGenericRotation,
|
|
7218
|
-
applyModelPartRotation,
|
|
7219
7210
|
axisToVec3,
|
|
7220
7211
|
base64decode,
|
|
7221
7212
|
base64encode,
|