minerender 2.1.0-alpha.52 → 2.1.0-alpha.54
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 +157 -47
- package/dist/browser/index.d.ts +157 -47
- package/dist/browser/index.js +364 -122
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +373 -131
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +329 -87
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +157 -47
- package/dist/node/index.d.ts +157 -47
- package/dist/node/index.js +364 -122
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +373 -131
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -33153,6 +33153,71 @@ var MineRender = (() => {
|
|
|
33153
33153
|
alphaTest: 0.5
|
|
33154
33154
|
});
|
|
33155
33155
|
}
|
|
33156
|
+
/** Whether vanilla's render type for the mode culls back faces. */
|
|
33157
|
+
static entityModeCulls(mode2 = "cutout") {
|
|
33158
|
+
return mode2 === "cutout_cull" || mode2 === "solid" || mode2 === "eyes" || mode2 === "water_mask";
|
|
33159
|
+
}
|
|
33160
|
+
/** UV offset per tick of entity age for the scrolling modes, as vanilla's texture matrix applies it. */
|
|
33161
|
+
static entityModeScroll(mode2 = "cutout") {
|
|
33162
|
+
if (mode2 === "energy_swirl") return [0.01, 0.01];
|
|
33163
|
+
if (mode2 === "breeze_wind") return [0.02, 0];
|
|
33164
|
+
return void 0;
|
|
33165
|
+
}
|
|
33166
|
+
/**
|
|
33167
|
+
* Entity material for one of vanilla's render types. Entities are unlit here, so the lit and full-bright modes
|
|
33168
|
+
* differ only in blending and depth state. Culling is not a material property: {@link entityModeCulls} decides
|
|
33169
|
+
* whether the geometry gets inward faces.
|
|
33170
|
+
*/
|
|
33171
|
+
static createEntityCanvasMaterial(canvas, mode2 = "cutout", tint) {
|
|
33172
|
+
const material = _Materials.createBasicCanvasMaterial(canvas);
|
|
33173
|
+
switch (mode2) {
|
|
33174
|
+
case "cutout":
|
|
33175
|
+
case "cutout_cull":
|
|
33176
|
+
break;
|
|
33177
|
+
case "cutout_z_offset":
|
|
33178
|
+
material.polygonOffset = true;
|
|
33179
|
+
material.polygonOffsetFactor = -1;
|
|
33180
|
+
material.polygonOffsetUnits = -10;
|
|
33181
|
+
break;
|
|
33182
|
+
case "solid":
|
|
33183
|
+
material.alphaTest = 0;
|
|
33184
|
+
break;
|
|
33185
|
+
case "translucent":
|
|
33186
|
+
case "breeze_wind":
|
|
33187
|
+
material.transparent = true;
|
|
33188
|
+
material.alphaTest = 0.1;
|
|
33189
|
+
break;
|
|
33190
|
+
case "translucent_emissive":
|
|
33191
|
+
material.transparent = true;
|
|
33192
|
+
material.alphaTest = 0.1;
|
|
33193
|
+
material.depthWrite = false;
|
|
33194
|
+
break;
|
|
33195
|
+
case "eyes":
|
|
33196
|
+
material.transparent = true;
|
|
33197
|
+
material.alphaTest = 0;
|
|
33198
|
+
material.depthWrite = false;
|
|
33199
|
+
break;
|
|
33200
|
+
case "energy_swirl":
|
|
33201
|
+
material.transparent = true;
|
|
33202
|
+
material.alphaTest = 0.1;
|
|
33203
|
+
material.blending = CustomBlending;
|
|
33204
|
+
material.blendSrc = OneFactor;
|
|
33205
|
+
material.blendDst = OneFactor;
|
|
33206
|
+
material.blendSrcAlpha = ZeroFactor;
|
|
33207
|
+
material.blendDstAlpha = OneFactor;
|
|
33208
|
+
material.color.set(8421504);
|
|
33209
|
+
break;
|
|
33210
|
+
case "water_mask":
|
|
33211
|
+
material.alphaTest = 0;
|
|
33212
|
+
material.colorWrite = false;
|
|
33213
|
+
break;
|
|
33214
|
+
}
|
|
33215
|
+
if (_Materials.entityModeScroll(mode2)) {
|
|
33216
|
+
material.map.wrapS = material.map.wrapT = RepeatWrapping;
|
|
33217
|
+
}
|
|
33218
|
+
if (tint !== void 0) material.color.multiply(new Color(tint));
|
|
33219
|
+
return material;
|
|
33220
|
+
}
|
|
33156
33221
|
static createGuiCanvasMaterial(canvas) {
|
|
33157
33222
|
const material = new MeshBasicMaterial({
|
|
33158
33223
|
map: Textures.createCanvasTexture(canvas),
|
|
@@ -79134,51 +79199,6 @@ ${key}` : key;
|
|
|
79134
79199
|
}
|
|
79135
79200
|
});
|
|
79136
79201
|
|
|
79137
|
-
// src/model/ModelCulling.ts
|
|
79138
|
-
var ModelCulling;
|
|
79139
|
-
var init_ModelCulling = __esm({
|
|
79140
|
-
"src/model/ModelCulling.ts"() {
|
|
79141
|
-
init_dirname();
|
|
79142
|
-
init_buffer2();
|
|
79143
|
-
init_process2();
|
|
79144
|
-
init_three_module();
|
|
79145
|
-
init_CubeFace();
|
|
79146
|
-
ModelCulling = class {
|
|
79147
|
-
static toLocalMask(worldMask, rotation) {
|
|
79148
|
-
let localMask = 0;
|
|
79149
|
-
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
79150
|
-
const normal = new Vector3(...offset).applyEuler(rotation);
|
|
79151
|
-
const worldFace = CUBE_FACE_OFFSETS.findIndex(([x4, y5, z4]) => Math.abs(normal.x - x4) < 1e-6 && Math.abs(normal.y - y5) < 1e-6 && Math.abs(normal.z - z4) < 1e-6);
|
|
79152
|
-
if (worldFace < 0) return 0;
|
|
79153
|
-
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
79154
|
-
}
|
|
79155
|
-
return localMask;
|
|
79156
|
-
}
|
|
79157
|
-
static isOpaqueFullCube(atlas) {
|
|
79158
|
-
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
79159
|
-
const element = atlas.model.elements[0];
|
|
79160
|
-
if (element.from.length !== 3 || !element.from.every((value) => value === 0) || element.to.length !== 3 || !element.to.every((value) => value === 16) || element.rotation && element.rotation.angle !== 0 || element.mappedUv?.length !== 48 || !element.mappedUv.every(Number.isFinite)) return false;
|
|
79161
|
-
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
79162
|
-
return CUBE_FACES.every((face, faceIndex) => {
|
|
79163
|
-
const texture = element.faces[face]?.texture;
|
|
79164
|
-
if (!texture?.startsWith("#")) return false;
|
|
79165
|
-
const key = texture.slice(1);
|
|
79166
|
-
const position = atlas.positions[key];
|
|
79167
|
-
const size = atlas.sizes[key];
|
|
79168
|
-
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
79169
|
-
for (let vertex2 = 0; vertex2 < 4; vertex2++) {
|
|
79170
|
-
const uvIndex = (faceIndex * 4 + vertex2) * 2;
|
|
79171
|
-
const x4 = element.mappedUv[uvIndex] * atlas.image.width;
|
|
79172
|
-
const y5 = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
79173
|
-
if (x4 < position[0] - 1e-6 || x4 > position[0] + size[0] + 1e-6 || y5 < position[1] - 1e-6 || y5 > position[1] + size[1] + 1e-6) return false;
|
|
79174
|
-
}
|
|
79175
|
-
return true;
|
|
79176
|
-
});
|
|
79177
|
-
}
|
|
79178
|
-
};
|
|
79179
|
-
}
|
|
79180
|
-
});
|
|
79181
|
-
|
|
79182
79202
|
// src/three/BufferGeometryUtils.js
|
|
79183
79203
|
function computeTangents(geometry) {
|
|
79184
79204
|
geometry.computeTangents();
|
|
@@ -79718,11 +79738,56 @@ ${key}` : key;
|
|
|
79718
79738
|
}
|
|
79719
79739
|
});
|
|
79720
79740
|
|
|
79741
|
+
// src/model/ModelCulling.ts
|
|
79742
|
+
var ModelCulling;
|
|
79743
|
+
var init_ModelCulling = __esm({
|
|
79744
|
+
"src/model/ModelCulling.ts"() {
|
|
79745
|
+
init_dirname();
|
|
79746
|
+
init_buffer2();
|
|
79747
|
+
init_process2();
|
|
79748
|
+
init_three_module();
|
|
79749
|
+
init_CubeFace();
|
|
79750
|
+
ModelCulling = class {
|
|
79751
|
+
static toLocalMask(worldMask, rotation) {
|
|
79752
|
+
let localMask = 0;
|
|
79753
|
+
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
79754
|
+
const normal = new Vector3(...offset).applyEuler(rotation);
|
|
79755
|
+
const worldFace = CUBE_FACE_OFFSETS.findIndex(([x4, y5, z4]) => Math.abs(normal.x - x4) < 1e-6 && Math.abs(normal.y - y5) < 1e-6 && Math.abs(normal.z - z4) < 1e-6);
|
|
79756
|
+
if (worldFace < 0) return 0;
|
|
79757
|
+
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
79758
|
+
}
|
|
79759
|
+
return localMask;
|
|
79760
|
+
}
|
|
79761
|
+
static isOpaqueFullCube(atlas) {
|
|
79762
|
+
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
79763
|
+
const element = atlas.model.elements[0];
|
|
79764
|
+
if (element.from.length !== 3 || !element.from.every((value) => value === 0) || element.to.length !== 3 || !element.to.every((value) => value === 16) || element.rotation && element.rotation.angle !== 0 || element.mappedUv?.length !== 48 || !element.mappedUv.every(Number.isFinite)) return false;
|
|
79765
|
+
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
79766
|
+
return CUBE_FACES.every((face, faceIndex) => {
|
|
79767
|
+
const texture = element.faces[face]?.texture;
|
|
79768
|
+
if (!texture?.startsWith("#")) return false;
|
|
79769
|
+
const key = texture.slice(1);
|
|
79770
|
+
const position = atlas.positions[key];
|
|
79771
|
+
const size = atlas.sizes[key];
|
|
79772
|
+
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
79773
|
+
for (let vertex2 = 0; vertex2 < 4; vertex2++) {
|
|
79774
|
+
const uvIndex = (faceIndex * 4 + vertex2) * 2;
|
|
79775
|
+
const x4 = element.mappedUv[uvIndex] * atlas.image.width;
|
|
79776
|
+
const y5 = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
79777
|
+
if (x4 < position[0] - 1e-6 || x4 > position[0] + size[0] + 1e-6 || y5 < position[1] - 1e-6 || y5 > position[1] + size[1] + 1e-6) return false;
|
|
79778
|
+
}
|
|
79779
|
+
return true;
|
|
79780
|
+
});
|
|
79781
|
+
}
|
|
79782
|
+
};
|
|
79783
|
+
}
|
|
79784
|
+
});
|
|
79785
|
+
|
|
79721
79786
|
// src/model/scene/ModelObject.ts
|
|
79722
79787
|
function isModelObject(obj) {
|
|
79723
79788
|
return obj.isModelObject;
|
|
79724
79789
|
}
|
|
79725
|
-
var import_ts_deepmerge5,
|
|
79790
|
+
var import_ts_deepmerge5, p10, _ModelObject, ModelObject;
|
|
79726
79791
|
var init_ModelObject = __esm({
|
|
79727
79792
|
"src/model/scene/ModelObject.ts"() {
|
|
79728
79793
|
init_dirname();
|
|
@@ -79739,7 +79804,7 @@ ${key}` : key;
|
|
|
79739
79804
|
init_CubeFace();
|
|
79740
79805
|
init_DisplayTransforms();
|
|
79741
79806
|
init_ModelCulling();
|
|
79742
|
-
|
|
79807
|
+
p10 = prefix("ModelObject");
|
|
79743
79808
|
_ModelObject = class _ModelObject extends SceneObject {
|
|
79744
79809
|
constructor(originalModel, options) {
|
|
79745
79810
|
super(options);
|
|
@@ -79818,10 +79883,10 @@ ${key}` : key;
|
|
|
79818
79883
|
}
|
|
79819
79884
|
});
|
|
79820
79885
|
} else {
|
|
79821
|
-
console.debug(
|
|
79886
|
+
console.debug(p10, this.atlas.model, "has no elements");
|
|
79822
79887
|
}
|
|
79823
79888
|
} else {
|
|
79824
|
-
console.debug(
|
|
79889
|
+
console.debug(p10, "Missing atlas for", this);
|
|
79825
79890
|
}
|
|
79826
79891
|
if (this.options.mergeMeshes) {
|
|
79827
79892
|
let combinedGeo;
|
|
@@ -83512,32 +83577,44 @@ ${key}` : key;
|
|
|
83512
83577
|
static async getLayerList(modelKey) {
|
|
83513
83578
|
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
83514
83579
|
}
|
|
83580
|
+
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
83581
|
+
static async getPassList(modelKey) {
|
|
83582
|
+
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
83583
|
+
}
|
|
83515
83584
|
static async getEntity(modelKey, textureKey, options) {
|
|
83516
83585
|
const model = await this.getModelFile(modelKey);
|
|
83517
83586
|
if (!model) return void 0;
|
|
83518
|
-
const
|
|
83519
|
-
|
|
83520
|
-
|
|
83521
|
-
|
|
83587
|
+
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
83588
|
+
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
83589
|
+
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
83590
|
+
draws.push(...passes);
|
|
83591
|
+
const names = [];
|
|
83592
|
+
const selected = draws.map((pass) => {
|
|
83593
|
+
const layer = model.layers[pass.layer];
|
|
83522
83594
|
if (!layer) {
|
|
83523
|
-
throw new MineRenderError(`Entity ${model.id} has no layer "${
|
|
83595
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
83524
83596
|
}
|
|
83525
|
-
|
|
83597
|
+
let name2 = pass.layer;
|
|
83598
|
+
for (let n4 = 2; names.includes(name2); n4++) name2 = `${pass.layer}#${n4}`;
|
|
83599
|
+
names.push(name2);
|
|
83600
|
+
return { name: name2, layer, pass };
|
|
83526
83601
|
});
|
|
83527
|
-
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name: name2, layer }, index) => {
|
|
83602
|
+
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name: name2, layer, pass }, index) => {
|
|
83528
83603
|
const override = options?.textures?.[name2] ?? (index === 0 ? textureKey : void 0);
|
|
83604
|
+
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
83529
83605
|
let texture;
|
|
83530
83606
|
if (override) {
|
|
83531
83607
|
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
83532
83608
|
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);
|
|
83533
|
-
} else if (
|
|
83534
|
-
texture = AssetKey.parse("textures",
|
|
83609
|
+
} else if (textureLocation !== void 0) {
|
|
83610
|
+
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
83535
83611
|
} else {
|
|
83536
83612
|
texture = await this.resolveTexture(modelKey);
|
|
83537
83613
|
}
|
|
83538
|
-
|
|
83614
|
+
const render = pass.render ?? layer.render;
|
|
83615
|
+
return [name2, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
83539
83616
|
})));
|
|
83540
|
-
return { ...layers[names[0]], id: model.id, layers };
|
|
83617
|
+
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
83541
83618
|
}
|
|
83542
83619
|
static async resolveTexture(modelKey) {
|
|
83543
83620
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
@@ -83672,6 +83749,7 @@ ${key}` : key;
|
|
|
83672
83749
|
init_Caching();
|
|
83673
83750
|
var import_ts_deepmerge4 = __toESM(require_dist());
|
|
83674
83751
|
init_three_module();
|
|
83752
|
+
init_Ticker();
|
|
83675
83753
|
init_model();
|
|
83676
83754
|
init_ModelTextures();
|
|
83677
83755
|
init_AssetKey();
|
|
@@ -83683,6 +83761,10 @@ ${key}` : key;
|
|
|
83683
83761
|
this.entity = entity;
|
|
83684
83762
|
this.isEntityObject = true;
|
|
83685
83763
|
this.meshesCreated = false;
|
|
83764
|
+
/** Scrolling materials are owned: their texture offset follows this entity's age. */
|
|
83765
|
+
this.scrollMaterials = [];
|
|
83766
|
+
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
83767
|
+
this.age = 0;
|
|
83686
83768
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
83687
83769
|
}
|
|
83688
83770
|
async init() {
|
|
@@ -83692,6 +83774,25 @@ ${key}` : key;
|
|
|
83692
83774
|
dispose() {
|
|
83693
83775
|
super.dispose();
|
|
83694
83776
|
}
|
|
83777
|
+
disposeAndRemoveAllChildren() {
|
|
83778
|
+
this.clearScrollMaterials();
|
|
83779
|
+
super.disposeAndRemoveAllChildren();
|
|
83780
|
+
}
|
|
83781
|
+
clearScrollMaterials() {
|
|
83782
|
+
Ticker.remove(this.scrollTicker);
|
|
83783
|
+
this.scrollTicker = void 0;
|
|
83784
|
+
for (const { material } of this.scrollMaterials.splice(0)) {
|
|
83785
|
+
material.map?.dispose();
|
|
83786
|
+
material.dispose();
|
|
83787
|
+
}
|
|
83788
|
+
}
|
|
83789
|
+
/** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
|
|
83790
|
+
updateScroll() {
|
|
83791
|
+
for (const { offset, speed } of this.scrollMaterials) {
|
|
83792
|
+
offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
|
|
83793
|
+
}
|
|
83794
|
+
this.notifyDirty();
|
|
83795
|
+
}
|
|
83695
83796
|
getLayerGroup(name2) {
|
|
83696
83797
|
return super.getGroupByName(`layer:${name2}`);
|
|
83697
83798
|
}
|
|
@@ -83722,16 +83823,29 @@ ${key}` : key;
|
|
|
83722
83823
|
createMeshes(force = false) {
|
|
83723
83824
|
if (this.meshesCreated && !force) return;
|
|
83724
83825
|
const modelRoot = new Object3D();
|
|
83725
|
-
|
|
83826
|
+
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
83827
|
+
if (transform) {
|
|
83828
|
+
for (const op of transform) {
|
|
83829
|
+
const matrix = new Matrix4();
|
|
83830
|
+
if ("scale" in op) matrix.makeScale(...op.scale);
|
|
83831
|
+
else if ("translate" in op) matrix.makeTranslation(...op.translate);
|
|
83832
|
+
else matrix.makeRotationFromEuler(new Euler(...op.rotate, "ZYX"));
|
|
83833
|
+
modelRoot.matrix.multiply(matrix);
|
|
83834
|
+
}
|
|
83835
|
+
modelRoot.matrixAutoUpdate = false;
|
|
83836
|
+
} else if (this.options.flip ?? true) {
|
|
83837
|
+
modelRoot.scale.set(-1, -1, 1);
|
|
83838
|
+
}
|
|
83726
83839
|
this.add(modelRoot);
|
|
83727
83840
|
Object.entries(this.entityLayers).forEach(([name2, layer], index) => {
|
|
83728
83841
|
const group = this.createGroup(`layer:${name2}`);
|
|
83729
83842
|
modelRoot.add(group);
|
|
83730
|
-
|
|
83843
|
+
const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
|
|
83844
|
+
this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
|
|
83731
83845
|
});
|
|
83732
83846
|
this.meshesCreated = true;
|
|
83733
83847
|
}
|
|
83734
|
-
createPart(name2, part, parent, textureSize, material, renderOrder) {
|
|
83848
|
+
createPart(name2, part, parent, textureSize, material, renderOrder, inward = true) {
|
|
83735
83849
|
const anchor = this.createGroup(name2);
|
|
83736
83850
|
anchor.position.fromArray(part.pose.offset);
|
|
83737
83851
|
anchor.rotation.set(...part.pose.rotation, "ZYX");
|
|
@@ -83750,7 +83864,7 @@ ${key}` : key;
|
|
|
83750
83864
|
uv
|
|
83751
83865
|
).clone();
|
|
83752
83866
|
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
83753
|
-
if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
83867
|
+
if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
83754
83868
|
const index = Array.from(geometry.getIndex().array);
|
|
83755
83869
|
geometry.setIndex(index.concat(index.slice().reverse()));
|
|
83756
83870
|
}
|
|
@@ -83760,30 +83874,46 @@ ${key}` : key;
|
|
|
83760
83874
|
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
83761
83875
|
}
|
|
83762
83876
|
for (const [childName, child] of Object.entries(part.children)) {
|
|
83763
|
-
this.createPart(childName, child, anchor, size, material, renderOrder);
|
|
83877
|
+
this.createPart(childName, child, anchor, size, material, renderOrder, inward);
|
|
83764
83878
|
}
|
|
83765
83879
|
}
|
|
83766
83880
|
async applyTextures() {
|
|
83881
|
+
this.clearScrollMaterials();
|
|
83767
83882
|
await Promise.all(Object.entries(this.entityLayers).map(async ([name2, layer]) => {
|
|
83883
|
+
const mode2 = layer.render ?? layer.layer.render ?? "cutout";
|
|
83884
|
+
const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
|
|
83885
|
+
const scroll = Materials.entityModeScroll(mode2);
|
|
83768
83886
|
const assetKeyStr = this.getTextureKey(layer).serialize();
|
|
83769
|
-
const keyStr = `entity:${assetKeyStr}`;
|
|
83770
|
-
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
83887
|
+
const keyStr = `entity:${mode2}:${tint === void 0 ? "" : new Color(tint).getHexString()}:${assetKeyStr}`;
|
|
83888
|
+
let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
|
|
83771
83889
|
if (!mat) {
|
|
83772
83890
|
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
83773
83891
|
const imageData = await this.loadTextures(layer);
|
|
83774
83892
|
if (!imageData) return;
|
|
83775
83893
|
const canvas = imageData.data.canvas;
|
|
83776
|
-
const createMaterial = () => Materials.
|
|
83777
|
-
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
83894
|
+
const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode2, tint);
|
|
83895
|
+
mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
83896
|
+
if (scroll) {
|
|
83897
|
+
this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
|
|
83898
|
+
}
|
|
83778
83899
|
}
|
|
83779
83900
|
this.getLayerGroup(name2)?.traverse((object) => {
|
|
83780
83901
|
if (isMesh(object)) object.material = mat;
|
|
83781
83902
|
});
|
|
83782
83903
|
}));
|
|
83904
|
+
if (!this.children.length) {
|
|
83905
|
+
this.clearScrollMaterials();
|
|
83906
|
+
} else if (this.scrollMaterials.length) {
|
|
83907
|
+
this.updateScroll();
|
|
83908
|
+
this.scrollTicker = Ticker.add(() => {
|
|
83909
|
+
this.age++;
|
|
83910
|
+
this.updateScroll();
|
|
83911
|
+
});
|
|
83912
|
+
}
|
|
83783
83913
|
this.notifyDirty();
|
|
83784
83914
|
}
|
|
83785
83915
|
};
|
|
83786
|
-
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS
|
|
83916
|
+
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
|
|
83787
83917
|
var EntityObject = _EntityObject;
|
|
83788
83918
|
function isEntityObject(obj) {
|
|
83789
83919
|
return obj.isEntityObject;
|
|
@@ -86328,11 +86458,69 @@ property list uchar int vertex_index
|
|
|
86328
86458
|
init_dirname();
|
|
86329
86459
|
init_buffer2();
|
|
86330
86460
|
init_process2();
|
|
86461
|
+
init_AssetKey();
|
|
86331
86462
|
var GuiHelper = class {
|
|
86332
86463
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
86333
86464
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
86334
86465
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
86335
86466
|
}
|
|
86467
|
+
/** Creates crafting-table layers for ingredients and the result; stack counts are not drawn. */
|
|
86468
|
+
static recipe(recipe, options = {}) {
|
|
86469
|
+
const layers = [
|
|
86470
|
+
{ name: "background", texture: "minecraft:gui/container/crafting_table", crop: [0, 0, 176, 166] }
|
|
86471
|
+
];
|
|
86472
|
+
const itemKey = (ingredient) => {
|
|
86473
|
+
const item = typeof ingredient === "string" && !ingredient.startsWith("#") ? ingredient : typeof ingredient === "object" && "item" in ingredient ? ingredient.item : options.resolveIngredient?.(ingredient);
|
|
86474
|
+
if (isAssetKey(item)) return item;
|
|
86475
|
+
if (!item || item.startsWith("#")) {
|
|
86476
|
+
throw new Error(`Select a concrete item for recipe ingredient ${JSON.stringify(ingredient)}`);
|
|
86477
|
+
}
|
|
86478
|
+
const key = AssetKey.parse("models", item);
|
|
86479
|
+
return new AssetKey(key.namespace, key.getFullPath(), "models", "item");
|
|
86480
|
+
};
|
|
86481
|
+
const addIngredient = (ingredient, slot) => {
|
|
86482
|
+
layers.push({
|
|
86483
|
+
name: `ingredient-${slot}`,
|
|
86484
|
+
item: itemKey(ingredient),
|
|
86485
|
+
position: this.inventorySlot(slot, [30, 17], [18, 18], 3)
|
|
86486
|
+
});
|
|
86487
|
+
};
|
|
86488
|
+
switch (recipe.type) {
|
|
86489
|
+
case "minecraft:crafting_shaped":
|
|
86490
|
+
case "crafting_shaped": {
|
|
86491
|
+
const pattern = recipe.pattern;
|
|
86492
|
+
if (!pattern.length || pattern.length > 3 || !pattern[0].length || pattern[0].length > 3 || pattern.some((row) => row.length !== pattern[0].length)) {
|
|
86493
|
+
throw new Error("Crafting patterns must be rectangular, with 1\u20133 rows and columns");
|
|
86494
|
+
}
|
|
86495
|
+
const cells = pattern.flatMap((row, y5) => row.split("").map((symbol, x4) => ({ symbol, x: x4, y: y5 }))).filter((cell) => cell.symbol !== " ");
|
|
86496
|
+
if (!cells.length) throw new Error("Crafting patterns must contain an ingredient");
|
|
86497
|
+
const minX = Math.min(...cells.map((cell) => cell.x)), maxX = Math.max(...cells.map((cell) => cell.x));
|
|
86498
|
+
const minY = Math.min(...cells.map((cell) => cell.y)), maxY = Math.max(...cells.map((cell) => cell.y));
|
|
86499
|
+
const offsetX = minX === maxX ? 1 : 0, offsetY = minY === maxY ? 1 : 0;
|
|
86500
|
+
for (const { symbol, x: x4, y: y5 } of cells) {
|
|
86501
|
+
const ingredient = recipe.key[symbol];
|
|
86502
|
+
if (!ingredient) throw new Error(`Missing recipe ingredient for symbol ${JSON.stringify(symbol)}`);
|
|
86503
|
+
addIngredient(ingredient, (y5 - minY + offsetY) * 3 + x4 - minX + offsetX);
|
|
86504
|
+
}
|
|
86505
|
+
break;
|
|
86506
|
+
}
|
|
86507
|
+
case "minecraft:crafting_shapeless":
|
|
86508
|
+
case "crafting_shapeless":
|
|
86509
|
+
if (!recipe.ingredients.length || recipe.ingredients.length > 9) {
|
|
86510
|
+
throw new Error("Shapeless crafting recipes require 1\u20139 ingredients");
|
|
86511
|
+
}
|
|
86512
|
+
recipe.ingredients.forEach(addIngredient);
|
|
86513
|
+
break;
|
|
86514
|
+
default:
|
|
86515
|
+
throw new Error(`Unsupported crafting recipe type: ${recipe.type}`);
|
|
86516
|
+
}
|
|
86517
|
+
layers.push({
|
|
86518
|
+
name: "result",
|
|
86519
|
+
item: itemKey("id" in recipe.result ? recipe.result.id : recipe.result.item),
|
|
86520
|
+
position: [124, 35]
|
|
86521
|
+
});
|
|
86522
|
+
return layers;
|
|
86523
|
+
}
|
|
86336
86524
|
};
|
|
86337
86525
|
|
|
86338
86526
|
// src/gui/GuiLayer.ts
|
|
@@ -86352,9 +86540,24 @@ property list uchar int vertex_index
|
|
|
86352
86540
|
init_three_module();
|
|
86353
86541
|
init_AssetKey();
|
|
86354
86542
|
init_ModelTextures();
|
|
86543
|
+
init_Models();
|
|
86355
86544
|
init_Caching();
|
|
86356
86545
|
init_SceneObject();
|
|
86357
86546
|
init_Materials();
|
|
86547
|
+
init_ModelObject();
|
|
86548
|
+
init_DisplayPosition();
|
|
86549
|
+
|
|
86550
|
+
// src/model/GuiLight.ts
|
|
86551
|
+
init_dirname();
|
|
86552
|
+
init_buffer2();
|
|
86553
|
+
init_process2();
|
|
86554
|
+
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
86555
|
+
GuiLight2["FRONT"] = "front";
|
|
86556
|
+
GuiLight2["SIDE"] = "side";
|
|
86557
|
+
return GuiLight2;
|
|
86558
|
+
})(GuiLight || {});
|
|
86559
|
+
|
|
86560
|
+
// src/gui/scene/GuiObject.ts
|
|
86358
86561
|
var GuiObject = class extends SceneObject {
|
|
86359
86562
|
constructor(textureLayers, options) {
|
|
86360
86563
|
super({ ...options, instanceMeshes: false, mergeMeshes: false });
|
|
@@ -86369,13 +86572,34 @@ property list uchar int vertex_index
|
|
|
86369
86572
|
async init() {
|
|
86370
86573
|
if (this.initialized) return;
|
|
86371
86574
|
try {
|
|
86575
|
+
let depth = 0;
|
|
86372
86576
|
for (const [index, layer] of this.textureLayers.entries()) {
|
|
86577
|
+
const [x4, y5] = layer.position ?? [0, 0];
|
|
86578
|
+
if ("item" in layer) {
|
|
86579
|
+
const [width2, height2] = layer.size ?? [16, 16];
|
|
86580
|
+
const item = await this.createItem(layer, index);
|
|
86581
|
+
item.position.set(x4 + width2 / 2, -y5 - height2 / 2, 0);
|
|
86582
|
+
item.scale.set(width2 / 16, height2 / 16, width2 / 16);
|
|
86583
|
+
item.updateMatrix();
|
|
86584
|
+
const bounds = new Box3();
|
|
86585
|
+
item.iterateAllMeshes((mesh2) => {
|
|
86586
|
+
mesh2.geometry.computeBoundingBox();
|
|
86587
|
+
bounds.union(mesh2.geometry.boundingBox);
|
|
86588
|
+
});
|
|
86589
|
+
bounds.applyMatrix4(item.matrix);
|
|
86590
|
+
item.position.z = depth - bounds.min.z;
|
|
86591
|
+
depth += bounds.max.z - bounds.min.z + 0.01;
|
|
86592
|
+
this.bounds.expandByPoint(new Vector2(x4, y5));
|
|
86593
|
+
this.bounds.expandByPoint(new Vector2(x4 + width2, y5 + height2));
|
|
86594
|
+
this.bounds.expandByPoint(new Vector2(bounds.min.x, -bounds.max.y));
|
|
86595
|
+
this.bounds.expandByPoint(new Vector2(bounds.max.x, -bounds.min.y));
|
|
86596
|
+
continue;
|
|
86597
|
+
}
|
|
86373
86598
|
const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
|
|
86374
86599
|
const material = await this.loadMaterial(key);
|
|
86375
86600
|
const image = material.map.image;
|
|
86376
86601
|
const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
|
|
86377
86602
|
const [width, height] = layer.size ?? [cropWidth, cropHeight];
|
|
86378
|
-
const [x4, y5] = layer.position ?? [0, 0];
|
|
86379
86603
|
const geometry = new PlaneGeometry(width, height);
|
|
86380
86604
|
this.geometries.add(geometry);
|
|
86381
86605
|
const uv = geometry.getAttribute("uv");
|
|
@@ -86388,12 +86612,14 @@ property list uchar int vertex_index
|
|
|
86388
86612
|
}
|
|
86389
86613
|
const mesh = new Mesh(geometry, material);
|
|
86390
86614
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
86391
|
-
mesh.position.set(x4 + width / 2, -y5 - height / 2,
|
|
86615
|
+
mesh.position.set(x4 + width / 2, -y5 - height / 2, depth);
|
|
86392
86616
|
mesh.renderOrder = index;
|
|
86393
86617
|
this.add(mesh);
|
|
86394
86618
|
this.bounds.expandByPoint(new Vector2(x4, y5));
|
|
86395
86619
|
this.bounds.expandByPoint(new Vector2(x4 + width, y5 + height));
|
|
86620
|
+
depth += 0.01;
|
|
86396
86621
|
}
|
|
86622
|
+
for (const child of this.children) child.position.z -= depth - 0.01;
|
|
86397
86623
|
this.initialized = true;
|
|
86398
86624
|
this.notifyDirty();
|
|
86399
86625
|
} catch (error) {
|
|
@@ -86401,6 +86627,32 @@ property list uchar int vertex_index
|
|
|
86401
86627
|
throw error;
|
|
86402
86628
|
}
|
|
86403
86629
|
}
|
|
86630
|
+
async createItem(layer, index) {
|
|
86631
|
+
const key = typeof layer.item === "string" ? AssetKey.parse("models", layer.item) : layer.item;
|
|
86632
|
+
const model = await Models.getMerged(key);
|
|
86633
|
+
if (!model) throw new Error(`Could not load GUI item ${key.toNamespacedString()}`);
|
|
86634
|
+
const item = new ModelObject(model, {
|
|
86635
|
+
displayPosition: "gui" /* GUI */,
|
|
86636
|
+
tints: layer.tints,
|
|
86637
|
+
instanceMeshes: false,
|
|
86638
|
+
mergeMeshes: true
|
|
86639
|
+
});
|
|
86640
|
+
item.name = `group:${layer.name ?? index}`;
|
|
86641
|
+
this.add(item);
|
|
86642
|
+
await item.init();
|
|
86643
|
+
item.iterateAllMeshes((mesh) => {
|
|
86644
|
+
this.geometries.add(mesh.geometry);
|
|
86645
|
+
mesh.name = `mesh:${layer.name ?? index}`;
|
|
86646
|
+
mesh.renderOrder = index;
|
|
86647
|
+
for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
|
|
86648
|
+
material.transparent = true;
|
|
86649
|
+
if (model.gui_light === "front" /* FRONT */ && material.uniforms?.SHADE) {
|
|
86650
|
+
material.uniforms.SHADE.value = false;
|
|
86651
|
+
}
|
|
86652
|
+
}
|
|
86653
|
+
});
|
|
86654
|
+
return item;
|
|
86655
|
+
}
|
|
86404
86656
|
async loadMaterial(key) {
|
|
86405
86657
|
const assetKey = key.serialize();
|
|
86406
86658
|
const materialKey = `gui:${assetKey}`;
|
|
@@ -86452,7 +86704,7 @@ property list uchar int vertex_index
|
|
|
86452
86704
|
init_util();
|
|
86453
86705
|
init_log();
|
|
86454
86706
|
init_three();
|
|
86455
|
-
var
|
|
86707
|
+
var p11 = prefix("SceneInspector");
|
|
86456
86708
|
var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
|
|
86457
86709
|
var SceneInspector = class {
|
|
86458
86710
|
constructor(renderer) {
|
|
@@ -86546,7 +86798,7 @@ property list uchar int vertex_index
|
|
|
86546
86798
|
}
|
|
86547
86799
|
selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
|
|
86548
86800
|
this.selectedObject = targetObject;
|
|
86549
|
-
console.log(
|
|
86801
|
+
console.log(p11, "selected", targetObject);
|
|
86550
86802
|
this.redraw(targetObject, targetIntersection, instance);
|
|
86551
86803
|
}
|
|
86552
86804
|
redraw(targetObject, targetIntersection, instance) {
|
|
@@ -86816,7 +87068,7 @@ property list uchar int vertex_index
|
|
|
86816
87068
|
init_buffer2();
|
|
86817
87069
|
init_process2();
|
|
86818
87070
|
init_log();
|
|
86819
|
-
var
|
|
87071
|
+
var p12 = prefix("InstanceManager");
|
|
86820
87072
|
var InstanceManager = class {
|
|
86821
87073
|
constructor() {
|
|
86822
87074
|
this.isInstanceManager = true;
|
|
@@ -86824,7 +87076,7 @@ property list uchar int vertex_index
|
|
|
86824
87076
|
}
|
|
86825
87077
|
async get(key) {
|
|
86826
87078
|
if (key in this.instanceCache) {
|
|
86827
|
-
console.debug(
|
|
87079
|
+
console.debug(p12, "key in cache", key);
|
|
86828
87080
|
return (await this.instanceCache[key]).nextInstance();
|
|
86829
87081
|
}
|
|
86830
87082
|
return void 0;
|
|
@@ -86833,7 +87085,7 @@ property list uchar int vertex_index
|
|
|
86833
87085
|
if (key in this.instanceCache) {
|
|
86834
87086
|
return await this.get(key);
|
|
86835
87087
|
}
|
|
86836
|
-
console.debug(
|
|
87088
|
+
console.debug(p12, "key not in cache", key);
|
|
86837
87089
|
const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
|
|
86838
87090
|
this.instanceCache[key] = pending;
|
|
86839
87091
|
try {
|
|
@@ -86878,16 +87130,6 @@ property list uchar int vertex_index
|
|
|
86878
87130
|
init_buffer2();
|
|
86879
87131
|
init_process2();
|
|
86880
87132
|
|
|
86881
|
-
// src/model/GuiLight.ts
|
|
86882
|
-
init_dirname();
|
|
86883
|
-
init_buffer2();
|
|
86884
|
-
init_process2();
|
|
86885
|
-
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
86886
|
-
GuiLight2["FRONT"] = "front";
|
|
86887
|
-
GuiLight2["SIDE"] = "side";
|
|
86888
|
-
return GuiLight2;
|
|
86889
|
-
})(GuiLight || {});
|
|
86890
|
-
|
|
86891
87133
|
// src/model/Model.ts
|
|
86892
87134
|
init_dirname();
|
|
86893
87135
|
init_buffer2();
|