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/browser/index.mjs
CHANGED
|
@@ -799,7 +799,7 @@ var init_Textures = __esm({
|
|
|
799
799
|
});
|
|
800
800
|
|
|
801
801
|
// src/Materials.ts
|
|
802
|
-
import { Color, DoubleSide, FrontSide, MeshBasicMaterial, MeshStandardMaterial, ShaderChunk, ShaderMaterial } from "three";
|
|
802
|
+
import { Color, CustomBlending, DoubleSide, OneFactor, RepeatWrapping, FrontSide, MeshBasicMaterial, MeshStandardMaterial, ShaderChunk, ShaderMaterial, ZeroFactor } from "three";
|
|
803
803
|
var _Materials, Materials;
|
|
804
804
|
var init_Materials = __esm({
|
|
805
805
|
"src/Materials.ts"() {
|
|
@@ -838,6 +838,71 @@ var init_Materials = __esm({
|
|
|
838
838
|
alphaTest: 0.5
|
|
839
839
|
});
|
|
840
840
|
}
|
|
841
|
+
/** Whether vanilla's render type for the mode culls back faces. */
|
|
842
|
+
static entityModeCulls(mode = "cutout") {
|
|
843
|
+
return mode === "cutout_cull" || mode === "solid" || mode === "eyes" || mode === "water_mask";
|
|
844
|
+
}
|
|
845
|
+
/** UV offset per tick of entity age for the scrolling modes, as vanilla's texture matrix applies it. */
|
|
846
|
+
static entityModeScroll(mode = "cutout") {
|
|
847
|
+
if (mode === "energy_swirl") return [0.01, 0.01];
|
|
848
|
+
if (mode === "breeze_wind") return [0.02, 0];
|
|
849
|
+
return void 0;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Entity material for one of vanilla's render types. Entities are unlit here, so the lit and full-bright modes
|
|
853
|
+
* differ only in blending and depth state. Culling is not a material property: {@link entityModeCulls} decides
|
|
854
|
+
* whether the geometry gets inward faces.
|
|
855
|
+
*/
|
|
856
|
+
static createEntityCanvasMaterial(canvas, mode = "cutout", tint) {
|
|
857
|
+
const material = _Materials.createBasicCanvasMaterial(canvas);
|
|
858
|
+
switch (mode) {
|
|
859
|
+
case "cutout":
|
|
860
|
+
case "cutout_cull":
|
|
861
|
+
break;
|
|
862
|
+
case "cutout_z_offset":
|
|
863
|
+
material.polygonOffset = true;
|
|
864
|
+
material.polygonOffsetFactor = -1;
|
|
865
|
+
material.polygonOffsetUnits = -10;
|
|
866
|
+
break;
|
|
867
|
+
case "solid":
|
|
868
|
+
material.alphaTest = 0;
|
|
869
|
+
break;
|
|
870
|
+
case "translucent":
|
|
871
|
+
case "breeze_wind":
|
|
872
|
+
material.transparent = true;
|
|
873
|
+
material.alphaTest = 0.1;
|
|
874
|
+
break;
|
|
875
|
+
case "translucent_emissive":
|
|
876
|
+
material.transparent = true;
|
|
877
|
+
material.alphaTest = 0.1;
|
|
878
|
+
material.depthWrite = false;
|
|
879
|
+
break;
|
|
880
|
+
case "eyes":
|
|
881
|
+
material.transparent = true;
|
|
882
|
+
material.alphaTest = 0;
|
|
883
|
+
material.depthWrite = false;
|
|
884
|
+
break;
|
|
885
|
+
case "energy_swirl":
|
|
886
|
+
material.transparent = true;
|
|
887
|
+
material.alphaTest = 0.1;
|
|
888
|
+
material.blending = CustomBlending;
|
|
889
|
+
material.blendSrc = OneFactor;
|
|
890
|
+
material.blendDst = OneFactor;
|
|
891
|
+
material.blendSrcAlpha = ZeroFactor;
|
|
892
|
+
material.blendDstAlpha = OneFactor;
|
|
893
|
+
material.color.set(8421504);
|
|
894
|
+
break;
|
|
895
|
+
case "water_mask":
|
|
896
|
+
material.alphaTest = 0;
|
|
897
|
+
material.colorWrite = false;
|
|
898
|
+
break;
|
|
899
|
+
}
|
|
900
|
+
if (_Materials.entityModeScroll(mode)) {
|
|
901
|
+
material.map.wrapS = material.map.wrapT = RepeatWrapping;
|
|
902
|
+
}
|
|
903
|
+
if (tint !== void 0) material.color.multiply(new Color(tint));
|
|
904
|
+
return material;
|
|
905
|
+
}
|
|
841
906
|
static createGuiCanvasMaterial(canvas) {
|
|
842
907
|
const material = new MeshBasicMaterial({
|
|
843
908
|
map: Textures.createCanvasTexture(canvas),
|
|
@@ -3450,48 +3515,6 @@ var init_SceneObject = __esm({
|
|
|
3450
3515
|
}
|
|
3451
3516
|
});
|
|
3452
3517
|
|
|
3453
|
-
// src/model/ModelCulling.ts
|
|
3454
|
-
import { Vector3 as Vector39 } from "three";
|
|
3455
|
-
var ModelCulling;
|
|
3456
|
-
var init_ModelCulling = __esm({
|
|
3457
|
-
"src/model/ModelCulling.ts"() {
|
|
3458
|
-
init_CubeFace();
|
|
3459
|
-
ModelCulling = class {
|
|
3460
|
-
static toLocalMask(worldMask, rotation) {
|
|
3461
|
-
let localMask = 0;
|
|
3462
|
-
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
3463
|
-
const normal = new Vector39(...offset).applyEuler(rotation);
|
|
3464
|
-
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);
|
|
3465
|
-
if (worldFace < 0) return 0;
|
|
3466
|
-
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
3467
|
-
}
|
|
3468
|
-
return localMask;
|
|
3469
|
-
}
|
|
3470
|
-
static isOpaqueFullCube(atlas) {
|
|
3471
|
-
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
3472
|
-
const element = atlas.model.elements[0];
|
|
3473
|
-
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;
|
|
3474
|
-
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
3475
|
-
return CUBE_FACES.every((face, faceIndex) => {
|
|
3476
|
-
const texture = element.faces[face]?.texture;
|
|
3477
|
-
if (!texture?.startsWith("#")) return false;
|
|
3478
|
-
const key = texture.slice(1);
|
|
3479
|
-
const position = atlas.positions[key];
|
|
3480
|
-
const size = atlas.sizes[key];
|
|
3481
|
-
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
3482
|
-
for (let vertex = 0; vertex < 4; vertex++) {
|
|
3483
|
-
const uvIndex = (faceIndex * 4 + vertex) * 2;
|
|
3484
|
-
const x = element.mappedUv[uvIndex] * atlas.image.width;
|
|
3485
|
-
const y = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
3486
|
-
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;
|
|
3487
|
-
}
|
|
3488
|
-
return true;
|
|
3489
|
-
});
|
|
3490
|
-
}
|
|
3491
|
-
};
|
|
3492
|
-
}
|
|
3493
|
-
});
|
|
3494
|
-
|
|
3495
3518
|
// src/three/BufferGeometryUtils.js
|
|
3496
3519
|
import {
|
|
3497
3520
|
BufferAttribute as BufferAttribute4,
|
|
@@ -3502,7 +3525,7 @@ import {
|
|
|
3502
3525
|
TriangleFanDrawMode,
|
|
3503
3526
|
TriangleStripDrawMode,
|
|
3504
3527
|
TrianglesDrawMode,
|
|
3505
|
-
Vector3 as
|
|
3528
|
+
Vector3 as Vector39
|
|
3506
3529
|
} from "three";
|
|
3507
3530
|
function computeTangents(geometry) {
|
|
3508
3531
|
geometry.computeTangents();
|
|
@@ -3821,15 +3844,15 @@ function computeMorphedAttributes(object) {
|
|
|
3821
3844
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
3822
3845
|
return null;
|
|
3823
3846
|
}
|
|
3824
|
-
const _vA = new
|
|
3825
|
-
const _vB = new
|
|
3826
|
-
const _vC = new
|
|
3827
|
-
const _tempA = new
|
|
3828
|
-
const _tempB = new
|
|
3829
|
-
const _tempC = new
|
|
3830
|
-
const _morphA = new
|
|
3831
|
-
const _morphB = new
|
|
3832
|
-
const _morphC = new
|
|
3847
|
+
const _vA = new Vector39();
|
|
3848
|
+
const _vB = new Vector39();
|
|
3849
|
+
const _vC = new Vector39();
|
|
3850
|
+
const _tempA = new Vector39();
|
|
3851
|
+
const _tempB = new Vector39();
|
|
3852
|
+
const _tempC = new Vector39();
|
|
3853
|
+
const _morphA = new Vector39();
|
|
3854
|
+
const _morphB = new Vector39();
|
|
3855
|
+
const _morphC = new Vector39();
|
|
3833
3856
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
3834
3857
|
_vA.fromBufferAttribute(attribute, a2);
|
|
3835
3858
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4038,12 +4061,54 @@ var init_BufferGeometryUtils = __esm({
|
|
|
4038
4061
|
}
|
|
4039
4062
|
});
|
|
4040
4063
|
|
|
4064
|
+
// src/model/ModelCulling.ts
|
|
4065
|
+
import { Vector3 as Vector310 } from "three";
|
|
4066
|
+
var ModelCulling;
|
|
4067
|
+
var init_ModelCulling = __esm({
|
|
4068
|
+
"src/model/ModelCulling.ts"() {
|
|
4069
|
+
init_CubeFace();
|
|
4070
|
+
ModelCulling = class {
|
|
4071
|
+
static toLocalMask(worldMask, rotation) {
|
|
4072
|
+
let localMask = 0;
|
|
4073
|
+
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
4074
|
+
const normal = new Vector310(...offset).applyEuler(rotation);
|
|
4075
|
+
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);
|
|
4076
|
+
if (worldFace < 0) return 0;
|
|
4077
|
+
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
4078
|
+
}
|
|
4079
|
+
return localMask;
|
|
4080
|
+
}
|
|
4081
|
+
static isOpaqueFullCube(atlas) {
|
|
4082
|
+
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
4083
|
+
const element = atlas.model.elements[0];
|
|
4084
|
+
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;
|
|
4085
|
+
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
4086
|
+
return CUBE_FACES.every((face, faceIndex) => {
|
|
4087
|
+
const texture = element.faces[face]?.texture;
|
|
4088
|
+
if (!texture?.startsWith("#")) return false;
|
|
4089
|
+
const key = texture.slice(1);
|
|
4090
|
+
const position = atlas.positions[key];
|
|
4091
|
+
const size = atlas.sizes[key];
|
|
4092
|
+
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
4093
|
+
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4094
|
+
const uvIndex = (faceIndex * 4 + vertex) * 2;
|
|
4095
|
+
const x = element.mappedUv[uvIndex] * atlas.image.width;
|
|
4096
|
+
const y = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
4097
|
+
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;
|
|
4098
|
+
}
|
|
4099
|
+
return true;
|
|
4100
|
+
});
|
|
4101
|
+
}
|
|
4102
|
+
};
|
|
4103
|
+
}
|
|
4104
|
+
});
|
|
4105
|
+
|
|
4041
4106
|
// src/model/scene/ModelObject.ts
|
|
4042
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as
|
|
4107
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as Matrix47 } from "three";
|
|
4043
4108
|
function isModelObject(obj) {
|
|
4044
4109
|
return obj.isModelObject;
|
|
4045
4110
|
}
|
|
4046
|
-
var import_ts_deepmerge5,
|
|
4111
|
+
var import_ts_deepmerge5, p7, _ModelObject, ModelObject;
|
|
4047
4112
|
var init_ModelObject = __esm({
|
|
4048
4113
|
"src/model/scene/ModelObject.ts"() {
|
|
4049
4114
|
init_SceneObject();
|
|
@@ -4056,7 +4121,7 @@ var init_ModelObject = __esm({
|
|
|
4056
4121
|
init_CubeFace();
|
|
4057
4122
|
init_DisplayTransforms();
|
|
4058
4123
|
init_ModelCulling();
|
|
4059
|
-
|
|
4124
|
+
p7 = prefix("ModelObject");
|
|
4060
4125
|
_ModelObject = class _ModelObject extends SceneObject {
|
|
4061
4126
|
constructor(originalModel, options) {
|
|
4062
4127
|
super(options);
|
|
@@ -4111,19 +4176,19 @@ var init_ModelObject = __esm({
|
|
|
4111
4176
|
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
4112
4177
|
const tint = this.options.tints[tintIndex];
|
|
4113
4178
|
if (tint === void 0) continue;
|
|
4114
|
-
const color = new
|
|
4179
|
+
const color = new Color8(tint);
|
|
4115
4180
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4116
4181
|
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
4117
4182
|
}
|
|
4118
4183
|
}
|
|
4119
4184
|
elGeo.setAttribute("color", new BufferAttribute5(colors, 3));
|
|
4120
4185
|
}
|
|
4121
|
-
elGeo.applyMatrix4(new
|
|
4122
|
-
elGeo.applyMatrix4(new
|
|
4186
|
+
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));
|
|
4187
|
+
elGeo.applyMatrix4(new Matrix47().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4123
4188
|
if (el.rotation) {
|
|
4124
4189
|
applyElementRotation(el.rotation, elGeo);
|
|
4125
4190
|
}
|
|
4126
|
-
elGeo.applyMatrix4(new
|
|
4191
|
+
elGeo.applyMatrix4(new Matrix47().makeTranslation(-8, -8, -8));
|
|
4127
4192
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4128
4193
|
if (this.options.mergeMeshes) {
|
|
4129
4194
|
allGeos.push(elGeo);
|
|
@@ -4135,10 +4200,10 @@ var init_ModelObject = __esm({
|
|
|
4135
4200
|
}
|
|
4136
4201
|
});
|
|
4137
4202
|
} else {
|
|
4138
|
-
console.debug(
|
|
4203
|
+
console.debug(p7, this.atlas.model, "has no elements");
|
|
4139
4204
|
}
|
|
4140
4205
|
} else {
|
|
4141
|
-
console.debug(
|
|
4206
|
+
console.debug(p7, "Missing atlas for", this);
|
|
4142
4207
|
}
|
|
4143
4208
|
if (this.options.mergeMeshes) {
|
|
4144
4209
|
let combinedGeo;
|
|
@@ -4238,7 +4303,7 @@ var init_fluidBlocks = __esm({
|
|
|
4238
4303
|
});
|
|
4239
4304
|
|
|
4240
4305
|
// src/model/fluid/FluidGeometry.ts
|
|
4241
|
-
import { BufferGeometry as
|
|
4306
|
+
import { BufferGeometry as BufferGeometry4, Float32BufferAttribute as Float32BufferAttribute5 } from "three";
|
|
4242
4307
|
function getBlockFluidState(key, state) {
|
|
4243
4308
|
const rule = key && fluidRules[key.toNamespacedString()];
|
|
4244
4309
|
if (rule) return {
|
|
@@ -4256,7 +4321,7 @@ function ownHeight(sample) {
|
|
|
4256
4321
|
return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
|
|
4257
4322
|
}
|
|
4258
4323
|
function createFluidGeometry(kind, sample) {
|
|
4259
|
-
const geometry = new
|
|
4324
|
+
const geometry = new BufferGeometry4();
|
|
4260
4325
|
const positions = [], normals = [], uvs = [], indices = [];
|
|
4261
4326
|
const self = sample(0, 0, 0);
|
|
4262
4327
|
const height = (x, z) => {
|
|
@@ -4377,7 +4442,7 @@ __export(FluidModelObject_exports, {
|
|
|
4377
4442
|
FluidModelObject: () => FluidModelObject,
|
|
4378
4443
|
sampleFluid: () => sampleFluid
|
|
4379
4444
|
});
|
|
4380
|
-
import { BufferAttribute as BufferAttribute6, Color as
|
|
4445
|
+
import { BufferAttribute as BufferAttribute6, Color as Color9, DoubleSide as DoubleSide3 } from "three";
|
|
4381
4446
|
function sampleFluid(kind, sample) {
|
|
4382
4447
|
const cells = [];
|
|
4383
4448
|
const key = [];
|
|
@@ -4428,7 +4493,7 @@ var init_FluidModelObject = __esm({
|
|
|
4428
4493
|
}
|
|
4429
4494
|
}
|
|
4430
4495
|
geometry.clearGroups();
|
|
4431
|
-
const color = new
|
|
4496
|
+
const color = new Color9(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
|
|
4432
4497
|
const colors = new Float32Array(geometry.getAttribute("position").count * 3);
|
|
4433
4498
|
for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
|
|
4434
4499
|
geometry.setAttribute("color", new BufferAttribute6(colors, 3));
|
|
@@ -4763,32 +4828,44 @@ var Entities = class {
|
|
|
4763
4828
|
static async getLayerList(modelKey) {
|
|
4764
4829
|
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
4765
4830
|
}
|
|
4831
|
+
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
4832
|
+
static async getPassList(modelKey) {
|
|
4833
|
+
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
4834
|
+
}
|
|
4766
4835
|
static async getEntity(modelKey, textureKey, options) {
|
|
4767
4836
|
const model = await this.getModelFile(modelKey);
|
|
4768
4837
|
if (!model) return void 0;
|
|
4769
|
-
const
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4838
|
+
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
4839
|
+
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
4840
|
+
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
4841
|
+
draws.push(...passes);
|
|
4842
|
+
const names = [];
|
|
4843
|
+
const selected = draws.map((pass) => {
|
|
4844
|
+
const layer = model.layers[pass.layer];
|
|
4773
4845
|
if (!layer) {
|
|
4774
|
-
throw new MineRenderError(`Entity ${model.id} has no layer "${
|
|
4846
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
4775
4847
|
}
|
|
4776
|
-
|
|
4848
|
+
let name = pass.layer;
|
|
4849
|
+
for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
|
|
4850
|
+
names.push(name);
|
|
4851
|
+
return { name, layer, pass };
|
|
4777
4852
|
});
|
|
4778
|
-
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer }, index) => {
|
|
4853
|
+
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
|
|
4779
4854
|
const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
|
|
4855
|
+
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
4780
4856
|
let texture;
|
|
4781
4857
|
if (override) {
|
|
4782
4858
|
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
4783
4859
|
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);
|
|
4784
|
-
} else if (
|
|
4785
|
-
texture = AssetKey.parse("textures",
|
|
4860
|
+
} else if (textureLocation !== void 0) {
|
|
4861
|
+
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
4786
4862
|
} else {
|
|
4787
4863
|
texture = await this.resolveTexture(modelKey);
|
|
4788
4864
|
}
|
|
4789
|
-
|
|
4865
|
+
const render = pass.render ?? layer.render;
|
|
4866
|
+
return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
4790
4867
|
})));
|
|
4791
|
-
return { ...layers[names[0]], id: model.id, layers };
|
|
4868
|
+
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4792
4869
|
}
|
|
4793
4870
|
static async resolveTexture(modelKey) {
|
|
4794
4871
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
@@ -4870,11 +4947,12 @@ function trimCanvas(source) {
|
|
|
4870
4947
|
init_SceneObject();
|
|
4871
4948
|
init_Caching();
|
|
4872
4949
|
var import_ts_deepmerge4 = __toESM(require_dist());
|
|
4950
|
+
init_Ticker();
|
|
4873
4951
|
init_model();
|
|
4874
4952
|
init_ModelTextures();
|
|
4875
4953
|
init_AssetKey();
|
|
4876
4954
|
init_Materials();
|
|
4877
|
-
import { Object3D as Object3D3 } from "three";
|
|
4955
|
+
import { Color as Color3, Euler as Euler4, Matrix4 as Matrix44, Object3D as Object3D3 } from "three";
|
|
4878
4956
|
init_three();
|
|
4879
4957
|
var _EntityObject = class _EntityObject extends SceneObject {
|
|
4880
4958
|
constructor(entity, options) {
|
|
@@ -4882,6 +4960,10 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4882
4960
|
this.entity = entity;
|
|
4883
4961
|
this.isEntityObject = true;
|
|
4884
4962
|
this.meshesCreated = false;
|
|
4963
|
+
/** Scrolling materials are owned: their texture offset follows this entity's age. */
|
|
4964
|
+
this.scrollMaterials = [];
|
|
4965
|
+
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
4966
|
+
this.age = 0;
|
|
4885
4967
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
4886
4968
|
}
|
|
4887
4969
|
async init() {
|
|
@@ -4891,6 +4973,25 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4891
4973
|
dispose() {
|
|
4892
4974
|
super.dispose();
|
|
4893
4975
|
}
|
|
4976
|
+
disposeAndRemoveAllChildren() {
|
|
4977
|
+
this.clearScrollMaterials();
|
|
4978
|
+
super.disposeAndRemoveAllChildren();
|
|
4979
|
+
}
|
|
4980
|
+
clearScrollMaterials() {
|
|
4981
|
+
Ticker.remove(this.scrollTicker);
|
|
4982
|
+
this.scrollTicker = void 0;
|
|
4983
|
+
for (const { material } of this.scrollMaterials.splice(0)) {
|
|
4984
|
+
material.map?.dispose();
|
|
4985
|
+
material.dispose();
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
/** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
|
|
4989
|
+
updateScroll() {
|
|
4990
|
+
for (const { offset, speed } of this.scrollMaterials) {
|
|
4991
|
+
offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
|
|
4992
|
+
}
|
|
4993
|
+
this.notifyDirty();
|
|
4994
|
+
}
|
|
4894
4995
|
getLayerGroup(name) {
|
|
4895
4996
|
return super.getGroupByName(`layer:${name}`);
|
|
4896
4997
|
}
|
|
@@ -4921,16 +5022,29 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4921
5022
|
createMeshes(force = false) {
|
|
4922
5023
|
if (this.meshesCreated && !force) return;
|
|
4923
5024
|
const modelRoot = new Object3D3();
|
|
4924
|
-
|
|
5025
|
+
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
5026
|
+
if (transform) {
|
|
5027
|
+
for (const op of transform) {
|
|
5028
|
+
const matrix = new Matrix44();
|
|
5029
|
+
if ("scale" in op) matrix.makeScale(...op.scale);
|
|
5030
|
+
else if ("translate" in op) matrix.makeTranslation(...op.translate);
|
|
5031
|
+
else matrix.makeRotationFromEuler(new Euler4(...op.rotate, "ZYX"));
|
|
5032
|
+
modelRoot.matrix.multiply(matrix);
|
|
5033
|
+
}
|
|
5034
|
+
modelRoot.matrixAutoUpdate = false;
|
|
5035
|
+
} else if (this.options.flip ?? true) {
|
|
5036
|
+
modelRoot.scale.set(-1, -1, 1);
|
|
5037
|
+
}
|
|
4925
5038
|
this.add(modelRoot);
|
|
4926
5039
|
Object.entries(this.entityLayers).forEach(([name, layer], index) => {
|
|
4927
5040
|
const group = this.createGroup(`layer:${name}`);
|
|
4928
5041
|
modelRoot.add(group);
|
|
4929
|
-
|
|
5042
|
+
const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
|
|
5043
|
+
this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
|
|
4930
5044
|
});
|
|
4931
5045
|
this.meshesCreated = true;
|
|
4932
5046
|
}
|
|
4933
|
-
createPart(name, part, parent, textureSize, material, renderOrder) {
|
|
5047
|
+
createPart(name, part, parent, textureSize, material, renderOrder, inward = true) {
|
|
4934
5048
|
const anchor = this.createGroup(name);
|
|
4935
5049
|
anchor.position.fromArray(part.pose.offset);
|
|
4936
5050
|
anchor.rotation.set(...part.pose.rotation, "ZYX");
|
|
@@ -4949,7 +5063,7 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4949
5063
|
uv
|
|
4950
5064
|
).clone();
|
|
4951
5065
|
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
4952
|
-
if (Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
5066
|
+
if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
4953
5067
|
const index = Array.from(geometry.getIndex().array);
|
|
4954
5068
|
geometry.setIndex(index.concat(index.slice().reverse()));
|
|
4955
5069
|
}
|
|
@@ -4959,30 +5073,46 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4959
5073
|
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
4960
5074
|
}
|
|
4961
5075
|
for (const [childName, child] of Object.entries(part.children)) {
|
|
4962
|
-
this.createPart(childName, child, anchor, size, material, renderOrder);
|
|
5076
|
+
this.createPart(childName, child, anchor, size, material, renderOrder, inward);
|
|
4963
5077
|
}
|
|
4964
5078
|
}
|
|
4965
5079
|
async applyTextures() {
|
|
5080
|
+
this.clearScrollMaterials();
|
|
4966
5081
|
await Promise.all(Object.entries(this.entityLayers).map(async ([name, layer]) => {
|
|
5082
|
+
const mode = layer.render ?? layer.layer.render ?? "cutout";
|
|
5083
|
+
const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
|
|
5084
|
+
const scroll = Materials.entityModeScroll(mode);
|
|
4967
5085
|
const assetKeyStr = this.getTextureKey(layer).serialize();
|
|
4968
|
-
const keyStr = `entity:${assetKeyStr}`;
|
|
4969
|
-
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
5086
|
+
const keyStr = `entity:${mode}:${tint === void 0 ? "" : new Color3(tint).getHexString()}:${assetKeyStr}`;
|
|
5087
|
+
let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
|
|
4970
5088
|
if (!mat) {
|
|
4971
5089
|
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
4972
5090
|
const imageData = await this.loadTextures(layer);
|
|
4973
5091
|
if (!imageData) return;
|
|
4974
5092
|
const canvas = imageData.data.canvas;
|
|
4975
|
-
const createMaterial = () => Materials.
|
|
4976
|
-
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
5093
|
+
const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode, tint);
|
|
5094
|
+
mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
5095
|
+
if (scroll) {
|
|
5096
|
+
this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
|
|
5097
|
+
}
|
|
4977
5098
|
}
|
|
4978
5099
|
this.getLayerGroup(name)?.traverse((object) => {
|
|
4979
5100
|
if (isMesh(object)) object.material = mat;
|
|
4980
5101
|
});
|
|
4981
5102
|
}));
|
|
5103
|
+
if (!this.children.length) {
|
|
5104
|
+
this.clearScrollMaterials();
|
|
5105
|
+
} else if (this.scrollMaterials.length) {
|
|
5106
|
+
this.updateScroll();
|
|
5107
|
+
this.scrollTicker = Ticker.add(() => {
|
|
5108
|
+
this.age++;
|
|
5109
|
+
this.updateScroll();
|
|
5110
|
+
});
|
|
5111
|
+
}
|
|
4982
5112
|
this.notifyDirty();
|
|
4983
5113
|
}
|
|
4984
5114
|
};
|
|
4985
|
-
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS
|
|
5115
|
+
_EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
|
|
4986
5116
|
var EntityObject = _EntityObject;
|
|
4987
5117
|
function isEntityObject(obj) {
|
|
4988
5118
|
return obj.isEntityObject;
|
|
@@ -4992,11 +5122,11 @@ function isEntityObject(obj) {
|
|
|
4992
5122
|
init_MineRenderError();
|
|
4993
5123
|
|
|
4994
5124
|
// src/export/SceneExporter.ts
|
|
4995
|
-
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as
|
|
5125
|
+
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";
|
|
4996
5126
|
|
|
4997
5127
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
4998
5128
|
import {
|
|
4999
|
-
Color as
|
|
5129
|
+
Color as Color4,
|
|
5000
5130
|
Matrix3,
|
|
5001
5131
|
Vector2 as Vector22,
|
|
5002
5132
|
Vector3 as Vector36
|
|
@@ -5008,7 +5138,7 @@ var OBJExporter = class {
|
|
|
5008
5138
|
let indexVertexUvs = 0;
|
|
5009
5139
|
let indexNormals = 0;
|
|
5010
5140
|
const vertex = new Vector36();
|
|
5011
|
-
const color = new
|
|
5141
|
+
const color = new Color4();
|
|
5012
5142
|
const normal = new Vector36();
|
|
5013
5143
|
const uv = new Vector22();
|
|
5014
5144
|
const face = [];
|
|
@@ -5139,7 +5269,7 @@ var OBJExporter = class {
|
|
|
5139
5269
|
import {
|
|
5140
5270
|
Matrix3 as Matrix32,
|
|
5141
5271
|
Vector3 as Vector37,
|
|
5142
|
-
Color as
|
|
5272
|
+
Color as Color5
|
|
5143
5273
|
} from "three";
|
|
5144
5274
|
var PLYExporter = class {
|
|
5145
5275
|
parse(object, onDone, options = {}) {
|
|
@@ -5197,7 +5327,7 @@ var PLYExporter = class {
|
|
|
5197
5327
|
includeIndices = false;
|
|
5198
5328
|
}
|
|
5199
5329
|
});
|
|
5200
|
-
const tempColor = new
|
|
5330
|
+
const tempColor = new Color5();
|
|
5201
5331
|
includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
|
|
5202
5332
|
includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
|
|
5203
5333
|
includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
|
|
@@ -5409,7 +5539,7 @@ property list uchar int vertex_index
|
|
|
5409
5539
|
import {
|
|
5410
5540
|
BufferAttribute as BufferAttribute3,
|
|
5411
5541
|
ClampToEdgeWrapping,
|
|
5412
|
-
Color as
|
|
5542
|
+
Color as Color6,
|
|
5413
5543
|
DoubleSide as DoubleSide2,
|
|
5414
5544
|
InterpolateDiscrete,
|
|
5415
5545
|
InterpolateLinear,
|
|
@@ -5418,14 +5548,14 @@ import {
|
|
|
5418
5548
|
LinearMipmapLinearFilter,
|
|
5419
5549
|
LinearMipmapNearestFilter,
|
|
5420
5550
|
MathUtils as MathUtils2,
|
|
5421
|
-
Matrix4 as
|
|
5551
|
+
Matrix4 as Matrix45,
|
|
5422
5552
|
MirroredRepeatWrapping,
|
|
5423
5553
|
NearestFilter as NearestFilter2,
|
|
5424
5554
|
NearestMipmapLinearFilter,
|
|
5425
5555
|
NearestMipmapNearestFilter,
|
|
5426
5556
|
PropertyBinding,
|
|
5427
5557
|
RGBAFormat as RGBAFormat2,
|
|
5428
|
-
RepeatWrapping,
|
|
5558
|
+
RepeatWrapping as RepeatWrapping2,
|
|
5429
5559
|
Scene as Scene3,
|
|
5430
5560
|
Source,
|
|
5431
5561
|
SRGBColorSpace as SRGBColorSpace4,
|
|
@@ -5643,7 +5773,7 @@ THREE_TO_WEBGL[LinearFilter] = WEBGL_CONSTANTS.LINEAR;
|
|
|
5643
5773
|
THREE_TO_WEBGL[LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
|
|
5644
5774
|
THREE_TO_WEBGL[LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
|
|
5645
5775
|
THREE_TO_WEBGL[ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
|
|
5646
|
-
THREE_TO_WEBGL[
|
|
5776
|
+
THREE_TO_WEBGL[RepeatWrapping2] = WEBGL_CONSTANTS.REPEAT;
|
|
5647
5777
|
THREE_TO_WEBGL[MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
|
|
5648
5778
|
var PATH_PROPERTIES = {
|
|
5649
5779
|
scale: "scale",
|
|
@@ -5651,7 +5781,7 @@ var PATH_PROPERTIES = {
|
|
|
5651
5781
|
quaternion: "rotation",
|
|
5652
5782
|
morphTargetInfluences: "weights"
|
|
5653
5783
|
};
|
|
5654
|
-
var DEFAULT_SPECULAR_COLOR = new
|
|
5784
|
+
var DEFAULT_SPECULAR_COLOR = new Color6();
|
|
5655
5785
|
var GLB_HEADER_BYTES = 12;
|
|
5656
5786
|
var GLB_HEADER_MAGIC = 1179937895;
|
|
5657
5787
|
var GLB_VERSION = 2;
|
|
@@ -6708,7 +6838,7 @@ var GLTFWriter = class {
|
|
|
6708
6838
|
if (rootJoint === void 0) return null;
|
|
6709
6839
|
const joints = [];
|
|
6710
6840
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
6711
|
-
const temporaryBoneInverse = new
|
|
6841
|
+
const temporaryBoneInverse = new Matrix45();
|
|
6712
6842
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
6713
6843
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
6714
6844
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7174,7 +7304,7 @@ var GLTFMeshGpuInstancing = class {
|
|
|
7174
7304
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
7175
7305
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
7176
7306
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
7177
|
-
const matrix = new
|
|
7307
|
+
const matrix = new Matrix45();
|
|
7178
7308
|
const position = new Vector38();
|
|
7179
7309
|
const quaternion = new Quaternion4();
|
|
7180
7310
|
const scale = new Vector38();
|
|
@@ -7348,7 +7478,7 @@ var SceneExporter = class {
|
|
|
7348
7478
|
}
|
|
7349
7479
|
};
|
|
7350
7480
|
function localMatrix(object) {
|
|
7351
|
-
return object.matrixAutoUpdate ? new
|
|
7481
|
+
return object.matrixAutoUpdate ? new Matrix46().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
7352
7482
|
}
|
|
7353
7483
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
7354
7484
|
const scene = new Scene4();
|
|
@@ -7433,7 +7563,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7433
7563
|
const material = copyMaterial(sourceMaterial, geometry);
|
|
7434
7564
|
if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
|
|
7435
7565
|
if (bakeColors || instanceColor) {
|
|
7436
|
-
const tint = (material.color ?? new
|
|
7566
|
+
const tint = (material.color ?? new Color7()).clone();
|
|
7437
7567
|
if (instanceColor) tint.multiply(instanceColor);
|
|
7438
7568
|
if (bakeColors) {
|
|
7439
7569
|
const original = geometry.getAttribute("color");
|
|
@@ -7460,9 +7590,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7460
7590
|
const instanced = mesh;
|
|
7461
7591
|
if (instanced.isInstancedMesh) {
|
|
7462
7592
|
for (let i = 0; i < instanced.count; i++) {
|
|
7463
|
-
const matrix = new
|
|
7593
|
+
const matrix = new Matrix46();
|
|
7464
7594
|
instanced.getMatrixAt(i, matrix);
|
|
7465
|
-
const color = instanced.instanceColor ? new
|
|
7595
|
+
const color = instanced.instanceColor ? new Color7().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
7466
7596
|
addMesh(mesh, world.clone().multiply(matrix), color);
|
|
7467
7597
|
}
|
|
7468
7598
|
} else {
|
|
@@ -7474,7 +7604,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7474
7604
|
try {
|
|
7475
7605
|
const ancestors = [];
|
|
7476
7606
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
7477
|
-
const world = new
|
|
7607
|
+
const world = new Matrix46();
|
|
7478
7608
|
for (const ancestor of ancestors) {
|
|
7479
7609
|
if (!ancestor.visible) return { scene, dispose };
|
|
7480
7610
|
world.multiply(localMatrix(ancestor));
|
|
@@ -7541,20 +7671,90 @@ function copyDataTexture(source) {
|
|
|
7541
7671
|
}
|
|
7542
7672
|
|
|
7543
7673
|
// src/gui/GuiHelper.ts
|
|
7674
|
+
init_AssetKey();
|
|
7544
7675
|
var GuiHelper = class {
|
|
7545
7676
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
7546
7677
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
7547
7678
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
7548
7679
|
}
|
|
7680
|
+
/** Creates crafting-table layers for ingredients and the result; stack counts are not drawn. */
|
|
7681
|
+
static recipe(recipe, options = {}) {
|
|
7682
|
+
const layers = [
|
|
7683
|
+
{ name: "background", texture: "minecraft:gui/container/crafting_table", crop: [0, 0, 176, 166] }
|
|
7684
|
+
];
|
|
7685
|
+
const itemKey = (ingredient) => {
|
|
7686
|
+
const item = typeof ingredient === "string" && !ingredient.startsWith("#") ? ingredient : typeof ingredient === "object" && "item" in ingredient ? ingredient.item : options.resolveIngredient?.(ingredient);
|
|
7687
|
+
if (isAssetKey(item)) return item;
|
|
7688
|
+
if (!item || item.startsWith("#")) {
|
|
7689
|
+
throw new Error(`Select a concrete item for recipe ingredient ${JSON.stringify(ingredient)}`);
|
|
7690
|
+
}
|
|
7691
|
+
const key = AssetKey.parse("models", item);
|
|
7692
|
+
return new AssetKey(key.namespace, key.getFullPath(), "models", "item");
|
|
7693
|
+
};
|
|
7694
|
+
const addIngredient = (ingredient, slot) => {
|
|
7695
|
+
layers.push({
|
|
7696
|
+
name: `ingredient-${slot}`,
|
|
7697
|
+
item: itemKey(ingredient),
|
|
7698
|
+
position: this.inventorySlot(slot, [30, 17], [18, 18], 3)
|
|
7699
|
+
});
|
|
7700
|
+
};
|
|
7701
|
+
switch (recipe.type) {
|
|
7702
|
+
case "minecraft:crafting_shaped":
|
|
7703
|
+
case "crafting_shaped": {
|
|
7704
|
+
const pattern = recipe.pattern;
|
|
7705
|
+
if (!pattern.length || pattern.length > 3 || !pattern[0].length || pattern[0].length > 3 || pattern.some((row) => row.length !== pattern[0].length)) {
|
|
7706
|
+
throw new Error("Crafting patterns must be rectangular, with 1\u20133 rows and columns");
|
|
7707
|
+
}
|
|
7708
|
+
const cells = pattern.flatMap((row, y) => row.split("").map((symbol, x) => ({ symbol, x, y }))).filter((cell) => cell.symbol !== " ");
|
|
7709
|
+
if (!cells.length) throw new Error("Crafting patterns must contain an ingredient");
|
|
7710
|
+
const minX = Math.min(...cells.map((cell) => cell.x)), maxX = Math.max(...cells.map((cell) => cell.x));
|
|
7711
|
+
const minY = Math.min(...cells.map((cell) => cell.y)), maxY = Math.max(...cells.map((cell) => cell.y));
|
|
7712
|
+
const offsetX = minX === maxX ? 1 : 0, offsetY = minY === maxY ? 1 : 0;
|
|
7713
|
+
for (const { symbol, x, y } of cells) {
|
|
7714
|
+
const ingredient = recipe.key[symbol];
|
|
7715
|
+
if (!ingredient) throw new Error(`Missing recipe ingredient for symbol ${JSON.stringify(symbol)}`);
|
|
7716
|
+
addIngredient(ingredient, (y - minY + offsetY) * 3 + x - minX + offsetX);
|
|
7717
|
+
}
|
|
7718
|
+
break;
|
|
7719
|
+
}
|
|
7720
|
+
case "minecraft:crafting_shapeless":
|
|
7721
|
+
case "crafting_shapeless":
|
|
7722
|
+
if (!recipe.ingredients.length || recipe.ingredients.length > 9) {
|
|
7723
|
+
throw new Error("Shapeless crafting recipes require 1\u20139 ingredients");
|
|
7724
|
+
}
|
|
7725
|
+
recipe.ingredients.forEach(addIngredient);
|
|
7726
|
+
break;
|
|
7727
|
+
default:
|
|
7728
|
+
throw new Error(`Unsupported crafting recipe type: ${recipe.type}`);
|
|
7729
|
+
}
|
|
7730
|
+
layers.push({
|
|
7731
|
+
name: "result",
|
|
7732
|
+
item: itemKey("id" in recipe.result ? recipe.result.id : recipe.result.item),
|
|
7733
|
+
position: [124, 35]
|
|
7734
|
+
});
|
|
7735
|
+
return layers;
|
|
7736
|
+
}
|
|
7549
7737
|
};
|
|
7550
7738
|
|
|
7551
7739
|
// src/gui/scene/GuiObject.ts
|
|
7552
7740
|
init_AssetKey();
|
|
7553
7741
|
init_ModelTextures();
|
|
7742
|
+
init_Models();
|
|
7554
7743
|
init_Caching();
|
|
7555
7744
|
init_SceneObject();
|
|
7556
7745
|
init_Materials();
|
|
7557
|
-
|
|
7746
|
+
init_ModelObject();
|
|
7747
|
+
init_DisplayPosition();
|
|
7748
|
+
import { Box2, Box3 as Box32, Mesh as Mesh7, PlaneGeometry as PlaneGeometry2, Vector2 as Vector23 } from "three";
|
|
7749
|
+
|
|
7750
|
+
// src/model/GuiLight.ts
|
|
7751
|
+
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
7752
|
+
GuiLight2["FRONT"] = "front";
|
|
7753
|
+
GuiLight2["SIDE"] = "side";
|
|
7754
|
+
return GuiLight2;
|
|
7755
|
+
})(GuiLight || {});
|
|
7756
|
+
|
|
7757
|
+
// src/gui/scene/GuiObject.ts
|
|
7558
7758
|
var GuiObject = class extends SceneObject {
|
|
7559
7759
|
constructor(textureLayers, options) {
|
|
7560
7760
|
super({ ...options, instanceMeshes: false, mergeMeshes: false });
|
|
@@ -7569,13 +7769,34 @@ var GuiObject = class extends SceneObject {
|
|
|
7569
7769
|
async init() {
|
|
7570
7770
|
if (this.initialized) return;
|
|
7571
7771
|
try {
|
|
7772
|
+
let depth = 0;
|
|
7572
7773
|
for (const [index, layer] of this.textureLayers.entries()) {
|
|
7774
|
+
const [x, y] = layer.position ?? [0, 0];
|
|
7775
|
+
if ("item" in layer) {
|
|
7776
|
+
const [width2, height2] = layer.size ?? [16, 16];
|
|
7777
|
+
const item = await this.createItem(layer, index);
|
|
7778
|
+
item.position.set(x + width2 / 2, -y - height2 / 2, 0);
|
|
7779
|
+
item.scale.set(width2 / 16, height2 / 16, width2 / 16);
|
|
7780
|
+
item.updateMatrix();
|
|
7781
|
+
const bounds = new Box32();
|
|
7782
|
+
item.iterateAllMeshes((mesh2) => {
|
|
7783
|
+
mesh2.geometry.computeBoundingBox();
|
|
7784
|
+
bounds.union(mesh2.geometry.boundingBox);
|
|
7785
|
+
});
|
|
7786
|
+
bounds.applyMatrix4(item.matrix);
|
|
7787
|
+
item.position.z = depth - bounds.min.z;
|
|
7788
|
+
depth += bounds.max.z - bounds.min.z + 0.01;
|
|
7789
|
+
this.bounds.expandByPoint(new Vector23(x, y));
|
|
7790
|
+
this.bounds.expandByPoint(new Vector23(x + width2, y + height2));
|
|
7791
|
+
this.bounds.expandByPoint(new Vector23(bounds.min.x, -bounds.max.y));
|
|
7792
|
+
this.bounds.expandByPoint(new Vector23(bounds.max.x, -bounds.min.y));
|
|
7793
|
+
continue;
|
|
7794
|
+
}
|
|
7573
7795
|
const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
|
|
7574
7796
|
const material = await this.loadMaterial(key);
|
|
7575
7797
|
const image = material.map.image;
|
|
7576
7798
|
const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
|
|
7577
7799
|
const [width, height] = layer.size ?? [cropWidth, cropHeight];
|
|
7578
|
-
const [x, y] = layer.position ?? [0, 0];
|
|
7579
7800
|
const geometry = new PlaneGeometry2(width, height);
|
|
7580
7801
|
this.geometries.add(geometry);
|
|
7581
7802
|
const uv = geometry.getAttribute("uv");
|
|
@@ -7586,14 +7807,16 @@ var GuiObject = class extends SceneObject {
|
|
|
7586
7807
|
1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
|
|
7587
7808
|
);
|
|
7588
7809
|
}
|
|
7589
|
-
const mesh = new
|
|
7810
|
+
const mesh = new Mesh7(geometry, material);
|
|
7590
7811
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
7591
|
-
mesh.position.set(x + width / 2, -y - height / 2,
|
|
7812
|
+
mesh.position.set(x + width / 2, -y - height / 2, depth);
|
|
7592
7813
|
mesh.renderOrder = index;
|
|
7593
7814
|
this.add(mesh);
|
|
7594
7815
|
this.bounds.expandByPoint(new Vector23(x, y));
|
|
7595
7816
|
this.bounds.expandByPoint(new Vector23(x + width, y + height));
|
|
7817
|
+
depth += 0.01;
|
|
7596
7818
|
}
|
|
7819
|
+
for (const child of this.children) child.position.z -= depth - 0.01;
|
|
7597
7820
|
this.initialized = true;
|
|
7598
7821
|
this.notifyDirty();
|
|
7599
7822
|
} catch (error) {
|
|
@@ -7601,6 +7824,32 @@ var GuiObject = class extends SceneObject {
|
|
|
7601
7824
|
throw error;
|
|
7602
7825
|
}
|
|
7603
7826
|
}
|
|
7827
|
+
async createItem(layer, index) {
|
|
7828
|
+
const key = typeof layer.item === "string" ? AssetKey.parse("models", layer.item) : layer.item;
|
|
7829
|
+
const model = await Models.getMerged(key);
|
|
7830
|
+
if (!model) throw new Error(`Could not load GUI item ${key.toNamespacedString()}`);
|
|
7831
|
+
const item = new ModelObject(model, {
|
|
7832
|
+
displayPosition: "gui" /* GUI */,
|
|
7833
|
+
tints: layer.tints,
|
|
7834
|
+
instanceMeshes: false,
|
|
7835
|
+
mergeMeshes: true
|
|
7836
|
+
});
|
|
7837
|
+
item.name = `group:${layer.name ?? index}`;
|
|
7838
|
+
this.add(item);
|
|
7839
|
+
await item.init();
|
|
7840
|
+
item.iterateAllMeshes((mesh) => {
|
|
7841
|
+
this.geometries.add(mesh.geometry);
|
|
7842
|
+
mesh.name = `mesh:${layer.name ?? index}`;
|
|
7843
|
+
mesh.renderOrder = index;
|
|
7844
|
+
for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
|
|
7845
|
+
material.transparent = true;
|
|
7846
|
+
if (model.gui_light === "front" /* FRONT */ && material.uniforms?.SHADE) {
|
|
7847
|
+
material.uniforms.SHADE.value = false;
|
|
7848
|
+
}
|
|
7849
|
+
}
|
|
7850
|
+
});
|
|
7851
|
+
return item;
|
|
7852
|
+
}
|
|
7604
7853
|
async loadMaterial(key) {
|
|
7605
7854
|
const assetKey = key.serialize();
|
|
7606
7855
|
const materialKey = `gui:${assetKey}`;
|
|
@@ -7644,7 +7893,7 @@ init_util();
|
|
|
7644
7893
|
import { Raycaster, Vector2 as Vector24 } from "three";
|
|
7645
7894
|
init_log();
|
|
7646
7895
|
init_three();
|
|
7647
|
-
var
|
|
7896
|
+
var p8 = prefix("SceneInspector");
|
|
7648
7897
|
var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
|
|
7649
7898
|
var SceneInspector = class {
|
|
7650
7899
|
constructor(renderer) {
|
|
@@ -7738,7 +7987,7 @@ var SceneInspector = class {
|
|
|
7738
7987
|
}
|
|
7739
7988
|
selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
|
|
7740
7989
|
this.selectedObject = targetObject;
|
|
7741
|
-
console.log(
|
|
7990
|
+
console.log(p8, "selected", targetObject);
|
|
7742
7991
|
this.redraw(targetObject, targetIntersection, instance);
|
|
7743
7992
|
}
|
|
7744
7993
|
redraw(targetObject, targetIntersection, instance) {
|
|
@@ -7997,7 +8246,7 @@ var SceneStatsDisplay = class {
|
|
|
7997
8246
|
|
|
7998
8247
|
// src/instance/InstanceManager.ts
|
|
7999
8248
|
init_log();
|
|
8000
|
-
var
|
|
8249
|
+
var p9 = prefix("InstanceManager");
|
|
8001
8250
|
var InstanceManager = class {
|
|
8002
8251
|
constructor() {
|
|
8003
8252
|
this.isInstanceManager = true;
|
|
@@ -8005,7 +8254,7 @@ var InstanceManager = class {
|
|
|
8005
8254
|
}
|
|
8006
8255
|
async get(key) {
|
|
8007
8256
|
if (key in this.instanceCache) {
|
|
8008
|
-
console.debug(
|
|
8257
|
+
console.debug(p9, "key in cache", key);
|
|
8009
8258
|
return (await this.instanceCache[key]).nextInstance();
|
|
8010
8259
|
}
|
|
8011
8260
|
return void 0;
|
|
@@ -8014,7 +8263,7 @@ var InstanceManager = class {
|
|
|
8014
8263
|
if (key in this.instanceCache) {
|
|
8015
8264
|
return await this.get(key);
|
|
8016
8265
|
}
|
|
8017
|
-
console.debug(
|
|
8266
|
+
console.debug(p9, "key not in cache", key);
|
|
8018
8267
|
const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
|
|
8019
8268
|
this.instanceCache[key] = pending;
|
|
8020
8269
|
try {
|
|
@@ -8048,13 +8297,6 @@ function isInstanceable(obj) {
|
|
|
8048
8297
|
init_DisplayPosition();
|
|
8049
8298
|
init_DisplayTransforms();
|
|
8050
8299
|
|
|
8051
|
-
// src/model/GuiLight.ts
|
|
8052
|
-
var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
8053
|
-
GuiLight2["FRONT"] = "front";
|
|
8054
|
-
GuiLight2["SIDE"] = "side";
|
|
8055
|
-
return GuiLight2;
|
|
8056
|
-
})(GuiLight || {});
|
|
8057
|
-
|
|
8058
8300
|
// src/model/Model.ts
|
|
8059
8301
|
var ITEM_GENERATED = "item/generated";
|
|
8060
8302
|
var BUILTIN_GENERATED = "builtin/generated";
|
|
@@ -8079,7 +8321,7 @@ init_ModelMerger();
|
|
|
8079
8321
|
init_BlockStates();
|
|
8080
8322
|
init_MineRenderError();
|
|
8081
8323
|
init_util();
|
|
8082
|
-
import { Euler as
|
|
8324
|
+
import { Euler as Euler7 } from "three";
|
|
8083
8325
|
function matchesCondition(condition, state) {
|
|
8084
8326
|
return Object.entries(condition).every(([key, value]) => {
|
|
8085
8327
|
if (Array.isArray(value)) {
|
|
@@ -8154,7 +8396,7 @@ var BlockStateResolver = class {
|
|
|
8154
8396
|
return variants[variants.length - 1];
|
|
8155
8397
|
}
|
|
8156
8398
|
static rotation(variant) {
|
|
8157
|
-
const rotation = new
|
|
8399
|
+
const rotation = new Euler7();
|
|
8158
8400
|
if (typeof variant.x !== "undefined") {
|
|
8159
8401
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
8160
8402
|
}
|
|
@@ -8264,7 +8506,7 @@ var import_ts_deepmerge6 = __toESM(require_dist());
|
|
|
8264
8506
|
init_MineRenderError();
|
|
8265
8507
|
init_InstanceReference();
|
|
8266
8508
|
init_AssetKey();
|
|
8267
|
-
import { Euler as
|
|
8509
|
+
import { Euler as Euler8, Matrix4 as Matrix48, Quaternion as Quaternion5, Vector3 as Vector311 } from "three";
|
|
8268
8510
|
init_ModelCulling();
|
|
8269
8511
|
init_FluidGeometry();
|
|
8270
8512
|
var _BlockObject = class _BlockObject extends SceneObject {
|
|
@@ -8330,7 +8572,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8330
8572
|
const scale = new Vector311();
|
|
8331
8573
|
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
8332
8574
|
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector311(1, 1, 1)) > 1e-10) return 0;
|
|
8333
|
-
return ModelCulling.toLocalMask(worldMask, new
|
|
8575
|
+
return ModelCulling.toLocalMask(worldMask, new Euler8().setFromQuaternion(rotation));
|
|
8334
8576
|
}
|
|
8335
8577
|
async setCullMask(worldMask) {
|
|
8336
8578
|
worldMask &= 63;
|
|
@@ -8392,7 +8634,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8392
8634
|
() => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
|
|
8393
8635
|
);
|
|
8394
8636
|
const previous = this._fluidModel;
|
|
8395
|
-
const matrix = previous ? this.getModelMatrix(previous) : new
|
|
8637
|
+
const matrix = previous ? this.getModelMatrix(previous) : new Matrix48().makeTranslation(...this.position.toArray());
|
|
8396
8638
|
if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
|
|
8397
8639
|
else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
8398
8640
|
this._models = this._models.filter((model) => model !== previous);
|
|
@@ -8523,7 +8765,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8523
8765
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
8524
8766
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
8525
8767
|
}
|
|
8526
|
-
getMatrixAt(index, matrix = new
|
|
8768
|
+
getMatrixAt(index, matrix = new Matrix48()) {
|
|
8527
8769
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
8528
8770
|
const child = this._models[0];
|
|
8529
8771
|
if (child && isModelObject(child)) {
|
|
@@ -13087,7 +13329,7 @@ init_CubeFace();
|
|
|
13087
13329
|
init_AssetKey();
|
|
13088
13330
|
init_Models();
|
|
13089
13331
|
init_CubeFace();
|
|
13090
|
-
import { Matrix4 as
|
|
13332
|
+
import { Matrix4 as Matrix49, Vector3 as Vector314 } from "three";
|
|
13091
13333
|
init_ModelCulling();
|
|
13092
13334
|
init_ModelObject();
|
|
13093
13335
|
init_UVMapper();
|
|
@@ -13150,7 +13392,7 @@ var SectionModels = class {
|
|
|
13150
13392
|
});
|
|
13151
13393
|
await object.init();
|
|
13152
13394
|
const geometry = object.children[0].geometry;
|
|
13153
|
-
geometry.applyMatrix4(new
|
|
13395
|
+
geometry.applyMatrix4(new Matrix49().makeRotationFromEuler(rotation));
|
|
13154
13396
|
object.clear();
|
|
13155
13397
|
const cullFaces = CUBE_FACES.map((face) => {
|
|
13156
13398
|
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
@@ -13400,7 +13642,7 @@ var MineRenderWorld = class {
|
|
|
13400
13642
|
// src/world/SectionMesh.ts
|
|
13401
13643
|
init_CanvasCompat();
|
|
13402
13644
|
init_Materials();
|
|
13403
|
-
import { BufferGeometry as
|
|
13645
|
+
import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute6, Group, Mesh as Mesh10 } from "three";
|
|
13404
13646
|
var SectionMesh = class _SectionMesh extends Group {
|
|
13405
13647
|
constructor() {
|
|
13406
13648
|
super(...arguments);
|
|
@@ -13474,7 +13716,7 @@ var SectionMesh = class _SectionMesh extends Group {
|
|
|
13474
13716
|
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
13475
13717
|
}
|
|
13476
13718
|
}
|
|
13477
|
-
const geometry = new
|
|
13719
|
+
const geometry = new BufferGeometry6();
|
|
13478
13720
|
geometry.setAttribute("position", new Float32BufferAttribute6(positions, 3));
|
|
13479
13721
|
geometry.setAttribute("normal", new Float32BufferAttribute6(normals, 3));
|
|
13480
13722
|
geometry.setAttribute("uv", new Float32BufferAttribute6(uvs, 2));
|