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/node/index.mjs
CHANGED
|
@@ -843,7 +843,7 @@ var init_Textures = __esm({
|
|
|
843
843
|
});
|
|
844
844
|
|
|
845
845
|
// src/Materials.ts
|
|
846
|
-
import { Color, DoubleSide, FrontSide, MeshBasicMaterial, MeshStandardMaterial, ShaderChunk, ShaderMaterial } from "three";
|
|
846
|
+
import { Color, CustomBlending, DoubleSide, OneFactor, RepeatWrapping, FrontSide, MeshBasicMaterial, MeshStandardMaterial, ShaderChunk, ShaderMaterial, ZeroFactor } from "three";
|
|
847
847
|
var Materials;
|
|
848
848
|
var init_Materials = __esm({
|
|
849
849
|
"src/Materials.ts"() {
|
|
@@ -885,6 +885,71 @@ var init_Materials = __esm({
|
|
|
885
885
|
alphaTest: 0.5
|
|
886
886
|
});
|
|
887
887
|
}
|
|
888
|
+
/** Whether vanilla's render type for the mode culls back faces. */
|
|
889
|
+
static entityModeCulls(mode = "cutout") {
|
|
890
|
+
return mode === "cutout_cull" || mode === "solid" || mode === "eyes" || mode === "water_mask";
|
|
891
|
+
}
|
|
892
|
+
/** UV offset per tick of entity age for the scrolling modes, as vanilla's texture matrix applies it. */
|
|
893
|
+
static entityModeScroll(mode = "cutout") {
|
|
894
|
+
if (mode === "energy_swirl") return [0.01, 0.01];
|
|
895
|
+
if (mode === "breeze_wind") return [0.02, 0];
|
|
896
|
+
return void 0;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Entity material for one of vanilla's render types. Entities are unlit here, so the lit and full-bright modes
|
|
900
|
+
* differ only in blending and depth state. Culling is not a material property: {@link entityModeCulls} decides
|
|
901
|
+
* whether the geometry gets inward faces.
|
|
902
|
+
*/
|
|
903
|
+
static createEntityCanvasMaterial(canvas, mode = "cutout", tint) {
|
|
904
|
+
const material = _Materials.createBasicCanvasMaterial(canvas);
|
|
905
|
+
switch (mode) {
|
|
906
|
+
case "cutout":
|
|
907
|
+
case "cutout_cull":
|
|
908
|
+
break;
|
|
909
|
+
case "cutout_z_offset":
|
|
910
|
+
material.polygonOffset = true;
|
|
911
|
+
material.polygonOffsetFactor = -1;
|
|
912
|
+
material.polygonOffsetUnits = -10;
|
|
913
|
+
break;
|
|
914
|
+
case "solid":
|
|
915
|
+
material.alphaTest = 0;
|
|
916
|
+
break;
|
|
917
|
+
case "translucent":
|
|
918
|
+
case "breeze_wind":
|
|
919
|
+
material.transparent = true;
|
|
920
|
+
material.alphaTest = 0.1;
|
|
921
|
+
break;
|
|
922
|
+
case "translucent_emissive":
|
|
923
|
+
material.transparent = true;
|
|
924
|
+
material.alphaTest = 0.1;
|
|
925
|
+
material.depthWrite = false;
|
|
926
|
+
break;
|
|
927
|
+
case "eyes":
|
|
928
|
+
material.transparent = true;
|
|
929
|
+
material.alphaTest = 0;
|
|
930
|
+
material.depthWrite = false;
|
|
931
|
+
break;
|
|
932
|
+
case "energy_swirl":
|
|
933
|
+
material.transparent = true;
|
|
934
|
+
material.alphaTest = 0.1;
|
|
935
|
+
material.blending = CustomBlending;
|
|
936
|
+
material.blendSrc = OneFactor;
|
|
937
|
+
material.blendDst = OneFactor;
|
|
938
|
+
material.blendSrcAlpha = ZeroFactor;
|
|
939
|
+
material.blendDstAlpha = OneFactor;
|
|
940
|
+
material.color.set(8421504);
|
|
941
|
+
break;
|
|
942
|
+
case "water_mask":
|
|
943
|
+
material.alphaTest = 0;
|
|
944
|
+
material.colorWrite = false;
|
|
945
|
+
break;
|
|
946
|
+
}
|
|
947
|
+
if (_Materials.entityModeScroll(mode)) {
|
|
948
|
+
material.map.wrapS = material.map.wrapT = RepeatWrapping;
|
|
949
|
+
}
|
|
950
|
+
if (tint !== void 0) material.color.multiply(new Color(tint));
|
|
951
|
+
return material;
|
|
952
|
+
}
|
|
888
953
|
static createGuiCanvasMaterial(canvas) {
|
|
889
954
|
const material = new MeshBasicMaterial({
|
|
890
955
|
map: Textures.createCanvasTexture(canvas),
|
|
@@ -3533,48 +3598,6 @@ var init_SceneObject = __esm({
|
|
|
3533
3598
|
}
|
|
3534
3599
|
});
|
|
3535
3600
|
|
|
3536
|
-
// src/model/ModelCulling.ts
|
|
3537
|
-
import { Vector3 as Vector39 } from "three";
|
|
3538
|
-
var ModelCulling;
|
|
3539
|
-
var init_ModelCulling = __esm({
|
|
3540
|
-
"src/model/ModelCulling.ts"() {
|
|
3541
|
-
init_CubeFace();
|
|
3542
|
-
ModelCulling = class {
|
|
3543
|
-
static toLocalMask(worldMask, rotation) {
|
|
3544
|
-
let localMask = 0;
|
|
3545
|
-
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
3546
|
-
const normal = new Vector39(...offset).applyEuler(rotation);
|
|
3547
|
-
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);
|
|
3548
|
-
if (worldFace < 0) return 0;
|
|
3549
|
-
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
3550
|
-
}
|
|
3551
|
-
return localMask;
|
|
3552
|
-
}
|
|
3553
|
-
static isOpaqueFullCube(atlas) {
|
|
3554
|
-
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
3555
|
-
const element = atlas.model.elements[0];
|
|
3556
|
-
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;
|
|
3557
|
-
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
3558
|
-
return CUBE_FACES.every((face, faceIndex) => {
|
|
3559
|
-
const texture = element.faces[face]?.texture;
|
|
3560
|
-
if (!texture?.startsWith("#")) return false;
|
|
3561
|
-
const key = texture.slice(1);
|
|
3562
|
-
const position = atlas.positions[key];
|
|
3563
|
-
const size = atlas.sizes[key];
|
|
3564
|
-
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
3565
|
-
for (let vertex = 0; vertex < 4; vertex++) {
|
|
3566
|
-
const uvIndex = (faceIndex * 4 + vertex) * 2;
|
|
3567
|
-
const x = element.mappedUv[uvIndex] * atlas.image.width;
|
|
3568
|
-
const y = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
3569
|
-
if (x < position[0] - 1e-6 || x > position[0] + size[0] + 1e-6 || y < position[1] - 1e-6 || y > position[1] + size[1] + 1e-6) return false;
|
|
3570
|
-
}
|
|
3571
|
-
return true;
|
|
3572
|
-
});
|
|
3573
|
-
}
|
|
3574
|
-
};
|
|
3575
|
-
}
|
|
3576
|
-
});
|
|
3577
|
-
|
|
3578
3601
|
// src/three/BufferGeometryUtils.js
|
|
3579
3602
|
import {
|
|
3580
3603
|
BufferAttribute as BufferAttribute4,
|
|
@@ -3585,7 +3608,7 @@ import {
|
|
|
3585
3608
|
TriangleFanDrawMode,
|
|
3586
3609
|
TriangleStripDrawMode,
|
|
3587
3610
|
TrianglesDrawMode,
|
|
3588
|
-
Vector3 as
|
|
3611
|
+
Vector3 as Vector39
|
|
3589
3612
|
} from "three";
|
|
3590
3613
|
function computeTangents(geometry) {
|
|
3591
3614
|
geometry.computeTangents();
|
|
@@ -3904,15 +3927,15 @@ function computeMorphedAttributes(object) {
|
|
|
3904
3927
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
3905
3928
|
return null;
|
|
3906
3929
|
}
|
|
3907
|
-
const _vA = new
|
|
3908
|
-
const _vB = new
|
|
3909
|
-
const _vC = new
|
|
3910
|
-
const _tempA = new
|
|
3911
|
-
const _tempB = new
|
|
3912
|
-
const _tempC = new
|
|
3913
|
-
const _morphA = new
|
|
3914
|
-
const _morphB = new
|
|
3915
|
-
const _morphC = new
|
|
3930
|
+
const _vA = new Vector39();
|
|
3931
|
+
const _vB = new Vector39();
|
|
3932
|
+
const _vC = new Vector39();
|
|
3933
|
+
const _tempA = new Vector39();
|
|
3934
|
+
const _tempB = new Vector39();
|
|
3935
|
+
const _tempC = new Vector39();
|
|
3936
|
+
const _morphA = new Vector39();
|
|
3937
|
+
const _morphB = new Vector39();
|
|
3938
|
+
const _morphC = new Vector39();
|
|
3916
3939
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
3917
3940
|
_vA.fromBufferAttribute(attribute, a2);
|
|
3918
3941
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4121,12 +4144,54 @@ var init_BufferGeometryUtils = __esm({
|
|
|
4121
4144
|
}
|
|
4122
4145
|
});
|
|
4123
4146
|
|
|
4147
|
+
// src/model/ModelCulling.ts
|
|
4148
|
+
import { Vector3 as Vector310 } from "three";
|
|
4149
|
+
var ModelCulling;
|
|
4150
|
+
var init_ModelCulling = __esm({
|
|
4151
|
+
"src/model/ModelCulling.ts"() {
|
|
4152
|
+
init_CubeFace();
|
|
4153
|
+
ModelCulling = class {
|
|
4154
|
+
static toLocalMask(worldMask, rotation) {
|
|
4155
|
+
let localMask = 0;
|
|
4156
|
+
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
4157
|
+
const normal = new Vector310(...offset).applyEuler(rotation);
|
|
4158
|
+
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);
|
|
4159
|
+
if (worldFace < 0) return 0;
|
|
4160
|
+
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
4161
|
+
}
|
|
4162
|
+
return localMask;
|
|
4163
|
+
}
|
|
4164
|
+
static isOpaqueFullCube(atlas) {
|
|
4165
|
+
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
4166
|
+
const element = atlas.model.elements[0];
|
|
4167
|
+
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;
|
|
4168
|
+
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
4169
|
+
return CUBE_FACES.every((face, faceIndex) => {
|
|
4170
|
+
const texture = element.faces[face]?.texture;
|
|
4171
|
+
if (!texture?.startsWith("#")) return false;
|
|
4172
|
+
const key = texture.slice(1);
|
|
4173
|
+
const position = atlas.positions[key];
|
|
4174
|
+
const size = atlas.sizes[key];
|
|
4175
|
+
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
4176
|
+
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4177
|
+
const uvIndex = (faceIndex * 4 + vertex) * 2;
|
|
4178
|
+
const x = element.mappedUv[uvIndex] * atlas.image.width;
|
|
4179
|
+
const y = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
4180
|
+
if (x < position[0] - 1e-6 || x > position[0] + size[0] + 1e-6 || y < position[1] - 1e-6 || y > position[1] + size[1] + 1e-6) return false;
|
|
4181
|
+
}
|
|
4182
|
+
return true;
|
|
4183
|
+
});
|
|
4184
|
+
}
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
});
|
|
4188
|
+
|
|
4124
4189
|
// src/model/scene/ModelObject.ts
|
|
4125
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as
|
|
4190
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as Matrix47 } from "three";
|
|
4126
4191
|
function isModelObject(obj) {
|
|
4127
4192
|
return obj.isModelObject;
|
|
4128
4193
|
}
|
|
4129
|
-
var import_ts_deepmerge5,
|
|
4194
|
+
var import_ts_deepmerge5, p7, ModelObject;
|
|
4130
4195
|
var init_ModelObject = __esm({
|
|
4131
4196
|
"src/model/scene/ModelObject.ts"() {
|
|
4132
4197
|
init_SceneObject();
|
|
@@ -4139,7 +4204,7 @@ var init_ModelObject = __esm({
|
|
|
4139
4204
|
init_CubeFace();
|
|
4140
4205
|
init_DisplayTransforms();
|
|
4141
4206
|
init_ModelCulling();
|
|
4142
|
-
|
|
4207
|
+
p7 = prefix("ModelObject");
|
|
4143
4208
|
ModelObject = class _ModelObject extends SceneObject {
|
|
4144
4209
|
constructor(originalModel, options) {
|
|
4145
4210
|
super(options);
|
|
@@ -4197,19 +4262,19 @@ var init_ModelObject = __esm({
|
|
|
4197
4262
|
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
4198
4263
|
const tint = this.options.tints[tintIndex];
|
|
4199
4264
|
if (tint === void 0) continue;
|
|
4200
|
-
const color = new
|
|
4265
|
+
const color = new Color8(tint);
|
|
4201
4266
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4202
4267
|
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
4203
4268
|
}
|
|
4204
4269
|
}
|
|
4205
4270
|
elGeo.setAttribute("color", new BufferAttribute5(colors, 3));
|
|
4206
4271
|
}
|
|
4207
|
-
elGeo.applyMatrix4(new
|
|
4208
|
-
elGeo.applyMatrix4(new
|
|
4272
|
+
elGeo.applyMatrix4(new Matrix47().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
|
|
4273
|
+
elGeo.applyMatrix4(new Matrix47().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4209
4274
|
if (el.rotation) {
|
|
4210
4275
|
applyElementRotation(el.rotation, elGeo);
|
|
4211
4276
|
}
|
|
4212
|
-
elGeo.applyMatrix4(new
|
|
4277
|
+
elGeo.applyMatrix4(new Matrix47().makeTranslation(-8, -8, -8));
|
|
4213
4278
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4214
4279
|
if (this.options.mergeMeshes) {
|
|
4215
4280
|
allGeos.push(elGeo);
|
|
@@ -4221,10 +4286,10 @@ var init_ModelObject = __esm({
|
|
|
4221
4286
|
}
|
|
4222
4287
|
});
|
|
4223
4288
|
} else {
|
|
4224
|
-
console.debug(
|
|
4289
|
+
console.debug(p7, this.atlas.model, "has no elements");
|
|
4225
4290
|
}
|
|
4226
4291
|
} else {
|
|
4227
|
-
console.debug(
|
|
4292
|
+
console.debug(p7, "Missing atlas for", this);
|
|
4228
4293
|
}
|
|
4229
4294
|
if (this.options.mergeMeshes) {
|
|
4230
4295
|
let combinedGeo;
|
|
@@ -4322,7 +4387,7 @@ var init_fluidBlocks = __esm({
|
|
|
4322
4387
|
});
|
|
4323
4388
|
|
|
4324
4389
|
// src/model/fluid/FluidGeometry.ts
|
|
4325
|
-
import { BufferGeometry as
|
|
4390
|
+
import { BufferGeometry as BufferGeometry4, Float32BufferAttribute as Float32BufferAttribute5 } from "three";
|
|
4326
4391
|
function getBlockFluidState(key, state) {
|
|
4327
4392
|
const rule = key && fluidRules[key.toNamespacedString()];
|
|
4328
4393
|
if (rule) return {
|
|
@@ -4340,7 +4405,7 @@ function ownHeight(sample) {
|
|
|
4340
4405
|
return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
|
|
4341
4406
|
}
|
|
4342
4407
|
function createFluidGeometry(kind, sample) {
|
|
4343
|
-
const geometry = new
|
|
4408
|
+
const geometry = new BufferGeometry4();
|
|
4344
4409
|
const positions = [], normals = [], uvs = [], indices = [];
|
|
4345
4410
|
const self = sample(0, 0, 0);
|
|
4346
4411
|
const height = (x, z) => {
|
|
@@ -4461,7 +4526,7 @@ __export(FluidModelObject_exports, {
|
|
|
4461
4526
|
FluidModelObject: () => FluidModelObject,
|
|
4462
4527
|
sampleFluid: () => sampleFluid
|
|
4463
4528
|
});
|
|
4464
|
-
import { BufferAttribute as BufferAttribute6, Color as
|
|
4529
|
+
import { BufferAttribute as BufferAttribute6, Color as Color9, DoubleSide as DoubleSide3 } from "three";
|
|
4465
4530
|
function sampleFluid(kind, sample) {
|
|
4466
4531
|
const cells = [];
|
|
4467
4532
|
const key = [];
|
|
@@ -4512,7 +4577,7 @@ var init_FluidModelObject = __esm({
|
|
|
4512
4577
|
}
|
|
4513
4578
|
}
|
|
4514
4579
|
geometry.clearGroups();
|
|
4515
|
-
const color = new
|
|
4580
|
+
const color = new Color9(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
|
|
4516
4581
|
const colors = new Float32Array(geometry.getAttribute("position").count * 3);
|
|
4517
4582
|
for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
|
|
4518
4583
|
geometry.setAttribute("color", new BufferAttribute6(colors, 3));
|
|
@@ -4809,32 +4874,44 @@ var Entities = class {
|
|
|
4809
4874
|
static async getLayerList(modelKey) {
|
|
4810
4875
|
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
4811
4876
|
}
|
|
4877
|
+
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
4878
|
+
static async getPassList(modelKey) {
|
|
4879
|
+
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
4880
|
+
}
|
|
4812
4881
|
static async getEntity(modelKey, textureKey, options) {
|
|
4813
4882
|
const model = await this.getModelFile(modelKey);
|
|
4814
4883
|
if (!model) return void 0;
|
|
4815
|
-
const
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4884
|
+
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
4885
|
+
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
4886
|
+
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
4887
|
+
draws.push(...passes);
|
|
4888
|
+
const names = [];
|
|
4889
|
+
const selected = draws.map((pass) => {
|
|
4890
|
+
const layer = model.layers[pass.layer];
|
|
4819
4891
|
if (!layer) {
|
|
4820
|
-
throw new MineRenderError(`Entity ${model.id} has no layer "${
|
|
4892
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
4821
4893
|
}
|
|
4822
|
-
|
|
4894
|
+
let name = pass.layer;
|
|
4895
|
+
for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
|
|
4896
|
+
names.push(name);
|
|
4897
|
+
return { name, layer, pass };
|
|
4823
4898
|
});
|
|
4824
|
-
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer }, index) => {
|
|
4899
|
+
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
|
|
4825
4900
|
const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
|
|
4901
|
+
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
4826
4902
|
let texture;
|
|
4827
4903
|
if (override) {
|
|
4828
4904
|
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
4829
4905
|
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);
|
|
4830
|
-
} else if (
|
|
4831
|
-
texture = AssetKey.parse("textures",
|
|
4906
|
+
} else if (textureLocation !== void 0) {
|
|
4907
|
+
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
4832
4908
|
} else {
|
|
4833
4909
|
texture = await this.resolveTexture(modelKey);
|
|
4834
4910
|
}
|
|
4835
|
-
|
|
4911
|
+
const render = pass.render ?? layer.render;
|
|
4912
|
+
return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
4836
4913
|
})));
|
|
4837
|
-
return { ...layers[names[0]], id: model.id, layers };
|
|
4914
|
+
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4838
4915
|
}
|
|
4839
4916
|
static async resolveTexture(modelKey) {
|
|
4840
4917
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
@@ -4916,11 +4993,12 @@ function trimCanvas(source) {
|
|
|
4916
4993
|
init_SceneObject();
|
|
4917
4994
|
init_Caching();
|
|
4918
4995
|
var import_ts_deepmerge4 = __toESM(require_dist());
|
|
4996
|
+
init_Ticker();
|
|
4919
4997
|
init_model();
|
|
4920
4998
|
init_ModelTextures();
|
|
4921
4999
|
init_AssetKey();
|
|
4922
5000
|
init_Materials();
|
|
4923
|
-
import { Object3D as Object3D3 } from "three";
|
|
5001
|
+
import { Color as Color3, Euler as Euler4, Matrix4 as Matrix44, Object3D as Object3D3 } from "three";
|
|
4924
5002
|
init_three();
|
|
4925
5003
|
var EntityObject = class _EntityObject extends SceneObject {
|
|
4926
5004
|
constructor(entity, options) {
|
|
@@ -4928,10 +5006,14 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
4928
5006
|
this.entity = entity;
|
|
4929
5007
|
this.isEntityObject = true;
|
|
4930
5008
|
this.meshesCreated = false;
|
|
5009
|
+
/** Scrolling materials are owned: their texture offset follows this entity's age. */
|
|
5010
|
+
this.scrollMaterials = [];
|
|
5011
|
+
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
5012
|
+
this.age = 0;
|
|
4931
5013
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
4932
5014
|
}
|
|
4933
5015
|
static {
|
|
4934
|
-
this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS
|
|
5016
|
+
this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
|
|
4935
5017
|
}
|
|
4936
5018
|
async init() {
|
|
4937
5019
|
this.createMeshes();
|
|
@@ -4940,6 +5022,25 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
4940
5022
|
dispose() {
|
|
4941
5023
|
super.dispose();
|
|
4942
5024
|
}
|
|
5025
|
+
disposeAndRemoveAllChildren() {
|
|
5026
|
+
this.clearScrollMaterials();
|
|
5027
|
+
super.disposeAndRemoveAllChildren();
|
|
5028
|
+
}
|
|
5029
|
+
clearScrollMaterials() {
|
|
5030
|
+
Ticker.remove(this.scrollTicker);
|
|
5031
|
+
this.scrollTicker = void 0;
|
|
5032
|
+
for (const { material } of this.scrollMaterials.splice(0)) {
|
|
5033
|
+
material.map?.dispose();
|
|
5034
|
+
material.dispose();
|
|
5035
|
+
}
|
|
5036
|
+
}
|
|
5037
|
+
/** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
|
|
5038
|
+
updateScroll() {
|
|
5039
|
+
for (const { offset, speed } of this.scrollMaterials) {
|
|
5040
|
+
offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
|
|
5041
|
+
}
|
|
5042
|
+
this.notifyDirty();
|
|
5043
|
+
}
|
|
4943
5044
|
getLayerGroup(name) {
|
|
4944
5045
|
return super.getGroupByName(`layer:${name}`);
|
|
4945
5046
|
}
|
|
@@ -4970,16 +5071,29 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
4970
5071
|
createMeshes(force = false) {
|
|
4971
5072
|
if (this.meshesCreated && !force) return;
|
|
4972
5073
|
const modelRoot = new Object3D3();
|
|
4973
|
-
|
|
5074
|
+
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
5075
|
+
if (transform) {
|
|
5076
|
+
for (const op of transform) {
|
|
5077
|
+
const matrix = new Matrix44();
|
|
5078
|
+
if ("scale" in op) matrix.makeScale(...op.scale);
|
|
5079
|
+
else if ("translate" in op) matrix.makeTranslation(...op.translate);
|
|
5080
|
+
else matrix.makeRotationFromEuler(new Euler4(...op.rotate, "ZYX"));
|
|
5081
|
+
modelRoot.matrix.multiply(matrix);
|
|
5082
|
+
}
|
|
5083
|
+
modelRoot.matrixAutoUpdate = false;
|
|
5084
|
+
} else if (this.options.flip ?? true) {
|
|
5085
|
+
modelRoot.scale.set(-1, -1, 1);
|
|
5086
|
+
}
|
|
4974
5087
|
this.add(modelRoot);
|
|
4975
5088
|
Object.entries(this.entityLayers).forEach(([name, layer], index) => {
|
|
4976
5089
|
const group = this.createGroup(`layer:${name}`);
|
|
4977
5090
|
modelRoot.add(group);
|
|
4978
|
-
|
|
5091
|
+
const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
|
|
5092
|
+
this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
|
|
4979
5093
|
});
|
|
4980
5094
|
this.meshesCreated = true;
|
|
4981
5095
|
}
|
|
4982
|
-
createPart(name, part, parent, textureSize, material, renderOrder) {
|
|
5096
|
+
createPart(name, part, parent, textureSize, material, renderOrder, inward = true) {
|
|
4983
5097
|
const anchor = this.createGroup(name);
|
|
4984
5098
|
anchor.position.fromArray(part.pose.offset);
|
|
4985
5099
|
anchor.rotation.set(...part.pose.rotation, "ZYX");
|
|
@@ -4998,7 +5112,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
4998
5112
|
uv
|
|
4999
5113
|
).clone();
|
|
5000
5114
|
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
5001
|
-
if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
5115
|
+
if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
5002
5116
|
const index = Array.from(geometry.getIndex().array);
|
|
5003
5117
|
geometry.setIndex(index.concat(index.slice().reverse()));
|
|
5004
5118
|
}
|
|
@@ -5008,26 +5122,42 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5008
5122
|
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
5009
5123
|
}
|
|
5010
5124
|
for (const [childName, child] of Object.entries(part.children)) {
|
|
5011
|
-
this.createPart(childName, child, anchor, size, material, renderOrder);
|
|
5125
|
+
this.createPart(childName, child, anchor, size, material, renderOrder, inward);
|
|
5012
5126
|
}
|
|
5013
5127
|
}
|
|
5014
5128
|
async applyTextures() {
|
|
5129
|
+
this.clearScrollMaterials();
|
|
5015
5130
|
await Promise.all(Object.entries(this.entityLayers).map(async ([name, layer]) => {
|
|
5131
|
+
const mode = layer.render ?? layer.layer.render ?? "cutout";
|
|
5132
|
+
const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
|
|
5133
|
+
const scroll = Materials.entityModeScroll(mode);
|
|
5016
5134
|
const assetKeyStr = this.getTextureKey(layer).serialize();
|
|
5017
|
-
const keyStr = `entity:${assetKeyStr}`;
|
|
5018
|
-
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
5135
|
+
const keyStr = `entity:${mode}:${tint === void 0 ? "" : new Color3(tint).getHexString()}:${assetKeyStr}`;
|
|
5136
|
+
let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
|
|
5019
5137
|
if (!mat) {
|
|
5020
5138
|
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
5021
5139
|
const imageData = await this.loadTextures(layer);
|
|
5022
5140
|
if (!imageData) return;
|
|
5023
5141
|
const canvas = imageData.data.canvas;
|
|
5024
|
-
const createMaterial = () => Materials.
|
|
5025
|
-
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
5142
|
+
const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode, tint);
|
|
5143
|
+
mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
5144
|
+
if (scroll) {
|
|
5145
|
+
this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
|
|
5146
|
+
}
|
|
5026
5147
|
}
|
|
5027
5148
|
this.getLayerGroup(name)?.traverse((object) => {
|
|
5028
5149
|
if (isMesh(object)) object.material = mat;
|
|
5029
5150
|
});
|
|
5030
5151
|
}));
|
|
5152
|
+
if (!this.children.length) {
|
|
5153
|
+
this.clearScrollMaterials();
|
|
5154
|
+
} else if (this.scrollMaterials.length) {
|
|
5155
|
+
this.updateScroll();
|
|
5156
|
+
this.scrollTicker = Ticker.add(() => {
|
|
5157
|
+
this.age++;
|
|
5158
|
+
this.updateScroll();
|
|
5159
|
+
});
|
|
5160
|
+
}
|
|
5031
5161
|
this.notifyDirty();
|
|
5032
5162
|
}
|
|
5033
5163
|
};
|
|
@@ -5039,11 +5169,11 @@ function isEntityObject(obj) {
|
|
|
5039
5169
|
init_MineRenderError();
|
|
5040
5170
|
|
|
5041
5171
|
// src/export/SceneExporter.ts
|
|
5042
|
-
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as
|
|
5172
|
+
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as Color7, Float32BufferAttribute as Float32BufferAttribute3, Matrix4 as Matrix46, Mesh as Mesh5, MeshBasicMaterial as MeshBasicMaterial2, NearestFilter as NearestFilter3, RGBAFormat as RGBAFormat3, Scene as Scene4, Source as Source2, Texture as Texture4, UnsignedByteType } from "three";
|
|
5043
5173
|
|
|
5044
5174
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
5045
5175
|
import {
|
|
5046
|
-
Color as
|
|
5176
|
+
Color as Color4,
|
|
5047
5177
|
Matrix3,
|
|
5048
5178
|
Vector2 as Vector22,
|
|
5049
5179
|
Vector3 as Vector36
|
|
@@ -5055,7 +5185,7 @@ var OBJExporter = class {
|
|
|
5055
5185
|
let indexVertexUvs = 0;
|
|
5056
5186
|
let indexNormals = 0;
|
|
5057
5187
|
const vertex = new Vector36();
|
|
5058
|
-
const color = new
|
|
5188
|
+
const color = new Color4();
|
|
5059
5189
|
const normal = new Vector36();
|
|
5060
5190
|
const uv = new Vector22();
|
|
5061
5191
|
const face = [];
|
|
@@ -5186,7 +5316,7 @@ var OBJExporter = class {
|
|
|
5186
5316
|
import {
|
|
5187
5317
|
Matrix3 as Matrix32,
|
|
5188
5318
|
Vector3 as Vector37,
|
|
5189
|
-
Color as
|
|
5319
|
+
Color as Color5
|
|
5190
5320
|
} from "three";
|
|
5191
5321
|
var PLYExporter = class {
|
|
5192
5322
|
parse(object, onDone, options = {}) {
|
|
@@ -5244,7 +5374,7 @@ var PLYExporter = class {
|
|
|
5244
5374
|
includeIndices = false;
|
|
5245
5375
|
}
|
|
5246
5376
|
});
|
|
5247
|
-
const tempColor = new
|
|
5377
|
+
const tempColor = new Color5();
|
|
5248
5378
|
includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
|
|
5249
5379
|
includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
|
|
5250
5380
|
includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
|
|
@@ -5456,7 +5586,7 @@ property list uchar int vertex_index
|
|
|
5456
5586
|
import {
|
|
5457
5587
|
BufferAttribute as BufferAttribute3,
|
|
5458
5588
|
ClampToEdgeWrapping,
|
|
5459
|
-
Color as
|
|
5589
|
+
Color as Color6,
|
|
5460
5590
|
DoubleSide as DoubleSide2,
|
|
5461
5591
|
InterpolateDiscrete,
|
|
5462
5592
|
InterpolateLinear,
|
|
@@ -5465,14 +5595,14 @@ import {
|
|
|
5465
5595
|
LinearMipmapLinearFilter,
|
|
5466
5596
|
LinearMipmapNearestFilter,
|
|
5467
5597
|
MathUtils as MathUtils2,
|
|
5468
|
-
Matrix4 as
|
|
5598
|
+
Matrix4 as Matrix45,
|
|
5469
5599
|
MirroredRepeatWrapping,
|
|
5470
5600
|
NearestFilter as NearestFilter2,
|
|
5471
5601
|
NearestMipmapLinearFilter,
|
|
5472
5602
|
NearestMipmapNearestFilter,
|
|
5473
5603
|
PropertyBinding,
|
|
5474
5604
|
RGBAFormat as RGBAFormat2,
|
|
5475
|
-
RepeatWrapping,
|
|
5605
|
+
RepeatWrapping as RepeatWrapping2,
|
|
5476
5606
|
Scene as Scene3,
|
|
5477
5607
|
Source,
|
|
5478
5608
|
SRGBColorSpace as SRGBColorSpace4,
|
|
@@ -5690,7 +5820,7 @@ THREE_TO_WEBGL[LinearFilter] = WEBGL_CONSTANTS.LINEAR;
|
|
|
5690
5820
|
THREE_TO_WEBGL[LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
|
|
5691
5821
|
THREE_TO_WEBGL[LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
|
|
5692
5822
|
THREE_TO_WEBGL[ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
|
|
5693
|
-
THREE_TO_WEBGL[
|
|
5823
|
+
THREE_TO_WEBGL[RepeatWrapping2] = WEBGL_CONSTANTS.REPEAT;
|
|
5694
5824
|
THREE_TO_WEBGL[MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
|
|
5695
5825
|
var PATH_PROPERTIES = {
|
|
5696
5826
|
scale: "scale",
|
|
@@ -5698,7 +5828,7 @@ var PATH_PROPERTIES = {
|
|
|
5698
5828
|
quaternion: "rotation",
|
|
5699
5829
|
morphTargetInfluences: "weights"
|
|
5700
5830
|
};
|
|
5701
|
-
var DEFAULT_SPECULAR_COLOR = new
|
|
5831
|
+
var DEFAULT_SPECULAR_COLOR = new Color6();
|
|
5702
5832
|
var GLB_HEADER_BYTES = 12;
|
|
5703
5833
|
var GLB_HEADER_MAGIC = 1179937895;
|
|
5704
5834
|
var GLB_VERSION = 2;
|
|
@@ -6755,7 +6885,7 @@ var GLTFWriter = class {
|
|
|
6755
6885
|
if (rootJoint === void 0) return null;
|
|
6756
6886
|
const joints = [];
|
|
6757
6887
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
6758
|
-
const temporaryBoneInverse = new
|
|
6888
|
+
const temporaryBoneInverse = new Matrix45();
|
|
6759
6889
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
6760
6890
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
6761
6891
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7221,7 +7351,7 @@ var GLTFMeshGpuInstancing = class {
|
|
|
7221
7351
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
7222
7352
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
7223
7353
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
7224
|
-
const matrix = new
|
|
7354
|
+
const matrix = new Matrix45();
|
|
7225
7355
|
const position = new Vector38();
|
|
7226
7356
|
const quaternion = new Quaternion4();
|
|
7227
7357
|
const scale = new Vector38();
|
|
@@ -7395,7 +7525,7 @@ var SceneExporter = class {
|
|
|
7395
7525
|
}
|
|
7396
7526
|
};
|
|
7397
7527
|
function localMatrix(object) {
|
|
7398
|
-
return object.matrixAutoUpdate ? new
|
|
7528
|
+
return object.matrixAutoUpdate ? new Matrix46().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
7399
7529
|
}
|
|
7400
7530
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
7401
7531
|
const scene = new Scene4();
|
|
@@ -7480,7 +7610,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7480
7610
|
const material = copyMaterial(sourceMaterial, geometry);
|
|
7481
7611
|
if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
|
|
7482
7612
|
if (bakeColors || instanceColor) {
|
|
7483
|
-
const tint = (material.color ?? new
|
|
7613
|
+
const tint = (material.color ?? new Color7()).clone();
|
|
7484
7614
|
if (instanceColor) tint.multiply(instanceColor);
|
|
7485
7615
|
if (bakeColors) {
|
|
7486
7616
|
const original = geometry.getAttribute("color");
|
|
@@ -7507,9 +7637,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7507
7637
|
const instanced = mesh;
|
|
7508
7638
|
if (instanced.isInstancedMesh) {
|
|
7509
7639
|
for (let i = 0; i < instanced.count; i++) {
|
|
7510
|
-
const matrix = new
|
|
7640
|
+
const matrix = new Matrix46();
|
|
7511
7641
|
instanced.getMatrixAt(i, matrix);
|
|
7512
|
-
const color = instanced.instanceColor ? new
|
|
7642
|
+
const color = instanced.instanceColor ? new Color7().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
7513
7643
|
addMesh(mesh, world.clone().multiply(matrix), color);
|
|
7514
7644
|
}
|
|
7515
7645
|
} else {
|
|
@@ -7521,7 +7651,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7521
7651
|
try {
|
|
7522
7652
|
const ancestors = [];
|
|
7523
7653
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
7524
|
-
const world = new
|
|
7654
|
+
const world = new Matrix46();
|
|
7525
7655
|
for (const ancestor of ancestors) {
|
|
7526
7656
|
if (!ancestor.visible) return { scene, dispose };
|
|
7527
7657
|
world.multiply(localMatrix(ancestor));
|
|
@@ -7588,20 +7718,90 @@ function copyDataTexture(source) {
|
|
|
7588
7718
|
}
|
|
7589
7719
|
|
|
7590
7720
|
// src/gui/GuiHelper.ts
|
|
7721
|
+
init_AssetKey();
|
|
7591
7722
|
var GuiHelper = class {
|
|
7592
7723
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
7593
7724
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
7594
7725
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
7595
7726
|
}
|
|
7727
|
+
/** Creates crafting-table layers for ingredients and the result; stack counts are not drawn. */
|
|
7728
|
+
static recipe(recipe, options = {}) {
|
|
7729
|
+
const layers = [
|
|
7730
|
+
{ name: "background", texture: "minecraft:gui/container/crafting_table", crop: [0, 0, 176, 166] }
|
|
7731
|
+
];
|
|
7732
|
+
const itemKey = (ingredient) => {
|
|
7733
|
+
const item = typeof ingredient === "string" && !ingredient.startsWith("#") ? ingredient : typeof ingredient === "object" && "item" in ingredient ? ingredient.item : options.resolveIngredient?.(ingredient);
|
|
7734
|
+
if (isAssetKey(item)) return item;
|
|
7735
|
+
if (!item || item.startsWith("#")) {
|
|
7736
|
+
throw new Error(`Select a concrete item for recipe ingredient ${JSON.stringify(ingredient)}`);
|
|
7737
|
+
}
|
|
7738
|
+
const key = AssetKey.parse("models", item);
|
|
7739
|
+
return new AssetKey(key.namespace, key.getFullPath(), "models", "item");
|
|
7740
|
+
};
|
|
7741
|
+
const addIngredient = (ingredient, slot) => {
|
|
7742
|
+
layers.push({
|
|
7743
|
+
name: `ingredient-${slot}`,
|
|
7744
|
+
item: itemKey(ingredient),
|
|
7745
|
+
position: this.inventorySlot(slot, [30, 17], [18, 18], 3)
|
|
7746
|
+
});
|
|
7747
|
+
};
|
|
7748
|
+
switch (recipe.type) {
|
|
7749
|
+
case "minecraft:crafting_shaped":
|
|
7750
|
+
case "crafting_shaped": {
|
|
7751
|
+
const pattern = recipe.pattern;
|
|
7752
|
+
if (!pattern.length || pattern.length > 3 || !pattern[0].length || pattern[0].length > 3 || pattern.some((row) => row.length !== pattern[0].length)) {
|
|
7753
|
+
throw new Error("Crafting patterns must be rectangular, with 1\u20133 rows and columns");
|
|
7754
|
+
}
|
|
7755
|
+
const cells = pattern.flatMap((row, y) => row.split("").map((symbol, x) => ({ symbol, x, y }))).filter((cell) => cell.symbol !== " ");
|
|
7756
|
+
if (!cells.length) throw new Error("Crafting patterns must contain an ingredient");
|
|
7757
|
+
const minX = Math.min(...cells.map((cell) => cell.x)), maxX = Math.max(...cells.map((cell) => cell.x));
|
|
7758
|
+
const minY = Math.min(...cells.map((cell) => cell.y)), maxY = Math.max(...cells.map((cell) => cell.y));
|
|
7759
|
+
const offsetX = minX === maxX ? 1 : 0, offsetY = minY === maxY ? 1 : 0;
|
|
7760
|
+
for (const { symbol, x, y } of cells) {
|
|
7761
|
+
const ingredient = recipe.key[symbol];
|
|
7762
|
+
if (!ingredient) throw new Error(`Missing recipe ingredient for symbol ${JSON.stringify(symbol)}`);
|
|
7763
|
+
addIngredient(ingredient, (y - minY + offsetY) * 3 + x - minX + offsetX);
|
|
7764
|
+
}
|
|
7765
|
+
break;
|
|
7766
|
+
}
|
|
7767
|
+
case "minecraft:crafting_shapeless":
|
|
7768
|
+
case "crafting_shapeless":
|
|
7769
|
+
if (!recipe.ingredients.length || recipe.ingredients.length > 9) {
|
|
7770
|
+
throw new Error("Shapeless crafting recipes require 1\u20139 ingredients");
|
|
7771
|
+
}
|
|
7772
|
+
recipe.ingredients.forEach(addIngredient);
|
|
7773
|
+
break;
|
|
7774
|
+
default:
|
|
7775
|
+
throw new Error(`Unsupported crafting recipe type: ${recipe.type}`);
|
|
7776
|
+
}
|
|
7777
|
+
layers.push({
|
|
7778
|
+
name: "result",
|
|
7779
|
+
item: itemKey("id" in recipe.result ? recipe.result.id : recipe.result.item),
|
|
7780
|
+
position: [124, 35]
|
|
7781
|
+
});
|
|
7782
|
+
return layers;
|
|
7783
|
+
}
|
|
7596
7784
|
};
|
|
7597
7785
|
|
|
7598
7786
|
// src/gui/scene/GuiObject.ts
|
|
7599
7787
|
init_AssetKey();
|
|
7600
7788
|
init_ModelTextures();
|
|
7789
|
+
init_Models();
|
|
7601
7790
|
init_Caching();
|
|
7602
7791
|
init_SceneObject();
|
|
7603
7792
|
init_Materials();
|
|
7604
|
-
|
|
7793
|
+
init_ModelObject();
|
|
7794
|
+
init_DisplayPosition();
|
|
7795
|
+
import { Box2, Box3 as Box32, Mesh as Mesh7, PlaneGeometry as PlaneGeometry2, Vector2 as Vector23 } from "three";
|
|
7796
|
+
|
|
7797
|
+
// src/model/GuiLight.ts
|
|
7798
|
+
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
7799
|
+
GuiLight2["FRONT"] = "front";
|
|
7800
|
+
GuiLight2["SIDE"] = "side";
|
|
7801
|
+
return GuiLight2;
|
|
7802
|
+
})(GuiLight || {});
|
|
7803
|
+
|
|
7804
|
+
// src/gui/scene/GuiObject.ts
|
|
7605
7805
|
var GuiObject = class extends SceneObject {
|
|
7606
7806
|
constructor(textureLayers, options) {
|
|
7607
7807
|
super({ ...options, instanceMeshes: false, mergeMeshes: false });
|
|
@@ -7616,13 +7816,34 @@ var GuiObject = class extends SceneObject {
|
|
|
7616
7816
|
async init() {
|
|
7617
7817
|
if (this.initialized) return;
|
|
7618
7818
|
try {
|
|
7819
|
+
let depth = 0;
|
|
7619
7820
|
for (const [index, layer] of this.textureLayers.entries()) {
|
|
7821
|
+
const [x, y] = layer.position ?? [0, 0];
|
|
7822
|
+
if ("item" in layer) {
|
|
7823
|
+
const [width2, height2] = layer.size ?? [16, 16];
|
|
7824
|
+
const item = await this.createItem(layer, index);
|
|
7825
|
+
item.position.set(x + width2 / 2, -y - height2 / 2, 0);
|
|
7826
|
+
item.scale.set(width2 / 16, height2 / 16, width2 / 16);
|
|
7827
|
+
item.updateMatrix();
|
|
7828
|
+
const bounds = new Box32();
|
|
7829
|
+
item.iterateAllMeshes((mesh2) => {
|
|
7830
|
+
mesh2.geometry.computeBoundingBox();
|
|
7831
|
+
bounds.union(mesh2.geometry.boundingBox);
|
|
7832
|
+
});
|
|
7833
|
+
bounds.applyMatrix4(item.matrix);
|
|
7834
|
+
item.position.z = depth - bounds.min.z;
|
|
7835
|
+
depth += bounds.max.z - bounds.min.z + 0.01;
|
|
7836
|
+
this.bounds.expandByPoint(new Vector23(x, y));
|
|
7837
|
+
this.bounds.expandByPoint(new Vector23(x + width2, y + height2));
|
|
7838
|
+
this.bounds.expandByPoint(new Vector23(bounds.min.x, -bounds.max.y));
|
|
7839
|
+
this.bounds.expandByPoint(new Vector23(bounds.max.x, -bounds.min.y));
|
|
7840
|
+
continue;
|
|
7841
|
+
}
|
|
7620
7842
|
const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
|
|
7621
7843
|
const material = await this.loadMaterial(key);
|
|
7622
7844
|
const image = material.map.image;
|
|
7623
7845
|
const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
|
|
7624
7846
|
const [width, height] = layer.size ?? [cropWidth, cropHeight];
|
|
7625
|
-
const [x, y] = layer.position ?? [0, 0];
|
|
7626
7847
|
const geometry = new PlaneGeometry2(width, height);
|
|
7627
7848
|
this.geometries.add(geometry);
|
|
7628
7849
|
const uv = geometry.getAttribute("uv");
|
|
@@ -7633,14 +7854,16 @@ var GuiObject = class extends SceneObject {
|
|
|
7633
7854
|
1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
|
|
7634
7855
|
);
|
|
7635
7856
|
}
|
|
7636
|
-
const mesh = new
|
|
7857
|
+
const mesh = new Mesh7(geometry, material);
|
|
7637
7858
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
7638
|
-
mesh.position.set(x + width / 2, -y - height / 2,
|
|
7859
|
+
mesh.position.set(x + width / 2, -y - height / 2, depth);
|
|
7639
7860
|
mesh.renderOrder = index;
|
|
7640
7861
|
this.add(mesh);
|
|
7641
7862
|
this.bounds.expandByPoint(new Vector23(x, y));
|
|
7642
7863
|
this.bounds.expandByPoint(new Vector23(x + width, y + height));
|
|
7864
|
+
depth += 0.01;
|
|
7643
7865
|
}
|
|
7866
|
+
for (const child of this.children) child.position.z -= depth - 0.01;
|
|
7644
7867
|
this.initialized = true;
|
|
7645
7868
|
this.notifyDirty();
|
|
7646
7869
|
} catch (error) {
|
|
@@ -7648,6 +7871,32 @@ var GuiObject = class extends SceneObject {
|
|
|
7648
7871
|
throw error;
|
|
7649
7872
|
}
|
|
7650
7873
|
}
|
|
7874
|
+
async createItem(layer, index) {
|
|
7875
|
+
const key = typeof layer.item === "string" ? AssetKey.parse("models", layer.item) : layer.item;
|
|
7876
|
+
const model = await Models.getMerged(key);
|
|
7877
|
+
if (!model) throw new Error(`Could not load GUI item ${key.toNamespacedString()}`);
|
|
7878
|
+
const item = new ModelObject(model, {
|
|
7879
|
+
displayPosition: "gui" /* GUI */,
|
|
7880
|
+
tints: layer.tints,
|
|
7881
|
+
instanceMeshes: false,
|
|
7882
|
+
mergeMeshes: true
|
|
7883
|
+
});
|
|
7884
|
+
item.name = `group:${layer.name ?? index}`;
|
|
7885
|
+
this.add(item);
|
|
7886
|
+
await item.init();
|
|
7887
|
+
item.iterateAllMeshes((mesh) => {
|
|
7888
|
+
this.geometries.add(mesh.geometry);
|
|
7889
|
+
mesh.name = `mesh:${layer.name ?? index}`;
|
|
7890
|
+
mesh.renderOrder = index;
|
|
7891
|
+
for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
|
|
7892
|
+
material.transparent = true;
|
|
7893
|
+
if (model.gui_light === "front" /* FRONT */ && material.uniforms?.SHADE) {
|
|
7894
|
+
material.uniforms.SHADE.value = false;
|
|
7895
|
+
}
|
|
7896
|
+
}
|
|
7897
|
+
});
|
|
7898
|
+
return item;
|
|
7899
|
+
}
|
|
7651
7900
|
async loadMaterial(key) {
|
|
7652
7901
|
const assetKey = key.serialize();
|
|
7653
7902
|
const materialKey = `gui:${assetKey}`;
|
|
@@ -7691,7 +7940,7 @@ init_util();
|
|
|
7691
7940
|
import { Raycaster, Vector2 as Vector24 } from "three";
|
|
7692
7941
|
init_log();
|
|
7693
7942
|
init_three();
|
|
7694
|
-
var
|
|
7943
|
+
var p8 = prefix("SceneInspector");
|
|
7695
7944
|
var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
|
|
7696
7945
|
var SceneInspector = class {
|
|
7697
7946
|
constructor(renderer) {
|
|
@@ -7785,7 +8034,7 @@ var SceneInspector = class {
|
|
|
7785
8034
|
}
|
|
7786
8035
|
selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
|
|
7787
8036
|
this.selectedObject = targetObject;
|
|
7788
|
-
console.log(
|
|
8037
|
+
console.log(p8, "selected", targetObject);
|
|
7789
8038
|
this.redraw(targetObject, targetIntersection, instance);
|
|
7790
8039
|
}
|
|
7791
8040
|
redraw(targetObject, targetIntersection, instance) {
|
|
@@ -8044,7 +8293,7 @@ var SceneStatsDisplay = class {
|
|
|
8044
8293
|
|
|
8045
8294
|
// src/instance/InstanceManager.ts
|
|
8046
8295
|
init_log();
|
|
8047
|
-
var
|
|
8296
|
+
var p9 = prefix("InstanceManager");
|
|
8048
8297
|
var InstanceManager = class {
|
|
8049
8298
|
constructor() {
|
|
8050
8299
|
this.isInstanceManager = true;
|
|
@@ -8052,7 +8301,7 @@ var InstanceManager = class {
|
|
|
8052
8301
|
}
|
|
8053
8302
|
async get(key) {
|
|
8054
8303
|
if (key in this.instanceCache) {
|
|
8055
|
-
console.debug(
|
|
8304
|
+
console.debug(p9, "key in cache", key);
|
|
8056
8305
|
return (await this.instanceCache[key]).nextInstance();
|
|
8057
8306
|
}
|
|
8058
8307
|
return void 0;
|
|
@@ -8061,7 +8310,7 @@ var InstanceManager = class {
|
|
|
8061
8310
|
if (key in this.instanceCache) {
|
|
8062
8311
|
return await this.get(key);
|
|
8063
8312
|
}
|
|
8064
|
-
console.debug(
|
|
8313
|
+
console.debug(p9, "key not in cache", key);
|
|
8065
8314
|
const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
|
|
8066
8315
|
this.instanceCache[key] = pending;
|
|
8067
8316
|
try {
|
|
@@ -8095,13 +8344,6 @@ function isInstanceable(obj) {
|
|
|
8095
8344
|
init_DisplayPosition();
|
|
8096
8345
|
init_DisplayTransforms();
|
|
8097
8346
|
|
|
8098
|
-
// src/model/GuiLight.ts
|
|
8099
|
-
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
8100
|
-
GuiLight2["FRONT"] = "front";
|
|
8101
|
-
GuiLight2["SIDE"] = "side";
|
|
8102
|
-
return GuiLight2;
|
|
8103
|
-
})(GuiLight || {});
|
|
8104
|
-
|
|
8105
8347
|
// src/model/Model.ts
|
|
8106
8348
|
var ITEM_GENERATED = "item/generated";
|
|
8107
8349
|
var BUILTIN_GENERATED = "builtin/generated";
|
|
@@ -8126,7 +8368,7 @@ init_ModelMerger();
|
|
|
8126
8368
|
init_BlockStates();
|
|
8127
8369
|
init_MineRenderError();
|
|
8128
8370
|
init_util();
|
|
8129
|
-
import { Euler as
|
|
8371
|
+
import { Euler as Euler7 } from "three";
|
|
8130
8372
|
function matchesCondition(condition, state) {
|
|
8131
8373
|
return Object.entries(condition).every(([key, value]) => {
|
|
8132
8374
|
if (Array.isArray(value)) {
|
|
@@ -8201,7 +8443,7 @@ var BlockStateResolver = class {
|
|
|
8201
8443
|
return variants[variants.length - 1];
|
|
8202
8444
|
}
|
|
8203
8445
|
static rotation(variant) {
|
|
8204
|
-
const rotation = new
|
|
8446
|
+
const rotation = new Euler7();
|
|
8205
8447
|
if (typeof variant.x !== "undefined") {
|
|
8206
8448
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
8207
8449
|
}
|
|
@@ -8311,7 +8553,7 @@ var import_ts_deepmerge6 = __toESM(require_dist());
|
|
|
8311
8553
|
init_MineRenderError();
|
|
8312
8554
|
init_InstanceReference();
|
|
8313
8555
|
init_AssetKey();
|
|
8314
|
-
import { Euler as
|
|
8556
|
+
import { Euler as Euler8, Matrix4 as Matrix48, Quaternion as Quaternion5, Vector3 as Vector311 } from "three";
|
|
8315
8557
|
init_ModelCulling();
|
|
8316
8558
|
init_FluidGeometry();
|
|
8317
8559
|
var BlockObject = class _BlockObject extends SceneObject {
|
|
@@ -8382,7 +8624,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8382
8624
|
const scale = new Vector311();
|
|
8383
8625
|
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
8384
8626
|
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector311(1, 1, 1)) > 1e-10) return 0;
|
|
8385
|
-
return ModelCulling.toLocalMask(worldMask, new
|
|
8627
|
+
return ModelCulling.toLocalMask(worldMask, new Euler8().setFromQuaternion(rotation));
|
|
8386
8628
|
}
|
|
8387
8629
|
async setCullMask(worldMask) {
|
|
8388
8630
|
worldMask &= 63;
|
|
@@ -8444,7 +8686,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8444
8686
|
() => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
|
|
8445
8687
|
);
|
|
8446
8688
|
const previous = this._fluidModel;
|
|
8447
|
-
const matrix = previous ? this.getModelMatrix(previous) : new
|
|
8689
|
+
const matrix = previous ? this.getModelMatrix(previous) : new Matrix48().makeTranslation(...this.position.toArray());
|
|
8448
8690
|
if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
|
|
8449
8691
|
else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
8450
8692
|
this._models = this._models.filter((model) => model !== previous);
|
|
@@ -8575,7 +8817,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8575
8817
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
8576
8818
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
8577
8819
|
}
|
|
8578
|
-
getMatrixAt(index, matrix = new
|
|
8820
|
+
getMatrixAt(index, matrix = new Matrix48()) {
|
|
8579
8821
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
8580
8822
|
const child = this._models[0];
|
|
8581
8823
|
if (child && isModelObject(child)) {
|
|
@@ -13137,7 +13379,7 @@ init_CubeFace();
|
|
|
13137
13379
|
init_AssetKey();
|
|
13138
13380
|
init_Models();
|
|
13139
13381
|
init_CubeFace();
|
|
13140
|
-
import { Matrix4 as
|
|
13382
|
+
import { Matrix4 as Matrix49, Vector3 as Vector314 } from "three";
|
|
13141
13383
|
init_ModelCulling();
|
|
13142
13384
|
init_ModelObject();
|
|
13143
13385
|
init_UVMapper();
|
|
@@ -13200,7 +13442,7 @@ var SectionModels = class {
|
|
|
13200
13442
|
});
|
|
13201
13443
|
await object.init();
|
|
13202
13444
|
const geometry = object.children[0].geometry;
|
|
13203
|
-
geometry.applyMatrix4(new
|
|
13445
|
+
geometry.applyMatrix4(new Matrix49().makeRotationFromEuler(rotation));
|
|
13204
13446
|
object.clear();
|
|
13205
13447
|
const cullFaces = CUBE_FACES.map((face) => {
|
|
13206
13448
|
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
@@ -13450,7 +13692,7 @@ var MineRenderWorld = class {
|
|
|
13450
13692
|
// src/world/SectionMesh.ts
|
|
13451
13693
|
init_CanvasCompat();
|
|
13452
13694
|
init_Materials();
|
|
13453
|
-
import { BufferGeometry as
|
|
13695
|
+
import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute6, Group, Mesh as Mesh10 } from "three";
|
|
13454
13696
|
var SectionMesh = class _SectionMesh extends Group {
|
|
13455
13697
|
constructor() {
|
|
13456
13698
|
super(...arguments);
|
|
@@ -13524,7 +13766,7 @@ var SectionMesh = class _SectionMesh extends Group {
|
|
|
13524
13766
|
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
13525
13767
|
}
|
|
13526
13768
|
}
|
|
13527
|
-
const geometry = new
|
|
13769
|
+
const geometry = new BufferGeometry6();
|
|
13528
13770
|
geometry.setAttribute("position", new Float32BufferAttribute6(positions, 3));
|
|
13529
13771
|
geometry.setAttribute("normal", new Float32BufferAttribute6(normals, 3));
|
|
13530
13772
|
geometry.setAttribute("uv", new Float32BufferAttribute6(uvs, 2));
|